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