dwarf.c revision 1.1.1.1.4.2 1 1.1.1.1.4.2 yamt /* dwarf.c -- Get file/line information from DWARF for backtraces.
2 1.1.1.1.4.2 yamt Copyright (C) 2012-2013 Free Software Foundation, Inc.
3 1.1.1.1.4.2 yamt Written by Ian Lance Taylor, Google.
4 1.1.1.1.4.2 yamt
5 1.1.1.1.4.2 yamt Redistribution and use in source and binary forms, with or without
6 1.1.1.1.4.2 yamt modification, are permitted provided that the following conditions are
7 1.1.1.1.4.2 yamt met:
8 1.1.1.1.4.2 yamt
9 1.1.1.1.4.2 yamt (1) Redistributions of source code must retain the above copyright
10 1.1.1.1.4.2 yamt notice, this list of conditions and the following disclaimer.
11 1.1.1.1.4.2 yamt
12 1.1.1.1.4.2 yamt (2) Redistributions in binary form must reproduce the above copyright
13 1.1.1.1.4.2 yamt notice, this list of conditions and the following disclaimer in
14 1.1.1.1.4.2 yamt the documentation and/or other materials provided with the
15 1.1.1.1.4.2 yamt distribution.
16 1.1.1.1.4.2 yamt
17 1.1.1.1.4.2 yamt (3) The name of the author may not be used to
18 1.1.1.1.4.2 yamt endorse or promote products derived from this software without
19 1.1.1.1.4.2 yamt specific prior written permission.
20 1.1.1.1.4.2 yamt
21 1.1.1.1.4.2 yamt THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 1.1.1.1.4.2 yamt IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 1.1.1.1.4.2 yamt WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 1.1.1.1.4.2 yamt DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
25 1.1.1.1.4.2 yamt INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 1.1.1.1.4.2 yamt (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 1.1.1.1.4.2 yamt SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 1.1.1.1.4.2 yamt HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29 1.1.1.1.4.2 yamt STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
30 1.1.1.1.4.2 yamt IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 1.1.1.1.4.2 yamt POSSIBILITY OF SUCH DAMAGE. */
32 1.1.1.1.4.2 yamt
33 1.1.1.1.4.2 yamt #include "config.h"
34 1.1.1.1.4.2 yamt
35 1.1.1.1.4.2 yamt #include <errno.h>
36 1.1.1.1.4.2 yamt #include <stdlib.h>
37 1.1.1.1.4.2 yamt #include <string.h>
38 1.1.1.1.4.2 yamt #include <sys/types.h>
39 1.1.1.1.4.2 yamt
40 1.1.1.1.4.2 yamt #include "dwarf2.h"
41 1.1.1.1.4.2 yamt #include "filenames.h"
42 1.1.1.1.4.2 yamt
43 1.1.1.1.4.2 yamt #include "backtrace.h"
44 1.1.1.1.4.2 yamt #include "internal.h"
45 1.1.1.1.4.2 yamt
46 1.1.1.1.4.2 yamt #if !defined(HAVE_DECL_STRNLEN) || !HAVE_DECL_STRNLEN
47 1.1.1.1.4.2 yamt
48 1.1.1.1.4.2 yamt /* If strnlen is not declared, provide our own version. */
49 1.1.1.1.4.2 yamt
50 1.1.1.1.4.2 yamt static size_t
51 1.1.1.1.4.2 yamt xstrnlen (const char *s, size_t maxlen)
52 1.1.1.1.4.2 yamt {
53 1.1.1.1.4.2 yamt size_t i;
54 1.1.1.1.4.2 yamt
55 1.1.1.1.4.2 yamt for (i = 0; i < maxlen; ++i)
56 1.1.1.1.4.2 yamt if (s[i] == '\0')
57 1.1.1.1.4.2 yamt break;
58 1.1.1.1.4.2 yamt return i;
59 1.1.1.1.4.2 yamt }
60 1.1.1.1.4.2 yamt
61 1.1.1.1.4.2 yamt #define strnlen xstrnlen
62 1.1.1.1.4.2 yamt
63 1.1.1.1.4.2 yamt #endif
64 1.1.1.1.4.2 yamt
65 1.1.1.1.4.2 yamt /* A buffer to read DWARF info. */
66 1.1.1.1.4.2 yamt
67 1.1.1.1.4.2 yamt struct dwarf_buf
68 1.1.1.1.4.2 yamt {
69 1.1.1.1.4.2 yamt /* Buffer name for error messages. */
70 1.1.1.1.4.2 yamt const char *name;
71 1.1.1.1.4.2 yamt /* Start of the buffer. */
72 1.1.1.1.4.2 yamt const unsigned char *start;
73 1.1.1.1.4.2 yamt /* Next byte to read. */
74 1.1.1.1.4.2 yamt const unsigned char *buf;
75 1.1.1.1.4.2 yamt /* The number of bytes remaining. */
76 1.1.1.1.4.2 yamt size_t left;
77 1.1.1.1.4.2 yamt /* Whether the data is big-endian. */
78 1.1.1.1.4.2 yamt int is_bigendian;
79 1.1.1.1.4.2 yamt /* Error callback routine. */
80 1.1.1.1.4.2 yamt backtrace_error_callback error_callback;
81 1.1.1.1.4.2 yamt /* Data for error_callback. */
82 1.1.1.1.4.2 yamt void *data;
83 1.1.1.1.4.2 yamt /* Non-zero if we've reported an underflow error. */
84 1.1.1.1.4.2 yamt int reported_underflow;
85 1.1.1.1.4.2 yamt };
86 1.1.1.1.4.2 yamt
87 1.1.1.1.4.2 yamt /* A single attribute in a DWARF abbreviation. */
88 1.1.1.1.4.2 yamt
89 1.1.1.1.4.2 yamt struct attr
90 1.1.1.1.4.2 yamt {
91 1.1.1.1.4.2 yamt /* The attribute name. */
92 1.1.1.1.4.2 yamt enum dwarf_attribute name;
93 1.1.1.1.4.2 yamt /* The attribute form. */
94 1.1.1.1.4.2 yamt enum dwarf_form form;
95 1.1.1.1.4.2 yamt };
96 1.1.1.1.4.2 yamt
97 1.1.1.1.4.2 yamt /* A single DWARF abbreviation. */
98 1.1.1.1.4.2 yamt
99 1.1.1.1.4.2 yamt struct abbrev
100 1.1.1.1.4.2 yamt {
101 1.1.1.1.4.2 yamt /* The abbrev code--the number used to refer to the abbrev. */
102 1.1.1.1.4.2 yamt uint64_t code;
103 1.1.1.1.4.2 yamt /* The entry tag. */
104 1.1.1.1.4.2 yamt enum dwarf_tag tag;
105 1.1.1.1.4.2 yamt /* Non-zero if this abbrev has child entries. */
106 1.1.1.1.4.2 yamt int has_children;
107 1.1.1.1.4.2 yamt /* The number of attributes. */
108 1.1.1.1.4.2 yamt size_t num_attrs;
109 1.1.1.1.4.2 yamt /* The attributes. */
110 1.1.1.1.4.2 yamt struct attr *attrs;
111 1.1.1.1.4.2 yamt };
112 1.1.1.1.4.2 yamt
113 1.1.1.1.4.2 yamt /* The DWARF abbreviations for a compilation unit. This structure
114 1.1.1.1.4.2 yamt only exists while reading the compilation unit. Most DWARF readers
115 1.1.1.1.4.2 yamt seem to a hash table to map abbrev ID's to abbrev entries.
116 1.1.1.1.4.2 yamt However, we primarily care about GCC, and GCC simply issues ID's in
117 1.1.1.1.4.2 yamt numerical order starting at 1. So we simply keep a sorted vector,
118 1.1.1.1.4.2 yamt and try to just look up the code. */
119 1.1.1.1.4.2 yamt
120 1.1.1.1.4.2 yamt struct abbrevs
121 1.1.1.1.4.2 yamt {
122 1.1.1.1.4.2 yamt /* The number of abbrevs in the vector. */
123 1.1.1.1.4.2 yamt size_t num_abbrevs;
124 1.1.1.1.4.2 yamt /* The abbrevs, sorted by the code field. */
125 1.1.1.1.4.2 yamt struct abbrev *abbrevs;
126 1.1.1.1.4.2 yamt };
127 1.1.1.1.4.2 yamt
128 1.1.1.1.4.2 yamt /* The different kinds of attribute values. */
129 1.1.1.1.4.2 yamt
130 1.1.1.1.4.2 yamt enum attr_val_encoding
131 1.1.1.1.4.2 yamt {
132 1.1.1.1.4.2 yamt /* An address. */
133 1.1.1.1.4.2 yamt ATTR_VAL_ADDRESS,
134 1.1.1.1.4.2 yamt /* A unsigned integer. */
135 1.1.1.1.4.2 yamt ATTR_VAL_UINT,
136 1.1.1.1.4.2 yamt /* A sigd integer. */
137 1.1.1.1.4.2 yamt ATTR_VAL_SINT,
138 1.1.1.1.4.2 yamt /* A string. */
139 1.1.1.1.4.2 yamt ATTR_VAL_STRING,
140 1.1.1.1.4.2 yamt /* An offset to other data in the containing unit. */
141 1.1.1.1.4.2 yamt ATTR_VAL_REF_UNIT,
142 1.1.1.1.4.2 yamt /* An offset to other data within the .dwarf_info section. */
143 1.1.1.1.4.2 yamt ATTR_VAL_REF_INFO,
144 1.1.1.1.4.2 yamt /* An offset to data in some other section. */
145 1.1.1.1.4.2 yamt ATTR_VAL_REF_SECTION,
146 1.1.1.1.4.2 yamt /* A type signature. */
147 1.1.1.1.4.2 yamt ATTR_VAL_REF_TYPE,
148 1.1.1.1.4.2 yamt /* A block of data (not represented). */
149 1.1.1.1.4.2 yamt ATTR_VAL_BLOCK,
150 1.1.1.1.4.2 yamt /* An expression (not represented). */
151 1.1.1.1.4.2 yamt ATTR_VAL_EXPR,
152 1.1.1.1.4.2 yamt };
153 1.1.1.1.4.2 yamt
154 1.1.1.1.4.2 yamt /* An attribute value. */
155 1.1.1.1.4.2 yamt
156 1.1.1.1.4.2 yamt struct attr_val
157 1.1.1.1.4.2 yamt {
158 1.1.1.1.4.2 yamt /* How the value is stored in the field u. */
159 1.1.1.1.4.2 yamt enum attr_val_encoding encoding;
160 1.1.1.1.4.2 yamt union
161 1.1.1.1.4.2 yamt {
162 1.1.1.1.4.2 yamt /* ATTR_VAL_ADDRESS, ATTR_VAL_UINT, ATTR_VAL_REF*. */
163 1.1.1.1.4.2 yamt uint64_t uint;
164 1.1.1.1.4.2 yamt /* ATTR_VAL_SINT. */
165 1.1.1.1.4.2 yamt int64_t sint;
166 1.1.1.1.4.2 yamt /* ATTR_VAL_STRING. */
167 1.1.1.1.4.2 yamt const char *string;
168 1.1.1.1.4.2 yamt /* ATTR_VAL_BLOCK not stored. */
169 1.1.1.1.4.2 yamt } u;
170 1.1.1.1.4.2 yamt };
171 1.1.1.1.4.2 yamt
172 1.1.1.1.4.2 yamt /* The line number program header. */
173 1.1.1.1.4.2 yamt
174 1.1.1.1.4.2 yamt struct line_header
175 1.1.1.1.4.2 yamt {
176 1.1.1.1.4.2 yamt /* The version of the line number information. */
177 1.1.1.1.4.2 yamt int version;
178 1.1.1.1.4.2 yamt /* The minimum instruction length. */
179 1.1.1.1.4.2 yamt unsigned int min_insn_len;
180 1.1.1.1.4.2 yamt /* The maximum number of ops per instruction. */
181 1.1.1.1.4.2 yamt unsigned int max_ops_per_insn;
182 1.1.1.1.4.2 yamt /* The line base for special opcodes. */
183 1.1.1.1.4.2 yamt int line_base;
184 1.1.1.1.4.2 yamt /* The line range for special opcodes. */
185 1.1.1.1.4.2 yamt unsigned int line_range;
186 1.1.1.1.4.2 yamt /* The opcode base--the first special opcode. */
187 1.1.1.1.4.2 yamt unsigned int opcode_base;
188 1.1.1.1.4.2 yamt /* Opcode lengths, indexed by opcode - 1. */
189 1.1.1.1.4.2 yamt const unsigned char *opcode_lengths;
190 1.1.1.1.4.2 yamt /* The number of directory entries. */
191 1.1.1.1.4.2 yamt size_t dirs_count;
192 1.1.1.1.4.2 yamt /* The directory entries. */
193 1.1.1.1.4.2 yamt const char **dirs;
194 1.1.1.1.4.2 yamt /* The number of filenames. */
195 1.1.1.1.4.2 yamt size_t filenames_count;
196 1.1.1.1.4.2 yamt /* The filenames. */
197 1.1.1.1.4.2 yamt const char **filenames;
198 1.1.1.1.4.2 yamt };
199 1.1.1.1.4.2 yamt
200 1.1.1.1.4.2 yamt /* Map a single PC value to a file/line. We will keep a vector of
201 1.1.1.1.4.2 yamt these sorted by PC value. Each file/line will be correct from the
202 1.1.1.1.4.2 yamt PC up to the PC of the next entry if there is one. We allocate one
203 1.1.1.1.4.2 yamt extra entry at the end so that we can use bsearch. */
204 1.1.1.1.4.2 yamt
205 1.1.1.1.4.2 yamt struct line
206 1.1.1.1.4.2 yamt {
207 1.1.1.1.4.2 yamt /* PC. */
208 1.1.1.1.4.2 yamt uintptr_t pc;
209 1.1.1.1.4.2 yamt /* File name. Many entries in the array are expected to point to
210 1.1.1.1.4.2 yamt the same file name. */
211 1.1.1.1.4.2 yamt const char *filename;
212 1.1.1.1.4.2 yamt /* Line number. */
213 1.1.1.1.4.2 yamt int lineno;
214 1.1.1.1.4.2 yamt };
215 1.1.1.1.4.2 yamt
216 1.1.1.1.4.2 yamt /* A growable vector of line number information. This is used while
217 1.1.1.1.4.2 yamt reading the line numbers. */
218 1.1.1.1.4.2 yamt
219 1.1.1.1.4.2 yamt struct line_vector
220 1.1.1.1.4.2 yamt {
221 1.1.1.1.4.2 yamt /* Memory. This is an array of struct line. */
222 1.1.1.1.4.2 yamt struct backtrace_vector vec;
223 1.1.1.1.4.2 yamt /* Number of valid mappings. */
224 1.1.1.1.4.2 yamt size_t count;
225 1.1.1.1.4.2 yamt };
226 1.1.1.1.4.2 yamt
227 1.1.1.1.4.2 yamt /* A function described in the debug info. */
228 1.1.1.1.4.2 yamt
229 1.1.1.1.4.2 yamt struct function
230 1.1.1.1.4.2 yamt {
231 1.1.1.1.4.2 yamt /* The name of the function. */
232 1.1.1.1.4.2 yamt const char *name;
233 1.1.1.1.4.2 yamt /* If this is an inlined function, the filename of the call
234 1.1.1.1.4.2 yamt site. */
235 1.1.1.1.4.2 yamt const char *caller_filename;
236 1.1.1.1.4.2 yamt /* If this is an inlined function, the line number of the call
237 1.1.1.1.4.2 yamt site. */
238 1.1.1.1.4.2 yamt int caller_lineno;
239 1.1.1.1.4.2 yamt /* Map PC ranges to inlined functions. */
240 1.1.1.1.4.2 yamt struct function_addrs *function_addrs;
241 1.1.1.1.4.2 yamt size_t function_addrs_count;
242 1.1.1.1.4.2 yamt };
243 1.1.1.1.4.2 yamt
244 1.1.1.1.4.2 yamt /* An address range for a function. This maps a PC value to a
245 1.1.1.1.4.2 yamt specific function. */
246 1.1.1.1.4.2 yamt
247 1.1.1.1.4.2 yamt struct function_addrs
248 1.1.1.1.4.2 yamt {
249 1.1.1.1.4.2 yamt /* Range is LOW <= PC < HIGH. */
250 1.1.1.1.4.2 yamt uint64_t low;
251 1.1.1.1.4.2 yamt uint64_t high;
252 1.1.1.1.4.2 yamt /* Function for this address range. */
253 1.1.1.1.4.2 yamt struct function *function;
254 1.1.1.1.4.2 yamt };
255 1.1.1.1.4.2 yamt
256 1.1.1.1.4.2 yamt /* A growable vector of function address ranges. */
257 1.1.1.1.4.2 yamt
258 1.1.1.1.4.2 yamt struct function_vector
259 1.1.1.1.4.2 yamt {
260 1.1.1.1.4.2 yamt /* Memory. This is an array of struct function_addrs. */
261 1.1.1.1.4.2 yamt struct backtrace_vector vec;
262 1.1.1.1.4.2 yamt /* Number of address ranges present. */
263 1.1.1.1.4.2 yamt size_t count;
264 1.1.1.1.4.2 yamt };
265 1.1.1.1.4.2 yamt
266 1.1.1.1.4.2 yamt /* A DWARF compilation unit. This only holds the information we need
267 1.1.1.1.4.2 yamt to map a PC to a file and line. */
268 1.1.1.1.4.2 yamt
269 1.1.1.1.4.2 yamt struct unit
270 1.1.1.1.4.2 yamt {
271 1.1.1.1.4.2 yamt /* The first entry for this compilation unit. */
272 1.1.1.1.4.2 yamt const unsigned char *unit_data;
273 1.1.1.1.4.2 yamt /* The length of the data for this compilation unit. */
274 1.1.1.1.4.2 yamt size_t unit_data_len;
275 1.1.1.1.4.2 yamt /* The offset of UNIT_DATA from the start of the information for
276 1.1.1.1.4.2 yamt this compilation unit. */
277 1.1.1.1.4.2 yamt size_t unit_data_offset;
278 1.1.1.1.4.2 yamt /* DWARF version. */
279 1.1.1.1.4.2 yamt int version;
280 1.1.1.1.4.2 yamt /* Whether unit is DWARF64. */
281 1.1.1.1.4.2 yamt int is_dwarf64;
282 1.1.1.1.4.2 yamt /* Address size. */
283 1.1.1.1.4.2 yamt int addrsize;
284 1.1.1.1.4.2 yamt /* Offset into line number information. */
285 1.1.1.1.4.2 yamt off_t lineoff;
286 1.1.1.1.4.2 yamt /* Primary source file. */
287 1.1.1.1.4.2 yamt const char *filename;
288 1.1.1.1.4.2 yamt /* Compilation command working directory. */
289 1.1.1.1.4.2 yamt const char *comp_dir;
290 1.1.1.1.4.2 yamt /* Absolute file name, only set if needed. */
291 1.1.1.1.4.2 yamt const char *abs_filename;
292 1.1.1.1.4.2 yamt /* The abbreviations for this unit. */
293 1.1.1.1.4.2 yamt struct abbrevs abbrevs;
294 1.1.1.1.4.2 yamt
295 1.1.1.1.4.2 yamt /* The fields above this point are read in during initialization and
296 1.1.1.1.4.2 yamt may be accessed freely. The fields below this point are read in
297 1.1.1.1.4.2 yamt as needed, and therefore require care, as different threads may
298 1.1.1.1.4.2 yamt try to initialize them simultaneously. */
299 1.1.1.1.4.2 yamt
300 1.1.1.1.4.2 yamt /* PC to line number mapping. This is NULL if the values have not
301 1.1.1.1.4.2 yamt been read. This is (struct line *) -1 if there was an error
302 1.1.1.1.4.2 yamt reading the values. */
303 1.1.1.1.4.2 yamt struct line *lines;
304 1.1.1.1.4.2 yamt /* Number of entries in lines. */
305 1.1.1.1.4.2 yamt size_t lines_count;
306 1.1.1.1.4.2 yamt /* PC ranges to function. */
307 1.1.1.1.4.2 yamt struct function_addrs *function_addrs;
308 1.1.1.1.4.2 yamt size_t function_addrs_count;
309 1.1.1.1.4.2 yamt };
310 1.1.1.1.4.2 yamt
311 1.1.1.1.4.2 yamt /* An address range for a compilation unit. This maps a PC value to a
312 1.1.1.1.4.2 yamt specific compilation unit. Note that we invert the representation
313 1.1.1.1.4.2 yamt in DWARF: instead of listing the units and attaching a list of
314 1.1.1.1.4.2 yamt ranges, we list the ranges and have each one point to the unit.
315 1.1.1.1.4.2 yamt This lets us do a binary search to find the unit. */
316 1.1.1.1.4.2 yamt
317 1.1.1.1.4.2 yamt struct unit_addrs
318 1.1.1.1.4.2 yamt {
319 1.1.1.1.4.2 yamt /* Range is LOW <= PC < HIGH. */
320 1.1.1.1.4.2 yamt uint64_t low;
321 1.1.1.1.4.2 yamt uint64_t high;
322 1.1.1.1.4.2 yamt /* Compilation unit for this address range. */
323 1.1.1.1.4.2 yamt struct unit *u;
324 1.1.1.1.4.2 yamt };
325 1.1.1.1.4.2 yamt
326 1.1.1.1.4.2 yamt /* A growable vector of compilation unit address ranges. */
327 1.1.1.1.4.2 yamt
328 1.1.1.1.4.2 yamt struct unit_addrs_vector
329 1.1.1.1.4.2 yamt {
330 1.1.1.1.4.2 yamt /* Memory. This is an array of struct unit_addrs. */
331 1.1.1.1.4.2 yamt struct backtrace_vector vec;
332 1.1.1.1.4.2 yamt /* Number of address ranges present. */
333 1.1.1.1.4.2 yamt size_t count;
334 1.1.1.1.4.2 yamt };
335 1.1.1.1.4.2 yamt
336 1.1.1.1.4.2 yamt /* The information we need to map a PC to a file and line. */
337 1.1.1.1.4.2 yamt
338 1.1.1.1.4.2 yamt struct dwarf_data
339 1.1.1.1.4.2 yamt {
340 1.1.1.1.4.2 yamt /* The data for the next file we know about. */
341 1.1.1.1.4.2 yamt struct dwarf_data *next;
342 1.1.1.1.4.2 yamt /* The base address for this file. */
343 1.1.1.1.4.2 yamt uintptr_t base_address;
344 1.1.1.1.4.2 yamt /* A sorted list of address ranges. */
345 1.1.1.1.4.2 yamt struct unit_addrs *addrs;
346 1.1.1.1.4.2 yamt /* Number of address ranges in list. */
347 1.1.1.1.4.2 yamt size_t addrs_count;
348 1.1.1.1.4.2 yamt /* The unparsed .debug_info section. */
349 1.1.1.1.4.2 yamt const unsigned char *dwarf_info;
350 1.1.1.1.4.2 yamt size_t dwarf_info_size;
351 1.1.1.1.4.2 yamt /* The unparsed .debug_line section. */
352 1.1.1.1.4.2 yamt const unsigned char *dwarf_line;
353 1.1.1.1.4.2 yamt size_t dwarf_line_size;
354 1.1.1.1.4.2 yamt /* The unparsed .debug_ranges section. */
355 1.1.1.1.4.2 yamt const unsigned char *dwarf_ranges;
356 1.1.1.1.4.2 yamt size_t dwarf_ranges_size;
357 1.1.1.1.4.2 yamt /* The unparsed .debug_str section. */
358 1.1.1.1.4.2 yamt const unsigned char *dwarf_str;
359 1.1.1.1.4.2 yamt size_t dwarf_str_size;
360 1.1.1.1.4.2 yamt /* Whether the data is big-endian or not. */
361 1.1.1.1.4.2 yamt int is_bigendian;
362 1.1.1.1.4.2 yamt /* A vector used for function addresses. We keep this here so that
363 1.1.1.1.4.2 yamt we can grow the vector as we read more functions. */
364 1.1.1.1.4.2 yamt struct function_vector fvec;
365 1.1.1.1.4.2 yamt };
366 1.1.1.1.4.2 yamt
367 1.1.1.1.4.2 yamt /* Report an error for a DWARF buffer. */
368 1.1.1.1.4.2 yamt
369 1.1.1.1.4.2 yamt static void
370 1.1.1.1.4.2 yamt dwarf_buf_error (struct dwarf_buf *buf, const char *msg)
371 1.1.1.1.4.2 yamt {
372 1.1.1.1.4.2 yamt char b[200];
373 1.1.1.1.4.2 yamt
374 1.1.1.1.4.2 yamt snprintf (b, sizeof b, "%s in %s at %d",
375 1.1.1.1.4.2 yamt msg, buf->name, (int) (buf->buf - buf->start));
376 1.1.1.1.4.2 yamt buf->error_callback (buf->data, b, 0);
377 1.1.1.1.4.2 yamt }
378 1.1.1.1.4.2 yamt
379 1.1.1.1.4.2 yamt /* Require at least COUNT bytes in BUF. Return 1 if all is well, 0 on
380 1.1.1.1.4.2 yamt error. */
381 1.1.1.1.4.2 yamt
382 1.1.1.1.4.2 yamt static int
383 1.1.1.1.4.2 yamt require (struct dwarf_buf *buf, size_t count)
384 1.1.1.1.4.2 yamt {
385 1.1.1.1.4.2 yamt if (buf->left >= count)
386 1.1.1.1.4.2 yamt return 1;
387 1.1.1.1.4.2 yamt
388 1.1.1.1.4.2 yamt if (!buf->reported_underflow)
389 1.1.1.1.4.2 yamt {
390 1.1.1.1.4.2 yamt dwarf_buf_error (buf, "DWARF underflow");
391 1.1.1.1.4.2 yamt buf->reported_underflow = 1;
392 1.1.1.1.4.2 yamt }
393 1.1.1.1.4.2 yamt
394 1.1.1.1.4.2 yamt return 0;
395 1.1.1.1.4.2 yamt }
396 1.1.1.1.4.2 yamt
397 1.1.1.1.4.2 yamt /* Advance COUNT bytes in BUF. Return 1 if all is well, 0 on
398 1.1.1.1.4.2 yamt error. */
399 1.1.1.1.4.2 yamt
400 1.1.1.1.4.2 yamt static int
401 1.1.1.1.4.2 yamt advance (struct dwarf_buf *buf, size_t count)
402 1.1.1.1.4.2 yamt {
403 1.1.1.1.4.2 yamt if (!require (buf, count))
404 1.1.1.1.4.2 yamt return 0;
405 1.1.1.1.4.2 yamt buf->buf += count;
406 1.1.1.1.4.2 yamt buf->left -= count;
407 1.1.1.1.4.2 yamt return 1;
408 1.1.1.1.4.2 yamt }
409 1.1.1.1.4.2 yamt
410 1.1.1.1.4.2 yamt /* Read one byte from BUF and advance 1 byte. */
411 1.1.1.1.4.2 yamt
412 1.1.1.1.4.2 yamt static unsigned char
413 1.1.1.1.4.2 yamt read_byte (struct dwarf_buf *buf)
414 1.1.1.1.4.2 yamt {
415 1.1.1.1.4.2 yamt const unsigned char *p = buf->buf;
416 1.1.1.1.4.2 yamt
417 1.1.1.1.4.2 yamt if (!advance (buf, 1))
418 1.1.1.1.4.2 yamt return 0;
419 1.1.1.1.4.2 yamt return p[0];
420 1.1.1.1.4.2 yamt }
421 1.1.1.1.4.2 yamt
422 1.1.1.1.4.2 yamt /* Read a signed char from BUF and advance 1 byte. */
423 1.1.1.1.4.2 yamt
424 1.1.1.1.4.2 yamt static signed char
425 1.1.1.1.4.2 yamt read_sbyte (struct dwarf_buf *buf)
426 1.1.1.1.4.2 yamt {
427 1.1.1.1.4.2 yamt const unsigned char *p = buf->buf;
428 1.1.1.1.4.2 yamt
429 1.1.1.1.4.2 yamt if (!advance (buf, 1))
430 1.1.1.1.4.2 yamt return 0;
431 1.1.1.1.4.2 yamt return (*p ^ 0x80) - 0x80;
432 1.1.1.1.4.2 yamt }
433 1.1.1.1.4.2 yamt
434 1.1.1.1.4.2 yamt /* Read a uint16 from BUF and advance 2 bytes. */
435 1.1.1.1.4.2 yamt
436 1.1.1.1.4.2 yamt static uint16_t
437 1.1.1.1.4.2 yamt read_uint16 (struct dwarf_buf *buf)
438 1.1.1.1.4.2 yamt {
439 1.1.1.1.4.2 yamt const unsigned char *p = buf->buf;
440 1.1.1.1.4.2 yamt
441 1.1.1.1.4.2 yamt if (!advance (buf, 2))
442 1.1.1.1.4.2 yamt return 0;
443 1.1.1.1.4.2 yamt if (buf->is_bigendian)
444 1.1.1.1.4.2 yamt return ((uint16_t) p[0] << 8) | (uint16_t) p[1];
445 1.1.1.1.4.2 yamt else
446 1.1.1.1.4.2 yamt return ((uint16_t) p[1] << 8) | (uint16_t) p[0];
447 1.1.1.1.4.2 yamt }
448 1.1.1.1.4.2 yamt
449 1.1.1.1.4.2 yamt /* Read a uint32 from BUF and advance 4 bytes. */
450 1.1.1.1.4.2 yamt
451 1.1.1.1.4.2 yamt static uint32_t
452 1.1.1.1.4.2 yamt read_uint32 (struct dwarf_buf *buf)
453 1.1.1.1.4.2 yamt {
454 1.1.1.1.4.2 yamt const unsigned char *p = buf->buf;
455 1.1.1.1.4.2 yamt
456 1.1.1.1.4.2 yamt if (!advance (buf, 4))
457 1.1.1.1.4.2 yamt return 0;
458 1.1.1.1.4.2 yamt if (buf->is_bigendian)
459 1.1.1.1.4.2 yamt return (((uint32_t) p[0] << 24) | ((uint32_t) p[1] << 16)
460 1.1.1.1.4.2 yamt | ((uint32_t) p[2] << 8) | (uint32_t) p[3]);
461 1.1.1.1.4.2 yamt else
462 1.1.1.1.4.2 yamt return (((uint32_t) p[3] << 24) | ((uint32_t) p[2] << 16)
463 1.1.1.1.4.2 yamt | ((uint32_t) p[1] << 8) | (uint32_t) p[0]);
464 1.1.1.1.4.2 yamt }
465 1.1.1.1.4.2 yamt
466 1.1.1.1.4.2 yamt /* Read a uint64 from BUF and advance 8 bytes. */
467 1.1.1.1.4.2 yamt
468 1.1.1.1.4.2 yamt static uint64_t
469 1.1.1.1.4.2 yamt read_uint64 (struct dwarf_buf *buf)
470 1.1.1.1.4.2 yamt {
471 1.1.1.1.4.2 yamt const unsigned char *p = buf->buf;
472 1.1.1.1.4.2 yamt
473 1.1.1.1.4.2 yamt if (!advance (buf, 8))
474 1.1.1.1.4.2 yamt return 0;
475 1.1.1.1.4.2 yamt if (buf->is_bigendian)
476 1.1.1.1.4.2 yamt return (((uint64_t) p[0] << 56) | ((uint64_t) p[1] << 48)
477 1.1.1.1.4.2 yamt | ((uint64_t) p[2] << 40) | ((uint64_t) p[3] << 32)
478 1.1.1.1.4.2 yamt | ((uint64_t) p[4] << 24) | ((uint64_t) p[5] << 16)
479 1.1.1.1.4.2 yamt | ((uint64_t) p[6] << 8) | (uint64_t) p[7]);
480 1.1.1.1.4.2 yamt else
481 1.1.1.1.4.2 yamt return (((uint64_t) p[7] << 56) | ((uint64_t) p[6] << 48)
482 1.1.1.1.4.2 yamt | ((uint64_t) p[5] << 40) | ((uint64_t) p[4] << 32)
483 1.1.1.1.4.2 yamt | ((uint64_t) p[3] << 24) | ((uint64_t) p[2] << 16)
484 1.1.1.1.4.2 yamt | ((uint64_t) p[1] << 8) | (uint64_t) p[0]);
485 1.1.1.1.4.2 yamt }
486 1.1.1.1.4.2 yamt
487 1.1.1.1.4.2 yamt /* Read an offset from BUF and advance the appropriate number of
488 1.1.1.1.4.2 yamt bytes. */
489 1.1.1.1.4.2 yamt
490 1.1.1.1.4.2 yamt static uint64_t
491 1.1.1.1.4.2 yamt read_offset (struct dwarf_buf *buf, int is_dwarf64)
492 1.1.1.1.4.2 yamt {
493 1.1.1.1.4.2 yamt if (is_dwarf64)
494 1.1.1.1.4.2 yamt return read_uint64 (buf);
495 1.1.1.1.4.2 yamt else
496 1.1.1.1.4.2 yamt return read_uint32 (buf);
497 1.1.1.1.4.2 yamt }
498 1.1.1.1.4.2 yamt
499 1.1.1.1.4.2 yamt /* Read an address from BUF and advance the appropriate number of
500 1.1.1.1.4.2 yamt bytes. */
501 1.1.1.1.4.2 yamt
502 1.1.1.1.4.2 yamt static uint64_t
503 1.1.1.1.4.2 yamt read_address (struct dwarf_buf *buf, int addrsize)
504 1.1.1.1.4.2 yamt {
505 1.1.1.1.4.2 yamt switch (addrsize)
506 1.1.1.1.4.2 yamt {
507 1.1.1.1.4.2 yamt case 1:
508 1.1.1.1.4.2 yamt return read_byte (buf);
509 1.1.1.1.4.2 yamt case 2:
510 1.1.1.1.4.2 yamt return read_uint16 (buf);
511 1.1.1.1.4.2 yamt case 4:
512 1.1.1.1.4.2 yamt return read_uint32 (buf);
513 1.1.1.1.4.2 yamt case 8:
514 1.1.1.1.4.2 yamt return read_uint64 (buf);
515 1.1.1.1.4.2 yamt default:
516 1.1.1.1.4.2 yamt dwarf_buf_error (buf, "unrecognized address size");
517 1.1.1.1.4.2 yamt return 0;
518 1.1.1.1.4.2 yamt }
519 1.1.1.1.4.2 yamt }
520 1.1.1.1.4.2 yamt
521 1.1.1.1.4.2 yamt /* Return whether a value is the highest possible address, given the
522 1.1.1.1.4.2 yamt address size. */
523 1.1.1.1.4.2 yamt
524 1.1.1.1.4.2 yamt static int
525 1.1.1.1.4.2 yamt is_highest_address (uint64_t address, int addrsize)
526 1.1.1.1.4.2 yamt {
527 1.1.1.1.4.2 yamt switch (addrsize)
528 1.1.1.1.4.2 yamt {
529 1.1.1.1.4.2 yamt case 1:
530 1.1.1.1.4.2 yamt return address == (unsigned char) -1;
531 1.1.1.1.4.2 yamt case 2:
532 1.1.1.1.4.2 yamt return address == (uint16_t) -1;
533 1.1.1.1.4.2 yamt case 4:
534 1.1.1.1.4.2 yamt return address == (uint32_t) -1;
535 1.1.1.1.4.2 yamt case 8:
536 1.1.1.1.4.2 yamt return address == (uint64_t) -1;
537 1.1.1.1.4.2 yamt default:
538 1.1.1.1.4.2 yamt return 0;
539 1.1.1.1.4.2 yamt }
540 1.1.1.1.4.2 yamt }
541 1.1.1.1.4.2 yamt
542 1.1.1.1.4.2 yamt /* Read an unsigned LEB128 number. */
543 1.1.1.1.4.2 yamt
544 1.1.1.1.4.2 yamt static uint64_t
545 1.1.1.1.4.2 yamt read_uleb128 (struct dwarf_buf *buf)
546 1.1.1.1.4.2 yamt {
547 1.1.1.1.4.2 yamt uint64_t ret;
548 1.1.1.1.4.2 yamt unsigned int shift;
549 1.1.1.1.4.2 yamt int overflow;
550 1.1.1.1.4.2 yamt unsigned char b;
551 1.1.1.1.4.2 yamt
552 1.1.1.1.4.2 yamt ret = 0;
553 1.1.1.1.4.2 yamt shift = 0;
554 1.1.1.1.4.2 yamt overflow = 0;
555 1.1.1.1.4.2 yamt do
556 1.1.1.1.4.2 yamt {
557 1.1.1.1.4.2 yamt const unsigned char *p;
558 1.1.1.1.4.2 yamt
559 1.1.1.1.4.2 yamt p = buf->buf;
560 1.1.1.1.4.2 yamt if (!advance (buf, 1))
561 1.1.1.1.4.2 yamt return 0;
562 1.1.1.1.4.2 yamt b = *p;
563 1.1.1.1.4.2 yamt if (shift < 64)
564 1.1.1.1.4.2 yamt ret |= ((uint64_t) (b & 0x7f)) << shift;
565 1.1.1.1.4.2 yamt else if (!overflow)
566 1.1.1.1.4.2 yamt {
567 1.1.1.1.4.2 yamt dwarf_buf_error (buf, "LEB128 overflows uint64_t");
568 1.1.1.1.4.2 yamt overflow = 1;
569 1.1.1.1.4.2 yamt }
570 1.1.1.1.4.2 yamt shift += 7;
571 1.1.1.1.4.2 yamt }
572 1.1.1.1.4.2 yamt while ((b & 0x80) != 0);
573 1.1.1.1.4.2 yamt
574 1.1.1.1.4.2 yamt return ret;
575 1.1.1.1.4.2 yamt }
576 1.1.1.1.4.2 yamt
577 1.1.1.1.4.2 yamt /* Read a signed LEB128 number. */
578 1.1.1.1.4.2 yamt
579 1.1.1.1.4.2 yamt static int64_t
580 1.1.1.1.4.2 yamt read_sleb128 (struct dwarf_buf *buf)
581 1.1.1.1.4.2 yamt {
582 1.1.1.1.4.2 yamt uint64_t val;
583 1.1.1.1.4.2 yamt unsigned int shift;
584 1.1.1.1.4.2 yamt int overflow;
585 1.1.1.1.4.2 yamt unsigned char b;
586 1.1.1.1.4.2 yamt
587 1.1.1.1.4.2 yamt val = 0;
588 1.1.1.1.4.2 yamt shift = 0;
589 1.1.1.1.4.2 yamt overflow = 0;
590 1.1.1.1.4.2 yamt do
591 1.1.1.1.4.2 yamt {
592 1.1.1.1.4.2 yamt const unsigned char *p;
593 1.1.1.1.4.2 yamt
594 1.1.1.1.4.2 yamt p = buf->buf;
595 1.1.1.1.4.2 yamt if (!advance (buf, 1))
596 1.1.1.1.4.2 yamt return 0;
597 1.1.1.1.4.2 yamt b = *p;
598 1.1.1.1.4.2 yamt if (shift < 64)
599 1.1.1.1.4.2 yamt val |= ((uint64_t) (b & 0x7f)) << shift;
600 1.1.1.1.4.2 yamt else if (!overflow)
601 1.1.1.1.4.2 yamt {
602 1.1.1.1.4.2 yamt dwarf_buf_error (buf, "signed LEB128 overflows uint64_t");
603 1.1.1.1.4.2 yamt overflow = 1;
604 1.1.1.1.4.2 yamt }
605 1.1.1.1.4.2 yamt shift += 7;
606 1.1.1.1.4.2 yamt }
607 1.1.1.1.4.2 yamt while ((b & 0x80) != 0);
608 1.1.1.1.4.2 yamt
609 1.1.1.1.4.2 yamt if ((b & 0x40) != 0 && shift < 64)
610 1.1.1.1.4.2 yamt val |= ((uint64_t) -1) << shift;
611 1.1.1.1.4.2 yamt
612 1.1.1.1.4.2 yamt return (int64_t) val;
613 1.1.1.1.4.2 yamt }
614 1.1.1.1.4.2 yamt
615 1.1.1.1.4.2 yamt /* Return the length of an LEB128 number. */
616 1.1.1.1.4.2 yamt
617 1.1.1.1.4.2 yamt static size_t
618 1.1.1.1.4.2 yamt leb128_len (const unsigned char *p)
619 1.1.1.1.4.2 yamt {
620 1.1.1.1.4.2 yamt size_t ret;
621 1.1.1.1.4.2 yamt
622 1.1.1.1.4.2 yamt ret = 1;
623 1.1.1.1.4.2 yamt while ((*p & 0x80) != 0)
624 1.1.1.1.4.2 yamt {
625 1.1.1.1.4.2 yamt ++p;
626 1.1.1.1.4.2 yamt ++ret;
627 1.1.1.1.4.2 yamt }
628 1.1.1.1.4.2 yamt return ret;
629 1.1.1.1.4.2 yamt }
630 1.1.1.1.4.2 yamt
631 1.1.1.1.4.2 yamt /* Free an abbreviations structure. */
632 1.1.1.1.4.2 yamt
633 1.1.1.1.4.2 yamt static void
634 1.1.1.1.4.2 yamt free_abbrevs (struct backtrace_state *state, struct abbrevs *abbrevs,
635 1.1.1.1.4.2 yamt backtrace_error_callback error_callback, void *data)
636 1.1.1.1.4.2 yamt {
637 1.1.1.1.4.2 yamt size_t i;
638 1.1.1.1.4.2 yamt
639 1.1.1.1.4.2 yamt for (i = 0; i < abbrevs->num_abbrevs; ++i)
640 1.1.1.1.4.2 yamt backtrace_free (state, abbrevs->abbrevs[i].attrs,
641 1.1.1.1.4.2 yamt abbrevs->abbrevs[i].num_attrs * sizeof (struct attr),
642 1.1.1.1.4.2 yamt error_callback, data);
643 1.1.1.1.4.2 yamt backtrace_free (state, abbrevs->abbrevs,
644 1.1.1.1.4.2 yamt abbrevs->num_abbrevs * sizeof (struct abbrev),
645 1.1.1.1.4.2 yamt error_callback, data);
646 1.1.1.1.4.2 yamt abbrevs->num_abbrevs = 0;
647 1.1.1.1.4.2 yamt abbrevs->abbrevs = NULL;
648 1.1.1.1.4.2 yamt }
649 1.1.1.1.4.2 yamt
650 1.1.1.1.4.2 yamt /* Read an attribute value. Returns 1 on success, 0 on failure. If
651 1.1.1.1.4.2 yamt the value can be represented as a uint64_t, sets *VAL and sets
652 1.1.1.1.4.2 yamt *IS_VALID to 1. We don't try to store the value of other attribute
653 1.1.1.1.4.2 yamt forms, because we don't care about them. */
654 1.1.1.1.4.2 yamt
655 1.1.1.1.4.2 yamt static int
656 1.1.1.1.4.2 yamt read_attribute (enum dwarf_form form, struct dwarf_buf *buf,
657 1.1.1.1.4.2 yamt int is_dwarf64, int version, int addrsize,
658 1.1.1.1.4.2 yamt const unsigned char *dwarf_str, size_t dwarf_str_size,
659 1.1.1.1.4.2 yamt struct attr_val *val)
660 1.1.1.1.4.2 yamt {
661 1.1.1.1.4.2 yamt /* Avoid warnings about val.u.FIELD may be used uninitialized if
662 1.1.1.1.4.2 yamt this function is inlined. The warnings aren't valid but can
663 1.1.1.1.4.2 yamt occur because the different fields are set and used
664 1.1.1.1.4.2 yamt conditionally. */
665 1.1.1.1.4.2 yamt memset (val, 0, sizeof *val);
666 1.1.1.1.4.2 yamt
667 1.1.1.1.4.2 yamt switch (form)
668 1.1.1.1.4.2 yamt {
669 1.1.1.1.4.2 yamt case DW_FORM_addr:
670 1.1.1.1.4.2 yamt val->encoding = ATTR_VAL_ADDRESS;
671 1.1.1.1.4.2 yamt val->u.uint = read_address (buf, addrsize);
672 1.1.1.1.4.2 yamt return 1;
673 1.1.1.1.4.2 yamt case DW_FORM_block2:
674 1.1.1.1.4.2 yamt val->encoding = ATTR_VAL_BLOCK;
675 1.1.1.1.4.2 yamt return advance (buf, read_uint16 (buf));
676 1.1.1.1.4.2 yamt case DW_FORM_block4:
677 1.1.1.1.4.2 yamt val->encoding = ATTR_VAL_BLOCK;
678 1.1.1.1.4.2 yamt return advance (buf, read_uint32 (buf));
679 1.1.1.1.4.2 yamt case DW_FORM_data2:
680 1.1.1.1.4.2 yamt val->encoding = ATTR_VAL_UINT;
681 1.1.1.1.4.2 yamt val->u.uint = read_uint16 (buf);
682 1.1.1.1.4.2 yamt return 1;
683 1.1.1.1.4.2 yamt case DW_FORM_data4:
684 1.1.1.1.4.2 yamt val->encoding = ATTR_VAL_UINT;
685 1.1.1.1.4.2 yamt val->u.uint = read_uint32 (buf);
686 1.1.1.1.4.2 yamt return 1;
687 1.1.1.1.4.2 yamt case DW_FORM_data8:
688 1.1.1.1.4.2 yamt val->encoding = ATTR_VAL_UINT;
689 1.1.1.1.4.2 yamt val->u.uint = read_uint64 (buf);
690 1.1.1.1.4.2 yamt return 1;
691 1.1.1.1.4.2 yamt case DW_FORM_string:
692 1.1.1.1.4.2 yamt val->encoding = ATTR_VAL_STRING;
693 1.1.1.1.4.2 yamt val->u.string = (const char *) buf->buf;
694 1.1.1.1.4.2 yamt return advance (buf, strnlen ((const char *) buf->buf, buf->left) + 1);
695 1.1.1.1.4.2 yamt case DW_FORM_block:
696 1.1.1.1.4.2 yamt val->encoding = ATTR_VAL_BLOCK;
697 1.1.1.1.4.2 yamt return advance (buf, read_uleb128 (buf));
698 1.1.1.1.4.2 yamt case DW_FORM_block1:
699 1.1.1.1.4.2 yamt val->encoding = ATTR_VAL_BLOCK;
700 1.1.1.1.4.2 yamt return advance (buf, read_byte (buf));
701 1.1.1.1.4.2 yamt case DW_FORM_data1:
702 1.1.1.1.4.2 yamt val->encoding = ATTR_VAL_UINT;
703 1.1.1.1.4.2 yamt val->u.uint = read_byte (buf);
704 1.1.1.1.4.2 yamt return 1;
705 1.1.1.1.4.2 yamt case DW_FORM_flag:
706 1.1.1.1.4.2 yamt val->encoding = ATTR_VAL_UINT;
707 1.1.1.1.4.2 yamt val->u.uint = read_byte (buf);
708 1.1.1.1.4.2 yamt return 1;
709 1.1.1.1.4.2 yamt case DW_FORM_sdata:
710 1.1.1.1.4.2 yamt val->encoding = ATTR_VAL_SINT;
711 1.1.1.1.4.2 yamt val->u.sint = read_sleb128 (buf);
712 1.1.1.1.4.2 yamt return 1;
713 1.1.1.1.4.2 yamt case DW_FORM_strp:
714 1.1.1.1.4.2 yamt {
715 1.1.1.1.4.2 yamt uint64_t offset;
716 1.1.1.1.4.2 yamt
717 1.1.1.1.4.2 yamt offset = read_offset (buf, is_dwarf64);
718 1.1.1.1.4.2 yamt if (offset >= dwarf_str_size)
719 1.1.1.1.4.2 yamt {
720 1.1.1.1.4.2 yamt dwarf_buf_error (buf, "DW_FORM_strp out of range");
721 1.1.1.1.4.2 yamt return 0;
722 1.1.1.1.4.2 yamt }
723 1.1.1.1.4.2 yamt val->encoding = ATTR_VAL_STRING;
724 1.1.1.1.4.2 yamt val->u.string = (const char *) dwarf_str + offset;
725 1.1.1.1.4.2 yamt return 1;
726 1.1.1.1.4.2 yamt }
727 1.1.1.1.4.2 yamt case DW_FORM_udata:
728 1.1.1.1.4.2 yamt val->encoding = ATTR_VAL_UINT;
729 1.1.1.1.4.2 yamt val->u.uint = read_uleb128 (buf);
730 1.1.1.1.4.2 yamt return 1;
731 1.1.1.1.4.2 yamt case DW_FORM_ref_addr:
732 1.1.1.1.4.2 yamt val->encoding = ATTR_VAL_REF_INFO;
733 1.1.1.1.4.2 yamt if (version == 2)
734 1.1.1.1.4.2 yamt val->u.uint = read_address (buf, addrsize);
735 1.1.1.1.4.2 yamt else
736 1.1.1.1.4.2 yamt val->u.uint = read_offset (buf, is_dwarf64);
737 1.1.1.1.4.2 yamt return 1;
738 1.1.1.1.4.2 yamt case DW_FORM_ref1:
739 1.1.1.1.4.2 yamt val->encoding = ATTR_VAL_REF_UNIT;
740 1.1.1.1.4.2 yamt val->u.uint = read_byte (buf);
741 1.1.1.1.4.2 yamt return 1;
742 1.1.1.1.4.2 yamt case DW_FORM_ref2:
743 1.1.1.1.4.2 yamt val->encoding = ATTR_VAL_REF_UNIT;
744 1.1.1.1.4.2 yamt val->u.uint = read_uint16 (buf);
745 1.1.1.1.4.2 yamt return 1;
746 1.1.1.1.4.2 yamt case DW_FORM_ref4:
747 1.1.1.1.4.2 yamt val->encoding = ATTR_VAL_REF_UNIT;
748 1.1.1.1.4.2 yamt val->u.uint = read_uint32 (buf);
749 1.1.1.1.4.2 yamt return 1;
750 1.1.1.1.4.2 yamt case DW_FORM_ref8:
751 1.1.1.1.4.2 yamt val->encoding = ATTR_VAL_REF_UNIT;
752 1.1.1.1.4.2 yamt val->u.uint = read_uint64 (buf);
753 1.1.1.1.4.2 yamt return 1;
754 1.1.1.1.4.2 yamt case DW_FORM_ref_udata:
755 1.1.1.1.4.2 yamt val->encoding = ATTR_VAL_REF_UNIT;
756 1.1.1.1.4.2 yamt val->u.uint = read_uleb128 (buf);
757 1.1.1.1.4.2 yamt return 1;
758 1.1.1.1.4.2 yamt case DW_FORM_indirect:
759 1.1.1.1.4.2 yamt {
760 1.1.1.1.4.2 yamt uint64_t form;
761 1.1.1.1.4.2 yamt
762 1.1.1.1.4.2 yamt form = read_uleb128 (buf);
763 1.1.1.1.4.2 yamt return read_attribute ((enum dwarf_form) form, buf, is_dwarf64,
764 1.1.1.1.4.2 yamt version, addrsize, dwarf_str, dwarf_str_size,
765 1.1.1.1.4.2 yamt val);
766 1.1.1.1.4.2 yamt }
767 1.1.1.1.4.2 yamt case DW_FORM_sec_offset:
768 1.1.1.1.4.2 yamt val->encoding = ATTR_VAL_REF_SECTION;
769 1.1.1.1.4.2 yamt val->u.uint = read_offset (buf, is_dwarf64);
770 1.1.1.1.4.2 yamt return 1;
771 1.1.1.1.4.2 yamt case DW_FORM_exprloc:
772 1.1.1.1.4.2 yamt val->encoding = ATTR_VAL_EXPR;
773 1.1.1.1.4.2 yamt return advance (buf, read_uleb128 (buf));
774 1.1.1.1.4.2 yamt case DW_FORM_flag_present:
775 1.1.1.1.4.2 yamt val->encoding = ATTR_VAL_UINT;
776 1.1.1.1.4.2 yamt val->u.uint = 1;
777 1.1.1.1.4.2 yamt return 1;
778 1.1.1.1.4.2 yamt case DW_FORM_ref_sig8:
779 1.1.1.1.4.2 yamt val->encoding = ATTR_VAL_REF_TYPE;
780 1.1.1.1.4.2 yamt val->u.uint = read_uint64 (buf);
781 1.1.1.1.4.2 yamt return 1;
782 1.1.1.1.4.2 yamt case DW_FORM_GNU_addr_index:
783 1.1.1.1.4.2 yamt val->encoding = ATTR_VAL_REF_SECTION;
784 1.1.1.1.4.2 yamt val->u.uint = read_uleb128 (buf);
785 1.1.1.1.4.2 yamt return 1;
786 1.1.1.1.4.2 yamt case DW_FORM_GNU_str_index:
787 1.1.1.1.4.2 yamt val->encoding = ATTR_VAL_REF_SECTION;
788 1.1.1.1.4.2 yamt val->u.uint = read_uleb128 (buf);
789 1.1.1.1.4.2 yamt return 1;
790 1.1.1.1.4.2 yamt case DW_FORM_GNU_ref_alt:
791 1.1.1.1.4.2 yamt val->encoding = ATTR_VAL_REF_SECTION;
792 1.1.1.1.4.2 yamt val->u.uint = read_offset (buf, is_dwarf64);
793 1.1.1.1.4.2 yamt return 1;
794 1.1.1.1.4.2 yamt case DW_FORM_GNU_strp_alt:
795 1.1.1.1.4.2 yamt val->encoding = ATTR_VAL_REF_SECTION;
796 1.1.1.1.4.2 yamt val->u.uint = read_offset (buf, is_dwarf64);
797 1.1.1.1.4.2 yamt return 1;
798 1.1.1.1.4.2 yamt default:
799 1.1.1.1.4.2 yamt dwarf_buf_error (buf, "unrecognized DWARF form");
800 1.1.1.1.4.2 yamt return 0;
801 1.1.1.1.4.2 yamt }
802 1.1.1.1.4.2 yamt }
803 1.1.1.1.4.2 yamt
804 1.1.1.1.4.2 yamt /* Compare function_addrs for qsort. When ranges are nested, make the
805 1.1.1.1.4.2 yamt smallest one sort last. */
806 1.1.1.1.4.2 yamt
807 1.1.1.1.4.2 yamt static int
808 1.1.1.1.4.2 yamt function_addrs_compare (const void *v1, const void *v2)
809 1.1.1.1.4.2 yamt {
810 1.1.1.1.4.2 yamt const struct function_addrs *a1 = (const struct function_addrs *) v1;
811 1.1.1.1.4.2 yamt const struct function_addrs *a2 = (const struct function_addrs *) v2;
812 1.1.1.1.4.2 yamt
813 1.1.1.1.4.2 yamt if (a1->low < a2->low)
814 1.1.1.1.4.2 yamt return -1;
815 1.1.1.1.4.2 yamt if (a1->low > a2->low)
816 1.1.1.1.4.2 yamt return 1;
817 1.1.1.1.4.2 yamt if (a1->high < a2->high)
818 1.1.1.1.4.2 yamt return 1;
819 1.1.1.1.4.2 yamt if (a1->high > a2->high)
820 1.1.1.1.4.2 yamt return -1;
821 1.1.1.1.4.2 yamt return strcmp (a1->function->name, a2->function->name);
822 1.1.1.1.4.2 yamt }
823 1.1.1.1.4.2 yamt
824 1.1.1.1.4.2 yamt /* Compare a PC against a function_addrs for bsearch. Note that if
825 1.1.1.1.4.2 yamt there are multiple ranges containing PC, which one will be returned
826 1.1.1.1.4.2 yamt is unpredictable. We compensate for that in dwarf_fileline. */
827 1.1.1.1.4.2 yamt
828 1.1.1.1.4.2 yamt static int
829 1.1.1.1.4.2 yamt function_addrs_search (const void *vkey, const void *ventry)
830 1.1.1.1.4.2 yamt {
831 1.1.1.1.4.2 yamt const uintptr_t *key = (const uintptr_t *) vkey;
832 1.1.1.1.4.2 yamt const struct function_addrs *entry = (const struct function_addrs *) ventry;
833 1.1.1.1.4.2 yamt uintptr_t pc;
834 1.1.1.1.4.2 yamt
835 1.1.1.1.4.2 yamt pc = *key;
836 1.1.1.1.4.2 yamt if (pc < entry->low)
837 1.1.1.1.4.2 yamt return -1;
838 1.1.1.1.4.2 yamt else if (pc >= entry->high)
839 1.1.1.1.4.2 yamt return 1;
840 1.1.1.1.4.2 yamt else
841 1.1.1.1.4.2 yamt return 0;
842 1.1.1.1.4.2 yamt }
843 1.1.1.1.4.2 yamt
844 1.1.1.1.4.2 yamt /* Add a new compilation unit address range to a vector. Returns 1 on
845 1.1.1.1.4.2 yamt success, 0 on failure. */
846 1.1.1.1.4.2 yamt
847 1.1.1.1.4.2 yamt static int
848 1.1.1.1.4.2 yamt add_unit_addr (struct backtrace_state *state, uintptr_t base_address,
849 1.1.1.1.4.2 yamt struct unit_addrs addrs,
850 1.1.1.1.4.2 yamt backtrace_error_callback error_callback, void *data,
851 1.1.1.1.4.2 yamt struct unit_addrs_vector *vec)
852 1.1.1.1.4.2 yamt {
853 1.1.1.1.4.2 yamt struct unit_addrs *p;
854 1.1.1.1.4.2 yamt
855 1.1.1.1.4.2 yamt /* Add in the base address of the module here, so that we can look
856 1.1.1.1.4.2 yamt up the PC directly. */
857 1.1.1.1.4.2 yamt addrs.low += base_address;
858 1.1.1.1.4.2 yamt addrs.high += base_address;
859 1.1.1.1.4.2 yamt
860 1.1.1.1.4.2 yamt /* Try to merge with the last entry. */
861 1.1.1.1.4.2 yamt if (vec->count > 0)
862 1.1.1.1.4.2 yamt {
863 1.1.1.1.4.2 yamt p = (struct unit_addrs *) vec->vec.base + (vec->count - 1);
864 1.1.1.1.4.2 yamt if ((addrs.low == p->high || addrs.low == p->high + 1)
865 1.1.1.1.4.2 yamt && addrs.u == p->u)
866 1.1.1.1.4.2 yamt {
867 1.1.1.1.4.2 yamt if (addrs.high > p->high)
868 1.1.1.1.4.2 yamt p->high = addrs.high;
869 1.1.1.1.4.2 yamt return 1;
870 1.1.1.1.4.2 yamt }
871 1.1.1.1.4.2 yamt }
872 1.1.1.1.4.2 yamt
873 1.1.1.1.4.2 yamt p = ((struct unit_addrs *)
874 1.1.1.1.4.2 yamt backtrace_vector_grow (state, sizeof (struct unit_addrs),
875 1.1.1.1.4.2 yamt error_callback, data, &vec->vec));
876 1.1.1.1.4.2 yamt if (p == NULL)
877 1.1.1.1.4.2 yamt return 0;
878 1.1.1.1.4.2 yamt
879 1.1.1.1.4.2 yamt *p = addrs;
880 1.1.1.1.4.2 yamt ++vec->count;
881 1.1.1.1.4.2 yamt return 1;
882 1.1.1.1.4.2 yamt }
883 1.1.1.1.4.2 yamt
884 1.1.1.1.4.2 yamt /* Free a unit address vector. */
885 1.1.1.1.4.2 yamt
886 1.1.1.1.4.2 yamt static void
887 1.1.1.1.4.2 yamt free_unit_addrs_vector (struct backtrace_state *state,
888 1.1.1.1.4.2 yamt struct unit_addrs_vector *vec,
889 1.1.1.1.4.2 yamt backtrace_error_callback error_callback, void *data)
890 1.1.1.1.4.2 yamt {
891 1.1.1.1.4.2 yamt struct unit_addrs *addrs;
892 1.1.1.1.4.2 yamt size_t i;
893 1.1.1.1.4.2 yamt
894 1.1.1.1.4.2 yamt addrs = (struct unit_addrs *) vec->vec.base;
895 1.1.1.1.4.2 yamt for (i = 0; i < vec->count; ++i)
896 1.1.1.1.4.2 yamt free_abbrevs (state, &addrs[i].u->abbrevs, error_callback, data);
897 1.1.1.1.4.2 yamt }
898 1.1.1.1.4.2 yamt
899 1.1.1.1.4.2 yamt /* Compare unit_addrs for qsort. When ranges are nested, make the
900 1.1.1.1.4.2 yamt smallest one sort last. */
901 1.1.1.1.4.2 yamt
902 1.1.1.1.4.2 yamt static int
903 1.1.1.1.4.2 yamt unit_addrs_compare (const void *v1, const void *v2)
904 1.1.1.1.4.2 yamt {
905 1.1.1.1.4.2 yamt const struct unit_addrs *a1 = (const struct unit_addrs *) v1;
906 1.1.1.1.4.2 yamt const struct unit_addrs *a2 = (const struct unit_addrs *) v2;
907 1.1.1.1.4.2 yamt
908 1.1.1.1.4.2 yamt if (a1->low < a2->low)
909 1.1.1.1.4.2 yamt return -1;
910 1.1.1.1.4.2 yamt if (a1->low > a2->low)
911 1.1.1.1.4.2 yamt return 1;
912 1.1.1.1.4.2 yamt if (a1->high < a2->high)
913 1.1.1.1.4.2 yamt return 1;
914 1.1.1.1.4.2 yamt if (a1->high > a2->high)
915 1.1.1.1.4.2 yamt return -1;
916 1.1.1.1.4.2 yamt if (a1->u->lineoff < a2->u->lineoff)
917 1.1.1.1.4.2 yamt return -1;
918 1.1.1.1.4.2 yamt if (a1->u->lineoff > a2->u->lineoff)
919 1.1.1.1.4.2 yamt return 1;
920 1.1.1.1.4.2 yamt return 0;
921 1.1.1.1.4.2 yamt }
922 1.1.1.1.4.2 yamt
923 1.1.1.1.4.2 yamt /* Compare a PC against a unit_addrs for bsearch. Note that if there
924 1.1.1.1.4.2 yamt are multiple ranges containing PC, which one will be returned is
925 1.1.1.1.4.2 yamt unpredictable. We compensate for that in dwarf_fileline. */
926 1.1.1.1.4.2 yamt
927 1.1.1.1.4.2 yamt static int
928 1.1.1.1.4.2 yamt unit_addrs_search (const void *vkey, const void *ventry)
929 1.1.1.1.4.2 yamt {
930 1.1.1.1.4.2 yamt const uintptr_t *key = (const uintptr_t *) vkey;
931 1.1.1.1.4.2 yamt const struct unit_addrs *entry = (const struct unit_addrs *) ventry;
932 1.1.1.1.4.2 yamt uintptr_t pc;
933 1.1.1.1.4.2 yamt
934 1.1.1.1.4.2 yamt pc = *key;
935 1.1.1.1.4.2 yamt if (pc < entry->low)
936 1.1.1.1.4.2 yamt return -1;
937 1.1.1.1.4.2 yamt else if (pc >= entry->high)
938 1.1.1.1.4.2 yamt return 1;
939 1.1.1.1.4.2 yamt else
940 1.1.1.1.4.2 yamt return 0;
941 1.1.1.1.4.2 yamt }
942 1.1.1.1.4.2 yamt
943 1.1.1.1.4.2 yamt /* Sort the line vector by PC. We want a stable sort here. We know
944 1.1.1.1.4.2 yamt that the pointers are into the same array, so it is safe to compare
945 1.1.1.1.4.2 yamt them directly. */
946 1.1.1.1.4.2 yamt
947 1.1.1.1.4.2 yamt static int
948 1.1.1.1.4.2 yamt line_compare (const void *v1, const void *v2)
949 1.1.1.1.4.2 yamt {
950 1.1.1.1.4.2 yamt const struct line *ln1 = (const struct line *) v1;
951 1.1.1.1.4.2 yamt const struct line *ln2 = (const struct line *) v2;
952 1.1.1.1.4.2 yamt
953 1.1.1.1.4.2 yamt if (ln1->pc < ln2->pc)
954 1.1.1.1.4.2 yamt return -1;
955 1.1.1.1.4.2 yamt else if (ln1->pc > ln2->pc)
956 1.1.1.1.4.2 yamt return 1;
957 1.1.1.1.4.2 yamt else if (ln1 < ln2)
958 1.1.1.1.4.2 yamt return -1;
959 1.1.1.1.4.2 yamt else if (ln1 > ln2)
960 1.1.1.1.4.2 yamt return 1;
961 1.1.1.1.4.2 yamt else
962 1.1.1.1.4.2 yamt return 0;
963 1.1.1.1.4.2 yamt }
964 1.1.1.1.4.2 yamt
965 1.1.1.1.4.2 yamt /* Find a PC in a line vector. We always allocate an extra entry at
966 1.1.1.1.4.2 yamt the end of the lines vector, so that this routine can safely look
967 1.1.1.1.4.2 yamt at the next entry. Note that when there are multiple mappings for
968 1.1.1.1.4.2 yamt the same PC value, this will return the last one. */
969 1.1.1.1.4.2 yamt
970 1.1.1.1.4.2 yamt static int
971 1.1.1.1.4.2 yamt line_search (const void *vkey, const void *ventry)
972 1.1.1.1.4.2 yamt {
973 1.1.1.1.4.2 yamt const uintptr_t *key = (const uintptr_t *) vkey;
974 1.1.1.1.4.2 yamt const struct line *entry = (const struct line *) ventry;
975 1.1.1.1.4.2 yamt uintptr_t pc;
976 1.1.1.1.4.2 yamt
977 1.1.1.1.4.2 yamt pc = *key;
978 1.1.1.1.4.2 yamt if (pc < entry->pc)
979 1.1.1.1.4.2 yamt return -1;
980 1.1.1.1.4.2 yamt else if (pc >= (entry + 1)->pc)
981 1.1.1.1.4.2 yamt return 1;
982 1.1.1.1.4.2 yamt else
983 1.1.1.1.4.2 yamt return 0;
984 1.1.1.1.4.2 yamt }
985 1.1.1.1.4.2 yamt
986 1.1.1.1.4.2 yamt /* Sort the abbrevs by the abbrev code. This function is passed to
987 1.1.1.1.4.2 yamt both qsort and bsearch. */
988 1.1.1.1.4.2 yamt
989 1.1.1.1.4.2 yamt static int
990 1.1.1.1.4.2 yamt abbrev_compare (const void *v1, const void *v2)
991 1.1.1.1.4.2 yamt {
992 1.1.1.1.4.2 yamt const struct abbrev *a1 = (const struct abbrev *) v1;
993 1.1.1.1.4.2 yamt const struct abbrev *a2 = (const struct abbrev *) v2;
994 1.1.1.1.4.2 yamt
995 1.1.1.1.4.2 yamt if (a1->code < a2->code)
996 1.1.1.1.4.2 yamt return -1;
997 1.1.1.1.4.2 yamt else if (a1->code > a2->code)
998 1.1.1.1.4.2 yamt return 1;
999 1.1.1.1.4.2 yamt else
1000 1.1.1.1.4.2 yamt {
1001 1.1.1.1.4.2 yamt /* This really shouldn't happen. It means there are two
1002 1.1.1.1.4.2 yamt different abbrevs with the same code, and that means we don't
1003 1.1.1.1.4.2 yamt know which one lookup_abbrev should return. */
1004 1.1.1.1.4.2 yamt return 0;
1005 1.1.1.1.4.2 yamt }
1006 1.1.1.1.4.2 yamt }
1007 1.1.1.1.4.2 yamt
1008 1.1.1.1.4.2 yamt /* Read the abbreviation table for a compilation unit. Returns 1 on
1009 1.1.1.1.4.2 yamt success, 0 on failure. */
1010 1.1.1.1.4.2 yamt
1011 1.1.1.1.4.2 yamt static int
1012 1.1.1.1.4.2 yamt read_abbrevs (struct backtrace_state *state, uint64_t abbrev_offset,
1013 1.1.1.1.4.2 yamt const unsigned char *dwarf_abbrev, size_t dwarf_abbrev_size,
1014 1.1.1.1.4.2 yamt int is_bigendian, backtrace_error_callback error_callback,
1015 1.1.1.1.4.2 yamt void *data, struct abbrevs *abbrevs)
1016 1.1.1.1.4.2 yamt {
1017 1.1.1.1.4.2 yamt struct dwarf_buf abbrev_buf;
1018 1.1.1.1.4.2 yamt struct dwarf_buf count_buf;
1019 1.1.1.1.4.2 yamt size_t num_abbrevs;
1020 1.1.1.1.4.2 yamt
1021 1.1.1.1.4.2 yamt abbrevs->num_abbrevs = 0;
1022 1.1.1.1.4.2 yamt abbrevs->abbrevs = NULL;
1023 1.1.1.1.4.2 yamt
1024 1.1.1.1.4.2 yamt if (abbrev_offset >= dwarf_abbrev_size)
1025 1.1.1.1.4.2 yamt {
1026 1.1.1.1.4.2 yamt error_callback (data, "abbrev offset out of range", 0);
1027 1.1.1.1.4.2 yamt return 0;
1028 1.1.1.1.4.2 yamt }
1029 1.1.1.1.4.2 yamt
1030 1.1.1.1.4.2 yamt abbrev_buf.name = ".debug_abbrev";
1031 1.1.1.1.4.2 yamt abbrev_buf.start = dwarf_abbrev;
1032 1.1.1.1.4.2 yamt abbrev_buf.buf = dwarf_abbrev + abbrev_offset;
1033 1.1.1.1.4.2 yamt abbrev_buf.left = dwarf_abbrev_size - abbrev_offset;
1034 1.1.1.1.4.2 yamt abbrev_buf.is_bigendian = is_bigendian;
1035 1.1.1.1.4.2 yamt abbrev_buf.error_callback = error_callback;
1036 1.1.1.1.4.2 yamt abbrev_buf.data = data;
1037 1.1.1.1.4.2 yamt abbrev_buf.reported_underflow = 0;
1038 1.1.1.1.4.2 yamt
1039 1.1.1.1.4.2 yamt /* Count the number of abbrevs in this list. */
1040 1.1.1.1.4.2 yamt
1041 1.1.1.1.4.2 yamt count_buf = abbrev_buf;
1042 1.1.1.1.4.2 yamt num_abbrevs = 0;
1043 1.1.1.1.4.2 yamt while (read_uleb128 (&count_buf) != 0)
1044 1.1.1.1.4.2 yamt {
1045 1.1.1.1.4.2 yamt if (count_buf.reported_underflow)
1046 1.1.1.1.4.2 yamt return 0;
1047 1.1.1.1.4.2 yamt ++num_abbrevs;
1048 1.1.1.1.4.2 yamt // Skip tag.
1049 1.1.1.1.4.2 yamt read_uleb128 (&count_buf);
1050 1.1.1.1.4.2 yamt // Skip has_children.
1051 1.1.1.1.4.2 yamt read_byte (&count_buf);
1052 1.1.1.1.4.2 yamt // Skip attributes.
1053 1.1.1.1.4.2 yamt while (read_uleb128 (&count_buf) != 0)
1054 1.1.1.1.4.2 yamt read_uleb128 (&count_buf);
1055 1.1.1.1.4.2 yamt // Skip form of last attribute.
1056 1.1.1.1.4.2 yamt read_uleb128 (&count_buf);
1057 1.1.1.1.4.2 yamt }
1058 1.1.1.1.4.2 yamt
1059 1.1.1.1.4.2 yamt if (count_buf.reported_underflow)
1060 1.1.1.1.4.2 yamt return 0;
1061 1.1.1.1.4.2 yamt
1062 1.1.1.1.4.2 yamt if (num_abbrevs == 0)
1063 1.1.1.1.4.2 yamt return 1;
1064 1.1.1.1.4.2 yamt
1065 1.1.1.1.4.2 yamt abbrevs->num_abbrevs = num_abbrevs;
1066 1.1.1.1.4.2 yamt abbrevs->abbrevs = ((struct abbrev *)
1067 1.1.1.1.4.2 yamt backtrace_alloc (state,
1068 1.1.1.1.4.2 yamt num_abbrevs * sizeof (struct abbrev),
1069 1.1.1.1.4.2 yamt error_callback, data));
1070 1.1.1.1.4.2 yamt if (abbrevs->abbrevs == NULL)
1071 1.1.1.1.4.2 yamt return 0;
1072 1.1.1.1.4.2 yamt memset (abbrevs->abbrevs, 0, num_abbrevs * sizeof (struct abbrev));
1073 1.1.1.1.4.2 yamt
1074 1.1.1.1.4.2 yamt num_abbrevs = 0;
1075 1.1.1.1.4.2 yamt while (1)
1076 1.1.1.1.4.2 yamt {
1077 1.1.1.1.4.2 yamt uint64_t code;
1078 1.1.1.1.4.2 yamt struct abbrev a;
1079 1.1.1.1.4.2 yamt size_t num_attrs;
1080 1.1.1.1.4.2 yamt struct attr *attrs;
1081 1.1.1.1.4.2 yamt
1082 1.1.1.1.4.2 yamt if (abbrev_buf.reported_underflow)
1083 1.1.1.1.4.2 yamt goto fail;
1084 1.1.1.1.4.2 yamt
1085 1.1.1.1.4.2 yamt code = read_uleb128 (&abbrev_buf);
1086 1.1.1.1.4.2 yamt if (code == 0)
1087 1.1.1.1.4.2 yamt break;
1088 1.1.1.1.4.2 yamt
1089 1.1.1.1.4.2 yamt a.code = code;
1090 1.1.1.1.4.2 yamt a.tag = (enum dwarf_tag) read_uleb128 (&abbrev_buf);
1091 1.1.1.1.4.2 yamt a.has_children = read_byte (&abbrev_buf);
1092 1.1.1.1.4.2 yamt
1093 1.1.1.1.4.2 yamt count_buf = abbrev_buf;
1094 1.1.1.1.4.2 yamt num_attrs = 0;
1095 1.1.1.1.4.2 yamt while (read_uleb128 (&count_buf) != 0)
1096 1.1.1.1.4.2 yamt {
1097 1.1.1.1.4.2 yamt ++num_attrs;
1098 1.1.1.1.4.2 yamt read_uleb128 (&count_buf);
1099 1.1.1.1.4.2 yamt }
1100 1.1.1.1.4.2 yamt
1101 1.1.1.1.4.2 yamt if (num_attrs == 0)
1102 1.1.1.1.4.2 yamt {
1103 1.1.1.1.4.2 yamt attrs = NULL;
1104 1.1.1.1.4.2 yamt read_uleb128 (&abbrev_buf);
1105 1.1.1.1.4.2 yamt read_uleb128 (&abbrev_buf);
1106 1.1.1.1.4.2 yamt }
1107 1.1.1.1.4.2 yamt else
1108 1.1.1.1.4.2 yamt {
1109 1.1.1.1.4.2 yamt attrs = ((struct attr *)
1110 1.1.1.1.4.2 yamt backtrace_alloc (state, num_attrs * sizeof *attrs,
1111 1.1.1.1.4.2 yamt error_callback, data));
1112 1.1.1.1.4.2 yamt if (attrs == NULL)
1113 1.1.1.1.4.2 yamt goto fail;
1114 1.1.1.1.4.2 yamt num_attrs = 0;
1115 1.1.1.1.4.2 yamt while (1)
1116 1.1.1.1.4.2 yamt {
1117 1.1.1.1.4.2 yamt uint64_t name;
1118 1.1.1.1.4.2 yamt uint64_t form;
1119 1.1.1.1.4.2 yamt
1120 1.1.1.1.4.2 yamt name = read_uleb128 (&abbrev_buf);
1121 1.1.1.1.4.2 yamt form = read_uleb128 (&abbrev_buf);
1122 1.1.1.1.4.2 yamt if (name == 0)
1123 1.1.1.1.4.2 yamt break;
1124 1.1.1.1.4.2 yamt attrs[num_attrs].name = (enum dwarf_attribute) name;
1125 1.1.1.1.4.2 yamt attrs[num_attrs].form = (enum dwarf_form) form;
1126 1.1.1.1.4.2 yamt ++num_attrs;
1127 1.1.1.1.4.2 yamt }
1128 1.1.1.1.4.2 yamt }
1129 1.1.1.1.4.2 yamt
1130 1.1.1.1.4.2 yamt a.num_attrs = num_attrs;
1131 1.1.1.1.4.2 yamt a.attrs = attrs;
1132 1.1.1.1.4.2 yamt
1133 1.1.1.1.4.2 yamt abbrevs->abbrevs[num_abbrevs] = a;
1134 1.1.1.1.4.2 yamt ++num_abbrevs;
1135 1.1.1.1.4.2 yamt }
1136 1.1.1.1.4.2 yamt
1137 1.1.1.1.4.2 yamt qsort (abbrevs->abbrevs, abbrevs->num_abbrevs, sizeof (struct abbrev),
1138 1.1.1.1.4.2 yamt abbrev_compare);
1139 1.1.1.1.4.2 yamt
1140 1.1.1.1.4.2 yamt return 1;
1141 1.1.1.1.4.2 yamt
1142 1.1.1.1.4.2 yamt fail:
1143 1.1.1.1.4.2 yamt free_abbrevs (state, abbrevs, error_callback, data);
1144 1.1.1.1.4.2 yamt return 0;
1145 1.1.1.1.4.2 yamt }
1146 1.1.1.1.4.2 yamt
1147 1.1.1.1.4.2 yamt /* Return the abbrev information for an abbrev code. */
1148 1.1.1.1.4.2 yamt
1149 1.1.1.1.4.2 yamt static const struct abbrev *
1150 1.1.1.1.4.2 yamt lookup_abbrev (struct abbrevs *abbrevs, uint64_t code,
1151 1.1.1.1.4.2 yamt backtrace_error_callback error_callback, void *data)
1152 1.1.1.1.4.2 yamt {
1153 1.1.1.1.4.2 yamt struct abbrev key;
1154 1.1.1.1.4.2 yamt void *p;
1155 1.1.1.1.4.2 yamt
1156 1.1.1.1.4.2 yamt /* With GCC, where abbrevs are simply numbered in order, we should
1157 1.1.1.1.4.2 yamt be able to just look up the entry. */
1158 1.1.1.1.4.2 yamt if (code - 1 < abbrevs->num_abbrevs
1159 1.1.1.1.4.2 yamt && abbrevs->abbrevs[code - 1].code == code)
1160 1.1.1.1.4.2 yamt return &abbrevs->abbrevs[code - 1];
1161 1.1.1.1.4.2 yamt
1162 1.1.1.1.4.2 yamt /* Otherwise we have to search. */
1163 1.1.1.1.4.2 yamt memset (&key, 0, sizeof key);
1164 1.1.1.1.4.2 yamt key.code = code;
1165 1.1.1.1.4.2 yamt p = bsearch (&key, abbrevs->abbrevs, abbrevs->num_abbrevs,
1166 1.1.1.1.4.2 yamt sizeof (struct abbrev), abbrev_compare);
1167 1.1.1.1.4.2 yamt if (p == NULL)
1168 1.1.1.1.4.2 yamt {
1169 1.1.1.1.4.2 yamt error_callback (data, "invalid abbreviation code", 0);
1170 1.1.1.1.4.2 yamt return NULL;
1171 1.1.1.1.4.2 yamt }
1172 1.1.1.1.4.2 yamt return (const struct abbrev *) p;
1173 1.1.1.1.4.2 yamt }
1174 1.1.1.1.4.2 yamt
1175 1.1.1.1.4.2 yamt /* Add non-contiguous address ranges for a compilation unit. Returns
1176 1.1.1.1.4.2 yamt 1 on success, 0 on failure. */
1177 1.1.1.1.4.2 yamt
1178 1.1.1.1.4.2 yamt static int
1179 1.1.1.1.4.2 yamt add_unit_ranges (struct backtrace_state *state, uintptr_t base_address,
1180 1.1.1.1.4.2 yamt struct unit *u, uint64_t ranges, uint64_t base,
1181 1.1.1.1.4.2 yamt int is_bigendian, const unsigned char *dwarf_ranges,
1182 1.1.1.1.4.2 yamt size_t dwarf_ranges_size,
1183 1.1.1.1.4.2 yamt backtrace_error_callback error_callback, void *data,
1184 1.1.1.1.4.2 yamt struct unit_addrs_vector *addrs)
1185 1.1.1.1.4.2 yamt {
1186 1.1.1.1.4.2 yamt struct dwarf_buf ranges_buf;
1187 1.1.1.1.4.2 yamt
1188 1.1.1.1.4.2 yamt if (ranges >= dwarf_ranges_size)
1189 1.1.1.1.4.2 yamt {
1190 1.1.1.1.4.2 yamt error_callback (data, "ranges offset out of range", 0);
1191 1.1.1.1.4.2 yamt return 0;
1192 1.1.1.1.4.2 yamt }
1193 1.1.1.1.4.2 yamt
1194 1.1.1.1.4.2 yamt ranges_buf.name = ".debug_ranges";
1195 1.1.1.1.4.2 yamt ranges_buf.start = dwarf_ranges;
1196 1.1.1.1.4.2 yamt ranges_buf.buf = dwarf_ranges + ranges;
1197 1.1.1.1.4.2 yamt ranges_buf.left = dwarf_ranges_size - ranges;
1198 1.1.1.1.4.2 yamt ranges_buf.is_bigendian = is_bigendian;
1199 1.1.1.1.4.2 yamt ranges_buf.error_callback = error_callback;
1200 1.1.1.1.4.2 yamt ranges_buf.data = data;
1201 1.1.1.1.4.2 yamt ranges_buf.reported_underflow = 0;
1202 1.1.1.1.4.2 yamt
1203 1.1.1.1.4.2 yamt while (1)
1204 1.1.1.1.4.2 yamt {
1205 1.1.1.1.4.2 yamt uint64_t low;
1206 1.1.1.1.4.2 yamt uint64_t high;
1207 1.1.1.1.4.2 yamt
1208 1.1.1.1.4.2 yamt if (ranges_buf.reported_underflow)
1209 1.1.1.1.4.2 yamt return 0;
1210 1.1.1.1.4.2 yamt
1211 1.1.1.1.4.2 yamt low = read_address (&ranges_buf, u->addrsize);
1212 1.1.1.1.4.2 yamt high = read_address (&ranges_buf, u->addrsize);
1213 1.1.1.1.4.2 yamt
1214 1.1.1.1.4.2 yamt if (low == 0 && high == 0)
1215 1.1.1.1.4.2 yamt break;
1216 1.1.1.1.4.2 yamt
1217 1.1.1.1.4.2 yamt if (is_highest_address (low, u->addrsize))
1218 1.1.1.1.4.2 yamt base = high;
1219 1.1.1.1.4.2 yamt else
1220 1.1.1.1.4.2 yamt {
1221 1.1.1.1.4.2 yamt struct unit_addrs a;
1222 1.1.1.1.4.2 yamt
1223 1.1.1.1.4.2 yamt a.low = low + base;
1224 1.1.1.1.4.2 yamt a.high = high + base;
1225 1.1.1.1.4.2 yamt a.u = u;
1226 1.1.1.1.4.2 yamt if (!add_unit_addr (state, base_address, a, error_callback, data,
1227 1.1.1.1.4.2 yamt addrs))
1228 1.1.1.1.4.2 yamt return 0;
1229 1.1.1.1.4.2 yamt }
1230 1.1.1.1.4.2 yamt }
1231 1.1.1.1.4.2 yamt
1232 1.1.1.1.4.2 yamt if (ranges_buf.reported_underflow)
1233 1.1.1.1.4.2 yamt return 0;
1234 1.1.1.1.4.2 yamt
1235 1.1.1.1.4.2 yamt return 1;
1236 1.1.1.1.4.2 yamt }
1237 1.1.1.1.4.2 yamt
1238 1.1.1.1.4.2 yamt /* Build a mapping from address ranges to the compilation units where
1239 1.1.1.1.4.2 yamt the line number information for that range can be found. Returns 1
1240 1.1.1.1.4.2 yamt on success, 0 on failure. */
1241 1.1.1.1.4.2 yamt
1242 1.1.1.1.4.2 yamt static int
1243 1.1.1.1.4.2 yamt build_address_map (struct backtrace_state *state, uintptr_t base_address,
1244 1.1.1.1.4.2 yamt const unsigned char *dwarf_info, size_t dwarf_info_size,
1245 1.1.1.1.4.2 yamt const unsigned char *dwarf_abbrev, size_t dwarf_abbrev_size,
1246 1.1.1.1.4.2 yamt const unsigned char *dwarf_ranges, size_t dwarf_ranges_size,
1247 1.1.1.1.4.2 yamt const unsigned char *dwarf_str, size_t dwarf_str_size,
1248 1.1.1.1.4.2 yamt int is_bigendian, backtrace_error_callback error_callback,
1249 1.1.1.1.4.2 yamt void *data, struct unit_addrs_vector *addrs)
1250 1.1.1.1.4.2 yamt {
1251 1.1.1.1.4.2 yamt struct dwarf_buf info;
1252 1.1.1.1.4.2 yamt struct abbrevs abbrevs;
1253 1.1.1.1.4.2 yamt
1254 1.1.1.1.4.2 yamt memset (&addrs->vec, 0, sizeof addrs->vec);
1255 1.1.1.1.4.2 yamt addrs->count = 0;
1256 1.1.1.1.4.2 yamt
1257 1.1.1.1.4.2 yamt /* Read through the .debug_info section. FIXME: Should we use the
1258 1.1.1.1.4.2 yamt .debug_aranges section? gdb and addr2line don't use it, but I'm
1259 1.1.1.1.4.2 yamt not sure why. */
1260 1.1.1.1.4.2 yamt
1261 1.1.1.1.4.2 yamt info.name = ".debug_info";
1262 1.1.1.1.4.2 yamt info.start = dwarf_info;
1263 1.1.1.1.4.2 yamt info.buf = dwarf_info;
1264 1.1.1.1.4.2 yamt info.left = dwarf_info_size;
1265 1.1.1.1.4.2 yamt info.is_bigendian = is_bigendian;
1266 1.1.1.1.4.2 yamt info.error_callback = error_callback;
1267 1.1.1.1.4.2 yamt info.data = data;
1268 1.1.1.1.4.2 yamt info.reported_underflow = 0;
1269 1.1.1.1.4.2 yamt
1270 1.1.1.1.4.2 yamt memset (&abbrevs, 0, sizeof abbrevs);
1271 1.1.1.1.4.2 yamt while (info.left > 0)
1272 1.1.1.1.4.2 yamt {
1273 1.1.1.1.4.2 yamt const unsigned char *unit_data_start;
1274 1.1.1.1.4.2 yamt uint64_t len;
1275 1.1.1.1.4.2 yamt int is_dwarf64;
1276 1.1.1.1.4.2 yamt struct dwarf_buf unit_buf;
1277 1.1.1.1.4.2 yamt int version;
1278 1.1.1.1.4.2 yamt uint64_t abbrev_offset;
1279 1.1.1.1.4.2 yamt const struct abbrev *abbrev;
1280 1.1.1.1.4.2 yamt int addrsize;
1281 1.1.1.1.4.2 yamt const unsigned char *unit_data;
1282 1.1.1.1.4.2 yamt size_t unit_data_len;
1283 1.1.1.1.4.2 yamt size_t unit_data_offset;
1284 1.1.1.1.4.2 yamt uint64_t code;
1285 1.1.1.1.4.2 yamt size_t i;
1286 1.1.1.1.4.2 yamt uint64_t lowpc;
1287 1.1.1.1.4.2 yamt int have_lowpc;
1288 1.1.1.1.4.2 yamt uint64_t highpc;
1289 1.1.1.1.4.2 yamt int have_highpc;
1290 1.1.1.1.4.2 yamt int highpc_is_relative;
1291 1.1.1.1.4.2 yamt uint64_t ranges;
1292 1.1.1.1.4.2 yamt int have_ranges;
1293 1.1.1.1.4.2 yamt uint64_t lineoff;
1294 1.1.1.1.4.2 yamt int have_lineoff;
1295 1.1.1.1.4.2 yamt const char *filename;
1296 1.1.1.1.4.2 yamt const char *comp_dir;
1297 1.1.1.1.4.2 yamt
1298 1.1.1.1.4.2 yamt if (info.reported_underflow)
1299 1.1.1.1.4.2 yamt goto fail;
1300 1.1.1.1.4.2 yamt
1301 1.1.1.1.4.2 yamt unit_data_start = info.buf;
1302 1.1.1.1.4.2 yamt
1303 1.1.1.1.4.2 yamt is_dwarf64 = 0;
1304 1.1.1.1.4.2 yamt len = read_uint32 (&info);
1305 1.1.1.1.4.2 yamt if (len == 0xffffffff)
1306 1.1.1.1.4.2 yamt {
1307 1.1.1.1.4.2 yamt len = read_uint64 (&info);
1308 1.1.1.1.4.2 yamt is_dwarf64 = 1;
1309 1.1.1.1.4.2 yamt }
1310 1.1.1.1.4.2 yamt
1311 1.1.1.1.4.2 yamt unit_buf = info;
1312 1.1.1.1.4.2 yamt unit_buf.left = len;
1313 1.1.1.1.4.2 yamt
1314 1.1.1.1.4.2 yamt if (!advance (&info, len))
1315 1.1.1.1.4.2 yamt goto fail;
1316 1.1.1.1.4.2 yamt
1317 1.1.1.1.4.2 yamt version = read_uint16 (&unit_buf);
1318 1.1.1.1.4.2 yamt if (version < 2 || version > 4)
1319 1.1.1.1.4.2 yamt {
1320 1.1.1.1.4.2 yamt dwarf_buf_error (&unit_buf, "unrecognized DWARF version");
1321 1.1.1.1.4.2 yamt goto fail;
1322 1.1.1.1.4.2 yamt }
1323 1.1.1.1.4.2 yamt
1324 1.1.1.1.4.2 yamt abbrev_offset = read_offset (&unit_buf, is_dwarf64);
1325 1.1.1.1.4.2 yamt if (!read_abbrevs (state, abbrev_offset, dwarf_abbrev, dwarf_abbrev_size,
1326 1.1.1.1.4.2 yamt is_bigendian, error_callback, data, &abbrevs))
1327 1.1.1.1.4.2 yamt goto fail;
1328 1.1.1.1.4.2 yamt
1329 1.1.1.1.4.2 yamt addrsize = read_byte (&unit_buf);
1330 1.1.1.1.4.2 yamt
1331 1.1.1.1.4.2 yamt unit_data = unit_buf.buf;
1332 1.1.1.1.4.2 yamt unit_data_len = unit_buf.left;
1333 1.1.1.1.4.2 yamt unit_data_offset = unit_buf.buf - unit_data_start;
1334 1.1.1.1.4.2 yamt
1335 1.1.1.1.4.2 yamt /* We only look at the first attribute in the compilation unit.
1336 1.1.1.1.4.2 yamt In practice this will be a DW_TAG_compile_unit which will
1337 1.1.1.1.4.2 yamt tell us the PC range and where to find the line number
1338 1.1.1.1.4.2 yamt information. */
1339 1.1.1.1.4.2 yamt
1340 1.1.1.1.4.2 yamt code = read_uleb128 (&unit_buf);
1341 1.1.1.1.4.2 yamt abbrev = lookup_abbrev (&abbrevs, code, error_callback, data);
1342 1.1.1.1.4.2 yamt if (abbrev == NULL)
1343 1.1.1.1.4.2 yamt goto fail;
1344 1.1.1.1.4.2 yamt
1345 1.1.1.1.4.2 yamt lowpc = 0;
1346 1.1.1.1.4.2 yamt have_lowpc = 0;
1347 1.1.1.1.4.2 yamt highpc = 0;
1348 1.1.1.1.4.2 yamt have_highpc = 0;
1349 1.1.1.1.4.2 yamt highpc_is_relative = 0;
1350 1.1.1.1.4.2 yamt ranges = 0;
1351 1.1.1.1.4.2 yamt have_ranges = 0;
1352 1.1.1.1.4.2 yamt lineoff = 0;
1353 1.1.1.1.4.2 yamt have_lineoff = 0;
1354 1.1.1.1.4.2 yamt filename = NULL;
1355 1.1.1.1.4.2 yamt comp_dir = NULL;
1356 1.1.1.1.4.2 yamt for (i = 0; i < abbrev->num_attrs; ++i)
1357 1.1.1.1.4.2 yamt {
1358 1.1.1.1.4.2 yamt struct attr_val val;
1359 1.1.1.1.4.2 yamt
1360 1.1.1.1.4.2 yamt if (!read_attribute (abbrev->attrs[i].form, &unit_buf, is_dwarf64,
1361 1.1.1.1.4.2 yamt version, addrsize, dwarf_str, dwarf_str_size,
1362 1.1.1.1.4.2 yamt &val))
1363 1.1.1.1.4.2 yamt goto fail;
1364 1.1.1.1.4.2 yamt
1365 1.1.1.1.4.2 yamt switch (abbrev->attrs[i].name)
1366 1.1.1.1.4.2 yamt {
1367 1.1.1.1.4.2 yamt case DW_AT_low_pc:
1368 1.1.1.1.4.2 yamt if (val.encoding == ATTR_VAL_ADDRESS)
1369 1.1.1.1.4.2 yamt {
1370 1.1.1.1.4.2 yamt lowpc = val.u.uint;
1371 1.1.1.1.4.2 yamt have_lowpc = 1;
1372 1.1.1.1.4.2 yamt }
1373 1.1.1.1.4.2 yamt break;
1374 1.1.1.1.4.2 yamt case DW_AT_high_pc:
1375 1.1.1.1.4.2 yamt if (val.encoding == ATTR_VAL_ADDRESS)
1376 1.1.1.1.4.2 yamt {
1377 1.1.1.1.4.2 yamt highpc = val.u.uint;
1378 1.1.1.1.4.2 yamt have_highpc = 1;
1379 1.1.1.1.4.2 yamt }
1380 1.1.1.1.4.2 yamt else if (val.encoding == ATTR_VAL_UINT)
1381 1.1.1.1.4.2 yamt {
1382 1.1.1.1.4.2 yamt highpc = val.u.uint;
1383 1.1.1.1.4.2 yamt have_highpc = 1;
1384 1.1.1.1.4.2 yamt highpc_is_relative = 1;
1385 1.1.1.1.4.2 yamt }
1386 1.1.1.1.4.2 yamt break;
1387 1.1.1.1.4.2 yamt case DW_AT_ranges:
1388 1.1.1.1.4.2 yamt if (val.encoding == ATTR_VAL_UINT
1389 1.1.1.1.4.2 yamt || val.encoding == ATTR_VAL_REF_SECTION)
1390 1.1.1.1.4.2 yamt {
1391 1.1.1.1.4.2 yamt ranges = val.u.uint;
1392 1.1.1.1.4.2 yamt have_ranges = 1;
1393 1.1.1.1.4.2 yamt }
1394 1.1.1.1.4.2 yamt break;
1395 1.1.1.1.4.2 yamt case DW_AT_stmt_list:
1396 1.1.1.1.4.2 yamt if (val.encoding == ATTR_VAL_UINT
1397 1.1.1.1.4.2 yamt || val.encoding == ATTR_VAL_REF_SECTION)
1398 1.1.1.1.4.2 yamt {
1399 1.1.1.1.4.2 yamt lineoff = val.u.uint;
1400 1.1.1.1.4.2 yamt have_lineoff = 1;
1401 1.1.1.1.4.2 yamt }
1402 1.1.1.1.4.2 yamt break;
1403 1.1.1.1.4.2 yamt case DW_AT_name:
1404 1.1.1.1.4.2 yamt if (val.encoding == ATTR_VAL_STRING)
1405 1.1.1.1.4.2 yamt filename = val.u.string;
1406 1.1.1.1.4.2 yamt break;
1407 1.1.1.1.4.2 yamt case DW_AT_comp_dir:
1408 1.1.1.1.4.2 yamt if (val.encoding == ATTR_VAL_STRING)
1409 1.1.1.1.4.2 yamt comp_dir = val.u.string;
1410 1.1.1.1.4.2 yamt break;
1411 1.1.1.1.4.2 yamt default:
1412 1.1.1.1.4.2 yamt break;
1413 1.1.1.1.4.2 yamt }
1414 1.1.1.1.4.2 yamt }
1415 1.1.1.1.4.2 yamt
1416 1.1.1.1.4.2 yamt if (unit_buf.reported_underflow)
1417 1.1.1.1.4.2 yamt goto fail;
1418 1.1.1.1.4.2 yamt
1419 1.1.1.1.4.2 yamt if (((have_lowpc && have_highpc) || have_ranges) && have_lineoff)
1420 1.1.1.1.4.2 yamt {
1421 1.1.1.1.4.2 yamt struct unit *u;
1422 1.1.1.1.4.2 yamt struct unit_addrs a;
1423 1.1.1.1.4.2 yamt
1424 1.1.1.1.4.2 yamt u = ((struct unit *)
1425 1.1.1.1.4.2 yamt backtrace_alloc (state, sizeof *u, error_callback, data));
1426 1.1.1.1.4.2 yamt if (u == NULL)
1427 1.1.1.1.4.2 yamt goto fail;
1428 1.1.1.1.4.2 yamt u->unit_data = unit_data;
1429 1.1.1.1.4.2 yamt u->unit_data_len = unit_data_len;
1430 1.1.1.1.4.2 yamt u->unit_data_offset = unit_data_offset;
1431 1.1.1.1.4.2 yamt u->version = version;
1432 1.1.1.1.4.2 yamt u->is_dwarf64 = is_dwarf64;
1433 1.1.1.1.4.2 yamt u->addrsize = addrsize;
1434 1.1.1.1.4.2 yamt u->filename = filename;
1435 1.1.1.1.4.2 yamt u->comp_dir = comp_dir;
1436 1.1.1.1.4.2 yamt u->abs_filename = NULL;
1437 1.1.1.1.4.2 yamt u->lineoff = lineoff;
1438 1.1.1.1.4.2 yamt u->abbrevs = abbrevs;
1439 1.1.1.1.4.2 yamt memset (&abbrevs, 0, sizeof abbrevs);
1440 1.1.1.1.4.2 yamt
1441 1.1.1.1.4.2 yamt /* The actual line number mappings will be read as
1442 1.1.1.1.4.2 yamt needed. */
1443 1.1.1.1.4.2 yamt u->lines = NULL;
1444 1.1.1.1.4.2 yamt u->lines_count = 0;
1445 1.1.1.1.4.2 yamt u->function_addrs = NULL;
1446 1.1.1.1.4.2 yamt u->function_addrs_count = 0;
1447 1.1.1.1.4.2 yamt
1448 1.1.1.1.4.2 yamt if (have_ranges)
1449 1.1.1.1.4.2 yamt {
1450 1.1.1.1.4.2 yamt if (!add_unit_ranges (state, base_address, u, ranges, lowpc,
1451 1.1.1.1.4.2 yamt is_bigendian, dwarf_ranges,
1452 1.1.1.1.4.2 yamt dwarf_ranges_size, error_callback, data,
1453 1.1.1.1.4.2 yamt addrs))
1454 1.1.1.1.4.2 yamt {
1455 1.1.1.1.4.2 yamt free_abbrevs (state, &u->abbrevs, error_callback, data);
1456 1.1.1.1.4.2 yamt backtrace_free (state, u, sizeof *u, error_callback, data);
1457 1.1.1.1.4.2 yamt goto fail;
1458 1.1.1.1.4.2 yamt }
1459 1.1.1.1.4.2 yamt }
1460 1.1.1.1.4.2 yamt else
1461 1.1.1.1.4.2 yamt {
1462 1.1.1.1.4.2 yamt if (highpc_is_relative)
1463 1.1.1.1.4.2 yamt highpc += lowpc;
1464 1.1.1.1.4.2 yamt a.low = lowpc;
1465 1.1.1.1.4.2 yamt a.high = highpc;
1466 1.1.1.1.4.2 yamt a.u = u;
1467 1.1.1.1.4.2 yamt
1468 1.1.1.1.4.2 yamt if (!add_unit_addr (state, base_address, a, error_callback, data,
1469 1.1.1.1.4.2 yamt addrs))
1470 1.1.1.1.4.2 yamt {
1471 1.1.1.1.4.2 yamt free_abbrevs (state, &u->abbrevs, error_callback, data);
1472 1.1.1.1.4.2 yamt backtrace_free (state, u, sizeof *u, error_callback, data);
1473 1.1.1.1.4.2 yamt goto fail;
1474 1.1.1.1.4.2 yamt }
1475 1.1.1.1.4.2 yamt }
1476 1.1.1.1.4.2 yamt }
1477 1.1.1.1.4.2 yamt else
1478 1.1.1.1.4.2 yamt {
1479 1.1.1.1.4.2 yamt free_abbrevs (state, &abbrevs, error_callback, data);
1480 1.1.1.1.4.2 yamt memset (&abbrevs, 0, sizeof abbrevs);
1481 1.1.1.1.4.2 yamt }
1482 1.1.1.1.4.2 yamt }
1483 1.1.1.1.4.2 yamt if (info.reported_underflow)
1484 1.1.1.1.4.2 yamt goto fail;
1485 1.1.1.1.4.2 yamt
1486 1.1.1.1.4.2 yamt return 1;
1487 1.1.1.1.4.2 yamt
1488 1.1.1.1.4.2 yamt fail:
1489 1.1.1.1.4.2 yamt free_abbrevs (state, &abbrevs, error_callback, data);
1490 1.1.1.1.4.2 yamt free_unit_addrs_vector (state, addrs, error_callback, data);
1491 1.1.1.1.4.2 yamt return 0;
1492 1.1.1.1.4.2 yamt }
1493 1.1.1.1.4.2 yamt
1494 1.1.1.1.4.2 yamt /* Add a new mapping to the vector of line mappings that we are
1495 1.1.1.1.4.2 yamt building. Returns 1 on success, 0 on failure. */
1496 1.1.1.1.4.2 yamt
1497 1.1.1.1.4.2 yamt static int
1498 1.1.1.1.4.2 yamt add_line (struct backtrace_state *state, struct dwarf_data *ddata,
1499 1.1.1.1.4.2 yamt uintptr_t pc, const char *filename, int lineno,
1500 1.1.1.1.4.2 yamt backtrace_error_callback error_callback, void *data,
1501 1.1.1.1.4.2 yamt struct line_vector *vec)
1502 1.1.1.1.4.2 yamt {
1503 1.1.1.1.4.2 yamt struct line *ln;
1504 1.1.1.1.4.2 yamt
1505 1.1.1.1.4.2 yamt /* If we are adding the same mapping, ignore it. This can happen
1506 1.1.1.1.4.2 yamt when using discriminators. */
1507 1.1.1.1.4.2 yamt if (vec->count > 0)
1508 1.1.1.1.4.2 yamt {
1509 1.1.1.1.4.2 yamt ln = (struct line *) vec->vec.base + (vec->count - 1);
1510 1.1.1.1.4.2 yamt if (pc == ln->pc && filename == ln->filename && lineno == ln->lineno)
1511 1.1.1.1.4.2 yamt return 1;
1512 1.1.1.1.4.2 yamt }
1513 1.1.1.1.4.2 yamt
1514 1.1.1.1.4.2 yamt ln = ((struct line *)
1515 1.1.1.1.4.2 yamt backtrace_vector_grow (state, sizeof (struct line), error_callback,
1516 1.1.1.1.4.2 yamt data, &vec->vec));
1517 1.1.1.1.4.2 yamt if (ln == NULL)
1518 1.1.1.1.4.2 yamt return 0;
1519 1.1.1.1.4.2 yamt
1520 1.1.1.1.4.2 yamt /* Add in the base address here, so that we can look up the PC
1521 1.1.1.1.4.2 yamt directly. */
1522 1.1.1.1.4.2 yamt ln->pc = pc + ddata->base_address;
1523 1.1.1.1.4.2 yamt
1524 1.1.1.1.4.2 yamt ln->filename = filename;
1525 1.1.1.1.4.2 yamt ln->lineno = lineno;
1526 1.1.1.1.4.2 yamt
1527 1.1.1.1.4.2 yamt ++vec->count;
1528 1.1.1.1.4.2 yamt
1529 1.1.1.1.4.2 yamt return 1;
1530 1.1.1.1.4.2 yamt }
1531 1.1.1.1.4.2 yamt
1532 1.1.1.1.4.2 yamt /* Free the line header information. If FREE_FILENAMES is true we
1533 1.1.1.1.4.2 yamt free the file names themselves, otherwise we leave them, as there
1534 1.1.1.1.4.2 yamt may be line structures pointing to them. */
1535 1.1.1.1.4.2 yamt
1536 1.1.1.1.4.2 yamt static void
1537 1.1.1.1.4.2 yamt free_line_header (struct backtrace_state *state, struct line_header *hdr,
1538 1.1.1.1.4.2 yamt backtrace_error_callback error_callback, void *data)
1539 1.1.1.1.4.2 yamt {
1540 1.1.1.1.4.2 yamt backtrace_free (state, hdr->dirs, hdr->dirs_count * sizeof (const char *),
1541 1.1.1.1.4.2 yamt error_callback, data);
1542 1.1.1.1.4.2 yamt backtrace_free (state, hdr->filenames,
1543 1.1.1.1.4.2 yamt hdr->filenames_count * sizeof (char *),
1544 1.1.1.1.4.2 yamt error_callback, data);
1545 1.1.1.1.4.2 yamt }
1546 1.1.1.1.4.2 yamt
1547 1.1.1.1.4.2 yamt /* Read the line header. Return 1 on success, 0 on failure. */
1548 1.1.1.1.4.2 yamt
1549 1.1.1.1.4.2 yamt static int
1550 1.1.1.1.4.2 yamt read_line_header (struct backtrace_state *state, struct unit *u,
1551 1.1.1.1.4.2 yamt int is_dwarf64, struct dwarf_buf *line_buf,
1552 1.1.1.1.4.2 yamt struct line_header *hdr)
1553 1.1.1.1.4.2 yamt {
1554 1.1.1.1.4.2 yamt uint64_t hdrlen;
1555 1.1.1.1.4.2 yamt struct dwarf_buf hdr_buf;
1556 1.1.1.1.4.2 yamt const unsigned char *p;
1557 1.1.1.1.4.2 yamt const unsigned char *pend;
1558 1.1.1.1.4.2 yamt size_t i;
1559 1.1.1.1.4.2 yamt
1560 1.1.1.1.4.2 yamt hdr->version = read_uint16 (line_buf);
1561 1.1.1.1.4.2 yamt if (hdr->version < 2 || hdr->version > 4)
1562 1.1.1.1.4.2 yamt {
1563 1.1.1.1.4.2 yamt dwarf_buf_error (line_buf, "unsupported line number version");
1564 1.1.1.1.4.2 yamt return 0;
1565 1.1.1.1.4.2 yamt }
1566 1.1.1.1.4.2 yamt
1567 1.1.1.1.4.2 yamt hdrlen = read_offset (line_buf, is_dwarf64);
1568 1.1.1.1.4.2 yamt
1569 1.1.1.1.4.2 yamt hdr_buf = *line_buf;
1570 1.1.1.1.4.2 yamt hdr_buf.left = hdrlen;
1571 1.1.1.1.4.2 yamt
1572 1.1.1.1.4.2 yamt if (!advance (line_buf, hdrlen))
1573 1.1.1.1.4.2 yamt return 0;
1574 1.1.1.1.4.2 yamt
1575 1.1.1.1.4.2 yamt hdr->min_insn_len = read_byte (&hdr_buf);
1576 1.1.1.1.4.2 yamt if (hdr->version < 4)
1577 1.1.1.1.4.2 yamt hdr->max_ops_per_insn = 1;
1578 1.1.1.1.4.2 yamt else
1579 1.1.1.1.4.2 yamt hdr->max_ops_per_insn = read_byte (&hdr_buf);
1580 1.1.1.1.4.2 yamt
1581 1.1.1.1.4.2 yamt /* We don't care about default_is_stmt. */
1582 1.1.1.1.4.2 yamt read_byte (&hdr_buf);
1583 1.1.1.1.4.2 yamt
1584 1.1.1.1.4.2 yamt hdr->line_base = read_sbyte (&hdr_buf);
1585 1.1.1.1.4.2 yamt hdr->line_range = read_byte (&hdr_buf);
1586 1.1.1.1.4.2 yamt
1587 1.1.1.1.4.2 yamt hdr->opcode_base = read_byte (&hdr_buf);
1588 1.1.1.1.4.2 yamt hdr->opcode_lengths = hdr_buf.buf;
1589 1.1.1.1.4.2 yamt if (!advance (&hdr_buf, hdr->opcode_base - 1))
1590 1.1.1.1.4.2 yamt return 0;
1591 1.1.1.1.4.2 yamt
1592 1.1.1.1.4.2 yamt /* Count the number of directory entries. */
1593 1.1.1.1.4.2 yamt hdr->dirs_count = 0;
1594 1.1.1.1.4.2 yamt p = hdr_buf.buf;
1595 1.1.1.1.4.2 yamt pend = p + hdr_buf.left;
1596 1.1.1.1.4.2 yamt while (p < pend && *p != '\0')
1597 1.1.1.1.4.2 yamt {
1598 1.1.1.1.4.2 yamt p += strnlen((const char *) p, pend - p) + 1;
1599 1.1.1.1.4.2 yamt ++hdr->dirs_count;
1600 1.1.1.1.4.2 yamt }
1601 1.1.1.1.4.2 yamt
1602 1.1.1.1.4.2 yamt hdr->dirs = ((const char **)
1603 1.1.1.1.4.2 yamt backtrace_alloc (state,
1604 1.1.1.1.4.2 yamt hdr->dirs_count * sizeof (const char *),
1605 1.1.1.1.4.2 yamt line_buf->error_callback, line_buf->data));
1606 1.1.1.1.4.2 yamt if (hdr->dirs == NULL)
1607 1.1.1.1.4.2 yamt return 0;
1608 1.1.1.1.4.2 yamt
1609 1.1.1.1.4.2 yamt i = 0;
1610 1.1.1.1.4.2 yamt while (*hdr_buf.buf != '\0')
1611 1.1.1.1.4.2 yamt {
1612 1.1.1.1.4.2 yamt if (hdr_buf.reported_underflow)
1613 1.1.1.1.4.2 yamt return 0;
1614 1.1.1.1.4.2 yamt
1615 1.1.1.1.4.2 yamt hdr->dirs[i] = (const char *) hdr_buf.buf;
1616 1.1.1.1.4.2 yamt ++i;
1617 1.1.1.1.4.2 yamt if (!advance (&hdr_buf,
1618 1.1.1.1.4.2 yamt strnlen ((const char *) hdr_buf.buf, hdr_buf.left) + 1))
1619 1.1.1.1.4.2 yamt return 0;
1620 1.1.1.1.4.2 yamt }
1621 1.1.1.1.4.2 yamt if (!advance (&hdr_buf, 1))
1622 1.1.1.1.4.2 yamt return 0;
1623 1.1.1.1.4.2 yamt
1624 1.1.1.1.4.2 yamt /* Count the number of file entries. */
1625 1.1.1.1.4.2 yamt hdr->filenames_count = 0;
1626 1.1.1.1.4.2 yamt p = hdr_buf.buf;
1627 1.1.1.1.4.2 yamt pend = p + hdr_buf.left;
1628 1.1.1.1.4.2 yamt while (p < pend && *p != '\0')
1629 1.1.1.1.4.2 yamt {
1630 1.1.1.1.4.2 yamt p += strnlen ((const char *) p, pend - p) + 1;
1631 1.1.1.1.4.2 yamt p += leb128_len (p);
1632 1.1.1.1.4.2 yamt p += leb128_len (p);
1633 1.1.1.1.4.2 yamt p += leb128_len (p);
1634 1.1.1.1.4.2 yamt ++hdr->filenames_count;
1635 1.1.1.1.4.2 yamt }
1636 1.1.1.1.4.2 yamt
1637 1.1.1.1.4.2 yamt hdr->filenames = ((const char **)
1638 1.1.1.1.4.2 yamt backtrace_alloc (state,
1639 1.1.1.1.4.2 yamt hdr->filenames_count * sizeof (char *),
1640 1.1.1.1.4.2 yamt line_buf->error_callback,
1641 1.1.1.1.4.2 yamt line_buf->data));
1642 1.1.1.1.4.2 yamt if (hdr->filenames == NULL)
1643 1.1.1.1.4.2 yamt return 0;
1644 1.1.1.1.4.2 yamt i = 0;
1645 1.1.1.1.4.2 yamt while (*hdr_buf.buf != '\0')
1646 1.1.1.1.4.2 yamt {
1647 1.1.1.1.4.2 yamt const char *filename;
1648 1.1.1.1.4.2 yamt uint64_t dir_index;
1649 1.1.1.1.4.2 yamt
1650 1.1.1.1.4.2 yamt if (hdr_buf.reported_underflow)
1651 1.1.1.1.4.2 yamt return 0;
1652 1.1.1.1.4.2 yamt
1653 1.1.1.1.4.2 yamt filename = (const char *) hdr_buf.buf;
1654 1.1.1.1.4.2 yamt if (!advance (&hdr_buf,
1655 1.1.1.1.4.2 yamt strnlen ((const char *) hdr_buf.buf, hdr_buf.left) + 1))
1656 1.1.1.1.4.2 yamt return 0;
1657 1.1.1.1.4.2 yamt dir_index = read_uleb128 (&hdr_buf);
1658 1.1.1.1.4.2 yamt if (IS_ABSOLUTE_PATH (filename)
1659 1.1.1.1.4.2 yamt || (dir_index == 0 && u->comp_dir == NULL))
1660 1.1.1.1.4.2 yamt hdr->filenames[i] = filename;
1661 1.1.1.1.4.2 yamt else
1662 1.1.1.1.4.2 yamt {
1663 1.1.1.1.4.2 yamt const char *dir;
1664 1.1.1.1.4.2 yamt size_t dir_len;
1665 1.1.1.1.4.2 yamt size_t filename_len;
1666 1.1.1.1.4.2 yamt char *s;
1667 1.1.1.1.4.2 yamt
1668 1.1.1.1.4.2 yamt if (dir_index == 0)
1669 1.1.1.1.4.2 yamt dir = u->comp_dir;
1670 1.1.1.1.4.2 yamt else if (dir_index - 1 < hdr->dirs_count)
1671 1.1.1.1.4.2 yamt dir = hdr->dirs[dir_index - 1];
1672 1.1.1.1.4.2 yamt else
1673 1.1.1.1.4.2 yamt {
1674 1.1.1.1.4.2 yamt dwarf_buf_error (line_buf,
1675 1.1.1.1.4.2 yamt ("invalid directory index in "
1676 1.1.1.1.4.2 yamt "line number program header"));
1677 1.1.1.1.4.2 yamt return 0;
1678 1.1.1.1.4.2 yamt }
1679 1.1.1.1.4.2 yamt dir_len = strlen (dir);
1680 1.1.1.1.4.2 yamt filename_len = strlen (filename);
1681 1.1.1.1.4.2 yamt s = ((char *)
1682 1.1.1.1.4.2 yamt backtrace_alloc (state, dir_len + filename_len + 2,
1683 1.1.1.1.4.2 yamt line_buf->error_callback, line_buf->data));
1684 1.1.1.1.4.2 yamt if (s == NULL)
1685 1.1.1.1.4.2 yamt return 0;
1686 1.1.1.1.4.2 yamt memcpy (s, dir, dir_len);
1687 1.1.1.1.4.2 yamt /* FIXME: If we are on a DOS-based file system, and the
1688 1.1.1.1.4.2 yamt directory or the file name use backslashes, then we
1689 1.1.1.1.4.2 yamt should use a backslash here. */
1690 1.1.1.1.4.2 yamt s[dir_len] = '/';
1691 1.1.1.1.4.2 yamt memcpy (s + dir_len + 1, filename, filename_len + 1);
1692 1.1.1.1.4.2 yamt hdr->filenames[i] = s;
1693 1.1.1.1.4.2 yamt }
1694 1.1.1.1.4.2 yamt
1695 1.1.1.1.4.2 yamt /* Ignore the modification time and size. */
1696 1.1.1.1.4.2 yamt read_uleb128 (&hdr_buf);
1697 1.1.1.1.4.2 yamt read_uleb128 (&hdr_buf);
1698 1.1.1.1.4.2 yamt
1699 1.1.1.1.4.2 yamt ++i;
1700 1.1.1.1.4.2 yamt }
1701 1.1.1.1.4.2 yamt
1702 1.1.1.1.4.2 yamt if (hdr_buf.reported_underflow)
1703 1.1.1.1.4.2 yamt return 0;
1704 1.1.1.1.4.2 yamt
1705 1.1.1.1.4.2 yamt return 1;
1706 1.1.1.1.4.2 yamt }
1707 1.1.1.1.4.2 yamt
1708 1.1.1.1.4.2 yamt /* Read the line program, adding line mappings to VEC. Return 1 on
1709 1.1.1.1.4.2 yamt success, 0 on failure. */
1710 1.1.1.1.4.2 yamt
1711 1.1.1.1.4.2 yamt static int
1712 1.1.1.1.4.2 yamt read_line_program (struct backtrace_state *state, struct dwarf_data *ddata,
1713 1.1.1.1.4.2 yamt struct unit *u, const struct line_header *hdr,
1714 1.1.1.1.4.2 yamt struct dwarf_buf *line_buf, struct line_vector *vec)
1715 1.1.1.1.4.2 yamt {
1716 1.1.1.1.4.2 yamt uint64_t address;
1717 1.1.1.1.4.2 yamt unsigned int op_index;
1718 1.1.1.1.4.2 yamt const char *reset_filename;
1719 1.1.1.1.4.2 yamt const char *filename;
1720 1.1.1.1.4.2 yamt int lineno;
1721 1.1.1.1.4.2 yamt
1722 1.1.1.1.4.2 yamt address = 0;
1723 1.1.1.1.4.2 yamt op_index = 0;
1724 1.1.1.1.4.2 yamt if (hdr->filenames_count > 0)
1725 1.1.1.1.4.2 yamt reset_filename = hdr->filenames[0];
1726 1.1.1.1.4.2 yamt else
1727 1.1.1.1.4.2 yamt reset_filename = "";
1728 1.1.1.1.4.2 yamt filename = reset_filename;
1729 1.1.1.1.4.2 yamt lineno = 1;
1730 1.1.1.1.4.2 yamt while (line_buf->left > 0)
1731 1.1.1.1.4.2 yamt {
1732 1.1.1.1.4.2 yamt unsigned int op;
1733 1.1.1.1.4.2 yamt
1734 1.1.1.1.4.2 yamt op = read_byte (line_buf);
1735 1.1.1.1.4.2 yamt if (op >= hdr->opcode_base)
1736 1.1.1.1.4.2 yamt {
1737 1.1.1.1.4.2 yamt unsigned int advance;
1738 1.1.1.1.4.2 yamt
1739 1.1.1.1.4.2 yamt /* Special opcode. */
1740 1.1.1.1.4.2 yamt op -= hdr->opcode_base;
1741 1.1.1.1.4.2 yamt advance = op / hdr->line_range;
1742 1.1.1.1.4.2 yamt address += (hdr->min_insn_len * (op_index + advance)
1743 1.1.1.1.4.2 yamt / hdr->max_ops_per_insn);
1744 1.1.1.1.4.2 yamt op_index = (op_index + advance) % hdr->max_ops_per_insn;
1745 1.1.1.1.4.2 yamt lineno += hdr->line_base + (int) (op % hdr->line_range);
1746 1.1.1.1.4.2 yamt add_line (state, ddata, address, filename, lineno,
1747 1.1.1.1.4.2 yamt line_buf->error_callback, line_buf->data, vec);
1748 1.1.1.1.4.2 yamt }
1749 1.1.1.1.4.2 yamt else if (op == DW_LNS_extended_op)
1750 1.1.1.1.4.2 yamt {
1751 1.1.1.1.4.2 yamt uint64_t len;
1752 1.1.1.1.4.2 yamt
1753 1.1.1.1.4.2 yamt len = read_uleb128 (line_buf);
1754 1.1.1.1.4.2 yamt op = read_byte (line_buf);
1755 1.1.1.1.4.2 yamt switch (op)
1756 1.1.1.1.4.2 yamt {
1757 1.1.1.1.4.2 yamt case DW_LNE_end_sequence:
1758 1.1.1.1.4.2 yamt /* FIXME: Should we mark the high PC here? It seems
1759 1.1.1.1.4.2 yamt that we already have that information from the
1760 1.1.1.1.4.2 yamt compilation unit. */
1761 1.1.1.1.4.2 yamt address = 0;
1762 1.1.1.1.4.2 yamt op_index = 0;
1763 1.1.1.1.4.2 yamt filename = reset_filename;
1764 1.1.1.1.4.2 yamt lineno = 1;
1765 1.1.1.1.4.2 yamt break;
1766 1.1.1.1.4.2 yamt case DW_LNE_set_address:
1767 1.1.1.1.4.2 yamt address = read_address (line_buf, u->addrsize);
1768 1.1.1.1.4.2 yamt break;
1769 1.1.1.1.4.2 yamt case DW_LNE_define_file:
1770 1.1.1.1.4.2 yamt {
1771 1.1.1.1.4.2 yamt const char *f;
1772 1.1.1.1.4.2 yamt unsigned int dir_index;
1773 1.1.1.1.4.2 yamt
1774 1.1.1.1.4.2 yamt f = (const char *) line_buf->buf;
1775 1.1.1.1.4.2 yamt if (!advance (line_buf, strnlen (f, line_buf->left) + 1))
1776 1.1.1.1.4.2 yamt return 0;
1777 1.1.1.1.4.2 yamt dir_index = read_uleb128 (line_buf);
1778 1.1.1.1.4.2 yamt /* Ignore that time and length. */
1779 1.1.1.1.4.2 yamt read_uleb128 (line_buf);
1780 1.1.1.1.4.2 yamt read_uleb128 (line_buf);
1781 1.1.1.1.4.2 yamt if (IS_ABSOLUTE_PATH (f))
1782 1.1.1.1.4.2 yamt filename = f;
1783 1.1.1.1.4.2 yamt else
1784 1.1.1.1.4.2 yamt {
1785 1.1.1.1.4.2 yamt const char *dir;
1786 1.1.1.1.4.2 yamt size_t dir_len;
1787 1.1.1.1.4.2 yamt size_t f_len;
1788 1.1.1.1.4.2 yamt char *p;
1789 1.1.1.1.4.2 yamt
1790 1.1.1.1.4.2 yamt if (dir_index == 0)
1791 1.1.1.1.4.2 yamt dir = u->comp_dir;
1792 1.1.1.1.4.2 yamt else if (dir_index - 1 < hdr->dirs_count)
1793 1.1.1.1.4.2 yamt dir = hdr->dirs[dir_index - 1];
1794 1.1.1.1.4.2 yamt else
1795 1.1.1.1.4.2 yamt {
1796 1.1.1.1.4.2 yamt dwarf_buf_error (line_buf,
1797 1.1.1.1.4.2 yamt ("invalid directory index "
1798 1.1.1.1.4.2 yamt "in line number program"));
1799 1.1.1.1.4.2 yamt return 0;
1800 1.1.1.1.4.2 yamt }
1801 1.1.1.1.4.2 yamt dir_len = strlen (dir);
1802 1.1.1.1.4.2 yamt f_len = strlen (f);
1803 1.1.1.1.4.2 yamt p = ((char *)
1804 1.1.1.1.4.2 yamt backtrace_alloc (state, dir_len + f_len + 2,
1805 1.1.1.1.4.2 yamt line_buf->error_callback,
1806 1.1.1.1.4.2 yamt line_buf->data));
1807 1.1.1.1.4.2 yamt if (p == NULL)
1808 1.1.1.1.4.2 yamt return 0;
1809 1.1.1.1.4.2 yamt memcpy (p, dir, dir_len);
1810 1.1.1.1.4.2 yamt /* FIXME: If we are on a DOS-based file system,
1811 1.1.1.1.4.2 yamt and the directory or the file name use
1812 1.1.1.1.4.2 yamt backslashes, then we should use a backslash
1813 1.1.1.1.4.2 yamt here. */
1814 1.1.1.1.4.2 yamt p[dir_len] = '/';
1815 1.1.1.1.4.2 yamt memcpy (p + dir_len + 1, f, f_len + 1);
1816 1.1.1.1.4.2 yamt filename = p;
1817 1.1.1.1.4.2 yamt }
1818 1.1.1.1.4.2 yamt }
1819 1.1.1.1.4.2 yamt break;
1820 1.1.1.1.4.2 yamt case DW_LNE_set_discriminator:
1821 1.1.1.1.4.2 yamt /* We don't care about discriminators. */
1822 1.1.1.1.4.2 yamt read_uleb128 (line_buf);
1823 1.1.1.1.4.2 yamt break;
1824 1.1.1.1.4.2 yamt default:
1825 1.1.1.1.4.2 yamt if (!advance (line_buf, len - 1))
1826 1.1.1.1.4.2 yamt return 0;
1827 1.1.1.1.4.2 yamt break;
1828 1.1.1.1.4.2 yamt }
1829 1.1.1.1.4.2 yamt }
1830 1.1.1.1.4.2 yamt else
1831 1.1.1.1.4.2 yamt {
1832 1.1.1.1.4.2 yamt switch (op)
1833 1.1.1.1.4.2 yamt {
1834 1.1.1.1.4.2 yamt case DW_LNS_copy:
1835 1.1.1.1.4.2 yamt add_line (state, ddata, address, filename, lineno,
1836 1.1.1.1.4.2 yamt line_buf->error_callback, line_buf->data, vec);
1837 1.1.1.1.4.2 yamt break;
1838 1.1.1.1.4.2 yamt case DW_LNS_advance_pc:
1839 1.1.1.1.4.2 yamt {
1840 1.1.1.1.4.2 yamt uint64_t advance;
1841 1.1.1.1.4.2 yamt
1842 1.1.1.1.4.2 yamt advance = read_uleb128 (line_buf);
1843 1.1.1.1.4.2 yamt address += (hdr->min_insn_len * (op_index + advance)
1844 1.1.1.1.4.2 yamt / hdr->max_ops_per_insn);
1845 1.1.1.1.4.2 yamt op_index = (op_index + advance) % hdr->max_ops_per_insn;
1846 1.1.1.1.4.2 yamt }
1847 1.1.1.1.4.2 yamt break;
1848 1.1.1.1.4.2 yamt case DW_LNS_advance_line:
1849 1.1.1.1.4.2 yamt lineno += (int) read_sleb128 (line_buf);
1850 1.1.1.1.4.2 yamt break;
1851 1.1.1.1.4.2 yamt case DW_LNS_set_file:
1852 1.1.1.1.4.2 yamt {
1853 1.1.1.1.4.2 yamt uint64_t fileno;
1854 1.1.1.1.4.2 yamt
1855 1.1.1.1.4.2 yamt fileno = read_uleb128 (line_buf);
1856 1.1.1.1.4.2 yamt if (fileno == 0)
1857 1.1.1.1.4.2 yamt filename = "";
1858 1.1.1.1.4.2 yamt else
1859 1.1.1.1.4.2 yamt {
1860 1.1.1.1.4.2 yamt if (fileno - 1 >= hdr->filenames_count)
1861 1.1.1.1.4.2 yamt {
1862 1.1.1.1.4.2 yamt dwarf_buf_error (line_buf,
1863 1.1.1.1.4.2 yamt ("invalid file number in "
1864 1.1.1.1.4.2 yamt "line number program"));
1865 1.1.1.1.4.2 yamt return 0;
1866 1.1.1.1.4.2 yamt }
1867 1.1.1.1.4.2 yamt filename = hdr->filenames[fileno - 1];
1868 1.1.1.1.4.2 yamt }
1869 1.1.1.1.4.2 yamt }
1870 1.1.1.1.4.2 yamt break;
1871 1.1.1.1.4.2 yamt case DW_LNS_set_column:
1872 1.1.1.1.4.2 yamt read_uleb128 (line_buf);
1873 1.1.1.1.4.2 yamt break;
1874 1.1.1.1.4.2 yamt case DW_LNS_negate_stmt:
1875 1.1.1.1.4.2 yamt break;
1876 1.1.1.1.4.2 yamt case DW_LNS_set_basic_block:
1877 1.1.1.1.4.2 yamt break;
1878 1.1.1.1.4.2 yamt case DW_LNS_const_add_pc:
1879 1.1.1.1.4.2 yamt {
1880 1.1.1.1.4.2 yamt unsigned int advance;
1881 1.1.1.1.4.2 yamt
1882 1.1.1.1.4.2 yamt op = 255 - hdr->opcode_base;
1883 1.1.1.1.4.2 yamt advance = op / hdr->line_range;
1884 1.1.1.1.4.2 yamt address += (hdr->min_insn_len * (op_index + advance)
1885 1.1.1.1.4.2 yamt / hdr->max_ops_per_insn);
1886 1.1.1.1.4.2 yamt op_index = (op_index + advance) % hdr->max_ops_per_insn;
1887 1.1.1.1.4.2 yamt }
1888 1.1.1.1.4.2 yamt break;
1889 1.1.1.1.4.2 yamt case DW_LNS_fixed_advance_pc:
1890 1.1.1.1.4.2 yamt address += read_uint16 (line_buf);
1891 1.1.1.1.4.2 yamt op_index = 0;
1892 1.1.1.1.4.2 yamt break;
1893 1.1.1.1.4.2 yamt case DW_LNS_set_prologue_end:
1894 1.1.1.1.4.2 yamt break;
1895 1.1.1.1.4.2 yamt case DW_LNS_set_epilogue_begin:
1896 1.1.1.1.4.2 yamt break;
1897 1.1.1.1.4.2 yamt case DW_LNS_set_isa:
1898 1.1.1.1.4.2 yamt read_uleb128 (line_buf);
1899 1.1.1.1.4.2 yamt break;
1900 1.1.1.1.4.2 yamt default:
1901 1.1.1.1.4.2 yamt {
1902 1.1.1.1.4.2 yamt unsigned int i;
1903 1.1.1.1.4.2 yamt
1904 1.1.1.1.4.2 yamt for (i = hdr->opcode_lengths[op - 1]; i > 0; --i)
1905 1.1.1.1.4.2 yamt read_uleb128 (line_buf);
1906 1.1.1.1.4.2 yamt }
1907 1.1.1.1.4.2 yamt break;
1908 1.1.1.1.4.2 yamt }
1909 1.1.1.1.4.2 yamt }
1910 1.1.1.1.4.2 yamt }
1911 1.1.1.1.4.2 yamt
1912 1.1.1.1.4.2 yamt return 1;
1913 1.1.1.1.4.2 yamt }
1914 1.1.1.1.4.2 yamt
1915 1.1.1.1.4.2 yamt /* Read the line number information for a compilation unit. Returns 1
1916 1.1.1.1.4.2 yamt on success, 0 on failure. */
1917 1.1.1.1.4.2 yamt
1918 1.1.1.1.4.2 yamt static int
1919 1.1.1.1.4.2 yamt read_line_info (struct backtrace_state *state, struct dwarf_data *ddata,
1920 1.1.1.1.4.2 yamt backtrace_error_callback error_callback, void *data,
1921 1.1.1.1.4.2 yamt struct unit *u, struct line_header *hdr, struct line **lines,
1922 1.1.1.1.4.2 yamt size_t *lines_count)
1923 1.1.1.1.4.2 yamt {
1924 1.1.1.1.4.2 yamt struct line_vector vec;
1925 1.1.1.1.4.2 yamt struct dwarf_buf line_buf;
1926 1.1.1.1.4.2 yamt uint64_t len;
1927 1.1.1.1.4.2 yamt int is_dwarf64;
1928 1.1.1.1.4.2 yamt struct line *ln;
1929 1.1.1.1.4.2 yamt
1930 1.1.1.1.4.2 yamt memset (&vec.vec, 0, sizeof vec.vec);
1931 1.1.1.1.4.2 yamt vec.count = 0;
1932 1.1.1.1.4.2 yamt
1933 1.1.1.1.4.2 yamt memset (hdr, 0, sizeof *hdr);
1934 1.1.1.1.4.2 yamt
1935 1.1.1.1.4.2 yamt if (u->lineoff != (off_t) (size_t) u->lineoff
1936 1.1.1.1.4.2 yamt || (size_t) u->lineoff >= ddata->dwarf_line_size)
1937 1.1.1.1.4.2 yamt {
1938 1.1.1.1.4.2 yamt error_callback (data, "unit line offset out of range", 0);
1939 1.1.1.1.4.2 yamt goto fail;
1940 1.1.1.1.4.2 yamt }
1941 1.1.1.1.4.2 yamt
1942 1.1.1.1.4.2 yamt line_buf.name = ".debug_line";
1943 1.1.1.1.4.2 yamt line_buf.start = ddata->dwarf_line;
1944 1.1.1.1.4.2 yamt line_buf.buf = ddata->dwarf_line + u->lineoff;
1945 1.1.1.1.4.2 yamt line_buf.left = ddata->dwarf_line_size - u->lineoff;
1946 1.1.1.1.4.2 yamt line_buf.is_bigendian = ddata->is_bigendian;
1947 1.1.1.1.4.2 yamt line_buf.error_callback = error_callback;
1948 1.1.1.1.4.2 yamt line_buf.data = data;
1949 1.1.1.1.4.2 yamt line_buf.reported_underflow = 0;
1950 1.1.1.1.4.2 yamt
1951 1.1.1.1.4.2 yamt is_dwarf64 = 0;
1952 1.1.1.1.4.2 yamt len = read_uint32 (&line_buf);
1953 1.1.1.1.4.2 yamt if (len == 0xffffffff)
1954 1.1.1.1.4.2 yamt {
1955 1.1.1.1.4.2 yamt len = read_uint64 (&line_buf);
1956 1.1.1.1.4.2 yamt is_dwarf64 = 1;
1957 1.1.1.1.4.2 yamt }
1958 1.1.1.1.4.2 yamt line_buf.left = len;
1959 1.1.1.1.4.2 yamt
1960 1.1.1.1.4.2 yamt if (!read_line_header (state, u, is_dwarf64, &line_buf, hdr))
1961 1.1.1.1.4.2 yamt goto fail;
1962 1.1.1.1.4.2 yamt
1963 1.1.1.1.4.2 yamt if (!read_line_program (state, ddata, u, hdr, &line_buf, &vec))
1964 1.1.1.1.4.2 yamt goto fail;
1965 1.1.1.1.4.2 yamt
1966 1.1.1.1.4.2 yamt if (line_buf.reported_underflow)
1967 1.1.1.1.4.2 yamt goto fail;
1968 1.1.1.1.4.2 yamt
1969 1.1.1.1.4.2 yamt if (vec.count == 0)
1970 1.1.1.1.4.2 yamt {
1971 1.1.1.1.4.2 yamt /* This is not a failure in the sense of a generating an error,
1972 1.1.1.1.4.2 yamt but it is a failure in that sense that we have no useful
1973 1.1.1.1.4.2 yamt information. */
1974 1.1.1.1.4.2 yamt goto fail;
1975 1.1.1.1.4.2 yamt }
1976 1.1.1.1.4.2 yamt
1977 1.1.1.1.4.2 yamt /* Allocate one extra entry at the end. */
1978 1.1.1.1.4.2 yamt ln = ((struct line *)
1979 1.1.1.1.4.2 yamt backtrace_vector_grow (state, sizeof (struct line), error_callback,
1980 1.1.1.1.4.2 yamt data, &vec.vec));
1981 1.1.1.1.4.2 yamt if (ln == NULL)
1982 1.1.1.1.4.2 yamt goto fail;
1983 1.1.1.1.4.2 yamt ln->pc = (uintptr_t) -1;
1984 1.1.1.1.4.2 yamt ln->filename = NULL;
1985 1.1.1.1.4.2 yamt ln->lineno = 0;
1986 1.1.1.1.4.2 yamt
1987 1.1.1.1.4.2 yamt if (!backtrace_vector_release (state, &vec.vec, error_callback, data))
1988 1.1.1.1.4.2 yamt goto fail;
1989 1.1.1.1.4.2 yamt
1990 1.1.1.1.4.2 yamt ln = (struct line *) vec.vec.base;
1991 1.1.1.1.4.2 yamt qsort (ln, vec.count, sizeof (struct line), line_compare);
1992 1.1.1.1.4.2 yamt
1993 1.1.1.1.4.2 yamt *lines = ln;
1994 1.1.1.1.4.2 yamt *lines_count = vec.count;
1995 1.1.1.1.4.2 yamt
1996 1.1.1.1.4.2 yamt return 1;
1997 1.1.1.1.4.2 yamt
1998 1.1.1.1.4.2 yamt fail:
1999 1.1.1.1.4.2 yamt vec.vec.alc += vec.vec.size;
2000 1.1.1.1.4.2 yamt vec.vec.size = 0;
2001 1.1.1.1.4.2 yamt backtrace_vector_release (state, &vec.vec, error_callback, data);
2002 1.1.1.1.4.2 yamt free_line_header (state, hdr, error_callback, data);
2003 1.1.1.1.4.2 yamt *lines = (struct line *) (uintptr_t) -1;
2004 1.1.1.1.4.2 yamt *lines_count = 0;
2005 1.1.1.1.4.2 yamt return 0;
2006 1.1.1.1.4.2 yamt }
2007 1.1.1.1.4.2 yamt
2008 1.1.1.1.4.2 yamt /* Read the name of a function from a DIE referenced by a
2009 1.1.1.1.4.2 yamt DW_AT_abstract_origin or DW_AT_specification tag. OFFSET is within
2010 1.1.1.1.4.2 yamt the same compilation unit. */
2011 1.1.1.1.4.2 yamt
2012 1.1.1.1.4.2 yamt static const char *
2013 1.1.1.1.4.2 yamt read_referenced_name (struct dwarf_data *ddata, struct unit *u,
2014 1.1.1.1.4.2 yamt uint64_t offset, backtrace_error_callback error_callback,
2015 1.1.1.1.4.2 yamt void *data)
2016 1.1.1.1.4.2 yamt {
2017 1.1.1.1.4.2 yamt struct dwarf_buf unit_buf;
2018 1.1.1.1.4.2 yamt uint64_t code;
2019 1.1.1.1.4.2 yamt const struct abbrev *abbrev;
2020 1.1.1.1.4.2 yamt const char *ret;
2021 1.1.1.1.4.2 yamt size_t i;
2022 1.1.1.1.4.2 yamt
2023 1.1.1.1.4.2 yamt /* OFFSET is from the start of the data for this compilation unit.
2024 1.1.1.1.4.2 yamt U->unit_data is the data, but it starts U->unit_data_offset bytes
2025 1.1.1.1.4.2 yamt from the beginning. */
2026 1.1.1.1.4.2 yamt
2027 1.1.1.1.4.2 yamt if (offset < u->unit_data_offset
2028 1.1.1.1.4.2 yamt || offset - u->unit_data_offset >= u->unit_data_len)
2029 1.1.1.1.4.2 yamt {
2030 1.1.1.1.4.2 yamt error_callback (data,
2031 1.1.1.1.4.2 yamt "abstract origin or specification out of range",
2032 1.1.1.1.4.2 yamt 0);
2033 1.1.1.1.4.2 yamt return NULL;
2034 1.1.1.1.4.2 yamt }
2035 1.1.1.1.4.2 yamt
2036 1.1.1.1.4.2 yamt offset -= u->unit_data_offset;
2037 1.1.1.1.4.2 yamt
2038 1.1.1.1.4.2 yamt unit_buf.name = ".debug_info";
2039 1.1.1.1.4.2 yamt unit_buf.start = ddata->dwarf_info;
2040 1.1.1.1.4.2 yamt unit_buf.buf = u->unit_data + offset;
2041 1.1.1.1.4.2 yamt unit_buf.left = u->unit_data_len - offset;
2042 1.1.1.1.4.2 yamt unit_buf.is_bigendian = ddata->is_bigendian;
2043 1.1.1.1.4.2 yamt unit_buf.error_callback = error_callback;
2044 1.1.1.1.4.2 yamt unit_buf.data = data;
2045 1.1.1.1.4.2 yamt unit_buf.reported_underflow = 0;
2046 1.1.1.1.4.2 yamt
2047 1.1.1.1.4.2 yamt code = read_uleb128 (&unit_buf);
2048 1.1.1.1.4.2 yamt if (code == 0)
2049 1.1.1.1.4.2 yamt {
2050 1.1.1.1.4.2 yamt dwarf_buf_error (&unit_buf, "invalid abstract origin or specification");
2051 1.1.1.1.4.2 yamt return NULL;
2052 1.1.1.1.4.2 yamt }
2053 1.1.1.1.4.2 yamt
2054 1.1.1.1.4.2 yamt abbrev = lookup_abbrev (&u->abbrevs, code, error_callback, data);
2055 1.1.1.1.4.2 yamt if (abbrev == NULL)
2056 1.1.1.1.4.2 yamt return NULL;
2057 1.1.1.1.4.2 yamt
2058 1.1.1.1.4.2 yamt ret = NULL;
2059 1.1.1.1.4.2 yamt for (i = 0; i < abbrev->num_attrs; ++i)
2060 1.1.1.1.4.2 yamt {
2061 1.1.1.1.4.2 yamt struct attr_val val;
2062 1.1.1.1.4.2 yamt
2063 1.1.1.1.4.2 yamt if (!read_attribute (abbrev->attrs[i].form, &unit_buf,
2064 1.1.1.1.4.2 yamt u->is_dwarf64, u->version, u->addrsize,
2065 1.1.1.1.4.2 yamt ddata->dwarf_str, ddata->dwarf_str_size,
2066 1.1.1.1.4.2 yamt &val))
2067 1.1.1.1.4.2 yamt return NULL;
2068 1.1.1.1.4.2 yamt
2069 1.1.1.1.4.2 yamt switch (abbrev->attrs[i].name)
2070 1.1.1.1.4.2 yamt {
2071 1.1.1.1.4.2 yamt case DW_AT_name:
2072 1.1.1.1.4.2 yamt /* We prefer the linkage name if get one. */
2073 1.1.1.1.4.2 yamt if (val.encoding == ATTR_VAL_STRING)
2074 1.1.1.1.4.2 yamt ret = val.u.string;
2075 1.1.1.1.4.2 yamt break;
2076 1.1.1.1.4.2 yamt
2077 1.1.1.1.4.2 yamt case DW_AT_linkage_name:
2078 1.1.1.1.4.2 yamt case DW_AT_MIPS_linkage_name:
2079 1.1.1.1.4.2 yamt if (val.encoding == ATTR_VAL_STRING)
2080 1.1.1.1.4.2 yamt return val.u.string;
2081 1.1.1.1.4.2 yamt break;
2082 1.1.1.1.4.2 yamt
2083 1.1.1.1.4.2 yamt case DW_AT_specification:
2084 1.1.1.1.4.2 yamt if (abbrev->attrs[i].form == DW_FORM_ref_addr
2085 1.1.1.1.4.2 yamt || abbrev->attrs[i].form == DW_FORM_ref_sig8)
2086 1.1.1.1.4.2 yamt {
2087 1.1.1.1.4.2 yamt /* This refers to a specification defined in some other
2088 1.1.1.1.4.2 yamt compilation unit. We can handle this case if we
2089 1.1.1.1.4.2 yamt must, but it's harder. */
2090 1.1.1.1.4.2 yamt break;
2091 1.1.1.1.4.2 yamt }
2092 1.1.1.1.4.2 yamt if (val.encoding == ATTR_VAL_UINT
2093 1.1.1.1.4.2 yamt || val.encoding == ATTR_VAL_REF_UNIT)
2094 1.1.1.1.4.2 yamt {
2095 1.1.1.1.4.2 yamt const char *name;
2096 1.1.1.1.4.2 yamt
2097 1.1.1.1.4.2 yamt name = read_referenced_name (ddata, u, val.u.uint,
2098 1.1.1.1.4.2 yamt error_callback, data);
2099 1.1.1.1.4.2 yamt if (name != NULL)
2100 1.1.1.1.4.2 yamt ret = name;
2101 1.1.1.1.4.2 yamt }
2102 1.1.1.1.4.2 yamt break;
2103 1.1.1.1.4.2 yamt
2104 1.1.1.1.4.2 yamt default:
2105 1.1.1.1.4.2 yamt break;
2106 1.1.1.1.4.2 yamt }
2107 1.1.1.1.4.2 yamt }
2108 1.1.1.1.4.2 yamt
2109 1.1.1.1.4.2 yamt return ret;
2110 1.1.1.1.4.2 yamt }
2111 1.1.1.1.4.2 yamt
2112 1.1.1.1.4.2 yamt /* Add a single range to U that maps to function. Returns 1 on
2113 1.1.1.1.4.2 yamt success, 0 on error. */
2114 1.1.1.1.4.2 yamt
2115 1.1.1.1.4.2 yamt static int
2116 1.1.1.1.4.2 yamt add_function_range (struct backtrace_state *state, struct dwarf_data *ddata,
2117 1.1.1.1.4.2 yamt struct function *function, uint64_t lowpc, uint64_t highpc,
2118 1.1.1.1.4.2 yamt backtrace_error_callback error_callback,
2119 1.1.1.1.4.2 yamt void *data, struct function_vector *vec)
2120 1.1.1.1.4.2 yamt {
2121 1.1.1.1.4.2 yamt struct function_addrs *p;
2122 1.1.1.1.4.2 yamt
2123 1.1.1.1.4.2 yamt /* Add in the base address here, so that we can look up the PC
2124 1.1.1.1.4.2 yamt directly. */
2125 1.1.1.1.4.2 yamt lowpc += ddata->base_address;
2126 1.1.1.1.4.2 yamt highpc += ddata->base_address;
2127 1.1.1.1.4.2 yamt
2128 1.1.1.1.4.2 yamt if (vec->count > 0)
2129 1.1.1.1.4.2 yamt {
2130 1.1.1.1.4.2 yamt p = (struct function_addrs *) vec->vec.base + vec->count - 1;
2131 1.1.1.1.4.2 yamt if ((lowpc == p->high || lowpc == p->high + 1)
2132 1.1.1.1.4.2 yamt && function == p->function)
2133 1.1.1.1.4.2 yamt {
2134 1.1.1.1.4.2 yamt if (highpc > p->high)
2135 1.1.1.1.4.2 yamt p->high = highpc;
2136 1.1.1.1.4.2 yamt return 1;
2137 1.1.1.1.4.2 yamt }
2138 1.1.1.1.4.2 yamt }
2139 1.1.1.1.4.2 yamt
2140 1.1.1.1.4.2 yamt p = ((struct function_addrs *)
2141 1.1.1.1.4.2 yamt backtrace_vector_grow (state, sizeof (struct function_addrs),
2142 1.1.1.1.4.2 yamt error_callback, data, &vec->vec));
2143 1.1.1.1.4.2 yamt if (p == NULL)
2144 1.1.1.1.4.2 yamt return 0;
2145 1.1.1.1.4.2 yamt
2146 1.1.1.1.4.2 yamt p->low = lowpc;
2147 1.1.1.1.4.2 yamt p->high = highpc;
2148 1.1.1.1.4.2 yamt p->function = function;
2149 1.1.1.1.4.2 yamt ++vec->count;
2150 1.1.1.1.4.2 yamt return 1;
2151 1.1.1.1.4.2 yamt }
2152 1.1.1.1.4.2 yamt
2153 1.1.1.1.4.2 yamt /* Add PC ranges to U that map to FUNCTION. Returns 1 on success, 0
2154 1.1.1.1.4.2 yamt on error. */
2155 1.1.1.1.4.2 yamt
2156 1.1.1.1.4.2 yamt static int
2157 1.1.1.1.4.2 yamt add_function_ranges (struct backtrace_state *state, struct dwarf_data *ddata,
2158 1.1.1.1.4.2 yamt struct unit *u, struct function *function,
2159 1.1.1.1.4.2 yamt uint64_t ranges, uint64_t base,
2160 1.1.1.1.4.2 yamt backtrace_error_callback error_callback, void *data,
2161 1.1.1.1.4.2 yamt struct function_vector *vec)
2162 1.1.1.1.4.2 yamt {
2163 1.1.1.1.4.2 yamt struct dwarf_buf ranges_buf;
2164 1.1.1.1.4.2 yamt
2165 1.1.1.1.4.2 yamt if (ranges >= ddata->dwarf_ranges_size)
2166 1.1.1.1.4.2 yamt {
2167 1.1.1.1.4.2 yamt error_callback (data, "function ranges offset out of range", 0);
2168 1.1.1.1.4.2 yamt return 0;
2169 1.1.1.1.4.2 yamt }
2170 1.1.1.1.4.2 yamt
2171 1.1.1.1.4.2 yamt ranges_buf.name = ".debug_ranges";
2172 1.1.1.1.4.2 yamt ranges_buf.start = ddata->dwarf_ranges;
2173 1.1.1.1.4.2 yamt ranges_buf.buf = ddata->dwarf_ranges + ranges;
2174 1.1.1.1.4.2 yamt ranges_buf.left = ddata->dwarf_ranges_size - ranges;
2175 1.1.1.1.4.2 yamt ranges_buf.is_bigendian = ddata->is_bigendian;
2176 1.1.1.1.4.2 yamt ranges_buf.error_callback = error_callback;
2177 1.1.1.1.4.2 yamt ranges_buf.data = data;
2178 1.1.1.1.4.2 yamt ranges_buf.reported_underflow = 0;
2179 1.1.1.1.4.2 yamt
2180 1.1.1.1.4.2 yamt while (1)
2181 1.1.1.1.4.2 yamt {
2182 1.1.1.1.4.2 yamt uint64_t low;
2183 1.1.1.1.4.2 yamt uint64_t high;
2184 1.1.1.1.4.2 yamt
2185 1.1.1.1.4.2 yamt if (ranges_buf.reported_underflow)
2186 1.1.1.1.4.2 yamt return 0;
2187 1.1.1.1.4.2 yamt
2188 1.1.1.1.4.2 yamt low = read_address (&ranges_buf, u->addrsize);
2189 1.1.1.1.4.2 yamt high = read_address (&ranges_buf, u->addrsize);
2190 1.1.1.1.4.2 yamt
2191 1.1.1.1.4.2 yamt if (low == 0 && high == 0)
2192 1.1.1.1.4.2 yamt break;
2193 1.1.1.1.4.2 yamt
2194 1.1.1.1.4.2 yamt if (is_highest_address (low, u->addrsize))
2195 1.1.1.1.4.2 yamt base = high;
2196 1.1.1.1.4.2 yamt else
2197 1.1.1.1.4.2 yamt {
2198 1.1.1.1.4.2 yamt if (!add_function_range (state, ddata, function, low + base,
2199 1.1.1.1.4.2 yamt high + base, error_callback, data, vec))
2200 1.1.1.1.4.2 yamt return 0;
2201 1.1.1.1.4.2 yamt }
2202 1.1.1.1.4.2 yamt }
2203 1.1.1.1.4.2 yamt
2204 1.1.1.1.4.2 yamt if (ranges_buf.reported_underflow)
2205 1.1.1.1.4.2 yamt return 0;
2206 1.1.1.1.4.2 yamt
2207 1.1.1.1.4.2 yamt return 1;
2208 1.1.1.1.4.2 yamt }
2209 1.1.1.1.4.2 yamt
2210 1.1.1.1.4.2 yamt /* Read one entry plus all its children. Add function addresses to
2211 1.1.1.1.4.2 yamt VEC. Returns 1 on success, 0 on error. */
2212 1.1.1.1.4.2 yamt
2213 1.1.1.1.4.2 yamt static int
2214 1.1.1.1.4.2 yamt read_function_entry (struct backtrace_state *state, struct dwarf_data *ddata,
2215 1.1.1.1.4.2 yamt struct unit *u, uint64_t base, struct dwarf_buf *unit_buf,
2216 1.1.1.1.4.2 yamt const struct line_header *lhdr,
2217 1.1.1.1.4.2 yamt backtrace_error_callback error_callback, void *data,
2218 1.1.1.1.4.2 yamt struct function_vector *vec)
2219 1.1.1.1.4.2 yamt {
2220 1.1.1.1.4.2 yamt while (unit_buf->left > 0)
2221 1.1.1.1.4.2 yamt {
2222 1.1.1.1.4.2 yamt uint64_t code;
2223 1.1.1.1.4.2 yamt const struct abbrev *abbrev;
2224 1.1.1.1.4.2 yamt int is_function;
2225 1.1.1.1.4.2 yamt struct function *function;
2226 1.1.1.1.4.2 yamt size_t i;
2227 1.1.1.1.4.2 yamt uint64_t lowpc;
2228 1.1.1.1.4.2 yamt int have_lowpc;
2229 1.1.1.1.4.2 yamt uint64_t highpc;
2230 1.1.1.1.4.2 yamt int have_highpc;
2231 1.1.1.1.4.2 yamt int highpc_is_relative;
2232 1.1.1.1.4.2 yamt uint64_t ranges;
2233 1.1.1.1.4.2 yamt int have_ranges;
2234 1.1.1.1.4.2 yamt
2235 1.1.1.1.4.2 yamt code = read_uleb128 (unit_buf);
2236 1.1.1.1.4.2 yamt if (code == 0)
2237 1.1.1.1.4.2 yamt return 1;
2238 1.1.1.1.4.2 yamt
2239 1.1.1.1.4.2 yamt abbrev = lookup_abbrev (&u->abbrevs, code, error_callback, data);
2240 1.1.1.1.4.2 yamt if (abbrev == NULL)
2241 1.1.1.1.4.2 yamt return 0;
2242 1.1.1.1.4.2 yamt
2243 1.1.1.1.4.2 yamt is_function = (abbrev->tag == DW_TAG_subprogram
2244 1.1.1.1.4.2 yamt || abbrev->tag == DW_TAG_entry_point
2245 1.1.1.1.4.2 yamt || abbrev->tag == DW_TAG_inlined_subroutine);
2246 1.1.1.1.4.2 yamt
2247 1.1.1.1.4.2 yamt function = NULL;
2248 1.1.1.1.4.2 yamt if (is_function)
2249 1.1.1.1.4.2 yamt {
2250 1.1.1.1.4.2 yamt function = ((struct function *)
2251 1.1.1.1.4.2 yamt backtrace_alloc (state, sizeof *function,
2252 1.1.1.1.4.2 yamt error_callback, data));
2253 1.1.1.1.4.2 yamt if (function == NULL)
2254 1.1.1.1.4.2 yamt return 0;
2255 1.1.1.1.4.2 yamt memset (function, 0, sizeof *function);
2256 1.1.1.1.4.2 yamt }
2257 1.1.1.1.4.2 yamt
2258 1.1.1.1.4.2 yamt lowpc = 0;
2259 1.1.1.1.4.2 yamt have_lowpc = 0;
2260 1.1.1.1.4.2 yamt highpc = 0;
2261 1.1.1.1.4.2 yamt have_highpc = 0;
2262 1.1.1.1.4.2 yamt highpc_is_relative = 0;
2263 1.1.1.1.4.2 yamt ranges = 0;
2264 1.1.1.1.4.2 yamt have_ranges = 0;
2265 1.1.1.1.4.2 yamt for (i = 0; i < abbrev->num_attrs; ++i)
2266 1.1.1.1.4.2 yamt {
2267 1.1.1.1.4.2 yamt struct attr_val val;
2268 1.1.1.1.4.2 yamt
2269 1.1.1.1.4.2 yamt if (!read_attribute (abbrev->attrs[i].form, unit_buf,
2270 1.1.1.1.4.2 yamt u->is_dwarf64, u->version, u->addrsize,
2271 1.1.1.1.4.2 yamt ddata->dwarf_str, ddata->dwarf_str_size,
2272 1.1.1.1.4.2 yamt &val))
2273 1.1.1.1.4.2 yamt return 0;
2274 1.1.1.1.4.2 yamt
2275 1.1.1.1.4.2 yamt /* The compile unit sets the base address for any address
2276 1.1.1.1.4.2 yamt ranges in the function entries. */
2277 1.1.1.1.4.2 yamt if (abbrev->tag == DW_TAG_compile_unit
2278 1.1.1.1.4.2 yamt && abbrev->attrs[i].name == DW_AT_low_pc
2279 1.1.1.1.4.2 yamt && val.encoding == ATTR_VAL_ADDRESS)
2280 1.1.1.1.4.2 yamt base = val.u.uint;
2281 1.1.1.1.4.2 yamt
2282 1.1.1.1.4.2 yamt if (is_function)
2283 1.1.1.1.4.2 yamt {
2284 1.1.1.1.4.2 yamt switch (abbrev->attrs[i].name)
2285 1.1.1.1.4.2 yamt {
2286 1.1.1.1.4.2 yamt case DW_AT_call_file:
2287 1.1.1.1.4.2 yamt if (val.encoding == ATTR_VAL_UINT)
2288 1.1.1.1.4.2 yamt {
2289 1.1.1.1.4.2 yamt if (val.u.uint == 0)
2290 1.1.1.1.4.2 yamt function->caller_filename = "";
2291 1.1.1.1.4.2 yamt else
2292 1.1.1.1.4.2 yamt {
2293 1.1.1.1.4.2 yamt if (val.u.uint - 1 >= lhdr->filenames_count)
2294 1.1.1.1.4.2 yamt {
2295 1.1.1.1.4.2 yamt dwarf_buf_error (unit_buf,
2296 1.1.1.1.4.2 yamt ("invalid file number in "
2297 1.1.1.1.4.2 yamt "DW_AT_call_file attribute"));
2298 1.1.1.1.4.2 yamt return 0;
2299 1.1.1.1.4.2 yamt }
2300 1.1.1.1.4.2 yamt function->caller_filename =
2301 1.1.1.1.4.2 yamt lhdr->filenames[val.u.uint - 1];
2302 1.1.1.1.4.2 yamt }
2303 1.1.1.1.4.2 yamt }
2304 1.1.1.1.4.2 yamt break;
2305 1.1.1.1.4.2 yamt
2306 1.1.1.1.4.2 yamt case DW_AT_call_line:
2307 1.1.1.1.4.2 yamt if (val.encoding == ATTR_VAL_UINT)
2308 1.1.1.1.4.2 yamt function->caller_lineno = val.u.uint;
2309 1.1.1.1.4.2 yamt break;
2310 1.1.1.1.4.2 yamt
2311 1.1.1.1.4.2 yamt case DW_AT_abstract_origin:
2312 1.1.1.1.4.2 yamt case DW_AT_specification:
2313 1.1.1.1.4.2 yamt if (abbrev->attrs[i].form == DW_FORM_ref_addr
2314 1.1.1.1.4.2 yamt || abbrev->attrs[i].form == DW_FORM_ref_sig8)
2315 1.1.1.1.4.2 yamt {
2316 1.1.1.1.4.2 yamt /* This refers to an abstract origin defined in
2317 1.1.1.1.4.2 yamt some other compilation unit. We can handle
2318 1.1.1.1.4.2 yamt this case if we must, but it's harder. */
2319 1.1.1.1.4.2 yamt break;
2320 1.1.1.1.4.2 yamt }
2321 1.1.1.1.4.2 yamt if (val.encoding == ATTR_VAL_UINT
2322 1.1.1.1.4.2 yamt || val.encoding == ATTR_VAL_REF_UNIT)
2323 1.1.1.1.4.2 yamt {
2324 1.1.1.1.4.2 yamt const char *name;
2325 1.1.1.1.4.2 yamt
2326 1.1.1.1.4.2 yamt name = read_referenced_name (ddata, u, val.u.uint,
2327 1.1.1.1.4.2 yamt error_callback, data);
2328 1.1.1.1.4.2 yamt if (name != NULL)
2329 1.1.1.1.4.2 yamt function->name = name;
2330 1.1.1.1.4.2 yamt }
2331 1.1.1.1.4.2 yamt break;
2332 1.1.1.1.4.2 yamt
2333 1.1.1.1.4.2 yamt case DW_AT_name:
2334 1.1.1.1.4.2 yamt if (val.encoding == ATTR_VAL_STRING)
2335 1.1.1.1.4.2 yamt {
2336 1.1.1.1.4.2 yamt /* Don't override a name we found in some other
2337 1.1.1.1.4.2 yamt way, as it will normally be more
2338 1.1.1.1.4.2 yamt useful--e.g., this name is normally not
2339 1.1.1.1.4.2 yamt mangled. */
2340 1.1.1.1.4.2 yamt if (function->name == NULL)
2341 1.1.1.1.4.2 yamt function->name = val.u.string;
2342 1.1.1.1.4.2 yamt }
2343 1.1.1.1.4.2 yamt break;
2344 1.1.1.1.4.2 yamt
2345 1.1.1.1.4.2 yamt case DW_AT_linkage_name:
2346 1.1.1.1.4.2 yamt case DW_AT_MIPS_linkage_name:
2347 1.1.1.1.4.2 yamt if (val.encoding == ATTR_VAL_STRING)
2348 1.1.1.1.4.2 yamt function->name = val.u.string;
2349 1.1.1.1.4.2 yamt break;
2350 1.1.1.1.4.2 yamt
2351 1.1.1.1.4.2 yamt case DW_AT_low_pc:
2352 1.1.1.1.4.2 yamt if (val.encoding == ATTR_VAL_ADDRESS)
2353 1.1.1.1.4.2 yamt {
2354 1.1.1.1.4.2 yamt lowpc = val.u.uint;
2355 1.1.1.1.4.2 yamt have_lowpc = 1;
2356 1.1.1.1.4.2 yamt }
2357 1.1.1.1.4.2 yamt break;
2358 1.1.1.1.4.2 yamt
2359 1.1.1.1.4.2 yamt case DW_AT_high_pc:
2360 1.1.1.1.4.2 yamt if (val.encoding == ATTR_VAL_ADDRESS)
2361 1.1.1.1.4.2 yamt {
2362 1.1.1.1.4.2 yamt highpc = val.u.uint;
2363 1.1.1.1.4.2 yamt have_highpc = 1;
2364 1.1.1.1.4.2 yamt }
2365 1.1.1.1.4.2 yamt else if (val.encoding == ATTR_VAL_UINT)
2366 1.1.1.1.4.2 yamt {
2367 1.1.1.1.4.2 yamt highpc = val.u.uint;
2368 1.1.1.1.4.2 yamt have_highpc = 1;
2369 1.1.1.1.4.2 yamt highpc_is_relative = 1;
2370 1.1.1.1.4.2 yamt }
2371 1.1.1.1.4.2 yamt break;
2372 1.1.1.1.4.2 yamt
2373 1.1.1.1.4.2 yamt case DW_AT_ranges:
2374 1.1.1.1.4.2 yamt if (val.encoding == ATTR_VAL_UINT
2375 1.1.1.1.4.2 yamt || val.encoding == ATTR_VAL_REF_SECTION)
2376 1.1.1.1.4.2 yamt {
2377 1.1.1.1.4.2 yamt ranges = val.u.uint;
2378 1.1.1.1.4.2 yamt have_ranges = 1;
2379 1.1.1.1.4.2 yamt }
2380 1.1.1.1.4.2 yamt break;
2381 1.1.1.1.4.2 yamt
2382 1.1.1.1.4.2 yamt default:
2383 1.1.1.1.4.2 yamt break;
2384 1.1.1.1.4.2 yamt }
2385 1.1.1.1.4.2 yamt }
2386 1.1.1.1.4.2 yamt }
2387 1.1.1.1.4.2 yamt
2388 1.1.1.1.4.2 yamt /* If we couldn't find a name for the function, we have no use
2389 1.1.1.1.4.2 yamt for it. */
2390 1.1.1.1.4.2 yamt if (is_function && function->name == NULL)
2391 1.1.1.1.4.2 yamt {
2392 1.1.1.1.4.2 yamt backtrace_free (state, function, sizeof *function,
2393 1.1.1.1.4.2 yamt error_callback, data);
2394 1.1.1.1.4.2 yamt is_function = 0;
2395 1.1.1.1.4.2 yamt }
2396 1.1.1.1.4.2 yamt
2397 1.1.1.1.4.2 yamt if (is_function)
2398 1.1.1.1.4.2 yamt {
2399 1.1.1.1.4.2 yamt if (have_ranges)
2400 1.1.1.1.4.2 yamt {
2401 1.1.1.1.4.2 yamt if (!add_function_ranges (state, ddata, u, function, ranges,
2402 1.1.1.1.4.2 yamt base, error_callback, data, vec))
2403 1.1.1.1.4.2 yamt return 0;
2404 1.1.1.1.4.2 yamt }
2405 1.1.1.1.4.2 yamt else if (have_lowpc && have_highpc)
2406 1.1.1.1.4.2 yamt {
2407 1.1.1.1.4.2 yamt if (highpc_is_relative)
2408 1.1.1.1.4.2 yamt highpc += lowpc;
2409 1.1.1.1.4.2 yamt if (!add_function_range (state, ddata, function, lowpc, highpc,
2410 1.1.1.1.4.2 yamt error_callback, data, vec))
2411 1.1.1.1.4.2 yamt return 0;
2412 1.1.1.1.4.2 yamt }
2413 1.1.1.1.4.2 yamt else
2414 1.1.1.1.4.2 yamt {
2415 1.1.1.1.4.2 yamt backtrace_free (state, function, sizeof *function,
2416 1.1.1.1.4.2 yamt error_callback, data);
2417 1.1.1.1.4.2 yamt is_function = 0;
2418 1.1.1.1.4.2 yamt }
2419 1.1.1.1.4.2 yamt }
2420 1.1.1.1.4.2 yamt
2421 1.1.1.1.4.2 yamt if (abbrev->has_children)
2422 1.1.1.1.4.2 yamt {
2423 1.1.1.1.4.2 yamt if (!is_function)
2424 1.1.1.1.4.2 yamt {
2425 1.1.1.1.4.2 yamt if (!read_function_entry (state, ddata, u, base, unit_buf, lhdr,
2426 1.1.1.1.4.2 yamt error_callback, data, vec))
2427 1.1.1.1.4.2 yamt return 0;
2428 1.1.1.1.4.2 yamt }
2429 1.1.1.1.4.2 yamt else
2430 1.1.1.1.4.2 yamt {
2431 1.1.1.1.4.2 yamt struct function_vector fvec;
2432 1.1.1.1.4.2 yamt
2433 1.1.1.1.4.2 yamt /* Gather any information for inlined functions in
2434 1.1.1.1.4.2 yamt FVEC. */
2435 1.1.1.1.4.2 yamt
2436 1.1.1.1.4.2 yamt memset (&fvec, 0, sizeof fvec);
2437 1.1.1.1.4.2 yamt
2438 1.1.1.1.4.2 yamt if (!read_function_entry (state, ddata, u, base, unit_buf, lhdr,
2439 1.1.1.1.4.2 yamt error_callback, data, &fvec))
2440 1.1.1.1.4.2 yamt return 0;
2441 1.1.1.1.4.2 yamt
2442 1.1.1.1.4.2 yamt if (fvec.count > 0)
2443 1.1.1.1.4.2 yamt {
2444 1.1.1.1.4.2 yamt struct function_addrs *faddrs;
2445 1.1.1.1.4.2 yamt
2446 1.1.1.1.4.2 yamt if (!backtrace_vector_release (state, &fvec.vec,
2447 1.1.1.1.4.2 yamt error_callback, data))
2448 1.1.1.1.4.2 yamt return 0;
2449 1.1.1.1.4.2 yamt
2450 1.1.1.1.4.2 yamt faddrs = (struct function_addrs *) fvec.vec.base;
2451 1.1.1.1.4.2 yamt qsort (faddrs, fvec.count,
2452 1.1.1.1.4.2 yamt sizeof (struct function_addrs),
2453 1.1.1.1.4.2 yamt function_addrs_compare);
2454 1.1.1.1.4.2 yamt
2455 1.1.1.1.4.2 yamt function->function_addrs = faddrs;
2456 1.1.1.1.4.2 yamt function->function_addrs_count = fvec.count;
2457 1.1.1.1.4.2 yamt }
2458 1.1.1.1.4.2 yamt }
2459 1.1.1.1.4.2 yamt }
2460 1.1.1.1.4.2 yamt }
2461 1.1.1.1.4.2 yamt
2462 1.1.1.1.4.2 yamt return 1;
2463 1.1.1.1.4.2 yamt }
2464 1.1.1.1.4.2 yamt
2465 1.1.1.1.4.2 yamt /* Read function name information for a compilation unit. We look
2466 1.1.1.1.4.2 yamt through the whole unit looking for function tags. */
2467 1.1.1.1.4.2 yamt
2468 1.1.1.1.4.2 yamt static void
2469 1.1.1.1.4.2 yamt read_function_info (struct backtrace_state *state, struct dwarf_data *ddata,
2470 1.1.1.1.4.2 yamt const struct line_header *lhdr,
2471 1.1.1.1.4.2 yamt backtrace_error_callback error_callback, void *data,
2472 1.1.1.1.4.2 yamt struct unit *u, struct function_vector *fvec,
2473 1.1.1.1.4.2 yamt struct function_addrs **ret_addrs,
2474 1.1.1.1.4.2 yamt size_t *ret_addrs_count)
2475 1.1.1.1.4.2 yamt {
2476 1.1.1.1.4.2 yamt struct function_vector lvec;
2477 1.1.1.1.4.2 yamt struct function_vector *pfvec;
2478 1.1.1.1.4.2 yamt struct dwarf_buf unit_buf;
2479 1.1.1.1.4.2 yamt struct function_addrs *addrs;
2480 1.1.1.1.4.2 yamt size_t addrs_count;
2481 1.1.1.1.4.2 yamt
2482 1.1.1.1.4.2 yamt /* Use FVEC if it is not NULL. Otherwise use our own vector. */
2483 1.1.1.1.4.2 yamt if (fvec != NULL)
2484 1.1.1.1.4.2 yamt pfvec = fvec;
2485 1.1.1.1.4.2 yamt else
2486 1.1.1.1.4.2 yamt {
2487 1.1.1.1.4.2 yamt memset (&lvec, 0, sizeof lvec);
2488 1.1.1.1.4.2 yamt pfvec = &lvec;
2489 1.1.1.1.4.2 yamt }
2490 1.1.1.1.4.2 yamt
2491 1.1.1.1.4.2 yamt unit_buf.name = ".debug_info";
2492 1.1.1.1.4.2 yamt unit_buf.start = ddata->dwarf_info;
2493 1.1.1.1.4.2 yamt unit_buf.buf = u->unit_data;
2494 1.1.1.1.4.2 yamt unit_buf.left = u->unit_data_len;
2495 1.1.1.1.4.2 yamt unit_buf.is_bigendian = ddata->is_bigendian;
2496 1.1.1.1.4.2 yamt unit_buf.error_callback = error_callback;
2497 1.1.1.1.4.2 yamt unit_buf.data = data;
2498 1.1.1.1.4.2 yamt unit_buf.reported_underflow = 0;
2499 1.1.1.1.4.2 yamt
2500 1.1.1.1.4.2 yamt while (unit_buf.left > 0)
2501 1.1.1.1.4.2 yamt {
2502 1.1.1.1.4.2 yamt if (!read_function_entry (state, ddata, u, 0, &unit_buf, lhdr,
2503 1.1.1.1.4.2 yamt error_callback, data, pfvec))
2504 1.1.1.1.4.2 yamt return;
2505 1.1.1.1.4.2 yamt }
2506 1.1.1.1.4.2 yamt
2507 1.1.1.1.4.2 yamt if (pfvec->count == 0)
2508 1.1.1.1.4.2 yamt return;
2509 1.1.1.1.4.2 yamt
2510 1.1.1.1.4.2 yamt addrs_count = pfvec->count;
2511 1.1.1.1.4.2 yamt
2512 1.1.1.1.4.2 yamt if (fvec == NULL)
2513 1.1.1.1.4.2 yamt {
2514 1.1.1.1.4.2 yamt if (!backtrace_vector_release (state, &lvec.vec, error_callback, data))
2515 1.1.1.1.4.2 yamt return;
2516 1.1.1.1.4.2 yamt addrs = (struct function_addrs *) pfvec->vec.base;
2517 1.1.1.1.4.2 yamt }
2518 1.1.1.1.4.2 yamt else
2519 1.1.1.1.4.2 yamt {
2520 1.1.1.1.4.2 yamt /* Finish this list of addresses, but leave the remaining space in
2521 1.1.1.1.4.2 yamt the vector available for the next function unit. */
2522 1.1.1.1.4.2 yamt addrs = ((struct function_addrs *)
2523 1.1.1.1.4.2 yamt backtrace_vector_finish (state, &fvec->vec,
2524 1.1.1.1.4.2 yamt error_callback, data));
2525 1.1.1.1.4.2 yamt if (addrs == NULL)
2526 1.1.1.1.4.2 yamt return;
2527 1.1.1.1.4.2 yamt fvec->count = 0;
2528 1.1.1.1.4.2 yamt }
2529 1.1.1.1.4.2 yamt
2530 1.1.1.1.4.2 yamt qsort (addrs, addrs_count, sizeof (struct function_addrs),
2531 1.1.1.1.4.2 yamt function_addrs_compare);
2532 1.1.1.1.4.2 yamt
2533 1.1.1.1.4.2 yamt *ret_addrs = addrs;
2534 1.1.1.1.4.2 yamt *ret_addrs_count = addrs_count;
2535 1.1.1.1.4.2 yamt }
2536 1.1.1.1.4.2 yamt
2537 1.1.1.1.4.2 yamt /* See if PC is inlined in FUNCTION. If it is, print out the inlined
2538 1.1.1.1.4.2 yamt information, and update FILENAME and LINENO for the caller.
2539 1.1.1.1.4.2 yamt Returns whatever CALLBACK returns, or 0 to keep going. */
2540 1.1.1.1.4.2 yamt
2541 1.1.1.1.4.2 yamt static int
2542 1.1.1.1.4.2 yamt report_inlined_functions (uintptr_t pc, struct function *function,
2543 1.1.1.1.4.2 yamt backtrace_full_callback callback, void *data,
2544 1.1.1.1.4.2 yamt const char **filename, int *lineno)
2545 1.1.1.1.4.2 yamt {
2546 1.1.1.1.4.2 yamt struct function_addrs *function_addrs;
2547 1.1.1.1.4.2 yamt struct function *inlined;
2548 1.1.1.1.4.2 yamt int ret;
2549 1.1.1.1.4.2 yamt
2550 1.1.1.1.4.2 yamt if (function->function_addrs_count == 0)
2551 1.1.1.1.4.2 yamt return 0;
2552 1.1.1.1.4.2 yamt
2553 1.1.1.1.4.2 yamt function_addrs = ((struct function_addrs *)
2554 1.1.1.1.4.2 yamt bsearch (&pc, function->function_addrs,
2555 1.1.1.1.4.2 yamt function->function_addrs_count,
2556 1.1.1.1.4.2 yamt sizeof (struct function_addrs),
2557 1.1.1.1.4.2 yamt function_addrs_search));
2558 1.1.1.1.4.2 yamt if (function_addrs == NULL)
2559 1.1.1.1.4.2 yamt return 0;
2560 1.1.1.1.4.2 yamt
2561 1.1.1.1.4.2 yamt while (((size_t) (function_addrs - function->function_addrs) + 1
2562 1.1.1.1.4.2 yamt < function->function_addrs_count)
2563 1.1.1.1.4.2 yamt && pc >= (function_addrs + 1)->low
2564 1.1.1.1.4.2 yamt && pc < (function_addrs + 1)->high)
2565 1.1.1.1.4.2 yamt ++function_addrs;
2566 1.1.1.1.4.2 yamt
2567 1.1.1.1.4.2 yamt /* We found an inlined call. */
2568 1.1.1.1.4.2 yamt
2569 1.1.1.1.4.2 yamt inlined = function_addrs->function;
2570 1.1.1.1.4.2 yamt
2571 1.1.1.1.4.2 yamt /* Report any calls inlined into this one. */
2572 1.1.1.1.4.2 yamt ret = report_inlined_functions (pc, inlined, callback, data,
2573 1.1.1.1.4.2 yamt filename, lineno);
2574 1.1.1.1.4.2 yamt if (ret != 0)
2575 1.1.1.1.4.2 yamt return ret;
2576 1.1.1.1.4.2 yamt
2577 1.1.1.1.4.2 yamt /* Report this inlined call. */
2578 1.1.1.1.4.2 yamt ret = callback (data, pc, *filename, *lineno, inlined->name);
2579 1.1.1.1.4.2 yamt if (ret != 0)
2580 1.1.1.1.4.2 yamt return ret;
2581 1.1.1.1.4.2 yamt
2582 1.1.1.1.4.2 yamt /* Our caller will report the caller of the inlined function; tell
2583 1.1.1.1.4.2 yamt it the appropriate filename and line number. */
2584 1.1.1.1.4.2 yamt *filename = inlined->caller_filename;
2585 1.1.1.1.4.2 yamt *lineno = inlined->caller_lineno;
2586 1.1.1.1.4.2 yamt
2587 1.1.1.1.4.2 yamt return 0;
2588 1.1.1.1.4.2 yamt }
2589 1.1.1.1.4.2 yamt
2590 1.1.1.1.4.2 yamt /* Look for a PC in the DWARF mapping for one module. On success,
2591 1.1.1.1.4.2 yamt call CALLBACK and return whatever it returns. On error, call
2592 1.1.1.1.4.2 yamt ERROR_CALLBACK and return 0. Sets *FOUND to 1 if the PC is found,
2593 1.1.1.1.4.2 yamt 0 if not. */
2594 1.1.1.1.4.2 yamt
2595 1.1.1.1.4.2 yamt static int
2596 1.1.1.1.4.2 yamt dwarf_lookup_pc (struct backtrace_state *state, struct dwarf_data *ddata,
2597 1.1.1.1.4.2 yamt uintptr_t pc, backtrace_full_callback callback,
2598 1.1.1.1.4.2 yamt backtrace_error_callback error_callback, void *data,
2599 1.1.1.1.4.2 yamt int *found)
2600 1.1.1.1.4.2 yamt {
2601 1.1.1.1.4.2 yamt struct unit_addrs *entry;
2602 1.1.1.1.4.2 yamt struct unit *u;
2603 1.1.1.1.4.2 yamt int new_data;
2604 1.1.1.1.4.2 yamt struct line *lines;
2605 1.1.1.1.4.2 yamt struct line *ln;
2606 1.1.1.1.4.2 yamt struct function_addrs *function_addrs;
2607 1.1.1.1.4.2 yamt struct function *function;
2608 1.1.1.1.4.2 yamt const char *filename;
2609 1.1.1.1.4.2 yamt int lineno;
2610 1.1.1.1.4.2 yamt int ret;
2611 1.1.1.1.4.2 yamt
2612 1.1.1.1.4.2 yamt *found = 1;
2613 1.1.1.1.4.2 yamt
2614 1.1.1.1.4.2 yamt /* Find an address range that includes PC. */
2615 1.1.1.1.4.2 yamt entry = bsearch (&pc, ddata->addrs, ddata->addrs_count,
2616 1.1.1.1.4.2 yamt sizeof (struct unit_addrs), unit_addrs_search);
2617 1.1.1.1.4.2 yamt
2618 1.1.1.1.4.2 yamt if (entry == NULL)
2619 1.1.1.1.4.2 yamt {
2620 1.1.1.1.4.2 yamt *found = 0;
2621 1.1.1.1.4.2 yamt return 0;
2622 1.1.1.1.4.2 yamt }
2623 1.1.1.1.4.2 yamt
2624 1.1.1.1.4.2 yamt /* If there are multiple ranges that contain PC, use the last one,
2625 1.1.1.1.4.2 yamt in order to produce predictable results. If we assume that all
2626 1.1.1.1.4.2 yamt ranges are properly nested, then the last range will be the
2627 1.1.1.1.4.2 yamt smallest one. */
2628 1.1.1.1.4.2 yamt while ((size_t) (entry - ddata->addrs) + 1 < ddata->addrs_count
2629 1.1.1.1.4.2 yamt && pc >= (entry + 1)->low
2630 1.1.1.1.4.2 yamt && pc < (entry + 1)->high)
2631 1.1.1.1.4.2 yamt ++entry;
2632 1.1.1.1.4.2 yamt
2633 1.1.1.1.4.2 yamt /* We need the lines, lines_count, function_addrs,
2634 1.1.1.1.4.2 yamt function_addrs_count fields of u. If they are not set, we need
2635 1.1.1.1.4.2 yamt to set them. When running in threaded mode, we need to allow for
2636 1.1.1.1.4.2 yamt the possibility that some other thread is setting them
2637 1.1.1.1.4.2 yamt simultaneously. */
2638 1.1.1.1.4.2 yamt
2639 1.1.1.1.4.2 yamt u = entry->u;
2640 1.1.1.1.4.2 yamt lines = u->lines;
2641 1.1.1.1.4.2 yamt
2642 1.1.1.1.4.2 yamt /* Skip units with no useful line number information by walking
2643 1.1.1.1.4.2 yamt backward. Useless line number information is marked by setting
2644 1.1.1.1.4.2 yamt lines == -1. */
2645 1.1.1.1.4.2 yamt while (entry > ddata->addrs
2646 1.1.1.1.4.2 yamt && pc >= (entry - 1)->low
2647 1.1.1.1.4.2 yamt && pc < (entry - 1)->high)
2648 1.1.1.1.4.2 yamt {
2649 1.1.1.1.4.2 yamt if (state->threaded)
2650 1.1.1.1.4.2 yamt {
2651 1.1.1.1.4.2 yamt /* Use __sync_bool_compare_and_swap to do a
2652 1.1.1.1.4.2 yamt load-acquire. */
2653 1.1.1.1.4.2 yamt while (!__sync_bool_compare_and_swap (&u->lines, lines, lines))
2654 1.1.1.1.4.2 yamt lines = u->lines;
2655 1.1.1.1.4.2 yamt }
2656 1.1.1.1.4.2 yamt
2657 1.1.1.1.4.2 yamt if (lines != (struct line *) (uintptr_t) -1)
2658 1.1.1.1.4.2 yamt break;
2659 1.1.1.1.4.2 yamt
2660 1.1.1.1.4.2 yamt --entry;
2661 1.1.1.1.4.2 yamt
2662 1.1.1.1.4.2 yamt u = entry->u;
2663 1.1.1.1.4.2 yamt lines = u->lines;
2664 1.1.1.1.4.2 yamt }
2665 1.1.1.1.4.2 yamt
2666 1.1.1.1.4.2 yamt /* Do a load-acquire of u->lines. */
2667 1.1.1.1.4.2 yamt if (state->threaded)
2668 1.1.1.1.4.2 yamt {
2669 1.1.1.1.4.2 yamt /* Use __sync_bool_compare_and_swap to do an atomic load. */
2670 1.1.1.1.4.2 yamt while (!__sync_bool_compare_and_swap (&u->lines, lines, lines))
2671 1.1.1.1.4.2 yamt lines = u->lines;
2672 1.1.1.1.4.2 yamt }
2673 1.1.1.1.4.2 yamt
2674 1.1.1.1.4.2 yamt new_data = 0;
2675 1.1.1.1.4.2 yamt if (lines == NULL)
2676 1.1.1.1.4.2 yamt {
2677 1.1.1.1.4.2 yamt size_t function_addrs_count;
2678 1.1.1.1.4.2 yamt struct line_header lhdr;
2679 1.1.1.1.4.2 yamt size_t count;
2680 1.1.1.1.4.2 yamt
2681 1.1.1.1.4.2 yamt /* We have never read the line information for this unit. Read
2682 1.1.1.1.4.2 yamt it now. */
2683 1.1.1.1.4.2 yamt
2684 1.1.1.1.4.2 yamt function_addrs = NULL;
2685 1.1.1.1.4.2 yamt function_addrs_count = 0;
2686 1.1.1.1.4.2 yamt if (read_line_info (state, ddata, error_callback, data, entry->u, &lhdr,
2687 1.1.1.1.4.2 yamt &lines, &count))
2688 1.1.1.1.4.2 yamt {
2689 1.1.1.1.4.2 yamt struct function_vector *pfvec;
2690 1.1.1.1.4.2 yamt
2691 1.1.1.1.4.2 yamt /* If not threaded, reuse DDATA->FVEC for better memory
2692 1.1.1.1.4.2 yamt consumption. */
2693 1.1.1.1.4.2 yamt if (state->threaded)
2694 1.1.1.1.4.2 yamt pfvec = NULL;
2695 1.1.1.1.4.2 yamt else
2696 1.1.1.1.4.2 yamt pfvec = &ddata->fvec;
2697 1.1.1.1.4.2 yamt read_function_info (state, ddata, &lhdr, error_callback, data,
2698 1.1.1.1.4.2 yamt entry->u, pfvec, &function_addrs,
2699 1.1.1.1.4.2 yamt &function_addrs_count);
2700 1.1.1.1.4.2 yamt free_line_header (state, &lhdr, error_callback, data);
2701 1.1.1.1.4.2 yamt new_data = 1;
2702 1.1.1.1.4.2 yamt }
2703 1.1.1.1.4.2 yamt
2704 1.1.1.1.4.2 yamt /* Atomically store the information we just read into the unit.
2705 1.1.1.1.4.2 yamt If another thread is simultaneously writing, it presumably
2706 1.1.1.1.4.2 yamt read the same information, and we don't care which one we
2707 1.1.1.1.4.2 yamt wind up with; we just leak the other one. We do have to
2708 1.1.1.1.4.2 yamt write the lines field last, so that the acquire-loads above
2709 1.1.1.1.4.2 yamt ensure that the other fields are set. */
2710 1.1.1.1.4.2 yamt
2711 1.1.1.1.4.2 yamt if (!state->threaded)
2712 1.1.1.1.4.2 yamt {
2713 1.1.1.1.4.2 yamt u->lines_count = count;
2714 1.1.1.1.4.2 yamt u->function_addrs = function_addrs;
2715 1.1.1.1.4.2 yamt u->function_addrs_count = function_addrs_count;
2716 1.1.1.1.4.2 yamt u->lines = lines;
2717 1.1.1.1.4.2 yamt }
2718 1.1.1.1.4.2 yamt else
2719 1.1.1.1.4.2 yamt {
2720 1.1.1.1.4.2 yamt __sync_bool_compare_and_swap (&u->lines_count, 0, count);
2721 1.1.1.1.4.2 yamt __sync_bool_compare_and_swap (&u->function_addrs, NULL,
2722 1.1.1.1.4.2 yamt function_addrs);
2723 1.1.1.1.4.2 yamt __sync_bool_compare_and_swap (&u->function_addrs_count, 0,
2724 1.1.1.1.4.2 yamt function_addrs_count);
2725 1.1.1.1.4.2 yamt __sync_bool_compare_and_swap (&u->lines, NULL, lines);
2726 1.1.1.1.4.2 yamt }
2727 1.1.1.1.4.2 yamt }
2728 1.1.1.1.4.2 yamt
2729 1.1.1.1.4.2 yamt /* Now all fields of U have been initialized. */
2730 1.1.1.1.4.2 yamt
2731 1.1.1.1.4.2 yamt if (lines == (struct line *) (uintptr_t) -1)
2732 1.1.1.1.4.2 yamt {
2733 1.1.1.1.4.2 yamt /* If reading the line number information failed in some way,
2734 1.1.1.1.4.2 yamt try again to see if there is a better compilation unit for
2735 1.1.1.1.4.2 yamt this PC. */
2736 1.1.1.1.4.2 yamt if (new_data)
2737 1.1.1.1.4.2 yamt return dwarf_lookup_pc (state, ddata, pc, callback, error_callback,
2738 1.1.1.1.4.2 yamt data, found);
2739 1.1.1.1.4.2 yamt return callback (data, pc, NULL, 0, NULL);
2740 1.1.1.1.4.2 yamt }
2741 1.1.1.1.4.2 yamt
2742 1.1.1.1.4.2 yamt /* Search for PC within this unit. */
2743 1.1.1.1.4.2 yamt
2744 1.1.1.1.4.2 yamt ln = (struct line *) bsearch (&pc, lines, entry->u->lines_count,
2745 1.1.1.1.4.2 yamt sizeof (struct line), line_search);
2746 1.1.1.1.4.2 yamt if (ln == NULL)
2747 1.1.1.1.4.2 yamt {
2748 1.1.1.1.4.2 yamt /* The PC is between the low_pc and high_pc attributes of the
2749 1.1.1.1.4.2 yamt compilation unit, but no entry in the line table covers it.
2750 1.1.1.1.4.2 yamt This implies that the start of the compilation unit has no
2751 1.1.1.1.4.2 yamt line number information. */
2752 1.1.1.1.4.2 yamt
2753 1.1.1.1.4.2 yamt if (entry->u->abs_filename == NULL)
2754 1.1.1.1.4.2 yamt {
2755 1.1.1.1.4.2 yamt const char *filename;
2756 1.1.1.1.4.2 yamt
2757 1.1.1.1.4.2 yamt filename = entry->u->filename;
2758 1.1.1.1.4.2 yamt if (filename != NULL
2759 1.1.1.1.4.2 yamt && !IS_ABSOLUTE_PATH (filename)
2760 1.1.1.1.4.2 yamt && entry->u->comp_dir != NULL)
2761 1.1.1.1.4.2 yamt {
2762 1.1.1.1.4.2 yamt size_t filename_len;
2763 1.1.1.1.4.2 yamt const char *dir;
2764 1.1.1.1.4.2 yamt size_t dir_len;
2765 1.1.1.1.4.2 yamt char *s;
2766 1.1.1.1.4.2 yamt
2767 1.1.1.1.4.2 yamt filename_len = strlen (filename);
2768 1.1.1.1.4.2 yamt dir = entry->u->comp_dir;
2769 1.1.1.1.4.2 yamt dir_len = strlen (dir);
2770 1.1.1.1.4.2 yamt s = (char *) backtrace_alloc (state, dir_len + filename_len + 2,
2771 1.1.1.1.4.2 yamt error_callback, data);
2772 1.1.1.1.4.2 yamt if (s == NULL)
2773 1.1.1.1.4.2 yamt {
2774 1.1.1.1.4.2 yamt *found = 0;
2775 1.1.1.1.4.2 yamt return 0;
2776 1.1.1.1.4.2 yamt }
2777 1.1.1.1.4.2 yamt memcpy (s, dir, dir_len);
2778 1.1.1.1.4.2 yamt /* FIXME: Should use backslash if DOS file system. */
2779 1.1.1.1.4.2 yamt s[dir_len] = '/';
2780 1.1.1.1.4.2 yamt memcpy (s + dir_len + 1, filename, filename_len + 1);
2781 1.1.1.1.4.2 yamt filename = s;
2782 1.1.1.1.4.2 yamt }
2783 1.1.1.1.4.2 yamt entry->u->abs_filename = filename;
2784 1.1.1.1.4.2 yamt }
2785 1.1.1.1.4.2 yamt
2786 1.1.1.1.4.2 yamt return callback (data, pc, entry->u->abs_filename, 0, NULL);
2787 1.1.1.1.4.2 yamt }
2788 1.1.1.1.4.2 yamt
2789 1.1.1.1.4.2 yamt /* Search for function name within this unit. */
2790 1.1.1.1.4.2 yamt
2791 1.1.1.1.4.2 yamt if (entry->u->function_addrs_count == 0)
2792 1.1.1.1.4.2 yamt return callback (data, pc, ln->filename, ln->lineno, NULL);
2793 1.1.1.1.4.2 yamt
2794 1.1.1.1.4.2 yamt function_addrs = ((struct function_addrs *)
2795 1.1.1.1.4.2 yamt bsearch (&pc, entry->u->function_addrs,
2796 1.1.1.1.4.2 yamt entry->u->function_addrs_count,
2797 1.1.1.1.4.2 yamt sizeof (struct function_addrs),
2798 1.1.1.1.4.2 yamt function_addrs_search));
2799 1.1.1.1.4.2 yamt if (function_addrs == NULL)
2800 1.1.1.1.4.2 yamt return callback (data, pc, ln->filename, ln->lineno, NULL);
2801 1.1.1.1.4.2 yamt
2802 1.1.1.1.4.2 yamt /* If there are multiple function ranges that contain PC, use the
2803 1.1.1.1.4.2 yamt last one, in order to produce predictable results. */
2804 1.1.1.1.4.2 yamt
2805 1.1.1.1.4.2 yamt while (((size_t) (function_addrs - entry->u->function_addrs + 1)
2806 1.1.1.1.4.2 yamt < entry->u->function_addrs_count)
2807 1.1.1.1.4.2 yamt && pc >= (function_addrs + 1)->low
2808 1.1.1.1.4.2 yamt && pc < (function_addrs + 1)->high)
2809 1.1.1.1.4.2 yamt ++function_addrs;
2810 1.1.1.1.4.2 yamt
2811 1.1.1.1.4.2 yamt function = function_addrs->function;
2812 1.1.1.1.4.2 yamt
2813 1.1.1.1.4.2 yamt filename = ln->filename;
2814 1.1.1.1.4.2 yamt lineno = ln->lineno;
2815 1.1.1.1.4.2 yamt
2816 1.1.1.1.4.2 yamt ret = report_inlined_functions (pc, function, callback, data,
2817 1.1.1.1.4.2 yamt &filename, &lineno);
2818 1.1.1.1.4.2 yamt if (ret != 0)
2819 1.1.1.1.4.2 yamt return ret;
2820 1.1.1.1.4.2 yamt
2821 1.1.1.1.4.2 yamt return callback (data, pc, filename, lineno, function->name);
2822 1.1.1.1.4.2 yamt }
2823 1.1.1.1.4.2 yamt
2824 1.1.1.1.4.2 yamt
2825 1.1.1.1.4.2 yamt /* Return the file/line information for a PC using the DWARF mapping
2826 1.1.1.1.4.2 yamt we built earlier. */
2827 1.1.1.1.4.2 yamt
2828 1.1.1.1.4.2 yamt static int
2829 1.1.1.1.4.2 yamt dwarf_fileline (struct backtrace_state *state, uintptr_t pc,
2830 1.1.1.1.4.2 yamt backtrace_full_callback callback,
2831 1.1.1.1.4.2 yamt backtrace_error_callback error_callback, void *data)
2832 1.1.1.1.4.2 yamt {
2833 1.1.1.1.4.2 yamt struct dwarf_data *ddata;
2834 1.1.1.1.4.2 yamt int found;
2835 1.1.1.1.4.2 yamt int ret;
2836 1.1.1.1.4.2 yamt
2837 1.1.1.1.4.2 yamt if (!state->threaded)
2838 1.1.1.1.4.2 yamt {
2839 1.1.1.1.4.2 yamt for (ddata = (struct dwarf_data *) state->fileline_data;
2840 1.1.1.1.4.2 yamt ddata != NULL;
2841 1.1.1.1.4.2 yamt ddata = ddata->next)
2842 1.1.1.1.4.2 yamt {
2843 1.1.1.1.4.2 yamt ret = dwarf_lookup_pc (state, ddata, pc, callback, error_callback,
2844 1.1.1.1.4.2 yamt data, &found);
2845 1.1.1.1.4.2 yamt if (ret != 0 || found)
2846 1.1.1.1.4.2 yamt return ret;
2847 1.1.1.1.4.2 yamt }
2848 1.1.1.1.4.2 yamt }
2849 1.1.1.1.4.2 yamt else
2850 1.1.1.1.4.2 yamt {
2851 1.1.1.1.4.2 yamt struct dwarf_data **pp;
2852 1.1.1.1.4.2 yamt
2853 1.1.1.1.4.2 yamt pp = (struct dwarf_data **) (void *) &state->fileline_data;
2854 1.1.1.1.4.2 yamt while (1)
2855 1.1.1.1.4.2 yamt {
2856 1.1.1.1.4.2 yamt ddata = *pp;
2857 1.1.1.1.4.2 yamt /* Atomic load. */
2858 1.1.1.1.4.2 yamt while (!__sync_bool_compare_and_swap (pp, ddata, ddata))
2859 1.1.1.1.4.2 yamt ddata = *pp;
2860 1.1.1.1.4.2 yamt
2861 1.1.1.1.4.2 yamt if (ddata == NULL)
2862 1.1.1.1.4.2 yamt break;
2863 1.1.1.1.4.2 yamt
2864 1.1.1.1.4.2 yamt ret = dwarf_lookup_pc (state, ddata, pc, callback, error_callback,
2865 1.1.1.1.4.2 yamt data, &found);
2866 1.1.1.1.4.2 yamt if (ret != 0 || found)
2867 1.1.1.1.4.2 yamt return ret;
2868 1.1.1.1.4.2 yamt
2869 1.1.1.1.4.2 yamt pp = &ddata->next;
2870 1.1.1.1.4.2 yamt }
2871 1.1.1.1.4.2 yamt }
2872 1.1.1.1.4.2 yamt
2873 1.1.1.1.4.2 yamt /* FIXME: See if any libraries have been dlopen'ed. */
2874 1.1.1.1.4.2 yamt
2875 1.1.1.1.4.2 yamt return callback (data, pc, NULL, 0, NULL);
2876 1.1.1.1.4.2 yamt }
2877 1.1.1.1.4.2 yamt
2878 1.1.1.1.4.2 yamt /* Initialize our data structures from the DWARF debug info for a
2879 1.1.1.1.4.2 yamt file. Return NULL on failure. */
2880 1.1.1.1.4.2 yamt
2881 1.1.1.1.4.2 yamt static struct dwarf_data *
2882 1.1.1.1.4.2 yamt build_dwarf_data (struct backtrace_state *state,
2883 1.1.1.1.4.2 yamt uintptr_t base_address,
2884 1.1.1.1.4.2 yamt const unsigned char *dwarf_info,
2885 1.1.1.1.4.2 yamt size_t dwarf_info_size,
2886 1.1.1.1.4.2 yamt const unsigned char *dwarf_line,
2887 1.1.1.1.4.2 yamt size_t dwarf_line_size,
2888 1.1.1.1.4.2 yamt const unsigned char *dwarf_abbrev,
2889 1.1.1.1.4.2 yamt size_t dwarf_abbrev_size,
2890 1.1.1.1.4.2 yamt const unsigned char *dwarf_ranges,
2891 1.1.1.1.4.2 yamt size_t dwarf_ranges_size,
2892 1.1.1.1.4.2 yamt const unsigned char *dwarf_str,
2893 1.1.1.1.4.2 yamt size_t dwarf_str_size,
2894 1.1.1.1.4.2 yamt int is_bigendian,
2895 1.1.1.1.4.2 yamt backtrace_error_callback error_callback,
2896 1.1.1.1.4.2 yamt void *data)
2897 1.1.1.1.4.2 yamt {
2898 1.1.1.1.4.2 yamt struct unit_addrs_vector addrs_vec;
2899 1.1.1.1.4.2 yamt struct unit_addrs *addrs;
2900 1.1.1.1.4.2 yamt size_t addrs_count;
2901 1.1.1.1.4.2 yamt struct dwarf_data *fdata;
2902 1.1.1.1.4.2 yamt
2903 1.1.1.1.4.2 yamt if (!build_address_map (state, base_address, dwarf_info, dwarf_info_size,
2904 1.1.1.1.4.2 yamt dwarf_abbrev, dwarf_abbrev_size, dwarf_ranges,
2905 1.1.1.1.4.2 yamt dwarf_ranges_size, dwarf_str, dwarf_str_size,
2906 1.1.1.1.4.2 yamt is_bigendian, error_callback, data, &addrs_vec))
2907 1.1.1.1.4.2 yamt return NULL;
2908 1.1.1.1.4.2 yamt
2909 1.1.1.1.4.2 yamt if (!backtrace_vector_release (state, &addrs_vec.vec, error_callback, data))
2910 1.1.1.1.4.2 yamt return NULL;
2911 1.1.1.1.4.2 yamt addrs = (struct unit_addrs *) addrs_vec.vec.base;
2912 1.1.1.1.4.2 yamt addrs_count = addrs_vec.count;
2913 1.1.1.1.4.2 yamt qsort (addrs, addrs_count, sizeof (struct unit_addrs), unit_addrs_compare);
2914 1.1.1.1.4.2 yamt
2915 1.1.1.1.4.2 yamt fdata = ((struct dwarf_data *)
2916 1.1.1.1.4.2 yamt backtrace_alloc (state, sizeof (struct dwarf_data),
2917 1.1.1.1.4.2 yamt error_callback, data));
2918 1.1.1.1.4.2 yamt if (fdata == NULL)
2919 1.1.1.1.4.2 yamt return NULL;
2920 1.1.1.1.4.2 yamt
2921 1.1.1.1.4.2 yamt fdata->next = NULL;
2922 1.1.1.1.4.2 yamt fdata->base_address = base_address;
2923 1.1.1.1.4.2 yamt fdata->addrs = addrs;
2924 1.1.1.1.4.2 yamt fdata->addrs_count = addrs_count;
2925 1.1.1.1.4.2 yamt fdata->dwarf_info = dwarf_info;
2926 1.1.1.1.4.2 yamt fdata->dwarf_info_size = dwarf_info_size;
2927 1.1.1.1.4.2 yamt fdata->dwarf_line = dwarf_line;
2928 1.1.1.1.4.2 yamt fdata->dwarf_line_size = dwarf_line_size;
2929 1.1.1.1.4.2 yamt fdata->dwarf_ranges = dwarf_ranges;
2930 1.1.1.1.4.2 yamt fdata->dwarf_ranges_size = dwarf_ranges_size;
2931 1.1.1.1.4.2 yamt fdata->dwarf_str = dwarf_str;
2932 1.1.1.1.4.2 yamt fdata->dwarf_str_size = dwarf_str_size;
2933 1.1.1.1.4.2 yamt fdata->is_bigendian = is_bigendian;
2934 1.1.1.1.4.2 yamt memset (&fdata->fvec, 0, sizeof fdata->fvec);
2935 1.1.1.1.4.2 yamt
2936 1.1.1.1.4.2 yamt return fdata;
2937 1.1.1.1.4.2 yamt }
2938 1.1.1.1.4.2 yamt
2939 1.1.1.1.4.2 yamt /* Build our data structures from the DWARF sections for a module.
2940 1.1.1.1.4.2 yamt Set FILELINE_FN and STATE->FILELINE_DATA. Return 1 on success, 0
2941 1.1.1.1.4.2 yamt on failure. */
2942 1.1.1.1.4.2 yamt
2943 1.1.1.1.4.2 yamt int
2944 1.1.1.1.4.2 yamt backtrace_dwarf_add (struct backtrace_state *state,
2945 1.1.1.1.4.2 yamt uintptr_t base_address,
2946 1.1.1.1.4.2 yamt const unsigned char *dwarf_info,
2947 1.1.1.1.4.2 yamt size_t dwarf_info_size,
2948 1.1.1.1.4.2 yamt const unsigned char *dwarf_line,
2949 1.1.1.1.4.2 yamt size_t dwarf_line_size,
2950 1.1.1.1.4.2 yamt const unsigned char *dwarf_abbrev,
2951 1.1.1.1.4.2 yamt size_t dwarf_abbrev_size,
2952 1.1.1.1.4.2 yamt const unsigned char *dwarf_ranges,
2953 1.1.1.1.4.2 yamt size_t dwarf_ranges_size,
2954 1.1.1.1.4.2 yamt const unsigned char *dwarf_str,
2955 1.1.1.1.4.2 yamt size_t dwarf_str_size,
2956 1.1.1.1.4.2 yamt int is_bigendian,
2957 1.1.1.1.4.2 yamt backtrace_error_callback error_callback,
2958 1.1.1.1.4.2 yamt void *data, fileline *fileline_fn)
2959 1.1.1.1.4.2 yamt {
2960 1.1.1.1.4.2 yamt struct dwarf_data *fdata;
2961 1.1.1.1.4.2 yamt
2962 1.1.1.1.4.2 yamt fdata = build_dwarf_data (state, base_address, dwarf_info, dwarf_info_size,
2963 1.1.1.1.4.2 yamt dwarf_line, dwarf_line_size, dwarf_abbrev,
2964 1.1.1.1.4.2 yamt dwarf_abbrev_size, dwarf_ranges, dwarf_ranges_size,
2965 1.1.1.1.4.2 yamt dwarf_str, dwarf_str_size, is_bigendian,
2966 1.1.1.1.4.2 yamt error_callback, data);
2967 1.1.1.1.4.2 yamt if (fdata == NULL)
2968 1.1.1.1.4.2 yamt return 0;
2969 1.1.1.1.4.2 yamt
2970 1.1.1.1.4.2 yamt if (!state->threaded)
2971 1.1.1.1.4.2 yamt {
2972 1.1.1.1.4.2 yamt struct dwarf_data **pp;
2973 1.1.1.1.4.2 yamt
2974 1.1.1.1.4.2 yamt for (pp = (struct dwarf_data **) (void *) &state->fileline_data;
2975 1.1.1.1.4.2 yamt *pp != NULL;
2976 1.1.1.1.4.2 yamt pp = &(*pp)->next)
2977 1.1.1.1.4.2 yamt ;
2978 1.1.1.1.4.2 yamt *pp = fdata;
2979 1.1.1.1.4.2 yamt }
2980 1.1.1.1.4.2 yamt else
2981 1.1.1.1.4.2 yamt {
2982 1.1.1.1.4.2 yamt while (1)
2983 1.1.1.1.4.2 yamt {
2984 1.1.1.1.4.2 yamt struct dwarf_data **pp;
2985 1.1.1.1.4.2 yamt
2986 1.1.1.1.4.2 yamt pp = (struct dwarf_data **) (void *) &state->fileline_data;
2987 1.1.1.1.4.2 yamt
2988 1.1.1.1.4.2 yamt while (1)
2989 1.1.1.1.4.2 yamt {
2990 1.1.1.1.4.2 yamt struct dwarf_data *p;
2991 1.1.1.1.4.2 yamt
2992 1.1.1.1.4.2 yamt /* Atomic load. */
2993 1.1.1.1.4.2 yamt p = *pp;
2994 1.1.1.1.4.2 yamt while (!__sync_bool_compare_and_swap (pp, p, p))
2995 1.1.1.1.4.2 yamt p = *pp;
2996 1.1.1.1.4.2 yamt
2997 1.1.1.1.4.2 yamt if (p == NULL)
2998 1.1.1.1.4.2 yamt break;
2999 1.1.1.1.4.2 yamt
3000 1.1.1.1.4.2 yamt pp = &p->next;
3001 1.1.1.1.4.2 yamt }
3002 1.1.1.1.4.2 yamt
3003 1.1.1.1.4.2 yamt if (__sync_bool_compare_and_swap (pp, NULL, fdata))
3004 1.1.1.1.4.2 yamt break;
3005 1.1.1.1.4.2 yamt }
3006 1.1.1.1.4.2 yamt }
3007 1.1.1.1.4.2 yamt
3008 1.1.1.1.4.2 yamt *fileline_fn = dwarf_fileline;
3009 1.1.1.1.4.2 yamt
3010 1.1.1.1.4.2 yamt return 1;
3011 1.1.1.1.4.2 yamt }
3012