Line data Source code
1 : /* Internal definitions for libdwarf.
2 : Copyright (C) 2002-2011, 2013-2016 Red Hat, Inc.
3 : This file is part of elfutils.
4 : Written by Ulrich Drepper <drepper@redhat.com>, 2002.
5 :
6 : This file is free software; you can redistribute it and/or modify
7 : it under the terms of either
8 :
9 : * the GNU Lesser General Public License as published by the Free
10 : Software Foundation; either version 3 of the License, or (at
11 : your option) any later version
12 :
13 : or
14 :
15 : * the GNU General Public License as published by the Free
16 : Software Foundation; either version 2 of the License, or (at
17 : your option) any later version
18 :
19 : or both in parallel, as here.
20 :
21 : elfutils is distributed in the hope that it will be useful, but
22 : WITHOUT ANY WARRANTY; without even the implied warranty of
23 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 : General Public License for more details.
25 :
26 : You should have received copies of the GNU General Public License and
27 : the GNU Lesser General Public License along with this program. If
28 : not, see <http://www.gnu.org/licenses/>. */
29 :
30 : #ifndef _LIBDWP_H
31 : #define _LIBDWP_H 1
32 :
33 : #include <libintl.h>
34 : #include <stdbool.h>
35 :
36 : #include <libdw.h>
37 : #include <dwarf.h>
38 :
39 :
40 : /* gettext helper macros. */
41 : #define _(Str) dgettext ("elfutils", Str)
42 :
43 :
44 : /* Known location expressions already decoded. */
45 : struct loc_s
46 : {
47 : void *addr;
48 : Dwarf_Op *loc;
49 : size_t nloc;
50 : };
51 :
52 : /* Known DW_OP_implicit_value blocks already decoded.
53 : This overlaps struct loc_s exactly, but only the
54 : first member really has to match. */
55 : struct loc_block_s
56 : {
57 : void *addr;
58 : unsigned char *data;
59 : size_t length;
60 : };
61 :
62 : /* Already decoded .debug_line units. */
63 : struct files_lines_s
64 : {
65 : Dwarf_Off debug_line_offset;
66 : Dwarf_Files *files;
67 : Dwarf_Lines *lines;
68 : };
69 :
70 : /* Valid indeces for the section data. */
71 : enum
72 : {
73 : IDX_debug_info = 0,
74 : IDX_debug_types,
75 : IDX_debug_abbrev,
76 : IDX_debug_aranges,
77 : IDX_debug_line,
78 : IDX_debug_frame,
79 : IDX_debug_loc,
80 : IDX_debug_pubnames,
81 : IDX_debug_str,
82 : IDX_debug_macinfo,
83 : IDX_debug_macro,
84 : IDX_debug_ranges,
85 : IDX_gnu_debugaltlink,
86 : IDX_last
87 : };
88 :
89 :
90 : /* Error values. */
91 : enum
92 : {
93 : DWARF_E_NOERROR = 0,
94 : DWARF_E_UNKNOWN_ERROR,
95 : DWARF_E_INVALID_ACCESS,
96 : DWARF_E_NO_REGFILE,
97 : DWARF_E_IO_ERROR,
98 : DWARF_E_INVALID_ELF,
99 : DWARF_E_NO_DWARF,
100 : DWARF_E_COMPRESSED_ERROR,
101 : DWARF_E_NOELF,
102 : DWARF_E_GETEHDR_ERROR,
103 : DWARF_E_NOMEM,
104 : DWARF_E_UNIMPL,
105 : DWARF_E_INVALID_CMD,
106 : DWARF_E_INVALID_VERSION,
107 : DWARF_E_INVALID_FILE,
108 : DWARF_E_NO_ENTRY,
109 : DWARF_E_INVALID_DWARF,
110 : DWARF_E_NO_STRING,
111 : DWARF_E_NO_ADDR,
112 : DWARF_E_NO_CONSTANT,
113 : DWARF_E_NO_REFERENCE,
114 : DWARF_E_INVALID_REFERENCE,
115 : DWARF_E_NO_DEBUG_LINE,
116 : DWARF_E_INVALID_DEBUG_LINE,
117 : DWARF_E_TOO_BIG,
118 : DWARF_E_VERSION,
119 : DWARF_E_INVALID_DIR_IDX,
120 : DWARF_E_ADDR_OUTOFRANGE,
121 : DWARF_E_NO_LOCLIST,
122 : DWARF_E_NO_BLOCK,
123 : DWARF_E_INVALID_LINE_IDX,
124 : DWARF_E_INVALID_ARANGE_IDX,
125 : DWARF_E_NO_MATCH,
126 : DWARF_E_NO_FLAG,
127 : DWARF_E_INVALID_OFFSET,
128 : DWARF_E_NO_DEBUG_RANGES,
129 : DWARF_E_INVALID_CFI,
130 : DWARF_E_NO_ALT_DEBUGLINK,
131 : DWARF_E_INVALID_OPCODE,
132 : DWARF_E_NOT_CUDIE,
133 : DWARF_E_UNKNOWN_LANGUAGE,
134 : };
135 :
136 :
137 : #include "dwarf_sig8_hash.h"
138 :
139 : /* This is the structure representing the debugging state. */
140 : struct Dwarf
141 : {
142 : /* The underlying ELF file. */
143 : Elf *elf;
144 :
145 : /* dwz alternate DWARF file. */
146 : Dwarf *alt_dwarf;
147 :
148 : /* The section data. */
149 : Elf_Data *sectiondata[IDX_last];
150 :
151 : /* True if the file has a byte order different from the host. */
152 : bool other_byte_order;
153 :
154 : /* If true, we allocated the ELF descriptor ourselves. */
155 : bool free_elf;
156 :
157 : /* Information for traversing the .debug_pubnames section. This is
158 : an array and separately allocated with malloc. */
159 : struct pubnames_s
160 : {
161 : Dwarf_Off cu_offset;
162 : Dwarf_Off set_start;
163 : unsigned int cu_header_size;
164 : int address_len;
165 : } *pubnames_sets;
166 : size_t pubnames_nsets;
167 :
168 : /* Search tree for the CUs. */
169 : void *cu_tree;
170 : Dwarf_Off next_cu_offset;
171 :
172 : /* Search tree and sig8 hash table for .debug_types type units. */
173 : void *tu_tree;
174 : Dwarf_Off next_tu_offset;
175 : Dwarf_Sig8_Hash sig8_hash;
176 :
177 : /* Search tree for .debug_macro operator tables. */
178 : void *macro_ops;
179 :
180 : /* Search tree for decoded .debug_line units. */
181 : void *files_lines;
182 :
183 : /* Address ranges. */
184 : Dwarf_Aranges *aranges;
185 :
186 : /* Cached info from the CFI section. */
187 : struct Dwarf_CFI_s *cfi;
188 :
189 : /* Fake loc CU. Used when synthesizing attributes for Dwarf_Ops that
190 : came from a location list entry in dwarf_getlocation_attr. */
191 : struct Dwarf_CU *fake_loc_cu;
192 :
193 : /* Internal memory handling. This is basically a simplified
194 : reimplementation of obstacks. Unfortunately the standard obstack
195 : implementation is not usable in libraries. */
196 : struct libdw_memblock
197 : {
198 : size_t size;
199 : size_t remaining;
200 : struct libdw_memblock *prev;
201 : char mem[0];
202 : } *mem_tail;
203 :
204 : /* Default size of allocated memory blocks. */
205 : size_t mem_default_size;
206 :
207 : /* Registered OOM handler. */
208 : Dwarf_OOM oom_handler;
209 : };
210 :
211 :
212 : /* Abbreviation representation. */
213 : struct Dwarf_Abbrev
214 : {
215 : Dwarf_Off offset;
216 : unsigned char *attrp;
217 : unsigned int attrcnt;
218 : unsigned int code;
219 : unsigned int tag;
220 : bool has_children;
221 : };
222 :
223 : #include "dwarf_abbrev_hash.h"
224 :
225 :
226 : /* Files in line information records. */
227 : struct Dwarf_Files_s
228 : {
229 : unsigned int ndirs;
230 : unsigned int nfiles;
231 : struct Dwarf_Fileinfo_s
232 : {
233 : char *name;
234 : Dwarf_Word mtime;
235 : Dwarf_Word length;
236 : } info[0];
237 : /* nfiles of those, followed by char *[ndirs]. */
238 : };
239 : typedef struct Dwarf_Fileinfo_s Dwarf_Fileinfo;
240 :
241 :
242 : /* Representation of a row in the line table. */
243 :
244 : struct Dwarf_Line_s
245 : {
246 : Dwarf_Files *files;
247 :
248 : Dwarf_Addr addr;
249 : unsigned int file;
250 : int line;
251 : unsigned short int column;
252 : unsigned int is_stmt:1;
253 : unsigned int basic_block:1;
254 : unsigned int end_sequence:1;
255 : unsigned int prologue_end:1;
256 : unsigned int epilogue_begin:1;
257 : /* The remaining bit fields are not flags, but hold values presumed to be
258 : small. All the flags and other bit fields should add up to 48 bits
259 : to give the whole struct a nice round size. */
260 : unsigned int op_index:8;
261 : unsigned int isa:8;
262 : unsigned int discriminator:24;
263 : };
264 :
265 : struct Dwarf_Lines_s
266 : {
267 : size_t nlines;
268 : struct Dwarf_Line_s info[0];
269 : };
270 :
271 : /* Representation of address ranges. */
272 : struct Dwarf_Aranges_s
273 : {
274 : Dwarf *dbg;
275 : size_t naranges;
276 :
277 : struct Dwarf_Arange_s
278 : {
279 : Dwarf_Addr addr;
280 : Dwarf_Word length;
281 : Dwarf_Off offset;
282 : } info[0];
283 : };
284 :
285 :
286 : /* CU representation. */
287 : struct Dwarf_CU
288 : {
289 : Dwarf *dbg;
290 : Dwarf_Off start;
291 : Dwarf_Off end;
292 : uint8_t address_size;
293 : uint8_t offset_size;
294 : uint16_t version;
295 :
296 : /* Zero if this is a normal CU. Nonzero if it is a type unit. */
297 : size_t type_offset;
298 : uint64_t type_sig8;
299 :
300 : /* Hash table for the abbreviations. */
301 : Dwarf_Abbrev_Hash abbrev_hash;
302 : /* Offset of the first abbreviation. */
303 : size_t orig_abbrev_offset;
304 : /* Offset past last read abbreviation. */
305 : size_t last_abbrev_offset;
306 :
307 : /* The srcline information. */
308 : Dwarf_Lines *lines;
309 :
310 : /* The source file information. */
311 : Dwarf_Files *files;
312 :
313 : /* Known location lists. */
314 : void *locs;
315 :
316 : /* Memory boundaries of this CU. */
317 : void *startp;
318 : void *endp;
319 : };
320 :
321 : /* Compute the offset of a CU's first DIE from its offset. This
322 : is either:
323 : LEN VER OFFSET ADDR
324 : 4-bytes + 2-bytes + 4-bytes + 1-byte for 32-bit dwarf
325 : 12-bytes + 2-bytes + 8-bytes + 1-byte for 64-bit dwarf
326 : or in .debug_types, SIGNATURE TYPE-OFFSET
327 : 4-bytes + 2-bytes + 4-bytes + 1-byte + 8-bytes + 4-bytes for 32-bit
328 : 12-bytes + 2-bytes + 8-bytes + 1-byte + 8-bytes + 8-bytes for 64-bit
329 :
330 : Note the trick in the computation. If the offset_size is 4
331 : the '- 4' term changes the '3 *' into a '2 *'. If the
332 : offset_size is 8 it accounts for the 4-byte escape value
333 : used at the start of the length. */
334 : #define DIE_OFFSET_FROM_CU_OFFSET(cu_offset, offset_size, type_unit) \
335 : ((type_unit) ? ((cu_offset) + 4 * (offset_size) - 4 + 3 + 8) \
336 : : ((cu_offset) + 3 * (offset_size) - 4 + 3))
337 :
338 : #define CUDIE(fromcu) \
339 : ((Dwarf_Die) \
340 : { \
341 : .cu = (fromcu), \
342 : .addr = ((char *) fromcu->dbg->sectiondata[cu_sec_idx (fromcu)]->d_buf \
343 : + DIE_OFFSET_FROM_CU_OFFSET ((fromcu)->start, \
344 : (fromcu)->offset_size, \
345 : (fromcu)->type_offset != 0)) \
346 : }) \
347 :
348 :
349 : /* Prototype of a single .debug_macro operator. */
350 : typedef struct
351 : {
352 : Dwarf_Word nforms;
353 : unsigned char const *forms;
354 : } Dwarf_Macro_Op_Proto;
355 :
356 : /* Prototype table. */
357 : typedef struct
358 : {
359 : /* Offset of .debug_macro section. */
360 : Dwarf_Off offset;
361 :
362 : /* Offset of associated .debug_line section. */
363 : Dwarf_Off line_offset;
364 :
365 : /* The source file information. */
366 : Dwarf_Files *files;
367 :
368 : /* If this macro unit was opened through dwarf_getmacros or
369 : dwarf_getmacros_die, this caches value of DW_AT_comp_dir, if
370 : present. */
371 : const char *comp_dir;
372 :
373 : /* Header length. */
374 : Dwarf_Half header_len;
375 :
376 : uint16_t version;
377 : bool is_64bit;
378 : uint8_t sec_index; /* IDX_debug_macro or IDX_debug_macinfo. */
379 :
380 : /* Shows where in TABLE each opcode is defined. Since opcode 0 is
381 : never used, it stores index of opcode X in X-1'th element. The
382 : value of 0xff means not stored at all. */
383 : unsigned char opcodes[255];
384 :
385 : /* Individual opcode prototypes. */
386 : Dwarf_Macro_Op_Proto table[];
387 : } Dwarf_Macro_Op_Table;
388 :
389 : struct Dwarf_Macro_s
390 : {
391 : Dwarf_Macro_Op_Table *table;
392 : Dwarf_Attribute *attributes;
393 : uint8_t opcode;
394 : };
395 :
396 : static inline Dwarf_Word
397 : libdw_macro_nforms (Dwarf_Macro *macro)
398 : {
399 648 : return macro->table->table[macro->table->opcodes[macro->opcode - 1]].nforms;
400 : }
401 :
402 : /* We have to include the file at this point because the inline
403 : functions access internals of the Dwarf structure. */
404 : #include "memory-access.h"
405 :
406 :
407 : /* Set error value. */
408 : extern void __libdw_seterrno (int value) internal_function;
409 :
410 :
411 : /* Memory handling, the easy parts. This macro does not do any locking. */
412 : #define libdw_alloc(dbg, type, tsize, cnt) \
413 : ({ struct libdw_memblock *_tail = (dbg)->mem_tail; \
414 : size_t _required = (tsize) * (cnt); \
415 : type *_result = (type *) (_tail->mem + (_tail->size - _tail->remaining));\
416 : size_t _padding = ((__alignof (type) \
417 : - ((uintptr_t) _result & (__alignof (type) - 1))) \
418 : & (__alignof (type) - 1)); \
419 : if (unlikely (_tail->remaining < _required + _padding)) \
420 : _result = (type *) __libdw_allocate (dbg, _required, __alignof (type));\
421 : else \
422 : { \
423 : _required += _padding; \
424 : _result = (type *) ((char *) _result + _padding); \
425 : _tail->remaining -= _required; \
426 : } \
427 : _result; })
428 :
429 : #define libdw_typed_alloc(dbg, type) \
430 : libdw_alloc (dbg, type, sizeof (type), 1)
431 :
432 : /* Callback to allocate more. */
433 : extern void *__libdw_allocate (Dwarf *dbg, size_t minsize, size_t align)
434 : __attribute__ ((__malloc__)) __nonnull_attribute__ (1);
435 :
436 : /* Default OOM handler. */
437 : extern void __libdw_oom (void) __attribute ((noreturn, visibility ("hidden")));
438 :
439 : /* Allocate the internal data for a unit not seen before. */
440 : extern struct Dwarf_CU *__libdw_intern_next_unit (Dwarf *dbg, bool debug_types)
441 : __nonnull_attribute__ (1) internal_function;
442 :
443 : /* Find CU for given offset. */
444 : extern struct Dwarf_CU *__libdw_findcu (Dwarf *dbg, Dwarf_Off offset, bool tu)
445 : __nonnull_attribute__ (1) internal_function;
446 :
447 : /* Get abbreviation with given code. */
448 : extern Dwarf_Abbrev *__libdw_findabbrev (struct Dwarf_CU *cu,
449 : unsigned int code)
450 : __nonnull_attribute__ (1) internal_function;
451 :
452 : /* Get abbreviation at given offset. */
453 : extern Dwarf_Abbrev *__libdw_getabbrev (Dwarf *dbg, struct Dwarf_CU *cu,
454 : Dwarf_Off offset, size_t *lengthp,
455 : Dwarf_Abbrev *result)
456 : __nonnull_attribute__ (1) internal_function;
457 :
458 : /* Get abbreviation of given DIE, and optionally set *READP to the DIE memory
459 : just past the abbreviation code. */
460 : static inline Dwarf_Abbrev *
461 : __nonnull_attribute__ (1)
462 20849856 : __libdw_dieabbrev (Dwarf_Die *die, const unsigned char **readp)
463 : {
464 : /* Do we need to get the abbreviation, or need to read after the code? */
465 20849856 : if (die->abbrev == NULL || readp != NULL)
466 : {
467 : /* Get the abbreviation code. */
468 : unsigned int code;
469 7065698 : const unsigned char *addr = die->addr;
470 7065698 : get_uleb128 (code, addr, die->cu->endp);
471 7065698 : if (readp != NULL)
472 4513960 : *readp = addr;
473 :
474 : /* Find the abbreviation. */
475 7065698 : if (die->abbrev == NULL)
476 3140560 : die->abbrev = __libdw_findabbrev (die->cu, code);
477 : }
478 20849856 : return die->abbrev;
479 : }
480 :
481 : /* Helper functions for form handling. */
482 : extern size_t __libdw_form_val_compute_len (struct Dwarf_CU *cu,
483 : unsigned int form,
484 : const unsigned char *valp)
485 : __nonnull_attribute__ (1, 3) internal_function;
486 :
487 : /* Find the length of a form attribute. */
488 : static inline size_t
489 : __nonnull_attribute__ (1, 3)
490 14733547 : __libdw_form_val_len (struct Dwarf_CU *cu, unsigned int form,
491 : const unsigned char *valp)
492 : {
493 : /* Small lookup table of forms with fixed lengths. Absent indexes are
494 : initialized 0, so any truly desired 0 is set to 0x80 and masked. */
495 : static const uint8_t form_lengths[] =
496 : {
497 : [DW_FORM_flag_present] = 0x80,
498 : [DW_FORM_data1] = 1, [DW_FORM_ref1] = 1, [DW_FORM_flag] = 1,
499 : [DW_FORM_data2] = 2, [DW_FORM_ref2] = 2,
500 : [DW_FORM_data4] = 4, [DW_FORM_ref4] = 4,
501 : [DW_FORM_data8] = 8, [DW_FORM_ref8] = 8, [DW_FORM_ref_sig8] = 8,
502 : };
503 :
504 : /* Return immediately for forms with fixed lengths. */
505 14733547 : if (form < sizeof form_lengths / sizeof form_lengths[0])
506 : {
507 14733312 : uint8_t len = form_lengths[form];
508 14733312 : if (len != 0)
509 : {
510 10541517 : const unsigned char *endp = cu->endp;
511 10541517 : len &= 0x7f; /* Mask to allow 0x80 -> 0. */
512 10541517 : if (unlikely (len > (size_t) (endp - valp)))
513 : {
514 0 : __libdw_seterrno (DWARF_E_INVALID_DWARF);
515 0 : return -1;
516 : }
517 : return len;
518 : }
519 : }
520 :
521 : /* Other forms require some computation. */
522 4192030 : return __libdw_form_val_compute_len (cu, form, valp);
523 : }
524 :
525 : /* Helper function for DW_FORM_ref* handling. */
526 : extern int __libdw_formref (Dwarf_Attribute *attr, Dwarf_Off *return_offset)
527 : __nonnull_attribute__ (1, 2) internal_function;
528 :
529 :
530 : /* Helper function to locate attribute. */
531 : extern unsigned char *__libdw_find_attr (Dwarf_Die *die,
532 : unsigned int search_name,
533 : unsigned int *codep,
534 : unsigned int *formp)
535 : __nonnull_attribute__ (1) internal_function;
536 :
537 : /* Helper function to access integer attribute. */
538 : extern int __libdw_attr_intval (Dwarf_Die *die, int *valp, int attval)
539 : __nonnull_attribute__ (1, 2) internal_function;
540 :
541 : /* Helper function to walk scopes. */
542 : struct Dwarf_Die_Chain
543 : {
544 : Dwarf_Die die;
545 : struct Dwarf_Die_Chain *parent;
546 : bool prune; /* The PREVISIT function can set this. */
547 : };
548 : extern int __libdw_visit_scopes (unsigned int depth,
549 : struct Dwarf_Die_Chain *root,
550 : struct Dwarf_Die_Chain *imports,
551 : int (*previsit) (unsigned int depth,
552 : struct Dwarf_Die_Chain *,
553 : void *arg),
554 : int (*postvisit) (unsigned int depth,
555 : struct Dwarf_Die_Chain *,
556 : void *arg),
557 : void *arg)
558 : __nonnull_attribute__ (2, 4) internal_function;
559 :
560 : /* Parse a DWARF Dwarf_Block into an array of Dwarf_Op's,
561 : and cache the result (via tsearch). */
562 : extern int __libdw_intern_expression (Dwarf *dbg,
563 : bool other_byte_order,
564 : unsigned int address_size,
565 : unsigned int ref_size,
566 : void **cache, const Dwarf_Block *block,
567 : bool cfap, bool valuep,
568 : Dwarf_Op **llbuf, size_t *listlen,
569 : int sec_index)
570 : __nonnull_attribute__ (5, 6, 9, 10) internal_function;
571 :
572 : extern Dwarf_Die *__libdw_offdie (Dwarf *dbg, Dwarf_Off offset,
573 : Dwarf_Die *result, bool debug_types)
574 : internal_function;
575 :
576 :
577 : /* Return error code of last failing function call. This value is kept
578 : separately for each thread. */
579 : extern int __dwarf_errno_internal (void);
580 :
581 :
582 : /* Reader hooks. */
583 :
584 : /* Relocation hooks return -1 on error (in that case the error code
585 : must already have been set), 0 if there is no relocation and 1 if a
586 : relocation was present.*/
587 :
588 : static inline int
589 : __libdw_relocate_address (Dwarf *dbg __attribute__ ((unused)),
590 : int sec_index __attribute__ ((unused)),
591 : const void *addr __attribute__ ((unused)),
592 : int width __attribute__ ((unused)),
593 : Dwarf_Addr *val __attribute__ ((unused)))
594 : {
595 : return 0;
596 : }
597 :
598 : static inline int
599 : __libdw_relocate_offset (Dwarf *dbg __attribute__ ((unused)),
600 : int sec_index __attribute__ ((unused)),
601 : const void *addr __attribute__ ((unused)),
602 : int width __attribute__ ((unused)),
603 : Dwarf_Off *val __attribute__ ((unused)))
604 : {
605 : return 0;
606 : }
607 :
608 : static inline Elf_Data *
609 : __libdw_checked_get_data (Dwarf *dbg, int sec_index)
610 : {
611 1924043 : Elf_Data *data = dbg->sectiondata[sec_index];
612 1924043 : if (unlikely (data == NULL)
613 1924043 : || unlikely (data->d_buf == NULL))
614 : {
615 0 : __libdw_seterrno (DWARF_E_INVALID_DWARF);
616 : return NULL;
617 : }
618 : return data;
619 : }
620 :
621 : static inline int
622 872439 : __libdw_offset_in_section (Dwarf *dbg, int sec_index,
623 : Dwarf_Off offset, size_t size)
624 : {
625 0 : Elf_Data *data = __libdw_checked_get_data (dbg, sec_index);
626 : if (data == NULL)
627 : return -1;
628 872439 : if (unlikely (offset > data->d_size)
629 872439 : || unlikely (data->d_size - offset < size))
630 : {
631 0 : __libdw_seterrno (DWARF_E_INVALID_OFFSET);
632 0 : return -1;
633 : }
634 :
635 : return 0;
636 : }
637 :
638 : static inline bool
639 1047261 : __libdw_in_section (Dwarf *dbg, int sec_index,
640 : const void *addr, size_t size)
641 : {
642 0 : Elf_Data *data = __libdw_checked_get_data (dbg, sec_index);
643 : if (data == NULL)
644 : return false;
645 1047261 : if (unlikely (addr < data->d_buf)
646 1047261 : || unlikely (data->d_size - (addr - data->d_buf) < size))
647 : {
648 0 : __libdw_seterrno (DWARF_E_INVALID_OFFSET);
649 0 : return false;
650 : }
651 :
652 : return true;
653 : }
654 :
655 : #define READ_AND_RELOCATE(RELOC_HOOK, VAL) \
656 : ({ \
657 : if (!__libdw_in_section (dbg, sec_index, addr, width)) \
658 : return -1; \
659 : \
660 : const unsigned char *orig_addr = addr; \
661 : if (width == 4) \
662 : VAL = read_4ubyte_unaligned_inc (dbg, addr); \
663 : else \
664 : VAL = read_8ubyte_unaligned_inc (dbg, addr); \
665 : \
666 : int status = RELOC_HOOK (dbg, sec_index, orig_addr, width, &VAL); \
667 : if (status < 0) \
668 : return status; \
669 : status > 0; \
670 : })
671 :
672 : static inline int
673 5653 : __libdw_read_address_inc (Dwarf *dbg,
674 : int sec_index, const unsigned char **addrp,
675 : int width, Dwarf_Addr *ret)
676 : {
677 5653 : const unsigned char *addr = *addrp;
678 5770 : READ_AND_RELOCATE (__libdw_relocate_address, (*ret));
679 5653 : *addrp = addr;
680 5653 : return 0;
681 : }
682 :
683 : static inline int
684 173274 : __libdw_read_address (Dwarf *dbg,
685 : int sec_index, const unsigned char *addr,
686 : int width, Dwarf_Addr *ret)
687 : {
688 173374 : READ_AND_RELOCATE (__libdw_relocate_address, (*ret));
689 : return 0;
690 : }
691 :
692 : static inline int
693 114919 : __libdw_read_offset_inc (Dwarf *dbg,
694 : int sec_index, const unsigned char **addrp,
695 : int width, Dwarf_Off *ret, int sec_ret,
696 : size_t size)
697 : {
698 114919 : const unsigned char *addr = *addrp;
699 115044 : READ_AND_RELOCATE (__libdw_relocate_offset, (*ret));
700 114919 : *addrp = addr;
701 114919 : return __libdw_offset_in_section (dbg, sec_ret, *ret, size);
702 : }
703 :
704 : static inline int
705 753169 : __libdw_read_offset (Dwarf *dbg, Dwarf *dbg_ret,
706 : int sec_index, const unsigned char *addr,
707 : int width, Dwarf_Off *ret, int sec_ret,
708 : size_t size)
709 : {
710 777646 : READ_AND_RELOCATE (__libdw_relocate_offset, (*ret));
711 753169 : return __libdw_offset_in_section (dbg_ret, sec_ret, *ret, size);
712 : }
713 :
714 : static inline size_t
715 : cu_sec_idx (struct Dwarf_CU *cu)
716 : {
717 986083 : return cu->type_offset == 0 ? IDX_debug_info : IDX_debug_types;
718 : }
719 :
720 : static inline bool
721 : is_cudie (Dwarf_Die *cudie)
722 : {
723 15246 : return CUDIE (cudie->cu).addr == cudie->addr;
724 : }
725 :
726 : /* Read up begin/end pair and increment read pointer.
727 : - If it's normal range record, set up *BEGINP and *ENDP and return 0.
728 : - If it's base address selection record, set up *BASEP and return 1.
729 : - If it's end of rangelist, don't set anything and return 2
730 : - If an error occurs, don't set anything and return <0. */
731 : int __libdw_read_begin_end_pair_inc (Dwarf *dbg, int sec_index,
732 : unsigned char **addr, int width,
733 : Dwarf_Addr *beginp, Dwarf_Addr *endp,
734 : Dwarf_Addr *basep)
735 : internal_function;
736 :
737 : unsigned char * __libdw_formptr (Dwarf_Attribute *attr, int sec_index,
738 : int err_nodata, unsigned char **endpp,
739 : Dwarf_Off *offsetp)
740 : internal_function;
741 :
742 : /* Fills in the given attribute to point at an empty location expression. */
743 : void __libdw_empty_loc_attr (Dwarf_Attribute *attr)
744 : internal_function;
745 :
746 : /* Load .debug_line unit at DEBUG_LINE_OFFSET. COMP_DIR is a value of
747 : DW_AT_comp_dir or NULL if that attribute is not available. Caches
748 : the loaded unit and optionally set *LINESP and/or *FILESP (if not
749 : NULL) with loaded information. Returns 0 for success or a negative
750 : value for failure. */
751 : int __libdw_getsrclines (Dwarf *dbg, Dwarf_Off debug_line_offset,
752 : const char *comp_dir, unsigned address_size,
753 : Dwarf_Lines **linesp, Dwarf_Files **filesp)
754 : internal_function
755 : __nonnull_attribute__ (1);
756 :
757 : /* Load and return value of DW_AT_comp_dir from CUDIE. */
758 : const char *__libdw_getcompdir (Dwarf_Die *cudie);
759 :
760 :
761 : /* Aliases to avoid PLTs. */
762 : INTDECL (dwarf_aggregate_size)
763 : INTDECL (dwarf_attr)
764 : INTDECL (dwarf_attr_integrate)
765 : INTDECL (dwarf_begin)
766 : INTDECL (dwarf_begin_elf)
767 : INTDECL (dwarf_child)
768 : INTDECL (dwarf_default_lower_bound)
769 : INTDECL (dwarf_dieoffset)
770 : INTDECL (dwarf_diename)
771 : INTDECL (dwarf_end)
772 : INTDECL (dwarf_entrypc)
773 : INTDECL (dwarf_errmsg)
774 : INTDECL (dwarf_formaddr)
775 : INTDECL (dwarf_formblock)
776 : INTDECL (dwarf_formref_die)
777 : INTDECL (dwarf_formsdata)
778 : INTDECL (dwarf_formstring)
779 : INTDECL (dwarf_formudata)
780 : INTDECL (dwarf_getalt)
781 : INTDECL (dwarf_getarange_addr)
782 : INTDECL (dwarf_getarangeinfo)
783 : INTDECL (dwarf_getaranges)
784 : INTDECL (dwarf_getlocation_die)
785 : INTDECL (dwarf_getsrcfiles)
786 : INTDECL (dwarf_getsrclines)
787 : INTDECL (dwarf_hasattr)
788 : INTDECL (dwarf_haschildren)
789 : INTDECL (dwarf_haspc)
790 : INTDECL (dwarf_highpc)
791 : INTDECL (dwarf_lowpc)
792 : INTDECL (dwarf_nextcu)
793 : INTDECL (dwarf_next_unit)
794 : INTDECL (dwarf_offdie)
795 : INTDECL (dwarf_peel_type)
796 : INTDECL (dwarf_ranges)
797 : INTDECL (dwarf_setalt)
798 : INTDECL (dwarf_siblingof)
799 : INTDECL (dwarf_srclang)
800 : INTDECL (dwarf_tag)
801 :
802 : #endif /* libdwP.h */
|