blob: 5ccb13c4bc831e10741ce959df528bc3e0239c53 [file] [log] [blame]
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001/* Internal definitions for libdwarf.
Mark Wielaarddf85bf92014-05-01 14:48:27 +02002 Copyright (C) 2002-2011, 2013, 2014 Red Hat, Inc.
Mark Wielaardde2ed972012-06-05 17:15:16 +02003 This file is part of elfutils.
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00004 Written by Ulrich Drepper <drepper@redhat.com>, 2002.
5
Mark Wielaardde2ed972012-06-05 17:15:16 +02006 This file is free software; you can redistribute it and/or modify
7 it under the terms of either
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00008
Mark Wielaardde2ed972012-06-05 17:15:16 +02009 * 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
Ulrich Drepper361df7d2006-04-04 21:38:57 +000022 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
Mark Wielaardde2ed972012-06-05 17:15:16 +020026 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/>. */
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000029
30#ifndef _LIBDWP_H
31#define _LIBDWP_H 1
32
33#include <libintl.h>
34#include <stdbool.h>
35
36#include <libdw.h>
Josh Stonec0d2a0b2013-12-09 13:52:10 -080037#include <dwarf.h>
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000038
39
40/* gettext helper macros. */
41#define _(Str) dgettext ("elfutils", Str)
42
43
Roland McGrath6724c902005-10-28 07:07:19 +000044/* Known location expressions already decoded. */
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000045struct loc_s
46{
47 void *addr;
Roland McGrath6724c902005-10-28 07:07:19 +000048 Dwarf_Op *loc;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000049 size_t nloc;
50};
51
Roland McGrathf0371042009-09-10 12:39:09 -070052/* 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. */
55struct loc_block_s
56{
57 void *addr;
58 unsigned char *data;
59 size_t length;
60};
61
Petr Machatafb90bf32014-10-17 02:47:03 +020062/* Already decoded .debug_line units. */
63struct files_lines_s
64{
65 Dwarf_Off debug_line_offset;
66 Dwarf_Files *files;
67 Dwarf_Lines *lines;
68};
69
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000070/* Valid indeces for the section data. */
71enum
72 {
73 IDX_debug_info = 0,
Roland McGrath827d4d12010-06-01 20:17:36 -070074 IDX_debug_types,
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000075 IDX_debug_abbrev,
76 IDX_debug_aranges,
77 IDX_debug_line,
78 IDX_debug_frame,
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000079 IDX_debug_loc,
80 IDX_debug_pubnames,
81 IDX_debug_str,
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000082 IDX_debug_macinfo,
Mark Wielaarda0172d72012-06-25 17:18:53 +020083 IDX_debug_macro,
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000084 IDX_debug_ranges,
Florian Weimerefa72a02014-04-15 14:04:19 +020085 IDX_gnu_debugaltlink,
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000086 IDX_last
87 };
88
89
90/* Error values. */
91enum
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_NOELF,
101 DWARF_E_GETEHDR_ERROR,
102 DWARF_E_NOMEM,
103 DWARF_E_UNIMPL,
104 DWARF_E_INVALID_CMD,
105 DWARF_E_INVALID_VERSION,
106 DWARF_E_INVALID_FILE,
107 DWARF_E_NO_ENTRY,
108 DWARF_E_INVALID_DWARF,
109 DWARF_E_NO_STRING,
110 DWARF_E_NO_ADDR,
111 DWARF_E_NO_CONSTANT,
112 DWARF_E_NO_REFERENCE,
113 DWARF_E_INVALID_REFERENCE,
114 DWARF_E_NO_DEBUG_LINE,
115 DWARF_E_INVALID_DEBUG_LINE,
116 DWARF_E_TOO_BIG,
117 DWARF_E_VERSION,
118 DWARF_E_INVALID_DIR_IDX,
119 DWARF_E_ADDR_OUTOFRANGE,
120 DWARF_E_NO_LOCLIST,
121 DWARF_E_NO_BLOCK,
122 DWARF_E_INVALID_LINE_IDX,
123 DWARF_E_INVALID_ARANGE_IDX,
124 DWARF_E_NO_MATCH,
125 DWARF_E_NO_FLAG,
126 DWARF_E_INVALID_OFFSET,
127 DWARF_E_NO_DEBUG_RANGES,
Roland McGrath3c84db32009-06-24 17:41:40 -0700128 DWARF_E_INVALID_CFI,
Petr Machatafb90bf32014-10-17 02:47:03 +0200129 DWARF_E_NO_ALT_DEBUGLINK,
130 DWARF_E_INVALID_OPCODE,
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000131};
132
133
Roland McGrath3e0f7d12010-06-15 23:10:35 -0700134#include "dwarf_sig8_hash.h"
135
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000136/* This is the structure representing the debugging state. */
137struct Dwarf
138{
139 /* The underlying ELF file. */
140 Elf *elf;
141
Mark Wielaard775375e2012-06-22 12:02:45 +0200142 /* dwz alternate DWARF file. */
143 Dwarf *alt_dwarf;
144
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000145 /* The section data. */
146 Elf_Data *sectiondata[IDX_last];
147
Roland McGrath725aad52011-02-23 19:52:46 -0800148#if USE_ZLIB
149 /* The 1 << N bit is set if sectiondata[N] is malloc'd decompressed data. */
150 unsigned int sectiondata_gzip_mask:IDX_last;
151#endif
152
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000153 /* True if the file has a byte order different from the host. */
154 bool other_byte_order;
155
156 /* If true, we allocated the ELF descriptor ourselves. */
157 bool free_elf;
158
159 /* Information for traversing the .debug_pubnames section. This is
160 an array and separately allocated with malloc. */
161 struct pubnames_s
162 {
163 Dwarf_Off cu_offset;
164 Dwarf_Off set_start;
165 unsigned int cu_header_size;
166 int address_len;
167 } *pubnames_sets;
168 size_t pubnames_nsets;
169
170 /* Search tree for the CUs. */
171 void *cu_tree;
172 Dwarf_Off next_cu_offset;
173
Roland McGrath2b1f0952010-06-20 17:55:50 -0700174 /* Search tree and sig8 hash table for .debug_types type units. */
175 void *tu_tree;
Roland McGrath3e0f7d12010-06-15 23:10:35 -0700176 Dwarf_Off next_tu_offset;
Roland McGrath2b1f0952010-06-20 17:55:50 -0700177 Dwarf_Sig8_Hash sig8_hash;
Roland McGrath3e0f7d12010-06-15 23:10:35 -0700178
Petr Machatafb90bf32014-10-17 02:47:03 +0200179 /* Search tree for .debug_macro operator tables. */
180 void *macro_ops;
181
182 /* Search tree for decoded .debug_line units. */
183 void *files_lines;
184
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000185 /* Address ranges. */
186 Dwarf_Aranges *aranges;
187
Roland McGrath3c84db32009-06-24 17:41:40 -0700188 /* Cached info from the CFI section. */
189 struct Dwarf_CFI_s *cfi;
190
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000191 /* Internal memory handling. This is basically a simplified
192 reimplementation of obstacks. Unfortunately the standard obstack
193 implementation is not usable in libraries. */
194 struct libdw_memblock
195 {
196 size_t size;
197 size_t remaining;
198 struct libdw_memblock *prev;
199 char mem[0];
200 } *mem_tail;
201
202 /* Default size of allocated memory blocks. */
203 size_t mem_default_size;
204
205 /* Registered OOM handler. */
206 Dwarf_OOM oom_handler;
207};
208
209
210/* Abbreviation representation. */
211struct Dwarf_Abbrev
212{
Roland McGrath1f6d2012008-12-31 00:21:04 -0800213 Dwarf_Off offset;
214 unsigned char *attrp;
215 unsigned int attrcnt;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000216 unsigned int code;
217 unsigned int tag;
Roland McGrath1f6d2012008-12-31 00:21:04 -0800218 bool has_children;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000219};
220
221#include "dwarf_abbrev_hash.h"
222
223
224/* Files in line information records. */
225struct Dwarf_Files_s
226 {
Roland McGrath43da9892007-04-16 23:13:37 +0000227 unsigned int ndirs;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000228 unsigned int nfiles;
229 struct Dwarf_Fileinfo_s
230 {
231 char *name;
232 Dwarf_Word mtime;
233 Dwarf_Word length;
234 } info[0];
Roland McGrath43da9892007-04-16 23:13:37 +0000235 /* nfiles of those, followed by char *[ndirs]. */
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000236 };
237typedef struct Dwarf_Fileinfo_s Dwarf_Fileinfo;
238
239
240/* Representation of a row in the line table. */
Roland McGrath03288f02009-01-28 22:00:54 -0800241
242struct Dwarf_Line_s
243{
Roland McGrath6e1f4652009-07-08 14:48:34 -0700244 Dwarf_Files *files;
245
Roland McGrath03288f02009-01-28 22:00:54 -0800246 Dwarf_Addr addr;
247 unsigned int file;
248 int line;
249 unsigned short int column;
250 unsigned int is_stmt:1;
251 unsigned int basic_block:1;
252 unsigned int end_sequence:1;
253 unsigned int prologue_end:1;
254 unsigned int epilogue_begin:1;
Roland McGrathc70cf4e2010-06-18 17:01:05 -0700255 /* The remaining bit fields are not flags, but hold values presumed to be
256 small. All the flags and other bit fields should add up to 48 bits
257 to give the whole struct a nice round size. */
258 unsigned int op_index:8;
259 unsigned int isa:8;
260 unsigned int discriminator:24;
Roland McGrath03288f02009-01-28 22:00:54 -0800261};
262
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000263struct Dwarf_Lines_s
Roland McGrath03288f02009-01-28 22:00:54 -0800264{
265 size_t nlines;
266 struct Dwarf_Line_s info[0];
267};
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000268
269/* Representation of address ranges. */
270struct Dwarf_Aranges_s
271{
272 Dwarf *dbg;
273 size_t naranges;
274
275 struct Dwarf_Arange_s
276 {
277 Dwarf_Addr addr;
278 Dwarf_Word length;
279 Dwarf_Off offset;
280 } info[0];
281};
282
283
284/* CU representation. */
285struct Dwarf_CU
286{
287 Dwarf *dbg;
288 Dwarf_Off start;
289 Dwarf_Off end;
290 uint8_t address_size;
291 uint8_t offset_size;
Roland McGrathe4c22ea2007-10-23 13:07:39 +0000292 uint16_t version;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000293
Roland McGrath3e0f7d12010-06-15 23:10:35 -0700294 /* Zero if this is a normal CU. Nonzero if it is a type unit. */
295 size_t type_offset;
296 uint64_t type_sig8;
297
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000298 /* Hash table for the abbreviations. */
299 Dwarf_Abbrev_Hash abbrev_hash;
300 /* Offset of the first abbreviation. */
301 size_t orig_abbrev_offset;
302 /* Offset past last read abbreviation. */
303 size_t last_abbrev_offset;
304
305 /* The srcline information. */
306 Dwarf_Lines *lines;
307
308 /* The source file information. */
309 Dwarf_Files *files;
310
311 /* Known location lists. */
312 void *locs;
313};
314
Ulrich Drepper35f08c42008-01-18 19:59:08 +0000315/* Compute the offset of a CU's first DIE from its offset. This
316 is either:
317 LEN VER OFFSET ADDR
318 4-bytes + 2-bytes + 4-bytes + 1-byte for 32-bit dwarf
319 12-bytes + 2-bytes + 8-bytes + 1-byte for 64-bit dwarf
Roland McGrath3e0f7d12010-06-15 23:10:35 -0700320 or in .debug_types, SIGNATURE TYPE-OFFSET
321 4-bytes + 2-bytes + 4-bytes + 1-byte + 8-bytes + 4-bytes for 32-bit
322 12-bytes + 2-bytes + 8-bytes + 1-byte + 8-bytes + 8-bytes for 64-bit
Ulrich Dreppera969d8e2008-01-22 06:15:00 +0000323
Ulrich Drepper35f08c42008-01-18 19:59:08 +0000324 Note the trick in the computation. If the offset_size is 4
325 the '- 4' term changes the '3 *' into a '2 *'. If the
326 offset_size is 8 it accounts for the 4-byte escape value
327 used at the start of the length. */
Roland McGrath3e0f7d12010-06-15 23:10:35 -0700328#define DIE_OFFSET_FROM_CU_OFFSET(cu_offset, offset_size, type_unit) \
329 ((type_unit) ? ((cu_offset) + 4 * (offset_size) - 4 + 3 + 8) \
330 : ((cu_offset) + 3 * (offset_size) - 4 + 3))
Ulrich Drepper35f08c42008-01-18 19:59:08 +0000331
Roland McGrath3e0f7d12010-06-15 23:10:35 -0700332#define CUDIE(fromcu) \
Roland McGrath6724c902005-10-28 07:07:19 +0000333 ((Dwarf_Die) \
334 { \
335 .cu = (fromcu), \
Roland McGrath5cc030d2010-06-20 17:25:35 -0700336 .addr = ((char *) cu_data (fromcu)->d_buf \
Roland McGrath3e0f7d12010-06-15 23:10:35 -0700337 + DIE_OFFSET_FROM_CU_OFFSET ((fromcu)->start, \
338 (fromcu)->offset_size, \
339 (fromcu)->type_offset != 0)) \
340 }) \
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000341
342
Petr Machatafb90bf32014-10-17 02:47:03 +0200343/* Prototype of a single .debug_macro operator. */
344typedef struct
345{
346 Dwarf_Word nforms;
347 unsigned char const *forms;
348} Dwarf_Macro_Op_Proto;
349
350/* Prototype table. */
351typedef struct
352{
353 /* Offset of .debug_macro section. */
354 Dwarf_Off offset;
355
356 /* Offset of associated .debug_line section. */
357 Dwarf_Off line_offset;
358
359 /* The source file information. */
360 Dwarf_Files *files;
361
362 /* If this macro unit was opened through dwarf_getmacros or
363 dwarf_getmacros_die, this caches value of DW_AT_comp_dir, if
364 present. */
365 const char *comp_dir;
366
367 /* Header length. */
368 Dwarf_Half header_len;
369
370 uint16_t version;
371 bool is_64bit;
372 uint8_t sec_index; /* IDX_debug_macro or IDX_debug_macinfo. */
373
374 /* Shows where in TABLE each opcode is defined. Since opcode 0 is
375 never used, it stores index of opcode X in X-1'th element. The
376 value of 0xff means not stored at all. */
377 unsigned char opcodes[255];
378
379 /* Individual opcode prototypes. */
380 Dwarf_Macro_Op_Proto table[];
381} Dwarf_Macro_Op_Table;
382
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000383struct Dwarf_Macro_s
384{
Petr Machatafb90bf32014-10-17 02:47:03 +0200385 Dwarf_Macro_Op_Table *table;
386 Dwarf_Attribute *attributes;
387 uint8_t opcode;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000388};
389
Petr Machatafb90bf32014-10-17 02:47:03 +0200390static inline Dwarf_Word
391libdw_macro_nforms (Dwarf_Macro *macro)
392{
393 return macro->table->table[macro->table->opcodes[macro->opcode - 1]].nforms;
394}
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000395
396/* We have to include the file at this point because the inline
397 functions access internals of the Dwarf structure. */
398#include "memory-access.h"
399
400
401/* Set error value. */
402extern void __libdw_seterrno (int value) internal_function;
403
404
405/* Memory handling, the easy parts. This macro does not do any locking. */
Ulrich Drepperdb1d5432006-10-10 15:34:34 +0000406#define libdw_alloc(dbg, type, tsize, cnt) \
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000407 ({ struct libdw_memblock *_tail = (dbg)->mem_tail; \
408 size_t _required = (tsize) * (cnt); \
409 type *_result = (type *) (_tail->mem + (_tail->size - _tail->remaining));\
410 size_t _padding = ((__alignof (type) \
411 - ((uintptr_t) _result & (__alignof (type) - 1))) \
412 & (__alignof (type) - 1)); \
413 if (unlikely (_tail->remaining < _required + _padding)) \
Roland McGrathc373d852006-10-10 00:25:21 +0000414 _result = (type *) __libdw_allocate (dbg, _required, __alignof (type));\
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000415 else \
416 { \
417 _required += _padding; \
418 _result = (type *) ((char *) _result + _padding); \
Roland McGrathc373d852006-10-10 00:25:21 +0000419 _tail->remaining -= _required; \
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000420 } \
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000421 _result; })
422
423#define libdw_typed_alloc(dbg, type) \
424 libdw_alloc (dbg, type, sizeof (type), 1)
425
426/* Callback to allocate more. */
Roland McGrathc373d852006-10-10 00:25:21 +0000427extern void *__libdw_allocate (Dwarf *dbg, size_t minsize, size_t align)
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000428 __attribute__ ((__malloc__)) __nonnull_attribute__ (1);
429
430/* Default OOM handler. */
431extern void __libdw_oom (void) __attribute ((noreturn, visibility ("hidden")));
432
Roland McGrath725aad52011-02-23 19:52:46 -0800433#if USE_ZLIB
434extern void __libdw_free_zdata (Dwarf *dwarf) internal_function;
435#else
436# define __libdw_free_zdata(dwarf) ((void) (dwarf))
437#endif
438
Roland McGrath3e0f7d12010-06-15 23:10:35 -0700439/* Allocate the internal data for a unit not seen before. */
440extern struct Dwarf_CU *__libdw_intern_next_unit (Dwarf *dbg, bool debug_types)
441 __nonnull_attribute__ (1) internal_function;
442
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000443/* Find CU for given offset. */
Roland McGrath2b1f0952010-06-20 17:55:50 -0700444extern struct Dwarf_CU *__libdw_findcu (Dwarf *dbg, Dwarf_Off offset, bool tu)
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000445 __nonnull_attribute__ (1) internal_function;
446
447/* Return tag of given DIE. */
448extern 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. */
453extern 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/* Helper functions for form handling. */
Josh Stonec0d2a0b2013-12-09 13:52:10 -0800459extern size_t __libdw_form_val_compute_len (Dwarf *dbg, struct Dwarf_CU *cu,
460 unsigned int form,
461 const unsigned char *valp)
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000462 __nonnull_attribute__ (1, 2, 4) internal_function;
463
Josh Stonec0d2a0b2013-12-09 13:52:10 -0800464/* Find the length of a form attribute. */
465static inline size_t
466__nonnull_attribute__ (1, 2, 4)
467__libdw_form_val_len (Dwarf *dbg, struct Dwarf_CU *cu,
468 unsigned int form, const unsigned char *valp)
469{
470 /* Small lookup table of forms with fixed lengths. Absent indexes are
471 initialized 0, so any truly desired 0 is set to 0x80 and masked. */
472 static const uint8_t form_lengths[] =
473 {
474 [DW_FORM_flag_present] = 0x80,
475 [DW_FORM_data1] = 1, [DW_FORM_ref1] = 1, [DW_FORM_flag] = 1,
476 [DW_FORM_data2] = 2, [DW_FORM_ref2] = 2,
477 [DW_FORM_data4] = 4, [DW_FORM_ref4] = 4,
478 [DW_FORM_data8] = 8, [DW_FORM_ref8] = 8, [DW_FORM_ref_sig8] = 8,
479 };
480
481 /* Return immediately for forms with fixed lengths. */
482 if (form < sizeof form_lengths / sizeof form_lengths[0])
483 {
484 uint8_t len = form_lengths[form];
485 if (len != 0)
486 return len & 0x7f; /* Mask to allow 0x80 -> 0. */
487 }
488
489 /* Other forms require some computation. */
490 return __libdw_form_val_compute_len (dbg, cu, form, valp);
491}
492
Roland McGrathe4c22ea2007-10-23 13:07:39 +0000493/* Helper function for DW_FORM_ref* handling. */
494extern int __libdw_formref (Dwarf_Attribute *attr, Dwarf_Off *return_offset)
495 __nonnull_attribute__ (1, 2) internal_function;
496
497
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000498/* Helper function to locate attribute. */
499extern unsigned char *__libdw_find_attr (Dwarf_Die *die,
500 unsigned int search_name,
501 unsigned int *codep,
502 unsigned int *formp)
503 __nonnull_attribute__ (1) internal_function;
504
505/* Helper function to access integer attribute. */
Roland McGrath6724c902005-10-28 07:07:19 +0000506extern int __libdw_attr_intval (Dwarf_Die *die, int *valp, int attval)
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000507 __nonnull_attribute__ (1, 2) internal_function;
508
Roland McGrath1ecb6062005-08-15 09:53:04 +0000509/* Helper function to walk scopes. */
Roland McGrath71e15a02005-08-27 10:33:26 +0000510struct Dwarf_Die_Chain
511{
512 Dwarf_Die die;
513 struct Dwarf_Die_Chain *parent;
514 bool prune; /* The PREVISIT function can set this. */
515};
516extern int __libdw_visit_scopes (unsigned int depth,
517 struct Dwarf_Die_Chain *root,
518 int (*previsit) (unsigned int depth,
519 struct Dwarf_Die_Chain *,
520 void *arg),
521 int (*postvisit) (unsigned int depth,
522 struct Dwarf_Die_Chain *,
523 void *arg),
Roland McGrath1ecb6062005-08-15 09:53:04 +0000524 void *arg)
525 __nonnull_attribute__ (2, 3) internal_function;
526
Roland McGrath3c84db32009-06-24 17:41:40 -0700527/* Parse a DWARF Dwarf_Block into an array of Dwarf_Op's,
528 and cache the result (via tsearch). */
529extern int __libdw_intern_expression (Dwarf *dbg,
530 bool other_byte_order,
531 unsigned int address_size,
Roland McGrath688f7fc2010-05-08 03:22:59 -0700532 unsigned int ref_size,
Roland McGrath3c84db32009-06-24 17:41:40 -0700533 void **cache, const Dwarf_Block *block,
Roland McGrath0ab97832010-04-26 11:50:27 -0700534 bool cfap, bool valuep,
Roland McGrath3c84db32009-06-24 17:41:40 -0700535 Dwarf_Op **llbuf, size_t *listlen,
536 int sec_index)
Roland McGrath688f7fc2010-05-08 03:22:59 -0700537 __nonnull_attribute__ (5, 6, 9, 10) internal_function;
Roland McGrath3c84db32009-06-24 17:41:40 -0700538
Roland McGrath932585d2010-05-08 04:01:14 -0700539extern Dwarf_Die *__libdw_offdie (Dwarf *dbg, Dwarf_Off offset,
540 Dwarf_Die *result, bool debug_types)
541 internal_function;
542
Roland McGrath3c84db32009-06-24 17:41:40 -0700543
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000544/* Return error code of last failing function call. This value is kept
545 separately for each thread. */
546extern int __dwarf_errno_internal (void);
547
548
Ulrich Drepper99d23722009-06-14 20:19:45 -0700549/* Reader hooks. */
550
551/* Relocation hooks return -1 on error (in that case the error code
552 must already have been set), 0 if there is no relocation and 1 if a
553 relocation was present.*/
554
555static inline int
556__libdw_relocate_address (Dwarf *dbg __attribute__ ((unused)),
557 int sec_index __attribute__ ((unused)),
558 const void *addr __attribute__ ((unused)),
559 int width __attribute__ ((unused)),
560 Dwarf_Addr *val __attribute__ ((unused)))
561{
562 return 0;
563}
564
565static inline int
566__libdw_relocate_offset (Dwarf *dbg __attribute__ ((unused)),
567 int sec_index __attribute__ ((unused)),
568 const void *addr __attribute__ ((unused)),
569 int width __attribute__ ((unused)),
570 Dwarf_Off *val __attribute__ ((unused)))
571{
572 return 0;
573}
574
575static inline Elf_Data *
576__libdw_checked_get_data (Dwarf *dbg, int sec_index)
577{
578 Elf_Data *data = dbg->sectiondata[sec_index];
579 if (unlikely (data == NULL)
580 || unlikely (data->d_buf == NULL))
581 {
582 __libdw_seterrno (DWARF_E_INVALID_DWARF);
583 return NULL;
584 }
585 return data;
586}
587
588static inline int
589__libdw_offset_in_section (Dwarf *dbg, int sec_index,
590 Dwarf_Off offset, size_t size)
591{
592 Elf_Data *data = __libdw_checked_get_data (dbg, sec_index);
593 if (data == NULL)
594 return -1;
595 if (unlikely (offset > data->d_size)
596 || unlikely (data->d_size - offset < size))
597 {
598 __libdw_seterrno (DWARF_E_INVALID_OFFSET);
599 return -1;
600 }
601
602 return 0;
603}
604
605static inline bool
606__libdw_in_section (Dwarf *dbg, int sec_index,
607 const void *addr, size_t size)
608{
609 Elf_Data *data = __libdw_checked_get_data (dbg, sec_index);
610 if (data == NULL)
611 return false;
612 if (unlikely (addr < data->d_buf)
613 || unlikely (data->d_size - (addr - data->d_buf) < size))
614 {
615 __libdw_seterrno (DWARF_E_INVALID_OFFSET);
616 return false;
617 }
618
619 return true;
620}
621
622#define READ_AND_RELOCATE(RELOC_HOOK, VAL) \
623 ({ \
624 if (!__libdw_in_section (dbg, sec_index, addr, width)) \
625 return -1; \
626 \
627 const unsigned char *orig_addr = addr; \
628 if (width == 4) \
629 VAL = read_4ubyte_unaligned_inc (dbg, addr); \
630 else \
631 VAL = read_8ubyte_unaligned_inc (dbg, addr); \
632 \
633 int status = RELOC_HOOK (dbg, sec_index, orig_addr, width, &VAL); \
634 if (status < 0) \
635 return status; \
636 status > 0; \
637 })
638
639static inline int
640__libdw_read_address_inc (Dwarf *dbg,
Roland McGrath05c4e042009-06-18 13:56:02 -0700641 int sec_index, const unsigned char **addrp,
Ulrich Drepper99d23722009-06-14 20:19:45 -0700642 int width, Dwarf_Addr *ret)
643{
Roland McGrath05c4e042009-06-18 13:56:02 -0700644 const unsigned char *addr = *addrp;
Ulrich Drepper99d23722009-06-14 20:19:45 -0700645 READ_AND_RELOCATE (__libdw_relocate_address, (*ret));
646 *addrp = addr;
647 return 0;
648}
649
650static inline int
651__libdw_read_address (Dwarf *dbg,
652 int sec_index, const unsigned char *addr,
653 int width, Dwarf_Addr *ret)
654{
655 READ_AND_RELOCATE (__libdw_relocate_address, (*ret));
656 return 0;
657}
658
659static inline int
660__libdw_read_offset_inc (Dwarf *dbg,
Roland McGrath05c4e042009-06-18 13:56:02 -0700661 int sec_index, const unsigned char **addrp,
Ulrich Drepper99d23722009-06-14 20:19:45 -0700662 int width, Dwarf_Off *ret, int sec_ret,
663 size_t size)
664{
Roland McGrath05c4e042009-06-18 13:56:02 -0700665 const unsigned char *addr = *addrp;
Ulrich Drepper99d23722009-06-14 20:19:45 -0700666 READ_AND_RELOCATE (__libdw_relocate_offset, (*ret));
667 *addrp = addr;
668 return __libdw_offset_in_section (dbg, sec_ret, *ret, size);
669}
670
671static inline int
Mark Wielaard775375e2012-06-22 12:02:45 +0200672__libdw_read_offset (Dwarf *dbg, Dwarf *dbg_ret,
Ulrich Drepper99d23722009-06-14 20:19:45 -0700673 int sec_index, const unsigned char *addr,
674 int width, Dwarf_Off *ret, int sec_ret,
675 size_t size)
676{
677 READ_AND_RELOCATE (__libdw_relocate_offset, (*ret));
Mark Wielaard775375e2012-06-22 12:02:45 +0200678 return __libdw_offset_in_section (dbg_ret, sec_ret, *ret, size);
Ulrich Drepper99d23722009-06-14 20:19:45 -0700679}
680
Roland McGrath3e0f7d12010-06-15 23:10:35 -0700681static inline size_t
682cu_sec_idx (struct Dwarf_CU *cu)
683{
684 return cu->type_offset == 0 ? IDX_debug_info : IDX_debug_types;
685}
686
687static inline Elf_Data *
688cu_data (struct Dwarf_CU *cu)
689{
690 return cu->dbg->sectiondata[cu_sec_idx (cu)];
691}
692
Ulrich Drepper99d23722009-06-14 20:19:45 -0700693/* Read up begin/end pair and increment read pointer.
694 - If it's normal range record, set up *BEGINP and *ENDP and return 0.
695 - If it's base address selection record, set up *BASEP and return 1.
696 - If it's end of rangelist, don't set anything and return 2
697 - If an error occurs, don't set anything and return <0. */
698int __libdw_read_begin_end_pair_inc (Dwarf *dbg, int sec_index,
699 unsigned char **addr, int width,
700 Dwarf_Addr *beginp, Dwarf_Addr *endp,
701 Dwarf_Addr *basep)
702 internal_function;
703
704unsigned char * __libdw_formptr (Dwarf_Attribute *attr, int sec_index,
705 int err_nodata, unsigned char **endpp,
706 Dwarf_Off *offsetp)
707 internal_function;
708
Mark Wielaard3951f2e2013-12-09 16:33:26 +0100709/* Fills in the given attribute to point at an empty location expression. */
710void __libdw_empty_loc_attr (Dwarf_Attribute *attr, struct Dwarf_CU *cu)
711 internal_function;
712
Petr Machatafb90bf32014-10-17 02:47:03 +0200713/* Load .debug_line unit at DEBUG_LINE_OFFSET. COMP_DIR is a value of
714 DW_AT_comp_dir or NULL if that attribute is not available. Caches
715 the loaded unit and optionally set *LINESP and/or *FILESP (if not
716 NULL) with loaded information. Returns 0 for success or a negative
717 value for failure. */
718int __libdw_getsrclines (Dwarf *dbg, Dwarf_Off debug_line_offset,
719 const char *comp_dir, unsigned address_size,
720 Dwarf_Lines **linesp, Dwarf_Files **filesp)
721 internal_function
722 __nonnull_attribute__ (1);
723
724/* Load and return value of DW_AT_comp_dir from CUDIE. */
725const char *__libdw_getcompdir (Dwarf_Die *cudie);
726
Ulrich Drepper99d23722009-06-14 20:19:45 -0700727
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000728/* Aliases to avoid PLTs. */
Roland McGrathebc5c882010-01-05 22:53:31 -0800729INTDECL (dwarf_aggregate_size)
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000730INTDECL (dwarf_attr)
731INTDECL (dwarf_attr_integrate)
Mark Wielaard775375e2012-06-22 12:02:45 +0200732INTDECL (dwarf_begin)
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000733INTDECL (dwarf_begin_elf)
734INTDECL (dwarf_child)
735INTDECL (dwarf_dieoffset)
Roland McGrath71e15a02005-08-27 10:33:26 +0000736INTDECL (dwarf_diename)
Roland McGrath4959bf82005-08-09 10:31:08 +0000737INTDECL (dwarf_end)
Roland McGrath07d4f2f2005-10-28 06:56:24 +0000738INTDECL (dwarf_entrypc)
Roland McGrath4959bf82005-08-09 10:31:08 +0000739INTDECL (dwarf_errmsg)
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000740INTDECL (dwarf_formaddr)
741INTDECL (dwarf_formblock)
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000742INTDECL (dwarf_formref_die)
743INTDECL (dwarf_formsdata)
744INTDECL (dwarf_formstring)
745INTDECL (dwarf_formudata)
Florian Weimer35e2a762014-04-15 14:31:55 +0200746INTDECL (dwarf_getalt)
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000747INTDECL (dwarf_getarange_addr)
748INTDECL (dwarf_getarangeinfo)
749INTDECL (dwarf_getaranges)
Mark Wielaardb2535b62013-08-30 23:55:12 +0200750INTDECL (dwarf_getlocation_die)
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000751INTDECL (dwarf_getsrcfiles)
752INTDECL (dwarf_getsrclines)
753INTDECL (dwarf_hasattr)
754INTDECL (dwarf_haschildren)
755INTDECL (dwarf_haspc)
756INTDECL (dwarf_highpc)
757INTDECL (dwarf_lowpc)
758INTDECL (dwarf_nextcu)
Roland McGrath3e0f7d12010-06-15 23:10:35 -0700759INTDECL (dwarf_next_unit)
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000760INTDECL (dwarf_offdie)
Mark Wielaard3a36e8a2014-10-06 22:00:16 +0200761INTDECL (dwarf_peel_type)
Roland McGrath07d4f2f2005-10-28 06:56:24 +0000762INTDECL (dwarf_ranges)
Florian Weimer35e2a762014-04-15 14:31:55 +0200763INTDECL (dwarf_setalt)
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000764INTDECL (dwarf_siblingof)
Roland McGrathebc5c882010-01-05 22:53:31 -0800765INTDECL (dwarf_srclang)
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000766INTDECL (dwarf_tag)
767
768#endif /* libdwP.h */