Remove unused variable and field
[official-gcc.git] / libbacktrace / elf.c
blobc1dbc5492e0ef261def2b99c7c177890c1172593
1 /* elf.c -- Get debug data from an ELF file for backtraces.
2 Copyright (C) 2012-2013 Free Software Foundation, Inc.
3 Written by Ian Lance Taylor, Google.
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are
7 met:
9 (1) Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
12 (2) Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in
14 the documentation and/or other materials provided with the
15 distribution.
17 (3) The name of the author may not be used to
18 endorse or promote products derived from this software without
19 specific prior written permission.
21 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
25 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
30 IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 POSSIBILITY OF SUCH DAMAGE. */
33 #include "config.h"
35 #include <stdlib.h>
36 #include <string.h>
37 #include <sys/types.h>
39 #ifdef HAVE_DL_ITERATE_PHDR
40 #include <link.h>
41 #endif
43 #include "backtrace.h"
44 #include "internal.h"
46 #ifndef HAVE_DL_ITERATE_PHDR
48 /* Dummy version of dl_iterate_phdr for systems that don't have it. */
50 #define dl_phdr_info x_dl_phdr_info
51 #define dl_iterate_phdr x_dl_iterate_phdr
53 struct dl_phdr_info
55 uintptr_t dlpi_addr;
56 const char *dlpi_name;
59 static int
60 dl_iterate_phdr (int (*callback) (struct dl_phdr_info *,
61 size_t, void *) ATTRIBUTE_UNUSED,
62 void *data ATTRIBUTE_UNUSED)
64 return 0;
67 #endif /* ! defined (HAVE_DL_ITERATE_PHDR) */
69 /* The configure script must tell us whether we are 32-bit or 64-bit
70 ELF. We could make this code test and support either possibility,
71 but there is no point. This code only works for the currently
72 running executable, which means that we know the ELF mode at
73 configure mode. */
75 #if BACKTRACE_ELF_SIZE != 32 && BACKTRACE_ELF_SIZE != 64
76 #error "Unknown BACKTRACE_ELF_SIZE"
77 #endif
79 /* <link.h> might #include <elf.h> which might define our constants
80 with slightly different values. Undefine them to be safe. */
82 #undef EI_NIDENT
83 #undef EI_MAG0
84 #undef EI_MAG1
85 #undef EI_MAG2
86 #undef EI_MAG3
87 #undef EI_CLASS
88 #undef EI_DATA
89 #undef EI_VERSION
90 #undef ELF_MAG0
91 #undef ELF_MAG1
92 #undef ELF_MAG2
93 #undef ELF_MAG3
94 #undef ELFCLASS32
95 #undef ELFCLASS64
96 #undef ELFDATA2LSB
97 #undef ELFDATA2MSB
98 #undef EV_CURRENT
99 #undef SHN_LORESERVE
100 #undef SHN_XINDEX
101 #undef SHT_SYMTAB
102 #undef SHT_STRTAB
103 #undef SHT_DYNSYM
104 #undef STT_FUNC
106 /* Basic types. */
108 typedef uint16_t b_elf_half; /* Elf_Half. */
109 typedef uint32_t b_elf_word; /* Elf_Word. */
110 typedef int32_t b_elf_sword; /* Elf_Sword. */
112 #if BACKTRACE_ELF_SIZE == 32
114 typedef uint32_t b_elf_addr; /* Elf_Addr. */
115 typedef uint32_t b_elf_off; /* Elf_Off. */
117 typedef uint32_t b_elf_wxword; /* 32-bit Elf_Word, 64-bit ELF_Xword. */
119 #else
121 typedef uint64_t b_elf_addr; /* Elf_Addr. */
122 typedef uint64_t b_elf_off; /* Elf_Off. */
123 typedef uint64_t b_elf_xword; /* Elf_Xword. */
124 typedef int64_t b_elf_sxword; /* Elf_Sxword. */
126 typedef uint64_t b_elf_wxword; /* 32-bit Elf_Word, 64-bit ELF_Xword. */
128 #endif
130 /* Data structures and associated constants. */
132 #define EI_NIDENT 16
134 typedef struct {
135 unsigned char e_ident[EI_NIDENT]; /* ELF "magic number" */
136 b_elf_half e_type; /* Identifies object file type */
137 b_elf_half e_machine; /* Specifies required architecture */
138 b_elf_word e_version; /* Identifies object file version */
139 b_elf_addr e_entry; /* Entry point virtual address */
140 b_elf_off e_phoff; /* Program header table file offset */
141 b_elf_off e_shoff; /* Section header table file offset */
142 b_elf_word e_flags; /* Processor-specific flags */
143 b_elf_half e_ehsize; /* ELF header size in bytes */
144 b_elf_half e_phentsize; /* Program header table entry size */
145 b_elf_half e_phnum; /* Program header table entry count */
146 b_elf_half e_shentsize; /* Section header table entry size */
147 b_elf_half e_shnum; /* Section header table entry count */
148 b_elf_half e_shstrndx; /* Section header string table index */
149 } b_elf_ehdr; /* Elf_Ehdr. */
151 #define EI_MAG0 0
152 #define EI_MAG1 1
153 #define EI_MAG2 2
154 #define EI_MAG3 3
155 #define EI_CLASS 4
156 #define EI_DATA 5
157 #define EI_VERSION 6
159 #define ELFMAG0 0x7f
160 #define ELFMAG1 'E'
161 #define ELFMAG2 'L'
162 #define ELFMAG3 'F'
164 #define ELFCLASS32 1
165 #define ELFCLASS64 2
167 #define ELFDATA2LSB 1
168 #define ELFDATA2MSB 2
170 #define EV_CURRENT 1
172 typedef struct {
173 b_elf_word sh_name; /* Section name, index in string tbl */
174 b_elf_word sh_type; /* Type of section */
175 b_elf_wxword sh_flags; /* Miscellaneous section attributes */
176 b_elf_addr sh_addr; /* Section virtual addr at execution */
177 b_elf_off sh_offset; /* Section file offset */
178 b_elf_wxword sh_size; /* Size of section in bytes */
179 b_elf_word sh_link; /* Index of another section */
180 b_elf_word sh_info; /* Additional section information */
181 b_elf_wxword sh_addralign; /* Section alignment */
182 b_elf_wxword sh_entsize; /* Entry size if section holds table */
183 } b_elf_shdr; /* Elf_Shdr. */
185 #define SHN_LORESERVE 0xFF00 /* Begin range of reserved indices */
186 #define SHN_XINDEX 0xFFFF /* Section index is held elsewhere */
188 #define SHT_SYMTAB 2
189 #define SHT_STRTAB 3
190 #define SHT_DYNSYM 11
192 #if BACKTRACE_ELF_SIZE == 32
194 typedef struct
196 b_elf_word st_name; /* Symbol name, index in string tbl */
197 b_elf_addr st_value; /* Symbol value */
198 b_elf_word st_size; /* Symbol size */
199 unsigned char st_info; /* Symbol binding and type */
200 unsigned char st_other; /* Visibility and other data */
201 b_elf_half st_shndx; /* Symbol section index */
202 } b_elf_sym; /* Elf_Sym. */
204 #else /* BACKTRACE_ELF_SIZE != 32 */
206 typedef struct
208 b_elf_word st_name; /* Symbol name, index in string tbl */
209 unsigned char st_info; /* Symbol binding and type */
210 unsigned char st_other; /* Visibility and other data */
211 b_elf_half st_shndx; /* Symbol section index */
212 b_elf_addr st_value; /* Symbol value */
213 b_elf_xword st_size; /* Symbol size */
214 } b_elf_sym; /* Elf_Sym. */
216 #endif /* BACKTRACE_ELF_SIZE != 32 */
218 #define STT_FUNC 2
220 /* An index of ELF sections we care about. */
222 enum debug_section
224 DEBUG_INFO,
225 DEBUG_LINE,
226 DEBUG_ABBREV,
227 DEBUG_RANGES,
228 DEBUG_STR,
229 DEBUG_MAX
232 /* Names of sections, indexed by enum elf_section. */
234 static const char * const debug_section_names[DEBUG_MAX] =
236 ".debug_info",
237 ".debug_line",
238 ".debug_abbrev",
239 ".debug_ranges",
240 ".debug_str"
243 /* Information we gather for the sections we care about. */
245 struct debug_section_info
247 /* Section file offset. */
248 off_t offset;
249 /* Section size. */
250 size_t size;
251 /* Section contents, after read from file. */
252 const unsigned char *data;
255 /* Information we keep for an ELF symbol. */
257 struct elf_symbol
259 /* The name of the symbol. */
260 const char *name;
261 /* The address of the symbol. */
262 uintptr_t address;
263 /* The size of the symbol. */
264 size_t size;
267 /* Information to pass to elf_syminfo. */
269 struct elf_syminfo_data
271 /* Symbols for the next module. */
272 struct elf_syminfo_data *next;
273 /* The ELF symbols, sorted by address. */
274 struct elf_symbol *symbols;
275 /* The number of symbols. */
276 size_t count;
279 /* A dummy callback function used when we can't find any debug info. */
281 static int
282 elf_nodebug (struct backtrace_state *state ATTRIBUTE_UNUSED,
283 uintptr_t pc ATTRIBUTE_UNUSED,
284 backtrace_full_callback callback ATTRIBUTE_UNUSED,
285 backtrace_error_callback error_callback, void *data)
287 error_callback (data, "no debug info in ELF executable", -1);
288 return 0;
291 /* A dummy callback function used when we can't find a symbol
292 table. */
294 static void
295 elf_nosyms (struct backtrace_state *state ATTRIBUTE_UNUSED,
296 uintptr_t pc ATTRIBUTE_UNUSED,
297 backtrace_syminfo_callback callback ATTRIBUTE_UNUSED,
298 backtrace_error_callback error_callback, void *data)
300 error_callback (data, "no symbol table in ELF executable", -1);
303 /* Compare struct elf_symbol for qsort. */
305 static int
306 elf_symbol_compare (const void *v1, const void *v2)
308 const struct elf_symbol *e1 = (const struct elf_symbol *) v1;
309 const struct elf_symbol *e2 = (const struct elf_symbol *) v2;
311 if (e1->address < e2->address)
312 return -1;
313 else if (e1->address > e2->address)
314 return 1;
315 else
316 return 0;
319 /* Compare a PC against an elf_symbol for bsearch. We allocate one
320 extra entry in the array so that this can look safely at the next
321 entry. */
323 static int
324 elf_symbol_search (const void *vkey, const void *ventry)
326 const uintptr_t *key = (const uintptr_t *) vkey;
327 const struct elf_symbol *entry = (const struct elf_symbol *) ventry;
328 uintptr_t pc;
330 pc = *key;
331 if (pc < entry->address)
332 return -1;
333 else if (pc >= entry->address + entry->size)
334 return 1;
335 else
336 return 0;
339 /* Initialize the symbol table info for elf_syminfo. */
341 static int
342 elf_initialize_syminfo (struct backtrace_state *state,
343 const unsigned char *symtab_data, size_t symtab_size,
344 const unsigned char *strtab, size_t strtab_size,
345 backtrace_error_callback error_callback,
346 void *data, struct elf_syminfo_data *sdata)
348 size_t sym_count;
349 const b_elf_sym *sym;
350 size_t elf_symbol_count;
351 size_t elf_symbol_size;
352 struct elf_symbol *elf_symbols;
353 size_t i;
354 unsigned int j;
356 sym_count = symtab_size / sizeof (b_elf_sym);
358 /* We only care about function symbols. Count them. */
359 sym = (const b_elf_sym *) symtab_data;
360 elf_symbol_count = 0;
361 for (i = 0; i < sym_count; ++i, ++sym)
363 if ((sym->st_info & 0xf) == STT_FUNC)
364 ++elf_symbol_count;
367 elf_symbol_size = elf_symbol_count * sizeof (struct elf_symbol);
368 elf_symbols = ((struct elf_symbol *)
369 backtrace_alloc (state, elf_symbol_size, error_callback,
370 data));
371 if (elf_symbols == NULL)
372 return 0;
374 sym = (const b_elf_sym *) symtab_data;
375 j = 0;
376 for (i = 0; i < sym_count; ++i, ++sym)
378 if ((sym->st_info & 0xf) != STT_FUNC)
379 continue;
380 if (sym->st_name >= strtab_size)
382 error_callback (data, "symbol string index out of range", 0);
383 backtrace_free (state, elf_symbols, elf_symbol_size, error_callback,
384 data);
385 return 0;
387 elf_symbols[j].name = (const char *) strtab + sym->st_name;
388 elf_symbols[j].address = sym->st_value;
389 elf_symbols[j].size = sym->st_size;
390 ++j;
393 qsort (elf_symbols, elf_symbol_count, sizeof (struct elf_symbol),
394 elf_symbol_compare);
396 sdata->next = NULL;
397 sdata->symbols = elf_symbols;
398 sdata->count = elf_symbol_count;
400 return 1;
403 /* Add EDATA to the list in STATE. */
405 static void
406 elf_add_syminfo_data (struct backtrace_state *state,
407 struct elf_syminfo_data *edata)
409 if (!state->threaded)
411 struct elf_syminfo_data **pp;
413 for (pp = (struct elf_syminfo_data **) (void *) &state->syminfo_data;
414 *pp != NULL;
415 pp = &(*pp)->next)
417 *pp = edata;
419 else
421 while (1)
423 struct elf_syminfo_data **pp;
425 pp = (struct elf_syminfo_data **) (void *) &state->syminfo_data;
427 while (1)
429 struct elf_syminfo_data *p;
431 /* Atomic load. */
432 p = *pp;
433 while (!__sync_bool_compare_and_swap (pp, p, p))
434 p = *pp;
436 if (p == NULL)
437 break;
439 pp = &p->next;
442 if (__sync_bool_compare_and_swap (pp, NULL, edata))
443 break;
448 /* Return the symbol name and value for a PC. */
450 static void
451 elf_syminfo (struct backtrace_state *state, uintptr_t pc,
452 backtrace_syminfo_callback callback,
453 backtrace_error_callback error_callback ATTRIBUTE_UNUSED,
454 void *data)
456 struct elf_syminfo_data *edata;
457 struct elf_symbol *sym = NULL;
459 if (!state->threaded)
461 for (edata = (struct elf_syminfo_data *) state->syminfo_data;
462 edata != NULL;
463 edata = edata->next)
465 sym = ((struct elf_symbol *)
466 bsearch (&pc, edata->symbols, edata->count,
467 sizeof (struct elf_symbol), elf_symbol_search));
468 if (sym != NULL)
469 break;
472 else
474 struct elf_syminfo_data **pp;
476 pp = (struct elf_syminfo_data **) (void *) &state->syminfo_data;
477 while (1)
479 edata = *pp;
480 /* Atomic load. */
481 while (!__sync_bool_compare_and_swap (pp, edata, edata))
482 edata = *pp;
484 if (edata == NULL)
485 break;
487 sym = ((struct elf_symbol *)
488 bsearch (&pc, edata->symbols, edata->count,
489 sizeof (struct elf_symbol), elf_symbol_search));
490 if (sym != NULL)
491 break;
493 pp = &edata->next;
497 if (sym == NULL)
498 callback (data, pc, NULL, 0);
499 else
500 callback (data, pc, sym->name, sym->address);
503 /* Add the backtrace data for one ELF file. */
505 static int
506 elf_add (struct backtrace_state *state, int descriptor, uintptr_t base_address,
507 backtrace_error_callback error_callback, void *data,
508 fileline *fileline_fn, int *found_sym, int *found_dwarf)
510 struct backtrace_view ehdr_view;
511 b_elf_ehdr ehdr;
512 off_t shoff;
513 unsigned int shnum;
514 unsigned int shstrndx;
515 struct backtrace_view shdrs_view;
516 int shdrs_view_valid;
517 const b_elf_shdr *shdrs;
518 const b_elf_shdr *shstrhdr;
519 size_t shstr_size;
520 off_t shstr_off;
521 struct backtrace_view names_view;
522 int names_view_valid;
523 const char *names;
524 unsigned int symtab_shndx;
525 unsigned int dynsym_shndx;
526 unsigned int i;
527 struct debug_section_info sections[DEBUG_MAX];
528 struct backtrace_view symtab_view;
529 int symtab_view_valid;
530 struct backtrace_view strtab_view;
531 int strtab_view_valid;
532 off_t min_offset;
533 off_t max_offset;
534 struct backtrace_view debug_view;
535 int debug_view_valid;
537 *found_sym = 0;
538 *found_dwarf = 0;
540 shdrs_view_valid = 0;
541 names_view_valid = 0;
542 symtab_view_valid = 0;
543 strtab_view_valid = 0;
544 debug_view_valid = 0;
546 if (!backtrace_get_view (state, descriptor, 0, sizeof ehdr, error_callback,
547 data, &ehdr_view))
548 goto fail;
550 memcpy (&ehdr, ehdr_view.data, sizeof ehdr);
552 backtrace_release_view (state, &ehdr_view, error_callback, data);
554 if (ehdr.e_ident[EI_MAG0] != ELFMAG0
555 || ehdr.e_ident[EI_MAG1] != ELFMAG1
556 || ehdr.e_ident[EI_MAG2] != ELFMAG2
557 || ehdr.e_ident[EI_MAG3] != ELFMAG3)
559 error_callback (data, "executable file is not ELF", 0);
560 goto fail;
562 if (ehdr.e_ident[EI_VERSION] != EV_CURRENT)
564 error_callback (data, "executable file is unrecognized ELF version", 0);
565 goto fail;
568 #if BACKTRACE_ELF_SIZE == 32
569 #define BACKTRACE_ELFCLASS ELFCLASS32
570 #else
571 #define BACKTRACE_ELFCLASS ELFCLASS64
572 #endif
574 if (ehdr.e_ident[EI_CLASS] != BACKTRACE_ELFCLASS)
576 error_callback (data, "executable file is unexpected ELF class", 0);
577 goto fail;
580 if (ehdr.e_ident[EI_DATA] != ELFDATA2LSB
581 && ehdr.e_ident[EI_DATA] != ELFDATA2MSB)
583 error_callback (data, "executable file has unknown endianness", 0);
584 goto fail;
587 shoff = ehdr.e_shoff;
588 shnum = ehdr.e_shnum;
589 shstrndx = ehdr.e_shstrndx;
591 if ((shnum == 0 || shstrndx == SHN_XINDEX)
592 && shoff != 0)
594 struct backtrace_view shdr_view;
595 const b_elf_shdr *shdr;
597 if (!backtrace_get_view (state, descriptor, shoff, sizeof shdr,
598 error_callback, data, &shdr_view))
599 goto fail;
601 shdr = (const b_elf_shdr *) shdr_view.data;
603 if (shnum == 0)
604 shnum = shdr->sh_size;
606 if (shstrndx == SHN_XINDEX)
608 shstrndx = shdr->sh_link;
610 /* Versions of the GNU binutils between 2.12 and 2.18 did
611 not handle objects with more than SHN_LORESERVE sections
612 correctly. All large section indexes were offset by
613 0x100. There is more information at
614 http://sourceware.org/bugzilla/show_bug.cgi?id-5900 .
615 Fortunately these object files are easy to detect, as the
616 GNU binutils always put the section header string table
617 near the end of the list of sections. Thus if the
618 section header string table index is larger than the
619 number of sections, then we know we have to subtract
620 0x100 to get the real section index. */
621 if (shstrndx >= shnum && shstrndx >= SHN_LORESERVE + 0x100)
622 shstrndx -= 0x100;
625 backtrace_release_view (state, &shdr_view, error_callback, data);
628 /* To translate PC to file/line when using DWARF, we need to find
629 the .debug_info and .debug_line sections. */
631 /* Read the section headers, skipping the first one. */
633 if (!backtrace_get_view (state, descriptor, shoff + sizeof (b_elf_shdr),
634 (shnum - 1) * sizeof (b_elf_shdr),
635 error_callback, data, &shdrs_view))
636 goto fail;
637 shdrs_view_valid = 1;
638 shdrs = (const b_elf_shdr *) shdrs_view.data;
640 /* Read the section names. */
642 shstrhdr = &shdrs[shstrndx - 1];
643 shstr_size = shstrhdr->sh_size;
644 shstr_off = shstrhdr->sh_offset;
646 if (!backtrace_get_view (state, descriptor, shstr_off, shstr_size,
647 error_callback, data, &names_view))
648 goto fail;
649 names_view_valid = 1;
650 names = (const char *) names_view.data;
652 symtab_shndx = 0;
653 dynsym_shndx = 0;
655 memset (sections, 0, sizeof sections);
657 /* Look for the symbol table. */
658 for (i = 1; i < shnum; ++i)
660 const b_elf_shdr *shdr;
661 unsigned int sh_name;
662 const char *name;
663 int j;
665 shdr = &shdrs[i - 1];
667 if (shdr->sh_type == SHT_SYMTAB)
668 symtab_shndx = i;
669 else if (shdr->sh_type == SHT_DYNSYM)
670 dynsym_shndx = i;
672 sh_name = shdr->sh_name;
673 if (sh_name >= shstr_size)
675 error_callback (data, "ELF section name out of range", 0);
676 goto fail;
679 name = names + sh_name;
681 for (j = 0; j < (int) DEBUG_MAX; ++j)
683 if (strcmp (name, debug_section_names[j]) == 0)
685 sections[j].offset = shdr->sh_offset;
686 sections[j].size = shdr->sh_size;
687 break;
692 if (symtab_shndx == 0)
693 symtab_shndx = dynsym_shndx;
694 if (symtab_shndx != 0)
696 const b_elf_shdr *symtab_shdr;
697 unsigned int strtab_shndx;
698 const b_elf_shdr *strtab_shdr;
699 struct elf_syminfo_data *sdata;
701 symtab_shdr = &shdrs[symtab_shndx - 1];
702 strtab_shndx = symtab_shdr->sh_link;
703 if (strtab_shndx >= shnum)
705 error_callback (data,
706 "ELF symbol table strtab link out of range", 0);
707 goto fail;
709 strtab_shdr = &shdrs[strtab_shndx - 1];
711 if (!backtrace_get_view (state, descriptor, symtab_shdr->sh_offset,
712 symtab_shdr->sh_size, error_callback, data,
713 &symtab_view))
714 goto fail;
715 symtab_view_valid = 1;
717 if (!backtrace_get_view (state, descriptor, strtab_shdr->sh_offset,
718 strtab_shdr->sh_size, error_callback, data,
719 &strtab_view))
720 goto fail;
721 strtab_view_valid = 1;
723 sdata = ((struct elf_syminfo_data *)
724 backtrace_alloc (state, sizeof *sdata, error_callback, data));
725 if (sdata == NULL)
726 goto fail;
728 if (!elf_initialize_syminfo (state,
729 symtab_view.data, symtab_shdr->sh_size,
730 strtab_view.data, strtab_shdr->sh_size,
731 error_callback, data, sdata))
733 backtrace_free (state, sdata, sizeof *sdata, error_callback, data);
734 goto fail;
737 /* We no longer need the symbol table, but we hold on to the
738 string table permanently. */
739 backtrace_release_view (state, &symtab_view, error_callback, data);
741 *found_sym = 1;
743 elf_add_syminfo_data (state, sdata);
746 /* FIXME: Need to handle compressed debug sections. */
748 backtrace_release_view (state, &shdrs_view, error_callback, data);
749 shdrs_view_valid = 0;
750 backtrace_release_view (state, &names_view, error_callback, data);
751 names_view_valid = 0;
753 /* Read all the debug sections in a single view, since they are
754 probably adjacent in the file. We never release this view. */
756 min_offset = 0;
757 max_offset = 0;
758 for (i = 0; i < (int) DEBUG_MAX; ++i)
760 off_t end;
762 if (min_offset == 0 || sections[i].offset < min_offset)
763 min_offset = sections[i].offset;
764 end = sections[i].offset + sections[i].size;
765 if (end > max_offset)
766 max_offset = end;
768 if (min_offset == 0 || max_offset == 0)
770 if (!backtrace_close (descriptor, error_callback, data))
771 goto fail;
772 *fileline_fn = elf_nodebug;
773 return 1;
776 if (!backtrace_get_view (state, descriptor, min_offset,
777 max_offset - min_offset,
778 error_callback, data, &debug_view))
779 goto fail;
780 debug_view_valid = 1;
782 /* We've read all we need from the executable. */
783 if (!backtrace_close (descriptor, error_callback, data))
784 goto fail;
785 descriptor = -1;
787 for (i = 0; i < (int) DEBUG_MAX; ++i)
788 sections[i].data = ((const unsigned char *) debug_view.data
789 + (sections[i].offset - min_offset));
791 if (!backtrace_dwarf_add (state, base_address,
792 sections[DEBUG_INFO].data,
793 sections[DEBUG_INFO].size,
794 sections[DEBUG_LINE].data,
795 sections[DEBUG_LINE].size,
796 sections[DEBUG_ABBREV].data,
797 sections[DEBUG_ABBREV].size,
798 sections[DEBUG_RANGES].data,
799 sections[DEBUG_RANGES].size,
800 sections[DEBUG_STR].data,
801 sections[DEBUG_STR].size,
802 ehdr.e_ident[EI_DATA] == ELFDATA2MSB,
803 error_callback, data, fileline_fn))
804 goto fail;
806 *found_dwarf = 1;
808 return 1;
810 fail:
811 if (shdrs_view_valid)
812 backtrace_release_view (state, &shdrs_view, error_callback, data);
813 if (names_view_valid)
814 backtrace_release_view (state, &names_view, error_callback, data);
815 if (symtab_view_valid)
816 backtrace_release_view (state, &symtab_view, error_callback, data);
817 if (strtab_view_valid)
818 backtrace_release_view (state, &strtab_view, error_callback, data);
819 if (debug_view_valid)
820 backtrace_release_view (state, &debug_view, error_callback, data);
821 if (descriptor != -1)
822 backtrace_close (descriptor, error_callback, data);
823 return 0;
826 /* Data passed to phdr_callback. */
828 struct phdr_data
830 struct backtrace_state *state;
831 backtrace_error_callback error_callback;
832 void *data;
833 fileline *fileline_fn;
834 int *found_sym;
835 int *found_dwarf;
838 /* Callback passed to dl_iterate_phdr. Load debug info from shared
839 libraries. */
841 static int
842 phdr_callback (struct dl_phdr_info *info, size_t size ATTRIBUTE_UNUSED,
843 void *pdata)
845 struct phdr_data *pd = (struct phdr_data *) pdata;
846 int descriptor;
847 int does_not_exist;
848 fileline elf_fileline_fn;
849 int found_dwarf;
851 /* There is not much we can do if we don't have the module name. If
852 the base address is 0, this is probably the executable, which we
853 already loaded. */
854 if (info->dlpi_name == NULL
855 || info->dlpi_name[0] == '\0'
856 || info->dlpi_addr == 0)
857 return 0;
859 descriptor = backtrace_open (info->dlpi_name, pd->error_callback, pd->data,
860 &does_not_exist);
861 if (descriptor < 0)
862 return 0;
864 if (elf_add (pd->state, descriptor, info->dlpi_addr, pd->error_callback,
865 pd->data, &elf_fileline_fn, pd->found_sym, &found_dwarf))
867 if (found_dwarf)
869 *pd->found_dwarf = 1;
870 *pd->fileline_fn = elf_fileline_fn;
874 return 0;
877 /* Initialize the backtrace data we need from an ELF executable. At
878 the ELF level, all we need to do is find the debug info
879 sections. */
882 backtrace_initialize (struct backtrace_state *state, int descriptor,
883 backtrace_error_callback error_callback,
884 void *data, fileline *fileline_fn)
886 int found_sym;
887 int found_dwarf;
888 syminfo elf_syminfo_fn;
889 fileline elf_fileline_fn;
890 struct phdr_data pd;
892 if (!elf_add (state, descriptor, 0, error_callback, data, &elf_fileline_fn,
893 &found_sym, &found_dwarf))
894 return 0;
896 pd.state = state;
897 pd.error_callback = error_callback;
898 pd.data = data;
899 pd.fileline_fn = &elf_fileline_fn;
900 pd.found_sym = &found_sym;
901 pd.found_dwarf = &found_dwarf;
903 dl_iterate_phdr (phdr_callback, (void *) &pd);
905 elf_syminfo_fn = found_sym ? elf_syminfo : elf_nosyms;
906 if (!state->threaded)
908 if (state->syminfo_fn == NULL || found_sym)
909 state->syminfo_fn = elf_syminfo_fn;
911 else
913 __sync_bool_compare_and_swap (&state->syminfo_fn, NULL, elf_syminfo_fn);
914 if (found_sym)
915 __sync_bool_compare_and_swap (&state->syminfo_fn, elf_nosyms,
916 elf_syminfo_fn);
919 if (!state->threaded)
921 if (state->fileline_fn == NULL || state->fileline_fn == elf_nodebug)
922 *fileline_fn = elf_fileline_fn;
924 else
926 fileline current_fn;
928 /* Atomic load. */
929 current_fn = state->fileline_fn;
930 while (!__sync_bool_compare_and_swap (&state->fileline_fn, current_fn,
931 current_fn))
932 current_fn = state->fileline_fn;
933 if (current_fn == NULL || current_fn == elf_nodebug)
934 *fileline_fn = elf_fileline_fn;
937 return 1;