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