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