GNU Linux-libre 4.4.288-gnu1
[releases.git] / arch / arc / kernel / unwind.c
1 /*
2  * Copyright (C) 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
3  * Copyright (C) 2002-2006 Novell, Inc.
4  *      Jan Beulich <jbeulich@novell.com>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * A simple API for unwinding kernel stacks.  This is used for
11  * debugging and error reporting purposes.  The kernel doesn't need
12  * full-blown stack unwinding with all the bells and whistles, so there
13  * is not much point in implementing the full Dwarf2 unwind API.
14  */
15
16 #include <linux/sched.h>
17 #include <linux/module.h>
18 #include <linux/bootmem.h>
19 #include <linux/sort.h>
20 #include <linux/slab.h>
21 #include <linux/stop_machine.h>
22 #include <linux/uaccess.h>
23 #include <linux/ptrace.h>
24 #include <asm/sections.h>
25 #include <asm/unaligned.h>
26 #include <asm/unwind.h>
27
28 extern char __start_unwind[], __end_unwind[];
29 /* extern const u8 __start_unwind_hdr[], __end_unwind_hdr[];*/
30
31 /* #define UNWIND_DEBUG */
32
33 #ifdef UNWIND_DEBUG
34 int dbg_unw;
35 #define unw_debug(fmt, ...)                     \
36 do {                                            \
37         if (dbg_unw)                            \
38                 pr_info(fmt, ##__VA_ARGS__);    \
39 } while (0);
40 #else
41 #define unw_debug(fmt, ...)
42 #endif
43
44 #define MAX_STACK_DEPTH 8
45
46 #define EXTRA_INFO(f) { \
47                 BUILD_BUG_ON_ZERO(offsetof(struct unwind_frame_info, f) \
48                                 % FIELD_SIZEOF(struct unwind_frame_info, f)) \
49                                 + offsetof(struct unwind_frame_info, f) \
50                                 / FIELD_SIZEOF(struct unwind_frame_info, f), \
51                                 FIELD_SIZEOF(struct unwind_frame_info, f) \
52         }
53 #define PTREGS_INFO(f) EXTRA_INFO(regs.f)
54
55 static const struct {
56         unsigned offs:BITS_PER_LONG / 2;
57         unsigned width:BITS_PER_LONG / 2;
58 } reg_info[] = {
59 UNW_REGISTER_INFO};
60
61 #undef PTREGS_INFO
62 #undef EXTRA_INFO
63
64 #ifndef REG_INVALID
65 #define REG_INVALID(r) (reg_info[r].width == 0)
66 #endif
67
68 #define DW_CFA_nop                          0x00
69 #define DW_CFA_set_loc                      0x01
70 #define DW_CFA_advance_loc1                 0x02
71 #define DW_CFA_advance_loc2                 0x03
72 #define DW_CFA_advance_loc4                 0x04
73 #define DW_CFA_offset_extended              0x05
74 #define DW_CFA_restore_extended             0x06
75 #define DW_CFA_undefined                    0x07
76 #define DW_CFA_same_value                   0x08
77 #define DW_CFA_register                     0x09
78 #define DW_CFA_remember_state               0x0a
79 #define DW_CFA_restore_state                0x0b
80 #define DW_CFA_def_cfa                      0x0c
81 #define DW_CFA_def_cfa_register             0x0d
82 #define DW_CFA_def_cfa_offset               0x0e
83 #define DW_CFA_def_cfa_expression           0x0f
84 #define DW_CFA_expression                   0x10
85 #define DW_CFA_offset_extended_sf           0x11
86 #define DW_CFA_def_cfa_sf                   0x12
87 #define DW_CFA_def_cfa_offset_sf            0x13
88 #define DW_CFA_val_offset                   0x14
89 #define DW_CFA_val_offset_sf                0x15
90 #define DW_CFA_val_expression               0x16
91 #define DW_CFA_lo_user                      0x1c
92 #define DW_CFA_GNU_window_save              0x2d
93 #define DW_CFA_GNU_args_size                0x2e
94 #define DW_CFA_GNU_negative_offset_extended 0x2f
95 #define DW_CFA_hi_user                      0x3f
96
97 #define DW_EH_PE_FORM     0x07
98 #define DW_EH_PE_native   0x00
99 #define DW_EH_PE_leb128   0x01
100 #define DW_EH_PE_data2    0x02
101 #define DW_EH_PE_data4    0x03
102 #define DW_EH_PE_data8    0x04
103 #define DW_EH_PE_signed   0x08
104 #define DW_EH_PE_ADJUST   0x70
105 #define DW_EH_PE_abs      0x00
106 #define DW_EH_PE_pcrel    0x10
107 #define DW_EH_PE_textrel  0x20
108 #define DW_EH_PE_datarel  0x30
109 #define DW_EH_PE_funcrel  0x40
110 #define DW_EH_PE_aligned  0x50
111 #define DW_EH_PE_indirect 0x80
112 #define DW_EH_PE_omit     0xff
113
114 typedef unsigned long uleb128_t;
115 typedef signed long sleb128_t;
116
117 static struct unwind_table {
118         struct {
119                 unsigned long pc;
120                 unsigned long range;
121         } core, init;
122         const void *address;
123         unsigned long size;
124         const unsigned char *header;
125         unsigned long hdrsz;
126         struct unwind_table *link;
127         const char *name;
128 } root_table;
129
130 struct unwind_item {
131         enum item_location {
132                 Nowhere,
133                 Memory,
134                 Register,
135                 Value
136         } where;
137         uleb128_t value;
138 };
139
140 struct unwind_state {
141         uleb128_t loc, org;
142         const u8 *cieStart, *cieEnd;
143         uleb128_t codeAlign;
144         sleb128_t dataAlign;
145         struct cfa {
146                 uleb128_t reg, offs;
147         } cfa;
148         struct unwind_item regs[ARRAY_SIZE(reg_info)];
149         unsigned stackDepth:8;
150         unsigned version:8;
151         const u8 *label;
152         const u8 *stack[MAX_STACK_DEPTH];
153 };
154
155 static const struct cfa badCFA = { ARRAY_SIZE(reg_info), 1 };
156
157 static struct unwind_table *find_table(unsigned long pc)
158 {
159         struct unwind_table *table;
160
161         for (table = &root_table; table; table = table->link)
162                 if ((pc >= table->core.pc
163                      && pc < table->core.pc + table->core.range)
164                     || (pc >= table->init.pc
165                         && pc < table->init.pc + table->init.range))
166                         break;
167
168         return table;
169 }
170
171 static unsigned long read_pointer(const u8 **pLoc,
172                                   const void *end, signed ptrType);
173 static void init_unwind_hdr(struct unwind_table *table,
174                             void *(*alloc) (unsigned long));
175
176 /*
177  * wrappers for header alloc (vs. calling one vs. other at call site)
178  * to elide section mismatches warnings
179  */
180 static void *__init unw_hdr_alloc_early(unsigned long sz)
181 {
182         return __alloc_bootmem_nopanic(sz, sizeof(unsigned int),
183                                        MAX_DMA_ADDRESS);
184 }
185
186 static void init_unwind_table(struct unwind_table *table, const char *name,
187                               const void *core_start, unsigned long core_size,
188                               const void *init_start, unsigned long init_size,
189                               const void *table_start, unsigned long table_size,
190                               const u8 *header_start, unsigned long header_size)
191 {
192         const u8 *ptr = header_start + 4;
193         const u8 *end = header_start + header_size;
194
195         table->core.pc = (unsigned long)core_start;
196         table->core.range = core_size;
197         table->init.pc = (unsigned long)init_start;
198         table->init.range = init_size;
199         table->address = table_start;
200         table->size = table_size;
201
202         /* See if the linker provided table looks valid. */
203         if (header_size <= 4
204             || header_start[0] != 1
205             || (void *)read_pointer(&ptr, end, header_start[1]) != table_start
206             || header_start[2] == DW_EH_PE_omit
207             || read_pointer(&ptr, end, header_start[2]) <= 0
208             || header_start[3] == DW_EH_PE_omit)
209                 header_start = NULL;
210
211         table->hdrsz = header_size;
212         smp_wmb();
213         table->header = header_start;
214         table->link = NULL;
215         table->name = name;
216 }
217
218 void __init arc_unwind_init(void)
219 {
220         init_unwind_table(&root_table, "kernel", _text, _end - _text, NULL, 0,
221                           __start_unwind, __end_unwind - __start_unwind,
222                           NULL, 0);
223           /*__start_unwind_hdr, __end_unwind_hdr - __start_unwind_hdr);*/
224
225         init_unwind_hdr(&root_table, unw_hdr_alloc_early);
226 }
227
228 static const u32 bad_cie, not_fde;
229 static const u32 *cie_for_fde(const u32 *fde, const struct unwind_table *);
230 static signed fde_pointer_type(const u32 *cie);
231
232 struct eh_frame_hdr_table_entry {
233         unsigned long start, fde;
234 };
235
236 static int cmp_eh_frame_hdr_table_entries(const void *p1, const void *p2)
237 {
238         const struct eh_frame_hdr_table_entry *e1 = p1;
239         const struct eh_frame_hdr_table_entry *e2 = p2;
240
241         return (e1->start > e2->start) - (e1->start < e2->start);
242 }
243
244 static void swap_eh_frame_hdr_table_entries(void *p1, void *p2, int size)
245 {
246         struct eh_frame_hdr_table_entry *e1 = p1;
247         struct eh_frame_hdr_table_entry *e2 = p2;
248         unsigned long v;
249
250         v = e1->start;
251         e1->start = e2->start;
252         e2->start = v;
253         v = e1->fde;
254         e1->fde = e2->fde;
255         e2->fde = v;
256 }
257
258 static void init_unwind_hdr(struct unwind_table *table,
259                             void *(*alloc) (unsigned long))
260 {
261         const u8 *ptr;
262         unsigned long tableSize = table->size, hdrSize;
263         unsigned n;
264         const u32 *fde;
265         struct {
266                 u8 version;
267                 u8 eh_frame_ptr_enc;
268                 u8 fde_count_enc;
269                 u8 table_enc;
270                 unsigned long eh_frame_ptr;
271                 unsigned int fde_count;
272                 struct eh_frame_hdr_table_entry table[];
273         } __attribute__ ((__packed__)) *header;
274
275         if (table->header)
276                 return;
277
278         if (table->hdrsz)
279                 pr_warn(".eh_frame_hdr for '%s' present but unusable\n",
280                         table->name);
281
282         if (tableSize & (sizeof(*fde) - 1))
283                 return;
284
285         for (fde = table->address, n = 0;
286              tableSize > sizeof(*fde) && tableSize - sizeof(*fde) >= *fde;
287              tableSize -= sizeof(*fde) + *fde, fde += 1 + *fde / sizeof(*fde)) {
288                 const u32 *cie = cie_for_fde(fde, table);
289                 signed ptrType;
290
291                 if (cie == &not_fde)
292                         continue;
293                 if (cie == NULL || cie == &bad_cie)
294                         goto ret_err;
295                 ptrType = fde_pointer_type(cie);
296                 if (ptrType < 0)
297                         goto ret_err;
298
299                 ptr = (const u8 *)(fde + 2);
300                 if (!read_pointer(&ptr, (const u8 *)(fde + 1) + *fde,
301                                                                 ptrType)) {
302                         /* FIXME_Rajesh We have 4 instances of null addresses
303                          * instead of the initial loc addr
304                          * return;
305                          */
306                         WARN(1, "unwinder: FDE->initial_location NULL %p\n",
307                                 (const u8 *)(fde + 1) + *fde);
308                 }
309                 ++n;
310         }
311
312         if (tableSize || !n)
313                 goto ret_err;
314
315         hdrSize = 4 + sizeof(unsigned long) + sizeof(unsigned int)
316             + 2 * n * sizeof(unsigned long);
317
318         header = alloc(hdrSize);
319         if (!header)
320                 goto ret_err;
321
322         header->version = 1;
323         header->eh_frame_ptr_enc = DW_EH_PE_abs | DW_EH_PE_native;
324         header->fde_count_enc = DW_EH_PE_abs | DW_EH_PE_data4;
325         header->table_enc = DW_EH_PE_abs | DW_EH_PE_native;
326         put_unaligned((unsigned long)table->address, &header->eh_frame_ptr);
327         BUILD_BUG_ON(offsetof(typeof(*header), fde_count)
328                      % __alignof(typeof(header->fde_count)));
329         header->fde_count = n;
330
331         BUILD_BUG_ON(offsetof(typeof(*header), table)
332                      % __alignof(typeof(*header->table)));
333         for (fde = table->address, tableSize = table->size, n = 0;
334              tableSize;
335              tableSize -= sizeof(*fde) + *fde, fde += 1 + *fde / sizeof(*fde)) {
336                 /* const u32 *cie = fde + 1 - fde[1] / sizeof(*fde); */
337                 const u32 *cie = (const u32 *)(fde[1]);
338
339                 if (fde[1] == 0xffffffff)
340                         continue;       /* this is a CIE */
341                 ptr = (const u8 *)(fde + 2);
342                 header->table[n].start = read_pointer(&ptr,
343                                                       (const u8 *)(fde + 1) +
344                                                       *fde,
345                                                       fde_pointer_type(cie));
346                 header->table[n].fde = (unsigned long)fde;
347                 ++n;
348         }
349         WARN_ON(n != header->fde_count);
350
351         sort(header->table,
352              n,
353              sizeof(*header->table),
354              cmp_eh_frame_hdr_table_entries, swap_eh_frame_hdr_table_entries);
355
356         table->hdrsz = hdrSize;
357         smp_wmb();
358         table->header = (const void *)header;
359         return;
360
361 ret_err:
362         panic("Attention !!! Dwarf FDE parsing errors\n");;
363 }
364
365 #ifdef CONFIG_MODULES
366 static void *unw_hdr_alloc(unsigned long sz)
367 {
368         return kmalloc(sz, GFP_KERNEL);
369 }
370
371 static struct unwind_table *last_table;
372
373 /* Must be called with module_mutex held. */
374 void *unwind_add_table(struct module *module, const void *table_start,
375                        unsigned long table_size)
376 {
377         struct unwind_table *table;
378
379         if (table_size <= 0)
380                 return NULL;
381
382         table = kmalloc(sizeof(*table), GFP_KERNEL);
383         if (!table)
384                 return NULL;
385
386         init_unwind_table(table, module->name,
387                           module->module_core, module->core_size,
388                           module->module_init, module->init_size,
389                           table_start, table_size,
390                           NULL, 0);
391
392         init_unwind_hdr(table, unw_hdr_alloc);
393
394 #ifdef UNWIND_DEBUG
395         unw_debug("Table added for [%s] %lx %lx\n",
396                 module->name, table->core.pc, table->core.range);
397 #endif
398         if (last_table)
399                 last_table->link = table;
400         else
401                 root_table.link = table;
402         last_table = table;
403
404         return table;
405 }
406
407 struct unlink_table_info {
408         struct unwind_table *table;
409         int init_only;
410 };
411
412 static int unlink_table(void *arg)
413 {
414         struct unlink_table_info *info = arg;
415         struct unwind_table *table = info->table, *prev;
416
417         for (prev = &root_table; prev->link && prev->link != table;
418              prev = prev->link)
419                 ;
420
421         if (prev->link) {
422                 if (info->init_only) {
423                         table->init.pc = 0;
424                         table->init.range = 0;
425                         info->table = NULL;
426                 } else {
427                         prev->link = table->link;
428                         if (!prev->link)
429                                 last_table = prev;
430                 }
431         } else
432                 info->table = NULL;
433
434         return 0;
435 }
436
437 /* Must be called with module_mutex held. */
438 void unwind_remove_table(void *handle, int init_only)
439 {
440         struct unwind_table *table = handle;
441         struct unlink_table_info info;
442
443         if (!table || table == &root_table)
444                 return;
445
446         if (init_only && table == last_table) {
447                 table->init.pc = 0;
448                 table->init.range = 0;
449                 return;
450         }
451
452         info.table = table;
453         info.init_only = init_only;
454
455         unlink_table(&info); /* XXX: SMP */
456         kfree(table->header);
457         kfree(table);
458 }
459
460 #endif /* CONFIG_MODULES */
461
462 static uleb128_t get_uleb128(const u8 **pcur, const u8 *end)
463 {
464         const u8 *cur = *pcur;
465         uleb128_t value;
466         unsigned shift;
467
468         for (shift = 0, value = 0; cur < end; shift += 7) {
469                 if (shift + 7 > 8 * sizeof(value)
470                     && (*cur & 0x7fU) >= (1U << (8 * sizeof(value) - shift))) {
471                         cur = end + 1;
472                         break;
473                 }
474                 value |= (uleb128_t) (*cur & 0x7f) << shift;
475                 if (!(*cur++ & 0x80))
476                         break;
477         }
478         *pcur = cur;
479
480         return value;
481 }
482
483 static sleb128_t get_sleb128(const u8 **pcur, const u8 *end)
484 {
485         const u8 *cur = *pcur;
486         sleb128_t value;
487         unsigned shift;
488
489         for (shift = 0, value = 0; cur < end; shift += 7) {
490                 if (shift + 7 > 8 * sizeof(value)
491                     && (*cur & 0x7fU) >= (1U << (8 * sizeof(value) - shift))) {
492                         cur = end + 1;
493                         break;
494                 }
495                 value |= (sleb128_t) (*cur & 0x7f) << shift;
496                 if (!(*cur & 0x80)) {
497                         value |= -(*cur++ & 0x40) << shift;
498                         break;
499                 }
500         }
501         *pcur = cur;
502
503         return value;
504 }
505
506 static const u32 *cie_for_fde(const u32 *fde, const struct unwind_table *table)
507 {
508         const u32 *cie;
509
510         if (!*fde || (*fde & (sizeof(*fde) - 1)))
511                 return &bad_cie;
512
513         if (fde[1] == 0xffffffff)
514                 return &not_fde;        /* this is a CIE */
515
516         if ((fde[1] & (sizeof(*fde) - 1)))
517 /* || fde[1] > (unsigned long)(fde + 1) - (unsigned long)table->address) */
518                 return NULL;    /* this is not a valid FDE */
519
520         /* cie = fde + 1 - fde[1] / sizeof(*fde); */
521         cie = (u32 *) fde[1];
522
523         if (*cie <= sizeof(*cie) + 4 || *cie >= fde[1] - sizeof(*fde)
524             || (*cie & (sizeof(*cie) - 1))
525             || (cie[1] != 0xffffffff))
526                 return NULL;    /* this is not a (valid) CIE */
527         return cie;
528 }
529
530 static unsigned long read_pointer(const u8 **pLoc, const void *end,
531                                   signed ptrType)
532 {
533         unsigned long value = 0;
534         union {
535                 const u8 *p8;
536                 const u16 *p16u;
537                 const s16 *p16s;
538                 const u32 *p32u;
539                 const s32 *p32s;
540                 const unsigned long *pul;
541         } ptr;
542
543         if (ptrType < 0 || ptrType == DW_EH_PE_omit)
544                 return 0;
545         ptr.p8 = *pLoc;
546         switch (ptrType & DW_EH_PE_FORM) {
547         case DW_EH_PE_data2:
548                 if (end < (const void *)(ptr.p16u + 1))
549                         return 0;
550                 if (ptrType & DW_EH_PE_signed)
551                         value = get_unaligned((u16 *) ptr.p16s++);
552                 else
553                         value = get_unaligned((u16 *) ptr.p16u++);
554                 break;
555         case DW_EH_PE_data4:
556 #ifdef CONFIG_64BIT
557                 if (end < (const void *)(ptr.p32u + 1))
558                         return 0;
559                 if (ptrType & DW_EH_PE_signed)
560                         value = get_unaligned(ptr.p32s++);
561                 else
562                         value = get_unaligned(ptr.p32u++);
563                 break;
564         case DW_EH_PE_data8:
565                 BUILD_BUG_ON(sizeof(u64) != sizeof(value));
566 #else
567                 BUILD_BUG_ON(sizeof(u32) != sizeof(value));
568 #endif
569         case DW_EH_PE_native:
570                 if (end < (const void *)(ptr.pul + 1))
571                         return 0;
572                 value = get_unaligned((unsigned long *)ptr.pul++);
573                 break;
574         case DW_EH_PE_leb128:
575                 BUILD_BUG_ON(sizeof(uleb128_t) > sizeof(value));
576                 value = ptrType & DW_EH_PE_signed ? get_sleb128(&ptr.p8, end)
577                     : get_uleb128(&ptr.p8, end);
578                 if ((const void *)ptr.p8 > end)
579                         return 0;
580                 break;
581         default:
582                 return 0;
583         }
584         switch (ptrType & DW_EH_PE_ADJUST) {
585         case DW_EH_PE_abs:
586                 break;
587         case DW_EH_PE_pcrel:
588                 value += (unsigned long)*pLoc;
589                 break;
590         default:
591                 return 0;
592         }
593         if ((ptrType & DW_EH_PE_indirect)
594             && __get_user(value, (unsigned long __user *)value))
595                 return 0;
596         *pLoc = ptr.p8;
597
598         return value;
599 }
600
601 static signed fde_pointer_type(const u32 *cie)
602 {
603         const u8 *ptr = (const u8 *)(cie + 2);
604         unsigned version = *ptr;
605
606         if (*++ptr) {
607                 const char *aug;
608                 const u8 *end = (const u8 *)(cie + 1) + *cie;
609                 uleb128_t len;
610
611                 /* check if augmentation size is first (and thus present) */
612                 if (*ptr != 'z')
613                         return -1;
614
615                 /* check if augmentation string is nul-terminated */
616                 aug = (const void *)ptr;
617                 ptr = memchr(aug, 0, end - ptr);
618                 if (ptr == NULL)
619                         return -1;
620
621                 ++ptr;          /* skip terminator */
622                 get_uleb128(&ptr, end); /* skip code alignment */
623                 get_sleb128(&ptr, end); /* skip data alignment */
624                 /* skip return address column */
625                 version <= 1 ? (void) ++ptr : (void)get_uleb128(&ptr, end);
626                 len = get_uleb128(&ptr, end);   /* augmentation length */
627
628                 if (ptr + len < ptr || ptr + len > end)
629                         return -1;
630
631                 end = ptr + len;
632                 while (*++aug) {
633                         if (ptr >= end)
634                                 return -1;
635                         switch (*aug) {
636                         case 'L':
637                                 ++ptr;
638                                 break;
639                         case 'P':{
640                                         signed ptrType = *ptr++;
641
642                                         if (!read_pointer(&ptr, end, ptrType)
643                                             || ptr > end)
644                                                 return -1;
645                                 }
646                                 break;
647                         case 'R':
648                                 return *ptr;
649                         default:
650                                 return -1;
651                         }
652                 }
653         }
654         return DW_EH_PE_native | DW_EH_PE_abs;
655 }
656
657 static int advance_loc(unsigned long delta, struct unwind_state *state)
658 {
659         state->loc += delta * state->codeAlign;
660
661         /* FIXME_Rajesh: Probably we are defining for the initial range as well;
662            return delta > 0;
663          */
664         unw_debug("delta %3lu => loc 0x%lx: ", delta, state->loc);
665         return 1;
666 }
667
668 static void set_rule(uleb128_t reg, enum item_location where, uleb128_t value,
669                      struct unwind_state *state)
670 {
671         if (reg < ARRAY_SIZE(state->regs)) {
672                 state->regs[reg].where = where;
673                 state->regs[reg].value = value;
674
675 #ifdef UNWIND_DEBUG
676                 unw_debug("r%lu: ", reg);
677                 switch (where) {
678                 case Nowhere:
679                         unw_debug("s ");
680                         break;
681                 case Memory:
682                         unw_debug("c(%lu) ", value);
683                         break;
684                 case Register:
685                         unw_debug("r(%lu) ", value);
686                         break;
687                 case Value:
688                         unw_debug("v(%lu) ", value);
689                         break;
690                 default:
691                         break;
692                 }
693 #endif
694         }
695 }
696
697 static int processCFI(const u8 *start, const u8 *end, unsigned long targetLoc,
698                       signed ptrType, struct unwind_state *state)
699 {
700         union {
701                 const u8 *p8;
702                 const u16 *p16;
703                 const u32 *p32;
704         } ptr;
705         int result = 1;
706         u8 opcode;
707
708         if (start != state->cieStart) {
709                 state->loc = state->org;
710                 result =
711                     processCFI(state->cieStart, state->cieEnd, 0, ptrType,
712                                state);
713                 if (targetLoc == 0 && state->label == NULL)
714                         return result;
715         }
716         for (ptr.p8 = start; result && ptr.p8 < end;) {
717                 switch (*ptr.p8 >> 6) {
718                         uleb128_t value;
719
720                 case 0:
721                         opcode = *ptr.p8++;
722
723                         switch (opcode) {
724                         case DW_CFA_nop:
725                                 unw_debug("cfa nop ");
726                                 break;
727                         case DW_CFA_set_loc:
728                                 state->loc = read_pointer(&ptr.p8, end,
729                                                           ptrType);
730                                 if (state->loc == 0)
731                                         result = 0;
732                                 unw_debug("cfa_set_loc: 0x%lx ", state->loc);
733                                 break;
734                         case DW_CFA_advance_loc1:
735                                 unw_debug("\ncfa advance loc1:");
736                                 result = ptr.p8 < end
737                                     && advance_loc(*ptr.p8++, state);
738                                 break;
739                         case DW_CFA_advance_loc2:
740                                 value = *ptr.p8++;
741                                 value += *ptr.p8++ << 8;
742                                 unw_debug("\ncfa advance loc2:");
743                                 result = ptr.p8 <= end + 2
744                                     /* && advance_loc(*ptr.p16++, state); */
745                                     && advance_loc(value, state);
746                                 break;
747                         case DW_CFA_advance_loc4:
748                                 unw_debug("\ncfa advance loc4:");
749                                 result = ptr.p8 <= end + 4
750                                     && advance_loc(*ptr.p32++, state);
751                                 break;
752                         case DW_CFA_offset_extended:
753                                 value = get_uleb128(&ptr.p8, end);
754                                 unw_debug("cfa_offset_extended: ");
755                                 set_rule(value, Memory,
756                                          get_uleb128(&ptr.p8, end), state);
757                                 break;
758                         case DW_CFA_val_offset:
759                                 value = get_uleb128(&ptr.p8, end);
760                                 set_rule(value, Value,
761                                          get_uleb128(&ptr.p8, end), state);
762                                 break;
763                         case DW_CFA_offset_extended_sf:
764                                 value = get_uleb128(&ptr.p8, end);
765                                 set_rule(value, Memory,
766                                          get_sleb128(&ptr.p8, end), state);
767                                 break;
768                         case DW_CFA_val_offset_sf:
769                                 value = get_uleb128(&ptr.p8, end);
770                                 set_rule(value, Value,
771                                          get_sleb128(&ptr.p8, end), state);
772                                 break;
773                         case DW_CFA_restore_extended:
774                                 unw_debug("cfa_restore_extended: ");
775                         case DW_CFA_undefined:
776                                 unw_debug("cfa_undefined: ");
777                         case DW_CFA_same_value:
778                                 unw_debug("cfa_same_value: ");
779                                 set_rule(get_uleb128(&ptr.p8, end), Nowhere, 0,
780                                          state);
781                                 break;
782                         case DW_CFA_register:
783                                 unw_debug("cfa_register: ");
784                                 value = get_uleb128(&ptr.p8, end);
785                                 set_rule(value,
786                                          Register,
787                                          get_uleb128(&ptr.p8, end), state);
788                                 break;
789                         case DW_CFA_remember_state:
790                                 unw_debug("cfa_remember_state: ");
791                                 if (ptr.p8 == state->label) {
792                                         state->label = NULL;
793                                         return 1;
794                                 }
795                                 if (state->stackDepth >= MAX_STACK_DEPTH)
796                                         return 0;
797                                 state->stack[state->stackDepth++] = ptr.p8;
798                                 break;
799                         case DW_CFA_restore_state:
800                                 unw_debug("cfa_restore_state: ");
801                                 if (state->stackDepth) {
802                                         const uleb128_t loc = state->loc;
803                                         const u8 *label = state->label;
804
805                                         state->label =
806                                             state->stack[state->stackDepth - 1];
807                                         memcpy(&state->cfa, &badCFA,
808                                                sizeof(state->cfa));
809                                         memset(state->regs, 0,
810                                                sizeof(state->regs));
811                                         state->stackDepth = 0;
812                                         result =
813                                             processCFI(start, end, 0, ptrType,
814                                                        state);
815                                         state->loc = loc;
816                                         state->label = label;
817                                 } else
818                                         return 0;
819                                 break;
820                         case DW_CFA_def_cfa:
821                                 state->cfa.reg = get_uleb128(&ptr.p8, end);
822                                 unw_debug("cfa_def_cfa: r%lu ", state->cfa.reg);
823                                 /*nobreak*/
824                         case DW_CFA_def_cfa_offset:
825                                 state->cfa.offs = get_uleb128(&ptr.p8, end);
826                                 unw_debug("cfa_def_cfa_offset: 0x%lx ",
827                                           state->cfa.offs);
828                                 break;
829                         case DW_CFA_def_cfa_sf:
830                                 state->cfa.reg = get_uleb128(&ptr.p8, end);
831                                 /*nobreak */
832                         case DW_CFA_def_cfa_offset_sf:
833                                 state->cfa.offs = get_sleb128(&ptr.p8, end)
834                                     * state->dataAlign;
835                                 break;
836                         case DW_CFA_def_cfa_register:
837                                 unw_debug("cfa_def_cfa_regsiter: ");
838                                 state->cfa.reg = get_uleb128(&ptr.p8, end);
839                                 break;
840                                 /*todo case DW_CFA_def_cfa_expression: */
841                                 /*todo case DW_CFA_expression: */
842                                 /*todo case DW_CFA_val_expression: */
843                         case DW_CFA_GNU_args_size:
844                                 get_uleb128(&ptr.p8, end);
845                                 break;
846                         case DW_CFA_GNU_negative_offset_extended:
847                                 value = get_uleb128(&ptr.p8, end);
848                                 set_rule(value,
849                                          Memory,
850                                          (uleb128_t) 0 - get_uleb128(&ptr.p8,
851                                                                      end),
852                                          state);
853                                 break;
854                         case DW_CFA_GNU_window_save:
855                         default:
856                                 unw_debug("UNKNOWN OPCODE 0x%x\n", opcode);
857                                 result = 0;
858                                 break;
859                         }
860                         break;
861                 case 1:
862                         unw_debug("\ncfa_adv_loc: ");
863                         result = advance_loc(*ptr.p8++ & 0x3f, state);
864                         break;
865                 case 2:
866                         unw_debug("cfa_offset: ");
867                         value = *ptr.p8++ & 0x3f;
868                         set_rule(value, Memory, get_uleb128(&ptr.p8, end),
869                                  state);
870                         break;
871                 case 3:
872                         unw_debug("cfa_restore: ");
873                         set_rule(*ptr.p8++ & 0x3f, Nowhere, 0, state);
874                         break;
875                 }
876
877                 if (ptr.p8 > end)
878                         result = 0;
879                 if (result && targetLoc != 0 && targetLoc < state->loc)
880                         return 1;
881         }
882
883         return result && ptr.p8 == end && (targetLoc == 0 || (
884                 /*todo While in theory this should apply, gcc in practice omits
885                   everything past the function prolog, and hence the location
886                   never reaches the end of the function.
887                 targetLoc < state->loc && */  state->label == NULL));
888 }
889
890 /* Unwind to previous to frame.  Returns 0 if successful, negative
891  * number in case of an error. */
892 int arc_unwind(struct unwind_frame_info *frame)
893 {
894 #define FRAME_REG(r, t) (((t *)frame)[reg_info[r].offs])
895         const u32 *fde = NULL, *cie = NULL;
896         const u8 *ptr = NULL, *end = NULL;
897         unsigned long pc = UNW_PC(frame) - frame->call_frame;
898         unsigned long startLoc = 0, endLoc = 0, cfa;
899         unsigned i;
900         signed ptrType = -1;
901         uleb128_t retAddrReg = 0;
902         const struct unwind_table *table;
903         struct unwind_state state;
904         unsigned long *fptr;
905         unsigned long addr;
906
907         unw_debug("\n\nUNWIND FRAME:\n");
908         unw_debug("PC: 0x%lx BLINK: 0x%lx, SP: 0x%lx, FP: 0x%x\n",
909                   UNW_PC(frame), UNW_BLINK(frame), UNW_SP(frame),
910                   UNW_FP(frame));
911
912         if (UNW_PC(frame) == 0)
913                 return -EINVAL;
914
915 #ifdef UNWIND_DEBUG
916         {
917                 unsigned long *sptr = (unsigned long *)UNW_SP(frame);
918                 unw_debug("\nStack Dump:\n");
919                 for (i = 0; i < 20; i++, sptr++)
920                         unw_debug("0x%p:  0x%lx\n", sptr, *sptr);
921                 unw_debug("\n");
922         }
923 #endif
924
925         table = find_table(pc);
926         if (table != NULL
927             && !(table->size & (sizeof(*fde) - 1))) {
928                 const u8 *hdr = table->header;
929                 unsigned long tableSize;
930
931                 smp_rmb();
932                 if (hdr && hdr[0] == 1) {
933                         switch (hdr[3] & DW_EH_PE_FORM) {
934                         case DW_EH_PE_native:
935                                 tableSize = sizeof(unsigned long);
936                                 break;
937                         case DW_EH_PE_data2:
938                                 tableSize = 2;
939                                 break;
940                         case DW_EH_PE_data4:
941                                 tableSize = 4;
942                                 break;
943                         case DW_EH_PE_data8:
944                                 tableSize = 8;
945                                 break;
946                         default:
947                                 tableSize = 0;
948                                 break;
949                         }
950                         ptr = hdr + 4;
951                         end = hdr + table->hdrsz;
952                         if (tableSize && read_pointer(&ptr, end, hdr[1])
953                             == (unsigned long)table->address
954                             && (i = read_pointer(&ptr, end, hdr[2])) > 0
955                             && i == (end - ptr) / (2 * tableSize)
956                             && !((end - ptr) % (2 * tableSize))) {
957                                 do {
958                                         const u8 *cur =
959                                             ptr + (i / 2) * (2 * tableSize);
960
961                                         startLoc = read_pointer(&cur,
962                                                                 cur + tableSize,
963                                                                 hdr[3]);
964                                         if (pc < startLoc)
965                                                 i /= 2;
966                                         else {
967                                                 ptr = cur - tableSize;
968                                                 i = (i + 1) / 2;
969                                         }
970                                 } while (startLoc && i > 1);
971                                 if (i == 1
972                                     && (startLoc = read_pointer(&ptr,
973                                                                 ptr + tableSize,
974                                                                 hdr[3])) != 0
975                                     && pc >= startLoc)
976                                         fde = (void *)read_pointer(&ptr,
977                                                                    ptr +
978                                                                    tableSize,
979                                                                    hdr[3]);
980                         }
981                 }
982
983                 if (fde != NULL) {
984                         cie = cie_for_fde(fde, table);
985                         ptr = (const u8 *)(fde + 2);
986                         if (cie != NULL
987                             && cie != &bad_cie
988                             && cie != &not_fde
989                             && (ptrType = fde_pointer_type(cie)) >= 0
990                             && read_pointer(&ptr,
991                                             (const u8 *)(fde + 1) + *fde,
992                                             ptrType) == startLoc) {
993                                 if (!(ptrType & DW_EH_PE_indirect))
994                                         ptrType &=
995                                             DW_EH_PE_FORM | DW_EH_PE_signed;
996                                 endLoc =
997                                     startLoc + read_pointer(&ptr,
998                                                             (const u8 *)(fde +
999                                                                          1) +
1000                                                             *fde, ptrType);
1001                                 if (pc >= endLoc) {
1002                                         fde = NULL;
1003                                         cie = NULL;
1004                                 }
1005                         } else {
1006                                 fde = NULL;
1007                                 cie = NULL;
1008                         }
1009                 }
1010         }
1011         if (cie != NULL) {
1012                 memset(&state, 0, sizeof(state));
1013                 state.cieEnd = ptr;     /* keep here temporarily */
1014                 ptr = (const u8 *)(cie + 2);
1015                 end = (const u8 *)(cie + 1) + *cie;
1016                 frame->call_frame = 1;
1017                 if (*++ptr) {
1018                         /* check if augmentation size is first (thus present) */
1019                         if (*ptr == 'z') {
1020                                 while (++ptr < end && *ptr) {
1021                                         switch (*ptr) {
1022                                         /* chk for ignorable or already handled
1023                                          * nul-terminated augmentation string */
1024                                         case 'L':
1025                                         case 'P':
1026                                         case 'R':
1027                                                 continue;
1028                                         case 'S':
1029                                                 frame->call_frame = 0;
1030                                                 continue;
1031                                         default:
1032                                                 break;
1033                                         }
1034                                         break;
1035                                 }
1036                         }
1037                         if (ptr >= end || *ptr)
1038                                 cie = NULL;
1039                 }
1040                 ++ptr;
1041         }
1042         if (cie != NULL) {
1043                 /* get code aligment factor */
1044                 state.codeAlign = get_uleb128(&ptr, end);
1045                 /* get data aligment factor */
1046                 state.dataAlign = get_sleb128(&ptr, end);
1047                 if (state.codeAlign == 0 || state.dataAlign == 0 || ptr >= end)
1048                         cie = NULL;
1049                 else {
1050                         retAddrReg =
1051                             state.version <= 1 ? *ptr++ : get_uleb128(&ptr,
1052                                                                       end);
1053                         unw_debug("CIE Frame Info:\n");
1054                         unw_debug("return Address register 0x%lx\n",
1055                                   retAddrReg);
1056                         unw_debug("data Align: %ld\n", state.dataAlign);
1057                         unw_debug("code Align: %lu\n", state.codeAlign);
1058                         /* skip augmentation */
1059                         if (((const char *)(cie + 2))[1] == 'z') {
1060                                 uleb128_t augSize = get_uleb128(&ptr, end);
1061
1062                                 ptr += augSize;
1063                         }
1064                         if (ptr > end || retAddrReg >= ARRAY_SIZE(reg_info)
1065                             || REG_INVALID(retAddrReg)
1066                             || reg_info[retAddrReg].width !=
1067                             sizeof(unsigned long))
1068                                 cie = NULL;
1069                 }
1070         }
1071         if (cie != NULL) {
1072                 state.cieStart = ptr;
1073                 ptr = state.cieEnd;
1074                 state.cieEnd = end;
1075                 end = (const u8 *)(fde + 1) + *fde;
1076                 /* skip augmentation */
1077                 if (((const char *)(cie + 2))[1] == 'z') {
1078                         uleb128_t augSize = get_uleb128(&ptr, end);
1079
1080                         if ((ptr += augSize) > end)
1081                                 fde = NULL;
1082                 }
1083         }
1084         if (cie == NULL || fde == NULL) {
1085 #ifdef CONFIG_FRAME_POINTER
1086                 unsigned long top, bottom;
1087
1088                 top = STACK_TOP_UNW(frame->task);
1089                 bottom = STACK_BOTTOM_UNW(frame->task);
1090 #if FRAME_RETADDR_OFFSET < 0
1091                 if (UNW_SP(frame) < top && UNW_FP(frame) <= UNW_SP(frame)
1092                     && bottom < UNW_FP(frame)
1093 #else
1094                 if (UNW_SP(frame) > top && UNW_FP(frame) >= UNW_SP(frame)
1095                     && bottom > UNW_FP(frame)
1096 #endif
1097                     && !((UNW_SP(frame) | UNW_FP(frame))
1098                          & (sizeof(unsigned long) - 1))) {
1099                         unsigned long link;
1100
1101                         if (!__get_user(link, (unsigned long *)
1102                                         (UNW_FP(frame) + FRAME_LINK_OFFSET))
1103 #if FRAME_RETADDR_OFFSET < 0
1104                             && link > bottom && link < UNW_FP(frame)
1105 #else
1106                             && link > UNW_FP(frame) && link < bottom
1107 #endif
1108                             && !(link & (sizeof(link) - 1))
1109                             && !__get_user(UNW_PC(frame),
1110                                            (unsigned long *)(UNW_FP(frame)
1111                                                 + FRAME_RETADDR_OFFSET)))
1112                         {
1113                                 UNW_SP(frame) =
1114                                     UNW_FP(frame) + FRAME_RETADDR_OFFSET
1115 #if FRAME_RETADDR_OFFSET < 0
1116                                     -
1117 #else
1118                                     +
1119 #endif
1120                                     sizeof(UNW_PC(frame));
1121                                 UNW_FP(frame) = link;
1122                                 return 0;
1123                         }
1124                 }
1125 #endif
1126                 return -ENXIO;
1127         }
1128         state.org = startLoc;
1129         memcpy(&state.cfa, &badCFA, sizeof(state.cfa));
1130
1131         unw_debug("\nProcess instructions\n");
1132
1133         /* process instructions
1134          * For ARC, we optimize by having blink(retAddrReg) with
1135          * the sameValue in the leaf function, so we should not check
1136          * state.regs[retAddrReg].where == Nowhere
1137          */
1138         if (!processCFI(ptr, end, pc, ptrType, &state)
1139             || state.loc > endLoc
1140 /*         || state.regs[retAddrReg].where == Nowhere */
1141             || state.cfa.reg >= ARRAY_SIZE(reg_info)
1142             || reg_info[state.cfa.reg].width != sizeof(unsigned long)
1143             || state.cfa.offs % sizeof(unsigned long))
1144                 return -EIO;
1145
1146 #ifdef UNWIND_DEBUG
1147         unw_debug("\n");
1148
1149         unw_debug("\nRegister State Based on the rules parsed from FDE:\n");
1150         for (i = 0; i < ARRAY_SIZE(state.regs); ++i) {
1151
1152                 if (REG_INVALID(i))
1153                         continue;
1154
1155                 switch (state.regs[i].where) {
1156                 case Nowhere:
1157                         break;
1158                 case Memory:
1159                         unw_debug(" r%d: c(%lu),", i, state.regs[i].value);
1160                         break;
1161                 case Register:
1162                         unw_debug(" r%d: r(%lu),", i, state.regs[i].value);
1163                         break;
1164                 case Value:
1165                         unw_debug(" r%d: v(%lu),", i, state.regs[i].value);
1166                         break;
1167                 }
1168         }
1169
1170         unw_debug("\n");
1171 #endif
1172
1173         /* update frame */
1174 #ifndef CONFIG_AS_CFI_SIGNAL_FRAME
1175         if (frame->call_frame
1176             && !UNW_DEFAULT_RA(state.regs[retAddrReg], state.dataAlign))
1177                 frame->call_frame = 0;
1178 #endif
1179         cfa = FRAME_REG(state.cfa.reg, unsigned long) + state.cfa.offs;
1180         startLoc = min_t(unsigned long, UNW_SP(frame), cfa);
1181         endLoc = max_t(unsigned long, UNW_SP(frame), cfa);
1182         if (STACK_LIMIT(startLoc) != STACK_LIMIT(endLoc)) {
1183                 startLoc = min(STACK_LIMIT(cfa), cfa);
1184                 endLoc = max(STACK_LIMIT(cfa), cfa);
1185         }
1186
1187         unw_debug("\nCFA reg: 0x%lx, offset: 0x%lx =>  0x%lx\n",
1188                   state.cfa.reg, state.cfa.offs, cfa);
1189
1190         for (i = 0; i < ARRAY_SIZE(state.regs); ++i) {
1191                 if (REG_INVALID(i)) {
1192                         if (state.regs[i].where == Nowhere)
1193                                 continue;
1194                         return -EIO;
1195                 }
1196                 switch (state.regs[i].where) {
1197                 default:
1198                         break;
1199                 case Register:
1200                         if (state.regs[i].value >= ARRAY_SIZE(reg_info)
1201                             || REG_INVALID(state.regs[i].value)
1202                             || reg_info[i].width >
1203                             reg_info[state.regs[i].value].width)
1204                                 return -EIO;
1205                         switch (reg_info[state.regs[i].value].width) {
1206                         case sizeof(u8):
1207                                 state.regs[i].value =
1208                                 FRAME_REG(state.regs[i].value, const u8);
1209                                 break;
1210                         case sizeof(u16):
1211                                 state.regs[i].value =
1212                                 FRAME_REG(state.regs[i].value, const u16);
1213                                 break;
1214                         case sizeof(u32):
1215                                 state.regs[i].value =
1216                                 FRAME_REG(state.regs[i].value, const u32);
1217                                 break;
1218 #ifdef CONFIG_64BIT
1219                         case sizeof(u64):
1220                                 state.regs[i].value =
1221                                 FRAME_REG(state.regs[i].value, const u64);
1222                                 break;
1223 #endif
1224                         default:
1225                                 return -EIO;
1226                         }
1227                         break;
1228                 }
1229         }
1230
1231         unw_debug("\nRegister state after evaluation with realtime Stack:\n");
1232         fptr = (unsigned long *)(&frame->regs);
1233         for (i = 0; i < ARRAY_SIZE(state.regs); ++i, fptr++) {
1234
1235                 if (REG_INVALID(i))
1236                         continue;
1237                 switch (state.regs[i].where) {
1238                 case Nowhere:
1239                         if (reg_info[i].width != sizeof(UNW_SP(frame))
1240                             || &FRAME_REG(i, __typeof__(UNW_SP(frame)))
1241                             != &UNW_SP(frame))
1242                                 continue;
1243                         UNW_SP(frame) = cfa;
1244                         break;
1245                 case Register:
1246                         switch (reg_info[i].width) {
1247                         case sizeof(u8):
1248                                 FRAME_REG(i, u8) = state.regs[i].value;
1249                                 break;
1250                         case sizeof(u16):
1251                                 FRAME_REG(i, u16) = state.regs[i].value;
1252                                 break;
1253                         case sizeof(u32):
1254                                 FRAME_REG(i, u32) = state.regs[i].value;
1255                                 break;
1256 #ifdef CONFIG_64BIT
1257                         case sizeof(u64):
1258                                 FRAME_REG(i, u64) = state.regs[i].value;
1259                                 break;
1260 #endif
1261                         default:
1262                                 return -EIO;
1263                         }
1264                         break;
1265                 case Value:
1266                         if (reg_info[i].width != sizeof(unsigned long))
1267                                 return -EIO;
1268                         FRAME_REG(i, unsigned long) = cfa + state.regs[i].value
1269                             * state.dataAlign;
1270                         break;
1271                 case Memory:
1272                         addr = cfa + state.regs[i].value * state.dataAlign;
1273
1274                         if ((state.regs[i].value * state.dataAlign)
1275                             % sizeof(unsigned long)
1276                             || addr < startLoc
1277                             || addr + sizeof(unsigned long) < addr
1278                             || addr + sizeof(unsigned long) > endLoc)
1279                                         return -EIO;
1280
1281                         switch (reg_info[i].width) {
1282                         case sizeof(u8):
1283                                 __get_user(FRAME_REG(i, u8),
1284                                            (u8 __user *)addr);
1285                                 break;
1286                         case sizeof(u16):
1287                                 __get_user(FRAME_REG(i, u16),
1288                                            (u16 __user *)addr);
1289                                 break;
1290                         case sizeof(u32):
1291                                 __get_user(FRAME_REG(i, u32),
1292                                            (u32 __user *)addr);
1293                                 break;
1294 #ifdef CONFIG_64BIT
1295                         case sizeof(u64):
1296                                 __get_user(FRAME_REG(i, u64),
1297                                            (u64 __user *)addr);
1298                                 break;
1299 #endif
1300                         default:
1301                                 return -EIO;
1302                         }
1303
1304                         break;
1305                 }
1306                 unw_debug("r%d: 0x%lx ", i, *fptr);
1307         }
1308
1309         return 0;
1310 #undef FRAME_REG
1311 }
1312 EXPORT_SYMBOL(arc_unwind);