]> git.cworth.org Git - apitrace/blob - thirdparty/libbacktrace/elf.c
thirdparty/libbacktrace: update from upstream
[apitrace] / thirdparty / libbacktrace / elf.c
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.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are
7 met:
8
9     (1) Redistributions of source code must retain the above copyright
10     notice, this list of conditions and the following disclaimer. 
11
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.  
16     
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.
20
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.  */
32
33 #include "config.h"
34
35 #include <stdlib.h>
36 #include <string.h>
37 #include <sys/types.h>
38
39 #ifdef HAVE_DL_ITERATE_PHDR
40 #include <link.h>
41 #endif
42
43 #include "backtrace.h"
44 #include "internal.h"
45
46 #ifndef HAVE_DL_ITERATE_PHDR
47
48 /* Dummy version of dl_iterate_phdr for systems that don't have it.  */
49
50 #define dl_phdr_info x_dl_phdr_info
51 #define dl_iterate_phdr x_dl_iterate_phdr
52
53 struct dl_phdr_info
54 {
55   uintptr_t dlpi_addr;
56   const char *dlpi_name;
57 };
58
59 static int
60 dl_iterate_phdr (int (*callback) (struct dl_phdr_info *,
61                                   size_t, void *) ATTRIBUTE_UNUSED,
62                  void *data ATTRIBUTE_UNUSED)
63 {
64   return 0;
65 }
66
67 #endif /* ! defined (HAVE_DL_ITERATE_PHDR) */
68
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.  */
74
75 #if BACKTRACE_ELF_SIZE != 32 && BACKTRACE_ELF_SIZE != 64
76 #error "Unknown BACKTRACE_ELF_SIZE"
77 #endif
78
79 /* <link.h> might #include <elf.h> which might define our constants
80    with slightly different values.  Undefine them to be safe.  */
81
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
105
106 /* Basic types.  */
107
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.  */
111
112 #if BACKTRACE_ELF_SIZE == 32
113
114 typedef uint32_t b_elf_addr;    /* Elf_Addr.  */
115 typedef uint32_t b_elf_off;     /* Elf_Off.  */
116
117 typedef uint32_t b_elf_wxword;  /* 32-bit Elf_Word, 64-bit ELF_Xword.  */
118
119 #else
120
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.  */
125
126 typedef uint64_t b_elf_wxword;  /* 32-bit Elf_Word, 64-bit ELF_Xword.  */
127
128 #endif
129
130 /* Data structures and associated constants.  */
131
132 #define EI_NIDENT 16
133
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.  */
150
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
158
159 #define ELFMAG0 0x7f
160 #define ELFMAG1 'E'
161 #define ELFMAG2 'L'
162 #define ELFMAG3 'F'
163
164 #define ELFCLASS32 1
165 #define ELFCLASS64 2
166
167 #define ELFDATA2LSB 1
168 #define ELFDATA2MSB 2
169
170 #define EV_CURRENT 1
171
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.  */
184
185 #define SHN_LORESERVE   0xFF00          /* Begin range of reserved indices */
186 #define SHN_XINDEX      0xFFFF          /* Section index is held elsewhere */
187
188 #define SHT_SYMTAB 2
189 #define SHT_STRTAB 3
190 #define SHT_DYNSYM 11
191
192 #if BACKTRACE_ELF_SIZE == 32
193
194 typedef struct
195 {
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.  */
203
204 #else /* BACKTRACE_ELF_SIZE != 32 */
205
206 typedef struct
207 {
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.  */
215
216 #endif /* BACKTRACE_ELF_SIZE != 32 */
217
218 #define STT_FUNC 2
219
220 /* An index of ELF sections we care about.  */
221
222 enum debug_section
223 {
224   DEBUG_INFO,
225   DEBUG_LINE,
226   DEBUG_ABBREV,
227   DEBUG_RANGES,
228   DEBUG_STR,
229   DEBUG_MAX
230 };
231
232 /* Names of sections, indexed by enum elf_section.  */
233
234 static const char * const debug_section_names[DEBUG_MAX] =
235 {
236   ".debug_info",
237   ".debug_line",
238   ".debug_abbrev",
239   ".debug_ranges",
240   ".debug_str"
241 };
242
243 /* Information we gather for the sections we care about.  */
244
245 struct debug_section_info
246 {
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;
253 };
254
255 /* Information we keep for an ELF symbol.  */
256
257 struct elf_symbol
258 {
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;
265 };
266
267 /* Information to pass to elf_syminfo.  */
268
269 struct elf_syminfo_data
270 {
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;
277 };
278
279 /* A dummy callback function used when we can't find any debug info.  */
280
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)
286 {
287   error_callback (data, "no debug info in ELF executable", -1);
288   return 0;
289 }
290
291 /* A dummy callback function used when we can't find a symbol
292    table.  */
293
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)
299 {
300   error_callback (data, "no symbol table in ELF executable", -1);
301 }
302
303 /* Compare struct elf_symbol for qsort.  */
304
305 static int
306 elf_symbol_compare (const void *v1, const void *v2)
307 {
308   const struct elf_symbol *e1 = (const struct elf_symbol *) v1;
309   const struct elf_symbol *e2 = (const struct elf_symbol *) v2;
310
311   if (e1->address < e2->address)
312     return -1;
313   else if (e1->address > e2->address)
314     return 1;
315   else
316     return 0;
317 }
318
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.  */
322
323 static int
324 elf_symbol_search (const void *vkey, const void *ventry)
325 {
326   const uintptr_t *key = (const uintptr_t *) vkey;
327   const struct elf_symbol *entry = (const struct elf_symbol *) ventry;
328   uintptr_t pc;
329
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;
337 }
338
339 /* Initialize the symbol table info for elf_syminfo.  */
340
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)
347 {
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;
355
356   sym_count = symtab_size / sizeof (b_elf_sym);
357
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)
362     {
363       if ((sym->st_info & 0xf) == STT_FUNC)
364         ++elf_symbol_count;
365     }
366
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;
373
374   sym = (const b_elf_sym *) symtab_data;
375   j = 0;
376   for (i = 0; i < sym_count; ++i, ++sym)
377     {
378       if ((sym->st_info & 0xf) != STT_FUNC)
379         continue;
380       if (sym->st_name >= strtab_size)
381         {
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;
386         }
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;
391     }
392
393   qsort (elf_symbols, elf_symbol_count, sizeof (struct elf_symbol),
394          elf_symbol_compare);
395
396   sdata->next = NULL;
397   sdata->symbols = elf_symbols;
398   sdata->count = elf_symbol_count;
399
400   return 1;
401 }
402
403 /* Add EDATA to the list in STATE.  */
404
405 static void
406 elf_add_syminfo_data (struct backtrace_state *state,
407                       struct elf_syminfo_data *edata)
408 {
409   if (!state->threaded)
410     {
411       struct elf_syminfo_data **pp;
412
413       for (pp = (struct elf_syminfo_data **) (void *) &state->syminfo_data;
414            *pp != NULL;
415            pp = &(*pp)->next)
416         ;
417       *pp = edata;
418     }
419   else
420     {
421       while (1)
422         {
423           struct elf_syminfo_data **pp;
424
425           pp = (struct elf_syminfo_data **) (void *) &state->syminfo_data;
426
427           while (1)
428             {
429               struct elf_syminfo_data *p;
430
431               /* Atomic load.  */
432               p = *pp;
433               while (!__sync_bool_compare_and_swap (pp, p, p))
434                 p = *pp;
435
436               if (p == NULL)
437                 break;
438
439               pp = &p->next;
440             }
441
442           if (__sync_bool_compare_and_swap (pp, NULL, edata))
443             break;
444         }
445     }
446 }
447
448 /* Return the symbol name and value for a PC.  */
449
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)
455 {
456   struct elf_syminfo_data *edata;
457   struct elf_symbol *sym = NULL;
458
459   if (!state->threaded)
460     {
461       for (edata = (struct elf_syminfo_data *) state->syminfo_data;
462            edata != NULL;
463            edata = edata->next)
464         {
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;
470         }
471     }
472   else
473     {
474       struct elf_syminfo_data **pp;
475
476       pp = (struct elf_syminfo_data **) (void *) &state->syminfo_data;
477       while (1)
478         {
479           edata = *pp;
480           /* Atomic load.  */
481           while (!__sync_bool_compare_and_swap (pp, edata, edata))
482             edata = *pp;
483
484           if (edata == NULL)
485             break;
486
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;
492
493           pp = &edata->next;
494         }
495     }
496
497   if (sym == NULL)
498     callback (data, pc, NULL, 0);
499   else
500     callback (data, pc, sym->name, sym->address);
501 }
502
503 /* Add the backtrace data for one ELF file.  */
504
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)
509 {
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;
536
537   *found_sym = 0;
538   *found_dwarf = 0;
539
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;
545
546   if (!backtrace_get_view (state, descriptor, 0, sizeof ehdr, error_callback,
547                            data, &ehdr_view))
548     goto fail;
549
550   memcpy (&ehdr, ehdr_view.data, sizeof ehdr);
551
552   backtrace_release_view (state, &ehdr_view, error_callback, data);
553
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)
558     {
559       error_callback (data, "executable file is not ELF", 0);
560       goto fail;
561     }
562   if (ehdr.e_ident[EI_VERSION] != EV_CURRENT)
563     {
564       error_callback (data, "executable file is unrecognized ELF version", 0);
565       goto fail;
566     }
567
568 #if BACKTRACE_ELF_SIZE == 32
569 #define BACKTRACE_ELFCLASS ELFCLASS32
570 #else
571 #define BACKTRACE_ELFCLASS ELFCLASS64
572 #endif
573
574   if (ehdr.e_ident[EI_CLASS] != BACKTRACE_ELFCLASS)
575     {
576       error_callback (data, "executable file is unexpected ELF class", 0);
577       goto fail;
578     }
579
580   if (ehdr.e_ident[EI_DATA] != ELFDATA2LSB
581       && ehdr.e_ident[EI_DATA] != ELFDATA2MSB)
582     {
583       error_callback (data, "executable file has unknown endianness", 0);
584       goto fail;
585     }
586
587   shoff = ehdr.e_shoff;
588   shnum = ehdr.e_shnum;
589   shstrndx = ehdr.e_shstrndx;
590
591   if ((shnum == 0 || shstrndx == SHN_XINDEX)
592       && shoff != 0)
593     {
594       struct backtrace_view shdr_view;
595       const b_elf_shdr *shdr;
596
597       if (!backtrace_get_view (state, descriptor, shoff, sizeof shdr,
598                                error_callback, data, &shdr_view))
599         goto fail;
600
601       shdr = (const b_elf_shdr *) shdr_view.data;
602
603       if (shnum == 0)
604         shnum = shdr->sh_size;
605
606       if (shstrndx == SHN_XINDEX)
607         {
608           shstrndx = shdr->sh_link;
609
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;
623         }
624
625       backtrace_release_view (state, &shdr_view, error_callback, data);
626     }
627
628   /* To translate PC to file/line when using DWARF, we need to find
629      the .debug_info and .debug_line sections.  */
630
631   /* Read the section headers, skipping the first one.  */
632
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;
639
640   /* Read the section names.  */
641
642   shstrhdr = &shdrs[shstrndx - 1];
643   shstr_size = shstrhdr->sh_size;
644   shstr_off = shstrhdr->sh_offset;
645
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;
651
652   symtab_shndx = 0;
653   dynsym_shndx = 0;
654
655   memset (sections, 0, sizeof sections);
656
657   /* Look for the symbol table.  */
658   for (i = 1; i < shnum; ++i)
659     {
660       const b_elf_shdr *shdr;
661       unsigned int sh_name;
662       const char *name;
663       int j;
664
665       shdr = &shdrs[i - 1];
666
667       if (shdr->sh_type == SHT_SYMTAB)
668         symtab_shndx = i;
669       else if (shdr->sh_type == SHT_DYNSYM)
670         dynsym_shndx = i;
671
672       sh_name = shdr->sh_name;
673       if (sh_name >= shstr_size)
674         {
675           error_callback (data, "ELF section name out of range", 0);
676           goto fail;
677         }
678
679       name = names + sh_name;
680
681       for (j = 0; j < (int) DEBUG_MAX; ++j)
682         {
683           if (strcmp (name, debug_section_names[j]) == 0)
684             {
685               sections[j].offset = shdr->sh_offset;
686               sections[j].size = shdr->sh_size;
687               break;
688             }
689         }
690     }
691
692   if (symtab_shndx == 0)
693     symtab_shndx = dynsym_shndx;
694   if (symtab_shndx != 0)
695     {
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;
700
701       symtab_shdr = &shdrs[symtab_shndx - 1];
702       strtab_shndx = symtab_shdr->sh_link;
703       if (strtab_shndx >= shnum)
704         {
705           error_callback (data,
706                           "ELF symbol table strtab link out of range", 0);
707           goto fail;
708         }
709       strtab_shdr = &shdrs[strtab_shndx - 1];
710
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;
716
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;
722
723       sdata = ((struct elf_syminfo_data *)
724                backtrace_alloc (state, sizeof *sdata, error_callback, data));
725       if (sdata == NULL)
726         goto fail;
727
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))
732         {
733           backtrace_free (state, sdata, sizeof *sdata, error_callback, data);
734           goto fail;
735         }
736
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);
740
741       *found_sym = 1;
742
743       elf_add_syminfo_data (state, sdata);
744     }
745
746   /* FIXME: Need to handle compressed debug sections.  */
747
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;
752
753   /* Read all the debug sections in a single view, since they are
754      probably adjacent in the file.  We never release this view.  */
755
756   min_offset = 0;
757   max_offset = 0;
758   for (i = 0; i < (int) DEBUG_MAX; ++i)
759     {
760       off_t end;
761
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;
767     }
768   if (min_offset == 0 || max_offset == 0)
769     {
770       if (!backtrace_close (descriptor, error_callback, data))
771         goto fail;
772       *fileline_fn = elf_nodebug;
773       return 1;
774     }
775
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;
781
782   /* We've read all we need from the executable.  */
783   if (!backtrace_close (descriptor, error_callback, data))
784     goto fail;
785   descriptor = -1;
786
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));
790
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;
805
806   *found_dwarf = 1;
807
808   return 1;
809
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;
824 }
825
826 /* Data passed to phdr_callback.  */
827
828 struct phdr_data
829 {
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;
836 };
837
838 /* Callback passed to dl_iterate_phdr.  Load debug info from shared
839    libraries.  */
840
841 static int
842 phdr_callback (struct dl_phdr_info *info, size_t size ATTRIBUTE_UNUSED,
843                void *pdata)
844 {
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;
850
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;
858
859   descriptor = backtrace_open (info->dlpi_name, pd->error_callback, pd->data,
860                                &does_not_exist);
861   if (descriptor < 0)
862     return 0;
863
864   if (elf_add (pd->state, descriptor, info->dlpi_addr, pd->error_callback,
865                pd->data, &elf_fileline_fn, pd->found_sym, &found_dwarf))
866     {
867       if (found_dwarf)
868         {
869           *pd->found_dwarf = 1;
870           *pd->fileline_fn = elf_fileline_fn;
871         }
872     }
873
874   return 0;
875 }
876
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.  */
880
881 int
882 backtrace_initialize (struct backtrace_state *state, int descriptor,
883                       backtrace_error_callback error_callback,
884                       void *data, fileline *fileline_fn)
885 {
886   int found_sym;
887   int found_dwarf;
888   syminfo elf_syminfo_fn;
889   fileline elf_fileline_fn;
890   struct phdr_data pd;
891
892   if (!elf_add (state, descriptor, 0, error_callback, data, &elf_fileline_fn,
893                 &found_sym, &found_dwarf))
894     return 0;
895
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;
902
903   dl_iterate_phdr (phdr_callback, (void *) &pd);
904
905   elf_syminfo_fn = found_sym ? elf_syminfo : elf_nosyms;
906   if (!state->threaded)
907     {
908       if (state->syminfo_fn == NULL || found_sym)
909         state->syminfo_fn = elf_syminfo_fn;
910     }
911   else
912     {
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);
917     }
918
919   if (!state->threaded)
920     {
921       if (state->fileline_fn == NULL || state->fileline_fn == elf_nodebug)
922         *fileline_fn = elf_fileline_fn;
923     }
924   else
925     {
926       fileline current_fn;
927
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;
935     }
936
937   return 1;
938 }