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