work around gdb issues recognizing sigreturn trampoline on x86_64

gdb can only backtrace/unwind across signal handlers if it recognizes
the sa_restorer trampoline. for x86_64, gdb first attempts to
determine the symbol name for the function in which the program
counter resides and match it against "__restore_rt". if no name can be
found (e.g. in the case of a stripped binary), the exact instruction
sequence is matched instead.

when matching the function name, however, gdb's unwind code wrongly
considers the interval [sym,sym+size] rather than [sym,sym+size).
thus, if __restore_rt begins immediately after another function, gdb
wrongly identifies pc as lying within the previous adjacent function.
this patch adds a nop before __restore_rt to preclude that
possibility. it also removes the symbol name __restore and replaces it
with a macro since the stability of whether gdb identifies the
function as __restore_rt or __restore is not clear.

for the no-symbols case, the instruction sequence is changed to use
%rax rather than %eax to match what gdb expects.

based on patch by Szabolcs Nagy, with extended description and
corresponding x32 changes added.
This commit is contained in:
Rich Felker 2016-11-12 19:43:37 -05:00
parent 1509494305
commit 54991729fd
4 changed files with 24 additions and 8 deletions

9
arch/x32/ksigaction.h Normal file
View File

@ -0,0 +1,9 @@
struct k_sigaction {
void (*handler)(int);
unsigned long flags;
void (*restorer)(void);
unsigned mask[2];
};
void __restore_rt();
#define __restore __restore_rt

9
arch/x86_64/ksigaction.h Normal file
View File

@ -0,0 +1,9 @@
struct k_sigaction {
void (*handler)(int);
unsigned long flags;
void (*restorer)(void);
unsigned mask[2];
};
void __restore_rt();
#define __restore __restore_rt

View File

@ -1,8 +1,7 @@
nop
.global __restore_rt
.global __restore
.type __restore_rt,@function
.type __restore,@function
__restore_rt:
__restore:
movl $0x40000201, %eax /* SYS_rt_sigreturn */
mov $0x40000201, %rax /* SYS_rt_sigreturn */
syscall
.size __restore_rt,.-__restore_rt

View File

@ -1,8 +1,7 @@
nop
.global __restore_rt
.global __restore
.type __restore_rt,@function
.type __restore,@function
__restore_rt:
__restore:
movl $15, %eax
mov $15, %rax
syscall
.size __restore_rt,.-__restore_rt