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