[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:
Yao Qi
2015-04-10 10:33:01 +01:00
parent 906d60cf46
commit ef713951c5
5 changed files with 83 additions and 10 deletions

View File

@ -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;
}