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