1 /* libunwind - a platform-independent unwind library 2 Copyright (c) 2003, 2005 Hewlett-Packard Development Company, L.P. 3 Contributed by David Mosberger-Tang <davidm (at) hpl.hp.com> 4 5 This file is part of libunwind. 6 7 Permission is hereby granted, free of charge, to any person obtaining 8 a copy of this software and associated documentation files (the 9 "Software"), to deal in the Software without restriction, including 10 without limitation the rights to use, copy, modify, merge, publish, 11 distribute, sublicense, and/or sell copies of the Software, and to 12 permit persons to whom the Software is furnished to do so, subject to 13 the following conditions: 14 15 The above copyright notice and this permission notice shall be 16 included in all copies or substantial portions of the Software. 17 18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 22 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 24 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 25 26 #include <stddef.h> 27 #include "dwarf_i.h" 28 #include "libunwind_i.h" 29 30 #define alloc_reg_state() (mempool_alloc (&dwarf_reg_state_pool)) 31 #define free_reg_state(rs) (mempool_free (&dwarf_reg_state_pool, rs)) 32 33 static inline int 34 read_regnum (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr, 35 unw_word_t *valp, void *arg) 36 { 37 int ret; 38 39 if ((ret = dwarf_read_uleb128 (as, a, addr, valp, arg)) < 0) 40 return ret; 41 42 if (*valp >= DWARF_NUM_PRESERVED_REGS) 43 { 44 Debug (1, "Invalid register number %u\n", (unsigned int) *valp); 45 return -UNW_EBADREG; 46 } 47 return 0; 48 } 49 50 static inline void 51 set_reg (dwarf_state_record_t *sr, unw_word_t regnum, dwarf_where_t where, 52 unw_word_t val) 53 { 54 sr->rs_current.reg[regnum].where = where; 55 sr->rs_current.reg[regnum].val = val; 56 } 57 58 /* Run a CFI program to update the register state. */ 59 static int 60 run_cfi_program (struct dwarf_cursor *c, dwarf_state_record_t *sr, 61 unw_word_t ip, unw_word_t *addr, unw_word_t end_addr, 62 struct dwarf_cie_info *dci) 63 { 64 unw_word_t curr_ip, operand = 0, regnum, val, len, fde_encoding; 65 dwarf_reg_state_t *rs_stack = NULL, *new_rs, *old_rs; 66 unw_addr_space_t as; 67 unw_accessors_t *a; 68 uint8_t u8, op; 69 uint16_t u16; 70 uint32_t u32; 71 void *arg; 72 int ret; 73 74 as = c->as; 75 arg = c->as_arg; 76 if (c->pi.flags & UNW_PI_FLAG_DEBUG_FRAME) 77 { 78 /* .debug_frame CFI is stored in local address space. */ 79 as = unw_local_addr_space; 80 arg = NULL; 81 } 82 a = unw_get_accessors (as); 83 curr_ip = c->pi.start_ip; 84 85 /* Process everything up to and including the current 'ip', 86 including all the DW_CFA_advance_loc instructions. See 87 'c->use_prev_instr' use in 'fetch_proc_info' for details. */ 88 while (curr_ip <= ip && *addr < end_addr) 89 { 90 if ((ret = dwarf_readu8 (as, a, addr, &op, arg)) < 0) 91 return ret; 92 93 if (op & DWARF_CFA_OPCODE_MASK) 94 { 95 operand = op & DWARF_CFA_OPERAND_MASK; 96 op &= ~DWARF_CFA_OPERAND_MASK; 97 } 98 switch ((dwarf_cfa_t) op) 99 { 100 case DW_CFA_advance_loc: 101 curr_ip += operand * dci->code_align; 102 Debug (15, "CFA_advance_loc to 0x%lx\n", (long) curr_ip); 103 break; 104 105 case DW_CFA_advance_loc1: 106 if ((ret = dwarf_readu8 (as, a, addr, &u8, arg)) < 0) 107 goto fail; 108 curr_ip += u8 * dci->code_align; 109 Debug (15, "CFA_advance_loc1 to 0x%lx\n", (long) curr_ip); 110 break; 111 112 case DW_CFA_advance_loc2: 113 if ((ret = dwarf_readu16 (as, a, addr, &u16, arg)) < 0) 114 goto fail; 115 curr_ip += u16 * dci->code_align; 116 Debug (15, "CFA_advance_loc2 to 0x%lx\n", (long) curr_ip); 117 break; 118 119 case DW_CFA_advance_loc4: 120 if ((ret = dwarf_readu32 (as, a, addr, &u32, arg)) < 0) 121 goto fail; 122 curr_ip += u32 * dci->code_align; 123 Debug (15, "CFA_advance_loc4 to 0x%lx\n", (long) curr_ip); 124 break; 125 126 case DW_CFA_MIPS_advance_loc8: 127 #ifdef UNW_TARGET_MIPS 128 { 129 uint64_t u64; 130 131 if ((ret = dwarf_readu64 (as, a, addr, &u64, arg)) < 0) 132 goto fail; 133 curr_ip += u64 * dci->code_align; 134 Debug (15, "CFA_MIPS_advance_loc8\n"); 135 break; 136 } 137 #else 138 Debug (1, "DW_CFA_MIPS_advance_loc8 on non-MIPS target\n"); 139 ret = -UNW_EINVAL; 140 goto fail; 141 #endif 142 143 case DW_CFA_offset: 144 regnum = operand; 145 if (regnum >= DWARF_NUM_PRESERVED_REGS) 146 { 147 Debug (1, "Invalid register number %u in DW_cfa_OFFSET\n", 148 (unsigned int) regnum); 149 ret = -UNW_EBADREG; 150 goto fail; 151 } 152 if ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0) 153 goto fail; 154 set_reg (sr, regnum, DWARF_WHERE_CFAREL, val * dci->data_align); 155 Debug (15, "CFA_offset r%lu at cfa+0x%lx\n", 156 (long) regnum, (long) (val * dci->data_align)); 157 break; 158 159 case DW_CFA_offset_extended: 160 if (((ret = read_regnum (as, a, addr, ®num, arg)) < 0) 161 || ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0)) 162 goto fail; 163 set_reg (sr, regnum, DWARF_WHERE_CFAREL, val * dci->data_align); 164 Debug (15, "CFA_offset_extended r%lu at cf+0x%lx\n", 165 (long) regnum, (long) (val * dci->data_align)); 166 break; 167 168 case DW_CFA_offset_extended_sf: 169 if (((ret = read_regnum (as, a, addr, ®num, arg)) < 0) 170 || ((ret = dwarf_read_sleb128 (as, a, addr, &val, arg)) < 0)) 171 goto fail; 172 set_reg (sr, regnum, DWARF_WHERE_CFAREL, val * dci->data_align); 173 Debug (15, "CFA_offset_extended_sf r%lu at cf+0x%lx\n", 174 (long) regnum, (long) (val * dci->data_align)); 175 break; 176 177 case DW_CFA_restore: 178 regnum = operand; 179 if (regnum >= DWARF_NUM_PRESERVED_REGS) 180 { 181 Debug (1, "Invalid register number %u in DW_CFA_restore\n", 182 (unsigned int) regnum); 183 ret = -UNW_EINVAL; 184 goto fail; 185 } 186 sr->rs_current.reg[regnum] = sr->rs_initial.reg[regnum]; 187 Debug (15, "CFA_restore r%lu\n", (long) regnum); 188 break; 189 190 case DW_CFA_restore_extended: 191 if ((ret = dwarf_read_uleb128 (as, a, addr, ®num, arg)) < 0) 192 goto fail; 193 if (regnum >= DWARF_NUM_PRESERVED_REGS) 194 { 195 Debug (1, "Invalid register number %u in " 196 "DW_CFA_restore_extended\n", (unsigned int) regnum); 197 ret = -UNW_EINVAL; 198 goto fail; 199 } 200 sr->rs_current.reg[regnum] = sr->rs_initial.reg[regnum]; 201 Debug (15, "CFA_restore_extended r%lu\n", (long) regnum); 202 break; 203 204 case DW_CFA_nop: 205 break; 206 207 case DW_CFA_set_loc: 208 fde_encoding = dci->fde_encoding; 209 if ((ret = dwarf_read_encoded_pointer (as, a, addr, fde_encoding, 210 &c->pi, &curr_ip, 211 arg)) < 0) 212 goto fail; 213 Debug (15, "CFA_set_loc to 0x%lx\n", (long) curr_ip); 214 break; 215 216 case DW_CFA_undefined: 217 if ((ret = read_regnum (as, a, addr, ®num, arg)) < 0) 218 goto fail; 219 set_reg (sr, regnum, DWARF_WHERE_UNDEF, 0); 220 Debug (15, "CFA_undefined r%lu\n", (long) regnum); 221 break; 222 223 case DW_CFA_same_value: 224 if ((ret = read_regnum (as, a, addr, ®num, arg)) < 0) 225 goto fail; 226 set_reg (sr, regnum, DWARF_WHERE_SAME, 0); 227 Debug (15, "CFA_same_value r%lu\n", (long) regnum); 228 break; 229 230 case DW_CFA_register: 231 if (((ret = read_regnum (as, a, addr, ®num, arg)) < 0) 232 || ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0)) 233 goto fail; 234 set_reg (sr, regnum, DWARF_WHERE_REG, val); 235 Debug (15, "CFA_register r%lu to r%lu\n", (long) regnum, (long) val); 236 break; 237 238 case DW_CFA_remember_state: 239 new_rs = alloc_reg_state (); 240 if (!new_rs) 241 { 242 Debug (1, "Out of memory in DW_CFA_remember_state\n"); 243 ret = -UNW_ENOMEM; 244 goto fail; 245 } 246 247 memcpy (new_rs->reg, sr->rs_current.reg, sizeof (new_rs->reg)); 248 new_rs->next = rs_stack; 249 rs_stack = new_rs; 250 Debug (15, "CFA_remember_state\n"); 251 break; 252 253 case DW_CFA_restore_state: 254 if (!rs_stack) 255 { 256 Debug (1, "register-state stack underflow\n"); 257 ret = -UNW_EINVAL; 258 goto fail; 259 } 260 memcpy (&sr->rs_current.reg, &rs_stack->reg, sizeof (rs_stack->reg)); 261 old_rs = rs_stack; 262 rs_stack = rs_stack->next; 263 free_reg_state (old_rs); 264 Debug (15, "CFA_restore_state\n"); 265 break; 266 267 case DW_CFA_def_cfa: 268 if (((ret = read_regnum (as, a, addr, ®num, arg)) < 0) 269 || ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0)) 270 goto fail; 271 set_reg (sr, DWARF_CFA_REG_COLUMN, DWARF_WHERE_REG, regnum); 272 set_reg (sr, DWARF_CFA_OFF_COLUMN, 0, val); /* NOT factored! */ 273 Debug (15, "CFA_def_cfa r%lu+0x%lx\n", (long) regnum, (long) val); 274 break; 275 276 case DW_CFA_def_cfa_sf: 277 if (((ret = read_regnum (as, a, addr, ®num, arg)) < 0) 278 || ((ret = dwarf_read_sleb128 (as, a, addr, &val, arg)) < 0)) 279 goto fail; 280 set_reg (sr, DWARF_CFA_REG_COLUMN, DWARF_WHERE_REG, regnum); 281 set_reg (sr, DWARF_CFA_OFF_COLUMN, 0, 282 val * dci->data_align); /* factored! */ 283 Debug (15, "CFA_def_cfa_sf r%lu+0x%lx\n", 284 (long) regnum, (long) (val * dci->data_align)); 285 break; 286 287 case DW_CFA_def_cfa_register: 288 if ((ret = read_regnum (as, a, addr, ®num, arg)) < 0) 289 goto fail; 290 set_reg (sr, DWARF_CFA_REG_COLUMN, DWARF_WHERE_REG, regnum); 291 Debug (15, "CFA_def_cfa_register r%lu\n", (long) regnum); 292 break; 293 294 case DW_CFA_def_cfa_offset: 295 if ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0) 296 goto fail; 297 set_reg (sr, DWARF_CFA_OFF_COLUMN, 0, val); /* NOT factored! */ 298 Debug (15, "CFA_def_cfa_offset 0x%lx\n", (long) val); 299 break; 300 301 case DW_CFA_def_cfa_offset_sf: 302 if ((ret = dwarf_read_sleb128 (as, a, addr, &val, arg)) < 0) 303 goto fail; 304 set_reg (sr, DWARF_CFA_OFF_COLUMN, 0, 305 val * dci->data_align); /* factored! */ 306 Debug (15, "CFA_def_cfa_offset_sf 0x%lx\n", 307 (long) (val * dci->data_align)); 308 break; 309 310 case DW_CFA_def_cfa_expression: 311 /* Save the address of the DW_FORM_block for later evaluation. */ 312 set_reg (sr, DWARF_CFA_REG_COLUMN, DWARF_WHERE_EXPR, *addr); 313 314 if ((ret = dwarf_read_uleb128 (as, a, addr, &len, arg)) < 0) 315 goto fail; 316 317 Debug (15, "CFA_def_cfa_expr @ 0x%lx [%lu bytes]\n", 318 (long) *addr, (long) len); 319 *addr += len; 320 break; 321 322 case DW_CFA_expression: 323 if ((ret = read_regnum (as, a, addr, ®num, arg)) < 0) 324 goto fail; 325 326 /* Save the address of the DW_FORM_block for later evaluation. */ 327 set_reg (sr, regnum, DWARF_WHERE_EXPR, *addr); 328 329 if ((ret = dwarf_read_uleb128 (as, a, addr, &len, arg)) < 0) 330 goto fail; 331 332 Debug (15, "CFA_expression r%lu @ 0x%lx [%lu bytes]\n", 333 (long) regnum, (long) addr, (long) len); 334 *addr += len; 335 break; 336 337 case DW_CFA_GNU_args_size: 338 if ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0) 339 goto fail; 340 sr->args_size = val; 341 Debug (15, "CFA_GNU_args_size %lu\n", (long) val); 342 break; 343 344 case DW_CFA_GNU_negative_offset_extended: 345 /* A comment in GCC says that this is obsoleted by 346 DW_CFA_offset_extended_sf, but that it's used by older 347 PowerPC code. */ 348 if (((ret = read_regnum (as, a, addr, ®num, arg)) < 0) 349 || ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0)) 350 goto fail; 351 set_reg (sr, regnum, DWARF_WHERE_CFAREL, -(val * dci->data_align)); 352 Debug (15, "CFA_GNU_negative_offset_extended cfa+0x%lx\n", 353 (long) -(val * dci->data_align)); 354 break; 355 356 case DW_CFA_GNU_window_save: 357 #ifdef UNW_TARGET_SPARC 358 /* This is a special CFA to handle all 16 windowed registers 359 on SPARC. */ 360 for (regnum = 16; regnum < 32; ++regnum) 361 set_reg (sr, regnum, DWARF_WHERE_CFAREL, 362 (regnum - 16) * sizeof (unw_word_t)); 363 Debug (15, "CFA_GNU_window_save\n"); 364 break; 365 #else 366 /* FALL THROUGH */ 367 #endif 368 case DW_CFA_lo_user: 369 case DW_CFA_hi_user: 370 Debug (1, "Unexpected CFA opcode 0x%x\n", op); 371 ret = -UNW_EINVAL; 372 goto fail; 373 } 374 } 375 ret = 0; 376 377 fail: 378 /* Free the register-state stack, if not empty already. */ 379 while (rs_stack) 380 { 381 old_rs = rs_stack; 382 rs_stack = rs_stack->next; 383 free_reg_state (old_rs); 384 } 385 return ret; 386 } 387 388 static int 389 fetch_proc_info (struct dwarf_cursor *c, unw_word_t ip, int need_unwind_info) 390 { 391 int ret, dynamic = 1; 392 393 /* The 'ip' can point either to the previous or next instruction 394 depending on what type of frame we have: normal call or a place 395 to resume execution (e.g. after signal frame). 396 397 For a normal call frame we need to back up so we point within the 398 call itself; this is important because a) the call might be the 399 very last instruction of the function and the edge of the FDE, 400 and b) so that run_cfi_program() runs locations up to the call 401 but not more. 402 403 For execution resume, we need to do the exact opposite and look 404 up using the current 'ip' value. That is where execution will 405 continue, and it's important we get this right, as 'ip' could be 406 right at the function entry and hence FDE edge, or at instruction 407 that manipulates CFA (push/pop). */ 408 if (c->use_prev_instr) 409 --ip; 410 411 if (c->pi_valid && !need_unwind_info) 412 return 0; 413 414 memset (&c->pi, 0, sizeof (c->pi)); 415 416 /* check dynamic info first --- it overrides everything else */ 417 ret = unwi_find_dynamic_proc_info (c->as, ip, &c->pi, need_unwind_info, 418 c->as_arg); 419 if (ret == -UNW_ENOINFO) 420 { 421 dynamic = 0; 422 if ((ret = tdep_find_proc_info (c, ip, need_unwind_info)) < 0) 423 return ret; 424 } 425 426 if (c->pi.format != UNW_INFO_FORMAT_DYNAMIC 427 && c->pi.format != UNW_INFO_FORMAT_TABLE 428 && c->pi.format != UNW_INFO_FORMAT_REMOTE_TABLE) 429 return -UNW_ENOINFO; 430 431 c->pi_valid = 1; 432 c->pi_is_dynamic = dynamic; 433 434 /* Let system/machine-dependent code determine frame-specific attributes. */ 435 if (ret >= 0) 436 tdep_fetch_frame (c, ip, need_unwind_info); 437 438 /* Update use_prev_instr for the next frame. */ 439 if (need_unwind_info) 440 { 441 assert(c->pi.unwind_info); 442 struct dwarf_cie_info *dci = c->pi.unwind_info; 443 c->use_prev_instr = ! dci->signal_frame; 444 } 445 446 return ret; 447 } 448 449 static int 450 parse_dynamic (struct dwarf_cursor *c, unw_word_t ip, dwarf_state_record_t *sr) 451 { 452 Debug (1, "Not yet implemented\n"); 453 #if 0 454 /* Don't forget to set the ret_addr_column! */ 455 c->ret_addr_column = XXX; 456 #endif 457 return -UNW_ENOINFO; 458 } 459 460 static inline void 461 put_unwind_info (struct dwarf_cursor *c, unw_proc_info_t *pi) 462 { 463 if (c->pi_is_dynamic) 464 unwi_put_dynamic_unwind_info (c->as, pi, c->as_arg); 465 else if (pi->unwind_info && pi->format == UNW_INFO_FORMAT_TABLE) 466 { 467 mempool_free (&dwarf_cie_info_pool, pi->unwind_info); 468 pi->unwind_info = NULL; 469 } 470 } 471 472 static inline int 473 parse_fde (struct dwarf_cursor *c, unw_word_t ip, dwarf_state_record_t *sr) 474 { 475 struct dwarf_cie_info *dci; 476 unw_word_t addr; 477 int ret; 478 479 dci = c->pi.unwind_info; 480 c->ret_addr_column = dci->ret_addr_column; 481 482 addr = dci->cie_instr_start; 483 if ((ret = run_cfi_program (c, sr, ~(unw_word_t) 0, &addr, 484 dci->cie_instr_end, dci)) < 0) 485 return ret; 486 487 memcpy (&sr->rs_initial, &sr->rs_current, sizeof (sr->rs_initial)); 488 489 addr = dci->fde_instr_start; 490 if ((ret = run_cfi_program (c, sr, ip, &addr, dci->fde_instr_end, dci)) < 0) 491 return ret; 492 493 return 0; 494 } 495 496 static inline void 497 flush_rs_cache (struct dwarf_rs_cache *cache) 498 { 499 int i; 500 501 cache->lru_head = DWARF_UNW_CACHE_SIZE - 1; 502 cache->lru_tail = 0; 503 504 for (i = 0; i < DWARF_UNW_CACHE_SIZE; ++i) 505 { 506 if (i > 0) 507 cache->buckets[i].lru_chain = (i - 1); 508 cache->buckets[i].coll_chain = -1; 509 cache->buckets[i].ip = 0; 510 cache->buckets[i].valid = 0; 511 } 512 for (i = 0; i<DWARF_UNW_HASH_SIZE; ++i) 513 cache->hash[i] = -1; 514 } 515 516 static inline struct dwarf_rs_cache * 517 get_rs_cache (unw_addr_space_t as, intrmask_t *saved_maskp) 518 { 519 struct dwarf_rs_cache *cache = &as->global_cache; 520 unw_caching_policy_t caching = as->caching_policy; 521 522 if (caching == UNW_CACHE_NONE) 523 return NULL; 524 525 if (likely (caching == UNW_CACHE_GLOBAL)) 526 { 527 Debug (16, "acquiring lock\n"); 528 lock_acquire (&cache->lock, *saved_maskp); 529 } 530 531 if (atomic_read (&as->cache_generation) != atomic_read (&cache->generation)) 532 { 533 flush_rs_cache (cache); 534 cache->generation = as->cache_generation; 535 } 536 537 return cache; 538 } 539 540 static inline void 541 put_rs_cache (unw_addr_space_t as, struct dwarf_rs_cache *cache, 542 intrmask_t *saved_maskp) 543 { 544 assert (as->caching_policy != UNW_CACHE_NONE); 545 546 Debug (16, "unmasking signals/interrupts and releasing lock\n"); 547 if (likely (as->caching_policy == UNW_CACHE_GLOBAL)) 548 lock_release (&cache->lock, *saved_maskp); 549 } 550 551 static inline unw_hash_index_t CONST_ATTR 552 hash (unw_word_t ip) 553 { 554 /* based on (sqrt(5)/2-1)*2^64 */ 555 # define magic ((unw_word_t) 0x9e3779b97f4a7c16ULL) 556 557 return ip * magic >> ((sizeof(unw_word_t) * 8) - DWARF_LOG_UNW_HASH_SIZE); 558 } 559 560 static inline long 561 cache_match (dwarf_reg_state_t *rs, unw_word_t ip) 562 { 563 if (rs->valid && (ip == rs->ip)) 564 return 1; 565 return 0; 566 } 567 568 static dwarf_reg_state_t * 569 rs_lookup (struct dwarf_rs_cache *cache, struct dwarf_cursor *c) 570 { 571 dwarf_reg_state_t *rs = cache->buckets + c->hint; 572 unsigned short index; 573 unw_word_t ip; 574 575 ip = c->ip; 576 577 if (cache_match (rs, ip)) 578 return rs; 579 580 index = cache->hash[hash (ip)]; 581 if (index >= DWARF_UNW_CACHE_SIZE) 582 return NULL; 583 584 rs = cache->buckets + index; 585 while (1) 586 { 587 if (cache_match (rs, ip)) 588 { 589 /* update hint; no locking needed: single-word writes are atomic */ 590 c->hint = cache->buckets[c->prev_rs].hint = 591 (rs - cache->buckets); 592 return rs; 593 } 594 if (rs->coll_chain >= DWARF_UNW_HASH_SIZE) 595 return NULL; 596 rs = cache->buckets + rs->coll_chain; 597 } 598 } 599 600 static inline dwarf_reg_state_t * 601 rs_new (struct dwarf_rs_cache *cache, struct dwarf_cursor * c) 602 { 603 dwarf_reg_state_t *rs, *prev, *tmp; 604 unw_hash_index_t index; 605 unsigned short head; 606 607 head = cache->lru_head; 608 rs = cache->buckets + head; 609 cache->lru_head = rs->lru_chain; 610 611 /* re-insert rs at the tail of the LRU chain: */ 612 cache->buckets[cache->lru_tail].lru_chain = head; 613 cache->lru_tail = head; 614 615 /* remove the old rs from the hash table (if it's there): */ 616 if (rs->ip) 617 { 618 index = hash (rs->ip); 619 tmp = cache->buckets + cache->hash[index]; 620 prev = NULL; 621 while (1) 622 { 623 if (tmp == rs) 624 { 625 if (prev) 626 prev->coll_chain = tmp->coll_chain; 627 else 628 cache->hash[index] = tmp->coll_chain; 629 break; 630 } 631 else 632 prev = tmp; 633 if (tmp->coll_chain >= DWARF_UNW_CACHE_SIZE) 634 /* old rs wasn't in the hash-table */ 635 break; 636 tmp = cache->buckets + tmp->coll_chain; 637 } 638 } 639 640 /* enter new rs in the hash table */ 641 index = hash (c->ip); 642 rs->coll_chain = cache->hash[index]; 643 cache->hash[index] = rs - cache->buckets; 644 645 rs->hint = 0; 646 rs->ip = c->ip; 647 rs->valid = 1; 648 rs->ret_addr_column = c->ret_addr_column; 649 rs->signal_frame = 0; 650 tdep_cache_frame (c, rs); 651 652 return rs; 653 } 654 655 static int 656 create_state_record_for (struct dwarf_cursor *c, dwarf_state_record_t *sr, 657 unw_word_t ip) 658 { 659 int i, ret; 660 661 assert (c->pi_valid); 662 663 memset (sr, 0, sizeof (*sr)); 664 for (i = 0; i < DWARF_NUM_PRESERVED_REGS + 2; ++i) 665 set_reg (sr, i, DWARF_WHERE_SAME, 0); 666 667 switch (c->pi.format) 668 { 669 case UNW_INFO_FORMAT_TABLE: 670 case UNW_INFO_FORMAT_REMOTE_TABLE: 671 ret = parse_fde (c, ip, sr); 672 break; 673 674 case UNW_INFO_FORMAT_DYNAMIC: 675 ret = parse_dynamic (c, ip, sr); 676 break; 677 678 default: 679 Debug (1, "Unexpected unwind-info format %d\n", c->pi.format); 680 ret = -UNW_EINVAL; 681 } 682 return ret; 683 } 684 685 static inline int 686 eval_location_expr (struct dwarf_cursor *c, unw_addr_space_t as, 687 unw_accessors_t *a, unw_word_t addr, 688 dwarf_loc_t *locp, void *arg) 689 { 690 int ret, is_register; 691 unw_word_t len, val; 692 693 /* read the length of the expression: */ 694 if ((ret = dwarf_read_uleb128 (as, a, &addr, &len, arg)) < 0) 695 return ret; 696 697 /* evaluate the expression: */ 698 if ((ret = dwarf_eval_expr (c, &addr, len, &val, &is_register)) < 0) 699 return ret; 700 701 if (is_register) 702 *locp = DWARF_REG_LOC (c, dwarf_to_unw_regnum (val)); 703 else 704 *locp = DWARF_MEM_LOC (c, val); 705 706 return 0; 707 } 708 709 static int 710 apply_reg_state (struct dwarf_cursor *c, struct dwarf_reg_state *rs) 711 { 712 unw_word_t regnum, addr, cfa, ip; 713 unw_word_t prev_ip, prev_cfa; 714 unw_addr_space_t as; 715 dwarf_loc_t cfa_loc; 716 unw_accessors_t *a; 717 int i, ret; 718 void *arg; 719 720 prev_ip = c->ip; 721 prev_cfa = c->cfa; 722 723 as = c->as; 724 arg = c->as_arg; 725 a = unw_get_accessors (as); 726 727 /* Evaluate the CFA first, because it may be referred to by other 728 expressions. */ 729 730 if (rs->reg[DWARF_CFA_REG_COLUMN].where == DWARF_WHERE_REG) 731 { 732 /* CFA is equal to [reg] + offset: */ 733 734 /* As a special-case, if the stack-pointer is the CFA and the 735 stack-pointer wasn't saved, popping the CFA implicitly pops 736 the stack-pointer as well. */ 737 if ((rs->reg[DWARF_CFA_REG_COLUMN].val == UNW_TDEP_SP) 738 && (UNW_TDEP_SP < ARRAY_SIZE(rs->reg)) 739 && (rs->reg[UNW_TDEP_SP].where == DWARF_WHERE_SAME)) 740 cfa = c->cfa; 741 else 742 { 743 regnum = dwarf_to_unw_regnum (rs->reg[DWARF_CFA_REG_COLUMN].val); 744 if ((ret = unw_get_reg ((unw_cursor_t *) c, regnum, &cfa)) < 0) 745 return ret; 746 } 747 cfa += rs->reg[DWARF_CFA_OFF_COLUMN].val; 748 } 749 else 750 { 751 /* CFA is equal to EXPR: */ 752 753 assert (rs->reg[DWARF_CFA_REG_COLUMN].where == DWARF_WHERE_EXPR); 754 755 addr = rs->reg[DWARF_CFA_REG_COLUMN].val; 756 if ((ret = eval_location_expr (c, as, a, addr, &cfa_loc, arg)) < 0) 757 return ret; 758 /* the returned location better be a memory location... */ 759 if (DWARF_IS_REG_LOC (cfa_loc)) 760 return -UNW_EBADFRAME; 761 cfa = DWARF_GET_LOC (cfa_loc); 762 } 763 764 for (i = 0; i < DWARF_NUM_PRESERVED_REGS; ++i) 765 { 766 switch ((dwarf_where_t) rs->reg[i].where) 767 { 768 case DWARF_WHERE_UNDEF: 769 c->loc[i] = DWARF_NULL_LOC; 770 break; 771 772 case DWARF_WHERE_SAME: 773 break; 774 775 case DWARF_WHERE_CFAREL: 776 c->loc[i] = DWARF_MEM_LOC (c, cfa + rs->reg[i].val); 777 break; 778 779 case DWARF_WHERE_REG: 780 c->loc[i] = DWARF_REG_LOC (c, dwarf_to_unw_regnum (rs->reg[i].val)); 781 break; 782 783 case DWARF_WHERE_EXPR: 784 addr = rs->reg[i].val; 785 if ((ret = eval_location_expr (c, as, a, addr, c->loc + i, arg)) < 0) 786 return ret; 787 break; 788 } 789 } 790 791 c->cfa = cfa; 792 /* DWARF spec says undefined return address location means end of stack. */ 793 if (DWARF_IS_NULL_LOC (c->loc[c->ret_addr_column])) 794 c->ip = 0; 795 else 796 { 797 ret = dwarf_get (c, c->loc[c->ret_addr_column], &ip); 798 if (ret < 0) 799 return ret; 800 c->ip = ip; 801 } 802 803 /* XXX: check for ip to be code_aligned */ 804 if (c->ip == prev_ip && c->cfa == prev_cfa) 805 { 806 Dprintf ("%s: ip and cfa unchanged; stopping here (ip=0x%lx)\n", 807 __FUNCTION__, (long) c->ip); 808 return -UNW_EBADFRAME; 809 } 810 811 if (c->stash_frames) 812 tdep_stash_frame (c, rs); 813 814 return 0; 815 } 816 817 static int 818 uncached_dwarf_find_save_locs (struct dwarf_cursor *c) 819 { 820 dwarf_state_record_t sr; 821 int ret; 822 823 if ((ret = fetch_proc_info (c, c->ip, 1)) < 0) 824 { 825 put_unwind_info (c, &c->pi); 826 return ret; 827 } 828 829 if ((ret = create_state_record_for (c, &sr, c->ip)) < 0) 830 { 831 /* ANDROID support update. */ 832 put_unwind_info (c, &c->pi); 833 /* End of ANDROID update. */ 834 return ret; 835 } 836 837 if ((ret = apply_reg_state (c, &sr.rs_current)) < 0) 838 { 839 /* ANDROID support update. */ 840 put_unwind_info (c, &c->pi); 841 /* End of ANDROID update. */ 842 return ret; 843 } 844 845 put_unwind_info (c, &c->pi); 846 return 0; 847 } 848 849 /* The function finds the saved locations and applies the register 850 state as well. */ 851 HIDDEN int 852 dwarf_find_save_locs (struct dwarf_cursor *c) 853 { 854 #if defined(CONSERVE_STACK) 855 dwarf_reg_state_t *rs_copy; 856 #else 857 dwarf_reg_state_t rs_copy_stack; 858 dwarf_reg_state_t *rs_copy = &rs_copy_stack; 859 #endif 860 dwarf_reg_state_t *rs; 861 struct dwarf_rs_cache *cache; 862 int ret = 0; 863 intrmask_t saved_mask; 864 865 if (c->as->caching_policy == UNW_CACHE_NONE) 866 return uncached_dwarf_find_save_locs (c); 867 868 cache = get_rs_cache(c->as, &saved_mask); 869 rs = rs_lookup(cache, c); 870 871 if (rs) 872 { 873 c->ret_addr_column = rs->ret_addr_column; 874 c->use_prev_instr = ! rs->signal_frame; 875 } 876 else 877 { 878 #if !defined(CONSERVE_STACK) 879 dwarf_state_record_t sr_stack; 880 dwarf_state_record_t *sr = &sr_stack; 881 #else 882 dwarf_state_record_t *sr = (dwarf_state_record_t*)malloc(sizeof(dwarf_state_record_t)); 883 884 if (sr == NULL) 885 return -UNW_ENOMEM; 886 #endif 887 888 if ((ret = fetch_proc_info (c, c->ip, 1)) < 0 || 889 (ret = create_state_record_for (c, sr, c->ip)) < 0) 890 { 891 put_rs_cache (c->as, cache, &saved_mask); 892 put_unwind_info (c, &c->pi); 893 #if defined(CONSERVE_STACK) 894 free(sr); 895 #endif 896 return ret; 897 } 898 899 rs = rs_new (cache, c); 900 memcpy(rs, &sr->rs_current, offsetof(struct dwarf_reg_state, ip)); 901 cache->buckets[c->prev_rs].hint = rs - cache->buckets; 902 903 c->hint = rs->hint; 904 c->prev_rs = rs - cache->buckets; 905 906 put_unwind_info (c, &c->pi); 907 908 #if defined(CONSERVE_STACK) 909 free(sr); 910 #endif 911 } 912 913 #if defined(CONSERVE_STACK) 914 rs_copy = (dwarf_reg_state_t*)malloc(sizeof(dwarf_reg_state_t)); 915 if (rs_copy == NULL) 916 return -UNW_ENOMEM; 917 #endif 918 919 memcpy (rs_copy, rs, sizeof (*rs_copy)); 920 put_rs_cache (c->as, cache, &saved_mask); 921 922 tdep_reuse_frame (c, rs_copy); 923 ret = apply_reg_state (c, rs_copy); 924 925 #if defined(CONSERVE_STACK) 926 free(rs_copy); 927 #endif 928 929 return ret; 930 } 931 932 /* The proc-info must be valid for IP before this routine can be 933 called. */ 934 HIDDEN int 935 dwarf_create_state_record (struct dwarf_cursor *c, dwarf_state_record_t *sr) 936 { 937 return create_state_record_for (c, sr, c->ip); 938 } 939 940 HIDDEN int 941 dwarf_make_proc_info (struct dwarf_cursor *c) 942 { 943 #if 0 944 if (c->as->caching_policy == UNW_CACHE_NONE 945 || get_cached_proc_info (c) < 0) 946 #endif 947 /* Lookup it up the slow way... */ 948 return fetch_proc_info (c, c->ip, 0); 949 return 0; 950 } 951