1 /* Internal definitions for libdwarf. 2 Copyright (C) 2002-2011, 2013-2015 Red Hat, Inc. 3 This file is part of elfutils. 4 Written by Ulrich Drepper <drepper (at) redhat.com>, 2002. 5 6 This file is free software; you can redistribute it and/or modify 7 it under the terms of either 8 9 * the GNU Lesser General Public License as published by the Free 10 Software Foundation; either version 3 of the License, or (at 11 your option) any later version 12 13 or 14 15 * the GNU General Public License as published by the Free 16 Software Foundation; either version 2 of the License, or (at 17 your option) any later version 18 19 or both in parallel, as here. 20 21 elfutils is distributed in the hope that it will be useful, but 22 WITHOUT ANY WARRANTY; without even the implied warranty of 23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 24 General Public License for more details. 25 26 You should have received copies of the GNU General Public License and 27 the GNU Lesser General Public License along with this program. If 28 not, see <http://www.gnu.org/licenses/>. */ 29 30 #ifndef _LIBDWP_H 31 #define _LIBDWP_H 1 32 33 #include <libintl.h> 34 #include <stdbool.h> 35 36 #include <libdw.h> 37 #include <dwarf.h> 38 39 40 /* gettext helper macros. */ 41 #define _(Str) dgettext ("elfutils", Str) 42 43 44 /* Known location expressions already decoded. */ 45 struct loc_s 46 { 47 void *addr; 48 Dwarf_Op *loc; 49 size_t nloc; 50 }; 51 52 /* Known DW_OP_implicit_value blocks already decoded. 53 This overlaps struct loc_s exactly, but only the 54 first member really has to match. */ 55 struct loc_block_s 56 { 57 void *addr; 58 unsigned char *data; 59 size_t length; 60 }; 61 62 /* Already decoded .debug_line units. */ 63 struct files_lines_s 64 { 65 Dwarf_Off debug_line_offset; 66 Dwarf_Files *files; 67 Dwarf_Lines *lines; 68 }; 69 70 /* Valid indeces for the section data. */ 71 enum 72 { 73 IDX_debug_info = 0, 74 IDX_debug_types, 75 IDX_debug_abbrev, 76 IDX_debug_aranges, 77 IDX_debug_line, 78 IDX_debug_frame, 79 IDX_debug_loc, 80 IDX_debug_pubnames, 81 IDX_debug_str, 82 IDX_debug_macinfo, 83 IDX_debug_macro, 84 IDX_debug_ranges, 85 IDX_gnu_debugaltlink, 86 IDX_last 87 }; 88 89 90 /* Error values. */ 91 enum 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_ADDR, 112 DWARF_E_NO_CONSTANT, 113 DWARF_E_NO_REFERENCE, 114 DWARF_E_INVALID_REFERENCE, 115 DWARF_E_NO_DEBUG_LINE, 116 DWARF_E_INVALID_DEBUG_LINE, 117 DWARF_E_TOO_BIG, 118 DWARF_E_VERSION, 119 DWARF_E_INVALID_DIR_IDX, 120 DWARF_E_ADDR_OUTOFRANGE, 121 DWARF_E_NO_LOCLIST, 122 DWARF_E_NO_BLOCK, 123 DWARF_E_INVALID_LINE_IDX, 124 DWARF_E_INVALID_ARANGE_IDX, 125 DWARF_E_NO_MATCH, 126 DWARF_E_NO_FLAG, 127 DWARF_E_INVALID_OFFSET, 128 DWARF_E_NO_DEBUG_RANGES, 129 DWARF_E_INVALID_CFI, 130 DWARF_E_NO_ALT_DEBUGLINK, 131 DWARF_E_INVALID_OPCODE, 132 DWARF_E_NOT_CUDIE, 133 }; 134 135 136 #include "dwarf_sig8_hash.h" 137 138 /* This is the structure representing the debugging state. */ 139 struct Dwarf 140 { 141 /* The underlying ELF file. */ 142 Elf *elf; 143 144 /* dwz alternate DWARF file. */ 145 Dwarf *alt_dwarf; 146 147 /* The section data. */ 148 Elf_Data *sectiondata[IDX_last]; 149 150 /* True if the file has a byte order different from the host. */ 151 bool other_byte_order; 152 153 /* If true, we allocated the ELF descriptor ourselves. */ 154 bool free_elf; 155 156 /* Information for traversing the .debug_pubnames section. This is 157 an array and separately allocated with malloc. */ 158 struct pubnames_s 159 { 160 Dwarf_Off cu_offset; 161 Dwarf_Off set_start; 162 unsigned int cu_header_size; 163 int address_len; 164 } *pubnames_sets; 165 size_t pubnames_nsets; 166 167 /* Search tree for the CUs. */ 168 void *cu_tree; 169 Dwarf_Off next_cu_offset; 170 171 /* Search tree and sig8 hash table for .debug_types type units. */ 172 void *tu_tree; 173 Dwarf_Off next_tu_offset; 174 Dwarf_Sig8_Hash sig8_hash; 175 176 /* Search tree for .debug_macro operator tables. */ 177 void *macro_ops; 178 179 /* Search tree for decoded .debug_line units. */ 180 void *files_lines; 181 182 /* Address ranges. */ 183 Dwarf_Aranges *aranges; 184 185 /* Cached info from the CFI section. */ 186 struct Dwarf_CFI_s *cfi; 187 188 /* Fake loc CU. Used when synthesizing attributes for Dwarf_Ops that 189 came from a location list entry in dwarf_getlocation_attr. */ 190 struct Dwarf_CU *fake_loc_cu; 191 192 /* Internal memory handling. This is basically a simplified 193 reimplementation of obstacks. Unfortunately the standard obstack 194 implementation is not usable in libraries. */ 195 struct libdw_memblock 196 { 197 size_t size; 198 size_t remaining; 199 struct libdw_memblock *prev; 200 char mem[0]; 201 } *mem_tail; 202 203 /* Default size of allocated memory blocks. */ 204 size_t mem_default_size; 205 206 /* Registered OOM handler. */ 207 Dwarf_OOM oom_handler; 208 }; 209 210 211 /* Abbreviation representation. */ 212 struct Dwarf_Abbrev 213 { 214 Dwarf_Off offset; 215 unsigned char *attrp; 216 unsigned int attrcnt; 217 unsigned int code; 218 unsigned int tag; 219 bool has_children; 220 }; 221 222 #include "dwarf_abbrev_hash.h" 223 224 225 /* Files in line information records. */ 226 struct Dwarf_Files_s 227 { 228 unsigned int ndirs; 229 unsigned int nfiles; 230 struct Dwarf_Fileinfo_s 231 { 232 char *name; 233 Dwarf_Word mtime; 234 Dwarf_Word length; 235 } info[0]; 236 /* nfiles of those, followed by char *[ndirs]. */ 237 }; 238 typedef struct Dwarf_Fileinfo_s Dwarf_Fileinfo; 239 240 241 /* Representation of a row in the line table. */ 242 243 struct Dwarf_Line_s 244 { 245 Dwarf_Files *files; 246 247 Dwarf_Addr addr; 248 unsigned int file; 249 int line; 250 unsigned short int column; 251 unsigned int is_stmt:1; 252 unsigned int basic_block:1; 253 unsigned int end_sequence:1; 254 unsigned int prologue_end:1; 255 unsigned int epilogue_begin:1; 256 /* The remaining bit fields are not flags, but hold values presumed to be 257 small. All the flags and other bit fields should add up to 48 bits 258 to give the whole struct a nice round size. */ 259 unsigned int op_index:8; 260 unsigned int isa:8; 261 unsigned int discriminator:24; 262 }; 263 264 struct Dwarf_Lines_s 265 { 266 size_t nlines; 267 struct Dwarf_Line_s info[0]; 268 }; 269 270 /* Representation of address ranges. */ 271 struct Dwarf_Aranges_s 272 { 273 Dwarf *dbg; 274 size_t naranges; 275 276 struct Dwarf_Arange_s 277 { 278 Dwarf_Addr addr; 279 Dwarf_Word length; 280 Dwarf_Off offset; 281 } info[0]; 282 }; 283 284 285 /* CU representation. */ 286 struct Dwarf_CU 287 { 288 Dwarf *dbg; 289 Dwarf_Off start; 290 Dwarf_Off end; 291 uint8_t address_size; 292 uint8_t offset_size; 293 uint16_t version; 294 295 /* Zero if this is a normal CU. Nonzero if it is a type unit. */ 296 size_t type_offset; 297 uint64_t type_sig8; 298 299 /* Hash table for the abbreviations. */ 300 Dwarf_Abbrev_Hash abbrev_hash; 301 /* Offset of the first abbreviation. */ 302 size_t orig_abbrev_offset; 303 /* Offset past last read abbreviation. */ 304 size_t last_abbrev_offset; 305 306 /* The srcline information. */ 307 Dwarf_Lines *lines; 308 309 /* The source file information. */ 310 Dwarf_Files *files; 311 312 /* Known location lists. */ 313 void *locs; 314 315 /* Memory boundaries of this CU. */ 316 void *startp; 317 void *endp; 318 }; 319 320 /* Compute the offset of a CU's first DIE from its offset. This 321 is either: 322 LEN VER OFFSET ADDR 323 4-bytes + 2-bytes + 4-bytes + 1-byte for 32-bit dwarf 324 12-bytes + 2-bytes + 8-bytes + 1-byte for 64-bit dwarf 325 or in .debug_types, SIGNATURE TYPE-OFFSET 326 4-bytes + 2-bytes + 4-bytes + 1-byte + 8-bytes + 4-bytes for 32-bit 327 12-bytes + 2-bytes + 8-bytes + 1-byte + 8-bytes + 8-bytes for 64-bit 328 329 Note the trick in the computation. If the offset_size is 4 330 the '- 4' term changes the '3 *' into a '2 *'. If the 331 offset_size is 8 it accounts for the 4-byte escape value 332 used at the start of the length. */ 333 #define DIE_OFFSET_FROM_CU_OFFSET(cu_offset, offset_size, type_unit) \ 334 ((type_unit) ? ((cu_offset) + 4 * (offset_size) - 4 + 3 + 8) \ 335 : ((cu_offset) + 3 * (offset_size) - 4 + 3)) 336 337 #define CUDIE(fromcu) \ 338 ((Dwarf_Die) \ 339 { \ 340 .cu = (fromcu), \ 341 .addr = ((char *) fromcu->dbg->sectiondata[cu_sec_idx (fromcu)]->d_buf \ 342 + DIE_OFFSET_FROM_CU_OFFSET ((fromcu)->start, \ 343 (fromcu)->offset_size, \ 344 (fromcu)->type_offset != 0)) \ 345 }) \ 346 347 348 /* Prototype of a single .debug_macro operator. */ 349 typedef struct 350 { 351 Dwarf_Word nforms; 352 unsigned char const *forms; 353 } Dwarf_Macro_Op_Proto; 354 355 /* Prototype table. */ 356 typedef struct 357 { 358 /* Offset of .debug_macro section. */ 359 Dwarf_Off offset; 360 361 /* Offset of associated .debug_line section. */ 362 Dwarf_Off line_offset; 363 364 /* The source file information. */ 365 Dwarf_Files *files; 366 367 /* If this macro unit was opened through dwarf_getmacros or 368 dwarf_getmacros_die, this caches value of DW_AT_comp_dir, if 369 present. */ 370 const char *comp_dir; 371 372 /* Header length. */ 373 Dwarf_Half header_len; 374 375 uint16_t version; 376 bool is_64bit; 377 uint8_t sec_index; /* IDX_debug_macro or IDX_debug_macinfo. */ 378 379 /* Shows where in TABLE each opcode is defined. Since opcode 0 is 380 never used, it stores index of opcode X in X-1'th element. The 381 value of 0xff means not stored at all. */ 382 unsigned char opcodes[255]; 383 384 /* Individual opcode prototypes. */ 385 Dwarf_Macro_Op_Proto table[]; 386 } Dwarf_Macro_Op_Table; 387 388 struct Dwarf_Macro_s 389 { 390 Dwarf_Macro_Op_Table *table; 391 Dwarf_Attribute *attributes; 392 uint8_t opcode; 393 }; 394 395 static inline Dwarf_Word 396 libdw_macro_nforms (Dwarf_Macro *macro) 397 { 398 return macro->table->table[macro->table->opcodes[macro->opcode - 1]].nforms; 399 } 400 401 /* We have to include the file at this point because the inline 402 functions access internals of the Dwarf structure. */ 403 #include "memory-access.h" 404 405 406 /* Set error value. */ 407 extern void __libdw_seterrno (int value) internal_function; 408 409 410 /* Memory handling, the easy parts. This macro does not do any locking. */ 411 #define libdw_alloc(dbg, type, tsize, cnt) \ 412 ({ struct libdw_memblock *_tail = (dbg)->mem_tail; \ 413 size_t _required = (tsize) * (cnt); \ 414 type *_result = (type *) (_tail->mem + (_tail->size - _tail->remaining));\ 415 size_t _padding = ((__alignof (type) \ 416 - ((uintptr_t) _result & (__alignof (type) - 1))) \ 417 & (__alignof (type) - 1)); \ 418 if (unlikely (_tail->remaining < _required + _padding)) \ 419 _result = (type *) __libdw_allocate (dbg, _required, __alignof (type));\ 420 else \ 421 { \ 422 _required += _padding; \ 423 _result = (type *) ((char *) _result + _padding); \ 424 _tail->remaining -= _required; \ 425 } \ 426 _result; }) 427 428 #define libdw_typed_alloc(dbg, type) \ 429 libdw_alloc (dbg, type, sizeof (type), 1) 430 431 /* Callback to allocate more. */ 432 extern void *__libdw_allocate (Dwarf *dbg, size_t minsize, size_t align) 433 __attribute__ ((__malloc__)) __nonnull_attribute__ (1); 434 435 /* Default OOM handler. */ 436 extern void __libdw_oom (void) __attribute ((noreturn, visibility ("hidden"))); 437 438 /* Allocate the internal data for a unit not seen before. */ 439 extern struct Dwarf_CU *__libdw_intern_next_unit (Dwarf *dbg, bool debug_types) 440 __nonnull_attribute__ (1) internal_function; 441 442 /* Find CU for given offset. */ 443 extern struct Dwarf_CU *__libdw_findcu (Dwarf *dbg, Dwarf_Off offset, bool tu) 444 __nonnull_attribute__ (1) internal_function; 445 446 /* Get abbreviation with given code. */ 447 extern Dwarf_Abbrev *__libdw_findabbrev (struct Dwarf_CU *cu, 448 unsigned int code) 449 __nonnull_attribute__ (1) internal_function; 450 451 /* Get abbreviation at given offset. */ 452 extern Dwarf_Abbrev *__libdw_getabbrev (Dwarf *dbg, struct Dwarf_CU *cu, 453 Dwarf_Off offset, size_t *lengthp, 454 Dwarf_Abbrev *result) 455 __nonnull_attribute__ (1) internal_function; 456 457 /* Get abbreviation of given DIE, and optionally set *READP to the DIE memory 458 just past the abbreviation code. */ 459 static inline Dwarf_Abbrev * 460 __nonnull_attribute__ (1) 461 __libdw_dieabbrev (Dwarf_Die *die, const unsigned char **readp) 462 { 463 /* Do we need to get the abbreviation, or need to read after the code? */ 464 if (die->abbrev == NULL || readp != NULL) 465 { 466 /* Get the abbreviation code. */ 467 unsigned int code; 468 const unsigned char *addr = die->addr; 469 get_uleb128 (code, addr, die->cu->endp); 470 if (readp != NULL) 471 *readp = addr; 472 473 /* Find the abbreviation. */ 474 if (die->abbrev == NULL) 475 die->abbrev = __libdw_findabbrev (die->cu, code); 476 } 477 return die->abbrev; 478 } 479 480 /* Helper functions for form handling. */ 481 extern size_t __libdw_form_val_compute_len (struct Dwarf_CU *cu, 482 unsigned int form, 483 const unsigned char *valp) 484 __nonnull_attribute__ (1, 3) internal_function; 485 486 /* Find the length of a form attribute. */ 487 static inline size_t 488 __nonnull_attribute__ (1, 3) 489 __libdw_form_val_len (struct Dwarf_CU *cu, unsigned int form, 490 const unsigned char *valp) 491 { 492 /* Small lookup table of forms with fixed lengths. Absent indexes are 493 initialized 0, so any truly desired 0 is set to 0x80 and masked. */ 494 static const uint8_t form_lengths[] = 495 { 496 [DW_FORM_flag_present] = 0x80, 497 [DW_FORM_data1] = 1, [DW_FORM_ref1] = 1, [DW_FORM_flag] = 1, 498 [DW_FORM_data2] = 2, [DW_FORM_ref2] = 2, 499 [DW_FORM_data4] = 4, [DW_FORM_ref4] = 4, 500 [DW_FORM_data8] = 8, [DW_FORM_ref8] = 8, [DW_FORM_ref_sig8] = 8, 501 }; 502 503 /* Return immediately for forms with fixed lengths. */ 504 if (form < sizeof form_lengths / sizeof form_lengths[0]) 505 { 506 uint8_t len = form_lengths[form]; 507 if (len != 0) 508 { 509 const unsigned char *endp = cu->endp; 510 len &= 0x7f; /* Mask to allow 0x80 -> 0. */ 511 if (unlikely (len > (size_t) (endp - valp))) 512 { 513 __libdw_seterrno (DWARF_E_INVALID_DWARF); 514 return -1; 515 } 516 return len; 517 } 518 } 519 520 /* Other forms require some computation. */ 521 return __libdw_form_val_compute_len (cu, form, valp); 522 } 523 524 /* Helper function for DW_FORM_ref* handling. */ 525 extern int __libdw_formref (Dwarf_Attribute *attr, Dwarf_Off *return_offset) 526 __nonnull_attribute__ (1, 2) internal_function; 527 528 529 /* Helper function to locate attribute. */ 530 extern unsigned char *__libdw_find_attr (Dwarf_Die *die, 531 unsigned int search_name, 532 unsigned int *codep, 533 unsigned int *formp) 534 __nonnull_attribute__ (1) internal_function; 535 536 /* Helper function to access integer attribute. */ 537 extern int __libdw_attr_intval (Dwarf_Die *die, int *valp, int attval) 538 __nonnull_attribute__ (1, 2) internal_function; 539 540 /* Helper function to walk scopes. */ 541 struct Dwarf_Die_Chain 542 { 543 Dwarf_Die die; 544 struct Dwarf_Die_Chain *parent; 545 bool prune; /* The PREVISIT function can set this. */ 546 }; 547 extern int __libdw_visit_scopes (unsigned int depth, 548 struct Dwarf_Die_Chain *root, 549 struct Dwarf_Die_Chain *imports, 550 int (*previsit) (unsigned int depth, 551 struct Dwarf_Die_Chain *, 552 void *arg), 553 int (*postvisit) (unsigned int depth, 554 struct Dwarf_Die_Chain *, 555 void *arg), 556 void *arg) 557 __nonnull_attribute__ (2, 4) internal_function; 558 559 /* Parse a DWARF Dwarf_Block into an array of Dwarf_Op's, 560 and cache the result (via tsearch). */ 561 extern int __libdw_intern_expression (Dwarf *dbg, 562 bool other_byte_order, 563 unsigned int address_size, 564 unsigned int ref_size, 565 void **cache, const Dwarf_Block *block, 566 bool cfap, bool valuep, 567 Dwarf_Op **llbuf, size_t *listlen, 568 int sec_index) 569 __nonnull_attribute__ (5, 6, 9, 10) internal_function; 570 571 extern Dwarf_Die *__libdw_offdie (Dwarf *dbg, Dwarf_Off offset, 572 Dwarf_Die *result, bool debug_types) 573 internal_function; 574 575 576 /* Return error code of last failing function call. This value is kept 577 separately for each thread. */ 578 extern int __dwarf_errno_internal (void); 579 580 581 /* Reader hooks. */ 582 583 /* Relocation hooks return -1 on error (in that case the error code 584 must already have been set), 0 if there is no relocation and 1 if a 585 relocation was present.*/ 586 587 static inline int 588 __libdw_relocate_address (Dwarf *dbg __attribute__ ((unused)), 589 int sec_index __attribute__ ((unused)), 590 const void *addr __attribute__ ((unused)), 591 int width __attribute__ ((unused)), 592 Dwarf_Addr *val __attribute__ ((unused))) 593 { 594 return 0; 595 } 596 597 static inline int 598 __libdw_relocate_offset (Dwarf *dbg __attribute__ ((unused)), 599 int sec_index __attribute__ ((unused)), 600 const void *addr __attribute__ ((unused)), 601 int width __attribute__ ((unused)), 602 Dwarf_Off *val __attribute__ ((unused))) 603 { 604 return 0; 605 } 606 607 static inline Elf_Data * 608 __libdw_checked_get_data (Dwarf *dbg, int sec_index) 609 { 610 Elf_Data *data = dbg->sectiondata[sec_index]; 611 if (unlikely (data == NULL) 612 || unlikely (data->d_buf == NULL)) 613 { 614 __libdw_seterrno (DWARF_E_INVALID_DWARF); 615 return NULL; 616 } 617 return data; 618 } 619 620 static inline int 621 __libdw_offset_in_section (Dwarf *dbg, int sec_index, 622 Dwarf_Off offset, size_t size) 623 { 624 Elf_Data *data = __libdw_checked_get_data (dbg, sec_index); 625 if (data == NULL) 626 return -1; 627 if (unlikely (offset > data->d_size) 628 || unlikely (data->d_size - offset < size)) 629 { 630 __libdw_seterrno (DWARF_E_INVALID_OFFSET); 631 return -1; 632 } 633 634 return 0; 635 } 636 637 static inline bool 638 __libdw_in_section (Dwarf *dbg, int sec_index, 639 const void *addr, size_t size) 640 { 641 Elf_Data *data = __libdw_checked_get_data (dbg, sec_index); 642 if (data == NULL) 643 return false; 644 if (unlikely (addr < data->d_buf) 645 || unlikely (data->d_size - (addr - data->d_buf) < size)) 646 { 647 __libdw_seterrno (DWARF_E_INVALID_OFFSET); 648 return false; 649 } 650 651 return true; 652 } 653 654 #define READ_AND_RELOCATE(RELOC_HOOK, VAL) \ 655 ({ \ 656 if (!__libdw_in_section (dbg, sec_index, addr, width)) \ 657 return -1; \ 658 \ 659 const unsigned char *orig_addr = addr; \ 660 if (width == 4) \ 661 VAL = read_4ubyte_unaligned_inc (dbg, addr); \ 662 else \ 663 VAL = read_8ubyte_unaligned_inc (dbg, addr); \ 664 \ 665 int status = RELOC_HOOK (dbg, sec_index, orig_addr, width, &VAL); \ 666 if (status < 0) \ 667 return status; \ 668 status > 0; \ 669 }) 670 671 static inline int 672 __libdw_read_address_inc (Dwarf *dbg, 673 int sec_index, const unsigned char **addrp, 674 int width, Dwarf_Addr *ret) 675 { 676 const unsigned char *addr = *addrp; 677 READ_AND_RELOCATE (__libdw_relocate_address, (*ret)); 678 *addrp = addr; 679 return 0; 680 } 681 682 static inline int 683 __libdw_read_address (Dwarf *dbg, 684 int sec_index, const unsigned char *addr, 685 int width, Dwarf_Addr *ret) 686 { 687 READ_AND_RELOCATE (__libdw_relocate_address, (*ret)); 688 return 0; 689 } 690 691 static inline int 692 __libdw_read_offset_inc (Dwarf *dbg, 693 int sec_index, const unsigned char **addrp, 694 int width, Dwarf_Off *ret, int sec_ret, 695 size_t size) 696 { 697 const unsigned char *addr = *addrp; 698 READ_AND_RELOCATE (__libdw_relocate_offset, (*ret)); 699 *addrp = addr; 700 return __libdw_offset_in_section (dbg, sec_ret, *ret, size); 701 } 702 703 static inline int 704 __libdw_read_offset (Dwarf *dbg, Dwarf *dbg_ret, 705 int sec_index, const unsigned char *addr, 706 int width, Dwarf_Off *ret, int sec_ret, 707 size_t size) 708 { 709 READ_AND_RELOCATE (__libdw_relocate_offset, (*ret)); 710 return __libdw_offset_in_section (dbg_ret, sec_ret, *ret, size); 711 } 712 713 static inline size_t 714 cu_sec_idx (struct Dwarf_CU *cu) 715 { 716 return cu->type_offset == 0 ? IDX_debug_info : IDX_debug_types; 717 } 718 719 static inline bool 720 is_cudie (Dwarf_Die *cudie) 721 { 722 return CUDIE (cudie->cu).addr == cudie->addr; 723 } 724 725 /* Read up begin/end pair and increment read pointer. 726 - If it's normal range record, set up *BEGINP and *ENDP and return 0. 727 - If it's base address selection record, set up *BASEP and return 1. 728 - If it's end of rangelist, don't set anything and return 2 729 - If an error occurs, don't set anything and return <0. */ 730 int __libdw_read_begin_end_pair_inc (Dwarf *dbg, int sec_index, 731 unsigned char **addr, int width, 732 Dwarf_Addr *beginp, Dwarf_Addr *endp, 733 Dwarf_Addr *basep) 734 internal_function; 735 736 unsigned char * __libdw_formptr (Dwarf_Attribute *attr, int sec_index, 737 int err_nodata, unsigned char **endpp, 738 Dwarf_Off *offsetp) 739 internal_function; 740 741 /* Fills in the given attribute to point at an empty location expression. */ 742 void __libdw_empty_loc_attr (Dwarf_Attribute *attr) 743 internal_function; 744 745 /* Load .debug_line unit at DEBUG_LINE_OFFSET. COMP_DIR is a value of 746 DW_AT_comp_dir or NULL if that attribute is not available. Caches 747 the loaded unit and optionally set *LINESP and/or *FILESP (if not 748 NULL) with loaded information. Returns 0 for success or a negative 749 value for failure. */ 750 int __libdw_getsrclines (Dwarf *dbg, Dwarf_Off debug_line_offset, 751 const char *comp_dir, unsigned address_size, 752 Dwarf_Lines **linesp, Dwarf_Files **filesp) 753 internal_function 754 __nonnull_attribute__ (1); 755 756 /* Load and return value of DW_AT_comp_dir from CUDIE. */ 757 const char *__libdw_getcompdir (Dwarf_Die *cudie); 758 759 760 /* Aliases to avoid PLTs. */ 761 INTDECL (dwarf_aggregate_size) 762 INTDECL (dwarf_attr) 763 INTDECL (dwarf_attr_integrate) 764 INTDECL (dwarf_begin) 765 INTDECL (dwarf_begin_elf) 766 INTDECL (dwarf_child) 767 INTDECL (dwarf_dieoffset) 768 INTDECL (dwarf_diename) 769 INTDECL (dwarf_end) 770 INTDECL (dwarf_entrypc) 771 INTDECL (dwarf_errmsg) 772 INTDECL (dwarf_formaddr) 773 INTDECL (dwarf_formblock) 774 INTDECL (dwarf_formref_die) 775 INTDECL (dwarf_formsdata) 776 INTDECL (dwarf_formstring) 777 INTDECL (dwarf_formudata) 778 INTDECL (dwarf_getalt) 779 INTDECL (dwarf_getarange_addr) 780 INTDECL (dwarf_getarangeinfo) 781 INTDECL (dwarf_getaranges) 782 INTDECL (dwarf_getlocation_die) 783 INTDECL (dwarf_getsrcfiles) 784 INTDECL (dwarf_getsrclines) 785 INTDECL (dwarf_hasattr) 786 INTDECL (dwarf_haschildren) 787 INTDECL (dwarf_haspc) 788 INTDECL (dwarf_highpc) 789 INTDECL (dwarf_lowpc) 790 INTDECL (dwarf_nextcu) 791 INTDECL (dwarf_next_unit) 792 INTDECL (dwarf_offdie) 793 INTDECL (dwarf_peel_type) 794 INTDECL (dwarf_ranges) 795 INTDECL (dwarf_setalt) 796 INTDECL (dwarf_siblingof) 797 INTDECL (dwarf_srclang) 798 INTDECL (dwarf_tag) 799 800 #endif /* libdwP.h */ 801