1 /* 2 3 Copyright (C) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. 4 Portions Copyright (C) 2007-2020 David Anderson. All Rights Reserved. 5 Portions Copyright 2012 SN Systems Ltd. All rights reserved. 6 7 8 This program is free software; you can redistribute it and/or modify it 9 under the terms of version 2.1 of the GNU Lesser General Public License 10 as published by the Free Software Foundation. 11 12 This program is distributed in the hope that it would be useful, but 13 WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 15 16 Further, this software is distributed without any warranty that it is 17 free of the rightful claim of any third person regarding infringement 18 or the like. Any license provided herein, whether implied or 19 otherwise, applies only to this software file. Patent licenses, if 20 any, provided herein do not apply to combinations of this program with 21 other software, or any other product whatsoever. 22 23 You should have received a copy of the GNU Lesser General Public 24 License along with this program; if not, write the Free Software 25 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, 26 USA. 27 28 */ 29 30 #include "config.h" 31 #include <stdio.h> 32 #include "dwarf_incl.h" 33 #include "dwarf_alloc.h" 34 #include "dwarf_error.h" 35 #include "dwarf_util.h" 36 #include "dwarf_arange.h" 37 #include "dwarf_global.h" /* for _dwarf_fixup_* */ 38 #include "dwarfstring.h" 39 40 static void 41 free_aranges_chain(Dwarf_Debug dbg, Dwarf_Chain head) 42 { 43 Dwarf_Chain cur = head; 44 Dwarf_Chain next = 0; 45 46 if(!head) { 47 return; 48 } 49 next = head->ch_next; 50 for( ;cur; cur = next) { 51 void *item = cur->ch_item; 52 int type = cur->ch_itemtype; 53 54 next = cur->ch_next; 55 if (item && type) { 56 dwarf_dealloc(dbg,item,type); 57 cur->ch_item = 0; 58 dwarf_dealloc(dbg,cur,DW_DLA_CHAIN); 59 } 60 } 61 } 62 63 /* Common code for two user-visible routines to share. 64 Errors here result in memory leaks, but errors here 65 are serious (making aranges unusable) so we assume 66 callers will not repeat the error often or mind the leaks. 67 */ 68 static int 69 dwarf_get_aranges_list(Dwarf_Debug dbg, 70 Dwarf_Chain * chain_out, 71 Dwarf_Signed * chain_count_out, 72 Dwarf_Error * error) 73 { 74 /* Sweeps through the arange. */ 75 Dwarf_Small *arange_ptr = 0; 76 Dwarf_Small *arange_ptr_start = 0; 77 78 /* Start of arange header. Used for rounding offset of arange_ptr 79 to twice the tuple size. Libdwarf requirement. */ 80 Dwarf_Small *header_ptr = 0; 81 82 /* Version of .debug_aranges header. */ 83 Dwarf_Unsigned version = 0; 84 85 /* Offset of current set of aranges into .debug_info. */ 86 Dwarf_Off info_offset = 0; 87 /* Size in bytes of addresses in target. */ 88 Dwarf_Small address_size = 0; 89 /* Size in bytes of segment offsets in target. */ 90 Dwarf_Small segment_size = 0; 91 /* Count of total number of aranges. */ 92 Dwarf_Signed arange_count = 0; 93 Dwarf_Arange arange = 0; 94 Dwarf_Unsigned section_size = 0; 95 Dwarf_Byte_Ptr arange_end_section = 0; 96 /* Used to chain Dwarf_Aranges structs. */ 97 Dwarf_Chain curr_chain = NULL; 98 Dwarf_Chain prev_chain = NULL; 99 Dwarf_Chain head_chain = NULL; 100 101 if (!dbg->de_debug_aranges.dss_size) { 102 return DW_DLV_NO_ENTRY; 103 } 104 arange_ptr = dbg->de_debug_aranges.dss_data; 105 arange_ptr_start = arange_ptr; 106 section_size = dbg->de_debug_aranges.dss_size; 107 arange_end_section = arange_ptr + section_size; 108 109 do { 110 /* Length of current set of aranges. 111 This is local length, which begins just 112 after the length field itself. */ 113 Dwarf_Unsigned area_length = 0; 114 Dwarf_Small remainder = 0; 115 Dwarf_Unsigned range_entry_size = 0; 116 int local_length_size; 117 int local_extension_size = 0; 118 Dwarf_Small *end_this_arange = 0; 119 int res = 0; 120 121 122 header_ptr = arange_ptr; 123 if (header_ptr >= arange_end_section) { 124 free_aranges_chain(dbg,head_chain); 125 _dwarf_error(dbg, error,DW_DLE_ARANGES_HEADER_ERROR); 126 return DW_DLV_ERROR; 127 } 128 res = _dwarf_read_area_length_ck_wrapper(dbg,&area_length, 129 &arange_ptr,&local_length_size,&local_extension_size, 130 section_size,arange_end_section,error); 131 if (res != DW_DLV_OK) { 132 free_aranges_chain(dbg,head_chain); 133 return res; 134 } 135 /* arange_ptr has been incremented appropriately past 136 the length field by READ_AREA_LENGTH. */ 137 138 if (area_length > dbg->de_debug_aranges.dss_size) { 139 free_aranges_chain(dbg,head_chain); 140 _dwarf_error(dbg, error,DW_DLE_ARANGES_HEADER_ERROR); 141 return DW_DLV_ERROR; 142 } 143 if ((area_length + local_length_size + local_extension_size) > 144 dbg->de_debug_aranges.dss_size) { 145 free_aranges_chain(dbg,head_chain); 146 _dwarf_error(dbg, error, DW_DLE_ARANGES_HEADER_ERROR); 147 return DW_DLV_ERROR; 148 } 149 150 end_this_arange = arange_ptr + area_length; 151 if (end_this_arange > arange_end_section) { 152 free_aranges_chain(dbg,head_chain); 153 _dwarf_error(dbg, error,DW_DLE_ARANGES_HEADER_ERROR); 154 return DW_DLV_ERROR; 155 } 156 if (!area_length) { 157 /* We read 4 bytes of zero, so area-length zero. 158 Keep scanning. First seen Nov 27, 2018 159 in GNU-cc in windows dll. */ 160 continue; 161 } 162 163 res = _dwarf_read_unaligned_ck_wrapper(dbg,&version, 164 arange_ptr,DWARF_HALF_SIZE,end_this_arange,error); 165 if (res != DW_DLV_OK) { 166 free_aranges_chain(dbg,head_chain); 167 return res; 168 } 169 arange_ptr += DWARF_HALF_SIZE; 170 if (arange_ptr >= end_this_arange) { 171 free_aranges_chain(dbg,head_chain); 172 _dwarf_error(dbg, error, DW_DLE_ARANGES_HEADER_ERROR); 173 return DW_DLV_ERROR; 174 } 175 if (version != DW_ARANGES_VERSION2) { 176 free_aranges_chain(dbg,head_chain); 177 _dwarf_error(dbg, error, DW_DLE_VERSION_STAMP_ERROR); 178 return (DW_DLV_ERROR); 179 } 180 res = _dwarf_read_unaligned_ck_wrapper(dbg,&info_offset, 181 arange_ptr,local_length_size,end_this_arange,error); 182 if (res != DW_DLV_OK) { 183 free_aranges_chain(dbg,head_chain); 184 return res; 185 } 186 187 arange_ptr += local_length_size; 188 if (arange_ptr >= end_this_arange) { 189 free_aranges_chain(dbg,head_chain); 190 _dwarf_error(dbg, error, DW_DLE_ARANGES_HEADER_ERROR); 191 return DW_DLV_ERROR; 192 } 193 /* This applies to debug_info only, not to debug_types. */ 194 if (info_offset >= dbg->de_debug_info.dss_size) { 195 FIX_UP_OFFSET_IRIX_BUG(dbg, info_offset, 196 "arange info offset.a"); 197 if (info_offset >= dbg->de_debug_info.dss_size) { 198 free_aranges_chain(dbg,head_chain); 199 _dwarf_error(dbg, error, DW_DLE_ARANGE_OFFSET_BAD); 200 return (DW_DLV_ERROR); 201 } 202 } 203 204 address_size = *(Dwarf_Small *) arange_ptr; 205 if (address_size > sizeof(Dwarf_Addr)) { 206 free_aranges_chain(dbg,head_chain); 207 _dwarf_error(dbg, error, DW_DLE_ADDRESS_SIZE_ERROR); 208 return DW_DLV_ERROR; 209 } 210 if (address_size == 0) { 211 free_aranges_chain(dbg,head_chain); 212 _dwarf_error(dbg, error, DW_DLE_ADDRESS_SIZE_ZERO); 213 return DW_DLV_ERROR; 214 } 215 /* It is not an error if the sizes differ. 216 Unusual, but not an error. */ 217 arange_ptr = arange_ptr + sizeof(Dwarf_Small); 218 219 /* The following deref means we better 220 check the pointer for off-end. */ 221 if (arange_ptr >= end_this_arange) { 222 free_aranges_chain(dbg,head_chain); 223 _dwarf_error(dbg, error, DW_DLE_ARANGE_OFFSET_BAD); 224 return DW_DLV_ERROR; 225 } 226 227 /* Even DWARF2 had a segment_size field here, meaning 228 size in bytes of a segment descriptor on the target 229 system. */ 230 segment_size = *(Dwarf_Small *) arange_ptr; 231 if (segment_size > sizeof(Dwarf_Addr)) { 232 free_aranges_chain(dbg,head_chain); 233 _dwarf_error(dbg, error, DW_DLE_SEGMENT_SIZE_BAD); 234 return (DW_DLV_ERROR); 235 } 236 arange_ptr = arange_ptr + sizeof(Dwarf_Small); 237 238 /* Code below will check for == end_this_arange as appropriate. */ 239 if (arange_ptr > end_this_arange) { 240 free_aranges_chain(dbg,head_chain); 241 _dwarf_error(dbg, error, DW_DLE_ARANGE_OFFSET_BAD); 242 return (DW_DLV_ERROR); 243 } 244 245 range_entry_size = 2*address_size + segment_size; 246 /* Round arange_ptr offset to next multiple of address_size. */ 247 remainder = (Dwarf_Unsigned) (arange_ptr - header_ptr) % 248 (range_entry_size); 249 if (remainder != 0) { 250 arange_ptr = arange_ptr + (2 * address_size) - remainder; 251 } 252 253 do { 254 Dwarf_Addr range_address = 0; 255 Dwarf_Unsigned segment_selector = 0; 256 Dwarf_Unsigned range_length = 0; 257 /* For segmented address spaces, the first field to 258 read is a segment selector (new in DWARF4). 259 The version number DID NOT CHANGE from 2, which 260 is quite surprising. 261 Also surprising since the segment_size 262 was always there 263 in the table header! */ 264 /* We want to test cu_version here but 265 currently with no way to do that. 266 So we just hope no one using 267 segment_selectors, really. FIXME */ 268 if (segment_size) { 269 /* Only applies if cu_version >= 4. */ 270 res = _dwarf_read_unaligned_ck_wrapper(dbg, 271 &segment_selector, 272 arange_ptr,segment_size,end_this_arange,error); 273 if (res != DW_DLV_OK) { 274 free_aranges_chain(dbg,head_chain); 275 return res; 276 } 277 arange_ptr += address_size; 278 } 279 280 res = _dwarf_read_unaligned_ck_wrapper(dbg,&range_address, 281 arange_ptr,address_size,end_this_arange,error); 282 if (res != DW_DLV_OK) { 283 free_aranges_chain(dbg,head_chain); 284 return res; 285 } 286 arange_ptr += address_size; 287 288 res = _dwarf_read_unaligned_ck_wrapper(dbg,&range_length, 289 arange_ptr,address_size,end_this_arange,error); 290 if (res != DW_DLV_OK) { 291 free_aranges_chain(dbg,head_chain); 292 return res; 293 } 294 295 arange_ptr += address_size; 296 297 { 298 /* We used to suppress all-zero entries, but 299 now we return all aranges entries so we show 300 the entire content. March 31, 2010. */ 301 302 arange = (Dwarf_Arange) 303 _dwarf_get_alloc(dbg, DW_DLA_ARANGE, 1); 304 if (arange == NULL) { 305 free_aranges_chain(dbg,head_chain); 306 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 307 return (DW_DLV_ERROR); 308 } 309 310 arange->ar_segment_selector = segment_selector; 311 arange->ar_segment_selector_size = segment_size; 312 arange->ar_address = range_address; 313 arange->ar_length = range_length; 314 arange->ar_info_offset = info_offset; 315 arange->ar_dbg = dbg; 316 arange_count++; 317 318 curr_chain = (Dwarf_Chain) 319 _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); 320 if (curr_chain == NULL) { 321 free_aranges_chain(dbg,head_chain); 322 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 323 return (DW_DLV_ERROR); 324 } 325 326 curr_chain->ch_item = arange; 327 curr_chain->ch_itemtype = DW_DLA_ARANGE; 328 if (head_chain == NULL) 329 head_chain = prev_chain = curr_chain; 330 else { 331 prev_chain->ch_next = curr_chain; 332 prev_chain = curr_chain; 333 } 334 } 335 /* The current set of ranges is terminated by 336 range_address 0 and range_length 0, but that 337 does not necessarily terminate the ranges for this CU! 338 There can be multiple sets in that DWARF 339 does not explicitly forbid multiple sets. 340 DWARF2,3,4 section 7.20 341 We stop short to avoid overrun of the end of the CU. */ 342 343 } while (end_this_arange >= (arange_ptr + range_entry_size)); 344 345 /* A compiler could emit some padding bytes here. dwarf2/3 346 (dwarf4 sec 7.20) does not clearly make extra padding 347 bytes illegal. */ 348 if (end_this_arange < arange_ptr) { 349 Dwarf_Unsigned pad_count = arange_ptr - end_this_arange; 350 Dwarf_Unsigned offset = arange_ptr - arange_ptr_start; 351 dwarfstring aramsg; 352 353 dwarfstring_constructor(&aramsg); 354 /* Safe. Length strictly limited. */ 355 dwarfstring_append_printf_u(&aramsg, 356 "DW_DLE_ARANGE_LENGTH_BAD." 357 " 0x%" DW_PR_XZEROS DW_PR_DUx, 358 pad_count); 359 dwarfstring_append_printf_u(&aramsg, 360 " pad bytes at offset 0x%" DW_PR_XZEROS DW_PR_DUx 361 " in .debug_aranges", 362 offset); 363 dwarf_insert_harmless_error(dbg, 364 dwarfstring_string(&aramsg)); 365 dwarfstring_destructor(&aramsg); 366 } 367 /* For most compilers, arange_ptr == end_this_arange at 368 this point. But not if there were padding bytes */ 369 arange_ptr = end_this_arange; 370 } while (arange_ptr < arange_end_section); 371 372 if (arange_ptr != arange_end_section) { 373 free_aranges_chain(dbg,head_chain); 374 _dwarf_error(dbg, error, DW_DLE_ARANGE_DECODE_ERROR); 375 return (DW_DLV_ERROR); 376 } 377 *chain_out = head_chain; 378 *chain_count_out = arange_count; 379 return DW_DLV_OK; 380 } 381 382 /* 383 This function returns the count of the number of 384 aranges in the .debug_aranges section. It sets 385 aranges to point to a block of Dwarf_Arange's 386 describing the arange's. It returns DW_DLV_ERROR 387 on error. 388 389 Must be identical in most aspects to 390 dwarf_get_aranges_addr_offsets! 391 392 */ 393 int 394 dwarf_get_aranges(Dwarf_Debug dbg, 395 Dwarf_Arange ** aranges, 396 Dwarf_Signed * returned_count, Dwarf_Error * error) 397 { 398 /* Count of total number of aranges. */ 399 Dwarf_Signed arange_count = 0; 400 401 Dwarf_Arange *arange_block = 0; 402 403 /* Used to chain Dwarf_Aranges structs. */ 404 Dwarf_Chain curr_chain = NULL; 405 Dwarf_Chain prev_chain = NULL; 406 Dwarf_Chain head_chain = NULL; 407 Dwarf_Signed i = 0; 408 int res = DW_DLV_ERROR; 409 410 /* ***** BEGIN CODE ***** */ 411 412 if (dbg == NULL) { 413 _dwarf_error(NULL, error, DW_DLE_DBG_NULL); 414 return (DW_DLV_ERROR); 415 } 416 417 res = _dwarf_load_section(dbg, &dbg->de_debug_aranges, error); 418 if (res != DW_DLV_OK) { 419 return res; 420 } 421 /* aranges points in to info, so if info needs expanding 422 we have to load it. */ 423 res = _dwarf_load_debug_info(dbg, error); 424 if (res != DW_DLV_OK) { 425 return res; 426 } 427 428 res = dwarf_get_aranges_list(dbg,&head_chain,&arange_count,error); 429 if (res != DW_DLV_OK) { 430 free_aranges_chain(dbg,head_chain); 431 return res; 432 } 433 434 arange_block = (Dwarf_Arange *) 435 _dwarf_get_alloc(dbg, DW_DLA_LIST, arange_count); 436 if (arange_block == NULL) { 437 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 438 free_aranges_chain(dbg,head_chain); 439 return DW_DLV_ERROR; 440 } 441 442 /* See also free_aranges_chain() above */ 443 curr_chain = head_chain; 444 for (i = 0; i < arange_count; i++) { 445 446 /* Copies pointers. No dealloc of ch_item, */ 447 *(arange_block + i) = curr_chain->ch_item; 448 curr_chain->ch_item = 0; 449 prev_chain = curr_chain; 450 curr_chain = curr_chain->ch_next; 451 dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN); 452 } 453 454 *aranges = arange_block; 455 *returned_count = (arange_count); 456 return DW_DLV_OK; 457 } 458 459 /* 460 This function returns DW_DLV_OK if it succeeds 461 and DW_DLV_ERR or DW_DLV_OK otherwise. 462 count is set to the number of addresses in the 463 .debug_aranges section. 464 For each address, the corresponding element in 465 an array is set to the address itself(aranges) and 466 the section offset (offsets). 467 Must be identical in most aspects to 468 dwarf_get_aranges! 469 */ 470 int 471 _dwarf_get_aranges_addr_offsets(Dwarf_Debug dbg, 472 Dwarf_Addr ** addrs, 473 Dwarf_Off ** offsets, 474 Dwarf_Signed * count, 475 Dwarf_Error * error) 476 { 477 Dwarf_Signed i = 0; 478 479 /* Used to chain Dwarf_Aranges structs. */ 480 Dwarf_Chain curr_chain = NULL; 481 Dwarf_Chain prev_chain = NULL; 482 Dwarf_Chain head_chain = NULL; 483 484 Dwarf_Signed arange_count = 0; 485 Dwarf_Addr *arange_addrs = 0; 486 Dwarf_Off *arange_offsets = 0; 487 488 int res = DW_DLV_ERROR; 489 490 /* ***** BEGIN CODE ***** */ 491 492 if (error != NULL) 493 *error = NULL; 494 495 if (dbg == NULL) { 496 _dwarf_error(NULL, error, DW_DLE_DBG_NULL); 497 return (DW_DLV_ERROR); 498 } 499 500 res = _dwarf_load_section(dbg, &dbg->de_debug_aranges,error); 501 if (res != DW_DLV_OK) { 502 return res; 503 } 504 /* aranges points in to info, so if info needs expanding 505 we have to load it. */ 506 res = _dwarf_load_debug_info(dbg, error); 507 if (res != DW_DLV_OK) { 508 return res; 509 } 510 res = dwarf_get_aranges_list(dbg,&head_chain,&arange_count,error); 511 if (res != DW_DLV_OK) { 512 return res; 513 } 514 arange_addrs = (Dwarf_Addr *) 515 _dwarf_get_alloc(dbg, DW_DLA_ADDR, arange_count); 516 if (arange_addrs == NULL) { 517 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 518 return (DW_DLV_ERROR); 519 } 520 arange_offsets = (Dwarf_Off *) 521 _dwarf_get_alloc(dbg, DW_DLA_ADDR, arange_count); 522 if (arange_offsets == NULL) { 523 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 524 return (DW_DLV_ERROR); 525 } 526 527 curr_chain = head_chain; 528 for (i = 0; i < arange_count; i++) { 529 Dwarf_Arange ar = curr_chain->ch_item; 530 int itemtype = curr_chain->ch_itemtype; 531 532 curr_chain->ch_item = 0; 533 arange_addrs[i] = ar->ar_address; 534 arange_offsets[i] = ar->ar_info_offset; 535 prev_chain = curr_chain; 536 curr_chain = curr_chain->ch_next; 537 if (ar && itemtype) { 538 dwarf_dealloc(dbg, ar, itemtype); 539 } 540 dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN); 541 } 542 *count = arange_count; 543 *offsets = arange_offsets; 544 *addrs = arange_addrs; 545 return (DW_DLV_OK); 546 } 547 548 549 /* 550 This function takes a pointer to a block 551 of Dwarf_Arange's, and a count of the 552 length of the block. It checks if the 553 given address is within the range of an 554 address range in the block. If yes, it 555 returns the appropriate Dwarf_Arange. 556 Otherwise, it returns DW_DLV_ERROR. 557 */ 558 int 559 dwarf_get_arange(Dwarf_Arange * aranges, 560 Dwarf_Unsigned arange_count, 561 Dwarf_Addr address, 562 Dwarf_Arange * returned_arange, Dwarf_Error * error) 563 { 564 Dwarf_Arange curr_arange = 0; 565 Dwarf_Unsigned i = 0; 566 567 if (aranges == NULL) { 568 _dwarf_error(NULL, error, DW_DLE_ARANGES_NULL); 569 return (DW_DLV_ERROR); 570 } 571 for (i = 0; i < arange_count; i++) { 572 curr_arange = *(aranges + i); 573 if (address >= curr_arange->ar_address && 574 address < 575 curr_arange->ar_address + curr_arange->ar_length) { 576 *returned_arange = curr_arange; 577 return (DW_DLV_OK); 578 } 579 } 580 581 return (DW_DLV_NO_ENTRY); 582 } 583 584 585 /* 586 This function takes an Dwarf_Arange, 587 and returns the offset of the first 588 die in the compilation-unit that the 589 arange belongs to. Returns DW_DLV_ERROR 590 on error. 591 592 For an arange, the cu_die can only be from debug_info, 593 not debug_types, it seems. 594 */ 595 int 596 dwarf_get_cu_die_offset(Dwarf_Arange arange, 597 Dwarf_Off * returned_offset, 598 Dwarf_Error * error) 599 { 600 Dwarf_Debug dbg = 0; 601 Dwarf_Off offset = 0; 602 Dwarf_Unsigned headerlen = 0; 603 int cres = 0; 604 605 if (arange == NULL) { 606 _dwarf_error(NULL, error, DW_DLE_ARANGE_NULL); 607 return (DW_DLV_ERROR); 608 } 609 dbg = arange->ar_dbg; 610 offset = arange->ar_info_offset; 611 /* This applies to debug_info only, not to debug_types. */ 612 if (!dbg->de_debug_info.dss_data) { 613 int res = _dwarf_load_debug_info(dbg, error); 614 615 if (res != DW_DLV_OK) { 616 return res; 617 } 618 } 619 620 cres = _dwarf_length_of_cu_header(dbg, offset, 621 true, &headerlen,error); 622 if (cres != DW_DLV_OK) { 623 return cres; 624 } 625 *returned_offset = headerlen + offset; 626 return DW_DLV_OK; 627 } 628 629 /* This function takes an Dwarf_Arange, 630 and returns the offset of the CU header 631 in the compilation-unit that the 632 arange belongs to. Returns DW_DLV_ERROR 633 on error. 634 Ensures .debug_info loaded so 635 the cu_offset is meaningful. */ 636 int 637 dwarf_get_arange_cu_header_offset(Dwarf_Arange arange, 638 Dwarf_Off * cu_header_offset_returned, 639 Dwarf_Error * error) 640 { 641 Dwarf_Debug dbg = 0; 642 if (arange == NULL) { 643 _dwarf_error(NULL, error, DW_DLE_ARANGE_NULL); 644 return (DW_DLV_ERROR); 645 } 646 dbg = arange->ar_dbg; 647 /* This applies to debug_info only, not to debug_types. */ 648 /* Like dwarf_get_arange_info this ensures debug_info loaded: 649 the cu_header is in debug_info and will be used else 650 we would not call dwarf_get_arange_cu_header_offset. */ 651 if (!dbg->de_debug_info.dss_data) { 652 int res = _dwarf_load_debug_info(dbg, error); 653 if (res != DW_DLV_OK) { 654 return res; 655 } 656 } 657 *cu_header_offset_returned = arange->ar_info_offset; 658 return DW_DLV_OK; 659 } 660 661 662 663 664 /* 665 This function takes a Dwarf_Arange, and returns 666 true if it is not NULL. It also stores the start 667 address of the range in *start, the length of the 668 range in *length, and the offset of the first die 669 in the compilation-unit in *cu_die_offset. It 670 returns false on error. 671 If cu_die_offset returned ensures .debug_info loaded so 672 the cu_die_offset is meaningful. 673 */ 674 int 675 dwarf_get_arange_info(Dwarf_Arange arange, 676 Dwarf_Addr * start, 677 Dwarf_Unsigned * length, 678 Dwarf_Off * cu_die_offset, Dwarf_Error * error) 679 { 680 if (arange == NULL) { 681 _dwarf_error(NULL, error, DW_DLE_ARANGE_NULL); 682 return (DW_DLV_ERROR); 683 } 684 685 if (start != NULL) 686 *start = arange->ar_address; 687 if (length != NULL) 688 *length = arange->ar_length; 689 if (cu_die_offset != NULL) { 690 Dwarf_Debug dbg = arange->ar_dbg; 691 Dwarf_Off headerlen = 0; 692 Dwarf_Off offset = arange->ar_info_offset; 693 int cres = 0; 694 695 /* This applies to debug_info only, not to debug_types. */ 696 if (!dbg->de_debug_info.dss_data) { 697 int res = _dwarf_load_debug_info(dbg, error); 698 if (res != DW_DLV_OK) { 699 return res; 700 } 701 } 702 703 cres = _dwarf_length_of_cu_header(dbg, offset, 704 true, &headerlen,error); 705 if (cres != DW_DLV_OK) { 706 return cres; 707 } 708 *cu_die_offset = headerlen + offset; 709 } 710 return (DW_DLV_OK); 711 } 712 713 714 /* New for DWARF4, entries may have segment information. 715 *segment is only meaningful if *segment_entry_size is non-zero. */ 716 int 717 dwarf_get_arange_info_b(Dwarf_Arange arange, 718 Dwarf_Unsigned* segment, 719 Dwarf_Unsigned* segment_entry_size, 720 Dwarf_Addr * start, 721 Dwarf_Unsigned* length, 722 Dwarf_Off * cu_die_offset, 723 Dwarf_Error * error) 724 { 725 if (arange == NULL) { 726 _dwarf_error(NULL, error, DW_DLE_ARANGE_NULL); 727 return DW_DLV_ERROR; 728 } 729 730 if (segment != NULL) { 731 *segment = arange->ar_segment_selector; 732 } 733 if (segment_entry_size != NULL) { 734 *segment_entry_size = arange->ar_segment_selector_size; 735 } 736 if (start != NULL) 737 *start = arange->ar_address; 738 if (length != NULL) 739 *length = arange->ar_length; 740 if (cu_die_offset != NULL) { 741 Dwarf_Debug dbg = arange->ar_dbg; 742 Dwarf_Off offset = arange->ar_info_offset; 743 Dwarf_Unsigned headerlen = 0; 744 int cres = 0; 745 746 /* This applies to debug_info only, not to debug_types. */ 747 if (!dbg->de_debug_info.dss_data) { 748 int res = _dwarf_load_debug_info(dbg, error); 749 if (res != DW_DLV_OK) { 750 return res; 751 } 752 } 753 cres = _dwarf_length_of_cu_header(dbg, offset, 754 true, &headerlen,error); 755 if (cres != DW_DLV_OK) { 756 return cres; 757 } 758 *cu_die_offset = offset + headerlen; 759 760 } 761 return (DW_DLV_OK); 762 } 763