Merge branch 'for-5.3/uclogic' into for-linus
[sfrench/cifs-2.6.git] / arch / arc / kernel / unwind.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (C) 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
4  * Copyright (C) 2002-2006 Novell, Inc.
5  *      Jan Beulich <jbeulich@novell.com>
6  *
7  * A simple API for unwinding kernel stacks.  This is used for
8  * debugging and error reporting purposes.  The kernel doesn't need
9  * full-blown stack unwinding with all the bells and whistles, so there
10  * is not much point in implementing the full Dwarf2 unwind API.
11  */
12
13 #include <linux/sched.h>
14 #include <linux/module.h>
15 #include <linux/memblock.h>
16 #include <linux/sort.h>
17 #include <linux/slab.h>
18 #include <linux/stop_machine.h>
19 #include <linux/uaccess.h>
20 #include <linux/ptrace.h>
21 #include <asm/sections.h>
22 #include <asm/unaligned.h>
23 #include <asm/unwind.h>
24
25 extern char __start_unwind[], __end_unwind[];
26 /* extern const u8 __start_unwind_hdr[], __end_unwind_hdr[];*/
27
28 /* #define UNWIND_DEBUG */
29
30 #ifdef UNWIND_DEBUG
31 int dbg_unw;
32 #define unw_debug(fmt, ...)                     \
33 do {                                            \
34         if (dbg_unw)                            \
35                 pr_info(fmt, ##__VA_ARGS__);    \
36 } while (0);
37 #else
38 #define unw_debug(fmt, ...)
39 #endif
40
41 #define MAX_STACK_DEPTH 8
42
43 #define EXTRA_INFO(f) { \
44                 BUILD_BUG_ON_ZERO(offsetof(struct unwind_frame_info, f) \
45                                 % FIELD_SIZEOF(struct unwind_frame_info, f)) \
46                                 + offsetof(struct unwind_frame_info, f) \
47                                 / FIELD_SIZEOF(struct unwind_frame_info, f), \
48                                 FIELD_SIZEOF(struct unwind_frame_info, f) \
49         }
50 #define PTREGS_INFO(f) EXTRA_INFO(regs.f)
51
52 static const struct {
53         unsigned offs:BITS_PER_LONG / 2;
54         unsigned width:BITS_PER_LONG / 2;
55 } reg_info[] = {
56 UNW_REGISTER_INFO};
57
58 #undef PTREGS_INFO
59 #undef EXTRA_INFO
60
61 #ifndef REG_INVALID
62 #define REG_INVALID(r) (reg_info[r].width == 0)
63 #endif
64
65 #define DW_CFA_nop                          0x00
66 #define DW_CFA_set_loc                      0x01
67 #define DW_CFA_advance_loc1                 0x02
68 #define DW_CFA_advance_loc2                 0x03
69 #define DW_CFA_advance_loc4                 0x04
70 #define DW_CFA_offset_extended              0x05
71 #define DW_CFA_restore_extended             0x06
72 #define DW_CFA_undefined                    0x07
73 #define DW_CFA_same_value                   0x08
74 #define DW_CFA_register                     0x09
75 #define DW_CFA_remember_state               0x0a
76 #define DW_CFA_restore_state                0x0b
77 #define DW_CFA_def_cfa                      0x0c
78 #define DW_CFA_def_cfa_register             0x0d
79 #define DW_CFA_def_cfa_offset               0x0e
80 #define DW_CFA_def_cfa_expression           0x0f
81 #define DW_CFA_expression                   0x10
82 #define DW_CFA_offset_extended_sf           0x11
83 #define DW_CFA_def_cfa_sf                   0x12
84 #define DW_CFA_def_cfa_offset_sf            0x13
85 #define DW_CFA_val_offset                   0x14
86 #define DW_CFA_val_offset_sf                0x15
87 #define DW_CFA_val_expression               0x16
88 #define DW_CFA_lo_user                      0x1c
89 #define DW_CFA_GNU_window_save              0x2d
90 #define DW_CFA_GNU_args_size                0x2e
91 #define DW_CFA_GNU_negative_offset_extended 0x2f
92 #define DW_CFA_hi_user                      0x3f
93
94 #define DW_EH_PE_FORM     0x07
95 #define DW_EH_PE_native   0x00
96 #define DW_EH_PE_leb128   0x01
97 #define DW_EH_PE_data2    0x02
98 #define DW_EH_PE_data4    0x03
99 #define DW_EH_PE_data8    0x04
100 #define DW_EH_PE_signed   0x08
101 #define DW_EH_PE_ADJUST   0x70
102 #define DW_EH_PE_abs      0x00
103 #define DW_EH_PE_pcrel    0x10
104 #define DW_EH_PE_textrel  0x20
105 #define DW_EH_PE_datarel  0x30
106 #define DW_EH_PE_funcrel  0x40
107 #define DW_EH_PE_aligned  0x50
108 #define DW_EH_PE_indirect 0x80
109 #define DW_EH_PE_omit     0xff
110
111 #define CIE_ID  0
112
113 typedef unsigned long uleb128_t;
114 typedef signed long sleb128_t;
115
116 static struct unwind_table {
117         struct {
118                 unsigned long pc;
119                 unsigned long range;
120         } core, init;
121         const void *address;
122         unsigned long size;
123         const unsigned char *header;
124         unsigned long hdrsz;
125         struct unwind_table *link;
126         const char *name;
127 } root_table;
128
129 struct unwind_item {
130         enum item_location {
131                 Nowhere,
132                 Memory,
133                 Register,
134                 Value
135         } where;
136         uleb128_t value;
137 };
138
139 struct unwind_state {
140         uleb128_t loc, org;
141         const u8 *cieStart, *cieEnd;
142         uleb128_t codeAlign;
143         sleb128_t dataAlign;
144         struct cfa {
145                 uleb128_t reg, offs;
146         } cfa;
147         struct unwind_item regs[ARRAY_SIZE(reg_info)];
148         unsigned stackDepth:8;
149         unsigned version:8;
150         const u8 *label;
151         const u8 *stack[MAX_STACK_DEPTH];
152 };
153
154 static const struct cfa badCFA = { ARRAY_SIZE(reg_info), 1 };
155
156 static struct unwind_table *find_table(unsigned long pc)
157 {
158         struct unwind_table *table;
159
160         for (table = &root_table; table; table = table->link)
161                 if ((pc >= table->core.pc
162                      && pc < table->core.pc + table->core.range)
163                     || (pc >= table->init.pc
164                         && pc < table->init.pc + table->init.range))
165                         break;
166
167         return table;
168 }
169
170 static unsigned long read_pointer(const u8 **pLoc,
171                                   const void *end, signed ptrType);
172 static void init_unwind_hdr(struct unwind_table *table,
173                             void *(*alloc) (unsigned long));
174
175 /*
176  * wrappers for header alloc (vs. calling one vs. other at call site)
177  * to elide section mismatches warnings
178  */
179 static void *__init unw_hdr_alloc_early(unsigned long sz)
180 {
181         return memblock_alloc_from(sz, sizeof(unsigned int), MAX_DMA_ADDRESS);
182 }
183
184 static void *unw_hdr_alloc(unsigned long sz)
185 {
186         return kmalloc(sz, GFP_KERNEL);
187 }
188
189 static void init_unwind_table(struct unwind_table *table, const char *name,
190                               const void *core_start, unsigned long core_size,
191                               const void *init_start, unsigned long init_size,
192                               const void *table_start, unsigned long table_size,
193                               const u8 *header_start, unsigned long header_size)
194 {
195         const u8 *ptr = header_start + 4;
196         const u8 *end = header_start + header_size;
197
198         table->core.pc = (unsigned long)core_start;
199         table->core.range = core_size;
200         table->init.pc = (unsigned long)init_start;
201         table->init.range = init_size;
202         table->address = table_start;
203         table->size = table_size;
204
205         /* See if the linker provided table looks valid. */
206         if (header_size <= 4
207             || header_start[0] != 1
208             || (void *)read_pointer(&ptr, end, header_start[1]) != table_start
209             || header_start[2] == DW_EH_PE_omit
210             || read_pointer(&ptr, end, header_start[2]) <= 0
211             || header_start[3] == DW_EH_PE_omit)
212                 header_start = NULL;
213
214         table->hdrsz = header_size;
215         smp_wmb();
216         table->header = header_start;
217         table->link = NULL;
218         table->name = name;
219 }
220
221 void __init arc_unwind_init(void)
222 {
223         init_unwind_table(&root_table, "kernel", _text, _end - _text, NULL, 0,
224                           __start_unwind, __end_unwind - __start_unwind,
225                           NULL, 0);
226           /*__start_unwind_hdr, __end_unwind_hdr - __start_unwind_hdr);*/
227
228         init_unwind_hdr(&root_table, unw_hdr_alloc_early);
229 }
230
231 static const u32 bad_cie, not_fde;
232 static const u32 *cie_for_fde(const u32 *fde, const struct unwind_table *);
233 static const u32 *__cie_for_fde(const u32 *fde);
234 static signed fde_pointer_type(const u32 *cie);
235
236 struct eh_frame_hdr_table_entry {
237         unsigned long start, fde;
238 };
239
240 static int cmp_eh_frame_hdr_table_entries(const void *p1, const void *p2)
241 {
242         const struct eh_frame_hdr_table_entry *e1 = p1;
243         const struct eh_frame_hdr_table_entry *e2 = p2;
244
245         return (e1->start > e2->start) - (e1->start < e2->start);
246 }
247
248 static void swap_eh_frame_hdr_table_entries(void *p1, void *p2, int size)
249 {
250         struct eh_frame_hdr_table_entry *e1 = p1;
251         struct eh_frame_hdr_table_entry *e2 = p2;
252         unsigned long v;
253
254         v = e1->start;
255         e1->start = e2->start;
256         e2->start = v;
257         v = e1->fde;
258         e1->fde = e2->fde;
259         e2->fde = v;
260 }
261
262 static void init_unwind_hdr(struct unwind_table *table,
263                             void *(*alloc) (unsigned long))
264 {
265         const u8 *ptr;
266         unsigned long tableSize = table->size, hdrSize;
267         unsigned n;
268         const u32 *fde;
269         struct {
270                 u8 version;
271                 u8 eh_frame_ptr_enc;
272                 u8 fde_count_enc;
273                 u8 table_enc;
274                 unsigned long eh_frame_ptr;
275                 unsigned int fde_count;
276                 struct eh_frame_hdr_table_entry table[];
277         } __attribute__ ((__packed__)) *header;
278
279         if (table->header)
280                 return;
281
282         if (table->hdrsz)
283                 pr_warn(".eh_frame_hdr for '%s' present but unusable\n",
284                         table->name);
285
286         if (tableSize & (sizeof(*fde) - 1))
287                 return;
288
289         for (fde = table->address, n = 0;
290              tableSize > sizeof(*fde) && tableSize - sizeof(*fde) >= *fde;
291              tableSize -= sizeof(*fde) + *fde, fde += 1 + *fde / sizeof(*fde)) {
292                 const u32 *cie = cie_for_fde(fde, table);
293                 signed ptrType;
294
295                 if (cie == &not_fde)
296                         continue;
297                 if (cie == NULL || cie == &bad_cie)
298                         goto ret_err;
299                 ptrType = fde_pointer_type(cie);
300                 if (ptrType < 0)
301                         goto ret_err;
302
303                 ptr = (const u8 *)(fde + 2);
304                 if (!read_pointer(&ptr, (const u8 *)(fde + 1) + *fde,
305                                                                 ptrType)) {
306                         /* FIXME_Rajesh We have 4 instances of null addresses
307                          * instead of the initial loc addr
308                          * return;
309                          */
310                         WARN(1, "unwinder: FDE->initial_location NULL %p\n",
311                                 (const u8 *)(fde + 1) + *fde);
312                 }
313                 ++n;
314         }
315
316         if (tableSize || !n)
317                 goto ret_err;
318
319         hdrSize = 4 + sizeof(unsigned long) + sizeof(unsigned int)
320             + 2 * n * sizeof(unsigned long);
321
322         header = alloc(hdrSize);
323         if (!header)
324                 goto ret_err;
325
326         header->version = 1;
327         header->eh_frame_ptr_enc = DW_EH_PE_abs | DW_EH_PE_native;
328         header->fde_count_enc = DW_EH_PE_abs | DW_EH_PE_data4;
329         header->table_enc = DW_EH_PE_abs | DW_EH_PE_native;
330         put_unaligned((unsigned long)table->address, &header->eh_frame_ptr);
331         BUILD_BUG_ON(offsetof(typeof(*header), fde_count)
332                      % __alignof(typeof(header->fde_count)));
333         header->fde_count = n;
334
335         BUILD_BUG_ON(offsetof(typeof(*header), table)
336                      % __alignof(typeof(*header->table)));
337         for (fde = table->address, tableSize = table->size, n = 0;
338              tableSize;
339              tableSize -= sizeof(*fde) + *fde, fde += 1 + *fde / sizeof(*fde)) {
340                 const u32 *cie = __cie_for_fde(fde);
341
342                 if (fde[1] == CIE_ID)
343                         continue;       /* this is a CIE */
344                 ptr = (const u8 *)(fde + 2);
345                 header->table[n].start = read_pointer(&ptr,
346                                                       (const u8 *)(fde + 1) +
347                                                       *fde,
348                                                       fde_pointer_type(cie));
349                 header->table[n].fde = (unsigned long)fde;
350                 ++n;
351         }
352         WARN_ON(n != header->fde_count);
353
354         sort(header->table,
355              n,
356              sizeof(*header->table),
357              cmp_eh_frame_hdr_table_entries, swap_eh_frame_hdr_table_entries);
358
359         table->hdrsz = hdrSize;
360         smp_wmb();
361         table->header = (const void *)header;
362         return;
363
364 ret_err:
365         panic("Attention !!! Dwarf FDE parsing errors\n");
366 }
367
368 #ifdef CONFIG_MODULES
369
370 static struct unwind_table *last_table;
371
372 /* Must be called with module_mutex held. */
373 void *unwind_add_table(struct module *module, const void *table_start,
374                        unsigned long table_size)
375 {
376         struct unwind_table *table;
377
378         if (table_size <= 0)
379                 return NULL;
380
381         table = kmalloc(sizeof(*table), GFP_KERNEL);
382         if (!table)
383                 return NULL;
384
385         init_unwind_table(table, module->name,
386                           module->core_layout.base, module->core_layout.size,
387                           module->init_layout.base, module->init_layout.size,
388                           table_start, table_size,
389                           NULL, 0);
390
391         init_unwind_hdr(table, unw_hdr_alloc);
392
393 #ifdef UNWIND_DEBUG
394         unw_debug("Table added for [%s] %lx %lx\n",
395                 module->name, table->core.pc, table->core.range);
396 #endif
397         if (last_table)
398                 last_table->link = table;
399         else
400                 root_table.link = table;
401         last_table = table;
402
403         return table;
404 }
405
406 struct unlink_table_info {
407         struct unwind_table *table;
408         int init_only;
409 };
410
411 static int unlink_table(void *arg)
412 {
413         struct unlink_table_info *info = arg;
414         struct unwind_table *table = info->table, *prev;
415
416         for (prev = &root_table; prev->link && prev->link != table;
417              prev = prev->link)
418                 ;
419
420         if (prev->link) {
421                 if (info->init_only) {
422                         table->init.pc = 0;
423                         table->init.range = 0;
424                         info->table = NULL;
425                 } else {
426                         prev->link = table->link;
427                         if (!prev->link)
428                                 last_table = prev;
429                 }
430         } else
431                 info->table = NULL;
432
433         return 0;
434 }
435
436 /* Must be called with module_mutex held. */
437 void unwind_remove_table(void *handle, int init_only)
438 {
439         struct unwind_table *table = handle;
440         struct unlink_table_info info;
441
442         if (!table || table == &root_table)
443                 return;
444
445         if (init_only && table == last_table) {
446                 table->init.pc = 0;
447                 table->init.range = 0;
448                 return;
449         }
450
451         info.table = table;
452         info.init_only = init_only;
453
454         unlink_table(&info); /* XXX: SMP */
455         kfree(table->header);
456         kfree(table);
457 }
458
459 #endif /* CONFIG_MODULES */
460
461 static uleb128_t get_uleb128(const u8 **pcur, const u8 *end)
462 {
463         const u8 *cur = *pcur;
464         uleb128_t value;
465         unsigned shift;
466
467         for (shift = 0, value = 0; cur < end; shift += 7) {
468                 if (shift + 7 > 8 * sizeof(value)
469                     && (*cur & 0x7fU) >= (1U << (8 * sizeof(value) - shift))) {
470                         cur = end + 1;
471                         break;
472                 }
473                 value |= (uleb128_t) (*cur & 0x7f) << shift;
474                 if (!(*cur++ & 0x80))
475                         break;
476         }
477         *pcur = cur;
478
479         return value;
480 }
481
482 static sleb128_t get_sleb128(const u8 **pcur, const u8 *end)
483 {
484         const u8 *cur = *pcur;
485         sleb128_t value;
486         unsigned shift;
487
488         for (shift = 0, value = 0; cur < end; shift += 7) {
489                 if (shift + 7 > 8 * sizeof(value)
490                     && (*cur & 0x7fU) >= (1U << (8 * sizeof(value) - shift))) {
491                         cur = end + 1;
492                         break;
493                 }
494                 value |= (sleb128_t) (*cur & 0x7f) << shift;
495                 if (!(*cur & 0x80)) {
496                         value |= -(*cur++ & 0x40) << shift;
497                         break;
498                 }
499         }
500         *pcur = cur;
501
502         return value;
503 }
504
505 static const u32 *__cie_for_fde(const u32 *fde)
506 {
507         const u32 *cie;
508
509         cie = fde + 1 - fde[1] / sizeof(*fde);
510
511         return cie;
512 }
513
514 static const u32 *cie_for_fde(const u32 *fde, const struct unwind_table *table)
515 {
516         const u32 *cie;
517
518         if (!*fde || (*fde & (sizeof(*fde) - 1)))
519                 return &bad_cie;
520
521         if (fde[1] == CIE_ID)
522                 return &not_fde;        /* this is a CIE */
523
524         if ((fde[1] & (sizeof(*fde) - 1)))
525 /* || fde[1] > (unsigned long)(fde + 1) - (unsigned long)table->address) */
526                 return NULL;    /* this is not a valid FDE */
527
528         cie = __cie_for_fde(fde);
529
530         if (*cie <= sizeof(*cie) + 4 || *cie >= fde[1] - sizeof(*fde)
531             || (*cie & (sizeof(*cie) - 1))
532             || (cie[1] != CIE_ID))
533                 return NULL;    /* this is not a (valid) CIE */
534         return cie;
535 }
536
537 static unsigned long read_pointer(const u8 **pLoc, const void *end,
538                                   signed ptrType)
539 {
540         unsigned long value = 0;
541         union {
542                 const u8 *p8;
543                 const u16 *p16u;
544                 const s16 *p16s;
545                 const u32 *p32u;
546                 const s32 *p32s;
547                 const unsigned long *pul;
548         } ptr;
549
550         if (ptrType < 0 || ptrType == DW_EH_PE_omit)
551                 return 0;
552         ptr.p8 = *pLoc;
553         switch (ptrType & DW_EH_PE_FORM) {
554         case DW_EH_PE_data2:
555                 if (end < (const void *)(ptr.p16u + 1))
556                         return 0;
557                 if (ptrType & DW_EH_PE_signed)
558                         value = get_unaligned((u16 *) ptr.p16s++);
559                 else
560                         value = get_unaligned((u16 *) ptr.p16u++);
561                 break;
562         case DW_EH_PE_data4:
563 #ifdef CONFIG_64BIT
564                 if (end < (const void *)(ptr.p32u + 1))
565                         return 0;
566                 if (ptrType & DW_EH_PE_signed)
567                         value = get_unaligned(ptr.p32s++);
568                 else
569                         value = get_unaligned(ptr.p32u++);
570                 break;
571         case DW_EH_PE_data8:
572                 BUILD_BUG_ON(sizeof(u64) != sizeof(value));
573 #else
574                 BUILD_BUG_ON(sizeof(u32) != sizeof(value));
575 #endif
576         case DW_EH_PE_native:
577                 if (end < (const void *)(ptr.pul + 1))
578                         return 0;
579                 value = get_unaligned((unsigned long *)ptr.pul++);
580                 break;
581         case DW_EH_PE_leb128:
582                 BUILD_BUG_ON(sizeof(uleb128_t) > sizeof(value));
583                 value = ptrType & DW_EH_PE_signed ? get_sleb128(&ptr.p8, end)
584                     : get_uleb128(&ptr.p8, end);
585                 if ((const void *)ptr.p8 > end)
586                         return 0;
587                 break;
588         default:
589                 return 0;
590         }
591         switch (ptrType & DW_EH_PE_ADJUST) {
592         case DW_EH_PE_abs:
593                 break;
594         case DW_EH_PE_pcrel:
595                 value += (unsigned long)*pLoc;
596                 break;
597         default:
598                 return 0;
599         }
600         if ((ptrType & DW_EH_PE_indirect)
601             && __get_user(value, (unsigned long __user *)value))
602                 return 0;
603         *pLoc = ptr.p8;
604
605         return value;
606 }
607
608 static signed fde_pointer_type(const u32 *cie)
609 {
610         const u8 *ptr = (const u8 *)(cie + 2);
611         unsigned version = *ptr;
612
613         if (*++ptr) {
614                 const char *aug;
615                 const u8 *end = (const u8 *)(cie + 1) + *cie;
616                 uleb128_t len;
617
618                 /* check if augmentation size is first (and thus present) */
619                 if (*ptr != 'z')
620                         return -1;
621
622                 /* check if augmentation string is nul-terminated */
623                 aug = (const void *)ptr;
624                 ptr = memchr(aug, 0, end - ptr);
625                 if (ptr == NULL)
626                         return -1;
627
628                 ++ptr;          /* skip terminator */
629                 get_uleb128(&ptr, end); /* skip code alignment */
630                 get_sleb128(&ptr, end); /* skip data alignment */
631                 /* skip return address column */
632                 version <= 1 ? (void) ++ptr : (void)get_uleb128(&ptr, end);
633                 len = get_uleb128(&ptr, end);   /* augmentation length */
634
635                 if (ptr + len < ptr || ptr + len > end)
636                         return -1;
637
638                 end = ptr + len;
639                 while (*++aug) {
640                         if (ptr >= end)
641                                 return -1;
642                         switch (*aug) {
643                         case 'L':
644                                 ++ptr;
645                                 break;
646                         case 'P':{
647                                         signed ptrType = *ptr++;
648
649                                         if (!read_pointer(&ptr, end, ptrType)
650                                             || ptr > end)
651                                                 return -1;
652                                 }
653                                 break;
654                         case 'R':
655                                 return *ptr;
656                         default:
657                                 return -1;
658                         }
659                 }
660         }
661         return DW_EH_PE_native | DW_EH_PE_abs;
662 }
663
664 static int advance_loc(unsigned long delta, struct unwind_state *state)
665 {
666         state->loc += delta * state->codeAlign;
667
668         /* FIXME_Rajesh: Probably we are defining for the initial range as well;
669            return delta > 0;
670          */
671         unw_debug("delta %3lu => loc 0x%lx: ", delta, state->loc);
672         return 1;
673 }
674
675 static void set_rule(uleb128_t reg, enum item_location where, uleb128_t value,
676                      struct unwind_state *state)
677 {
678         if (reg < ARRAY_SIZE(state->regs)) {
679                 state->regs[reg].where = where;
680                 state->regs[reg].value = value;
681
682 #ifdef UNWIND_DEBUG
683                 unw_debug("r%lu: ", reg);
684                 switch (where) {
685                 case Nowhere:
686                         unw_debug("s ");
687                         break;
688                 case Memory:
689                         unw_debug("c(%lu) ", value);
690                         break;
691                 case Register:
692                         unw_debug("r(%lu) ", value);
693                         break;
694                 case Value:
695                         unw_debug("v(%lu) ", value);
696                         break;
697                 default:
698                         break;
699                 }
700 #endif
701         }
702 }
703
704 static int processCFI(const u8 *start, const u8 *end, unsigned long targetLoc,
705                       signed ptrType, struct unwind_state *state)
706 {
707         union {
708                 const u8 *p8;
709                 const u16 *p16;
710                 const u32 *p32;
711         } ptr;
712         int result = 1;
713         u8 opcode;
714
715         if (start != state->cieStart) {
716                 state->loc = state->org;
717                 result =
718                     processCFI(state->cieStart, state->cieEnd, 0, ptrType,
719                                state);
720                 if (targetLoc == 0 && state->label == NULL)
721                         return result;
722         }
723         for (ptr.p8 = start; result && ptr.p8 < end;) {
724                 switch (*ptr.p8 >> 6) {
725                         uleb128_t value;
726
727                 case 0:
728                         opcode = *ptr.p8++;
729
730                         switch (opcode) {
731                         case DW_CFA_nop:
732                                 unw_debug("cfa nop ");
733                                 break;
734                         case DW_CFA_set_loc:
735                                 state->loc = read_pointer(&ptr.p8, end,
736                                                           ptrType);
737                                 if (state->loc == 0)
738                                         result = 0;
739                                 unw_debug("cfa_set_loc: 0x%lx ", state->loc);
740                                 break;
741                         case DW_CFA_advance_loc1:
742                                 unw_debug("\ncfa advance loc1:");
743                                 result = ptr.p8 < end
744                                     && advance_loc(*ptr.p8++, state);
745                                 break;
746                         case DW_CFA_advance_loc2:
747                                 value = *ptr.p8++;
748                                 value += *ptr.p8++ << 8;
749                                 unw_debug("\ncfa advance loc2:");
750                                 result = ptr.p8 <= end + 2
751                                     /* && advance_loc(*ptr.p16++, state); */
752                                     && advance_loc(value, state);
753                                 break;
754                         case DW_CFA_advance_loc4:
755                                 unw_debug("\ncfa advance loc4:");
756                                 result = ptr.p8 <= end + 4
757                                     && advance_loc(*ptr.p32++, state);
758                                 break;
759                         case DW_CFA_offset_extended:
760                                 value = get_uleb128(&ptr.p8, end);
761                                 unw_debug("cfa_offset_extended: ");
762                                 set_rule(value, Memory,
763                                          get_uleb128(&ptr.p8, end), state);
764                                 break;
765                         case DW_CFA_val_offset:
766                                 value = get_uleb128(&ptr.p8, end);
767                                 set_rule(value, Value,
768                                          get_uleb128(&ptr.p8, end), state);
769                                 break;
770                         case DW_CFA_offset_extended_sf:
771                                 value = get_uleb128(&ptr.p8, end);
772                                 set_rule(value, Memory,
773                                          get_sleb128(&ptr.p8, end), state);
774                                 break;
775                         case DW_CFA_val_offset_sf:
776                                 value = get_uleb128(&ptr.p8, end);
777                                 set_rule(value, Value,
778                                          get_sleb128(&ptr.p8, end), state);
779                                 break;
780                         case DW_CFA_restore_extended:
781                                 unw_debug("cfa_restore_extended: ");
782                         case DW_CFA_undefined:
783                                 unw_debug("cfa_undefined: ");
784                         case DW_CFA_same_value:
785                                 unw_debug("cfa_same_value: ");
786                                 set_rule(get_uleb128(&ptr.p8, end), Nowhere, 0,
787                                          state);
788                                 break;
789                         case DW_CFA_register:
790                                 unw_debug("cfa_register: ");
791                                 value = get_uleb128(&ptr.p8, end);
792                                 set_rule(value,
793                                          Register,
794                                          get_uleb128(&ptr.p8, end), state);
795                                 break;
796                         case DW_CFA_remember_state:
797                                 unw_debug("cfa_remember_state: ");
798                                 if (ptr.p8 == state->label) {
799                                         state->label = NULL;
800                                         return 1;
801                                 }
802                                 if (state->stackDepth >= MAX_STACK_DEPTH)
803                                         return 0;
804                                 state->stack[state->stackDepth++] = ptr.p8;
805                                 break;
806                         case DW_CFA_restore_state:
807                                 unw_debug("cfa_restore_state: ");
808                                 if (state->stackDepth) {
809                                         const uleb128_t loc = state->loc;
810                                         const u8 *label = state->label;
811
812                                         state->label =
813                                             state->stack[state->stackDepth - 1];
814                                         memcpy(&state->cfa, &badCFA,
815                                                sizeof(state->cfa));
816                                         memset(state->regs, 0,
817                                                sizeof(state->regs));
818                                         state->stackDepth = 0;
819                                         result =
820                                             processCFI(start, end, 0, ptrType,
821                                                        state);
822                                         state->loc = loc;
823                                         state->label = label;
824                                 } else
825                                         return 0;
826                                 break;
827                         case DW_CFA_def_cfa:
828                                 state->cfa.reg = get_uleb128(&ptr.p8, end);
829                                 unw_debug("cfa_def_cfa: r%lu ", state->cfa.reg);
830                                 /*nobreak*/
831                         case DW_CFA_def_cfa_offset:
832                                 state->cfa.offs = get_uleb128(&ptr.p8, end);
833                                 unw_debug("cfa_def_cfa_offset: 0x%lx ",
834                                           state->cfa.offs);
835                                 break;
836                         case DW_CFA_def_cfa_sf:
837                                 state->cfa.reg = get_uleb128(&ptr.p8, end);
838                                 /*nobreak */
839                         case DW_CFA_def_cfa_offset_sf:
840                                 state->cfa.offs = get_sleb128(&ptr.p8, end)
841                                     * state->dataAlign;
842                                 break;
843                         case DW_CFA_def_cfa_register:
844                                 unw_debug("cfa_def_cfa_register: ");
845                                 state->cfa.reg = get_uleb128(&ptr.p8, end);
846                                 break;
847                                 /*todo case DW_CFA_def_cfa_expression: */
848                                 /*todo case DW_CFA_expression: */
849                                 /*todo case DW_CFA_val_expression: */
850                         case DW_CFA_GNU_args_size:
851                                 get_uleb128(&ptr.p8, end);
852                                 break;
853                         case DW_CFA_GNU_negative_offset_extended:
854                                 value = get_uleb128(&ptr.p8, end);
855                                 set_rule(value,
856                                          Memory,
857                                          (uleb128_t) 0 - get_uleb128(&ptr.p8,
858                                                                      end),
859                                          state);
860                                 break;
861                         case DW_CFA_GNU_window_save:
862                         default:
863                                 unw_debug("UNKNOWN OPCODE 0x%x\n", opcode);
864                                 result = 0;
865                                 break;
866                         }
867                         break;
868                 case 1:
869                         unw_debug("\ncfa_adv_loc: ");
870                         result = advance_loc(*ptr.p8++ & 0x3f, state);
871                         break;
872                 case 2:
873                         unw_debug("cfa_offset: ");
874                         value = *ptr.p8++ & 0x3f;
875                         set_rule(value, Memory, get_uleb128(&ptr.p8, end),
876                                  state);
877                         break;
878                 case 3:
879                         unw_debug("cfa_restore: ");
880                         set_rule(*ptr.p8++ & 0x3f, Nowhere, 0, state);
881                         break;
882                 }
883
884                 if (ptr.p8 > end)
885                         result = 0;
886                 if (result && targetLoc != 0 && targetLoc < state->loc)
887                         return 1;
888         }
889
890         return result && ptr.p8 == end && (targetLoc == 0 || (
891                 /*todo While in theory this should apply, gcc in practice omits
892                   everything past the function prolog, and hence the location
893                   never reaches the end of the function.
894                 targetLoc < state->loc && */  state->label == NULL));
895 }
896
897 /* Unwind to previous to frame.  Returns 0 if successful, negative
898  * number in case of an error. */
899 int arc_unwind(struct unwind_frame_info *frame)
900 {
901 #define FRAME_REG(r, t) (((t *)frame)[reg_info[r].offs])
902         const u32 *fde = NULL, *cie = NULL;
903         const u8 *ptr = NULL, *end = NULL;
904         unsigned long pc = UNW_PC(frame) - frame->call_frame;
905         unsigned long startLoc = 0, endLoc = 0, cfa;
906         unsigned i;
907         signed ptrType = -1;
908         uleb128_t retAddrReg = 0;
909         const struct unwind_table *table;
910         struct unwind_state state;
911         unsigned long *fptr;
912         unsigned long addr;
913
914         unw_debug("\n\nUNWIND FRAME:\n");
915         unw_debug("PC: 0x%lx BLINK: 0x%lx, SP: 0x%lx, FP: 0x%x\n",
916                   UNW_PC(frame), UNW_BLINK(frame), UNW_SP(frame),
917                   UNW_FP(frame));
918
919         if (UNW_PC(frame) == 0)
920                 return -EINVAL;
921
922 #ifdef UNWIND_DEBUG
923         {
924                 unsigned long *sptr = (unsigned long *)UNW_SP(frame);
925                 unw_debug("\nStack Dump:\n");
926                 for (i = 0; i < 20; i++, sptr++)
927                         unw_debug("0x%p:  0x%lx\n", sptr, *sptr);
928                 unw_debug("\n");
929         }
930 #endif
931
932         table = find_table(pc);
933         if (table != NULL
934             && !(table->size & (sizeof(*fde) - 1))) {
935                 const u8 *hdr = table->header;
936                 unsigned long tableSize;
937
938                 smp_rmb();
939                 if (hdr && hdr[0] == 1) {
940                         switch (hdr[3] & DW_EH_PE_FORM) {
941                         case DW_EH_PE_native:
942                                 tableSize = sizeof(unsigned long);
943                                 break;
944                         case DW_EH_PE_data2:
945                                 tableSize = 2;
946                                 break;
947                         case DW_EH_PE_data4:
948                                 tableSize = 4;
949                                 break;
950                         case DW_EH_PE_data8:
951                                 tableSize = 8;
952                                 break;
953                         default:
954                                 tableSize = 0;
955                                 break;
956                         }
957                         ptr = hdr + 4;
958                         end = hdr + table->hdrsz;
959                         if (tableSize && read_pointer(&ptr, end, hdr[1])
960                             == (unsigned long)table->address
961                             && (i = read_pointer(&ptr, end, hdr[2])) > 0
962                             && i == (end - ptr) / (2 * tableSize)
963                             && !((end - ptr) % (2 * tableSize))) {
964                                 do {
965                                         const u8 *cur =
966                                             ptr + (i / 2) * (2 * tableSize);
967
968                                         startLoc = read_pointer(&cur,
969                                                                 cur + tableSize,
970                                                                 hdr[3]);
971                                         if (pc < startLoc)
972                                                 i /= 2;
973                                         else {
974                                                 ptr = cur - tableSize;
975                                                 i = (i + 1) / 2;
976                                         }
977                                 } while (startLoc && i > 1);
978                                 if (i == 1
979                                     && (startLoc = read_pointer(&ptr,
980                                                                 ptr + tableSize,
981                                                                 hdr[3])) != 0
982                                     && pc >= startLoc)
983                                         fde = (void *)read_pointer(&ptr,
984                                                                    ptr +
985                                                                    tableSize,
986                                                                    hdr[3]);
987                         }
988                 }
989
990                 if (fde != NULL) {
991                         cie = cie_for_fde(fde, table);
992                         ptr = (const u8 *)(fde + 2);
993                         if (cie != NULL
994                             && cie != &bad_cie
995                             && cie != &not_fde
996                             && (ptrType = fde_pointer_type(cie)) >= 0
997                             && read_pointer(&ptr,
998                                             (const u8 *)(fde + 1) + *fde,
999                                             ptrType) == startLoc) {
1000                                 if (!(ptrType & DW_EH_PE_indirect))
1001                                         ptrType &=
1002                                             DW_EH_PE_FORM | DW_EH_PE_signed;
1003                                 endLoc =
1004                                     startLoc + read_pointer(&ptr,
1005                                                             (const u8 *)(fde +
1006                                                                          1) +
1007                                                             *fde, ptrType);
1008                                 if (pc >= endLoc) {
1009                                         fde = NULL;
1010                                         cie = NULL;
1011                                 }
1012                         } else {
1013                                 fde = NULL;
1014                                 cie = NULL;
1015                         }
1016                 }
1017         }
1018         if (cie != NULL) {
1019                 memset(&state, 0, sizeof(state));
1020                 state.cieEnd = ptr;     /* keep here temporarily */
1021                 ptr = (const u8 *)(cie + 2);
1022                 end = (const u8 *)(cie + 1) + *cie;
1023                 frame->call_frame = 1;
1024                 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 alignment factor */
1051                 state.codeAlign = get_uleb128(&ptr, end);
1052                 /* get data alignment 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);