aboutsummaryrefslogtreecommitdiffstats
path: root/main/musl/0033-work-around-gdb-issues-recognizing-sigreturn-trampol.patch
blob: a2484645022cac961b991582370f364988b617a0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
From 54991729fd1e3d3a0cb71884d758d86afe6da9e0 Mon Sep 17 00:00:00 2001
From: Rich Felker <dalias@aerifal.cx>
Date: Sat, 12 Nov 2016 19:43:37 -0500
Subject: [PATCH] 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.
---
 arch/x32/ksigaction.h       | 9 +++++++++
 arch/x86_64/ksigaction.h    | 9 +++++++++
 src/signal/x32/restore.s    | 7 +++----
 src/signal/x86_64/restore.s | 7 +++----
 4 files changed, 24 insertions(+), 8 deletions(-)
 create mode 100644 arch/x32/ksigaction.h
 create mode 100644 arch/x86_64/ksigaction.h

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
-- 
2.11.0