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