diff options
-rw-r--r-- | arch/sh/Kconfig.debug | 8 | ||||
-rw-r--r-- | arch/sh/Makefile | 4 | ||||
-rw-r--r-- | arch/sh/include/asm/dwarf.h | 407 | ||||
-rw-r--r-- | arch/sh/include/asm/sections.h | 1 | ||||
-rw-r--r-- | arch/sh/include/asm/vmlinux.lds.h | 17 | ||||
-rw-r--r-- | arch/sh/kernel/Makefile_32 | 1 | ||||
-rw-r--r-- | arch/sh/kernel/Makefile_64 | 1 | ||||
-rw-r--r-- | arch/sh/kernel/dwarf.c | 876 | ||||
-rw-r--r-- | arch/sh/kernel/irq.c | 4 | ||||
-rw-r--r-- | arch/sh/kernel/vmlinux.lds.S | 4 |
10 files changed, 1322 insertions, 1 deletions
diff --git a/arch/sh/Kconfig.debug b/arch/sh/Kconfig.debug index 763b792b1611..741d20fab2e1 100644 --- a/arch/sh/Kconfig.debug +++ b/arch/sh/Kconfig.debug | |||
@@ -110,6 +110,14 @@ config DUMP_CODE | |||
110 | 110 | ||
111 | Those looking for more verbose debugging output should say Y. | 111 | Those looking for more verbose debugging output should say Y. |
112 | 112 | ||
113 | config DWARF_UNWINDER | ||
114 | bool "Enable the DWARF unwinder for stacktraces" | ||
115 | select FRAME_POINTER | ||
116 | default n | ||
117 | help | ||
118 | Enabling this option will make stacktraces more accurate, at | ||
119 | the cost of an increase in overall kernel size. | ||
120 | |||
113 | config SH_NO_BSS_INIT | 121 | config SH_NO_BSS_INIT |
114 | bool "Avoid zeroing BSS (to speed-up startup on suitable platforms)" | 122 | bool "Avoid zeroing BSS (to speed-up startup on suitable platforms)" |
115 | depends on DEBUG_KERNEL | 123 | depends on DEBUG_KERNEL |
diff --git a/arch/sh/Makefile b/arch/sh/Makefile index b6ff337fd856..e26421bf9976 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile | |||
@@ -191,6 +191,10 @@ ifeq ($(CONFIG_MCOUNT),y) | |||
191 | KBUILD_CFLAGS += -pg | 191 | KBUILD_CFLAGS += -pg |
192 | endif | 192 | endif |
193 | 193 | ||
194 | ifeq ($(CONFIG_DWARF_UNWINDER),y) | ||
195 | KBUILD_CFLAGS += -fasynchronous-unwind-tables | ||
196 | endif | ||
197 | |||
194 | libs-$(CONFIG_SUPERH32) := arch/sh/lib/ $(libs-y) | 198 | libs-$(CONFIG_SUPERH32) := arch/sh/lib/ $(libs-y) |
195 | libs-$(CONFIG_SUPERH64) := arch/sh/lib64/ $(libs-y) | 199 | libs-$(CONFIG_SUPERH64) := arch/sh/lib64/ $(libs-y) |
196 | 200 | ||
diff --git a/arch/sh/include/asm/dwarf.h b/arch/sh/include/asm/dwarf.h new file mode 100644 index 000000000000..23eba12880b3 --- /dev/null +++ b/arch/sh/include/asm/dwarf.h | |||
@@ -0,0 +1,407 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2009 Matt Fleming <matt@console-pimps.org> | ||
3 | * | ||
4 | * This file is subject to the terms and conditions of the GNU General Public | ||
5 | * License. See the file "COPYING" in the main directory of this archive | ||
6 | * for more details. | ||
7 | * | ||
8 | */ | ||
9 | #ifndef __ASM_SH_DWARF_H | ||
10 | #define __ASM_SH_DWARF_H | ||
11 | |||
12 | #ifdef CONFIG_DWARF_UNWINDER | ||
13 | |||
14 | /* | ||
15 | * DWARF expression operations | ||
16 | */ | ||
17 | #define DW_OP_addr 0x03 | ||
18 | #define DW_OP_deref 0x06 | ||
19 | #define DW_OP_const1u 0x08 | ||
20 | #define DW_OP_const1s 0x09 | ||
21 | #define DW_OP_const2u 0x0a | ||
22 | #define DW_OP_const2s 0x0b | ||
23 | #define DW_OP_const4u 0x0c | ||
24 | #define DW_OP_const4s 0x0d | ||
25 | #define DW_OP_const8u 0x0e | ||
26 | #define DW_OP_const8s 0x0f | ||
27 | #define DW_OP_constu 0x10 | ||
28 | #define DW_OP_consts 0x11 | ||
29 | #define DW_OP_dup 0x12 | ||
30 | #define DW_OP_drop 0x13 | ||
31 | #define DW_OP_over 0x14 | ||
32 | #define DW_OP_pick 0x15 | ||
33 | #define DW_OP_swap 0x16 | ||
34 | #define DW_OP_rot 0x17 | ||
35 | #define DW_OP_xderef 0x18 | ||
36 | #define DW_OP_abs 0x19 | ||
37 | #define DW_OP_and 0x1a | ||
38 | #define DW_OP_div 0x1b | ||
39 | #define DW_OP_minus 0x1c | ||
40 | #define DW_OP_mod 0x1d | ||
41 | #define DW_OP_mul 0x1e | ||
42 | #define DW_OP_neg 0x1f | ||
43 | #define DW_OP_not 0x20 | ||
44 | #define DW_OP_or 0x21 | ||
45 | #define DW_OP_plus 0x22 | ||
46 | #define DW_OP_plus_uconst 0x23 | ||
47 | #define DW_OP_shl 0x24 | ||
48 | #define DW_OP_shr 0x25 | ||
49 | #define DW_OP_shra 0x26 | ||
50 | #define DW_OP_xor 0x27 | ||
51 | #define DW_OP_skip 0x2f | ||
52 | #define DW_OP_bra 0x28 | ||
53 | #define DW_OP_eq 0x29 | ||
54 | #define DW_OP_ge 0x2a | ||
55 | #define DW_OP_gt 0x2b | ||
56 | #define DW_OP_le 0x2c | ||
57 | #define DW_OP_lt 0x2d | ||
58 | #define DW_OP_ne 0x2e | ||
59 | #define DW_OP_lit0 0x30 | ||
60 | #define DW_OP_lit1 0x31 | ||
61 | #define DW_OP_lit2 0x32 | ||
62 | #define DW_OP_lit3 0x33 | ||
63 | #define DW_OP_lit4 0x34 | ||
64 | #define DW_OP_lit5 0x35 | ||
65 | #define DW_OP_lit6 0x36 | ||
66 | #define DW_OP_lit7 0x37 | ||
67 | #define DW_OP_lit8 0x38 | ||
68 | #define DW_OP_lit9 0x39 | ||
69 | #define DW_OP_lit10 0x3a | ||
70 | #define DW_OP_lit11 0x3b | ||
71 | #define DW_OP_lit12 0x3c | ||
72 | #define DW_OP_lit13 0x3d | ||
73 | #define DW_OP_lit14 0x3e | ||
74 | #define DW_OP_lit15 0x3f | ||
75 | #define DW_OP_lit16 0x40 | ||
76 | #define DW_OP_lit17 0x41 | ||
77 | #define DW_OP_lit18 0x42 | ||
78 | #define DW_OP_lit19 0x43 | ||
79 | #define DW_OP_lit20 0x44 | ||
80 | #define DW_OP_lit21 0x45 | ||
81 | #define DW_OP_lit22 0x46 | ||
82 | #define DW_OP_lit23 0x47 | ||
83 | #define DW_OP_lit24 0x48 | ||
84 | #define DW_OP_lit25 0x49 | ||
85 | #define DW_OP_lit26 0x4a | ||
86 | #define DW_OP_lit27 0x4b | ||
87 | #define DW_OP_lit28 0x4c | ||
88 | #define DW_OP_lit29 0x4d | ||
89 | #define DW_OP_lit30 0x4e | ||
90 | #define DW_OP_lit31 0x4f | ||
91 | #define DW_OP_reg0 0x50 | ||
92 | #define DW_OP_reg1 0x51 | ||
93 | #define DW_OP_reg2 0x52 | ||
94 | #define DW_OP_reg3 0x53 | ||
95 | #define DW_OP_reg4 0x54 | ||
96 | #define DW_OP_reg5 0x55 | ||
97 | #define DW_OP_reg6 0x56 | ||
98 | #define DW_OP_reg7 0x57 | ||
99 | #define DW_OP_reg8 0x58 | ||
100 | #define DW_OP_reg9 0x59 | ||
101 | #define DW_OP_reg10 0x5a | ||
102 | #define DW_OP_reg11 0x5b | ||
103 | #define DW_OP_reg12 0x5c | ||
104 | #define DW_OP_reg13 0x5d | ||
105 | #define DW_OP_reg14 0x5e | ||
106 | #define DW_OP_reg15 0x5f | ||
107 | #define DW_OP_reg16 0x60 | ||
108 | #define DW_OP_reg17 0x61 | ||
109 | #define DW_OP_reg18 0x62 | ||
110 | #define DW_OP_reg19 0x63 | ||
111 | #define DW_OP_reg20 0x64 | ||
112 | #define DW_OP_reg21 0x65 | ||
113 | #define DW_OP_reg22 0x66 | ||
114 | #define DW_OP_reg23 0x67 | ||
115 | #define DW_OP_reg24 0x68 | ||
116 | #define DW_OP_reg25 0x69 | ||
117 | #define DW_OP_reg26 0x6a | ||
118 | #define DW_OP_reg27 0x6b | ||
119 | #define DW_OP_reg28 0x6c | ||
120 | #define DW_OP_reg29 0x6d | ||
121 | #define DW_OP_reg30 0x6e | ||
122 | #define DW_OP_reg31 0x6f | ||
123 | #define DW_OP_breg0 0x70 | ||
124 | #define DW_OP_breg1 0x71 | ||
125 | #define DW_OP_breg2 0x72 | ||
126 | #define DW_OP_breg3 0x73 | ||
127 | #define DW_OP_breg4 0x74 | ||
128 | #define DW_OP_breg5 0x75 | ||
129 | #define DW_OP_breg6 0x76 | ||
130 | #define DW_OP_breg7 0x77 | ||
131 | #define DW_OP_breg8 0x78 | ||
132 | #define DW_OP_breg9 0x79 | ||
133 | #define DW_OP_breg10 0x7a | ||
134 | #define DW_OP_breg11 0x7b | ||
135 | #define DW_OP_breg12 0x7c | ||
136 | #define DW_OP_breg13 0x7d | ||
137 | #define DW_OP_breg14 0x7e | ||
138 | #define DW_OP_breg15 0x7f | ||
139 | #define DW_OP_breg16 0x80 | ||
140 | #define DW_OP_breg17 0x81 | ||
141 | #define DW_OP_breg18 0x82 | ||
142 | #define DW_OP_breg19 0x83 | ||
143 | #define DW_OP_breg20 0x84 | ||
144 | #define DW_OP_breg21 0x85 | ||
145 | #define DW_OP_breg22 0x86 | ||
146 | #define DW_OP_breg23 0x87 | ||
147 | #define DW_OP_breg24 0x88 | ||
148 | #define DW_OP_breg25 0x89 | ||
149 | #define DW_OP_breg26 0x8a | ||
150 | #define DW_OP_breg27 0x8b | ||
151 | #define DW_OP_breg28 0x8c | ||
152 | #define DW_OP_breg29 0x8d | ||
153 | #define DW_OP_breg30 0x8e | ||
154 | #define DW_OP_breg31 0x8f | ||
155 | #define DW_OP_regx 0x90 | ||
156 | #define DW_OP_fbreg 0x91 | ||
157 | #define DW_OP_bregx 0x92 | ||
158 | #define DW_OP_piece 0x93 | ||
159 | #define DW_OP_deref_size 0x94 | ||
160 | #define DW_OP_xderef_size 0x95 | ||
161 | #define DW_OP_nop 0x96 | ||
162 | #define DW_OP_push_object_address 0x97 | ||
163 | #define DW_OP_call2 0x98 | ||
164 | #define DW_OP_call4 0x99 | ||
165 | #define DW_OP_call_ref 0x9a | ||
166 | #define DW_OP_form_tls_address 0x9b | ||
167 | #define DW_OP_call_frame_cfa 0x9c | ||
168 | #define DW_OP_bit_piece 0x9d | ||
169 | #define DW_OP_lo_user 0xe0 | ||
170 | #define DW_OP_hi_user 0xff | ||
171 | |||
172 | /* | ||
173 | * Addresses used in FDE entries in the .eh_frame section may be encoded | ||
174 | * using one of the following encodings. | ||
175 | */ | ||
176 | #define DW_EH_PE_absptr 0x00 | ||
177 | #define DW_EH_PE_omit 0xff | ||
178 | #define DW_EH_PE_uleb128 0x01 | ||
179 | #define DW_EH_PE_udata2 0x02 | ||
180 | #define DW_EH_PE_udata4 0x03 | ||
181 | #define DW_EH_PE_udata8 0x04 | ||
182 | #define DW_EH_PE_sleb128 0x09 | ||
183 | #define DW_EH_PE_sdata2 0x0a | ||
184 | #define DW_EH_PE_sdata4 0x0b | ||
185 | #define DW_EH_PE_sdata8 0x0c | ||
186 | #define DW_EH_PE_signed 0x09 | ||
187 | |||
188 | #define DW_EH_PE_pcrel 0x10 | ||
189 | |||
190 | /* | ||
191 | * The architecture-specific register number that contains the return | ||
192 | * address in the .debug_frame table. | ||
193 | */ | ||
194 | #define DWARF_ARCH_RA_REG 17 | ||
195 | |||
196 | /* | ||
197 | * At what offset into dwarf_unwind_stack() is DWARF_ARCH_RA_REG setup? | ||
198 | */ | ||
199 | #define DWARF_ARCH_UNWIND_OFFSET 0x20 | ||
200 | |||
201 | #ifndef __ASSEMBLY__ | ||
202 | /* | ||
203 | * Read either the frame pointer (r14) or the stack pointer (r15). | ||
204 | * NOTE: this MUST be inlined. | ||
205 | */ | ||
206 | static __always_inline unsigned long dwarf_read_arch_reg(unsigned int reg) | ||
207 | { | ||
208 | unsigned long value; | ||
209 | |||
210 | switch (reg) { | ||
211 | case 14: | ||
212 | __asm__ __volatile__("mov r14, %0\n" : "=r" (value)); | ||
213 | break; | ||
214 | case 15: | ||
215 | __asm__ __volatile__("mov r15, %0\n" : "=r" (value)); | ||
216 | break; | ||
217 | default: | ||
218 | BUG(); | ||
219 | } | ||
220 | |||
221 | return value; | ||
222 | } | ||
223 | |||
224 | /** | ||
225 | * dwarf_cie - Common Information Entry | ||
226 | */ | ||
227 | struct dwarf_cie { | ||
228 | unsigned long length; | ||
229 | unsigned long cie_id; | ||
230 | unsigned char version; | ||
231 | const char *augmentation; | ||
232 | unsigned int code_alignment_factor; | ||
233 | int data_alignment_factor; | ||
234 | |||
235 | /* Which column in the rule table represents return addr of func. */ | ||
236 | unsigned int return_address_reg; | ||
237 | |||
238 | unsigned char *initial_instructions; | ||
239 | unsigned char *instructions_end; | ||
240 | |||
241 | unsigned char encoding; | ||
242 | |||
243 | unsigned long cie_pointer; | ||
244 | |||
245 | struct list_head link; | ||
246 | |||
247 | unsigned long flags; | ||
248 | #define DWARF_CIE_Z_AUGMENTATION (1 << 0) | ||
249 | }; | ||
250 | |||
251 | /** | ||
252 | * dwarf_fde - Frame Description Entry | ||
253 | */ | ||
254 | struct dwarf_fde { | ||
255 | unsigned long length; | ||
256 | unsigned long cie_pointer; | ||
257 | struct dwarf_cie *cie; | ||
258 | unsigned long initial_location; | ||
259 | unsigned long address_range; | ||
260 | unsigned char *instructions; | ||
261 | unsigned char *end; | ||
262 | struct list_head link; | ||
263 | }; | ||
264 | |||
265 | /** | ||
266 | * dwarf_frame - DWARF information for a frame in the call stack | ||
267 | */ | ||
268 | struct dwarf_frame { | ||
269 | struct dwarf_frame *prev, *next; | ||
270 | |||
271 | unsigned long pc; | ||
272 | |||
273 | struct dwarf_reg *regs; | ||
274 | unsigned int num_regs; /* how many regs are allocated? */ | ||
275 | |||
276 | unsigned int depth; /* what level are we in the callstack? */ | ||
277 | |||
278 | unsigned long cfa; | ||
279 | |||
280 | /* Valid when DW_FRAME_CFA_REG_OFFSET is set in flags */ | ||
281 | unsigned int cfa_register; | ||
282 | unsigned int cfa_offset; | ||
283 | |||
284 | /* Valid when DW_FRAME_CFA_REG_EXP is set in flags */ | ||
285 | unsigned char *cfa_expr; | ||
286 | unsigned int cfa_expr_len; | ||
287 | |||
288 | unsigned long flags; | ||
289 | #define DWARF_FRAME_CFA_REG_OFFSET (1 << 0) | ||
290 | #define DWARF_FRAME_CFA_REG_EXP (1 << 1) | ||
291 | |||
292 | unsigned long return_addr; | ||
293 | }; | ||
294 | |||
295 | /** | ||
296 | * dwarf_reg - DWARF register | ||
297 | * @flags: Describes how to calculate the value of this register | ||
298 | */ | ||
299 | struct dwarf_reg { | ||
300 | unsigned long addr; | ||
301 | unsigned long flags; | ||
302 | #define DWARF_REG_OFFSET (1 << 0) | ||
303 | }; | ||
304 | |||
305 | /** | ||
306 | * dwarf_stack - a DWARF stack contains a collection of DWARF frames | ||
307 | * @depth: the number of frames in the stack | ||
308 | * @level: an array of DWARF frames, indexed by stack level | ||
309 | * | ||
310 | */ | ||
311 | struct dwarf_stack { | ||
312 | unsigned int depth; | ||
313 | struct dwarf_frame **level; | ||
314 | }; | ||
315 | |||
316 | /* | ||
317 | * Call Frame instruction opcodes. | ||
318 | */ | ||
319 | #define DW_CFA_advance_loc 0x40 | ||
320 | #define DW_CFA_offset 0x80 | ||
321 | #define DW_CFA_restore 0xc0 | ||
322 | #define DW_CFA_nop 0x00 | ||
323 | #define DW_CFA_set_loc 0x01 | ||
324 | #define DW_CFA_advance_loc1 0x02 | ||
325 | #define DW_CFA_advance_loc2 0x03 | ||
326 | #define DW_CFA_advance_loc4 0x04 | ||
327 | #define DW_CFA_offset_extended 0x05 | ||
328 | #define DW_CFA_restore_extended 0x06 | ||
329 | #define DW_CFA_undefined 0x07 | ||
330 | #define DW_CFA_same_value 0x08 | ||
331 | #define DW_CFA_register 0x09 | ||
332 | #define DW_CFA_remember_state 0x0a | ||
333 | #define DW_CFA_restore_state 0x0b | ||
334 | #define DW_CFA_def_cfa 0x0c | ||
335 | #define DW_CFA_def_cfa_register 0x0d | ||
336 | #define DW_CFA_def_cfa_offset 0x0e | ||
337 | #define DW_CFA_def_cfa_expression 0x0f | ||
338 | #define DW_CFA_expression 0x10 | ||
339 | #define DW_CFA_offset_extended_sf 0x11 | ||
340 | #define DW_CFA_def_cfa_sf 0x12 | ||
341 | #define DW_CFA_def_cfa_offset_sf 0x13 | ||
342 | #define DW_CFA_val_offset 0x14 | ||
343 | #define DW_CFA_val_offset_sf 0x15 | ||
344 | #define DW_CFA_val_expression 0x16 | ||
345 | #define DW_CFA_lo_user 0x1c | ||
346 | #define DW_CFA_hi_user 0x3f | ||
347 | |||
348 | /* | ||
349 | * Some call frame instructions encode their operands in the opcode. We | ||
350 | * need some helper functions to extract both the opcode and operands | ||
351 | * from an instruction. | ||
352 | */ | ||
353 | static inline unsigned int DW_CFA_opcode(unsigned long insn) | ||
354 | { | ||
355 | return (insn & 0xc0); | ||
356 | } | ||
357 | |||
358 | static inline unsigned int DW_CFA_operand(unsigned long insn) | ||
359 | { | ||
360 | return (insn & 0x3f); | ||
361 | } | ||
362 | |||
363 | #define DW_EH_FRAME_CIE 0 /* .eh_frame CIE IDs are 0 */ | ||
364 | #define DW_CIE_ID 0xffffffff | ||
365 | #define DW64_CIE_ID 0xffffffffffffffffULL | ||
366 | |||
367 | /* | ||
368 | * DWARF FDE/CIE length field values. | ||
369 | */ | ||
370 | #define DW_EXT_LO 0xfffffff0 | ||
371 | #define DW_EXT_HI 0xffffffff | ||
372 | #define DW_EXT_DWARF64 DW_EXT_HI | ||
373 | |||
374 | extern void dwarf_unwinder_init(void); | ||
375 | |||
376 | extern struct dwarf_frame *dwarf_unwind_stack(unsigned long, | ||
377 | struct dwarf_frame *); | ||
378 | #endif /* __ASSEMBLY__ */ | ||
379 | |||
380 | #define CFI_STARTPROC .cfi_startproc | ||
381 | #define CFI_ENDPROC .cfi_endproc | ||
382 | #define CFI_DEF_CFA .cfi_def_cfa | ||
383 | #define CFI_REGISTER .cfi_register | ||
384 | #define CFI_REL_OFFSET .cfi_rel_offset | ||
385 | |||
386 | #else | ||
387 | |||
388 | /* | ||
389 | * Use the asm comment character to ignore the rest of the line. | ||
390 | */ | ||
391 | #define CFI_IGNORE ! | ||
392 | |||
393 | #define CFI_STARTPROC CFI_IGNORE | ||
394 | #define CFI_ENDPROC CFI_IGNORE | ||
395 | #define CFI_DEF_CFA CFI_IGNORE | ||
396 | #define CFI_REGISTER CFI_IGNORE | ||
397 | #define CFI_REL_OFFSET CFI_IGNORE | ||
398 | |||
399 | #ifndef __ASSEMBLY__ | ||
400 | static inline void dwarf_unwinder_init(void) | ||
401 | { | ||
402 | } | ||
403 | #endif | ||
404 | |||
405 | #endif /* CONFIG_DWARF_UNWINDER */ | ||
406 | |||
407 | #endif /* __ASM_SH_DWARF_H */ | ||
diff --git a/arch/sh/include/asm/sections.h b/arch/sh/include/asm/sections.h index 01a4076a3719..a78701da775b 100644 --- a/arch/sh/include/asm/sections.h +++ b/arch/sh/include/asm/sections.h | |||
@@ -7,6 +7,7 @@ extern void __nosave_begin, __nosave_end; | |||
7 | extern long __machvec_start, __machvec_end; | 7 | extern long __machvec_start, __machvec_end; |
8 | extern char __uncached_start, __uncached_end; | 8 | extern char __uncached_start, __uncached_end; |
9 | extern char _ebss[]; | 9 | extern char _ebss[]; |
10 | extern char __start_eh_frame[], __stop_eh_frame[]; | ||
10 | 11 | ||
11 | #endif /* __ASM_SH_SECTIONS_H */ | 12 | #endif /* __ASM_SH_SECTIONS_H */ |
12 | 13 | ||
diff --git a/arch/sh/include/asm/vmlinux.lds.h b/arch/sh/include/asm/vmlinux.lds.h new file mode 100644 index 000000000000..244ec4ad9a79 --- /dev/null +++ b/arch/sh/include/asm/vmlinux.lds.h | |||
@@ -0,0 +1,17 @@ | |||
1 | #ifndef __ASM_SH_VMLINUX_LDS_H | ||
2 | #define __ASM_SH_VMLINUX_LDS_H | ||
3 | |||
4 | #include <asm-generic/vmlinux.lds.h> | ||
5 | |||
6 | #ifdef CONFIG_DWARF_UNWINDER | ||
7 | #define DWARF_EH_FRAME \ | ||
8 | .eh_frame : AT(ADDR(.eh_frame) - LOAD_OFFSET) { \ | ||
9 | VMLINUX_SYMBOL(__start_eh_frame) = .; \ | ||
10 | *(.eh_frame) \ | ||
11 | VMLINUX_SYMBOL(__stop_eh_frame) = .; \ | ||
12 | } | ||
13 | #else | ||
14 | #define DWARF_EH_FRAME | ||
15 | #endif | ||
16 | |||
17 | #endif /* __ASM_SH_VMLINUX_LDS_H */ | ||
diff --git a/arch/sh/kernel/Makefile_32 b/arch/sh/kernel/Makefile_32 index 37a3b7704fc6..f2245ebf0b31 100644 --- a/arch/sh/kernel/Makefile_32 +++ b/arch/sh/kernel/Makefile_32 | |||
@@ -33,6 +33,7 @@ obj-$(CONFIG_FTRACE_SYSCALLS) += ftrace.o | |||
33 | obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o | 33 | obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o |
34 | obj-$(CONFIG_DUMP_CODE) += disassemble.o | 34 | obj-$(CONFIG_DUMP_CODE) += disassemble.o |
35 | obj-$(CONFIG_HIBERNATION) += swsusp.o | 35 | obj-$(CONFIG_HIBERNATION) += swsusp.o |
36 | obj-$(CONFIG_DWARF_UNWINDER) += dwarf.o | ||
36 | 37 | ||
37 | obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) += localtimer.o | 38 | obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) += localtimer.o |
38 | 39 | ||
diff --git a/arch/sh/kernel/Makefile_64 b/arch/sh/kernel/Makefile_64 index 00b73e7598cb..639ee514266c 100644 --- a/arch/sh/kernel/Makefile_64 +++ b/arch/sh/kernel/Makefile_64 | |||
@@ -13,6 +13,7 @@ obj-$(CONFIG_CRASH_DUMP) += crash_dump.o | |||
13 | obj-$(CONFIG_STACKTRACE) += stacktrace.o | 13 | obj-$(CONFIG_STACKTRACE) += stacktrace.o |
14 | obj-$(CONFIG_IO_TRAPPED) += io_trapped.o | 14 | obj-$(CONFIG_IO_TRAPPED) += io_trapped.o |
15 | obj-$(CONFIG_GENERIC_GPIO) += gpio.o | 15 | obj-$(CONFIG_GENERIC_GPIO) += gpio.o |
16 | obj-$(CONFIG_DWARF_UNWINDER) += dwarf.o | ||
16 | 17 | ||
17 | obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) += localtimer.o | 18 | obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) += localtimer.o |
18 | 19 | ||
diff --git a/arch/sh/kernel/dwarf.c b/arch/sh/kernel/dwarf.c new file mode 100644 index 000000000000..09c6fd7fd05f --- /dev/null +++ b/arch/sh/kernel/dwarf.c | |||
@@ -0,0 +1,876 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2009 Matt Fleming <matt@console-pimps.org> | ||
3 | * | ||
4 | * This file is subject to the terms and conditions of the GNU General Public | ||
5 | * License. See the file "COPYING" in the main directory of this archive | ||
6 | * for more details. | ||
7 | * | ||
8 | * This is an implementation of a DWARF unwinder. Its main purpose is | ||
9 | * for generating stacktrace information. Based on the DWARF 3 | ||
10 | * specification from http://www.dwarfstd.org. | ||
11 | * | ||
12 | * TODO: | ||
13 | * - DWARF64 doesn't work. | ||
14 | */ | ||
15 | |||
16 | /* #define DEBUG */ | ||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/io.h> | ||
19 | #include <linux/list.h> | ||
20 | #include <linux/mm.h> | ||
21 | #include <asm/dwarf.h> | ||
22 | #include <asm/unwinder.h> | ||
23 | #include <asm/sections.h> | ||
24 | #include <asm-generic/unaligned.h> | ||
25 | #include <asm/dwarf.h> | ||
26 | #include <asm/stacktrace.h> | ||
27 | |||
28 | static LIST_HEAD(dwarf_cie_list); | ||
29 | DEFINE_SPINLOCK(dwarf_cie_lock); | ||
30 | |||
31 | static LIST_HEAD(dwarf_fde_list); | ||
32 | DEFINE_SPINLOCK(dwarf_fde_lock); | ||
33 | |||
34 | static struct dwarf_cie *cached_cie; | ||
35 | |||
36 | /* | ||
37 | * Figure out whether we need to allocate some dwarf registers. If dwarf | ||
38 | * registers have already been allocated then we may need to realloc | ||
39 | * them. "reg" is a register number that we need to be able to access | ||
40 | * after this call. | ||
41 | * | ||
42 | * Register numbers start at zero, therefore we need to allocate space | ||
43 | * for "reg" + 1 registers. | ||
44 | */ | ||
45 | static void dwarf_frame_alloc_regs(struct dwarf_frame *frame, | ||
46 | unsigned int reg) | ||
47 | { | ||
48 | struct dwarf_reg *regs; | ||
49 | unsigned int num_regs = reg + 1; | ||
50 | size_t new_size; | ||
51 | size_t old_size; | ||
52 | |||
53 | new_size = num_regs * sizeof(*regs); | ||
54 | old_size = frame->num_regs * sizeof(*regs); | ||
55 | |||
56 | /* Fast path: don't allocate any regs if we've already got enough. */ | ||
57 | if (frame->num_regs >= num_regs) | ||
58 | return; | ||
59 | |||
60 | regs = kzalloc(new_size, GFP_KERNEL); | ||
61 | if (!regs) { | ||
62 | printk(KERN_WARNING "Unable to allocate DWARF registers\n"); | ||
63 | /* | ||
64 | * Let's just bomb hard here, we have no way to | ||
65 | * gracefully recover. | ||
66 | */ | ||
67 | BUG(); | ||
68 | } | ||
69 | |||
70 | if (frame->regs) { | ||
71 | memcpy(regs, frame->regs, old_size); | ||
72 | kfree(frame->regs); | ||
73 | } | ||
74 | |||
75 | frame->regs = regs; | ||
76 | frame->num_regs = num_regs; | ||
77 | } | ||
78 | |||
79 | /** | ||
80 | * dwarf_read_addr - read dwarf data | ||
81 | * @src: source address of data | ||
82 | * @dst: destination address to store the data to | ||
83 | * | ||
84 | * Read 'n' bytes from @src, where 'n' is the size of an address on | ||
85 | * the native machine. We return the number of bytes read, which | ||
86 | * should always be 'n'. We also have to be careful when reading | ||
87 | * from @src and writing to @dst, because they can be arbitrarily | ||
88 | * aligned. Return 'n' - the number of bytes read. | ||
89 | */ | ||
90 | static inline int dwarf_read_addr(void *src, void *dst) | ||
91 | { | ||
92 | u32 val = __get_unaligned_cpu32(src); | ||
93 | __put_unaligned_cpu32(val, dst); | ||
94 | |||
95 | return sizeof(unsigned long *); | ||
96 | } | ||
97 | |||
98 | /** | ||
99 | * dwarf_read_uleb128 - read unsigned LEB128 data | ||
100 | * @addr: the address where the ULEB128 data is stored | ||
101 | * @ret: address to store the result | ||
102 | * | ||
103 | * Decode an unsigned LEB128 encoded datum. The algorithm is taken | ||
104 | * from Appendix C of the DWARF 3 spec. For information on the | ||
105 | * encodings refer to section "7.6 - Variable Length Data". Return | ||
106 | * the number of bytes read. | ||
107 | */ | ||
108 | static inline unsigned long dwarf_read_uleb128(char *addr, unsigned int *ret) | ||
109 | { | ||
110 | unsigned int result; | ||
111 | unsigned char byte; | ||
112 | int shift, count; | ||
113 | |||
114 | result = 0; | ||
115 | shift = 0; | ||
116 | count = 0; | ||
117 | |||
118 | while (1) { | ||
119 | byte = __raw_readb(addr); | ||
120 | addr++; | ||
121 | count++; | ||
122 | |||
123 | result |= (byte & 0x7f) << shift; | ||
124 | shift += 7; | ||
125 | |||
126 | if (!(byte & 0x80)) | ||
127 | break; | ||
128 | } | ||
129 | |||
130 | *ret = result; | ||
131 | |||
132 | return count; | ||
133 | } | ||
134 | |||
135 | /** | ||
136 | * dwarf_read_leb128 - read signed LEB128 data | ||
137 | * @addr: the address of the LEB128 encoded data | ||
138 | * @ret: address to store the result | ||
139 | * | ||
140 | * Decode signed LEB128 data. The algorithm is taken from Appendix | ||
141 | * C of the DWARF 3 spec. Return the number of bytes read. | ||
142 | */ | ||
143 | static inline unsigned long dwarf_read_leb128(char *addr, int *ret) | ||
144 | { | ||
145 | unsigned char byte; | ||
146 | int result, shift; | ||
147 | int num_bits; | ||
148 | int count; | ||
149 | |||
150 | result = 0; | ||
151 | shift = 0; | ||
152 | count = 0; | ||
153 | |||
154 | while (1) { | ||
155 | byte = __raw_readb(addr); | ||
156 | addr++; | ||
157 | result |= (byte & 0x7f) << shift; | ||
158 | shift += 7; | ||
159 | count++; | ||
160 | |||
161 | if (!(byte & 0x80)) | ||
162 | break; | ||
163 | } | ||
164 | |||
165 | /* The number of bits in a signed integer. */ | ||
166 | num_bits = 8 * sizeof(result); | ||
167 | |||
168 | if ((shift < num_bits) && (byte & 0x40)) | ||
169 | result |= (-1 << shift); | ||
170 | |||
171 | *ret = result; | ||
172 | |||
173 | return count; | ||
174 | } | ||
175 | |||
176 | /** | ||
177 | * dwarf_read_encoded_value - return the decoded value at @addr | ||
178 | * @addr: the address of the encoded value | ||
179 | * @val: where to write the decoded value | ||
180 | * @encoding: the encoding with which we can decode @addr | ||
181 | * | ||
182 | * GCC emits encoded address in the .eh_frame FDE entries. Decode | ||
183 | * the value at @addr using @encoding. The decoded value is written | ||
184 | * to @val and the number of bytes read is returned. | ||
185 | */ | ||
186 | static int dwarf_read_encoded_value(char *addr, unsigned long *val, | ||
187 | char encoding) | ||
188 | { | ||
189 | unsigned long decoded_addr = 0; | ||
190 | int count = 0; | ||
191 | |||
192 | switch (encoding & 0x70) { | ||
193 | case DW_EH_PE_absptr: | ||
194 | break; | ||
195 | case DW_EH_PE_pcrel: | ||
196 | decoded_addr = (unsigned long)addr; | ||
197 | break; | ||
198 | default: | ||
199 | pr_debug("encoding=0x%x\n", (encoding & 0x70)); | ||
200 | BUG(); | ||
201 | } | ||
202 | |||
203 | if ((encoding & 0x07) == 0x00) | ||
204 | encoding |= DW_EH_PE_udata4; | ||
205 | |||
206 | switch (encoding & 0x0f) { | ||
207 | case DW_EH_PE_sdata4: | ||
208 | case DW_EH_PE_udata4: | ||
209 | count += 4; | ||
210 | decoded_addr += __get_unaligned_cpu32(addr); | ||
211 | __raw_writel(decoded_addr, val); | ||
212 | break; | ||
213 | default: | ||
214 | pr_debug("encoding=0x%x\n", encoding); | ||
215 | BUG(); | ||
216 | } | ||
217 | |||
218 | return count; | ||
219 | } | ||
220 | |||
221 | /** | ||
222 | * dwarf_entry_len - return the length of an FDE or CIE | ||
223 | * @addr: the address of the entry | ||
224 | * @len: the length of the entry | ||
225 | * | ||
226 | * Read the initial_length field of the entry and store the size of | ||
227 | * the entry in @len. We return the number of bytes read. Return a | ||
228 | * count of 0 on error. | ||
229 | */ | ||
230 | static inline int dwarf_entry_len(char *addr, unsigned long *len) | ||
231 | { | ||
232 | u32 initial_len; | ||
233 | int count; | ||
234 | |||
235 | initial_len = __get_unaligned_cpu32(addr); | ||
236 | count = 4; | ||
237 | |||
238 | /* | ||
239 | * An initial length field value in the range DW_LEN_EXT_LO - | ||
240 | * DW_LEN_EXT_HI indicates an extension, and should not be | ||
241 | * interpreted as a length. The only extension that we currently | ||
242 | * understand is the use of DWARF64 addresses. | ||
243 | */ | ||
244 | if (initial_len >= DW_EXT_LO && initial_len <= DW_EXT_HI) { | ||
245 | /* | ||
246 | * The 64-bit length field immediately follows the | ||
247 | * compulsory 32-bit length field. | ||
248 | */ | ||
249 | if (initial_len == DW_EXT_DWARF64) { | ||
250 | *len = __get_unaligned_cpu64(addr + 4); | ||
251 | count = 12; | ||
252 | } else { | ||
253 | printk(KERN_WARNING "Unknown DWARF extension\n"); | ||
254 | count = 0; | ||
255 | } | ||
256 | } else | ||
257 | *len = initial_len; | ||
258 | |||
259 | return count; | ||
260 | } | ||
261 | |||
262 | /** | ||
263 | * dwarf_lookup_cie - locate the cie | ||
264 | * @cie_ptr: pointer to help with lookup | ||
265 | */ | ||
266 | static struct dwarf_cie *dwarf_lookup_cie(unsigned long cie_ptr) | ||
267 | { | ||
268 | struct dwarf_cie *cie, *n; | ||
269 | unsigned long flags; | ||
270 | |||
271 | spin_lock_irqsave(&dwarf_cie_lock, flags); | ||
272 | |||
273 | /* | ||
274 | * We've cached the last CIE we looked up because chances are | ||
275 | * that the FDE wants this CIE. | ||
276 | */ | ||
277 | if (cached_cie && cached_cie->cie_pointer == cie_ptr) { | ||
278 | cie = cached_cie; | ||
279 | goto out; | ||
280 | } | ||
281 | |||
282 | list_for_each_entry_safe(cie, n, &dwarf_cie_list, link) { | ||
283 | if (cie->cie_pointer == cie_ptr) { | ||
284 | cached_cie = cie; | ||
285 | break; | ||
286 | } | ||
287 | } | ||
288 | |||
289 | /* Couldn't find the entry in the list. */ | ||
290 | if (&cie->link == &dwarf_cie_list) | ||
291 | cie = NULL; | ||
292 | out: | ||
293 | spin_unlock_irqrestore(&dwarf_cie_lock, flags); | ||
294 | return cie; | ||
295 | } | ||
296 | |||
297 | /** | ||
298 | * dwarf_lookup_fde - locate the FDE that covers pc | ||
299 | * @pc: the program counter | ||
300 | */ | ||
301 | struct dwarf_fde *dwarf_lookup_fde(unsigned long pc) | ||
302 | { | ||
303 | unsigned long flags; | ||
304 | struct dwarf_fde *fde, *n; | ||
305 | |||
306 | spin_lock_irqsave(&dwarf_fde_lock, flags); | ||
307 | list_for_each_entry_safe(fde, n, &dwarf_fde_list, link) { | ||
308 | unsigned long start, end; | ||
309 | |||
310 | start = fde->initial_location; | ||
311 | end = fde->initial_location + fde->address_range; | ||
312 | |||
313 | if (pc >= start && pc < end) | ||
314 | break; | ||
315 | } | ||
316 | |||
317 | /* Couldn't find the entry in the list. */ | ||
318 | if (&fde->link == &dwarf_fde_list) | ||
319 | fde = NULL; | ||
320 | |||
321 | spin_unlock_irqrestore(&dwarf_fde_lock, flags); | ||
322 | |||
323 | return fde; | ||
324 | } | ||
325 | |||
326 | /** | ||
327 | * dwarf_cfa_execute_insns - execute instructions to calculate a CFA | ||
328 | * @insn_start: address of the first instruction | ||
329 | * @insn_end: address of the last instruction | ||
330 | * @cie: the CIE for this function | ||
331 | * @fde: the FDE for this function | ||
332 | * @frame: the instructions calculate the CFA for this frame | ||
333 | * @pc: the program counter of the address we're interested in | ||
334 | * | ||
335 | * Execute the Call Frame instruction sequence starting at | ||
336 | * @insn_start and ending at @insn_end. The instructions describe | ||
337 | * how to calculate the Canonical Frame Address of a stackframe. | ||
338 | * Store the results in @frame. | ||
339 | */ | ||
340 | static int dwarf_cfa_execute_insns(unsigned char *insn_start, | ||
341 | unsigned char *insn_end, | ||
342 | struct dwarf_cie *cie, | ||
343 | struct dwarf_fde *fde, | ||
344 | struct dwarf_frame *frame, | ||
345 | unsigned long pc) | ||
346 | { | ||
347 | unsigned char insn; | ||
348 | unsigned char *current_insn; | ||
349 | unsigned int count, delta, reg, expr_len, offset; | ||
350 | |||
351 | current_insn = insn_start; | ||
352 | |||
353 | while (current_insn < insn_end && frame->pc <= pc) { | ||
354 | insn = __raw_readb(current_insn++); | ||
355 | |||
356 | /* | ||
357 | * Firstly, handle the opcodes that embed their operands | ||
358 | * in the instructions. | ||
359 | */ | ||
360 | switch (DW_CFA_opcode(insn)) { | ||
361 | case DW_CFA_advance_loc: | ||
362 | delta = DW_CFA_operand(insn); | ||
363 | delta *= cie->code_alignment_factor; | ||
364 | frame->pc += delta; | ||
365 | continue; | ||
366 | /* NOTREACHED */ | ||
367 | case DW_CFA_offset: | ||
368 | reg = DW_CFA_operand(insn); | ||
369 | count = dwarf_read_uleb128(current_insn, &offset); | ||
370 | current_insn += count; | ||
371 | offset *= cie->data_alignment_factor; | ||
372 | dwarf_frame_alloc_regs(frame, reg); | ||
373 | frame->regs[reg].addr = offset; | ||
374 | frame->regs[reg].flags |= DWARF_REG_OFFSET; | ||
375 | continue; | ||
376 | /* NOTREACHED */ | ||
377 | case DW_CFA_restore: | ||
378 | reg = DW_CFA_operand(insn); | ||
379 | continue; | ||
380 | /* NOTREACHED */ | ||
381 | } | ||
382 | |||
383 | /* | ||
384 | * Secondly, handle the opcodes that don't embed their | ||
385 | * operands in the instruction. | ||
386 | */ | ||
387 | switch (insn) { | ||
388 | case DW_CFA_nop: | ||
389 | continue; | ||
390 | case DW_CFA_advance_loc1: | ||
391 | delta = *current_insn++; | ||
392 | frame->pc += delta * cie->code_alignment_factor; | ||
393 | break; | ||
394 | case DW_CFA_advance_loc2: | ||
395 | delta = __get_unaligned_cpu16(current_insn); | ||
396 | current_insn += 2; | ||
397 | frame->pc += delta * cie->code_alignment_factor; | ||
398 | break; | ||
399 | case DW_CFA_advance_loc4: | ||
400 | delta = __get_unaligned_cpu32(current_insn); | ||
401 | current_insn += 4; | ||
402 | frame->pc += delta * cie->code_alignment_factor; | ||
403 | break; | ||
404 | case DW_CFA_offset_extended: | ||
405 | count = dwarf_read_uleb128(current_insn, ®); | ||
406 | current_insn += count; | ||
407 | count = dwarf_read_uleb128(current_insn, &offset); | ||
408 | current_insn += count; | ||
409 | offset *= cie->data_alignment_factor; | ||
410 | break; | ||
411 | case DW_CFA_restore_extended: | ||
412 | count = dwarf_read_uleb128(current_insn, ®); | ||
413 | current_insn += count; | ||
414 | break; | ||
415 | case DW_CFA_undefined: | ||
416 | count = dwarf_read_uleb128(current_insn, ®); | ||
417 | current_insn += count; | ||
418 | break; | ||
419 | case DW_CFA_def_cfa: | ||
420 | count = dwarf_read_uleb128(current_insn, | ||
421 | &frame->cfa_register); | ||
422 | current_insn += count; | ||
423 | count = dwarf_read_uleb128(current_insn, | ||
424 | &frame->cfa_offset); | ||
425 | current_insn += count; | ||
426 | |||
427 | frame->flags |= DWARF_FRAME_CFA_REG_OFFSET; | ||
428 | break; | ||
429 | case DW_CFA_def_cfa_register: | ||
430 | count = dwarf_read_uleb128(current_insn, | ||
431 | &frame->cfa_register); | ||
432 | current_insn += count; | ||
433 | frame->flags |= DWARF_FRAME_CFA_REG_OFFSET; | ||
434 | break; | ||
435 | case DW_CFA_def_cfa_offset: | ||
436 | count = dwarf_read_uleb128(current_insn, &offset); | ||
437 | current_insn += count; | ||
438 | frame->cfa_offset = offset; | ||
439 | break; | ||
440 | case DW_CFA_def_cfa_expression: | ||
441 | count = dwarf_read_uleb128(current_insn, &expr_len); | ||
442 | current_insn += count; | ||
443 | |||
444 | frame->cfa_expr = current_insn; | ||
445 | frame->cfa_expr_len = expr_len; | ||
446 | current_insn += expr_len; | ||
447 | |||
448 | frame->flags |= DWARF_FRAME_CFA_REG_EXP; | ||
449 | break; | ||
450 | case DW_CFA_offset_extended_sf: | ||
451 | count = dwarf_read_uleb128(current_insn, ®); | ||
452 | current_insn += count; | ||
453 | count = dwarf_read_leb128(current_insn, &offset); | ||
454 | current_insn += count; | ||
455 | offset *= cie->data_alignment_factor; | ||
456 | dwarf_frame_alloc_regs(frame, reg); | ||
457 | frame->regs[reg].flags |= DWARF_REG_OFFSET; | ||
458 | frame->regs[reg].addr = offset; | ||
459 | break; | ||
460 | case DW_CFA_val_offset: | ||
461 | count = dwarf_read_uleb128(current_insn, ®); | ||
462 | current_insn += count; | ||
463 | count = dwarf_read_leb128(current_insn, &offset); | ||
464 | offset *= cie->data_alignment_factor; | ||
465 | frame->regs[reg].flags |= DWARF_REG_OFFSET; | ||
466 | frame->regs[reg].addr = offset; | ||
467 | break; | ||
468 | default: | ||
469 | pr_debug("unhandled DWARF instruction 0x%x\n", insn); | ||
470 | break; | ||
471 | } | ||
472 | } | ||
473 | |||
474 | return 0; | ||
475 | } | ||
476 | |||
477 | /** | ||
478 | * dwarf_unwind_stack - recursively unwind the stack | ||
479 | * @pc: address of the function to unwind | ||
480 | * @prev: struct dwarf_frame of the previous stackframe on the callstack | ||
481 | * | ||
482 | * Return a struct dwarf_frame representing the most recent frame | ||
483 | * on the callstack. Each of the lower (older) stack frames are | ||
484 | * linked via the "prev" member. | ||
485 | */ | ||
486 | struct dwarf_frame *dwarf_unwind_stack(unsigned long pc, | ||
487 | struct dwarf_frame *prev) | ||
488 | { | ||
489 | struct dwarf_frame *frame; | ||
490 | struct dwarf_cie *cie; | ||
491 | struct dwarf_fde *fde; | ||
492 | unsigned long addr; | ||
493 | int i, offset; | ||
494 | |||
495 | /* | ||
496 | * If this is the first invocation of this recursive function we | ||
497 | * need get the contents of a physical register to get the CFA | ||
498 | * in order to begin the virtual unwinding of the stack. | ||
499 | * | ||
500 | * The constant DWARF_ARCH_UNWIND_OFFSET is added to the address of | ||
501 | * this function because the return address register | ||
502 | * (DWARF_ARCH_RA_REG) will probably not be initialised until a | ||
503 | * few instructions into the prologue. | ||
504 | */ | ||
505 | if (!pc && !prev) { | ||
506 | pc = (unsigned long)&dwarf_unwind_stack; | ||
507 | pc += DWARF_ARCH_UNWIND_OFFSET; | ||
508 | } | ||
509 | |||
510 | frame = kzalloc(sizeof(*frame), GFP_KERNEL); | ||
511 | if (!frame) | ||
512 | return NULL; | ||
513 | |||
514 | frame->prev = prev; | ||
515 | |||
516 | fde = dwarf_lookup_fde(pc); | ||
517 | if (!fde) { | ||
518 | /* | ||
519 | * This is our normal exit path - the one that stops the | ||
520 | * recursion. There's two reasons why we might exit | ||
521 | * here, | ||
522 | * | ||
523 | * a) pc has no asscociated DWARF frame info and so | ||
524 | * we don't know how to unwind this frame. This is | ||
525 | * usually the case when we're trying to unwind a | ||
526 | * frame that was called from some assembly code | ||
527 | * that has no DWARF info, e.g. syscalls. | ||
528 | * | ||
529 | * b) the DEBUG info for pc is bogus. There's | ||
530 | * really no way to distinguish this case from the | ||
531 | * case above, which sucks because we could print a | ||
532 | * warning here. | ||
533 | */ | ||
534 | return NULL; | ||
535 | } | ||
536 | |||
537 | cie = dwarf_lookup_cie(fde->cie_pointer); | ||
538 | |||
539 | frame->pc = fde->initial_location; | ||
540 | |||
541 | /* CIE initial instructions */ | ||
542 | dwarf_cfa_execute_insns(cie->initial_instructions, | ||
543 | cie->instructions_end, cie, fde, frame, pc); | ||
544 | |||
545 | /* FDE instructions */ | ||
546 | dwarf_cfa_execute_insns(fde->instructions, fde->end, cie, | ||
547 | fde, frame, pc); | ||
548 | |||
549 | /* Calculate the CFA */ | ||
550 | switch (frame->flags) { | ||
551 | case DWARF_FRAME_CFA_REG_OFFSET: | ||
552 | if (prev) { | ||
553 | BUG_ON(!prev->regs[frame->cfa_register].flags); | ||
554 | |||
555 | addr = prev->cfa; | ||
556 | addr += prev->regs[frame->cfa_register].addr; | ||
557 | frame->cfa = __raw_readl(addr); | ||
558 | |||
559 | } else { | ||
560 | /* | ||
561 | * Again, this is the first invocation of this | ||
562 | * recurisve function. We need to physically | ||
563 | * read the contents of a register in order to | ||
564 | * get the Canonical Frame Address for this | ||
565 | * function. | ||
566 | */ | ||
567 | frame->cfa = dwarf_read_arch_reg(frame->cfa_register); | ||
568 | } | ||
569 | |||
570 | frame->cfa += frame->cfa_offset; | ||
571 | break; | ||
572 | default: | ||
573 | BUG(); | ||
574 | } | ||
575 | |||
576 | /* If we haven't seen the return address reg, we're screwed. */ | ||
577 | BUG_ON(!frame->regs[DWARF_ARCH_RA_REG].flags); | ||
578 | |||
579 | for (i = 0; i <= frame->num_regs; i++) { | ||
580 | struct dwarf_reg *reg = &frame->regs[i]; | ||
581 | |||
582 | if (!reg->flags) | ||
583 | continue; | ||
584 | |||
585 | offset = reg->addr; | ||
586 | offset += frame->cfa; | ||
587 | } | ||
588 | |||
589 | addr = frame->cfa + frame->regs[DWARF_ARCH_RA_REG].addr; | ||
590 | frame->return_addr = __raw_readl(addr); | ||
591 | |||
592 | frame->next = dwarf_unwind_stack(frame->return_addr, frame); | ||
593 | return frame; | ||
594 | } | ||
595 | |||
596 | static int dwarf_parse_cie(void *entry, void *p, unsigned long len, | ||
597 | unsigned char *end) | ||
598 | { | ||
599 | struct dwarf_cie *cie; | ||
600 | unsigned long flags; | ||
601 | int count; | ||
602 | |||
603 | cie = kzalloc(sizeof(*cie), GFP_KERNEL); | ||
604 | if (!cie) | ||
605 | return -ENOMEM; | ||
606 | |||
607 | cie->length = len; | ||
608 | |||
609 | /* | ||
610 | * Record the offset into the .eh_frame section | ||
611 | * for this CIE. It allows this CIE to be | ||
612 | * quickly and easily looked up from the | ||
613 | * corresponding FDE. | ||
614 | */ | ||
615 | cie->cie_pointer = (unsigned long)entry; | ||
616 | |||
617 | cie->version = *(char *)p++; | ||
618 | BUG_ON(cie->version != 1); | ||
619 | |||
620 | cie->augmentation = p; | ||
621 | p += strlen(cie->augmentation) + 1; | ||
622 | |||
623 | count = dwarf_read_uleb128(p, &cie->code_alignment_factor); | ||
624 | p += count; | ||
625 | |||
626 | count = dwarf_read_leb128(p, &cie->data_alignment_factor); | ||
627 | p += count; | ||
628 | |||
629 | /* | ||
630 | * Which column in the rule table contains the | ||
631 | * return address? | ||
632 | */ | ||
633 | if (cie->version == 1) { | ||
634 | cie->return_address_reg = __raw_readb(p); | ||
635 | p++; | ||
636 | } else { | ||
637 | count = dwarf_read_uleb128(p, &cie->return_address_reg); | ||
638 | p += count; | ||
639 | } | ||
640 | |||
641 | if (cie->augmentation[0] == 'z') { | ||
642 | unsigned int length, count; | ||
643 | cie->flags |= DWARF_CIE_Z_AUGMENTATION; | ||
644 | |||
645 | count = dwarf_read_uleb128(p, &length); | ||
646 | p += count; | ||
647 | |||
648 | BUG_ON((unsigned char *)p > end); | ||
649 | |||
650 | cie->initial_instructions = p + length; | ||
651 | cie->augmentation++; | ||
652 | } | ||
653 | |||
654 | while (*cie->augmentation) { | ||
655 | /* | ||
656 | * "L" indicates a byte showing how the | ||
657 | * LSDA pointer is encoded. Skip it. | ||
658 | */ | ||
659 | if (*cie->augmentation == 'L') { | ||
660 | p++; | ||
661 | cie->augmentation++; | ||
662 | } else if (*cie->augmentation == 'R') { | ||
663 | /* | ||
664 | * "R" indicates a byte showing | ||
665 | * how FDE addresses are | ||
666 | * encoded. | ||
667 | */ | ||
668 | cie->encoding = *(char *)p++; | ||
669 | cie->augmentation++; | ||
670 | } else if (*cie->augmentation == 'P') { | ||
671 | /* | ||
672 | * "R" indicates a personality | ||
673 | * routine in the CIE | ||
674 | * augmentation. | ||
675 | */ | ||
676 | BUG(); | ||
677 | } else if (*cie->augmentation == 'S') { | ||
678 | BUG(); | ||
679 | } else { | ||
680 | /* | ||
681 | * Unknown augmentation. Assume | ||
682 | * 'z' augmentation. | ||
683 | */ | ||
684 | p = cie->initial_instructions; | ||
685 | BUG_ON(!p); | ||
686 | break; | ||
687 | } | ||
688 | } | ||
689 | |||
690 | cie->initial_instructions = p; | ||
691 | cie->instructions_end = end; | ||
692 | |||
693 | /* Add to list */ | ||
694 | spin_lock_irqsave(&dwarf_cie_lock, flags); | ||
695 | list_add_tail(&cie->link, &dwarf_cie_list); | ||
696 | spin_unlock_irqrestore(&dwarf_cie_lock, flags); | ||
697 | |||
698 | return 0; | ||
699 | } | ||
700 | |||
701 | static int dwarf_parse_fde(void *entry, u32 entry_type, | ||
702 | void *start, unsigned long len) | ||
703 | { | ||
704 | struct dwarf_fde *fde; | ||
705 | struct dwarf_cie *cie; | ||
706 | unsigned long flags; | ||
707 | int count; | ||
708 | void *p = start; | ||
709 | |||
710 | fde = kzalloc(sizeof(*fde), GFP_KERNEL); | ||
711 | if (!fde) | ||
712 | return -ENOMEM; | ||
713 | |||
714 | fde->length = len; | ||
715 | |||
716 | /* | ||
717 | * In a .eh_frame section the CIE pointer is the | ||
718 | * delta between the address within the FDE | ||
719 | */ | ||
720 | fde->cie_pointer = (unsigned long)(p - entry_type - 4); | ||
721 | |||
722 | cie = dwarf_lookup_cie(fde->cie_pointer); | ||
723 | fde->cie = cie; | ||
724 | |||
725 | if (cie->encoding) | ||
726 | count = dwarf_read_encoded_value(p, &fde->initial_location, | ||
727 | cie->encoding); | ||
728 | else | ||
729 | count = dwarf_read_addr(p, &fde->initial_location); | ||
730 | |||
731 | p += count; | ||
732 | |||
733 | if (cie->encoding) | ||
734 | count = dwarf_read_encoded_value(p, &fde->address_range, | ||
735 | cie->encoding & 0x0f); | ||
736 | else | ||
737 | count = dwarf_read_addr(p, &fde->address_range); | ||
738 | |||
739 | p += count; | ||
740 | |||
741 | if (fde->cie->flags & DWARF_CIE_Z_AUGMENTATION) { | ||
742 | unsigned int length; | ||
743 | count = dwarf_read_uleb128(p, &length); | ||
744 | p += count + length; | ||
745 | } | ||
746 | |||
747 | /* Call frame instructions. */ | ||
748 | fde->instructions = p; | ||
749 | fde->end = start + len; | ||
750 | |||
751 | /* Add to list. */ | ||
752 | spin_lock_irqsave(&dwarf_fde_lock, flags); | ||
753 | list_add_tail(&fde->link, &dwarf_fde_list); | ||
754 | spin_unlock_irqrestore(&dwarf_fde_lock, flags); | ||
755 | |||
756 | return 0; | ||
757 | } | ||
758 | |||
759 | static void dwarf_unwinder_dump(struct task_struct *task, struct pt_regs *regs, | ||
760 | unsigned long *sp, | ||
761 | const struct stacktrace_ops *ops, void *data) | ||
762 | { | ||
763 | struct dwarf_frame *frame; | ||
764 | |||
765 | frame = dwarf_unwind_stack(0, NULL); | ||
766 | |||
767 | while (frame && frame->return_addr) { | ||
768 | ops->address(data, frame->return_addr, 1); | ||
769 | frame = frame->next; | ||
770 | } | ||
771 | } | ||
772 | |||
773 | static struct unwinder dwarf_unwinder = { | ||
774 | .name = "dwarf-unwinder", | ||
775 | .dump = dwarf_unwinder_dump, | ||
776 | .rating = 150, | ||
777 | }; | ||
778 | |||
779 | static void dwarf_unwinder_cleanup(void) | ||
780 | { | ||
781 | struct dwarf_cie *cie, *m; | ||
782 | struct dwarf_fde *fde, *n; | ||
783 | unsigned long flags; | ||
784 | |||
785 | /* | ||
786 | * Deallocate all the memory allocated for the DWARF unwinder. | ||
787 | * Traverse all the FDE/CIE lists and remove and free all the | ||
788 | * memory associated with those data structures. | ||
789 | */ | ||
790 | spin_lock_irqsave(&dwarf_cie_lock, flags); | ||
791 | list_for_each_entry_safe(cie, m, &dwarf_cie_list, link) | ||
792 | kfree(cie); | ||
793 | spin_unlock_irqrestore(&dwarf_cie_lock, flags); | ||
794 | |||
795 | spin_lock_irqsave(&dwarf_fde_lock, flags); | ||
796 | list_for_each_entry_safe(fde, n, &dwarf_fde_list, link) | ||
797 | kfree(fde); | ||
798 | spin_unlock_irqrestore(&dwarf_fde_lock, flags); | ||
799 | } | ||
800 | |||
801 | /** | ||
802 | * dwarf_unwinder_init - initialise the dwarf unwinder | ||
803 | * | ||
804 | * Build the data structures describing the .dwarf_frame section to | ||
805 | * make it easier to lookup CIE and FDE entries. Because the | ||
806 | * .eh_frame section is packed as tightly as possible it is not | ||
807 | * easy to lookup the FDE for a given PC, so we build a list of FDE | ||
808 | * and CIE entries that make it easier. | ||
809 | */ | ||
810 | void dwarf_unwinder_init(void) | ||
811 | { | ||
812 | u32 entry_type; | ||
813 | void *p, *entry; | ||
814 | int count, err; | ||
815 | unsigned long len; | ||
816 | unsigned int c_entries, f_entries; | ||
817 | unsigned char *end; | ||
818 | INIT_LIST_HEAD(&dwarf_cie_list); | ||
819 | INIT_LIST_HEAD(&dwarf_fde_list); | ||
820 | |||
821 | c_entries = 0; | ||
822 | f_entries = 0; | ||
823 | entry = &__start_eh_frame; | ||
824 | |||
825 | while ((char *)entry < __stop_eh_frame) { | ||
826 | p = entry; | ||
827 | |||
828 | count = dwarf_entry_len(p, &len); | ||
829 | if (count == 0) { | ||
830 | /* | ||
831 | * We read a bogus length field value. There is | ||
832 | * nothing we can do here apart from disabling | ||
833 | * the DWARF unwinder. We can't even skip this | ||
834 | * entry and move to the next one because 'len' | ||
835 | * tells us where our next entry is. | ||
836 | */ | ||
837 | goto out; | ||
838 | } else | ||
839 | p += count; | ||
840 | |||
841 | /* initial length does not include itself */ | ||
842 | end = p + len; | ||
843 | |||
844 | entry_type = __get_unaligned_cpu32(p); | ||
845 | p += 4; | ||
846 | |||
847 | if (entry_type == DW_EH_FRAME_CIE) { | ||
848 | err = dwarf_parse_cie(entry, p, len, end); | ||
849 | if (err < 0) | ||
850 | goto out; | ||
851 | else | ||
852 | c_entries++; | ||
853 | } else { | ||
854 | err = dwarf_parse_fde(entry, entry_type, p, len); | ||
855 | if (err < 0) | ||
856 | goto out; | ||
857 | else | ||
858 | f_entries++; | ||
859 | } | ||
860 | |||
861 | entry = (char *)entry + len + 4; | ||
862 | } | ||
863 | |||
864 | printk(KERN_INFO "DWARF unwinder initialised: read %u CIEs, %u FDEs\n", | ||
865 | c_entries, f_entries); | ||
866 | |||
867 | err = unwinder_register(&dwarf_unwinder); | ||
868 | if (err) | ||
869 | goto out; | ||
870 | |||
871 | return; | ||
872 | |||
873 | out: | ||
874 | printk(KERN_ERR "Failed to initialise DWARF unwinder: %d\n", err); | ||
875 | dwarf_unwinder_cleanup(); | ||
876 | } | ||
diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c index 278c68c60488..2bb43dc74f22 100644 --- a/arch/sh/kernel/irq.c +++ b/arch/sh/kernel/irq.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <asm/processor.h> | 14 | #include <asm/processor.h> |
15 | #include <asm/machvec.h> | 15 | #include <asm/machvec.h> |
16 | #include <asm/uaccess.h> | 16 | #include <asm/uaccess.h> |
17 | #include <asm/dwarf.h> | ||
17 | #include <asm/thread_info.h> | 18 | #include <asm/thread_info.h> |
18 | #include <cpu/mmu_context.h> | 19 | #include <cpu/mmu_context.h> |
19 | 20 | ||
@@ -261,6 +262,9 @@ void __init init_IRQ(void) | |||
261 | sh_mv.mv_init_irq(); | 262 | sh_mv.mv_init_irq(); |
262 | 263 | ||
263 | irq_ctx_init(smp_processor_id()); | 264 | irq_ctx_init(smp_processor_id()); |
265 | |||
266 | /* This needs to be early, but not too early.. */ | ||
267 | dwarf_unwinder_init(); | ||
264 | } | 268 | } |
265 | 269 | ||
266 | #ifdef CONFIG_SPARSE_IRQ | 270 | #ifdef CONFIG_SPARSE_IRQ |
diff --git a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S index 80dc9f8d9412..1b7d9d541e01 100644 --- a/arch/sh/kernel/vmlinux.lds.S +++ b/arch/sh/kernel/vmlinux.lds.S | |||
@@ -12,7 +12,7 @@ OUTPUT_ARCH(sh) | |||
12 | 12 | ||
13 | #include <asm/thread_info.h> | 13 | #include <asm/thread_info.h> |
14 | #include <asm/cache.h> | 14 | #include <asm/cache.h> |
15 | #include <asm-generic/vmlinux.lds.h> | 15 | #include <asm/vmlinux.lds.h> |
16 | 16 | ||
17 | ENTRY(_start) | 17 | ENTRY(_start) |
18 | SECTIONS | 18 | SECTIONS |
@@ -70,6 +70,8 @@ SECTIONS | |||
70 | 70 | ||
71 | _edata = .; /* End of data section */ | 71 | _edata = .; /* End of data section */ |
72 | 72 | ||
73 | DWARF_EH_FRAME | ||
74 | |||
73 | . = ALIGN(PAGE_SIZE); /* Init code and data */ | 75 | . = ALIGN(PAGE_SIZE); /* Init code and data */ |
74 | __init_begin = .; | 76 | __init_begin = .; |
75 | INIT_TEXT_SECTION(PAGE_SIZE) | 77 | INIT_TEXT_SECTION(PAGE_SIZE) |