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