diff options
-rw-r--r-- | arch/i386/Makefile | 4 | ||||
-rw-r--r-- | arch/i386/kernel/entry.S | 4 | ||||
-rw-r--r-- | arch/x86_64/Makefile | 4 | ||||
-rw-r--r-- | arch/x86_64/ia32/ia32entry.S | 4 | ||||
-rw-r--r-- | arch/x86_64/kernel/entry.S | 4 | ||||
-rw-r--r-- | include/asm-i386/dwarf2.h | 7 | ||||
-rw-r--r-- | include/asm-i386/unwind.h | 5 | ||||
-rw-r--r-- | include/asm-x86_64/dwarf2.h | 6 | ||||
-rw-r--r-- | include/asm-x86_64/unwind.h | 5 | ||||
-rw-r--r-- | kernel/unwind.c | 35 | ||||
-rw-r--r-- | scripts/Kbuild.include | 4 |
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 | |||
50 | cflags-y += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,) | 50 | cflags-y += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,) |
51 | AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,) | 51 | AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,) |
52 | 52 | ||
53 | # is .cfi_signal_frame supported too? | ||
54 | cflags-y += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,) | ||
55 | AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,) | ||
56 | |||
53 | CFLAGS += $(cflags-y) | 57 | CFLAGS += $(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 |
276 | ENTRY(sysenter_entry) | 279 | ENTRY(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,) | |||
58 | cflags-y += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,) | 58 | cflags-y += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,) |
59 | AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,) | 59 | AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,) |
60 | 60 | ||
61 | # is .cfi_signal_frame supported too? | ||
62 | cflags-y += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,) | ||
63 | AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,) | ||
64 | |||
61 | cflags-$(CONFIG_CC_STACKPROTECTOR) += $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-x86_64-has-stack-protector.sh $(CC) -fstack-protector ) | 65 | cflags-$(CONFIG_CC_STACKPROTECTOR) += $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-x86_64-has-stack-protector.sh $(CC) -fstack-protector ) |
62 | cflags-$(CONFIG_CC_STACKPROTECTOR_ALL) += $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-x86_64-has-stack-protector.sh $(CC) -fstack-protector-all ) | 66 | cflags-$(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 | */ |
72 | ENTRY(ia32_sysenter_target) | 72 | ENTRY(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 | */ |
187 | ENTRY(ia32_cstar_target) | 188 | ENTRY(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 | ||
294 | ENTRY(ia32_syscall) | 296 | ENTRY(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 | ||
208 | ENTRY(system_call) | 209 | ENTRY(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 | */ |
325 | ENTRY(int_ret_from_sys_call) | 327 | ENTRY(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 | |||
47 | static inline void arch_unw_init_frame_info(struct unwind_frame_info *info, | 52 | static 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 | |||
60 | static inline void arch_unw_init_frame_info(struct unwind_frame_info *info, | 65 | static 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 | ||
69 | as-instr = $(shell if echo -e "$(1)" | $(AS) -Z -o astest$$$$.out \ | 69 | as-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 |