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