Detect the arm/thumb mode of code SIGRETURN or RT_SIGRETURN returns to
This patch fixes the following regression introduced by commit
d0e59a68
step^M
39 } /* handler */^M
1: x/i $pc^M
=> 0x8740 <handler+80>: sub sp, r11, #0^M
(gdb) step^M
^M
Program received signal SIGSEGV, Segmentation fault.^M
setitimer () at ../sysdeps/unix/syscall-template.S:81^M
81 ../sysdeps/unix/syscall-template.S: No such file or directory.^M
1: x/i $pc^M
=> 0xb6eff9c0 <setitimer>: push {r7}^M
(gdb) FAIL: gdb.base/sigstep.exp: continue to handler, si+advance in handler, step from handler: leave handler
in my test setting, program is compiled in arm mode, but the glibc
is built in thumb mode, so when we do 'step' to step over syscall
instruction svc for SIGRETURN, GDB should set breakpoint for arm mode
in the program, even though the current program in glibc is in thumb
mode. Current GDB doesn't consider the case that the mode of program
SIGRETURN goes to can be different from current program mode.
In fact, GDB has taken care of this arm/thumb mode changes already,
see
/* Copy the value of next pc of sigreturn and rt_sigrturn into PC,
return 1. In addition, set IS_THUMB depending on whether we
will return to ARM or Thumb code. Return 0 if it is not a
rt_sigreturn/sigreturn syscall. */
static int
arm_linux_sigreturn_return_addr (struct frame_info *frame,
unsigned long svc_number,
CORE_ADDR *pc, int *is_thumb)
but in the commit
d0e59a68
> - arm_linux_sigreturn_return_addr (frame, svc_number, &return_addr, &is_thumb);
> + if (svc_number == ARM_SIGRETURN || svc_number == ARM_RT_SIGRETURN)
> + next_pc = arm_linux_sigreturn_next_pc (regcache, svc_number);
the IS_THUMB setting is lost, so it is a regression.
gdb:
2016-01-21 Yao Qi <yao.qi@linaro.org>
* arm-linux-tdep.c (arm_linux_sigreturn_next_pc): Add parameter
is_thumb and set it according to CPSR saved on the stack.
(arm_linux_get_next_pcs_syscall_next_pc): Pass is_thumb to
arm_linux_sigreturn_next_pc.
gdb/gdbserver:
2016-01-21 Yao Qi <yao.qi@linaro.org>
* linux-arm-low.c (arm_sigreturn_next_pc): Add parameter
is_thumb and set it according to CPSR saved on the stack.
(get_next_pcs_syscall_next_pc): Pass is_thumb to
arm_sigreturn_next_pc.