1 /* Internal definitions for libdw.
2 Copyright (C) 2002-2011, 2013-2018 Red Hat, Inc.
3 This file is part of elfutils.
4
5 This file is free software; you can redistribute it and/or modify
6 it under the terms of either
7
8 * the GNU Lesser General Public License as published by the Free
9 Software Foundation; either version 3 of the License, or (at
10 your option) any later version
11
12 or
13
14 * the GNU General Public License as published by the Free
15 Software Foundation; either version 2 of the License, or (at
16 your option) any later version
17
18 or both in parallel, as here.
19
20 elfutils is distributed in the hope that it will be useful, but
21 WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 General Public License for more details.
24
25 You should have received copies of the GNU General Public License and
26 the GNU Lesser General Public License along with this program. If
27 not, see <http://www.gnu.org/licenses/>. */
28
29 #ifndef _LIBDWP_H
30 #define _LIBDWP_H 1
31
32 #include <libintl.h>
33 #include <stdbool.h>
34
35 #include <libdw.h>
36 #include <dwarf.h>
37
38
39 /* gettext helper macros. */
40 #define _(Str) dgettext ("elfutils", Str)
41
42
43 /* Known location expressions already decoded. */
44 struct loc_s
45 {
46 void *addr;
47 Dwarf_Op *loc;
48 size_t nloc;
49 };
50
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. */
54 struct loc_block_s
55 {
56 void *addr;
57 unsigned char *data;
58 size_t length;
59 };
60
61 /* Already decoded .debug_line units. */
62 struct files_lines_s
63 {
64 Dwarf_Off debug_line_offset;
65 Dwarf_Files *files;
66 Dwarf_Lines *lines;
67 };
68
69 /* Valid indeces for the section data. */
70 enum
71 {
72 IDX_debug_info = 0,
73 IDX_debug_types,
74 IDX_debug_abbrev,
75 IDX_debug_aranges,
76 IDX_debug_addr,
77 IDX_debug_line,
78 IDX_debug_line_str,
79 IDX_debug_frame,
80 IDX_debug_loc,
81 IDX_debug_loclists,
82 IDX_debug_pubnames,
83 IDX_debug_str,
84 IDX_debug_str_offsets,
85 IDX_debug_macinfo,
86 IDX_debug_macro,
87 IDX_debug_ranges,
88 IDX_debug_rnglists,
89 IDX_gnu_debugaltlink,
90 IDX_last
91 };
92
93
94 /* Error values. */
95 enum
96 {
97 DWARF_E_NOERROR = 0,
98 DWARF_E_UNKNOWN_ERROR,
99 DWARF_E_INVALID_ACCESS,
100 DWARF_E_NO_REGFILE,
101 DWARF_E_IO_ERROR,
102 DWARF_E_INVALID_ELF,
103 DWARF_E_NO_DWARF,
104 DWARF_E_COMPRESSED_ERROR,
105 DWARF_E_NOELF,
106 DWARF_E_GETEHDR_ERROR,
107 DWARF_E_NOMEM,
108 DWARF_E_UNIMPL,
109 DWARF_E_INVALID_CMD,
110 DWARF_E_INVALID_VERSION,
111 DWARF_E_INVALID_FILE,
112 DWARF_E_NO_ENTRY,
113 DWARF_E_INVALID_DWARF,
114 DWARF_E_NO_STRING,
115 DWARF_E_NO_DEBUG_STR,
116 DWARF_E_NO_DEBUG_LINE_STR,
117 DWARF_E_NO_STR_OFFSETS,
118 DWARF_E_NO_ADDR,
119 DWARF_E_NO_CONSTANT,
120 DWARF_E_NO_REFERENCE,
121 DWARF_E_INVALID_REFERENCE,
122 DWARF_E_NO_DEBUG_LINE,
123 DWARF_E_INVALID_DEBUG_LINE,
124 DWARF_E_TOO_BIG,
125 DWARF_E_VERSION,
126 DWARF_E_INVALID_DIR_IDX,
127 DWARF_E_ADDR_OUTOFRANGE,
128 DWARF_E_NO_DEBUG_LOC,
129 DWARF_E_NO_DEBUG_LOCLISTS,
130 DWARF_E_NO_LOC_VALUE,
131 DWARF_E_NO_BLOCK,
132 DWARF_E_INVALID_LINE_IDX,
133 DWARF_E_INVALID_ARANGE_IDX,
134 DWARF_E_NO_MATCH,
135 DWARF_E_NO_FLAG,
136 DWARF_E_INVALID_OFFSET,
137 DWARF_E_NO_DEBUG_RANGES,
138 DWARF_E_NO_DEBUG_RNGLISTS,
139 DWARF_E_INVALID_CFI,
140 DWARF_E_NO_ALT_DEBUGLINK,
141 DWARF_E_INVALID_OPCODE,
142 DWARF_E_NOT_CUDIE,
143 DWARF_E_UNKNOWN_LANGUAGE,
144 DWARF_E_NO_DEBUG_ADDR,
145 };
146
147
148 #include "dwarf_sig8_hash.h"
149
150 /* This is the structure representing the debugging state. */
151 struct Dwarf
152 {
153 /* The underlying ELF file. */
154 Elf *elf;
155
156 /* The (absolute) path to the ELF dir, if known. To help locating
157 alt and dwo files. */
158 char *debugdir;
159
160 /* dwz alternate DWARF file. */
161 Dwarf *alt_dwarf;
162
163 /* The section data. */
164 Elf_Data *sectiondata[IDX_last];
165
166 /* True if the file has a byte order different from the host. */
167 bool other_byte_order;
168
169 /* If true, we allocated the ELF descriptor ourselves. */
170 bool free_elf;
171
172 /* If >= 0, we allocated the alt_dwarf ourselves and must end it and
173 close this file descriptor. */
174 int alt_fd;
175
176 /* Information for traversing the .debug_pubnames section. This is
177 an array and separately allocated with malloc. */
178 struct pubnames_s
179 {
180 Dwarf_Off cu_offset;
181 Dwarf_Off set_start;
182 unsigned int cu_header_size;
183 int address_len;
184 } *pubnames_sets;
185 size_t pubnames_nsets;
186
187 /* Search tree for the CUs. */
188 void *cu_tree;
189 Dwarf_Off next_cu_offset;
190
191 /* Search tree and sig8 hash table for .debug_types type units. */
192 void *tu_tree;
193 Dwarf_Off next_tu_offset;
194 Dwarf_Sig8_Hash sig8_hash;
195
196 /* Search tree for split Dwarf associated with CUs in this debug. */
197 void *split_tree;
198
199 /* Search tree for .debug_macro operator tables. */
200 void *macro_ops;
201
202 /* Search tree for decoded .debug_line units. */
203 void *files_lines;
204
205 /* Address ranges. */
206 Dwarf_Aranges *aranges;
207
208 /* Cached info from the CFI section. */
209 struct Dwarf_CFI_s *cfi;
210
211 /* Fake loc CU. Used when synthesizing attributes for Dwarf_Ops that
212 came from a location list entry in dwarf_getlocation_attr.
213 Depending on version this is the .debug_loc or .debug_loclists
214 section (could be both if mixing CUs with different DWARF versions). */
215 struct Dwarf_CU *fake_loc_cu;
216 struct Dwarf_CU *fake_loclists_cu;
217
218 /* Similar for addrx/constx, which will come from .debug_addr section. */
219 struct Dwarf_CU *fake_addr_cu;
220
221 /* Internal memory handling. This is basically a simplified
222 reimplementation of obstacks. Unfortunately the standard obstack
223 implementation is not usable in libraries. */
224 struct libdw_memblock
225 {
226 size_t size;
227 size_t remaining;
228 struct libdw_memblock *prev;
229 char mem[0];
230 } *mem_tail;
231
232 /* Default size of allocated memory blocks. */
233 size_t mem_default_size;
234
235 /* Registered OOM handler. */
236 Dwarf_OOM oom_handler;
237 };
238
239
240 /* Abbreviation representation. */
241 struct Dwarf_Abbrev
242 {
243 Dwarf_Off offset; /* Offset to start of abbrev into .debug_abbrev. */
244 unsigned char *attrp; /* Pointer to start of attribute name/form pairs. */
245 bool has_children : 1; /* Whether or not the DIE has children. */
246 unsigned int code : 31; /* The (unique) abbrev code. */
247 unsigned int tag; /* The tag of the DIE. */
248 } attribute_packed;
249
250 #include "dwarf_abbrev_hash.h"
251
252
253 /* Files in line information records. */
254 struct Dwarf_Files_s
255 {
256 unsigned int ndirs;
257 unsigned int nfiles;
258 struct Dwarf_Fileinfo_s
259 {
260 char *name;
261 Dwarf_Word mtime;
262 Dwarf_Word length;
263 } info[0];
264 /* nfiles of those, followed by char *[ndirs]. */
265 };
266 typedef struct Dwarf_Fileinfo_s Dwarf_Fileinfo;
267
268
269 /* Representation of a row in the line table. */
270
271 struct Dwarf_Line_s
272 {
273 Dwarf_Files *files;
274
275 Dwarf_Addr addr;
276 unsigned int file;
277 int line;
278 unsigned short int column;
279 unsigned int is_stmt:1;
280 unsigned int basic_block:1;
281 unsigned int end_sequence:1;
282 unsigned int prologue_end:1;
283 unsigned int epilogue_begin:1;
284 /* The remaining bit fields are not flags, but hold values presumed to be
285 small. All the flags and other bit fields should add up to 48 bits
286 to give the whole struct a nice round size. */
287 unsigned int op_index:8;
288 unsigned int isa:8;
289 unsigned int discriminator:24;
290 };
291
292 struct Dwarf_Lines_s
293 {
294 size_t nlines;
295 struct Dwarf_Line_s info[0];
296 };
297
298 /* Representation of address ranges. */
299 struct Dwarf_Aranges_s
300 {
301 Dwarf *dbg;
302 size_t naranges;
303
304 struct Dwarf_Arange_s
305 {
306 Dwarf_Addr addr;
307 Dwarf_Word length;
308 Dwarf_Off offset;
309 } info[0];
310 };
311
312
313 /* CU representation. */
314 struct Dwarf_CU
315 {
316 Dwarf *dbg;
317 Dwarf_Off start;
318 Dwarf_Off end;
319 uint8_t address_size;
320 uint8_t offset_size;
321 uint16_t version;
322
323 size_t sec_idx; /* Normally .debug_info, could be .debug_type or "fake". */
324
325 /* The unit type if version >= 5. Otherwise 0 for normal CUs (from
326 .debug_info) or 1 for v4 type units (from .debug_types). */
327 uint8_t unit_type;
328
329 /* Zero if the unit type doesn't support a die/type offset and/or id/sig.
330 Nonzero if it is a v4 type unit or for DWARFv5 units depending on
331 unit_type. */
332 size_t subdie_offset;
333 uint64_t unit_id8;
334
335 /* If this is a skeleton unit this points to the split compile unit.
336 Or the other way around if this is a split compile unit. Set to -1
337 if not yet searched. Always use __libdw_find_split_unit to access
338 this field. */
339 struct Dwarf_CU *split;
340
341 /* Hash table for the abbreviations. */
342 Dwarf_Abbrev_Hash abbrev_hash;
343 /* Offset of the first abbreviation. */
344 size_t orig_abbrev_offset;
345 /* Offset past last read abbreviation. */
346 size_t last_abbrev_offset;
347
348 /* The srcline information. */
349 Dwarf_Lines *lines;
350
351 /* The source file information. */
352 Dwarf_Files *files;
353
354 /* Known location lists. */
355 void *locs;
356
357 /* Base address for use with ranges and locs.
358 Don't access directly, call __libdw_cu_base_address. */
359 Dwarf_Addr base_address;
360
361 /* The offset into the .debug_addr section where index zero begins.
362 Don't access directly, call __libdw_cu_addr_base. */
363 Dwarf_Off addr_base;
364
365 /* The offset into the .debug_str_offsets section where index zero begins.
366 Don't access directly, call __libdw_cu_str_off_base. */
367 Dwarf_Off str_off_base;
368
369 /* The offset into the .debug_ranges section to use for GNU
370 DebugFission split units. Don't access directly, call
371 __libdw_cu_ranges_base. */
372 Dwarf_Off ranges_base;
373
374 /* The start of the offset table in .debug_loclists.
375 Don't access directly, call __libdw_cu_locs_base. */
376 Dwarf_Off locs_base;
377
378 /* Memory boundaries of this CU. */
379 void *startp;
380 void *endp;
381 };
382
383 #define ISV4TU(cu) ((cu)->version == 4 && (cu)->sec_idx == IDX_debug_types)
384
385 /* Compute the offset of a CU's first DIE from the CU offset.
386 CU must be a valid/known version/unit_type. */
387 static inline Dwarf_Off
__libdw_first_die_from_cu_start(Dwarf_Off cu_start,uint8_t offset_size,uint16_t version,uint8_t unit_type)388 __libdw_first_die_from_cu_start (Dwarf_Off cu_start,
389 uint8_t offset_size,
390 uint16_t version,
391 uint8_t unit_type)
392 {
393 /*
394 assert (offset_size == 4 || offset_size == 8);
395 assert (version >= 2 && version <= 5);
396 assert (unit_type == DW_UT_compile
397 || unit_type == DW_UT_partial
398 || unit_type == DW_UT_skeleton
399 || unit_type == DW_UT_split_compile
400 || unit_type == DW_UT_type
401 || unit_type == DW_UT_split_type);
402 */
403
404 Dwarf_Off off = cu_start;
405 if (version < 5)
406 {
407 /*
408 LEN VER OFFSET ADDR
409 4-bytes + 2-bytes + 4-bytes + 1-byte for 32-bit dwarf
410 12-bytes + 2-bytes + 8-bytes + 1-byte for 64-bit dwarf
411 or in .debug_types, SIGNATURE TYPE-OFFSET
412 4-bytes + 2-bytes + 4-bytes + 1-byte + 8-bytes + 4-bytes for 32-bit
413 12-bytes + 2-bytes + 8-bytes + 1-byte + 8-bytes + 8-bytes for 64-bit
414
415 Note the trick in the computation. If the offset_size is 4
416 the '- 4' term changes the '3 *' (or '4 *') into a '2 *' (or '3 *).
417 If the offset_size is 8 it accounts for the 4-byte escape value
418 used at the start of the length. */
419 if (unit_type != DW_UT_type)
420 off += 3 * offset_size - 4 + 3;
421 else
422 off += 4 * offset_size - 4 + 3 + 8;
423 }
424 else
425 {
426 /*
427 LEN VER TYPE ADDR OFFSET SIGNATURE TYPE-OFFSET
428 4-bytes + 2-bytes + 1-byte + 1-byte + 4-bytes + 8-bytes + 4-bytes 32-bit
429 12-bytes + 2-bytes + 1-byte + 1-byte + 8-bytes + 8-bytes + 8-bytes 64-bit
430 Both signature and type offset are optional.
431
432 Note same 4/8 offset size trick as above.
433 We explicitly ignore unknow unit types (see asserts above). */
434 off += 3 * offset_size - 4 + 4;
435 if (unit_type == DW_UT_skeleton || unit_type == DW_UT_split_compile
436 || unit_type == DW_UT_type || unit_type == DW_UT_split_type)
437 {
438 off += 8;
439 if (unit_type == DW_UT_type || unit_type == DW_UT_split_type)
440 off += offset_size;
441 }
442 }
443
444 return off;
445 }
446
447 static inline Dwarf_Off
__libdw_first_die_off_from_cu(struct Dwarf_CU * cu)448 __libdw_first_die_off_from_cu (struct Dwarf_CU *cu)
449 {
450 return __libdw_first_die_from_cu_start (cu->start,
451 cu->offset_size,
452 cu->version,
453 cu->unit_type);
454 }
455
456 #define CUDIE(fromcu) \
457 ((Dwarf_Die) \
458 { \
459 .cu = (fromcu), \
460 .addr = ((char *) (fromcu)->dbg->sectiondata[cu_sec_idx (fromcu)]->d_buf \
461 + __libdw_first_die_off_from_cu (fromcu)) \
462 })
463
464 #define SUBDIE(fromcu) \
465 ((Dwarf_Die) \
466 { \
467 .cu = (fromcu), \
468 .addr = ((char *) (fromcu)->dbg->sectiondata[cu_sec_idx (fromcu)]->d_buf \
469 + (fromcu)->start + (fromcu)->subdie_offset) \
470 })
471
472
473 /* Prototype of a single .debug_macro operator. */
474 typedef struct
475 {
476 Dwarf_Word nforms;
477 unsigned char const *forms;
478 } Dwarf_Macro_Op_Proto;
479
480 /* Prototype table. */
481 typedef struct
482 {
483 /* Offset of .debug_macro section. */
484 Dwarf_Off offset;
485
486 /* Offset of associated .debug_line section. */
487 Dwarf_Off line_offset;
488
489 /* The source file information. */
490 Dwarf_Files *files;
491
492 /* If this macro unit was opened through dwarf_getmacros or
493 dwarf_getmacros_die, this caches value of DW_AT_comp_dir, if
494 present. */
495 const char *comp_dir;
496
497 /* Header length. */
498 Dwarf_Half header_len;
499
500 uint16_t version;
501 bool is_64bit;
502 uint8_t sec_index; /* IDX_debug_macro or IDX_debug_macinfo. */
503
504 /* Shows where in TABLE each opcode is defined. Since opcode 0 is
505 never used, it stores index of opcode X in X-1'th element. The
506 value of 0xff means not stored at all. */
507 unsigned char opcodes[255];
508
509 /* Individual opcode prototypes. */
510 Dwarf_Macro_Op_Proto table[];
511 } Dwarf_Macro_Op_Table;
512
513 struct Dwarf_Macro_s
514 {
515 Dwarf_Macro_Op_Table *table;
516 Dwarf_Attribute *attributes;
517 uint8_t opcode;
518 };
519
520 static inline Dwarf_Word
libdw_macro_nforms(Dwarf_Macro * macro)521 libdw_macro_nforms (Dwarf_Macro *macro)
522 {
523 return macro->table->table[macro->table->opcodes[macro->opcode - 1]].nforms;
524 }
525
526 /* Returns true for any allowed FORM in the opcode_operands_table as
527 mentioned in the DWARF5 spec (6.3.1 Macro Information Header).
528 Or those mentioned in DWARF5 spec (6.2.4.2 Vendor-defined Content
529 Descriptions) for the directory/file table (plus DW_FORM_strp_sup). */
530 static inline bool
libdw_valid_user_form(int form)531 libdw_valid_user_form (int form)
532 {
533 switch (form)
534 {
535 case DW_FORM_block:
536 case DW_FORM_block1:
537 case DW_FORM_block2:
538 case DW_FORM_block4:
539 case DW_FORM_data1:
540 case DW_FORM_data2:
541 case DW_FORM_data4:
542 case DW_FORM_data8:
543 case DW_FORM_data16:
544 case DW_FORM_flag:
545 case DW_FORM_line_strp:
546 case DW_FORM_sdata:
547 case DW_FORM_sec_offset:
548 case DW_FORM_string:
549 case DW_FORM_strp:
550 case DW_FORM_strp_sup:
551 case DW_FORM_strx:
552 case DW_FORM_strx1:
553 case DW_FORM_strx2:
554 case DW_FORM_strx3:
555 case DW_FORM_strx4:
556 case DW_FORM_udata:
557 return true;
558 default:
559 return false;
560 }
561 }
562
563
564 /* We have to include the file at this point because the inline
565 functions access internals of the Dwarf structure. */
566 #include "memory-access.h"
567
568
569 /* Set error value. */
570 extern void __libdw_seterrno (int value) internal_function;
571
572
573 /* Memory handling, the easy parts. This macro does not do any locking. */
574 #define libdw_alloc(dbg, type, tsize, cnt) \
575 ({ struct libdw_memblock *_tail = (dbg)->mem_tail; \
576 size_t _required = (tsize) * (cnt); \
577 type *_result = (type *) (_tail->mem + (_tail->size - _tail->remaining));\
578 size_t _padding = ((__alignof (type) \
579 - ((uintptr_t) _result & (__alignof (type) - 1))) \
580 & (__alignof (type) - 1)); \
581 if (unlikely (_tail->remaining < _required + _padding)) \
582 _result = (type *) __libdw_allocate (dbg, _required, __alignof (type));\
583 else \
584 { \
585 _required += _padding; \
586 _result = (type *) ((char *) _result + _padding); \
587 _tail->remaining -= _required; \
588 } \
589 _result; })
590
591 #define libdw_typed_alloc(dbg, type) \
592 libdw_alloc (dbg, type, sizeof (type), 1)
593
594 /* Callback to allocate more. */
595 extern void *__libdw_allocate (Dwarf *dbg, size_t minsize, size_t align)
596 __attribute__ ((__malloc__)) __nonnull_attribute__ (1);
597
598 /* Default OOM handler. */
599 extern void __libdw_oom (void) __attribute ((noreturn)) attribute_hidden;
600
601 /* Read next unit (or v4 debug type) and return next offset. Doesn't
602 create an actual Dwarf_CU just provides necessary header fields. */
603 extern int
604 internal_function
605 __libdw_next_unit (Dwarf *dbg, bool v4_debug_types, Dwarf_Off off,
606 Dwarf_Off *next_off, size_t *header_sizep,
607 Dwarf_Half *versionp, uint8_t *unit_typep,
608 Dwarf_Off *abbrev_offsetp, uint8_t *address_sizep,
609 uint8_t *offset_sizep, uint64_t *unit_id8p,
610 Dwarf_Off *subdie_offsetp)
611 __nonnull_attribute__ (4) internal_function;
612
613 /* Allocate the internal data for a unit not seen before. */
614 extern struct Dwarf_CU *__libdw_intern_next_unit (Dwarf *dbg, bool debug_types)
615 __nonnull_attribute__ (1) internal_function;
616
617 /* Find CU for given offset. */
618 extern struct Dwarf_CU *__libdw_findcu (Dwarf *dbg, Dwarf_Off offset, bool tu)
619 __nonnull_attribute__ (1) internal_function;
620
621 /* Find CU for given DIE address. */
622 extern struct Dwarf_CU *__libdw_findcu_addr (Dwarf *dbg, void *addr)
623 __nonnull_attribute__ (1) internal_function;
624
625 /* Find split Dwarf for given DIE address. */
626 extern struct Dwarf *__libdw_find_split_dbg_addr (Dwarf *dbg, void *addr)
627 __nonnull_attribute__ (1) internal_function;
628
629 /* Find the split (or skeleton) unit. */
630 extern struct Dwarf_CU *__libdw_find_split_unit (Dwarf_CU *cu)
631 internal_function;
632
633 /* Get abbreviation with given code. */
634 extern Dwarf_Abbrev *__libdw_findabbrev (struct Dwarf_CU *cu,
635 unsigned int code)
636 __nonnull_attribute__ (1) internal_function;
637
638 /* Get abbreviation at given offset. */
639 extern Dwarf_Abbrev *__libdw_getabbrev (Dwarf *dbg, struct Dwarf_CU *cu,
640 Dwarf_Off offset, size_t *lengthp,
641 Dwarf_Abbrev *result)
642 __nonnull_attribute__ (1) internal_function;
643
644 /* Get abbreviation of given DIE, and optionally set *READP to the DIE memory
645 just past the abbreviation code. */
646 static inline Dwarf_Abbrev *
647 __nonnull_attribute__ (1)
__libdw_dieabbrev(Dwarf_Die * die,const unsigned char ** readp)648 __libdw_dieabbrev (Dwarf_Die *die, const unsigned char **readp)
649 {
650 /* Do we need to get the abbreviation, or need to read after the code? */
651 if (die->abbrev == NULL || readp != NULL)
652 {
653 /* Get the abbreviation code. */
654 unsigned int code;
655 const unsigned char *addr = die->addr;
656 if (unlikely (die->cu == NULL
657 || addr >= (const unsigned char *) die->cu->endp))
658 return die->abbrev = DWARF_END_ABBREV;
659 get_uleb128 (code, addr, die->cu->endp);
660 if (readp != NULL)
661 *readp = addr;
662
663 /* Find the abbreviation. */
664 if (die->abbrev == NULL)
665 die->abbrev = __libdw_findabbrev (die->cu, code);
666 }
667 return die->abbrev;
668 }
669
670 /* Helper functions for form handling. */
671 extern size_t __libdw_form_val_compute_len (struct Dwarf_CU *cu,
672 unsigned int form,
673 const unsigned char *valp)
674 __nonnull_attribute__ (1, 3) internal_function;
675
676 /* Find the length of a form attribute in DIE/info data. */
677 static inline size_t
678 __nonnull_attribute__ (1, 3)
__libdw_form_val_len(struct Dwarf_CU * cu,unsigned int form,const unsigned char * valp)679 __libdw_form_val_len (struct Dwarf_CU *cu, unsigned int form,
680 const unsigned char *valp)
681 {
682 /* Small lookup table of forms with fixed lengths. Absent indexes are
683 initialized 0, so any truly desired 0 is set to 0x80 and masked. */
684 static const uint8_t form_lengths[] =
685 {
686 [DW_FORM_flag_present] = 0x80,
687 [DW_FORM_implicit_const] = 0x80, /* Value is in abbrev, not in info. */
688
689 [DW_FORM_flag] = 1,
690 [DW_FORM_data1] = 1, [DW_FORM_ref1] = 1,
691 [DW_FORM_addrx1] = 1, [DW_FORM_strx1] = 1,
692
693 [DW_FORM_data2] = 2, [DW_FORM_ref2] = 2,
694 [DW_FORM_addrx2] = 2, [DW_FORM_strx2] = 2,
695
696 [DW_FORM_addrx3] = 3, [DW_FORM_strx3] = 3,
697
698 [DW_FORM_data4] = 4, [DW_FORM_ref4] = 4, [DW_FORM_ref_sup4] = 4,
699 [DW_FORM_addrx4] = 4, [DW_FORM_strx4] = 4,
700
701 [DW_FORM_ref_sig8] = 8,
702 [DW_FORM_data8] = 8, [DW_FORM_ref8] = 8, [DW_FORM_ref_sup8] = 8,
703
704 [DW_FORM_data16] = 16,
705 };
706
707 /* Return immediately for forms with fixed lengths. */
708 if (form < sizeof form_lengths / sizeof form_lengths[0])
709 {
710 uint8_t len = form_lengths[form];
711 if (len != 0)
712 {
713 const unsigned char *endp = cu->endp;
714 len &= 0x7f; /* Mask to allow 0x80 -> 0. */
715 if (unlikely (len > (size_t) (endp - valp)))
716 {
717 __libdw_seterrno (DWARF_E_INVALID_DWARF);
718 return -1;
719 }
720 return len;
721 }
722 }
723
724 /* Other forms require some computation. */
725 return __libdw_form_val_compute_len (cu, form, valp);
726 }
727
728 /* Helper function for DW_FORM_ref* handling. */
729 extern int __libdw_formref (Dwarf_Attribute *attr, Dwarf_Off *return_offset)
730 __nonnull_attribute__ (1, 2) internal_function;
731
732
733 /* Helper function to locate attribute. */
734 extern unsigned char *__libdw_find_attr (Dwarf_Die *die,
735 unsigned int search_name,
736 unsigned int *codep,
737 unsigned int *formp)
738 __nonnull_attribute__ (1) internal_function;
739
740 /* Helper function to access integer attribute. */
741 extern int __libdw_attr_intval (Dwarf_Die *die, int *valp, int attval)
742 __nonnull_attribute__ (1, 2) internal_function;
743
744 /* Helper function to walk scopes. */
745 struct Dwarf_Die_Chain
746 {
747 Dwarf_Die die;
748 struct Dwarf_Die_Chain *parent;
749 bool prune; /* The PREVISIT function can set this. */
750 };
751 extern int __libdw_visit_scopes (unsigned int depth,
752 struct Dwarf_Die_Chain *root,
753 struct Dwarf_Die_Chain *imports,
754 int (*previsit) (unsigned int depth,
755 struct Dwarf_Die_Chain *,
756 void *arg),
757 int (*postvisit) (unsigned int depth,
758 struct Dwarf_Die_Chain *,
759 void *arg),
760 void *arg)
761 __nonnull_attribute__ (2, 4) internal_function;
762
763 /* Parse a DWARF Dwarf_Block into an array of Dwarf_Op's,
764 and cache the result (via tsearch). */
765 extern int __libdw_intern_expression (Dwarf *dbg,
766 bool other_byte_order,
767 unsigned int address_size,
768 unsigned int ref_size,
769 void **cache, const Dwarf_Block *block,
770 bool cfap, bool valuep,
771 Dwarf_Op **llbuf, size_t *listlen,
772 int sec_index)
773 __nonnull_attribute__ (5, 6, 9, 10) internal_function;
774
775 extern Dwarf_Die *__libdw_offdie (Dwarf *dbg, Dwarf_Off offset,
776 Dwarf_Die *result, bool debug_types)
777 internal_function;
778
779
780 /* Return error code of last failing function call. This value is kept
781 separately for each thread. */
782 extern int __dwarf_errno_internal (void);
783
784
785 /* Reader hooks. */
786
787 /* Relocation hooks return -1 on error (in that case the error code
788 must already have been set), 0 if there is no relocation and 1 if a
789 relocation was present.*/
790
791 static inline int
__libdw_relocate_address(Dwarf * dbg,int sec_index,const void * addr,int width,Dwarf_Addr * val)792 __libdw_relocate_address (Dwarf *dbg __attribute__ ((unused)),
793 int sec_index __attribute__ ((unused)),
794 const void *addr __attribute__ ((unused)),
795 int width __attribute__ ((unused)),
796 Dwarf_Addr *val __attribute__ ((unused)))
797 {
798 return 0;
799 }
800
801 static inline int
__libdw_relocate_offset(Dwarf * dbg,int sec_index,const void * addr,int width,Dwarf_Off * val)802 __libdw_relocate_offset (Dwarf *dbg __attribute__ ((unused)),
803 int sec_index __attribute__ ((unused)),
804 const void *addr __attribute__ ((unused)),
805 int width __attribute__ ((unused)),
806 Dwarf_Off *val __attribute__ ((unused)))
807 {
808 return 0;
809 }
810
811 static inline Elf_Data *
__libdw_checked_get_data(Dwarf * dbg,int sec_index)812 __libdw_checked_get_data (Dwarf *dbg, int sec_index)
813 {
814 Elf_Data *data = dbg->sectiondata[sec_index];
815 if (unlikely (data == NULL)
816 || unlikely (data->d_buf == NULL))
817 {
818 __libdw_seterrno (DWARF_E_INVALID_DWARF);
819 return NULL;
820 }
821 return data;
822 }
823
824 static inline int
__libdw_offset_in_section(Dwarf * dbg,int sec_index,Dwarf_Off offset,size_t size)825 __libdw_offset_in_section (Dwarf *dbg, int sec_index,
826 Dwarf_Off offset, size_t size)
827 {
828 Elf_Data *data = __libdw_checked_get_data (dbg, sec_index);
829 if (data == NULL)
830 return -1;
831 if (unlikely (offset > data->d_size)
832 || unlikely (data->d_size < size)
833 || unlikely (offset > data->d_size - size))
834 {
835 __libdw_seterrno (DWARF_E_INVALID_OFFSET);
836 return -1;
837 }
838
839 return 0;
840 }
841
842 static inline bool
__libdw_in_section(Dwarf * dbg,int sec_index,const void * addr,size_t size)843 __libdw_in_section (Dwarf *dbg, int sec_index,
844 const void *addr, size_t size)
845 {
846 Elf_Data *data = __libdw_checked_get_data (dbg, sec_index);
847 if (data == NULL)
848 return false;
849 if (unlikely (addr < data->d_buf)
850 || unlikely (data->d_size < size)
851 || unlikely ((size_t)(addr - data->d_buf) > data->d_size - size))
852 {
853 __libdw_seterrno (DWARF_E_INVALID_OFFSET);
854 return false;
855 }
856
857 return true;
858 }
859
860 #define READ_AND_RELOCATE(RELOC_HOOK, VAL) \
861 ({ \
862 if (!__libdw_in_section (dbg, sec_index, addr, width)) \
863 return -1; \
864 \
865 const unsigned char *orig_addr = addr; \
866 if (width == 4) \
867 VAL = read_4ubyte_unaligned_inc (dbg, addr); \
868 else \
869 VAL = read_8ubyte_unaligned_inc (dbg, addr); \
870 \
871 int status = RELOC_HOOK (dbg, sec_index, orig_addr, width, &VAL); \
872 if (status < 0) \
873 return status; \
874 status > 0; \
875 })
876
877 static inline int
__libdw_read_address_inc(Dwarf * dbg,int sec_index,const unsigned char ** addrp,int width,Dwarf_Addr * ret)878 __libdw_read_address_inc (Dwarf *dbg,
879 int sec_index, const unsigned char **addrp,
880 int width, Dwarf_Addr *ret)
881 {
882 const unsigned char *addr = *addrp;
883 READ_AND_RELOCATE (__libdw_relocate_address, (*ret));
884 *addrp = addr;
885 return 0;
886 }
887
888 static inline int
__libdw_read_address(Dwarf * dbg,int sec_index,const unsigned char * addr,int width,Dwarf_Addr * ret)889 __libdw_read_address (Dwarf *dbg,
890 int sec_index, const unsigned char *addr,
891 int width, Dwarf_Addr *ret)
892 {
893 READ_AND_RELOCATE (__libdw_relocate_address, (*ret));
894 return 0;
895 }
896
897 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)898 __libdw_read_offset_inc (Dwarf *dbg,
899 int sec_index, const unsigned char **addrp,
900 int width, Dwarf_Off *ret, int sec_ret,
901 size_t size)
902 {
903 const unsigned char *addr = *addrp;
904 READ_AND_RELOCATE (__libdw_relocate_offset, (*ret));
905 *addrp = addr;
906 return __libdw_offset_in_section (dbg, sec_ret, *ret, size);
907 }
908
909 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)910 __libdw_read_offset (Dwarf *dbg, Dwarf *dbg_ret,
911 int sec_index, const unsigned char *addr,
912 int width, Dwarf_Off *ret, int sec_ret,
913 size_t size)
914 {
915 READ_AND_RELOCATE (__libdw_relocate_offset, (*ret));
916 return __libdw_offset_in_section (dbg_ret, sec_ret, *ret, size);
917 }
918
919 static inline size_t
cu_sec_idx(struct Dwarf_CU * cu)920 cu_sec_idx (struct Dwarf_CU *cu)
921 {
922 return cu->sec_idx;
923 }
924
925 static inline bool
is_cudie(Dwarf_Die * cudie)926 is_cudie (Dwarf_Die *cudie)
927 {
928 return cudie->cu != NULL && CUDIE (cudie->cu).addr == cudie->addr;
929 }
930
931 /* Read up begin/end pair and increment read pointer.
932 - If it's normal range record, set up *BEGINP and *ENDP and return 0.
933 - If it's base address selection record, set up *BASEP and return 1.
934 - If it's end of rangelist, don't set anything and return 2
935 - If an error occurs, don't set anything and return <0. */
936 int __libdw_read_begin_end_pair_inc (Dwarf_CU *cu, int sec_index,
937 const unsigned char **readp,
938 const unsigned char *readend,
939 int width,
940 Dwarf_Addr *beginp, Dwarf_Addr *endp,
941 Dwarf_Addr *basep)
942 internal_function;
943
944 const unsigned char * __libdw_formptr (Dwarf_Attribute *attr, int sec_index,
945 int err_nodata,
946 const unsigned char **endpp,
947 Dwarf_Off *offsetp)
948 internal_function;
949
950 /* Fills in the given attribute to point at an empty location expression. */
951 void __libdw_empty_loc_attr (Dwarf_Attribute *attr)
952 internal_function;
953
954 /* Load .debug_line unit at DEBUG_LINE_OFFSET. COMP_DIR is a value of
955 DW_AT_comp_dir or NULL if that attribute is not available. Caches
956 the loaded unit and optionally set *LINESP and/or *FILESP (if not
957 NULL) with loaded information. Returns 0 for success or a negative
958 value for failure. */
959 int __libdw_getsrclines (Dwarf *dbg, Dwarf_Off debug_line_offset,
960 const char *comp_dir, unsigned address_size,
961 Dwarf_Lines **linesp, Dwarf_Files **filesp)
962 internal_function
963 __nonnull_attribute__ (1);
964
965 /* Load and return value of DW_AT_comp_dir from CUDIE. */
966 const char *__libdw_getcompdir (Dwarf_Die *cudie);
967
968 /* Get the base address for the CU, fetches it when not yet set.
969 This is used as initial base address for ranges and loclists. */
970 Dwarf_Addr __libdw_cu_base_address (Dwarf_CU *cu);
971
972 /* Get the address base for the CU, fetches it when not yet set. */
973 static inline Dwarf_Off
__libdw_cu_addr_base(Dwarf_CU * cu)974 __libdw_cu_addr_base (Dwarf_CU *cu)
975 {
976 if (cu->addr_base == (Dwarf_Off) -1)
977 {
978 Dwarf_Die cu_die = CUDIE(cu);
979 Dwarf_Attribute attr;
980 Dwarf_Off offset = 0;
981 if (dwarf_attr (&cu_die, DW_AT_GNU_addr_base, &attr) != NULL
982 || dwarf_attr (&cu_die, DW_AT_addr_base, &attr) != NULL)
983 {
984 Dwarf_Word off;
985 if (dwarf_formudata (&attr, &off) == 0)
986 offset = off;
987 }
988 cu->addr_base = offset;
989 }
990
991 return cu->addr_base;
992 }
993
994 /* Gets the .debug_str_offsets base offset to use. static inline to
995 be shared between libdw and eu-readelf. */
996 static inline Dwarf_Off
str_offsets_base_off(Dwarf * dbg,Dwarf_CU * cu)997 str_offsets_base_off (Dwarf *dbg, Dwarf_CU *cu)
998 {
999 /* If we don't have a CU, then find and use the first one in the
1000 debug file (when we support .dwp files, we must actually find the
1001 one matching our "caller" - aka macro or line). If we (now) have
1002 a cu and str_offsets_base attribute, just use that. Otherwise
1003 use the first offset. But we might have to parse the header
1004 first, but only if this is version 5. Assume if all else fails,
1005 this is version 4, without header. */
1006
1007 if (cu == NULL && dbg != NULL)
1008 {
1009 Dwarf_CU *first_cu;
1010 if (dwarf_get_units (dbg, NULL, &first_cu,
1011 NULL, NULL, NULL, NULL) == 0)
1012 cu = first_cu;
1013 }
1014
1015 if (cu != NULL)
1016 {
1017 if (cu->str_off_base == (Dwarf_Off) -1)
1018 {
1019 Dwarf_Die cu_die = CUDIE(cu);
1020 Dwarf_Attribute attr;
1021 if (dwarf_attr (&cu_die, DW_AT_str_offsets_base, &attr) != NULL)
1022 {
1023 Dwarf_Word off;
1024 if (dwarf_formudata (&attr, &off) == 0)
1025 {
1026 cu->str_off_base = off;
1027 return cu->str_off_base;
1028 }
1029 }
1030 /* For older DWARF simply assume zero (no header). */
1031 if (cu->version < 5)
1032 {
1033 cu->str_off_base = 0;
1034 return cu->str_off_base;
1035 }
1036
1037 if (dbg == NULL)
1038 dbg = cu->dbg;
1039 }
1040 else
1041 return cu->str_off_base;
1042 }
1043
1044 /* No str_offsets_base attribute, we have to assume "zero".
1045 But there could be a header first. */
1046 Dwarf_Off off = 0;
1047 if (dbg == NULL)
1048 goto no_header;
1049
1050 Elf_Data *data = dbg->sectiondata[IDX_debug_str_offsets];
1051 if (data == NULL)
1052 goto no_header;
1053
1054 const unsigned char *start;
1055 const unsigned char *readp;
1056 const unsigned char *readendp;
1057 start = readp = (const unsigned char *) data->d_buf;
1058 readendp = (const unsigned char *) data->d_buf + data->d_size;
1059
1060 uint64_t unit_length;
1061 uint16_t version;
1062
1063 unit_length = read_4ubyte_unaligned_inc (dbg, readp);
1064 if (unlikely (unit_length == 0xffffffff))
1065 {
1066 if (unlikely (readendp - readp < 8))
1067 goto no_header;
1068 unit_length = read_8ubyte_unaligned_inc (dbg, readp);
1069 /* In theory the offset size could be different
1070 between CU and str_offsets unit. But we just
1071 ignore that here. */
1072 }
1073
1074 /* We need at least 2-bytes (version) + 2-bytes (padding) =
1075 4 bytes to complete the header. And this unit cannot go
1076 beyond the section data. */
1077 if (readendp - readp < 4
1078 || unit_length < 4
1079 || (uint64_t) (readendp - readp) < unit_length)
1080 goto no_header;
1081
1082 version = read_2ubyte_unaligned_inc (dbg, readp);
1083 if (version != 5)
1084 goto no_header;
1085 /* padding */
1086 read_2ubyte_unaligned_inc (dbg, readp);
1087
1088 off = (Dwarf_Off) (readp - start);
1089
1090 no_header:
1091 if (cu != NULL)
1092 cu->str_off_base = off;
1093
1094 return off;
1095 }
1096
1097
1098 /* Get the string offsets base for the CU, fetches it when not yet set. */
__libdw_cu_str_off_base(Dwarf_CU * cu)1099 static inline Dwarf_Off __libdw_cu_str_off_base (Dwarf_CU *cu)
1100 {
1101 return str_offsets_base_off (NULL, cu);
1102 }
1103
1104
1105 /* Either a direct offset into .debug_ranges for version < 5, or the
1106 start of the offset table in .debug_rnglists for version > 5. */
1107 static inline Dwarf_Off
__libdw_cu_ranges_base(Dwarf_CU * cu)1108 __libdw_cu_ranges_base (Dwarf_CU *cu)
1109 {
1110 if (cu->ranges_base == (Dwarf_Off) -1)
1111 {
1112 Dwarf_Off offset = 0;
1113 Dwarf_Die cu_die = CUDIE(cu);
1114 Dwarf_Attribute attr;
1115 if (cu->version < 5)
1116 {
1117 if (dwarf_attr (&cu_die, DW_AT_GNU_ranges_base, &attr) != NULL)
1118 {
1119 Dwarf_Word off;
1120 if (dwarf_formudata (&attr, &off) == 0)
1121 offset = off;
1122 }
1123 }
1124 else
1125 {
1126 if (dwarf_attr (&cu_die, DW_AT_rnglists_base, &attr) != NULL)
1127 {
1128 Dwarf_Word off;
1129 if (dwarf_formudata (&attr, &off) == 0)
1130 offset = off;
1131 }
1132
1133 /* There wasn't an rnglists_base, if the Dwarf does have a
1134 .debug_rnglists section, then it might be we need the
1135 base after the first header. */
1136 Elf_Data *data = cu->dbg->sectiondata[IDX_debug_rnglists];
1137 if (offset == 0 && data != NULL)
1138 {
1139 Dwarf *dbg = cu->dbg;
1140 const unsigned char *readp = data->d_buf;
1141 const unsigned char *const dataend
1142 = (unsigned char *) data->d_buf + data->d_size;
1143
1144 uint64_t unit_length = read_4ubyte_unaligned_inc (dbg, readp);
1145 unsigned int offset_size = 4;
1146 if (unlikely (unit_length == 0xffffffff))
1147 {
1148 if (unlikely (readp > dataend - 8))
1149 goto no_header;
1150
1151 unit_length = read_8ubyte_unaligned_inc (dbg, readp);
1152 offset_size = 8;
1153 }
1154
1155 if (readp > dataend - 8
1156 || unit_length < 8
1157 || unit_length > (uint64_t) (dataend - readp))
1158 goto no_header;
1159
1160 uint16_t version = read_2ubyte_unaligned_inc (dbg, readp);
1161 if (version != 5)
1162 goto no_header;
1163
1164 uint8_t address_size = *readp++;
1165 if (address_size != 4 && address_size != 8)
1166 goto no_header;
1167
1168 uint8_t segment_size = *readp++;
1169 if (segment_size != 0)
1170 goto no_header;
1171
1172 uint32_t offset_entry_count;
1173 offset_entry_count = read_4ubyte_unaligned_inc (dbg, readp);
1174
1175 const unsigned char *offset_array_start = readp;
1176 if (offset_entry_count <= 0)
1177 goto no_header;
1178
1179 uint64_t needed = offset_entry_count * offset_size;
1180 if (unit_length - 8 < needed)
1181 goto no_header;
1182
1183 offset = (Dwarf_Off) (offset_array_start
1184 - (unsigned char *) data->d_buf);
1185 }
1186 }
1187 no_header:
1188 cu->ranges_base = offset;
1189 }
1190
1191 return cu->ranges_base;
1192 }
1193
1194
1195 /* The start of the offset table in .debug_loclists for DWARF5. */
1196 static inline Dwarf_Off
__libdw_cu_locs_base(Dwarf_CU * cu)1197 __libdw_cu_locs_base (Dwarf_CU *cu)
1198 {
1199 if (cu->locs_base == (Dwarf_Off) -1)
1200 {
1201 Dwarf_Off offset = 0;
1202 Dwarf_Die cu_die = CUDIE(cu);
1203 Dwarf_Attribute attr;
1204 if (dwarf_attr (&cu_die, DW_AT_loclists_base, &attr) != NULL)
1205 {
1206 Dwarf_Word off;
1207 if (dwarf_formudata (&attr, &off) == 0)
1208 offset = off;
1209 }
1210
1211 /* There wasn't an loclists_base, if the Dwarf does have a
1212 .debug_loclists section, then it might be we need the
1213 base after the first header. */
1214 Elf_Data *data = cu->dbg->sectiondata[IDX_debug_loclists];
1215 if (offset == 0 && data != NULL)
1216 {
1217 Dwarf *dbg = cu->dbg;
1218 const unsigned char *readp = data->d_buf;
1219 const unsigned char *const dataend
1220 = (unsigned char *) data->d_buf + data->d_size;
1221
1222 uint64_t unit_length = read_4ubyte_unaligned_inc (dbg, readp);
1223 unsigned int offset_size = 4;
1224 if (unlikely (unit_length == 0xffffffff))
1225 {
1226 if (unlikely (readp > dataend - 8))
1227 goto no_header;
1228
1229 unit_length = read_8ubyte_unaligned_inc (dbg, readp);
1230 offset_size = 8;
1231 }
1232
1233 if (readp > dataend - 8
1234 || unit_length < 8
1235 || unit_length > (uint64_t) (dataend - readp))
1236 goto no_header;
1237
1238 uint16_t version = read_2ubyte_unaligned_inc (dbg, readp);
1239 if (version != 5)
1240 goto no_header;
1241
1242 uint8_t address_size = *readp++;
1243 if (address_size != 4 && address_size != 8)
1244 goto no_header;
1245
1246 uint8_t segment_size = *readp++;
1247 if (segment_size != 0)
1248 goto no_header;
1249
1250 uint32_t offset_entry_count;
1251 offset_entry_count = read_4ubyte_unaligned_inc (dbg, readp);
1252
1253 const unsigned char *offset_array_start = readp;
1254 if (offset_entry_count <= 0)
1255 goto no_header;
1256
1257 uint64_t needed = offset_entry_count * offset_size;
1258 if (unit_length - 8 < needed)
1259 goto no_header;
1260
1261 offset = (Dwarf_Off) (offset_array_start
1262 - (unsigned char *) data->d_buf);
1263 }
1264
1265 no_header:
1266 cu->locs_base = offset;
1267 }
1268
1269 return cu->locs_base;
1270 }
1271
1272 /* Helper function for tsearch/tfind split_tree Dwarf. */
1273 int __libdw_finddbg_cb (const void *arg1, const void *arg2);
1274
1275 /* Link skeleton and split compile units. */
1276 static inline void
__libdw_link_skel_split(Dwarf_CU * skel,Dwarf_CU * split)1277 __libdw_link_skel_split (Dwarf_CU *skel, Dwarf_CU *split)
1278 {
1279 skel->split = split;
1280 split->split = skel;
1281
1282 /* Get .debug_addr and addr_base greedy.
1283 We also need it for the fake addr cu.
1284 There is only one per split debug. */
1285 Dwarf *dbg = skel->dbg;
1286 Dwarf *sdbg = split->dbg;
1287 if (sdbg->sectiondata[IDX_debug_addr] == NULL
1288 && dbg->sectiondata[IDX_debug_addr] != NULL)
1289 {
1290 sdbg->sectiondata[IDX_debug_addr]
1291 = dbg->sectiondata[IDX_debug_addr];
1292 split->addr_base = __libdw_cu_addr_base (skel);
1293 sdbg->fake_addr_cu = dbg->fake_addr_cu;
1294 }
1295 }
1296
1297
1298 /* Given an address index for a CU return the address.
1299 Returns -1 and sets libdw_errno if an error occurs. */
1300 int __libdw_addrx (Dwarf_CU *cu, Dwarf_Word idx, Dwarf_Addr *addr);
1301
1302
1303 /* Helper function to set debugdir field in Dwarf, used from dwarf_begin_elf
1304 and libdwfl process_file. */
1305 char * __libdw_debugdir (int fd);
1306
1307
1308 /* Given the directory of a debug file, an absolute or relative dir
1309 to look in, and file returns a full path.
1310
1311 If the file is absolute (starts with a /) a copy of file is returned.
1312 the file isn't absolute, but dir is absolute, then a path that is
1313 the concatenation of dir and file is returned. If neither file,
1314 nor dir is absolute, the path will be constructed using dir (if not
1315 NULL) and file relative to the debugdir (if valid).
1316
1317 The debugdir and the dir may be NULL (in which case they aren't used).
1318 If file is NULL, or no full path can be constructed NULL is returned.
1319
1320 The caller is responsible for freeing the result if not NULL. */
1321 char * __libdw_filepath (const char *debugdir, const char *dir,
1322 const char *file)
1323 internal_function;
1324
1325
1326 /* Aliases to avoid PLTs. */
1327 INTDECL (dwarf_aggregate_size)
1328 INTDECL (dwarf_attr)
1329 INTDECL (dwarf_attr_integrate)
1330 INTDECL (dwarf_begin)
1331 INTDECL (dwarf_begin_elf)
1332 INTDECL (dwarf_child)
1333 INTDECL (dwarf_default_lower_bound)
1334 INTDECL (dwarf_dieoffset)
1335 INTDECL (dwarf_diename)
1336 INTDECL (dwarf_end)
1337 INTDECL (dwarf_entrypc)
1338 INTDECL (dwarf_errmsg)
1339 INTDECL (dwarf_formaddr)
1340 INTDECL (dwarf_formblock)
1341 INTDECL (dwarf_formref_die)
1342 INTDECL (dwarf_formsdata)
1343 INTDECL (dwarf_formstring)
1344 INTDECL (dwarf_formudata)
1345 INTDECL (dwarf_getabbrevattr_data)
1346 INTDECL (dwarf_getalt)
1347 INTDECL (dwarf_getarange_addr)
1348 INTDECL (dwarf_getarangeinfo)
1349 INTDECL (dwarf_getaranges)
1350 INTDECL (dwarf_getlocation_die)
1351 INTDECL (dwarf_getsrcfiles)
1352 INTDECL (dwarf_getsrclines)
1353 INTDECL (dwarf_hasattr)
1354 INTDECL (dwarf_haschildren)
1355 INTDECL (dwarf_haspc)
1356 INTDECL (dwarf_highpc)
1357 INTDECL (dwarf_lowpc)
1358 INTDECL (dwarf_nextcu)
1359 INTDECL (dwarf_next_unit)
1360 INTDECL (dwarf_offdie)
1361 INTDECL (dwarf_peel_type)
1362 INTDECL (dwarf_ranges)
1363 INTDECL (dwarf_setalt)
1364 INTDECL (dwarf_siblingof)
1365 INTDECL (dwarf_srclang)
1366 INTDECL (dwarf_tag)
1367
1368 #endif /* libdwP.h */
1369