aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorMatt Fleming <matt@console-pimps.org>2009-08-13 12:58:43 -0400
committerPaul Mundt <lethal@linux-sh.org>2009-08-13 12:58:43 -0400
commitbd353861c735b2265c9d8b2559960c693e7c68ab (patch)
tree2cd13808cb4d50b6b4d63eff0d7ad5fa6d19f04d /arch
parent0eff9f66de79a0707a9c3a2f8528ccfd62100f0b (diff)
sh: dwarf unwinder support.
This is a first cut at a generic DWARF unwinder for the kernel. It's still lacking DWARF64 support and the DWARF expression support hasn't been tested very well but it is generating proper stacktraces on SH for WARN_ON() and NULL dereferences. Signed-off-by: Matt Fleming <matt@console-pimps.org> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/sh/Kconfig.debug8
-rw-r--r--arch/sh/Makefile4
-rw-r--r--arch/sh/include/asm/dwarf.h407
-rw-r--r--arch/sh/include/asm/sections.h1
-rw-r--r--arch/sh/include/asm/vmlinux.lds.h17
-rw-r--r--arch/sh/kernel/Makefile_321
-rw-r--r--arch/sh/kernel/Makefile_641
-rw-r--r--arch/sh/kernel/dwarf.c876
-rw-r--r--arch/sh/kernel/irq.c4
-rw-r--r--arch/sh/kernel/vmlinux.lds.S4
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
113config 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
113config SH_NO_BSS_INIT 121config 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
192endif 192endif
193 193
194ifeq ($(CONFIG_DWARF_UNWINDER),y)
195 KBUILD_CFLAGS += -fasynchronous-unwind-tables
196endif
197
194libs-$(CONFIG_SUPERH32) := arch/sh/lib/ $(libs-y) 198libs-$(CONFIG_SUPERH32) := arch/sh/lib/ $(libs-y)
195libs-$(CONFIG_SUPERH64) := arch/sh/lib64/ $(libs-y) 199libs-$(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 */
206static __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 */
227struct 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 */
254struct 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 */
268struct 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 */
299struct 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 */
311struct 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 */
353static inline unsigned int DW_CFA_opcode(unsigned long insn)
354{
355 return (insn & 0xc0);
356}
357
358static 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
374extern void dwarf_unwinder_init(void);
375
376extern 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__
400static 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;
7extern long __machvec_start, __machvec_end; 7extern long __machvec_start, __machvec_end;
8extern char __uncached_start, __uncached_end; 8extern char __uncached_start, __uncached_end;
9extern char _ebss[]; 9extern char _ebss[];
10extern 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
33obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o 33obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
34obj-$(CONFIG_DUMP_CODE) += disassemble.o 34obj-$(CONFIG_DUMP_CODE) += disassemble.o
35obj-$(CONFIG_HIBERNATION) += swsusp.o 35obj-$(CONFIG_HIBERNATION) += swsusp.o
36obj-$(CONFIG_DWARF_UNWINDER) += dwarf.o
36 37
37obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) += localtimer.o 38obj-$(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
13obj-$(CONFIG_STACKTRACE) += stacktrace.o 13obj-$(CONFIG_STACKTRACE) += stacktrace.o
14obj-$(CONFIG_IO_TRAPPED) += io_trapped.o 14obj-$(CONFIG_IO_TRAPPED) += io_trapped.o
15obj-$(CONFIG_GENERIC_GPIO) += gpio.o 15obj-$(CONFIG_GENERIC_GPIO) += gpio.o
16obj-$(CONFIG_DWARF_UNWINDER) += dwarf.o
16 17
17obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) += localtimer.o 18obj-$(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
28static LIST_HEAD(dwarf_cie_list);
29DEFINE_SPINLOCK(dwarf_cie_lock);
30
31static LIST_HEAD(dwarf_fde_list);
32DEFINE_SPINLOCK(dwarf_fde_lock);
33
34static 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 */
45static 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 */
90static 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 */
108static 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 */
143static 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 */
186static 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 */
230static 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 */
266static 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;
292out:
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 */
301struct 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 */
340static 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, &reg);
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, &reg);
413 current_insn += count;
414 break;
415 case DW_CFA_undefined:
416 count = dwarf_read_uleb128(current_insn, &reg);
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, &reg);
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, &reg);
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 */
486struct 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
596static 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
701static 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
759static 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
773static struct unwinder dwarf_unwinder = {
774 .name = "dwarf-unwinder",
775 .dump = dwarf_unwinder_dump,
776 .rating = 150,
777};
778
779static 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 */
810void 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
873out:
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
17ENTRY(_start) 17ENTRY(_start)
18SECTIONS 18SECTIONS
@@ -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)