blob: af48168a3afbd91408da9bcc487cdc345f4a3086 [file] [log] [blame]
Jan Beulich4552d5d2006-06-26 13:57:28 +02001/*
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.
5 *
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.
10 */
11
12#include <linux/unwind.h>
13#include <linux/module.h>
Jan Beulich690a973f2006-10-21 18:37:01 +020014#include <linux/bootmem.h>
15#include <linux/sort.h>
Jan Beulich4552d5d2006-06-26 13:57:28 +020016#include <linux/stop_machine.h>
Andi Kleene2124bb2006-12-07 02:14:12 +010017#include <linux/uaccess.h>
Jan Beulich4552d5d2006-06-26 13:57:28 +020018#include <asm/sections.h>
19#include <asm/uaccess.h>
20#include <asm/unaligned.h>
21
22extern char __start_unwind[], __end_unwind[];
Jan Beulich690a973f2006-10-21 18:37:01 +020023extern const u8 __start_unwind_hdr[], __end_unwind_hdr[];
Jan Beulich4552d5d2006-06-26 13:57:28 +020024
25#define MAX_STACK_DEPTH 8
26
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) \
33 }
34#define PTREGS_INFO(f) EXTRA_INFO(regs.f)
35
36static const struct {
37 unsigned offs:BITS_PER_LONG / 2;
38 unsigned width:BITS_PER_LONG / 2;
39} reg_info[] = {
40 UNW_REGISTER_INFO
41};
42
43#undef PTREGS_INFO
44#undef EXTRA_INFO
45
46#ifndef REG_INVALID
47#define REG_INVALID(r) (reg_info[r].width == 0)
48#endif
49
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
78
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
95
96typedef unsigned long uleb128_t;
97typedef signed long sleb128_t;
98
99static struct unwind_table {
100 struct {
101 unsigned long pc;
102 unsigned long range;
103 } core, init;
104 const void *address;
105 unsigned long size;
Jan Beulich690a973f2006-10-21 18:37:01 +0200106 const unsigned char *header;
107 unsigned long hdrsz;
Jan Beulich4552d5d2006-06-26 13:57:28 +0200108 struct unwind_table *link;
109 const char *name;
Chuck Ebberte6cab992006-09-29 01:59:57 -0700110} root_table;
Jan Beulich4552d5d2006-06-26 13:57:28 +0200111
112struct unwind_item {
113 enum item_location {
114 Nowhere,
115 Memory,
116 Register,
117 Value
118 } where;
119 uleb128_t value;
120};
121
122struct unwind_state {
123 uleb128_t loc, org;
124 const u8 *cieStart, *cieEnd;
125 uleb128_t codeAlign;
126 sleb128_t dataAlign;
127 struct cfa {
128 uleb128_t reg, offs;
129 } cfa;
130 struct unwind_item regs[ARRAY_SIZE(reg_info)];
131 unsigned stackDepth:8;
132 unsigned version:8;
133 const u8 *label;
134 const u8 *stack[MAX_STACK_DEPTH];
135};
136
137static const struct cfa badCFA = { ARRAY_SIZE(reg_info), 1 };
138
139static struct unwind_table *find_table(unsigned long pc)
140{
141 struct unwind_table *table;
142
143 for (table = &root_table; table; table = table->link)
144 if ((pc >= table->core.pc
145 && pc < table->core.pc + table->core.range)
146 || (pc >= table->init.pc
147 && pc < table->init.pc + table->init.range))
148 break;
149
150 return table;
151}
152
Jan Beulich690a973f2006-10-21 18:37:01 +0200153static unsigned long read_pointer(const u8 **pLoc,
154 const void *end,
155 signed ptrType);
156
Jan Beulich4552d5d2006-06-26 13:57:28 +0200157static void init_unwind_table(struct unwind_table *table,
158 const char *name,
159 const void *core_start,
160 unsigned long core_size,
161 const void *init_start,
162 unsigned long init_size,
163 const void *table_start,
Jan Beulich690a973f2006-10-21 18:37:01 +0200164 unsigned long table_size,
165 const u8 *header_start,
166 unsigned long header_size)
Jan Beulich4552d5d2006-06-26 13:57:28 +0200167{
Jan Beulich690a973f2006-10-21 18:37:01 +0200168 const u8 *ptr = header_start + 4;
169 const u8 *end = header_start + header_size;
170
Jan Beulich4552d5d2006-06-26 13:57:28 +0200171 table->core.pc = (unsigned long)core_start;
172 table->core.range = core_size;
173 table->init.pc = (unsigned long)init_start;
174 table->init.range = init_size;
175 table->address = table_start;
176 table->size = table_size;
Jan Beulich690a973f2006-10-21 18:37:01 +0200177 /* See if the linker provided table looks valid. */
178 if (header_size <= 4
179 || header_start[0] != 1
180 || (void *)read_pointer(&ptr, end, header_start[1]) != table_start
181 || header_start[2] == DW_EH_PE_omit
182 || read_pointer(&ptr, end, header_start[2]) <= 0
183 || header_start[3] == DW_EH_PE_omit)
184 header_start = NULL;
185 table->hdrsz = header_size;
186 smp_wmb();
187 table->header = header_start;
Jan Beulich4552d5d2006-06-26 13:57:28 +0200188 table->link = NULL;
189 table->name = name;
190}
191
192void __init unwind_init(void)
193{
194 init_unwind_table(&root_table, "kernel",
195 _text, _end - _text,
196 NULL, 0,
Jan Beulich690a973f2006-10-21 18:37:01 +0200197 __start_unwind, __end_unwind - __start_unwind,
198 __start_unwind_hdr, __end_unwind_hdr - __start_unwind_hdr);
199}
200
201static const u32 bad_cie, not_fde;
202static const u32 *cie_for_fde(const u32 *fde, const struct unwind_table *);
203static signed fde_pointer_type(const u32 *cie);
204
205struct eh_frame_hdr_table_entry {
206 unsigned long start, fde;
207};
208
209static int cmp_eh_frame_hdr_table_entries(const void *p1, const void *p2)
210{
211 const struct eh_frame_hdr_table_entry *e1 = p1;
212 const struct eh_frame_hdr_table_entry *e2 = p2;
213
214 return (e1->start > e2->start) - (e1->start < e2->start);
215}
216
217static void swap_eh_frame_hdr_table_entries(void *p1, void *p2, int size)
218{
219 struct eh_frame_hdr_table_entry *e1 = p1;
220 struct eh_frame_hdr_table_entry *e2 = p2;
221 unsigned long v;
222
223 v = e1->start;
224 e1->start = e2->start;
225 e2->start = v;
226 v = e1->fde;
227 e1->fde = e2->fde;
228 e2->fde = v;
229}
230
231static void __init setup_unwind_table(struct unwind_table *table,
232 void *(*alloc)(unsigned long))
233{
234 const u8 *ptr;
235 unsigned long tableSize = table->size, hdrSize;
236 unsigned n;
237 const u32 *fde;
238 struct {
239 u8 version;
240 u8 eh_frame_ptr_enc;
241 u8 fde_count_enc;
242 u8 table_enc;
243 unsigned long eh_frame_ptr;
244 unsigned int fde_count;
245 struct eh_frame_hdr_table_entry table[];
246 } __attribute__((__packed__)) *header;
247
248 if (table->header)
249 return;
250
251 if (table->hdrsz)
252 printk(KERN_WARNING ".eh_frame_hdr for '%s' present but unusable\n",
253 table->name);
254
255 if (tableSize & (sizeof(*fde) - 1))
256 return;
257
258 for (fde = table->address, n = 0;
259 tableSize > sizeof(*fde) && tableSize - sizeof(*fde) >= *fde;
260 tableSize -= sizeof(*fde) + *fde, fde += 1 + *fde / sizeof(*fde)) {
261 const u32 *cie = cie_for_fde(fde, table);
262 signed ptrType;
263
264 if (cie == &not_fde)
265 continue;
266 if (cie == NULL
267 || cie == &bad_cie
268 || (ptrType = fde_pointer_type(cie)) < 0)
269 return;
270 ptr = (const u8 *)(fde + 2);
271 if (!read_pointer(&ptr,
272 (const u8 *)(fde + 1) + *fde,
273 ptrType))
274 return;
275 ++n;
276 }
277
278 if (tableSize || !n)
279 return;
280
281 hdrSize = 4 + sizeof(unsigned long) + sizeof(unsigned int)
282 + 2 * n * sizeof(unsigned long);
283 header = alloc(hdrSize);
284 if (!header)
285 return;
286 header->version = 1;
287 header->eh_frame_ptr_enc = DW_EH_PE_abs|DW_EH_PE_native;
288 header->fde_count_enc = DW_EH_PE_abs|DW_EH_PE_data4;
289 header->table_enc = DW_EH_PE_abs|DW_EH_PE_native;
290 put_unaligned((unsigned long)table->address, &header->eh_frame_ptr);
291 BUILD_BUG_ON(offsetof(typeof(*header), fde_count)
292 % __alignof(typeof(header->fde_count)));
293 header->fde_count = n;
294
295 BUILD_BUG_ON(offsetof(typeof(*header), table)
296 % __alignof(typeof(*header->table)));
297 for (fde = table->address, tableSize = table->size, n = 0;
298 tableSize;
299 tableSize -= sizeof(*fde) + *fde, fde += 1 + *fde / sizeof(*fde)) {
300 const u32 *cie = fde + 1 - fde[1] / sizeof(*fde);
301
302 if (!fde[1])
303 continue; /* this is a CIE */
304 ptr = (const u8 *)(fde + 2);
305 header->table[n].start = read_pointer(&ptr,
306 (const u8 *)(fde + 1) + *fde,
307 fde_pointer_type(cie));
308 header->table[n].fde = (unsigned long)fde;
309 ++n;
310 }
311 WARN_ON(n != header->fde_count);
312
313 sort(header->table,
314 n,
315 sizeof(*header->table),
316 cmp_eh_frame_hdr_table_entries,
317 swap_eh_frame_hdr_table_entries);
318
319 table->hdrsz = hdrSize;
320 smp_wmb();
321 table->header = (const void *)header;
322}
323
324static void *__init balloc(unsigned long sz)
325{
326 return __alloc_bootmem_nopanic(sz,
327 sizeof(unsigned int),
328 __pa(MAX_DMA_ADDRESS));
329}
330
331void __init unwind_setup(void)
332{
333 setup_unwind_table(&root_table, balloc);
Jan Beulich4552d5d2006-06-26 13:57:28 +0200334}
335
Jan Beulich83f4fcc2006-06-26 13:57:50 +0200336#ifdef CONFIG_MODULES
337
Chuck Ebberte6cab992006-09-29 01:59:57 -0700338static struct unwind_table *last_table;
339
Jan Beulich4552d5d2006-06-26 13:57:28 +0200340/* Must be called with module_mutex held. */
341void *unwind_add_table(struct module *module,
342 const void *table_start,
343 unsigned long table_size)
344{
345 struct unwind_table *table;
346
347 if (table_size <= 0)
348 return NULL;
349
350 table = kmalloc(sizeof(*table), GFP_KERNEL);
351 if (!table)
352 return NULL;
353
354 init_unwind_table(table, module->name,
355 module->module_core, module->core_size,
356 module->module_init, module->init_size,
Jan Beulich690a973f2006-10-21 18:37:01 +0200357 table_start, table_size,
358 NULL, 0);
Jan Beulich4552d5d2006-06-26 13:57:28 +0200359
360 if (last_table)
361 last_table->link = table;
362 else
363 root_table.link = table;
364 last_table = table;
365
366 return table;
367}
368
369struct unlink_table_info
370{
371 struct unwind_table *table;
372 int init_only;
373};
374
375static int unlink_table(void *arg)
376{
377 struct unlink_table_info *info = arg;
378 struct unwind_table *table = info->table, *prev;
379
380 for (prev = &root_table; prev->link && prev->link != table; prev = prev->link)
381 ;
382
383 if (prev->link) {
384 if (info->init_only) {
385 table->init.pc = 0;
386 table->init.range = 0;
387 info->table = NULL;
388 } else {
389 prev->link = table->link;
390 if (!prev->link)
391 last_table = prev;
392 }
393 } else
394 info->table = NULL;
395
396 return 0;
397}
398
399/* Must be called with module_mutex held. */
400void unwind_remove_table(void *handle, int init_only)
401{
402 struct unwind_table *table = handle;
403 struct unlink_table_info info;
404
405 if (!table || table == &root_table)
406 return;
407
408 if (init_only && table == last_table) {
409 table->init.pc = 0;
410 table->init.range = 0;
411 return;
412 }
413
414 info.table = table;
415 info.init_only = init_only;
416 stop_machine_run(unlink_table, &info, NR_CPUS);
417
418 if (info.table)
419 kfree(table);
420}
421
Jan Beulich83f4fcc2006-06-26 13:57:50 +0200422#endif /* CONFIG_MODULES */
423
Jan Beulich4552d5d2006-06-26 13:57:28 +0200424static uleb128_t get_uleb128(const u8 **pcur, const u8 *end)
425{
426 const u8 *cur = *pcur;
427 uleb128_t value;
428 unsigned shift;
429
430 for (shift = 0, value = 0; cur < end; shift += 7) {
431 if (shift + 7 > 8 * sizeof(value)
432 && (*cur & 0x7fU) >= (1U << (8 * sizeof(value) - shift))) {
433 cur = end + 1;
434 break;
435 }
436 value |= (uleb128_t)(*cur & 0x7f) << shift;
437 if (!(*cur++ & 0x80))
438 break;
439 }
440 *pcur = cur;
441
442 return value;
443}
444
445static sleb128_t get_sleb128(const u8 **pcur, const u8 *end)
446{
447 const u8 *cur = *pcur;
448 sleb128_t value;
449 unsigned shift;
450
451 for (shift = 0, value = 0; cur < end; shift += 7) {
452 if (shift + 7 > 8 * sizeof(value)
453 && (*cur & 0x7fU) >= (1U << (8 * sizeof(value) - shift))) {
454 cur = end + 1;
455 break;
456 }
457 value |= (sleb128_t)(*cur & 0x7f) << shift;
458 if (!(*cur & 0x80)) {
459 value |= -(*cur++ & 0x40) << shift;
460 break;
461 }
462 }
463 *pcur = cur;
464
465 return value;
466}
467
Jan Beulich690a973f2006-10-21 18:37:01 +0200468static const u32 *cie_for_fde(const u32 *fde, const struct unwind_table *table)
469{
470 const u32 *cie;
471
472 if (!*fde || (*fde & (sizeof(*fde) - 1)))
473 return &bad_cie;
474 if (!fde[1])
475 return &not_fde; /* this is a CIE */
476 if ((fde[1] & (sizeof(*fde) - 1))
477 || fde[1] > (unsigned long)(fde + 1) - (unsigned long)table->address)
478 return NULL; /* this is not a valid FDE */
479 cie = fde + 1 - fde[1] / sizeof(*fde);
480 if (*cie <= sizeof(*cie) + 4
481 || *cie >= fde[1] - sizeof(*fde)
482 || (*cie & (sizeof(*cie) - 1))
483 || cie[1])
484 return NULL; /* this is not a (valid) CIE */
485 return cie;
486}
487
Jan Beulich4552d5d2006-06-26 13:57:28 +0200488static unsigned long read_pointer(const u8 **pLoc,
489 const void *end,
490 signed ptrType)
491{
492 unsigned long value = 0;
493 union {
494 const u8 *p8;
495 const u16 *p16u;
496 const s16 *p16s;
497 const u32 *p32u;
498 const s32 *p32s;
499 const unsigned long *pul;
500 } ptr;
501
502 if (ptrType < 0 || ptrType == DW_EH_PE_omit)
503 return 0;
504 ptr.p8 = *pLoc;
505 switch(ptrType & DW_EH_PE_FORM) {
506 case DW_EH_PE_data2:
507 if (end < (const void *)(ptr.p16u + 1))
508 return 0;
509 if(ptrType & DW_EH_PE_signed)
510 value = get_unaligned(ptr.p16s++);
511 else
512 value = get_unaligned(ptr.p16u++);
513 break;
514 case DW_EH_PE_data4:
515#ifdef CONFIG_64BIT
516 if (end < (const void *)(ptr.p32u + 1))
517 return 0;
518 if(ptrType & DW_EH_PE_signed)
519 value = get_unaligned(ptr.p32s++);
520 else
521 value = get_unaligned(ptr.p32u++);
522 break;
523 case DW_EH_PE_data8:
524 BUILD_BUG_ON(sizeof(u64) != sizeof(value));
525#else
526 BUILD_BUG_ON(sizeof(u32) != sizeof(value));
527#endif
528 case DW_EH_PE_native:
529 if (end < (const void *)(ptr.pul + 1))
530 return 0;
531 value = get_unaligned(ptr.pul++);
532 break;
533 case DW_EH_PE_leb128:
534 BUILD_BUG_ON(sizeof(uleb128_t) > sizeof(value));
535 value = ptrType & DW_EH_PE_signed
536 ? get_sleb128(&ptr.p8, end)
537 : get_uleb128(&ptr.p8, end);
538 if ((const void *)ptr.p8 > end)
539 return 0;
540 break;
541 default:
542 return 0;
543 }
544 switch(ptrType & DW_EH_PE_ADJUST) {
545 case DW_EH_PE_abs:
546 break;
547 case DW_EH_PE_pcrel:
548 value += (unsigned long)*pLoc;
549 break;
550 default:
551 return 0;
552 }
553 if ((ptrType & DW_EH_PE_indirect)
Andi Kleene2124bb2006-12-07 02:14:12 +0100554 && probe_kernel_address((unsigned long *)value, value))
Jan Beulich4552d5d2006-06-26 13:57:28 +0200555 return 0;
556 *pLoc = ptr.p8;
557
558 return value;
559}
560
561static signed fde_pointer_type(const u32 *cie)
562{
563 const u8 *ptr = (const u8 *)(cie + 2);
564 unsigned version = *ptr;
565
566 if (version != 1)
567 return -1; /* unsupported */
568 if (*++ptr) {
569 const char *aug;
570 const u8 *end = (const u8 *)(cie + 1) + *cie;
571 uleb128_t len;
572
573 /* check if augmentation size is first (and thus present) */
574 if (*ptr != 'z')
575 return -1;
576 /* check if augmentation string is nul-terminated */
577 if ((ptr = memchr(aug = (const void *)ptr, 0, end - ptr)) == NULL)
578 return -1;
579 ++ptr; /* skip terminator */
580 get_uleb128(&ptr, end); /* skip code alignment */
581 get_sleb128(&ptr, end); /* skip data alignment */
582 /* skip return address column */
583 version <= 1 ? (void)++ptr : (void)get_uleb128(&ptr, end);
584 len = get_uleb128(&ptr, end); /* augmentation length */
585 if (ptr + len < ptr || ptr + len > end)
586 return -1;
587 end = ptr + len;
588 while (*++aug) {
589 if (ptr >= end)
590 return -1;
591 switch(*aug) {
592 case 'L':
593 ++ptr;
594 break;
595 case 'P': {
596 signed ptrType = *ptr++;
597
598 if (!read_pointer(&ptr, end, ptrType) || ptr > end)
599 return -1;
600 }
601 break;
602 case 'R':
603 return *ptr;
604 default:
605 return -1;
606 }
607 }
608 }
609 return DW_EH_PE_native|DW_EH_PE_abs;
610}
611
612static int advance_loc(unsigned long delta, struct unwind_state *state)
613{
614 state->loc += delta * state->codeAlign;
615
616 return delta > 0;
617}
618
619static void set_rule(uleb128_t reg,
620 enum item_location where,
621 uleb128_t value,
622 struct unwind_state *state)
623{
624 if (reg < ARRAY_SIZE(state->regs)) {
625 state->regs[reg].where = where;
626 state->regs[reg].value = value;
627 }
628}
629
630static int processCFI(const u8 *start,
631 const u8 *end,
632 unsigned long targetLoc,
633 signed ptrType,
634 struct unwind_state *state)
635{
636 union {
637 const u8 *p8;
638 const u16 *p16;
639 const u32 *p32;
640 } ptr;
641 int result = 1;
642
643 if (start != state->cieStart) {
644 state->loc = state->org;
645 result = processCFI(state->cieStart, state->cieEnd, 0, ptrType, state);
646 if (targetLoc == 0 && state->label == NULL)
647 return result;
648 }
649 for (ptr.p8 = start; result && ptr.p8 < end; ) {
650 switch(*ptr.p8 >> 6) {
651 uleb128_t value;
652
653 case 0:
654 switch(*ptr.p8++) {
655 case DW_CFA_nop:
656 break;
657 case DW_CFA_set_loc:
658 if ((state->loc = read_pointer(&ptr.p8, end, ptrType)) == 0)
659 result = 0;
660 break;
661 case DW_CFA_advance_loc1:
662 result = ptr.p8 < end && advance_loc(*ptr.p8++, state);
663 break;
664 case DW_CFA_advance_loc2:
665 result = ptr.p8 <= end + 2
666 && advance_loc(*ptr.p16++, state);
667 break;
668 case DW_CFA_advance_loc4:
669 result = ptr.p8 <= end + 4
670 && advance_loc(*ptr.p32++, state);
671 break;
672 case DW_CFA_offset_extended:
673 value = get_uleb128(&ptr.p8, end);
674 set_rule(value, Memory, get_uleb128(&ptr.p8, end), state);
675 break;
676 case DW_CFA_val_offset:
677 value = get_uleb128(&ptr.p8, end);
678 set_rule(value, Value, get_uleb128(&ptr.p8, end), state);
679 break;
680 case DW_CFA_offset_extended_sf:
681 value = get_uleb128(&ptr.p8, end);
682 set_rule(value, Memory, get_sleb128(&ptr.p8, end), state);
683 break;
684 case DW_CFA_val_offset_sf:
685 value = get_uleb128(&ptr.p8, end);
686 set_rule(value, Value, get_sleb128(&ptr.p8, end), state);
687 break;
688 case DW_CFA_restore_extended:
689 case DW_CFA_undefined:
690 case DW_CFA_same_value:
691 set_rule(get_uleb128(&ptr.p8, end), Nowhere, 0, state);
692 break;
693 case DW_CFA_register:
694 value = get_uleb128(&ptr.p8, end);
695 set_rule(value,
696 Register,
697 get_uleb128(&ptr.p8, end), state);
698 break;
699 case DW_CFA_remember_state:
700 if (ptr.p8 == state->label) {
701 state->label = NULL;
702 return 1;
703 }
704 if (state->stackDepth >= MAX_STACK_DEPTH)
705 return 0;
706 state->stack[state->stackDepth++] = ptr.p8;
707 break;
708 case DW_CFA_restore_state:
709 if (state->stackDepth) {
710 const uleb128_t loc = state->loc;
711 const u8 *label = state->label;
712
713 state->label = state->stack[state->stackDepth - 1];
714 memcpy(&state->cfa, &badCFA, sizeof(state->cfa));
715 memset(state->regs, 0, sizeof(state->regs));
716 state->stackDepth = 0;
717 result = processCFI(start, end, 0, ptrType, state);
718 state->loc = loc;
719 state->label = label;
720 } else
721 return 0;
722 break;
723 case DW_CFA_def_cfa:
724 state->cfa.reg = get_uleb128(&ptr.p8, end);
725 /*nobreak*/
726 case DW_CFA_def_cfa_offset:
727 state->cfa.offs = get_uleb128(&ptr.p8, end);
728 break;
729 case DW_CFA_def_cfa_sf:
730 state->cfa.reg = get_uleb128(&ptr.p8, end);
731 /*nobreak*/
732 case DW_CFA_def_cfa_offset_sf:
733 state->cfa.offs = get_sleb128(&ptr.p8, end)
734 * state->dataAlign;
735 break;
736 case DW_CFA_def_cfa_register:
737 state->cfa.reg = get_uleb128(&ptr.p8, end);
738 break;
739 /*todo case DW_CFA_def_cfa_expression: */
740 /*todo case DW_CFA_expression: */
741 /*todo case DW_CFA_val_expression: */
742 case DW_CFA_GNU_args_size:
743 get_uleb128(&ptr.p8, end);
744 break;
745 case DW_CFA_GNU_negative_offset_extended:
746 value = get_uleb128(&ptr.p8, end);
747 set_rule(value,
748 Memory,
749 (uleb128_t)0 - get_uleb128(&ptr.p8, end), state);
750 break;
751 case DW_CFA_GNU_window_save:
752 default:
753 result = 0;
754 break;
755 }
756 break;
757 case 1:
758 result = advance_loc(*ptr.p8++ & 0x3f, state);
759 break;
760 case 2:
761 value = *ptr.p8++ & 0x3f;
762 set_rule(value, Memory, get_uleb128(&ptr.p8, end), state);
763 break;
764 case 3:
765 set_rule(*ptr.p8++ & 0x3f, Nowhere, 0, state);
766 break;
767 }
768 if (ptr.p8 > end)
769 result = 0;
770 if (result && targetLoc != 0 && targetLoc < state->loc)
771 return 1;
772 }
773
774 return result
775 && ptr.p8 == end
776 && (targetLoc == 0
777 || (/*todo While in theory this should apply, gcc in practice omits
778 everything past the function prolog, and hence the location
779 never reaches the end of the function.
780 targetLoc < state->loc &&*/ state->label == NULL));
781}
782
783/* Unwind to previous to frame. Returns 0 if successful, negative
784 * number in case of an error. */
785int unwind(struct unwind_frame_info *frame)
786{
787#define FRAME_REG(r, t) (((t *)frame)[reg_info[r].offs])
788 const u32 *fde = NULL, *cie = NULL;
789 const u8 *ptr = NULL, *end = NULL;
Jan Beulichadf14232006-09-26 10:52:41 +0200790 unsigned long pc = UNW_PC(frame) - frame->call_frame;
Jan Beulich4552d5d2006-06-26 13:57:28 +0200791 unsigned long startLoc = 0, endLoc = 0, cfa;
792 unsigned i;
793 signed ptrType = -1;
794 uleb128_t retAddrReg = 0;
Jan Beulich690a973f2006-10-21 18:37:01 +0200795 const struct unwind_table *table;
Jan Beulich4552d5d2006-06-26 13:57:28 +0200796 struct unwind_state state;
797
798 if (UNW_PC(frame) == 0)
799 return -EINVAL;
Jan Beulichadf14232006-09-26 10:52:41 +0200800 if ((table = find_table(pc)) != NULL
Jan Beulich4552d5d2006-06-26 13:57:28 +0200801 && !(table->size & (sizeof(*fde) - 1))) {
Jan Beulich690a973f2006-10-21 18:37:01 +0200802 const u8 *hdr = table->header;
803 unsigned long tableSize;
Jan Beulich4552d5d2006-06-26 13:57:28 +0200804
Jan Beulich690a973f2006-10-21 18:37:01 +0200805 smp_rmb();
806 if (hdr && hdr[0] == 1) {
807 switch(hdr[3] & DW_EH_PE_FORM) {
808 case DW_EH_PE_native: tableSize = sizeof(unsigned long); break;
809 case DW_EH_PE_data2: tableSize = 2; break;
810 case DW_EH_PE_data4: tableSize = 4; break;
811 case DW_EH_PE_data8: tableSize = 8; break;
812 default: tableSize = 0; break;
Jan Beulich4552d5d2006-06-26 13:57:28 +0200813 }
Jan Beulich690a973f2006-10-21 18:37:01 +0200814 ptr = hdr + 4;
815 end = hdr + table->hdrsz;
816 if (tableSize
817 && read_pointer(&ptr, end, hdr[1])
818 == (unsigned long)table->address
819 && (i = read_pointer(&ptr, end, hdr[2])) > 0
820 && i == (end - ptr) / (2 * tableSize)
821 && !((end - ptr) % (2 * tableSize))) {
822 do {
823 const u8 *cur = ptr + (i / 2) * (2 * tableSize);
824
825 startLoc = read_pointer(&cur,
826 cur + tableSize,
827 hdr[3]);
828 if (pc < startLoc)
829 i /= 2;
830 else {
831 ptr = cur - tableSize;
832 i = (i + 1) / 2;
833 }
834 } while (startLoc && i > 1);
835 if (i == 1
836 && (startLoc = read_pointer(&ptr,
837 ptr + tableSize,
838 hdr[3])) != 0
839 && pc >= startLoc)
840 fde = (void *)read_pointer(&ptr,
841 ptr + tableSize,
842 hdr[3]);
843 }
844 }
845
846 if (fde != NULL) {
847 cie = cie_for_fde(fde, table);
Jan Beulich4552d5d2006-06-26 13:57:28 +0200848 ptr = (const u8 *)(fde + 2);
Jan Beulich690a973f2006-10-21 18:37:01 +0200849 if(cie != NULL
850 && cie != &bad_cie
851 && cie != &not_fde
852 && (ptrType = fde_pointer_type(cie)) >= 0
853 && read_pointer(&ptr,
854 (const u8 *)(fde + 1) + *fde,
855 ptrType) == startLoc) {
856 if (!(ptrType & DW_EH_PE_indirect))
857 ptrType &= DW_EH_PE_FORM|DW_EH_PE_signed;
858 endLoc = startLoc
859 + read_pointer(&ptr,
860 (const u8 *)(fde + 1) + *fde,
861 ptrType);
862 if(pc >= endLoc)
863 fde = NULL;
864 } else
865 fde = NULL;
866 }
867 if (fde == NULL) {
868 for (fde = table->address, tableSize = table->size;
869 cie = NULL, tableSize > sizeof(*fde)
870 && tableSize - sizeof(*fde) >= *fde;
871 tableSize -= sizeof(*fde) + *fde,
872 fde += 1 + *fde / sizeof(*fde)) {
873 cie = cie_for_fde(fde, table);
874 if (cie == &bad_cie) {
875 cie = NULL;
876 break;
877 }
878 if (cie == NULL
879 || cie == &not_fde
880 || (ptrType = fde_pointer_type(cie)) < 0)
881 continue;
882 ptr = (const u8 *)(fde + 2);
883 startLoc = read_pointer(&ptr,
884 (const u8 *)(fde + 1) + *fde,
885 ptrType);
886 if (!startLoc)
887 continue;
888 if (!(ptrType & DW_EH_PE_indirect))
889 ptrType &= DW_EH_PE_FORM|DW_EH_PE_signed;
890 endLoc = startLoc
891 + read_pointer(&ptr,
892 (const u8 *)(fde + 1) + *fde,
893 ptrType);
894 if (pc >= startLoc && pc < endLoc)
895 break;
896 }
Jan Beulich4552d5d2006-06-26 13:57:28 +0200897 }
898 }
899 if (cie != NULL) {
900 memset(&state, 0, sizeof(state));
901 state.cieEnd = ptr; /* keep here temporarily */
902 ptr = (const u8 *)(cie + 2);
903 end = (const u8 *)(cie + 1) + *cie;
Jan Beulichadf14232006-09-26 10:52:41 +0200904 frame->call_frame = 1;
Jan Beulich4552d5d2006-06-26 13:57:28 +0200905 if ((state.version = *ptr) != 1)
906 cie = NULL; /* unsupported version */
907 else if (*++ptr) {
908 /* check if augmentation size is first (and thus present) */
909 if (*ptr == 'z') {
Jan Beulichadf14232006-09-26 10:52:41 +0200910 while (++ptr < end && *ptr) {
911 switch(*ptr) {
912 /* check for ignorable (or already handled)
913 * nul-terminated augmentation string */
914 case 'L':
915 case 'P':
916 case 'R':
917 continue;
918 case 'S':
919 frame->call_frame = 0;
920 continue;
921 default:
Jan Beulich4552d5d2006-06-26 13:57:28 +0200922 break;
Jan Beulichadf14232006-09-26 10:52:41 +0200923 }
924 break;
925 }
Jan Beulich4552d5d2006-06-26 13:57:28 +0200926 }
927 if (ptr >= end || *ptr)
928 cie = NULL;
929 }
930 ++ptr;
931 }
932 if (cie != NULL) {
933 /* get code aligment factor */
934 state.codeAlign = get_uleb128(&ptr, end);
935 /* get data aligment factor */
936 state.dataAlign = get_sleb128(&ptr, end);
937 if (state.codeAlign == 0 || state.dataAlign == 0 || ptr >= end)
938 cie = NULL;
939 else {
940 retAddrReg = state.version <= 1 ? *ptr++ : get_uleb128(&ptr, end);
941 /* skip augmentation */
Jan Beulichff0a5382006-11-28 20:12:59 +0100942 if (((const char *)(cie + 2))[1] == 'z') {
943 uleb128_t augSize = get_uleb128(&ptr, end);
944
945 ptr += augSize;
946 }
Jan Beulich4552d5d2006-06-26 13:57:28 +0200947 if (ptr > end
948 || retAddrReg >= ARRAY_SIZE(reg_info)
949 || REG_INVALID(retAddrReg)
950 || reg_info[retAddrReg].width != sizeof(unsigned long))
951 cie = NULL;
952 }
953 }
954 if (cie != NULL) {
955 state.cieStart = ptr;
956 ptr = state.cieEnd;
957 state.cieEnd = end;
958 end = (const u8 *)(fde + 1) + *fde;
959 /* skip augmentation */
960 if (((const char *)(cie + 2))[1] == 'z') {
961 uleb128_t augSize = get_uleb128(&ptr, end);
962
963 if ((ptr += augSize) > end)
964 fde = NULL;
965 }
966 }
967 if (cie == NULL || fde == NULL) {
968#ifdef CONFIG_FRAME_POINTER
969 unsigned long top, bottom;
Jan Beulich4552d5d2006-06-26 13:57:28 +0200970
Jan Beulich4552d5d2006-06-26 13:57:28 +0200971 top = STACK_TOP(frame->task);
972 bottom = STACK_BOTTOM(frame->task);
973# if FRAME_RETADDR_OFFSET < 0
974 if (UNW_SP(frame) < top
975 && UNW_FP(frame) <= UNW_SP(frame)
976 && bottom < UNW_FP(frame)
977# else
978 if (UNW_SP(frame) > top
979 && UNW_FP(frame) >= UNW_SP(frame)
980 && bottom > UNW_FP(frame)
981# endif
982 && !((UNW_SP(frame) | UNW_FP(frame))
983 & (sizeof(unsigned long) - 1))) {
984 unsigned long link;
985
Andi Kleene2124bb2006-12-07 02:14:12 +0100986 if (!probe_kernel_address(
Jan Beulich4552d5d2006-06-26 13:57:28 +0200987 (unsigned long *)(UNW_FP(frame)
Andi Kleene2124bb2006-12-07 02:14:12 +0100988 + FRAME_LINK_OFFSET),
989 link)
Jan Beulich4552d5d2006-06-26 13:57:28 +0200990# if FRAME_RETADDR_OFFSET < 0
991 && link > bottom && link < UNW_FP(frame)
992# else
993 && link > UNW_FP(frame) && link < bottom
994# endif
995 && !(link & (sizeof(link) - 1))
Andi Kleene2124bb2006-12-07 02:14:12 +0100996 && !probe_kernel_address(
Jan Beulich4552d5d2006-06-26 13:57:28 +0200997 (unsigned long *)(UNW_FP(frame)
Andi Kleene2124bb2006-12-07 02:14:12 +0100998 + FRAME_RETADDR_OFFSET), UNW_PC(frame))) {
Jan Beulich4552d5d2006-06-26 13:57:28 +0200999 UNW_SP(frame) = UNW_FP(frame) + FRAME_RETADDR_OFFSET
1000# if FRAME_RETADDR_OFFSET < 0
1001 -
1002# else
1003 +
1004# endif
1005 sizeof(UNW_PC(frame));
1006 UNW_FP(frame) = link;
1007 return 0;
1008 }
1009 }
1010#endif
1011 return -ENXIO;
1012 }
1013 state.org = startLoc;
1014 memcpy(&state.cfa, &badCFA, sizeof(state.cfa));
1015 /* process instructions */
Jan Beulichadf14232006-09-26 10:52:41 +02001016 if (!processCFI(ptr, end, pc, ptrType, &state)
Jan Beulich4552d5d2006-06-26 13:57:28 +02001017 || state.loc > endLoc
1018 || state.regs[retAddrReg].where == Nowhere
1019 || state.cfa.reg >= ARRAY_SIZE(reg_info)
1020 || reg_info[state.cfa.reg].width != sizeof(unsigned long)
1021 || state.cfa.offs % sizeof(unsigned long))
1022 return -EIO;
1023 /* update frame */
Jan Beulichadf14232006-09-26 10:52:41 +02001024#ifndef CONFIG_AS_CFI_SIGNAL_FRAME
1025 if(frame->call_frame
1026 && !UNW_DEFAULT_RA(state.regs[retAddrReg], state.dataAlign))
1027 frame->call_frame = 0;
1028#endif
Jan Beulich4552d5d2006-06-26 13:57:28 +02001029 cfa = FRAME_REG(state.cfa.reg, unsigned long) + state.cfa.offs;
1030 startLoc = min((unsigned long)UNW_SP(frame), cfa);
1031 endLoc = max((unsigned long)UNW_SP(frame), cfa);
1032 if (STACK_LIMIT(startLoc) != STACK_LIMIT(endLoc)) {
1033 startLoc = min(STACK_LIMIT(cfa), cfa);
1034 endLoc = max(STACK_LIMIT(cfa), cfa);
1035 }
1036#ifndef CONFIG_64BIT
1037# define CASES CASE(8); CASE(16); CASE(32)
1038#else
1039# define CASES CASE(8); CASE(16); CASE(32); CASE(64)
1040#endif
1041 for (i = 0; i < ARRAY_SIZE(state.regs); ++i) {
1042 if (REG_INVALID(i)) {
1043 if (state.regs[i].where == Nowhere)
1044 continue;
1045 return -EIO;
1046 }
1047 switch(state.regs[i].where) {
1048 default:
1049 break;
1050 case Register:
1051 if (state.regs[i].value >= ARRAY_SIZE(reg_info)
1052 || REG_INVALID(state.regs[i].value)
1053 || reg_info[i].width > reg_info[state.regs[i].value].width)
1054 return -EIO;
1055 switch(reg_info[state.regs[i].value].width) {
1056#define CASE(n) \
1057 case sizeof(u##n): \
1058 state.regs[i].value = FRAME_REG(state.regs[i].value, \
1059 const u##n); \
1060 break
1061 CASES;
1062#undef CASE
1063 default:
1064 return -EIO;
1065 }
1066 break;
1067 }
1068 }
1069 for (i = 0; i < ARRAY_SIZE(state.regs); ++i) {
1070 if (REG_INVALID(i))
1071 continue;
1072 switch(state.regs[i].where) {
1073 case Nowhere:
1074 if (reg_info[i].width != sizeof(UNW_SP(frame))
1075 || &FRAME_REG(i, __typeof__(UNW_SP(frame)))
1076 != &UNW_SP(frame))
1077 continue;
1078 UNW_SP(frame) = cfa;
1079 break;
1080 case Register:
1081 switch(reg_info[i].width) {
1082#define CASE(n) case sizeof(u##n): \
1083 FRAME_REG(i, u##n) = state.regs[i].value; \
1084 break
1085 CASES;
1086#undef CASE
1087 default:
1088 return -EIO;
1089 }
1090 break;
1091 case Value:
1092 if (reg_info[i].width != sizeof(unsigned long))
1093 return -EIO;
1094 FRAME_REG(i, unsigned long) = cfa + state.regs[i].value
1095 * state.dataAlign;
1096 break;
1097 case Memory: {
1098 unsigned long addr = cfa + state.regs[i].value
1099 * state.dataAlign;
1100
1101 if ((state.regs[i].value * state.dataAlign)
1102 % sizeof(unsigned long)
1103 || addr < startLoc
1104 || addr + sizeof(unsigned long) < addr
1105 || addr + sizeof(unsigned long) > endLoc)
1106 return -EIO;
1107 switch(reg_info[i].width) {
1108#define CASE(n) case sizeof(u##n): \
Andi Kleene2124bb2006-12-07 02:14:12 +01001109 probe_kernel_address((u##n *)addr, FRAME_REG(i, u##n)); \
Jan Beulich4552d5d2006-06-26 13:57:28 +02001110 break
1111 CASES;
1112#undef CASE
1113 default:
1114 return -EIO;
1115 }
1116 }
1117 break;
1118 }
1119 }
1120
1121 return 0;
1122#undef CASES
1123#undef FRAME_REG
1124}
1125EXPORT_SYMBOL(unwind);
1126
1127int unwind_init_frame_info(struct unwind_frame_info *info,
1128 struct task_struct *tsk,
1129 /*const*/ struct pt_regs *regs)
1130{
1131 info->task = tsk;
Jan Beulichadf14232006-09-26 10:52:41 +02001132 info->call_frame = 0;
Jan Beulich4552d5d2006-06-26 13:57:28 +02001133 arch_unw_init_frame_info(info, regs);
1134
1135 return 0;
1136}
1137EXPORT_SYMBOL(unwind_init_frame_info);
1138
1139/*
1140 * Prepare to unwind a blocked task.
1141 */
1142int unwind_init_blocked(struct unwind_frame_info *info,
1143 struct task_struct *tsk)
1144{
1145 info->task = tsk;
Jan Beulichadf14232006-09-26 10:52:41 +02001146 info->call_frame = 0;
Jan Beulich4552d5d2006-06-26 13:57:28 +02001147 arch_unw_init_blocked(info);
1148
1149 return 0;
1150}
1151EXPORT_SYMBOL(unwind_init_blocked);
1152
1153/*
1154 * Prepare to unwind the currently running thread.
1155 */
1156int unwind_init_running(struct unwind_frame_info *info,
Jan Beulichc33bd9a2006-06-26 13:57:47 +02001157 asmlinkage int (*callback)(struct unwind_frame_info *,
1158 void *arg),
Jan Beulich4552d5d2006-06-26 13:57:28 +02001159 void *arg)
1160{
1161 info->task = current;
Jan Beulichadf14232006-09-26 10:52:41 +02001162 info->call_frame = 0;
Jan Beulich4552d5d2006-06-26 13:57:28 +02001163
Jan Beulichc33bd9a2006-06-26 13:57:47 +02001164 return arch_unwind_init_running(info, callback, arg);
Jan Beulich4552d5d2006-06-26 13:57:28 +02001165}
1166EXPORT_SYMBOL(unwind_init_running);
1167
1168/*
1169 * Unwind until the return pointer is in user-land (or until an error
1170 * occurs). Returns 0 if successful, negative number in case of
1171 * error.
1172 */
1173int unwind_to_user(struct unwind_frame_info *info)
1174{
1175 while (!arch_unw_user_mode(info)) {
1176 int err = unwind(info);
1177
1178 if (err < 0)
1179 return err;
1180 }
1181
1182 return 0;
1183}
1184EXPORT_SYMBOL(unwind_to_user);