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