]> git.ipfire.org Git - thirdparty/gcc.git/blame - libbacktrace/elf.c
Update copyright years in libbacktrace.
[thirdparty/gcc.git] / libbacktrace / elf.c
CommitLineData
eff02e4f 1/* elf.c -- Get debug data from an ELF file for backtraces.
f8a7e1a4 2 Copyright (C) 2012-2013 Free Software Foundation, Inc.
eff02e4f
ILT
3 Written by Ian Lance Taylor, Google.
4
5Redistribution and use in source and binary forms, with or without
6modification, are permitted provided that the following conditions are
7met:
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
21THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
25INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
30IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31POSSIBILITY OF SUCH DAMAGE. */
32
33#include "config.h"
34
35#include <stdlib.h>
36#include <string.h>
37#include <sys/types.h>
38
e561a992
ILT
39#ifdef HAVE_DL_ITERATE_PHDR
40#include <link.h>
41#endif
42
eff02e4f
ILT
43#include "backtrace.h"
44#include "internal.h"
45
e561a992
ILT
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
53struct dl_phdr_info
54{
55 uintptr_t dlpi_addr;
56 const char *dlpi_name;
57};
58
59static int
60dl_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
eff02e4f
ILT
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
e561a992
ILT
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
eff02e4f
ILT
106/* Basic types. */
107
40d15b5b
ILT
108typedef uint16_t b_elf_half; /* Elf_Half. */
109typedef uint32_t b_elf_word; /* Elf_Word. */
110typedef int32_t b_elf_sword; /* Elf_Sword. */
eff02e4f
ILT
111
112#if BACKTRACE_ELF_SIZE == 32
113
40d15b5b
ILT
114typedef uint32_t b_elf_addr; /* Elf_Addr. */
115typedef uint32_t b_elf_off; /* Elf_Off. */
eff02e4f 116
40d15b5b 117typedef uint32_t b_elf_wxword; /* 32-bit Elf_Word, 64-bit ELF_Xword. */
eff02e4f
ILT
118
119#else
120
40d15b5b
ILT
121typedef uint64_t b_elf_addr; /* Elf_Addr. */
122typedef uint64_t b_elf_off; /* Elf_Off. */
123typedef uint64_t b_elf_xword; /* Elf_Xword. */
124typedef int64_t b_elf_sxword; /* Elf_Sxword. */
eff02e4f 125
40d15b5b 126typedef uint64_t b_elf_wxword; /* 32-bit Elf_Word, 64-bit ELF_Xword. */
eff02e4f
ILT
127
128#endif
129
130/* Data structures and associated constants. */
131
132#define EI_NIDENT 16
133
134typedef struct {
135 unsigned char e_ident[EI_NIDENT]; /* ELF "magic number" */
40d15b5b
ILT
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. */
eff02e4f
ILT
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
172typedef struct {
40d15b5b
ILT
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. */
eff02e4f
ILT
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
194typedef struct
195{
40d15b5b
ILT
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 */
eff02e4f
ILT
199 unsigned char st_info; /* Symbol binding and type */
200 unsigned char st_other; /* Visibility and other data */
40d15b5b
ILT
201 b_elf_half st_shndx; /* Symbol section index */
202} b_elf_sym; /* Elf_Sym. */
eff02e4f
ILT
203
204#else /* BACKTRACE_ELF_SIZE != 32 */
205
206typedef struct
207{
40d15b5b 208 b_elf_word st_name; /* Symbol name, index in string tbl */
eff02e4f
ILT
209 unsigned char st_info; /* Symbol binding and type */
210 unsigned char st_other; /* Visibility and other data */
40d15b5b
ILT
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. */
eff02e4f
ILT
215
216#endif /* BACKTRACE_ELF_SIZE != 32 */
217
218#define STT_FUNC 2
219
220/* An index of ELF sections we care about. */
221
222enum 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
234static 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
245struct 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
257struct 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
269struct elf_syminfo_data
270{
e561a992
ILT
271 /* Symbols for the next module. */
272 struct elf_syminfo_data *next;
eff02e4f
ILT
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
281static int
282elf_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
294static void
295elf_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
305static int
306elf_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
323static int
324elf_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
341static int
342elf_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;
40d15b5b 349 const b_elf_sym *sym;
eff02e4f
ILT
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
40d15b5b 356 sym_count = symtab_size / sizeof (b_elf_sym);
eff02e4f
ILT
357
358 /* We only care about function symbols. Count them. */
40d15b5b 359 sym = (const b_elf_sym *) symtab_data;
eff02e4f
ILT
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
40d15b5b 374 sym = (const b_elf_sym *) symtab_data;
eff02e4f
ILT
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
e561a992 396 sdata->next = NULL;
eff02e4f
ILT
397 sdata->symbols = elf_symbols;
398 sdata->count = elf_symbol_count;
399
400 return 1;
401}
402
e561a992
ILT
403/* Add EDATA to the list in STATE. */
404
405static void
406elf_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
74f80620 413 for (pp = (struct elf_syminfo_data **) (void *) &state->syminfo_data;
e561a992
ILT
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
74f80620 425 pp = (struct elf_syminfo_data **) (void *) &state->syminfo_data;
e561a992
ILT
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
eff02e4f
ILT
448/* Return the symbol name and value for a PC. */
449
450static void
451elf_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;
458
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));
463 if (sym == NULL)
464 callback (data, pc, NULL, 0);
465 else
466 callback (data, pc, sym->name, sym->address);
467}
468
e561a992 469/* Add the backtrace data for one ELF file. */
eff02e4f 470
e561a992
ILT
471static int
472elf_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)
eff02e4f
ILT
475{
476 struct backtrace_view ehdr_view;
40d15b5b 477 b_elf_ehdr ehdr;
eff02e4f
ILT
478 off_t shoff;
479 unsigned int shnum;
480 unsigned int shstrndx;
481 struct backtrace_view shdrs_view;
482 int shdrs_view_valid;
40d15b5b
ILT
483 const b_elf_shdr *shdrs;
484 const b_elf_shdr *shstrhdr;
eff02e4f
ILT
485 size_t shstr_size;
486 off_t shstr_off;
487 struct backtrace_view names_view;
488 int names_view_valid;
489 const char *names;
490 unsigned int symtab_shndx;
491 unsigned int dynsym_shndx;
492 unsigned int i;
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;
498 off_t min_offset;
499 off_t max_offset;
500 struct backtrace_view debug_view;
501 int debug_view_valid;
502
e561a992
ILT
503 *found_sym = 0;
504 *found_dwarf = 0;
505
eff02e4f
ILT
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;
511
512 if (!backtrace_get_view (state, descriptor, 0, sizeof ehdr, error_callback,
513 data, &ehdr_view))
514 goto fail;
515
516 memcpy (&ehdr, ehdr_view.data, sizeof ehdr);
517
518 backtrace_release_view (state, &ehdr_view, error_callback, data);
519
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)
524 {
525 error_callback (data, "executable file is not ELF", 0);
526 goto fail;
527 }
528 if (ehdr.e_ident[EI_VERSION] != EV_CURRENT)
529 {
530 error_callback (data, "executable file is unrecognized ELF version", 0);
531 goto fail;
532 }
533
534#if BACKTRACE_ELF_SIZE == 32
535#define BACKTRACE_ELFCLASS ELFCLASS32
536#else
537#define BACKTRACE_ELFCLASS ELFCLASS64
538#endif
539
540 if (ehdr.e_ident[EI_CLASS] != BACKTRACE_ELFCLASS)
541 {
542 error_callback (data, "executable file is unexpected ELF class", 0);
543 goto fail;
544 }
545
546 if (ehdr.e_ident[EI_DATA] != ELFDATA2LSB
547 && ehdr.e_ident[EI_DATA] != ELFDATA2MSB)
548 {
549 error_callback (data, "executable file has unknown endianness", 0);
550 goto fail;
551 }
552
553 shoff = ehdr.e_shoff;
554 shnum = ehdr.e_shnum;
555 shstrndx = ehdr.e_shstrndx;
556
557 if ((shnum == 0 || shstrndx == SHN_XINDEX)
558 && shoff != 0)
559 {
560 struct backtrace_view shdr_view;
40d15b5b 561 const b_elf_shdr *shdr;
eff02e4f
ILT
562
563 if (!backtrace_get_view (state, descriptor, shoff, sizeof shdr,
564 error_callback, data, &shdr_view))
565 goto fail;
566
40d15b5b 567 shdr = (const b_elf_shdr *) shdr_view.data;
eff02e4f
ILT
568
569 if (shnum == 0)
570 shnum = shdr->sh_size;
571
572 if (shstrndx == SHN_XINDEX)
573 {
574 shstrndx = shdr->sh_link;
575
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)
588 shstrndx -= 0x100;
589 }
590
591 backtrace_release_view (state, &shdr_view, error_callback, data);
592 }
593
594 /* To translate PC to file/line when using DWARF, we need to find
595 the .debug_info and .debug_line sections. */
596
597 /* Read the section headers, skipping the first one. */
598
40d15b5b
ILT
599 if (!backtrace_get_view (state, descriptor, shoff + sizeof (b_elf_shdr),
600 (shnum - 1) * sizeof (b_elf_shdr),
eff02e4f
ILT
601 error_callback, data, &shdrs_view))
602 goto fail;
603 shdrs_view_valid = 1;
40d15b5b 604 shdrs = (const b_elf_shdr *) shdrs_view.data;
eff02e4f
ILT
605
606 /* Read the section names. */
607
608 shstrhdr = &shdrs[shstrndx - 1];
609 shstr_size = shstrhdr->sh_size;
610 shstr_off = shstrhdr->sh_offset;
611
612 if (!backtrace_get_view (state, descriptor, shstr_off, shstr_size,
613 error_callback, data, &names_view))
614 goto fail;
615 names_view_valid = 1;
616 names = (const char *) names_view.data;
617
618 symtab_shndx = 0;
619 dynsym_shndx = 0;
620
621 memset (sections, 0, sizeof sections);
e561a992
ILT
622
623 /* Look for the symbol table. */
eff02e4f
ILT
624 for (i = 1; i < shnum; ++i)
625 {
40d15b5b 626 const b_elf_shdr *shdr;
eff02e4f
ILT
627 unsigned int sh_name;
628 const char *name;
629 int j;
630
631 shdr = &shdrs[i - 1];
632
633 if (shdr->sh_type == SHT_SYMTAB)
634 symtab_shndx = i;
635 else if (shdr->sh_type == SHT_DYNSYM)
636 dynsym_shndx = i;
637
638 sh_name = shdr->sh_name;
639 if (sh_name >= shstr_size)
640 {
641 error_callback (data, "ELF section name out of range", 0);
642 goto fail;
643 }
644
645 name = names + sh_name;
646
647 for (j = 0; j < (int) DEBUG_MAX; ++j)
648 {
649 if (strcmp (name, debug_section_names[j]) == 0)
650 {
651 sections[j].offset = shdr->sh_offset;
652 sections[j].size = shdr->sh_size;
653 break;
654 }
655 }
656 }
657
658 if (symtab_shndx == 0)
659 symtab_shndx = dynsym_shndx;
e561a992 660 if (symtab_shndx != 0)
eff02e4f 661 {
40d15b5b 662 const b_elf_shdr *symtab_shdr;
eff02e4f 663 unsigned int strtab_shndx;
40d15b5b 664 const b_elf_shdr *strtab_shdr;
eff02e4f
ILT
665 struct elf_syminfo_data *sdata;
666
667 symtab_shdr = &shdrs[symtab_shndx - 1];
668 strtab_shndx = symtab_shdr->sh_link;
669 if (strtab_shndx >= shnum)
670 {
671 error_callback (data,
672 "ELF symbol table strtab link out of range", 0);
673 goto fail;
674 }
675 strtab_shdr = &shdrs[strtab_shndx - 1];
676
677 if (!backtrace_get_view (state, descriptor, symtab_shdr->sh_offset,
678 symtab_shdr->sh_size, error_callback, data,
679 &symtab_view))
680 goto fail;
681 symtab_view_valid = 1;
682
683 if (!backtrace_get_view (state, descriptor, strtab_shdr->sh_offset,
684 strtab_shdr->sh_size, error_callback, data,
685 &strtab_view))
686 goto fail;
687 strtab_view_valid = 1;
688
689 sdata = ((struct elf_syminfo_data *)
690 backtrace_alloc (state, sizeof *sdata, error_callback, data));
691 if (sdata == NULL)
692 goto fail;
693
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))
698 {
699 backtrace_free (state, sdata, sizeof *sdata, error_callback, data);
700 goto fail;
701 }
702
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);
706
e561a992
ILT
707 *found_sym = 1;
708
709 elf_add_syminfo_data (state, sdata);
eff02e4f
ILT
710 }
711
712 /* FIXME: Need to handle compressed debug sections. */
713
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;
718
719 /* Read all the debug sections in a single view, since they are
720 probably adjacent in the file. We never release this view. */
721
722 min_offset = 0;
723 max_offset = 0;
724 for (i = 0; i < (int) DEBUG_MAX; ++i)
725 {
726 off_t end;
727
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)
732 max_offset = end;
733 }
734 if (min_offset == 0 || max_offset == 0)
735 {
736 if (!backtrace_close (descriptor, error_callback, data))
737 goto fail;
588f4f8f 738 *fileline_fn = elf_nodebug;
eff02e4f
ILT
739 return 1;
740 }
741
742 if (!backtrace_get_view (state, descriptor, min_offset,
743 max_offset - min_offset,
744 error_callback, data, &debug_view))
745 goto fail;
746 debug_view_valid = 1;
747
748 /* We've read all we need from the executable. */
749 if (!backtrace_close (descriptor, error_callback, data))
750 goto fail;
751 descriptor = -1;
752
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));
756
e561a992
ILT
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))
eff02e4f
ILT
770 goto fail;
771
e561a992
ILT
772 *found_dwarf = 1;
773
eff02e4f
ILT
774 return 1;
775
776 fail:
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);
789 return 0;
790}
e561a992
ILT
791
792/* Data passed to phdr_callback. */
793
794struct phdr_data
795{
796 struct backtrace_state *state;
797 backtrace_error_callback error_callback;
798 void *data;
799 fileline *fileline_fn;
800 int *found_sym;
801 int *found_dwarf;
802};
803
804/* Callback passed to dl_iterate_phdr. Load debug info from shared
805 libraries. */
806
807static int
808phdr_callback (struct dl_phdr_info *info, size_t size ATTRIBUTE_UNUSED,
809 void *pdata)
810{
811 struct phdr_data *pd = (struct phdr_data *) pdata;
812 int descriptor;
73f41491 813 int does_not_exist;
e561a992
ILT
814 fileline elf_fileline_fn;
815 int found_dwarf;
816
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
819 already loaded. */
820 if (info->dlpi_name == NULL
821 || info->dlpi_name[0] == '\0'
822 || info->dlpi_addr == 0)
823 return 0;
824
73f41491
ILT
825 descriptor = backtrace_open (info->dlpi_name, pd->error_callback, pd->data,
826 &does_not_exist);
e561a992
ILT
827 if (descriptor < 0)
828 return 0;
829
830 if (elf_add (pd->state, descriptor, info->dlpi_addr, pd->error_callback,
831 pd->data, &elf_fileline_fn, pd->found_sym, &found_dwarf))
832 {
833 if (found_dwarf)
834 {
835 *pd->found_dwarf = 1;
836 *pd->fileline_fn = elf_fileline_fn;
837 }
838 }
839
840 return 0;
841}
842
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
845 sections. */
846
847int
848backtrace_initialize (struct backtrace_state *state, int descriptor,
849 backtrace_error_callback error_callback,
850 void *data, fileline *fileline_fn)
851{
852 int found_sym;
853 int found_dwarf;
854 syminfo elf_syminfo_fn;
855 fileline elf_fileline_fn;
856 struct phdr_data pd;
857
858 if (!elf_add (state, descriptor, 0, error_callback, data, &elf_fileline_fn,
859 &found_sym, &found_dwarf))
860 return 0;
861
862 pd.state = state;
863 pd.error_callback = error_callback;
864 pd.data = data;
865 pd.fileline_fn = fileline_fn;
866 pd.found_sym = &found_sym;
867 pd.found_dwarf = &found_dwarf;
868
869 dl_iterate_phdr (phdr_callback, (void *) &pd);
870
871 elf_syminfo_fn = found_sym ? elf_syminfo : elf_nosyms;
872 if (!state->threaded)
873 {
874 if (state->syminfo_fn == NULL || found_sym)
875 state->syminfo_fn = elf_syminfo_fn;
876 }
877 else
878 {
879 __sync_bool_compare_and_swap (&state->syminfo_fn, NULL, elf_syminfo_fn);
880 if (found_sym)
881 __sync_bool_compare_and_swap (&state->syminfo_fn, elf_nosyms,
882 elf_syminfo_fn);
883 }
884
885 if (!state->threaded)
886 {
887 if (state->fileline_fn == NULL || state->fileline_fn == elf_nodebug)
888 *fileline_fn = elf_fileline_fn;
889 }
890 else
891 {
892 fileline current_fn;
893
894 /* Atomic load. */
895 current_fn = state->fileline_fn;
896 while (!__sync_bool_compare_and_swap (&state->fileline_fn, current_fn,
897 current_fn))
898 current_fn = state->fileline_fn;
899 if (current_fn == NULL || current_fn == elf_nodebug)
900 *fileline_fn = elf_fileline_fn;
901 }
902
903 return 1;
904}