summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2016-11-12 19:43:37 -0500
committerRich Felker <dalias@aerifal.cx>2016-11-12 19:54:43 -0500
commit54991729fd1e3d3a0cb71884d758d86afe6da9e0 (patch)
tree220f219af4477a552995f66de3d26a71e603c26b
parent15094943050eb9a564f409323070e50b40f78816 (diff)
downloadmusl-54991729fd1e3d3a0cb71884d758d86afe6da9e0.tar.gz
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.
-rw-r--r--arch/x32/ksigaction.h9
-rw-r--r--arch/x86_64/ksigaction.h9
-rw-r--r--src/signal/x32/restore.s7
-rw-r--r--src/signal/x86_64/restore.s7
4 files changed, 24 insertions, 8 deletions
diff --git a/arch/x32/ksigaction.h b/arch/x32/ksigaction.h
new file mode 100644
index 00000000..7743c5c6
--- /dev/null
+++ b/arch/x32/ksigaction.h
@@ -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
diff --git a/arch/x86_64/ksigaction.h b/arch/x86_64/ksigaction.h
new file mode 100644
index 00000000..7743c5c6
--- /dev/null
+++ b/arch/x86_64/ksigaction.h
@@ -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
diff --git a/src/signal/x32/restore.s b/src/signal/x32/restore.s
index 27cd3cef..2f06e787 100644
--- a/src/signal/x32/restore.s
+++ b/src/signal/x32/restore.s
@@ -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
diff --git a/src/signal/x86_64/restore.s b/src/signal/x86_64/restore.s
index 682af2dd..b5c6e37f 100644
--- a/src/signal/x86_64/restore.s
+++ b/src/signal/x86_64/restore.s
@@ -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