1 /* elf.c -- Get debug data from an ELF file for backtraces.
2 Copyright (C) 2012 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. */
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. */
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. */
130 /* Data structures and associated constants. */
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. */
167 #define ELFDATA2LSB 1
168 #define ELFDATA2MSB 2
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 */
190 #define SHT_DYNSYM 11
192 #if BACKTRACE_ELF_SIZE == 32
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 */
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 */
220 /* An index of ELF sections we care about. */
232 /* Names of sections, indexed by enum elf_section. */
234 static const char * const debug_section_names
[DEBUG_MAX
] =
243 /* Information we gather for the sections we care about. */
245 struct debug_section_info
247 /* Section file offset. */
251 /* Section contents, after read from file. */
252 const unsigned char *data
;
255 /* Information we keep for an ELF symbol. */
259 /* The name of the symbol. */
261 /* The address of the symbol. */
263 /* The size of the symbol. */
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. */
279 /* A dummy callback function used when we can't find any debug info. */
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);
291 /* A dummy callback function used when we can't find a symbol
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. */
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
)
313 else if (e1
->address
> e2
->address
)
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
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
;
331 if (pc
< entry
->address
)
333 else if (pc
>= entry
->address
+ entry
->size
)
339 /* Initialize the symbol table info for elf_syminfo. */
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
)
349 const b_elf_sym
*sym
;
350 size_t elf_symbol_count
;
351 size_t elf_symbol_size
;
352 struct elf_symbol
*elf_symbols
;
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
)
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
,
371 if (elf_symbols
== NULL
)
374 sym
= (const b_elf_sym
*) symtab_data
;
376 for (i
= 0; i
< sym_count
; ++i
, ++sym
)
378 if ((sym
->st_info
& 0xf) != STT_FUNC
)
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
,
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
;
393 qsort (elf_symbols
, elf_symbol_count
, sizeof (struct elf_symbol
),
397 sdata
->symbols
= elf_symbols
;
398 sdata
->count
= elf_symbol_count
;
403 /* Add EDATA to the list in STATE. */
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
;
423 struct elf_syminfo_data
**pp
;
425 pp
= (struct elf_syminfo_data
**) (void *) &state
->syminfo_data
;
429 struct elf_syminfo_data
*p
;
433 while (!__sync_bool_compare_and_swap (pp
, p
, p
))
442 if (__sync_bool_compare_and_swap (pp
, NULL
, edata
))
448 /* Return the symbol name and value for a PC. */
451 elf_syminfo (struct backtrace_state
*state
, uintptr_t pc
,
452 backtrace_syminfo_callback callback
,
453 backtrace_error_callback error_callback ATTRIBUTE_UNUSED
,
456 struct elf_syminfo_data
*edata
;
457 struct elf_symbol
*sym
;
459 edata
= (struct elf_syminfo_data
*) state
->syminfo_data
;
460 sym
= ((struct elf_symbol
*)
461 bsearch (&pc
, edata
->symbols
, edata
->count
,
462 sizeof (struct elf_symbol
), elf_symbol_search
));
464 callback (data
, pc
, NULL
, 0);
466 callback (data
, pc
, sym
->name
, sym
->address
);
469 /* Add the backtrace data for one ELF file. */
472 elf_add (struct backtrace_state
*state
, int descriptor
, uintptr_t base_address
,
473 backtrace_error_callback error_callback
, void *data
,
474 fileline
*fileline_fn
, int *found_sym
, int *found_dwarf
)
476 struct backtrace_view ehdr_view
;
480 unsigned int shstrndx
;
481 struct backtrace_view shdrs_view
;
482 int shdrs_view_valid
;
483 const b_elf_shdr
*shdrs
;
484 const b_elf_shdr
*shstrhdr
;
487 struct backtrace_view names_view
;
488 int names_view_valid
;
490 unsigned int symtab_shndx
;
491 unsigned int dynsym_shndx
;
493 struct debug_section_info sections
[DEBUG_MAX
];
494 struct backtrace_view symtab_view
;
495 int symtab_view_valid
;
496 struct backtrace_view strtab_view
;
497 int strtab_view_valid
;
500 struct backtrace_view debug_view
;
501 int debug_view_valid
;
506 shdrs_view_valid
= 0;
507 names_view_valid
= 0;
508 symtab_view_valid
= 0;
509 strtab_view_valid
= 0;
510 debug_view_valid
= 0;
512 if (!backtrace_get_view (state
, descriptor
, 0, sizeof ehdr
, error_callback
,
516 memcpy (&ehdr
, ehdr_view
.data
, sizeof ehdr
);
518 backtrace_release_view (state
, &ehdr_view
, error_callback
, data
);
520 if (ehdr
.e_ident
[EI_MAG0
] != ELFMAG0
521 || ehdr
.e_ident
[EI_MAG1
] != ELFMAG1
522 || ehdr
.e_ident
[EI_MAG2
] != ELFMAG2
523 || ehdr
.e_ident
[EI_MAG3
] != ELFMAG3
)
525 error_callback (data
, "executable file is not ELF", 0);
528 if (ehdr
.e_ident
[EI_VERSION
] != EV_CURRENT
)
530 error_callback (data
, "executable file is unrecognized ELF version", 0);
534 #if BACKTRACE_ELF_SIZE == 32
535 #define BACKTRACE_ELFCLASS ELFCLASS32
537 #define BACKTRACE_ELFCLASS ELFCLASS64
540 if (ehdr
.e_ident
[EI_CLASS
] != BACKTRACE_ELFCLASS
)
542 error_callback (data
, "executable file is unexpected ELF class", 0);
546 if (ehdr
.e_ident
[EI_DATA
] != ELFDATA2LSB
547 && ehdr
.e_ident
[EI_DATA
] != ELFDATA2MSB
)
549 error_callback (data
, "executable file has unknown endianness", 0);
553 shoff
= ehdr
.e_shoff
;
554 shnum
= ehdr
.e_shnum
;
555 shstrndx
= ehdr
.e_shstrndx
;
557 if ((shnum
== 0 || shstrndx
== SHN_XINDEX
)
560 struct backtrace_view shdr_view
;
561 const b_elf_shdr
*shdr
;
563 if (!backtrace_get_view (state
, descriptor
, shoff
, sizeof shdr
,
564 error_callback
, data
, &shdr_view
))
567 shdr
= (const b_elf_shdr
*) shdr_view
.data
;
570 shnum
= shdr
->sh_size
;
572 if (shstrndx
== SHN_XINDEX
)
574 shstrndx
= shdr
->sh_link
;
576 /* Versions of the GNU binutils between 2.12 and 2.18 did
577 not handle objects with more than SHN_LORESERVE sections
578 correctly. All large section indexes were offset by
579 0x100. There is more information at
580 http://sourceware.org/bugzilla/show_bug.cgi?id-5900 .
581 Fortunately these object files are easy to detect, as the
582 GNU binutils always put the section header string table
583 near the end of the list of sections. Thus if the
584 section header string table index is larger than the
585 number of sections, then we know we have to subtract
586 0x100 to get the real section index. */
587 if (shstrndx
>= shnum
&& shstrndx
>= SHN_LORESERVE
+ 0x100)
591 backtrace_release_view (state
, &shdr_view
, error_callback
, data
);
594 /* To translate PC to file/line when using DWARF, we need to find
595 the .debug_info and .debug_line sections. */
597 /* Read the section headers, skipping the first one. */
599 if (!backtrace_get_view (state
, descriptor
, shoff
+ sizeof (b_elf_shdr
),
600 (shnum
- 1) * sizeof (b_elf_shdr
),
601 error_callback
, data
, &shdrs_view
))
603 shdrs_view_valid
= 1;
604 shdrs
= (const b_elf_shdr
*) shdrs_view
.data
;
606 /* Read the section names. */
608 shstrhdr
= &shdrs
[shstrndx
- 1];
609 shstr_size
= shstrhdr
->sh_size
;
610 shstr_off
= shstrhdr
->sh_offset
;
612 if (!backtrace_get_view (state
, descriptor
, shstr_off
, shstr_size
,
613 error_callback
, data
, &names_view
))
615 names_view_valid
= 1;
616 names
= (const char *) names_view
.data
;
621 memset (sections
, 0, sizeof sections
);
623 /* Look for the symbol table. */
624 for (i
= 1; i
< shnum
; ++i
)
626 const b_elf_shdr
*shdr
;
627 unsigned int sh_name
;
631 shdr
= &shdrs
[i
- 1];
633 if (shdr
->sh_type
== SHT_SYMTAB
)
635 else if (shdr
->sh_type
== SHT_DYNSYM
)
638 sh_name
= shdr
->sh_name
;
639 if (sh_name
>= shstr_size
)
641 error_callback (data
, "ELF section name out of range", 0);
645 name
= names
+ sh_name
;
647 for (j
= 0; j
< (int) DEBUG_MAX
; ++j
)
649 if (strcmp (name
, debug_section_names
[j
]) == 0)
651 sections
[j
].offset
= shdr
->sh_offset
;
652 sections
[j
].size
= shdr
->sh_size
;
658 if (symtab_shndx
== 0)
659 symtab_shndx
= dynsym_shndx
;
660 if (symtab_shndx
!= 0)
662 const b_elf_shdr
*symtab_shdr
;
663 unsigned int strtab_shndx
;
664 const b_elf_shdr
*strtab_shdr
;
665 struct elf_syminfo_data
*sdata
;
667 symtab_shdr
= &shdrs
[symtab_shndx
- 1];
668 strtab_shndx
= symtab_shdr
->sh_link
;
669 if (strtab_shndx
>= shnum
)
671 error_callback (data
,
672 "ELF symbol table strtab link out of range", 0);
675 strtab_shdr
= &shdrs
[strtab_shndx
- 1];
677 if (!backtrace_get_view (state
, descriptor
, symtab_shdr
->sh_offset
,
678 symtab_shdr
->sh_size
, error_callback
, data
,
681 symtab_view_valid
= 1;
683 if (!backtrace_get_view (state
, descriptor
, strtab_shdr
->sh_offset
,
684 strtab_shdr
->sh_size
, error_callback
, data
,
687 strtab_view_valid
= 1;
689 sdata
= ((struct elf_syminfo_data
*)
690 backtrace_alloc (state
, sizeof *sdata
, error_callback
, data
));
694 if (!elf_initialize_syminfo (state
,
695 symtab_view
.data
, symtab_shdr
->sh_size
,
696 strtab_view
.data
, strtab_shdr
->sh_size
,
697 error_callback
, data
, sdata
))
699 backtrace_free (state
, sdata
, sizeof *sdata
, error_callback
, data
);
703 /* We no longer need the symbol table, but we hold on to the
704 string table permanently. */
705 backtrace_release_view (state
, &symtab_view
, error_callback
, data
);
709 elf_add_syminfo_data (state
, sdata
);
712 /* FIXME: Need to handle compressed debug sections. */
714 backtrace_release_view (state
, &shdrs_view
, error_callback
, data
);
715 shdrs_view_valid
= 0;
716 backtrace_release_view (state
, &names_view
, error_callback
, data
);
717 names_view_valid
= 0;
719 /* Read all the debug sections in a single view, since they are
720 probably adjacent in the file. We never release this view. */
724 for (i
= 0; i
< (int) DEBUG_MAX
; ++i
)
728 if (min_offset
== 0 || sections
[i
].offset
< min_offset
)
729 min_offset
= sections
[i
].offset
;
730 end
= sections
[i
].offset
+ sections
[i
].size
;
731 if (end
> max_offset
)
734 if (min_offset
== 0 || max_offset
== 0)
736 if (!backtrace_close (descriptor
, error_callback
, data
))
738 *fileline_fn
= elf_nodebug
;
742 if (!backtrace_get_view (state
, descriptor
, min_offset
,
743 max_offset
- min_offset
,
744 error_callback
, data
, &debug_view
))
746 debug_view_valid
= 1;
748 /* We've read all we need from the executable. */
749 if (!backtrace_close (descriptor
, error_callback
, data
))
753 for (i
= 0; i
< (int) DEBUG_MAX
; ++i
)
754 sections
[i
].data
= ((const unsigned char *) debug_view
.data
755 + (sections
[i
].offset
- min_offset
));
757 if (!backtrace_dwarf_add (state
, base_address
,
758 sections
[DEBUG_INFO
].data
,
759 sections
[DEBUG_INFO
].size
,
760 sections
[DEBUG_LINE
].data
,
761 sections
[DEBUG_LINE
].size
,
762 sections
[DEBUG_ABBREV
].data
,
763 sections
[DEBUG_ABBREV
].size
,
764 sections
[DEBUG_RANGES
].data
,
765 sections
[DEBUG_RANGES
].size
,
766 sections
[DEBUG_STR
].data
,
767 sections
[DEBUG_STR
].size
,
768 ehdr
.e_ident
[EI_DATA
] == ELFDATA2MSB
,
769 error_callback
, data
, fileline_fn
))
777 if (shdrs_view_valid
)
778 backtrace_release_view (state
, &shdrs_view
, error_callback
, data
);
779 if (names_view_valid
)
780 backtrace_release_view (state
, &names_view
, error_callback
, data
);
781 if (symtab_view_valid
)
782 backtrace_release_view (state
, &symtab_view
, error_callback
, data
);
783 if (strtab_view_valid
)
784 backtrace_release_view (state
, &strtab_view
, error_callback
, data
);
785 if (debug_view_valid
)
786 backtrace_release_view (state
, &debug_view
, error_callback
, data
);
787 if (descriptor
!= -1)
788 backtrace_close (descriptor
, error_callback
, data
);
792 /* Data passed to phdr_callback. */
796 struct backtrace_state
*state
;
797 backtrace_error_callback error_callback
;
799 fileline
*fileline_fn
;
804 /* Callback passed to dl_iterate_phdr. Load debug info from shared
808 phdr_callback (struct dl_phdr_info
*info
, size_t size ATTRIBUTE_UNUSED
,
811 struct phdr_data
*pd
= (struct phdr_data
*) pdata
;
814 fileline elf_fileline_fn
;
817 /* There is not much we can do if we don't have the module name. If
818 the base address is 0, this is probably the executable, which we
820 if (info
->dlpi_name
== NULL
821 || info
->dlpi_name
[0] == '\0'
822 || info
->dlpi_addr
== 0)
825 descriptor
= backtrace_open (info
->dlpi_name
, pd
->error_callback
, pd
->data
,
830 if (elf_add (pd
->state
, descriptor
, info
->dlpi_addr
, pd
->error_callback
,
831 pd
->data
, &elf_fileline_fn
, pd
->found_sym
, &found_dwarf
))
835 *pd
->found_dwarf
= 1;
836 *pd
->fileline_fn
= elf_fileline_fn
;
843 /* Initialize the backtrace data we need from an ELF executable. At
844 the ELF level, all we need to do is find the debug info
848 backtrace_initialize (struct backtrace_state
*state
, int descriptor
,
849 backtrace_error_callback error_callback
,
850 void *data
, fileline
*fileline_fn
)
854 syminfo elf_syminfo_fn
;
855 fileline elf_fileline_fn
;
858 if (!elf_add (state
, descriptor
, 0, error_callback
, data
, &elf_fileline_fn
,
859 &found_sym
, &found_dwarf
))
863 pd
.error_callback
= error_callback
;
865 pd
.fileline_fn
= fileline_fn
;
866 pd
.found_sym
= &found_sym
;
867 pd
.found_dwarf
= &found_dwarf
;
869 dl_iterate_phdr (phdr_callback
, (void *) &pd
);
871 elf_syminfo_fn
= found_sym
? elf_syminfo
: elf_nosyms
;
872 if (!state
->threaded
)
874 if (state
->syminfo_fn
== NULL
|| found_sym
)
875 state
->syminfo_fn
= elf_syminfo_fn
;
879 __sync_bool_compare_and_swap (&state
->syminfo_fn
, NULL
, elf_syminfo_fn
);
881 __sync_bool_compare_and_swap (&state
->syminfo_fn
, elf_nosyms
,
885 if (!state
->threaded
)
887 if (state
->fileline_fn
== NULL
|| state
->fileline_fn
== elf_nodebug
)
888 *fileline_fn
= elf_fileline_fn
;
895 current_fn
= state
->fileline_fn
;
896 while (!__sync_bool_compare_and_swap (&state
->fileline_fn
, current_fn
,
898 current_fn
= state
->fileline_fn
;
899 if (current_fn
== NULL
|| current_fn
== elf_nodebug
)
900 *fileline_fn
= elf_fileline_fn
;