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