aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86_64/kernel/entry.S
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@novell.com>2006-09-26 04:52:41 -0400
committerAndi Kleen <andi@basil.nowhere.org>2006-09-26 04:52:41 -0400
commitadf1423698f00d00b267f7dca8231340ce7d65ef (patch)
treeec2e28a32d467cc3c618c8ee0cedd3d1a49f9c43 /arch/x86_64/kernel/entry.S
parentab2e0b46cb9a197fab7d98e147cac7cd41a14047 (diff)
[PATCH] i386/x86-64: Work around gcc bug with noreturn functions in unwinder
Current gcc generates calls not jumps to noreturn functions. When that happens the return address can point to the next function, which confuses the unwinder. This patch works around it by marking asynchronous exception frames in contrast normal call frames in the unwind information. Then teach the unwinder to decode this. For normal call frames the unwinder now subtracts one from the address which avoids this problem. The standard libgcc unwinder uses the same trick. It doesn't include adjustment of the printed address (i.e. for the original example, it'd still be kernel_math_error+0 that gets displayed, but the unwinder wouldn't get confused anymore. This only works with binutils 2.6.17+ and some versions of H.J.Lu's 2.6.16 unfortunately because earlier binutils don't support .cfi_signal_frame [AK: added automatic detection of the new binutils and wrote description] Signed-off-by: Jan Beulich <jbeulich@novell.com> Signed-off-by: Andi Kleen <ak@suse.de>
Diffstat (limited to 'arch/x86_64/kernel/entry.S')
-rw-r--r--arch/x86_64/kernel/entry.S4
1 files changed, 4 insertions, 0 deletions
diff --git a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S
index ea32688386fd..4cbc65290ae7 100644
--- a/arch/x86_64/kernel/entry.S
+++ b/arch/x86_64/kernel/entry.S
@@ -123,6 +123,7 @@
123 .macro CFI_DEFAULT_STACK start=1 123 .macro CFI_DEFAULT_STACK start=1
124 .if \start 124 .if \start
125 CFI_STARTPROC simple 125 CFI_STARTPROC simple
126 CFI_SIGNAL_FRAME
126 CFI_DEF_CFA rsp,SS+8 127 CFI_DEF_CFA rsp,SS+8
127 .else 128 .else
128 CFI_DEF_CFA_OFFSET SS+8 129 CFI_DEF_CFA_OFFSET SS+8
@@ -207,6 +208,7 @@ END(ret_from_fork)
207 208
208ENTRY(system_call) 209ENTRY(system_call)
209 CFI_STARTPROC simple 210 CFI_STARTPROC simple
211 CFI_SIGNAL_FRAME
210 CFI_DEF_CFA rsp,PDA_STACKOFFSET 212 CFI_DEF_CFA rsp,PDA_STACKOFFSET
211 CFI_REGISTER rip,rcx 213 CFI_REGISTER rip,rcx
212 /*CFI_REGISTER rflags,r11*/ 214 /*CFI_REGISTER rflags,r11*/
@@ -324,6 +326,7 @@ END(system_call)
324 */ 326 */
325ENTRY(int_ret_from_sys_call) 327ENTRY(int_ret_from_sys_call)
326 CFI_STARTPROC simple 328 CFI_STARTPROC simple
329 CFI_SIGNAL_FRAME
327 CFI_DEF_CFA rsp,SS+8-ARGOFFSET 330 CFI_DEF_CFA rsp,SS+8-ARGOFFSET
328 /*CFI_REL_OFFSET ss,SS-ARGOFFSET*/ 331 /*CFI_REL_OFFSET ss,SS-ARGOFFSET*/
329 CFI_REL_OFFSET rsp,RSP-ARGOFFSET 332 CFI_REL_OFFSET rsp,RSP-ARGOFFSET
@@ -484,6 +487,7 @@ END(stub_rt_sigreturn)
484 */ 487 */
485 .macro _frame ref 488 .macro _frame ref
486 CFI_STARTPROC simple 489 CFI_STARTPROC simple
490 CFI_SIGNAL_FRAME
487 CFI_DEF_CFA rsp,SS+8-\ref 491 CFI_DEF_CFA rsp,SS+8-\ref
488 /*CFI_REL_OFFSET ss,SS-\ref*/ 492 /*CFI_REL_OFFSET ss,SS-\ref*/
489 CFI_REL_OFFSET rsp,RSP-\ref 493 CFI_REL_OFFSET rsp,RSP-\ref