1 /* Internal definitions for libdwarf. 2 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Red Hat, Inc. 3 This file is part of Red Hat elfutils. 4 Written by Ulrich Drepper <drepper (at) redhat.com>, 2002. 5 6 Red Hat elfutils is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by the 8 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 DWARF specification we support. */ 65 #define DWARF_VERSION 3 66 67 /* Version of the CIE format. */ 68 #define CIE_VERSION 1 69 70 71 /* Known location expressions already decoded. */ 72 struct loc_s 73 { 74 void *addr; 75 Dwarf_Op *loc; 76 size_t nloc; 77 }; 78 79 /* Valid indeces for the section data. */ 80 enum 81 { 82 IDX_debug_info = 0, 83 IDX_debug_abbrev, 84 IDX_debug_aranges, 85 IDX_debug_line, 86 IDX_debug_frame, 87 IDX_eh_frame, 88 IDX_debug_loc, 89 IDX_debug_pubnames, 90 IDX_debug_str, 91 IDX_debug_funcnames, 92 IDX_debug_typenames, 93 IDX_debug_varnames, 94 IDX_debug_weaknames, 95 IDX_debug_macinfo, 96 IDX_debug_ranges, 97 IDX_last 98 }; 99 100 101 /* Error values. */ 102 enum 103 { 104 DWARF_E_NOERROR = 0, 105 DWARF_E_UNKNOWN_ERROR, 106 DWARF_E_INVALID_ACCESS, 107 DWARF_E_NO_REGFILE, 108 DWARF_E_IO_ERROR, 109 DWARF_E_INVALID_ELF, 110 DWARF_E_NO_DWARF, 111 DWARF_E_NOELF, 112 DWARF_E_GETEHDR_ERROR, 113 DWARF_E_NOMEM, 114 DWARF_E_UNIMPL, 115 DWARF_E_INVALID_CMD, 116 DWARF_E_INVALID_VERSION, 117 DWARF_E_INVALID_FILE, 118 DWARF_E_NO_ENTRY, 119 DWARF_E_INVALID_DWARF, 120 DWARF_E_NO_STRING, 121 DWARF_E_NO_ADDR, 122 DWARF_E_NO_CONSTANT, 123 DWARF_E_NO_REFERENCE, 124 DWARF_E_INVALID_REFERENCE, 125 DWARF_E_NO_DEBUG_LINE, 126 DWARF_E_INVALID_DEBUG_LINE, 127 DWARF_E_TOO_BIG, 128 DWARF_E_VERSION, 129 DWARF_E_INVALID_DIR_IDX, 130 DWARF_E_ADDR_OUTOFRANGE, 131 DWARF_E_NO_LOCLIST, 132 DWARF_E_NO_BLOCK, 133 DWARF_E_INVALID_LINE_IDX, 134 DWARF_E_INVALID_ARANGE_IDX, 135 DWARF_E_NO_MATCH, 136 DWARF_E_NO_FLAG, 137 DWARF_E_INVALID_OFFSET, 138 DWARF_E_NO_DEBUG_RANGES, 139 }; 140 141 142 /* This is the structure representing the debugging state. */ 143 struct Dwarf 144 { 145 /* The underlying ELF file. */ 146 Elf *elf; 147 148 /* The section data. */ 149 Elf_Data *sectiondata[IDX_last]; 150 151 /* True if the file has a byte order different from the host. */ 152 bool other_byte_order; 153 154 /* If true, we allocated the ELF descriptor ourselves. */ 155 bool free_elf; 156 157 /* Information for traversing the .debug_pubnames section. This is 158 an array and separately allocated with malloc. */ 159 struct pubnames_s 160 { 161 Dwarf_Off cu_offset; 162 Dwarf_Off set_start; 163 unsigned int cu_header_size; 164 int address_len; 165 } *pubnames_sets; 166 size_t pubnames_nsets; 167 168 /* Search tree for the CUs. */ 169 void *cu_tree; 170 Dwarf_Off next_cu_offset; 171 172 /* Address ranges. */ 173 Dwarf_Aranges *aranges; 174 175 /* Internal memory handling. This is basically a simplified 176 reimplementation of obstacks. Unfortunately the standard obstack 177 implementation is not usable in libraries. */ 178 struct libdw_memblock 179 { 180 size_t size; 181 size_t remaining; 182 struct libdw_memblock *prev; 183 char mem[0]; 184 } *mem_tail; 185 186 /* Default size of allocated memory blocks. */ 187 size_t mem_default_size; 188 189 /* Registered OOM handler. */ 190 Dwarf_OOM oom_handler; 191 }; 192 193 194 /* Abbreviation representation. */ 195 struct Dwarf_Abbrev 196 { 197 unsigned int code; 198 unsigned int tag; 199 int has_children; 200 unsigned int attrcnt; 201 unsigned char *attrp; 202 Dwarf_Off offset; 203 }; 204 205 #include "dwarf_abbrev_hash.h" 206 207 208 /* Files in line information records. */ 209 struct Dwarf_Files_s 210 { 211 Dwarf *dbg; 212 unsigned int ndirs; 213 unsigned int nfiles; 214 struct Dwarf_Fileinfo_s 215 { 216 char *name; 217 Dwarf_Word mtime; 218 Dwarf_Word length; 219 } info[0]; 220 /* nfiles of those, followed by char *[ndirs]. */ 221 }; 222 typedef struct Dwarf_Fileinfo_s Dwarf_Fileinfo; 223 224 225 /* Representation of a row in the line table. */ 226 struct Dwarf_Lines_s 227 { 228 size_t nlines; 229 230 struct Dwarf_Line_s 231 { 232 Dwarf_Addr addr; 233 unsigned int file; 234 int line; 235 unsigned short int column; 236 unsigned int is_stmt:1; 237 unsigned int basic_block:1; 238 unsigned int end_sequence:1; 239 unsigned int prologue_end:1; 240 unsigned int epilogue_begin:1; 241 242 Dwarf_Files *files; 243 } info[0]; 244 }; 245 246 247 /* Representation of address ranges. */ 248 struct Dwarf_Aranges_s 249 { 250 Dwarf *dbg; 251 size_t naranges; 252 253 struct Dwarf_Arange_s 254 { 255 Dwarf_Addr addr; 256 Dwarf_Word length; 257 Dwarf_Off offset; 258 } info[0]; 259 }; 260 261 262 /* CU representation. */ 263 struct Dwarf_CU 264 { 265 Dwarf *dbg; 266 Dwarf_Off start; 267 Dwarf_Off end; 268 uint8_t address_size; 269 uint8_t offset_size; 270 uint16_t version; 271 272 /* Hash table for the abbreviations. */ 273 Dwarf_Abbrev_Hash abbrev_hash; 274 /* Offset of the first abbreviation. */ 275 size_t orig_abbrev_offset; 276 /* Offset past last read abbreviation. */ 277 size_t last_abbrev_offset; 278 279 /* The srcline information. */ 280 Dwarf_Lines *lines; 281 282 /* The source file information. */ 283 Dwarf_Files *files; 284 285 /* Known location lists. */ 286 void *locs; 287 }; 288 289 /* Compute the offset of a CU's first DIE from its offset. This 290 is either: 291 LEN VER OFFSET ADDR 292 4-bytes + 2-bytes + 4-bytes + 1-byte for 32-bit dwarf 293 12-bytes + 2-bytes + 8-bytes + 1-byte for 64-bit dwarf 294 295 Note the trick in the computation. If the offset_size is 4 296 the '- 4' term changes the '3 *' into a '2 *'. If the 297 offset_size is 8 it accounts for the 4-byte escape value 298 used at the start of the length. */ 299 #define DIE_OFFSET_FROM_CU_OFFSET(cu_offset, offset_size) \ 300 ((cu_offset) + 3 * (offset_size) - 4 + 3) 301 302 #define CUDIE(fromcu) \ 303 ((Dwarf_Die) \ 304 { \ 305 .cu = (fromcu), \ 306 .addr = ((char *) (fromcu)->dbg->sectiondata[IDX_debug_info]->d_buf \ 307 + (fromcu)->start + 3 * (fromcu)->offset_size - 4 + 3), \ 308 }) 309 310 311 /* Macro information. */ 312 struct Dwarf_Macro_s 313 { 314 unsigned int opcode; 315 Dwarf_Word param1; 316 union 317 { 318 Dwarf_Word u; 319 const char *s; 320 } param2; 321 }; 322 323 324 /* We have to include the file at this point because the inline 325 functions access internals of the Dwarf structure. */ 326 #include "memory-access.h" 327 328 329 /* Set error value. */ 330 extern void __libdw_seterrno (int value) internal_function; 331 332 333 /* Memory handling, the easy parts. This macro does not do any locking. */ 334 #define libdw_alloc(dbg, type, tsize, cnt) \ 335 ({ struct libdw_memblock *_tail = (dbg)->mem_tail; \ 336 size_t _required = (tsize) * (cnt); \ 337 type *_result = (type *) (_tail->mem + (_tail->size - _tail->remaining));\ 338 size_t _padding = ((__alignof (type) \ 339 - ((uintptr_t) _result & (__alignof (type) - 1))) \ 340 & (__alignof (type) - 1)); \ 341 if (unlikely (_tail->remaining < _required + _padding)) \ 342 _result = (type *) __libdw_allocate (dbg, _required, __alignof (type));\ 343 else \ 344 { \ 345 _required += _padding; \ 346 _result = (type *) ((char *) _result + _padding); \ 347 _tail->remaining -= _required; \ 348 } \ 349 _result; }) 350 351 #define libdw_typed_alloc(dbg, type) \ 352 libdw_alloc (dbg, type, sizeof (type), 1) 353 354 /* Callback to allocate more. */ 355 extern void *__libdw_allocate (Dwarf *dbg, size_t minsize, size_t align) 356 __attribute__ ((__malloc__)) __nonnull_attribute__ (1); 357 358 /* Default OOM handler. */ 359 extern void __libdw_oom (void) __attribute ((noreturn, visibility ("hidden"))); 360 361 /* Find CU for given offset. */ 362 extern struct Dwarf_CU *__libdw_findcu (Dwarf *dbg, Dwarf_Off offset) 363 __nonnull_attribute__ (1) internal_function; 364 365 /* Return tag of given DIE. */ 366 extern Dwarf_Abbrev *__libdw_findabbrev (struct Dwarf_CU *cu, 367 unsigned int code) 368 __nonnull_attribute__ (1) internal_function; 369 370 /* Get abbreviation at given offset. */ 371 extern Dwarf_Abbrev *__libdw_getabbrev (Dwarf *dbg, struct Dwarf_CU *cu, 372 Dwarf_Off offset, size_t *lengthp, 373 Dwarf_Abbrev *result) 374 __nonnull_attribute__ (1) internal_function; 375 376 /* Helper functions for form handling. */ 377 extern size_t __libdw_form_val_len (Dwarf *dbg, struct Dwarf_CU *cu, 378 unsigned int form, 379 const unsigned char *valp) 380 __nonnull_attribute__ (1, 2, 4) internal_function; 381 382 /* Helper function for DW_FORM_ref* handling. */ 383 extern int __libdw_formref (Dwarf_Attribute *attr, Dwarf_Off *return_offset) 384 __nonnull_attribute__ (1, 2) internal_function; 385 386 387 /* Helper function to locate attribute. */ 388 extern unsigned char *__libdw_find_attr (Dwarf_Die *die, 389 unsigned int search_name, 390 unsigned int *codep, 391 unsigned int *formp) 392 __nonnull_attribute__ (1) internal_function; 393 394 /* Helper function to access integer attribute. */ 395 extern int __libdw_attr_intval (Dwarf_Die *die, int *valp, int attval) 396 __nonnull_attribute__ (1, 2) internal_function; 397 398 /* Helper function to walk scopes. */ 399 struct Dwarf_Die_Chain 400 { 401 Dwarf_Die die; 402 struct Dwarf_Die_Chain *parent; 403 bool prune; /* The PREVISIT function can set this. */ 404 }; 405 extern int __libdw_visit_scopes (unsigned int depth, 406 struct Dwarf_Die_Chain *root, 407 int (*previsit) (unsigned int depth, 408 struct Dwarf_Die_Chain *, 409 void *arg), 410 int (*postvisit) (unsigned int depth, 411 struct Dwarf_Die_Chain *, 412 void *arg), 413 void *arg) 414 __nonnull_attribute__ (2, 3) internal_function; 415 416 /* Return error code of last failing function call. This value is kept 417 separately for each thread. */ 418 extern int __dwarf_errno_internal (void); 419 420 421 /* Aliases to avoid PLTs. */ 422 INTDECL (dwarf_attr) 423 INTDECL (dwarf_attr_integrate) 424 INTDECL (dwarf_begin_elf) 425 INTDECL (dwarf_child) 426 INTDECL (dwarf_dieoffset) 427 INTDECL (dwarf_diename) 428 INTDECL (dwarf_end) 429 INTDECL (dwarf_entrypc) 430 INTDECL (dwarf_errmsg) 431 INTDECL (dwarf_formaddr) 432 INTDECL (dwarf_formblock) 433 INTDECL (dwarf_formref_die) 434 INTDECL (dwarf_formsdata) 435 INTDECL (dwarf_formstring) 436 INTDECL (dwarf_formudata) 437 INTDECL (dwarf_getarange_addr) 438 INTDECL (dwarf_getarangeinfo) 439 INTDECL (dwarf_getaranges) 440 INTDECL (dwarf_getsrcfiles) 441 INTDECL (dwarf_getsrclines) 442 INTDECL (dwarf_hasattr) 443 INTDECL (dwarf_haschildren) 444 INTDECL (dwarf_haspc) 445 INTDECL (dwarf_highpc) 446 INTDECL (dwarf_lowpc) 447 INTDECL (dwarf_nextcu) 448 INTDECL (dwarf_offdie) 449 INTDECL (dwarf_ranges) 450 INTDECL (dwarf_siblingof) 451 INTDECL (dwarf_tag) 452 453 #endif /* libdwP.h */ 454