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
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. */
109 typedef uint16_t b_elf_half
; /* Elf_Half. */
110 typedef uint32_t b_elf_word
; /* Elf_Word. */
111 typedef int32_t b_elf_sword
; /* Elf_Sword. */
113 #if BACKTRACE_ELF_SIZE == 32
115 typedef uint32_t b_elf_addr
; /* Elf_Addr. */
116 typedef uint32_t b_elf_off
; /* Elf_Off. */
118 typedef uint32_t b_elf_wxword
; /* 32-bit Elf_Word, 64-bit ELF_Xword. */
122 typedef uint64_t b_elf_addr
; /* Elf_Addr. */
123 typedef uint64_t b_elf_off
; /* Elf_Off. */
124 typedef uint64_t b_elf_xword
; /* Elf_Xword. */
125 typedef int64_t b_elf_sxword
; /* Elf_Sxword. */
127 typedef uint64_t b_elf_wxword
; /* 32-bit Elf_Word, 64-bit ELF_Xword. */
131 /* Data structures and associated constants. */
136 unsigned char e_ident
[EI_NIDENT
]; /* ELF "magic number" */
137 b_elf_half e_type
; /* Identifies object file type */
138 b_elf_half e_machine
; /* Specifies required architecture */
139 b_elf_word e_version
; /* Identifies object file version */
140 b_elf_addr e_entry
; /* Entry point virtual address */
141 b_elf_off e_phoff
; /* Program header table file offset */
142 b_elf_off e_shoff
; /* Section header table file offset */
143 b_elf_word e_flags
; /* Processor-specific flags */
144 b_elf_half e_ehsize
; /* ELF header size in bytes */
145 b_elf_half e_phentsize
; /* Program header table entry size */
146 b_elf_half e_phnum
; /* Program header table entry count */
147 b_elf_half e_shentsize
; /* Section header table entry size */
148 b_elf_half e_shnum
; /* Section header table entry count */
149 b_elf_half e_shstrndx
; /* Section header string table index */
150 } b_elf_ehdr
; /* Elf_Ehdr. */
168 #define ELFDATA2LSB 1
169 #define ELFDATA2MSB 2
174 b_elf_word sh_name
; /* Section name, index in string tbl */
175 b_elf_word sh_type
; /* Type of section */
176 b_elf_wxword sh_flags
; /* Miscellaneous section attributes */
177 b_elf_addr sh_addr
; /* Section virtual addr at execution */
178 b_elf_off sh_offset
; /* Section file offset */
179 b_elf_wxword sh_size
; /* Size of section in bytes */
180 b_elf_word sh_link
; /* Index of another section */
181 b_elf_word sh_info
; /* Additional section information */
182 b_elf_wxword sh_addralign
; /* Section alignment */
183 b_elf_wxword sh_entsize
; /* Entry size if section holds table */
184 } b_elf_shdr
; /* Elf_Shdr. */
186 #define SHN_LORESERVE 0xFF00 /* Begin range of reserved indices */
187 #define SHN_XINDEX 0xFFFF /* Section index is held elsewhere */
191 #define SHT_DYNSYM 11
193 #if BACKTRACE_ELF_SIZE == 32
197 b_elf_word st_name
; /* Symbol name, index in string tbl */
198 b_elf_addr st_value
; /* Symbol value */
199 b_elf_word st_size
; /* Symbol size */
200 unsigned char st_info
; /* Symbol binding and type */
201 unsigned char st_other
; /* Visibility and other data */
202 b_elf_half st_shndx
; /* Symbol section index */
203 } b_elf_sym
; /* Elf_Sym. */
205 #else /* BACKTRACE_ELF_SIZE != 32 */
209 b_elf_word st_name
; /* Symbol name, index in string tbl */
210 unsigned char st_info
; /* Symbol binding and type */
211 unsigned char st_other
; /* Visibility and other data */
212 b_elf_half st_shndx
; /* Symbol section index */
213 b_elf_addr st_value
; /* Symbol value */
214 b_elf_xword st_size
; /* Symbol size */
215 } b_elf_sym
; /* Elf_Sym. */
217 #endif /* BACKTRACE_ELF_SIZE != 32 */
222 /* An index of ELF sections we care about. */
234 /* Names of sections, indexed by enum elf_section. */
236 static const char * const debug_section_names
[DEBUG_MAX
] =
245 /* Information we gather for the sections we care about. */
247 struct debug_section_info
249 /* Section file offset. */
253 /* Section contents, after read from file. */
254 const unsigned char *data
;
257 /* Information we keep for an ELF symbol. */
261 /* The name of the symbol. */
263 /* The address of the symbol. */
265 /* The size of the symbol. */
269 /* Information to pass to elf_syminfo. */
271 struct elf_syminfo_data
273 /* Symbols for the next module. */
274 struct elf_syminfo_data
*next
;
275 /* The ELF symbols, sorted by address. */
276 struct elf_symbol
*symbols
;
277 /* The number of symbols. */
281 /* A dummy callback function used when we can't find any debug info. */
284 elf_nodebug (struct backtrace_state
*state ATTRIBUTE_UNUSED
,
285 uintptr_t pc ATTRIBUTE_UNUSED
,
286 backtrace_full_callback callback ATTRIBUTE_UNUSED
,
287 backtrace_error_callback error_callback
, void *data
)
289 error_callback (data
, "no debug info in ELF executable", -1);
293 /* A dummy callback function used when we can't find a symbol
297 elf_nosyms (struct backtrace_state
*state ATTRIBUTE_UNUSED
,
298 uintptr_t addr ATTRIBUTE_UNUSED
,
299 backtrace_syminfo_callback callback ATTRIBUTE_UNUSED
,
300 backtrace_error_callback error_callback
, void *data
)
302 error_callback (data
, "no symbol table in ELF executable", -1);
305 /* Compare struct elf_symbol for qsort. */
308 elf_symbol_compare (const void *v1
, const void *v2
)
310 const struct elf_symbol
*e1
= (const struct elf_symbol
*) v1
;
311 const struct elf_symbol
*e2
= (const struct elf_symbol
*) v2
;
313 if (e1
->address
< e2
->address
)
315 else if (e1
->address
> e2
->address
)
321 /* Compare an ADDR against an elf_symbol for bsearch. We allocate one
322 extra entry in the array so that this can look safely at the next
326 elf_symbol_search (const void *vkey
, const void *ventry
)
328 const uintptr_t *key
= (const uintptr_t *) vkey
;
329 const struct elf_symbol
*entry
= (const struct elf_symbol
*) ventry
;
333 if (addr
< entry
->address
)
335 else if (addr
>= entry
->address
+ entry
->size
)
341 /* Initialize the symbol table info for elf_syminfo. */
344 elf_initialize_syminfo (struct backtrace_state
*state
,
345 const unsigned char *symtab_data
, size_t symtab_size
,
346 const unsigned char *strtab
, size_t strtab_size
,
347 backtrace_error_callback error_callback
,
348 void *data
, struct elf_syminfo_data
*sdata
)
351 const b_elf_sym
*sym
;
352 size_t elf_symbol_count
;
353 size_t elf_symbol_size
;
354 struct elf_symbol
*elf_symbols
;
358 sym_count
= symtab_size
/ sizeof (b_elf_sym
);
360 /* We only care about function symbols. Count them. */
361 sym
= (const b_elf_sym
*) symtab_data
;
362 elf_symbol_count
= 0;
363 for (i
= 0; i
< sym_count
; ++i
, ++sym
)
367 info
= sym
->st_info
& 0xf;
368 if (info
== STT_FUNC
|| info
== STT_OBJECT
)
372 elf_symbol_size
= elf_symbol_count
* sizeof (struct elf_symbol
);
373 elf_symbols
= ((struct elf_symbol
*)
374 backtrace_alloc (state
, elf_symbol_size
, error_callback
,
376 if (elf_symbols
== NULL
)
379 sym
= (const b_elf_sym
*) symtab_data
;
381 for (i
= 0; i
< sym_count
; ++i
, ++sym
)
385 info
= sym
->st_info
& 0xf;
386 if (info
!= STT_FUNC
&& info
!= STT_OBJECT
)
388 if (sym
->st_name
>= strtab_size
)
390 error_callback (data
, "symbol string index out of range", 0);
391 backtrace_free (state
, elf_symbols
, elf_symbol_size
, error_callback
,
395 elf_symbols
[j
].name
= (const char *) strtab
+ sym
->st_name
;
396 elf_symbols
[j
].address
= sym
->st_value
;
397 elf_symbols
[j
].size
= sym
->st_size
;
401 qsort (elf_symbols
, elf_symbol_count
, sizeof (struct elf_symbol
),
405 sdata
->symbols
= elf_symbols
;
406 sdata
->count
= elf_symbol_count
;
411 /* Add EDATA to the list in STATE. */
414 elf_add_syminfo_data (struct backtrace_state
*state
,
415 struct elf_syminfo_data
*edata
)
417 if (!state
->threaded
)
419 struct elf_syminfo_data
**pp
;
421 for (pp
= (struct elf_syminfo_data
**) (void *) &state
->syminfo_data
;
431 struct elf_syminfo_data
**pp
;
433 pp
= (struct elf_syminfo_data
**) (void *) &state
->syminfo_data
;
437 struct elf_syminfo_data
*p
;
441 while (!__sync_bool_compare_and_swap (pp
, p
, p
))
450 if (__sync_bool_compare_and_swap (pp
, NULL
, edata
))
456 /* Return the symbol name and value for an ADDR. */
459 elf_syminfo (struct backtrace_state
*state
, uintptr_t addr
,
460 backtrace_syminfo_callback callback
,
461 backtrace_error_callback error_callback ATTRIBUTE_UNUSED
,
464 struct elf_syminfo_data
*edata
;
465 struct elf_symbol
*sym
= NULL
;
467 if (!state
->threaded
)
469 for (edata
= (struct elf_syminfo_data
*) state
->syminfo_data
;
473 sym
= ((struct elf_symbol
*)
474 bsearch (&addr
, edata
->symbols
, edata
->count
,
475 sizeof (struct elf_symbol
), elf_symbol_search
));
482 struct elf_syminfo_data
**pp
;
484 pp
= (struct elf_syminfo_data
**) (void *) &state
->syminfo_data
;
489 while (!__sync_bool_compare_and_swap (pp
, edata
, edata
))
495 sym
= ((struct elf_symbol
*)
496 bsearch (&addr
, edata
->symbols
, edata
->count
,
497 sizeof (struct elf_symbol
), elf_symbol_search
));
506 callback (data
, addr
, NULL
, 0);
508 callback (data
, addr
, sym
->name
, sym
->address
);
511 /* Add the backtrace data for one ELF file. */
514 elf_add (struct backtrace_state
*state
, int descriptor
, uintptr_t base_address
,
515 backtrace_error_callback error_callback
, void *data
,
516 fileline
*fileline_fn
, int *found_sym
, int *found_dwarf
)
518 struct backtrace_view ehdr_view
;
522 unsigned int shstrndx
;
523 struct backtrace_view shdrs_view
;
524 int shdrs_view_valid
;
525 const b_elf_shdr
*shdrs
;
526 const b_elf_shdr
*shstrhdr
;
529 struct backtrace_view names_view
;
530 int names_view_valid
;
532 unsigned int symtab_shndx
;
533 unsigned int dynsym_shndx
;
535 struct debug_section_info sections
[DEBUG_MAX
];
536 struct backtrace_view symtab_view
;
537 int symtab_view_valid
;
538 struct backtrace_view strtab_view
;
539 int strtab_view_valid
;
542 struct backtrace_view debug_view
;
543 int debug_view_valid
;
548 shdrs_view_valid
= 0;
549 names_view_valid
= 0;
550 symtab_view_valid
= 0;
551 strtab_view_valid
= 0;
552 debug_view_valid
= 0;
554 if (!backtrace_get_view (state
, descriptor
, 0, sizeof ehdr
, error_callback
,
558 memcpy (&ehdr
, ehdr_view
.data
, sizeof ehdr
);
560 backtrace_release_view (state
, &ehdr_view
, error_callback
, data
);
562 if (ehdr
.e_ident
[EI_MAG0
] != ELFMAG0
563 || ehdr
.e_ident
[EI_MAG1
] != ELFMAG1
564 || ehdr
.e_ident
[EI_MAG2
] != ELFMAG2
565 || ehdr
.e_ident
[EI_MAG3
] != ELFMAG3
)
567 error_callback (data
, "executable file is not ELF", 0);
570 if (ehdr
.e_ident
[EI_VERSION
] != EV_CURRENT
)
572 error_callback (data
, "executable file is unrecognized ELF version", 0);
576 #if BACKTRACE_ELF_SIZE == 32
577 #define BACKTRACE_ELFCLASS ELFCLASS32
579 #define BACKTRACE_ELFCLASS ELFCLASS64
582 if (ehdr
.e_ident
[EI_CLASS
] != BACKTRACE_ELFCLASS
)
584 error_callback (data
, "executable file is unexpected ELF class", 0);
588 if (ehdr
.e_ident
[EI_DATA
] != ELFDATA2LSB
589 && ehdr
.e_ident
[EI_DATA
] != ELFDATA2MSB
)
591 error_callback (data
, "executable file has unknown endianness", 0);
595 shoff
= ehdr
.e_shoff
;
596 shnum
= ehdr
.e_shnum
;
597 shstrndx
= ehdr
.e_shstrndx
;
599 if ((shnum
== 0 || shstrndx
== SHN_XINDEX
)
602 struct backtrace_view shdr_view
;
603 const b_elf_shdr
*shdr
;
605 if (!backtrace_get_view (state
, descriptor
, shoff
, sizeof shdr
,
606 error_callback
, data
, &shdr_view
))
609 shdr
= (const b_elf_shdr
*) shdr_view
.data
;
612 shnum
= shdr
->sh_size
;
614 if (shstrndx
== SHN_XINDEX
)
616 shstrndx
= shdr
->sh_link
;
618 /* Versions of the GNU binutils between 2.12 and 2.18 did
619 not handle objects with more than SHN_LORESERVE sections
620 correctly. All large section indexes were offset by
621 0x100. There is more information at
622 http://sourceware.org/bugzilla/show_bug.cgi?id-5900 .
623 Fortunately these object files are easy to detect, as the
624 GNU binutils always put the section header string table
625 near the end of the list of sections. Thus if the
626 section header string table index is larger than the
627 number of sections, then we know we have to subtract
628 0x100 to get the real section index. */
629 if (shstrndx
>= shnum
&& shstrndx
>= SHN_LORESERVE
+ 0x100)
633 backtrace_release_view (state
, &shdr_view
, error_callback
, data
);
636 /* To translate PC to file/line when using DWARF, we need to find
637 the .debug_info and .debug_line sections. */
639 /* Read the section headers, skipping the first one. */
641 if (!backtrace_get_view (state
, descriptor
, shoff
+ sizeof (b_elf_shdr
),
642 (shnum
- 1) * sizeof (b_elf_shdr
),
643 error_callback
, data
, &shdrs_view
))
645 shdrs_view_valid
= 1;
646 shdrs
= (const b_elf_shdr
*) shdrs_view
.data
;
648 /* Read the section names. */
650 shstrhdr
= &shdrs
[shstrndx
- 1];
651 shstr_size
= shstrhdr
->sh_size
;
652 shstr_off
= shstrhdr
->sh_offset
;
654 if (!backtrace_get_view (state
, descriptor
, shstr_off
, shstr_size
,
655 error_callback
, data
, &names_view
))
657 names_view_valid
= 1;
658 names
= (const char *) names_view
.data
;
663 memset (sections
, 0, sizeof sections
);
665 /* Look for the symbol table. */
666 for (i
= 1; i
< shnum
; ++i
)
668 const b_elf_shdr
*shdr
;
669 unsigned int sh_name
;
673 shdr
= &shdrs
[i
- 1];
675 if (shdr
->sh_type
== SHT_SYMTAB
)
677 else if (shdr
->sh_type
== SHT_DYNSYM
)
680 sh_name
= shdr
->sh_name
;
681 if (sh_name
>= shstr_size
)
683 error_callback (data
, "ELF section name out of range", 0);
687 name
= names
+ sh_name
;
689 for (j
= 0; j
< (int) DEBUG_MAX
; ++j
)
691 if (strcmp (name
, debug_section_names
[j
]) == 0)
693 sections
[j
].offset
= shdr
->sh_offset
;
694 sections
[j
].size
= shdr
->sh_size
;
700 if (symtab_shndx
== 0)
701 symtab_shndx
= dynsym_shndx
;
702 if (symtab_shndx
!= 0)
704 const b_elf_shdr
*symtab_shdr
;
705 unsigned int strtab_shndx
;
706 const b_elf_shdr
*strtab_shdr
;
707 struct elf_syminfo_data
*sdata
;
709 symtab_shdr
= &shdrs
[symtab_shndx
- 1];
710 strtab_shndx
= symtab_shdr
->sh_link
;
711 if (strtab_shndx
>= shnum
)
713 error_callback (data
,
714 "ELF symbol table strtab link out of range", 0);
717 strtab_shdr
= &shdrs
[strtab_shndx
- 1];
719 if (!backtrace_get_view (state
, descriptor
, symtab_shdr
->sh_offset
,
720 symtab_shdr
->sh_size
, error_callback
, data
,
723 symtab_view_valid
= 1;
725 if (!backtrace_get_view (state
, descriptor
, strtab_shdr
->sh_offset
,
726 strtab_shdr
->sh_size
, error_callback
, data
,
729 strtab_view_valid
= 1;
731 sdata
= ((struct elf_syminfo_data
*)
732 backtrace_alloc (state
, sizeof *sdata
, error_callback
, data
));
736 if (!elf_initialize_syminfo (state
,
737 symtab_view
.data
, symtab_shdr
->sh_size
,
738 strtab_view
.data
, strtab_shdr
->sh_size
,
739 error_callback
, data
, sdata
))
741 backtrace_free (state
, sdata
, sizeof *sdata
, error_callback
, data
);
745 /* We no longer need the symbol table, but we hold on to the
746 string table permanently. */
747 backtrace_release_view (state
, &symtab_view
, error_callback
, data
);
751 elf_add_syminfo_data (state
, sdata
);
754 /* FIXME: Need to handle compressed debug sections. */
756 backtrace_release_view (state
, &shdrs_view
, error_callback
, data
);
757 shdrs_view_valid
= 0;
758 backtrace_release_view (state
, &names_view
, error_callback
, data
);
759 names_view_valid
= 0;
761 /* Read all the debug sections in a single view, since they are
762 probably adjacent in the file. We never release this view. */
766 for (i
= 0; i
< (int) DEBUG_MAX
; ++i
)
770 if (sections
[i
].size
== 0)
772 if (min_offset
== 0 || sections
[i
].offset
< min_offset
)
773 min_offset
= sections
[i
].offset
;
774 end
= sections
[i
].offset
+ sections
[i
].size
;
775 if (end
> max_offset
)
778 if (min_offset
== 0 || max_offset
== 0)
780 if (!backtrace_close (descriptor
, error_callback
, data
))
782 *fileline_fn
= elf_nodebug
;
786 if (!backtrace_get_view (state
, descriptor
, min_offset
,
787 max_offset
- min_offset
,
788 error_callback
, data
, &debug_view
))
790 debug_view_valid
= 1;
792 /* We've read all we need from the executable. */
793 if (!backtrace_close (descriptor
, error_callback
, data
))
797 for (i
= 0; i
< (int) DEBUG_MAX
; ++i
)
799 if (sections
[i
].size
== 0)
800 sections
[i
].data
= NULL
;
802 sections
[i
].data
= ((const unsigned char *) debug_view
.data
803 + (sections
[i
].offset
- min_offset
));
806 if (!backtrace_dwarf_add (state
, base_address
,
807 sections
[DEBUG_INFO
].data
,
808 sections
[DEBUG_INFO
].size
,
809 sections
[DEBUG_LINE
].data
,
810 sections
[DEBUG_LINE
].size
,
811 sections
[DEBUG_ABBREV
].data
,
812 sections
[DEBUG_ABBREV
].size
,
813 sections
[DEBUG_RANGES
].data
,
814 sections
[DEBUG_RANGES
].size
,
815 sections
[DEBUG_STR
].data
,
816 sections
[DEBUG_STR
].size
,
817 ehdr
.e_ident
[EI_DATA
] == ELFDATA2MSB
,
818 error_callback
, data
, fileline_fn
))
826 if (shdrs_view_valid
)
827 backtrace_release_view (state
, &shdrs_view
, error_callback
, data
);
828 if (names_view_valid
)
829 backtrace_release_view (state
, &names_view
, error_callback
, data
);
830 if (symtab_view_valid
)
831 backtrace_release_view (state
, &symtab_view
, error_callback
, data
);
832 if (strtab_view_valid
)
833 backtrace_release_view (state
, &strtab_view
, error_callback
, data
);
834 if (debug_view_valid
)
835 backtrace_release_view (state
, &debug_view
, error_callback
, data
);
836 if (descriptor
!= -1)
837 backtrace_close (descriptor
, error_callback
, data
);
841 /* Data passed to phdr_callback. */
845 struct backtrace_state
*state
;
846 backtrace_error_callback error_callback
;
848 fileline
*fileline_fn
;
853 /* Callback passed to dl_iterate_phdr. Load debug info from shared
857 phdr_callback (struct dl_phdr_info
*info
, size_t size ATTRIBUTE_UNUSED
,
860 struct phdr_data
*pd
= (struct phdr_data
*) pdata
;
863 fileline elf_fileline_fn
;
866 /* There is not much we can do if we don't have the module name. */
867 if (info
->dlpi_name
== NULL
|| info
->dlpi_name
[0] == '\0')
870 descriptor
= backtrace_open (info
->dlpi_name
, pd
->error_callback
, pd
->data
,
875 if (elf_add (pd
->state
, descriptor
, info
->dlpi_addr
, pd
->error_callback
,
876 pd
->data
, &elf_fileline_fn
, pd
->found_sym
, &found_dwarf
))
880 *pd
->found_dwarf
= 1;
881 *pd
->fileline_fn
= elf_fileline_fn
;
888 /* Initialize the backtrace data we need from an ELF executable. At
889 the ELF level, all we need to do is find the debug info
893 backtrace_initialize (struct backtrace_state
*state
, int descriptor
,
894 backtrace_error_callback error_callback
,
895 void *data
, fileline
*fileline_fn
)
899 syminfo elf_syminfo_fn
;
900 fileline elf_fileline_fn
;
903 if (!elf_add (state
, descriptor
, 0, error_callback
, data
, &elf_fileline_fn
,
904 &found_sym
, &found_dwarf
))
908 pd
.error_callback
= error_callback
;
910 pd
.fileline_fn
= &elf_fileline_fn
;
911 pd
.found_sym
= &found_sym
;
912 pd
.found_dwarf
= &found_dwarf
;
914 dl_iterate_phdr (phdr_callback
, (void *) &pd
);
916 elf_syminfo_fn
= found_sym
? elf_syminfo
: elf_nosyms
;
917 if (!state
->threaded
)
919 if (state
->syminfo_fn
== NULL
|| found_sym
)
920 state
->syminfo_fn
= elf_syminfo_fn
;
924 __sync_bool_compare_and_swap (&state
->syminfo_fn
, NULL
, elf_syminfo_fn
);
926 __sync_bool_compare_and_swap (&state
->syminfo_fn
, elf_nosyms
,
930 if (!state
->threaded
)
932 if (state
->fileline_fn
== NULL
|| state
->fileline_fn
== elf_nodebug
)
933 *fileline_fn
= elf_fileline_fn
;
940 current_fn
= state
->fileline_fn
;
941 while (!__sync_bool_compare_and_swap (&state
->fileline_fn
, current_fn
,
943 current_fn
= state
->fileline_fn
;
944 if (current_fn
== NULL
|| current_fn
== elf_nodebug
)
945 *fileline_fn
= elf_fileline_fn
;