1 /* Internal definitions for libdwarf.
2 Copyright (C) 2002-2011 Red Hat, Inc.
3 This file is part of elfutils.
4 Written by Ulrich Drepper <drepper@redhat.com>, 2002.
6 This file is free software; you can redistribute it and/or modify
7 it under the terms of either
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
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
19 or both in parallel, as here.
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.
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/>. */
39 /* gettext helper macros. */
40 #define _(Str) dgettext ("elfutils", Str)
43 /* Known location expressions already decoded. */
51 /* Known DW_OP_implicit_value blocks already decoded.
52 This overlaps struct loc_s exactly, but only the
53 first member really has to match. */
61 /* Valid indeces for the section data. */
84 DWARF_E_UNKNOWN_ERROR,
85 DWARF_E_INVALID_ACCESS,
91 DWARF_E_GETEHDR_ERROR,
95 DWARF_E_INVALID_VERSION,
98 DWARF_E_INVALID_DWARF,
102 DWARF_E_NO_REFERENCE,
103 DWARF_E_INVALID_REFERENCE,
104 DWARF_E_NO_DEBUG_LINE,
105 DWARF_E_INVALID_DEBUG_LINE,
108 DWARF_E_INVALID_DIR_IDX,
109 DWARF_E_ADDR_OUTOFRANGE,
112 DWARF_E_INVALID_LINE_IDX,
113 DWARF_E_INVALID_ARANGE_IDX,
116 DWARF_E_INVALID_OFFSET,
117 DWARF_E_NO_DEBUG_RANGES,
119 DWARF_E_NO_ALT_DEBUGLINK
123 #include "dwarf_sig8_hash.h"
125 /* This is the structure representing the debugging state. */
128 /* The underlying ELF file. */
131 /* dwz alternate DWARF file. */
134 /* The section data. */
135 Elf_Data *sectiondata[IDX_last];
138 /* The 1 << N bit is set if sectiondata[N] is malloc'd decompressed data. */
139 unsigned int sectiondata_gzip_mask:IDX_last;
142 /* True if the file has a byte order different from the host. */
143 bool other_byte_order;
145 /* If true, we allocated the ELF descriptor ourselves. */
148 /* If true, we allocated the Dwarf descriptor for alt_dwarf ourselves. */
151 /* Information for traversing the .debug_pubnames section. This is
152 an array and separately allocated with malloc. */
157 unsigned int cu_header_size;
160 size_t pubnames_nsets;
162 /* Search tree for the CUs. */
164 Dwarf_Off next_cu_offset;
166 /* Search tree and sig8 hash table for .debug_types type units. */
168 Dwarf_Off next_tu_offset;
169 Dwarf_Sig8_Hash sig8_hash;
171 /* Address ranges. */
172 Dwarf_Aranges *aranges;
174 /* Cached info from the CFI section. */
175 struct Dwarf_CFI_s *cfi;
177 /* Internal memory handling. This is basically a simplified
178 reimplementation of obstacks. Unfortunately the standard obstack
179 implementation is not usable in libraries. */
180 struct libdw_memblock
184 struct libdw_memblock *prev;
188 /* Default size of allocated memory blocks. */
189 size_t mem_default_size;
191 /* Registered OOM handler. */
192 Dwarf_OOM oom_handler;
196 /* Abbreviation representation. */
200 unsigned char *attrp;
201 unsigned int attrcnt;
207 #include "dwarf_abbrev_hash.h"
210 /* Files in line information records. */
216 struct Dwarf_Fileinfo_s
222 /* nfiles of those, followed by char *[ndirs]. */
224 typedef struct Dwarf_Fileinfo_s Dwarf_Fileinfo;
227 /* Representation of a row in the line table. */
236 unsigned short int column;
237 unsigned int is_stmt:1;
238 unsigned int basic_block:1;
239 unsigned int end_sequence:1;
240 unsigned int prologue_end:1;
241 unsigned int epilogue_begin:1;
242 /* The remaining bit fields are not flags, but hold values presumed to be
243 small. All the flags and other bit fields should add up to 48 bits
244 to give the whole struct a nice round size. */
245 unsigned int op_index:8;
247 unsigned int discriminator:24;
253 struct Dwarf_Line_s info[0];
256 /* Representation of address ranges. */
257 struct Dwarf_Aranges_s
262 struct Dwarf_Arange_s
271 /* CU representation. */
277 uint8_t address_size;
281 /* Zero if this is a normal CU. Nonzero if it is a type unit. */
285 /* Hash table for the abbreviations. */
286 Dwarf_Abbrev_Hash abbrev_hash;
287 /* Offset of the first abbreviation. */
288 size_t orig_abbrev_offset;
289 /* Offset past last read abbreviation. */
290 size_t last_abbrev_offset;
292 /* The srcline information. */
295 /* The source file information. */
298 /* Known location lists. */
302 /* Compute the offset of a CU's first DIE from its offset. This
305 4-bytes + 2-bytes + 4-bytes + 1-byte for 32-bit dwarf
306 12-bytes + 2-bytes + 8-bytes + 1-byte for 64-bit dwarf
307 or in .debug_types, SIGNATURE TYPE-OFFSET
308 4-bytes + 2-bytes + 4-bytes + 1-byte + 8-bytes + 4-bytes for 32-bit
309 12-bytes + 2-bytes + 8-bytes + 1-byte + 8-bytes + 8-bytes for 64-bit
311 Note the trick in the computation. If the offset_size is 4
312 the '- 4' term changes the '3 *' into a '2 *'. If the
313 offset_size is 8 it accounts for the 4-byte escape value
314 used at the start of the length. */
315 #define DIE_OFFSET_FROM_CU_OFFSET(cu_offset, offset_size, type_unit) \
316 ((type_unit) ? ((cu_offset) + 4 * (offset_size) - 4 + 3 + 8) \
317 : ((cu_offset) + 3 * (offset_size) - 4 + 3))
319 #define CUDIE(fromcu) \
323 .addr = ((char *) cu_data (fromcu)->d_buf \
324 + DIE_OFFSET_FROM_CU_OFFSET ((fromcu)->start, \
325 (fromcu)->offset_size, \
326 (fromcu)->type_offset != 0)) \
330 /* Macro information. */
343 /* We have to include the file at this point because the inline
344 functions access internals of the Dwarf structure. */
345 #include "memory-access.h"
348 /* Set error value. */
349 extern void __libdw_seterrno (int value) internal_function;
352 /* Memory handling, the easy parts. This macro does not do any locking. */
353 #define libdw_alloc(dbg, type, tsize, cnt) \
354 ({ struct libdw_memblock *_tail = (dbg)->mem_tail; \
355 size_t _required = (tsize) * (cnt); \
356 type *_result = (type *) (_tail->mem + (_tail->size - _tail->remaining));\
357 size_t _padding = ((__alignof (type) \
358 - ((uintptr_t) _result & (__alignof (type) - 1))) \
359 & (__alignof (type) - 1)); \
360 if (unlikely (_tail->remaining < _required + _padding)) \
361 _result = (type *) __libdw_allocate (dbg, _required, __alignof (type));\
364 _required += _padding; \
365 _result = (type *) ((char *) _result + _padding); \
366 _tail->remaining -= _required; \
370 #define libdw_typed_alloc(dbg, type) \
371 libdw_alloc (dbg, type, sizeof (type), 1)
373 /* Callback to allocate more. */
374 extern void *__libdw_allocate (Dwarf *dbg, size_t minsize, size_t align)
375 __attribute__ ((__malloc__)) __nonnull_attribute__ (1);
377 /* Default OOM handler. */
378 extern void __libdw_oom (void) __attribute ((noreturn, visibility ("hidden")));
381 extern void __libdw_free_zdata (Dwarf *dwarf) internal_function;
383 # define __libdw_free_zdata(dwarf) ((void) (dwarf))
386 /* Allocate the internal data for a unit not seen before. */
387 extern struct Dwarf_CU *__libdw_intern_next_unit (Dwarf *dbg, bool debug_types)
388 __nonnull_attribute__ (1) internal_function;
390 /* Find CU for given offset. */
391 extern struct Dwarf_CU *__libdw_findcu (Dwarf *dbg, Dwarf_Off offset, bool tu)
392 __nonnull_attribute__ (1) internal_function;
394 /* Return tag of given DIE. */
395 extern Dwarf_Abbrev *__libdw_findabbrev (struct Dwarf_CU *cu,
397 __nonnull_attribute__ (1) internal_function;
399 /* Get abbreviation at given offset. */
400 extern Dwarf_Abbrev *__libdw_getabbrev (Dwarf *dbg, struct Dwarf_CU *cu,
401 Dwarf_Off offset, size_t *lengthp,
402 Dwarf_Abbrev *result)
403 __nonnull_attribute__ (1) internal_function;
405 /* Helper functions for form handling. */
406 extern size_t __libdw_form_val_len (Dwarf *dbg, struct Dwarf_CU *cu,
408 const unsigned char *valp)
409 __nonnull_attribute__ (1, 2, 4) internal_function;
411 /* Helper function for DW_FORM_ref* handling. */
412 extern int __libdw_formref (Dwarf_Attribute *attr, Dwarf_Off *return_offset)
413 __nonnull_attribute__ (1, 2) internal_function;
416 /* Helper function to locate attribute. */
417 extern unsigned char *__libdw_find_attr (Dwarf_Die *die,
418 unsigned int search_name,
421 __nonnull_attribute__ (1) internal_function;
423 /* Helper function to access integer attribute. */
424 extern int __libdw_attr_intval (Dwarf_Die *die, int *valp, int attval)
425 __nonnull_attribute__ (1, 2) internal_function;
427 /* Helper function to walk scopes. */
428 struct Dwarf_Die_Chain
431 struct Dwarf_Die_Chain *parent;
432 bool prune; /* The PREVISIT function can set this. */
434 extern int __libdw_visit_scopes (unsigned int depth,
435 struct Dwarf_Die_Chain *root,
436 int (*previsit) (unsigned int depth,
437 struct Dwarf_Die_Chain *,
439 int (*postvisit) (unsigned int depth,
440 struct Dwarf_Die_Chain *,
443 __nonnull_attribute__ (2, 3) internal_function;
445 /* Parse a DWARF Dwarf_Block into an array of Dwarf_Op's,
446 and cache the result (via tsearch). */
447 extern int __libdw_intern_expression (Dwarf *dbg,
448 bool other_byte_order,
449 unsigned int address_size,
450 unsigned int ref_size,
451 void **cache, const Dwarf_Block *block,
452 bool cfap, bool valuep,
453 Dwarf_Op **llbuf, size_t *listlen,
455 __nonnull_attribute__ (5, 6, 9, 10) internal_function;
457 extern Dwarf_Die *__libdw_offdie (Dwarf *dbg, Dwarf_Off offset,
458 Dwarf_Die *result, bool debug_types)
462 /* Return error code of last failing function call. This value is kept
463 separately for each thread. */
464 extern int __dwarf_errno_internal (void);
469 /* Relocation hooks return -1 on error (in that case the error code
470 must already have been set), 0 if there is no relocation and 1 if a
471 relocation was present.*/
474 __libdw_relocate_address (Dwarf *dbg __attribute__ ((unused)),
475 int sec_index __attribute__ ((unused)),
476 const void *addr __attribute__ ((unused)),
477 int width __attribute__ ((unused)),
478 Dwarf_Addr *val __attribute__ ((unused)))
484 __libdw_relocate_offset (Dwarf *dbg __attribute__ ((unused)),
485 int sec_index __attribute__ ((unused)),
486 const void *addr __attribute__ ((unused)),
487 int width __attribute__ ((unused)),
488 Dwarf_Off *val __attribute__ ((unused)))
493 static inline Elf_Data *
494 __libdw_checked_get_data (Dwarf *dbg, int sec_index)
496 Elf_Data *data = dbg->sectiondata[sec_index];
497 if (unlikely (data == NULL)
498 || unlikely (data->d_buf == NULL))
500 __libdw_seterrno (DWARF_E_INVALID_DWARF);
507 __libdw_offset_in_section (Dwarf *dbg, int sec_index,
508 Dwarf_Off offset, size_t size)
510 Elf_Data *data = __libdw_checked_get_data (dbg, sec_index);
513 if (unlikely (offset > data->d_size)
514 || unlikely (data->d_size - offset < size))
516 __libdw_seterrno (DWARF_E_INVALID_OFFSET);
524 __libdw_in_section (Dwarf *dbg, int sec_index,
525 const void *addr, size_t size)
527 Elf_Data *data = __libdw_checked_get_data (dbg, sec_index);
530 if (unlikely (addr < data->d_buf)
531 || unlikely (data->d_size - (addr - data->d_buf) < size))
533 __libdw_seterrno (DWARF_E_INVALID_OFFSET);
540 #define READ_AND_RELOCATE(RELOC_HOOK, VAL) \
542 if (!__libdw_in_section (dbg, sec_index, addr, width)) \
545 const unsigned char *orig_addr = addr; \
547 VAL = read_4ubyte_unaligned_inc (dbg, addr); \
549 VAL = read_8ubyte_unaligned_inc (dbg, addr); \
551 int status = RELOC_HOOK (dbg, sec_index, orig_addr, width, &VAL); \
558 __libdw_read_address_inc (Dwarf *dbg,
559 int sec_index, const unsigned char **addrp,
560 int width, Dwarf_Addr *ret)
562 const unsigned char *addr = *addrp;
563 READ_AND_RELOCATE (__libdw_relocate_address, (*ret));
569 __libdw_read_address (Dwarf *dbg,
570 int sec_index, const unsigned char *addr,
571 int width, Dwarf_Addr *ret)
573 READ_AND_RELOCATE (__libdw_relocate_address, (*ret));
578 __libdw_read_offset_inc (Dwarf *dbg,
579 int sec_index, const unsigned char **addrp,
580 int width, Dwarf_Off *ret, int sec_ret,
583 const unsigned char *addr = *addrp;
584 READ_AND_RELOCATE (__libdw_relocate_offset, (*ret));
586 return __libdw_offset_in_section (dbg, sec_ret, *ret, size);
590 __libdw_read_offset (Dwarf *dbg, Dwarf *dbg_ret,
591 int sec_index, const unsigned char *addr,
592 int width, Dwarf_Off *ret, int sec_ret,
595 READ_AND_RELOCATE (__libdw_relocate_offset, (*ret));
596 return __libdw_offset_in_section (dbg_ret, sec_ret, *ret, size);
600 cu_sec_idx (struct Dwarf_CU *cu)
602 return cu->type_offset == 0 ? IDX_debug_info : IDX_debug_types;
605 static inline Elf_Data *
606 cu_data (struct Dwarf_CU *cu)
608 return cu->dbg->sectiondata[cu_sec_idx (cu)];
611 /* Read up begin/end pair and increment read pointer.
612 - If it's normal range record, set up *BEGINP and *ENDP and return 0.
613 - If it's base address selection record, set up *BASEP and return 1.
614 - If it's end of rangelist, don't set anything and return 2
615 - If an error occurs, don't set anything and return <0. */
616 int __libdw_read_begin_end_pair_inc (Dwarf *dbg, int sec_index,
617 unsigned char **addr, int width,
618 Dwarf_Addr *beginp, Dwarf_Addr *endp,
622 unsigned char * __libdw_formptr (Dwarf_Attribute *attr, int sec_index,
623 int err_nodata, unsigned char **endpp,
628 /* Checks that the build_id of the underlying Elf matches the expected.
629 Returns zero on match, -1 on error or no build_id found or 1 when
630 build_id doesn't match. */
631 int __check_build_id (Dwarf *dw, const uint8_t *build_id, const size_t id_len)
633 #endif /* ENABLE_DWZ */
636 /* Aliases to avoid PLTs. */
637 INTDECL (dwarf_aggregate_size)
639 INTDECL (dwarf_attr_integrate)
640 INTDECL (dwarf_begin)
641 INTDECL (dwarf_begin_elf)
642 INTDECL (dwarf_child)
643 INTDECL (dwarf_dieoffset)
644 INTDECL (dwarf_diename)
646 INTDECL (dwarf_entrypc)
647 INTDECL (dwarf_errmsg)
648 INTDECL (dwarf_formaddr)
649 INTDECL (dwarf_formblock)
650 INTDECL (dwarf_formref_die)
651 INTDECL (dwarf_formsdata)
652 INTDECL (dwarf_formstring)
653 INTDECL (dwarf_formudata)
654 INTDECL (dwarf_getarange_addr)
655 INTDECL (dwarf_getarangeinfo)
656 INTDECL (dwarf_getaranges)
657 INTDECL (dwarf_getsrcfiles)
658 INTDECL (dwarf_getsrclines)
659 INTDECL (dwarf_hasattr)
660 INTDECL (dwarf_haschildren)
661 INTDECL (dwarf_haspc)
662 INTDECL (dwarf_highpc)
663 INTDECL (dwarf_lowpc)
664 INTDECL (dwarf_nextcu)
665 INTDECL (dwarf_next_unit)
666 INTDECL (dwarf_offdie)
667 INTDECL (dwarf_ranges)
668 INTDECL (dwarf_siblingof)
669 INTDECL (dwarf_srclang)
672 #endif /* libdwP.h */