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