1 /* 2 3 Copyright (C) 2000,2003 Silicon Graphics, Inc. All Rights Reserved. 4 5 This program is free software; you can redistribute it and/or modify it 6 under the terms of version 2.1 of the GNU Lesser General Public License 7 as published by the Free Software Foundation. 8 9 This program is distributed in the hope that it would be useful, but 10 WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 13 Further, this software is distributed without any warranty that it is 14 free of the rightful claim of any third person regarding infringement 15 or the like. Any license provided herein, whether implied or 16 otherwise, applies only to this software file. Patent licenses, if 17 any, provided herein do not apply to combinations of this program with 18 other software, or any other product whatsoever. 19 20 You should have received a copy of the GNU Lesser General Public 21 License along with this program; if not, write the Free Software 22 Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 23 USA. 24 25 Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pky, 26 Mountain View, CA 94043, or: 27 28 http://www.sgi.com 29 30 For further information regarding this notice, see: 31 32 http://oss.sgi.com/projects/GenInfo/NoticeExplan 33 34 */ 35 36 37 38 #include "config.h" 39 #include "dwarf_incl.h" 40 #include "dwarf_loc.h" 41 42 43 /* 44 Given a Dwarf_Block that represents a location expression, 45 this function returns a pointer to a Dwarf_Locdesc struct 46 that has its ld_cents field set to the number of location 47 operators in the block, and its ld_s field pointing to a 48 contiguous block of Dwarf_Loc structs. However, the 49 ld_lopc and ld_hipc values are uninitialized. Returns 50 NULL on error. This function assumes that the length of 51 the block is greater than 0. Zero length location expressions 52 to represent variables that have been optimized away are 53 handled in the calling function. 54 */ 55 static Dwarf_Locdesc * 56 _dwarf_get_locdesc(Dwarf_Debug dbg, 57 Dwarf_Block * loc_block, 58 Dwarf_Addr lowpc, 59 Dwarf_Addr highpc, Dwarf_Error * error) 60 { 61 /* Size of the block containing the location expression. */ 62 Dwarf_Unsigned loc_len; 63 64 /* Sweeps the block containing the location expression. */ 65 Dwarf_Small *loc_ptr; 66 67 /* Current location operator. */ 68 Dwarf_Small atom; 69 70 /* Offset of current operator from start of block. */ 71 Dwarf_Unsigned offset; 72 73 /* Operands of current location operator. */ 74 Dwarf_Unsigned operand1, operand2; 75 76 /* Used to chain the Dwarf_Loc_Chain_s structs. */ 77 Dwarf_Loc_Chain curr_loc, prev_loc, head_loc = NULL; 78 79 /* Count of the number of location operators. */ 80 Dwarf_Unsigned op_count; 81 82 /* Contiguous block of Dwarf_Loc's for Dwarf_Locdesc. */ 83 Dwarf_Loc *block_loc; 84 85 /* Dwarf_Locdesc pointer to be returned. */ 86 Dwarf_Locdesc *locdesc; 87 88 Dwarf_Word leb128_length; 89 Dwarf_Unsigned i; 90 91 /* ***** BEGIN CODE ***** */ 92 93 loc_len = loc_block->bl_len; 94 loc_ptr = loc_block->bl_data; 95 96 offset = 0; 97 op_count = 0; 98 while (offset < loc_len) { 99 100 operand1 = 0; 101 operand2 = 0; 102 op_count++; 103 104 atom = *(Dwarf_Small *) loc_ptr; 105 loc_ptr++; 106 offset++; 107 108 curr_loc = 109 (Dwarf_Loc_Chain) _dwarf_get_alloc(dbg, DW_DLA_LOC_CHAIN, 110 1); 111 if (curr_loc == NULL) { 112 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 113 return (NULL); 114 } 115 curr_loc->lc_offset = offset; 116 curr_loc->lc_atom = atom; 117 switch (atom) { 118 119 case DW_OP_reg0: 120 case DW_OP_reg1: 121 case DW_OP_reg2: 122 case DW_OP_reg3: 123 case DW_OP_reg4: 124 case DW_OP_reg5: 125 case DW_OP_reg6: 126 case DW_OP_reg7: 127 case DW_OP_reg8: 128 case DW_OP_reg9: 129 case DW_OP_reg10: 130 case DW_OP_reg11: 131 case DW_OP_reg12: 132 case DW_OP_reg13: 133 case DW_OP_reg14: 134 case DW_OP_reg15: 135 case DW_OP_reg16: 136 case DW_OP_reg17: 137 case DW_OP_reg18: 138 case DW_OP_reg19: 139 case DW_OP_reg20: 140 case DW_OP_reg21: 141 case DW_OP_reg22: 142 case DW_OP_reg23: 143 case DW_OP_reg24: 144 case DW_OP_reg25: 145 case DW_OP_reg26: 146 case DW_OP_reg27: 147 case DW_OP_reg28: 148 case DW_OP_reg29: 149 case DW_OP_reg30: 150 case DW_OP_reg31: 151 break; 152 153 case DW_OP_regx: 154 operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length); 155 loc_ptr = loc_ptr + leb128_length; 156 offset = offset + leb128_length; 157 break; 158 159 case DW_OP_lit0: 160 case DW_OP_lit1: 161 case DW_OP_lit2: 162 case DW_OP_lit3: 163 case DW_OP_lit4: 164 case DW_OP_lit5: 165 case DW_OP_lit6: 166 case DW_OP_lit7: 167 case DW_OP_lit8: 168 case DW_OP_lit9: 169 case DW_OP_lit10: 170 case DW_OP_lit11: 171 case DW_OP_lit12: 172 case DW_OP_lit13: 173 case DW_OP_lit14: 174 case DW_OP_lit15: 175 case DW_OP_lit16: 176 case DW_OP_lit17: 177 case DW_OP_lit18: 178 case DW_OP_lit19: 179 case DW_OP_lit20: 180 case DW_OP_lit21: 181 case DW_OP_lit22: 182 case DW_OP_lit23: 183 case DW_OP_lit24: 184 case DW_OP_lit25: 185 case DW_OP_lit26: 186 case DW_OP_lit27: 187 case DW_OP_lit28: 188 case DW_OP_lit29: 189 case DW_OP_lit30: 190 case DW_OP_lit31: 191 operand1 = atom - DW_OP_lit0; 192 break; 193 194 case DW_OP_addr: 195 READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, 196 loc_ptr, dbg->de_pointer_size); 197 loc_ptr += dbg->de_pointer_size; 198 offset += dbg->de_pointer_size; 199 break; 200 201 case DW_OP_const1u: 202 operand1 = *(Dwarf_Small *) loc_ptr; 203 loc_ptr = loc_ptr + 1; 204 offset = offset + 1; 205 break; 206 207 case DW_OP_const1s: 208 operand1 = *(Dwarf_Sbyte *) loc_ptr; 209 loc_ptr = loc_ptr + 1; 210 offset = offset + 1; 211 break; 212 213 case DW_OP_const2u: 214 READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 2); 215 loc_ptr = loc_ptr + 2; 216 offset = offset + 2; 217 break; 218 219 case DW_OP_const2s: 220 READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 2); 221 loc_ptr = loc_ptr + 2; 222 offset = offset + 2; 223 break; 224 225 case DW_OP_const4u: 226 READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 4); 227 loc_ptr = loc_ptr + 4; 228 offset = offset + 4; 229 break; 230 231 case DW_OP_const4s: 232 READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 4); 233 loc_ptr = loc_ptr + 4; 234 offset = offset + 4; 235 break; 236 237 case DW_OP_const8u: 238 READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 8); 239 loc_ptr = loc_ptr + 8; 240 offset = offset + 8; 241 break; 242 243 case DW_OP_const8s: 244 READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 8); 245 loc_ptr = loc_ptr + 8; 246 offset = offset + 8; 247 break; 248 249 case DW_OP_constu: 250 operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length); 251 loc_ptr = loc_ptr + leb128_length; 252 offset = offset + leb128_length; 253 break; 254 255 case DW_OP_consts: 256 operand1 = _dwarf_decode_s_leb128(loc_ptr, &leb128_length); 257 loc_ptr = loc_ptr + leb128_length; 258 offset = offset + leb128_length; 259 break; 260 261 case DW_OP_fbreg: 262 operand1 = _dwarf_decode_s_leb128(loc_ptr, &leb128_length); 263 loc_ptr = loc_ptr + leb128_length; 264 offset = offset + leb128_length; 265 break; 266 267 case DW_OP_breg0: 268 case DW_OP_breg1: 269 case DW_OP_breg2: 270 case DW_OP_breg3: 271 case DW_OP_breg4: 272 case DW_OP_breg5: 273 case DW_OP_breg6: 274 case DW_OP_breg7: 275 case DW_OP_breg8: 276 case DW_OP_breg9: 277 case DW_OP_breg10: 278 case DW_OP_breg11: 279 case DW_OP_breg12: 280 case DW_OP_breg13: 281 case DW_OP_breg14: 282 case DW_OP_breg15: 283 case DW_OP_breg16: 284 case DW_OP_breg17: 285 case DW_OP_breg18: 286 case DW_OP_breg19: 287 case DW_OP_breg20: 288 case DW_OP_breg21: 289 case DW_OP_breg22: 290 case DW_OP_breg23: 291 case DW_OP_breg24: 292 case DW_OP_breg25: 293 case DW_OP_breg26: 294 case DW_OP_breg27: 295 case DW_OP_breg28: 296 case DW_OP_breg29: 297 case DW_OP_breg30: 298 case DW_OP_breg31: 299 operand1 = _dwarf_decode_s_leb128(loc_ptr, &leb128_length); 300 loc_ptr = loc_ptr + leb128_length; 301 offset = offset + leb128_length; 302 break; 303 304 case DW_OP_bregx: 305 /* uleb reg num followed by sleb offset */ 306 operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length); 307 loc_ptr = loc_ptr + leb128_length; 308 offset = offset + leb128_length; 309 310 operand2 = _dwarf_decode_s_leb128(loc_ptr, &leb128_length); 311 loc_ptr = loc_ptr + leb128_length; 312 offset = offset + leb128_length; 313 break; 314 315 case DW_OP_dup: 316 case DW_OP_drop: 317 break; 318 319 case DW_OP_pick: 320 operand1 = *(Dwarf_Small *) loc_ptr; 321 loc_ptr = loc_ptr + 1; 322 offset = offset + 1; 323 break; 324 325 case DW_OP_over: 326 case DW_OP_swap: 327 case DW_OP_rot: 328 case DW_OP_deref: 329 break; 330 331 case DW_OP_deref_size: 332 operand1 = *(Dwarf_Small *) loc_ptr; 333 loc_ptr = loc_ptr + 1; 334 offset = offset + 1; 335 break; 336 337 case DW_OP_xderef: 338 break; 339 340 case DW_OP_xderef_size: 341 operand1 = *(Dwarf_Small *) loc_ptr; 342 loc_ptr = loc_ptr + 1; 343 offset = offset + 1; 344 break; 345 346 case DW_OP_abs: 347 case DW_OP_and: 348 case DW_OP_div: 349 case DW_OP_minus: 350 case DW_OP_mod: 351 case DW_OP_mul: 352 case DW_OP_neg: 353 case DW_OP_not: 354 case DW_OP_or: 355 case DW_OP_plus: 356 break; 357 358 case DW_OP_plus_uconst: 359 operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length); 360 loc_ptr = loc_ptr + leb128_length; 361 offset = offset + leb128_length; 362 break; 363 364 case DW_OP_shl: 365 case DW_OP_shr: 366 case DW_OP_shra: 367 case DW_OP_xor: 368 break; 369 370 case DW_OP_le: 371 case DW_OP_ge: 372 case DW_OP_eq: 373 case DW_OP_lt: 374 case DW_OP_gt: 375 case DW_OP_ne: 376 break; 377 378 case DW_OP_skip: 379 case DW_OP_bra: 380 READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 2); 381 loc_ptr = loc_ptr + 2; 382 offset = offset + 2; 383 break; 384 385 case DW_OP_piece: 386 operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length); 387 loc_ptr = loc_ptr + leb128_length; 388 offset = offset + leb128_length; 389 break; 390 391 case DW_OP_nop: 392 break; 393 394 default: 395 _dwarf_error(dbg, error, DW_DLE_LOC_EXPR_BAD); 396 return (NULL); 397 } 398 399 400 curr_loc->lc_number = operand1; 401 curr_loc->lc_number2 = operand2; 402 403 if (head_loc == NULL) 404 head_loc = prev_loc = curr_loc; 405 else { 406 prev_loc->lc_next = curr_loc; 407 prev_loc = curr_loc; 408 } 409 } 410 411 block_loc = 412 (Dwarf_Loc *) _dwarf_get_alloc(dbg, DW_DLA_LOC_BLOCK, op_count); 413 if (block_loc == NULL) { 414 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 415 return (NULL); 416 } 417 418 curr_loc = head_loc; 419 for (i = 0; i < op_count; i++) { 420 (block_loc + i)->lr_atom = curr_loc->lc_atom; 421 (block_loc + i)->lr_number = curr_loc->lc_number; 422 (block_loc + i)->lr_number2 = curr_loc->lc_number2; 423 (block_loc + i)->lr_offset = curr_loc->lc_offset; 424 425 prev_loc = curr_loc; 426 curr_loc = curr_loc->lc_next; 427 dwarf_dealloc(dbg, prev_loc, DW_DLA_LOC_CHAIN); 428 } 429 430 locdesc = 431 (Dwarf_Locdesc *) _dwarf_get_alloc(dbg, DW_DLA_LOCDESC, 1); 432 if (locdesc == NULL) { 433 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 434 return (NULL); 435 } 436 437 locdesc->ld_cents = op_count; 438 locdesc->ld_s = block_loc; 439 locdesc->ld_from_loclist = loc_block->bl_from_loclist; 440 locdesc->ld_section_offset = loc_block->bl_section_offset; 441 locdesc->ld_lopc = lowpc; 442 locdesc->ld_hipc = highpc; 443 444 return (locdesc); 445 } 446 447 /* Using a loclist offset to get the in-memory 448 address of .debug_loc data to read, returns the loclist 449 'header' info in return_block. 450 */ 451 452 #define MAX_ADDR ((address_size == 8)?0xffffffffffffffffULL:0xffffffff) 453 454 static int 455 _dwarf_read_loc_section(Dwarf_Debug dbg, 456 Dwarf_Block * return_block, 457 Dwarf_Addr * lowpc, Dwarf_Addr * hipc, 458 Dwarf_Off sec_offset, Dwarf_Error * error) 459 { 460 Dwarf_Small *beg = dbg->de_debug_loc + sec_offset; 461 int address_size = dbg->de_pointer_size; 462 463 Dwarf_Addr start_addr = 0; 464 Dwarf_Addr end_addr = 0; 465 Dwarf_Half exprblock_size = 0; 466 Dwarf_Unsigned exprblock_off = 467 2 * address_size + sizeof(Dwarf_Half); 468 469 if (sec_offset >= dbg->de_debug_loc_size) { 470 /* We're at the end. No more present. */ 471 return DW_DLV_NO_ENTRY; 472 } 473 474 /* If it goes past end, error */ 475 if (exprblock_off > dbg->de_debug_loc_size) { 476 _dwarf_error(NULL, error, DW_DLE_DEBUG_LOC_SECTION_SHORT); 477 return DW_DLV_ERROR; 478 } 479 480 READ_UNALIGNED(dbg, start_addr, Dwarf_Addr, beg, address_size); 481 READ_UNALIGNED(dbg, end_addr, Dwarf_Addr, 482 beg + address_size, address_size); 483 if (start_addr == 0 && end_addr == 0) { 484 /* If start_addr and end_addr are 0, it's the end and no 485 exprblock_size field follows. */ 486 exprblock_size = 0; 487 exprblock_off -= sizeof(Dwarf_Half); 488 } else if (start_addr == MAX_ADDR) { 489 /* end address is a base address, no exprblock_size field here 490 either */ 491 exprblock_size = 0; 492 exprblock_off -= sizeof(Dwarf_Half); 493 } else { 494 495 READ_UNALIGNED(dbg, exprblock_size, Dwarf_Half, 496 beg + 2 * address_size, sizeof(Dwarf_Half)); 497 /* exprblock_size can be zero, means no expression */ 498 if ((exprblock_off + exprblock_size) > dbg->de_debug_loc_size) { 499 _dwarf_error(NULL, error, DW_DLE_DEBUG_LOC_SECTION_SHORT); 500 return DW_DLV_ERROR; 501 } 502 } 503 #undef MAX_ADDR 504 *lowpc = start_addr; 505 *hipc = end_addr; 506 507 return_block->bl_len = exprblock_size; 508 return_block->bl_from_loclist = 1; 509 return_block->bl_data = beg + exprblock_off; 510 return_block->bl_section_offset = 511 ((Dwarf_Small *) return_block->bl_data) - dbg->de_debug_loc; 512 513 return DW_DLV_OK; 514 515 } 516 static int 517 _dwarf_get_loclist_count(Dwarf_Debug dbg, 518 Dwarf_Off loclist_offset, 519 int *loclist_count, Dwarf_Error * error) 520 { 521 int count = 0; 522 Dwarf_Off offset = loclist_offset; 523 524 525 for (;;) { 526 Dwarf_Block b; 527 Dwarf_Addr lowpc; 528 Dwarf_Addr highpc; 529 int res = _dwarf_read_loc_section(dbg, &b, 530 531 &lowpc, &highpc, 532 offset, error); 533 534 if (res != DW_DLV_OK) { 535 return res; 536 } 537 offset = b.bl_len + b.bl_section_offset; 538 if (lowpc == 0 && highpc == 0) { 539 break; 540 } 541 count++; 542 } 543 *loclist_count = count; 544 return DW_DLV_OK; 545 } 546 547 /* Helper routine to avoid code duplication. 548 */ 549 static int 550 _dwarf_setup_loc(Dwarf_Attribute attr, 551 Dwarf_Debug * dbg_ret, 552 Dwarf_Half * form_ret, Dwarf_Error * error) 553 { 554 Dwarf_Debug dbg = 0; 555 Dwarf_Half form = 0; 556 int blkres; 557 558 if (attr == NULL) { 559 _dwarf_error(NULL, error, DW_DLE_ATTR_NULL); 560 return (DW_DLV_ERROR); 561 } 562 if (attr->ar_cu_context == NULL) { 563 _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT); 564 return (DW_DLV_ERROR); 565 } 566 567 dbg = attr->ar_cu_context->cc_dbg; 568 if (dbg == NULL) { 569 _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL); 570 return (DW_DLV_ERROR); 571 } 572 *dbg_ret = dbg; 573 blkres = dwarf_whatform(attr, &form, error); 574 if (blkres != DW_DLV_OK) { 575 _dwarf_error(dbg, error, DW_DLE_LOC_EXPR_BAD); 576 return blkres; 577 } 578 *form_ret = form; 579 580 return DW_DLV_OK; 581 } 582 583 /* Helper routine to avoid code duplication. 584 */ 585 static int 586 _dwarf_get_loclist_header_start(Dwarf_Debug dbg, 587 Dwarf_Attribute attr, 588 Dwarf_Unsigned * loclist_offset, 589 Dwarf_Error * error) 590 { 591 int secload = 0; 592 int blkres = dwarf_formudata(attr, loclist_offset, error); 593 594 if (blkres != DW_DLV_OK) { 595 return (blkres); 596 } 597 598 if (!dbg->de_debug_loc) { 599 secload = _dwarf_load_section(dbg, 600 dbg->de_debug_loc_index, 601 &dbg->de_debug_loc, error); 602 if (secload != DW_DLV_OK) { 603 return secload; 604 } 605 } 606 return DW_DLV_OK; 607 } 608 609 /* When llbuf (see dwarf_loclist_n) is partially set up 610 and an error is encountered, tear it down as it 611 won't be used. 612 */ 613 static void 614 _dwarf_cleanup_llbuf(Dwarf_Debug dbg, Dwarf_Locdesc ** llbuf, int count) 615 { 616 int i; 617 618 for (i = 0; i < count; ++i) { 619 dwarf_dealloc(dbg, llbuf[i]->ld_s, DW_DLA_LOC_BLOCK); 620 dwarf_dealloc(dbg, llbuf[i], DW_DLA_LOCDESC); 621 } 622 dwarf_dealloc(dbg, llbuf, DW_DLA_LIST); 623 } 624 625 /* 626 Handles simple location entries and loclists. 627 Returns all the Locdesc's thru llbuf. 628 629 */ 630 int 631 dwarf_loclist_n(Dwarf_Attribute attr, 632 Dwarf_Locdesc *** llbuf_out, 633 Dwarf_Signed * listlen_out, Dwarf_Error * error) 634 { 635 Dwarf_Debug dbg; 636 637 /* 638 Dwarf_Attribute that describes the DW_AT_location in die, if 639 present. */ 640 Dwarf_Attribute loc_attr = attr; 641 642 /* Dwarf_Block that describes a single location expression. */ 643 Dwarf_Block loc_block; 644 645 /* A pointer to the current Dwarf_Locdesc read. */ 646 Dwarf_Locdesc *locdesc = 0; 647 648 Dwarf_Half form = 0; 649 Dwarf_Addr lowpc = 0; 650 Dwarf_Addr highpc = 0; 651 Dwarf_Signed listlen = 0; 652 Dwarf_Locdesc **llbuf = 0; 653 654 int blkres; 655 int setup_res; 656 657 /* ***** BEGIN CODE ***** */ 658 setup_res = _dwarf_setup_loc(attr, &dbg, &form, error); 659 if (setup_res != DW_DLV_OK) { 660 return setup_res; 661 } 662 /* If this is a form_block then it's a location expression. If it's 663 DW_FORM_data4 or DW_FORM_data8 it's a loclist offset */ 664 if (form == DW_FORM_data4 || form == DW_FORM_data8) { 665 666 /* A reference to .debug_loc, with an offset in .debug_loc of a 667 loclist */ 668 Dwarf_Unsigned loclist_offset = 0; 669 int off_res; 670 int count_res; 671 int loclist_count; 672 int lli; 673 674 off_res = _dwarf_get_loclist_header_start(dbg, 675 attr, &loclist_offset, 676 error); 677 if (off_res != DW_DLV_OK) { 678 return off_res; 679 } 680 count_res = _dwarf_get_loclist_count(dbg, loclist_offset, 681 &loclist_count, error); 682 listlen = loclist_count; 683 if (count_res != DW_DLV_OK) { 684 return count_res; 685 } 686 if (loclist_count == 0) { 687 return DW_DLV_NO_ENTRY; 688 } 689 690 llbuf = (Dwarf_Locdesc **) 691 _dwarf_get_alloc(dbg, DW_DLA_LIST, loclist_count); 692 if (!llbuf) { 693 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 694 return (DW_DLV_ERROR); 695 } 696 697 for (lli = 0; lli < loclist_count; ++lli) { 698 blkres = _dwarf_read_loc_section(dbg, &loc_block, 699 &lowpc, 700 &highpc, 701 loclist_offset, error); 702 if (blkres != DW_DLV_OK) { 703 _dwarf_cleanup_llbuf(dbg, llbuf, lli); 704 return (blkres); 705 } 706 locdesc = _dwarf_get_locdesc(dbg, &loc_block, 707 lowpc, highpc, error); 708 if (locdesc == NULL) { 709 _dwarf_cleanup_llbuf(dbg, llbuf, lli); 710 /* low level error already set: let it be passed back */ 711 return (DW_DLV_ERROR); 712 } 713 llbuf[lli] = locdesc; 714 715 /* Now get to next loclist entry offset. */ 716 loclist_offset = loc_block.bl_section_offset + 717 loc_block.bl_len; 718 } 719 720 721 } else { 722 Dwarf_Block *tblock = 0; 723 724 blkres = dwarf_formblock(loc_attr, &tblock, error); 725 if (blkres != DW_DLV_OK) { 726 return (blkres); 727 } 728 loc_block = *tblock; 729 /* We copied tblock contents to the stack var, so can dealloc 730 tblock now. Avoids leaks. */ 731 dwarf_dealloc(dbg, tblock, DW_DLA_BLOCK); 732 listlen = 1; /* One by definition of a location 733 entry. */ 734 lowpc = 0; /* HACK */ 735 highpc = (Dwarf_Unsigned) (-1LL); /* HACK */ 736 737 /* An empty location description (block length 0) means the 738 code generator emitted no variable, the variable was not 739 generated, it was unused or perhaps never tested after being 740 set. Dwarf2, section 2.4.1 In other words, it is not an 741 error, and we don't test for block length 0 specially here. */ 742 locdesc = _dwarf_get_locdesc(dbg, &loc_block, 743 lowpc, highpc, error); 744 if (locdesc == NULL) { 745 /* low level error already set: let it be passed back */ 746 return (DW_DLV_ERROR); 747 } 748 llbuf = (Dwarf_Locdesc **) 749 _dwarf_get_alloc(dbg, DW_DLA_LIST, listlen); 750 if (!llbuf) { 751 /* Free the locdesc we allocated but won't use. */ 752 dwarf_dealloc(dbg, locdesc, DW_DLA_LOCDESC); 753 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 754 return (DW_DLV_ERROR); 755 } 756 llbuf[0] = locdesc; 757 } 758 759 *llbuf_out = llbuf; 760 *listlen_out = listlen; 761 return (DW_DLV_OK); 762 } 763 764 /* 765 Handles only a location expression. 766 If called on a loclist, just returns one of those. 767 Cannot not handle a real loclist. 768 It returns the location expression as a loclist with 769 a single entry. 770 See dwarf_loclist_n() which handles any number 771 of location list entries. 772 773 This is the original definition, and it simply 774 does not work for loclists. Kept for compatibility. 775 */ 776 int 777 dwarf_loclist(Dwarf_Attribute attr, 778 Dwarf_Locdesc ** llbuf, 779 Dwarf_Signed * listlen, Dwarf_Error * error) 780 { 781 Dwarf_Debug dbg; 782 783 /* 784 Dwarf_Attribute that describes the DW_AT_location in die, if 785 present. */ 786 Dwarf_Attribute loc_attr = attr; 787 788 /* Dwarf_Block that describes a single location expression. */ 789 Dwarf_Block loc_block; 790 791 /* A pointer to the current Dwarf_Locdesc read. */ 792 Dwarf_Locdesc *locdesc = 0; 793 794 Dwarf_Half form = 0; 795 Dwarf_Addr lowpc = 0; 796 Dwarf_Addr highpc = 0; 797 798 int blkres; 799 int setup_res; 800 801 /* ***** BEGIN CODE ***** */ 802 setup_res = _dwarf_setup_loc(attr, &dbg, &form, error); 803 if (setup_res != DW_DLV_OK) { 804 return setup_res; 805 } 806 /* If this is a form_block then it's a location expression. If it's 807 DW_FORM_data4 or DW_FORM_data8 it's a loclist offset */ 808 if (form == DW_FORM_data4 || form == DW_FORM_data8) { 809 810 /* A reference to .debug_loc, with an offset in .debug_loc of a 811 loclist */ 812 Dwarf_Unsigned loclist_offset = 0; 813 int off_res; 814 815 off_res = _dwarf_get_loclist_header_start(dbg, 816 attr, &loclist_offset, 817 error); 818 if (off_res != DW_DLV_OK) { 819 return off_res; 820 } 821 822 /* With dwarf_loclist, just read a single entry */ 823 blkres = _dwarf_read_loc_section(dbg, &loc_block, 824 &lowpc, 825 &highpc, 826 loclist_offset, error); 827 if (blkres != DW_DLV_OK) { 828 return (blkres); 829 } 830 831 832 833 834 } else { 835 Dwarf_Block *tblock = 0; 836 837 blkres = dwarf_formblock(loc_attr, &tblock, error); 838 if (blkres != DW_DLV_OK) { 839 return (blkres); 840 } 841 loc_block = *tblock; 842 /* We copied tblock contents to the stack var, so can dealloc 843 tblock now. Avoids leaks. */ 844 dwarf_dealloc(dbg, tblock, DW_DLA_BLOCK); 845 lowpc = 0; /* HACK */ 846 highpc = (Dwarf_Unsigned) (-1LL); /* HACK */ 847 } 848 849 /* An empty location description (block length 0) means the code 850 generator emitted no variable, the variable was not generated, 851 it was unused or perhaps never tested after being set. Dwarf2, 852 section 2.4.1 In other words, it is not an error, and we don't 853 test for block length 0 specially here. FIXME: doing this once 854 is wrong, needs to handle low/hi pc sets. */ 855 locdesc = _dwarf_get_locdesc(dbg, &loc_block, lowpc, highpc, error); 856 if (locdesc == NULL) { 857 /* low level error already set: let it be passed back */ 858 return (DW_DLV_ERROR); 859 } 860 861 *llbuf = locdesc; 862 *listlen = 1; 863 return (DW_DLV_OK); 864 } 865 866 /* Usable to read a single loclist or to read a block of them 867 or to read an entire section's loclists. 868 869 */ 870 871 /*ARGSUSED*/ int 872 dwarf_get_loclist_entry(Dwarf_Debug dbg, 873 Dwarf_Unsigned offset, 874 Dwarf_Addr * hipc_offset, 875 Dwarf_Addr * lopc_offset, 876 Dwarf_Ptr * data, 877 Dwarf_Unsigned * entry_len, 878 Dwarf_Unsigned * next_entry, 879 Dwarf_Error * error) 880 { 881 Dwarf_Block b; 882 Dwarf_Addr lowpc; 883 Dwarf_Addr highpc; 884 int res; 885 886 if (!dbg->de_debug_loc) { 887 int secload = _dwarf_load_section(dbg, 888 dbg->de_debug_loc_index, 889 &dbg->de_debug_loc, 890 error); 891 892 if (secload != DW_DLV_OK) { 893 return secload; 894 } 895 } 896 897 res = _dwarf_read_loc_section(dbg, 898 &b, &lowpc, &highpc, offset, error); 899 if (res != DW_DLV_OK) { 900 return res; 901 } 902 *hipc_offset = highpc; 903 *lopc_offset = lowpc; 904 *entry_len = b.bl_len; 905 *data = b.bl_data; 906 *next_entry = b.bl_len + b.bl_section_offset; 907 908 return DW_DLV_OK; 909 910 911 912 } 913