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