Skip to content

Commit 5499172

Browse files
committed
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.
1 parent 1509494 commit 5499172

File tree

4 files changed

+24
-8
lines changed

4 files changed

+24
-8
lines changed

arch/x32/ksigaction.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
struct k_sigaction {
2+
void (*handler)(int);
3+
unsigned long flags;
4+
void (*restorer)(void);
5+
unsigned mask[2];
6+
};
7+
8+
void __restore_rt();
9+
#define __restore __restore_rt

arch/x86_64/ksigaction.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
struct k_sigaction {
2+
void (*handler)(int);
3+
unsigned long flags;
4+
void (*restorer)(void);
5+
unsigned mask[2];
6+
};
7+
8+
void __restore_rt();
9+
#define __restore __restore_rt

src/signal/x32/restore.s

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1+
nop
12
.global __restore_rt
2-
.global __restore
33
.type __restore_rt,@function
4-
.type __restore,@function
54
__restore_rt:
6-
__restore:
7-
movl $0x40000201, %eax /* SYS_rt_sigreturn */
5+
mov $0x40000201, %rax /* SYS_rt_sigreturn */
86
syscall
7+
.size __restore_rt,.-__restore_rt

src/signal/x86_64/restore.s

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1+
nop
12
.global __restore_rt
2-
.global __restore
33
.type __restore_rt,@function
4-
.type __restore,@function
54
__restore_rt:
6-
__restore:
7-
movl $15, %eax
5+
mov $15, %rax
86
syscall
7+
.size __restore_rt,.-__restore_rt

0 commit comments

Comments
 (0)