1/* Internal definitions for libdw. 2 Copyright (C) 2002-2011, 2013-2018 Red Hat, Inc. 3 This file is part of elfutils. 4 5 This file is free software; you can redistribute it and/or modify 6 it under the terms of either 7 8 * the GNU Lesser General Public License as published by the Free 9 Software Foundation; either version 3 of the License, or (at 10 your option) any later version 11 12 or 13 14 * the GNU General Public License as published by the Free 15 Software Foundation; either version 2 of the License, or (at 16 your option) any later version 17 18 or both in parallel, as here. 19 20 elfutils is distributed in the hope that it will be useful, but 21 WITHOUT ANY WARRANTY; without even the implied warranty of 22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 23 General Public License for more details. 24 25 You should have received copies of the GNU General Public License and 26 the GNU Lesser General Public License along with this program. If 27 not, see <http://www.gnu.org/licenses/>. */ 28 29#ifndef _LIBDWP_H 30#define _LIBDWP_H 1 31 32#include <stdbool.h> 33#include <pthread.h> 34 35#include <libdw.h> 36#include <dwarf.h> 37 38 39/* Known location expressions already decoded. */ 40struct loc_s 41{ 42 void *addr; 43 Dwarf_Op *loc; 44 size_t nloc; 45}; 46 47/* Known DW_OP_implicit_value blocks already decoded. 48 This overlaps struct loc_s exactly, but only the 49 first member really has to match. */ 50struct loc_block_s 51{ 52 void *addr; 53 unsigned char *data; 54 size_t length; 55}; 56 57/* Already decoded .debug_line units. */ 58struct files_lines_s 59{ 60 Dwarf_Off debug_line_offset; 61 Dwarf_Files *files; 62 Dwarf_Lines *lines; 63}; 64 65/* Valid indices for the section data. */ 66enum 67 { 68 IDX_debug_info = 0, 69 IDX_debug_types, 70 IDX_debug_abbrev, 71 IDX_debug_aranges, 72 IDX_debug_addr, 73 IDX_debug_line, 74 IDX_debug_line_str, 75 IDX_debug_frame, 76 IDX_debug_loc, 77 IDX_debug_loclists, 78 IDX_debug_pubnames, 79 IDX_debug_str, 80 IDX_debug_str_offsets, 81 IDX_debug_macinfo, 82 IDX_debug_macro, 83 IDX_debug_ranges, 84 IDX_debug_rnglists, 85 IDX_gnu_debugaltlink, 86 IDX_last 87 }; 88 89 90/* Error values. */ 91enum 92{ 93 DWARF_E_NOERROR = 0, 94 DWARF_E_UNKNOWN_ERROR, 95 DWARF_E_INVALID_ACCESS, 96 DWARF_E_NO_REGFILE, 97 DWARF_E_IO_ERROR, 98 DWARF_E_INVALID_ELF, 99 DWARF_E_NO_DWARF, 100 DWARF_E_COMPRESSED_ERROR, 101 DWARF_E_NOELF, 102 DWARF_E_GETEHDR_ERROR, 103 DWARF_E_NOMEM, 104 DWARF_E_UNIMPL, 105 DWARF_E_INVALID_CMD, 106 DWARF_E_INVALID_VERSION, 107 DWARF_E_INVALID_FILE, 108 DWARF_E_NO_ENTRY, 109 DWARF_E_INVALID_DWARF, 110 DWARF_E_NO_STRING, 111 DWARF_E_NO_DEBUG_STR, 112 DWARF_E_NO_DEBUG_LINE_STR, 113 DWARF_E_NO_STR_OFFSETS, 114 DWARF_E_NO_ADDR, 115 DWARF_E_NO_CONSTANT, 116 DWARF_E_NO_REFERENCE, 117 DWARF_E_INVALID_REFERENCE, 118 DWARF_E_NO_DEBUG_LINE, 119 DWARF_E_INVALID_DEBUG_LINE, 120 DWARF_E_TOO_BIG, 121 DWARF_E_VERSION, 122 DWARF_E_INVALID_DIR_IDX, 123 DWARF_E_ADDR_OUTOFRANGE, 124 DWARF_E_NO_DEBUG_LOC, 125 DWARF_E_NO_DEBUG_LOCLISTS, 126 DWARF_E_NO_LOC_VALUE, 127 DWARF_E_NO_BLOCK, 128 DWARF_E_INVALID_LINE_IDX, 129 DWARF_E_INVALID_ARANGE_IDX, 130 DWARF_E_NO_MATCH, 131 DWARF_E_NO_FLAG, 132 DWARF_E_INVALID_OFFSET, 133 DWARF_E_NO_DEBUG_RANGES, 134 DWARF_E_NO_DEBUG_RNGLISTS, 135 DWARF_E_INVALID_CFI, 136 DWARF_E_NO_ALT_DEBUGLINK, 137 DWARF_E_INVALID_OPCODE, 138 DWARF_E_NOT_CUDIE, 139 DWARF_E_UNKNOWN_LANGUAGE, 140 DWARF_E_NO_DEBUG_ADDR, 141}; 142 143 144#include "dwarf_sig8_hash.h" 145 146/* The type of Dwarf object, sorted by preference 147 (if there is a higher order type, we pick that one over the others). */ 148enum dwarf_type 149 { 150 TYPE_UNKNOWN = 0, 151 TYPE_GNU_LTO = 16, 152 TYPE_DWO = 32, 153 TYPE_PLAIN = 64, 154 }; 155 156/* This is the structure representing the debugging state. */ 157struct Dwarf 158{ 159 /* The underlying ELF file. */ 160 Elf *elf; 161 162 /* The (absolute) path to the ELF dir, if known. To help locating 163 alt and dwo files. */ 164 char *debugdir; 165 166 /* dwz alternate DWARF file. */ 167 Dwarf *alt_dwarf; 168 169 /* The section data. */ 170 Elf_Data *sectiondata[IDX_last]; 171 172 /* True if the file has a byte order different from the host. */ 173 bool other_byte_order; 174 175 /* If true, we allocated the ELF descriptor ourselves. */ 176 bool free_elf; 177 178 /* If >= 0, we allocated the alt_dwarf ourselves and must end it and 179 close this file descriptor. */ 180 int alt_fd; 181 182 /* Information for traversing the .debug_pubnames section. This is 183 an array and separately allocated with malloc. */ 184 struct pubnames_s 185 { 186 Dwarf_Off cu_offset; 187 Dwarf_Off set_start; 188 unsigned int cu_header_size; 189 int address_len; 190 } *pubnames_sets; 191 size_t pubnames_nsets; 192 193 /* Search tree for the CUs. */ 194 void *cu_tree; 195 Dwarf_Off next_cu_offset; 196 197 /* Search tree and sig8 hash table for .debug_types type units. */ 198 void *tu_tree; 199 Dwarf_Off next_tu_offset; 200 Dwarf_Sig8_Hash sig8_hash; 201 202 /* Search tree for split Dwarf associated with CUs in this debug. */ 203 void *split_tree; 204 205 /* Search tree for .debug_macro operator tables. */ 206 void *macro_ops; 207 208 /* Search tree for decoded .debug_line units. */ 209 void *files_lines; 210 211 /* Address ranges. */ 212 Dwarf_Aranges *aranges; 213 214 /* Cached info from the CFI section. */ 215 struct Dwarf_CFI_s *cfi; 216 217 /* Fake loc CU. Used when synthesizing attributes for Dwarf_Ops that 218 came from a location list entry in dwarf_getlocation_attr. 219 Depending on version this is the .debug_loc or .debug_loclists 220 section (could be both if mixing CUs with different DWARF versions). */ 221 struct Dwarf_CU *fake_loc_cu; 222 struct Dwarf_CU *fake_loclists_cu; 223 224 /* Similar for addrx/constx, which will come from .debug_addr section. */ 225 struct Dwarf_CU *fake_addr_cu; 226 227 enum dwarf_type type; 228 229 /* Supporting lock for internal memory handling. Ensures threads that have 230 an entry in the mem_tails array are not disturbed by new threads doing 231 allocations for this Dwarf. */ 232 pthread_rwlock_t mem_rwl; 233 234 /* Internal memory handling. This is basically a simplified thread-local 235 reimplementation of obstacks. Unfortunately the standard obstack 236 implementation is not usable in libraries. */ 237 size_t mem_stacks; 238 struct libdw_memblock 239 { 240 size_t size; 241 size_t remaining; 242 struct libdw_memblock *prev; 243 char mem[0]; 244 } **mem_tails; 245 246 /* Default size of allocated memory blocks. */ 247 size_t mem_default_size; 248 249 /* Registered OOM handler. */ 250 Dwarf_OOM oom_handler; 251}; 252 253 254/* Abbreviation representation. */ 255struct Dwarf_Abbrev 256{ 257 Dwarf_Off offset; /* Offset to start of abbrev into .debug_abbrev. */ 258 unsigned char *attrp; /* Pointer to start of attribute name/form pairs. */ 259 bool has_children : 1; /* Whether or not the DIE has children. */ 260 unsigned int code : 31; /* The (unique) abbrev code. */ 261 unsigned int tag; /* The tag of the DIE. */ 262} attribute_packed; 263 264#include "dwarf_abbrev_hash.h" 265 266 267/* Files in line information records. */ 268struct Dwarf_Files_s 269 { 270 unsigned int ndirs; 271 unsigned int nfiles; 272 struct Dwarf_Fileinfo_s 273 { 274 char *name; 275 Dwarf_Word mtime; 276 Dwarf_Word length; 277 } info[0]; 278 /* nfiles of those, followed by char *[ndirs]. */ 279 }; 280typedef struct Dwarf_Fileinfo_s Dwarf_Fileinfo; 281 282 283/* Representation of a row in the line table. */ 284 285struct Dwarf_Line_s 286{ 287 Dwarf_Files *files; 288 289 Dwarf_Addr addr; 290 unsigned int file; 291 int line; 292 unsigned short int column; 293 unsigned int is_stmt:1; 294 unsigned int basic_block:1; 295 unsigned int end_sequence:1; 296 unsigned int prologue_end:1; 297 unsigned int epilogue_begin:1; 298 /* The remaining bit fields are not flags, but hold values presumed to be 299 small. All the flags and other bit fields should add up to 48 bits 300 to give the whole struct a nice round size. */ 301 unsigned int op_index:8; 302 unsigned int isa:8; 303 unsigned int discriminator:24; 304 /* These are currently only used for the NVIDIA extensions. */ 305 unsigned int context; 306 unsigned int function_name; 307}; 308 309struct Dwarf_Lines_s 310{ 311 size_t nlines; 312 struct Dwarf_Line_s info[0]; 313}; 314 315/* Representation of address ranges. */ 316struct Dwarf_Aranges_s 317{ 318 Dwarf *dbg; 319 size_t naranges; 320 321 struct Dwarf_Arange_s 322 { 323 Dwarf_Addr addr; 324 Dwarf_Word length; 325 Dwarf_Off offset; 326 } info[0]; 327}; 328 329 330/* CU representation. */ 331struct Dwarf_CU 332{ 333 Dwarf *dbg; 334 Dwarf_Off start; 335 Dwarf_Off end; 336 uint8_t address_size; 337 uint8_t offset_size; 338 uint16_t version; 339 340 size_t sec_idx; /* Normally .debug_info, could be .debug_type or "fake". */ 341 342 /* The unit type if version >= 5. Otherwise 0 for normal CUs (from 343 .debug_info) or 1 for v4 type units (from .debug_types). */ 344 uint8_t unit_type; 345 346 /* Zero if the unit type doesn't support a die/type offset and/or id/sig. 347 Nonzero if it is a v4 type unit or for DWARFv5 units depending on 348 unit_type. */ 349 size_t subdie_offset; 350 uint64_t unit_id8; 351 352 /* If this is a skeleton unit this points to the split compile unit. 353 Or the other way around if this is a split compile unit. Set to -1 354 if not yet searched. Always use __libdw_find_split_unit to access 355 this field. */ 356 struct Dwarf_CU *split; 357 358 /* Hash table for the abbreviations. */ 359 Dwarf_Abbrev_Hash abbrev_hash; 360 /* Offset of the first abbreviation. */ 361 size_t orig_abbrev_offset; 362 /* Offset past last read abbreviation. */ 363 size_t last_abbrev_offset; 364 365 /* The srcline information. */ 366 Dwarf_Lines *lines; 367 368 /* The source file information. */ 369 Dwarf_Files *files; 370 371 /* Known location lists. */ 372 void *locs; 373 374 /* Base address for use with ranges and locs. 375 Don't access directly, call __libdw_cu_base_address. */ 376 Dwarf_Addr base_address; 377 378 /* The offset into the .debug_addr section where index zero begins. 379 Don't access directly, call __libdw_cu_addr_base. */ 380 Dwarf_Off addr_base; 381 382 /* The offset into the .debug_str_offsets section where index zero begins. 383 Don't access directly, call __libdw_cu_str_off_base. */ 384 Dwarf_Off str_off_base; 385 386 /* The offset into the .debug_ranges section to use for GNU 387 DebugFission split units. Don't access directly, call 388 __libdw_cu_ranges_base. */ 389 Dwarf_Off ranges_base; 390 391 /* The start of the offset table in .debug_loclists. 392 Don't access directly, call __libdw_cu_locs_base. */ 393 Dwarf_Off locs_base; 394 395 /* Memory boundaries of this CU. */ 396 void *startp; 397 void *endp; 398}; 399 400#define ISV4TU(cu) ((cu)->version == 4 && (cu)->sec_idx == IDX_debug_types) 401 402/* Compute the offset of a CU's first DIE from the CU offset. 403 CU must be a valid/known version/unit_type. */ 404static inline Dwarf_Off 405__libdw_first_die_from_cu_start (Dwarf_Off cu_start, 406 uint8_t offset_size, 407 uint16_t version, 408 uint8_t unit_type) 409{ 410/* 411 assert (offset_size == 4 || offset_size == 8); 412 assert (version >= 2 && version <= 5); 413 assert (unit_type == DW_UT_compile 414 || unit_type == DW_UT_partial 415 || unit_type == DW_UT_skeleton 416 || unit_type == DW_UT_split_compile 417 || unit_type == DW_UT_type 418 || unit_type == DW_UT_split_type); 419*/ 420 421 Dwarf_Off off = cu_start; 422 if (version < 5) 423 { 424 /* 425 LEN VER OFFSET ADDR 426 4-bytes + 2-bytes + 4-bytes + 1-byte for 32-bit dwarf 427 12-bytes + 2-bytes + 8-bytes + 1-byte for 64-bit dwarf 428 or in .debug_types, SIGNATURE TYPE-OFFSET 429 4-bytes + 2-bytes + 4-bytes + 1-byte + 8-bytes + 4-bytes for 32-bit 430 12-bytes + 2-bytes + 8-bytes + 1-byte + 8-bytes + 8-bytes for 64-bit 431 432 Note the trick in the computation. If the offset_size is 4 433 the '- 4' term changes the '3 *' (or '4 *') into a '2 *' (or '3 *). 434 If the offset_size is 8 it accounts for the 4-byte escape value 435 used at the start of the length. */ 436 if (unit_type != DW_UT_type) 437 off += 3 * offset_size - 4 + 3; 438 else 439 off += 4 * offset_size - 4 + 3 + 8; 440 } 441 else 442 { 443 /* 444 LEN VER TYPE ADDR OFFSET SIGNATURE TYPE-OFFSET 445 4-bytes + 2-bytes + 1-byte + 1-byte + 4-bytes + 8-bytes + 4-bytes 32-bit 446 12-bytes + 2-bytes + 1-byte + 1-byte + 8-bytes + 8-bytes + 8-bytes 64-bit 447 Both signature and type offset are optional. 448 449 Note same 4/8 offset size trick as above. 450 We explicitly ignore unknown unit types (see asserts above). */ 451 off += 3 * offset_size - 4 + 4; 452 if (unit_type == DW_UT_skeleton || unit_type == DW_UT_split_compile 453 || unit_type == DW_UT_type || unit_type == DW_UT_split_type) 454 { 455 off += 8; 456 if (unit_type == DW_UT_type || unit_type == DW_UT_split_type) 457 off += offset_size; 458 } 459 } 460 461 return off; 462} 463 464static inline Dwarf_Off 465__libdw_first_die_off_from_cu (struct Dwarf_CU *cu) 466{ 467 return __libdw_first_die_from_cu_start (cu->start, 468 cu->offset_size, 469 cu->version, 470 cu->unit_type); 471} 472 473#define CUDIE(fromcu) \ 474 ((Dwarf_Die) \ 475 { \ 476 .cu = (fromcu), \ 477 .addr = ((char *) (fromcu)->dbg->sectiondata[cu_sec_idx (fromcu)]->d_buf \ 478 + __libdw_first_die_off_from_cu (fromcu)) \ 479 }) 480 481#define SUBDIE(fromcu) \ 482 ((Dwarf_Die) \ 483 { \ 484 .cu = (fromcu), \ 485 .addr = ((char *) (fromcu)->dbg->sectiondata[cu_sec_idx (fromcu)]->d_buf \ 486 + (fromcu)->start + (fromcu)->subdie_offset) \ 487 }) 488 489 490/* Prototype of a single .debug_macro operator. */ 491typedef struct 492{ 493 Dwarf_Word nforms; 494 unsigned char const *forms; 495} Dwarf_Macro_Op_Proto; 496 497/* Prototype table. */ 498typedef struct 499{ 500 /* Offset of .debug_macro section. */ 501 Dwarf_Off offset; 502 503 /* Offset of associated .debug_line section. */ 504 Dwarf_Off line_offset; 505 506 /* The source file information. */ 507 Dwarf_Files *files; 508 509 /* If this macro unit was opened through dwarf_getmacros or 510 dwarf_getmacros_die, this caches value of DW_AT_comp_dir, if 511 present. */ 512 const char *comp_dir; 513 514 /* Header length. */ 515 Dwarf_Half header_len; 516 517 uint16_t version; 518 bool is_64bit; 519 uint8_t sec_index; /* IDX_debug_macro or IDX_debug_macinfo. */ 520 521 /* Shows where in TABLE each opcode is defined. Since opcode 0 is 522 never used, it stores index of opcode X in X-1'th element. The 523 value of 0xff means not stored at all. */ 524 unsigned char opcodes[255]; 525 526 /* Individual opcode prototypes. */ 527 Dwarf_Macro_Op_Proto table[]; 528} Dwarf_Macro_Op_Table; 529 530struct Dwarf_Macro_s 531{ 532 Dwarf_Macro_Op_Table *table; 533 Dwarf_Attribute *attributes; 534 uint8_t opcode; 535}; 536 537static inline Dwarf_Word 538libdw_macro_nforms (Dwarf_Macro *macro) 539{ 540 return macro->table->table[macro->table->opcodes[macro->opcode - 1]].nforms; 541} 542 543/* Returns true for any allowed FORM in the opcode_operands_table as 544 mentioned in the DWARF5 spec (6.3.1 Macro Information Header). 545 Or those mentioned in DWARF5 spec (6.2.4.2 Vendor-defined Content 546 Descriptions) for the directory/file table (plus DW_FORM_strp_sup). */ 547static inline bool 548libdw_valid_user_form (int form) 549{ 550 switch (form) 551 { 552 case DW_FORM_block: 553 case DW_FORM_block1: 554 case DW_FORM_block2: 555 case DW_FORM_block4: 556 case DW_FORM_data1: 557 case DW_FORM_data2: 558 case DW_FORM_data4: 559 case DW_FORM_data8: 560 case DW_FORM_data16: 561 case DW_FORM_flag: 562 case DW_FORM_line_strp: 563 case DW_FORM_sdata: 564 case DW_FORM_sec_offset: 565 case DW_FORM_string: 566 case DW_FORM_strp: 567 case DW_FORM_strp_sup: 568 case DW_FORM_strx: 569 case DW_FORM_strx1: 570 case DW_FORM_strx2: 571 case DW_FORM_strx3: 572 case DW_FORM_strx4: 573 case DW_FORM_udata: 574 return true; 575 default: 576 return false; 577 } 578} 579 580 581/* We have to include the file at this point because the inline 582 functions access internals of the Dwarf structure. */ 583#include "memory-access.h" 584 585 586/* Set error value. */ 587extern void __libdw_seterrno (int value) internal_function; 588 589 590/* Memory handling, the easy parts. */ 591#define libdw_alloc(dbg, type, tsize, cnt) \ 592 ({ struct libdw_memblock *_tail = __libdw_alloc_tail(dbg); \ 593 size_t _required = (tsize) * (cnt); \ 594 type *_result = (type *) (_tail->mem + (_tail->size - _tail->remaining));\ 595 size_t _padding = ((__alignof (type) \ 596 - ((uintptr_t) _result & (__alignof (type) - 1))) \ 597 & (__alignof (type) - 1)); \ 598 if (unlikely (_tail->remaining < _required + _padding)) \ 599 _result = (type *) __libdw_allocate (dbg, _required, __alignof (type));\ 600 else \ 601 { \ 602 _required += _padding; \ 603 _result = (type *) ((char *) _result + _padding); \ 604 _tail->remaining -= _required; \ 605 } \ 606 _result; }) 607 608#define libdw_typed_alloc(dbg, type) \ 609 libdw_alloc (dbg, type, sizeof (type), 1) 610 611/* Can only be used to undo the last libdw_alloc. */ 612#define libdw_unalloc(dbg, type, tsize, cnt) \ 613 ({ struct libdw_memblock *_tail = __libdw_thread_tail (dbg); \ 614 size_t _required = (tsize) * (cnt); \ 615 /* We cannot know the padding, it is lost. */ \ 616 _tail->remaining += _required; }) \ 617 618#define libdw_typed_unalloc(dbg, type) \ 619 libdw_unalloc (dbg, type, sizeof (type), 1) 620 621/* Callback to choose a thread-local memory allocation stack. */ 622extern struct libdw_memblock *__libdw_alloc_tail (Dwarf* dbg) 623 __nonnull_attribute__ (1); 624 625extern struct libdw_memblock *__libdw_thread_tail (Dwarf* dbg) 626 __nonnull_attribute__ (1); 627 628/* Callback to allocate more. */ 629extern void *__libdw_allocate (Dwarf *dbg, size_t minsize, size_t align) 630 __attribute__ ((__malloc__)) __nonnull_attribute__ (1); 631 632/* Default OOM handler. */ 633extern void __libdw_oom (void) __attribute ((noreturn)) attribute_hidden; 634 635/* Read next unit (or v4 debug type) and return next offset. Doesn't 636 create an actual Dwarf_CU just provides necessary header fields. */ 637extern int 638internal_function 639__libdw_next_unit (Dwarf *dbg, bool v4_debug_types, Dwarf_Off off, 640 Dwarf_Off *next_off, size_t *header_sizep, 641 Dwarf_Half *versionp, uint8_t *unit_typep, 642 Dwarf_Off *abbrev_offsetp, uint8_t *address_sizep, 643 uint8_t *offset_sizep, uint64_t *unit_id8p, 644 Dwarf_Off *subdie_offsetp) 645 __nonnull_attribute__ (4) internal_function; 646 647/* Allocate the internal data for a unit not seen before. */ 648extern struct Dwarf_CU *__libdw_intern_next_unit (Dwarf *dbg, bool debug_types) 649 __nonnull_attribute__ (1) internal_function; 650 651/* Find CU for given offset. */ 652extern struct Dwarf_CU *__libdw_findcu (Dwarf *dbg, Dwarf_Off offset, bool tu) 653 __nonnull_attribute__ (1) internal_function; 654 655/* Find CU for given DIE address. */ 656extern struct Dwarf_CU *__libdw_findcu_addr (Dwarf *dbg, void *addr) 657 __nonnull_attribute__ (1) internal_function; 658 659/* Find split Dwarf for given DIE address. */ 660extern struct Dwarf *__libdw_find_split_dbg_addr (Dwarf *dbg, void *addr) 661 __nonnull_attribute__ (1) internal_function; 662 663/* Find the split (or skeleton) unit. */ 664extern struct Dwarf_CU *__libdw_find_split_unit (Dwarf_CU *cu) 665 internal_function; 666 667/* Get abbreviation with given code. */ 668extern Dwarf_Abbrev *__libdw_findabbrev (struct Dwarf_CU *cu, 669 unsigned int code) 670 __nonnull_attribute__ (1) internal_function; 671 672/* Get abbreviation at given offset. */ 673extern Dwarf_Abbrev *__libdw_getabbrev (Dwarf *dbg, struct Dwarf_CU *cu, 674 Dwarf_Off offset, size_t *lengthp, 675 Dwarf_Abbrev *result) 676 __nonnull_attribute__ (1) internal_function; 677 678/* Get abbreviation of given DIE, and optionally set *READP to the DIE memory 679 just past the abbreviation code. */ 680static inline Dwarf_Abbrev * 681__nonnull_attribute__ (1) 682__libdw_dieabbrev (Dwarf_Die *die, const unsigned char **readp) 683{ 684 /* Do we need to get the abbreviation, or need to read after the code? */ 685 if (die->abbrev == NULL || readp != NULL) 686 { 687 /* Get the abbreviation code. */ 688 unsigned int code; 689 const unsigned char *addr = die->addr; 690 if (unlikely (die->cu == NULL 691 || addr >= (const unsigned char *) die->cu->endp)) 692 return die->abbrev = DWARF_END_ABBREV; 693 get_uleb128 (code, addr, die->cu->endp); 694 if (readp != NULL) 695 *readp = addr; 696 697 /* Find the abbreviation. */ 698 if (die->abbrev == NULL) 699 die->abbrev = __libdw_findabbrev (die->cu, code); 700 } 701 return die->abbrev; 702} 703 704/* Helper functions for form handling. */ 705extern size_t __libdw_form_val_compute_len (struct Dwarf_CU *cu, 706 unsigned int form, 707 const unsigned char *valp) 708 __nonnull_attribute__ (1, 3) internal_function; 709 710/* Find the length of a form attribute in DIE/info data. */ 711static inline size_t 712__nonnull_attribute__ (1, 3) 713__libdw_form_val_len (struct Dwarf_CU *cu, unsigned int form, 714 const unsigned char *valp) 715{ 716 /* Small lookup table of forms with fixed lengths. Absent indexes are 717 initialized 0, so any truly desired 0 is set to 0x80 and masked. */ 718 static const uint8_t form_lengths[] = 719 { 720 [DW_FORM_flag_present] = 0x80, 721 [DW_FORM_implicit_const] = 0x80, /* Value is in abbrev, not in info. */ 722 723 [DW_FORM_flag] = 1, 724 [DW_FORM_data1] = 1, [DW_FORM_ref1] = 1, 725 [DW_FORM_addrx1] = 1, [DW_FORM_strx1] = 1, 726 727 [DW_FORM_data2] = 2, [DW_FORM_ref2] = 2, 728 [DW_FORM_addrx2] = 2, [DW_FORM_strx2] = 2, 729 730 [DW_FORM_addrx3] = 3, [DW_FORM_strx3] = 3, 731 732 [DW_FORM_data4] = 4, [DW_FORM_ref4] = 4, [DW_FORM_ref_sup4] = 4, 733 [DW_FORM_addrx4] = 4, [DW_FORM_strx4] = 4, 734 735 [DW_FORM_ref_sig8] = 8, 736 [DW_FORM_data8] = 8, [DW_FORM_ref8] = 8, [DW_FORM_ref_sup8] = 8, 737 738 [DW_FORM_data16] = 16, 739 }; 740 741 /* Return immediately for forms with fixed lengths. */ 742 if (form < sizeof form_lengths / sizeof form_lengths[0]) 743 { 744 uint8_t len = form_lengths[form]; 745 if (len != 0) 746 { 747 const unsigned char *endp = cu->endp; 748 len &= 0x7f; /* Mask to allow 0x80 -> 0. */ 749 if (unlikely (len > (size_t) (endp - valp))) 750 { 751 __libdw_seterrno (DWARF_E_INVALID_DWARF); 752 return -1; 753 } 754 return len; 755 } 756 } 757 758 /* Other forms require some computation. */ 759 return __libdw_form_val_compute_len (cu, form, valp); 760} 761 762/* Helper function for DW_FORM_ref* handling. */ 763extern int __libdw_formref (Dwarf_Attribute *attr, Dwarf_Off *return_offset) 764 __nonnull_attribute__ (1, 2) internal_function; 765 766 767/* Helper function to locate attribute. */ 768extern unsigned char *__libdw_find_attr (Dwarf_Die *die, 769 unsigned int search_name, 770 unsigned int *codep, 771 unsigned int *formp) 772 __nonnull_attribute__ (1) internal_function; 773 774/* Helper function to access integer attribute. */ 775extern int __libdw_attr_intval (Dwarf_Die *die, int *valp, int attval) 776 __nonnull_attribute__ (1, 2) internal_function; 777 778/* Helper function to walk scopes. */ 779struct Dwarf_Die_Chain 780{ 781 Dwarf_Die die; 782 struct Dwarf_Die_Chain *parent; 783 bool prune; /* The PREVISIT function can set this. */ 784}; 785extern int __libdw_visit_scopes (unsigned int depth, 786 struct Dwarf_Die_Chain *root, 787 struct Dwarf_Die_Chain *imports, 788 int (*previsit) (unsigned int depth, 789 struct Dwarf_Die_Chain *, 790 void *arg), 791 int (*postvisit) (unsigned int depth, 792 struct Dwarf_Die_Chain *, 793 void *arg), 794 void *arg) 795 __nonnull_attribute__ (2, 4) internal_function; 796 797/* Parse a DWARF Dwarf_Block into an array of Dwarf_Op's, 798 and cache the result (via tsearch). */ 799extern int __libdw_intern_expression (Dwarf *dbg, 800 bool other_byte_order, 801 unsigned int address_size, 802 unsigned int ref_size, 803 void **cache, const Dwarf_Block *block, 804 bool cfap, bool valuep, 805 Dwarf_Op **llbuf, size_t *listlen, 806 int sec_index) 807 __nonnull_attribute__ (5, 6, 9, 10) internal_function; 808 809extern Dwarf_Die *__libdw_offdie (Dwarf *dbg, Dwarf_Off offset, 810 Dwarf_Die *result, bool debug_types) 811 internal_function; 812 813 814/* Return error code of last failing function call. This value is kept 815 separately for each thread. */ 816extern int __dwarf_errno_internal (void); 817 818 819/* Reader hooks. */ 820 821/* Relocation hooks return -1 on error (in that case the error code 822 must already have been set), 0 if there is no relocation and 1 if a 823 relocation was present.*/ 824 825static inline int 826__libdw_relocate_address (Dwarf *dbg __attribute__ ((unused)), 827 int sec_index __attribute__ ((unused)), 828 const void *addr __attribute__ ((unused)), 829 int width __attribute__ ((unused)), 830 Dwarf_Addr *val __attribute__ ((unused))) 831{ 832 return 0; 833} 834 835static inline int 836__libdw_relocate_offset (Dwarf *dbg __attribute__ ((unused)), 837 int sec_index __attribute__ ((unused)), 838 const void *addr __attribute__ ((unused)), 839 int width __attribute__ ((unused)), 840 Dwarf_Off *val __attribute__ ((unused))) 841{ 842 return 0; 843} 844 845static inline Elf_Data * 846__libdw_checked_get_data (Dwarf *dbg, int sec_index) 847{ 848 Elf_Data *data = dbg->sectiondata[sec_index]; 849 if (unlikely (data == NULL) 850 || unlikely (data->d_buf == NULL)) 851 { 852 __libdw_seterrno (DWARF_E_INVALID_DWARF); 853 return NULL; 854 } 855 return data; 856} 857 858static inline int 859__libdw_offset_in_section (Dwarf *dbg, int sec_index, 860 Dwarf_Off offset, size_t size) 861{ 862 Elf_Data *data = __libdw_checked_get_data (dbg, sec_index); 863 if (data == NULL) 864 return -1; 865 if (unlikely (offset > data->d_size) 866 || unlikely (data->d_size < size) 867 || unlikely (offset > data->d_size - size)) 868 { 869 __libdw_seterrno (DWARF_E_INVALID_OFFSET); 870 return -1; 871 } 872 873 return 0; 874} 875 876static inline bool 877__libdw_in_section (Dwarf *dbg, int sec_index, 878 const void *addr, size_t size) 879{ 880 Elf_Data *data = __libdw_checked_get_data (dbg, sec_index); 881 if (data == NULL) 882 return false; 883 if (unlikely (addr < data->d_buf) 884 || unlikely (data->d_size < size) 885 || unlikely ((size_t)(addr - data->d_buf) > data->d_size - size)) 886 { 887 __libdw_seterrno (DWARF_E_INVALID_OFFSET); 888 return false; 889 } 890 891 return true; 892} 893 894#define READ_AND_RELOCATE(RELOC_HOOK, VAL) \ 895 ({ \ 896 if (!__libdw_in_section (dbg, sec_index, addr, width)) \ 897 return -1; \ 898 \ 899 const unsigned char *orig_addr = addr; \ 900 if (width == 4) \ 901 VAL = read_4ubyte_unaligned_inc (dbg, addr); \ 902 else \ 903 VAL = read_8ubyte_unaligned_inc (dbg, addr); \ 904 \ 905 int status = RELOC_HOOK (dbg, sec_index, orig_addr, width, &VAL); \ 906 if (status < 0) \ 907 return status; \ 908 status > 0; \ 909 }) 910 911static inline int 912__libdw_read_address_inc (Dwarf *dbg, 913 int sec_index, const unsigned char **addrp, 914 int width, Dwarf_Addr *ret) 915{ 916 const unsigned char *addr = *addrp; 917 READ_AND_RELOCATE (__libdw_relocate_address, (*ret)); 918 *addrp = addr; 919 return 0; 920} 921 922static inline int 923__libdw_read_address (Dwarf *dbg, 924 int sec_index, const unsigned char *addr, 925 int width, Dwarf_Addr *ret) 926{ 927 READ_AND_RELOCATE (__libdw_relocate_address, (*ret)); 928 return 0; 929} 930 931static inline int 932__libdw_read_offset_inc (Dwarf *dbg, 933 int sec_index, const unsigned char **addrp, 934 int width, Dwarf_Off *ret, int sec_ret, 935 size_t size) 936{ 937 const unsigned char *addr = *addrp; 938 READ_AND_RELOCATE (__libdw_relocate_offset, (*ret)); 939 *addrp = addr; 940 return __libdw_offset_in_section (dbg, sec_ret, *ret, size); 941} 942 943static inline int 944__libdw_read_offset (Dwarf *dbg, Dwarf *dbg_ret, 945 int sec_index, const unsigned char *addr, 946 int width, Dwarf_Off *ret, int sec_ret, 947 size_t size) 948{ 949 READ_AND_RELOCATE (__libdw_relocate_offset, (*ret)); 950 return __libdw_offset_in_section (dbg_ret, sec_ret, *ret, size); 951} 952 953static inline size_t 954cu_sec_idx (struct Dwarf_CU *cu) 955{ 956 return cu->sec_idx; 957} 958 959static inline bool 960is_cudie (Dwarf_Die *cudie) 961{ 962 return cudie->cu != NULL && CUDIE (cudie->cu).addr == cudie->addr; 963} 964 965/* Read up begin/end pair and increment read pointer. 966 - If it's normal range record, set up *BEGINP and *ENDP and return 0. 967 - If it's base address selection record, set up *BASEP and return 1. 968 - If it's end of rangelist, don't set anything and return 2 969 - If an error occurs, don't set anything and return <0. */ 970int __libdw_read_begin_end_pair_inc (Dwarf_CU *cu, int sec_index, 971 const unsigned char **readp, 972 const unsigned char *readend, 973 int width, 974 Dwarf_Addr *beginp, Dwarf_Addr *endp, 975 Dwarf_Addr *basep) 976 internal_function; 977 978const unsigned char * __libdw_formptr (Dwarf_Attribute *attr, int sec_index, 979 int err_nodata, 980 const unsigned char **endpp, 981 Dwarf_Off *offsetp) 982 internal_function; 983 984/* Fills in the given attribute to point at an empty location expression. */ 985void __libdw_empty_loc_attr (Dwarf_Attribute *attr) 986 internal_function; 987 988/* Load .debug_line unit at DEBUG_LINE_OFFSET. COMP_DIR is a value of 989 DW_AT_comp_dir or NULL if that attribute is not available. Caches 990 the loaded unit and optionally set *LINESP and/or *FILESP (if not 991 NULL) with loaded information. Returns 0 for success or a negative 992 value for failure. */ 993int __libdw_getsrclines (Dwarf *dbg, Dwarf_Off debug_line_offset, 994 const char *comp_dir, unsigned address_size, 995 Dwarf_Lines **linesp, Dwarf_Files **filesp) 996 internal_function 997 __nonnull_attribute__ (1); 998 999/* Load and return value of DW_AT_comp_dir from CUDIE. */ 1000const char *__libdw_getcompdir (Dwarf_Die *cudie); 1001 1002/* Get the base address for the CU, fetches it when not yet set. 1003 This is used as initial base address for ranges and loclists. */ 1004Dwarf_Addr __libdw_cu_base_address (Dwarf_CU *cu); 1005 1006/* Get the address base for the CU, fetches it when not yet set. */ 1007static inline Dwarf_Off 1008__libdw_cu_addr_base (Dwarf_CU *cu) 1009{ 1010 if (cu->addr_base == (Dwarf_Off) -1) 1011 { 1012 Dwarf_Die cu_die = CUDIE(cu); 1013 Dwarf_Attribute attr; 1014 Dwarf_Off offset = 0; 1015 if (dwarf_attr (&cu_die, DW_AT_GNU_addr_base, &attr) != NULL 1016 || dwarf_attr (&cu_die, DW_AT_addr_base, &attr) != NULL) 1017 { 1018 Dwarf_Word off; 1019 if (dwarf_formudata (&attr, &off) == 0) 1020 offset = off; 1021 } 1022 cu->addr_base = offset; 1023 } 1024 1025 return cu->addr_base; 1026} 1027 1028/* Gets the .debug_str_offsets base offset to use. static inline to 1029 be shared between libdw and eu-readelf. */ 1030static inline Dwarf_Off 1031str_offsets_base_off (Dwarf *dbg, Dwarf_CU *cu) 1032{ 1033 /* If we don't have a CU, then find and use the first one in the 1034 debug file (when we support .dwp files, we must actually find the 1035 one matching our "caller" - aka macro or line). If we (now) have 1036 a cu and str_offsets_base attribute, just use that. Otherwise 1037 use the first offset. But we might have to parse the header 1038 first, but only if this is version 5. Assume if all else fails, 1039 this is version 4, without header. */ 1040 1041 if (cu == NULL && dbg != NULL) 1042 { 1043 Dwarf_CU *first_cu; 1044 if (dwarf_get_units (dbg, NULL, &first_cu, 1045 NULL, NULL, NULL, NULL) == 0) 1046 cu = first_cu; 1047 } 1048 1049 if (cu != NULL) 1050 { 1051 if (cu->str_off_base == (Dwarf_Off) -1) 1052 { 1053 Dwarf_Die cu_die = CUDIE(cu); 1054 Dwarf_Attribute attr; 1055 if (dwarf_attr (&cu_die, DW_AT_str_offsets_base, &attr) != NULL) 1056 { 1057 Dwarf_Word off; 1058 if (dwarf_formudata (&attr, &off) == 0) 1059 { 1060 cu->str_off_base = off; 1061 return cu->str_off_base; 1062 } 1063 } 1064 /* For older DWARF simply assume zero (no header). */ 1065 if (cu->version < 5) 1066 { 1067 cu->str_off_base = 0; 1068 return cu->str_off_base; 1069 } 1070 1071 if (dbg == NULL) 1072 dbg = cu->dbg; 1073 } 1074 else 1075 return cu->str_off_base; 1076 } 1077 1078 /* No str_offsets_base attribute, we have to assume "zero". 1079 But there could be a header first. */ 1080 Dwarf_Off off = 0; 1081 if (dbg == NULL) 1082 goto no_header; 1083 1084 Elf_Data *data = dbg->sectiondata[IDX_debug_str_offsets]; 1085 if (data == NULL) 1086 goto no_header; 1087 1088 const unsigned char *start; 1089 const unsigned char *readp; 1090 const unsigned char *readendp; 1091 start = readp = (const unsigned char *) data->d_buf; 1092 readendp = (const unsigned char *) data->d_buf + data->d_size; 1093 1094 uint64_t unit_length; 1095 uint16_t version; 1096 1097 unit_length = read_4ubyte_unaligned_inc (dbg, readp); 1098 if (unlikely (unit_length == 0xffffffff)) 1099 { 1100 if (unlikely (readendp - readp < 8)) 1101 goto no_header; 1102 unit_length = read_8ubyte_unaligned_inc (dbg, readp); 1103 /* In theory the offset size could be different 1104 between CU and str_offsets unit. But we just 1105 ignore that here. */ 1106 } 1107 1108 /* We need at least 2-bytes (version) + 2-bytes (padding) = 1109 4 bytes to complete the header. And this unit cannot go 1110 beyond the section data. */ 1111 if (readendp - readp < 4 1112 || unit_length < 4 1113 || (uint64_t) (readendp - readp) < unit_length) 1114 goto no_header; 1115 1116 version = read_2ubyte_unaligned_inc (dbg, readp); 1117 if (version != 5) 1118 goto no_header; 1119 /* padding */ 1120 read_2ubyte_unaligned_inc (dbg, readp); 1121 1122 off = (Dwarf_Off) (readp - start); 1123 1124 no_header: 1125 if (cu != NULL) 1126 cu->str_off_base = off; 1127 1128 return off; 1129} 1130 1131 1132/* Get the string offsets base for the CU, fetches it when not yet set. */ 1133static inline Dwarf_Off __libdw_cu_str_off_base (Dwarf_CU *cu) 1134{ 1135 return str_offsets_base_off (NULL, cu); 1136} 1137 1138 1139/* Either a direct offset into .debug_ranges for version < 5, or the 1140 start of the offset table in .debug_rnglists for version > 5. */ 1141static inline Dwarf_Off 1142__libdw_cu_ranges_base (Dwarf_CU *cu) 1143{ 1144 if (cu->ranges_base == (Dwarf_Off) -1) 1145 { 1146 Dwarf_Off offset = 0; 1147 Dwarf_Die cu_die = CUDIE(cu); 1148 Dwarf_Attribute attr; 1149 if (cu->version < 5) 1150 { 1151 if (dwarf_attr (&cu_die, DW_AT_GNU_ranges_base, &attr) != NULL) 1152 { 1153 Dwarf_Word off; 1154 if (dwarf_formudata (&attr, &off) == 0) 1155 offset = off; 1156 } 1157 } 1158 else 1159 { 1160 if (dwarf_attr (&cu_die, DW_AT_rnglists_base, &attr) != NULL) 1161 { 1162 Dwarf_Word off; 1163 if (dwarf_formudata (&attr, &off) == 0) 1164 offset = off; 1165 } 1166 1167 /* There wasn't an rnglists_base, if the Dwarf does have a 1168 .debug_rnglists section, then it might be we need the 1169 base after the first header. */ 1170 Elf_Data *data = cu->dbg->sectiondata[IDX_debug_rnglists]; 1171 if (offset == 0 && data != NULL) 1172 { 1173 Dwarf *dbg = cu->dbg; 1174 const unsigned char *readp = data->d_buf; 1175 const unsigned char *const dataend 1176 = (unsigned char *) data->d_buf + data->d_size; 1177 1178 uint64_t unit_length = read_4ubyte_unaligned_inc (dbg, readp); 1179 unsigned int offset_size = 4; 1180 if (unlikely (unit_length == 0xffffffff)) 1181 { 1182 if (unlikely (readp > dataend - 8)) 1183 goto no_header; 1184 1185 unit_length = read_8ubyte_unaligned_inc (dbg, readp); 1186 offset_size = 8; 1187 } 1188 1189 if (readp > dataend - 8 1190 || unit_length < 8 1191 || unit_length > (uint64_t) (dataend - readp)) 1192 goto no_header; 1193 1194 uint16_t version = read_2ubyte_unaligned_inc (dbg, readp); 1195 if (version != 5) 1196 goto no_header; 1197 1198 uint8_t address_size = *readp++; 1199 if (address_size != 4 && address_size != 8) 1200 goto no_header; 1201 1202 uint8_t segment_size = *readp++; 1203 if (segment_size != 0) 1204 goto no_header; 1205 1206 uint32_t offset_entry_count; 1207 offset_entry_count = read_4ubyte_unaligned_inc (dbg, readp); 1208 1209 const unsigned char *offset_array_start = readp; 1210 if (offset_entry_count <= 0) 1211 goto no_header; 1212 1213 uint64_t needed = offset_entry_count * offset_size; 1214 if (unit_length - 8 < needed) 1215 goto no_header; 1216 1217 offset = (Dwarf_Off) (offset_array_start 1218 - (unsigned char *) data->d_buf); 1219 } 1220 } 1221 no_header: 1222 cu->ranges_base = offset; 1223 } 1224 1225 return cu->ranges_base; 1226} 1227 1228 1229/* The start of the offset table in .debug_loclists for DWARF5. */ 1230static inline Dwarf_Off 1231__libdw_cu_locs_base (Dwarf_CU *cu) 1232{ 1233 if (cu->locs_base == (Dwarf_Off) -1) 1234 { 1235 Dwarf_Off offset = 0; 1236 Dwarf_Die cu_die = CUDIE(cu); 1237 Dwarf_Attribute attr; 1238 if (dwarf_attr (&cu_die, DW_AT_loclists_base, &attr) != NULL) 1239 { 1240 Dwarf_Word off; 1241 if (dwarf_formudata (&attr, &off) == 0) 1242 offset = off; 1243 } 1244 1245 /* There wasn't an loclists_base, if the Dwarf does have a 1246 .debug_loclists section, then it might be we need the 1247 base after the first header. */ 1248 Elf_Data *data = cu->dbg->sectiondata[IDX_debug_loclists]; 1249 if (offset == 0 && data != NULL) 1250 { 1251 Dwarf *dbg = cu->dbg; 1252 const unsigned char *readp = data->d_buf; 1253 const unsigned char *const dataend 1254 = (unsigned char *) data->d_buf + data->d_size; 1255 1256 uint64_t unit_length = read_4ubyte_unaligned_inc (dbg, readp); 1257 unsigned int offset_size = 4; 1258 if (unlikely (unit_length == 0xffffffff)) 1259 { 1260 if (unlikely (readp > dataend - 8)) 1261 goto no_header; 1262 1263 unit_length = read_8ubyte_unaligned_inc (dbg, readp); 1264 offset_size = 8; 1265 } 1266 1267 if (readp > dataend - 8 1268 || unit_length < 8 1269 || unit_length > (uint64_t) (dataend - readp)) 1270 goto no_header; 1271 1272 uint16_t version = read_2ubyte_unaligned_inc (dbg, readp); 1273 if (version != 5) 1274 goto no_header; 1275 1276 uint8_t address_size = *readp++; 1277 if (address_size != 4 && address_size != 8) 1278 goto no_header; 1279 1280 uint8_t segment_size = *readp++; 1281 if (segment_size != 0) 1282 goto no_header; 1283 1284 uint32_t offset_entry_count; 1285 offset_entry_count = read_4ubyte_unaligned_inc (dbg, readp); 1286 1287 const unsigned char *offset_array_start = readp; 1288 if (offset_entry_count <= 0) 1289 goto no_header; 1290 1291 uint64_t needed = offset_entry_count * offset_size; 1292 if (unit_length - 8 < needed) 1293 goto no_header; 1294 1295 offset = (Dwarf_Off) (offset_array_start 1296 - (unsigned char *) data->d_buf); 1297 } 1298 1299 no_header: 1300 cu->locs_base = offset; 1301 } 1302 1303 return cu->locs_base; 1304} 1305 1306/* Helper function for tsearch/tfind split_tree Dwarf. */ 1307int __libdw_finddbg_cb (const void *arg1, const void *arg2); 1308 1309/* Link skeleton and split compile units. */ 1310static inline void 1311__libdw_link_skel_split (Dwarf_CU *skel, Dwarf_CU *split) 1312{ 1313 skel->split = split; 1314 split->split = skel; 1315 1316 /* Get .debug_addr and addr_base greedy. 1317 We also need it for the fake addr cu. 1318 There is only one per split debug. */ 1319 Dwarf *dbg = skel->dbg; 1320 Dwarf *sdbg = split->dbg; 1321 if (sdbg->sectiondata[IDX_debug_addr] == NULL 1322 && dbg->sectiondata[IDX_debug_addr] != NULL) 1323 { 1324 sdbg->sectiondata[IDX_debug_addr] 1325 = dbg->sectiondata[IDX_debug_addr]; 1326 split->addr_base = __libdw_cu_addr_base (skel); 1327 sdbg->fake_addr_cu = dbg->fake_addr_cu; 1328 } 1329} 1330 1331 1332/* Given an address index for a CU return the address. 1333 Returns -1 and sets libdw_errno if an error occurs. */ 1334int __libdw_addrx (Dwarf_CU *cu, Dwarf_Word idx, Dwarf_Addr *addr); 1335 1336 1337/* Helper function to set debugdir field in Dwarf, used from dwarf_begin_elf 1338 and libdwfl process_file. */ 1339char * __libdw_debugdir (int fd); 1340 1341 1342/* Given the directory of a debug file, an absolute or relative dir 1343 to look in, and file returns a full path. 1344 1345 If the file is absolute (starts with a /) a copy of file is returned. 1346 the file isn't absolute, but dir is absolute, then a path that is 1347 the concatenation of dir and file is returned. If neither file, 1348 nor dir is absolute, the path will be constructed using dir (if not 1349 NULL) and file relative to the debugdir (if valid). 1350 1351 The debugdir and the dir may be NULL (in which case they aren't used). 1352 If file is NULL, or no full path can be constructed NULL is returned. 1353 1354 The caller is responsible for freeing the result if not NULL. */ 1355char * __libdw_filepath (const char *debugdir, const char *dir, 1356 const char *file) 1357 internal_function; 1358 1359 1360/* Aliases to avoid PLTs. */ 1361INTDECL (dwarf_aggregate_size) 1362INTDECL (dwarf_attr) 1363INTDECL (dwarf_attr_integrate) 1364INTDECL (dwarf_begin) 1365INTDECL (dwarf_begin_elf) 1366INTDECL (dwarf_child) 1367INTDECL (dwarf_default_lower_bound) 1368INTDECL (dwarf_dieoffset) 1369INTDECL (dwarf_diename) 1370INTDECL (dwarf_end) 1371INTDECL (dwarf_entrypc) 1372INTDECL (dwarf_errmsg) 1373INTDECL (dwarf_formaddr) 1374INTDECL (dwarf_formblock) 1375INTDECL (dwarf_formref_die) 1376INTDECL (dwarf_formsdata) 1377INTDECL (dwarf_formstring) 1378INTDECL (dwarf_formudata) 1379INTDECL (dwarf_getabbrevattr_data) 1380INTDECL (dwarf_getalt) 1381INTDECL (dwarf_getarange_addr) 1382INTDECL (dwarf_getarangeinfo) 1383INTDECL (dwarf_getaranges) 1384INTDECL (dwarf_getlocation_die) 1385INTDECL (dwarf_getsrcfiles) 1386INTDECL (dwarf_getsrclines) 1387INTDECL (dwarf_hasattr) 1388INTDECL (dwarf_haschildren) 1389INTDECL (dwarf_haspc) 1390INTDECL (dwarf_highpc) 1391INTDECL (dwarf_lowpc) 1392INTDECL (dwarf_nextcu) 1393INTDECL (dwarf_next_unit) 1394INTDECL (dwarf_offdie) 1395INTDECL (dwarf_peel_type) 1396INTDECL (dwarf_ranges) 1397INTDECL (dwarf_setalt) 1398INTDECL (dwarf_siblingof) 1399INTDECL (dwarf_srclang) 1400INTDECL (dwarf_tag) 1401 1402#endif /* libdwP.h */ 1403