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