1 /* 2 3 Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. 4 Portions Copyright (C) 2007-2010 David Anderson. All Rights Reserved. 5 6 This program is free software; you can redistribute it and/or modify it 7 under the terms of version 2.1 of the GNU Lesser General Public License 8 as published by the Free Software Foundation. 9 10 This program is distributed in the hope that it would be useful, but 11 WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13 14 Further, this software is distributed without any warranty that it is 15 free of the rightful claim of any third person regarding infringement 16 or the like. Any license provided herein, whether implied or 17 otherwise, applies only to this software file. Patent licenses, if 18 any, provided herein do not apply to combinations of this program with 19 other software, or any other product whatsoever. 20 21 You should have received a copy of the GNU Lesser General Public 22 License along with this program; if not, write the Free Software 23 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, 24 USA. 25 26 Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, 27 Mountain View, CA 94043, or: 28 29 http://www.sgi.com 30 31 For further information regarding this notice, see: 32 33 http://oss.sgi.com/projects/GenInfo/NoticeExplan 34 35 */ 36 /* The address of the Free Software Foundation is 37 Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 38 Boston, MA 02110-1301, USA. 39 SGI has moved from the Crittenden Lane address. 40 */ 41 42 43 44 45 #include "config.h" 46 #include "dwarf_incl.h" 47 #ifdef HAVE_ELF_H 48 #include <elf.h> 49 #endif 50 #include <stdio.h> 51 #include "dwarf_die_deliv.h" 52 53 54 /* 55 For a given Dwarf_Debug dbg, this function checks 56 if a CU that includes the given offset has been read 57 or not. If yes, it returns the Dwarf_CU_Context 58 for the CU. Otherwise it returns NULL. Being an 59 internal routine, it is assumed that a valid dbg 60 is passed. 61 62 **This is a sequential search. May be too slow. 63 64 If debug_info and debug_abbrev not loaded, this will 65 wind up returning NULL. So no need to load before calling 66 this. 67 */ 68 static Dwarf_CU_Context 69 _dwarf_find_CU_Context(Dwarf_Debug dbg, Dwarf_Off offset) 70 { 71 Dwarf_CU_Context cu_context = 0; 72 73 if (offset >= dbg->de_info_last_offset) 74 return (NULL); 75 76 if (dbg->de_cu_context != NULL && 77 dbg->de_cu_context->cc_next != NULL && 78 dbg->de_cu_context->cc_next->cc_debug_info_offset == offset) { 79 80 return (dbg->de_cu_context->cc_next); 81 } 82 83 if (dbg->de_cu_context != NULL && 84 dbg->de_cu_context->cc_debug_info_offset <= offset) { 85 86 for (cu_context = dbg->de_cu_context; 87 cu_context != NULL; cu_context = cu_context->cc_next) { 88 89 if (offset >= cu_context->cc_debug_info_offset && 90 offset < cu_context->cc_debug_info_offset + 91 cu_context->cc_length + cu_context->cc_length_size 92 + cu_context->cc_extension_size) { 93 94 return (cu_context); 95 } 96 } 97 } 98 99 for (cu_context = dbg->de_cu_context_list; 100 cu_context != NULL; cu_context = cu_context->cc_next) { 101 102 if (offset >= cu_context->cc_debug_info_offset && 103 offset < cu_context->cc_debug_info_offset + 104 cu_context->cc_length + cu_context->cc_length_size 105 + cu_context->cc_extension_size) { 106 107 return (cu_context); 108 } 109 } 110 111 return (NULL); 112 } 113 114 115 /* 116 This routine checks the dwarf_offdie() list of 117 CU contexts for the right CU context. 118 */ 119 static Dwarf_CU_Context 120 _dwarf_find_offdie_CU_Context(Dwarf_Debug dbg, Dwarf_Off offset) 121 { 122 Dwarf_CU_Context cu_context = 0; 123 124 for (cu_context = dbg->de_offdie_cu_context; 125 cu_context != NULL; cu_context = cu_context->cc_next) 126 127 if (offset >= cu_context->cc_debug_info_offset && 128 offset < cu_context->cc_debug_info_offset + 129 cu_context->cc_length + cu_context->cc_length_size 130 + cu_context->cc_extension_size) 131 132 return (cu_context); 133 134 return (NULL); 135 } 136 137 138 /* 139 This function is used to create a CU Context for 140 a compilation-unit that begins at offset in 141 .debug_info. The CU Context is attached to the 142 list of CU Contexts for this dbg. It is assumed 143 that the CU at offset has not been read before, 144 and so do not call this routine before making 145 sure of this with _dwarf_find_CU_Context(). 146 Returns NULL on error. As always, being an 147 internal routine, assumes a good dbg. 148 149 This function must always set a dwarf error code 150 before returning NULL. Always. 151 */ 152 static Dwarf_CU_Context 153 _dwarf_make_CU_Context(Dwarf_Debug dbg, 154 Dwarf_Off offset, Dwarf_Error * error) 155 { 156 Dwarf_CU_Context cu_context = 0; 157 Dwarf_Unsigned length = 0; 158 Dwarf_Signed abbrev_offset = 0; 159 Dwarf_Byte_Ptr cu_ptr = 0; 160 int local_extension_size = 0; 161 int local_length_size = 0; 162 163 cu_context = 164 (Dwarf_CU_Context) _dwarf_get_alloc(dbg, DW_DLA_CU_CONTEXT, 1); 165 if (cu_context == NULL) { 166 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 167 return (NULL); 168 } 169 cu_context->cc_dbg = dbg; 170 171 cu_ptr = (Dwarf_Byte_Ptr) (dbg->de_debug_info.dss_data + offset); 172 173 /* READ_AREA_LENGTH updates cu_ptr for consumed bytes */ 174 READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned, 175 cu_ptr, local_length_size, local_extension_size); 176 cu_context->cc_length_size = local_length_size; 177 cu_context->cc_extension_size = local_extension_size; 178 179 180 cu_context->cc_length = (Dwarf_Word) length; 181 182 READ_UNALIGNED(dbg, cu_context->cc_version_stamp, Dwarf_Half, 183 cu_ptr, sizeof(Dwarf_Half)); 184 cu_ptr += sizeof(Dwarf_Half); 185 186 READ_UNALIGNED(dbg, abbrev_offset, Dwarf_Signed, 187 cu_ptr, local_length_size); 188 cu_ptr += local_length_size; 189 cu_context->cc_abbrev_offset = (Dwarf_Sword) abbrev_offset; 190 191 cu_context->cc_address_size = *(Dwarf_Small *) cu_ptr; 192 193 if ((length < CU_VERSION_STAMP_SIZE + local_length_size + 194 CU_ADDRESS_SIZE_SIZE) || 195 (offset + length + local_length_size + 196 local_extension_size > dbg->de_debug_info.dss_size)) { 197 198 dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT); 199 _dwarf_error(dbg, error, DW_DLE_CU_LENGTH_ERROR); 200 return (NULL); 201 } 202 203 if (cu_context->cc_version_stamp != CURRENT_VERSION_STAMP 204 && cu_context->cc_version_stamp != CURRENT_VERSION_STAMP3 205 && cu_context->cc_version_stamp != CURRENT_VERSION_STAMP4) { 206 dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT); 207 _dwarf_error(dbg, error, DW_DLE_VERSION_STAMP_ERROR); 208 return (NULL); 209 } 210 211 if (abbrev_offset >= dbg->de_debug_abbrev.dss_size) { 212 dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT); 213 _dwarf_error(dbg, error, DW_DLE_ABBREV_OFFSET_ERROR); 214 return (NULL); 215 } 216 217 cu_context->cc_abbrev_hash_table = 218 (Dwarf_Hash_Table) _dwarf_get_alloc(dbg, DW_DLA_HASH_TABLE, 1); 219 if (cu_context->cc_abbrev_hash_table == NULL) { 220 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 221 return (NULL); 222 } 223 224 cu_context->cc_debug_info_offset = (Dwarf_Word) offset; 225 dbg->de_info_last_offset = 226 (Dwarf_Word) (offset + length + 227 local_extension_size + local_length_size); 228 229 if (dbg->de_cu_context_list == NULL) { 230 dbg->de_cu_context_list = cu_context; 231 dbg->de_cu_context_list_end = cu_context; 232 } else { 233 dbg->de_cu_context_list_end->cc_next = cu_context; 234 dbg->de_cu_context_list_end = cu_context; 235 } 236 237 return (cu_context); 238 } 239 240 241 /* 242 Returns offset of next compilation-unit thru next_cu_offset 243 pointer. 244 It basically sequentially moves from one 245 cu to the next. The current cu is recorded 246 internally by libdwarf. 247 248 The _b form is new for DWARF4 adding new returned fields. 249 */ 250 int 251 dwarf_next_cu_header(Dwarf_Debug dbg, 252 Dwarf_Unsigned * cu_header_length, 253 Dwarf_Half * version_stamp, 254 Dwarf_Unsigned * abbrev_offset, 255 Dwarf_Half * address_size, 256 Dwarf_Unsigned * next_cu_offset, 257 Dwarf_Error * error) 258 { 259 return dwarf_next_cu_header_b(dbg, 260 cu_header_length, 261 version_stamp, 262 abbrev_offset, 263 address_size, 264 0,0, 265 next_cu_offset, 266 error); 267 } 268 int 269 dwarf_next_cu_header_b(Dwarf_Debug dbg, 270 Dwarf_Unsigned * cu_header_length, 271 Dwarf_Half * version_stamp, 272 Dwarf_Unsigned * abbrev_offset, 273 Dwarf_Half * address_size, 274 Dwarf_Half * offset_size, 275 Dwarf_Half * extension_size, 276 Dwarf_Unsigned * next_cu_offset, 277 Dwarf_Error * error) 278 { 279 /* Offset for current and new CU. */ 280 Dwarf_Unsigned new_offset = 0; 281 282 /* CU Context for current CU. */ 283 Dwarf_CU_Context cu_context = 0; 284 285 /* ***** BEGIN CODE ***** */ 286 287 if (dbg == NULL) { 288 _dwarf_error(NULL, error, DW_DLE_DBG_NULL); 289 return (DW_DLV_ERROR); 290 } 291 /* 292 Get offset into .debug_info of next CU. If dbg has no context, 293 this has to be the first one. */ 294 if (dbg->de_cu_context == NULL) { 295 new_offset = 0; 296 if (!dbg->de_debug_info.dss_data) { 297 int res = _dwarf_load_debug_info(dbg, error); 298 299 if (res != DW_DLV_OK) { 300 return res; 301 } 302 } 303 304 } else { 305 new_offset = dbg->de_cu_context->cc_debug_info_offset + 306 dbg->de_cu_context->cc_length + 307 dbg->de_cu_context->cc_length_size + 308 dbg->de_cu_context->cc_extension_size; 309 } 310 311 /* 312 Check that there is room in .debug_info beyond the new offset 313 for at least a new cu header. If not, return 0 to indicate end 314 of debug_info section, and reset de_cu_debug_info_offset to 315 enable looping back through the cu's. */ 316 if ((new_offset + _dwarf_length_of_cu_header_simple(dbg)) >= 317 dbg->de_debug_info.dss_size) { 318 dbg->de_cu_context = NULL; 319 return (DW_DLV_NO_ENTRY); 320 } 321 322 /* Check if this CU has been read before. */ 323 cu_context = _dwarf_find_CU_Context(dbg, new_offset); 324 325 /* If not, make CU Context for it. */ 326 if (cu_context == NULL) { 327 cu_context = _dwarf_make_CU_Context(dbg, new_offset, error); 328 if (cu_context == NULL) { 329 /* Error if CU Context could not be made. Since 330 _dwarf_make_CU_Context has already registered an error 331 we do not do that here: we let the lower error pass 332 thru. */ 333 return (DW_DLV_ERROR); 334 } 335 } 336 337 dbg->de_cu_context = cu_context; 338 339 if (cu_header_length != NULL) 340 *cu_header_length = cu_context->cc_length; 341 342 if (version_stamp != NULL) 343 *version_stamp = cu_context->cc_version_stamp; 344 345 if (abbrev_offset != NULL) 346 *abbrev_offset = cu_context->cc_abbrev_offset; 347 348 if (address_size != NULL) 349 *address_size = cu_context->cc_address_size; 350 if (offset_size != NULL) 351 *offset_size = cu_context->cc_length_size; 352 if (extension_size != NULL) 353 *extension_size = cu_context->cc_extension_size; 354 355 new_offset = new_offset + cu_context->cc_length + 356 cu_context->cc_length_size + cu_context->cc_extension_size; 357 *next_cu_offset = new_offset; 358 return (DW_DLV_OK); 359 } 360 361 362 /* 363 This function does two slightly different things 364 depending on the input flag want_AT_sibling. If 365 this flag is true, it checks if the input die has 366 a DW_AT_sibling attribute. If it does it returns 367 a pointer to the start of the sibling die in the 368 .debug_info section. Otherwise it behaves the 369 same as the want_AT_sibling false case. 370 371 If the want_AT_sibling flag is false, it returns 372 a pointer to the immediately adjacent die in the 373 .debug_info section. 374 375 Die_info_end points to the end of the .debug_info 376 portion for the cu the die belongs to. It is used 377 to check that the search for the next die does not 378 cross the end of the current cu. Cu_info_start points 379 to the start of the .debug_info portion for the 380 current cu, and is used to add to the offset for 381 DW_AT_sibling attributes. Finally, has_die_child 382 is a pointer to a Dwarf_Bool that is set true if 383 the present die has children, false otherwise. 384 However, in case want_AT_child is true and the die 385 has a DW_AT_sibling attribute *has_die_child is set 386 false to indicate that the children are being skipped. 387 388 die_info_end points to the last byte+1 of the cu. 389 390 */ 391 static Dwarf_Byte_Ptr 392 _dwarf_next_die_info_ptr(Dwarf_Byte_Ptr die_info_ptr, 393 Dwarf_CU_Context cu_context, 394 Dwarf_Byte_Ptr die_info_end, 395 Dwarf_Byte_Ptr cu_info_start, 396 Dwarf_Bool want_AT_sibling, 397 Dwarf_Bool * has_die_child) 398 { 399 Dwarf_Byte_Ptr info_ptr = 0; 400 Dwarf_Byte_Ptr abbrev_ptr = 0; 401 Dwarf_Word abbrev_code = 0; 402 Dwarf_Abbrev_List abbrev_list; 403 Dwarf_Half attr = 0; 404 Dwarf_Half attr_form = 0; 405 Dwarf_Unsigned offset = 0; 406 Dwarf_Word leb128_length = 0; 407 Dwarf_Unsigned utmp = 0; 408 Dwarf_Debug dbg = 0; 409 410 info_ptr = die_info_ptr; 411 DECODE_LEB128_UWORD(info_ptr, utmp); 412 abbrev_code = (Dwarf_Word) utmp; 413 if (abbrev_code == 0) { 414 return NULL; 415 } 416 417 418 abbrev_list = _dwarf_get_abbrev_for_code(cu_context, abbrev_code); 419 if (abbrev_list == NULL) { 420 return (NULL); 421 } 422 dbg = cu_context->cc_dbg; 423 424 *has_die_child = abbrev_list->ab_has_child; 425 426 abbrev_ptr = abbrev_list->ab_abbrev_ptr; 427 do { 428 Dwarf_Unsigned utmp2; 429 430 DECODE_LEB128_UWORD(abbrev_ptr, utmp2); 431 attr = (Dwarf_Half) utmp2; 432 DECODE_LEB128_UWORD(abbrev_ptr, utmp2); 433 attr_form = (Dwarf_Half) utmp2; 434 if (attr_form == DW_FORM_indirect) { 435 Dwarf_Unsigned utmp6; 436 437 /* DECODE_LEB128_UWORD updates info_ptr */ 438 DECODE_LEB128_UWORD(info_ptr, utmp6); 439 attr_form = (Dwarf_Half) utmp6; 440 441 } 442 443 if (want_AT_sibling && attr == DW_AT_sibling) { 444 switch (attr_form) { 445 case DW_FORM_ref1: 446 offset = *(Dwarf_Small *) info_ptr; 447 break; 448 case DW_FORM_ref2: 449 /* READ_UNALIGNED does not update info_ptr */ 450 READ_UNALIGNED(dbg, offset, Dwarf_Unsigned, 451 info_ptr, sizeof(Dwarf_Half)); 452 break; 453 case DW_FORM_ref4: 454 READ_UNALIGNED(dbg, offset, Dwarf_Unsigned, 455 info_ptr, sizeof(Dwarf_ufixed)); 456 break; 457 case DW_FORM_ref8: 458 READ_UNALIGNED(dbg, offset, Dwarf_Unsigned, 459 info_ptr, sizeof(Dwarf_Unsigned)); 460 break; 461 case DW_FORM_ref_udata: 462 offset = 463 _dwarf_decode_u_leb128(info_ptr, &leb128_length); 464 break; 465 case DW_FORM_ref_addr: 466 /* Very unusual. The FORM is intended to refer to 467 a different CU, but a different CU cannot 468 be a sibling, can it? 469 We could ignore this and treat as if no DW_AT_sibling 470 present. Or derive the offset from it and if 471 it is in the same CU use it directly. 472 The offset here is *supposed* to be a global offset, 473 so adding cu_info_start is wrong to any offset 474 we find here unless cu_info_start 475 is zero! Lets pretend there is no DW_AT_sibling 476 attribute. */ 477 goto no_sibling_attr; 478 default: 479 return (NULL); 480 } 481 482 /* Reset *has_die_child to indicate children skipped. */ 483 *has_die_child = false; 484 485 /* A value beyond die_info_end indicates an error. Exactly 486 at die_info_end means 1-past-cu-end and simply means we 487 are at the end, do not return NULL. Higher level code 488 will detect that we are at the end. */ 489 if (cu_info_start + offset > die_info_end) { 490 /* Error case, bad DWARF. */ 491 return (NULL); 492 } 493 /* At or before end-of-cu */ 494 return (cu_info_start + offset); 495 } 496 497 no_sibling_attr: 498 if (attr_form != 0) { 499 info_ptr += _dwarf_get_size_of_val(cu_context->cc_dbg, 500 attr_form, 501 cu_context->cc_address_size, 502 info_ptr, 503 cu_context->cc_length_size); 504 /* It is ok for info_ptr == die_info_end, as we will test 505 later before using a too-large info_ptr */ 506 if (info_ptr > die_info_end) { 507 /* More than one-past-end indicates a bug somewhere, 508 likely bad dwarf generation. */ 509 return (NULL); 510 } 511 } 512 } while (attr != 0 || attr_form != 0); 513 514 return (info_ptr); 515 } 516 517 518 /* 519 Given a Dwarf_Debug dbg, and a Dwarf_Die die, it returns 520 a Dwarf_Die for the sibling of die. In case die is NULL, 521 it returns (thru ptr) a Dwarf_Die for the first die in the current 522 cu in dbg. Returns DW_DLV_ERROR on error. 523 524 It is assumed that every sibling chain including those with 525 only one element is terminated with a NULL die, except a 526 chain with only a NULL die. 527 528 The algorithm moves from one die to the adjacent one. It 529 returns when the depth of children it sees equals the number 530 of sibling chain terminations. A single count, child_depth 531 is used to track the depth of children and sibling terminations 532 encountered. Child_depth is incremented when a die has the 533 Has-Child flag set unless the child happens to be a NULL die. 534 Child_depth is decremented when a die has Has-Child false, 535 and the adjacent die is NULL. Algorithm returns when 536 child_depth is 0. 537 538 **NOTE: Do not modify input die, since it is used at the end. 539 */ 540 int 541 dwarf_siblingof(Dwarf_Debug dbg, 542 Dwarf_Die die, 543 Dwarf_Die * caller_ret_die, Dwarf_Error * error) 544 { 545 Dwarf_Die ret_die = 0; 546 Dwarf_Byte_Ptr die_info_ptr = 0; 547 Dwarf_Byte_Ptr cu_info_start = 0; 548 549 /* die_info_end points 1-past end of die (once set) */ 550 Dwarf_Byte_Ptr die_info_end = 0; 551 Dwarf_Word abbrev_code = 0; 552 Dwarf_Unsigned utmp = 0; 553 554 555 if (dbg == NULL) { 556 _dwarf_error(NULL, error, DW_DLE_DBG_NULL); 557 return (DW_DLV_ERROR); 558 } 559 560 if (die == NULL) { 561 /* Find root die of cu */ 562 /* die_info_end is untouched here, need not be set in this 563 branch. */ 564 Dwarf_Off off2; 565 566 /* If we've not loaded debug_info, de_cu_context will be NULL, 567 so no need to laod */ 568 569 if (dbg->de_cu_context == NULL) { 570 _dwarf_error(dbg, error, DW_DLE_DBG_NO_CU_CONTEXT); 571 return (DW_DLV_ERROR); 572 } 573 574 off2 = dbg->de_cu_context->cc_debug_info_offset; 575 die_info_ptr = dbg->de_debug_info.dss_data + 576 off2 + _dwarf_length_of_cu_header(dbg, off2); 577 } else { 578 /* Find sibling die. */ 579 Dwarf_Bool has_child = false; 580 Dwarf_Sword child_depth = 0; 581 582 /* We cannot have a legal die unless debug_info was loaded, so 583 no need to load debug_info here. */ 584 CHECK_DIE(die, DW_DLV_ERROR); 585 586 die_info_ptr = die->di_debug_info_ptr; 587 if (*die_info_ptr == 0) { 588 return (DW_DLV_NO_ENTRY); 589 } 590 cu_info_start = dbg->de_debug_info.dss_data + 591 die->di_cu_context->cc_debug_info_offset; 592 die_info_end = cu_info_start + die->di_cu_context->cc_length + 593 die->di_cu_context->cc_length_size + 594 die->di_cu_context->cc_extension_size; 595 596 if ((*die_info_ptr) == 0) { 597 return (DW_DLV_NO_ENTRY); 598 } 599 child_depth = 0; 600 do { 601 die_info_ptr = _dwarf_next_die_info_ptr(die_info_ptr, 602 die->di_cu_context, 603 die_info_end, 604 cu_info_start, true, 605 &has_child); 606 if (die_info_ptr == NULL) { 607 _dwarf_error(dbg, error, DW_DLE_NEXT_DIE_PTR_NULL); 608 return (DW_DLV_ERROR); 609 } 610 611 /* die_info_end is one past end. Do not read it! 612 A test for ``!= die_info_end'' would work as well, 613 but perhaps < reads more like the meaning. */ 614 if(die_info_ptr < die_info_end) { 615 if ((*die_info_ptr) == 0 && has_child) { 616 die_info_ptr++; 617 has_child = false; 618 } 619 } 620 621 /* die_info_ptr can be one-past-end. */ 622 if ((die_info_ptr == die_info_end) || 623 ((*die_info_ptr) == 0)) { 624 for (; child_depth > 0 && *die_info_ptr == 0; 625 child_depth--, die_info_ptr++); 626 } else { 627 child_depth = has_child ? child_depth + 1 : child_depth; 628 } 629 630 } while (child_depth != 0); 631 } 632 633 /* die_info_ptr > die_info_end is really a bug (possibly in dwarf 634 generation)(but we are past end, no more DIEs here), whereas 635 die_info_ptr == die_info_end means 'one past end, no more DIEs 636 here'. */ 637 if (die != NULL && die_info_ptr >= die_info_end) { 638 return (DW_DLV_NO_ENTRY); 639 } 640 641 if ((*die_info_ptr) == 0) { 642 return (DW_DLV_NO_ENTRY); 643 } 644 645 ret_die = (Dwarf_Die) _dwarf_get_alloc(dbg, DW_DLA_DIE, 1); 646 if (ret_die == NULL) { 647 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 648 return (DW_DLV_ERROR); 649 } 650 651 ret_die->di_debug_info_ptr = die_info_ptr; 652 ret_die->di_cu_context = 653 die == NULL ? dbg->de_cu_context : die->di_cu_context; 654 655 DECODE_LEB128_UWORD(die_info_ptr, utmp); 656 abbrev_code = (Dwarf_Word) utmp; 657 if (abbrev_code == 0) { 658 /* Zero means a null DIE */ 659 dwarf_dealloc(dbg, ret_die, DW_DLA_DIE); 660 return (DW_DLV_NO_ENTRY); 661 } 662 ret_die->di_abbrev_code = abbrev_code; 663 ret_die->di_abbrev_list = 664 _dwarf_get_abbrev_for_code(ret_die->di_cu_context, abbrev_code); 665 if (ret_die->di_abbrev_list == NULL || (die == NULL && 666 ret_die->di_abbrev_list-> 667 ab_tag != 668 DW_TAG_compile_unit)) { 669 dwarf_dealloc(dbg, ret_die, DW_DLA_DIE); 670 _dwarf_error(dbg, error, DW_DLE_FIRST_DIE_NOT_CU); 671 return (DW_DLV_ERROR); 672 } 673 674 *caller_ret_die = ret_die; 675 return (DW_DLV_OK); 676 } 677 678 679 int 680 dwarf_child(Dwarf_Die die, 681 Dwarf_Die * caller_ret_die, Dwarf_Error * error) 682 { 683 Dwarf_Byte_Ptr die_info_ptr = 0; 684 685 /* die_info_end points one-past-end of die area. */ 686 Dwarf_Byte_Ptr die_info_end = 0; 687 Dwarf_Die ret_die = 0; 688 Dwarf_Bool has_die_child = 0; 689 Dwarf_Debug dbg; 690 Dwarf_Word abbrev_code = 0; 691 Dwarf_Unsigned utmp = 0; 692 693 694 CHECK_DIE(die, DW_DLV_ERROR); 695 dbg = die->di_cu_context->cc_dbg; 696 die_info_ptr = die->di_debug_info_ptr; 697 698 /* NULL die has no child. */ 699 if ((*die_info_ptr) == 0) 700 return (DW_DLV_NO_ENTRY); 701 702 die_info_end = dbg->de_debug_info.dss_data + 703 die->di_cu_context->cc_debug_info_offset + 704 die->di_cu_context->cc_length + 705 die->di_cu_context->cc_length_size + 706 die->di_cu_context->cc_extension_size; 707 708 die_info_ptr = 709 _dwarf_next_die_info_ptr(die_info_ptr, die->di_cu_context, 710 die_info_end, NULL, false, 711 &has_die_child); 712 if (die_info_ptr == NULL) { 713 _dwarf_error(dbg, error, DW_DLE_NEXT_DIE_PTR_NULL); 714 return (DW_DLV_ERROR); 715 } 716 717 if (!has_die_child) 718 return (DW_DLV_NO_ENTRY); 719 720 ret_die = (Dwarf_Die) _dwarf_get_alloc(dbg, DW_DLA_DIE, 1); 721 if (ret_die == NULL) { 722 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 723 return (DW_DLV_ERROR); 724 } 725 ret_die->di_debug_info_ptr = die_info_ptr; 726 ret_die->di_cu_context = die->di_cu_context; 727 728 DECODE_LEB128_UWORD(die_info_ptr, utmp); 729 abbrev_code = (Dwarf_Word) utmp; 730 if (abbrev_code == 0) { 731 /* We have arrived at a null DIE, at the end of a CU or the end 732 of a list of siblings. */ 733 *caller_ret_die = 0; 734 dwarf_dealloc(dbg, ret_die, DW_DLA_DIE); 735 return DW_DLV_NO_ENTRY; 736 } 737 ret_die->di_abbrev_code = abbrev_code; 738 ret_die->di_abbrev_list = 739 _dwarf_get_abbrev_for_code(die->di_cu_context, abbrev_code); 740 if (ret_die->di_abbrev_list == NULL) { 741 dwarf_dealloc(dbg, ret_die, DW_DLA_DIE); 742 _dwarf_error(dbg, error, DW_DLE_DIE_BAD); 743 return (DW_DLV_ERROR); 744 } 745 746 *caller_ret_die = ret_die; 747 return (DW_DLV_OK); 748 } 749 750 /* 751 Given a (global, not cu_relative) die offset, this returns 752 a pointer to a DIE thru *new_die. 753 It is up to the caller to do a 754 dwarf_dealloc(dbg,*new_die,DW_DLE_DIE); 755 */ 756 int 757 dwarf_offdie(Dwarf_Debug dbg, 758 Dwarf_Off offset, Dwarf_Die * new_die, Dwarf_Error * error) 759 { 760 Dwarf_CU_Context cu_context = 0; 761 Dwarf_Off new_cu_offset = 0; 762 Dwarf_Die die = 0; 763 Dwarf_Byte_Ptr info_ptr = 0; 764 Dwarf_Unsigned abbrev_code = 0; 765 Dwarf_Unsigned utmp = 0; 766 767 if (dbg == NULL) { 768 _dwarf_error(NULL, error, DW_DLE_DBG_NULL); 769 return (DW_DLV_ERROR); 770 } 771 772 cu_context = _dwarf_find_CU_Context(dbg, offset); 773 if (cu_context == NULL) 774 cu_context = _dwarf_find_offdie_CU_Context(dbg, offset); 775 776 if (cu_context == NULL) { 777 int res = _dwarf_load_debug_info(dbg, error); 778 779 if (res != DW_DLV_OK) { 780 return res; 781 } 782 783 if (dbg->de_offdie_cu_context_end != NULL) { 784 Dwarf_CU_Context lcu_context = 785 dbg->de_offdie_cu_context_end; 786 new_cu_offset = 787 lcu_context->cc_debug_info_offset + 788 lcu_context->cc_length + 789 lcu_context->cc_length_size + 790 lcu_context->cc_extension_size; 791 } 792 793 794 do { 795 if ((new_cu_offset + 796 _dwarf_length_of_cu_header_simple(dbg)) >= 797 dbg->de_debug_info.dss_size) { 798 _dwarf_error(dbg, error, DW_DLE_OFFSET_BAD); 799 return (DW_DLV_ERROR); 800 } 801 802 cu_context = 803 _dwarf_make_CU_Context(dbg, new_cu_offset, error); 804 if (cu_context == NULL) { 805 /* Error if CU Context could not be made. Since 806 _dwarf_make_CU_Context has already registered an 807 error we do not do that here: we let the lower error 808 pass thru. */ 809 810 return (DW_DLV_ERROR); 811 } 812 813 if (dbg->de_offdie_cu_context == NULL) { 814 dbg->de_offdie_cu_context = cu_context; 815 dbg->de_offdie_cu_context_end = cu_context; 816 } else { 817 dbg->de_offdie_cu_context_end->cc_next = cu_context; 818 dbg->de_offdie_cu_context_end = cu_context; 819 } 820 821 new_cu_offset = new_cu_offset + cu_context->cc_length + 822 cu_context->cc_length_size; 823 824 } while (offset >= new_cu_offset); 825 } 826 827 die = (Dwarf_Die) _dwarf_get_alloc(dbg, DW_DLA_DIE, 1); 828 if (die == NULL) { 829 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 830 return (DW_DLV_ERROR); 831 } 832 die->di_cu_context = cu_context; 833 834 info_ptr = dbg->de_debug_info.dss_data + offset; 835 die->di_debug_info_ptr = info_ptr; 836 DECODE_LEB128_UWORD(info_ptr, utmp); 837 abbrev_code = utmp; 838 if (abbrev_code == 0) { 839 /* we are at a null DIE (or there is a bug). */ 840 *new_die = 0; 841 dwarf_dealloc(dbg, die, DW_DLA_DIE); 842 return DW_DLV_NO_ENTRY; 843 } 844 die->di_abbrev_code = abbrev_code; 845 die->di_abbrev_list = 846 _dwarf_get_abbrev_for_code(cu_context, abbrev_code); 847 if (die->di_abbrev_list == NULL) { 848 dwarf_dealloc(dbg, die, DW_DLA_DIE); 849 _dwarf_error(dbg, error, DW_DLE_DIE_ABBREV_LIST_NULL); 850 return (DW_DLV_ERROR); 851 } 852 853 *new_die = die; 854 return (DW_DLV_OK); 855 } 856