1 /* 2 3 Copyright (C) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. 4 Portions Copyright (C) 2007-2011 David Anderson. All Rights Reserved. 5 6 This program is free software; you can redistribute it 7 and/or modify it under the terms of version 2.1 of the 8 GNU Lesser General Public License as published by the Free 9 Software Foundation. 10 11 This program is distributed in the hope that it would be 12 useful, but WITHOUT ANY WARRANTY; without even the implied 13 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 14 PURPOSE. 15 16 Further, this software is distributed without any warranty 17 that it is free of the rightful claim of any third person 18 regarding infringement or the like. Any license provided 19 herein, whether implied or otherwise, applies only to this 20 software file. Patent licenses, if any, provided herein 21 do not apply to combinations of this program with other 22 software, or any other product whatsoever. 23 24 You should have received a copy of the GNU Lesser General 25 Public License along with this program; if not, write the 26 Free Software Foundation, Inc., 51 Franklin Street - Fifth 27 Floor, Boston MA 02110-1301, USA. 28 29 */ 30 31 #include "config.h" 32 #include <stdio.h> 33 #include "dwarf_incl.h" 34 #include "dwarf_alloc.h" 35 #include "dwarf_error.h" 36 #include "dwarf_util.h" 37 #include "dwarfstring.h" 38 #include "dwarf_global.h" 39 40 41 #ifdef __sgi /* __sgi should only be defined for IRIX/MIPS. */ 42 /* The 'fixup' here intended for IRIX targets only. 43 With a 2+GB Elf64 IRIX executable (under 4GB in size), 44 some DIE offsets wrongly 45 got the 32bit upper bit sign extended. For the cu-header 46 offset in the .debug_pubnames section and in the 47 .debug_aranges section. 48 the 'varp' here is a pointer to an offset into .debug_info. 49 We fix up the offset here if it seems advisable.. 50 51 As of June 2005 we have identified a series of mistakes 52 in ldx64 that can cause this (64 bit values getting passed 53 thru 32-bit signed knothole). 54 */ 55 void 56 _dwarf_fix_up_offset_irix(Dwarf_Debug dbg, 57 Dwarf_Unsigned * varp, char *caller_site_name) 58 { 59 60 Dwarf_Unsigned var = *varp; 61 62 #define UPPER33 0xffffffff80000000LL 63 #define LOWER32 0xffffffffLL 64 /* Restrict the hack to the known case. Upper 32 bits erroneously 65 sign extended from lower 32 upper bit. */ 66 if ((var & UPPER33) == UPPER33) { 67 var &= LOWER32; 68 /* Apply the fix. Dreadful hack. */ 69 *varp = var; 70 } 71 #undef UPPER33 72 #undef LOWER32 73 return; 74 } 75 #endif /* __sgi */ 76 77 static void 78 dealloc_globals_chain(Dwarf_Debug dbg, 79 Dwarf_Chain head_chain) 80 { 81 Dwarf_Chain curr_chain = 0; 82 Dwarf_Chain prev_chain = 0; 83 int chaintype = DW_DLA_CHAIN; 84 85 curr_chain = head_chain; 86 for (; curr_chain; ) { 87 void *item = curr_chain->ch_item; 88 int itemtype = curr_chain->ch_itemtype; 89 90 prev_chain = curr_chain; 91 dwarf_dealloc(dbg, item,itemtype); 92 prev_chain->ch_item = 0; 93 curr_chain = curr_chain->ch_next; 94 dwarf_dealloc(dbg, prev_chain, chaintype); 95 } 96 } 97 98 int 99 dwarf_get_globals(Dwarf_Debug dbg, 100 Dwarf_Global ** globals, 101 Dwarf_Signed * return_count, Dwarf_Error * error) 102 { 103 int res = _dwarf_load_section(dbg, &dbg->de_debug_pubnames,error); 104 if (res != DW_DLV_OK) { 105 return res; 106 } 107 if (!dbg->de_debug_pubnames.dss_size) { 108 return DW_DLV_NO_ENTRY; 109 } 110 111 res = _dwarf_internal_get_pubnames_like_data(dbg, 112 dbg->de_debug_pubnames.dss_data, 113 dbg->de_debug_pubnames.dss_size, 114 globals, 115 return_count, 116 error, 117 DW_DLA_GLOBAL_CONTEXT, 118 DW_DLA_GLOBAL, 119 DW_DLE_PUBNAMES_LENGTH_BAD, 120 DW_DLE_PUBNAMES_VERSION_ERROR); 121 return res; 122 123 } 124 125 /* Deallocating fully requires deallocating the list 126 and all entries. But some internal data is 127 not exposed, so we need a function with internal knowledge. 128 */ 129 130 void 131 dwarf_globals_dealloc(Dwarf_Debug dbg, Dwarf_Global * dwgl, 132 Dwarf_Signed count) 133 { 134 _dwarf_internal_globals_dealloc(dbg, dwgl, 135 count, 136 DW_DLA_GLOBAL_CONTEXT, 137 DW_DLA_GLOBAL, DW_DLA_LIST); 138 return; 139 } 140 141 void 142 _dwarf_internal_globals_dealloc(Dwarf_Debug dbg, Dwarf_Global * dwgl, 143 Dwarf_Signed count, 144 int context_DLA_code, 145 int global_DLA_code, int list_DLA_code) 146 { 147 Dwarf_Signed i; 148 struct Dwarf_Global_Context_s *glcp = 0; 149 struct Dwarf_Global_Context_s *lastglcp = 0; 150 151 if(!dwgl) { 152 return; 153 } 154 for (i = 0; i < count; i++) { 155 Dwarf_Global dgb = dwgl[i]; 156 157 if (!dgb) { 158 continue; 159 } 160 /* Avoids duplicate frees of repeated 161 use of contexts (while assuming that 162 all uses of a particular gl_context 163 will appear next to each other. */ 164 glcp = dgb->gl_context; 165 if (lastglcp != glcp) { 166 lastglcp = glcp; 167 dwarf_dealloc(dbg, glcp, context_DLA_code); 168 } 169 dwarf_dealloc(dbg, dgb, global_DLA_code); 170 } 171 dwarf_dealloc(dbg, dwgl, list_DLA_code); 172 return; 173 } 174 175 /* Sweeps the complete section. */ 176 int 177 _dwarf_internal_get_pubnames_like_data(Dwarf_Debug dbg, 178 Dwarf_Small * section_data_ptr, 179 Dwarf_Unsigned section_length, 180 Dwarf_Global ** globals, 181 Dwarf_Signed * return_count, 182 Dwarf_Error * error, 183 int context_DLA_code, 184 int global_DLA_code, 185 int length_err_num, 186 int version_err_num) 187 { 188 Dwarf_Small *pubnames_like_ptr = 0; 189 Dwarf_Off pubnames_section_offset = 0; 190 Dwarf_Small *section_end_ptr = section_data_ptr +section_length; 191 192 /* Points to the context for the current set of global names, and 193 contains information to identify the compilation-unit that the 194 set refers to. */ 195 Dwarf_Global_Context pubnames_context = 0; 196 197 Dwarf_Unsigned version = 0; 198 199 /* Offset from the start of compilation-unit for the current 200 global. */ 201 Dwarf_Off die_offset_in_cu = 0; 202 203 Dwarf_Unsigned global_count = 0; 204 205 /* Points to the current global read. */ 206 Dwarf_Global global = 0; 207 208 /* Used to chain the Dwarf_Global_s structs for creating contiguous 209 list of pointers to the structs. */ 210 Dwarf_Chain curr_chain = 0; 211 Dwarf_Chain prev_chain = 0; 212 Dwarf_Chain head_chain = 0; 213 214 /* Points to contiguous block of Dwarf_Global's to be returned. */ 215 Dwarf_Global *ret_globals = 0; 216 int mres = 0; 217 218 /* Temporary counter. */ 219 Dwarf_Unsigned i = 0; 220 221 if (dbg == NULL) { 222 _dwarf_error(NULL, error, DW_DLE_DBG_NULL); 223 return (DW_DLV_ERROR); 224 } 225 /* We will eventually need the .debug_info data. Load it now. */ 226 if (!dbg->de_debug_info.dss_data) { 227 int res = _dwarf_load_debug_info(dbg, error); 228 229 if (res != DW_DLV_OK) { 230 return res; 231 } 232 } 233 if (section_data_ptr == NULL) { 234 return (DW_DLV_NO_ENTRY); 235 } 236 pubnames_like_ptr = section_data_ptr; 237 do { 238 Dwarf_Unsigned length = 0; 239 int local_extension_size = 0; 240 int local_length_size = 0; 241 242 /* Some compilers emit padding at the end of each cu's area. 243 pubnames_ptr_past_end_cu records the true area end for the 244 pubnames(like) content of a cu. 245 Essentially the length in the header and the 0 246 terminator of the data are redundant information. The 247 dwarf2/3 spec does not mention what to do if the length is 248 past the 0 terminator. So we take any bytes left after the 0 249 as padding and ignore them. */ 250 Dwarf_Small *pubnames_ptr_past_end_cu = 0; 251 252 253 pubnames_context = (Dwarf_Global_Context) 254 _dwarf_get_alloc(dbg, context_DLA_code, 1); 255 if (pubnames_context == NULL) { 256 dealloc_globals_chain(dbg,head_chain); 257 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 258 return DW_DLV_ERROR; 259 } 260 /* READ_AREA_LENGTH updates pubnames_like_ptr for consumed 261 bytes. */ 262 mres = _dwarf_read_area_length_ck_wrapper(dbg, 263 &length,&pubnames_like_ptr,&local_length_size, 264 &local_extension_size,section_length,section_end_ptr, 265 error); 266 if (mres != DW_DLV_OK) { 267 dealloc_globals_chain(dbg,head_chain); 268 dwarf_dealloc(dbg,pubnames_context,context_DLA_code); 269 return mres; 270 } 271 pubnames_context->pu_length_size = local_length_size; 272 pubnames_context->pu_length = length; 273 pubnames_context->pu_extension_size = local_extension_size; 274 pubnames_context->pu_dbg = dbg; 275 pubnames_context->pu_pub_offset = pubnames_section_offset; 276 pubnames_ptr_past_end_cu = pubnames_like_ptr + length; 277 278 mres = _dwarf_read_unaligned_ck_wrapper(dbg, 279 &version,pubnames_like_ptr,DWARF_HALF_SIZE, 280 section_end_ptr,error); 281 if (mres != DW_DLV_OK) { 282 dealloc_globals_chain(dbg,head_chain); 283 dwarf_dealloc(dbg,pubnames_context,context_DLA_code); 284 return mres; 285 } 286 pubnames_context->pu_version = version; 287 pubnames_like_ptr += DWARF_HALF_SIZE; 288 /* ASSERT: DW_PUBNAMES_VERSION2 == DW_PUBTYPES_VERSION2 */ 289 if (version != DW_PUBNAMES_VERSION2) { 290 dealloc_globals_chain(dbg,head_chain); 291 dwarf_dealloc(dbg,pubnames_context,context_DLA_code); 292 _dwarf_error(dbg, error, version_err_num); 293 return DW_DLV_ERROR; 294 } 295 296 /* Offset of CU header in debug section. */ 297 mres = _dwarf_read_unaligned_ck_wrapper(dbg, 298 &pubnames_context->pu_offset_of_cu_header, 299 pubnames_like_ptr, 300 pubnames_context->pu_length_size, 301 section_end_ptr,error); 302 if (mres != DW_DLV_OK) { 303 dealloc_globals_chain(dbg,head_chain); 304 dwarf_dealloc(dbg,pubnames_context,context_DLA_code); 305 return mres; 306 } 307 308 pubnames_like_ptr += pubnames_context->pu_length_size; 309 310 FIX_UP_OFFSET_IRIX_BUG(dbg, 311 pubnames_context->pu_offset_of_cu_header, 312 "pubnames cu header offset"); 313 mres = _dwarf_read_unaligned_ck_wrapper(dbg, 314 &pubnames_context->pu_info_length, 315 pubnames_like_ptr, 316 pubnames_context->pu_length_size, 317 section_end_ptr,error); 318 if (mres != DW_DLV_OK) { 319 dealloc_globals_chain(dbg,head_chain); 320 dwarf_dealloc(dbg,pubnames_context,context_DLA_code); 321 return mres; 322 } 323 pubnames_like_ptr += pubnames_context->pu_length_size; 324 325 if (pubnames_like_ptr > (section_data_ptr + section_length)) { 326 dealloc_globals_chain(dbg,head_chain); 327 dwarf_dealloc(dbg,pubnames_context,context_DLA_code); 328 _dwarf_error(dbg, error, length_err_num); 329 return (DW_DLV_ERROR); 330 } 331 332 /* Read initial offset (of DIE within CU) of a pubname, final 333 entry is not a pair, just a zero offset. */ 334 mres = _dwarf_read_unaligned_ck_wrapper(dbg, 335 &die_offset_in_cu, 336 pubnames_like_ptr, 337 pubnames_context->pu_length_size, 338 section_end_ptr,error); 339 if (mres != DW_DLV_OK) { 340 dealloc_globals_chain(dbg,head_chain); 341 dwarf_dealloc(dbg,pubnames_context,context_DLA_code); 342 return mres; 343 } 344 pubnames_like_ptr += pubnames_context->pu_length_size; 345 FIX_UP_OFFSET_IRIX_BUG(dbg, 346 die_offset_in_cu, "offset of die in cu"); 347 if (pubnames_like_ptr > (section_data_ptr + section_length)) { 348 dealloc_globals_chain(dbg,head_chain); 349 dwarf_dealloc(dbg,pubnames_context,context_DLA_code); 350 _dwarf_error(dbg, error, length_err_num); 351 return DW_DLV_ERROR; 352 } 353 354 /* Loop thru pairs. DIE off with CU followed by string. */ 355 if (dbg->de_return_empty_pubnames && die_offset_in_cu == 0) { 356 /* Here we have a pubnames CU with no actual 357 entries so we fake up an entry to hold the 358 header data. There are no 'pairs' here, 359 just the end of list zero value. We do this 360 only if de_return_empty_pubnames is set 361 so that we by default return exactly the same 362 data this always returned, yet dwarfdump can 363 request the empty-cu records get created 364 to test that feature. 365 see dwarf_get_globals_header() */ 366 global = 367 (Dwarf_Global) _dwarf_get_alloc(dbg, global_DLA_code, 1); 368 if (global == NULL) { 369 dealloc_globals_chain(dbg,head_chain); 370 dwarf_dealloc(dbg,pubnames_context,context_DLA_code); 371 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 372 return (DW_DLV_ERROR); 373 } 374 global_count++; 375 global->gl_context = pubnames_context; 376 global->gl_named_die_offset_within_cu = 0; 377 global->gl_name = (Dwarf_Small *)""; 378 /* Finish off current entry chain */ 379 curr_chain = 380 (Dwarf_Chain) _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); 381 if (curr_chain == NULL) { 382 dealloc_globals_chain(dbg,head_chain); 383 dwarf_dealloc(dbg,pubnames_context,context_DLA_code); 384 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 385 return DW_DLV_ERROR; 386 } 387 /* Put current global on singly_linked list. */ 388 curr_chain->ch_itemtype = global_DLA_code; 389 curr_chain->ch_item = (Dwarf_Global) global; 390 if (head_chain == NULL) 391 head_chain = prev_chain = curr_chain; 392 else { 393 prev_chain->ch_next = curr_chain; 394 prev_chain = curr_chain; 395 } 396 /* There is no next entry, we are at it already */ 397 } else if (!die_offset_in_cu) { 398 /* The section is empty. 399 Nowhere to record pubnames_context); */ 400 dwarf_dealloc(dbg,pubnames_context,context_DLA_code); 401 pubnames_context = 0; 402 continue; 403 } 404 while (die_offset_in_cu) { 405 int res = 0; 406 407 /* Already read offset, pubnames_like_ptr 408 now points to the string. */ 409 global = 410 (Dwarf_Global) _dwarf_get_alloc(dbg, global_DLA_code, 1); 411 if (global == NULL) { 412 dealloc_globals_chain(dbg,head_chain); 413 dwarf_dealloc(dbg,pubnames_context,context_DLA_code); 414 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 415 return (DW_DLV_ERROR); 416 } 417 global_count++; 418 global->gl_context = pubnames_context; 419 global->gl_named_die_offset_within_cu = die_offset_in_cu; 420 global->gl_name = pubnames_like_ptr; 421 res = _dwarf_check_string_valid(dbg,section_data_ptr, 422 pubnames_like_ptr,section_end_ptr, 423 DW_DLE_STRING_OFF_END_PUBNAMES_LIKE,error); 424 if (res != DW_DLV_OK) { 425 dealloc_globals_chain(dbg,head_chain); 426 dwarf_dealloc(dbg,pubnames_context,context_DLA_code); 427 return res; 428 } 429 pubnames_like_ptr = pubnames_like_ptr + 430 strlen((char *) pubnames_like_ptr) + 1; 431 432 /* Finish off current entry chain */ 433 curr_chain = 434 (Dwarf_Chain) _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); 435 if (curr_chain == NULL) { 436 dealloc_globals_chain(dbg,head_chain); 437 dwarf_dealloc(dbg,pubnames_context,context_DLA_code); 438 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 439 return (DW_DLV_ERROR); 440 } 441 /* Put current global on singly_linked list. */ 442 curr_chain->ch_item = (Dwarf_Global) global; 443 curr_chain->ch_itemtype = global_DLA_code; 444 if (head_chain == NULL) 445 head_chain = prev_chain = curr_chain; 446 else { 447 prev_chain->ch_next = curr_chain; 448 prev_chain = curr_chain; 449 } 450 451 /* Read offset for the *next* entry */ 452 mres = _dwarf_read_unaligned_ck_wrapper(dbg, 453 &die_offset_in_cu, 454 pubnames_like_ptr, 455 pubnames_context->pu_length_size, 456 section_end_ptr,error); 457 if (mres != DW_DLV_OK) { 458 dealloc_globals_chain(dbg,head_chain); 459 dwarf_dealloc(dbg,pubnames_context,context_DLA_code); 460 return mres; 461 } 462 pubnames_like_ptr += pubnames_context->pu_length_size; 463 FIX_UP_OFFSET_IRIX_BUG(dbg, 464 die_offset_in_cu, "offset of next die in cu"); 465 if (pubnames_like_ptr > (section_data_ptr + section_length)) { 466 dealloc_globals_chain(dbg,head_chain); 467 dwarf_dealloc(dbg,pubnames_context,context_DLA_code); 468 _dwarf_error(dbg, error, length_err_num); 469 return DW_DLV_ERROR; 470 } 471 } 472 /* ASSERT: die_offset_in_cu == 0 */ 473 if (pubnames_like_ptr > pubnames_ptr_past_end_cu) { 474 /* This is some kind of error. This simply cannot happen. 475 The encoding is wrong or the length in the header for 476 this cu's contribution is wrong. */ 477 _dwarf_error(dbg, error, length_err_num); 478 dealloc_globals_chain(dbg,head_chain); 479 dwarf_dealloc(dbg,pubnames_context,context_DLA_code); 480 return DW_DLV_ERROR; 481 } 482 /* If there is some kind of padding at the end of the section, 483 as emitted by some compilers, skip over that padding and 484 simply ignore the bytes thus passed-over. With most 485 compilers, pubnames_like_ptr == pubnames_ptr_past_end_cu at 486 this point */ 487 { 488 Dwarf_Unsigned increment = 489 pubnames_context->pu_length_size + 490 pubnames_context->pu_length + 491 pubnames_context->pu_extension_size; 492 pubnames_section_offset += increment; 493 } 494 pubnames_like_ptr = pubnames_ptr_past_end_cu; 495 } while (pubnames_like_ptr < section_end_ptr); 496 497 /* Points to contiguous block of Dwarf_Global's. */ 498 ret_globals = (Dwarf_Global *) 499 _dwarf_get_alloc(dbg, DW_DLA_LIST, global_count); 500 if (ret_globals == NULL) { 501 dealloc_globals_chain(dbg,head_chain); 502 dwarf_dealloc(dbg,pubnames_context,context_DLA_code); 503 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 504 return DW_DLV_ERROR; 505 } 506 507 /* Store pointers to Dwarf_Global_s structs in contiguous block, 508 and deallocate the chain. This ignores the various 509 headers */ 510 curr_chain = head_chain; 511 for (i = 0; i < global_count; i++) { 512 *(ret_globals + i) = curr_chain->ch_item; 513 prev_chain = curr_chain; 514 curr_chain = curr_chain->ch_next; 515 prev_chain->ch_item = 0; /* Not actually necessary. */ 516 dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN); 517 } 518 *globals = ret_globals; 519 *return_count = (Dwarf_Signed) global_count; 520 return DW_DLV_OK; 521 } 522 523 524 /* Given a pubnames entry (or other like section entry) 525 return thru the ret_name pointer 526 a pointer to the string which is the entry name. */ 527 int 528 dwarf_globname(Dwarf_Global glob, char **ret_name, Dwarf_Error * error) 529 { 530 if (glob == NULL) { 531 _dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL); 532 return (DW_DLV_ERROR); 533 } 534 535 *ret_name = (char *) (glob->gl_name); 536 return DW_DLV_OK; 537 } 538 539 540 /* Given a pubnames entry (or other like section entry) 541 return thru the ret_off pointer the 542 global offset of the DIE for this entry. 543 The global offset is the offset within the .debug_info 544 section as a whole. */ 545 int 546 dwarf_global_die_offset(Dwarf_Global global, 547 Dwarf_Off * ret_off, Dwarf_Error * error) 548 { 549 if (global == NULL) { 550 _dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL); 551 return (DW_DLV_ERROR); 552 } 553 554 if (global->gl_context == NULL) { 555 _dwarf_error(NULL, error, DW_DLE_GLOBAL_CONTEXT_NULL); 556 return (DW_DLV_ERROR); 557 } 558 559 *ret_off = (global->gl_named_die_offset_within_cu + 560 global->gl_context->pu_offset_of_cu_header); 561 return DW_DLV_OK; 562 } 563 564 /* Given a pubnames entry (or other like section entry) 565 return thru the ret_off pointer the 566 offset of the compilation unit header of the 567 compilation unit the global is part of. 568 569 In early versions of this, the value returned was 570 the offset of the compilation unit die, and 571 other cu-local die offsets were faked so adding this to 572 such a cu-local offset got a true section offset. 573 Now things do as they say (adding *cu_header_offset to 574 a cu-local offset gets the section offset). */ 575 int 576 dwarf_global_cu_offset(Dwarf_Global global, 577 Dwarf_Off * cu_header_offset, 578 Dwarf_Error * error) 579 { 580 Dwarf_Global_Context con = 0; 581 582 if (global == NULL) { 583 _dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL); 584 return (DW_DLV_ERROR); 585 } 586 587 con = global->gl_context; 588 589 if (con == NULL) { 590 _dwarf_error(NULL, error, DW_DLE_GLOBAL_CONTEXT_NULL); 591 return (DW_DLV_ERROR); 592 } 593 594 /* In early libdwarf, this incorrectly returned the offset of the 595 CU DIE. Now correctly returns the header offset. */ 596 *cu_header_offset = con->pu_offset_of_cu_header; 597 598 return DW_DLV_OK; 599 } 600 601 static void 602 build_off_end_msg(Dwarf_Unsigned offval, 603 Dwarf_Unsigned withincr, 604 Dwarf_Unsigned secsize, 605 dwarfstring *m) 606 { 607 const char *msg = "past"; 608 if (offval < secsize){ 609 msg = "too near"; 610 } 611 dwarfstring_append_printf_u(m,"DW_DLE_OFFSET_BAD: " 612 "The CU header offset of %u in a pubnames-like entry ", 613 withincr); 614 dwarfstring_append_printf_s(m, 615 "would put us %s the end of .debug_info. " 616 "No room for a DIE there... " 617 "Corrupt Dwarf.",(char *)msg); 618 return; 619 } 620 621 622 /* 623 Give back the pubnames entry (or any other like section) 624 name, symbol DIE offset, and the cu-DIE offset. 625 626 Various errors are possible. 627 628 The string pointer returned thru ret_name is not 629 dwarf_get_alloc()ed, so no dwarf_dealloc() 630 DW_DLA_STRING should be applied to it. 631 632 */ 633 int 634 dwarf_global_name_offsets(Dwarf_Global global, 635 char **ret_name, 636 Dwarf_Off * die_offset, 637 Dwarf_Off * cu_die_offset, 638 Dwarf_Error * error) 639 { 640 Dwarf_Global_Context con = 0; 641 Dwarf_Debug dbg = 0; 642 Dwarf_Off cuhdr_off = 0; 643 644 if (global == NULL) { 645 _dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL); 646 return (DW_DLV_ERROR); 647 } 648 649 con = global->gl_context; 650 651 if (con == NULL) { 652 _dwarf_error(NULL, error, DW_DLE_GLOBAL_CONTEXT_NULL); 653 return (DW_DLV_ERROR); 654 } 655 656 cuhdr_off = con->pu_offset_of_cu_header; 657 /* The offset had better not be too close to the end. If it is, 658 _dwarf_length_of_cu_header() will step off the end and therefore 659 must not be used. 10 is a meaningless heuristic, but no CU 660 header is that small so it is safe. An erroneous offset is due 661 to a bug in the tool chain. A bug like this has been seen on 662 IRIX with MIPSpro 7.3.1.3 and an executable > 2GB in size and 663 with 2 million pubnames entries. */ 664 #define MIN_CU_HDR_SIZE 10 665 dbg = con->pu_dbg; 666 if (dbg == NULL) { 667 _dwarf_error(NULL, error, DW_DLE_DBG_NULL); 668 return (DW_DLV_ERROR); 669 } 670 /* Cannot refer to debug_types */ 671 if (dbg->de_debug_info.dss_size && 672 ((cuhdr_off + MIN_CU_HDR_SIZE) >= dbg->de_debug_info.dss_size)) { 673 dwarfstring m; 674 dwarfstring_constructor(&m); 675 build_off_end_msg(cuhdr_off,cuhdr_off+MIN_CU_HDR_SIZE, 676 dbg->de_debug_info.dss_size,&m); 677 _dwarf_error_string(dbg, error, DW_DLE_OFFSET_BAD, 678 dwarfstring_string(&m)); 679 dwarfstring_destructor(&m); 680 return (DW_DLV_ERROR); 681 } 682 #undef MIN_CU_HDR_SIZE 683 /* If global->gl_named_die_offset_within_cu 684 is zero then this is a fake global for 685 a pubnames CU with no pubnames. The offset is from the 686 start of the CU header, so no die can have a zero 687 offset, all valid offsets are positive numbers */ 688 if (die_offset) { 689 if(global->gl_named_die_offset_within_cu) { 690 *die_offset = global->gl_named_die_offset_within_cu + cuhdr_off; 691 } else { 692 *die_offset = 0; 693 } 694 } 695 *ret_name = (char *) global->gl_name; 696 if (cu_die_offset) { 697 /* Globals cannot refer to debug_types */ 698 int cres = 0; 699 Dwarf_Unsigned headerlen = 0; 700 int res = _dwarf_load_debug_info(dbg, error); 701 702 if (res != DW_DLV_OK) { 703 return res; 704 } 705 /* The offset had better not be too close to the end. 706 If it is, 707 _dwarf_length_of_cu_header() will step off the end and 708 therefore must not be used. 10 is a meaningless heuristic, 709 but no CU header is that small so it is safe. */ 710 /* Globals cannot refer to debug_types */ 711 if ((cuhdr_off + 10) >= dbg->de_debug_info.dss_size) { 712 dwarfstring m; 713 714 dwarfstring_constructor(&m); 715 build_off_end_msg(cuhdr_off,cuhdr_off+10, 716 dbg->de_debug_info.dss_size,&m); 717 _dwarf_error_string(dbg, error, DW_DLE_OFFSET_BAD, 718 dwarfstring_string(&m)); 719 dwarfstring_destructor(&m); 720 return (DW_DLV_ERROR); 721 } 722 cres = _dwarf_length_of_cu_header(dbg, cuhdr_off,true, 723 &headerlen,error); 724 if(cres != DW_DLV_OK) { 725 return cres; 726 } 727 *cu_die_offset = cuhdr_off + headerlen; 728 } 729 return DW_DLV_OK; 730 } 731 732 733 /* New February 2019 from better dwarfdump printing 734 of debug_pubnames and pubtypes. 735 For ao the Dwarf_Global records in one pubnames 736 CU group exactly the same data will be returned. 737 738 */ 739 int 740 dwarf_get_globals_header(Dwarf_Global global, 741 Dwarf_Off *pub_section_hdr_offset, 742 Dwarf_Unsigned *pub_offset_size, 743 Dwarf_Unsigned *pub_cu_length, 744 Dwarf_Unsigned *version, 745 Dwarf_Off *info_header_offset, 746 Dwarf_Unsigned *info_length, 747 Dwarf_Error* error) 748 { 749 Dwarf_Global_Context con = 0; 750 Dwarf_Debug dbg = 0; 751 752 if (global == NULL) { 753 _dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL); 754 return DW_DLV_ERROR; 755 } 756 con = global->gl_context; 757 if (con == NULL) { 758 _dwarf_error(NULL, error, DW_DLE_GLOBAL_CONTEXT_NULL); 759 return DW_DLV_ERROR; 760 } 761 dbg = con->pu_dbg; 762 if (dbg == NULL) { 763 _dwarf_error(NULL, error, DW_DLE_DBG_NULL); 764 return DW_DLV_ERROR; 765 } 766 if(pub_section_hdr_offset) { 767 *pub_section_hdr_offset = con->pu_pub_offset; 768 } 769 if (pub_offset_size) { 770 *pub_offset_size = con->pu_length_size; 771 } 772 if (pub_cu_length) { 773 *pub_cu_length = con->pu_length; 774 } 775 if (version) { 776 *version = con->pu_version; 777 } 778 if(info_header_offset) { 779 *info_header_offset = con->pu_offset_of_cu_header; 780 } 781 if (info_length) { 782 *info_length = con->pu_info_length; 783 } 784 return DW_DLV_OK; 785 } 786 787 788 /* We have the offset to a CU header. 789 Return thru outFileOffset the offset of the CU DIE. 790 791 New June, 2001. 792 Used by SGI IRIX debuggers. 793 No error used to be possible. 794 As of May 2016 an error is possible if the DWARF is 795 corrupted! (IRIX debuggers are no longer built ...) 796 797 See also dwarf_CU_dieoffset_given_die(). 798 799 This is assumed to never apply to data in .debug_types, it 800 only refers to .debug_info. 801 802 */ 803 804 /* ARGSUSED */ 805 int 806 dwarf_get_cu_die_offset_given_cu_header_offset(Dwarf_Debug dbg, 807 Dwarf_Off in_cu_header_offset, 808 Dwarf_Off * out_cu_die_offset, 809 UNUSEDARG Dwarf_Error * err) 810 { 811 Dwarf_Off headerlen = 0; 812 int cres = 0; 813 814 cres = _dwarf_length_of_cu_header(dbg, in_cu_header_offset,true, 815 &headerlen,err); 816 if (cres != DW_DLV_OK) { 817 return cres; 818 } 819 *out_cu_die_offset = in_cu_header_offset + headerlen; 820 return DW_DLV_OK; 821 } 822 823 /* The following version new in October 2011, does allow finding 824 the offset if one knows whether debug_info or debug_types. 825 826 However, it is not accurate in DWARF5 because 827 there are two different header lengths (CU and TU) 828 in DWARF5 .debug_info. In that case, pretend 829 that it's .debug_types (here) and pass is_info zero for 830 a TU (as if it was in .debug_types). 831 */ 832 int 833 dwarf_get_cu_die_offset_given_cu_header_offset_b(Dwarf_Debug dbg, 834 Dwarf_Off in_cu_header_offset, 835 Dwarf_Bool is_info, 836 Dwarf_Off * out_cu_die_offset, 837 UNUSEDARG Dwarf_Error * err) 838 { 839 Dwarf_Off headerlen = 0; 840 int cres = 0; 841 842 cres = _dwarf_length_of_cu_header(dbg, in_cu_header_offset,is_info, 843 &headerlen,err); 844 if (cres != DW_DLV_OK) { 845 return cres; 846 } 847 *out_cu_die_offset = in_cu_header_offset + headerlen; 848 return DW_DLV_OK; 849 } 850 /* dwarf_CU_dieoffset_given_die returns 851 the global debug_info section offset of the CU die 852 that is the CU containing the given (passed-in) die. 853 This information makes it possible for a consumer to 854 find and print context information for any die. 855 856 Use dwarf_offdie() passing in the offset this returns 857 to get a die pointer to the CU die. */ 858 int 859 dwarf_CU_dieoffset_given_die(Dwarf_Die die, 860 Dwarf_Off* return_offset, 861 Dwarf_Error* error) 862 { 863 Dwarf_Off dieoff = 0; 864 Dwarf_CU_Context cucontext = 0; 865 866 CHECK_DIE(die, DW_DLV_ERROR); 867 cucontext = die->di_cu_context; 868 dieoff = cucontext->cc_debug_offset; 869 /* The following call cannot fail, so no error check. */ 870 dwarf_get_cu_die_offset_given_cu_header_offset_b( 871 cucontext->cc_dbg, dieoff, 872 die->di_is_info, return_offset,error); 873 return DW_DLV_OK; 874 } 875 876 /* We do not want to screw up error in case 877 it has something important. So not touching it now. */ 878 int dwarf_return_empty_pubnames(Dwarf_Debug dbg, 879 int flag, UNUSEDARG Dwarf_Error *err ) 880 { 881 if (dbg == NULL) { 882 return DW_DLV_OK; 883 } 884 if (flag && flag != 1) { 885 return DW_DLV_OK; 886 } 887 dbg->de_return_empty_pubnames = (unsigned char)flag; 888 return DW_DLV_OK; 889 } 890