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