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