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