1 /* Return location expression list. 2 Copyright (C) 2000-2010, 2013-2015, 2017, 2018 Red Hat, Inc. 3 This file is part of elfutils. 4 5 This file is free software; you can redistribute it and/or modify 6 it under the terms of either 7 8 * the GNU Lesser General Public License as published by the Free 9 Software Foundation; either version 3 of the License, or (at 10 your option) any later version 11 12 or 13 14 * the GNU General Public License as published by the Free 15 Software Foundation; either version 2 of the License, or (at 16 your option) any later version 17 18 or both in parallel, as here. 19 20 elfutils is distributed in the hope that it will be useful, but 21 WITHOUT ANY WARRANTY; without even the implied warranty of 22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 23 General Public License for more details. 24 25 You should have received copies of the GNU General Public License and 26 the GNU Lesser General Public License along with this program. If 27 not, see <http://www.gnu.org/licenses/>. */ 28 29 #ifdef HAVE_CONFIG_H 30 # include <config.h> 31 #endif 32 33 #include <dwarf.h> 34 #include <search.h> 35 #include <stdlib.h> 36 #include <assert.h> 37 38 #include <libdwP.h> 39 40 41 static bool 42 attr_ok (Dwarf_Attribute *attr) 43 { 44 if (attr == NULL) 45 return false; 46 47 /* If it is an exprloc, it is obviously OK. */ 48 if (dwarf_whatform (attr) == DW_FORM_exprloc) 49 return true; 50 51 /* Otherwise must be one of the attributes listed below. Older 52 DWARF versions might have encoded the exprloc as block, and we 53 cannot easily distinquish attributes in the loclist class because 54 the same forms are used for different classes. */ 55 switch (attr->code) 56 { 57 case DW_AT_location: 58 case DW_AT_byte_size: 59 case DW_AT_bit_offset: 60 case DW_AT_bit_size: 61 case DW_AT_lower_bound: 62 case DW_AT_bit_stride: 63 case DW_AT_upper_bound: 64 case DW_AT_count: 65 case DW_AT_allocated: 66 case DW_AT_associated: 67 case DW_AT_data_location: 68 case DW_AT_byte_stride: 69 case DW_AT_rank: 70 case DW_AT_call_value: 71 case DW_AT_call_target: 72 case DW_AT_call_target_clobbered: 73 case DW_AT_call_data_location: 74 case DW_AT_call_data_value: 75 case DW_AT_data_member_location: 76 case DW_AT_vtable_elem_location: 77 case DW_AT_string_length: 78 case DW_AT_use_location: 79 case DW_AT_frame_base: 80 case DW_AT_return_addr: 81 case DW_AT_static_link: 82 case DW_AT_segment: 83 case DW_AT_GNU_call_site_value: 84 case DW_AT_GNU_call_site_data_value: 85 case DW_AT_GNU_call_site_target: 86 case DW_AT_GNU_call_site_target_clobbered: 87 break; 88 89 default: 90 __libdw_seterrno (DWARF_E_NO_LOC_VALUE); 91 return false; 92 } 93 94 return true; 95 } 96 97 98 struct loclist 99 { 100 uint8_t atom; 101 Dwarf_Word number; 102 Dwarf_Word number2; 103 Dwarf_Word offset; 104 struct loclist *next; 105 }; 106 107 108 static int 109 loc_compare (const void *p1, const void *p2) 110 { 111 const struct loc_s *l1 = (const struct loc_s *) p1; 112 const struct loc_s *l2 = (const struct loc_s *) p2; 113 114 if ((uintptr_t) l1->addr < (uintptr_t) l2->addr) 115 return -1; 116 if ((uintptr_t) l1->addr > (uintptr_t) l2->addr) 117 return 1; 118 119 return 0; 120 } 121 122 /* For each DW_OP_implicit_value, we store a special entry in the cache. 123 This points us directly to the block data for later fetching. 124 Returns zero on success, -1 on bad DWARF or 1 if tsearch failed. */ 125 static int 126 store_implicit_value (Dwarf *dbg, void **cache, Dwarf_Op *op) 127 { 128 struct loc_block_s *block = libdw_alloc (dbg, struct loc_block_s, 129 sizeof (struct loc_block_s), 1); 130 const unsigned char *data = (const unsigned char *) (uintptr_t) op->number2; 131 uint64_t len = __libdw_get_uleb128 (&data, data + len_leb128 (Dwarf_Word)); 132 if (unlikely (len != op->number)) 133 return -1; 134 block->addr = op; 135 block->data = (unsigned char *) data; 136 block->length = op->number; 137 if (unlikely (tsearch (block, cache, loc_compare) == NULL)) 138 return 1; 139 return 0; 140 } 141 142 int 143 dwarf_getlocation_implicit_value (Dwarf_Attribute *attr, const Dwarf_Op *op, 144 Dwarf_Block *return_block) 145 { 146 if (attr == NULL) 147 return -1; 148 149 struct loc_block_s fake = { .addr = (void *) op }; 150 struct loc_block_s **found = tfind (&fake, &attr->cu->locs, loc_compare); 151 if (unlikely (found == NULL)) 152 { 153 __libdw_seterrno (DWARF_E_NO_BLOCK); 154 return -1; 155 } 156 157 return_block->length = (*found)->length; 158 return_block->data = (*found)->data; 159 return 0; 160 } 161 162 /* DW_AT_data_member_location can be a constant as well as a loclistptr. 163 Only data[48] indicate a loclistptr. */ 164 static int 165 check_constant_offset (Dwarf_Attribute *attr, 166 Dwarf_Op **llbuf, size_t *listlen) 167 { 168 if (attr->code != DW_AT_data_member_location) 169 return 1; 170 171 switch (attr->form) 172 { 173 /* Punt for any non-constant form. */ 174 default: 175 return 1; 176 177 /* Note, we don't regard DW_FORM_data16 as a constant form, 178 even though technically it is according to the standard. */ 179 case DW_FORM_data1: 180 case DW_FORM_data2: 181 case DW_FORM_data4: 182 case DW_FORM_data8: 183 case DW_FORM_sdata: 184 case DW_FORM_udata: 185 break; 186 } 187 188 /* Check whether we already cached this location. */ 189 struct loc_s fake = { .addr = attr->valp }; 190 struct loc_s **found = tfind (&fake, &attr->cu->locs, loc_compare); 191 192 if (found == NULL) 193 { 194 Dwarf_Word offset; 195 if (INTUSE(dwarf_formudata) (attr, &offset) != 0) 196 return -1; 197 198 Dwarf_Op *result = libdw_alloc (attr->cu->dbg, 199 Dwarf_Op, sizeof (Dwarf_Op), 1); 200 201 result->atom = DW_OP_plus_uconst; 202 result->number = offset; 203 result->number2 = 0; 204 result->offset = 0; 205 206 /* Insert a record in the search tree so we can find it again later. */ 207 struct loc_s *newp = libdw_alloc (attr->cu->dbg, 208 struct loc_s, sizeof (struct loc_s), 209 1); 210 newp->addr = attr->valp; 211 newp->loc = result; 212 newp->nloc = 1; 213 214 found = tsearch (newp, &attr->cu->locs, loc_compare); 215 } 216 217 assert ((*found)->nloc == 1); 218 219 if (llbuf != NULL) 220 { 221 *llbuf = (*found)->loc; 222 *listlen = 1; 223 } 224 225 return 0; 226 } 227 228 int 229 internal_function 230 __libdw_intern_expression (Dwarf *dbg, bool other_byte_order, 231 unsigned int address_size, unsigned int ref_size, 232 void **cache, const Dwarf_Block *block, 233 bool cfap, bool valuep, 234 Dwarf_Op **llbuf, size_t *listlen, int sec_index) 235 { 236 /* Empty location expressions don't have any ops to intern. */ 237 if (block->length == 0) 238 { 239 *listlen = 0; 240 return 0; 241 } 242 243 /* Check whether we already looked at this list. */ 244 struct loc_s fake = { .addr = block->data }; 245 struct loc_s **found = tfind (&fake, cache, loc_compare); 246 if (found != NULL) 247 { 248 /* We already saw it. */ 249 *llbuf = (*found)->loc; 250 *listlen = (*found)->nloc; 251 252 if (valuep) 253 { 254 assert (*listlen > 1); 255 assert ((*llbuf)[*listlen - 1].atom == DW_OP_stack_value); 256 } 257 258 return 0; 259 } 260 261 const unsigned char *data = block->data; 262 const unsigned char *const end_data = data + block->length; 263 264 const struct { bool other_byte_order; } bo = { other_byte_order }; 265 266 struct loclist *loclist = NULL; 267 unsigned int n = 0; 268 269 /* Stack allocate at most this many locs. */ 270 #define MAX_STACK_LOCS 256 271 struct loclist stack_locs[MAX_STACK_LOCS]; 272 #define NEW_LOC() ({ struct loclist *ll; \ 273 ll = (likely (n < MAX_STACK_LOCS) \ 274 ? &stack_locs[n] \ 275 : malloc (sizeof (struct loclist))); \ 276 if (unlikely (ll == NULL)) \ 277 goto nomem; \ 278 n++; \ 279 ll->next = loclist; \ 280 loclist = ll; \ 281 ll; }) 282 283 if (cfap) 284 { 285 /* Synthesize the operation to push the CFA before the expression. */ 286 struct loclist *newloc = NEW_LOC (); 287 newloc->atom = DW_OP_call_frame_cfa; 288 newloc->number = 0; 289 newloc->number2 = 0; 290 newloc->offset = -1; 291 } 292 293 /* Decode the opcodes. It is possible in some situations to have a 294 block of size zero. */ 295 while (data < end_data) 296 { 297 struct loclist *newloc; 298 newloc = NEW_LOC (); 299 newloc->number = 0; 300 newloc->number2 = 0; 301 newloc->offset = data - block->data; 302 303 switch ((newloc->atom = *data++)) 304 { 305 case DW_OP_addr: 306 /* Address, depends on address size of CU. */ 307 if (dbg == NULL) 308 { 309 // XXX relocation? 310 if (address_size == 4) 311 { 312 if (unlikely (data + 4 > end_data)) 313 goto invalid; 314 else 315 newloc->number = read_4ubyte_unaligned_inc (&bo, data); 316 } 317 else 318 { 319 if (unlikely (data + 8 > end_data)) 320 goto invalid; 321 else 322 newloc->number = read_8ubyte_unaligned_inc (&bo, data); 323 } 324 } 325 else if (__libdw_read_address_inc (dbg, sec_index, &data, 326 address_size, &newloc->number)) 327 goto invalid; 328 break; 329 330 case DW_OP_call_ref: 331 case DW_OP_GNU_variable_value: 332 /* DW_FORM_ref_addr, depends on offset size of CU. */ 333 if (dbg == NULL || __libdw_read_offset_inc (dbg, sec_index, &data, 334 ref_size, 335 &newloc->number, 336 IDX_debug_info, 0)) 337 goto invalid; 338 break; 339 340 case DW_OP_deref: 341 case DW_OP_dup: 342 case DW_OP_drop: 343 case DW_OP_over: 344 case DW_OP_swap: 345 case DW_OP_rot: 346 case DW_OP_xderef: 347 case DW_OP_abs: 348 case DW_OP_and: 349 case DW_OP_div: 350 case DW_OP_minus: 351 case DW_OP_mod: 352 case DW_OP_mul: 353 case DW_OP_neg: 354 case DW_OP_not: 355 case DW_OP_or: 356 case DW_OP_plus: 357 case DW_OP_shl: 358 case DW_OP_shr: 359 case DW_OP_shra: 360 case DW_OP_xor: 361 case DW_OP_eq: 362 case DW_OP_ge: 363 case DW_OP_gt: 364 case DW_OP_le: 365 case DW_OP_lt: 366 case DW_OP_ne: 367 case DW_OP_lit0 ... DW_OP_lit31: 368 case DW_OP_reg0 ... DW_OP_reg31: 369 case DW_OP_nop: 370 case DW_OP_push_object_address: 371 case DW_OP_call_frame_cfa: 372 case DW_OP_form_tls_address: 373 case DW_OP_GNU_push_tls_address: 374 case DW_OP_stack_value: 375 /* No operand. */ 376 break; 377 378 case DW_OP_const1u: 379 case DW_OP_pick: 380 case DW_OP_deref_size: 381 case DW_OP_xderef_size: 382 if (unlikely (data >= end_data)) 383 { 384 invalid: 385 __libdw_seterrno (DWARF_E_INVALID_DWARF); 386 returnmem: 387 /* Free any dynamicly allocated loclists, if any. */ 388 while (n > MAX_STACK_LOCS) 389 { 390 struct loclist *loc = loclist; 391 loclist = loc->next; 392 free (loc); 393 n--; 394 } 395 return -1; 396 } 397 398 newloc->number = *data++; 399 break; 400 401 case DW_OP_const1s: 402 if (unlikely (data >= end_data)) 403 goto invalid; 404 405 newloc->number = *((int8_t *) data); 406 ++data; 407 break; 408 409 case DW_OP_const2u: 410 if (unlikely (data + 2 > end_data)) 411 goto invalid; 412 413 newloc->number = read_2ubyte_unaligned_inc (&bo, data); 414 break; 415 416 case DW_OP_const2s: 417 case DW_OP_skip: 418 case DW_OP_bra: 419 case DW_OP_call2: 420 if (unlikely (data + 2 > end_data)) 421 goto invalid; 422 423 newloc->number = read_2sbyte_unaligned_inc (&bo, data); 424 break; 425 426 case DW_OP_const4u: 427 if (unlikely (data + 4 > end_data)) 428 goto invalid; 429 430 newloc->number = read_4ubyte_unaligned_inc (&bo, data); 431 break; 432 433 case DW_OP_const4s: 434 case DW_OP_call4: 435 case DW_OP_GNU_parameter_ref: 436 if (unlikely (data + 4 > end_data)) 437 goto invalid; 438 439 newloc->number = read_4sbyte_unaligned_inc (&bo, data); 440 break; 441 442 case DW_OP_const8u: 443 if (unlikely (data + 8 > end_data)) 444 goto invalid; 445 446 newloc->number = read_8ubyte_unaligned_inc (&bo, data); 447 break; 448 449 case DW_OP_const8s: 450 if (unlikely (data + 8 > end_data)) 451 goto invalid; 452 453 newloc->number = read_8sbyte_unaligned_inc (&bo, data); 454 break; 455 456 case DW_OP_constu: 457 case DW_OP_plus_uconst: 458 case DW_OP_regx: 459 case DW_OP_piece: 460 case DW_OP_convert: 461 case DW_OP_GNU_convert: 462 case DW_OP_reinterpret: 463 case DW_OP_GNU_reinterpret: 464 case DW_OP_addrx: 465 case DW_OP_GNU_addr_index: 466 case DW_OP_constx: 467 case DW_OP_GNU_const_index: 468 get_uleb128 (newloc->number, data, end_data); 469 break; 470 471 case DW_OP_consts: 472 case DW_OP_breg0 ... DW_OP_breg31: 473 case DW_OP_fbreg: 474 get_sleb128 (newloc->number, data, end_data); 475 break; 476 477 case DW_OP_bregx: 478 get_uleb128 (newloc->number, data, end_data); 479 if (unlikely (data >= end_data)) 480 goto invalid; 481 get_sleb128 (newloc->number2, data, end_data); 482 break; 483 484 case DW_OP_bit_piece: 485 case DW_OP_regval_type: 486 case DW_OP_GNU_regval_type: 487 get_uleb128 (newloc->number, data, end_data); 488 if (unlikely (data >= end_data)) 489 goto invalid; 490 get_uleb128 (newloc->number2, data, end_data); 491 break; 492 493 case DW_OP_implicit_value: 494 case DW_OP_entry_value: 495 case DW_OP_GNU_entry_value: 496 /* This cannot be used in a CFI expression. */ 497 if (unlikely (dbg == NULL)) 498 goto invalid; 499 500 /* start of block inc. len. */ 501 newloc->number2 = (Dwarf_Word) (uintptr_t) data; 502 get_uleb128 (newloc->number, data, end_data); /* Block length. */ 503 if (unlikely ((Dwarf_Word) (end_data - data) < newloc->number)) 504 goto invalid; 505 data += newloc->number; /* Skip the block. */ 506 break; 507 508 case DW_OP_implicit_pointer: 509 case DW_OP_GNU_implicit_pointer: 510 /* DW_FORM_ref_addr, depends on offset size of CU. */ 511 if (dbg == NULL || __libdw_read_offset_inc (dbg, sec_index, &data, 512 ref_size, 513 &newloc->number, 514 IDX_debug_info, 0)) 515 goto invalid; 516 if (unlikely (data >= end_data)) 517 goto invalid; 518 get_uleb128 (newloc->number2, data, end_data); /* Byte offset. */ 519 break; 520 521 case DW_OP_deref_type: 522 case DW_OP_GNU_deref_type: 523 case DW_OP_xderef_type: 524 if (unlikely (data + 1 >= end_data)) 525 goto invalid; 526 newloc->number = *data++; 527 get_uleb128 (newloc->number2, data, end_data); 528 break; 529 530 case DW_OP_const_type: 531 case DW_OP_GNU_const_type: 532 { 533 size_t size; 534 get_uleb128 (newloc->number, data, end_data); 535 if (unlikely (data >= end_data)) 536 goto invalid; 537 538 /* start of block inc. len. */ 539 newloc->number2 = (Dwarf_Word) (uintptr_t) data; 540 size = *data++; 541 if (unlikely ((Dwarf_Word) (end_data - data) < size)) 542 goto invalid; 543 data += size; /* Skip the block. */ 544 } 545 break; 546 547 default: 548 goto invalid; 549 } 550 } 551 552 if (unlikely (n == 0)) 553 { 554 /* This is not allowed. 555 It would mean an empty location expression, which we handled 556 already as a special case above. */ 557 goto invalid; 558 } 559 560 if (valuep) 561 { 562 struct loclist *newloc = NEW_LOC (); 563 newloc->atom = DW_OP_stack_value; 564 newloc->number = 0; 565 newloc->number2 = 0; 566 newloc->offset = data - block->data; 567 } 568 569 /* Allocate the array. */ 570 Dwarf_Op *result; 571 if (dbg != NULL) 572 result = libdw_alloc (dbg, Dwarf_Op, sizeof (Dwarf_Op), n); 573 else 574 { 575 result = malloc (sizeof *result * n); 576 if (result == NULL) 577 { 578 nomem: 579 __libdw_seterrno (DWARF_E_NOMEM); 580 goto returnmem; 581 } 582 } 583 584 /* Store the result. */ 585 *llbuf = result; 586 *listlen = n; 587 588 do 589 { 590 /* We populate the array from the back since the list is backwards. */ 591 --n; 592 result[n].atom = loclist->atom; 593 result[n].number = loclist->number; 594 result[n].number2 = loclist->number2; 595 result[n].offset = loclist->offset; 596 597 if (result[n].atom == DW_OP_implicit_value) 598 { 599 int store = store_implicit_value (dbg, cache, &result[n]); 600 if (unlikely (store != 0)) 601 { 602 if (store < 0) 603 goto invalid; 604 else 605 goto nomem; 606 } 607 } 608 609 struct loclist *loc = loclist; 610 loclist = loclist->next; 611 if (unlikely (n + 1 > MAX_STACK_LOCS)) 612 free (loc); 613 } 614 while (n > 0); 615 616 /* Insert a record in the search tree so that we can find it again later. */ 617 struct loc_s *newp; 618 if (dbg != NULL) 619 newp = libdw_alloc (dbg, struct loc_s, sizeof (struct loc_s), 1); 620 else 621 { 622 newp = malloc (sizeof *newp); 623 if (newp == NULL) 624 { 625 free (result); 626 goto nomem; 627 } 628 } 629 630 newp->addr = block->data; 631 newp->loc = result; 632 newp->nloc = *listlen; 633 (void) tsearch (newp, cache, loc_compare); 634 635 /* We did it. */ 636 return 0; 637 } 638 639 static int 640 getlocation (struct Dwarf_CU *cu, const Dwarf_Block *block, 641 Dwarf_Op **llbuf, size_t *listlen, int sec_index) 642 { 643 /* Empty location expressions don't have any ops to intern. 644 Note that synthetic empty_cu doesn't have an associated DWARF dbg. */ 645 if (block->length == 0) 646 { 647 *listlen = 0; 648 return 0; 649 } 650 651 return __libdw_intern_expression (cu->dbg, cu->dbg->other_byte_order, 652 cu->address_size, (cu->version == 2 653 ? cu->address_size 654 : cu->offset_size), 655 &cu->locs, block, 656 false, false, 657 llbuf, listlen, sec_index); 658 } 659 660 int 661 dwarf_getlocation (Dwarf_Attribute *attr, Dwarf_Op **llbuf, size_t *listlen) 662 { 663 if (! attr_ok (attr)) 664 return -1; 665 666 int result = check_constant_offset (attr, llbuf, listlen); 667 if (result != 1) 668 return result; 669 670 /* If it has a block form, it's a single location expression. 671 Except for DW_FORM_data16, which is a 128bit constant. */ 672 if (attr->form == DW_FORM_data16) 673 { 674 __libdw_seterrno (DWARF_E_NO_BLOCK); 675 return -1; 676 } 677 Dwarf_Block block; 678 if (INTUSE(dwarf_formblock) (attr, &block) != 0) 679 return -1; 680 681 return getlocation (attr->cu, &block, llbuf, listlen, cu_sec_idx (attr->cu)); 682 } 683 684 Dwarf_Addr 685 __libdw_cu_base_address (Dwarf_CU *cu) 686 { 687 if (cu->base_address == (Dwarf_Addr) -1) 688 { 689 Dwarf_Addr base; 690 691 /* Fetch the CU's base address. */ 692 Dwarf_Die cudie = CUDIE (cu); 693 694 /* Find the base address of the compilation unit. It will 695 normally be specified by DW_AT_low_pc. In DWARF-3 draft 4, 696 the base address could be overridden by DW_AT_entry_pc. It's 697 been removed, but GCC emits DW_AT_entry_pc and not DW_AT_lowpc 698 for compilation units with discontinuous ranges. */ 699 Dwarf_Attribute attr_mem; 700 if (INTUSE(dwarf_lowpc) (&cudie, &base) != 0 701 && INTUSE(dwarf_formaddr) (INTUSE(dwarf_attr) (&cudie, 702 DW_AT_entry_pc, 703 &attr_mem), 704 &base) != 0) 705 { 706 /* The compiler provided no base address when it should 707 have. Buggy GCC does this when it used absolute 708 addresses in the location list and no DW_AT_ranges. */ 709 base = 0; 710 } 711 cu->base_address = base; 712 } 713 714 return cu->base_address; 715 } 716 717 static int 718 initial_offset (Dwarf_Attribute *attr, ptrdiff_t *offset) 719 { 720 size_t secidx = (attr->cu->version < 5 721 ? IDX_debug_loc : IDX_debug_loclists); 722 723 Dwarf_Word start_offset; 724 if (attr->form == DW_FORM_loclistx) 725 { 726 Dwarf_Word idx; 727 Dwarf_CU *cu = attr->cu; 728 const unsigned char *datap = attr->valp; 729 const unsigned char *endp = cu->endp; 730 if (datap >= endp) 731 { 732 __libdw_seterrno (DWARF_E_INVALID_DWARF); 733 return -1; 734 } 735 get_uleb128 (idx, datap, endp); 736 737 Elf_Data *data = cu->dbg->sectiondata[secidx]; 738 if (data == NULL && cu->unit_type == DW_UT_split_compile) 739 { 740 cu = __libdw_find_split_unit (cu); 741 if (cu != NULL) 742 data = cu->dbg->sectiondata[secidx]; 743 } 744 745 if (data == NULL) 746 { 747 __libdw_seterrno (secidx == IDX_debug_loc 748 ? DWARF_E_NO_DEBUG_LOC 749 : DWARF_E_NO_DEBUG_LOCLISTS); 750 return -1; 751 } 752 753 Dwarf_Off loc_base_off = __libdw_cu_locs_base (cu); 754 755 /* The section should at least contain room for one offset. */ 756 size_t sec_size = cu->dbg->sectiondata[secidx]->d_size; 757 size_t offset_size = cu->offset_size; 758 if (offset_size > sec_size) 759 { 760 invalid_offset: 761 __libdw_seterrno (DWARF_E_INVALID_OFFSET); 762 return -1; 763 } 764 765 /* And the base offset should be at least inside the section. */ 766 if (loc_base_off > (sec_size - offset_size)) 767 goto invalid_offset; 768 769 size_t max_idx = (sec_size - offset_size - loc_base_off) / offset_size; 770 if (idx > max_idx) 771 goto invalid_offset; 772 773 datap = (cu->dbg->sectiondata[secidx]->d_buf 774 + loc_base_off + (idx * offset_size)); 775 if (offset_size == 4) 776 start_offset = read_4ubyte_unaligned (cu->dbg, datap); 777 else 778 start_offset = read_8ubyte_unaligned (cu->dbg, datap); 779 780 start_offset += loc_base_off; 781 } 782 else 783 { 784 if (__libdw_formptr (attr, secidx, 785 (secidx == IDX_debug_loc 786 ? DWARF_E_NO_DEBUG_LOC 787 : DWARF_E_NO_DEBUG_LOCLISTS), 788 NULL, &start_offset) == NULL) 789 return -1; 790 } 791 792 *offset = start_offset; 793 return 0; 794 } 795 796 static ptrdiff_t 797 getlocations_addr (Dwarf_Attribute *attr, ptrdiff_t offset, 798 Dwarf_Addr *basep, Dwarf_Addr *startp, Dwarf_Addr *endp, 799 Dwarf_Addr address, const Elf_Data *locs, Dwarf_Op **expr, 800 size_t *exprlen) 801 { 802 Dwarf_CU *cu = attr->cu; 803 Dwarf *dbg = cu->dbg; 804 size_t secidx = cu->version < 5 ? IDX_debug_loc : IDX_debug_loclists; 805 const unsigned char *readp = locs->d_buf + offset; 806 const unsigned char *readendp = locs->d_buf + locs->d_size; 807 808 Dwarf_Addr begin; 809 Dwarf_Addr end; 810 811 next: 812 switch (__libdw_read_begin_end_pair_inc (cu, secidx, 813 &readp, readendp, 814 cu->address_size, 815 &begin, &end, basep)) 816 { 817 case 0: /* got location range. */ 818 break; 819 case 1: /* base address setup. */ 820 goto next; 821 case 2: /* end of loclist */ 822 return 0; 823 default: /* error */ 824 return -1; 825 } 826 827 /* We have a location expression. */ 828 Dwarf_Block block; 829 if (secidx == IDX_debug_loc) 830 { 831 if (readendp - readp < 2) 832 { 833 invalid: 834 __libdw_seterrno (DWARF_E_INVALID_DWARF); 835 return -1; 836 } 837 block.length = read_2ubyte_unaligned_inc (dbg, readp); 838 } 839 else 840 { 841 if (readendp - readp < 1) 842 goto invalid; 843 get_uleb128 (block.length, readp, readendp); 844 } 845 block.data = (unsigned char *) readp; 846 if (readendp - readp < (ptrdiff_t) block.length) 847 goto invalid; 848 readp += block.length; 849 850 /* Note these addresses include any base (if necessary) already. */ 851 *startp = begin; 852 *endp = end; 853 854 /* If address is minus one we want them all, otherwise only matching. */ 855 if (address != (Dwarf_Word) -1 && (address < *startp || address >= *endp)) 856 goto next; 857 858 if (getlocation (cu, &block, expr, exprlen, secidx) != 0) 859 return -1; 860 861 return readp - (unsigned char *) locs->d_buf; 862 } 863 864 int 865 dwarf_getlocation_addr (Dwarf_Attribute *attr, Dwarf_Addr address, 866 Dwarf_Op **llbufs, size_t *listlens, size_t maxlocs) 867 { 868 if (! attr_ok (attr)) 869 return -1; 870 871 if (llbufs == NULL) 872 maxlocs = SIZE_MAX; 873 874 /* If it has a block form, it's a single location expression. 875 Except for DW_FORM_data16, which is a 128bit constant. */ 876 Dwarf_Block block; 877 if (attr->form != DW_FORM_data16 878 && INTUSE(dwarf_formblock) (attr, &block) == 0) 879 { 880 if (maxlocs == 0) 881 return 0; 882 if (llbufs != NULL && 883 getlocation (attr->cu, &block, &llbufs[0], &listlens[0], 884 cu_sec_idx (attr->cu)) != 0) 885 return -1; 886 return listlens[0] == 0 ? 0 : 1; 887 } 888 889 if (attr->form != DW_FORM_data16) 890 { 891 int error = INTUSE(dwarf_errno) (); 892 if (unlikely (error != DWARF_E_NO_BLOCK)) 893 { 894 __libdw_seterrno (error); 895 return -1; 896 } 897 } 898 899 int result = check_constant_offset (attr, &llbufs[0], &listlens[0]); 900 if (result != 1) 901 return result ?: 1; 902 903 Dwarf_Addr base, start, end; 904 Dwarf_Op *expr; 905 size_t expr_len; 906 ptrdiff_t off = 0; 907 size_t got = 0; 908 909 /* This is a true loclistptr, fetch the initial base address and offset. */ 910 base = __libdw_cu_base_address (attr->cu); 911 if (base == (Dwarf_Addr) -1) 912 return -1; 913 914 if (initial_offset (attr, &off) != 0) 915 return -1; 916 917 size_t secidx = attr->cu->version < 5 ? IDX_debug_loc : IDX_debug_loclists; 918 const Elf_Data *d = attr->cu->dbg->sectiondata[secidx]; 919 920 while (got < maxlocs 921 && (off = getlocations_addr (attr, off, &base, &start, &end, 922 address, d, &expr, &expr_len)) > 0) 923 { 924 /* This one matches the address. */ 925 if (llbufs != NULL) 926 { 927 llbufs[got] = expr; 928 listlens[got] = expr_len; 929 } 930 ++got; 931 } 932 933 /* We might stop early, so off can be zero or positive on success. */ 934 if (off < 0) 935 return -1; 936 937 return got; 938 } 939 940 ptrdiff_t 941 dwarf_getlocations (Dwarf_Attribute *attr, ptrdiff_t offset, Dwarf_Addr *basep, 942 Dwarf_Addr *startp, Dwarf_Addr *endp, Dwarf_Op **expr, 943 size_t *exprlen) 944 { 945 if (! attr_ok (attr)) 946 return -1; 947 948 /* 1 is an invalid offset, meaning no more locations. */ 949 if (offset == 1) 950 return 0; 951 952 if (offset == 0) 953 { 954 /* If it has a block form, it's a single location expression. 955 Except for DW_FORM_data16, which is a 128bit constant. */ 956 Dwarf_Block block; 957 if (attr->form != DW_FORM_data16 958 && INTUSE(dwarf_formblock) (attr, &block) == 0) 959 { 960 if (getlocation (attr->cu, &block, expr, exprlen, 961 cu_sec_idx (attr->cu)) != 0) 962 return -1; 963 964 /* This is the one and only location covering everything. */ 965 *startp = 0; 966 *endp = -1; 967 return 1; 968 } 969 970 if (attr->form != DW_FORM_data16) 971 { 972 int error = INTUSE(dwarf_errno) (); 973 if (unlikely (error != DWARF_E_NO_BLOCK)) 974 { 975 __libdw_seterrno (error); 976 return -1; 977 } 978 } 979 980 int result = check_constant_offset (attr, expr, exprlen); 981 if (result != 1) 982 { 983 if (result == 0) 984 { 985 /* This is the one and only location covering everything. */ 986 *startp = 0; 987 *endp = -1; 988 return 1; 989 } 990 return result; 991 } 992 993 /* We must be looking at a true loclistptr, fetch the initial 994 base address and offset. */ 995 *basep = __libdw_cu_base_address (attr->cu); 996 if (*basep == (Dwarf_Addr) -1) 997 return -1; 998 999 if (initial_offset (attr, &offset) != 0) 1000 return -1; 1001 } 1002 1003 size_t secidx = attr->cu->version < 5 ? IDX_debug_loc : IDX_debug_loclists; 1004 const Elf_Data *d = attr->cu->dbg->sectiondata[secidx]; 1005 1006 return getlocations_addr (attr, offset, basep, startp, endp, 1007 (Dwarf_Word) -1, d, expr, exprlen); 1008 } 1009