diff options
author | Vineet Gupta <vgupta@synopsys.com> | 2013-06-24 11:52:06 -0400 |
---|---|---|
committer | Vineet Gupta <vgupta@synopsys.com> | 2016-09-30 17:48:20 -0400 |
commit | 6716dbbdefa9867ba98dea91d89b14168043a48c (patch) | |
tree | d134bd3853996ec3ebae718a786ec9bfe365c8b1 | |
parent | d040876b4aad0c157c5c95779128b71a121ff27d (diff) |
ARC: dw2 unwind: switch to .eh_frame based unwinding
So finally after almost 8 years of dealing with .debug_frame, we are
finally switching to .eh_frame. The reason being stripped kernel
binaries had non-functional unwinder as .debug_frame was gone.
Also, in general .eh_frame seems more common way of doing unwinding.
This also folds a revert of f52e126cc747 ("ARC: unwind: ensure that
.debug_frame is generated (vs. .eh_frame)") to ensure that we start
getting .eh_frame
Reported-by: Daniel Mentz <danielmentz@google.com>
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
-rw-r--r-- | arch/arc/Makefile | 2 | ||||
-rw-r--r-- | arch/arc/kernel/entry.S | 12 | ||||
-rw-r--r-- | arch/arc/kernel/module.c | 13 | ||||
-rw-r--r-- | arch/arc/kernel/unwind.c | 5 | ||||
-rw-r--r-- | arch/arc/kernel/vmlinux.lds.S | 15 |
5 files changed, 13 insertions, 34 deletions
diff --git a/arch/arc/Makefile b/arch/arc/Makefile index 601ed173080b..fc6ff8f09f23 100644 --- a/arch/arc/Makefile +++ b/arch/arc/Makefile | |||
@@ -66,6 +66,8 @@ endif | |||
66 | 66 | ||
67 | endif | 67 | endif |
68 | 68 | ||
69 | cflags-$(CONFIG_ARC_DW2_UNWIND) += -fasynchronous-unwind-tables | ||
70 | |||
69 | # By default gcc 4.8 generates dwarf4 which kernel unwinder can't grok | 71 | # By default gcc 4.8 generates dwarf4 which kernel unwinder can't grok |
70 | ifeq ($(atleast_gcc48),y) | 72 | ifeq ($(atleast_gcc48),y) |
71 | cflags-$(CONFIG_ARC_DW2_UNWIND) += -gdwarf-2 | 73 | cflags-$(CONFIG_ARC_DW2_UNWIND) += -gdwarf-2 |
diff --git a/arch/arc/kernel/entry.S b/arch/arc/kernel/entry.S index 2efb0625331d..741712d4d6ff 100644 --- a/arch/arc/kernel/entry.S +++ b/arch/arc/kernel/entry.S | |||
@@ -61,18 +61,6 @@ ENTRY(ret_from_fork) | |||
61 | b ret_from_exception | 61 | b ret_from_exception |
62 | END(ret_from_fork) | 62 | END(ret_from_fork) |
63 | 63 | ||
64 | #ifdef CONFIG_ARC_DW2_UNWIND | ||
65 | ; Workaround for bug 94179 (STAR ): | ||
66 | ; Despite -fasynchronous-unwind-tables, linker is not making dwarf2 unwinder | ||
67 | ; section (.debug_frame) as loadable. So we force it here. | ||
68 | ; This also fixes STAR 9000487933 where the prev-workaround (objcopy --setflag) | ||
69 | ; would not work after a clean build due to kernel build system dependencies. | ||
70 | .section .debug_frame, "wa",@progbits | ||
71 | |||
72 | ; Reset to .text as this file is included in entry-<isa>.S | ||
73 | .section .text, "ax",@progbits | ||
74 | #endif | ||
75 | |||
76 | ;################### Non TLB Exception Handling ############################# | 64 | ;################### Non TLB Exception Handling ############################# |
77 | 65 | ||
78 | ; --------------------------------------------- | 66 | ; --------------------------------------------- |
diff --git a/arch/arc/kernel/module.c b/arch/arc/kernel/module.c index 576a238434a1..9a2849756022 100644 --- a/arch/arc/kernel/module.c +++ b/arch/arc/kernel/module.c | |||
@@ -22,13 +22,9 @@ static inline void arc_write_me(unsigned short *addr, unsigned long value) | |||
22 | *(addr + 1) = (value & 0xffff); | 22 | *(addr + 1) = (value & 0xffff); |
23 | } | 23 | } |
24 | 24 | ||
25 | /* ARC specific section quirks - before relocation loop in generic loader | 25 | /* |
26 | * | 26 | * This gets called before relocation loop in generic loader |
27 | * For dwarf unwinding out of modules, this needs to | 27 | * Make a note of the section index of unwinding section |
28 | * 1. Ensure the .debug_frame is allocatable (ARC Linker bug: despite | ||
29 | * -fasynchronous-unwind-tables it doesn't). | ||
30 | * 2. Since we are iterating thru sec hdr tbl anyways, make a note of | ||
31 | * the exact section index, for later use. | ||
32 | */ | 28 | */ |
33 | int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, | 29 | int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, |
34 | char *secstr, struct module *mod) | 30 | char *secstr, struct module *mod) |
@@ -40,8 +36,7 @@ int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, | |||
40 | mod->arch.unw_info = NULL; | 36 | mod->arch.unw_info = NULL; |
41 | 37 | ||
42 | for (i = 1; i < hdr->e_shnum; i++) { | 38 | for (i = 1; i < hdr->e_shnum; i++) { |
43 | if (strcmp(secstr+sechdrs[i].sh_name, ".debug_frame") == 0) { | 39 | if (strcmp(secstr+sechdrs[i].sh_name, ".eh_frame") == 0) { |
44 | sechdrs[i].sh_flags |= SHF_ALLOC; | ||
45 | mod->arch.unw_sec_idx = i; | 40 | mod->arch.unw_sec_idx = i; |
46 | break; | 41 | break; |
47 | } | 42 | } |
diff --git a/arch/arc/kernel/unwind.c b/arch/arc/kernel/unwind.c index 4e5dbe7617a1..61fd1ce63c56 100644 --- a/arch/arc/kernel/unwind.c +++ b/arch/arc/kernel/unwind.c | |||
@@ -111,7 +111,7 @@ UNW_REGISTER_INFO}; | |||
111 | #define DW_EH_PE_indirect 0x80 | 111 | #define DW_EH_PE_indirect 0x80 |
112 | #define DW_EH_PE_omit 0xff | 112 | #define DW_EH_PE_omit 0xff |
113 | 113 | ||
114 | #define CIE_ID 0xffffffffUL | 114 | #define CIE_ID 0 |
115 | 115 | ||
116 | typedef unsigned long uleb128_t; | 116 | typedef unsigned long uleb128_t; |
117 | typedef signed long sleb128_t; | 117 | typedef signed long sleb128_t; |
@@ -510,8 +510,7 @@ static const u32 *__cie_for_fde(const u32 *fde) | |||
510 | { | 510 | { |
511 | const u32 *cie; | 511 | const u32 *cie; |
512 | 512 | ||
513 | /* cie = fde + 1 - fde[1] / sizeof(*fde); */ | 513 | cie = fde + 1 - fde[1] / sizeof(*fde); |
514 | cie = (u32 *) fde[1]; | ||
515 | 514 | ||
516 | return cie; | 515 | return cie; |
517 | } | 516 | } |
diff --git a/arch/arc/kernel/vmlinux.lds.S b/arch/arc/kernel/vmlinux.lds.S index 894e696bddaa..bb6d8c5ff2e9 100644 --- a/arch/arc/kernel/vmlinux.lds.S +++ b/arch/arc/kernel/vmlinux.lds.S | |||
@@ -84,7 +84,7 @@ SECTIONS | |||
84 | 84 | ||
85 | /* | 85 | /* |
86 | * .exit.text is discard at runtime, not link time, to deal with | 86 | * .exit.text is discard at runtime, not link time, to deal with |
87 | * references from .debug_frame | 87 | * references from unwinding sections |
88 | * It will be init freed, being inside [__init_start : __init_end] | 88 | * It will be init freed, being inside [__init_start : __init_end] |
89 | */ | 89 | */ |
90 | .exit.text : { EXIT_TEXT } | 90 | .exit.text : { EXIT_TEXT } |
@@ -120,18 +120,13 @@ SECTIONS | |||
120 | 120 | ||
121 | #ifdef CONFIG_ARC_DW2_UNWIND | 121 | #ifdef CONFIG_ARC_DW2_UNWIND |
122 | . = ALIGN(PAGE_SIZE); | 122 | . = ALIGN(PAGE_SIZE); |
123 | .debug_frame : { | 123 | .eh_frame : { |
124 | __start_unwind = .; | 124 | __start_unwind = .; |
125 | *(.debug_frame) | 125 | *(.eh_frame) |
126 | __end_unwind = .; | 126 | __end_unwind = .; |
127 | } | 127 | } |
128 | /* | ||
129 | * gcc 4.8 generates this for -fasynchonous-unwind-tables, | ||
130 | * while we still use the .debug_frame based unwinder | ||
131 | */ | ||
132 | /DISCARD/ : { *(.eh_frame) } | ||
133 | #else | 128 | #else |
134 | /DISCARD/ : { *(.debug_frame) } | 129 | /DISCARD/ : { *(.eh_frame) } |
135 | #endif | 130 | #endif |
136 | 131 | ||
137 | NOTES | 132 | NOTES |
@@ -148,7 +143,7 @@ SECTIONS | |||
148 | } | 143 | } |
149 | 144 | ||
150 | #ifndef CONFIG_DEBUG_INFO | 145 | #ifndef CONFIG_DEBUG_INFO |
151 | /* open-coded because we need .debug_frame seperately for unwinding */ | 146 | /DISCARD/ : { *(.debug_frame) } |
152 | /DISCARD/ : { *(.debug_aranges) } | 147 | /DISCARD/ : { *(.debug_aranges) } |
153 | /DISCARD/ : { *(.debug_pubnames) } | 148 | /DISCARD/ : { *(.debug_pubnames) } |
154 | /DISCARD/ : { *(.debug_info) } | 149 | /DISCARD/ : { *(.debug_info) } |