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