libdwP.h revision 675229bb5dcf38df3c09f7f74e41b861e32dd0f2
15a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt/* Internal definitions for libdwarf. 25a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt Copyright (C) 2002-2010 Red Hat, Inc. 35a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt This file is part of Red Hat elfutils. 45a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt Written by Ulrich Drepper <drepper@redhat.com>, 2002. 55a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt 65a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt Red Hat elfutils is free software; you can redistribute it and/or modify 75a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt it under the terms of the GNU General Public License as published by the 85a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt Free Software Foundation; version 2 of the License. 9 10 Red Hat elfutils is distributed in the hope that it will be useful, but 11 WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 General Public License for more details. 14 15 You should have received a copy of the GNU General Public License along 16 with Red Hat elfutils; if not, write to the Free Software Foundation, 17 Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. 18 19 In addition, as a special exception, Red Hat, Inc. gives You the 20 additional right to link the code of Red Hat elfutils with code licensed 21 under any Open Source Initiative certified open source license 22 (http://www.opensource.org/licenses/index.php) which requires the 23 distribution of source code with any binary distribution and to 24 distribute linked combinations of the two. Non-GPL Code permitted under 25 this exception must only link to the code of Red Hat elfutils through 26 those well defined interfaces identified in the file named EXCEPTION 27 found in the source code files (the "Approved Interfaces"). The files 28 of Non-GPL Code may instantiate templates or use macros or inline 29 functions from the Approved Interfaces without causing the resulting 30 work to be covered by the GNU General Public License. Only Red Hat, 31 Inc. may make changes or additions to the list of Approved Interfaces. 32 Red Hat's grant of this exception is conditioned upon your not adding 33 any new exceptions. If you wish to add a new Approved Interface or 34 exception, please contact Red Hat. You must obey the GNU General Public 35 License in all respects for all of the Red Hat elfutils code and other 36 code used in conjunction with Red Hat elfutils except the Non-GPL Code 37 covered by this exception. If you modify this file, you may extend this 38 exception to your version of the file, but you are not obligated to do 39 so. If you do not wish to provide this exception without modification, 40 you must delete this exception statement from your version and license 41 this file solely under the GPL without exception. 42 43 Red Hat elfutils is an included package of the Open Invention Network. 44 An included package of the Open Invention Network is a package for which 45 Open Invention Network licensees cross-license their patents. No patent 46 license is granted, either expressly or impliedly, by designation as an 47 included package. Should you wish to participate in the Open Invention 48 Network licensing program, please visit www.openinventionnetwork.com 49 <http://www.openinventionnetwork.com>. */ 50 51#ifndef _LIBDWP_H 52#define _LIBDWP_H 1 53 54#include <libintl.h> 55#include <stdbool.h> 56 57#include <libdw.h> 58 59 60/* gettext helper macros. */ 61#define _(Str) dgettext ("elfutils", Str) 62 63 64/* Version of the CIE format. */ 65#define CIE_VERSION 1 66 67 68/* Known location expressions already decoded. */ 69struct loc_s 70{ 71 void *addr; 72 Dwarf_Op *loc; 73 size_t nloc; 74}; 75 76/* Known DW_OP_implicit_value blocks already decoded. 77 This overlaps struct loc_s exactly, but only the 78 first member really has to match. */ 79struct loc_block_s 80{ 81 void *addr; 82 unsigned char *data; 83 size_t length; 84}; 85 86/* Valid indeces for the section data. */ 87enum 88 { 89 IDX_debug_info = 0, 90 IDX_debug_abbrev, 91 IDX_debug_aranges, 92 IDX_debug_line, 93 IDX_debug_frame, 94 IDX_debug_loc, 95 IDX_debug_pubnames, 96 IDX_debug_str, 97 IDX_debug_funcnames, 98 IDX_debug_typenames, 99 IDX_debug_varnames, 100 IDX_debug_weaknames, 101 IDX_debug_macinfo, 102 IDX_debug_ranges, 103 IDX_last 104 }; 105 106 107/* Error values. */ 108enum 109{ 110 DWARF_E_NOERROR = 0, 111 DWARF_E_UNKNOWN_ERROR, 112 DWARF_E_INVALID_ACCESS, 113 DWARF_E_NO_REGFILE, 114 DWARF_E_IO_ERROR, 115 DWARF_E_INVALID_ELF, 116 DWARF_E_NO_DWARF, 117 DWARF_E_NOELF, 118 DWARF_E_GETEHDR_ERROR, 119 DWARF_E_NOMEM, 120 DWARF_E_UNIMPL, 121 DWARF_E_INVALID_CMD, 122 DWARF_E_INVALID_VERSION, 123 DWARF_E_INVALID_FILE, 124 DWARF_E_NO_ENTRY, 125 DWARF_E_INVALID_DWARF, 126 DWARF_E_NO_STRING, 127 DWARF_E_NO_ADDR, 128 DWARF_E_NO_CONSTANT, 129 DWARF_E_NO_REFERENCE, 130 DWARF_E_INVALID_REFERENCE, 131 DWARF_E_NO_DEBUG_LINE, 132 DWARF_E_INVALID_DEBUG_LINE, 133 DWARF_E_TOO_BIG, 134 DWARF_E_VERSION, 135 DWARF_E_INVALID_DIR_IDX, 136 DWARF_E_ADDR_OUTOFRANGE, 137 DWARF_E_NO_LOCLIST, 138 DWARF_E_NO_BLOCK, 139 DWARF_E_INVALID_LINE_IDX, 140 DWARF_E_INVALID_ARANGE_IDX, 141 DWARF_E_NO_MATCH, 142 DWARF_E_NO_FLAG, 143 DWARF_E_INVALID_OFFSET, 144 DWARF_E_NO_DEBUG_RANGES, 145 DWARF_E_INVALID_CFI, 146}; 147 148 149/* This is the structure representing the debugging state. */ 150struct Dwarf 151{ 152 /* The underlying ELF file. */ 153 Elf *elf; 154 155 /* The section data. */ 156 Elf_Data *sectiondata[IDX_last]; 157 158 /* True if the file has a byte order different from the host. */ 159 bool other_byte_order; 160 161 /* If true, we allocated the ELF descriptor ourselves. */ 162 bool free_elf; 163 164 /* Information for traversing the .debug_pubnames section. This is 165 an array and separately allocated with malloc. */ 166 struct pubnames_s 167 { 168 Dwarf_Off cu_offset; 169 Dwarf_Off set_start; 170 unsigned int cu_header_size; 171 int address_len; 172 } *pubnames_sets; 173 size_t pubnames_nsets; 174 175 /* Search tree for the CUs. */ 176 void *cu_tree; 177 Dwarf_Off next_cu_offset; 178 179 /* Address ranges. */ 180 Dwarf_Aranges *aranges; 181 182 /* Cached info from the CFI section. */ 183 struct Dwarf_CFI_s *cfi; 184 185 /* Internal memory handling. This is basically a simplified 186 reimplementation of obstacks. Unfortunately the standard obstack 187 implementation is not usable in libraries. */ 188 struct libdw_memblock 189 { 190 size_t size; 191 size_t remaining; 192 struct libdw_memblock *prev; 193 char mem[0]; 194 } *mem_tail; 195 196 /* Default size of allocated memory blocks. */ 197 size_t mem_default_size; 198 199 /* Registered OOM handler. */ 200 Dwarf_OOM oom_handler; 201}; 202 203 204/* Abbreviation representation. */ 205struct Dwarf_Abbrev 206{ 207 Dwarf_Off offset; 208 unsigned char *attrp; 209 unsigned int attrcnt; 210 unsigned int code; 211 unsigned int tag; 212 bool has_children; 213}; 214 215#include "dwarf_abbrev_hash.h" 216 217 218/* Files in line information records. */ 219struct Dwarf_Files_s 220 { 221 struct Dwarf_CU *cu; 222 unsigned int ndirs; 223 unsigned int nfiles; 224 struct Dwarf_Fileinfo_s 225 { 226 char *name; 227 Dwarf_Word mtime; 228 Dwarf_Word length; 229 } info[0]; 230 /* nfiles of those, followed by char *[ndirs]. */ 231 }; 232typedef struct Dwarf_Fileinfo_s Dwarf_Fileinfo; 233 234 235/* Representation of a row in the line table. */ 236 237struct Dwarf_Line_s 238{ 239 Dwarf_Files *files; 240 241 Dwarf_Addr addr; 242 unsigned int file; 243 int line; 244 unsigned short int column; 245 unsigned int is_stmt:1; 246 unsigned int basic_block:1; 247 unsigned int end_sequence:1; 248 unsigned int prologue_end:1; 249 unsigned int epilogue_begin:1; 250}; 251 252struct Dwarf_Lines_s 253{ 254 size_t nlines; 255 struct Dwarf_Line_s info[0]; 256}; 257 258/* Representation of address ranges. */ 259struct Dwarf_Aranges_s 260{ 261 Dwarf *dbg; 262 size_t naranges; 263 264 struct Dwarf_Arange_s 265 { 266 Dwarf_Addr addr; 267 Dwarf_Word length; 268 Dwarf_Off offset; 269 } info[0]; 270}; 271 272 273/* CU representation. */ 274struct Dwarf_CU 275{ 276 Dwarf *dbg; 277 Dwarf_Off start; 278 Dwarf_Off end; 279 uint8_t address_size; 280 uint8_t offset_size; 281 uint16_t version; 282 283 /* Hash table for the abbreviations. */ 284 Dwarf_Abbrev_Hash abbrev_hash; 285 /* Offset of the first abbreviation. */ 286 size_t orig_abbrev_offset; 287 /* Offset past last read abbreviation. */ 288 size_t last_abbrev_offset; 289 290 /* The srcline information. */ 291 Dwarf_Lines *lines; 292 293 /* The source file information. */ 294 Dwarf_Files *files; 295 296 /* Known location lists. */ 297 void *locs; 298}; 299 300/* Compute the offset of a CU's first DIE from its offset. This 301 is either: 302 LEN VER OFFSET ADDR 303 4-bytes + 2-bytes + 4-bytes + 1-byte for 32-bit dwarf 304 12-bytes + 2-bytes + 8-bytes + 1-byte for 64-bit dwarf 305 306 Note the trick in the computation. If the offset_size is 4 307 the '- 4' term changes the '3 *' into a '2 *'. If the 308 offset_size is 8 it accounts for the 4-byte escape value 309 used at the start of the length. */ 310#define DIE_OFFSET_FROM_CU_OFFSET(cu_offset, offset_size) \ 311 ((cu_offset) + 3 * (offset_size) - 4 + 3) 312 313#define CUDIE(fromcu) \ 314 ((Dwarf_Die) \ 315 { \ 316 .cu = (fromcu), \ 317 .addr = ((char *) (fromcu)->dbg->sectiondata[IDX_debug_info]->d_buf \ 318 + (fromcu)->start + 3 * (fromcu)->offset_size - 4 + 3), \ 319 }) 320 321 322/* Macro information. */ 323struct Dwarf_Macro_s 324{ 325 unsigned int opcode; 326 Dwarf_Word param1; 327 union 328 { 329 Dwarf_Word u; 330 const char *s; 331 } param2; 332}; 333 334 335/* We have to include the file at this point because the inline 336 functions access internals of the Dwarf structure. */ 337#include "memory-access.h" 338 339 340/* Set error value. */ 341extern void __libdw_seterrno (int value) internal_function; 342 343 344/* Memory handling, the easy parts. This macro does not do any locking. */ 345#define libdw_alloc(dbg, type, tsize, cnt) \ 346 ({ struct libdw_memblock *_tail = (dbg)->mem_tail; \ 347 size_t _required = (tsize) * (cnt); \ 348 type *_result = (type *) (_tail->mem + (_tail->size - _tail->remaining));\ 349 size_t _padding = ((__alignof (type) \ 350 - ((uintptr_t) _result & (__alignof (type) - 1))) \ 351 & (__alignof (type) - 1)); \ 352 if (unlikely (_tail->remaining < _required + _padding)) \ 353 _result = (type *) __libdw_allocate (dbg, _required, __alignof (type));\ 354 else \ 355 { \ 356 _required += _padding; \ 357 _result = (type *) ((char *) _result + _padding); \ 358 _tail->remaining -= _required; \ 359 } \ 360 _result; }) 361 362#define libdw_typed_alloc(dbg, type) \ 363 libdw_alloc (dbg, type, sizeof (type), 1) 364 365/* Callback to allocate more. */ 366extern void *__libdw_allocate (Dwarf *dbg, size_t minsize, size_t align) 367 __attribute__ ((__malloc__)) __nonnull_attribute__ (1); 368 369/* Default OOM handler. */ 370extern void __libdw_oom (void) __attribute ((noreturn, visibility ("hidden"))); 371 372/* Find CU for given offset. */ 373extern struct Dwarf_CU *__libdw_findcu (Dwarf *dbg, Dwarf_Off offset) 374 __nonnull_attribute__ (1) internal_function; 375 376/* Return tag of given DIE. */ 377extern Dwarf_Abbrev *__libdw_findabbrev (struct Dwarf_CU *cu, 378 unsigned int code) 379 __nonnull_attribute__ (1) internal_function; 380 381/* Get abbreviation at given offset. */ 382extern Dwarf_Abbrev *__libdw_getabbrev (Dwarf *dbg, struct Dwarf_CU *cu, 383 Dwarf_Off offset, size_t *lengthp, 384 Dwarf_Abbrev *result) 385 __nonnull_attribute__ (1) internal_function; 386 387/* Helper functions for form handling. */ 388extern size_t __libdw_form_val_len (Dwarf *dbg, struct Dwarf_CU *cu, 389 unsigned int form, 390 const unsigned char *valp) 391 __nonnull_attribute__ (1, 2, 4) internal_function; 392 393/* Helper function for DW_FORM_ref* handling. */ 394extern int __libdw_formref (Dwarf_Attribute *attr, Dwarf_Off *return_offset) 395 __nonnull_attribute__ (1, 2) internal_function; 396 397 398/* Helper function to locate attribute. */ 399extern unsigned char *__libdw_find_attr (Dwarf_Die *die, 400 unsigned int search_name, 401 unsigned int *codep, 402 unsigned int *formp) 403 __nonnull_attribute__ (1) internal_function; 404 405/* Helper function to access integer attribute. */ 406extern int __libdw_attr_intval (Dwarf_Die *die, int *valp, int attval) 407 __nonnull_attribute__ (1, 2) internal_function; 408 409/* Helper function to walk scopes. */ 410struct Dwarf_Die_Chain 411{ 412 Dwarf_Die die; 413 struct Dwarf_Die_Chain *parent; 414 bool prune; /* The PREVISIT function can set this. */ 415}; 416extern int __libdw_visit_scopes (unsigned int depth, 417 struct Dwarf_Die_Chain *root, 418 int (*previsit) (unsigned int depth, 419 struct Dwarf_Die_Chain *, 420 void *arg), 421 int (*postvisit) (unsigned int depth, 422 struct Dwarf_Die_Chain *, 423 void *arg), 424 void *arg) 425 __nonnull_attribute__ (2, 3) internal_function; 426 427/* Parse a DWARF Dwarf_Block into an array of Dwarf_Op's, 428 and cache the result (via tsearch). */ 429extern int __libdw_intern_expression (Dwarf *dbg, 430 bool other_byte_order, 431 unsigned int address_size, 432 unsigned int ref_size, 433 void **cache, const Dwarf_Block *block, 434 bool cfap, bool valuep, 435 Dwarf_Op **llbuf, size_t *listlen, 436 int sec_index) 437 __nonnull_attribute__ (5, 6, 9, 10) internal_function; 438 439 440/* Return error code of last failing function call. This value is kept 441 separately for each thread. */ 442extern int __dwarf_errno_internal (void); 443 444 445/* Reader hooks. */ 446 447/* Relocation hooks return -1 on error (in that case the error code 448 must already have been set), 0 if there is no relocation and 1 if a 449 relocation was present.*/ 450 451static inline int 452__libdw_relocate_address (Dwarf *dbg __attribute__ ((unused)), 453 int sec_index __attribute__ ((unused)), 454 const void *addr __attribute__ ((unused)), 455 int width __attribute__ ((unused)), 456 Dwarf_Addr *val __attribute__ ((unused))) 457{ 458 return 0; 459} 460 461static inline int 462__libdw_relocate_offset (Dwarf *dbg __attribute__ ((unused)), 463 int sec_index __attribute__ ((unused)), 464 const void *addr __attribute__ ((unused)), 465 int width __attribute__ ((unused)), 466 Dwarf_Off *val __attribute__ ((unused))) 467{ 468 return 0; 469} 470 471static inline Elf_Data * 472__libdw_checked_get_data (Dwarf *dbg, int sec_index) 473{ 474 Elf_Data *data = dbg->sectiondata[sec_index]; 475 if (unlikely (data == NULL) 476 || unlikely (data->d_buf == NULL)) 477 { 478 __libdw_seterrno (DWARF_E_INVALID_DWARF); 479 return NULL; 480 } 481 return data; 482} 483 484static inline int 485__libdw_offset_in_section (Dwarf *dbg, int sec_index, 486 Dwarf_Off offset, size_t size) 487{ 488 Elf_Data *data = __libdw_checked_get_data (dbg, sec_index); 489 if (data == NULL) 490 return -1; 491 if (unlikely (offset > data->d_size) 492 || unlikely (data->d_size - offset < size)) 493 { 494 __libdw_seterrno (DWARF_E_INVALID_OFFSET); 495 return -1; 496 } 497 498 return 0; 499} 500 501static inline bool 502__libdw_in_section (Dwarf *dbg, int sec_index, 503 const void *addr, size_t size) 504{ 505 Elf_Data *data = __libdw_checked_get_data (dbg, sec_index); 506 if (data == NULL) 507 return false; 508 if (unlikely (addr < data->d_buf) 509 || unlikely (data->d_size - (addr - data->d_buf) < size)) 510 { 511 __libdw_seterrno (DWARF_E_INVALID_OFFSET); 512 return false; 513 } 514 515 return true; 516} 517 518#define READ_AND_RELOCATE(RELOC_HOOK, VAL) \ 519 ({ \ 520 if (!__libdw_in_section (dbg, sec_index, addr, width)) \ 521 return -1; \ 522 \ 523 const unsigned char *orig_addr = addr; \ 524 if (width == 4) \ 525 VAL = read_4ubyte_unaligned_inc (dbg, addr); \ 526 else \ 527 VAL = read_8ubyte_unaligned_inc (dbg, addr); \ 528 \ 529 int status = RELOC_HOOK (dbg, sec_index, orig_addr, width, &VAL); \ 530 if (status < 0) \ 531 return status; \ 532 status > 0; \ 533 }) 534 535static inline int 536__libdw_read_address_inc (Dwarf *dbg, 537 int sec_index, const unsigned char **addrp, 538 int width, Dwarf_Addr *ret) 539{ 540 const unsigned char *addr = *addrp; 541 READ_AND_RELOCATE (__libdw_relocate_address, (*ret)); 542 *addrp = addr; 543 return 0; 544} 545 546static inline int 547__libdw_read_address (Dwarf *dbg, 548 int sec_index, const unsigned char *addr, 549 int width, Dwarf_Addr *ret) 550{ 551 READ_AND_RELOCATE (__libdw_relocate_address, (*ret)); 552 return 0; 553} 554 555static inline int 556__libdw_read_offset_inc (Dwarf *dbg, 557 int sec_index, const unsigned char **addrp, 558 int width, Dwarf_Off *ret, int sec_ret, 559 size_t size) 560{ 561 const unsigned char *addr = *addrp; 562 READ_AND_RELOCATE (__libdw_relocate_offset, (*ret)); 563 *addrp = addr; 564 return __libdw_offset_in_section (dbg, sec_ret, *ret, size); 565} 566 567static inline int 568__libdw_read_offset (Dwarf *dbg, 569 int sec_index, const unsigned char *addr, 570 int width, Dwarf_Off *ret, int sec_ret, 571 size_t size) 572{ 573 READ_AND_RELOCATE (__libdw_relocate_offset, (*ret)); 574 return __libdw_offset_in_section (dbg, sec_ret, *ret, size); 575} 576 577/* Read up begin/end pair and increment read pointer. 578 - If it's normal range record, set up *BEGINP and *ENDP and return 0. 579 - If it's base address selection record, set up *BASEP and return 1. 580 - If it's end of rangelist, don't set anything and return 2 581 - If an error occurs, don't set anything and return <0. */ 582int __libdw_read_begin_end_pair_inc (Dwarf *dbg, int sec_index, 583 unsigned char **addr, int width, 584 Dwarf_Addr *beginp, Dwarf_Addr *endp, 585 Dwarf_Addr *basep) 586 internal_function; 587 588unsigned char * __libdw_formptr (Dwarf_Attribute *attr, int sec_index, 589 int err_nodata, unsigned char **endpp, 590 Dwarf_Off *offsetp) 591 internal_function; 592 593 594 595/* Aliases to avoid PLTs. */ 596INTDECL (dwarf_aggregate_size) 597INTDECL (dwarf_attr) 598INTDECL (dwarf_attr_integrate) 599INTDECL (dwarf_begin_elf) 600INTDECL (dwarf_child) 601INTDECL (dwarf_dieoffset) 602INTDECL (dwarf_diename) 603INTDECL (dwarf_end) 604INTDECL (dwarf_entrypc) 605INTDECL (dwarf_errmsg) 606INTDECL (dwarf_formaddr) 607INTDECL (dwarf_formblock) 608INTDECL (dwarf_formref_die) 609INTDECL (dwarf_formsdata) 610INTDECL (dwarf_formstring) 611INTDECL (dwarf_formudata) 612INTDECL (dwarf_getarange_addr) 613INTDECL (dwarf_getarangeinfo) 614INTDECL (dwarf_getaranges) 615INTDECL (dwarf_getsrcfiles) 616INTDECL (dwarf_getsrclines) 617INTDECL (dwarf_hasattr) 618INTDECL (dwarf_haschildren) 619INTDECL (dwarf_haspc) 620INTDECL (dwarf_highpc) 621INTDECL (dwarf_lowpc) 622INTDECL (dwarf_nextcu) 623INTDECL (dwarf_offdie) 624INTDECL (dwarf_ranges) 625INTDECL (dwarf_siblingof) 626INTDECL (dwarf_srclang) 627INTDECL (dwarf_tag) 628 629#endif /* libdwP.h */ 630