dwarf.c revision 1.1.1.1.2.1 1 1.1 christos /* dwarf.c -- Get file/line information from DWARF for backtraces.
2 1.1.1.1.2.1 perseant Copyright (C) 2012-2024 Free Software Foundation, Inc.
3 1.1 christos Written by Ian Lance Taylor, Google.
4 1.1 christos
5 1.1 christos Redistribution and use in source and binary forms, with or without
6 1.1 christos modification, are permitted provided that the following conditions are
7 1.1 christos met:
8 1.1 christos
9 1.1 christos (1) Redistributions of source code must retain the above copyright
10 1.1 christos notice, this list of conditions and the following disclaimer.
11 1.1 christos
12 1.1 christos (2) Redistributions in binary form must reproduce the above copyright
13 1.1 christos notice, this list of conditions and the following disclaimer in
14 1.1 christos the documentation and/or other materials provided with the
15 1.1 christos distribution.
16 1.1 christos
17 1.1 christos (3) The name of the author may not be used to
18 1.1 christos endorse or promote products derived from this software without
19 1.1 christos specific prior written permission.
20 1.1 christos
21 1.1 christos THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 1.1 christos IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 1.1 christos WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 1.1 christos DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
25 1.1 christos INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 1.1 christos (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 1.1 christos SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 1.1 christos HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29 1.1 christos STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
30 1.1 christos IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 1.1 christos POSSIBILITY OF SUCH DAMAGE. */
32 1.1 christos
33 1.1 christos #include "config.h"
34 1.1 christos
35 1.1 christos #include <errno.h>
36 1.1 christos #include <stdlib.h>
37 1.1 christos #include <string.h>
38 1.1 christos #include <sys/types.h>
39 1.1 christos
40 1.1 christos #include "dwarf2.h"
41 1.1 christos #include "filenames.h"
42 1.1 christos
43 1.1 christos #include "backtrace.h"
44 1.1 christos #include "internal.h"
45 1.1 christos
46 1.1 christos #if !defined(HAVE_DECL_STRNLEN) || !HAVE_DECL_STRNLEN
47 1.1 christos
48 1.1 christos /* If strnlen is not declared, provide our own version. */
49 1.1 christos
50 1.1 christos static size_t
51 1.1 christos xstrnlen (const char *s, size_t maxlen)
52 1.1 christos {
53 1.1 christos size_t i;
54 1.1 christos
55 1.1 christos for (i = 0; i < maxlen; ++i)
56 1.1 christos if (s[i] == '\0')
57 1.1 christos break;
58 1.1 christos return i;
59 1.1 christos }
60 1.1 christos
61 1.1 christos #define strnlen xstrnlen
62 1.1 christos
63 1.1 christos #endif
64 1.1 christos
65 1.1 christos /* A buffer to read DWARF info. */
66 1.1 christos
67 1.1 christos struct dwarf_buf
68 1.1 christos {
69 1.1 christos /* Buffer name for error messages. */
70 1.1 christos const char *name;
71 1.1 christos /* Start of the buffer. */
72 1.1 christos const unsigned char *start;
73 1.1 christos /* Next byte to read. */
74 1.1 christos const unsigned char *buf;
75 1.1 christos /* The number of bytes remaining. */
76 1.1 christos size_t left;
77 1.1 christos /* Whether the data is big-endian. */
78 1.1 christos int is_bigendian;
79 1.1 christos /* Error callback routine. */
80 1.1 christos backtrace_error_callback error_callback;
81 1.1 christos /* Data for error_callback. */
82 1.1 christos void *data;
83 1.1 christos /* Non-zero if we've reported an underflow error. */
84 1.1 christos int reported_underflow;
85 1.1 christos };
86 1.1 christos
87 1.1 christos /* A single attribute in a DWARF abbreviation. */
88 1.1 christos
89 1.1 christos struct attr
90 1.1 christos {
91 1.1 christos /* The attribute name. */
92 1.1 christos enum dwarf_attribute name;
93 1.1 christos /* The attribute form. */
94 1.1 christos enum dwarf_form form;
95 1.1 christos /* The attribute value, for DW_FORM_implicit_const. */
96 1.1 christos int64_t val;
97 1.1 christos };
98 1.1 christos
99 1.1 christos /* A single DWARF abbreviation. */
100 1.1 christos
101 1.1 christos struct abbrev
102 1.1 christos {
103 1.1 christos /* The abbrev code--the number used to refer to the abbrev. */
104 1.1 christos uint64_t code;
105 1.1 christos /* The entry tag. */
106 1.1 christos enum dwarf_tag tag;
107 1.1 christos /* Non-zero if this abbrev has child entries. */
108 1.1 christos int has_children;
109 1.1 christos /* The number of attributes. */
110 1.1 christos size_t num_attrs;
111 1.1 christos /* The attributes. */
112 1.1 christos struct attr *attrs;
113 1.1 christos };
114 1.1 christos
115 1.1 christos /* The DWARF abbreviations for a compilation unit. This structure
116 1.1 christos only exists while reading the compilation unit. Most DWARF readers
117 1.1 christos seem to a hash table to map abbrev ID's to abbrev entries.
118 1.1 christos However, we primarily care about GCC, and GCC simply issues ID's in
119 1.1 christos numerical order starting at 1. So we simply keep a sorted vector,
120 1.1 christos and try to just look up the code. */
121 1.1 christos
122 1.1 christos struct abbrevs
123 1.1 christos {
124 1.1 christos /* The number of abbrevs in the vector. */
125 1.1 christos size_t num_abbrevs;
126 1.1 christos /* The abbrevs, sorted by the code field. */
127 1.1 christos struct abbrev *abbrevs;
128 1.1 christos };
129 1.1 christos
130 1.1 christos /* The different kinds of attribute values. */
131 1.1 christos
132 1.1 christos enum attr_val_encoding
133 1.1 christos {
134 1.1 christos /* No attribute value. */
135 1.1 christos ATTR_VAL_NONE,
136 1.1 christos /* An address. */
137 1.1 christos ATTR_VAL_ADDRESS,
138 1.1 christos /* An index into the .debug_addr section, whose value is relative to
139 1.1.1.1.2.1 perseant the DW_AT_addr_base attribute of the compilation unit. */
140 1.1 christos ATTR_VAL_ADDRESS_INDEX,
141 1.1 christos /* A unsigned integer. */
142 1.1 christos ATTR_VAL_UINT,
143 1.1 christos /* A sigd integer. */
144 1.1 christos ATTR_VAL_SINT,
145 1.1 christos /* A string. */
146 1.1 christos ATTR_VAL_STRING,
147 1.1 christos /* An index into the .debug_str_offsets section. */
148 1.1 christos ATTR_VAL_STRING_INDEX,
149 1.1 christos /* An offset to other data in the containing unit. */
150 1.1 christos ATTR_VAL_REF_UNIT,
151 1.1 christos /* An offset to other data within the .debug_info section. */
152 1.1 christos ATTR_VAL_REF_INFO,
153 1.1 christos /* An offset to other data within the alt .debug_info section. */
154 1.1 christos ATTR_VAL_REF_ALT_INFO,
155 1.1 christos /* An offset to data in some other section. */
156 1.1 christos ATTR_VAL_REF_SECTION,
157 1.1 christos /* A type signature. */
158 1.1 christos ATTR_VAL_REF_TYPE,
159 1.1 christos /* An index into the .debug_rnglists section. */
160 1.1 christos ATTR_VAL_RNGLISTS_INDEX,
161 1.1 christos /* A block of data (not represented). */
162 1.1 christos ATTR_VAL_BLOCK,
163 1.1 christos /* An expression (not represented). */
164 1.1 christos ATTR_VAL_EXPR,
165 1.1 christos };
166 1.1 christos
167 1.1 christos /* An attribute value. */
168 1.1 christos
169 1.1 christos struct attr_val
170 1.1 christos {
171 1.1 christos /* How the value is stored in the field u. */
172 1.1 christos enum attr_val_encoding encoding;
173 1.1 christos union
174 1.1 christos {
175 1.1 christos /* ATTR_VAL_ADDRESS*, ATTR_VAL_UINT, ATTR_VAL_REF*. */
176 1.1 christos uint64_t uint;
177 1.1 christos /* ATTR_VAL_SINT. */
178 1.1 christos int64_t sint;
179 1.1 christos /* ATTR_VAL_STRING. */
180 1.1 christos const char *string;
181 1.1 christos /* ATTR_VAL_BLOCK not stored. */
182 1.1 christos } u;
183 1.1 christos };
184 1.1 christos
185 1.1 christos /* The line number program header. */
186 1.1 christos
187 1.1 christos struct line_header
188 1.1 christos {
189 1.1 christos /* The version of the line number information. */
190 1.1 christos int version;
191 1.1 christos /* Address size. */
192 1.1 christos int addrsize;
193 1.1 christos /* The minimum instruction length. */
194 1.1 christos unsigned int min_insn_len;
195 1.1 christos /* The maximum number of ops per instruction. */
196 1.1 christos unsigned int max_ops_per_insn;
197 1.1 christos /* The line base for special opcodes. */
198 1.1 christos int line_base;
199 1.1 christos /* The line range for special opcodes. */
200 1.1 christos unsigned int line_range;
201 1.1 christos /* The opcode base--the first special opcode. */
202 1.1 christos unsigned int opcode_base;
203 1.1 christos /* Opcode lengths, indexed by opcode - 1. */
204 1.1 christos const unsigned char *opcode_lengths;
205 1.1 christos /* The number of directory entries. */
206 1.1 christos size_t dirs_count;
207 1.1 christos /* The directory entries. */
208 1.1 christos const char **dirs;
209 1.1 christos /* The number of filenames. */
210 1.1 christos size_t filenames_count;
211 1.1 christos /* The filenames. */
212 1.1 christos const char **filenames;
213 1.1 christos };
214 1.1 christos
215 1.1 christos /* A format description from a line header. */
216 1.1 christos
217 1.1 christos struct line_header_format
218 1.1 christos {
219 1.1 christos int lnct; /* LNCT code. */
220 1.1 christos enum dwarf_form form; /* Form of entry data. */
221 1.1 christos };
222 1.1 christos
223 1.1 christos /* Map a single PC value to a file/line. We will keep a vector of
224 1.1 christos these sorted by PC value. Each file/line will be correct from the
225 1.1 christos PC up to the PC of the next entry if there is one. We allocate one
226 1.1 christos extra entry at the end so that we can use bsearch. */
227 1.1 christos
228 1.1 christos struct line
229 1.1 christos {
230 1.1 christos /* PC. */
231 1.1 christos uintptr_t pc;
232 1.1 christos /* File name. Many entries in the array are expected to point to
233 1.1 christos the same file name. */
234 1.1 christos const char *filename;
235 1.1 christos /* Line number. */
236 1.1 christos int lineno;
237 1.1 christos /* Index of the object in the original array read from the DWARF
238 1.1 christos section, before it has been sorted. The index makes it possible
239 1.1 christos to use Quicksort and maintain stability. */
240 1.1 christos int idx;
241 1.1 christos };
242 1.1 christos
243 1.1 christos /* A growable vector of line number information. This is used while
244 1.1 christos reading the line numbers. */
245 1.1 christos
246 1.1 christos struct line_vector
247 1.1 christos {
248 1.1 christos /* Memory. This is an array of struct line. */
249 1.1 christos struct backtrace_vector vec;
250 1.1 christos /* Number of valid mappings. */
251 1.1 christos size_t count;
252 1.1 christos };
253 1.1 christos
254 1.1 christos /* A function described in the debug info. */
255 1.1 christos
256 1.1 christos struct function
257 1.1 christos {
258 1.1 christos /* The name of the function. */
259 1.1 christos const char *name;
260 1.1 christos /* If this is an inlined function, the filename of the call
261 1.1 christos site. */
262 1.1 christos const char *caller_filename;
263 1.1 christos /* If this is an inlined function, the line number of the call
264 1.1 christos site. */
265 1.1 christos int caller_lineno;
266 1.1 christos /* Map PC ranges to inlined functions. */
267 1.1 christos struct function_addrs *function_addrs;
268 1.1 christos size_t function_addrs_count;
269 1.1 christos };
270 1.1 christos
271 1.1 christos /* An address range for a function. This maps a PC value to a
272 1.1 christos specific function. */
273 1.1 christos
274 1.1 christos struct function_addrs
275 1.1 christos {
276 1.1 christos /* Range is LOW <= PC < HIGH. */
277 1.1.1.1.2.1 perseant uintptr_t low;
278 1.1.1.1.2.1 perseant uintptr_t high;
279 1.1 christos /* Function for this address range. */
280 1.1 christos struct function *function;
281 1.1 christos };
282 1.1 christos
283 1.1 christos /* A growable vector of function address ranges. */
284 1.1 christos
285 1.1 christos struct function_vector
286 1.1 christos {
287 1.1 christos /* Memory. This is an array of struct function_addrs. */
288 1.1 christos struct backtrace_vector vec;
289 1.1 christos /* Number of address ranges present. */
290 1.1 christos size_t count;
291 1.1 christos };
292 1.1 christos
293 1.1 christos /* A DWARF compilation unit. This only holds the information we need
294 1.1 christos to map a PC to a file and line. */
295 1.1 christos
296 1.1 christos struct unit
297 1.1 christos {
298 1.1 christos /* The first entry for this compilation unit. */
299 1.1 christos const unsigned char *unit_data;
300 1.1 christos /* The length of the data for this compilation unit. */
301 1.1 christos size_t unit_data_len;
302 1.1 christos /* The offset of UNIT_DATA from the start of the information for
303 1.1 christos this compilation unit. */
304 1.1 christos size_t unit_data_offset;
305 1.1 christos /* Offset of the start of the compilation unit from the start of the
306 1.1 christos .debug_info section. */
307 1.1 christos size_t low_offset;
308 1.1 christos /* Offset of the end of the compilation unit from the start of the
309 1.1 christos .debug_info section. */
310 1.1 christos size_t high_offset;
311 1.1 christos /* DWARF version. */
312 1.1 christos int version;
313 1.1 christos /* Whether unit is DWARF64. */
314 1.1 christos int is_dwarf64;
315 1.1 christos /* Address size. */
316 1.1 christos int addrsize;
317 1.1 christos /* Offset into line number information. */
318 1.1 christos off_t lineoff;
319 1.1 christos /* Offset of compilation unit in .debug_str_offsets. */
320 1.1 christos uint64_t str_offsets_base;
321 1.1 christos /* Offset of compilation unit in .debug_addr. */
322 1.1 christos uint64_t addr_base;
323 1.1 christos /* Offset of compilation unit in .debug_rnglists. */
324 1.1 christos uint64_t rnglists_base;
325 1.1 christos /* Primary source file. */
326 1.1 christos const char *filename;
327 1.1 christos /* Compilation command working directory. */
328 1.1 christos const char *comp_dir;
329 1.1 christos /* Absolute file name, only set if needed. */
330 1.1 christos const char *abs_filename;
331 1.1 christos /* The abbreviations for this unit. */
332 1.1 christos struct abbrevs abbrevs;
333 1.1 christos
334 1.1 christos /* The fields above this point are read in during initialization and
335 1.1 christos may be accessed freely. The fields below this point are read in
336 1.1 christos as needed, and therefore require care, as different threads may
337 1.1 christos try to initialize them simultaneously. */
338 1.1 christos
339 1.1 christos /* PC to line number mapping. This is NULL if the values have not
340 1.1 christos been read. This is (struct line *) -1 if there was an error
341 1.1 christos reading the values. */
342 1.1 christos struct line *lines;
343 1.1 christos /* Number of entries in lines. */
344 1.1 christos size_t lines_count;
345 1.1 christos /* PC ranges to function. */
346 1.1 christos struct function_addrs *function_addrs;
347 1.1 christos size_t function_addrs_count;
348 1.1 christos };
349 1.1 christos
350 1.1 christos /* An address range for a compilation unit. This maps a PC value to a
351 1.1 christos specific compilation unit. Note that we invert the representation
352 1.1 christos in DWARF: instead of listing the units and attaching a list of
353 1.1 christos ranges, we list the ranges and have each one point to the unit.
354 1.1 christos This lets us do a binary search to find the unit. */
355 1.1 christos
356 1.1 christos struct unit_addrs
357 1.1 christos {
358 1.1 christos /* Range is LOW <= PC < HIGH. */
359 1.1.1.1.2.1 perseant uintptr_t low;
360 1.1.1.1.2.1 perseant uintptr_t high;
361 1.1 christos /* Compilation unit for this address range. */
362 1.1 christos struct unit *u;
363 1.1 christos };
364 1.1 christos
365 1.1 christos /* A growable vector of compilation unit address ranges. */
366 1.1 christos
367 1.1 christos struct unit_addrs_vector
368 1.1 christos {
369 1.1 christos /* Memory. This is an array of struct unit_addrs. */
370 1.1 christos struct backtrace_vector vec;
371 1.1 christos /* Number of address ranges present. */
372 1.1 christos size_t count;
373 1.1 christos };
374 1.1 christos
375 1.1 christos /* A growable vector of compilation unit pointer. */
376 1.1 christos
377 1.1 christos struct unit_vector
378 1.1 christos {
379 1.1 christos struct backtrace_vector vec;
380 1.1 christos size_t count;
381 1.1 christos };
382 1.1 christos
383 1.1 christos /* The information we need to map a PC to a file and line. */
384 1.1 christos
385 1.1 christos struct dwarf_data
386 1.1 christos {
387 1.1 christos /* The data for the next file we know about. */
388 1.1 christos struct dwarf_data *next;
389 1.1 christos /* The data for .gnu_debugaltlink. */
390 1.1 christos struct dwarf_data *altlink;
391 1.1 christos /* The base address for this file. */
392 1.1 christos uintptr_t base_address;
393 1.1 christos /* A sorted list of address ranges. */
394 1.1 christos struct unit_addrs *addrs;
395 1.1 christos /* Number of address ranges in list. */
396 1.1 christos size_t addrs_count;
397 1.1 christos /* A sorted list of units. */
398 1.1 christos struct unit **units;
399 1.1 christos /* Number of units in the list. */
400 1.1 christos size_t units_count;
401 1.1 christos /* The unparsed DWARF debug data. */
402 1.1 christos struct dwarf_sections dwarf_sections;
403 1.1 christos /* Whether the data is big-endian or not. */
404 1.1 christos int is_bigendian;
405 1.1 christos /* A vector used for function addresses. We keep this here so that
406 1.1 christos we can grow the vector as we read more functions. */
407 1.1 christos struct function_vector fvec;
408 1.1 christos };
409 1.1 christos
410 1.1 christos /* Report an error for a DWARF buffer. */
411 1.1 christos
412 1.1 christos static void
413 1.1 christos dwarf_buf_error (struct dwarf_buf *buf, const char *msg, int errnum)
414 1.1 christos {
415 1.1 christos char b[200];
416 1.1 christos
417 1.1 christos snprintf (b, sizeof b, "%s in %s at %d",
418 1.1 christos msg, buf->name, (int) (buf->buf - buf->start));
419 1.1 christos buf->error_callback (buf->data, b, errnum);
420 1.1 christos }
421 1.1 christos
422 1.1 christos /* Require at least COUNT bytes in BUF. Return 1 if all is well, 0 on
423 1.1 christos error. */
424 1.1 christos
425 1.1 christos static int
426 1.1 christos require (struct dwarf_buf *buf, size_t count)
427 1.1 christos {
428 1.1 christos if (buf->left >= count)
429 1.1 christos return 1;
430 1.1 christos
431 1.1 christos if (!buf->reported_underflow)
432 1.1 christos {
433 1.1 christos dwarf_buf_error (buf, "DWARF underflow", 0);
434 1.1 christos buf->reported_underflow = 1;
435 1.1 christos }
436 1.1 christos
437 1.1 christos return 0;
438 1.1 christos }
439 1.1 christos
440 1.1 christos /* Advance COUNT bytes in BUF. Return 1 if all is well, 0 on
441 1.1 christos error. */
442 1.1 christos
443 1.1 christos static int
444 1.1 christos advance (struct dwarf_buf *buf, size_t count)
445 1.1 christos {
446 1.1 christos if (!require (buf, count))
447 1.1 christos return 0;
448 1.1 christos buf->buf += count;
449 1.1 christos buf->left -= count;
450 1.1 christos return 1;
451 1.1 christos }
452 1.1 christos
453 1.1 christos /* Read one zero-terminated string from BUF and advance past the string. */
454 1.1 christos
455 1.1 christos static const char *
456 1.1 christos read_string (struct dwarf_buf *buf)
457 1.1 christos {
458 1.1 christos const char *p = (const char *)buf->buf;
459 1.1 christos size_t len = strnlen (p, buf->left);
460 1.1 christos
461 1.1 christos /* - If len == left, we ran out of buffer before finding the zero terminator.
462 1.1 christos Generate an error by advancing len + 1.
463 1.1 christos - If len < left, advance by len + 1 to skip past the zero terminator. */
464 1.1 christos size_t count = len + 1;
465 1.1 christos
466 1.1 christos if (!advance (buf, count))
467 1.1 christos return NULL;
468 1.1 christos
469 1.1 christos return p;
470 1.1 christos }
471 1.1 christos
472 1.1 christos /* Read one byte from BUF and advance 1 byte. */
473 1.1 christos
474 1.1 christos static unsigned char
475 1.1 christos read_byte (struct dwarf_buf *buf)
476 1.1 christos {
477 1.1 christos const unsigned char *p = buf->buf;
478 1.1 christos
479 1.1 christos if (!advance (buf, 1))
480 1.1 christos return 0;
481 1.1 christos return p[0];
482 1.1 christos }
483 1.1 christos
484 1.1 christos /* Read a signed char from BUF and advance 1 byte. */
485 1.1 christos
486 1.1 christos static signed char
487 1.1 christos read_sbyte (struct dwarf_buf *buf)
488 1.1 christos {
489 1.1 christos const unsigned char *p = buf->buf;
490 1.1 christos
491 1.1 christos if (!advance (buf, 1))
492 1.1 christos return 0;
493 1.1 christos return (*p ^ 0x80) - 0x80;
494 1.1 christos }
495 1.1 christos
496 1.1 christos /* Read a uint16 from BUF and advance 2 bytes. */
497 1.1 christos
498 1.1 christos static uint16_t
499 1.1 christos read_uint16 (struct dwarf_buf *buf)
500 1.1 christos {
501 1.1 christos const unsigned char *p = buf->buf;
502 1.1 christos
503 1.1 christos if (!advance (buf, 2))
504 1.1 christos return 0;
505 1.1 christos if (buf->is_bigendian)
506 1.1 christos return ((uint16_t) p[0] << 8) | (uint16_t) p[1];
507 1.1 christos else
508 1.1 christos return ((uint16_t) p[1] << 8) | (uint16_t) p[0];
509 1.1 christos }
510 1.1 christos
511 1.1 christos /* Read a 24 bit value from BUF and advance 3 bytes. */
512 1.1 christos
513 1.1 christos static uint32_t
514 1.1 christos read_uint24 (struct dwarf_buf *buf)
515 1.1 christos {
516 1.1 christos const unsigned char *p = buf->buf;
517 1.1 christos
518 1.1 christos if (!advance (buf, 3))
519 1.1 christos return 0;
520 1.1 christos if (buf->is_bigendian)
521 1.1 christos return (((uint32_t) p[0] << 16) | ((uint32_t) p[1] << 8)
522 1.1 christos | (uint32_t) p[2]);
523 1.1 christos else
524 1.1 christos return (((uint32_t) p[2] << 16) | ((uint32_t) p[1] << 8)
525 1.1 christos | (uint32_t) p[0]);
526 1.1 christos }
527 1.1 christos
528 1.1 christos /* Read a uint32 from BUF and advance 4 bytes. */
529 1.1 christos
530 1.1 christos static uint32_t
531 1.1 christos read_uint32 (struct dwarf_buf *buf)
532 1.1 christos {
533 1.1 christos const unsigned char *p = buf->buf;
534 1.1 christos
535 1.1 christos if (!advance (buf, 4))
536 1.1 christos return 0;
537 1.1 christos if (buf->is_bigendian)
538 1.1 christos return (((uint32_t) p[0] << 24) | ((uint32_t) p[1] << 16)
539 1.1 christos | ((uint32_t) p[2] << 8) | (uint32_t) p[3]);
540 1.1 christos else
541 1.1 christos return (((uint32_t) p[3] << 24) | ((uint32_t) p[2] << 16)
542 1.1 christos | ((uint32_t) p[1] << 8) | (uint32_t) p[0]);
543 1.1 christos }
544 1.1 christos
545 1.1 christos /* Read a uint64 from BUF and advance 8 bytes. */
546 1.1 christos
547 1.1 christos static uint64_t
548 1.1 christos read_uint64 (struct dwarf_buf *buf)
549 1.1 christos {
550 1.1 christos const unsigned char *p = buf->buf;
551 1.1 christos
552 1.1 christos if (!advance (buf, 8))
553 1.1 christos return 0;
554 1.1 christos if (buf->is_bigendian)
555 1.1 christos return (((uint64_t) p[0] << 56) | ((uint64_t) p[1] << 48)
556 1.1 christos | ((uint64_t) p[2] << 40) | ((uint64_t) p[3] << 32)
557 1.1 christos | ((uint64_t) p[4] << 24) | ((uint64_t) p[5] << 16)
558 1.1 christos | ((uint64_t) p[6] << 8) | (uint64_t) p[7]);
559 1.1 christos else
560 1.1 christos return (((uint64_t) p[7] << 56) | ((uint64_t) p[6] << 48)
561 1.1 christos | ((uint64_t) p[5] << 40) | ((uint64_t) p[4] << 32)
562 1.1 christos | ((uint64_t) p[3] << 24) | ((uint64_t) p[2] << 16)
563 1.1 christos | ((uint64_t) p[1] << 8) | (uint64_t) p[0]);
564 1.1 christos }
565 1.1 christos
566 1.1 christos /* Read an offset from BUF and advance the appropriate number of
567 1.1 christos bytes. */
568 1.1 christos
569 1.1 christos static uint64_t
570 1.1 christos read_offset (struct dwarf_buf *buf, int is_dwarf64)
571 1.1 christos {
572 1.1 christos if (is_dwarf64)
573 1.1 christos return read_uint64 (buf);
574 1.1 christos else
575 1.1 christos return read_uint32 (buf);
576 1.1 christos }
577 1.1 christos
578 1.1 christos /* Read an address from BUF and advance the appropriate number of
579 1.1 christos bytes. */
580 1.1 christos
581 1.1 christos static uint64_t
582 1.1 christos read_address (struct dwarf_buf *buf, int addrsize)
583 1.1 christos {
584 1.1 christos switch (addrsize)
585 1.1 christos {
586 1.1 christos case 1:
587 1.1 christos return read_byte (buf);
588 1.1 christos case 2:
589 1.1 christos return read_uint16 (buf);
590 1.1 christos case 4:
591 1.1 christos return read_uint32 (buf);
592 1.1 christos case 8:
593 1.1 christos return read_uint64 (buf);
594 1.1 christos default:
595 1.1 christos dwarf_buf_error (buf, "unrecognized address size", 0);
596 1.1 christos return 0;
597 1.1 christos }
598 1.1 christos }
599 1.1 christos
600 1.1 christos /* Return whether a value is the highest possible address, given the
601 1.1 christos address size. */
602 1.1 christos
603 1.1 christos static int
604 1.1 christos is_highest_address (uint64_t address, int addrsize)
605 1.1 christos {
606 1.1 christos switch (addrsize)
607 1.1 christos {
608 1.1 christos case 1:
609 1.1 christos return address == (unsigned char) -1;
610 1.1 christos case 2:
611 1.1 christos return address == (uint16_t) -1;
612 1.1 christos case 4:
613 1.1 christos return address == (uint32_t) -1;
614 1.1 christos case 8:
615 1.1 christos return address == (uint64_t) -1;
616 1.1 christos default:
617 1.1 christos return 0;
618 1.1 christos }
619 1.1 christos }
620 1.1 christos
621 1.1 christos /* Read an unsigned LEB128 number. */
622 1.1 christos
623 1.1 christos static uint64_t
624 1.1 christos read_uleb128 (struct dwarf_buf *buf)
625 1.1 christos {
626 1.1 christos uint64_t ret;
627 1.1 christos unsigned int shift;
628 1.1 christos int overflow;
629 1.1 christos unsigned char b;
630 1.1 christos
631 1.1 christos ret = 0;
632 1.1 christos shift = 0;
633 1.1 christos overflow = 0;
634 1.1 christos do
635 1.1 christos {
636 1.1 christos const unsigned char *p;
637 1.1 christos
638 1.1 christos p = buf->buf;
639 1.1 christos if (!advance (buf, 1))
640 1.1 christos return 0;
641 1.1 christos b = *p;
642 1.1 christos if (shift < 64)
643 1.1 christos ret |= ((uint64_t) (b & 0x7f)) << shift;
644 1.1 christos else if (!overflow)
645 1.1 christos {
646 1.1 christos dwarf_buf_error (buf, "LEB128 overflows uint64_t", 0);
647 1.1 christos overflow = 1;
648 1.1 christos }
649 1.1 christos shift += 7;
650 1.1 christos }
651 1.1 christos while ((b & 0x80) != 0);
652 1.1 christos
653 1.1 christos return ret;
654 1.1 christos }
655 1.1 christos
656 1.1 christos /* Read a signed LEB128 number. */
657 1.1 christos
658 1.1 christos static int64_t
659 1.1 christos read_sleb128 (struct dwarf_buf *buf)
660 1.1 christos {
661 1.1 christos uint64_t val;
662 1.1 christos unsigned int shift;
663 1.1 christos int overflow;
664 1.1 christos unsigned char b;
665 1.1 christos
666 1.1 christos val = 0;
667 1.1 christos shift = 0;
668 1.1 christos overflow = 0;
669 1.1 christos do
670 1.1 christos {
671 1.1 christos const unsigned char *p;
672 1.1 christos
673 1.1 christos p = buf->buf;
674 1.1 christos if (!advance (buf, 1))
675 1.1 christos return 0;
676 1.1 christos b = *p;
677 1.1 christos if (shift < 64)
678 1.1 christos val |= ((uint64_t) (b & 0x7f)) << shift;
679 1.1 christos else if (!overflow)
680 1.1 christos {
681 1.1 christos dwarf_buf_error (buf, "signed LEB128 overflows uint64_t", 0);
682 1.1 christos overflow = 1;
683 1.1 christos }
684 1.1 christos shift += 7;
685 1.1 christos }
686 1.1 christos while ((b & 0x80) != 0);
687 1.1 christos
688 1.1 christos if ((b & 0x40) != 0 && shift < 64)
689 1.1 christos val |= ((uint64_t) -1) << shift;
690 1.1 christos
691 1.1 christos return (int64_t) val;
692 1.1 christos }
693 1.1 christos
694 1.1 christos /* Return the length of an LEB128 number. */
695 1.1 christos
696 1.1 christos static size_t
697 1.1 christos leb128_len (const unsigned char *p)
698 1.1 christos {
699 1.1 christos size_t ret;
700 1.1 christos
701 1.1 christos ret = 1;
702 1.1 christos while ((*p & 0x80) != 0)
703 1.1 christos {
704 1.1 christos ++p;
705 1.1 christos ++ret;
706 1.1 christos }
707 1.1 christos return ret;
708 1.1 christos }
709 1.1 christos
710 1.1 christos /* Read initial_length from BUF and advance the appropriate number of bytes. */
711 1.1 christos
712 1.1 christos static uint64_t
713 1.1 christos read_initial_length (struct dwarf_buf *buf, int *is_dwarf64)
714 1.1 christos {
715 1.1 christos uint64_t len;
716 1.1 christos
717 1.1 christos len = read_uint32 (buf);
718 1.1 christos if (len == 0xffffffff)
719 1.1 christos {
720 1.1 christos len = read_uint64 (buf);
721 1.1 christos *is_dwarf64 = 1;
722 1.1 christos }
723 1.1 christos else
724 1.1 christos *is_dwarf64 = 0;
725 1.1 christos
726 1.1 christos return len;
727 1.1 christos }
728 1.1 christos
729 1.1 christos /* Free an abbreviations structure. */
730 1.1 christos
731 1.1 christos static void
732 1.1 christos free_abbrevs (struct backtrace_state *state, struct abbrevs *abbrevs,
733 1.1 christos backtrace_error_callback error_callback, void *data)
734 1.1 christos {
735 1.1 christos size_t i;
736 1.1 christos
737 1.1 christos for (i = 0; i < abbrevs->num_abbrevs; ++i)
738 1.1 christos backtrace_free (state, abbrevs->abbrevs[i].attrs,
739 1.1 christos abbrevs->abbrevs[i].num_attrs * sizeof (struct attr),
740 1.1 christos error_callback, data);
741 1.1 christos backtrace_free (state, abbrevs->abbrevs,
742 1.1 christos abbrevs->num_abbrevs * sizeof (struct abbrev),
743 1.1 christos error_callback, data);
744 1.1 christos abbrevs->num_abbrevs = 0;
745 1.1 christos abbrevs->abbrevs = NULL;
746 1.1 christos }
747 1.1 christos
748 1.1 christos /* Read an attribute value. Returns 1 on success, 0 on failure. If
749 1.1 christos the value can be represented as a uint64_t, sets *VAL and sets
750 1.1 christos *IS_VALID to 1. We don't try to store the value of other attribute
751 1.1 christos forms, because we don't care about them. */
752 1.1 christos
753 1.1 christos static int
754 1.1 christos read_attribute (enum dwarf_form form, uint64_t implicit_val,
755 1.1 christos struct dwarf_buf *buf, int is_dwarf64, int version,
756 1.1 christos int addrsize, const struct dwarf_sections *dwarf_sections,
757 1.1 christos struct dwarf_data *altlink, struct attr_val *val)
758 1.1 christos {
759 1.1 christos /* Avoid warnings about val.u.FIELD may be used uninitialized if
760 1.1 christos this function is inlined. The warnings aren't valid but can
761 1.1 christos occur because the different fields are set and used
762 1.1 christos conditionally. */
763 1.1 christos memset (val, 0, sizeof *val);
764 1.1 christos
765 1.1 christos switch (form)
766 1.1 christos {
767 1.1 christos case DW_FORM_addr:
768 1.1 christos val->encoding = ATTR_VAL_ADDRESS;
769 1.1 christos val->u.uint = read_address (buf, addrsize);
770 1.1 christos return 1;
771 1.1 christos case DW_FORM_block2:
772 1.1 christos val->encoding = ATTR_VAL_BLOCK;
773 1.1 christos return advance (buf, read_uint16 (buf));
774 1.1 christos case DW_FORM_block4:
775 1.1 christos val->encoding = ATTR_VAL_BLOCK;
776 1.1 christos return advance (buf, read_uint32 (buf));
777 1.1 christos case DW_FORM_data2:
778 1.1 christos val->encoding = ATTR_VAL_UINT;
779 1.1 christos val->u.uint = read_uint16 (buf);
780 1.1 christos return 1;
781 1.1 christos case DW_FORM_data4:
782 1.1 christos val->encoding = ATTR_VAL_UINT;
783 1.1 christos val->u.uint = read_uint32 (buf);
784 1.1 christos return 1;
785 1.1 christos case DW_FORM_data8:
786 1.1 christos val->encoding = ATTR_VAL_UINT;
787 1.1 christos val->u.uint = read_uint64 (buf);
788 1.1 christos return 1;
789 1.1 christos case DW_FORM_data16:
790 1.1 christos val->encoding = ATTR_VAL_BLOCK;
791 1.1 christos return advance (buf, 16);
792 1.1 christos case DW_FORM_string:
793 1.1 christos val->encoding = ATTR_VAL_STRING;
794 1.1 christos val->u.string = read_string (buf);
795 1.1 christos return val->u.string == NULL ? 0 : 1;
796 1.1 christos case DW_FORM_block:
797 1.1 christos val->encoding = ATTR_VAL_BLOCK;
798 1.1 christos return advance (buf, read_uleb128 (buf));
799 1.1 christos case DW_FORM_block1:
800 1.1 christos val->encoding = ATTR_VAL_BLOCK;
801 1.1 christos return advance (buf, read_byte (buf));
802 1.1 christos case DW_FORM_data1:
803 1.1 christos val->encoding = ATTR_VAL_UINT;
804 1.1 christos val->u.uint = read_byte (buf);
805 1.1 christos return 1;
806 1.1 christos case DW_FORM_flag:
807 1.1 christos val->encoding = ATTR_VAL_UINT;
808 1.1 christos val->u.uint = read_byte (buf);
809 1.1 christos return 1;
810 1.1 christos case DW_FORM_sdata:
811 1.1 christos val->encoding = ATTR_VAL_SINT;
812 1.1 christos val->u.sint = read_sleb128 (buf);
813 1.1 christos return 1;
814 1.1 christos case DW_FORM_strp:
815 1.1 christos {
816 1.1 christos uint64_t offset;
817 1.1 christos
818 1.1 christos offset = read_offset (buf, is_dwarf64);
819 1.1 christos if (offset >= dwarf_sections->size[DEBUG_STR])
820 1.1 christos {
821 1.1 christos dwarf_buf_error (buf, "DW_FORM_strp out of range", 0);
822 1.1 christos return 0;
823 1.1 christos }
824 1.1 christos val->encoding = ATTR_VAL_STRING;
825 1.1 christos val->u.string =
826 1.1 christos (const char *) dwarf_sections->data[DEBUG_STR] + offset;
827 1.1 christos return 1;
828 1.1 christos }
829 1.1 christos case DW_FORM_line_strp:
830 1.1 christos {
831 1.1 christos uint64_t offset;
832 1.1 christos
833 1.1 christos offset = read_offset (buf, is_dwarf64);
834 1.1 christos if (offset >= dwarf_sections->size[DEBUG_LINE_STR])
835 1.1 christos {
836 1.1 christos dwarf_buf_error (buf, "DW_FORM_line_strp out of range", 0);
837 1.1 christos return 0;
838 1.1 christos }
839 1.1 christos val->encoding = ATTR_VAL_STRING;
840 1.1 christos val->u.string =
841 1.1 christos (const char *) dwarf_sections->data[DEBUG_LINE_STR] + offset;
842 1.1 christos return 1;
843 1.1 christos }
844 1.1 christos case DW_FORM_udata:
845 1.1 christos val->encoding = ATTR_VAL_UINT;
846 1.1 christos val->u.uint = read_uleb128 (buf);
847 1.1 christos return 1;
848 1.1 christos case DW_FORM_ref_addr:
849 1.1 christos val->encoding = ATTR_VAL_REF_INFO;
850 1.1 christos if (version == 2)
851 1.1 christos val->u.uint = read_address (buf, addrsize);
852 1.1 christos else
853 1.1 christos val->u.uint = read_offset (buf, is_dwarf64);
854 1.1 christos return 1;
855 1.1 christos case DW_FORM_ref1:
856 1.1 christos val->encoding = ATTR_VAL_REF_UNIT;
857 1.1 christos val->u.uint = read_byte (buf);
858 1.1 christos return 1;
859 1.1 christos case DW_FORM_ref2:
860 1.1 christos val->encoding = ATTR_VAL_REF_UNIT;
861 1.1 christos val->u.uint = read_uint16 (buf);
862 1.1 christos return 1;
863 1.1 christos case DW_FORM_ref4:
864 1.1 christos val->encoding = ATTR_VAL_REF_UNIT;
865 1.1 christos val->u.uint = read_uint32 (buf);
866 1.1 christos return 1;
867 1.1 christos case DW_FORM_ref8:
868 1.1 christos val->encoding = ATTR_VAL_REF_UNIT;
869 1.1 christos val->u.uint = read_uint64 (buf);
870 1.1 christos return 1;
871 1.1 christos case DW_FORM_ref_udata:
872 1.1 christos val->encoding = ATTR_VAL_REF_UNIT;
873 1.1 christos val->u.uint = read_uleb128 (buf);
874 1.1 christos return 1;
875 1.1 christos case DW_FORM_indirect:
876 1.1 christos {
877 1.1 christos uint64_t form;
878 1.1 christos
879 1.1 christos form = read_uleb128 (buf);
880 1.1 christos if (form == DW_FORM_implicit_const)
881 1.1 christos {
882 1.1 christos dwarf_buf_error (buf,
883 1.1 christos "DW_FORM_indirect to DW_FORM_implicit_const",
884 1.1 christos 0);
885 1.1 christos return 0;
886 1.1 christos }
887 1.1 christos return read_attribute ((enum dwarf_form) form, 0, buf, is_dwarf64,
888 1.1 christos version, addrsize, dwarf_sections, altlink,
889 1.1 christos val);
890 1.1 christos }
891 1.1 christos case DW_FORM_sec_offset:
892 1.1 christos val->encoding = ATTR_VAL_REF_SECTION;
893 1.1 christos val->u.uint = read_offset (buf, is_dwarf64);
894 1.1 christos return 1;
895 1.1 christos case DW_FORM_exprloc:
896 1.1 christos val->encoding = ATTR_VAL_EXPR;
897 1.1 christos return advance (buf, read_uleb128 (buf));
898 1.1 christos case DW_FORM_flag_present:
899 1.1 christos val->encoding = ATTR_VAL_UINT;
900 1.1 christos val->u.uint = 1;
901 1.1 christos return 1;
902 1.1 christos case DW_FORM_ref_sig8:
903 1.1 christos val->encoding = ATTR_VAL_REF_TYPE;
904 1.1 christos val->u.uint = read_uint64 (buf);
905 1.1 christos return 1;
906 1.1 christos case DW_FORM_strx: case DW_FORM_strx1: case DW_FORM_strx2:
907 1.1 christos case DW_FORM_strx3: case DW_FORM_strx4:
908 1.1 christos {
909 1.1 christos uint64_t offset;
910 1.1 christos
911 1.1 christos switch (form)
912 1.1 christos {
913 1.1 christos case DW_FORM_strx:
914 1.1 christos offset = read_uleb128 (buf);
915 1.1 christos break;
916 1.1 christos case DW_FORM_strx1:
917 1.1 christos offset = read_byte (buf);
918 1.1 christos break;
919 1.1 christos case DW_FORM_strx2:
920 1.1 christos offset = read_uint16 (buf);
921 1.1 christos break;
922 1.1 christos case DW_FORM_strx3:
923 1.1 christos offset = read_uint24 (buf);
924 1.1 christos break;
925 1.1 christos case DW_FORM_strx4:
926 1.1 christos offset = read_uint32 (buf);
927 1.1 christos break;
928 1.1 christos default:
929 1.1 christos /* This case can't happen. */
930 1.1 christos return 0;
931 1.1 christos }
932 1.1 christos val->encoding = ATTR_VAL_STRING_INDEX;
933 1.1 christos val->u.uint = offset;
934 1.1 christos return 1;
935 1.1 christos }
936 1.1 christos case DW_FORM_addrx: case DW_FORM_addrx1: case DW_FORM_addrx2:
937 1.1 christos case DW_FORM_addrx3: case DW_FORM_addrx4:
938 1.1 christos {
939 1.1 christos uint64_t offset;
940 1.1 christos
941 1.1 christos switch (form)
942 1.1 christos {
943 1.1 christos case DW_FORM_addrx:
944 1.1 christos offset = read_uleb128 (buf);
945 1.1 christos break;
946 1.1 christos case DW_FORM_addrx1:
947 1.1 christos offset = read_byte (buf);
948 1.1 christos break;
949 1.1 christos case DW_FORM_addrx2:
950 1.1 christos offset = read_uint16 (buf);
951 1.1 christos break;
952 1.1 christos case DW_FORM_addrx3:
953 1.1 christos offset = read_uint24 (buf);
954 1.1 christos break;
955 1.1 christos case DW_FORM_addrx4:
956 1.1 christos offset = read_uint32 (buf);
957 1.1 christos break;
958 1.1 christos default:
959 1.1 christos /* This case can't happen. */
960 1.1 christos return 0;
961 1.1 christos }
962 1.1 christos val->encoding = ATTR_VAL_ADDRESS_INDEX;
963 1.1 christos val->u.uint = offset;
964 1.1 christos return 1;
965 1.1 christos }
966 1.1 christos case DW_FORM_ref_sup4:
967 1.1 christos val->encoding = ATTR_VAL_REF_SECTION;
968 1.1 christos val->u.uint = read_uint32 (buf);
969 1.1 christos return 1;
970 1.1 christos case DW_FORM_ref_sup8:
971 1.1 christos val->encoding = ATTR_VAL_REF_SECTION;
972 1.1 christos val->u.uint = read_uint64 (buf);
973 1.1 christos return 1;
974 1.1 christos case DW_FORM_implicit_const:
975 1.1 christos val->encoding = ATTR_VAL_UINT;
976 1.1 christos val->u.uint = implicit_val;
977 1.1 christos return 1;
978 1.1 christos case DW_FORM_loclistx:
979 1.1 christos /* We don't distinguish this from DW_FORM_sec_offset. It
980 1.1 christos * shouldn't matter since we don't care about loclists. */
981 1.1 christos val->encoding = ATTR_VAL_REF_SECTION;
982 1.1 christos val->u.uint = read_uleb128 (buf);
983 1.1 christos return 1;
984 1.1 christos case DW_FORM_rnglistx:
985 1.1 christos val->encoding = ATTR_VAL_RNGLISTS_INDEX;
986 1.1 christos val->u.uint = read_uleb128 (buf);
987 1.1 christos return 1;
988 1.1 christos case DW_FORM_GNU_addr_index:
989 1.1 christos val->encoding = ATTR_VAL_REF_SECTION;
990 1.1 christos val->u.uint = read_uleb128 (buf);
991 1.1 christos return 1;
992 1.1 christos case DW_FORM_GNU_str_index:
993 1.1 christos val->encoding = ATTR_VAL_REF_SECTION;
994 1.1 christos val->u.uint = read_uleb128 (buf);
995 1.1 christos return 1;
996 1.1 christos case DW_FORM_GNU_ref_alt:
997 1.1 christos val->u.uint = read_offset (buf, is_dwarf64);
998 1.1 christos if (altlink == NULL)
999 1.1 christos {
1000 1.1 christos val->encoding = ATTR_VAL_NONE;
1001 1.1 christos return 1;
1002 1.1 christos }
1003 1.1 christos val->encoding = ATTR_VAL_REF_ALT_INFO;
1004 1.1 christos return 1;
1005 1.1 christos case DW_FORM_strp_sup: case DW_FORM_GNU_strp_alt:
1006 1.1 christos {
1007 1.1 christos uint64_t offset;
1008 1.1 christos
1009 1.1 christos offset = read_offset (buf, is_dwarf64);
1010 1.1 christos if (altlink == NULL)
1011 1.1 christos {
1012 1.1 christos val->encoding = ATTR_VAL_NONE;
1013 1.1 christos return 1;
1014 1.1 christos }
1015 1.1 christos if (offset >= altlink->dwarf_sections.size[DEBUG_STR])
1016 1.1 christos {
1017 1.1 christos dwarf_buf_error (buf, "DW_FORM_strp_sup out of range", 0);
1018 1.1 christos return 0;
1019 1.1 christos }
1020 1.1 christos val->encoding = ATTR_VAL_STRING;
1021 1.1 christos val->u.string =
1022 1.1 christos (const char *) altlink->dwarf_sections.data[DEBUG_STR] + offset;
1023 1.1 christos return 1;
1024 1.1 christos }
1025 1.1 christos default:
1026 1.1 christos dwarf_buf_error (buf, "unrecognized DWARF form", -1);
1027 1.1 christos return 0;
1028 1.1 christos }
1029 1.1 christos }
1030 1.1 christos
1031 1.1 christos /* If we can determine the value of a string attribute, set *STRING to
1032 1.1 christos point to the string. Return 1 on success, 0 on error. If we don't
1033 1.1 christos know the value, we consider that a success, and we don't change
1034 1.1 christos *STRING. An error is only reported for some sort of out of range
1035 1.1 christos offset. */
1036 1.1 christos
1037 1.1 christos static int
1038 1.1 christos resolve_string (const struct dwarf_sections *dwarf_sections, int is_dwarf64,
1039 1.1 christos int is_bigendian, uint64_t str_offsets_base,
1040 1.1 christos const struct attr_val *val,
1041 1.1 christos backtrace_error_callback error_callback, void *data,
1042 1.1 christos const char **string)
1043 1.1 christos {
1044 1.1 christos switch (val->encoding)
1045 1.1 christos {
1046 1.1 christos case ATTR_VAL_STRING:
1047 1.1 christos *string = val->u.string;
1048 1.1 christos return 1;
1049 1.1 christos
1050 1.1 christos case ATTR_VAL_STRING_INDEX:
1051 1.1 christos {
1052 1.1 christos uint64_t offset;
1053 1.1 christos struct dwarf_buf offset_buf;
1054 1.1 christos
1055 1.1 christos offset = val->u.uint * (is_dwarf64 ? 8 : 4) + str_offsets_base;
1056 1.1 christos if (offset + (is_dwarf64 ? 8 : 4)
1057 1.1 christos > dwarf_sections->size[DEBUG_STR_OFFSETS])
1058 1.1 christos {
1059 1.1 christos error_callback (data, "DW_FORM_strx value out of range", 0);
1060 1.1 christos return 0;
1061 1.1 christos }
1062 1.1 christos
1063 1.1 christos offset_buf.name = ".debug_str_offsets";
1064 1.1 christos offset_buf.start = dwarf_sections->data[DEBUG_STR_OFFSETS];
1065 1.1 christos offset_buf.buf = dwarf_sections->data[DEBUG_STR_OFFSETS] + offset;
1066 1.1 christos offset_buf.left = dwarf_sections->size[DEBUG_STR_OFFSETS] - offset;
1067 1.1 christos offset_buf.is_bigendian = is_bigendian;
1068 1.1 christos offset_buf.error_callback = error_callback;
1069 1.1 christos offset_buf.data = data;
1070 1.1 christos offset_buf.reported_underflow = 0;
1071 1.1 christos
1072 1.1 christos offset = read_offset (&offset_buf, is_dwarf64);
1073 1.1 christos if (offset >= dwarf_sections->size[DEBUG_STR])
1074 1.1 christos {
1075 1.1 christos dwarf_buf_error (&offset_buf,
1076 1.1 christos "DW_FORM_strx offset out of range",
1077 1.1 christos 0);
1078 1.1 christos return 0;
1079 1.1 christos }
1080 1.1 christos *string = (const char *) dwarf_sections->data[DEBUG_STR] + offset;
1081 1.1 christos return 1;
1082 1.1 christos }
1083 1.1 christos
1084 1.1 christos default:
1085 1.1 christos return 1;
1086 1.1 christos }
1087 1.1 christos }
1088 1.1 christos
1089 1.1 christos /* Set *ADDRESS to the real address for a ATTR_VAL_ADDRESS_INDEX.
1090 1.1 christos Return 1 on success, 0 on error. */
1091 1.1 christos
1092 1.1 christos static int
1093 1.1 christos resolve_addr_index (const struct dwarf_sections *dwarf_sections,
1094 1.1 christos uint64_t addr_base, int addrsize, int is_bigendian,
1095 1.1 christos uint64_t addr_index,
1096 1.1 christos backtrace_error_callback error_callback, void *data,
1097 1.1.1.1.2.1 perseant uintptr_t *address)
1098 1.1 christos {
1099 1.1 christos uint64_t offset;
1100 1.1 christos struct dwarf_buf addr_buf;
1101 1.1 christos
1102 1.1 christos offset = addr_index * addrsize + addr_base;
1103 1.1 christos if (offset + addrsize > dwarf_sections->size[DEBUG_ADDR])
1104 1.1 christos {
1105 1.1 christos error_callback (data, "DW_FORM_addrx value out of range", 0);
1106 1.1 christos return 0;
1107 1.1 christos }
1108 1.1 christos
1109 1.1 christos addr_buf.name = ".debug_addr";
1110 1.1 christos addr_buf.start = dwarf_sections->data[DEBUG_ADDR];
1111 1.1 christos addr_buf.buf = dwarf_sections->data[DEBUG_ADDR] + offset;
1112 1.1 christos addr_buf.left = dwarf_sections->size[DEBUG_ADDR] - offset;
1113 1.1 christos addr_buf.is_bigendian = is_bigendian;
1114 1.1 christos addr_buf.error_callback = error_callback;
1115 1.1 christos addr_buf.data = data;
1116 1.1 christos addr_buf.reported_underflow = 0;
1117 1.1 christos
1118 1.1.1.1.2.1 perseant *address = (uintptr_t) read_address (&addr_buf, addrsize);
1119 1.1 christos return 1;
1120 1.1 christos }
1121 1.1 christos
1122 1.1 christos /* Compare a unit offset against a unit for bsearch. */
1123 1.1 christos
1124 1.1 christos static int
1125 1.1 christos units_search (const void *vkey, const void *ventry)
1126 1.1 christos {
1127 1.1 christos const size_t *key = (const size_t *) vkey;
1128 1.1 christos const struct unit *entry = *((const struct unit *const *) ventry);
1129 1.1 christos size_t offset;
1130 1.1 christos
1131 1.1 christos offset = *key;
1132 1.1 christos if (offset < entry->low_offset)
1133 1.1 christos return -1;
1134 1.1 christos else if (offset >= entry->high_offset)
1135 1.1 christos return 1;
1136 1.1 christos else
1137 1.1 christos return 0;
1138 1.1 christos }
1139 1.1 christos
1140 1.1 christos /* Find a unit in PU containing OFFSET. */
1141 1.1 christos
1142 1.1 christos static struct unit *
1143 1.1 christos find_unit (struct unit **pu, size_t units_count, size_t offset)
1144 1.1 christos {
1145 1.1 christos struct unit **u;
1146 1.1 christos u = bsearch (&offset, pu, units_count, sizeof (struct unit *), units_search);
1147 1.1 christos return u == NULL ? NULL : *u;
1148 1.1 christos }
1149 1.1 christos
1150 1.1 christos /* Compare function_addrs for qsort. When ranges are nested, make the
1151 1.1 christos smallest one sort last. */
1152 1.1 christos
1153 1.1 christos static int
1154 1.1 christos function_addrs_compare (const void *v1, const void *v2)
1155 1.1 christos {
1156 1.1 christos const struct function_addrs *a1 = (const struct function_addrs *) v1;
1157 1.1 christos const struct function_addrs *a2 = (const struct function_addrs *) v2;
1158 1.1 christos
1159 1.1 christos if (a1->low < a2->low)
1160 1.1 christos return -1;
1161 1.1 christos if (a1->low > a2->low)
1162 1.1 christos return 1;
1163 1.1 christos if (a1->high < a2->high)
1164 1.1 christos return 1;
1165 1.1 christos if (a1->high > a2->high)
1166 1.1 christos return -1;
1167 1.1 christos return strcmp (a1->function->name, a2->function->name);
1168 1.1 christos }
1169 1.1 christos
1170 1.1 christos /* Compare a PC against a function_addrs for bsearch. We always
1171 1.1 christos allocate an entra entry at the end of the vector, so that this
1172 1.1 christos routine can safely look at the next entry. Note that if there are
1173 1.1 christos multiple ranges containing PC, which one will be returned is
1174 1.1 christos unpredictable. We compensate for that in dwarf_fileline. */
1175 1.1 christos
1176 1.1 christos static int
1177 1.1 christos function_addrs_search (const void *vkey, const void *ventry)
1178 1.1 christos {
1179 1.1 christos const uintptr_t *key = (const uintptr_t *) vkey;
1180 1.1 christos const struct function_addrs *entry = (const struct function_addrs *) ventry;
1181 1.1 christos uintptr_t pc;
1182 1.1 christos
1183 1.1 christos pc = *key;
1184 1.1 christos if (pc < entry->low)
1185 1.1 christos return -1;
1186 1.1 christos else if (pc > (entry + 1)->low)
1187 1.1 christos return 1;
1188 1.1 christos else
1189 1.1 christos return 0;
1190 1.1 christos }
1191 1.1 christos
1192 1.1 christos /* Add a new compilation unit address range to a vector. This is
1193 1.1 christos called via add_ranges. Returns 1 on success, 0 on failure. */
1194 1.1 christos
1195 1.1 christos static int
1196 1.1 christos add_unit_addr (struct backtrace_state *state, void *rdata,
1197 1.1.1.1.2.1 perseant uintptr_t lowpc, uintptr_t highpc,
1198 1.1 christos backtrace_error_callback error_callback, void *data,
1199 1.1 christos void *pvec)
1200 1.1 christos {
1201 1.1 christos struct unit *u = (struct unit *) rdata;
1202 1.1 christos struct unit_addrs_vector *vec = (struct unit_addrs_vector *) pvec;
1203 1.1 christos struct unit_addrs *p;
1204 1.1 christos
1205 1.1 christos /* Try to merge with the last entry. */
1206 1.1 christos if (vec->count > 0)
1207 1.1 christos {
1208 1.1 christos p = (struct unit_addrs *) vec->vec.base + (vec->count - 1);
1209 1.1 christos if ((lowpc == p->high || lowpc == p->high + 1)
1210 1.1 christos && u == p->u)
1211 1.1 christos {
1212 1.1 christos if (highpc > p->high)
1213 1.1 christos p->high = highpc;
1214 1.1 christos return 1;
1215 1.1 christos }
1216 1.1 christos }
1217 1.1 christos
1218 1.1 christos p = ((struct unit_addrs *)
1219 1.1 christos backtrace_vector_grow (state, sizeof (struct unit_addrs),
1220 1.1 christos error_callback, data, &vec->vec));
1221 1.1 christos if (p == NULL)
1222 1.1 christos return 0;
1223 1.1 christos
1224 1.1 christos p->low = lowpc;
1225 1.1 christos p->high = highpc;
1226 1.1 christos p->u = u;
1227 1.1 christos
1228 1.1 christos ++vec->count;
1229 1.1 christos
1230 1.1 christos return 1;
1231 1.1 christos }
1232 1.1 christos
1233 1.1 christos /* Compare unit_addrs for qsort. When ranges are nested, make the
1234 1.1 christos smallest one sort last. */
1235 1.1 christos
1236 1.1 christos static int
1237 1.1 christos unit_addrs_compare (const void *v1, const void *v2)
1238 1.1 christos {
1239 1.1 christos const struct unit_addrs *a1 = (const struct unit_addrs *) v1;
1240 1.1 christos const struct unit_addrs *a2 = (const struct unit_addrs *) v2;
1241 1.1 christos
1242 1.1 christos if (a1->low < a2->low)
1243 1.1 christos return -1;
1244 1.1 christos if (a1->low > a2->low)
1245 1.1 christos return 1;
1246 1.1 christos if (a1->high < a2->high)
1247 1.1 christos return 1;
1248 1.1 christos if (a1->high > a2->high)
1249 1.1 christos return -1;
1250 1.1 christos if (a1->u->lineoff < a2->u->lineoff)
1251 1.1 christos return -1;
1252 1.1 christos if (a1->u->lineoff > a2->u->lineoff)
1253 1.1 christos return 1;
1254 1.1 christos return 0;
1255 1.1 christos }
1256 1.1 christos
1257 1.1 christos /* Compare a PC against a unit_addrs for bsearch. We always allocate
1258 1.1 christos an entry entry at the end of the vector, so that this routine can
1259 1.1 christos safely look at the next entry. Note that if there are multiple
1260 1.1 christos ranges containing PC, which one will be returned is unpredictable.
1261 1.1 christos We compensate for that in dwarf_fileline. */
1262 1.1 christos
1263 1.1 christos static int
1264 1.1 christos unit_addrs_search (const void *vkey, const void *ventry)
1265 1.1 christos {
1266 1.1 christos const uintptr_t *key = (const uintptr_t *) vkey;
1267 1.1 christos const struct unit_addrs *entry = (const struct unit_addrs *) ventry;
1268 1.1 christos uintptr_t pc;
1269 1.1 christos
1270 1.1 christos pc = *key;
1271 1.1 christos if (pc < entry->low)
1272 1.1 christos return -1;
1273 1.1 christos else if (pc > (entry + 1)->low)
1274 1.1 christos return 1;
1275 1.1 christos else
1276 1.1 christos return 0;
1277 1.1 christos }
1278 1.1 christos
1279 1.1 christos /* Sort the line vector by PC. We want a stable sort here to maintain
1280 1.1 christos the order of lines for the same PC values. Since the sequence is
1281 1.1 christos being sorted in place, their addresses cannot be relied on to
1282 1.1 christos maintain stability. That is the purpose of the index member. */
1283 1.1 christos
1284 1.1 christos static int
1285 1.1 christos line_compare (const void *v1, const void *v2)
1286 1.1 christos {
1287 1.1 christos const struct line *ln1 = (const struct line *) v1;
1288 1.1 christos const struct line *ln2 = (const struct line *) v2;
1289 1.1 christos
1290 1.1 christos if (ln1->pc < ln2->pc)
1291 1.1 christos return -1;
1292 1.1 christos else if (ln1->pc > ln2->pc)
1293 1.1 christos return 1;
1294 1.1 christos else if (ln1->idx < ln2->idx)
1295 1.1 christos return -1;
1296 1.1 christos else if (ln1->idx > ln2->idx)
1297 1.1 christos return 1;
1298 1.1 christos else
1299 1.1 christos return 0;
1300 1.1 christos }
1301 1.1 christos
1302 1.1 christos /* Find a PC in a line vector. We always allocate an extra entry at
1303 1.1 christos the end of the lines vector, so that this routine can safely look
1304 1.1 christos at the next entry. Note that when there are multiple mappings for
1305 1.1 christos the same PC value, this will return the last one. */
1306 1.1 christos
1307 1.1 christos static int
1308 1.1 christos line_search (const void *vkey, const void *ventry)
1309 1.1 christos {
1310 1.1 christos const uintptr_t *key = (const uintptr_t *) vkey;
1311 1.1 christos const struct line *entry = (const struct line *) ventry;
1312 1.1 christos uintptr_t pc;
1313 1.1 christos
1314 1.1 christos pc = *key;
1315 1.1 christos if (pc < entry->pc)
1316 1.1 christos return -1;
1317 1.1 christos else if (pc >= (entry + 1)->pc)
1318 1.1 christos return 1;
1319 1.1 christos else
1320 1.1 christos return 0;
1321 1.1 christos }
1322 1.1 christos
1323 1.1 christos /* Sort the abbrevs by the abbrev code. This function is passed to
1324 1.1 christos both qsort and bsearch. */
1325 1.1 christos
1326 1.1 christos static int
1327 1.1 christos abbrev_compare (const void *v1, const void *v2)
1328 1.1 christos {
1329 1.1 christos const struct abbrev *a1 = (const struct abbrev *) v1;
1330 1.1 christos const struct abbrev *a2 = (const struct abbrev *) v2;
1331 1.1 christos
1332 1.1 christos if (a1->code < a2->code)
1333 1.1 christos return -1;
1334 1.1 christos else if (a1->code > a2->code)
1335 1.1 christos return 1;
1336 1.1 christos else
1337 1.1 christos {
1338 1.1 christos /* This really shouldn't happen. It means there are two
1339 1.1 christos different abbrevs with the same code, and that means we don't
1340 1.1 christos know which one lookup_abbrev should return. */
1341 1.1 christos return 0;
1342 1.1 christos }
1343 1.1 christos }
1344 1.1 christos
1345 1.1 christos /* Read the abbreviation table for a compilation unit. Returns 1 on
1346 1.1 christos success, 0 on failure. */
1347 1.1 christos
1348 1.1 christos static int
1349 1.1 christos read_abbrevs (struct backtrace_state *state, uint64_t abbrev_offset,
1350 1.1 christos const unsigned char *dwarf_abbrev, size_t dwarf_abbrev_size,
1351 1.1 christos int is_bigendian, backtrace_error_callback error_callback,
1352 1.1 christos void *data, struct abbrevs *abbrevs)
1353 1.1 christos {
1354 1.1 christos struct dwarf_buf abbrev_buf;
1355 1.1 christos struct dwarf_buf count_buf;
1356 1.1 christos size_t num_abbrevs;
1357 1.1 christos
1358 1.1 christos abbrevs->num_abbrevs = 0;
1359 1.1 christos abbrevs->abbrevs = NULL;
1360 1.1 christos
1361 1.1 christos if (abbrev_offset >= dwarf_abbrev_size)
1362 1.1 christos {
1363 1.1 christos error_callback (data, "abbrev offset out of range", 0);
1364 1.1 christos return 0;
1365 1.1 christos }
1366 1.1 christos
1367 1.1 christos abbrev_buf.name = ".debug_abbrev";
1368 1.1 christos abbrev_buf.start = dwarf_abbrev;
1369 1.1 christos abbrev_buf.buf = dwarf_abbrev + abbrev_offset;
1370 1.1 christos abbrev_buf.left = dwarf_abbrev_size - abbrev_offset;
1371 1.1 christos abbrev_buf.is_bigendian = is_bigendian;
1372 1.1 christos abbrev_buf.error_callback = error_callback;
1373 1.1 christos abbrev_buf.data = data;
1374 1.1 christos abbrev_buf.reported_underflow = 0;
1375 1.1 christos
1376 1.1 christos /* Count the number of abbrevs in this list. */
1377 1.1 christos
1378 1.1 christos count_buf = abbrev_buf;
1379 1.1 christos num_abbrevs = 0;
1380 1.1 christos while (read_uleb128 (&count_buf) != 0)
1381 1.1 christos {
1382 1.1 christos if (count_buf.reported_underflow)
1383 1.1 christos return 0;
1384 1.1 christos ++num_abbrevs;
1385 1.1 christos // Skip tag.
1386 1.1 christos read_uleb128 (&count_buf);
1387 1.1 christos // Skip has_children.
1388 1.1 christos read_byte (&count_buf);
1389 1.1 christos // Skip attributes.
1390 1.1 christos while (read_uleb128 (&count_buf) != 0)
1391 1.1 christos {
1392 1.1 christos uint64_t form;
1393 1.1 christos
1394 1.1 christos form = read_uleb128 (&count_buf);
1395 1.1 christos if ((enum dwarf_form) form == DW_FORM_implicit_const)
1396 1.1 christos read_sleb128 (&count_buf);
1397 1.1 christos }
1398 1.1 christos // Skip form of last attribute.
1399 1.1 christos read_uleb128 (&count_buf);
1400 1.1 christos }
1401 1.1 christos
1402 1.1 christos if (count_buf.reported_underflow)
1403 1.1 christos return 0;
1404 1.1 christos
1405 1.1 christos if (num_abbrevs == 0)
1406 1.1 christos return 1;
1407 1.1 christos
1408 1.1 christos abbrevs->abbrevs = ((struct abbrev *)
1409 1.1 christos backtrace_alloc (state,
1410 1.1 christos num_abbrevs * sizeof (struct abbrev),
1411 1.1 christos error_callback, data));
1412 1.1 christos if (abbrevs->abbrevs == NULL)
1413 1.1 christos return 0;
1414 1.1 christos abbrevs->num_abbrevs = num_abbrevs;
1415 1.1 christos memset (abbrevs->abbrevs, 0, num_abbrevs * sizeof (struct abbrev));
1416 1.1 christos
1417 1.1 christos num_abbrevs = 0;
1418 1.1 christos while (1)
1419 1.1 christos {
1420 1.1 christos uint64_t code;
1421 1.1 christos struct abbrev a;
1422 1.1 christos size_t num_attrs;
1423 1.1 christos struct attr *attrs;
1424 1.1 christos
1425 1.1 christos if (abbrev_buf.reported_underflow)
1426 1.1 christos goto fail;
1427 1.1 christos
1428 1.1 christos code = read_uleb128 (&abbrev_buf);
1429 1.1 christos if (code == 0)
1430 1.1 christos break;
1431 1.1 christos
1432 1.1 christos a.code = code;
1433 1.1 christos a.tag = (enum dwarf_tag) read_uleb128 (&abbrev_buf);
1434 1.1 christos a.has_children = read_byte (&abbrev_buf);
1435 1.1 christos
1436 1.1 christos count_buf = abbrev_buf;
1437 1.1 christos num_attrs = 0;
1438 1.1 christos while (read_uleb128 (&count_buf) != 0)
1439 1.1 christos {
1440 1.1 christos uint64_t form;
1441 1.1 christos
1442 1.1 christos ++num_attrs;
1443 1.1 christos form = read_uleb128 (&count_buf);
1444 1.1 christos if ((enum dwarf_form) form == DW_FORM_implicit_const)
1445 1.1 christos read_sleb128 (&count_buf);
1446 1.1 christos }
1447 1.1 christos
1448 1.1 christos if (num_attrs == 0)
1449 1.1 christos {
1450 1.1 christos attrs = NULL;
1451 1.1 christos read_uleb128 (&abbrev_buf);
1452 1.1 christos read_uleb128 (&abbrev_buf);
1453 1.1 christos }
1454 1.1 christos else
1455 1.1 christos {
1456 1.1 christos attrs = ((struct attr *)
1457 1.1 christos backtrace_alloc (state, num_attrs * sizeof *attrs,
1458 1.1 christos error_callback, data));
1459 1.1 christos if (attrs == NULL)
1460 1.1 christos goto fail;
1461 1.1 christos num_attrs = 0;
1462 1.1 christos while (1)
1463 1.1 christos {
1464 1.1 christos uint64_t name;
1465 1.1 christos uint64_t form;
1466 1.1 christos
1467 1.1 christos name = read_uleb128 (&abbrev_buf);
1468 1.1 christos form = read_uleb128 (&abbrev_buf);
1469 1.1 christos if (name == 0)
1470 1.1 christos break;
1471 1.1 christos attrs[num_attrs].name = (enum dwarf_attribute) name;
1472 1.1 christos attrs[num_attrs].form = (enum dwarf_form) form;
1473 1.1 christos if ((enum dwarf_form) form == DW_FORM_implicit_const)
1474 1.1 christos attrs[num_attrs].val = read_sleb128 (&abbrev_buf);
1475 1.1 christos else
1476 1.1 christos attrs[num_attrs].val = 0;
1477 1.1 christos ++num_attrs;
1478 1.1 christos }
1479 1.1 christos }
1480 1.1 christos
1481 1.1 christos a.num_attrs = num_attrs;
1482 1.1 christos a.attrs = attrs;
1483 1.1 christos
1484 1.1 christos abbrevs->abbrevs[num_abbrevs] = a;
1485 1.1 christos ++num_abbrevs;
1486 1.1 christos }
1487 1.1 christos
1488 1.1 christos backtrace_qsort (abbrevs->abbrevs, abbrevs->num_abbrevs,
1489 1.1 christos sizeof (struct abbrev), abbrev_compare);
1490 1.1 christos
1491 1.1 christos return 1;
1492 1.1 christos
1493 1.1 christos fail:
1494 1.1 christos free_abbrevs (state, abbrevs, error_callback, data);
1495 1.1 christos return 0;
1496 1.1 christos }
1497 1.1 christos
1498 1.1 christos /* Return the abbrev information for an abbrev code. */
1499 1.1 christos
1500 1.1 christos static const struct abbrev *
1501 1.1 christos lookup_abbrev (struct abbrevs *abbrevs, uint64_t code,
1502 1.1 christos backtrace_error_callback error_callback, void *data)
1503 1.1 christos {
1504 1.1 christos struct abbrev key;
1505 1.1 christos void *p;
1506 1.1 christos
1507 1.1 christos /* With GCC, where abbrevs are simply numbered in order, we should
1508 1.1 christos be able to just look up the entry. */
1509 1.1 christos if (code - 1 < abbrevs->num_abbrevs
1510 1.1 christos && abbrevs->abbrevs[code - 1].code == code)
1511 1.1 christos return &abbrevs->abbrevs[code - 1];
1512 1.1 christos
1513 1.1 christos /* Otherwise we have to search. */
1514 1.1 christos memset (&key, 0, sizeof key);
1515 1.1 christos key.code = code;
1516 1.1 christos p = bsearch (&key, abbrevs->abbrevs, abbrevs->num_abbrevs,
1517 1.1 christos sizeof (struct abbrev), abbrev_compare);
1518 1.1 christos if (p == NULL)
1519 1.1 christos {
1520 1.1 christos error_callback (data, "invalid abbreviation code", 0);
1521 1.1 christos return NULL;
1522 1.1 christos }
1523 1.1 christos return (const struct abbrev *) p;
1524 1.1 christos }
1525 1.1 christos
1526 1.1 christos /* This struct is used to gather address range information while
1527 1.1 christos reading attributes. We use this while building a mapping from
1528 1.1 christos address ranges to compilation units and then again while mapping
1529 1.1 christos from address ranges to function entries. Normally either
1530 1.1 christos lowpc/highpc is set or ranges is set. */
1531 1.1 christos
1532 1.1 christos struct pcrange {
1533 1.1.1.1.2.1 perseant uintptr_t lowpc; /* The low PC value. */
1534 1.1 christos int have_lowpc; /* Whether a low PC value was found. */
1535 1.1 christos int lowpc_is_addr_index; /* Whether lowpc is in .debug_addr. */
1536 1.1.1.1.2.1 perseant uintptr_t highpc; /* The high PC value. */
1537 1.1 christos int have_highpc; /* Whether a high PC value was found. */
1538 1.1 christos int highpc_is_relative; /* Whether highpc is relative to lowpc. */
1539 1.1 christos int highpc_is_addr_index; /* Whether highpc is in .debug_addr. */
1540 1.1 christos uint64_t ranges; /* Offset in ranges section. */
1541 1.1 christos int have_ranges; /* Whether ranges is valid. */
1542 1.1 christos int ranges_is_index; /* Whether ranges is DW_FORM_rnglistx. */
1543 1.1 christos };
1544 1.1 christos
1545 1.1 christos /* Update PCRANGE from an attribute value. */
1546 1.1 christos
1547 1.1 christos static void
1548 1.1 christos update_pcrange (const struct attr* attr, const struct attr_val* val,
1549 1.1 christos struct pcrange *pcrange)
1550 1.1 christos {
1551 1.1 christos switch (attr->name)
1552 1.1 christos {
1553 1.1 christos case DW_AT_low_pc:
1554 1.1 christos if (val->encoding == ATTR_VAL_ADDRESS)
1555 1.1 christos {
1556 1.1.1.1.2.1 perseant pcrange->lowpc = (uintptr_t) val->u.uint;
1557 1.1 christos pcrange->have_lowpc = 1;
1558 1.1 christos }
1559 1.1 christos else if (val->encoding == ATTR_VAL_ADDRESS_INDEX)
1560 1.1 christos {
1561 1.1.1.1.2.1 perseant pcrange->lowpc = (uintptr_t) val->u.uint;
1562 1.1 christos pcrange->have_lowpc = 1;
1563 1.1 christos pcrange->lowpc_is_addr_index = 1;
1564 1.1 christos }
1565 1.1 christos break;
1566 1.1 christos
1567 1.1 christos case DW_AT_high_pc:
1568 1.1 christos if (val->encoding == ATTR_VAL_ADDRESS)
1569 1.1 christos {
1570 1.1.1.1.2.1 perseant pcrange->highpc = (uintptr_t) val->u.uint;
1571 1.1 christos pcrange->have_highpc = 1;
1572 1.1 christos }
1573 1.1 christos else if (val->encoding == ATTR_VAL_UINT)
1574 1.1 christos {
1575 1.1.1.1.2.1 perseant pcrange->highpc = (uintptr_t) val->u.uint;
1576 1.1 christos pcrange->have_highpc = 1;
1577 1.1 christos pcrange->highpc_is_relative = 1;
1578 1.1 christos }
1579 1.1 christos else if (val->encoding == ATTR_VAL_ADDRESS_INDEX)
1580 1.1 christos {
1581 1.1.1.1.2.1 perseant pcrange->highpc = (uintptr_t) val->u.uint;
1582 1.1 christos pcrange->have_highpc = 1;
1583 1.1 christos pcrange->highpc_is_addr_index = 1;
1584 1.1 christos }
1585 1.1 christos break;
1586 1.1 christos
1587 1.1 christos case DW_AT_ranges:
1588 1.1 christos if (val->encoding == ATTR_VAL_UINT
1589 1.1 christos || val->encoding == ATTR_VAL_REF_SECTION)
1590 1.1 christos {
1591 1.1 christos pcrange->ranges = val->u.uint;
1592 1.1 christos pcrange->have_ranges = 1;
1593 1.1 christos }
1594 1.1 christos else if (val->encoding == ATTR_VAL_RNGLISTS_INDEX)
1595 1.1 christos {
1596 1.1 christos pcrange->ranges = val->u.uint;
1597 1.1 christos pcrange->have_ranges = 1;
1598 1.1 christos pcrange->ranges_is_index = 1;
1599 1.1 christos }
1600 1.1 christos break;
1601 1.1 christos
1602 1.1 christos default:
1603 1.1 christos break;
1604 1.1 christos }
1605 1.1 christos }
1606 1.1 christos
1607 1.1 christos /* Call ADD_RANGE for a low/high PC pair. Returns 1 on success, 0 on
1608 1.1 christos error. */
1609 1.1 christos
1610 1.1 christos static int
1611 1.1 christos add_low_high_range (struct backtrace_state *state,
1612 1.1 christos const struct dwarf_sections *dwarf_sections,
1613 1.1 christos uintptr_t base_address, int is_bigendian,
1614 1.1 christos struct unit *u, const struct pcrange *pcrange,
1615 1.1 christos int (*add_range) (struct backtrace_state *state,
1616 1.1.1.1.2.1 perseant void *rdata, uintptr_t lowpc,
1617 1.1.1.1.2.1 perseant uintptr_t highpc,
1618 1.1 christos backtrace_error_callback error_callback,
1619 1.1 christos void *data, void *vec),
1620 1.1 christos void *rdata,
1621 1.1 christos backtrace_error_callback error_callback, void *data,
1622 1.1 christos void *vec)
1623 1.1 christos {
1624 1.1.1.1.2.1 perseant uintptr_t lowpc;
1625 1.1.1.1.2.1 perseant uintptr_t highpc;
1626 1.1 christos
1627 1.1 christos lowpc = pcrange->lowpc;
1628 1.1 christos if (pcrange->lowpc_is_addr_index)
1629 1.1 christos {
1630 1.1 christos if (!resolve_addr_index (dwarf_sections, u->addr_base, u->addrsize,
1631 1.1 christos is_bigendian, lowpc, error_callback, data,
1632 1.1 christos &lowpc))
1633 1.1 christos return 0;
1634 1.1 christos }
1635 1.1 christos
1636 1.1 christos highpc = pcrange->highpc;
1637 1.1 christos if (pcrange->highpc_is_addr_index)
1638 1.1 christos {
1639 1.1 christos if (!resolve_addr_index (dwarf_sections, u->addr_base, u->addrsize,
1640 1.1 christos is_bigendian, highpc, error_callback, data,
1641 1.1 christos &highpc))
1642 1.1 christos return 0;
1643 1.1 christos }
1644 1.1 christos if (pcrange->highpc_is_relative)
1645 1.1 christos highpc += lowpc;
1646 1.1 christos
1647 1.1 christos /* Add in the base address of the module when recording PC values,
1648 1.1 christos so that we can look up the PC directly. */
1649 1.1 christos lowpc += base_address;
1650 1.1 christos highpc += base_address;
1651 1.1 christos
1652 1.1 christos return add_range (state, rdata, lowpc, highpc, error_callback, data, vec);
1653 1.1 christos }
1654 1.1 christos
1655 1.1 christos /* Call ADD_RANGE for each range read from .debug_ranges, as used in
1656 1.1 christos DWARF versions 2 through 4. */
1657 1.1 christos
1658 1.1 christos static int
1659 1.1 christos add_ranges_from_ranges (
1660 1.1 christos struct backtrace_state *state,
1661 1.1 christos const struct dwarf_sections *dwarf_sections,
1662 1.1 christos uintptr_t base_address, int is_bigendian,
1663 1.1.1.1.2.1 perseant struct unit *u, uintptr_t base,
1664 1.1 christos const struct pcrange *pcrange,
1665 1.1 christos int (*add_range) (struct backtrace_state *state, void *rdata,
1666 1.1.1.1.2.1 perseant uintptr_t lowpc, uintptr_t highpc,
1667 1.1 christos backtrace_error_callback error_callback, void *data,
1668 1.1 christos void *vec),
1669 1.1 christos void *rdata,
1670 1.1 christos backtrace_error_callback error_callback, void *data,
1671 1.1 christos void *vec)
1672 1.1 christos {
1673 1.1 christos struct dwarf_buf ranges_buf;
1674 1.1 christos
1675 1.1 christos if (pcrange->ranges >= dwarf_sections->size[DEBUG_RANGES])
1676 1.1 christos {
1677 1.1 christos error_callback (data, "ranges offset out of range", 0);
1678 1.1 christos return 0;
1679 1.1 christos }
1680 1.1 christos
1681 1.1 christos ranges_buf.name = ".debug_ranges";
1682 1.1 christos ranges_buf.start = dwarf_sections->data[DEBUG_RANGES];
1683 1.1 christos ranges_buf.buf = dwarf_sections->data[DEBUG_RANGES] + pcrange->ranges;
1684 1.1 christos ranges_buf.left = dwarf_sections->size[DEBUG_RANGES] - pcrange->ranges;
1685 1.1 christos ranges_buf.is_bigendian = is_bigendian;
1686 1.1 christos ranges_buf.error_callback = error_callback;
1687 1.1 christos ranges_buf.data = data;
1688 1.1 christos ranges_buf.reported_underflow = 0;
1689 1.1 christos
1690 1.1 christos while (1)
1691 1.1 christos {
1692 1.1 christos uint64_t low;
1693 1.1 christos uint64_t high;
1694 1.1 christos
1695 1.1 christos if (ranges_buf.reported_underflow)
1696 1.1 christos return 0;
1697 1.1 christos
1698 1.1 christos low = read_address (&ranges_buf, u->addrsize);
1699 1.1 christos high = read_address (&ranges_buf, u->addrsize);
1700 1.1 christos
1701 1.1 christos if (low == 0 && high == 0)
1702 1.1 christos break;
1703 1.1 christos
1704 1.1 christos if (is_highest_address (low, u->addrsize))
1705 1.1.1.1.2.1 perseant base = (uintptr_t) high;
1706 1.1 christos else
1707 1.1 christos {
1708 1.1 christos if (!add_range (state, rdata,
1709 1.1.1.1.2.1 perseant (uintptr_t) low + base + base_address,
1710 1.1.1.1.2.1 perseant (uintptr_t) high + base + base_address,
1711 1.1 christos error_callback, data, vec))
1712 1.1 christos return 0;
1713 1.1 christos }
1714 1.1 christos }
1715 1.1 christos
1716 1.1 christos if (ranges_buf.reported_underflow)
1717 1.1 christos return 0;
1718 1.1 christos
1719 1.1 christos return 1;
1720 1.1 christos }
1721 1.1 christos
1722 1.1 christos /* Call ADD_RANGE for each range read from .debug_rnglists, as used in
1723 1.1 christos DWARF version 5. */
1724 1.1 christos
1725 1.1 christos static int
1726 1.1 christos add_ranges_from_rnglists (
1727 1.1 christos struct backtrace_state *state,
1728 1.1 christos const struct dwarf_sections *dwarf_sections,
1729 1.1 christos uintptr_t base_address, int is_bigendian,
1730 1.1.1.1.2.1 perseant struct unit *u, uintptr_t base,
1731 1.1 christos const struct pcrange *pcrange,
1732 1.1 christos int (*add_range) (struct backtrace_state *state, void *rdata,
1733 1.1.1.1.2.1 perseant uintptr_t lowpc, uintptr_t highpc,
1734 1.1 christos backtrace_error_callback error_callback, void *data,
1735 1.1 christos void *vec),
1736 1.1 christos void *rdata,
1737 1.1 christos backtrace_error_callback error_callback, void *data,
1738 1.1 christos void *vec)
1739 1.1 christos {
1740 1.1 christos uint64_t offset;
1741 1.1 christos struct dwarf_buf rnglists_buf;
1742 1.1 christos
1743 1.1 christos if (!pcrange->ranges_is_index)
1744 1.1 christos offset = pcrange->ranges;
1745 1.1 christos else
1746 1.1 christos offset = u->rnglists_base + pcrange->ranges * (u->is_dwarf64 ? 8 : 4);
1747 1.1 christos if (offset >= dwarf_sections->size[DEBUG_RNGLISTS])
1748 1.1 christos {
1749 1.1 christos error_callback (data, "rnglists offset out of range", 0);
1750 1.1 christos return 0;
1751 1.1 christos }
1752 1.1 christos
1753 1.1 christos rnglists_buf.name = ".debug_rnglists";
1754 1.1 christos rnglists_buf.start = dwarf_sections->data[DEBUG_RNGLISTS];
1755 1.1 christos rnglists_buf.buf = dwarf_sections->data[DEBUG_RNGLISTS] + offset;
1756 1.1 christos rnglists_buf.left = dwarf_sections->size[DEBUG_RNGLISTS] - offset;
1757 1.1 christos rnglists_buf.is_bigendian = is_bigendian;
1758 1.1 christos rnglists_buf.error_callback = error_callback;
1759 1.1 christos rnglists_buf.data = data;
1760 1.1 christos rnglists_buf.reported_underflow = 0;
1761 1.1 christos
1762 1.1 christos if (pcrange->ranges_is_index)
1763 1.1 christos {
1764 1.1 christos offset = read_offset (&rnglists_buf, u->is_dwarf64);
1765 1.1 christos offset += u->rnglists_base;
1766 1.1 christos if (offset >= dwarf_sections->size[DEBUG_RNGLISTS])
1767 1.1 christos {
1768 1.1 christos error_callback (data, "rnglists index offset out of range", 0);
1769 1.1 christos return 0;
1770 1.1 christos }
1771 1.1 christos rnglists_buf.buf = dwarf_sections->data[DEBUG_RNGLISTS] + offset;
1772 1.1 christos rnglists_buf.left = dwarf_sections->size[DEBUG_RNGLISTS] - offset;
1773 1.1 christos }
1774 1.1 christos
1775 1.1 christos while (1)
1776 1.1 christos {
1777 1.1 christos unsigned char rle;
1778 1.1 christos
1779 1.1 christos rle = read_byte (&rnglists_buf);
1780 1.1 christos if (rle == DW_RLE_end_of_list)
1781 1.1 christos break;
1782 1.1 christos switch (rle)
1783 1.1 christos {
1784 1.1 christos case DW_RLE_base_addressx:
1785 1.1 christos {
1786 1.1 christos uint64_t index;
1787 1.1 christos
1788 1.1 christos index = read_uleb128 (&rnglists_buf);
1789 1.1 christos if (!resolve_addr_index (dwarf_sections, u->addr_base,
1790 1.1 christos u->addrsize, is_bigendian, index,
1791 1.1 christos error_callback, data, &base))
1792 1.1 christos return 0;
1793 1.1 christos }
1794 1.1 christos break;
1795 1.1 christos
1796 1.1 christos case DW_RLE_startx_endx:
1797 1.1 christos {
1798 1.1 christos uint64_t index;
1799 1.1.1.1.2.1 perseant uintptr_t low;
1800 1.1.1.1.2.1 perseant uintptr_t high;
1801 1.1 christos
1802 1.1 christos index = read_uleb128 (&rnglists_buf);
1803 1.1 christos if (!resolve_addr_index (dwarf_sections, u->addr_base,
1804 1.1 christos u->addrsize, is_bigendian, index,
1805 1.1 christos error_callback, data, &low))
1806 1.1 christos return 0;
1807 1.1 christos index = read_uleb128 (&rnglists_buf);
1808 1.1 christos if (!resolve_addr_index (dwarf_sections, u->addr_base,
1809 1.1 christos u->addrsize, is_bigendian, index,
1810 1.1 christos error_callback, data, &high))
1811 1.1 christos return 0;
1812 1.1 christos if (!add_range (state, rdata, low + base_address,
1813 1.1 christos high + base_address, error_callback, data,
1814 1.1 christos vec))
1815 1.1 christos return 0;
1816 1.1 christos }
1817 1.1 christos break;
1818 1.1 christos
1819 1.1 christos case DW_RLE_startx_length:
1820 1.1 christos {
1821 1.1 christos uint64_t index;
1822 1.1.1.1.2.1 perseant uintptr_t low;
1823 1.1.1.1.2.1 perseant uintptr_t length;
1824 1.1 christos
1825 1.1 christos index = read_uleb128 (&rnglists_buf);
1826 1.1 christos if (!resolve_addr_index (dwarf_sections, u->addr_base,
1827 1.1 christos u->addrsize, is_bigendian, index,
1828 1.1 christos error_callback, data, &low))
1829 1.1 christos return 0;
1830 1.1 christos length = read_uleb128 (&rnglists_buf);
1831 1.1 christos low += base_address;
1832 1.1 christos if (!add_range (state, rdata, low, low + length,
1833 1.1 christos error_callback, data, vec))
1834 1.1 christos return 0;
1835 1.1 christos }
1836 1.1 christos break;
1837 1.1 christos
1838 1.1 christos case DW_RLE_offset_pair:
1839 1.1 christos {
1840 1.1 christos uint64_t low;
1841 1.1 christos uint64_t high;
1842 1.1 christos
1843 1.1 christos low = read_uleb128 (&rnglists_buf);
1844 1.1 christos high = read_uleb128 (&rnglists_buf);
1845 1.1 christos if (!add_range (state, rdata, low + base + base_address,
1846 1.1 christos high + base + base_address,
1847 1.1 christos error_callback, data, vec))
1848 1.1 christos return 0;
1849 1.1 christos }
1850 1.1 christos break;
1851 1.1 christos
1852 1.1 christos case DW_RLE_base_address:
1853 1.1.1.1.2.1 perseant base = (uintptr_t) read_address (&rnglists_buf, u->addrsize);
1854 1.1 christos break;
1855 1.1 christos
1856 1.1 christos case DW_RLE_start_end:
1857 1.1 christos {
1858 1.1.1.1.2.1 perseant uintptr_t low;
1859 1.1.1.1.2.1 perseant uintptr_t high;
1860 1.1 christos
1861 1.1.1.1.2.1 perseant low = (uintptr_t) read_address (&rnglists_buf, u->addrsize);
1862 1.1.1.1.2.1 perseant high = (uintptr_t) read_address (&rnglists_buf, u->addrsize);
1863 1.1 christos if (!add_range (state, rdata, low + base_address,
1864 1.1 christos high + base_address, error_callback, data,
1865 1.1 christos vec))
1866 1.1 christos return 0;
1867 1.1 christos }
1868 1.1 christos break;
1869 1.1 christos
1870 1.1 christos case DW_RLE_start_length:
1871 1.1 christos {
1872 1.1.1.1.2.1 perseant uintptr_t low;
1873 1.1.1.1.2.1 perseant uintptr_t length;
1874 1.1 christos
1875 1.1.1.1.2.1 perseant low = (uintptr_t) read_address (&rnglists_buf, u->addrsize);
1876 1.1.1.1.2.1 perseant length = (uintptr_t) read_uleb128 (&rnglists_buf);
1877 1.1 christos low += base_address;
1878 1.1 christos if (!add_range (state, rdata, low, low + length,
1879 1.1 christos error_callback, data, vec))
1880 1.1 christos return 0;
1881 1.1 christos }
1882 1.1 christos break;
1883 1.1 christos
1884 1.1 christos default:
1885 1.1 christos dwarf_buf_error (&rnglists_buf, "unrecognized DW_RLE value", -1);
1886 1.1 christos return 0;
1887 1.1 christos }
1888 1.1 christos }
1889 1.1 christos
1890 1.1 christos if (rnglists_buf.reported_underflow)
1891 1.1 christos return 0;
1892 1.1 christos
1893 1.1 christos return 1;
1894 1.1 christos }
1895 1.1 christos
1896 1.1 christos /* Call ADD_RANGE for each lowpc/highpc pair in PCRANGE. RDATA is
1897 1.1 christos passed to ADD_RANGE, and is either a struct unit * or a struct
1898 1.1 christos function *. VEC is the vector we are adding ranges to, and is
1899 1.1 christos either a struct unit_addrs_vector * or a struct function_vector *.
1900 1.1 christos Returns 1 on success, 0 on error. */
1901 1.1 christos
1902 1.1 christos static int
1903 1.1 christos add_ranges (struct backtrace_state *state,
1904 1.1 christos const struct dwarf_sections *dwarf_sections,
1905 1.1 christos uintptr_t base_address, int is_bigendian,
1906 1.1.1.1.2.1 perseant struct unit *u, uintptr_t base, const struct pcrange *pcrange,
1907 1.1 christos int (*add_range) (struct backtrace_state *state, void *rdata,
1908 1.1.1.1.2.1 perseant uintptr_t lowpc, uintptr_t highpc,
1909 1.1 christos backtrace_error_callback error_callback,
1910 1.1 christos void *data, void *vec),
1911 1.1 christos void *rdata,
1912 1.1 christos backtrace_error_callback error_callback, void *data,
1913 1.1 christos void *vec)
1914 1.1 christos {
1915 1.1 christos if (pcrange->have_lowpc && pcrange->have_highpc)
1916 1.1 christos return add_low_high_range (state, dwarf_sections, base_address,
1917 1.1 christos is_bigendian, u, pcrange, add_range, rdata,
1918 1.1 christos error_callback, data, vec);
1919 1.1 christos
1920 1.1 christos if (!pcrange->have_ranges)
1921 1.1 christos {
1922 1.1 christos /* Did not find any address ranges to add. */
1923 1.1 christos return 1;
1924 1.1 christos }
1925 1.1 christos
1926 1.1 christos if (u->version < 5)
1927 1.1 christos return add_ranges_from_ranges (state, dwarf_sections, base_address,
1928 1.1 christos is_bigendian, u, base, pcrange, add_range,
1929 1.1 christos rdata, error_callback, data, vec);
1930 1.1 christos else
1931 1.1 christos return add_ranges_from_rnglists (state, dwarf_sections, base_address,
1932 1.1 christos is_bigendian, u, base, pcrange, add_range,
1933 1.1 christos rdata, error_callback, data, vec);
1934 1.1 christos }
1935 1.1 christos
1936 1.1 christos /* Find the address range covered by a compilation unit, reading from
1937 1.1 christos UNIT_BUF and adding values to U. Returns 1 if all data could be
1938 1.1 christos read, 0 if there is some error. */
1939 1.1 christos
1940 1.1 christos static int
1941 1.1 christos find_address_ranges (struct backtrace_state *state, uintptr_t base_address,
1942 1.1 christos struct dwarf_buf *unit_buf,
1943 1.1 christos const struct dwarf_sections *dwarf_sections,
1944 1.1 christos int is_bigendian, struct dwarf_data *altlink,
1945 1.1 christos backtrace_error_callback error_callback, void *data,
1946 1.1 christos struct unit *u, struct unit_addrs_vector *addrs,
1947 1.1 christos enum dwarf_tag *unit_tag)
1948 1.1 christos {
1949 1.1 christos while (unit_buf->left > 0)
1950 1.1 christos {
1951 1.1 christos uint64_t code;
1952 1.1 christos const struct abbrev *abbrev;
1953 1.1 christos struct pcrange pcrange;
1954 1.1 christos struct attr_val name_val;
1955 1.1 christos int have_name_val;
1956 1.1 christos struct attr_val comp_dir_val;
1957 1.1 christos int have_comp_dir_val;
1958 1.1 christos size_t i;
1959 1.1 christos
1960 1.1 christos code = read_uleb128 (unit_buf);
1961 1.1 christos if (code == 0)
1962 1.1 christos return 1;
1963 1.1 christos
1964 1.1 christos abbrev = lookup_abbrev (&u->abbrevs, code, error_callback, data);
1965 1.1 christos if (abbrev == NULL)
1966 1.1 christos return 0;
1967 1.1 christos
1968 1.1 christos if (unit_tag != NULL)
1969 1.1 christos *unit_tag = abbrev->tag;
1970 1.1 christos
1971 1.1 christos memset (&pcrange, 0, sizeof pcrange);
1972 1.1 christos memset (&name_val, 0, sizeof name_val);
1973 1.1 christos have_name_val = 0;
1974 1.1 christos memset (&comp_dir_val, 0, sizeof comp_dir_val);
1975 1.1 christos have_comp_dir_val = 0;
1976 1.1 christos for (i = 0; i < abbrev->num_attrs; ++i)
1977 1.1 christos {
1978 1.1 christos struct attr_val val;
1979 1.1 christos
1980 1.1 christos if (!read_attribute (abbrev->attrs[i].form, abbrev->attrs[i].val,
1981 1.1 christos unit_buf, u->is_dwarf64, u->version,
1982 1.1 christos u->addrsize, dwarf_sections, altlink, &val))
1983 1.1 christos return 0;
1984 1.1 christos
1985 1.1 christos switch (abbrev->attrs[i].name)
1986 1.1 christos {
1987 1.1 christos case DW_AT_low_pc: case DW_AT_high_pc: case DW_AT_ranges:
1988 1.1 christos update_pcrange (&abbrev->attrs[i], &val, &pcrange);
1989 1.1 christos break;
1990 1.1 christos
1991 1.1 christos case DW_AT_stmt_list:
1992 1.1.1.1.2.1 perseant if ((abbrev->tag == DW_TAG_compile_unit
1993 1.1.1.1.2.1 perseant || abbrev->tag == DW_TAG_skeleton_unit)
1994 1.1 christos && (val.encoding == ATTR_VAL_UINT
1995 1.1 christos || val.encoding == ATTR_VAL_REF_SECTION))
1996 1.1 christos u->lineoff = val.u.uint;
1997 1.1 christos break;
1998 1.1 christos
1999 1.1 christos case DW_AT_name:
2000 1.1.1.1.2.1 perseant if (abbrev->tag == DW_TAG_compile_unit
2001 1.1.1.1.2.1 perseant || abbrev->tag == DW_TAG_skeleton_unit)
2002 1.1 christos {
2003 1.1 christos name_val = val;
2004 1.1 christos have_name_val = 1;
2005 1.1 christos }
2006 1.1 christos break;
2007 1.1 christos
2008 1.1 christos case DW_AT_comp_dir:
2009 1.1.1.1.2.1 perseant if (abbrev->tag == DW_TAG_compile_unit
2010 1.1.1.1.2.1 perseant || abbrev->tag == DW_TAG_skeleton_unit)
2011 1.1 christos {
2012 1.1 christos comp_dir_val = val;
2013 1.1 christos have_comp_dir_val = 1;
2014 1.1 christos }
2015 1.1 christos break;
2016 1.1 christos
2017 1.1 christos case DW_AT_str_offsets_base:
2018 1.1.1.1.2.1 perseant if ((abbrev->tag == DW_TAG_compile_unit
2019 1.1.1.1.2.1 perseant || abbrev->tag == DW_TAG_skeleton_unit)
2020 1.1 christos && val.encoding == ATTR_VAL_REF_SECTION)
2021 1.1 christos u->str_offsets_base = val.u.uint;
2022 1.1 christos break;
2023 1.1 christos
2024 1.1 christos case DW_AT_addr_base:
2025 1.1.1.1.2.1 perseant if ((abbrev->tag == DW_TAG_compile_unit
2026 1.1.1.1.2.1 perseant || abbrev->tag == DW_TAG_skeleton_unit)
2027 1.1 christos && val.encoding == ATTR_VAL_REF_SECTION)
2028 1.1 christos u->addr_base = val.u.uint;
2029 1.1 christos break;
2030 1.1 christos
2031 1.1 christos case DW_AT_rnglists_base:
2032 1.1.1.1.2.1 perseant if ((abbrev->tag == DW_TAG_compile_unit
2033 1.1.1.1.2.1 perseant || abbrev->tag == DW_TAG_skeleton_unit)
2034 1.1 christos && val.encoding == ATTR_VAL_REF_SECTION)
2035 1.1 christos u->rnglists_base = val.u.uint;
2036 1.1 christos break;
2037 1.1 christos
2038 1.1 christos default:
2039 1.1 christos break;
2040 1.1 christos }
2041 1.1 christos }
2042 1.1 christos
2043 1.1 christos // Resolve strings after we're sure that we have seen
2044 1.1 christos // DW_AT_str_offsets_base.
2045 1.1 christos if (have_name_val)
2046 1.1 christos {
2047 1.1 christos if (!resolve_string (dwarf_sections, u->is_dwarf64, is_bigendian,
2048 1.1 christos u->str_offsets_base, &name_val,
2049 1.1 christos error_callback, data, &u->filename))
2050 1.1 christos return 0;
2051 1.1 christos }
2052 1.1 christos if (have_comp_dir_val)
2053 1.1 christos {
2054 1.1 christos if (!resolve_string (dwarf_sections, u->is_dwarf64, is_bigendian,
2055 1.1 christos u->str_offsets_base, &comp_dir_val,
2056 1.1 christos error_callback, data, &u->comp_dir))
2057 1.1 christos return 0;
2058 1.1 christos }
2059 1.1 christos
2060 1.1 christos if (abbrev->tag == DW_TAG_compile_unit
2061 1.1.1.1.2.1 perseant || abbrev->tag == DW_TAG_subprogram
2062 1.1.1.1.2.1 perseant || abbrev->tag == DW_TAG_skeleton_unit)
2063 1.1 christos {
2064 1.1 christos if (!add_ranges (state, dwarf_sections, base_address,
2065 1.1 christos is_bigendian, u, pcrange.lowpc, &pcrange,
2066 1.1 christos add_unit_addr, (void *) u, error_callback, data,
2067 1.1 christos (void *) addrs))
2068 1.1 christos return 0;
2069 1.1 christos
2070 1.1.1.1.2.1 perseant /* If we found the PC range in the DW_TAG_compile_unit or
2071 1.1.1.1.2.1 perseant DW_TAG_skeleton_unit, we can stop now. */
2072 1.1.1.1.2.1 perseant if ((abbrev->tag == DW_TAG_compile_unit
2073 1.1.1.1.2.1 perseant || abbrev->tag == DW_TAG_skeleton_unit)
2074 1.1 christos && (pcrange.have_ranges
2075 1.1 christos || (pcrange.have_lowpc && pcrange.have_highpc)))
2076 1.1 christos return 1;
2077 1.1 christos }
2078 1.1 christos
2079 1.1 christos if (abbrev->has_children)
2080 1.1 christos {
2081 1.1 christos if (!find_address_ranges (state, base_address, unit_buf,
2082 1.1 christos dwarf_sections, is_bigendian, altlink,
2083 1.1 christos error_callback, data, u, addrs, NULL))
2084 1.1 christos return 0;
2085 1.1 christos }
2086 1.1 christos }
2087 1.1 christos
2088 1.1 christos return 1;
2089 1.1 christos }
2090 1.1 christos
2091 1.1 christos /* Build a mapping from address ranges to the compilation units where
2092 1.1 christos the line number information for that range can be found. Returns 1
2093 1.1 christos on success, 0 on failure. */
2094 1.1 christos
2095 1.1 christos static int
2096 1.1 christos build_address_map (struct backtrace_state *state, uintptr_t base_address,
2097 1.1 christos const struct dwarf_sections *dwarf_sections,
2098 1.1 christos int is_bigendian, struct dwarf_data *altlink,
2099 1.1 christos backtrace_error_callback error_callback, void *data,
2100 1.1 christos struct unit_addrs_vector *addrs,
2101 1.1 christos struct unit_vector *unit_vec)
2102 1.1 christos {
2103 1.1 christos struct dwarf_buf info;
2104 1.1 christos struct backtrace_vector units;
2105 1.1 christos size_t units_count;
2106 1.1 christos size_t i;
2107 1.1 christos struct unit **pu;
2108 1.1 christos size_t unit_offset = 0;
2109 1.1 christos struct unit_addrs *pa;
2110 1.1 christos
2111 1.1 christos memset (&addrs->vec, 0, sizeof addrs->vec);
2112 1.1 christos memset (&unit_vec->vec, 0, sizeof unit_vec->vec);
2113 1.1 christos addrs->count = 0;
2114 1.1 christos unit_vec->count = 0;
2115 1.1 christos
2116 1.1 christos /* Read through the .debug_info section. FIXME: Should we use the
2117 1.1 christos .debug_aranges section? gdb and addr2line don't use it, but I'm
2118 1.1 christos not sure why. */
2119 1.1 christos
2120 1.1 christos info.name = ".debug_info";
2121 1.1 christos info.start = dwarf_sections->data[DEBUG_INFO];
2122 1.1 christos info.buf = info.start;
2123 1.1 christos info.left = dwarf_sections->size[DEBUG_INFO];
2124 1.1 christos info.is_bigendian = is_bigendian;
2125 1.1 christos info.error_callback = error_callback;
2126 1.1 christos info.data = data;
2127 1.1 christos info.reported_underflow = 0;
2128 1.1 christos
2129 1.1 christos memset (&units, 0, sizeof units);
2130 1.1 christos units_count = 0;
2131 1.1 christos
2132 1.1 christos while (info.left > 0)
2133 1.1 christos {
2134 1.1 christos const unsigned char *unit_data_start;
2135 1.1 christos uint64_t len;
2136 1.1 christos int is_dwarf64;
2137 1.1 christos struct dwarf_buf unit_buf;
2138 1.1 christos int version;
2139 1.1 christos int unit_type;
2140 1.1 christos uint64_t abbrev_offset;
2141 1.1 christos int addrsize;
2142 1.1 christos struct unit *u;
2143 1.1 christos enum dwarf_tag unit_tag;
2144 1.1 christos
2145 1.1 christos if (info.reported_underflow)
2146 1.1 christos goto fail;
2147 1.1 christos
2148 1.1 christos unit_data_start = info.buf;
2149 1.1 christos
2150 1.1 christos len = read_initial_length (&info, &is_dwarf64);
2151 1.1 christos unit_buf = info;
2152 1.1 christos unit_buf.left = len;
2153 1.1 christos
2154 1.1 christos if (!advance (&info, len))
2155 1.1 christos goto fail;
2156 1.1 christos
2157 1.1 christos version = read_uint16 (&unit_buf);
2158 1.1 christos if (version < 2 || version > 5)
2159 1.1 christos {
2160 1.1 christos dwarf_buf_error (&unit_buf, "unrecognized DWARF version", -1);
2161 1.1 christos goto fail;
2162 1.1 christos }
2163 1.1 christos
2164 1.1 christos if (version < 5)
2165 1.1 christos unit_type = 0;
2166 1.1 christos else
2167 1.1 christos {
2168 1.1 christos unit_type = read_byte (&unit_buf);
2169 1.1 christos if (unit_type == DW_UT_type || unit_type == DW_UT_split_type)
2170 1.1 christos {
2171 1.1 christos /* This unit doesn't have anything we need. */
2172 1.1 christos continue;
2173 1.1 christos }
2174 1.1 christos }
2175 1.1 christos
2176 1.1 christos pu = ((struct unit **)
2177 1.1 christos backtrace_vector_grow (state, sizeof (struct unit *),
2178 1.1 christos error_callback, data, &units));
2179 1.1 christos if (pu == NULL)
2180 1.1 christos goto fail;
2181 1.1 christos
2182 1.1 christos u = ((struct unit *)
2183 1.1 christos backtrace_alloc (state, sizeof *u, error_callback, data));
2184 1.1 christos if (u == NULL)
2185 1.1 christos goto fail;
2186 1.1 christos
2187 1.1 christos *pu = u;
2188 1.1 christos ++units_count;
2189 1.1 christos
2190 1.1 christos if (version < 5)
2191 1.1 christos addrsize = 0; /* Set below. */
2192 1.1 christos else
2193 1.1 christos addrsize = read_byte (&unit_buf);
2194 1.1 christos
2195 1.1 christos memset (&u->abbrevs, 0, sizeof u->abbrevs);
2196 1.1 christos abbrev_offset = read_offset (&unit_buf, is_dwarf64);
2197 1.1 christos if (!read_abbrevs (state, abbrev_offset,
2198 1.1 christos dwarf_sections->data[DEBUG_ABBREV],
2199 1.1 christos dwarf_sections->size[DEBUG_ABBREV],
2200 1.1 christos is_bigendian, error_callback, data, &u->abbrevs))
2201 1.1 christos goto fail;
2202 1.1 christos
2203 1.1 christos if (version < 5)
2204 1.1 christos addrsize = read_byte (&unit_buf);
2205 1.1 christos
2206 1.1 christos switch (unit_type)
2207 1.1 christos {
2208 1.1 christos case 0:
2209 1.1 christos break;
2210 1.1 christos case DW_UT_compile: case DW_UT_partial:
2211 1.1 christos break;
2212 1.1 christos case DW_UT_skeleton: case DW_UT_split_compile:
2213 1.1 christos read_uint64 (&unit_buf); /* dwo_id */
2214 1.1 christos break;
2215 1.1 christos default:
2216 1.1 christos break;
2217 1.1 christos }
2218 1.1 christos
2219 1.1 christos u->low_offset = unit_offset;
2220 1.1 christos unit_offset += len + (is_dwarf64 ? 12 : 4);
2221 1.1 christos u->high_offset = unit_offset;
2222 1.1 christos u->unit_data = unit_buf.buf;
2223 1.1 christos u->unit_data_len = unit_buf.left;
2224 1.1 christos u->unit_data_offset = unit_buf.buf - unit_data_start;
2225 1.1 christos u->version = version;
2226 1.1 christos u->is_dwarf64 = is_dwarf64;
2227 1.1 christos u->addrsize = addrsize;
2228 1.1 christos u->filename = NULL;
2229 1.1 christos u->comp_dir = NULL;
2230 1.1 christos u->abs_filename = NULL;
2231 1.1 christos u->lineoff = 0;
2232 1.1.1.1.2.1 perseant u->str_offsets_base = 0;
2233 1.1.1.1.2.1 perseant u->addr_base = 0;
2234 1.1.1.1.2.1 perseant u->rnglists_base = 0;
2235 1.1 christos
2236 1.1 christos /* The actual line number mappings will be read as needed. */
2237 1.1 christos u->lines = NULL;
2238 1.1 christos u->lines_count = 0;
2239 1.1 christos u->function_addrs = NULL;
2240 1.1 christos u->function_addrs_count = 0;
2241 1.1 christos
2242 1.1 christos if (!find_address_ranges (state, base_address, &unit_buf, dwarf_sections,
2243 1.1 christos is_bigendian, altlink, error_callback, data,
2244 1.1 christos u, addrs, &unit_tag))
2245 1.1 christos goto fail;
2246 1.1 christos
2247 1.1 christos if (unit_buf.reported_underflow)
2248 1.1 christos goto fail;
2249 1.1 christos }
2250 1.1 christos if (info.reported_underflow)
2251 1.1 christos goto fail;
2252 1.1 christos
2253 1.1 christos /* Add a trailing addrs entry, but don't include it in addrs->count. */
2254 1.1 christos pa = ((struct unit_addrs *)
2255 1.1 christos backtrace_vector_grow (state, sizeof (struct unit_addrs),
2256 1.1 christos error_callback, data, &addrs->vec));
2257 1.1 christos if (pa == NULL)
2258 1.1 christos goto fail;
2259 1.1 christos pa->low = 0;
2260 1.1 christos --pa->low;
2261 1.1 christos pa->high = pa->low;
2262 1.1 christos pa->u = NULL;
2263 1.1 christos
2264 1.1 christos unit_vec->vec = units;
2265 1.1 christos unit_vec->count = units_count;
2266 1.1 christos return 1;
2267 1.1 christos
2268 1.1 christos fail:
2269 1.1 christos if (units_count > 0)
2270 1.1 christos {
2271 1.1 christos pu = (struct unit **) units.base;
2272 1.1 christos for (i = 0; i < units_count; i++)
2273 1.1 christos {
2274 1.1 christos free_abbrevs (state, &pu[i]->abbrevs, error_callback, data);
2275 1.1 christos backtrace_free (state, pu[i], sizeof **pu, error_callback, data);
2276 1.1 christos }
2277 1.1 christos backtrace_vector_free (state, &units, error_callback, data);
2278 1.1 christos }
2279 1.1 christos if (addrs->count > 0)
2280 1.1 christos {
2281 1.1 christos backtrace_vector_free (state, &addrs->vec, error_callback, data);
2282 1.1 christos addrs->count = 0;
2283 1.1 christos }
2284 1.1 christos return 0;
2285 1.1 christos }
2286 1.1 christos
2287 1.1 christos /* Add a new mapping to the vector of line mappings that we are
2288 1.1 christos building. Returns 1 on success, 0 on failure. */
2289 1.1 christos
2290 1.1 christos static int
2291 1.1 christos add_line (struct backtrace_state *state, struct dwarf_data *ddata,
2292 1.1 christos uintptr_t pc, const char *filename, int lineno,
2293 1.1 christos backtrace_error_callback error_callback, void *data,
2294 1.1 christos struct line_vector *vec)
2295 1.1 christos {
2296 1.1 christos struct line *ln;
2297 1.1 christos
2298 1.1 christos /* If we are adding the same mapping, ignore it. This can happen
2299 1.1 christos when using discriminators. */
2300 1.1 christos if (vec->count > 0)
2301 1.1 christos {
2302 1.1 christos ln = (struct line *) vec->vec.base + (vec->count - 1);
2303 1.1 christos if (pc == ln->pc && filename == ln->filename && lineno == ln->lineno)
2304 1.1 christos return 1;
2305 1.1 christos }
2306 1.1 christos
2307 1.1 christos ln = ((struct line *)
2308 1.1 christos backtrace_vector_grow (state, sizeof (struct line), error_callback,
2309 1.1 christos data, &vec->vec));
2310 1.1 christos if (ln == NULL)
2311 1.1 christos return 0;
2312 1.1 christos
2313 1.1 christos /* Add in the base address here, so that we can look up the PC
2314 1.1 christos directly. */
2315 1.1 christos ln->pc = pc + ddata->base_address;
2316 1.1 christos
2317 1.1 christos ln->filename = filename;
2318 1.1 christos ln->lineno = lineno;
2319 1.1 christos ln->idx = vec->count;
2320 1.1 christos
2321 1.1 christos ++vec->count;
2322 1.1 christos
2323 1.1 christos return 1;
2324 1.1 christos }
2325 1.1 christos
2326 1.1 christos /* Free the line header information. */
2327 1.1 christos
2328 1.1 christos static void
2329 1.1 christos free_line_header (struct backtrace_state *state, struct line_header *hdr,
2330 1.1 christos backtrace_error_callback error_callback, void *data)
2331 1.1 christos {
2332 1.1 christos if (hdr->dirs_count != 0)
2333 1.1 christos backtrace_free (state, hdr->dirs, hdr->dirs_count * sizeof (const char *),
2334 1.1 christos error_callback, data);
2335 1.1 christos backtrace_free (state, hdr->filenames,
2336 1.1 christos hdr->filenames_count * sizeof (char *),
2337 1.1 christos error_callback, data);
2338 1.1 christos }
2339 1.1 christos
2340 1.1 christos /* Read the directories and file names for a line header for version
2341 1.1 christos 2, setting fields in HDR. Return 1 on success, 0 on failure. */
2342 1.1 christos
2343 1.1 christos static int
2344 1.1 christos read_v2_paths (struct backtrace_state *state, struct unit *u,
2345 1.1 christos struct dwarf_buf *hdr_buf, struct line_header *hdr)
2346 1.1 christos {
2347 1.1 christos const unsigned char *p;
2348 1.1 christos const unsigned char *pend;
2349 1.1 christos size_t i;
2350 1.1 christos
2351 1.1 christos /* Count the number of directory entries. */
2352 1.1 christos hdr->dirs_count = 0;
2353 1.1 christos p = hdr_buf->buf;
2354 1.1 christos pend = p + hdr_buf->left;
2355 1.1 christos while (p < pend && *p != '\0')
2356 1.1 christos {
2357 1.1 christos p += strnlen((const char *) p, pend - p) + 1;
2358 1.1 christos ++hdr->dirs_count;
2359 1.1 christos }
2360 1.1 christos
2361 1.1 christos /* The index of the first entry in the list of directories is 1. Index 0 is
2362 1.1 christos used for the current directory of the compilation. To simplify index
2363 1.1 christos handling, we set entry 0 to the compilation unit directory. */
2364 1.1 christos ++hdr->dirs_count;
2365 1.1 christos hdr->dirs = ((const char **)
2366 1.1 christos backtrace_alloc (state,
2367 1.1 christos hdr->dirs_count * sizeof (const char *),
2368 1.1 christos hdr_buf->error_callback,
2369 1.1 christos hdr_buf->data));
2370 1.1 christos if (hdr->dirs == NULL)
2371 1.1 christos return 0;
2372 1.1 christos
2373 1.1 christos hdr->dirs[0] = u->comp_dir;
2374 1.1 christos i = 1;
2375 1.1 christos while (*hdr_buf->buf != '\0')
2376 1.1 christos {
2377 1.1 christos if (hdr_buf->reported_underflow)
2378 1.1 christos return 0;
2379 1.1 christos
2380 1.1 christos hdr->dirs[i] = read_string (hdr_buf);
2381 1.1 christos if (hdr->dirs[i] == NULL)
2382 1.1 christos return 0;
2383 1.1 christos ++i;
2384 1.1 christos }
2385 1.1 christos if (!advance (hdr_buf, 1))
2386 1.1 christos return 0;
2387 1.1 christos
2388 1.1 christos /* Count the number of file entries. */
2389 1.1 christos hdr->filenames_count = 0;
2390 1.1 christos p = hdr_buf->buf;
2391 1.1 christos pend = p + hdr_buf->left;
2392 1.1 christos while (p < pend && *p != '\0')
2393 1.1 christos {
2394 1.1 christos p += strnlen ((const char *) p, pend - p) + 1;
2395 1.1 christos p += leb128_len (p);
2396 1.1 christos p += leb128_len (p);
2397 1.1 christos p += leb128_len (p);
2398 1.1 christos ++hdr->filenames_count;
2399 1.1 christos }
2400 1.1 christos
2401 1.1 christos /* The index of the first entry in the list of file names is 1. Index 0 is
2402 1.1 christos used for the DW_AT_name of the compilation unit. To simplify index
2403 1.1 christos handling, we set entry 0 to the compilation unit file name. */
2404 1.1 christos ++hdr->filenames_count;
2405 1.1 christos hdr->filenames = ((const char **)
2406 1.1 christos backtrace_alloc (state,
2407 1.1 christos hdr->filenames_count * sizeof (char *),
2408 1.1 christos hdr_buf->error_callback,
2409 1.1 christos hdr_buf->data));
2410 1.1 christos if (hdr->filenames == NULL)
2411 1.1 christos return 0;
2412 1.1 christos hdr->filenames[0] = u->filename;
2413 1.1 christos i = 1;
2414 1.1 christos while (*hdr_buf->buf != '\0')
2415 1.1 christos {
2416 1.1 christos const char *filename;
2417 1.1 christos uint64_t dir_index;
2418 1.1 christos
2419 1.1 christos if (hdr_buf->reported_underflow)
2420 1.1 christos return 0;
2421 1.1 christos
2422 1.1 christos filename = read_string (hdr_buf);
2423 1.1 christos if (filename == NULL)
2424 1.1 christos return 0;
2425 1.1 christos dir_index = read_uleb128 (hdr_buf);
2426 1.1 christos if (IS_ABSOLUTE_PATH (filename)
2427 1.1 christos || (dir_index < hdr->dirs_count && hdr->dirs[dir_index] == NULL))
2428 1.1 christos hdr->filenames[i] = filename;
2429 1.1 christos else
2430 1.1 christos {
2431 1.1 christos const char *dir;
2432 1.1 christos size_t dir_len;
2433 1.1 christos size_t filename_len;
2434 1.1 christos char *s;
2435 1.1 christos
2436 1.1 christos if (dir_index < hdr->dirs_count)
2437 1.1 christos dir = hdr->dirs[dir_index];
2438 1.1 christos else
2439 1.1 christos {
2440 1.1 christos dwarf_buf_error (hdr_buf,
2441 1.1 christos ("invalid directory index in "
2442 1.1 christos "line number program header"),
2443 1.1 christos 0);
2444 1.1 christos return 0;
2445 1.1 christos }
2446 1.1 christos dir_len = strlen (dir);
2447 1.1 christos filename_len = strlen (filename);
2448 1.1 christos s = ((char *) backtrace_alloc (state, dir_len + filename_len + 2,
2449 1.1 christos hdr_buf->error_callback,
2450 1.1 christos hdr_buf->data));
2451 1.1 christos if (s == NULL)
2452 1.1 christos return 0;
2453 1.1 christos memcpy (s, dir, dir_len);
2454 1.1 christos /* FIXME: If we are on a DOS-based file system, and the
2455 1.1 christos directory or the file name use backslashes, then we
2456 1.1 christos should use a backslash here. */
2457 1.1 christos s[dir_len] = '/';
2458 1.1 christos memcpy (s + dir_len + 1, filename, filename_len + 1);
2459 1.1 christos hdr->filenames[i] = s;
2460 1.1 christos }
2461 1.1 christos
2462 1.1 christos /* Ignore the modification time and size. */
2463 1.1 christos read_uleb128 (hdr_buf);
2464 1.1 christos read_uleb128 (hdr_buf);
2465 1.1 christos
2466 1.1 christos ++i;
2467 1.1 christos }
2468 1.1 christos
2469 1.1 christos return 1;
2470 1.1 christos }
2471 1.1 christos
2472 1.1 christos /* Read a single version 5 LNCT entry for a directory or file name in a
2473 1.1 christos line header. Sets *STRING to the resulting name, ignoring other
2474 1.1 christos data. Return 1 on success, 0 on failure. */
2475 1.1 christos
2476 1.1 christos static int
2477 1.1 christos read_lnct (struct backtrace_state *state, struct dwarf_data *ddata,
2478 1.1 christos struct unit *u, struct dwarf_buf *hdr_buf,
2479 1.1 christos const struct line_header *hdr, size_t formats_count,
2480 1.1 christos const struct line_header_format *formats, const char **string)
2481 1.1 christos {
2482 1.1 christos size_t i;
2483 1.1 christos const char *dir;
2484 1.1 christos const char *path;
2485 1.1 christos
2486 1.1 christos dir = NULL;
2487 1.1 christos path = NULL;
2488 1.1 christos for (i = 0; i < formats_count; i++)
2489 1.1 christos {
2490 1.1 christos struct attr_val val;
2491 1.1 christos
2492 1.1 christos if (!read_attribute (formats[i].form, 0, hdr_buf, u->is_dwarf64,
2493 1.1 christos u->version, hdr->addrsize, &ddata->dwarf_sections,
2494 1.1 christos ddata->altlink, &val))
2495 1.1 christos return 0;
2496 1.1 christos switch (formats[i].lnct)
2497 1.1 christos {
2498 1.1 christos case DW_LNCT_path:
2499 1.1 christos if (!resolve_string (&ddata->dwarf_sections, u->is_dwarf64,
2500 1.1 christos ddata->is_bigendian, u->str_offsets_base,
2501 1.1 christos &val, hdr_buf->error_callback, hdr_buf->data,
2502 1.1 christos &path))
2503 1.1 christos return 0;
2504 1.1 christos break;
2505 1.1 christos case DW_LNCT_directory_index:
2506 1.1 christos if (val.encoding == ATTR_VAL_UINT)
2507 1.1 christos {
2508 1.1 christos if (val.u.uint >= hdr->dirs_count)
2509 1.1 christos {
2510 1.1 christos dwarf_buf_error (hdr_buf,
2511 1.1 christos ("invalid directory index in "
2512 1.1 christos "line number program header"),
2513 1.1 christos 0);
2514 1.1 christos return 0;
2515 1.1 christos }
2516 1.1 christos dir = hdr->dirs[val.u.uint];
2517 1.1 christos }
2518 1.1 christos break;
2519 1.1 christos default:
2520 1.1 christos /* We don't care about timestamps or sizes or hashes. */
2521 1.1 christos break;
2522 1.1 christos }
2523 1.1 christos }
2524 1.1 christos
2525 1.1 christos if (path == NULL)
2526 1.1 christos {
2527 1.1 christos dwarf_buf_error (hdr_buf,
2528 1.1 christos "missing file name in line number program header",
2529 1.1 christos 0);
2530 1.1 christos return 0;
2531 1.1 christos }
2532 1.1 christos
2533 1.1 christos if (dir == NULL)
2534 1.1 christos *string = path;
2535 1.1 christos else
2536 1.1 christos {
2537 1.1 christos size_t dir_len;
2538 1.1 christos size_t path_len;
2539 1.1 christos char *s;
2540 1.1 christos
2541 1.1 christos dir_len = strlen (dir);
2542 1.1 christos path_len = strlen (path);
2543 1.1 christos s = (char *) backtrace_alloc (state, dir_len + path_len + 2,
2544 1.1 christos hdr_buf->error_callback, hdr_buf->data);
2545 1.1 christos if (s == NULL)
2546 1.1 christos return 0;
2547 1.1 christos memcpy (s, dir, dir_len);
2548 1.1 christos /* FIXME: If we are on a DOS-based file system, and the
2549 1.1 christos directory or the path name use backslashes, then we should
2550 1.1 christos use a backslash here. */
2551 1.1 christos s[dir_len] = '/';
2552 1.1 christos memcpy (s + dir_len + 1, path, path_len + 1);
2553 1.1 christos *string = s;
2554 1.1 christos }
2555 1.1 christos
2556 1.1 christos return 1;
2557 1.1 christos }
2558 1.1 christos
2559 1.1 christos /* Read a set of DWARF 5 line header format entries, setting *PCOUNT
2560 1.1 christos and *PPATHS. Return 1 on success, 0 on failure. */
2561 1.1 christos
2562 1.1 christos static int
2563 1.1 christos read_line_header_format_entries (struct backtrace_state *state,
2564 1.1 christos struct dwarf_data *ddata,
2565 1.1 christos struct unit *u,
2566 1.1 christos struct dwarf_buf *hdr_buf,
2567 1.1 christos struct line_header *hdr,
2568 1.1 christos size_t *pcount,
2569 1.1 christos const char ***ppaths)
2570 1.1 christos {
2571 1.1 christos size_t formats_count;
2572 1.1 christos struct line_header_format *formats;
2573 1.1 christos size_t paths_count;
2574 1.1 christos const char **paths;
2575 1.1 christos size_t i;
2576 1.1 christos int ret;
2577 1.1 christos
2578 1.1 christos formats_count = read_byte (hdr_buf);
2579 1.1 christos if (formats_count == 0)
2580 1.1 christos formats = NULL;
2581 1.1 christos else
2582 1.1 christos {
2583 1.1 christos formats = ((struct line_header_format *)
2584 1.1 christos backtrace_alloc (state,
2585 1.1 christos (formats_count
2586 1.1 christos * sizeof (struct line_header_format)),
2587 1.1 christos hdr_buf->error_callback,
2588 1.1 christos hdr_buf->data));
2589 1.1 christos if (formats == NULL)
2590 1.1 christos return 0;
2591 1.1 christos
2592 1.1 christos for (i = 0; i < formats_count; i++)
2593 1.1 christos {
2594 1.1 christos formats[i].lnct = (int) read_uleb128(hdr_buf);
2595 1.1 christos formats[i].form = (enum dwarf_form) read_uleb128 (hdr_buf);
2596 1.1 christos }
2597 1.1 christos }
2598 1.1 christos
2599 1.1 christos paths_count = read_uleb128 (hdr_buf);
2600 1.1 christos if (paths_count == 0)
2601 1.1 christos {
2602 1.1 christos *pcount = 0;
2603 1.1 christos *ppaths = NULL;
2604 1.1 christos ret = 1;
2605 1.1 christos goto exit;
2606 1.1 christos }
2607 1.1 christos
2608 1.1 christos paths = ((const char **)
2609 1.1 christos backtrace_alloc (state, paths_count * sizeof (const char *),
2610 1.1 christos hdr_buf->error_callback, hdr_buf->data));
2611 1.1 christos if (paths == NULL)
2612 1.1 christos {
2613 1.1 christos ret = 0;
2614 1.1 christos goto exit;
2615 1.1 christos }
2616 1.1 christos for (i = 0; i < paths_count; i++)
2617 1.1 christos {
2618 1.1 christos if (!read_lnct (state, ddata, u, hdr_buf, hdr, formats_count,
2619 1.1 christos formats, &paths[i]))
2620 1.1 christos {
2621 1.1 christos backtrace_free (state, paths,
2622 1.1 christos paths_count * sizeof (const char *),
2623 1.1 christos hdr_buf->error_callback, hdr_buf->data);
2624 1.1 christos ret = 0;
2625 1.1 christos goto exit;
2626 1.1 christos }
2627 1.1 christos }
2628 1.1 christos
2629 1.1 christos *pcount = paths_count;
2630 1.1 christos *ppaths = paths;
2631 1.1 christos
2632 1.1 christos ret = 1;
2633 1.1 christos
2634 1.1 christos exit:
2635 1.1 christos if (formats != NULL)
2636 1.1 christos backtrace_free (state, formats,
2637 1.1 christos formats_count * sizeof (struct line_header_format),
2638 1.1 christos hdr_buf->error_callback, hdr_buf->data);
2639 1.1 christos
2640 1.1 christos return ret;
2641 1.1 christos }
2642 1.1 christos
2643 1.1 christos /* Read the line header. Return 1 on success, 0 on failure. */
2644 1.1 christos
2645 1.1 christos static int
2646 1.1 christos read_line_header (struct backtrace_state *state, struct dwarf_data *ddata,
2647 1.1 christos struct unit *u, int is_dwarf64, struct dwarf_buf *line_buf,
2648 1.1 christos struct line_header *hdr)
2649 1.1 christos {
2650 1.1 christos uint64_t hdrlen;
2651 1.1 christos struct dwarf_buf hdr_buf;
2652 1.1 christos
2653 1.1 christos hdr->version = read_uint16 (line_buf);
2654 1.1 christos if (hdr->version < 2 || hdr->version > 5)
2655 1.1 christos {
2656 1.1 christos dwarf_buf_error (line_buf, "unsupported line number version", -1);
2657 1.1 christos return 0;
2658 1.1 christos }
2659 1.1 christos
2660 1.1 christos if (hdr->version < 5)
2661 1.1 christos hdr->addrsize = u->addrsize;
2662 1.1 christos else
2663 1.1 christos {
2664 1.1 christos hdr->addrsize = read_byte (line_buf);
2665 1.1 christos /* We could support a non-zero segment_selector_size but I doubt
2666 1.1 christos we'll ever see it. */
2667 1.1 christos if (read_byte (line_buf) != 0)
2668 1.1 christos {
2669 1.1 christos dwarf_buf_error (line_buf,
2670 1.1 christos "non-zero segment_selector_size not supported",
2671 1.1 christos -1);
2672 1.1 christos return 0;
2673 1.1 christos }
2674 1.1 christos }
2675 1.1 christos
2676 1.1 christos hdrlen = read_offset (line_buf, is_dwarf64);
2677 1.1 christos
2678 1.1 christos hdr_buf = *line_buf;
2679 1.1 christos hdr_buf.left = hdrlen;
2680 1.1 christos
2681 1.1 christos if (!advance (line_buf, hdrlen))
2682 1.1 christos return 0;
2683 1.1 christos
2684 1.1 christos hdr->min_insn_len = read_byte (&hdr_buf);
2685 1.1 christos if (hdr->version < 4)
2686 1.1 christos hdr->max_ops_per_insn = 1;
2687 1.1 christos else
2688 1.1 christos hdr->max_ops_per_insn = read_byte (&hdr_buf);
2689 1.1 christos
2690 1.1 christos /* We don't care about default_is_stmt. */
2691 1.1 christos read_byte (&hdr_buf);
2692 1.1 christos
2693 1.1 christos hdr->line_base = read_sbyte (&hdr_buf);
2694 1.1 christos hdr->line_range = read_byte (&hdr_buf);
2695 1.1 christos
2696 1.1 christos hdr->opcode_base = read_byte (&hdr_buf);
2697 1.1 christos hdr->opcode_lengths = hdr_buf.buf;
2698 1.1 christos if (!advance (&hdr_buf, hdr->opcode_base - 1))
2699 1.1 christos return 0;
2700 1.1 christos
2701 1.1 christos if (hdr->version < 5)
2702 1.1 christos {
2703 1.1 christos if (!read_v2_paths (state, u, &hdr_buf, hdr))
2704 1.1 christos return 0;
2705 1.1 christos }
2706 1.1 christos else
2707 1.1 christos {
2708 1.1 christos if (!read_line_header_format_entries (state, ddata, u, &hdr_buf, hdr,
2709 1.1 christos &hdr->dirs_count,
2710 1.1 christos &hdr->dirs))
2711 1.1 christos return 0;
2712 1.1 christos if (!read_line_header_format_entries (state, ddata, u, &hdr_buf, hdr,
2713 1.1 christos &hdr->filenames_count,
2714 1.1 christos &hdr->filenames))
2715 1.1 christos return 0;
2716 1.1 christos }
2717 1.1 christos
2718 1.1 christos if (hdr_buf.reported_underflow)
2719 1.1 christos return 0;
2720 1.1 christos
2721 1.1 christos return 1;
2722 1.1 christos }
2723 1.1 christos
2724 1.1 christos /* Read the line program, adding line mappings to VEC. Return 1 on
2725 1.1 christos success, 0 on failure. */
2726 1.1 christos
2727 1.1 christos static int
2728 1.1 christos read_line_program (struct backtrace_state *state, struct dwarf_data *ddata,
2729 1.1 christos const struct line_header *hdr, struct dwarf_buf *line_buf,
2730 1.1 christos struct line_vector *vec)
2731 1.1 christos {
2732 1.1 christos uint64_t address;
2733 1.1 christos unsigned int op_index;
2734 1.1 christos const char *reset_filename;
2735 1.1 christos const char *filename;
2736 1.1 christos int lineno;
2737 1.1 christos
2738 1.1 christos address = 0;
2739 1.1 christos op_index = 0;
2740 1.1 christos if (hdr->filenames_count > 1)
2741 1.1 christos reset_filename = hdr->filenames[1];
2742 1.1 christos else
2743 1.1 christos reset_filename = "";
2744 1.1 christos filename = reset_filename;
2745 1.1 christos lineno = 1;
2746 1.1 christos while (line_buf->left > 0)
2747 1.1 christos {
2748 1.1 christos unsigned int op;
2749 1.1 christos
2750 1.1 christos op = read_byte (line_buf);
2751 1.1 christos if (op >= hdr->opcode_base)
2752 1.1 christos {
2753 1.1 christos unsigned int advance;
2754 1.1 christos
2755 1.1 christos /* Special opcode. */
2756 1.1 christos op -= hdr->opcode_base;
2757 1.1 christos advance = op / hdr->line_range;
2758 1.1 christos address += (hdr->min_insn_len * (op_index + advance)
2759 1.1 christos / hdr->max_ops_per_insn);
2760 1.1 christos op_index = (op_index + advance) % hdr->max_ops_per_insn;
2761 1.1 christos lineno += hdr->line_base + (int) (op % hdr->line_range);
2762 1.1 christos add_line (state, ddata, address, filename, lineno,
2763 1.1 christos line_buf->error_callback, line_buf->data, vec);
2764 1.1 christos }
2765 1.1 christos else if (op == DW_LNS_extended_op)
2766 1.1 christos {
2767 1.1 christos uint64_t len;
2768 1.1 christos
2769 1.1 christos len = read_uleb128 (line_buf);
2770 1.1 christos op = read_byte (line_buf);
2771 1.1 christos switch (op)
2772 1.1 christos {
2773 1.1 christos case DW_LNE_end_sequence:
2774 1.1 christos /* FIXME: Should we mark the high PC here? It seems
2775 1.1 christos that we already have that information from the
2776 1.1 christos compilation unit. */
2777 1.1 christos address = 0;
2778 1.1 christos op_index = 0;
2779 1.1 christos filename = reset_filename;
2780 1.1 christos lineno = 1;
2781 1.1 christos break;
2782 1.1 christos case DW_LNE_set_address:
2783 1.1 christos address = read_address (line_buf, hdr->addrsize);
2784 1.1 christos break;
2785 1.1 christos case DW_LNE_define_file:
2786 1.1 christos {
2787 1.1 christos const char *f;
2788 1.1 christos unsigned int dir_index;
2789 1.1 christos
2790 1.1 christos f = read_string (line_buf);
2791 1.1 christos if (f == NULL)
2792 1.1 christos return 0;
2793 1.1 christos dir_index = read_uleb128 (line_buf);
2794 1.1 christos /* Ignore that time and length. */
2795 1.1 christos read_uleb128 (line_buf);
2796 1.1 christos read_uleb128 (line_buf);
2797 1.1 christos if (IS_ABSOLUTE_PATH (f))
2798 1.1 christos filename = f;
2799 1.1 christos else
2800 1.1 christos {
2801 1.1 christos const char *dir;
2802 1.1 christos size_t dir_len;
2803 1.1 christos size_t f_len;
2804 1.1 christos char *p;
2805 1.1 christos
2806 1.1 christos if (dir_index < hdr->dirs_count)
2807 1.1 christos dir = hdr->dirs[dir_index];
2808 1.1 christos else
2809 1.1 christos {
2810 1.1 christos dwarf_buf_error (line_buf,
2811 1.1 christos ("invalid directory index "
2812 1.1 christos "in line number program"),
2813 1.1 christos 0);
2814 1.1 christos return 0;
2815 1.1 christos }
2816 1.1 christos dir_len = strlen (dir);
2817 1.1 christos f_len = strlen (f);
2818 1.1 christos p = ((char *)
2819 1.1 christos backtrace_alloc (state, dir_len + f_len + 2,
2820 1.1 christos line_buf->error_callback,
2821 1.1 christos line_buf->data));
2822 1.1 christos if (p == NULL)
2823 1.1 christos return 0;
2824 1.1 christos memcpy (p, dir, dir_len);
2825 1.1 christos /* FIXME: If we are on a DOS-based file system,
2826 1.1 christos and the directory or the file name use
2827 1.1 christos backslashes, then we should use a backslash
2828 1.1 christos here. */
2829 1.1 christos p[dir_len] = '/';
2830 1.1 christos memcpy (p + dir_len + 1, f, f_len + 1);
2831 1.1 christos filename = p;
2832 1.1 christos }
2833 1.1 christos }
2834 1.1 christos break;
2835 1.1 christos case DW_LNE_set_discriminator:
2836 1.1 christos /* We don't care about discriminators. */
2837 1.1 christos read_uleb128 (line_buf);
2838 1.1 christos break;
2839 1.1 christos default:
2840 1.1 christos if (!advance (line_buf, len - 1))
2841 1.1 christos return 0;
2842 1.1 christos break;
2843 1.1 christos }
2844 1.1 christos }
2845 1.1 christos else
2846 1.1 christos {
2847 1.1 christos switch (op)
2848 1.1 christos {
2849 1.1 christos case DW_LNS_copy:
2850 1.1 christos add_line (state, ddata, address, filename, lineno,
2851 1.1 christos line_buf->error_callback, line_buf->data, vec);
2852 1.1 christos break;
2853 1.1 christos case DW_LNS_advance_pc:
2854 1.1 christos {
2855 1.1 christos uint64_t advance;
2856 1.1 christos
2857 1.1 christos advance = read_uleb128 (line_buf);
2858 1.1 christos address += (hdr->min_insn_len * (op_index + advance)
2859 1.1 christos / hdr->max_ops_per_insn);
2860 1.1 christos op_index = (op_index + advance) % hdr->max_ops_per_insn;
2861 1.1 christos }
2862 1.1 christos break;
2863 1.1 christos case DW_LNS_advance_line:
2864 1.1 christos lineno += (int) read_sleb128 (line_buf);
2865 1.1 christos break;
2866 1.1 christos case DW_LNS_set_file:
2867 1.1 christos {
2868 1.1 christos uint64_t fileno;
2869 1.1 christos
2870 1.1 christos fileno = read_uleb128 (line_buf);
2871 1.1 christos if (fileno >= hdr->filenames_count)
2872 1.1 christos {
2873 1.1 christos dwarf_buf_error (line_buf,
2874 1.1 christos ("invalid file number in "
2875 1.1 christos "line number program"),
2876 1.1 christos 0);
2877 1.1 christos return 0;
2878 1.1 christos }
2879 1.1 christos filename = hdr->filenames[fileno];
2880 1.1 christos }
2881 1.1 christos break;
2882 1.1 christos case DW_LNS_set_column:
2883 1.1 christos read_uleb128 (line_buf);
2884 1.1 christos break;
2885 1.1 christos case DW_LNS_negate_stmt:
2886 1.1 christos break;
2887 1.1 christos case DW_LNS_set_basic_block:
2888 1.1 christos break;
2889 1.1 christos case DW_LNS_const_add_pc:
2890 1.1 christos {
2891 1.1 christos unsigned int advance;
2892 1.1 christos
2893 1.1 christos op = 255 - hdr->opcode_base;
2894 1.1 christos advance = op / hdr->line_range;
2895 1.1 christos address += (hdr->min_insn_len * (op_index + advance)
2896 1.1 christos / hdr->max_ops_per_insn);
2897 1.1 christos op_index = (op_index + advance) % hdr->max_ops_per_insn;
2898 1.1 christos }
2899 1.1 christos break;
2900 1.1 christos case DW_LNS_fixed_advance_pc:
2901 1.1 christos address += read_uint16 (line_buf);
2902 1.1 christos op_index = 0;
2903 1.1 christos break;
2904 1.1 christos case DW_LNS_set_prologue_end:
2905 1.1 christos break;
2906 1.1 christos case DW_LNS_set_epilogue_begin:
2907 1.1 christos break;
2908 1.1 christos case DW_LNS_set_isa:
2909 1.1 christos read_uleb128 (line_buf);
2910 1.1 christos break;
2911 1.1 christos default:
2912 1.1 christos {
2913 1.1 christos unsigned int i;
2914 1.1 christos
2915 1.1 christos for (i = hdr->opcode_lengths[op - 1]; i > 0; --i)
2916 1.1 christos read_uleb128 (line_buf);
2917 1.1 christos }
2918 1.1 christos break;
2919 1.1 christos }
2920 1.1 christos }
2921 1.1 christos }
2922 1.1 christos
2923 1.1 christos return 1;
2924 1.1 christos }
2925 1.1 christos
2926 1.1 christos /* Read the line number information for a compilation unit. Returns 1
2927 1.1 christos on success, 0 on failure. */
2928 1.1 christos
2929 1.1 christos static int
2930 1.1 christos read_line_info (struct backtrace_state *state, struct dwarf_data *ddata,
2931 1.1 christos backtrace_error_callback error_callback, void *data,
2932 1.1 christos struct unit *u, struct line_header *hdr, struct line **lines,
2933 1.1 christos size_t *lines_count)
2934 1.1 christos {
2935 1.1 christos struct line_vector vec;
2936 1.1 christos struct dwarf_buf line_buf;
2937 1.1 christos uint64_t len;
2938 1.1 christos int is_dwarf64;
2939 1.1 christos struct line *ln;
2940 1.1 christos
2941 1.1 christos memset (&vec.vec, 0, sizeof vec.vec);
2942 1.1 christos vec.count = 0;
2943 1.1 christos
2944 1.1 christos memset (hdr, 0, sizeof *hdr);
2945 1.1 christos
2946 1.1 christos if (u->lineoff != (off_t) (size_t) u->lineoff
2947 1.1 christos || (size_t) u->lineoff >= ddata->dwarf_sections.size[DEBUG_LINE])
2948 1.1 christos {
2949 1.1 christos error_callback (data, "unit line offset out of range", 0);
2950 1.1 christos goto fail;
2951 1.1 christos }
2952 1.1 christos
2953 1.1 christos line_buf.name = ".debug_line";
2954 1.1 christos line_buf.start = ddata->dwarf_sections.data[DEBUG_LINE];
2955 1.1 christos line_buf.buf = ddata->dwarf_sections.data[DEBUG_LINE] + u->lineoff;
2956 1.1 christos line_buf.left = ddata->dwarf_sections.size[DEBUG_LINE] - u->lineoff;
2957 1.1 christos line_buf.is_bigendian = ddata->is_bigendian;
2958 1.1 christos line_buf.error_callback = error_callback;
2959 1.1 christos line_buf.data = data;
2960 1.1 christos line_buf.reported_underflow = 0;
2961 1.1 christos
2962 1.1 christos len = read_initial_length (&line_buf, &is_dwarf64);
2963 1.1 christos line_buf.left = len;
2964 1.1 christos
2965 1.1 christos if (!read_line_header (state, ddata, u, is_dwarf64, &line_buf, hdr))
2966 1.1 christos goto fail;
2967 1.1 christos
2968 1.1 christos if (!read_line_program (state, ddata, hdr, &line_buf, &vec))
2969 1.1 christos goto fail;
2970 1.1 christos
2971 1.1 christos if (line_buf.reported_underflow)
2972 1.1 christos goto fail;
2973 1.1 christos
2974 1.1 christos if (vec.count == 0)
2975 1.1 christos {
2976 1.1 christos /* This is not a failure in the sense of a generating an error,
2977 1.1 christos but it is a failure in that sense that we have no useful
2978 1.1 christos information. */
2979 1.1 christos goto fail;
2980 1.1 christos }
2981 1.1 christos
2982 1.1 christos /* Allocate one extra entry at the end. */
2983 1.1 christos ln = ((struct line *)
2984 1.1 christos backtrace_vector_grow (state, sizeof (struct line), error_callback,
2985 1.1 christos data, &vec.vec));
2986 1.1 christos if (ln == NULL)
2987 1.1 christos goto fail;
2988 1.1 christos ln->pc = (uintptr_t) -1;
2989 1.1 christos ln->filename = NULL;
2990 1.1 christos ln->lineno = 0;
2991 1.1 christos ln->idx = 0;
2992 1.1 christos
2993 1.1 christos if (!backtrace_vector_release (state, &vec.vec, error_callback, data))
2994 1.1 christos goto fail;
2995 1.1 christos
2996 1.1 christos ln = (struct line *) vec.vec.base;
2997 1.1 christos backtrace_qsort (ln, vec.count, sizeof (struct line), line_compare);
2998 1.1 christos
2999 1.1 christos *lines = ln;
3000 1.1 christos *lines_count = vec.count;
3001 1.1 christos
3002 1.1 christos return 1;
3003 1.1 christos
3004 1.1 christos fail:
3005 1.1 christos backtrace_vector_free (state, &vec.vec, error_callback, data);
3006 1.1 christos free_line_header (state, hdr, error_callback, data);
3007 1.1 christos *lines = (struct line *) (uintptr_t) -1;
3008 1.1 christos *lines_count = 0;
3009 1.1 christos return 0;
3010 1.1 christos }
3011 1.1 christos
3012 1.1 christos static const char *read_referenced_name (struct dwarf_data *, struct unit *,
3013 1.1 christos uint64_t, backtrace_error_callback,
3014 1.1 christos void *);
3015 1.1 christos
3016 1.1 christos /* Read the name of a function from a DIE referenced by ATTR with VAL. */
3017 1.1 christos
3018 1.1 christos static const char *
3019 1.1 christos read_referenced_name_from_attr (struct dwarf_data *ddata, struct unit *u,
3020 1.1 christos struct attr *attr, struct attr_val *val,
3021 1.1 christos backtrace_error_callback error_callback,
3022 1.1 christos void *data)
3023 1.1 christos {
3024 1.1 christos switch (attr->name)
3025 1.1 christos {
3026 1.1 christos case DW_AT_abstract_origin:
3027 1.1 christos case DW_AT_specification:
3028 1.1 christos break;
3029 1.1 christos default:
3030 1.1 christos return NULL;
3031 1.1 christos }
3032 1.1 christos
3033 1.1 christos if (attr->form == DW_FORM_ref_sig8)
3034 1.1 christos return NULL;
3035 1.1 christos
3036 1.1 christos if (val->encoding == ATTR_VAL_REF_INFO)
3037 1.1 christos {
3038 1.1 christos struct unit *unit
3039 1.1 christos = find_unit (ddata->units, ddata->units_count,
3040 1.1 christos val->u.uint);
3041 1.1 christos if (unit == NULL)
3042 1.1 christos return NULL;
3043 1.1 christos
3044 1.1 christos uint64_t offset = val->u.uint - unit->low_offset;
3045 1.1 christos return read_referenced_name (ddata, unit, offset, error_callback, data);
3046 1.1 christos }
3047 1.1 christos
3048 1.1 christos if (val->encoding == ATTR_VAL_UINT
3049 1.1 christos || val->encoding == ATTR_VAL_REF_UNIT)
3050 1.1 christos return read_referenced_name (ddata, u, val->u.uint, error_callback, data);
3051 1.1 christos
3052 1.1 christos if (val->encoding == ATTR_VAL_REF_ALT_INFO)
3053 1.1 christos {
3054 1.1 christos struct unit *alt_unit
3055 1.1 christos = find_unit (ddata->altlink->units, ddata->altlink->units_count,
3056 1.1 christos val->u.uint);
3057 1.1 christos if (alt_unit == NULL)
3058 1.1 christos return NULL;
3059 1.1 christos
3060 1.1 christos uint64_t offset = val->u.uint - alt_unit->low_offset;
3061 1.1 christos return read_referenced_name (ddata->altlink, alt_unit, offset,
3062 1.1 christos error_callback, data);
3063 1.1 christos }
3064 1.1 christos
3065 1.1 christos return NULL;
3066 1.1 christos }
3067 1.1 christos
3068 1.1 christos /* Read the name of a function from a DIE referenced by a
3069 1.1 christos DW_AT_abstract_origin or DW_AT_specification tag. OFFSET is within
3070 1.1 christos the same compilation unit. */
3071 1.1 christos
3072 1.1 christos static const char *
3073 1.1 christos read_referenced_name (struct dwarf_data *ddata, struct unit *u,
3074 1.1 christos uint64_t offset, backtrace_error_callback error_callback,
3075 1.1 christos void *data)
3076 1.1 christos {
3077 1.1 christos struct dwarf_buf unit_buf;
3078 1.1 christos uint64_t code;
3079 1.1 christos const struct abbrev *abbrev;
3080 1.1 christos const char *ret;
3081 1.1 christos size_t i;
3082 1.1 christos
3083 1.1 christos /* OFFSET is from the start of the data for this compilation unit.
3084 1.1 christos U->unit_data is the data, but it starts U->unit_data_offset bytes
3085 1.1 christos from the beginning. */
3086 1.1 christos
3087 1.1 christos if (offset < u->unit_data_offset
3088 1.1 christos || offset - u->unit_data_offset >= u->unit_data_len)
3089 1.1 christos {
3090 1.1 christos error_callback (data,
3091 1.1 christos "abstract origin or specification out of range",
3092 1.1 christos 0);
3093 1.1 christos return NULL;
3094 1.1 christos }
3095 1.1 christos
3096 1.1 christos offset -= u->unit_data_offset;
3097 1.1 christos
3098 1.1 christos unit_buf.name = ".debug_info";
3099 1.1 christos unit_buf.start = ddata->dwarf_sections.data[DEBUG_INFO];
3100 1.1 christos unit_buf.buf = u->unit_data + offset;
3101 1.1 christos unit_buf.left = u->unit_data_len - offset;
3102 1.1 christos unit_buf.is_bigendian = ddata->is_bigendian;
3103 1.1 christos unit_buf.error_callback = error_callback;
3104 1.1 christos unit_buf.data = data;
3105 1.1 christos unit_buf.reported_underflow = 0;
3106 1.1 christos
3107 1.1 christos code = read_uleb128 (&unit_buf);
3108 1.1 christos if (code == 0)
3109 1.1 christos {
3110 1.1 christos dwarf_buf_error (&unit_buf,
3111 1.1 christos "invalid abstract origin or specification",
3112 1.1 christos 0);
3113 1.1 christos return NULL;
3114 1.1 christos }
3115 1.1 christos
3116 1.1 christos abbrev = lookup_abbrev (&u->abbrevs, code, error_callback, data);
3117 1.1 christos if (abbrev == NULL)
3118 1.1 christos return NULL;
3119 1.1 christos
3120 1.1 christos ret = NULL;
3121 1.1 christos for (i = 0; i < abbrev->num_attrs; ++i)
3122 1.1 christos {
3123 1.1 christos struct attr_val val;
3124 1.1 christos
3125 1.1 christos if (!read_attribute (abbrev->attrs[i].form, abbrev->attrs[i].val,
3126 1.1 christos &unit_buf, u->is_dwarf64, u->version, u->addrsize,
3127 1.1 christos &ddata->dwarf_sections, ddata->altlink, &val))
3128 1.1 christos return NULL;
3129 1.1 christos
3130 1.1 christos switch (abbrev->attrs[i].name)
3131 1.1 christos {
3132 1.1 christos case DW_AT_name:
3133 1.1 christos /* Third name preference: don't override. A name we found in some
3134 1.1 christos other way, will normally be more useful -- e.g., this name is
3135 1.1 christos normally not mangled. */
3136 1.1 christos if (ret != NULL)
3137 1.1 christos break;
3138 1.1 christos if (!resolve_string (&ddata->dwarf_sections, u->is_dwarf64,
3139 1.1 christos ddata->is_bigendian, u->str_offsets_base,
3140 1.1 christos &val, error_callback, data, &ret))
3141 1.1 christos return NULL;
3142 1.1 christos break;
3143 1.1 christos
3144 1.1 christos case DW_AT_linkage_name:
3145 1.1 christos case DW_AT_MIPS_linkage_name:
3146 1.1 christos /* First name preference: override all. */
3147 1.1 christos {
3148 1.1 christos const char *s;
3149 1.1 christos
3150 1.1 christos s = NULL;
3151 1.1 christos if (!resolve_string (&ddata->dwarf_sections, u->is_dwarf64,
3152 1.1 christos ddata->is_bigendian, u->str_offsets_base,
3153 1.1 christos &val, error_callback, data, &s))
3154 1.1 christos return NULL;
3155 1.1 christos if (s != NULL)
3156 1.1 christos return s;
3157 1.1 christos }
3158 1.1 christos break;
3159 1.1 christos
3160 1.1 christos case DW_AT_specification:
3161 1.1 christos /* Second name preference: override DW_AT_name, don't override
3162 1.1 christos DW_AT_linkage_name. */
3163 1.1 christos {
3164 1.1 christos const char *name;
3165 1.1 christos
3166 1.1 christos name = read_referenced_name_from_attr (ddata, u, &abbrev->attrs[i],
3167 1.1 christos &val, error_callback, data);
3168 1.1 christos if (name != NULL)
3169 1.1 christos ret = name;
3170 1.1 christos }
3171 1.1 christos break;
3172 1.1 christos
3173 1.1 christos default:
3174 1.1 christos break;
3175 1.1 christos }
3176 1.1 christos }
3177 1.1 christos
3178 1.1 christos return ret;
3179 1.1 christos }
3180 1.1 christos
3181 1.1 christos /* Add a range to a unit that maps to a function. This is called via
3182 1.1 christos add_ranges. Returns 1 on success, 0 on error. */
3183 1.1 christos
3184 1.1 christos static int
3185 1.1 christos add_function_range (struct backtrace_state *state, void *rdata,
3186 1.1.1.1.2.1 perseant uintptr_t lowpc, uintptr_t highpc,
3187 1.1 christos backtrace_error_callback error_callback, void *data,
3188 1.1 christos void *pvec)
3189 1.1 christos {
3190 1.1 christos struct function *function = (struct function *) rdata;
3191 1.1 christos struct function_vector *vec = (struct function_vector *) pvec;
3192 1.1 christos struct function_addrs *p;
3193 1.1 christos
3194 1.1 christos if (vec->count > 0)
3195 1.1 christos {
3196 1.1 christos p = (struct function_addrs *) vec->vec.base + (vec->count - 1);
3197 1.1 christos if ((lowpc == p->high || lowpc == p->high + 1)
3198 1.1 christos && function == p->function)
3199 1.1 christos {
3200 1.1 christos if (highpc > p->high)
3201 1.1 christos p->high = highpc;
3202 1.1 christos return 1;
3203 1.1 christos }
3204 1.1 christos }
3205 1.1 christos
3206 1.1 christos p = ((struct function_addrs *)
3207 1.1 christos backtrace_vector_grow (state, sizeof (struct function_addrs),
3208 1.1 christos error_callback, data, &vec->vec));
3209 1.1 christos if (p == NULL)
3210 1.1 christos return 0;
3211 1.1 christos
3212 1.1 christos p->low = lowpc;
3213 1.1 christos p->high = highpc;
3214 1.1 christos p->function = function;
3215 1.1 christos
3216 1.1 christos ++vec->count;
3217 1.1 christos
3218 1.1 christos return 1;
3219 1.1 christos }
3220 1.1 christos
3221 1.1 christos /* Read one entry plus all its children. Add function addresses to
3222 1.1 christos VEC. Returns 1 on success, 0 on error. */
3223 1.1 christos
3224 1.1 christos static int
3225 1.1 christos read_function_entry (struct backtrace_state *state, struct dwarf_data *ddata,
3226 1.1.1.1.2.1 perseant struct unit *u, uintptr_t base, struct dwarf_buf *unit_buf,
3227 1.1 christos const struct line_header *lhdr,
3228 1.1 christos backtrace_error_callback error_callback, void *data,
3229 1.1 christos struct function_vector *vec_function,
3230 1.1 christos struct function_vector *vec_inlined)
3231 1.1 christos {
3232 1.1 christos while (unit_buf->left > 0)
3233 1.1 christos {
3234 1.1 christos uint64_t code;
3235 1.1 christos const struct abbrev *abbrev;
3236 1.1 christos int is_function;
3237 1.1 christos struct function *function;
3238 1.1 christos struct function_vector *vec;
3239 1.1 christos size_t i;
3240 1.1 christos struct pcrange pcrange;
3241 1.1 christos int have_linkage_name;
3242 1.1 christos
3243 1.1 christos code = read_uleb128 (unit_buf);
3244 1.1 christos if (code == 0)
3245 1.1 christos return 1;
3246 1.1 christos
3247 1.1 christos abbrev = lookup_abbrev (&u->abbrevs, code, error_callback, data);
3248 1.1 christos if (abbrev == NULL)
3249 1.1 christos return 0;
3250 1.1 christos
3251 1.1 christos is_function = (abbrev->tag == DW_TAG_subprogram
3252 1.1 christos || abbrev->tag == DW_TAG_entry_point
3253 1.1 christos || abbrev->tag == DW_TAG_inlined_subroutine);
3254 1.1 christos
3255 1.1 christos if (abbrev->tag == DW_TAG_inlined_subroutine)
3256 1.1 christos vec = vec_inlined;
3257 1.1 christos else
3258 1.1 christos vec = vec_function;
3259 1.1 christos
3260 1.1 christos function = NULL;
3261 1.1 christos if (is_function)
3262 1.1 christos {
3263 1.1 christos function = ((struct function *)
3264 1.1 christos backtrace_alloc (state, sizeof *function,
3265 1.1 christos error_callback, data));
3266 1.1 christos if (function == NULL)
3267 1.1 christos return 0;
3268 1.1 christos memset (function, 0, sizeof *function);
3269 1.1 christos }
3270 1.1 christos
3271 1.1 christos memset (&pcrange, 0, sizeof pcrange);
3272 1.1 christos have_linkage_name = 0;
3273 1.1 christos for (i = 0; i < abbrev->num_attrs; ++i)
3274 1.1 christos {
3275 1.1 christos struct attr_val val;
3276 1.1 christos
3277 1.1 christos if (!read_attribute (abbrev->attrs[i].form, abbrev->attrs[i].val,
3278 1.1 christos unit_buf, u->is_dwarf64, u->version,
3279 1.1 christos u->addrsize, &ddata->dwarf_sections,
3280 1.1 christos ddata->altlink, &val))
3281 1.1 christos return 0;
3282 1.1 christos
3283 1.1 christos /* The compile unit sets the base address for any address
3284 1.1 christos ranges in the function entries. */
3285 1.1.1.1.2.1 perseant if ((abbrev->tag == DW_TAG_compile_unit
3286 1.1.1.1.2.1 perseant || abbrev->tag == DW_TAG_skeleton_unit)
3287 1.1 christos && abbrev->attrs[i].name == DW_AT_low_pc)
3288 1.1 christos {
3289 1.1 christos if (val.encoding == ATTR_VAL_ADDRESS)
3290 1.1.1.1.2.1 perseant base = (uintptr_t) val.u.uint;
3291 1.1 christos else if (val.encoding == ATTR_VAL_ADDRESS_INDEX)
3292 1.1 christos {
3293 1.1 christos if (!resolve_addr_index (&ddata->dwarf_sections,
3294 1.1 christos u->addr_base, u->addrsize,
3295 1.1 christos ddata->is_bigendian, val.u.uint,
3296 1.1 christos error_callback, data, &base))
3297 1.1 christos return 0;
3298 1.1 christos }
3299 1.1 christos }
3300 1.1 christos
3301 1.1 christos if (is_function)
3302 1.1 christos {
3303 1.1 christos switch (abbrev->attrs[i].name)
3304 1.1 christos {
3305 1.1 christos case DW_AT_call_file:
3306 1.1 christos if (val.encoding == ATTR_VAL_UINT)
3307 1.1 christos {
3308 1.1 christos if (val.u.uint >= lhdr->filenames_count)
3309 1.1 christos {
3310 1.1 christos dwarf_buf_error (unit_buf,
3311 1.1 christos ("invalid file number in "
3312 1.1 christos "DW_AT_call_file attribute"),
3313 1.1 christos 0);
3314 1.1 christos return 0;
3315 1.1 christos }
3316 1.1 christos function->caller_filename = lhdr->filenames[val.u.uint];
3317 1.1 christos }
3318 1.1 christos break;
3319 1.1 christos
3320 1.1 christos case DW_AT_call_line:
3321 1.1 christos if (val.encoding == ATTR_VAL_UINT)
3322 1.1 christos function->caller_lineno = val.u.uint;
3323 1.1 christos break;
3324 1.1 christos
3325 1.1 christos case DW_AT_abstract_origin:
3326 1.1 christos case DW_AT_specification:
3327 1.1 christos /* Second name preference: override DW_AT_name, don't override
3328 1.1 christos DW_AT_linkage_name. */
3329 1.1 christos if (have_linkage_name)
3330 1.1 christos break;
3331 1.1 christos {
3332 1.1 christos const char *name;
3333 1.1 christos
3334 1.1 christos name
3335 1.1 christos = read_referenced_name_from_attr (ddata, u,
3336 1.1 christos &abbrev->attrs[i], &val,
3337 1.1 christos error_callback, data);
3338 1.1 christos if (name != NULL)
3339 1.1 christos function->name = name;
3340 1.1 christos }
3341 1.1 christos break;
3342 1.1 christos
3343 1.1 christos case DW_AT_name:
3344 1.1 christos /* Third name preference: don't override. */
3345 1.1 christos if (function->name != NULL)
3346 1.1 christos break;
3347 1.1 christos if (!resolve_string (&ddata->dwarf_sections, u->is_dwarf64,
3348 1.1 christos ddata->is_bigendian,
3349 1.1 christos u->str_offsets_base, &val,
3350 1.1 christos error_callback, data, &function->name))
3351 1.1 christos return 0;
3352 1.1 christos break;
3353 1.1 christos
3354 1.1 christos case DW_AT_linkage_name:
3355 1.1 christos case DW_AT_MIPS_linkage_name:
3356 1.1 christos /* First name preference: override all. */
3357 1.1 christos {
3358 1.1 christos const char *s;
3359 1.1 christos
3360 1.1 christos s = NULL;
3361 1.1 christos if (!resolve_string (&ddata->dwarf_sections, u->is_dwarf64,
3362 1.1 christos ddata->is_bigendian,
3363 1.1 christos u->str_offsets_base, &val,
3364 1.1 christos error_callback, data, &s))
3365 1.1 christos return 0;
3366 1.1 christos if (s != NULL)
3367 1.1 christos {
3368 1.1 christos function->name = s;
3369 1.1 christos have_linkage_name = 1;
3370 1.1 christos }
3371 1.1 christos }
3372 1.1 christos break;
3373 1.1 christos
3374 1.1 christos case DW_AT_low_pc: case DW_AT_high_pc: case DW_AT_ranges:
3375 1.1 christos update_pcrange (&abbrev->attrs[i], &val, &pcrange);
3376 1.1 christos break;
3377 1.1 christos
3378 1.1 christos default:
3379 1.1 christos break;
3380 1.1 christos }
3381 1.1 christos }
3382 1.1 christos }
3383 1.1 christos
3384 1.1 christos /* If we couldn't find a name for the function, we have no use
3385 1.1 christos for it. */
3386 1.1 christos if (is_function && function->name == NULL)
3387 1.1 christos {
3388 1.1 christos backtrace_free (state, function, sizeof *function,
3389 1.1 christos error_callback, data);
3390 1.1 christos is_function = 0;
3391 1.1 christos }
3392 1.1 christos
3393 1.1 christos if (is_function)
3394 1.1 christos {
3395 1.1 christos if (pcrange.have_ranges
3396 1.1 christos || (pcrange.have_lowpc && pcrange.have_highpc))
3397 1.1 christos {
3398 1.1 christos if (!add_ranges (state, &ddata->dwarf_sections,
3399 1.1 christos ddata->base_address, ddata->is_bigendian,
3400 1.1 christos u, base, &pcrange, add_function_range,
3401 1.1 christos (void *) function, error_callback, data,
3402 1.1 christos (void *) vec))
3403 1.1 christos return 0;
3404 1.1 christos }
3405 1.1 christos else
3406 1.1 christos {
3407 1.1 christos backtrace_free (state, function, sizeof *function,
3408 1.1 christos error_callback, data);
3409 1.1 christos is_function = 0;
3410 1.1 christos }
3411 1.1 christos }
3412 1.1 christos
3413 1.1 christos if (abbrev->has_children)
3414 1.1 christos {
3415 1.1 christos if (!is_function)
3416 1.1 christos {
3417 1.1 christos if (!read_function_entry (state, ddata, u, base, unit_buf, lhdr,
3418 1.1 christos error_callback, data, vec_function,
3419 1.1 christos vec_inlined))
3420 1.1 christos return 0;
3421 1.1 christos }
3422 1.1 christos else
3423 1.1 christos {
3424 1.1 christos struct function_vector fvec;
3425 1.1 christos
3426 1.1 christos /* Gather any information for inlined functions in
3427 1.1 christos FVEC. */
3428 1.1 christos
3429 1.1 christos memset (&fvec, 0, sizeof fvec);
3430 1.1 christos
3431 1.1 christos if (!read_function_entry (state, ddata, u, base, unit_buf, lhdr,
3432 1.1 christos error_callback, data, vec_function,
3433 1.1 christos &fvec))
3434 1.1 christos return 0;
3435 1.1 christos
3436 1.1 christos if (fvec.count > 0)
3437 1.1 christos {
3438 1.1 christos struct function_addrs *p;
3439 1.1 christos struct function_addrs *faddrs;
3440 1.1 christos
3441 1.1 christos /* Allocate a trailing entry, but don't include it
3442 1.1 christos in fvec.count. */
3443 1.1 christos p = ((struct function_addrs *)
3444 1.1 christos backtrace_vector_grow (state,
3445 1.1 christos sizeof (struct function_addrs),
3446 1.1 christos error_callback, data,
3447 1.1 christos &fvec.vec));
3448 1.1 christos if (p == NULL)
3449 1.1 christos return 0;
3450 1.1 christos p->low = 0;
3451 1.1 christos --p->low;
3452 1.1 christos p->high = p->low;
3453 1.1 christos p->function = NULL;
3454 1.1 christos
3455 1.1 christos if (!backtrace_vector_release (state, &fvec.vec,
3456 1.1 christos error_callback, data))
3457 1.1 christos return 0;
3458 1.1 christos
3459 1.1 christos faddrs = (struct function_addrs *) fvec.vec.base;
3460 1.1 christos backtrace_qsort (faddrs, fvec.count,
3461 1.1 christos sizeof (struct function_addrs),
3462 1.1 christos function_addrs_compare);
3463 1.1 christos
3464 1.1 christos function->function_addrs = faddrs;
3465 1.1 christos function->function_addrs_count = fvec.count;
3466 1.1 christos }
3467 1.1 christos }
3468 1.1 christos }
3469 1.1 christos }
3470 1.1 christos
3471 1.1 christos return 1;
3472 1.1 christos }
3473 1.1 christos
3474 1.1 christos /* Read function name information for a compilation unit. We look
3475 1.1 christos through the whole unit looking for function tags. */
3476 1.1 christos
3477 1.1 christos static void
3478 1.1 christos read_function_info (struct backtrace_state *state, struct dwarf_data *ddata,
3479 1.1 christos const struct line_header *lhdr,
3480 1.1 christos backtrace_error_callback error_callback, void *data,
3481 1.1 christos struct unit *u, struct function_vector *fvec,
3482 1.1 christos struct function_addrs **ret_addrs,
3483 1.1 christos size_t *ret_addrs_count)
3484 1.1 christos {
3485 1.1 christos struct function_vector lvec;
3486 1.1 christos struct function_vector *pfvec;
3487 1.1 christos struct dwarf_buf unit_buf;
3488 1.1 christos struct function_addrs *p;
3489 1.1 christos struct function_addrs *addrs;
3490 1.1 christos size_t addrs_count;
3491 1.1 christos
3492 1.1 christos /* Use FVEC if it is not NULL. Otherwise use our own vector. */
3493 1.1 christos if (fvec != NULL)
3494 1.1 christos pfvec = fvec;
3495 1.1 christos else
3496 1.1 christos {
3497 1.1 christos memset (&lvec, 0, sizeof lvec);
3498 1.1 christos pfvec = &lvec;
3499 1.1 christos }
3500 1.1 christos
3501 1.1 christos unit_buf.name = ".debug_info";
3502 1.1 christos unit_buf.start = ddata->dwarf_sections.data[DEBUG_INFO];
3503 1.1 christos unit_buf.buf = u->unit_data;
3504 1.1 christos unit_buf.left = u->unit_data_len;
3505 1.1 christos unit_buf.is_bigendian = ddata->is_bigendian;
3506 1.1 christos unit_buf.error_callback = error_callback;
3507 1.1 christos unit_buf.data = data;
3508 1.1 christos unit_buf.reported_underflow = 0;
3509 1.1 christos
3510 1.1 christos while (unit_buf.left > 0)
3511 1.1 christos {
3512 1.1 christos if (!read_function_entry (state, ddata, u, 0, &unit_buf, lhdr,
3513 1.1 christos error_callback, data, pfvec, pfvec))
3514 1.1 christos return;
3515 1.1 christos }
3516 1.1 christos
3517 1.1 christos if (pfvec->count == 0)
3518 1.1 christos return;
3519 1.1 christos
3520 1.1 christos /* Allocate a trailing entry, but don't include it in
3521 1.1 christos pfvec->count. */
3522 1.1 christos p = ((struct function_addrs *)
3523 1.1 christos backtrace_vector_grow (state, sizeof (struct function_addrs),
3524 1.1 christos error_callback, data, &pfvec->vec));
3525 1.1 christos if (p == NULL)
3526 1.1 christos return;
3527 1.1 christos p->low = 0;
3528 1.1 christos --p->low;
3529 1.1 christos p->high = p->low;
3530 1.1 christos p->function = NULL;
3531 1.1 christos
3532 1.1 christos addrs_count = pfvec->count;
3533 1.1 christos
3534 1.1 christos if (fvec == NULL)
3535 1.1 christos {
3536 1.1 christos if (!backtrace_vector_release (state, &lvec.vec, error_callback, data))
3537 1.1 christos return;
3538 1.1 christos addrs = (struct function_addrs *) pfvec->vec.base;
3539 1.1 christos }
3540 1.1 christos else
3541 1.1 christos {
3542 1.1 christos /* Finish this list of addresses, but leave the remaining space in
3543 1.1 christos the vector available for the next function unit. */
3544 1.1 christos addrs = ((struct function_addrs *)
3545 1.1 christos backtrace_vector_finish (state, &fvec->vec,
3546 1.1 christos error_callback, data));
3547 1.1 christos if (addrs == NULL)
3548 1.1 christos return;
3549 1.1 christos fvec->count = 0;
3550 1.1 christos }
3551 1.1 christos
3552 1.1 christos backtrace_qsort (addrs, addrs_count, sizeof (struct function_addrs),
3553 1.1 christos function_addrs_compare);
3554 1.1 christos
3555 1.1 christos *ret_addrs = addrs;
3556 1.1 christos *ret_addrs_count = addrs_count;
3557 1.1 christos }
3558 1.1 christos
3559 1.1 christos /* See if PC is inlined in FUNCTION. If it is, print out the inlined
3560 1.1 christos information, and update FILENAME and LINENO for the caller.
3561 1.1 christos Returns whatever CALLBACK returns, or 0 to keep going. */
3562 1.1 christos
3563 1.1 christos static int
3564 1.1 christos report_inlined_functions (uintptr_t pc, struct function *function,
3565 1.1 christos backtrace_full_callback callback, void *data,
3566 1.1 christos const char **filename, int *lineno)
3567 1.1 christos {
3568 1.1 christos struct function_addrs *p;
3569 1.1 christos struct function_addrs *match;
3570 1.1 christos struct function *inlined;
3571 1.1 christos int ret;
3572 1.1 christos
3573 1.1 christos if (function->function_addrs_count == 0)
3574 1.1 christos return 0;
3575 1.1 christos
3576 1.1 christos /* Our search isn't safe if pc == -1, as that is the sentinel
3577 1.1 christos value. */
3578 1.1 christos if (pc + 1 == 0)
3579 1.1 christos return 0;
3580 1.1 christos
3581 1.1 christos p = ((struct function_addrs *)
3582 1.1 christos bsearch (&pc, function->function_addrs,
3583 1.1 christos function->function_addrs_count,
3584 1.1 christos sizeof (struct function_addrs),
3585 1.1 christos function_addrs_search));
3586 1.1 christos if (p == NULL)
3587 1.1 christos return 0;
3588 1.1 christos
3589 1.1 christos /* Here pc >= p->low && pc < (p + 1)->low. The function_addrs are
3590 1.1 christos sorted by low, so if pc > p->low we are at the end of a range of
3591 1.1 christos function_addrs with the same low value. If pc == p->low walk
3592 1.1 christos forward to the end of the range with that low value. Then walk
3593 1.1 christos backward and use the first range that includes pc. */
3594 1.1 christos while (pc == (p + 1)->low)
3595 1.1 christos ++p;
3596 1.1 christos match = NULL;
3597 1.1 christos while (1)
3598 1.1 christos {
3599 1.1 christos if (pc < p->high)
3600 1.1 christos {
3601 1.1 christos match = p;
3602 1.1 christos break;
3603 1.1 christos }
3604 1.1 christos if (p == function->function_addrs)
3605 1.1 christos break;
3606 1.1 christos if ((p - 1)->low < p->low)
3607 1.1 christos break;
3608 1.1 christos --p;
3609 1.1 christos }
3610 1.1 christos if (match == NULL)
3611 1.1 christos return 0;
3612 1.1 christos
3613 1.1 christos /* We found an inlined call. */
3614 1.1 christos
3615 1.1 christos inlined = match->function;
3616 1.1 christos
3617 1.1 christos /* Report any calls inlined into this one. */
3618 1.1 christos ret = report_inlined_functions (pc, inlined, callback, data,
3619 1.1 christos filename, lineno);
3620 1.1 christos if (ret != 0)
3621 1.1 christos return ret;
3622 1.1 christos
3623 1.1 christos /* Report this inlined call. */
3624 1.1 christos ret = callback (data, pc, *filename, *lineno, inlined->name);
3625 1.1 christos if (ret != 0)
3626 1.1 christos return ret;
3627 1.1 christos
3628 1.1 christos /* Our caller will report the caller of the inlined function; tell
3629 1.1 christos it the appropriate filename and line number. */
3630 1.1 christos *filename = inlined->caller_filename;
3631 1.1 christos *lineno = inlined->caller_lineno;
3632 1.1 christos
3633 1.1 christos return 0;
3634 1.1 christos }
3635 1.1 christos
3636 1.1 christos /* Look for a PC in the DWARF mapping for one module. On success,
3637 1.1 christos call CALLBACK and return whatever it returns. On error, call
3638 1.1 christos ERROR_CALLBACK and return 0. Sets *FOUND to 1 if the PC is found,
3639 1.1 christos 0 if not. */
3640 1.1 christos
3641 1.1 christos static int
3642 1.1 christos dwarf_lookup_pc (struct backtrace_state *state, struct dwarf_data *ddata,
3643 1.1 christos uintptr_t pc, backtrace_full_callback callback,
3644 1.1 christos backtrace_error_callback error_callback, void *data,
3645 1.1 christos int *found)
3646 1.1 christos {
3647 1.1 christos struct unit_addrs *entry;
3648 1.1 christos int found_entry;
3649 1.1 christos struct unit *u;
3650 1.1 christos int new_data;
3651 1.1 christos struct line *lines;
3652 1.1 christos struct line *ln;
3653 1.1 christos struct function_addrs *p;
3654 1.1 christos struct function_addrs *fmatch;
3655 1.1 christos struct function *function;
3656 1.1 christos const char *filename;
3657 1.1 christos int lineno;
3658 1.1 christos int ret;
3659 1.1 christos
3660 1.1 christos *found = 1;
3661 1.1 christos
3662 1.1 christos /* Find an address range that includes PC. Our search isn't safe if
3663 1.1 christos PC == -1, as we use that as a sentinel value, so skip the search
3664 1.1 christos in that case. */
3665 1.1 christos entry = (ddata->addrs_count == 0 || pc + 1 == 0
3666 1.1 christos ? NULL
3667 1.1 christos : bsearch (&pc, ddata->addrs, ddata->addrs_count,
3668 1.1 christos sizeof (struct unit_addrs), unit_addrs_search));
3669 1.1 christos
3670 1.1 christos if (entry == NULL)
3671 1.1 christos {
3672 1.1 christos *found = 0;
3673 1.1 christos return 0;
3674 1.1 christos }
3675 1.1 christos
3676 1.1 christos /* Here pc >= entry->low && pc < (entry + 1)->low. The unit_addrs
3677 1.1 christos are sorted by low, so if pc > p->low we are at the end of a range
3678 1.1 christos of unit_addrs with the same low value. If pc == p->low walk
3679 1.1 christos forward to the end of the range with that low value. Then walk
3680 1.1 christos backward and use the first range that includes pc. */
3681 1.1 christos while (pc == (entry + 1)->low)
3682 1.1 christos ++entry;
3683 1.1 christos found_entry = 0;
3684 1.1 christos while (1)
3685 1.1 christos {
3686 1.1 christos if (pc < entry->high)
3687 1.1 christos {
3688 1.1 christos found_entry = 1;
3689 1.1 christos break;
3690 1.1 christos }
3691 1.1 christos if (entry == ddata->addrs)
3692 1.1 christos break;
3693 1.1 christos if ((entry - 1)->low < entry->low)
3694 1.1 christos break;
3695 1.1 christos --entry;
3696 1.1 christos }
3697 1.1 christos if (!found_entry)
3698 1.1 christos {
3699 1.1 christos *found = 0;
3700 1.1 christos return 0;
3701 1.1 christos }
3702 1.1 christos
3703 1.1 christos /* We need the lines, lines_count, function_addrs,
3704 1.1 christos function_addrs_count fields of u. If they are not set, we need
3705 1.1 christos to set them. When running in threaded mode, we need to allow for
3706 1.1 christos the possibility that some other thread is setting them
3707 1.1 christos simultaneously. */
3708 1.1 christos
3709 1.1 christos u = entry->u;
3710 1.1 christos lines = u->lines;
3711 1.1 christos
3712 1.1 christos /* Skip units with no useful line number information by walking
3713 1.1 christos backward. Useless line number information is marked by setting
3714 1.1 christos lines == -1. */
3715 1.1 christos while (entry > ddata->addrs
3716 1.1 christos && pc >= (entry - 1)->low
3717 1.1 christos && pc < (entry - 1)->high)
3718 1.1 christos {
3719 1.1 christos if (state->threaded)
3720 1.1 christos lines = (struct line *) backtrace_atomic_load_pointer (&u->lines);
3721 1.1 christos
3722 1.1 christos if (lines != (struct line *) (uintptr_t) -1)
3723 1.1 christos break;
3724 1.1 christos
3725 1.1 christos --entry;
3726 1.1 christos
3727 1.1 christos u = entry->u;
3728 1.1 christos lines = u->lines;
3729 1.1 christos }
3730 1.1 christos
3731 1.1 christos if (state->threaded)
3732 1.1 christos lines = backtrace_atomic_load_pointer (&u->lines);
3733 1.1 christos
3734 1.1 christos new_data = 0;
3735 1.1 christos if (lines == NULL)
3736 1.1 christos {
3737 1.1 christos struct function_addrs *function_addrs;
3738 1.1 christos size_t function_addrs_count;
3739 1.1 christos struct line_header lhdr;
3740 1.1 christos size_t count;
3741 1.1 christos
3742 1.1 christos /* We have never read the line information for this unit. Read
3743 1.1 christos it now. */
3744 1.1 christos
3745 1.1 christos function_addrs = NULL;
3746 1.1 christos function_addrs_count = 0;
3747 1.1 christos if (read_line_info (state, ddata, error_callback, data, entry->u, &lhdr,
3748 1.1 christos &lines, &count))
3749 1.1 christos {
3750 1.1 christos struct function_vector *pfvec;
3751 1.1 christos
3752 1.1 christos /* If not threaded, reuse DDATA->FVEC for better memory
3753 1.1 christos consumption. */
3754 1.1 christos if (state->threaded)
3755 1.1 christos pfvec = NULL;
3756 1.1 christos else
3757 1.1 christos pfvec = &ddata->fvec;
3758 1.1 christos read_function_info (state, ddata, &lhdr, error_callback, data,
3759 1.1 christos entry->u, pfvec, &function_addrs,
3760 1.1 christos &function_addrs_count);
3761 1.1 christos free_line_header (state, &lhdr, error_callback, data);
3762 1.1 christos new_data = 1;
3763 1.1 christos }
3764 1.1 christos
3765 1.1 christos /* Atomically store the information we just read into the unit.
3766 1.1 christos If another thread is simultaneously writing, it presumably
3767 1.1 christos read the same information, and we don't care which one we
3768 1.1 christos wind up with; we just leak the other one. We do have to
3769 1.1 christos write the lines field last, so that the acquire-loads above
3770 1.1 christos ensure that the other fields are set. */
3771 1.1 christos
3772 1.1 christos if (!state->threaded)
3773 1.1 christos {
3774 1.1 christos u->lines_count = count;
3775 1.1 christos u->function_addrs = function_addrs;
3776 1.1 christos u->function_addrs_count = function_addrs_count;
3777 1.1 christos u->lines = lines;
3778 1.1 christos }
3779 1.1 christos else
3780 1.1 christos {
3781 1.1 christos backtrace_atomic_store_size_t (&u->lines_count, count);
3782 1.1 christos backtrace_atomic_store_pointer (&u->function_addrs, function_addrs);
3783 1.1 christos backtrace_atomic_store_size_t (&u->function_addrs_count,
3784 1.1 christos function_addrs_count);
3785 1.1 christos backtrace_atomic_store_pointer (&u->lines, lines);
3786 1.1 christos }
3787 1.1 christos }
3788 1.1 christos
3789 1.1 christos /* Now all fields of U have been initialized. */
3790 1.1 christos
3791 1.1 christos if (lines == (struct line *) (uintptr_t) -1)
3792 1.1 christos {
3793 1.1 christos /* If reading the line number information failed in some way,
3794 1.1 christos try again to see if there is a better compilation unit for
3795 1.1 christos this PC. */
3796 1.1 christos if (new_data)
3797 1.1 christos return dwarf_lookup_pc (state, ddata, pc, callback, error_callback,
3798 1.1 christos data, found);
3799 1.1 christos return callback (data, pc, NULL, 0, NULL);
3800 1.1 christos }
3801 1.1 christos
3802 1.1 christos /* Search for PC within this unit. */
3803 1.1 christos
3804 1.1 christos ln = (struct line *) bsearch (&pc, lines, entry->u->lines_count,
3805 1.1 christos sizeof (struct line), line_search);
3806 1.1 christos if (ln == NULL)
3807 1.1 christos {
3808 1.1 christos /* The PC is between the low_pc and high_pc attributes of the
3809 1.1 christos compilation unit, but no entry in the line table covers it.
3810 1.1 christos This implies that the start of the compilation unit has no
3811 1.1 christos line number information. */
3812 1.1 christos
3813 1.1 christos if (entry->u->abs_filename == NULL)
3814 1.1 christos {
3815 1.1 christos const char *filename;
3816 1.1 christos
3817 1.1 christos filename = entry->u->filename;
3818 1.1 christos if (filename != NULL
3819 1.1 christos && !IS_ABSOLUTE_PATH (filename)
3820 1.1 christos && entry->u->comp_dir != NULL)
3821 1.1 christos {
3822 1.1 christos size_t filename_len;
3823 1.1 christos const char *dir;
3824 1.1 christos size_t dir_len;
3825 1.1 christos char *s;
3826 1.1 christos
3827 1.1 christos filename_len = strlen (filename);
3828 1.1 christos dir = entry->u->comp_dir;
3829 1.1 christos dir_len = strlen (dir);
3830 1.1 christos s = (char *) backtrace_alloc (state, dir_len + filename_len + 2,
3831 1.1 christos error_callback, data);
3832 1.1 christos if (s == NULL)
3833 1.1 christos {
3834 1.1 christos *found = 0;
3835 1.1 christos return 0;
3836 1.1 christos }
3837 1.1 christos memcpy (s, dir, dir_len);
3838 1.1 christos /* FIXME: Should use backslash if DOS file system. */
3839 1.1 christos s[dir_len] = '/';
3840 1.1 christos memcpy (s + dir_len + 1, filename, filename_len + 1);
3841 1.1 christos filename = s;
3842 1.1 christos }
3843 1.1 christos entry->u->abs_filename = filename;
3844 1.1 christos }
3845 1.1 christos
3846 1.1 christos return callback (data, pc, entry->u->abs_filename, 0, NULL);
3847 1.1 christos }
3848 1.1 christos
3849 1.1 christos /* Search for function name within this unit. */
3850 1.1 christos
3851 1.1 christos if (entry->u->function_addrs_count == 0)
3852 1.1 christos return callback (data, pc, ln->filename, ln->lineno, NULL);
3853 1.1 christos
3854 1.1 christos p = ((struct function_addrs *)
3855 1.1 christos bsearch (&pc, entry->u->function_addrs,
3856 1.1 christos entry->u->function_addrs_count,
3857 1.1 christos sizeof (struct function_addrs),
3858 1.1 christos function_addrs_search));
3859 1.1 christos if (p == NULL)
3860 1.1 christos return callback (data, pc, ln->filename, ln->lineno, NULL);
3861 1.1 christos
3862 1.1 christos /* Here pc >= p->low && pc < (p + 1)->low. The function_addrs are
3863 1.1 christos sorted by low, so if pc > p->low we are at the end of a range of
3864 1.1 christos function_addrs with the same low value. If pc == p->low walk
3865 1.1 christos forward to the end of the range with that low value. Then walk
3866 1.1 christos backward and use the first range that includes pc. */
3867 1.1 christos while (pc == (p + 1)->low)
3868 1.1 christos ++p;
3869 1.1 christos fmatch = NULL;
3870 1.1 christos while (1)
3871 1.1 christos {
3872 1.1 christos if (pc < p->high)
3873 1.1 christos {
3874 1.1 christos fmatch = p;
3875 1.1 christos break;
3876 1.1 christos }
3877 1.1 christos if (p == entry->u->function_addrs)
3878 1.1 christos break;
3879 1.1 christos if ((p - 1)->low < p->low)
3880 1.1 christos break;
3881 1.1 christos --p;
3882 1.1 christos }
3883 1.1 christos if (fmatch == NULL)
3884 1.1 christos return callback (data, pc, ln->filename, ln->lineno, NULL);
3885 1.1 christos
3886 1.1 christos function = fmatch->function;
3887 1.1 christos
3888 1.1 christos filename = ln->filename;
3889 1.1 christos lineno = ln->lineno;
3890 1.1 christos
3891 1.1 christos ret = report_inlined_functions (pc, function, callback, data,
3892 1.1 christos &filename, &lineno);
3893 1.1 christos if (ret != 0)
3894 1.1 christos return ret;
3895 1.1 christos
3896 1.1 christos return callback (data, pc, filename, lineno, function->name);
3897 1.1 christos }
3898 1.1 christos
3899 1.1 christos
3900 1.1 christos /* Return the file/line information for a PC using the DWARF mapping
3901 1.1 christos we built earlier. */
3902 1.1 christos
3903 1.1 christos static int
3904 1.1 christos dwarf_fileline (struct backtrace_state *state, uintptr_t pc,
3905 1.1 christos backtrace_full_callback callback,
3906 1.1 christos backtrace_error_callback error_callback, void *data)
3907 1.1 christos {
3908 1.1 christos struct dwarf_data *ddata;
3909 1.1 christos int found;
3910 1.1 christos int ret;
3911 1.1 christos
3912 1.1 christos if (!state->threaded)
3913 1.1 christos {
3914 1.1 christos for (ddata = (struct dwarf_data *) state->fileline_data;
3915 1.1 christos ddata != NULL;
3916 1.1 christos ddata = ddata->next)
3917 1.1 christos {
3918 1.1 christos ret = dwarf_lookup_pc (state, ddata, pc, callback, error_callback,
3919 1.1 christos data, &found);
3920 1.1 christos if (ret != 0 || found)
3921 1.1 christos return ret;
3922 1.1 christos }
3923 1.1 christos }
3924 1.1 christos else
3925 1.1 christos {
3926 1.1 christos struct dwarf_data **pp;
3927 1.1 christos
3928 1.1 christos pp = (struct dwarf_data **) (void *) &state->fileline_data;
3929 1.1 christos while (1)
3930 1.1 christos {
3931 1.1 christos ddata = backtrace_atomic_load_pointer (pp);
3932 1.1 christos if (ddata == NULL)
3933 1.1 christos break;
3934 1.1 christos
3935 1.1 christos ret = dwarf_lookup_pc (state, ddata, pc, callback, error_callback,
3936 1.1 christos data, &found);
3937 1.1 christos if (ret != 0 || found)
3938 1.1 christos return ret;
3939 1.1 christos
3940 1.1 christos pp = &ddata->next;
3941 1.1 christos }
3942 1.1 christos }
3943 1.1 christos
3944 1.1 christos /* FIXME: See if any libraries have been dlopen'ed. */
3945 1.1 christos
3946 1.1 christos return callback (data, pc, NULL, 0, NULL);
3947 1.1 christos }
3948 1.1 christos
3949 1.1 christos /* Initialize our data structures from the DWARF debug info for a
3950 1.1 christos file. Return NULL on failure. */
3951 1.1 christos
3952 1.1 christos static struct dwarf_data *
3953 1.1 christos build_dwarf_data (struct backtrace_state *state,
3954 1.1 christos uintptr_t base_address,
3955 1.1 christos const struct dwarf_sections *dwarf_sections,
3956 1.1 christos int is_bigendian,
3957 1.1 christos struct dwarf_data *altlink,
3958 1.1 christos backtrace_error_callback error_callback,
3959 1.1 christos void *data)
3960 1.1 christos {
3961 1.1 christos struct unit_addrs_vector addrs_vec;
3962 1.1 christos struct unit_addrs *addrs;
3963 1.1 christos size_t addrs_count;
3964 1.1 christos struct unit_vector units_vec;
3965 1.1 christos struct unit **units;
3966 1.1 christos size_t units_count;
3967 1.1 christos struct dwarf_data *fdata;
3968 1.1 christos
3969 1.1 christos if (!build_address_map (state, base_address, dwarf_sections, is_bigendian,
3970 1.1 christos altlink, error_callback, data, &addrs_vec,
3971 1.1 christos &units_vec))
3972 1.1 christos return NULL;
3973 1.1 christos
3974 1.1 christos if (!backtrace_vector_release (state, &addrs_vec.vec, error_callback, data))
3975 1.1 christos return NULL;
3976 1.1 christos if (!backtrace_vector_release (state, &units_vec.vec, error_callback, data))
3977 1.1 christos return NULL;
3978 1.1 christos addrs = (struct unit_addrs *) addrs_vec.vec.base;
3979 1.1 christos units = (struct unit **) units_vec.vec.base;
3980 1.1 christos addrs_count = addrs_vec.count;
3981 1.1 christos units_count = units_vec.count;
3982 1.1 christos backtrace_qsort (addrs, addrs_count, sizeof (struct unit_addrs),
3983 1.1 christos unit_addrs_compare);
3984 1.1 christos /* No qsort for units required, already sorted. */
3985 1.1 christos
3986 1.1 christos fdata = ((struct dwarf_data *)
3987 1.1 christos backtrace_alloc (state, sizeof (struct dwarf_data),
3988 1.1 christos error_callback, data));
3989 1.1 christos if (fdata == NULL)
3990 1.1 christos return NULL;
3991 1.1 christos
3992 1.1 christos fdata->next = NULL;
3993 1.1 christos fdata->altlink = altlink;
3994 1.1 christos fdata->base_address = base_address;
3995 1.1 christos fdata->addrs = addrs;
3996 1.1 christos fdata->addrs_count = addrs_count;
3997 1.1 christos fdata->units = units;
3998 1.1 christos fdata->units_count = units_count;
3999 1.1 christos fdata->dwarf_sections = *dwarf_sections;
4000 1.1 christos fdata->is_bigendian = is_bigendian;
4001 1.1 christos memset (&fdata->fvec, 0, sizeof fdata->fvec);
4002 1.1 christos
4003 1.1 christos return fdata;
4004 1.1 christos }
4005 1.1 christos
4006 1.1 christos /* Build our data structures from the DWARF sections for a module.
4007 1.1 christos Set FILELINE_FN and STATE->FILELINE_DATA. Return 1 on success, 0
4008 1.1 christos on failure. */
4009 1.1 christos
4010 1.1 christos int
4011 1.1 christos backtrace_dwarf_add (struct backtrace_state *state,
4012 1.1 christos uintptr_t base_address,
4013 1.1 christos const struct dwarf_sections *dwarf_sections,
4014 1.1 christos int is_bigendian,
4015 1.1 christos struct dwarf_data *fileline_altlink,
4016 1.1 christos backtrace_error_callback error_callback,
4017 1.1 christos void *data, fileline *fileline_fn,
4018 1.1 christos struct dwarf_data **fileline_entry)
4019 1.1 christos {
4020 1.1 christos struct dwarf_data *fdata;
4021 1.1 christos
4022 1.1 christos fdata = build_dwarf_data (state, base_address, dwarf_sections, is_bigendian,
4023 1.1 christos fileline_altlink, error_callback, data);
4024 1.1 christos if (fdata == NULL)
4025 1.1 christos return 0;
4026 1.1 christos
4027 1.1 christos if (fileline_entry != NULL)
4028 1.1 christos *fileline_entry = fdata;
4029 1.1 christos
4030 1.1 christos if (!state->threaded)
4031 1.1 christos {
4032 1.1 christos struct dwarf_data **pp;
4033 1.1 christos
4034 1.1 christos for (pp = (struct dwarf_data **) (void *) &state->fileline_data;
4035 1.1 christos *pp != NULL;
4036 1.1 christos pp = &(*pp)->next)
4037 1.1 christos ;
4038 1.1 christos *pp = fdata;
4039 1.1 christos }
4040 1.1 christos else
4041 1.1 christos {
4042 1.1 christos while (1)
4043 1.1 christos {
4044 1.1 christos struct dwarf_data **pp;
4045 1.1 christos
4046 1.1 christos pp = (struct dwarf_data **) (void *) &state->fileline_data;
4047 1.1 christos
4048 1.1 christos while (1)
4049 1.1 christos {
4050 1.1 christos struct dwarf_data *p;
4051 1.1 christos
4052 1.1 christos p = backtrace_atomic_load_pointer (pp);
4053 1.1 christos
4054 1.1 christos if (p == NULL)
4055 1.1 christos break;
4056 1.1 christos
4057 1.1 christos pp = &p->next;
4058 1.1 christos }
4059 1.1 christos
4060 1.1 christos if (__sync_bool_compare_and_swap (pp, NULL, fdata))
4061 1.1 christos break;
4062 1.1 christos }
4063 1.1 christos }
4064 1.1 christos
4065 1.1 christos *fileline_fn = dwarf_fileline;
4066 1.1 christos
4067 1.1 christos return 1;
4068 1.1 christos }
4069