mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-02-23 13:21:43 +08:00
[arm] Fix displaced stepping for thumb alu reg instruction
Recent patch series "V2 All-stop on top of non-stop" causes a SIGSEGV in the test case, > -PASS: gdb.base/info-shared.exp: continue to breakpoint: library function #4 > +FAIL: gdb.base/info-shared.exp: continue to breakpoint: library function #4 > > continue^M > Continuing.^M > ^M > Program received signal SIGSEGV, Segmentation fault.^M > 0x40021564 in ?? () gdb/testsuite/gdb.base/info-shared-solib1.so^M > (gdb) FAIL: gdb.base/info-shared.exp: continue to breakpoint: library function #4 and an ARM displaced stepping bug is exposed. It can be reproduced by the modified gdb.arch/arm-disp-step.exp as below, continue^M Continuing.^M ^M Program received signal SIGSEGV, Segmentation fault.^M 0xa713cfcc in ?? ()^M (gdb) FAIL: gdb.arch/arm-disp-step.exp: continue to breakpoint: continue to test_add_rn_pc_end This patch is to fix it. gdb: 2015-04-10 Yao Qi <yao.qi@linaro.org> * arm-tdep.c (install_alu_reg): Update comment. (thumb_copy_alu_reg): Remove local variable rn. Update debugging message. Use r2 instead of r1 in the modified instruction. gdb/testsuite: 2015-04-10 Yao Qi <yao.qi@linaro.org> * gdb.arch/arm-disp-step.S (main): Call test_add_rn_pc. (test_add_rn_pc): New function. * gdb.arch/arm-disp-step.exp (test_add_rn_pc): New proc. (top level): Invoke test_add_rn_pc.
This commit is contained in:
parent
906d60cf46
commit
ef713951c5
@ -1,3 +1,10 @@
|
||||
2015-04-10 Yao Qi <yao.qi@linaro.org>
|
||||
|
||||
* arm-tdep.c (install_alu_reg): Update comment.
|
||||
(thumb_copy_alu_reg): Remove local variable rn. Update
|
||||
debugging message. Use r2 instead of r1 in the modified
|
||||
instruction.
|
||||
|
||||
2015-04-10 Pedro Alves <palves@redhat.com>
|
||||
|
||||
PR gdb/13858
|
||||
|
@ -6407,7 +6407,7 @@ install_alu_reg (struct gdbarch *gdbarch, struct regcache *regs,
|
||||
|
||||
Preparation: tmp1, tmp2, tmp3 <- r0, r1, r2;
|
||||
r0, r1, r2 <- rd, rn, rm
|
||||
Insn: <op><cond> r0, r1, r2 [, <shift>]
|
||||
Insn: <op><cond> r0, [r1,] r2 [, <shift>]
|
||||
Cleanup: rd <- r0; r0, r1, r2 <- tmp1, tmp2, tmp3
|
||||
*/
|
||||
|
||||
@ -6454,22 +6454,21 @@ thumb_copy_alu_reg (struct gdbarch *gdbarch, uint16_t insn,
|
||||
struct regcache *regs,
|
||||
struct displaced_step_closure *dsc)
|
||||
{
|
||||
unsigned rn, rm, rd;
|
||||
unsigned rm, rd;
|
||||
|
||||
rd = bits (insn, 3, 6);
|
||||
rn = (bit (insn, 7) << 3) | bits (insn, 0, 2);
|
||||
rm = 2;
|
||||
rm = bits (insn, 3, 6);
|
||||
rd = (bit (insn, 7) << 3) | bits (insn, 0, 2);
|
||||
|
||||
if (rd != ARM_PC_REGNUM && rn != ARM_PC_REGNUM)
|
||||
if (rd != ARM_PC_REGNUM && rm != ARM_PC_REGNUM)
|
||||
return thumb_copy_unmodified_16bit (gdbarch, insn, "ALU reg", dsc);
|
||||
|
||||
if (debug_displaced)
|
||||
fprintf_unfiltered (gdb_stdlog, "displaced: copying reg %s insn %.4x\n",
|
||||
"ALU", (unsigned short) insn);
|
||||
fprintf_unfiltered (gdb_stdlog, "displaced: copying ALU reg insn %.4x\n",
|
||||
(unsigned short) insn);
|
||||
|
||||
dsc->modinsn[0] = ((insn & 0xff00) | 0x08);
|
||||
dsc->modinsn[0] = ((insn & 0xff00) | 0x10);
|
||||
|
||||
install_alu_reg (gdbarch, regs, dsc, rd, rn, rm);
|
||||
install_alu_reg (gdbarch, regs, dsc, rd, rd, rm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,3 +1,10 @@
|
||||
2015-04-10 Yao Qi <yao.qi@linaro.org>
|
||||
|
||||
* gdb.arch/arm-disp-step.S (main): Call test_add_rn_pc.
|
||||
(test_add_rn_pc): New function.
|
||||
* gdb.arch/arm-disp-step.exp (test_add_rn_pc): New proc.
|
||||
(top level): Invoke test_add_rn_pc.
|
||||
|
||||
2015-04-10 Pedro Alves <palves@redhat.com>
|
||||
|
||||
PR gdb/13858
|
||||
|
@ -78,6 +78,11 @@ test_ret_end:
|
||||
#if !defined(__thumb__)
|
||||
bl test_str_pc
|
||||
#endif
|
||||
|
||||
/* Test add with pc in Thumb and Thumb-2 */
|
||||
#if defined(__thumb__)
|
||||
bl test_add_rn_pc
|
||||
#endif
|
||||
/* Return */
|
||||
mov sp, r7
|
||||
sub sp, sp, #4
|
||||
@ -372,3 +377,17 @@ pc_offset_wrong:
|
||||
test_str_pc_end:
|
||||
bx lr
|
||||
#endif
|
||||
|
||||
#if defined(__thumb__)
|
||||
.global test_add_rn_pc
|
||||
.code 16
|
||||
.thumb_func
|
||||
test_add_rn_pc:
|
||||
mov r3, 4
|
||||
test_add_rn_pc_start:
|
||||
add r3, pc
|
||||
.global test_add_rn_pc_end
|
||||
test_add_rn_pc_end:
|
||||
bx lr
|
||||
.size test_add_rn_pc, .-test_add_rn_pc
|
||||
#endif
|
||||
|
@ -371,6 +371,45 @@ proc test_str_pc {} {
|
||||
".*bx lr.*"
|
||||
}
|
||||
|
||||
# Test 16 bit thumb instruction 'add rd, pc'.
|
||||
|
||||
proc test_add_rn_pc {} {
|
||||
global srcfile gdb_prompt
|
||||
|
||||
set test "break test_add_rn_pc"
|
||||
gdb_test_multiple "break *test_add_rn_pc" $test {
|
||||
-re "Breakpoint.*at.* file .*$srcfile, line.*\r\n$gdb_prompt $" {
|
||||
pass $test
|
||||
}
|
||||
-re "No symbol.*\r\n$gdb_prompt $" {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
gdb_continue_to_breakpoint "continue to test_add_rn_pc" \
|
||||
".*mov.*r3, 4.*"
|
||||
|
||||
gdb_test "break *test_add_rn_pc_start" \
|
||||
"Breakpoint.*at.* file .*$srcfile, line.*" \
|
||||
"break test_add_rn_pc_start"
|
||||
|
||||
gdb_continue_to_breakpoint "continue to test_add_rn_pc_start" \
|
||||
".*add.*r3,.*pc.*"
|
||||
|
||||
set pc_val [get_integer_valueof "\$pc" 0]
|
||||
|
||||
gdb_test "break *test_add_rn_pc_end" \
|
||||
"Breakpoint.*at.* file .*$srcfile, line.*" \
|
||||
"break test_add_rn_pc_end"
|
||||
|
||||
gdb_continue_to_breakpoint "continue to test_add_rn_pc_end" \
|
||||
".*bx lr.*"
|
||||
|
||||
set r3_val [get_integer_valueof "\$r3" 0]
|
||||
# Test the value in r3 is correct.
|
||||
gdb_assert { [expr {$pc_val + 4 + 4} == $r3_val] }
|
||||
}
|
||||
|
||||
# Get things started.
|
||||
|
||||
clean_restart ${testfile}
|
||||
@ -410,6 +449,8 @@ test_pop_pc
|
||||
|
||||
test_str_pc
|
||||
|
||||
test_add_rn_pc
|
||||
|
||||
##########################################
|
||||
|
||||
# Done, run program to exit.
|
||||
|
Loading…
Reference in New Issue
Block a user