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 156 static struct unwind_table *find_table(unsigned long pc) 157 { 158 struct unwind_table *table; 159 160 for (table = &root_table; table; table = table->link) 161 if ((pc >= table->core.pc 162 && pc < table->core.pc + table->core.range) 163 || (pc >= table->init.pc 164 && pc < table->init.pc + table->init.range)) 165 break; 166 167 return table; 168 } 169 170 static unsigned long read_pointer(const u8 **pLoc, 171 const void *end, signed ptrType); 172 static void init_unwind_hdr(struct unwind_table *table, 173 void *(*alloc) (unsigned long)); 174 175 /* 176 * wrappers for header alloc (vs. calling one vs. other at call site) 177 * to elide section mismatches warnings 178 */ 179 static void *__init unw_hdr_alloc_early(unsigned long sz) 180 { 181 return memblock_alloc_from(sz, sizeof(unsigned int), MAX_DMA_ADDRESS); 182 } 183 184 static void 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 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 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 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 == ¬_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 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. */ 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 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. */ 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 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 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 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 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 ¬_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 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 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 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 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 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. */ 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 != ¬_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