dwarf.c revision 1.1.1.1 1 1.1 christos /* dwarf.c -- Get file/line information from DWARF for backtraces.
2 1.1 christos Copyright (C) 2012-2021 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 christos * 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 christos uint64_t low;
278 1.1 christos uint64_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 christos uint64_t low;
360 1.1 christos uint64_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 christos uint64_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 christos *address = 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 christos uint64_t lowpc, uint64_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 christos uint64_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 christos uint64_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 christos pcrange->lowpc = 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 christos pcrange->lowpc = 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 christos pcrange->highpc = 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 christos pcrange->highpc = 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 christos pcrange->highpc = 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 christos void *rdata, uint64_t lowpc,
1617 1.1 christos uint64_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 christos uint64_t lowpc;
1625 1.1 christos uint64_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 christos struct unit *u, uint64_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 christos uint64_t lowpc, uint64_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 christos base = high;
1706 1.1 christos else
1707 1.1 christos {
1708 1.1 christos if (!add_range (state, rdata,
1709 1.1 christos low + base + base_address,
1710 1.1 christos 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 christos struct unit *u, uint64_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 christos uint64_t lowpc, uint64_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 christos uint64_t low;
1800 1.1 christos uint64_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 christos uint64_t low;
1823 1.1 christos uint64_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 christos base = 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 christos uint64_t low;
1859 1.1 christos uint64_t high;
1860 1.1 christos
1861 1.1 christos low = read_address (&rnglists_buf, u->addrsize);
1862 1.1 christos high = 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 christos uint64_t low;
1873 1.1 christos uint64_t length;
1874 1.1 christos
1875 1.1 christos low = read_address (&rnglists_buf, u->addrsize);
1876 1.1 christos length = 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 christos struct unit *u, uint64_t base, const struct pcrange *pcrange,
1907 1.1 christos int (*add_range) (struct backtrace_state *state, void *rdata,
1908 1.1 christos uint64_t lowpc, uint64_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 christos if (abbrev->tag == DW_TAG_compile_unit
1993 1.1 christos && (val.encoding == ATTR_VAL_UINT
1994 1.1 christos || val.encoding == ATTR_VAL_REF_SECTION))
1995 1.1 christos u->lineoff = val.u.uint;
1996 1.1 christos break;
1997 1.1 christos
1998 1.1 christos case DW_AT_name:
1999 1.1 christos if (abbrev->tag == DW_TAG_compile_unit)
2000 1.1 christos {
2001 1.1 christos name_val = val;
2002 1.1 christos have_name_val = 1;
2003 1.1 christos }
2004 1.1 christos break;
2005 1.1 christos
2006 1.1 christos case DW_AT_comp_dir:
2007 1.1 christos if (abbrev->tag == DW_TAG_compile_unit)
2008 1.1 christos {
2009 1.1 christos comp_dir_val = val;
2010 1.1 christos have_comp_dir_val = 1;
2011 1.1 christos }
2012 1.1 christos break;
2013 1.1 christos
2014 1.1 christos case DW_AT_str_offsets_base:
2015 1.1 christos if (abbrev->tag == DW_TAG_compile_unit
2016 1.1 christos && val.encoding == ATTR_VAL_REF_SECTION)
2017 1.1 christos u->str_offsets_base = val.u.uint;
2018 1.1 christos break;
2019 1.1 christos
2020 1.1 christos case DW_AT_addr_base:
2021 1.1 christos if (abbrev->tag == DW_TAG_compile_unit
2022 1.1 christos && val.encoding == ATTR_VAL_REF_SECTION)
2023 1.1 christos u->addr_base = val.u.uint;
2024 1.1 christos break;
2025 1.1 christos
2026 1.1 christos case DW_AT_rnglists_base:
2027 1.1 christos if (abbrev->tag == DW_TAG_compile_unit
2028 1.1 christos && val.encoding == ATTR_VAL_REF_SECTION)
2029 1.1 christos u->rnglists_base = val.u.uint;
2030 1.1 christos break;
2031 1.1 christos
2032 1.1 christos default:
2033 1.1 christos break;
2034 1.1 christos }
2035 1.1 christos }
2036 1.1 christos
2037 1.1 christos // Resolve strings after we're sure that we have seen
2038 1.1 christos // DW_AT_str_offsets_base.
2039 1.1 christos if (have_name_val)
2040 1.1 christos {
2041 1.1 christos if (!resolve_string (dwarf_sections, u->is_dwarf64, is_bigendian,
2042 1.1 christos u->str_offsets_base, &name_val,
2043 1.1 christos error_callback, data, &u->filename))
2044 1.1 christos return 0;
2045 1.1 christos }
2046 1.1 christos if (have_comp_dir_val)
2047 1.1 christos {
2048 1.1 christos if (!resolve_string (dwarf_sections, u->is_dwarf64, is_bigendian,
2049 1.1 christos u->str_offsets_base, &comp_dir_val,
2050 1.1 christos error_callback, data, &u->comp_dir))
2051 1.1 christos return 0;
2052 1.1 christos }
2053 1.1 christos
2054 1.1 christos if (abbrev->tag == DW_TAG_compile_unit
2055 1.1 christos || abbrev->tag == DW_TAG_subprogram)
2056 1.1 christos {
2057 1.1 christos if (!add_ranges (state, dwarf_sections, base_address,
2058 1.1 christos is_bigendian, u, pcrange.lowpc, &pcrange,
2059 1.1 christos add_unit_addr, (void *) u, error_callback, data,
2060 1.1 christos (void *) addrs))
2061 1.1 christos return 0;
2062 1.1 christos
2063 1.1 christos /* If we found the PC range in the DW_TAG_compile_unit, we
2064 1.1 christos can stop now. */
2065 1.1 christos if (abbrev->tag == DW_TAG_compile_unit
2066 1.1 christos && (pcrange.have_ranges
2067 1.1 christos || (pcrange.have_lowpc && pcrange.have_highpc)))
2068 1.1 christos return 1;
2069 1.1 christos }
2070 1.1 christos
2071 1.1 christos if (abbrev->has_children)
2072 1.1 christos {
2073 1.1 christos if (!find_address_ranges (state, base_address, unit_buf,
2074 1.1 christos dwarf_sections, is_bigendian, altlink,
2075 1.1 christos error_callback, data, u, addrs, NULL))
2076 1.1 christos return 0;
2077 1.1 christos }
2078 1.1 christos }
2079 1.1 christos
2080 1.1 christos return 1;
2081 1.1 christos }
2082 1.1 christos
2083 1.1 christos /* Build a mapping from address ranges to the compilation units where
2084 1.1 christos the line number information for that range can be found. Returns 1
2085 1.1 christos on success, 0 on failure. */
2086 1.1 christos
2087 1.1 christos static int
2088 1.1 christos build_address_map (struct backtrace_state *state, uintptr_t base_address,
2089 1.1 christos const struct dwarf_sections *dwarf_sections,
2090 1.1 christos int is_bigendian, struct dwarf_data *altlink,
2091 1.1 christos backtrace_error_callback error_callback, void *data,
2092 1.1 christos struct unit_addrs_vector *addrs,
2093 1.1 christos struct unit_vector *unit_vec)
2094 1.1 christos {
2095 1.1 christos struct dwarf_buf info;
2096 1.1 christos struct backtrace_vector units;
2097 1.1 christos size_t units_count;
2098 1.1 christos size_t i;
2099 1.1 christos struct unit **pu;
2100 1.1 christos size_t unit_offset = 0;
2101 1.1 christos struct unit_addrs *pa;
2102 1.1 christos
2103 1.1 christos memset (&addrs->vec, 0, sizeof addrs->vec);
2104 1.1 christos memset (&unit_vec->vec, 0, sizeof unit_vec->vec);
2105 1.1 christos addrs->count = 0;
2106 1.1 christos unit_vec->count = 0;
2107 1.1 christos
2108 1.1 christos /* Read through the .debug_info section. FIXME: Should we use the
2109 1.1 christos .debug_aranges section? gdb and addr2line don't use it, but I'm
2110 1.1 christos not sure why. */
2111 1.1 christos
2112 1.1 christos info.name = ".debug_info";
2113 1.1 christos info.start = dwarf_sections->data[DEBUG_INFO];
2114 1.1 christos info.buf = info.start;
2115 1.1 christos info.left = dwarf_sections->size[DEBUG_INFO];
2116 1.1 christos info.is_bigendian = is_bigendian;
2117 1.1 christos info.error_callback = error_callback;
2118 1.1 christos info.data = data;
2119 1.1 christos info.reported_underflow = 0;
2120 1.1 christos
2121 1.1 christos memset (&units, 0, sizeof units);
2122 1.1 christos units_count = 0;
2123 1.1 christos
2124 1.1 christos while (info.left > 0)
2125 1.1 christos {
2126 1.1 christos const unsigned char *unit_data_start;
2127 1.1 christos uint64_t len;
2128 1.1 christos int is_dwarf64;
2129 1.1 christos struct dwarf_buf unit_buf;
2130 1.1 christos int version;
2131 1.1 christos int unit_type;
2132 1.1 christos uint64_t abbrev_offset;
2133 1.1 christos int addrsize;
2134 1.1 christos struct unit *u;
2135 1.1 christos enum dwarf_tag unit_tag;
2136 1.1 christos
2137 1.1 christos if (info.reported_underflow)
2138 1.1 christos goto fail;
2139 1.1 christos
2140 1.1 christos unit_data_start = info.buf;
2141 1.1 christos
2142 1.1 christos len = read_initial_length (&info, &is_dwarf64);
2143 1.1 christos unit_buf = info;
2144 1.1 christos unit_buf.left = len;
2145 1.1 christos
2146 1.1 christos if (!advance (&info, len))
2147 1.1 christos goto fail;
2148 1.1 christos
2149 1.1 christos version = read_uint16 (&unit_buf);
2150 1.1 christos if (version < 2 || version > 5)
2151 1.1 christos {
2152 1.1 christos dwarf_buf_error (&unit_buf, "unrecognized DWARF version", -1);
2153 1.1 christos goto fail;
2154 1.1 christos }
2155 1.1 christos
2156 1.1 christos if (version < 5)
2157 1.1 christos unit_type = 0;
2158 1.1 christos else
2159 1.1 christos {
2160 1.1 christos unit_type = read_byte (&unit_buf);
2161 1.1 christos if (unit_type == DW_UT_type || unit_type == DW_UT_split_type)
2162 1.1 christos {
2163 1.1 christos /* This unit doesn't have anything we need. */
2164 1.1 christos continue;
2165 1.1 christos }
2166 1.1 christos }
2167 1.1 christos
2168 1.1 christos pu = ((struct unit **)
2169 1.1 christos backtrace_vector_grow (state, sizeof (struct unit *),
2170 1.1 christos error_callback, data, &units));
2171 1.1 christos if (pu == NULL)
2172 1.1 christos goto fail;
2173 1.1 christos
2174 1.1 christos u = ((struct unit *)
2175 1.1 christos backtrace_alloc (state, sizeof *u, error_callback, data));
2176 1.1 christos if (u == NULL)
2177 1.1 christos goto fail;
2178 1.1 christos
2179 1.1 christos *pu = u;
2180 1.1 christos ++units_count;
2181 1.1 christos
2182 1.1 christos if (version < 5)
2183 1.1 christos addrsize = 0; /* Set below. */
2184 1.1 christos else
2185 1.1 christos addrsize = read_byte (&unit_buf);
2186 1.1 christos
2187 1.1 christos memset (&u->abbrevs, 0, sizeof u->abbrevs);
2188 1.1 christos abbrev_offset = read_offset (&unit_buf, is_dwarf64);
2189 1.1 christos if (!read_abbrevs (state, abbrev_offset,
2190 1.1 christos dwarf_sections->data[DEBUG_ABBREV],
2191 1.1 christos dwarf_sections->size[DEBUG_ABBREV],
2192 1.1 christos is_bigendian, error_callback, data, &u->abbrevs))
2193 1.1 christos goto fail;
2194 1.1 christos
2195 1.1 christos if (version < 5)
2196 1.1 christos addrsize = read_byte (&unit_buf);
2197 1.1 christos
2198 1.1 christos switch (unit_type)
2199 1.1 christos {
2200 1.1 christos case 0:
2201 1.1 christos break;
2202 1.1 christos case DW_UT_compile: case DW_UT_partial:
2203 1.1 christos break;
2204 1.1 christos case DW_UT_skeleton: case DW_UT_split_compile:
2205 1.1 christos read_uint64 (&unit_buf); /* dwo_id */
2206 1.1 christos break;
2207 1.1 christos default:
2208 1.1 christos break;
2209 1.1 christos }
2210 1.1 christos
2211 1.1 christos u->low_offset = unit_offset;
2212 1.1 christos unit_offset += len + (is_dwarf64 ? 12 : 4);
2213 1.1 christos u->high_offset = unit_offset;
2214 1.1 christos u->unit_data = unit_buf.buf;
2215 1.1 christos u->unit_data_len = unit_buf.left;
2216 1.1 christos u->unit_data_offset = unit_buf.buf - unit_data_start;
2217 1.1 christos u->version = version;
2218 1.1 christos u->is_dwarf64 = is_dwarf64;
2219 1.1 christos u->addrsize = addrsize;
2220 1.1 christos u->filename = NULL;
2221 1.1 christos u->comp_dir = NULL;
2222 1.1 christos u->abs_filename = NULL;
2223 1.1 christos u->lineoff = 0;
2224 1.1 christos
2225 1.1 christos /* The actual line number mappings will be read as needed. */
2226 1.1 christos u->lines = NULL;
2227 1.1 christos u->lines_count = 0;
2228 1.1 christos u->function_addrs = NULL;
2229 1.1 christos u->function_addrs_count = 0;
2230 1.1 christos
2231 1.1 christos if (!find_address_ranges (state, base_address, &unit_buf, dwarf_sections,
2232 1.1 christos is_bigendian, altlink, error_callback, data,
2233 1.1 christos u, addrs, &unit_tag))
2234 1.1 christos goto fail;
2235 1.1 christos
2236 1.1 christos if (unit_buf.reported_underflow)
2237 1.1 christos goto fail;
2238 1.1 christos }
2239 1.1 christos if (info.reported_underflow)
2240 1.1 christos goto fail;
2241 1.1 christos
2242 1.1 christos /* Add a trailing addrs entry, but don't include it in addrs->count. */
2243 1.1 christos pa = ((struct unit_addrs *)
2244 1.1 christos backtrace_vector_grow (state, sizeof (struct unit_addrs),
2245 1.1 christos error_callback, data, &addrs->vec));
2246 1.1 christos if (pa == NULL)
2247 1.1 christos goto fail;
2248 1.1 christos pa->low = 0;
2249 1.1 christos --pa->low;
2250 1.1 christos pa->high = pa->low;
2251 1.1 christos pa->u = NULL;
2252 1.1 christos
2253 1.1 christos unit_vec->vec = units;
2254 1.1 christos unit_vec->count = units_count;
2255 1.1 christos return 1;
2256 1.1 christos
2257 1.1 christos fail:
2258 1.1 christos if (units_count > 0)
2259 1.1 christos {
2260 1.1 christos pu = (struct unit **) units.base;
2261 1.1 christos for (i = 0; i < units_count; i++)
2262 1.1 christos {
2263 1.1 christos free_abbrevs (state, &pu[i]->abbrevs, error_callback, data);
2264 1.1 christos backtrace_free (state, pu[i], sizeof **pu, error_callback, data);
2265 1.1 christos }
2266 1.1 christos backtrace_vector_free (state, &units, error_callback, data);
2267 1.1 christos }
2268 1.1 christos if (addrs->count > 0)
2269 1.1 christos {
2270 1.1 christos backtrace_vector_free (state, &addrs->vec, error_callback, data);
2271 1.1 christos addrs->count = 0;
2272 1.1 christos }
2273 1.1 christos return 0;
2274 1.1 christos }
2275 1.1 christos
2276 1.1 christos /* Add a new mapping to the vector of line mappings that we are
2277 1.1 christos building. Returns 1 on success, 0 on failure. */
2278 1.1 christos
2279 1.1 christos static int
2280 1.1 christos add_line (struct backtrace_state *state, struct dwarf_data *ddata,
2281 1.1 christos uintptr_t pc, const char *filename, int lineno,
2282 1.1 christos backtrace_error_callback error_callback, void *data,
2283 1.1 christos struct line_vector *vec)
2284 1.1 christos {
2285 1.1 christos struct line *ln;
2286 1.1 christos
2287 1.1 christos /* If we are adding the same mapping, ignore it. This can happen
2288 1.1 christos when using discriminators. */
2289 1.1 christos if (vec->count > 0)
2290 1.1 christos {
2291 1.1 christos ln = (struct line *) vec->vec.base + (vec->count - 1);
2292 1.1 christos if (pc == ln->pc && filename == ln->filename && lineno == ln->lineno)
2293 1.1 christos return 1;
2294 1.1 christos }
2295 1.1 christos
2296 1.1 christos ln = ((struct line *)
2297 1.1 christos backtrace_vector_grow (state, sizeof (struct line), error_callback,
2298 1.1 christos data, &vec->vec));
2299 1.1 christos if (ln == NULL)
2300 1.1 christos return 0;
2301 1.1 christos
2302 1.1 christos /* Add in the base address here, so that we can look up the PC
2303 1.1 christos directly. */
2304 1.1 christos ln->pc = pc + ddata->base_address;
2305 1.1 christos
2306 1.1 christos ln->filename = filename;
2307 1.1 christos ln->lineno = lineno;
2308 1.1 christos ln->idx = vec->count;
2309 1.1 christos
2310 1.1 christos ++vec->count;
2311 1.1 christos
2312 1.1 christos return 1;
2313 1.1 christos }
2314 1.1 christos
2315 1.1 christos /* Free the line header information. */
2316 1.1 christos
2317 1.1 christos static void
2318 1.1 christos free_line_header (struct backtrace_state *state, struct line_header *hdr,
2319 1.1 christos backtrace_error_callback error_callback, void *data)
2320 1.1 christos {
2321 1.1 christos if (hdr->dirs_count != 0)
2322 1.1 christos backtrace_free (state, hdr->dirs, hdr->dirs_count * sizeof (const char *),
2323 1.1 christos error_callback, data);
2324 1.1 christos backtrace_free (state, hdr->filenames,
2325 1.1 christos hdr->filenames_count * sizeof (char *),
2326 1.1 christos error_callback, data);
2327 1.1 christos }
2328 1.1 christos
2329 1.1 christos /* Read the directories and file names for a line header for version
2330 1.1 christos 2, setting fields in HDR. Return 1 on success, 0 on failure. */
2331 1.1 christos
2332 1.1 christos static int
2333 1.1 christos read_v2_paths (struct backtrace_state *state, struct unit *u,
2334 1.1 christos struct dwarf_buf *hdr_buf, struct line_header *hdr)
2335 1.1 christos {
2336 1.1 christos const unsigned char *p;
2337 1.1 christos const unsigned char *pend;
2338 1.1 christos size_t i;
2339 1.1 christos
2340 1.1 christos /* Count the number of directory entries. */
2341 1.1 christos hdr->dirs_count = 0;
2342 1.1 christos p = hdr_buf->buf;
2343 1.1 christos pend = p + hdr_buf->left;
2344 1.1 christos while (p < pend && *p != '\0')
2345 1.1 christos {
2346 1.1 christos p += strnlen((const char *) p, pend - p) + 1;
2347 1.1 christos ++hdr->dirs_count;
2348 1.1 christos }
2349 1.1 christos
2350 1.1 christos /* The index of the first entry in the list of directories is 1. Index 0 is
2351 1.1 christos used for the current directory of the compilation. To simplify index
2352 1.1 christos handling, we set entry 0 to the compilation unit directory. */
2353 1.1 christos ++hdr->dirs_count;
2354 1.1 christos hdr->dirs = ((const char **)
2355 1.1 christos backtrace_alloc (state,
2356 1.1 christos hdr->dirs_count * sizeof (const char *),
2357 1.1 christos hdr_buf->error_callback,
2358 1.1 christos hdr_buf->data));
2359 1.1 christos if (hdr->dirs == NULL)
2360 1.1 christos return 0;
2361 1.1 christos
2362 1.1 christos hdr->dirs[0] = u->comp_dir;
2363 1.1 christos i = 1;
2364 1.1 christos while (*hdr_buf->buf != '\0')
2365 1.1 christos {
2366 1.1 christos if (hdr_buf->reported_underflow)
2367 1.1 christos return 0;
2368 1.1 christos
2369 1.1 christos hdr->dirs[i] = read_string (hdr_buf);
2370 1.1 christos if (hdr->dirs[i] == NULL)
2371 1.1 christos return 0;
2372 1.1 christos ++i;
2373 1.1 christos }
2374 1.1 christos if (!advance (hdr_buf, 1))
2375 1.1 christos return 0;
2376 1.1 christos
2377 1.1 christos /* Count the number of file entries. */
2378 1.1 christos hdr->filenames_count = 0;
2379 1.1 christos p = hdr_buf->buf;
2380 1.1 christos pend = p + hdr_buf->left;
2381 1.1 christos while (p < pend && *p != '\0')
2382 1.1 christos {
2383 1.1 christos p += strnlen ((const char *) p, pend - p) + 1;
2384 1.1 christos p += leb128_len (p);
2385 1.1 christos p += leb128_len (p);
2386 1.1 christos p += leb128_len (p);
2387 1.1 christos ++hdr->filenames_count;
2388 1.1 christos }
2389 1.1 christos
2390 1.1 christos /* The index of the first entry in the list of file names is 1. Index 0 is
2391 1.1 christos used for the DW_AT_name of the compilation unit. To simplify index
2392 1.1 christos handling, we set entry 0 to the compilation unit file name. */
2393 1.1 christos ++hdr->filenames_count;
2394 1.1 christos hdr->filenames = ((const char **)
2395 1.1 christos backtrace_alloc (state,
2396 1.1 christos hdr->filenames_count * sizeof (char *),
2397 1.1 christos hdr_buf->error_callback,
2398 1.1 christos hdr_buf->data));
2399 1.1 christos if (hdr->filenames == NULL)
2400 1.1 christos return 0;
2401 1.1 christos hdr->filenames[0] = u->filename;
2402 1.1 christos i = 1;
2403 1.1 christos while (*hdr_buf->buf != '\0')
2404 1.1 christos {
2405 1.1 christos const char *filename;
2406 1.1 christos uint64_t dir_index;
2407 1.1 christos
2408 1.1 christos if (hdr_buf->reported_underflow)
2409 1.1 christos return 0;
2410 1.1 christos
2411 1.1 christos filename = read_string (hdr_buf);
2412 1.1 christos if (filename == NULL)
2413 1.1 christos return 0;
2414 1.1 christos dir_index = read_uleb128 (hdr_buf);
2415 1.1 christos if (IS_ABSOLUTE_PATH (filename)
2416 1.1 christos || (dir_index < hdr->dirs_count && hdr->dirs[dir_index] == NULL))
2417 1.1 christos hdr->filenames[i] = filename;
2418 1.1 christos else
2419 1.1 christos {
2420 1.1 christos const char *dir;
2421 1.1 christos size_t dir_len;
2422 1.1 christos size_t filename_len;
2423 1.1 christos char *s;
2424 1.1 christos
2425 1.1 christos if (dir_index < hdr->dirs_count)
2426 1.1 christos dir = hdr->dirs[dir_index];
2427 1.1 christos else
2428 1.1 christos {
2429 1.1 christos dwarf_buf_error (hdr_buf,
2430 1.1 christos ("invalid directory index in "
2431 1.1 christos "line number program header"),
2432 1.1 christos 0);
2433 1.1 christos return 0;
2434 1.1 christos }
2435 1.1 christos dir_len = strlen (dir);
2436 1.1 christos filename_len = strlen (filename);
2437 1.1 christos s = ((char *) backtrace_alloc (state, dir_len + filename_len + 2,
2438 1.1 christos hdr_buf->error_callback,
2439 1.1 christos hdr_buf->data));
2440 1.1 christos if (s == NULL)
2441 1.1 christos return 0;
2442 1.1 christos memcpy (s, dir, dir_len);
2443 1.1 christos /* FIXME: If we are on a DOS-based file system, and the
2444 1.1 christos directory or the file name use backslashes, then we
2445 1.1 christos should use a backslash here. */
2446 1.1 christos s[dir_len] = '/';
2447 1.1 christos memcpy (s + dir_len + 1, filename, filename_len + 1);
2448 1.1 christos hdr->filenames[i] = s;
2449 1.1 christos }
2450 1.1 christos
2451 1.1 christos /* Ignore the modification time and size. */
2452 1.1 christos read_uleb128 (hdr_buf);
2453 1.1 christos read_uleb128 (hdr_buf);
2454 1.1 christos
2455 1.1 christos ++i;
2456 1.1 christos }
2457 1.1 christos
2458 1.1 christos return 1;
2459 1.1 christos }
2460 1.1 christos
2461 1.1 christos /* Read a single version 5 LNCT entry for a directory or file name in a
2462 1.1 christos line header. Sets *STRING to the resulting name, ignoring other
2463 1.1 christos data. Return 1 on success, 0 on failure. */
2464 1.1 christos
2465 1.1 christos static int
2466 1.1 christos read_lnct (struct backtrace_state *state, struct dwarf_data *ddata,
2467 1.1 christos struct unit *u, struct dwarf_buf *hdr_buf,
2468 1.1 christos const struct line_header *hdr, size_t formats_count,
2469 1.1 christos const struct line_header_format *formats, const char **string)
2470 1.1 christos {
2471 1.1 christos size_t i;
2472 1.1 christos const char *dir;
2473 1.1 christos const char *path;
2474 1.1 christos
2475 1.1 christos dir = NULL;
2476 1.1 christos path = NULL;
2477 1.1 christos for (i = 0; i < formats_count; i++)
2478 1.1 christos {
2479 1.1 christos struct attr_val val;
2480 1.1 christos
2481 1.1 christos if (!read_attribute (formats[i].form, 0, hdr_buf, u->is_dwarf64,
2482 1.1 christos u->version, hdr->addrsize, &ddata->dwarf_sections,
2483 1.1 christos ddata->altlink, &val))
2484 1.1 christos return 0;
2485 1.1 christos switch (formats[i].lnct)
2486 1.1 christos {
2487 1.1 christos case DW_LNCT_path:
2488 1.1 christos if (!resolve_string (&ddata->dwarf_sections, u->is_dwarf64,
2489 1.1 christos ddata->is_bigendian, u->str_offsets_base,
2490 1.1 christos &val, hdr_buf->error_callback, hdr_buf->data,
2491 1.1 christos &path))
2492 1.1 christos return 0;
2493 1.1 christos break;
2494 1.1 christos case DW_LNCT_directory_index:
2495 1.1 christos if (val.encoding == ATTR_VAL_UINT)
2496 1.1 christos {
2497 1.1 christos if (val.u.uint >= hdr->dirs_count)
2498 1.1 christos {
2499 1.1 christos dwarf_buf_error (hdr_buf,
2500 1.1 christos ("invalid directory index in "
2501 1.1 christos "line number program header"),
2502 1.1 christos 0);
2503 1.1 christos return 0;
2504 1.1 christos }
2505 1.1 christos dir = hdr->dirs[val.u.uint];
2506 1.1 christos }
2507 1.1 christos break;
2508 1.1 christos default:
2509 1.1 christos /* We don't care about timestamps or sizes or hashes. */
2510 1.1 christos break;
2511 1.1 christos }
2512 1.1 christos }
2513 1.1 christos
2514 1.1 christos if (path == NULL)
2515 1.1 christos {
2516 1.1 christos dwarf_buf_error (hdr_buf,
2517 1.1 christos "missing file name in line number program header",
2518 1.1 christos 0);
2519 1.1 christos return 0;
2520 1.1 christos }
2521 1.1 christos
2522 1.1 christos if (dir == NULL)
2523 1.1 christos *string = path;
2524 1.1 christos else
2525 1.1 christos {
2526 1.1 christos size_t dir_len;
2527 1.1 christos size_t path_len;
2528 1.1 christos char *s;
2529 1.1 christos
2530 1.1 christos dir_len = strlen (dir);
2531 1.1 christos path_len = strlen (path);
2532 1.1 christos s = (char *) backtrace_alloc (state, dir_len + path_len + 2,
2533 1.1 christos hdr_buf->error_callback, hdr_buf->data);
2534 1.1 christos if (s == NULL)
2535 1.1 christos return 0;
2536 1.1 christos memcpy (s, dir, dir_len);
2537 1.1 christos /* FIXME: If we are on a DOS-based file system, and the
2538 1.1 christos directory or the path name use backslashes, then we should
2539 1.1 christos use a backslash here. */
2540 1.1 christos s[dir_len] = '/';
2541 1.1 christos memcpy (s + dir_len + 1, path, path_len + 1);
2542 1.1 christos *string = s;
2543 1.1 christos }
2544 1.1 christos
2545 1.1 christos return 1;
2546 1.1 christos }
2547 1.1 christos
2548 1.1 christos /* Read a set of DWARF 5 line header format entries, setting *PCOUNT
2549 1.1 christos and *PPATHS. Return 1 on success, 0 on failure. */
2550 1.1 christos
2551 1.1 christos static int
2552 1.1 christos read_line_header_format_entries (struct backtrace_state *state,
2553 1.1 christos struct dwarf_data *ddata,
2554 1.1 christos struct unit *u,
2555 1.1 christos struct dwarf_buf *hdr_buf,
2556 1.1 christos struct line_header *hdr,
2557 1.1 christos size_t *pcount,
2558 1.1 christos const char ***ppaths)
2559 1.1 christos {
2560 1.1 christos size_t formats_count;
2561 1.1 christos struct line_header_format *formats;
2562 1.1 christos size_t paths_count;
2563 1.1 christos const char **paths;
2564 1.1 christos size_t i;
2565 1.1 christos int ret;
2566 1.1 christos
2567 1.1 christos formats_count = read_byte (hdr_buf);
2568 1.1 christos if (formats_count == 0)
2569 1.1 christos formats = NULL;
2570 1.1 christos else
2571 1.1 christos {
2572 1.1 christos formats = ((struct line_header_format *)
2573 1.1 christos backtrace_alloc (state,
2574 1.1 christos (formats_count
2575 1.1 christos * sizeof (struct line_header_format)),
2576 1.1 christos hdr_buf->error_callback,
2577 1.1 christos hdr_buf->data));
2578 1.1 christos if (formats == NULL)
2579 1.1 christos return 0;
2580 1.1 christos
2581 1.1 christos for (i = 0; i < formats_count; i++)
2582 1.1 christos {
2583 1.1 christos formats[i].lnct = (int) read_uleb128(hdr_buf);
2584 1.1 christos formats[i].form = (enum dwarf_form) read_uleb128 (hdr_buf);
2585 1.1 christos }
2586 1.1 christos }
2587 1.1 christos
2588 1.1 christos paths_count = read_uleb128 (hdr_buf);
2589 1.1 christos if (paths_count == 0)
2590 1.1 christos {
2591 1.1 christos *pcount = 0;
2592 1.1 christos *ppaths = NULL;
2593 1.1 christos ret = 1;
2594 1.1 christos goto exit;
2595 1.1 christos }
2596 1.1 christos
2597 1.1 christos paths = ((const char **)
2598 1.1 christos backtrace_alloc (state, paths_count * sizeof (const char *),
2599 1.1 christos hdr_buf->error_callback, hdr_buf->data));
2600 1.1 christos if (paths == NULL)
2601 1.1 christos {
2602 1.1 christos ret = 0;
2603 1.1 christos goto exit;
2604 1.1 christos }
2605 1.1 christos for (i = 0; i < paths_count; i++)
2606 1.1 christos {
2607 1.1 christos if (!read_lnct (state, ddata, u, hdr_buf, hdr, formats_count,
2608 1.1 christos formats, &paths[i]))
2609 1.1 christos {
2610 1.1 christos backtrace_free (state, paths,
2611 1.1 christos paths_count * sizeof (const char *),
2612 1.1 christos hdr_buf->error_callback, hdr_buf->data);
2613 1.1 christos ret = 0;
2614 1.1 christos goto exit;
2615 1.1 christos }
2616 1.1 christos }
2617 1.1 christos
2618 1.1 christos *pcount = paths_count;
2619 1.1 christos *ppaths = paths;
2620 1.1 christos
2621 1.1 christos ret = 1;
2622 1.1 christos
2623 1.1 christos exit:
2624 1.1 christos if (formats != NULL)
2625 1.1 christos backtrace_free (state, formats,
2626 1.1 christos formats_count * sizeof (struct line_header_format),
2627 1.1 christos hdr_buf->error_callback, hdr_buf->data);
2628 1.1 christos
2629 1.1 christos return ret;
2630 1.1 christos }
2631 1.1 christos
2632 1.1 christos /* Read the line header. Return 1 on success, 0 on failure. */
2633 1.1 christos
2634 1.1 christos static int
2635 1.1 christos read_line_header (struct backtrace_state *state, struct dwarf_data *ddata,
2636 1.1 christos struct unit *u, int is_dwarf64, struct dwarf_buf *line_buf,
2637 1.1 christos struct line_header *hdr)
2638 1.1 christos {
2639 1.1 christos uint64_t hdrlen;
2640 1.1 christos struct dwarf_buf hdr_buf;
2641 1.1 christos
2642 1.1 christos hdr->version = read_uint16 (line_buf);
2643 1.1 christos if (hdr->version < 2 || hdr->version > 5)
2644 1.1 christos {
2645 1.1 christos dwarf_buf_error (line_buf, "unsupported line number version", -1);
2646 1.1 christos return 0;
2647 1.1 christos }
2648 1.1 christos
2649 1.1 christos if (hdr->version < 5)
2650 1.1 christos hdr->addrsize = u->addrsize;
2651 1.1 christos else
2652 1.1 christos {
2653 1.1 christos hdr->addrsize = read_byte (line_buf);
2654 1.1 christos /* We could support a non-zero segment_selector_size but I doubt
2655 1.1 christos we'll ever see it. */
2656 1.1 christos if (read_byte (line_buf) != 0)
2657 1.1 christos {
2658 1.1 christos dwarf_buf_error (line_buf,
2659 1.1 christos "non-zero segment_selector_size not supported",
2660 1.1 christos -1);
2661 1.1 christos return 0;
2662 1.1 christos }
2663 1.1 christos }
2664 1.1 christos
2665 1.1 christos hdrlen = read_offset (line_buf, is_dwarf64);
2666 1.1 christos
2667 1.1 christos hdr_buf = *line_buf;
2668 1.1 christos hdr_buf.left = hdrlen;
2669 1.1 christos
2670 1.1 christos if (!advance (line_buf, hdrlen))
2671 1.1 christos return 0;
2672 1.1 christos
2673 1.1 christos hdr->min_insn_len = read_byte (&hdr_buf);
2674 1.1 christos if (hdr->version < 4)
2675 1.1 christos hdr->max_ops_per_insn = 1;
2676 1.1 christos else
2677 1.1 christos hdr->max_ops_per_insn = read_byte (&hdr_buf);
2678 1.1 christos
2679 1.1 christos /* We don't care about default_is_stmt. */
2680 1.1 christos read_byte (&hdr_buf);
2681 1.1 christos
2682 1.1 christos hdr->line_base = read_sbyte (&hdr_buf);
2683 1.1 christos hdr->line_range = read_byte (&hdr_buf);
2684 1.1 christos
2685 1.1 christos hdr->opcode_base = read_byte (&hdr_buf);
2686 1.1 christos hdr->opcode_lengths = hdr_buf.buf;
2687 1.1 christos if (!advance (&hdr_buf, hdr->opcode_base - 1))
2688 1.1 christos return 0;
2689 1.1 christos
2690 1.1 christos if (hdr->version < 5)
2691 1.1 christos {
2692 1.1 christos if (!read_v2_paths (state, u, &hdr_buf, hdr))
2693 1.1 christos return 0;
2694 1.1 christos }
2695 1.1 christos else
2696 1.1 christos {
2697 1.1 christos if (!read_line_header_format_entries (state, ddata, u, &hdr_buf, hdr,
2698 1.1 christos &hdr->dirs_count,
2699 1.1 christos &hdr->dirs))
2700 1.1 christos return 0;
2701 1.1 christos if (!read_line_header_format_entries (state, ddata, u, &hdr_buf, hdr,
2702 1.1 christos &hdr->filenames_count,
2703 1.1 christos &hdr->filenames))
2704 1.1 christos return 0;
2705 1.1 christos }
2706 1.1 christos
2707 1.1 christos if (hdr_buf.reported_underflow)
2708 1.1 christos return 0;
2709 1.1 christos
2710 1.1 christos return 1;
2711 1.1 christos }
2712 1.1 christos
2713 1.1 christos /* Read the line program, adding line mappings to VEC. Return 1 on
2714 1.1 christos success, 0 on failure. */
2715 1.1 christos
2716 1.1 christos static int
2717 1.1 christos read_line_program (struct backtrace_state *state, struct dwarf_data *ddata,
2718 1.1 christos const struct line_header *hdr, struct dwarf_buf *line_buf,
2719 1.1 christos struct line_vector *vec)
2720 1.1 christos {
2721 1.1 christos uint64_t address;
2722 1.1 christos unsigned int op_index;
2723 1.1 christos const char *reset_filename;
2724 1.1 christos const char *filename;
2725 1.1 christos int lineno;
2726 1.1 christos
2727 1.1 christos address = 0;
2728 1.1 christos op_index = 0;
2729 1.1 christos if (hdr->filenames_count > 1)
2730 1.1 christos reset_filename = hdr->filenames[1];
2731 1.1 christos else
2732 1.1 christos reset_filename = "";
2733 1.1 christos filename = reset_filename;
2734 1.1 christos lineno = 1;
2735 1.1 christos while (line_buf->left > 0)
2736 1.1 christos {
2737 1.1 christos unsigned int op;
2738 1.1 christos
2739 1.1 christos op = read_byte (line_buf);
2740 1.1 christos if (op >= hdr->opcode_base)
2741 1.1 christos {
2742 1.1 christos unsigned int advance;
2743 1.1 christos
2744 1.1 christos /* Special opcode. */
2745 1.1 christos op -= hdr->opcode_base;
2746 1.1 christos advance = op / hdr->line_range;
2747 1.1 christos address += (hdr->min_insn_len * (op_index + advance)
2748 1.1 christos / hdr->max_ops_per_insn);
2749 1.1 christos op_index = (op_index + advance) % hdr->max_ops_per_insn;
2750 1.1 christos lineno += hdr->line_base + (int) (op % hdr->line_range);
2751 1.1 christos add_line (state, ddata, address, filename, lineno,
2752 1.1 christos line_buf->error_callback, line_buf->data, vec);
2753 1.1 christos }
2754 1.1 christos else if (op == DW_LNS_extended_op)
2755 1.1 christos {
2756 1.1 christos uint64_t len;
2757 1.1 christos
2758 1.1 christos len = read_uleb128 (line_buf);
2759 1.1 christos op = read_byte (line_buf);
2760 1.1 christos switch (op)
2761 1.1 christos {
2762 1.1 christos case DW_LNE_end_sequence:
2763 1.1 christos /* FIXME: Should we mark the high PC here? It seems
2764 1.1 christos that we already have that information from the
2765 1.1 christos compilation unit. */
2766 1.1 christos address = 0;
2767 1.1 christos op_index = 0;
2768 1.1 christos filename = reset_filename;
2769 1.1 christos lineno = 1;
2770 1.1 christos break;
2771 1.1 christos case DW_LNE_set_address:
2772 1.1 christos address = read_address (line_buf, hdr->addrsize);
2773 1.1 christos break;
2774 1.1 christos case DW_LNE_define_file:
2775 1.1 christos {
2776 1.1 christos const char *f;
2777 1.1 christos unsigned int dir_index;
2778 1.1 christos
2779 1.1 christos f = read_string (line_buf);
2780 1.1 christos if (f == NULL)
2781 1.1 christos return 0;
2782 1.1 christos dir_index = read_uleb128 (line_buf);
2783 1.1 christos /* Ignore that time and length. */
2784 1.1 christos read_uleb128 (line_buf);
2785 1.1 christos read_uleb128 (line_buf);
2786 1.1 christos if (IS_ABSOLUTE_PATH (f))
2787 1.1 christos filename = f;
2788 1.1 christos else
2789 1.1 christos {
2790 1.1 christos const char *dir;
2791 1.1 christos size_t dir_len;
2792 1.1 christos size_t f_len;
2793 1.1 christos char *p;
2794 1.1 christos
2795 1.1 christos if (dir_index < hdr->dirs_count)
2796 1.1 christos dir = hdr->dirs[dir_index];
2797 1.1 christos else
2798 1.1 christos {
2799 1.1 christos dwarf_buf_error (line_buf,
2800 1.1 christos ("invalid directory index "
2801 1.1 christos "in line number program"),
2802 1.1 christos 0);
2803 1.1 christos return 0;
2804 1.1 christos }
2805 1.1 christos dir_len = strlen (dir);
2806 1.1 christos f_len = strlen (f);
2807 1.1 christos p = ((char *)
2808 1.1 christos backtrace_alloc (state, dir_len + f_len + 2,
2809 1.1 christos line_buf->error_callback,
2810 1.1 christos line_buf->data));
2811 1.1 christos if (p == NULL)
2812 1.1 christos return 0;
2813 1.1 christos memcpy (p, dir, dir_len);
2814 1.1 christos /* FIXME: If we are on a DOS-based file system,
2815 1.1 christos and the directory or the file name use
2816 1.1 christos backslashes, then we should use a backslash
2817 1.1 christos here. */
2818 1.1 christos p[dir_len] = '/';
2819 1.1 christos memcpy (p + dir_len + 1, f, f_len + 1);
2820 1.1 christos filename = p;
2821 1.1 christos }
2822 1.1 christos }
2823 1.1 christos break;
2824 1.1 christos case DW_LNE_set_discriminator:
2825 1.1 christos /* We don't care about discriminators. */
2826 1.1 christos read_uleb128 (line_buf);
2827 1.1 christos break;
2828 1.1 christos default:
2829 1.1 christos if (!advance (line_buf, len - 1))
2830 1.1 christos return 0;
2831 1.1 christos break;
2832 1.1 christos }
2833 1.1 christos }
2834 1.1 christos else
2835 1.1 christos {
2836 1.1 christos switch (op)
2837 1.1 christos {
2838 1.1 christos case DW_LNS_copy:
2839 1.1 christos add_line (state, ddata, address, filename, lineno,
2840 1.1 christos line_buf->error_callback, line_buf->data, vec);
2841 1.1 christos break;
2842 1.1 christos case DW_LNS_advance_pc:
2843 1.1 christos {
2844 1.1 christos uint64_t advance;
2845 1.1 christos
2846 1.1 christos advance = read_uleb128 (line_buf);
2847 1.1 christos address += (hdr->min_insn_len * (op_index + advance)
2848 1.1 christos / hdr->max_ops_per_insn);
2849 1.1 christos op_index = (op_index + advance) % hdr->max_ops_per_insn;
2850 1.1 christos }
2851 1.1 christos break;
2852 1.1 christos case DW_LNS_advance_line:
2853 1.1 christos lineno += (int) read_sleb128 (line_buf);
2854 1.1 christos break;
2855 1.1 christos case DW_LNS_set_file:
2856 1.1 christos {
2857 1.1 christos uint64_t fileno;
2858 1.1 christos
2859 1.1 christos fileno = read_uleb128 (line_buf);
2860 1.1 christos if (fileno >= hdr->filenames_count)
2861 1.1 christos {
2862 1.1 christos dwarf_buf_error (line_buf,
2863 1.1 christos ("invalid file number in "
2864 1.1 christos "line number program"),
2865 1.1 christos 0);
2866 1.1 christos return 0;
2867 1.1 christos }
2868 1.1 christos filename = hdr->filenames[fileno];
2869 1.1 christos }
2870 1.1 christos break;
2871 1.1 christos case DW_LNS_set_column:
2872 1.1 christos read_uleb128 (line_buf);
2873 1.1 christos break;
2874 1.1 christos case DW_LNS_negate_stmt:
2875 1.1 christos break;
2876 1.1 christos case DW_LNS_set_basic_block:
2877 1.1 christos break;
2878 1.1 christos case DW_LNS_const_add_pc:
2879 1.1 christos {
2880 1.1 christos unsigned int advance;
2881 1.1 christos
2882 1.1 christos op = 255 - hdr->opcode_base;
2883 1.1 christos advance = op / hdr->line_range;
2884 1.1 christos address += (hdr->min_insn_len * (op_index + advance)
2885 1.1 christos / hdr->max_ops_per_insn);
2886 1.1 christos op_index = (op_index + advance) % hdr->max_ops_per_insn;
2887 1.1 christos }
2888 1.1 christos break;
2889 1.1 christos case DW_LNS_fixed_advance_pc:
2890 1.1 christos address += read_uint16 (line_buf);
2891 1.1 christos op_index = 0;
2892 1.1 christos break;
2893 1.1 christos case DW_LNS_set_prologue_end:
2894 1.1 christos break;
2895 1.1 christos case DW_LNS_set_epilogue_begin:
2896 1.1 christos break;
2897 1.1 christos case DW_LNS_set_isa:
2898 1.1 christos read_uleb128 (line_buf);
2899 1.1 christos break;
2900 1.1 christos default:
2901 1.1 christos {
2902 1.1 christos unsigned int i;
2903 1.1 christos
2904 1.1 christos for (i = hdr->opcode_lengths[op - 1]; i > 0; --i)
2905 1.1 christos read_uleb128 (line_buf);
2906 1.1 christos }
2907 1.1 christos break;
2908 1.1 christos }
2909 1.1 christos }
2910 1.1 christos }
2911 1.1 christos
2912 1.1 christos return 1;
2913 1.1 christos }
2914 1.1 christos
2915 1.1 christos /* Read the line number information for a compilation unit. Returns 1
2916 1.1 christos on success, 0 on failure. */
2917 1.1 christos
2918 1.1 christos static int
2919 1.1 christos read_line_info (struct backtrace_state *state, struct dwarf_data *ddata,
2920 1.1 christos backtrace_error_callback error_callback, void *data,
2921 1.1 christos struct unit *u, struct line_header *hdr, struct line **lines,
2922 1.1 christos size_t *lines_count)
2923 1.1 christos {
2924 1.1 christos struct line_vector vec;
2925 1.1 christos struct dwarf_buf line_buf;
2926 1.1 christos uint64_t len;
2927 1.1 christos int is_dwarf64;
2928 1.1 christos struct line *ln;
2929 1.1 christos
2930 1.1 christos memset (&vec.vec, 0, sizeof vec.vec);
2931 1.1 christos vec.count = 0;
2932 1.1 christos
2933 1.1 christos memset (hdr, 0, sizeof *hdr);
2934 1.1 christos
2935 1.1 christos if (u->lineoff != (off_t) (size_t) u->lineoff
2936 1.1 christos || (size_t) u->lineoff >= ddata->dwarf_sections.size[DEBUG_LINE])
2937 1.1 christos {
2938 1.1 christos error_callback (data, "unit line offset out of range", 0);
2939 1.1 christos goto fail;
2940 1.1 christos }
2941 1.1 christos
2942 1.1 christos line_buf.name = ".debug_line";
2943 1.1 christos line_buf.start = ddata->dwarf_sections.data[DEBUG_LINE];
2944 1.1 christos line_buf.buf = ddata->dwarf_sections.data[DEBUG_LINE] + u->lineoff;
2945 1.1 christos line_buf.left = ddata->dwarf_sections.size[DEBUG_LINE] - u->lineoff;
2946 1.1 christos line_buf.is_bigendian = ddata->is_bigendian;
2947 1.1 christos line_buf.error_callback = error_callback;
2948 1.1 christos line_buf.data = data;
2949 1.1 christos line_buf.reported_underflow = 0;
2950 1.1 christos
2951 1.1 christos len = read_initial_length (&line_buf, &is_dwarf64);
2952 1.1 christos line_buf.left = len;
2953 1.1 christos
2954 1.1 christos if (!read_line_header (state, ddata, u, is_dwarf64, &line_buf, hdr))
2955 1.1 christos goto fail;
2956 1.1 christos
2957 1.1 christos if (!read_line_program (state, ddata, hdr, &line_buf, &vec))
2958 1.1 christos goto fail;
2959 1.1 christos
2960 1.1 christos if (line_buf.reported_underflow)
2961 1.1 christos goto fail;
2962 1.1 christos
2963 1.1 christos if (vec.count == 0)
2964 1.1 christos {
2965 1.1 christos /* This is not a failure in the sense of a generating an error,
2966 1.1 christos but it is a failure in that sense that we have no useful
2967 1.1 christos information. */
2968 1.1 christos goto fail;
2969 1.1 christos }
2970 1.1 christos
2971 1.1 christos /* Allocate one extra entry at the end. */
2972 1.1 christos ln = ((struct line *)
2973 1.1 christos backtrace_vector_grow (state, sizeof (struct line), error_callback,
2974 1.1 christos data, &vec.vec));
2975 1.1 christos if (ln == NULL)
2976 1.1 christos goto fail;
2977 1.1 christos ln->pc = (uintptr_t) -1;
2978 1.1 christos ln->filename = NULL;
2979 1.1 christos ln->lineno = 0;
2980 1.1 christos ln->idx = 0;
2981 1.1 christos
2982 1.1 christos if (!backtrace_vector_release (state, &vec.vec, error_callback, data))
2983 1.1 christos goto fail;
2984 1.1 christos
2985 1.1 christos ln = (struct line *) vec.vec.base;
2986 1.1 christos backtrace_qsort (ln, vec.count, sizeof (struct line), line_compare);
2987 1.1 christos
2988 1.1 christos *lines = ln;
2989 1.1 christos *lines_count = vec.count;
2990 1.1 christos
2991 1.1 christos return 1;
2992 1.1 christos
2993 1.1 christos fail:
2994 1.1 christos backtrace_vector_free (state, &vec.vec, error_callback, data);
2995 1.1 christos free_line_header (state, hdr, error_callback, data);
2996 1.1 christos *lines = (struct line *) (uintptr_t) -1;
2997 1.1 christos *lines_count = 0;
2998 1.1 christos return 0;
2999 1.1 christos }
3000 1.1 christos
3001 1.1 christos static const char *read_referenced_name (struct dwarf_data *, struct unit *,
3002 1.1 christos uint64_t, backtrace_error_callback,
3003 1.1 christos void *);
3004 1.1 christos
3005 1.1 christos /* Read the name of a function from a DIE referenced by ATTR with VAL. */
3006 1.1 christos
3007 1.1 christos static const char *
3008 1.1 christos read_referenced_name_from_attr (struct dwarf_data *ddata, struct unit *u,
3009 1.1 christos struct attr *attr, struct attr_val *val,
3010 1.1 christos backtrace_error_callback error_callback,
3011 1.1 christos void *data)
3012 1.1 christos {
3013 1.1 christos switch (attr->name)
3014 1.1 christos {
3015 1.1 christos case DW_AT_abstract_origin:
3016 1.1 christos case DW_AT_specification:
3017 1.1 christos break;
3018 1.1 christos default:
3019 1.1 christos return NULL;
3020 1.1 christos }
3021 1.1 christos
3022 1.1 christos if (attr->form == DW_FORM_ref_sig8)
3023 1.1 christos return NULL;
3024 1.1 christos
3025 1.1 christos if (val->encoding == ATTR_VAL_REF_INFO)
3026 1.1 christos {
3027 1.1 christos struct unit *unit
3028 1.1 christos = find_unit (ddata->units, ddata->units_count,
3029 1.1 christos val->u.uint);
3030 1.1 christos if (unit == NULL)
3031 1.1 christos return NULL;
3032 1.1 christos
3033 1.1 christos uint64_t offset = val->u.uint - unit->low_offset;
3034 1.1 christos return read_referenced_name (ddata, unit, offset, error_callback, data);
3035 1.1 christos }
3036 1.1 christos
3037 1.1 christos if (val->encoding == ATTR_VAL_UINT
3038 1.1 christos || val->encoding == ATTR_VAL_REF_UNIT)
3039 1.1 christos return read_referenced_name (ddata, u, val->u.uint, error_callback, data);
3040 1.1 christos
3041 1.1 christos if (val->encoding == ATTR_VAL_REF_ALT_INFO)
3042 1.1 christos {
3043 1.1 christos struct unit *alt_unit
3044 1.1 christos = find_unit (ddata->altlink->units, ddata->altlink->units_count,
3045 1.1 christos val->u.uint);
3046 1.1 christos if (alt_unit == NULL)
3047 1.1 christos return NULL;
3048 1.1 christos
3049 1.1 christos uint64_t offset = val->u.uint - alt_unit->low_offset;
3050 1.1 christos return read_referenced_name (ddata->altlink, alt_unit, offset,
3051 1.1 christos error_callback, data);
3052 1.1 christos }
3053 1.1 christos
3054 1.1 christos return NULL;
3055 1.1 christos }
3056 1.1 christos
3057 1.1 christos /* Read the name of a function from a DIE referenced by a
3058 1.1 christos DW_AT_abstract_origin or DW_AT_specification tag. OFFSET is within
3059 1.1 christos the same compilation unit. */
3060 1.1 christos
3061 1.1 christos static const char *
3062 1.1 christos read_referenced_name (struct dwarf_data *ddata, struct unit *u,
3063 1.1 christos uint64_t offset, backtrace_error_callback error_callback,
3064 1.1 christos void *data)
3065 1.1 christos {
3066 1.1 christos struct dwarf_buf unit_buf;
3067 1.1 christos uint64_t code;
3068 1.1 christos const struct abbrev *abbrev;
3069 1.1 christos const char *ret;
3070 1.1 christos size_t i;
3071 1.1 christos
3072 1.1 christos /* OFFSET is from the start of the data for this compilation unit.
3073 1.1 christos U->unit_data is the data, but it starts U->unit_data_offset bytes
3074 1.1 christos from the beginning. */
3075 1.1 christos
3076 1.1 christos if (offset < u->unit_data_offset
3077 1.1 christos || offset - u->unit_data_offset >= u->unit_data_len)
3078 1.1 christos {
3079 1.1 christos error_callback (data,
3080 1.1 christos "abstract origin or specification out of range",
3081 1.1 christos 0);
3082 1.1 christos return NULL;
3083 1.1 christos }
3084 1.1 christos
3085 1.1 christos offset -= u->unit_data_offset;
3086 1.1 christos
3087 1.1 christos unit_buf.name = ".debug_info";
3088 1.1 christos unit_buf.start = ddata->dwarf_sections.data[DEBUG_INFO];
3089 1.1 christos unit_buf.buf = u->unit_data + offset;
3090 1.1 christos unit_buf.left = u->unit_data_len - offset;
3091 1.1 christos unit_buf.is_bigendian = ddata->is_bigendian;
3092 1.1 christos unit_buf.error_callback = error_callback;
3093 1.1 christos unit_buf.data = data;
3094 1.1 christos unit_buf.reported_underflow = 0;
3095 1.1 christos
3096 1.1 christos code = read_uleb128 (&unit_buf);
3097 1.1 christos if (code == 0)
3098 1.1 christos {
3099 1.1 christos dwarf_buf_error (&unit_buf,
3100 1.1 christos "invalid abstract origin or specification",
3101 1.1 christos 0);
3102 1.1 christos return NULL;
3103 1.1 christos }
3104 1.1 christos
3105 1.1 christos abbrev = lookup_abbrev (&u->abbrevs, code, error_callback, data);
3106 1.1 christos if (abbrev == NULL)
3107 1.1 christos return NULL;
3108 1.1 christos
3109 1.1 christos ret = NULL;
3110 1.1 christos for (i = 0; i < abbrev->num_attrs; ++i)
3111 1.1 christos {
3112 1.1 christos struct attr_val val;
3113 1.1 christos
3114 1.1 christos if (!read_attribute (abbrev->attrs[i].form, abbrev->attrs[i].val,
3115 1.1 christos &unit_buf, u->is_dwarf64, u->version, u->addrsize,
3116 1.1 christos &ddata->dwarf_sections, ddata->altlink, &val))
3117 1.1 christos return NULL;
3118 1.1 christos
3119 1.1 christos switch (abbrev->attrs[i].name)
3120 1.1 christos {
3121 1.1 christos case DW_AT_name:
3122 1.1 christos /* Third name preference: don't override. A name we found in some
3123 1.1 christos other way, will normally be more useful -- e.g., this name is
3124 1.1 christos normally not mangled. */
3125 1.1 christos if (ret != NULL)
3126 1.1 christos break;
3127 1.1 christos if (!resolve_string (&ddata->dwarf_sections, u->is_dwarf64,
3128 1.1 christos ddata->is_bigendian, u->str_offsets_base,
3129 1.1 christos &val, error_callback, data, &ret))
3130 1.1 christos return NULL;
3131 1.1 christos break;
3132 1.1 christos
3133 1.1 christos case DW_AT_linkage_name:
3134 1.1 christos case DW_AT_MIPS_linkage_name:
3135 1.1 christos /* First name preference: override all. */
3136 1.1 christos {
3137 1.1 christos const char *s;
3138 1.1 christos
3139 1.1 christos s = NULL;
3140 1.1 christos if (!resolve_string (&ddata->dwarf_sections, u->is_dwarf64,
3141 1.1 christos ddata->is_bigendian, u->str_offsets_base,
3142 1.1 christos &val, error_callback, data, &s))
3143 1.1 christos return NULL;
3144 1.1 christos if (s != NULL)
3145 1.1 christos return s;
3146 1.1 christos }
3147 1.1 christos break;
3148 1.1 christos
3149 1.1 christos case DW_AT_specification:
3150 1.1 christos /* Second name preference: override DW_AT_name, don't override
3151 1.1 christos DW_AT_linkage_name. */
3152 1.1 christos {
3153 1.1 christos const char *name;
3154 1.1 christos
3155 1.1 christos name = read_referenced_name_from_attr (ddata, u, &abbrev->attrs[i],
3156 1.1 christos &val, error_callback, data);
3157 1.1 christos if (name != NULL)
3158 1.1 christos ret = name;
3159 1.1 christos }
3160 1.1 christos break;
3161 1.1 christos
3162 1.1 christos default:
3163 1.1 christos break;
3164 1.1 christos }
3165 1.1 christos }
3166 1.1 christos
3167 1.1 christos return ret;
3168 1.1 christos }
3169 1.1 christos
3170 1.1 christos /* Add a range to a unit that maps to a function. This is called via
3171 1.1 christos add_ranges. Returns 1 on success, 0 on error. */
3172 1.1 christos
3173 1.1 christos static int
3174 1.1 christos add_function_range (struct backtrace_state *state, void *rdata,
3175 1.1 christos uint64_t lowpc, uint64_t highpc,
3176 1.1 christos backtrace_error_callback error_callback, void *data,
3177 1.1 christos void *pvec)
3178 1.1 christos {
3179 1.1 christos struct function *function = (struct function *) rdata;
3180 1.1 christos struct function_vector *vec = (struct function_vector *) pvec;
3181 1.1 christos struct function_addrs *p;
3182 1.1 christos
3183 1.1 christos if (vec->count > 0)
3184 1.1 christos {
3185 1.1 christos p = (struct function_addrs *) vec->vec.base + (vec->count - 1);
3186 1.1 christos if ((lowpc == p->high || lowpc == p->high + 1)
3187 1.1 christos && function == p->function)
3188 1.1 christos {
3189 1.1 christos if (highpc > p->high)
3190 1.1 christos p->high = highpc;
3191 1.1 christos return 1;
3192 1.1 christos }
3193 1.1 christos }
3194 1.1 christos
3195 1.1 christos p = ((struct function_addrs *)
3196 1.1 christos backtrace_vector_grow (state, sizeof (struct function_addrs),
3197 1.1 christos error_callback, data, &vec->vec));
3198 1.1 christos if (p == NULL)
3199 1.1 christos return 0;
3200 1.1 christos
3201 1.1 christos p->low = lowpc;
3202 1.1 christos p->high = highpc;
3203 1.1 christos p->function = function;
3204 1.1 christos
3205 1.1 christos ++vec->count;
3206 1.1 christos
3207 1.1 christos return 1;
3208 1.1 christos }
3209 1.1 christos
3210 1.1 christos /* Read one entry plus all its children. Add function addresses to
3211 1.1 christos VEC. Returns 1 on success, 0 on error. */
3212 1.1 christos
3213 1.1 christos static int
3214 1.1 christos read_function_entry (struct backtrace_state *state, struct dwarf_data *ddata,
3215 1.1 christos struct unit *u, uint64_t base, struct dwarf_buf *unit_buf,
3216 1.1 christos const struct line_header *lhdr,
3217 1.1 christos backtrace_error_callback error_callback, void *data,
3218 1.1 christos struct function_vector *vec_function,
3219 1.1 christos struct function_vector *vec_inlined)
3220 1.1 christos {
3221 1.1 christos while (unit_buf->left > 0)
3222 1.1 christos {
3223 1.1 christos uint64_t code;
3224 1.1 christos const struct abbrev *abbrev;
3225 1.1 christos int is_function;
3226 1.1 christos struct function *function;
3227 1.1 christos struct function_vector *vec;
3228 1.1 christos size_t i;
3229 1.1 christos struct pcrange pcrange;
3230 1.1 christos int have_linkage_name;
3231 1.1 christos
3232 1.1 christos code = read_uleb128 (unit_buf);
3233 1.1 christos if (code == 0)
3234 1.1 christos return 1;
3235 1.1 christos
3236 1.1 christos abbrev = lookup_abbrev (&u->abbrevs, code, error_callback, data);
3237 1.1 christos if (abbrev == NULL)
3238 1.1 christos return 0;
3239 1.1 christos
3240 1.1 christos is_function = (abbrev->tag == DW_TAG_subprogram
3241 1.1 christos || abbrev->tag == DW_TAG_entry_point
3242 1.1 christos || abbrev->tag == DW_TAG_inlined_subroutine);
3243 1.1 christos
3244 1.1 christos if (abbrev->tag == DW_TAG_inlined_subroutine)
3245 1.1 christos vec = vec_inlined;
3246 1.1 christos else
3247 1.1 christos vec = vec_function;
3248 1.1 christos
3249 1.1 christos function = NULL;
3250 1.1 christos if (is_function)
3251 1.1 christos {
3252 1.1 christos function = ((struct function *)
3253 1.1 christos backtrace_alloc (state, sizeof *function,
3254 1.1 christos error_callback, data));
3255 1.1 christos if (function == NULL)
3256 1.1 christos return 0;
3257 1.1 christos memset (function, 0, sizeof *function);
3258 1.1 christos }
3259 1.1 christos
3260 1.1 christos memset (&pcrange, 0, sizeof pcrange);
3261 1.1 christos have_linkage_name = 0;
3262 1.1 christos for (i = 0; i < abbrev->num_attrs; ++i)
3263 1.1 christos {
3264 1.1 christos struct attr_val val;
3265 1.1 christos
3266 1.1 christos if (!read_attribute (abbrev->attrs[i].form, abbrev->attrs[i].val,
3267 1.1 christos unit_buf, u->is_dwarf64, u->version,
3268 1.1 christos u->addrsize, &ddata->dwarf_sections,
3269 1.1 christos ddata->altlink, &val))
3270 1.1 christos return 0;
3271 1.1 christos
3272 1.1 christos /* The compile unit sets the base address for any address
3273 1.1 christos ranges in the function entries. */
3274 1.1 christos if (abbrev->tag == DW_TAG_compile_unit
3275 1.1 christos && abbrev->attrs[i].name == DW_AT_low_pc)
3276 1.1 christos {
3277 1.1 christos if (val.encoding == ATTR_VAL_ADDRESS)
3278 1.1 christos base = val.u.uint;
3279 1.1 christos else if (val.encoding == ATTR_VAL_ADDRESS_INDEX)
3280 1.1 christos {
3281 1.1 christos if (!resolve_addr_index (&ddata->dwarf_sections,
3282 1.1 christos u->addr_base, u->addrsize,
3283 1.1 christos ddata->is_bigendian, val.u.uint,
3284 1.1 christos error_callback, data, &base))
3285 1.1 christos return 0;
3286 1.1 christos }
3287 1.1 christos }
3288 1.1 christos
3289 1.1 christos if (is_function)
3290 1.1 christos {
3291 1.1 christos switch (abbrev->attrs[i].name)
3292 1.1 christos {
3293 1.1 christos case DW_AT_call_file:
3294 1.1 christos if (val.encoding == ATTR_VAL_UINT)
3295 1.1 christos {
3296 1.1 christos if (val.u.uint >= lhdr->filenames_count)
3297 1.1 christos {
3298 1.1 christos dwarf_buf_error (unit_buf,
3299 1.1 christos ("invalid file number in "
3300 1.1 christos "DW_AT_call_file attribute"),
3301 1.1 christos 0);
3302 1.1 christos return 0;
3303 1.1 christos }
3304 1.1 christos function->caller_filename = lhdr->filenames[val.u.uint];
3305 1.1 christos }
3306 1.1 christos break;
3307 1.1 christos
3308 1.1 christos case DW_AT_call_line:
3309 1.1 christos if (val.encoding == ATTR_VAL_UINT)
3310 1.1 christos function->caller_lineno = val.u.uint;
3311 1.1 christos break;
3312 1.1 christos
3313 1.1 christos case DW_AT_abstract_origin:
3314 1.1 christos case DW_AT_specification:
3315 1.1 christos /* Second name preference: override DW_AT_name, don't override
3316 1.1 christos DW_AT_linkage_name. */
3317 1.1 christos if (have_linkage_name)
3318 1.1 christos break;
3319 1.1 christos {
3320 1.1 christos const char *name;
3321 1.1 christos
3322 1.1 christos name
3323 1.1 christos = read_referenced_name_from_attr (ddata, u,
3324 1.1 christos &abbrev->attrs[i], &val,
3325 1.1 christos error_callback, data);
3326 1.1 christos if (name != NULL)
3327 1.1 christos function->name = name;
3328 1.1 christos }
3329 1.1 christos break;
3330 1.1 christos
3331 1.1 christos case DW_AT_name:
3332 1.1 christos /* Third name preference: don't override. */
3333 1.1 christos if (function->name != NULL)
3334 1.1 christos break;
3335 1.1 christos if (!resolve_string (&ddata->dwarf_sections, u->is_dwarf64,
3336 1.1 christos ddata->is_bigendian,
3337 1.1 christos u->str_offsets_base, &val,
3338 1.1 christos error_callback, data, &function->name))
3339 1.1 christos return 0;
3340 1.1 christos break;
3341 1.1 christos
3342 1.1 christos case DW_AT_linkage_name:
3343 1.1 christos case DW_AT_MIPS_linkage_name:
3344 1.1 christos /* First name preference: override all. */
3345 1.1 christos {
3346 1.1 christos const char *s;
3347 1.1 christos
3348 1.1 christos s = NULL;
3349 1.1 christos if (!resolve_string (&ddata->dwarf_sections, u->is_dwarf64,
3350 1.1 christos ddata->is_bigendian,
3351 1.1 christos u->str_offsets_base, &val,
3352 1.1 christos error_callback, data, &s))
3353 1.1 christos return 0;
3354 1.1 christos if (s != NULL)
3355 1.1 christos {
3356 1.1 christos function->name = s;
3357 1.1 christos have_linkage_name = 1;
3358 1.1 christos }
3359 1.1 christos }
3360 1.1 christos break;
3361 1.1 christos
3362 1.1 christos case DW_AT_low_pc: case DW_AT_high_pc: case DW_AT_ranges:
3363 1.1 christos update_pcrange (&abbrev->attrs[i], &val, &pcrange);
3364 1.1 christos break;
3365 1.1 christos
3366 1.1 christos default:
3367 1.1 christos break;
3368 1.1 christos }
3369 1.1 christos }
3370 1.1 christos }
3371 1.1 christos
3372 1.1 christos /* If we couldn't find a name for the function, we have no use
3373 1.1 christos for it. */
3374 1.1 christos if (is_function && function->name == NULL)
3375 1.1 christos {
3376 1.1 christos backtrace_free (state, function, sizeof *function,
3377 1.1 christos error_callback, data);
3378 1.1 christos is_function = 0;
3379 1.1 christos }
3380 1.1 christos
3381 1.1 christos if (is_function)
3382 1.1 christos {
3383 1.1 christos if (pcrange.have_ranges
3384 1.1 christos || (pcrange.have_lowpc && pcrange.have_highpc))
3385 1.1 christos {
3386 1.1 christos if (!add_ranges (state, &ddata->dwarf_sections,
3387 1.1 christos ddata->base_address, ddata->is_bigendian,
3388 1.1 christos u, base, &pcrange, add_function_range,
3389 1.1 christos (void *) function, error_callback, data,
3390 1.1 christos (void *) vec))
3391 1.1 christos return 0;
3392 1.1 christos }
3393 1.1 christos else
3394 1.1 christos {
3395 1.1 christos backtrace_free (state, function, sizeof *function,
3396 1.1 christos error_callback, data);
3397 1.1 christos is_function = 0;
3398 1.1 christos }
3399 1.1 christos }
3400 1.1 christos
3401 1.1 christos if (abbrev->has_children)
3402 1.1 christos {
3403 1.1 christos if (!is_function)
3404 1.1 christos {
3405 1.1 christos if (!read_function_entry (state, ddata, u, base, unit_buf, lhdr,
3406 1.1 christos error_callback, data, vec_function,
3407 1.1 christos vec_inlined))
3408 1.1 christos return 0;
3409 1.1 christos }
3410 1.1 christos else
3411 1.1 christos {
3412 1.1 christos struct function_vector fvec;
3413 1.1 christos
3414 1.1 christos /* Gather any information for inlined functions in
3415 1.1 christos FVEC. */
3416 1.1 christos
3417 1.1 christos memset (&fvec, 0, sizeof fvec);
3418 1.1 christos
3419 1.1 christos if (!read_function_entry (state, ddata, u, base, unit_buf, lhdr,
3420 1.1 christos error_callback, data, vec_function,
3421 1.1 christos &fvec))
3422 1.1 christos return 0;
3423 1.1 christos
3424 1.1 christos if (fvec.count > 0)
3425 1.1 christos {
3426 1.1 christos struct function_addrs *p;
3427 1.1 christos struct function_addrs *faddrs;
3428 1.1 christos
3429 1.1 christos /* Allocate a trailing entry, but don't include it
3430 1.1 christos in fvec.count. */
3431 1.1 christos p = ((struct function_addrs *)
3432 1.1 christos backtrace_vector_grow (state,
3433 1.1 christos sizeof (struct function_addrs),
3434 1.1 christos error_callback, data,
3435 1.1 christos &fvec.vec));
3436 1.1 christos if (p == NULL)
3437 1.1 christos return 0;
3438 1.1 christos p->low = 0;
3439 1.1 christos --p->low;
3440 1.1 christos p->high = p->low;
3441 1.1 christos p->function = NULL;
3442 1.1 christos
3443 1.1 christos if (!backtrace_vector_release (state, &fvec.vec,
3444 1.1 christos error_callback, data))
3445 1.1 christos return 0;
3446 1.1 christos
3447 1.1 christos faddrs = (struct function_addrs *) fvec.vec.base;
3448 1.1 christos backtrace_qsort (faddrs, fvec.count,
3449 1.1 christos sizeof (struct function_addrs),
3450 1.1 christos function_addrs_compare);
3451 1.1 christos
3452 1.1 christos function->function_addrs = faddrs;
3453 1.1 christos function->function_addrs_count = fvec.count;
3454 1.1 christos }
3455 1.1 christos }
3456 1.1 christos }
3457 1.1 christos }
3458 1.1 christos
3459 1.1 christos return 1;
3460 1.1 christos }
3461 1.1 christos
3462 1.1 christos /* Read function name information for a compilation unit. We look
3463 1.1 christos through the whole unit looking for function tags. */
3464 1.1 christos
3465 1.1 christos static void
3466 1.1 christos read_function_info (struct backtrace_state *state, struct dwarf_data *ddata,
3467 1.1 christos const struct line_header *lhdr,
3468 1.1 christos backtrace_error_callback error_callback, void *data,
3469 1.1 christos struct unit *u, struct function_vector *fvec,
3470 1.1 christos struct function_addrs **ret_addrs,
3471 1.1 christos size_t *ret_addrs_count)
3472 1.1 christos {
3473 1.1 christos struct function_vector lvec;
3474 1.1 christos struct function_vector *pfvec;
3475 1.1 christos struct dwarf_buf unit_buf;
3476 1.1 christos struct function_addrs *p;
3477 1.1 christos struct function_addrs *addrs;
3478 1.1 christos size_t addrs_count;
3479 1.1 christos
3480 1.1 christos /* Use FVEC if it is not NULL. Otherwise use our own vector. */
3481 1.1 christos if (fvec != NULL)
3482 1.1 christos pfvec = fvec;
3483 1.1 christos else
3484 1.1 christos {
3485 1.1 christos memset (&lvec, 0, sizeof lvec);
3486 1.1 christos pfvec = &lvec;
3487 1.1 christos }
3488 1.1 christos
3489 1.1 christos unit_buf.name = ".debug_info";
3490 1.1 christos unit_buf.start = ddata->dwarf_sections.data[DEBUG_INFO];
3491 1.1 christos unit_buf.buf = u->unit_data;
3492 1.1 christos unit_buf.left = u->unit_data_len;
3493 1.1 christos unit_buf.is_bigendian = ddata->is_bigendian;
3494 1.1 christos unit_buf.error_callback = error_callback;
3495 1.1 christos unit_buf.data = data;
3496 1.1 christos unit_buf.reported_underflow = 0;
3497 1.1 christos
3498 1.1 christos while (unit_buf.left > 0)
3499 1.1 christos {
3500 1.1 christos if (!read_function_entry (state, ddata, u, 0, &unit_buf, lhdr,
3501 1.1 christos error_callback, data, pfvec, pfvec))
3502 1.1 christos return;
3503 1.1 christos }
3504 1.1 christos
3505 1.1 christos if (pfvec->count == 0)
3506 1.1 christos return;
3507 1.1 christos
3508 1.1 christos /* Allocate a trailing entry, but don't include it in
3509 1.1 christos pfvec->count. */
3510 1.1 christos p = ((struct function_addrs *)
3511 1.1 christos backtrace_vector_grow (state, sizeof (struct function_addrs),
3512 1.1 christos error_callback, data, &pfvec->vec));
3513 1.1 christos if (p == NULL)
3514 1.1 christos return;
3515 1.1 christos p->low = 0;
3516 1.1 christos --p->low;
3517 1.1 christos p->high = p->low;
3518 1.1 christos p->function = NULL;
3519 1.1 christos
3520 1.1 christos addrs_count = pfvec->count;
3521 1.1 christos
3522 1.1 christos if (fvec == NULL)
3523 1.1 christos {
3524 1.1 christos if (!backtrace_vector_release (state, &lvec.vec, error_callback, data))
3525 1.1 christos return;
3526 1.1 christos addrs = (struct function_addrs *) pfvec->vec.base;
3527 1.1 christos }
3528 1.1 christos else
3529 1.1 christos {
3530 1.1 christos /* Finish this list of addresses, but leave the remaining space in
3531 1.1 christos the vector available for the next function unit. */
3532 1.1 christos addrs = ((struct function_addrs *)
3533 1.1 christos backtrace_vector_finish (state, &fvec->vec,
3534 1.1 christos error_callback, data));
3535 1.1 christos if (addrs == NULL)
3536 1.1 christos return;
3537 1.1 christos fvec->count = 0;
3538 1.1 christos }
3539 1.1 christos
3540 1.1 christos backtrace_qsort (addrs, addrs_count, sizeof (struct function_addrs),
3541 1.1 christos function_addrs_compare);
3542 1.1 christos
3543 1.1 christos *ret_addrs = addrs;
3544 1.1 christos *ret_addrs_count = addrs_count;
3545 1.1 christos }
3546 1.1 christos
3547 1.1 christos /* See if PC is inlined in FUNCTION. If it is, print out the inlined
3548 1.1 christos information, and update FILENAME and LINENO for the caller.
3549 1.1 christos Returns whatever CALLBACK returns, or 0 to keep going. */
3550 1.1 christos
3551 1.1 christos static int
3552 1.1 christos report_inlined_functions (uintptr_t pc, struct function *function,
3553 1.1 christos backtrace_full_callback callback, void *data,
3554 1.1 christos const char **filename, int *lineno)
3555 1.1 christos {
3556 1.1 christos struct function_addrs *p;
3557 1.1 christos struct function_addrs *match;
3558 1.1 christos struct function *inlined;
3559 1.1 christos int ret;
3560 1.1 christos
3561 1.1 christos if (function->function_addrs_count == 0)
3562 1.1 christos return 0;
3563 1.1 christos
3564 1.1 christos /* Our search isn't safe if pc == -1, as that is the sentinel
3565 1.1 christos value. */
3566 1.1 christos if (pc + 1 == 0)
3567 1.1 christos return 0;
3568 1.1 christos
3569 1.1 christos p = ((struct function_addrs *)
3570 1.1 christos bsearch (&pc, function->function_addrs,
3571 1.1 christos function->function_addrs_count,
3572 1.1 christos sizeof (struct function_addrs),
3573 1.1 christos function_addrs_search));
3574 1.1 christos if (p == NULL)
3575 1.1 christos return 0;
3576 1.1 christos
3577 1.1 christos /* Here pc >= p->low && pc < (p + 1)->low. The function_addrs are
3578 1.1 christos sorted by low, so if pc > p->low we are at the end of a range of
3579 1.1 christos function_addrs with the same low value. If pc == p->low walk
3580 1.1 christos forward to the end of the range with that low value. Then walk
3581 1.1 christos backward and use the first range that includes pc. */
3582 1.1 christos while (pc == (p + 1)->low)
3583 1.1 christos ++p;
3584 1.1 christos match = NULL;
3585 1.1 christos while (1)
3586 1.1 christos {
3587 1.1 christos if (pc < p->high)
3588 1.1 christos {
3589 1.1 christos match = p;
3590 1.1 christos break;
3591 1.1 christos }
3592 1.1 christos if (p == function->function_addrs)
3593 1.1 christos break;
3594 1.1 christos if ((p - 1)->low < p->low)
3595 1.1 christos break;
3596 1.1 christos --p;
3597 1.1 christos }
3598 1.1 christos if (match == NULL)
3599 1.1 christos return 0;
3600 1.1 christos
3601 1.1 christos /* We found an inlined call. */
3602 1.1 christos
3603 1.1 christos inlined = match->function;
3604 1.1 christos
3605 1.1 christos /* Report any calls inlined into this one. */
3606 1.1 christos ret = report_inlined_functions (pc, inlined, callback, data,
3607 1.1 christos filename, lineno);
3608 1.1 christos if (ret != 0)
3609 1.1 christos return ret;
3610 1.1 christos
3611 1.1 christos /* Report this inlined call. */
3612 1.1 christos ret = callback (data, pc, *filename, *lineno, inlined->name);
3613 1.1 christos if (ret != 0)
3614 1.1 christos return ret;
3615 1.1 christos
3616 1.1 christos /* Our caller will report the caller of the inlined function; tell
3617 1.1 christos it the appropriate filename and line number. */
3618 1.1 christos *filename = inlined->caller_filename;
3619 1.1 christos *lineno = inlined->caller_lineno;
3620 1.1 christos
3621 1.1 christos return 0;
3622 1.1 christos }
3623 1.1 christos
3624 1.1 christos /* Look for a PC in the DWARF mapping for one module. On success,
3625 1.1 christos call CALLBACK and return whatever it returns. On error, call
3626 1.1 christos ERROR_CALLBACK and return 0. Sets *FOUND to 1 if the PC is found,
3627 1.1 christos 0 if not. */
3628 1.1 christos
3629 1.1 christos static int
3630 1.1 christos dwarf_lookup_pc (struct backtrace_state *state, struct dwarf_data *ddata,
3631 1.1 christos uintptr_t pc, backtrace_full_callback callback,
3632 1.1 christos backtrace_error_callback error_callback, void *data,
3633 1.1 christos int *found)
3634 1.1 christos {
3635 1.1 christos struct unit_addrs *entry;
3636 1.1 christos int found_entry;
3637 1.1 christos struct unit *u;
3638 1.1 christos int new_data;
3639 1.1 christos struct line *lines;
3640 1.1 christos struct line *ln;
3641 1.1 christos struct function_addrs *p;
3642 1.1 christos struct function_addrs *fmatch;
3643 1.1 christos struct function *function;
3644 1.1 christos const char *filename;
3645 1.1 christos int lineno;
3646 1.1 christos int ret;
3647 1.1 christos
3648 1.1 christos *found = 1;
3649 1.1 christos
3650 1.1 christos /* Find an address range that includes PC. Our search isn't safe if
3651 1.1 christos PC == -1, as we use that as a sentinel value, so skip the search
3652 1.1 christos in that case. */
3653 1.1 christos entry = (ddata->addrs_count == 0 || pc + 1 == 0
3654 1.1 christos ? NULL
3655 1.1 christos : bsearch (&pc, ddata->addrs, ddata->addrs_count,
3656 1.1 christos sizeof (struct unit_addrs), unit_addrs_search));
3657 1.1 christos
3658 1.1 christos if (entry == NULL)
3659 1.1 christos {
3660 1.1 christos *found = 0;
3661 1.1 christos return 0;
3662 1.1 christos }
3663 1.1 christos
3664 1.1 christos /* Here pc >= entry->low && pc < (entry + 1)->low. The unit_addrs
3665 1.1 christos are sorted by low, so if pc > p->low we are at the end of a range
3666 1.1 christos of unit_addrs with the same low value. If pc == p->low walk
3667 1.1 christos forward to the end of the range with that low value. Then walk
3668 1.1 christos backward and use the first range that includes pc. */
3669 1.1 christos while (pc == (entry + 1)->low)
3670 1.1 christos ++entry;
3671 1.1 christos found_entry = 0;
3672 1.1 christos while (1)
3673 1.1 christos {
3674 1.1 christos if (pc < entry->high)
3675 1.1 christos {
3676 1.1 christos found_entry = 1;
3677 1.1 christos break;
3678 1.1 christos }
3679 1.1 christos if (entry == ddata->addrs)
3680 1.1 christos break;
3681 1.1 christos if ((entry - 1)->low < entry->low)
3682 1.1 christos break;
3683 1.1 christos --entry;
3684 1.1 christos }
3685 1.1 christos if (!found_entry)
3686 1.1 christos {
3687 1.1 christos *found = 0;
3688 1.1 christos return 0;
3689 1.1 christos }
3690 1.1 christos
3691 1.1 christos /* We need the lines, lines_count, function_addrs,
3692 1.1 christos function_addrs_count fields of u. If they are not set, we need
3693 1.1 christos to set them. When running in threaded mode, we need to allow for
3694 1.1 christos the possibility that some other thread is setting them
3695 1.1 christos simultaneously. */
3696 1.1 christos
3697 1.1 christos u = entry->u;
3698 1.1 christos lines = u->lines;
3699 1.1 christos
3700 1.1 christos /* Skip units with no useful line number information by walking
3701 1.1 christos backward. Useless line number information is marked by setting
3702 1.1 christos lines == -1. */
3703 1.1 christos while (entry > ddata->addrs
3704 1.1 christos && pc >= (entry - 1)->low
3705 1.1 christos && pc < (entry - 1)->high)
3706 1.1 christos {
3707 1.1 christos if (state->threaded)
3708 1.1 christos lines = (struct line *) backtrace_atomic_load_pointer (&u->lines);
3709 1.1 christos
3710 1.1 christos if (lines != (struct line *) (uintptr_t) -1)
3711 1.1 christos break;
3712 1.1 christos
3713 1.1 christos --entry;
3714 1.1 christos
3715 1.1 christos u = entry->u;
3716 1.1 christos lines = u->lines;
3717 1.1 christos }
3718 1.1 christos
3719 1.1 christos if (state->threaded)
3720 1.1 christos lines = backtrace_atomic_load_pointer (&u->lines);
3721 1.1 christos
3722 1.1 christos new_data = 0;
3723 1.1 christos if (lines == NULL)
3724 1.1 christos {
3725 1.1 christos struct function_addrs *function_addrs;
3726 1.1 christos size_t function_addrs_count;
3727 1.1 christos struct line_header lhdr;
3728 1.1 christos size_t count;
3729 1.1 christos
3730 1.1 christos /* We have never read the line information for this unit. Read
3731 1.1 christos it now. */
3732 1.1 christos
3733 1.1 christos function_addrs = NULL;
3734 1.1 christos function_addrs_count = 0;
3735 1.1 christos if (read_line_info (state, ddata, error_callback, data, entry->u, &lhdr,
3736 1.1 christos &lines, &count))
3737 1.1 christos {
3738 1.1 christos struct function_vector *pfvec;
3739 1.1 christos
3740 1.1 christos /* If not threaded, reuse DDATA->FVEC for better memory
3741 1.1 christos consumption. */
3742 1.1 christos if (state->threaded)
3743 1.1 christos pfvec = NULL;
3744 1.1 christos else
3745 1.1 christos pfvec = &ddata->fvec;
3746 1.1 christos read_function_info (state, ddata, &lhdr, error_callback, data,
3747 1.1 christos entry->u, pfvec, &function_addrs,
3748 1.1 christos &function_addrs_count);
3749 1.1 christos free_line_header (state, &lhdr, error_callback, data);
3750 1.1 christos new_data = 1;
3751 1.1 christos }
3752 1.1 christos
3753 1.1 christos /* Atomically store the information we just read into the unit.
3754 1.1 christos If another thread is simultaneously writing, it presumably
3755 1.1 christos read the same information, and we don't care which one we
3756 1.1 christos wind up with; we just leak the other one. We do have to
3757 1.1 christos write the lines field last, so that the acquire-loads above
3758 1.1 christos ensure that the other fields are set. */
3759 1.1 christos
3760 1.1 christos if (!state->threaded)
3761 1.1 christos {
3762 1.1 christos u->lines_count = count;
3763 1.1 christos u->function_addrs = function_addrs;
3764 1.1 christos u->function_addrs_count = function_addrs_count;
3765 1.1 christos u->lines = lines;
3766 1.1 christos }
3767 1.1 christos else
3768 1.1 christos {
3769 1.1 christos backtrace_atomic_store_size_t (&u->lines_count, count);
3770 1.1 christos backtrace_atomic_store_pointer (&u->function_addrs, function_addrs);
3771 1.1 christos backtrace_atomic_store_size_t (&u->function_addrs_count,
3772 1.1 christos function_addrs_count);
3773 1.1 christos backtrace_atomic_store_pointer (&u->lines, lines);
3774 1.1 christos }
3775 1.1 christos }
3776 1.1 christos
3777 1.1 christos /* Now all fields of U have been initialized. */
3778 1.1 christos
3779 1.1 christos if (lines == (struct line *) (uintptr_t) -1)
3780 1.1 christos {
3781 1.1 christos /* If reading the line number information failed in some way,
3782 1.1 christos try again to see if there is a better compilation unit for
3783 1.1 christos this PC. */
3784 1.1 christos if (new_data)
3785 1.1 christos return dwarf_lookup_pc (state, ddata, pc, callback, error_callback,
3786 1.1 christos data, found);
3787 1.1 christos return callback (data, pc, NULL, 0, NULL);
3788 1.1 christos }
3789 1.1 christos
3790 1.1 christos /* Search for PC within this unit. */
3791 1.1 christos
3792 1.1 christos ln = (struct line *) bsearch (&pc, lines, entry->u->lines_count,
3793 1.1 christos sizeof (struct line), line_search);
3794 1.1 christos if (ln == NULL)
3795 1.1 christos {
3796 1.1 christos /* The PC is between the low_pc and high_pc attributes of the
3797 1.1 christos compilation unit, but no entry in the line table covers it.
3798 1.1 christos This implies that the start of the compilation unit has no
3799 1.1 christos line number information. */
3800 1.1 christos
3801 1.1 christos if (entry->u->abs_filename == NULL)
3802 1.1 christos {
3803 1.1 christos const char *filename;
3804 1.1 christos
3805 1.1 christos filename = entry->u->filename;
3806 1.1 christos if (filename != NULL
3807 1.1 christos && !IS_ABSOLUTE_PATH (filename)
3808 1.1 christos && entry->u->comp_dir != NULL)
3809 1.1 christos {
3810 1.1 christos size_t filename_len;
3811 1.1 christos const char *dir;
3812 1.1 christos size_t dir_len;
3813 1.1 christos char *s;
3814 1.1 christos
3815 1.1 christos filename_len = strlen (filename);
3816 1.1 christos dir = entry->u->comp_dir;
3817 1.1 christos dir_len = strlen (dir);
3818 1.1 christos s = (char *) backtrace_alloc (state, dir_len + filename_len + 2,
3819 1.1 christos error_callback, data);
3820 1.1 christos if (s == NULL)
3821 1.1 christos {
3822 1.1 christos *found = 0;
3823 1.1 christos return 0;
3824 1.1 christos }
3825 1.1 christos memcpy (s, dir, dir_len);
3826 1.1 christos /* FIXME: Should use backslash if DOS file system. */
3827 1.1 christos s[dir_len] = '/';
3828 1.1 christos memcpy (s + dir_len + 1, filename, filename_len + 1);
3829 1.1 christos filename = s;
3830 1.1 christos }
3831 1.1 christos entry->u->abs_filename = filename;
3832 1.1 christos }
3833 1.1 christos
3834 1.1 christos return callback (data, pc, entry->u->abs_filename, 0, NULL);
3835 1.1 christos }
3836 1.1 christos
3837 1.1 christos /* Search for function name within this unit. */
3838 1.1 christos
3839 1.1 christos if (entry->u->function_addrs_count == 0)
3840 1.1 christos return callback (data, pc, ln->filename, ln->lineno, NULL);
3841 1.1 christos
3842 1.1 christos p = ((struct function_addrs *)
3843 1.1 christos bsearch (&pc, entry->u->function_addrs,
3844 1.1 christos entry->u->function_addrs_count,
3845 1.1 christos sizeof (struct function_addrs),
3846 1.1 christos function_addrs_search));
3847 1.1 christos if (p == NULL)
3848 1.1 christos return callback (data, pc, ln->filename, ln->lineno, NULL);
3849 1.1 christos
3850 1.1 christos /* Here pc >= p->low && pc < (p + 1)->low. The function_addrs are
3851 1.1 christos sorted by low, so if pc > p->low we are at the end of a range of
3852 1.1 christos function_addrs with the same low value. If pc == p->low walk
3853 1.1 christos forward to the end of the range with that low value. Then walk
3854 1.1 christos backward and use the first range that includes pc. */
3855 1.1 christos while (pc == (p + 1)->low)
3856 1.1 christos ++p;
3857 1.1 christos fmatch = NULL;
3858 1.1 christos while (1)
3859 1.1 christos {
3860 1.1 christos if (pc < p->high)
3861 1.1 christos {
3862 1.1 christos fmatch = p;
3863 1.1 christos break;
3864 1.1 christos }
3865 1.1 christos if (p == entry->u->function_addrs)
3866 1.1 christos break;
3867 1.1 christos if ((p - 1)->low < p->low)
3868 1.1 christos break;
3869 1.1 christos --p;
3870 1.1 christos }
3871 1.1 christos if (fmatch == NULL)
3872 1.1 christos return callback (data, pc, ln->filename, ln->lineno, NULL);
3873 1.1 christos
3874 1.1 christos function = fmatch->function;
3875 1.1 christos
3876 1.1 christos filename = ln->filename;
3877 1.1 christos lineno = ln->lineno;
3878 1.1 christos
3879 1.1 christos ret = report_inlined_functions (pc, function, callback, data,
3880 1.1 christos &filename, &lineno);
3881 1.1 christos if (ret != 0)
3882 1.1 christos return ret;
3883 1.1 christos
3884 1.1 christos return callback (data, pc, filename, lineno, function->name);
3885 1.1 christos }
3886 1.1 christos
3887 1.1 christos
3888 1.1 christos /* Return the file/line information for a PC using the DWARF mapping
3889 1.1 christos we built earlier. */
3890 1.1 christos
3891 1.1 christos static int
3892 1.1 christos dwarf_fileline (struct backtrace_state *state, uintptr_t pc,
3893 1.1 christos backtrace_full_callback callback,
3894 1.1 christos backtrace_error_callback error_callback, void *data)
3895 1.1 christos {
3896 1.1 christos struct dwarf_data *ddata;
3897 1.1 christos int found;
3898 1.1 christos int ret;
3899 1.1 christos
3900 1.1 christos if (!state->threaded)
3901 1.1 christos {
3902 1.1 christos for (ddata = (struct dwarf_data *) state->fileline_data;
3903 1.1 christos ddata != NULL;
3904 1.1 christos ddata = ddata->next)
3905 1.1 christos {
3906 1.1 christos ret = dwarf_lookup_pc (state, ddata, pc, callback, error_callback,
3907 1.1 christos data, &found);
3908 1.1 christos if (ret != 0 || found)
3909 1.1 christos return ret;
3910 1.1 christos }
3911 1.1 christos }
3912 1.1 christos else
3913 1.1 christos {
3914 1.1 christos struct dwarf_data **pp;
3915 1.1 christos
3916 1.1 christos pp = (struct dwarf_data **) (void *) &state->fileline_data;
3917 1.1 christos while (1)
3918 1.1 christos {
3919 1.1 christos ddata = backtrace_atomic_load_pointer (pp);
3920 1.1 christos if (ddata == NULL)
3921 1.1 christos break;
3922 1.1 christos
3923 1.1 christos ret = dwarf_lookup_pc (state, ddata, pc, callback, error_callback,
3924 1.1 christos data, &found);
3925 1.1 christos if (ret != 0 || found)
3926 1.1 christos return ret;
3927 1.1 christos
3928 1.1 christos pp = &ddata->next;
3929 1.1 christos }
3930 1.1 christos }
3931 1.1 christos
3932 1.1 christos /* FIXME: See if any libraries have been dlopen'ed. */
3933 1.1 christos
3934 1.1 christos return callback (data, pc, NULL, 0, NULL);
3935 1.1 christos }
3936 1.1 christos
3937 1.1 christos /* Initialize our data structures from the DWARF debug info for a
3938 1.1 christos file. Return NULL on failure. */
3939 1.1 christos
3940 1.1 christos static struct dwarf_data *
3941 1.1 christos build_dwarf_data (struct backtrace_state *state,
3942 1.1 christos uintptr_t base_address,
3943 1.1 christos const struct dwarf_sections *dwarf_sections,
3944 1.1 christos int is_bigendian,
3945 1.1 christos struct dwarf_data *altlink,
3946 1.1 christos backtrace_error_callback error_callback,
3947 1.1 christos void *data)
3948 1.1 christos {
3949 1.1 christos struct unit_addrs_vector addrs_vec;
3950 1.1 christos struct unit_addrs *addrs;
3951 1.1 christos size_t addrs_count;
3952 1.1 christos struct unit_vector units_vec;
3953 1.1 christos struct unit **units;
3954 1.1 christos size_t units_count;
3955 1.1 christos struct dwarf_data *fdata;
3956 1.1 christos
3957 1.1 christos if (!build_address_map (state, base_address, dwarf_sections, is_bigendian,
3958 1.1 christos altlink, error_callback, data, &addrs_vec,
3959 1.1 christos &units_vec))
3960 1.1 christos return NULL;
3961 1.1 christos
3962 1.1 christos if (!backtrace_vector_release (state, &addrs_vec.vec, error_callback, data))
3963 1.1 christos return NULL;
3964 1.1 christos if (!backtrace_vector_release (state, &units_vec.vec, error_callback, data))
3965 1.1 christos return NULL;
3966 1.1 christos addrs = (struct unit_addrs *) addrs_vec.vec.base;
3967 1.1 christos units = (struct unit **) units_vec.vec.base;
3968 1.1 christos addrs_count = addrs_vec.count;
3969 1.1 christos units_count = units_vec.count;
3970 1.1 christos backtrace_qsort (addrs, addrs_count, sizeof (struct unit_addrs),
3971 1.1 christos unit_addrs_compare);
3972 1.1 christos /* No qsort for units required, already sorted. */
3973 1.1 christos
3974 1.1 christos fdata = ((struct dwarf_data *)
3975 1.1 christos backtrace_alloc (state, sizeof (struct dwarf_data),
3976 1.1 christos error_callback, data));
3977 1.1 christos if (fdata == NULL)
3978 1.1 christos return NULL;
3979 1.1 christos
3980 1.1 christos fdata->next = NULL;
3981 1.1 christos fdata->altlink = altlink;
3982 1.1 christos fdata->base_address = base_address;
3983 1.1 christos fdata->addrs = addrs;
3984 1.1 christos fdata->addrs_count = addrs_count;
3985 1.1 christos fdata->units = units;
3986 1.1 christos fdata->units_count = units_count;
3987 1.1 christos fdata->dwarf_sections = *dwarf_sections;
3988 1.1 christos fdata->is_bigendian = is_bigendian;
3989 1.1 christos memset (&fdata->fvec, 0, sizeof fdata->fvec);
3990 1.1 christos
3991 1.1 christos return fdata;
3992 1.1 christos }
3993 1.1 christos
3994 1.1 christos /* Build our data structures from the DWARF sections for a module.
3995 1.1 christos Set FILELINE_FN and STATE->FILELINE_DATA. Return 1 on success, 0
3996 1.1 christos on failure. */
3997 1.1 christos
3998 1.1 christos int
3999 1.1 christos backtrace_dwarf_add (struct backtrace_state *state,
4000 1.1 christos uintptr_t base_address,
4001 1.1 christos const struct dwarf_sections *dwarf_sections,
4002 1.1 christos int is_bigendian,
4003 1.1 christos struct dwarf_data *fileline_altlink,
4004 1.1 christos backtrace_error_callback error_callback,
4005 1.1 christos void *data, fileline *fileline_fn,
4006 1.1 christos struct dwarf_data **fileline_entry)
4007 1.1 christos {
4008 1.1 christos struct dwarf_data *fdata;
4009 1.1 christos
4010 1.1 christos fdata = build_dwarf_data (state, base_address, dwarf_sections, is_bigendian,
4011 1.1 christos fileline_altlink, error_callback, data);
4012 1.1 christos if (fdata == NULL)
4013 1.1 christos return 0;
4014 1.1 christos
4015 1.1 christos if (fileline_entry != NULL)
4016 1.1 christos *fileline_entry = fdata;
4017 1.1 christos
4018 1.1 christos if (!state->threaded)
4019 1.1 christos {
4020 1.1 christos struct dwarf_data **pp;
4021 1.1 christos
4022 1.1 christos for (pp = (struct dwarf_data **) (void *) &state->fileline_data;
4023 1.1 christos *pp != NULL;
4024 1.1 christos pp = &(*pp)->next)
4025 1.1 christos ;
4026 1.1 christos *pp = fdata;
4027 1.1 christos }
4028 1.1 christos else
4029 1.1 christos {
4030 1.1 christos while (1)
4031 1.1 christos {
4032 1.1 christos struct dwarf_data **pp;
4033 1.1 christos
4034 1.1 christos pp = (struct dwarf_data **) (void *) &state->fileline_data;
4035 1.1 christos
4036 1.1 christos while (1)
4037 1.1 christos {
4038 1.1 christos struct dwarf_data *p;
4039 1.1 christos
4040 1.1 christos p = backtrace_atomic_load_pointer (pp);
4041 1.1 christos
4042 1.1 christos if (p == NULL)
4043 1.1 christos break;
4044 1.1 christos
4045 1.1 christos pp = &p->next;
4046 1.1 christos }
4047 1.1 christos
4048 1.1 christos if (__sync_bool_compare_and_swap (pp, NULL, fdata))
4049 1.1 christos break;
4050 1.1 christos }
4051 1.1 christos }
4052 1.1 christos
4053 1.1 christos *fileline_fn = dwarf_fileline;
4054 1.1 christos
4055 1.1 christos return 1;
4056 1.1 christos }
4057