aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--arch/i386/Makefile4
-rw-r--r--arch/i386/kernel/entry.S4
-rw-r--r--arch/x86_64/Makefile4
-rw-r--r--arch/x86_64/ia32/ia32entry.S4
-rw-r--r--arch/x86_64/kernel/entry.S4
-rw-r--r--include/asm-i386/dwarf2.h7
-rw-r--r--include/asm-i386/unwind.h5
-rw-r--r--include/asm-x86_64/dwarf2.h6
-rw-r--r--include/asm-x86_64/unwind.h5
-rw-r--r--kernel/unwind.c35
-rw-r--r--scripts/Kbuild.include4
11 files changed, 73 insertions, 9 deletions
diff --git a/arch/i386/Makefile b/arch/i386/Makefile
index 508cdbeb3a09..7cc0b189b82b 100644
--- a/arch/i386/Makefile
+++ b/arch/i386/Makefile
@@ -50,6 +50,10 @@ CFLAGS += $(shell if [ $(call cc-version) -lt 0400 ] ; then echo $(call cc-op
50cflags-y += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,) 50cflags-y += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
51AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,) 51AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
52 52
53# is .cfi_signal_frame supported too?
54cflags-y += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
55AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
56
53CFLAGS += $(cflags-y) 57CFLAGS += $(cflags-y)
54 58
55# Default subarch .c files 59# Default subarch .c files
diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S
index 284f2e908ad0..5a63d6fdb70e 100644
--- a/arch/i386/kernel/entry.S
+++ b/arch/i386/kernel/entry.S
@@ -183,18 +183,21 @@ VM_MASK = 0x00020000
183 183
184#define RING0_INT_FRAME \ 184#define RING0_INT_FRAME \
185 CFI_STARTPROC simple;\ 185 CFI_STARTPROC simple;\
186 CFI_SIGNAL_FRAME;\
186 CFI_DEF_CFA esp, 3*4;\ 187 CFI_DEF_CFA esp, 3*4;\
187 /*CFI_OFFSET cs, -2*4;*/\ 188 /*CFI_OFFSET cs, -2*4;*/\
188 CFI_OFFSET eip, -3*4 189 CFI_OFFSET eip, -3*4
189 190
190#define RING0_EC_FRAME \ 191#define RING0_EC_FRAME \
191 CFI_STARTPROC simple;\ 192 CFI_STARTPROC simple;\
193 CFI_SIGNAL_FRAME;\
192 CFI_DEF_CFA esp, 4*4;\ 194 CFI_DEF_CFA esp, 4*4;\
193 /*CFI_OFFSET cs, -2*4;*/\ 195 /*CFI_OFFSET cs, -2*4;*/\
194 CFI_OFFSET eip, -3*4 196 CFI_OFFSET eip, -3*4
195 197
196#define RING0_PTREGS_FRAME \ 198#define RING0_PTREGS_FRAME \
197 CFI_STARTPROC simple;\ 199 CFI_STARTPROC simple;\
200 CFI_SIGNAL_FRAME;\
198 CFI_DEF_CFA esp, OLDESP-EBX;\ 201 CFI_DEF_CFA esp, OLDESP-EBX;\
199 /*CFI_OFFSET cs, CS-OLDESP;*/\ 202 /*CFI_OFFSET cs, CS-OLDESP;*/\
200 CFI_OFFSET eip, EIP-OLDESP;\ 203 CFI_OFFSET eip, EIP-OLDESP;\
@@ -275,6 +278,7 @@ need_resched:
275 # sysenter call handler stub 278 # sysenter call handler stub
276ENTRY(sysenter_entry) 279ENTRY(sysenter_entry)
277 CFI_STARTPROC simple 280 CFI_STARTPROC simple
281 CFI_SIGNAL_FRAME
278 CFI_DEF_CFA esp, 0 282 CFI_DEF_CFA esp, 0
279 CFI_REGISTER esp, ebp 283 CFI_REGISTER esp, ebp
280 movl TSS_sysenter_esp0(%esp),%esp 284 movl TSS_sysenter_esp0(%esp),%esp
diff --git a/arch/x86_64/Makefile b/arch/x86_64/Makefile
index 2b8d07c70106..1c0f18d4f887 100644
--- a/arch/x86_64/Makefile
+++ b/arch/x86_64/Makefile
@@ -58,6 +58,10 @@ cflags-y += $(call cc-option,-mno-sse -mno-mmx -mno-sse2 -mno-3dnow,)
58cflags-y += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,) 58cflags-y += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
59AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,) 59AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,)
60 60
61# is .cfi_signal_frame supported too?
62cflags-y += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,)
63AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,)
64
61cflags-$(CONFIG_CC_STACKPROTECTOR) += $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-x86_64-has-stack-protector.sh $(CC) -fstack-protector ) 65cflags-$(CONFIG_CC_STACKPROTECTOR) += $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-x86_64-has-stack-protector.sh $(CC) -fstack-protector )
62cflags-$(CONFIG_CC_STACKPROTECTOR_ALL) += $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-x86_64-has-stack-protector.sh $(CC) -fstack-protector-all ) 66cflags-$(CONFIG_CC_STACKPROTECTOR_ALL) += $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-x86_64-has-stack-protector.sh $(CC) -fstack-protector-all )
63 67
diff --git a/arch/x86_64/ia32/ia32entry.S b/arch/x86_64/ia32/ia32entry.S
index 32fd32bea07c..b4aa875e175b 100644
--- a/arch/x86_64/ia32/ia32entry.S
+++ b/arch/x86_64/ia32/ia32entry.S
@@ -71,6 +71,7 @@
71 */ 71 */
72ENTRY(ia32_sysenter_target) 72ENTRY(ia32_sysenter_target)
73 CFI_STARTPROC32 simple 73 CFI_STARTPROC32 simple
74 CFI_SIGNAL_FRAME
74 CFI_DEF_CFA rsp,0 75 CFI_DEF_CFA rsp,0
75 CFI_REGISTER rsp,rbp 76 CFI_REGISTER rsp,rbp
76 swapgs 77 swapgs
@@ -186,6 +187,7 @@ ENDPROC(ia32_sysenter_target)
186 */ 187 */
187ENTRY(ia32_cstar_target) 188ENTRY(ia32_cstar_target)
188 CFI_STARTPROC32 simple 189 CFI_STARTPROC32 simple
190 CFI_SIGNAL_FRAME
189 CFI_DEF_CFA rsp,PDA_STACKOFFSET 191 CFI_DEF_CFA rsp,PDA_STACKOFFSET
190 CFI_REGISTER rip,rcx 192 CFI_REGISTER rip,rcx
191 /*CFI_REGISTER rflags,r11*/ 193 /*CFI_REGISTER rflags,r11*/
@@ -293,6 +295,7 @@ ia32_badarg:
293 295
294ENTRY(ia32_syscall) 296ENTRY(ia32_syscall)
295 CFI_STARTPROC simple 297 CFI_STARTPROC simple
298 CFI_SIGNAL_FRAME
296 CFI_DEF_CFA rsp,SS+8-RIP 299 CFI_DEF_CFA rsp,SS+8-RIP
297 /*CFI_REL_OFFSET ss,SS-RIP*/ 300 /*CFI_REL_OFFSET ss,SS-RIP*/
298 CFI_REL_OFFSET rsp,RSP-RIP 301 CFI_REL_OFFSET rsp,RSP-RIP
@@ -370,6 +373,7 @@ ENTRY(ia32_ptregs_common)
370 popq %r11 373 popq %r11
371 CFI_ENDPROC 374 CFI_ENDPROC
372 CFI_STARTPROC32 simple 375 CFI_STARTPROC32 simple
376 CFI_SIGNAL_FRAME
373 CFI_DEF_CFA rsp,SS+8-ARGOFFSET 377 CFI_DEF_CFA rsp,SS+8-ARGOFFSET
374 CFI_REL_OFFSET rax,RAX-ARGOFFSET 378 CFI_REL_OFFSET rax,RAX-ARGOFFSET
375 CFI_REL_OFFSET rcx,RCX-ARGOFFSET 379 CFI_REL_OFFSET rcx,RCX-ARGOFFSET
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
diff --git a/include/asm-i386/dwarf2.h b/include/asm-i386/dwarf2.h
index 5d1a8db5a9b0..6d66398a307d 100644
--- a/include/asm-i386/dwarf2.h
+++ b/include/asm-i386/dwarf2.h
@@ -28,6 +28,12 @@
28#define CFI_RESTORE_STATE .cfi_restore_state 28#define CFI_RESTORE_STATE .cfi_restore_state
29#define CFI_UNDEFINED .cfi_undefined 29#define CFI_UNDEFINED .cfi_undefined
30 30
31#ifdef CONFIG_AS_CFI_SIGNAL_FRAME
32#define CFI_SIGNAL_FRAME .cfi_signal_frame
33#else
34#define CFI_SIGNAL_FRAME
35#endif
36
31#else 37#else
32 38
33/* Due to the structure of pre-exisiting code, don't use assembler line 39/* Due to the structure of pre-exisiting code, don't use assembler line
@@ -48,6 +54,7 @@
48#define CFI_REMEMBER_STATE ignore 54#define CFI_REMEMBER_STATE ignore
49#define CFI_RESTORE_STATE ignore 55#define CFI_RESTORE_STATE ignore
50#define CFI_UNDEFINED ignore 56#define CFI_UNDEFINED ignore
57#define CFI_SIGNAL_FRAME ignore
51 58
52#endif 59#endif
53 60
diff --git a/include/asm-i386/unwind.h b/include/asm-i386/unwind.h
index f0ac399bae3c..5031d693b89d 100644
--- a/include/asm-i386/unwind.h
+++ b/include/asm-i386/unwind.h
@@ -18,6 +18,7 @@ struct unwind_frame_info
18{ 18{
19 struct pt_regs regs; 19 struct pt_regs regs;
20 struct task_struct *task; 20 struct task_struct *task;
21 unsigned call_frame:1;
21}; 22};
22 23
23#define UNW_PC(frame) (frame)->regs.eip 24#define UNW_PC(frame) (frame)->regs.eip
@@ -44,6 +45,10 @@ struct unwind_frame_info
44 PTREGS_INFO(edi), \ 45 PTREGS_INFO(edi), \
45 PTREGS_INFO(eip) 46 PTREGS_INFO(eip)
46 47
48#define UNW_DEFAULT_RA(raItem, dataAlign) \
49 ((raItem).where == Memory && \
50 !((raItem).value * (dataAlign) + 4))
51
47static inline void arch_unw_init_frame_info(struct unwind_frame_info *info, 52static inline void arch_unw_init_frame_info(struct unwind_frame_info *info,
48 /*const*/ struct pt_regs *regs) 53 /*const*/ struct pt_regs *regs)
49{ 54{
diff --git a/include/asm-x86_64/dwarf2.h b/include/asm-x86_64/dwarf2.h
index 2b9368365fad..eedc08526b0b 100644
--- a/include/asm-x86_64/dwarf2.h
+++ b/include/asm-x86_64/dwarf2.h
@@ -28,6 +28,11 @@
28#define CFI_REMEMBER_STATE .cfi_remember_state 28#define CFI_REMEMBER_STATE .cfi_remember_state
29#define CFI_RESTORE_STATE .cfi_restore_state 29#define CFI_RESTORE_STATE .cfi_restore_state
30#define CFI_UNDEFINED .cfi_undefined 30#define CFI_UNDEFINED .cfi_undefined
31#ifdef CONFIG_AS_CFI_SIGNAL_FRAME
32#define CFI_SIGNAL_FRAME .cfi_signal_frame
33#else
34#define CFI_SIGNAL_FRAME
35#endif
31 36
32#else 37#else
33 38
@@ -45,6 +50,7 @@
45#define CFI_REMEMBER_STATE # 50#define CFI_REMEMBER_STATE #
46#define CFI_RESTORE_STATE # 51#define CFI_RESTORE_STATE #
47#define CFI_UNDEFINED # 52#define CFI_UNDEFINED #
53#define CFI_SIGNAL_FRAME #
48 54
49#endif 55#endif
50 56
diff --git a/include/asm-x86_64/unwind.h b/include/asm-x86_64/unwind.h
index 1f6e9bfb569e..b8fa5cb7ff88 100644
--- a/include/asm-x86_64/unwind.h
+++ b/include/asm-x86_64/unwind.h
@@ -18,6 +18,7 @@ struct unwind_frame_info
18{ 18{
19 struct pt_regs regs; 19 struct pt_regs regs;
20 struct task_struct *task; 20 struct task_struct *task;
21 unsigned call_frame:1;
21}; 22};
22 23
23#define UNW_PC(frame) (frame)->regs.rip 24#define UNW_PC(frame) (frame)->regs.rip
@@ -57,6 +58,10 @@ struct unwind_frame_info
57 PTREGS_INFO(r15), \ 58 PTREGS_INFO(r15), \
58 PTREGS_INFO(rip) 59 PTREGS_INFO(rip)
59 60
61#define UNW_DEFAULT_RA(raItem, dataAlign) \
62 ((raItem).where == Memory && \
63 !((raItem).value * (dataAlign) + 8))
64
60static inline void arch_unw_init_frame_info(struct unwind_frame_info *info, 65static inline void arch_unw_init_frame_info(struct unwind_frame_info *info,
61 /*const*/ struct pt_regs *regs) 66 /*const*/ struct pt_regs *regs)
62{ 67{
diff --git a/kernel/unwind.c b/kernel/unwind.c
index f69c804c8e62..3430475fcd88 100644
--- a/kernel/unwind.c
+++ b/kernel/unwind.c
@@ -603,6 +603,7 @@ int unwind(struct unwind_frame_info *frame)
603#define FRAME_REG(r, t) (((t *)frame)[reg_info[r].offs]) 603#define FRAME_REG(r, t) (((t *)frame)[reg_info[r].offs])
604 const u32 *fde = NULL, *cie = NULL; 604 const u32 *fde = NULL, *cie = NULL;
605 const u8 *ptr = NULL, *end = NULL; 605 const u8 *ptr = NULL, *end = NULL;
606 unsigned long pc = UNW_PC(frame) - frame->call_frame;
606 unsigned long startLoc = 0, endLoc = 0, cfa; 607 unsigned long startLoc = 0, endLoc = 0, cfa;
607 unsigned i; 608 unsigned i;
608 signed ptrType = -1; 609 signed ptrType = -1;
@@ -612,7 +613,7 @@ int unwind(struct unwind_frame_info *frame)
612 613
613 if (UNW_PC(frame) == 0) 614 if (UNW_PC(frame) == 0)
614 return -EINVAL; 615 return -EINVAL;
615 if ((table = find_table(UNW_PC(frame))) != NULL 616 if ((table = find_table(pc)) != NULL
616 && !(table->size & (sizeof(*fde) - 1))) { 617 && !(table->size & (sizeof(*fde) - 1))) {
617 unsigned long tableSize = table->size; 618 unsigned long tableSize = table->size;
618 619
@@ -647,7 +648,7 @@ int unwind(struct unwind_frame_info *frame)
647 ptrType & DW_EH_PE_indirect 648 ptrType & DW_EH_PE_indirect
648 ? ptrType 649 ? ptrType
649 : ptrType & (DW_EH_PE_FORM|DW_EH_PE_signed)); 650 : ptrType & (DW_EH_PE_FORM|DW_EH_PE_signed));
650 if (UNW_PC(frame) >= startLoc && UNW_PC(frame) < endLoc) 651 if (pc >= startLoc && pc < endLoc)
651 break; 652 break;
652 cie = NULL; 653 cie = NULL;
653 } 654 }
@@ -657,16 +658,28 @@ int unwind(struct unwind_frame_info *frame)
657 state.cieEnd = ptr; /* keep here temporarily */ 658 state.cieEnd = ptr; /* keep here temporarily */
658 ptr = (const u8 *)(cie + 2); 659 ptr = (const u8 *)(cie + 2);
659 end = (const u8 *)(cie + 1) + *cie; 660 end = (const u8 *)(cie + 1) + *cie;
661 frame->call_frame = 1;
660 if ((state.version = *ptr) != 1) 662 if ((state.version = *ptr) != 1)
661 cie = NULL; /* unsupported version */ 663 cie = NULL; /* unsupported version */
662 else if (*++ptr) { 664 else if (*++ptr) {
663 /* check if augmentation size is first (and thus present) */ 665 /* check if augmentation size is first (and thus present) */
664 if (*ptr == 'z') { 666 if (*ptr == 'z') {
665 /* check for ignorable (or already handled) 667 while (++ptr < end && *ptr) {
666 * nul-terminated augmentation string */ 668 switch(*ptr) {
667 while (++ptr < end && *ptr) 669 /* check for ignorable (or already handled)
668 if (strchr("LPR", *ptr) == NULL) 670 * nul-terminated augmentation string */
671 case 'L':
672 case 'P':
673 case 'R':
674 continue;
675 case 'S':
676 frame->call_frame = 0;
677 continue;
678 default:
669 break; 679 break;
680 }
681 break;
682 }
670 } 683 }
671 if (ptr >= end || *ptr) 684 if (ptr >= end || *ptr)
672 cie = NULL; 685 cie = NULL;
@@ -755,7 +768,7 @@ int unwind(struct unwind_frame_info *frame)
755 state.org = startLoc; 768 state.org = startLoc;
756 memcpy(&state.cfa, &badCFA, sizeof(state.cfa)); 769 memcpy(&state.cfa, &badCFA, sizeof(state.cfa));
757 /* process instructions */ 770 /* process instructions */
758 if (!processCFI(ptr, end, UNW_PC(frame), ptrType, &state) 771 if (!processCFI(ptr, end, pc, ptrType, &state)
759 || state.loc > endLoc 772 || state.loc > endLoc
760 || state.regs[retAddrReg].where == Nowhere 773 || state.regs[retAddrReg].where == Nowhere
761 || state.cfa.reg >= ARRAY_SIZE(reg_info) 774 || state.cfa.reg >= ARRAY_SIZE(reg_info)
@@ -763,6 +776,11 @@ int unwind(struct unwind_frame_info *frame)
763 || state.cfa.offs % sizeof(unsigned long)) 776 || state.cfa.offs % sizeof(unsigned long))
764 return -EIO; 777 return -EIO;
765 /* update frame */ 778 /* update frame */
779#ifndef CONFIG_AS_CFI_SIGNAL_FRAME
780 if(frame->call_frame
781 && !UNW_DEFAULT_RA(state.regs[retAddrReg], state.dataAlign))
782 frame->call_frame = 0;
783#endif
766 cfa = FRAME_REG(state.cfa.reg, unsigned long) + state.cfa.offs; 784 cfa = FRAME_REG(state.cfa.reg, unsigned long) + state.cfa.offs;
767 startLoc = min((unsigned long)UNW_SP(frame), cfa); 785 startLoc = min((unsigned long)UNW_SP(frame), cfa);
768 endLoc = max((unsigned long)UNW_SP(frame), cfa); 786 endLoc = max((unsigned long)UNW_SP(frame), cfa);
@@ -866,6 +884,7 @@ int unwind_init_frame_info(struct unwind_frame_info *info,
866 /*const*/ struct pt_regs *regs) 884 /*const*/ struct pt_regs *regs)
867{ 885{
868 info->task = tsk; 886 info->task = tsk;
887 info->call_frame = 0;
869 arch_unw_init_frame_info(info, regs); 888 arch_unw_init_frame_info(info, regs);
870 889
871 return 0; 890 return 0;
@@ -879,6 +898,7 @@ int unwind_init_blocked(struct unwind_frame_info *info,
879 struct task_struct *tsk) 898 struct task_struct *tsk)
880{ 899{
881 info->task = tsk; 900 info->task = tsk;
901 info->call_frame = 0;
882 arch_unw_init_blocked(info); 902 arch_unw_init_blocked(info);
883 903
884 return 0; 904 return 0;
@@ -894,6 +914,7 @@ int unwind_init_running(struct unwind_frame_info *info,
894 void *arg) 914 void *arg)
895{ 915{
896 info->task = current; 916 info->task = current;
917 info->call_frame = 0;
897 918
898 return arch_unwind_init_running(info, callback, arg); 919 return arch_unwind_init_running(info, callback, arg);
899} 920}
diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include
index 7adef12a0c26..4f5ff19b992b 100644
--- a/scripts/Kbuild.include
+++ b/scripts/Kbuild.include
@@ -66,8 +66,8 @@ as-option = $(shell if $(CC) $(CFLAGS) $(1) -Wa,-Z -c -o /dev/null \
66# as-instr 66# as-instr
67# Usage: cflags-y += $(call as-instr, instr, option1, option2) 67# Usage: cflags-y += $(call as-instr, instr, option1, option2)
68 68
69as-instr = $(shell if echo -e "$(1)" | $(AS) -Z -o astest$$$$.out \ 69as-instr = $(shell if echo -e "$(1)" | $(AS) >/dev/null 2>&1 -W -Z -o astest$$$$.out ; \
70 2>&1 >/dev/null ; then echo "$(2)"; else echo "$(3)"; fi; \ 70 then echo "$(2)"; else echo "$(3)"; fi; \
71 rm -f astest$$$$.out) 71 rm -f astest$$$$.out)
72 72
73# cc-option 73# cc-option