1 /* elf.c -- Get debug data from an ELF file for backtraces.
2 Copyright (C) 2012-2014 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
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
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. */
37 #include <sys/types.h>
39 #ifdef HAVE_DL_ITERATE_PHDR
43 #include "backtrace.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
56 const char *dlpi_name
;
60 dl_iterate_phdr (int (*callback
) (struct dl_phdr_info
*,
61 size_t, void *) ATTRIBUTE_UNUSED
,
62 void *data ATTRIBUTE_UNUSED
)
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
75 #if BACKTRACE_ELF_SIZE != 32 && BACKTRACE_ELF_SIZE != 64
76 #error "Unknown BACKTRACE_ELF_SIZE"
79 /* <link.h> might #include <elf.h> which might define our constants
80 with slightly different values. Undefine them to be safe. */
111 typedef uint16_t b_elf_half
; /* Elf_Half. */
112 typedef uint32_t b_elf_word
; /* Elf_Word. */
113 typedef int32_t b_elf_sword
; /* Elf_Sword. */
115 #if BACKTRACE_ELF_SIZE == 32
117 typedef uint32_t b_elf_addr
; /* Elf_Addr. */
118 typedef uint32_t b_elf_off
; /* Elf_Off. */
120 typedef uint32_t b_elf_wxword
; /* 32-bit Elf_Word, 64-bit ELF_Xword. */
124 typedef uint64_t b_elf_addr
; /* Elf_Addr. */
125 typedef uint64_t b_elf_off
; /* Elf_Off. */
126 typedef uint64_t b_elf_xword
; /* Elf_Xword. */
127 typedef int64_t b_elf_sxword
; /* Elf_Sxword. */
129 typedef uint64_t b_elf_wxword
; /* 32-bit Elf_Word, 64-bit ELF_Xword. */
133 /* Data structures and associated constants. */
138 unsigned char e_ident
[EI_NIDENT
]; /* ELF "magic number" */
139 b_elf_half e_type
; /* Identifies object file type */
140 b_elf_half e_machine
; /* Specifies required architecture */
141 b_elf_word e_version
; /* Identifies object file version */
142 b_elf_addr e_entry
; /* Entry point virtual address */
143 b_elf_off e_phoff
; /* Program header table file offset */
144 b_elf_off e_shoff
; /* Section header table file offset */
145 b_elf_word e_flags
; /* Processor-specific flags */
146 b_elf_half e_ehsize
; /* ELF header size in bytes */
147 b_elf_half e_phentsize
; /* Program header table entry size */
148 b_elf_half e_phnum
; /* Program header table entry count */
149 b_elf_half e_shentsize
; /* Section header table entry size */
150 b_elf_half e_shnum
; /* Section header table entry count */
151 b_elf_half e_shstrndx
; /* Section header string table index */
152 } b_elf_ehdr
; /* Elf_Ehdr. */
170 #define ELFDATA2LSB 1
171 #define ELFDATA2MSB 2
178 b_elf_word sh_name
; /* Section name, index in string tbl */
179 b_elf_word sh_type
; /* Type of section */
180 b_elf_wxword sh_flags
; /* Miscellaneous section attributes */
181 b_elf_addr sh_addr
; /* Section virtual addr at execution */
182 b_elf_off sh_offset
; /* Section file offset */
183 b_elf_wxword sh_size
; /* Size of section in bytes */
184 b_elf_word sh_link
; /* Index of another section */
185 b_elf_word sh_info
; /* Additional section information */
186 b_elf_wxword sh_addralign
; /* Section alignment */
187 b_elf_wxword sh_entsize
; /* Entry size if section holds table */
188 } b_elf_shdr
; /* Elf_Shdr. */
190 #define SHN_UNDEF 0x0000 /* Undefined section */
191 #define SHN_LORESERVE 0xFF00 /* Begin range of reserved indices */
192 #define SHN_XINDEX 0xFFFF /* Section index is held elsewhere */
196 #define SHT_DYNSYM 11
198 #if BACKTRACE_ELF_SIZE == 32
202 b_elf_word st_name
; /* Symbol name, index in string tbl */
203 b_elf_addr st_value
; /* Symbol value */
204 b_elf_word st_size
; /* Symbol size */
205 unsigned char st_info
; /* Symbol binding and type */
206 unsigned char st_other
; /* Visibility and other data */
207 b_elf_half st_shndx
; /* Symbol section index */
208 } b_elf_sym
; /* Elf_Sym. */
210 #else /* BACKTRACE_ELF_SIZE != 32 */
214 b_elf_word st_name
; /* Symbol name, index in string tbl */
215 unsigned char st_info
; /* Symbol binding and type */
216 unsigned char st_other
; /* Visibility and other data */
217 b_elf_half st_shndx
; /* Symbol section index */
218 b_elf_addr st_value
; /* Symbol value */
219 b_elf_xword st_size
; /* Symbol size */
220 } b_elf_sym
; /* Elf_Sym. */
222 #endif /* BACKTRACE_ELF_SIZE != 32 */
227 /* An index of ELF sections we care about. */
239 /* Names of sections, indexed by enum elf_section. */
241 static const char * const debug_section_names
[DEBUG_MAX
] =
250 /* Information we gather for the sections we care about. */
252 struct debug_section_info
254 /* Section file offset. */
258 /* Section contents, after read from file. */
259 const unsigned char *data
;
262 /* Information we keep for an ELF symbol. */
266 /* The name of the symbol. */
268 /* The address of the symbol. */
270 /* The size of the symbol. */
274 /* Information to pass to elf_syminfo. */
276 struct elf_syminfo_data
278 /* Symbols for the next module. */
279 struct elf_syminfo_data
*next
;
280 /* The ELF symbols, sorted by address. */
281 struct elf_symbol
*symbols
;
282 /* The number of symbols. */
286 /* A dummy callback function used when we can't find any debug info. */
289 elf_nodebug (struct backtrace_state
*state ATTRIBUTE_UNUSED
,
290 uintptr_t pc ATTRIBUTE_UNUSED
,
291 backtrace_full_callback callback ATTRIBUTE_UNUSED
,
292 backtrace_error_callback error_callback
, void *data
)
294 error_callback (data
, "no debug info in ELF executable", -1);
298 /* A dummy callback function used when we can't find a symbol
302 elf_nosyms (struct backtrace_state
*state ATTRIBUTE_UNUSED
,
303 uintptr_t addr ATTRIBUTE_UNUSED
,
304 backtrace_syminfo_callback callback ATTRIBUTE_UNUSED
,
305 backtrace_error_callback error_callback
, void *data
)
307 error_callback (data
, "no symbol table in ELF executable", -1);
310 /* Compare struct elf_symbol for qsort. */
313 elf_symbol_compare (const void *v1
, const void *v2
)
315 const struct elf_symbol
*e1
= (const struct elf_symbol
*) v1
;
316 const struct elf_symbol
*e2
= (const struct elf_symbol
*) v2
;
318 if (e1
->address
< e2
->address
)
320 else if (e1
->address
> e2
->address
)
326 /* Compare an ADDR against an elf_symbol for bsearch. We allocate one
327 extra entry in the array so that this can look safely at the next
331 elf_symbol_search (const void *vkey
, const void *ventry
)
333 const uintptr_t *key
= (const uintptr_t *) vkey
;
334 const struct elf_symbol
*entry
= (const struct elf_symbol
*) ventry
;
338 if (addr
< entry
->address
)
340 else if (addr
>= entry
->address
+ entry
->size
)
346 /* Initialize the symbol table info for elf_syminfo. */
349 elf_initialize_syminfo (struct backtrace_state
*state
,
350 uintptr_t base_address
,
351 const unsigned char *symtab_data
, size_t symtab_size
,
352 const unsigned char *strtab
, size_t strtab_size
,
353 backtrace_error_callback error_callback
,
354 void *data
, struct elf_syminfo_data
*sdata
)
357 const b_elf_sym
*sym
;
358 size_t elf_symbol_count
;
359 size_t elf_symbol_size
;
360 struct elf_symbol
*elf_symbols
;
364 sym_count
= symtab_size
/ sizeof (b_elf_sym
);
366 /* We only care about function symbols. Count them. */
367 sym
= (const b_elf_sym
*) symtab_data
;
368 elf_symbol_count
= 0;
369 for (i
= 0; i
< sym_count
; ++i
, ++sym
)
373 info
= sym
->st_info
& 0xf;
374 if ((info
== STT_FUNC
|| info
== STT_OBJECT
)
375 && sym
->st_shndx
!= SHN_UNDEF
)
379 elf_symbol_size
= elf_symbol_count
* sizeof (struct elf_symbol
);
380 elf_symbols
= ((struct elf_symbol
*)
381 backtrace_alloc (state
, elf_symbol_size
, error_callback
,
383 if (elf_symbols
== NULL
)
386 sym
= (const b_elf_sym
*) symtab_data
;
388 for (i
= 0; i
< sym_count
; ++i
, ++sym
)
392 info
= sym
->st_info
& 0xf;
393 if (info
!= STT_FUNC
&& info
!= STT_OBJECT
)
395 if (sym
->st_shndx
== SHN_UNDEF
)
397 if (sym
->st_name
>= strtab_size
)
399 error_callback (data
, "symbol string index out of range", 0);
400 backtrace_free (state
, elf_symbols
, elf_symbol_size
, error_callback
,
404 elf_symbols
[j
].name
= (const char *) strtab
+ sym
->st_name
;
405 elf_symbols
[j
].address
= sym
->st_value
+ base_address
;
406 elf_symbols
[j
].size
= sym
->st_size
;
410 qsort (elf_symbols
, elf_symbol_count
, sizeof (struct elf_symbol
),
414 sdata
->symbols
= elf_symbols
;
415 sdata
->count
= elf_symbol_count
;
420 /* Add EDATA to the list in STATE. */
423 elf_add_syminfo_data (struct backtrace_state
*state
,
424 struct elf_syminfo_data
*edata
)
426 if (!state
->threaded
)
428 struct elf_syminfo_data
**pp
;
430 for (pp
= (struct elf_syminfo_data
**) (void *) &state
->syminfo_data
;
440 struct elf_syminfo_data
**pp
;
442 pp
= (struct elf_syminfo_data
**) (void *) &state
->syminfo_data
;
446 struct elf_syminfo_data
*p
;
448 p
= backtrace_atomic_load_pointer (pp
);
456 if (__sync_bool_compare_and_swap (pp
, NULL
, edata
))
462 /* Return the symbol name and value for an ADDR. */
465 elf_syminfo (struct backtrace_state
*state
, uintptr_t addr
,
466 backtrace_syminfo_callback callback
,
467 backtrace_error_callback error_callback ATTRIBUTE_UNUSED
,
470 struct elf_syminfo_data
*edata
;
471 struct elf_symbol
*sym
= NULL
;
473 if (!state
->threaded
)
475 for (edata
= (struct elf_syminfo_data
*) state
->syminfo_data
;
479 sym
= ((struct elf_symbol
*)
480 bsearch (&addr
, edata
->symbols
, edata
->count
,
481 sizeof (struct elf_symbol
), elf_symbol_search
));
488 struct elf_syminfo_data
**pp
;
490 pp
= (struct elf_syminfo_data
**) (void *) &state
->syminfo_data
;
493 edata
= backtrace_atomic_load_pointer (pp
);
497 sym
= ((struct elf_symbol
*)
498 bsearch (&addr
, edata
->symbols
, edata
->count
,
499 sizeof (struct elf_symbol
), elf_symbol_search
));
508 callback (data
, addr
, NULL
, 0, 0);
510 callback (data
, addr
, sym
->name
, sym
->address
, sym
->size
);
513 /* Add the backtrace data for one ELF file. Returns 1 on success,
514 0 on failure (in both cases descriptor is closed) or -1 if exe
515 is non-zero and the ELF file is ET_DYN, which tells the caller that
516 elf_add will need to be called on the descriptor again after
517 base_address is determined. */
520 elf_add (struct backtrace_state
*state
, int descriptor
, uintptr_t base_address
,
521 backtrace_error_callback error_callback
, void *data
,
522 fileline
*fileline_fn
, int *found_sym
, int *found_dwarf
, int exe
)
524 struct backtrace_view ehdr_view
;
528 unsigned int shstrndx
;
529 struct backtrace_view shdrs_view
;
530 int shdrs_view_valid
;
531 const b_elf_shdr
*shdrs
;
532 const b_elf_shdr
*shstrhdr
;
535 struct backtrace_view names_view
;
536 int names_view_valid
;
538 unsigned int symtab_shndx
;
539 unsigned int dynsym_shndx
;
541 struct debug_section_info sections
[DEBUG_MAX
];
542 struct backtrace_view symtab_view
;
543 int symtab_view_valid
;
544 struct backtrace_view strtab_view
;
545 int strtab_view_valid
;
548 struct backtrace_view debug_view
;
549 int debug_view_valid
;
554 shdrs_view_valid
= 0;
555 names_view_valid
= 0;
556 symtab_view_valid
= 0;
557 strtab_view_valid
= 0;
558 debug_view_valid
= 0;
560 if (!backtrace_get_view (state
, descriptor
, 0, sizeof ehdr
, error_callback
,
564 memcpy (&ehdr
, ehdr_view
.data
, sizeof ehdr
);
566 backtrace_release_view (state
, &ehdr_view
, error_callback
, data
);
568 if (ehdr
.e_ident
[EI_MAG0
] != ELFMAG0
569 || ehdr
.e_ident
[EI_MAG1
] != ELFMAG1
570 || ehdr
.e_ident
[EI_MAG2
] != ELFMAG2
571 || ehdr
.e_ident
[EI_MAG3
] != ELFMAG3
)
573 error_callback (data
, "executable file is not ELF", 0);
576 if (ehdr
.e_ident
[EI_VERSION
] != EV_CURRENT
)
578 error_callback (data
, "executable file is unrecognized ELF version", 0);
582 #if BACKTRACE_ELF_SIZE == 32
583 #define BACKTRACE_ELFCLASS ELFCLASS32
585 #define BACKTRACE_ELFCLASS ELFCLASS64
588 if (ehdr
.e_ident
[EI_CLASS
] != BACKTRACE_ELFCLASS
)
590 error_callback (data
, "executable file is unexpected ELF class", 0);
594 if (ehdr
.e_ident
[EI_DATA
] != ELFDATA2LSB
595 && ehdr
.e_ident
[EI_DATA
] != ELFDATA2MSB
)
597 error_callback (data
, "executable file has unknown endianness", 0);
601 /* If the executable is ET_DYN, it is either a PIE, or we are running
602 directly a shared library with .interp. We need to wait for
603 dl_iterate_phdr in that case to determine the actual base_address. */
604 if (exe
&& ehdr
.e_type
== ET_DYN
)
607 shoff
= ehdr
.e_shoff
;
608 shnum
= ehdr
.e_shnum
;
609 shstrndx
= ehdr
.e_shstrndx
;
611 if ((shnum
== 0 || shstrndx
== SHN_XINDEX
)
614 struct backtrace_view shdr_view
;
615 const b_elf_shdr
*shdr
;
617 if (!backtrace_get_view (state
, descriptor
, shoff
, sizeof shdr
,
618 error_callback
, data
, &shdr_view
))
621 shdr
= (const b_elf_shdr
*) shdr_view
.data
;
624 shnum
= shdr
->sh_size
;
626 if (shstrndx
== SHN_XINDEX
)
628 shstrndx
= shdr
->sh_link
;
630 /* Versions of the GNU binutils between 2.12 and 2.18 did
631 not handle objects with more than SHN_LORESERVE sections
632 correctly. All large section indexes were offset by
633 0x100. There is more information at
634 http://sourceware.org/bugzilla/show_bug.cgi?id-5900 .
635 Fortunately these object files are easy to detect, as the
636 GNU binutils always put the section header string table
637 near the end of the list of sections. Thus if the
638 section header string table index is larger than the
639 number of sections, then we know we have to subtract
640 0x100 to get the real section index. */
641 if (shstrndx
>= shnum
&& shstrndx
>= SHN_LORESERVE
+ 0x100)
645 backtrace_release_view (state
, &shdr_view
, error_callback
, data
);
648 /* To translate PC to file/line when using DWARF, we need to find
649 the .debug_info and .debug_line sections. */
651 /* Read the section headers, skipping the first one. */
653 if (!backtrace_get_view (state
, descriptor
, shoff
+ sizeof (b_elf_shdr
),
654 (shnum
- 1) * sizeof (b_elf_shdr
),
655 error_callback
, data
, &shdrs_view
))
657 shdrs_view_valid
= 1;
658 shdrs
= (const b_elf_shdr
*) shdrs_view
.data
;
660 /* Read the section names. */
662 shstrhdr
= &shdrs
[shstrndx
- 1];
663 shstr_size
= shstrhdr
->sh_size
;
664 shstr_off
= shstrhdr
->sh_offset
;
666 if (!backtrace_get_view (state
, descriptor
, shstr_off
, shstr_size
,
667 error_callback
, data
, &names_view
))
669 names_view_valid
= 1;
670 names
= (const char *) names_view
.data
;
675 memset (sections
, 0, sizeof sections
);
677 /* Look for the symbol table. */
678 for (i
= 1; i
< shnum
; ++i
)
680 const b_elf_shdr
*shdr
;
681 unsigned int sh_name
;
685 shdr
= &shdrs
[i
- 1];
687 if (shdr
->sh_type
== SHT_SYMTAB
)
689 else if (shdr
->sh_type
== SHT_DYNSYM
)
692 sh_name
= shdr
->sh_name
;
693 if (sh_name
>= shstr_size
)
695 error_callback (data
, "ELF section name out of range", 0);
699 name
= names
+ sh_name
;
701 for (j
= 0; j
< (int) DEBUG_MAX
; ++j
)
703 if (strcmp (name
, debug_section_names
[j
]) == 0)
705 sections
[j
].offset
= shdr
->sh_offset
;
706 sections
[j
].size
= shdr
->sh_size
;
712 if (symtab_shndx
== 0)
713 symtab_shndx
= dynsym_shndx
;
714 if (symtab_shndx
!= 0)
716 const b_elf_shdr
*symtab_shdr
;
717 unsigned int strtab_shndx
;
718 const b_elf_shdr
*strtab_shdr
;
719 struct elf_syminfo_data
*sdata
;
721 symtab_shdr
= &shdrs
[symtab_shndx
- 1];
722 strtab_shndx
= symtab_shdr
->sh_link
;
723 if (strtab_shndx
>= shnum
)
725 error_callback (data
,
726 "ELF symbol table strtab link out of range", 0);
729 strtab_shdr
= &shdrs
[strtab_shndx
- 1];
731 if (!backtrace_get_view (state
, descriptor
, symtab_shdr
->sh_offset
,
732 symtab_shdr
->sh_size
, error_callback
, data
,
735 symtab_view_valid
= 1;
737 if (!backtrace_get_view (state
, descriptor
, strtab_shdr
->sh_offset
,
738 strtab_shdr
->sh_size
, error_callback
, data
,
741 strtab_view_valid
= 1;
743 sdata
= ((struct elf_syminfo_data
*)
744 backtrace_alloc (state
, sizeof *sdata
, error_callback
, data
));
748 if (!elf_initialize_syminfo (state
, base_address
,
749 symtab_view
.data
, symtab_shdr
->sh_size
,
750 strtab_view
.data
, strtab_shdr
->sh_size
,
751 error_callback
, data
, sdata
))
753 backtrace_free (state
, sdata
, sizeof *sdata
, error_callback
, data
);
757 /* We no longer need the symbol table, but we hold on to the
758 string table permanently. */
759 backtrace_release_view (state
, &symtab_view
, error_callback
, data
);
763 elf_add_syminfo_data (state
, sdata
);
766 /* FIXME: Need to handle compressed debug sections. */
768 backtrace_release_view (state
, &shdrs_view
, error_callback
, data
);
769 shdrs_view_valid
= 0;
770 backtrace_release_view (state
, &names_view
, error_callback
, data
);
771 names_view_valid
= 0;
773 /* Read all the debug sections in a single view, since they are
774 probably adjacent in the file. We never release this view. */
778 for (i
= 0; i
< (int) DEBUG_MAX
; ++i
)
782 if (sections
[i
].size
== 0)
784 if (min_offset
== 0 || sections
[i
].offset
< min_offset
)
785 min_offset
= sections
[i
].offset
;
786 end
= sections
[i
].offset
+ sections
[i
].size
;
787 if (end
> max_offset
)
790 if (min_offset
== 0 || max_offset
== 0)
792 if (!backtrace_close (descriptor
, error_callback
, data
))
794 *fileline_fn
= elf_nodebug
;
798 if (!backtrace_get_view (state
, descriptor
, min_offset
,
799 max_offset
- min_offset
,
800 error_callback
, data
, &debug_view
))
802 debug_view_valid
= 1;
804 /* We've read all we need from the executable. */
805 if (!backtrace_close (descriptor
, error_callback
, data
))
809 for (i
= 0; i
< (int) DEBUG_MAX
; ++i
)
811 if (sections
[i
].size
== 0)
812 sections
[i
].data
= NULL
;
814 sections
[i
].data
= ((const unsigned char *) debug_view
.data
815 + (sections
[i
].offset
- min_offset
));
818 if (!backtrace_dwarf_add (state
, base_address
,
819 sections
[DEBUG_INFO
].data
,
820 sections
[DEBUG_INFO
].size
,
821 sections
[DEBUG_LINE
].data
,
822 sections
[DEBUG_LINE
].size
,
823 sections
[DEBUG_ABBREV
].data
,
824 sections
[DEBUG_ABBREV
].size
,
825 sections
[DEBUG_RANGES
].data
,
826 sections
[DEBUG_RANGES
].size
,
827 sections
[DEBUG_STR
].data
,
828 sections
[DEBUG_STR
].size
,
829 ehdr
.e_ident
[EI_DATA
] == ELFDATA2MSB
,
830 error_callback
, data
, fileline_fn
))
838 if (shdrs_view_valid
)
839 backtrace_release_view (state
, &shdrs_view
, error_callback
, data
);
840 if (names_view_valid
)
841 backtrace_release_view (state
, &names_view
, error_callback
, data
);
842 if (symtab_view_valid
)
843 backtrace_release_view (state
, &symtab_view
, error_callback
, data
);
844 if (strtab_view_valid
)
845 backtrace_release_view (state
, &strtab_view
, error_callback
, data
);
846 if (debug_view_valid
)
847 backtrace_release_view (state
, &debug_view
, error_callback
, data
);
848 if (descriptor
!= -1)
849 backtrace_close (descriptor
, error_callback
, data
);
853 /* Data passed to phdr_callback. */
857 struct backtrace_state
*state
;
858 backtrace_error_callback error_callback
;
860 fileline
*fileline_fn
;
866 /* Callback passed to dl_iterate_phdr. Load debug info from shared
870 phdr_callback (struct dl_phdr_info
*info
, size_t size ATTRIBUTE_UNUSED
,
873 struct phdr_data
*pd
= (struct phdr_data
*) pdata
;
876 fileline elf_fileline_fn
;
879 /* There is not much we can do if we don't have the module name,
880 unless executable is ET_DYN, where we expect the very first
881 phdr_callback to be for the PIE. */
882 if (info
->dlpi_name
== NULL
|| info
->dlpi_name
[0] == '\0')
884 if (pd
->exe_descriptor
== -1)
886 descriptor
= pd
->exe_descriptor
;
887 pd
->exe_descriptor
= -1;
891 if (pd
->exe_descriptor
!= -1)
893 backtrace_close (pd
->exe_descriptor
, pd
->error_callback
, pd
->data
);
894 pd
->exe_descriptor
= -1;
897 descriptor
= backtrace_open (info
->dlpi_name
, pd
->error_callback
,
898 pd
->data
, &does_not_exist
);
903 if (elf_add (pd
->state
, descriptor
, info
->dlpi_addr
, pd
->error_callback
,
904 pd
->data
, &elf_fileline_fn
, pd
->found_sym
, &found_dwarf
, 0))
908 *pd
->found_dwarf
= 1;
909 *pd
->fileline_fn
= elf_fileline_fn
;
916 /* Initialize the backtrace data we need from an ELF executable. At
917 the ELF level, all we need to do is find the debug info
921 backtrace_initialize (struct backtrace_state
*state
, int descriptor
,
922 backtrace_error_callback error_callback
,
923 void *data
, fileline
*fileline_fn
)
928 fileline elf_fileline_fn
;
931 ret
= elf_add (state
, descriptor
, 0, error_callback
, data
, &elf_fileline_fn
,
932 &found_sym
, &found_dwarf
, 1);
937 pd
.error_callback
= error_callback
;
939 pd
.fileline_fn
= &elf_fileline_fn
;
940 pd
.found_sym
= &found_sym
;
941 pd
.found_dwarf
= &found_dwarf
;
942 pd
.exe_descriptor
= ret
< 0 ? descriptor
: -1;
944 dl_iterate_phdr (phdr_callback
, (void *) &pd
);
946 if (!state
->threaded
)
949 state
->syminfo_fn
= elf_syminfo
;
950 else if (state
->syminfo_fn
== NULL
)
951 state
->syminfo_fn
= elf_nosyms
;
956 backtrace_atomic_store_pointer (&state
->syminfo_fn
, elf_syminfo
);
958 __sync_bool_compare_and_swap (&state
->syminfo_fn
, NULL
, elf_nosyms
);
961 if (!state
->threaded
)
963 if (state
->fileline_fn
== NULL
|| state
->fileline_fn
== elf_nodebug
)
964 *fileline_fn
= elf_fileline_fn
;
970 current_fn
= backtrace_atomic_load_pointer (&state
->fileline_fn
);
971 if (current_fn
== NULL
|| current_fn
== elf_nodebug
)
972 *fileline_fn
= elf_fileline_fn
;