2 * Copyright (C) 2002-2006 Novell, Inc.
3 * Jan Beulich <jbeulich@novell.com>
4 * This code is released under version 2 of the GNU GPL.
6 * A simple API for unwinding kernel stacks. This is used for
7 * debugging and error reporting purposes. The kernel doesn't need
8 * full-blown stack unwinding with all the bells and whistles, so there
9 * is not much point in implementing the full Dwarf2 unwind API.
12 #include <linux/unwind.h>
13 #include <linux/module.h>
14 #include <linux/bootmem.h>
15 #include <linux/sort.h>
16 #include <linux/stop_machine.h>
17 #include <linux/uaccess.h>
18 #include <asm/sections.h>
19 #include <asm/uaccess.h>
20 #include <asm/unaligned.h>
22 extern char __start_unwind
[], __end_unwind
[];
23 extern const u8 __start_unwind_hdr
[], __end_unwind_hdr
[];
25 #define MAX_STACK_DEPTH 8
27 #define EXTRA_INFO(f) { \
28 BUILD_BUG_ON_ZERO(offsetof(struct unwind_frame_info, f) \
29 % FIELD_SIZEOF(struct unwind_frame_info, f)) \
30 + offsetof(struct unwind_frame_info, f) \
31 / FIELD_SIZEOF(struct unwind_frame_info, f), \
32 FIELD_SIZEOF(struct unwind_frame_info, f) \
34 #define PTREGS_INFO(f) EXTRA_INFO(regs.f)
37 unsigned offs
:BITS_PER_LONG
/ 2;
38 unsigned width
:BITS_PER_LONG
/ 2;
47 #define REG_INVALID(r) (reg_info[r].width == 0)
50 #define DW_CFA_nop 0x00
51 #define DW_CFA_set_loc 0x01
52 #define DW_CFA_advance_loc1 0x02
53 #define DW_CFA_advance_loc2 0x03
54 #define DW_CFA_advance_loc4 0x04
55 #define DW_CFA_offset_extended 0x05
56 #define DW_CFA_restore_extended 0x06
57 #define DW_CFA_undefined 0x07
58 #define DW_CFA_same_value 0x08
59 #define DW_CFA_register 0x09
60 #define DW_CFA_remember_state 0x0a
61 #define DW_CFA_restore_state 0x0b
62 #define DW_CFA_def_cfa 0x0c
63 #define DW_CFA_def_cfa_register 0x0d
64 #define DW_CFA_def_cfa_offset 0x0e
65 #define DW_CFA_def_cfa_expression 0x0f
66 #define DW_CFA_expression 0x10
67 #define DW_CFA_offset_extended_sf 0x11
68 #define DW_CFA_def_cfa_sf 0x12
69 #define DW_CFA_def_cfa_offset_sf 0x13
70 #define DW_CFA_val_offset 0x14
71 #define DW_CFA_val_offset_sf 0x15
72 #define DW_CFA_val_expression 0x16
73 #define DW_CFA_lo_user 0x1c
74 #define DW_CFA_GNU_window_save 0x2d
75 #define DW_CFA_GNU_args_size 0x2e
76 #define DW_CFA_GNU_negative_offset_extended 0x2f
77 #define DW_CFA_hi_user 0x3f
79 #define DW_EH_PE_FORM 0x07
80 #define DW_EH_PE_native 0x00
81 #define DW_EH_PE_leb128 0x01
82 #define DW_EH_PE_data2 0x02
83 #define DW_EH_PE_data4 0x03
84 #define DW_EH_PE_data8 0x04
85 #define DW_EH_PE_signed 0x08
86 #define DW_EH_PE_ADJUST 0x70
87 #define DW_EH_PE_abs 0x00
88 #define DW_EH_PE_pcrel 0x10
89 #define DW_EH_PE_textrel 0x20
90 #define DW_EH_PE_datarel 0x30
91 #define DW_EH_PE_funcrel 0x40
92 #define DW_EH_PE_aligned 0x50
93 #define DW_EH_PE_indirect 0x80
94 #define DW_EH_PE_omit 0xff
96 typedef unsigned long uleb128_t
;
97 typedef signed long sleb128_t
;
98 #define sleb128abs __builtin_labs
100 static struct unwind_table
{
107 const unsigned char *header
;
109 struct unwind_table
*link
;
123 struct unwind_state
{
125 const u8
*cieStart
, *cieEnd
;
131 struct unwind_item regs
[ARRAY_SIZE(reg_info
)];
132 unsigned stackDepth
:8;
135 const u8
*stack
[MAX_STACK_DEPTH
];
138 static const struct cfa badCFA
= { ARRAY_SIZE(reg_info
), 1 };
140 static struct unwind_table
*find_table(unsigned long pc
)
142 struct unwind_table
*table
;
144 for (table
= &root_table
; table
; table
= table
->link
)
145 if ((pc
>= table
->core
.pc
146 && pc
< table
->core
.pc
+ table
->core
.range
)
147 || (pc
>= table
->init
.pc
148 && pc
< table
->init
.pc
+ table
->init
.range
))
154 static unsigned long read_pointer(const u8
**pLoc
,
158 static void init_unwind_table(struct unwind_table
*table
,
160 const void *core_start
,
161 unsigned long core_size
,
162 const void *init_start
,
163 unsigned long init_size
,
164 const void *table_start
,
165 unsigned long table_size
,
166 const u8
*header_start
,
167 unsigned long header_size
)
169 const u8
*ptr
= header_start
+ 4;
170 const u8
*end
= header_start
+ header_size
;
172 table
->core
.pc
= (unsigned long)core_start
;
173 table
->core
.range
= core_size
;
174 table
->init
.pc
= (unsigned long)init_start
;
175 table
->init
.range
= init_size
;
176 table
->address
= table_start
;
177 table
->size
= table_size
;
178 /* See if the linker provided table looks valid. */
180 || header_start
[0] != 1
181 || (void *)read_pointer(&ptr
, end
, header_start
[1]) != table_start
182 || header_start
[2] == DW_EH_PE_omit
183 || read_pointer(&ptr
, end
, header_start
[2]) <= 0
184 || header_start
[3] == DW_EH_PE_omit
)
186 table
->hdrsz
= header_size
;
188 table
->header
= header_start
;
193 void __init
unwind_init(void)
195 init_unwind_table(&root_table
, "kernel",
198 __start_unwind
, __end_unwind
- __start_unwind
,
199 __start_unwind_hdr
, __end_unwind_hdr
- __start_unwind_hdr
);
202 static const u32 bad_cie
, not_fde
;
203 static const u32
*cie_for_fde(const u32
*fde
, const struct unwind_table
*);
204 static signed fde_pointer_type(const u32
*cie
);
206 struct eh_frame_hdr_table_entry
{
207 unsigned long start
, fde
;
210 static int cmp_eh_frame_hdr_table_entries(const void *p1
, const void *p2
)
212 const struct eh_frame_hdr_table_entry
*e1
= p1
;
213 const struct eh_frame_hdr_table_entry
*e2
= p2
;
215 return (e1
->start
> e2
->start
) - (e1
->start
< e2
->start
);
218 static void swap_eh_frame_hdr_table_entries(void *p1
, void *p2
, int size
)
220 struct eh_frame_hdr_table_entry
*e1
= p1
;
221 struct eh_frame_hdr_table_entry
*e2
= p2
;
225 e1
->start
= e2
->start
;
232 static void __init
setup_unwind_table(struct unwind_table
*table
,
233 void *(*alloc
)(unsigned long))
236 unsigned long tableSize
= table
->size
, hdrSize
;
244 unsigned long eh_frame_ptr
;
245 unsigned int fde_count
;
246 struct eh_frame_hdr_table_entry table
[];
247 } __attribute__((__packed__
)) *header
;
253 printk(KERN_WARNING
".eh_frame_hdr for '%s' present but unusable\n",
256 if (tableSize
& (sizeof(*fde
) - 1))
259 for (fde
= table
->address
, n
= 0;
260 tableSize
> sizeof(*fde
) && tableSize
- sizeof(*fde
) >= *fde
;
261 tableSize
-= sizeof(*fde
) + *fde
, fde
+= 1 + *fde
/ sizeof(*fde
)) {
262 const u32
*cie
= cie_for_fde(fde
, table
);
269 || (ptrType
= fde_pointer_type(cie
)) < 0)
271 ptr
= (const u8
*)(fde
+ 2);
272 if (!read_pointer(&ptr
,
273 (const u8
*)(fde
+ 1) + *fde
,
282 hdrSize
= 4 + sizeof(unsigned long) + sizeof(unsigned int)
283 + 2 * n
* sizeof(unsigned long);
284 header
= alloc(hdrSize
);
288 header
->eh_frame_ptr_enc
= DW_EH_PE_abs
|DW_EH_PE_native
;
289 header
->fde_count_enc
= DW_EH_PE_abs
|DW_EH_PE_data4
;
290 header
->table_enc
= DW_EH_PE_abs
|DW_EH_PE_native
;
291 put_unaligned((unsigned long)table
->address
, &header
->eh_frame_ptr
);
292 BUILD_BUG_ON(offsetof(typeof(*header
), fde_count
)
293 % __alignof(typeof(header
->fde_count
)));
294 header
->fde_count
= n
;
296 BUILD_BUG_ON(offsetof(typeof(*header
), table
)
297 % __alignof(typeof(*header
->table
)));
298 for (fde
= table
->address
, tableSize
= table
->size
, n
= 0;
300 tableSize
-= sizeof(*fde
) + *fde
, fde
+= 1 + *fde
/ sizeof(*fde
)) {
301 const u32
*cie
= fde
+ 1 - fde
[1] / sizeof(*fde
);
304 continue; /* this is a CIE */
305 ptr
= (const u8
*)(fde
+ 2);
306 header
->table
[n
].start
= read_pointer(&ptr
,
307 (const u8
*)(fde
+ 1) + *fde
,
308 fde_pointer_type(cie
));
309 header
->table
[n
].fde
= (unsigned long)fde
;
312 WARN_ON(n
!= header
->fde_count
);
316 sizeof(*header
->table
),
317 cmp_eh_frame_hdr_table_entries
,
318 swap_eh_frame_hdr_table_entries
);
320 table
->hdrsz
= hdrSize
;
322 table
->header
= (const void *)header
;
325 static void *__init
balloc(unsigned long sz
)
327 return __alloc_bootmem_nopanic(sz
,
328 sizeof(unsigned int),
329 __pa(MAX_DMA_ADDRESS
));
332 void __init
unwind_setup(void)
334 setup_unwind_table(&root_table
, balloc
);
337 #ifdef CONFIG_MODULES
339 static struct unwind_table
*last_table
;
341 /* Must be called with module_mutex held. */
342 void *unwind_add_table(struct module
*module
,
343 const void *table_start
,
344 unsigned long table_size
)
346 struct unwind_table
*table
;
351 table
= kmalloc(sizeof(*table
), GFP_KERNEL
);
355 init_unwind_table(table
, module
->name
,
356 module
->module_core
, module
->core_size
,
357 module
->module_init
, module
->init_size
,
358 table_start
, table_size
,
362 last_table
->link
= table
;
364 root_table
.link
= table
;
370 struct unlink_table_info
372 struct unwind_table
*table
;
376 static int unlink_table(void *arg
)
378 struct unlink_table_info
*info
= arg
;
379 struct unwind_table
*table
= info
->table
, *prev
;
381 for (prev
= &root_table
; prev
->link
&& prev
->link
!= table
; prev
= prev
->link
)
385 if (info
->init_only
) {
387 table
->init
.range
= 0;
390 prev
->link
= table
->link
;
400 /* Must be called with module_mutex held. */
401 void unwind_remove_table(void *handle
, int init_only
)
403 struct unwind_table
*table
= handle
;
404 struct unlink_table_info info
;
406 if (!table
|| table
== &root_table
)
409 if (init_only
&& table
== last_table
) {
411 table
->init
.range
= 0;
416 info
.init_only
= init_only
;
417 stop_machine_run(unlink_table
, &info
, NR_CPUS
);
423 #endif /* CONFIG_MODULES */
425 static uleb128_t
get_uleb128(const u8
**pcur
, const u8
*end
)
427 const u8
*cur
= *pcur
;
431 for (shift
= 0, value
= 0; cur
< end
; shift
+= 7) {
432 if (shift
+ 7 > 8 * sizeof(value
)
433 && (*cur
& 0x7fU
) >= (1U << (8 * sizeof(value
) - shift
))) {
437 value
|= (uleb128_t
)(*cur
& 0x7f) << shift
;
438 if (!(*cur
++ & 0x80))
446 static sleb128_t
get_sleb128(const u8
**pcur
, const u8
*end
)
448 const u8
*cur
= *pcur
;
452 for (shift
= 0, value
= 0; cur
< end
; shift
+= 7) {
453 if (shift
+ 7 > 8 * sizeof(value
)
454 && (*cur
& 0x7fU
) >= (1U << (8 * sizeof(value
) - shift
))) {
458 value
|= (sleb128_t
)(*cur
& 0x7f) << shift
;
459 if (!(*cur
& 0x80)) {
460 value
|= -(*cur
++ & 0x40) << shift
;
469 static const u32
*cie_for_fde(const u32
*fde
, const struct unwind_table
*table
)
473 if (!*fde
|| (*fde
& (sizeof(*fde
) - 1)))
476 return ¬_fde
; /* this is a CIE */
477 if ((fde
[1] & (sizeof(*fde
) - 1))
478 || fde
[1] > (unsigned long)(fde
+ 1) - (unsigned long)table
->address
)
479 return NULL
; /* this is not a valid FDE */
480 cie
= fde
+ 1 - fde
[1] / sizeof(*fde
);
481 if (*cie
<= sizeof(*cie
) + 4
482 || *cie
>= fde
[1] - sizeof(*fde
)
483 || (*cie
& (sizeof(*cie
) - 1))
485 return NULL
; /* this is not a (valid) CIE */
489 static unsigned long read_pointer(const u8
**pLoc
,
493 unsigned long value
= 0;
500 const unsigned long *pul
;
503 if (ptrType
< 0 || ptrType
== DW_EH_PE_omit
)
506 switch(ptrType
& DW_EH_PE_FORM
) {
508 if (end
< (const void *)(ptr
.p16u
+ 1))
510 if(ptrType
& DW_EH_PE_signed
)
511 value
= get_unaligned(ptr
.p16s
++);
513 value
= get_unaligned(ptr
.p16u
++);
517 if (end
< (const void *)(ptr
.p32u
+ 1))
519 if(ptrType
& DW_EH_PE_signed
)
520 value
= get_unaligned(ptr
.p32s
++);
522 value
= get_unaligned(ptr
.p32u
++);
525 BUILD_BUG_ON(sizeof(u64
) != sizeof(value
));
527 BUILD_BUG_ON(sizeof(u32
) != sizeof(value
));
529 case DW_EH_PE_native
:
530 if (end
< (const void *)(ptr
.pul
+ 1))
532 value
= get_unaligned(ptr
.pul
++);
534 case DW_EH_PE_leb128
:
535 BUILD_BUG_ON(sizeof(uleb128_t
) > sizeof(value
));
536 value
= ptrType
& DW_EH_PE_signed
537 ? get_sleb128(&ptr
.p8
, end
)
538 : get_uleb128(&ptr
.p8
, end
);
539 if ((const void *)ptr
.p8
> end
)
545 switch(ptrType
& DW_EH_PE_ADJUST
) {
549 value
+= (unsigned long)*pLoc
;
554 if ((ptrType
& DW_EH_PE_indirect
)
555 && probe_kernel_address((unsigned long *)value
, value
))
562 static signed fde_pointer_type(const u32
*cie
)
564 const u8
*ptr
= (const u8
*)(cie
+ 2);
565 unsigned version
= *ptr
;
568 return -1; /* unsupported */
571 const u8
*end
= (const u8
*)(cie
+ 1) + *cie
;
574 /* check if augmentation size is first (and thus present) */
577 /* check if augmentation string is nul-terminated */
578 if ((ptr
= memchr(aug
= (const void *)ptr
, 0, end
- ptr
)) == NULL
)
580 ++ptr
; /* skip terminator */
581 get_uleb128(&ptr
, end
); /* skip code alignment */
582 get_sleb128(&ptr
, end
); /* skip data alignment */
583 /* skip return address column */
584 version
<= 1 ? (void)++ptr
: (void)get_uleb128(&ptr
, end
);
585 len
= get_uleb128(&ptr
, end
); /* augmentation length */
586 if (ptr
+ len
< ptr
|| ptr
+ len
> end
)
597 signed ptrType
= *ptr
++;
599 if (!read_pointer(&ptr
, end
, ptrType
) || ptr
> end
)
610 return DW_EH_PE_native
|DW_EH_PE_abs
;
613 static int advance_loc(unsigned long delta
, struct unwind_state
*state
)
615 state
->loc
+= delta
* state
->codeAlign
;
620 static void set_rule(uleb128_t reg
,
621 enum item_location where
,
623 struct unwind_state
*state
)
625 if (reg
< ARRAY_SIZE(state
->regs
)) {
626 state
->regs
[reg
].where
= where
;
627 state
->regs
[reg
].value
= value
;
631 static int processCFI(const u8
*start
,
633 unsigned long targetLoc
,
635 struct unwind_state
*state
)
644 if (start
!= state
->cieStart
) {
645 state
->loc
= state
->org
;
646 result
= processCFI(state
->cieStart
, state
->cieEnd
, 0, ptrType
, state
);
647 if (targetLoc
== 0 && state
->label
== NULL
)
650 for (ptr
.p8
= start
; result
&& ptr
.p8
< end
; ) {
651 switch(*ptr
.p8
>> 6) {
659 if ((state
->loc
= read_pointer(&ptr
.p8
, end
, ptrType
)) == 0)
662 case DW_CFA_advance_loc1
:
663 result
= ptr
.p8
< end
&& advance_loc(*ptr
.p8
++, state
);
665 case DW_CFA_advance_loc2
:
666 result
= ptr
.p8
<= end
+ 2
667 && advance_loc(*ptr
.p16
++, state
);
669 case DW_CFA_advance_loc4
:
670 result
= ptr
.p8
<= end
+ 4
671 && advance_loc(*ptr
.p32
++, state
);
673 case DW_CFA_offset_extended
:
674 value
= get_uleb128(&ptr
.p8
, end
);
675 set_rule(value
, Memory
, get_uleb128(&ptr
.p8
, end
), state
);
677 case DW_CFA_val_offset
:
678 value
= get_uleb128(&ptr
.p8
, end
);
679 set_rule(value
, Value
, get_uleb128(&ptr
.p8
, end
), state
);
681 case DW_CFA_offset_extended_sf
:
682 value
= get_uleb128(&ptr
.p8
, end
);
683 set_rule(value
, Memory
, get_sleb128(&ptr
.p8
, end
), state
);
685 case DW_CFA_val_offset_sf
:
686 value
= get_uleb128(&ptr
.p8
, end
);
687 set_rule(value
, Value
, get_sleb128(&ptr
.p8
, end
), state
);
689 case DW_CFA_restore_extended
:
690 case DW_CFA_undefined
:
691 case DW_CFA_same_value
:
692 set_rule(get_uleb128(&ptr
.p8
, end
), Nowhere
, 0, state
);
694 case DW_CFA_register
:
695 value
= get_uleb128(&ptr
.p8
, end
);
698 get_uleb128(&ptr
.p8
, end
), state
);
700 case DW_CFA_remember_state
:
701 if (ptr
.p8
== state
->label
) {
705 if (state
->stackDepth
>= MAX_STACK_DEPTH
)
707 state
->stack
[state
->stackDepth
++] = ptr
.p8
;
709 case DW_CFA_restore_state
:
710 if (state
->stackDepth
) {
711 const uleb128_t loc
= state
->loc
;
712 const u8
*label
= state
->label
;
714 state
->label
= state
->stack
[state
->stackDepth
- 1];
715 memcpy(&state
->cfa
, &badCFA
, sizeof(state
->cfa
));
716 memset(state
->regs
, 0, sizeof(state
->regs
));
717 state
->stackDepth
= 0;
718 result
= processCFI(start
, end
, 0, ptrType
, state
);
720 state
->label
= label
;
725 state
->cfa
.reg
= get_uleb128(&ptr
.p8
, end
);
727 case DW_CFA_def_cfa_offset
:
728 state
->cfa
.offs
= get_uleb128(&ptr
.p8
, end
);
730 case DW_CFA_def_cfa_sf
:
731 state
->cfa
.reg
= get_uleb128(&ptr
.p8
, end
);
733 case DW_CFA_def_cfa_offset_sf
:
734 state
->cfa
.offs
= get_sleb128(&ptr
.p8
, end
)
737 case DW_CFA_def_cfa_register
:
738 state
->cfa
.reg
= get_uleb128(&ptr
.p8
, end
);
740 /*todo case DW_CFA_def_cfa_expression: */
741 /*todo case DW_CFA_expression: */
742 /*todo case DW_CFA_val_expression: */
743 case DW_CFA_GNU_args_size
:
744 get_uleb128(&ptr
.p8
, end
);
746 case DW_CFA_GNU_negative_offset_extended
:
747 value
= get_uleb128(&ptr
.p8
, end
);
750 (uleb128_t
)0 - get_uleb128(&ptr
.p8
, end
), state
);
752 case DW_CFA_GNU_window_save
:
759 result
= advance_loc(*ptr
.p8
++ & 0x3f, state
);
762 value
= *ptr
.p8
++ & 0x3f;
763 set_rule(value
, Memory
, get_uleb128(&ptr
.p8
, end
), state
);
766 set_rule(*ptr
.p8
++ & 0x3f, Nowhere
, 0, state
);
771 if (result
&& targetLoc
!= 0 && targetLoc
< state
->loc
)
778 || (/*todo While in theory this should apply, gcc in practice omits
779 everything past the function prolog, and hence the location
780 never reaches the end of the function.
781 targetLoc < state->loc &&*/ state
->label
== NULL
));
784 /* Unwind to previous to frame. Returns 0 if successful, negative
785 * number in case of an error. */
786 int unwind(struct unwind_frame_info
*frame
)
788 #define FRAME_REG(r, t) (((t *)frame)[reg_info[r].offs])
789 const u32
*fde
= NULL
, *cie
= NULL
;
790 const u8
*ptr
= NULL
, *end
= NULL
;
791 unsigned long pc
= UNW_PC(frame
) - frame
->call_frame
, sp
;
792 unsigned long startLoc
= 0, endLoc
= 0, cfa
;
795 uleb128_t retAddrReg
= 0;
796 const struct unwind_table
*table
;
797 struct unwind_state state
;
799 if (UNW_PC(frame
) == 0)
801 if ((table
= find_table(pc
)) != NULL
802 && !(table
->size
& (sizeof(*fde
) - 1))) {
803 const u8
*hdr
= table
->header
;
804 unsigned long tableSize
;
807 if (hdr
&& hdr
[0] == 1) {
808 switch(hdr
[3] & DW_EH_PE_FORM
) {
809 case DW_EH_PE_native
: tableSize
= sizeof(unsigned long); break;
810 case DW_EH_PE_data2
: tableSize
= 2; break;
811 case DW_EH_PE_data4
: tableSize
= 4; break;
812 case DW_EH_PE_data8
: tableSize
= 8; break;
813 default: tableSize
= 0; break;
816 end
= hdr
+ table
->hdrsz
;
818 && read_pointer(&ptr
, end
, hdr
[1])
819 == (unsigned long)table
->address
820 && (i
= read_pointer(&ptr
, end
, hdr
[2])) > 0
821 && i
== (end
- ptr
) / (2 * tableSize
)
822 && !((end
- ptr
) % (2 * tableSize
))) {
824 const u8
*cur
= ptr
+ (i
/ 2) * (2 * tableSize
);
826 startLoc
= read_pointer(&cur
,
832 ptr
= cur
- tableSize
;
835 } while (startLoc
&& i
> 1);
837 && (startLoc
= read_pointer(&ptr
,
841 fde
= (void *)read_pointer(&ptr
,
848 cie
= cie_for_fde(fde
, table
);
849 ptr
= (const u8
*)(fde
+ 2);
853 && (ptrType
= fde_pointer_type(cie
)) >= 0
854 && read_pointer(&ptr
,
855 (const u8
*)(fde
+ 1) + *fde
,
856 ptrType
) == startLoc
) {
857 if (!(ptrType
& DW_EH_PE_indirect
))
858 ptrType
&= DW_EH_PE_FORM
|DW_EH_PE_signed
;
861 (const u8
*)(fde
+ 1) + *fde
,
869 for (fde
= table
->address
, tableSize
= table
->size
;
870 cie
= NULL
, tableSize
> sizeof(*fde
)
871 && tableSize
- sizeof(*fde
) >= *fde
;
872 tableSize
-= sizeof(*fde
) + *fde
,
873 fde
+= 1 + *fde
/ sizeof(*fde
)) {
874 cie
= cie_for_fde(fde
, table
);
875 if (cie
== &bad_cie
) {
881 || (ptrType
= fde_pointer_type(cie
)) < 0)
883 ptr
= (const u8
*)(fde
+ 2);
884 startLoc
= read_pointer(&ptr
,
885 (const u8
*)(fde
+ 1) + *fde
,
889 if (!(ptrType
& DW_EH_PE_indirect
))
890 ptrType
&= DW_EH_PE_FORM
|DW_EH_PE_signed
;
893 (const u8
*)(fde
+ 1) + *fde
,
895 if (pc
>= startLoc
&& pc
< endLoc
)
901 memset(&state
, 0, sizeof(state
));
902 state
.cieEnd
= ptr
; /* keep here temporarily */
903 ptr
= (const u8
*)(cie
+ 2);
904 end
= (const u8
*)(cie
+ 1) + *cie
;
905 frame
->call_frame
= 1;
906 if ((state
.version
= *ptr
) != 1)
907 cie
= NULL
; /* unsupported version */
909 /* check if augmentation size is first (and thus present) */
911 while (++ptr
< end
&& *ptr
) {
913 /* check for ignorable (or already handled)
914 * nul-terminated augmentation string */
920 frame
->call_frame
= 0;
928 if (ptr
>= end
|| *ptr
)
934 /* get code aligment factor */
935 state
.codeAlign
= get_uleb128(&ptr
, end
);
936 /* get data aligment factor */
937 state
.dataAlign
= get_sleb128(&ptr
, end
);
938 if (state
.codeAlign
== 0 || state
.dataAlign
== 0 || ptr
>= end
)
940 else if (UNW_PC(frame
) % state
.codeAlign
941 || UNW_SP(frame
) % sleb128abs(state
.dataAlign
))
944 retAddrReg
= state
.version
<= 1 ? *ptr
++ : get_uleb128(&ptr
, end
);
945 /* skip augmentation */
946 if (((const char *)(cie
+ 2))[1] == 'z') {
947 uleb128_t augSize
= get_uleb128(&ptr
, end
);
952 || retAddrReg
>= ARRAY_SIZE(reg_info
)
953 || REG_INVALID(retAddrReg
)
954 || reg_info
[retAddrReg
].width
!= sizeof(unsigned long))
959 state
.cieStart
= ptr
;
962 end
= (const u8
*)(fde
+ 1) + *fde
;
963 /* skip augmentation */
964 if (((const char *)(cie
+ 2))[1] == 'z') {
965 uleb128_t augSize
= get_uleb128(&ptr
, end
);
967 if ((ptr
+= augSize
) > end
)
971 if (cie
== NULL
|| fde
== NULL
) {
972 #ifdef CONFIG_FRAME_POINTER
973 unsigned long top
, bottom
;
975 if ((UNW_SP(frame
) | UNW_FP(frame
)) % sizeof(unsigned long))
977 top
= STACK_TOP(frame
->task
);
978 bottom
= STACK_BOTTOM(frame
->task
);
979 # if FRAME_RETADDR_OFFSET < 0
980 if (UNW_SP(frame
) < top
981 && UNW_FP(frame
) <= UNW_SP(frame
)
982 && bottom
< UNW_FP(frame
)
984 if (UNW_SP(frame
) > top
985 && UNW_FP(frame
) >= UNW_SP(frame
)
986 && bottom
> UNW_FP(frame
)
988 && !((UNW_SP(frame
) | UNW_FP(frame
))
989 & (sizeof(unsigned long) - 1))) {
992 if (!probe_kernel_address(
993 (unsigned long *)(UNW_FP(frame
)
994 + FRAME_LINK_OFFSET
),
996 # if FRAME_RETADDR_OFFSET < 0
997 && link
> bottom
&& link
< UNW_FP(frame
)
999 && link
> UNW_FP(frame
) && link
< bottom
1001 && !(link
& (sizeof(link
) - 1))
1002 && !probe_kernel_address(
1003 (unsigned long *)(UNW_FP(frame
)
1004 + FRAME_RETADDR_OFFSET
), UNW_PC(frame
))) {
1005 UNW_SP(frame
) = UNW_FP(frame
) + FRAME_RETADDR_OFFSET
1006 # if FRAME_RETADDR_OFFSET < 0
1011 sizeof(UNW_PC(frame
));
1012 UNW_FP(frame
) = link
;
1019 state
.org
= startLoc
;
1020 memcpy(&state
.cfa
, &badCFA
, sizeof(state
.cfa
));
1021 /* process instructions */
1022 if (!processCFI(ptr
, end
, pc
, ptrType
, &state
)
1023 || state
.loc
> endLoc
1024 || state
.regs
[retAddrReg
].where
== Nowhere
1025 || state
.cfa
.reg
>= ARRAY_SIZE(reg_info
)
1026 || reg_info
[state
.cfa
.reg
].width
!= sizeof(unsigned long)
1027 || FRAME_REG(state
.cfa
.reg
, unsigned long) % sizeof(unsigned long)
1028 || state
.cfa
.offs
% sizeof(unsigned long))
1031 #ifndef CONFIG_AS_CFI_SIGNAL_FRAME
1032 if(frame
->call_frame
1033 && !UNW_DEFAULT_RA(state
.regs
[retAddrReg
], state
.dataAlign
))
1034 frame
->call_frame
= 0;
1036 cfa
= FRAME_REG(state
.cfa
.reg
, unsigned long) + state
.cfa
.offs
;
1037 startLoc
= min((unsigned long)UNW_SP(frame
), cfa
);
1038 endLoc
= max((unsigned long)UNW_SP(frame
), cfa
);
1039 if (STACK_LIMIT(startLoc
) != STACK_LIMIT(endLoc
)) {
1040 startLoc
= min(STACK_LIMIT(cfa
), cfa
);
1041 endLoc
= max(STACK_LIMIT(cfa
), cfa
);
1043 #ifndef CONFIG_64BIT
1044 # define CASES CASE(8); CASE(16); CASE(32)
1046 # define CASES CASE(8); CASE(16); CASE(32); CASE(64)
1050 for (i
= 0; i
< ARRAY_SIZE(state
.regs
); ++i
) {
1051 if (REG_INVALID(i
)) {
1052 if (state
.regs
[i
].where
== Nowhere
)
1056 switch(state
.regs
[i
].where
) {
1060 if (state
.regs
[i
].value
>= ARRAY_SIZE(reg_info
)
1061 || REG_INVALID(state
.regs
[i
].value
)
1062 || reg_info
[i
].width
> reg_info
[state
.regs
[i
].value
].width
)
1064 switch(reg_info
[state
.regs
[i
].value
].width
) {
1066 case sizeof(u##n): \
1067 state.regs[i].value = FRAME_REG(state.regs[i].value, \
1078 for (i
= 0; i
< ARRAY_SIZE(state
.regs
); ++i
) {
1081 switch(state
.regs
[i
].where
) {
1083 if (reg_info
[i
].width
!= sizeof(UNW_SP(frame
))
1084 || &FRAME_REG(i
, __typeof__(UNW_SP(frame
)))
1087 UNW_SP(frame
) = cfa
;
1090 switch(reg_info
[i
].width
) {
1091 #define CASE(n) case sizeof(u##n): \
1092 FRAME_REG(i, u##n) = state.regs[i].value; \
1101 if (reg_info
[i
].width
!= sizeof(unsigned long))
1103 FRAME_REG(i
, unsigned long) = cfa
+ state
.regs
[i
].value
1107 unsigned long addr
= cfa
+ state
.regs
[i
].value
1110 if ((state
.regs
[i
].value
* state
.dataAlign
)
1111 % sizeof(unsigned long)
1113 || addr
+ sizeof(unsigned long) < addr
1114 || addr
+ sizeof(unsigned long) > endLoc
)
1116 switch(reg_info
[i
].width
) {
1117 #define CASE(n) case sizeof(u##n): \
1118 probe_kernel_address((u##n *)addr, FRAME_REG(i, u##n)); \
1130 if (UNW_PC(frame
) % state
.codeAlign
1131 || UNW_SP(frame
) % sleb128abs(state
.dataAlign
)
1132 || (pc
== UNW_PC(frame
) && sp
== UNW_SP(frame
)))
1139 EXPORT_SYMBOL(unwind
);
1141 int unwind_init_frame_info(struct unwind_frame_info
*info
,
1142 struct task_struct
*tsk
,
1143 /*const*/ struct pt_regs
*regs
)
1146 info
->call_frame
= 0;
1147 arch_unw_init_frame_info(info
, regs
);
1151 EXPORT_SYMBOL(unwind_init_frame_info
);
1154 * Prepare to unwind a blocked task.
1156 int unwind_init_blocked(struct unwind_frame_info
*info
,
1157 struct task_struct
*tsk
)
1160 info
->call_frame
= 0;
1161 arch_unw_init_blocked(info
);
1165 EXPORT_SYMBOL(unwind_init_blocked
);
1168 * Prepare to unwind the currently running thread.
1170 int unwind_init_running(struct unwind_frame_info
*info
,
1171 asmlinkage
int (*callback
)(struct unwind_frame_info
*,
1175 info
->task
= current
;
1176 info
->call_frame
= 0;
1178 return arch_unwind_init_running(info
, callback
, arg
);
1180 EXPORT_SYMBOL(unwind_init_running
);
1183 * Unwind until the return pointer is in user-land (or until an error
1184 * occurs). Returns 0 if successful, negative number in case of
1187 int unwind_to_user(struct unwind_frame_info
*info
)
1189 while (!arch_unw_user_mode(info
)) {
1190 int err
= unwind(info
);
1198 EXPORT_SYMBOL(unwind_to_user
);