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 Dwarf_Abbrev *result)
696 __nonnull_attribute__ (1) internal_function;
697
698 /* Get abbreviation of given DIE, and optionally set *READP to the DIE memory
699 just past the abbreviation code. */
700 static inline Dwarf_Abbrev *
701 __nonnull_attribute__ (1)
__libdw_dieabbrev(Dwarf_Die * die,const unsigned char ** readp)702 __libdw_dieabbrev (Dwarf_Die *die, const unsigned char **readp)
703 {
704 /* Do we need to get the abbreviation, or need to read after the code? */
705 if (die->abbrev == NULL || readp != NULL)
706 {
707 /* Get the abbreviation code. */
708 unsigned int code;
709 const unsigned char *addr = die->addr;
710 if (unlikely (die->cu == NULL
711 || addr >= (const unsigned char *) die->cu->endp))
712 return die->abbrev = DWARF_END_ABBREV;
713 get_uleb128 (code, addr, die->cu->endp);
714 if (readp != NULL)
715 *readp = addr;
716
717 /* Find the abbreviation. */
718 if (die->abbrev == NULL)
719 die->abbrev = __libdw_findabbrev (die->cu, code);
720 }
721 return die->abbrev;
722 }
723
724 /* Helper functions for form handling. */
725 extern size_t __libdw_form_val_compute_len (struct Dwarf_CU *cu,
726 unsigned int form,
727 const unsigned char *valp)
728 __nonnull_attribute__ (1, 3) internal_function;
729
730 /* Find the length of a form attribute in DIE/info data. */
731 static inline size_t
732 __nonnull_attribute__ (1, 3)
__libdw_form_val_len(struct Dwarf_CU * cu,unsigned int form,const unsigned char * valp)733 __libdw_form_val_len (struct Dwarf_CU *cu, unsigned int form,
734 const unsigned char *valp)
735 {
736 /* Small lookup table of forms with fixed lengths. Absent indexes are
737 initialized 0, so any truly desired 0 is set to 0x80 and masked. */
738 static const uint8_t form_lengths[] =
739 {
740 [DW_FORM_flag_present] = 0x80,
741 [DW_FORM_implicit_const] = 0x80, /* Value is in abbrev, not in info. */
742
743 [DW_FORM_flag] = 1,
744 [DW_FORM_data1] = 1, [DW_FORM_ref1] = 1,
745 [DW_FORM_addrx1] = 1, [DW_FORM_strx1] = 1,
746
747 [DW_FORM_data2] = 2, [DW_FORM_ref2] = 2,
748 [DW_FORM_addrx2] = 2, [DW_FORM_strx2] = 2,
749
750 [DW_FORM_addrx3] = 3, [DW_FORM_strx3] = 3,
751
752 [DW_FORM_data4] = 4, [DW_FORM_ref4] = 4, [DW_FORM_ref_sup4] = 4,
753 [DW_FORM_addrx4] = 4, [DW_FORM_strx4] = 4,
754
755 [DW_FORM_ref_sig8] = 8,
756 [DW_FORM_data8] = 8, [DW_FORM_ref8] = 8, [DW_FORM_ref_sup8] = 8,
757
758 [DW_FORM_data16] = 16,
759 };
760
761 /* Return immediately for forms with fixed lengths. */
762 if (form < sizeof form_lengths / sizeof form_lengths[0])
763 {
764 uint8_t len = form_lengths[form];
765 if (len != 0)
766 {
767 const unsigned char *endp = cu->endp;
768 len &= 0x7f; /* Mask to allow 0x80 -> 0. */
769 if (unlikely (len > (size_t) (endp - valp)))
770 {
771 __libdw_seterrno (DWARF_E_INVALID_DWARF);
772 return -1;
773 }
774 return len;
775 }
776 }
777
778 /* Other forms require some computation. */
779 return __libdw_form_val_compute_len (cu, form, valp);
780 }
781
782 /* Helper function for DW_FORM_ref* handling. */
783 extern int __libdw_formref (Dwarf_Attribute *attr, Dwarf_Off *return_offset)
784 __nonnull_attribute__ (1, 2) internal_function;
785
786
787 /* Helper function to locate attribute. */
788 extern unsigned char *__libdw_find_attr (Dwarf_Die *die,
789 unsigned int search_name,
790 unsigned int *codep,
791 unsigned int *formp)
792 __nonnull_attribute__ (1) internal_function;
793
794 /* Helper function to access integer attribute. */
795 extern int __libdw_attr_intval (Dwarf_Die *die, int *valp, int attval)
796 __nonnull_attribute__ (1, 2) internal_function;
797
798 /* Helper function to walk scopes. */
799 struct Dwarf_Die_Chain
800 {
801 Dwarf_Die die;
802 struct Dwarf_Die_Chain *parent;
803 bool prune; /* The PREVISIT function can set this. */
804 };
805 extern int __libdw_visit_scopes (unsigned int depth,
806 struct Dwarf_Die_Chain *root,
807 struct Dwarf_Die_Chain *imports,
808 int (*previsit) (unsigned int depth,
809 struct Dwarf_Die_Chain *,
810 void *arg),
811 int (*postvisit) (unsigned int depth,
812 struct Dwarf_Die_Chain *,
813 void *arg),
814 void *arg)
815 __nonnull_attribute__ (2, 4) internal_function;
816
817 /* Parse a DWARF Dwarf_Block into an array of Dwarf_Op's,
818 and cache the result (via tsearch). */
819 extern int __libdw_intern_expression (Dwarf *dbg,
820 bool other_byte_order,
821 unsigned int address_size,
822 unsigned int ref_size,
823 void **cache, const Dwarf_Block *block,
824 bool cfap, bool valuep,
825 Dwarf_Op **llbuf, size_t *listlen,
826 int sec_index)
827 __nonnull_attribute__ (5, 6, 9, 10) internal_function;
828
829 extern Dwarf_Die *__libdw_offdie (Dwarf *dbg, Dwarf_Off offset,
830 Dwarf_Die *result, bool debug_types)
831 internal_function;
832
833
834 /* Return error code of last failing function call. This value is kept
835 separately for each thread. */
836 extern int __dwarf_errno_internal (void);
837
838
839 /* Reader hooks. */
840
841 /* Relocation hooks return -1 on error (in that case the error code
842 must already have been set), 0 if there is no relocation and 1 if a
843 relocation was present.*/
844
845 static inline int
__libdw_relocate_address(Dwarf * dbg,int sec_index,const void * addr,int width,Dwarf_Addr * val)846 __libdw_relocate_address (Dwarf *dbg __attribute__ ((unused)),
847 int sec_index __attribute__ ((unused)),
848 const void *addr __attribute__ ((unused)),
849 int width __attribute__ ((unused)),
850 Dwarf_Addr *val __attribute__ ((unused)))
851 {
852 return 0;
853 }
854
855 static inline int
__libdw_relocate_offset(Dwarf * dbg,int sec_index,const void * addr,int width,Dwarf_Off * val)856 __libdw_relocate_offset (Dwarf *dbg __attribute__ ((unused)),
857 int sec_index __attribute__ ((unused)),
858 const void *addr __attribute__ ((unused)),
859 int width __attribute__ ((unused)),
860 Dwarf_Off *val __attribute__ ((unused)))
861 {
862 return 0;
863 }
864
865 static inline Elf_Data *
__libdw_checked_get_data(Dwarf * dbg,int sec_index)866 __libdw_checked_get_data (Dwarf *dbg, int sec_index)
867 {
868 Elf_Data *data = dbg->sectiondata[sec_index];
869 if (unlikely (data == NULL)
870 || unlikely (data->d_buf == NULL))
871 {
872 __libdw_seterrno (DWARF_E_INVALID_DWARF);
873 return NULL;
874 }
875 return data;
876 }
877
878 static inline int
__libdw_offset_in_section(Dwarf * dbg,int sec_index,Dwarf_Off offset,size_t size)879 __libdw_offset_in_section (Dwarf *dbg, int sec_index,
880 Dwarf_Off offset, size_t size)
881 {
882 Elf_Data *data = __libdw_checked_get_data (dbg, sec_index);
883 if (data == NULL)
884 return -1;
885 if (unlikely (offset > data->d_size)
886 || unlikely (data->d_size < size)
887 || unlikely (offset > data->d_size - size))
888 {
889 __libdw_seterrno (DWARF_E_INVALID_OFFSET);
890 return -1;
891 }
892
893 return 0;
894 }
895
896 static inline bool
__libdw_in_section(Dwarf * dbg,int sec_index,const void * addr,size_t size)897 __libdw_in_section (Dwarf *dbg, int sec_index,
898 const void *addr, size_t size)
899 {
900 Elf_Data *data = __libdw_checked_get_data (dbg, sec_index);
901 if (data == NULL)
902 return false;
903 if (unlikely (addr < data->d_buf)
904 || unlikely (data->d_size < size)
905 || unlikely ((size_t)(addr - data->d_buf) > data->d_size - size))
906 {
907 __libdw_seterrno (DWARF_E_INVALID_OFFSET);
908 return false;
909 }
910
911 return true;
912 }
913
914 #define READ_AND_RELOCATE(RELOC_HOOK, VAL) \
915 ({ \
916 if (!__libdw_in_section (dbg, sec_index, addr, width)) \
917 return -1; \
918 \
919 const unsigned char *orig_addr = addr; \
920 if (width == 4) \
921 VAL = read_4ubyte_unaligned_inc (dbg, addr); \
922 else \
923 VAL = read_8ubyte_unaligned_inc (dbg, addr); \
924 \
925 int status = RELOC_HOOK (dbg, sec_index, orig_addr, width, &VAL); \
926 if (status < 0) \
927 return status; \
928 status > 0; \
929 })
930
931 static inline int
__libdw_read_address_inc(Dwarf * dbg,int sec_index,const unsigned char ** addrp,int width,Dwarf_Addr * ret)932 __libdw_read_address_inc (Dwarf *dbg,
933 int sec_index, const unsigned char **addrp,
934 int width, Dwarf_Addr *ret)
935 {
936 const unsigned char *addr = *addrp;
937 READ_AND_RELOCATE (__libdw_relocate_address, (*ret));
938 *addrp = addr;
939 return 0;
940 }
941
942 static inline int
__libdw_read_address(Dwarf * dbg,int sec_index,const unsigned char * addr,int width,Dwarf_Addr * ret)943 __libdw_read_address (Dwarf *dbg,
944 int sec_index, const unsigned char *addr,
945 int width, Dwarf_Addr *ret)
946 {
947 READ_AND_RELOCATE (__libdw_relocate_address, (*ret));
948 return 0;
949 }
950
951 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)952 __libdw_read_offset_inc (Dwarf *dbg,
953 int sec_index, const unsigned char **addrp,
954 int width, Dwarf_Off *ret, int sec_ret,
955 size_t size)
956 {
957 const unsigned char *addr = *addrp;
958 READ_AND_RELOCATE (__libdw_relocate_offset, (*ret));
959 *addrp = addr;
960 return __libdw_offset_in_section (dbg, sec_ret, *ret, size);
961 }
962
963 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)964 __libdw_read_offset (Dwarf *dbg, Dwarf *dbg_ret,
965 int sec_index, const unsigned char *addr,
966 int width, Dwarf_Off *ret, int sec_ret,
967 size_t size)
968 {
969 READ_AND_RELOCATE (__libdw_relocate_offset, (*ret));
970 return __libdw_offset_in_section (dbg_ret, sec_ret, *ret, size);
971 }
972
973 static inline size_t
cu_sec_idx(struct Dwarf_CU * cu)974 cu_sec_idx (struct Dwarf_CU *cu)
975 {
976 return cu->sec_idx;
977 }
978
979 static inline bool
is_cudie(Dwarf_Die * cudie)980 is_cudie (Dwarf_Die *cudie)
981 {
982 return cudie->cu != NULL && CUDIE (cudie->cu).addr == cudie->addr;
983 }
984
985 /* Read up begin/end pair and increment read pointer.
986 - If it's normal range record, set up *BEGINP and *ENDP and return 0.
987 - If it's base address selection record, set up *BASEP and return 1.
988 - If it's end of rangelist, don't set anything and return 2
989 - If an error occurs, don't set anything and return <0. */
990 int __libdw_read_begin_end_pair_inc (Dwarf_CU *cu, int sec_index,
991 const unsigned char **readp,
992 const unsigned char *readend,
993 int width,
994 Dwarf_Addr *beginp, Dwarf_Addr *endp,
995 Dwarf_Addr *basep)
996 internal_function;
997
998 const unsigned char * __libdw_formptr (Dwarf_Attribute *attr, int sec_index,
999 int err_nodata,
1000 const unsigned char **endpp,
1001 Dwarf_Off *offsetp)
1002 internal_function;
1003
1004 /* Fills in the given attribute to point at an empty location expression. */
1005 void __libdw_empty_loc_attr (Dwarf_Attribute *attr)
1006 internal_function;
1007
1008 /* Load .debug_line unit at DEBUG_LINE_OFFSET. COMP_DIR is a value of
1009 DW_AT_comp_dir or NULL if that attribute is not available. Caches
1010 the loaded unit and optionally set *LINESP and/or *FILESP (if not
1011 NULL) with loaded information. Returns 0 for success or a negative
1012 value for failure. */
1013 int __libdw_getsrclines (Dwarf *dbg, Dwarf_Off debug_line_offset,
1014 const char *comp_dir, unsigned address_size,
1015 Dwarf_Lines **linesp, Dwarf_Files **filesp)
1016 internal_function
1017 __nonnull_attribute__ (1);
1018
1019 /* Load and return value of DW_AT_comp_dir from CUDIE. */
1020 const char *__libdw_getcompdir (Dwarf_Die *cudie);
1021
1022 /* Get the base address for the CU, fetches it when not yet set.
1023 This is used as initial base address for ranges and loclists. */
1024 Dwarf_Addr __libdw_cu_base_address (Dwarf_CU *cu);
1025
1026 /* Get the address base for the CU, fetches it when not yet set. */
1027 static inline Dwarf_Off
__libdw_cu_addr_base(Dwarf_CU * cu)1028 __libdw_cu_addr_base (Dwarf_CU *cu)
1029 {
1030 if (cu->addr_base == (Dwarf_Off) -1)
1031 {
1032 Dwarf_Die cu_die = CUDIE(cu);
1033 Dwarf_Attribute attr;
1034 Dwarf_Off offset = 0;
1035 if (dwarf_attr (&cu_die, DW_AT_GNU_addr_base, &attr) != NULL
1036 || dwarf_attr (&cu_die, DW_AT_addr_base, &attr) != NULL)
1037 {
1038 Dwarf_Word off;
1039 if (dwarf_formudata (&attr, &off) == 0)
1040 offset = off;
1041 }
1042 cu->addr_base = offset;
1043 }
1044
1045 return cu->addr_base;
1046 }
1047
1048 /* Gets the .debug_str_offsets base offset to use. static inline to
1049 be shared between libdw and eu-readelf. */
1050 static inline Dwarf_Off
str_offsets_base_off(Dwarf * dbg,Dwarf_CU * cu)1051 str_offsets_base_off (Dwarf *dbg, Dwarf_CU *cu)
1052 {
1053 /* If we don't have a CU, then find and use the first one in the
1054 debug file (when we support .dwp files, we must actually find the
1055 one matching our "caller" - aka macro or line). If we (now) have
1056 a cu and str_offsets_base attribute, just use that. Otherwise
1057 use the first offset. But we might have to parse the header
1058 first, but only if this is version 5. Assume if all else fails,
1059 this is version 4, without header. */
1060
1061 if (cu == NULL && dbg != NULL)
1062 {
1063 Dwarf_CU *first_cu;
1064 if (dwarf_get_units (dbg, NULL, &first_cu,
1065 NULL, NULL, NULL, NULL) == 0)
1066 cu = first_cu;
1067 }
1068
1069 if (cu != NULL)
1070 {
1071 if (cu->str_off_base == (Dwarf_Off) -1)
1072 {
1073 Dwarf_Die cu_die = CUDIE(cu);
1074 Dwarf_Attribute attr;
1075 if (dwarf_attr (&cu_die, DW_AT_str_offsets_base, &attr) != NULL)
1076 {
1077 Dwarf_Word off;
1078 if (dwarf_formudata (&attr, &off) == 0)
1079 {
1080 cu->str_off_base = off;
1081 return cu->str_off_base;
1082 }
1083 }
1084 /* For older DWARF simply assume zero (no header). */
1085 if (cu->version < 5)
1086 {
1087 cu->str_off_base = 0;
1088 return cu->str_off_base;
1089 }
1090
1091 if (dbg == NULL)
1092 dbg = cu->dbg;
1093 }
1094 else
1095 return cu->str_off_base;
1096 }
1097
1098 /* No str_offsets_base attribute, we have to assume "zero".
1099 But there could be a header first. */
1100 Dwarf_Off off = 0;
1101 if (dbg == NULL)
1102 goto no_header;
1103
1104 Elf_Data *data = dbg->sectiondata[IDX_debug_str_offsets];
1105 if (data == NULL)
1106 goto no_header;
1107
1108 const unsigned char *start;
1109 const unsigned char *readp;
1110 const unsigned char *readendp;
1111 start = readp = (const unsigned char *) data->d_buf;
1112 readendp = (const unsigned char *) data->d_buf + data->d_size;
1113
1114 uint64_t unit_length;
1115 uint16_t version;
1116
1117 unit_length = read_4ubyte_unaligned_inc (dbg, readp);
1118 if (unlikely (unit_length == 0xffffffff))
1119 {
1120 if (unlikely (readendp - readp < 8))
1121 goto no_header;
1122 unit_length = read_8ubyte_unaligned_inc (dbg, readp);
1123 /* In theory the offset size could be different
1124 between CU and str_offsets unit. But we just
1125 ignore that here. */
1126 }
1127
1128 /* We need at least 2-bytes (version) + 2-bytes (padding) =
1129 4 bytes to complete the header. And this unit cannot go
1130 beyond the section data. */
1131 if (readendp - readp < 4
1132 || unit_length < 4
1133 || (uint64_t) (readendp - readp) < unit_length)
1134 goto no_header;
1135
1136 version = read_2ubyte_unaligned_inc (dbg, readp);
1137 if (version != 5)
1138 goto no_header;
1139 /* padding */
1140 read_2ubyte_unaligned_inc (dbg, readp);
1141
1142 off = (Dwarf_Off) (readp - start);
1143
1144 no_header:
1145 if (cu != NULL)
1146 cu->str_off_base = off;
1147
1148 return off;
1149 }
1150
1151
1152 /* Get the string offsets base for the CU, fetches it when not yet set. */
__libdw_cu_str_off_base(Dwarf_CU * cu)1153 static inline Dwarf_Off __libdw_cu_str_off_base (Dwarf_CU *cu)
1154 {
1155 return str_offsets_base_off (NULL, cu);
1156 }
1157
1158
1159 /* Either a direct offset into .debug_ranges for version < 5, or the
1160 start of the offset table in .debug_rnglists for version > 5. */
1161 static inline Dwarf_Off
__libdw_cu_ranges_base(Dwarf_CU * cu)1162 __libdw_cu_ranges_base (Dwarf_CU *cu)
1163 {
1164 if (cu->ranges_base == (Dwarf_Off) -1)
1165 {
1166 Dwarf_Off offset = 0;
1167 Dwarf_Die cu_die = CUDIE(cu);
1168 Dwarf_Attribute attr;
1169 if (cu->version < 5)
1170 {
1171 if (dwarf_attr (&cu_die, DW_AT_GNU_ranges_base, &attr) != NULL)
1172 {
1173 Dwarf_Word off;
1174 if (dwarf_formudata (&attr, &off) == 0)
1175 offset = off;
1176 }
1177 }
1178 else
1179 {
1180 if (dwarf_attr (&cu_die, DW_AT_rnglists_base, &attr) != NULL)
1181 {
1182 Dwarf_Word off;
1183 if (dwarf_formudata (&attr, &off) == 0)
1184 offset = off;
1185 }
1186
1187 /* There wasn't an rnglists_base, if the Dwarf does have a
1188 .debug_rnglists section, then it might be we need the
1189 base after the first header. */
1190 Elf_Data *data = cu->dbg->sectiondata[IDX_debug_rnglists];
1191 if (offset == 0 && data != NULL)
1192 {
1193 Dwarf *dbg = cu->dbg;
1194 const unsigned char *readp = data->d_buf;
1195 const unsigned char *const dataend
1196 = (unsigned char *) data->d_buf + data->d_size;
1197
1198 uint64_t unit_length = read_4ubyte_unaligned_inc (dbg, readp);
1199 unsigned int offset_size = 4;
1200 if (unlikely (unit_length == 0xffffffff))
1201 {
1202 if (unlikely (readp > dataend - 8))
1203 goto no_header;
1204
1205 unit_length = read_8ubyte_unaligned_inc (dbg, readp);
1206 offset_size = 8;
1207 }
1208
1209 if (readp > dataend - 8
1210 || unit_length < 8
1211 || unit_length > (uint64_t) (dataend - readp))
1212 goto no_header;
1213
1214 uint16_t version = read_2ubyte_unaligned_inc (dbg, readp);
1215 if (version != 5)
1216 goto no_header;
1217
1218 uint8_t address_size = *readp++;
1219 if (address_size != 4 && address_size != 8)
1220 goto no_header;
1221
1222 uint8_t segment_size = *readp++;
1223 if (segment_size != 0)
1224 goto no_header;
1225
1226 uint32_t offset_entry_count;
1227 offset_entry_count = read_4ubyte_unaligned_inc (dbg, readp);
1228
1229 const unsigned char *offset_array_start = readp;
1230 if (offset_entry_count <= 0)
1231 goto no_header;
1232
1233 uint64_t needed = offset_entry_count * offset_size;
1234 if (unit_length - 8 < needed)
1235 goto no_header;
1236
1237 offset = (Dwarf_Off) (offset_array_start
1238 - (unsigned char *) data->d_buf);
1239 }
1240 }
1241 no_header:
1242 cu->ranges_base = offset;
1243 }
1244
1245 return cu->ranges_base;
1246 }
1247
1248
1249 /* The start of the offset table in .debug_loclists for DWARF5. */
1250 static inline Dwarf_Off
__libdw_cu_locs_base(Dwarf_CU * cu)1251 __libdw_cu_locs_base (Dwarf_CU *cu)
1252 {
1253 if (cu->locs_base == (Dwarf_Off) -1)
1254 {
1255 Dwarf_Off offset = 0;
1256 Dwarf_Die cu_die = CUDIE(cu);
1257 Dwarf_Attribute attr;
1258 if (dwarf_attr (&cu_die, DW_AT_loclists_base, &attr) != NULL)
1259 {
1260 Dwarf_Word off;
1261 if (dwarf_formudata (&attr, &off) == 0)
1262 offset = off;
1263 }
1264
1265 /* There wasn't an loclists_base, if the Dwarf does have a
1266 .debug_loclists section, then it might be we need the
1267 base after the first header. */
1268 Elf_Data *data = cu->dbg->sectiondata[IDX_debug_loclists];
1269 if (offset == 0 && data != NULL)
1270 {
1271 Dwarf *dbg = cu->dbg;
1272 const unsigned char *readp = data->d_buf;
1273 const unsigned char *const dataend
1274 = (unsigned char *) data->d_buf + data->d_size;
1275
1276 uint64_t unit_length = read_4ubyte_unaligned_inc (dbg, readp);
1277 unsigned int offset_size = 4;
1278 if (unlikely (unit_length == 0xffffffff))
1279 {
1280 if (unlikely (readp > dataend - 8))
1281 goto no_header;
1282
1283 unit_length = read_8ubyte_unaligned_inc (dbg, readp);
1284 offset_size = 8;
1285 }
1286
1287 if (readp > dataend - 8
1288 || unit_length < 8
1289 || unit_length > (uint64_t) (dataend - readp))
1290 goto no_header;
1291
1292 uint16_t version = read_2ubyte_unaligned_inc (dbg, readp);
1293 if (version != 5)
1294 goto no_header;
1295
1296 uint8_t address_size = *readp++;
1297 if (address_size != 4 && address_size != 8)
1298 goto no_header;
1299
1300 uint8_t segment_size = *readp++;
1301 if (segment_size != 0)
1302 goto no_header;
1303
1304 uint32_t offset_entry_count;
1305 offset_entry_count = read_4ubyte_unaligned_inc (dbg, readp);
1306
1307 const unsigned char *offset_array_start = readp;
1308 if (offset_entry_count <= 0)
1309 goto no_header;
1310
1311 uint64_t needed = offset_entry_count * offset_size;
1312 if (unit_length - 8 < needed)
1313 goto no_header;
1314
1315 offset = (Dwarf_Off) (offset_array_start
1316 - (unsigned char *) data->d_buf);
1317 }
1318
1319 no_header:
1320 cu->locs_base = offset;
1321 }
1322
1323 return cu->locs_base;
1324 }
1325
1326 /* Helper function for tsearch/tfind split_tree Dwarf. */
1327 int __libdw_finddbg_cb (const void *arg1, const void *arg2);
1328
1329 /* Link skeleton and split compile units. */
1330 static inline void
__libdw_link_skel_split(Dwarf_CU * skel,Dwarf_CU * split)1331 __libdw_link_skel_split (Dwarf_CU *skel, Dwarf_CU *split)
1332 {
1333 skel->split = split;
1334 split->split = skel;
1335
1336 /* Get .debug_addr and addr_base greedy.
1337 We also need it for the fake addr cu.
1338 There is only one per split debug. */
1339 Dwarf *dbg = skel->dbg;
1340 Dwarf *sdbg = split->dbg;
1341 if (sdbg->sectiondata[IDX_debug_addr] == NULL
1342 && dbg->sectiondata[IDX_debug_addr] != NULL)
1343 {
1344 sdbg->sectiondata[IDX_debug_addr]
1345 = dbg->sectiondata[IDX_debug_addr];
1346 split->addr_base = __libdw_cu_addr_base (skel);
1347 sdbg->fake_addr_cu = dbg->fake_addr_cu;
1348 }
1349 }
1350
1351
1352 /* Given an address index for a CU return the address.
1353 Returns -1 and sets libdw_errno if an error occurs. */
1354 int __libdw_addrx (Dwarf_CU *cu, Dwarf_Word idx, Dwarf_Addr *addr);
1355
1356
1357 /* Helper function to set elfpath field in Dwarf, used from dwarf_begin_elf
1358 and libdwfl process_file. */
1359 char * __libdw_elfpath (int fd);
1360
1361 /* Helper function to set debugdir field in Dwarf after elfpath field has been
1362 set. */
1363 void __libdw_set_debugdir (Dwarf *dbg);
1364
1365
1366 /* Given the directory of a debug file, an absolute or relative dir
1367 to look in, and file returns a full path.
1368
1369 If the file is absolute (starts with a /) a copy of file is returned.
1370 the file isn't absolute, but dir is absolute, then a path that is
1371 the concatenation of dir and file is returned. If neither file,
1372 nor dir is absolute, the path will be constructed using dir (if not
1373 NULL) and file relative to the debugdir (if valid).
1374
1375 The debugdir and the dir may be NULL (in which case they aren't used).
1376 If file is NULL, or no full path can be constructed NULL is returned.
1377
1378 The caller is responsible for freeing the result if not NULL. */
1379 char * __libdw_filepath (const char *debugdir, const char *dir,
1380 const char *file)
1381 internal_function;
1382
1383
1384 /* Aliases to avoid PLTs. */
1385 INTDECL (dwarf_aggregate_size)
1386 INTDECL (dwarf_attr)
1387 INTDECL (dwarf_attr_integrate)
1388 INTDECL (dwarf_begin)
1389 INTDECL (dwarf_begin_elf)
1390 INTDECL (dwarf_child)
1391 INTDECL (dwarf_default_lower_bound)
1392 INTDECL (dwarf_dieoffset)
1393 INTDECL (dwarf_diename)
1394 INTDECL (dwarf_end)
1395 INTDECL (dwarf_entrypc)
1396 INTDECL (dwarf_errmsg)
1397 INTDECL (dwarf_formaddr)
1398 INTDECL (dwarf_formblock)
1399 INTDECL (dwarf_formref_die)
1400 INTDECL (dwarf_formsdata)
1401 INTDECL (dwarf_formstring)
1402 INTDECL (dwarf_formudata)
1403 INTDECL (dwarf_getabbrevattr_data)
1404 INTDECL (dwarf_getalt)
1405 INTDECL (dwarf_getarange_addr)
1406 INTDECL (dwarf_getarangeinfo)
1407 INTDECL (dwarf_getaranges)
1408 INTDECL (dwarf_getlocation_die)
1409 INTDECL (dwarf_getsrcfiles)
1410 INTDECL (dwarf_getsrclines)
1411 INTDECL (dwarf_hasattr)
1412 INTDECL (dwarf_haschildren)
1413 INTDECL (dwarf_haspc)
1414 INTDECL (dwarf_highpc)
1415 INTDECL (dwarf_lowpc)
1416 INTDECL (dwarf_nextcu)
1417 INTDECL (dwarf_next_unit)
1418 INTDECL (dwarf_offdie)
1419 INTDECL (dwarf_peel_type)
1420 INTDECL (dwarf_ranges)
1421 INTDECL (dwarf_setalt)
1422 INTDECL (dwarf_siblingof)
1423 INTDECL (dwarf_srclang)
1424 INTDECL (dwarf_tag)
1425
1426 #endif /* libdwP.h */
1427