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