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