xref: /dflybsd-src/contrib/gcc-8.0/libbacktrace/elf.c (revision 95059079af47f9a66a175f374f2da1a5020e3255)
138fd1498Szrj /* elf.c -- Get debug data from an ELF file for backtraces.
238fd1498Szrj    Copyright (C) 2012-2018 Free Software Foundation, Inc.
338fd1498Szrj    Written by Ian Lance Taylor, Google.
438fd1498Szrj 
538fd1498Szrj Redistribution and use in source and binary forms, with or without
638fd1498Szrj modification, are permitted provided that the following conditions are
738fd1498Szrj met:
838fd1498Szrj 
938fd1498Szrj     (1) Redistributions of source code must retain the above copyright
1038fd1498Szrj     notice, this list of conditions and the following disclaimer.
1138fd1498Szrj 
1238fd1498Szrj     (2) Redistributions in binary form must reproduce the above copyright
1338fd1498Szrj     notice, this list of conditions and the following disclaimer in
1438fd1498Szrj     the documentation and/or other materials provided with the
1538fd1498Szrj     distribution.
1638fd1498Szrj 
1738fd1498Szrj     (3) The name of the author may not be used to
1838fd1498Szrj     endorse or promote products derived from this software without
1938fd1498Szrj     specific prior written permission.
2038fd1498Szrj 
2138fd1498Szrj THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
2238fd1498Szrj IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2338fd1498Szrj WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
2438fd1498Szrj DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
2538fd1498Szrj INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2638fd1498Szrj (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
2738fd1498Szrj SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2838fd1498Szrj HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
2938fd1498Szrj STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
3038fd1498Szrj IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3138fd1498Szrj POSSIBILITY OF SUCH DAMAGE.  */
3238fd1498Szrj 
3338fd1498Szrj #include "config.h"
3438fd1498Szrj 
3538fd1498Szrj #include <errno.h>
3638fd1498Szrj #include <stdlib.h>
3738fd1498Szrj #include <string.h>
3838fd1498Szrj #include <sys/types.h>
3938fd1498Szrj #include <sys/stat.h>
4038fd1498Szrj #include <unistd.h>
4138fd1498Szrj 
4238fd1498Szrj #ifdef HAVE_DL_ITERATE_PHDR
4338fd1498Szrj #include <link.h>
4438fd1498Szrj #endif
4538fd1498Szrj 
4638fd1498Szrj #include "backtrace.h"
4738fd1498Szrj #include "internal.h"
4838fd1498Szrj 
4938fd1498Szrj #ifndef S_ISLNK
5038fd1498Szrj  #ifndef S_IFLNK
5138fd1498Szrj   #define S_IFLNK 0120000
5238fd1498Szrj  #endif
5338fd1498Szrj  #ifndef S_IFMT
5438fd1498Szrj   #define S_IFMT 0170000
5538fd1498Szrj  #endif
5638fd1498Szrj  #define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
5738fd1498Szrj #endif
5838fd1498Szrj 
5938fd1498Szrj #ifndef __GNUC__
6038fd1498Szrj #define __builtin_prefetch(p, r, l)
6138fd1498Szrj #define unlikely(x) (x)
6238fd1498Szrj #else
6338fd1498Szrj #define unlikely(x) __builtin_expect(!!(x), 0)
6438fd1498Szrj #endif
6538fd1498Szrj 
6638fd1498Szrj #if !defined(HAVE_DECL_STRNLEN) || !HAVE_DECL_STRNLEN
6738fd1498Szrj 
6838fd1498Szrj /* If strnlen is not declared, provide our own version.  */
6938fd1498Szrj 
7038fd1498Szrj static size_t
xstrnlen(const char * s,size_t maxlen)7138fd1498Szrj xstrnlen (const char *s, size_t maxlen)
7238fd1498Szrj {
7338fd1498Szrj   size_t i;
7438fd1498Szrj 
7538fd1498Szrj   for (i = 0; i < maxlen; ++i)
7638fd1498Szrj     if (s[i] == '\0')
7738fd1498Szrj       break;
7838fd1498Szrj   return i;
7938fd1498Szrj }
8038fd1498Szrj 
8138fd1498Szrj #define strnlen xstrnlen
8238fd1498Szrj 
8338fd1498Szrj #endif
8438fd1498Szrj 
8538fd1498Szrj #ifndef HAVE_LSTAT
8638fd1498Szrj 
8738fd1498Szrj /* Dummy version of lstat for systems that don't have it.  */
8838fd1498Szrj 
8938fd1498Szrj static int
xlstat(const char * path ATTRIBUTE_UNUSED,struct stat * st ATTRIBUTE_UNUSED)9038fd1498Szrj xlstat (const char *path ATTRIBUTE_UNUSED, struct stat *st ATTRIBUTE_UNUSED)
9138fd1498Szrj {
9238fd1498Szrj   return -1;
9338fd1498Szrj }
9438fd1498Szrj 
9538fd1498Szrj #define lstat xlstat
9638fd1498Szrj 
9738fd1498Szrj #endif
9838fd1498Szrj 
9938fd1498Szrj #ifndef HAVE_READLINK
10038fd1498Szrj 
10138fd1498Szrj /* Dummy version of readlink for systems that don't have it.  */
10238fd1498Szrj 
10338fd1498Szrj static ssize_t
xreadlink(const char * path ATTRIBUTE_UNUSED,char * buf ATTRIBUTE_UNUSED,size_t bufsz ATTRIBUTE_UNUSED)10438fd1498Szrj xreadlink (const char *path ATTRIBUTE_UNUSED, char *buf ATTRIBUTE_UNUSED,
10538fd1498Szrj 	   size_t bufsz ATTRIBUTE_UNUSED)
10638fd1498Szrj {
10738fd1498Szrj   return -1;
10838fd1498Szrj }
10938fd1498Szrj 
11038fd1498Szrj #define readlink xreadlink
11138fd1498Szrj 
11238fd1498Szrj #endif
11338fd1498Szrj 
11438fd1498Szrj #ifndef HAVE_DL_ITERATE_PHDR
11538fd1498Szrj 
11638fd1498Szrj /* Dummy version of dl_iterate_phdr for systems that don't have it.  */
11738fd1498Szrj 
11838fd1498Szrj #define dl_phdr_info x_dl_phdr_info
11938fd1498Szrj #define dl_iterate_phdr x_dl_iterate_phdr
12038fd1498Szrj 
12138fd1498Szrj struct dl_phdr_info
12238fd1498Szrj {
12338fd1498Szrj   uintptr_t dlpi_addr;
12438fd1498Szrj   const char *dlpi_name;
12538fd1498Szrj };
12638fd1498Szrj 
12738fd1498Szrj static int
dl_iterate_phdr(int (* callback)(struct dl_phdr_info *,size_t,void *)ATTRIBUTE_UNUSED,void * data ATTRIBUTE_UNUSED)12838fd1498Szrj dl_iterate_phdr (int (*callback) (struct dl_phdr_info *,
12938fd1498Szrj 				  size_t, void *) ATTRIBUTE_UNUSED,
13038fd1498Szrj 		 void *data ATTRIBUTE_UNUSED)
13138fd1498Szrj {
13238fd1498Szrj   return 0;
13338fd1498Szrj }
13438fd1498Szrj 
13538fd1498Szrj #endif /* ! defined (HAVE_DL_ITERATE_PHDR) */
13638fd1498Szrj 
13738fd1498Szrj /* The configure script must tell us whether we are 32-bit or 64-bit
13838fd1498Szrj    ELF.  We could make this code test and support either possibility,
13938fd1498Szrj    but there is no point.  This code only works for the currently
14038fd1498Szrj    running executable, which means that we know the ELF mode at
14138fd1498Szrj    configure time.  */
14238fd1498Szrj 
14338fd1498Szrj #if BACKTRACE_ELF_SIZE != 32 && BACKTRACE_ELF_SIZE != 64
14438fd1498Szrj #error "Unknown BACKTRACE_ELF_SIZE"
14538fd1498Szrj #endif
14638fd1498Szrj 
14738fd1498Szrj /* <link.h> might #include <elf.h> which might define our constants
14838fd1498Szrj    with slightly different values.  Undefine them to be safe.  */
14938fd1498Szrj 
15038fd1498Szrj #undef EI_NIDENT
15138fd1498Szrj #undef EI_MAG0
15238fd1498Szrj #undef EI_MAG1
15338fd1498Szrj #undef EI_MAG2
15438fd1498Szrj #undef EI_MAG3
15538fd1498Szrj #undef EI_CLASS
15638fd1498Szrj #undef EI_DATA
15738fd1498Szrj #undef EI_VERSION
15838fd1498Szrj #undef ELF_MAG0
15938fd1498Szrj #undef ELF_MAG1
16038fd1498Szrj #undef ELF_MAG2
16138fd1498Szrj #undef ELF_MAG3
16238fd1498Szrj #undef ELFCLASS32
16338fd1498Szrj #undef ELFCLASS64
16438fd1498Szrj #undef ELFDATA2LSB
16538fd1498Szrj #undef ELFDATA2MSB
16638fd1498Szrj #undef EV_CURRENT
16738fd1498Szrj #undef ET_DYN
16838fd1498Szrj #undef EM_PPC64
16938fd1498Szrj #undef EF_PPC64_ABI
17038fd1498Szrj #undef SHN_LORESERVE
17138fd1498Szrj #undef SHN_XINDEX
17238fd1498Szrj #undef SHN_UNDEF
17338fd1498Szrj #undef SHT_PROGBITS
17438fd1498Szrj #undef SHT_SYMTAB
17538fd1498Szrj #undef SHT_STRTAB
17638fd1498Szrj #undef SHT_DYNSYM
17738fd1498Szrj #undef SHF_COMPRESSED
17838fd1498Szrj #undef STT_OBJECT
17938fd1498Szrj #undef STT_FUNC
18038fd1498Szrj #undef NT_GNU_BUILD_ID
18138fd1498Szrj #undef ELFCOMPRESS_ZLIB
18238fd1498Szrj 
18338fd1498Szrj /* Basic types.  */
18438fd1498Szrj 
18538fd1498Szrj typedef uint16_t b_elf_half;    /* Elf_Half.  */
18638fd1498Szrj typedef uint32_t b_elf_word;    /* Elf_Word.  */
18738fd1498Szrj typedef int32_t  b_elf_sword;   /* Elf_Sword.  */
18838fd1498Szrj 
18938fd1498Szrj #if BACKTRACE_ELF_SIZE == 32
19038fd1498Szrj 
19138fd1498Szrj typedef uint32_t b_elf_addr;    /* Elf_Addr.  */
19238fd1498Szrj typedef uint32_t b_elf_off;     /* Elf_Off.  */
19338fd1498Szrj 
19438fd1498Szrj typedef uint32_t b_elf_wxword;  /* 32-bit Elf_Word, 64-bit ELF_Xword.  */
19538fd1498Szrj 
19638fd1498Szrj #else
19738fd1498Szrj 
19838fd1498Szrj typedef uint64_t b_elf_addr;    /* Elf_Addr.  */
19938fd1498Szrj typedef uint64_t b_elf_off;     /* Elf_Off.  */
20038fd1498Szrj typedef uint64_t b_elf_xword;   /* Elf_Xword.  */
20138fd1498Szrj typedef int64_t  b_elf_sxword;  /* Elf_Sxword.  */
20238fd1498Szrj 
20338fd1498Szrj typedef uint64_t b_elf_wxword;  /* 32-bit Elf_Word, 64-bit ELF_Xword.  */
20438fd1498Szrj 
20538fd1498Szrj #endif
20638fd1498Szrj 
20738fd1498Szrj /* Data structures and associated constants.  */
20838fd1498Szrj 
20938fd1498Szrj #define EI_NIDENT 16
21038fd1498Szrj 
21138fd1498Szrj typedef struct {
21238fd1498Szrj   unsigned char	e_ident[EI_NIDENT];	/* ELF "magic number" */
21338fd1498Szrj   b_elf_half	e_type;			/* Identifies object file type */
21438fd1498Szrj   b_elf_half	e_machine;		/* Specifies required architecture */
21538fd1498Szrj   b_elf_word	e_version;		/* Identifies object file version */
21638fd1498Szrj   b_elf_addr	e_entry;		/* Entry point virtual address */
21738fd1498Szrj   b_elf_off	e_phoff;		/* Program header table file offset */
21838fd1498Szrj   b_elf_off	e_shoff;		/* Section header table file offset */
21938fd1498Szrj   b_elf_word	e_flags;		/* Processor-specific flags */
22038fd1498Szrj   b_elf_half	e_ehsize;		/* ELF header size in bytes */
22138fd1498Szrj   b_elf_half	e_phentsize;		/* Program header table entry size */
22238fd1498Szrj   b_elf_half	e_phnum;		/* Program header table entry count */
22338fd1498Szrj   b_elf_half	e_shentsize;		/* Section header table entry size */
22438fd1498Szrj   b_elf_half	e_shnum;		/* Section header table entry count */
22538fd1498Szrj   b_elf_half	e_shstrndx;		/* Section header string table index */
22638fd1498Szrj } b_elf_ehdr;  /* Elf_Ehdr.  */
22738fd1498Szrj 
22838fd1498Szrj #define EI_MAG0 0
22938fd1498Szrj #define EI_MAG1 1
23038fd1498Szrj #define EI_MAG2 2
23138fd1498Szrj #define EI_MAG3 3
23238fd1498Szrj #define EI_CLASS 4
23338fd1498Szrj #define EI_DATA 5
23438fd1498Szrj #define EI_VERSION 6
23538fd1498Szrj 
23638fd1498Szrj #define ELFMAG0 0x7f
23738fd1498Szrj #define ELFMAG1 'E'
23838fd1498Szrj #define ELFMAG2 'L'
23938fd1498Szrj #define ELFMAG3 'F'
24038fd1498Szrj 
24138fd1498Szrj #define ELFCLASS32 1
24238fd1498Szrj #define ELFCLASS64 2
24338fd1498Szrj 
24438fd1498Szrj #define ELFDATA2LSB 1
24538fd1498Szrj #define ELFDATA2MSB 2
24638fd1498Szrj 
24738fd1498Szrj #define EV_CURRENT 1
24838fd1498Szrj 
24938fd1498Szrj #define ET_DYN 3
25038fd1498Szrj 
25138fd1498Szrj #define EM_PPC64 21
25238fd1498Szrj #define EF_PPC64_ABI 3
25338fd1498Szrj 
25438fd1498Szrj typedef struct {
25538fd1498Szrj   b_elf_word	sh_name;		/* Section name, index in string tbl */
25638fd1498Szrj   b_elf_word	sh_type;		/* Type of section */
25738fd1498Szrj   b_elf_wxword	sh_flags;		/* Miscellaneous section attributes */
25838fd1498Szrj   b_elf_addr	sh_addr;		/* Section virtual addr at execution */
25938fd1498Szrj   b_elf_off	sh_offset;		/* Section file offset */
26038fd1498Szrj   b_elf_wxword	sh_size;		/* Size of section in bytes */
26138fd1498Szrj   b_elf_word	sh_link;		/* Index of another section */
26238fd1498Szrj   b_elf_word	sh_info;		/* Additional section information */
26338fd1498Szrj   b_elf_wxword	sh_addralign;		/* Section alignment */
26438fd1498Szrj   b_elf_wxword	sh_entsize;		/* Entry size if section holds table */
26538fd1498Szrj } b_elf_shdr;  /* Elf_Shdr.  */
26638fd1498Szrj 
26738fd1498Szrj #define SHN_UNDEF	0x0000		/* Undefined section */
26838fd1498Szrj #define SHN_LORESERVE	0xFF00		/* Begin range of reserved indices */
26938fd1498Szrj #define SHN_XINDEX	0xFFFF		/* Section index is held elsewhere */
27038fd1498Szrj 
27138fd1498Szrj #define SHT_PROGBITS 1
27238fd1498Szrj #define SHT_SYMTAB 2
27338fd1498Szrj #define SHT_STRTAB 3
27438fd1498Szrj #define SHT_DYNSYM 11
27538fd1498Szrj 
27638fd1498Szrj #define SHF_COMPRESSED 0x800
27738fd1498Szrj 
27838fd1498Szrj #if BACKTRACE_ELF_SIZE == 32
27938fd1498Szrj 
28038fd1498Szrj typedef struct
28138fd1498Szrj {
28238fd1498Szrj   b_elf_word	st_name;		/* Symbol name, index in string tbl */
28338fd1498Szrj   b_elf_addr	st_value;		/* Symbol value */
28438fd1498Szrj   b_elf_word	st_size;		/* Symbol size */
28538fd1498Szrj   unsigned char	st_info;		/* Symbol binding and type */
28638fd1498Szrj   unsigned char	st_other;		/* Visibility and other data */
28738fd1498Szrj   b_elf_half	st_shndx;		/* Symbol section index */
28838fd1498Szrj } b_elf_sym;  /* Elf_Sym.  */
28938fd1498Szrj 
29038fd1498Szrj #else /* BACKTRACE_ELF_SIZE != 32 */
29138fd1498Szrj 
29238fd1498Szrj typedef struct
29338fd1498Szrj {
29438fd1498Szrj   b_elf_word	st_name;		/* Symbol name, index in string tbl */
29538fd1498Szrj   unsigned char	st_info;		/* Symbol binding and type */
29638fd1498Szrj   unsigned char	st_other;		/* Visibility and other data */
29738fd1498Szrj   b_elf_half	st_shndx;		/* Symbol section index */
29838fd1498Szrj   b_elf_addr	st_value;		/* Symbol value */
29938fd1498Szrj   b_elf_xword	st_size;		/* Symbol size */
30038fd1498Szrj } b_elf_sym;  /* Elf_Sym.  */
30138fd1498Szrj 
30238fd1498Szrj #endif /* BACKTRACE_ELF_SIZE != 32 */
30338fd1498Szrj 
30438fd1498Szrj #define STT_OBJECT 1
30538fd1498Szrj #define STT_FUNC 2
30638fd1498Szrj 
30738fd1498Szrj typedef struct
30838fd1498Szrj {
30938fd1498Szrj   uint32_t namesz;
31038fd1498Szrj   uint32_t descsz;
31138fd1498Szrj   uint32_t type;
31238fd1498Szrj   char name[1];
31338fd1498Szrj } b_elf_note;
31438fd1498Szrj 
31538fd1498Szrj #define NT_GNU_BUILD_ID 3
31638fd1498Szrj 
31738fd1498Szrj #if BACKTRACE_ELF_SIZE == 32
31838fd1498Szrj 
31938fd1498Szrj typedef struct
32038fd1498Szrj {
32138fd1498Szrj   b_elf_word	ch_type;		/* Compresstion algorithm */
32238fd1498Szrj   b_elf_word	ch_size;		/* Uncompressed size */
32338fd1498Szrj   b_elf_word	ch_addralign;		/* Alignment for uncompressed data */
32438fd1498Szrj } b_elf_chdr;  /* Elf_Chdr */
32538fd1498Szrj 
32638fd1498Szrj #else /* BACKTRACE_ELF_SIZE != 32 */
32738fd1498Szrj 
32838fd1498Szrj typedef struct
32938fd1498Szrj {
33038fd1498Szrj   b_elf_word	ch_type;		/* Compression algorithm */
33138fd1498Szrj   b_elf_word	ch_reserved;		/* Reserved */
33238fd1498Szrj   b_elf_xword	ch_size;		/* Uncompressed size */
33338fd1498Szrj   b_elf_xword	ch_addralign;		/* Alignment for uncompressed data */
33438fd1498Szrj } b_elf_chdr;  /* Elf_Chdr */
33538fd1498Szrj 
33638fd1498Szrj #endif /* BACKTRACE_ELF_SIZE != 32 */
33738fd1498Szrj 
33838fd1498Szrj #define ELFCOMPRESS_ZLIB 1
33938fd1498Szrj 
34038fd1498Szrj /* An index of ELF sections we care about.  */
34138fd1498Szrj 
34238fd1498Szrj enum debug_section
34338fd1498Szrj {
34438fd1498Szrj   DEBUG_INFO,
34538fd1498Szrj   DEBUG_LINE,
34638fd1498Szrj   DEBUG_ABBREV,
34738fd1498Szrj   DEBUG_RANGES,
34838fd1498Szrj   DEBUG_STR,
34938fd1498Szrj 
35038fd1498Szrj   /* The old style compressed sections.  This list must correspond to
35138fd1498Szrj      the list of normal debug sections.  */
35238fd1498Szrj   ZDEBUG_INFO,
35338fd1498Szrj   ZDEBUG_LINE,
35438fd1498Szrj   ZDEBUG_ABBREV,
35538fd1498Szrj   ZDEBUG_RANGES,
35638fd1498Szrj   ZDEBUG_STR,
35738fd1498Szrj 
35838fd1498Szrj   DEBUG_MAX
35938fd1498Szrj };
36038fd1498Szrj 
36138fd1498Szrj /* Names of sections, indexed by enum elf_section.  */
36238fd1498Szrj 
36338fd1498Szrj static const char * const debug_section_names[DEBUG_MAX] =
36438fd1498Szrj {
36538fd1498Szrj   ".debug_info",
36638fd1498Szrj   ".debug_line",
36738fd1498Szrj   ".debug_abbrev",
36838fd1498Szrj   ".debug_ranges",
36938fd1498Szrj   ".debug_str",
37038fd1498Szrj   ".zdebug_info",
37138fd1498Szrj   ".zdebug_line",
37238fd1498Szrj   ".zdebug_abbrev",
37338fd1498Szrj   ".zdebug_ranges",
37438fd1498Szrj   ".zdebug_str"
37538fd1498Szrj };
37638fd1498Szrj 
37738fd1498Szrj /* Information we gather for the sections we care about.  */
37838fd1498Szrj 
37938fd1498Szrj struct debug_section_info
38038fd1498Szrj {
38138fd1498Szrj   /* Section file offset.  */
38238fd1498Szrj   off_t offset;
38338fd1498Szrj   /* Section size.  */
38438fd1498Szrj   size_t size;
38538fd1498Szrj   /* Section contents, after read from file.  */
38638fd1498Szrj   const unsigned char *data;
38738fd1498Szrj   /* Whether the SHF_COMPRESSED flag is set for the section.  */
38838fd1498Szrj   int compressed;
38938fd1498Szrj };
39038fd1498Szrj 
39138fd1498Szrj /* Information we keep for an ELF symbol.  */
39238fd1498Szrj 
39338fd1498Szrj struct elf_symbol
39438fd1498Szrj {
39538fd1498Szrj   /* The name of the symbol.  */
39638fd1498Szrj   const char *name;
39738fd1498Szrj   /* The address of the symbol.  */
39838fd1498Szrj   uintptr_t address;
39938fd1498Szrj   /* The size of the symbol.  */
40038fd1498Szrj   size_t size;
40138fd1498Szrj };
40238fd1498Szrj 
40338fd1498Szrj /* Information to pass to elf_syminfo.  */
40438fd1498Szrj 
40538fd1498Szrj struct elf_syminfo_data
40638fd1498Szrj {
40738fd1498Szrj   /* Symbols for the next module.  */
40838fd1498Szrj   struct elf_syminfo_data *next;
40938fd1498Szrj   /* The ELF symbols, sorted by address.  */
41038fd1498Szrj   struct elf_symbol *symbols;
41138fd1498Szrj   /* The number of symbols.  */
41238fd1498Szrj   size_t count;
41338fd1498Szrj };
41438fd1498Szrj 
41538fd1498Szrj /* Information about PowerPC64 ELFv1 .opd section.  */
41638fd1498Szrj 
41738fd1498Szrj struct elf_ppc64_opd_data
41838fd1498Szrj {
41938fd1498Szrj   /* Address of the .opd section.  */
42038fd1498Szrj   b_elf_addr addr;
42138fd1498Szrj   /* Section data.  */
42238fd1498Szrj   const char *data;
42338fd1498Szrj   /* Size of the .opd section.  */
42438fd1498Szrj   size_t size;
42538fd1498Szrj   /* Corresponding section view.  */
42638fd1498Szrj   struct backtrace_view view;
42738fd1498Szrj };
42838fd1498Szrj 
42938fd1498Szrj /* Compute the CRC-32 of BUF/LEN.  This uses the CRC used for
43038fd1498Szrj    .gnu_debuglink files.  */
43138fd1498Szrj 
43238fd1498Szrj static uint32_t
elf_crc32(uint32_t crc,const unsigned char * buf,size_t len)43338fd1498Szrj elf_crc32 (uint32_t crc, const unsigned char *buf, size_t len)
43438fd1498Szrj {
43538fd1498Szrj   static const uint32_t crc32_table[256] =
43638fd1498Szrj     {
43738fd1498Szrj       0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
43838fd1498Szrj       0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
43938fd1498Szrj       0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
44038fd1498Szrj       0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
44138fd1498Szrj       0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
44238fd1498Szrj       0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
44338fd1498Szrj       0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
44438fd1498Szrj       0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
44538fd1498Szrj       0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
44638fd1498Szrj       0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
44738fd1498Szrj       0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
44838fd1498Szrj       0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
44938fd1498Szrj       0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
45038fd1498Szrj       0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
45138fd1498Szrj       0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
45238fd1498Szrj       0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
45338fd1498Szrj       0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
45438fd1498Szrj       0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
45538fd1498Szrj       0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
45638fd1498Szrj       0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
45738fd1498Szrj       0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
45838fd1498Szrj       0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
45938fd1498Szrj       0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
46038fd1498Szrj       0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
46138fd1498Szrj       0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
46238fd1498Szrj       0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
46338fd1498Szrj       0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
46438fd1498Szrj       0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
46538fd1498Szrj       0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
46638fd1498Szrj       0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
46738fd1498Szrj       0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
46838fd1498Szrj       0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
46938fd1498Szrj       0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
47038fd1498Szrj       0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
47138fd1498Szrj       0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
47238fd1498Szrj       0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
47338fd1498Szrj       0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
47438fd1498Szrj       0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
47538fd1498Szrj       0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
47638fd1498Szrj       0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
47738fd1498Szrj       0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
47838fd1498Szrj       0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
47938fd1498Szrj       0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
48038fd1498Szrj       0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
48138fd1498Szrj       0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
48238fd1498Szrj       0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
48338fd1498Szrj       0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
48438fd1498Szrj       0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
48538fd1498Szrj       0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
48638fd1498Szrj       0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
48738fd1498Szrj       0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
48838fd1498Szrj       0x2d02ef8d
48938fd1498Szrj     };
49038fd1498Szrj   const unsigned char *end;
49138fd1498Szrj 
49238fd1498Szrj   crc = ~crc;
49338fd1498Szrj   for (end = buf + len; buf < end; ++ buf)
49438fd1498Szrj     crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8);
49538fd1498Szrj   return ~crc;
49638fd1498Szrj }
49738fd1498Szrj 
49838fd1498Szrj /* Return the CRC-32 of the entire file open at DESCRIPTOR.  */
49938fd1498Szrj 
50038fd1498Szrj static uint32_t
elf_crc32_file(struct backtrace_state * state,int descriptor,backtrace_error_callback error_callback,void * data)50138fd1498Szrj elf_crc32_file (struct backtrace_state *state, int descriptor,
50238fd1498Szrj 		backtrace_error_callback error_callback, void *data)
50338fd1498Szrj {
50438fd1498Szrj   struct stat st;
50538fd1498Szrj   struct backtrace_view file_view;
50638fd1498Szrj   uint32_t ret;
50738fd1498Szrj 
50838fd1498Szrj   if (fstat (descriptor, &st) < 0)
50938fd1498Szrj     {
51038fd1498Szrj       error_callback (data, "fstat", errno);
51138fd1498Szrj       return 0;
51238fd1498Szrj     }
51338fd1498Szrj 
51438fd1498Szrj   if (!backtrace_get_view (state, descriptor, 0, st.st_size, error_callback,
51538fd1498Szrj 			   data, &file_view))
51638fd1498Szrj     return 0;
51738fd1498Szrj 
51838fd1498Szrj   ret = elf_crc32 (0, (const unsigned char *) file_view.data, st.st_size);
51938fd1498Szrj 
52038fd1498Szrj   backtrace_release_view (state, &file_view, error_callback, data);
52138fd1498Szrj 
52238fd1498Szrj   return ret;
52338fd1498Szrj }
52438fd1498Szrj 
52538fd1498Szrj /* A dummy callback function used when we can't find any debug info.  */
52638fd1498Szrj 
52738fd1498Szrj static int
elf_nodebug(struct backtrace_state * state ATTRIBUTE_UNUSED,uintptr_t pc ATTRIBUTE_UNUSED,backtrace_full_callback callback ATTRIBUTE_UNUSED,backtrace_error_callback error_callback,void * data)52838fd1498Szrj elf_nodebug (struct backtrace_state *state ATTRIBUTE_UNUSED,
52938fd1498Szrj 	     uintptr_t pc ATTRIBUTE_UNUSED,
53038fd1498Szrj 	     backtrace_full_callback callback ATTRIBUTE_UNUSED,
53138fd1498Szrj 	     backtrace_error_callback error_callback, void *data)
53238fd1498Szrj {
53338fd1498Szrj   error_callback (data, "no debug info in ELF executable", -1);
53438fd1498Szrj   return 0;
53538fd1498Szrj }
53638fd1498Szrj 
53738fd1498Szrj /* A dummy callback function used when we can't find a symbol
53838fd1498Szrj    table.  */
53938fd1498Szrj 
54038fd1498Szrj static void
elf_nosyms(struct backtrace_state * state ATTRIBUTE_UNUSED,uintptr_t addr ATTRIBUTE_UNUSED,backtrace_syminfo_callback callback ATTRIBUTE_UNUSED,backtrace_error_callback error_callback,void * data)54138fd1498Szrj elf_nosyms (struct backtrace_state *state ATTRIBUTE_UNUSED,
54238fd1498Szrj 	    uintptr_t addr ATTRIBUTE_UNUSED,
54338fd1498Szrj 	    backtrace_syminfo_callback callback ATTRIBUTE_UNUSED,
54438fd1498Szrj 	    backtrace_error_callback error_callback, void *data)
54538fd1498Szrj {
54638fd1498Szrj   error_callback (data, "no symbol table in ELF executable", -1);
54738fd1498Szrj }
54838fd1498Szrj 
54938fd1498Szrj /* Compare struct elf_symbol for qsort.  */
55038fd1498Szrj 
55138fd1498Szrj static int
elf_symbol_compare(const void * v1,const void * v2)55238fd1498Szrj elf_symbol_compare (const void *v1, const void *v2)
55338fd1498Szrj {
55438fd1498Szrj   const struct elf_symbol *e1 = (const struct elf_symbol *) v1;
55538fd1498Szrj   const struct elf_symbol *e2 = (const struct elf_symbol *) v2;
55638fd1498Szrj 
55738fd1498Szrj   if (e1->address < e2->address)
55838fd1498Szrj     return -1;
55938fd1498Szrj   else if (e1->address > e2->address)
56038fd1498Szrj     return 1;
56138fd1498Szrj   else
56238fd1498Szrj     return 0;
56338fd1498Szrj }
56438fd1498Szrj 
56538fd1498Szrj /* Compare an ADDR against an elf_symbol for bsearch.  We allocate one
56638fd1498Szrj    extra entry in the array so that this can look safely at the next
56738fd1498Szrj    entry.  */
56838fd1498Szrj 
56938fd1498Szrj static int
elf_symbol_search(const void * vkey,const void * ventry)57038fd1498Szrj elf_symbol_search (const void *vkey, const void *ventry)
57138fd1498Szrj {
57238fd1498Szrj   const uintptr_t *key = (const uintptr_t *) vkey;
57338fd1498Szrj   const struct elf_symbol *entry = (const struct elf_symbol *) ventry;
57438fd1498Szrj   uintptr_t addr;
57538fd1498Szrj 
57638fd1498Szrj   addr = *key;
57738fd1498Szrj   if (addr < entry->address)
57838fd1498Szrj     return -1;
57938fd1498Szrj   else if (addr >= entry->address + entry->size)
58038fd1498Szrj     return 1;
58138fd1498Szrj   else
58238fd1498Szrj     return 0;
58338fd1498Szrj }
58438fd1498Szrj 
58538fd1498Szrj /* Initialize the symbol table info for elf_syminfo.  */
58638fd1498Szrj 
58738fd1498Szrj static int
elf_initialize_syminfo(struct backtrace_state * state,uintptr_t base_address,const unsigned char * symtab_data,size_t symtab_size,const unsigned char * strtab,size_t strtab_size,backtrace_error_callback error_callback,void * data,struct elf_syminfo_data * sdata,struct elf_ppc64_opd_data * opd)58838fd1498Szrj elf_initialize_syminfo (struct backtrace_state *state,
58938fd1498Szrj 			uintptr_t base_address,
59038fd1498Szrj 			const unsigned char *symtab_data, size_t symtab_size,
59138fd1498Szrj 			const unsigned char *strtab, size_t strtab_size,
59238fd1498Szrj 			backtrace_error_callback error_callback,
59338fd1498Szrj 			void *data, struct elf_syminfo_data *sdata,
59438fd1498Szrj 			struct elf_ppc64_opd_data *opd)
59538fd1498Szrj {
59638fd1498Szrj   size_t sym_count;
59738fd1498Szrj   const b_elf_sym *sym;
59838fd1498Szrj   size_t elf_symbol_count;
59938fd1498Szrj   size_t elf_symbol_size;
60038fd1498Szrj   struct elf_symbol *elf_symbols;
60138fd1498Szrj   size_t i;
60238fd1498Szrj   unsigned int j;
60338fd1498Szrj 
60438fd1498Szrj   sym_count = symtab_size / sizeof (b_elf_sym);
60538fd1498Szrj 
60638fd1498Szrj   /* We only care about function symbols.  Count them.  */
60738fd1498Szrj   sym = (const b_elf_sym *) symtab_data;
60838fd1498Szrj   elf_symbol_count = 0;
60938fd1498Szrj   for (i = 0; i < sym_count; ++i, ++sym)
61038fd1498Szrj     {
61138fd1498Szrj       int info;
61238fd1498Szrj 
61338fd1498Szrj       info = sym->st_info & 0xf;
61438fd1498Szrj       if ((info == STT_FUNC || info == STT_OBJECT)
61538fd1498Szrj 	  && sym->st_shndx != SHN_UNDEF)
61638fd1498Szrj 	++elf_symbol_count;
61738fd1498Szrj     }
61838fd1498Szrj 
61938fd1498Szrj   elf_symbol_size = elf_symbol_count * sizeof (struct elf_symbol);
62038fd1498Szrj   elf_symbols = ((struct elf_symbol *)
62138fd1498Szrj 		 backtrace_alloc (state, elf_symbol_size, error_callback,
62238fd1498Szrj 				  data));
62338fd1498Szrj   if (elf_symbols == NULL)
62438fd1498Szrj     return 0;
62538fd1498Szrj 
62638fd1498Szrj   sym = (const b_elf_sym *) symtab_data;
62738fd1498Szrj   j = 0;
62838fd1498Szrj   for (i = 0; i < sym_count; ++i, ++sym)
62938fd1498Szrj     {
63038fd1498Szrj       int info;
63138fd1498Szrj 
63238fd1498Szrj       info = sym->st_info & 0xf;
63338fd1498Szrj       if (info != STT_FUNC && info != STT_OBJECT)
63438fd1498Szrj 	continue;
63538fd1498Szrj       if (sym->st_shndx == SHN_UNDEF)
63638fd1498Szrj 	continue;
63738fd1498Szrj       if (sym->st_name >= strtab_size)
63838fd1498Szrj 	{
63938fd1498Szrj 	  error_callback (data, "symbol string index out of range", 0);
64038fd1498Szrj 	  backtrace_free (state, elf_symbols, elf_symbol_size, error_callback,
64138fd1498Szrj 			  data);
64238fd1498Szrj 	  return 0;
64338fd1498Szrj 	}
64438fd1498Szrj       elf_symbols[j].name = (const char *) strtab + sym->st_name;
64538fd1498Szrj       /* Special case PowerPC64 ELFv1 symbols in .opd section, if the symbol
64638fd1498Szrj 	 is a function descriptor, read the actual code address from the
64738fd1498Szrj 	 descriptor.  */
64838fd1498Szrj       if (opd
64938fd1498Szrj 	  && sym->st_value >= opd->addr
65038fd1498Szrj 	  && sym->st_value < opd->addr + opd->size)
65138fd1498Szrj 	elf_symbols[j].address
65238fd1498Szrj 	  = *(const b_elf_addr *) (opd->data + (sym->st_value - opd->addr));
65338fd1498Szrj       else
65438fd1498Szrj 	elf_symbols[j].address = sym->st_value;
65538fd1498Szrj       elf_symbols[j].address += base_address;
65638fd1498Szrj       elf_symbols[j].size = sym->st_size;
65738fd1498Szrj       ++j;
65838fd1498Szrj     }
65938fd1498Szrj 
66038fd1498Szrj   backtrace_qsort (elf_symbols, elf_symbol_count, sizeof (struct elf_symbol),
66138fd1498Szrj 		   elf_symbol_compare);
66238fd1498Szrj 
66338fd1498Szrj   sdata->next = NULL;
66438fd1498Szrj   sdata->symbols = elf_symbols;
66538fd1498Szrj   sdata->count = elf_symbol_count;
66638fd1498Szrj 
66738fd1498Szrj   return 1;
66838fd1498Szrj }
66938fd1498Szrj 
67038fd1498Szrj /* Add EDATA to the list in STATE.  */
67138fd1498Szrj 
67238fd1498Szrj static void
elf_add_syminfo_data(struct backtrace_state * state,struct elf_syminfo_data * edata)67338fd1498Szrj elf_add_syminfo_data (struct backtrace_state *state,
67438fd1498Szrj 		      struct elf_syminfo_data *edata)
67538fd1498Szrj {
67638fd1498Szrj   if (!state->threaded)
67738fd1498Szrj     {
67838fd1498Szrj       struct elf_syminfo_data **pp;
67938fd1498Szrj 
68038fd1498Szrj       for (pp = (struct elf_syminfo_data **) (void *) &state->syminfo_data;
68138fd1498Szrj 	   *pp != NULL;
68238fd1498Szrj 	   pp = &(*pp)->next)
68338fd1498Szrj 	;
68438fd1498Szrj       *pp = edata;
68538fd1498Szrj     }
68638fd1498Szrj   else
68738fd1498Szrj     {
68838fd1498Szrj       while (1)
68938fd1498Szrj 	{
69038fd1498Szrj 	  struct elf_syminfo_data **pp;
69138fd1498Szrj 
69238fd1498Szrj 	  pp = (struct elf_syminfo_data **) (void *) &state->syminfo_data;
69338fd1498Szrj 
69438fd1498Szrj 	  while (1)
69538fd1498Szrj 	    {
69638fd1498Szrj 	      struct elf_syminfo_data *p;
69738fd1498Szrj 
69838fd1498Szrj 	      p = backtrace_atomic_load_pointer (pp);
69938fd1498Szrj 
70038fd1498Szrj 	      if (p == NULL)
70138fd1498Szrj 		break;
70238fd1498Szrj 
70338fd1498Szrj 	      pp = &p->next;
70438fd1498Szrj 	    }
70538fd1498Szrj 
70638fd1498Szrj 	  if (__sync_bool_compare_and_swap (pp, NULL, edata))
70738fd1498Szrj 	    break;
70838fd1498Szrj 	}
70938fd1498Szrj     }
71038fd1498Szrj }
71138fd1498Szrj 
71238fd1498Szrj /* Return the symbol name and value for an ADDR.  */
71338fd1498Szrj 
71438fd1498Szrj static void
elf_syminfo(struct backtrace_state * state,uintptr_t addr,backtrace_syminfo_callback callback,backtrace_error_callback error_callback ATTRIBUTE_UNUSED,void * data)71538fd1498Szrj elf_syminfo (struct backtrace_state *state, uintptr_t addr,
71638fd1498Szrj 	     backtrace_syminfo_callback callback,
71738fd1498Szrj 	     backtrace_error_callback error_callback ATTRIBUTE_UNUSED,
71838fd1498Szrj 	     void *data)
71938fd1498Szrj {
72038fd1498Szrj   struct elf_syminfo_data *edata;
72138fd1498Szrj   struct elf_symbol *sym = NULL;
72238fd1498Szrj 
72338fd1498Szrj   if (!state->threaded)
72438fd1498Szrj     {
72538fd1498Szrj       for (edata = (struct elf_syminfo_data *) state->syminfo_data;
72638fd1498Szrj 	   edata != NULL;
72738fd1498Szrj 	   edata = edata->next)
72838fd1498Szrj 	{
72938fd1498Szrj 	  sym = ((struct elf_symbol *)
73038fd1498Szrj 		 bsearch (&addr, edata->symbols, edata->count,
73138fd1498Szrj 			  sizeof (struct elf_symbol), elf_symbol_search));
73238fd1498Szrj 	  if (sym != NULL)
73338fd1498Szrj 	    break;
73438fd1498Szrj 	}
73538fd1498Szrj     }
73638fd1498Szrj   else
73738fd1498Szrj     {
73838fd1498Szrj       struct elf_syminfo_data **pp;
73938fd1498Szrj 
74038fd1498Szrj       pp = (struct elf_syminfo_data **) (void *) &state->syminfo_data;
74138fd1498Szrj       while (1)
74238fd1498Szrj 	{
74338fd1498Szrj 	  edata = backtrace_atomic_load_pointer (pp);
74438fd1498Szrj 	  if (edata == NULL)
74538fd1498Szrj 	    break;
74638fd1498Szrj 
74738fd1498Szrj 	  sym = ((struct elf_symbol *)
74838fd1498Szrj 		 bsearch (&addr, edata->symbols, edata->count,
74938fd1498Szrj 			  sizeof (struct elf_symbol), elf_symbol_search));
75038fd1498Szrj 	  if (sym != NULL)
75138fd1498Szrj 	    break;
75238fd1498Szrj 
75338fd1498Szrj 	  pp = &edata->next;
75438fd1498Szrj 	}
75538fd1498Szrj     }
75638fd1498Szrj 
75738fd1498Szrj   if (sym == NULL)
75838fd1498Szrj     callback (data, addr, NULL, 0, 0);
75938fd1498Szrj   else
76038fd1498Szrj     callback (data, addr, sym->name, sym->address, sym->size);
76138fd1498Szrj }
76238fd1498Szrj 
76338fd1498Szrj /* Return whether FILENAME is a symlink.  */
76438fd1498Szrj 
76538fd1498Szrj static int
elf_is_symlink(const char * filename)76638fd1498Szrj elf_is_symlink (const char *filename)
76738fd1498Szrj {
76838fd1498Szrj   struct stat st;
76938fd1498Szrj 
77038fd1498Szrj   if (lstat (filename, &st) < 0)
77138fd1498Szrj     return 0;
77238fd1498Szrj   return S_ISLNK (st.st_mode);
77338fd1498Szrj }
77438fd1498Szrj 
77538fd1498Szrj /* Return the results of reading the symlink FILENAME in a buffer
77638fd1498Szrj    allocated by backtrace_alloc.  Return the length of the buffer in
77738fd1498Szrj    *LEN.  */
77838fd1498Szrj 
77938fd1498Szrj static char *
elf_readlink(struct backtrace_state * state,const char * filename,backtrace_error_callback error_callback,void * data,size_t * plen)78038fd1498Szrj elf_readlink (struct backtrace_state *state, const char *filename,
78138fd1498Szrj 	      backtrace_error_callback error_callback, void *data,
78238fd1498Szrj 	      size_t *plen)
78338fd1498Szrj {
78438fd1498Szrj   size_t len;
78538fd1498Szrj   char *buf;
78638fd1498Szrj 
78738fd1498Szrj   len = 128;
78838fd1498Szrj   while (1)
78938fd1498Szrj     {
79038fd1498Szrj       ssize_t rl;
79138fd1498Szrj 
79238fd1498Szrj       buf = backtrace_alloc (state, len, error_callback, data);
79338fd1498Szrj       if (buf == NULL)
79438fd1498Szrj 	return NULL;
79538fd1498Szrj       rl = readlink (filename, buf, len);
79638fd1498Szrj       if (rl < 0)
79738fd1498Szrj 	{
79838fd1498Szrj 	  backtrace_free (state, buf, len, error_callback, data);
79938fd1498Szrj 	  return NULL;
80038fd1498Szrj 	}
80138fd1498Szrj       if ((size_t) rl < len - 1)
80238fd1498Szrj 	{
80338fd1498Szrj 	  buf[rl] = '\0';
80438fd1498Szrj 	  *plen = len;
80538fd1498Szrj 	  return buf;
80638fd1498Szrj 	}
80738fd1498Szrj       backtrace_free (state, buf, len, error_callback, data);
80838fd1498Szrj       len *= 2;
80938fd1498Szrj     }
81038fd1498Szrj }
81138fd1498Szrj 
81238fd1498Szrj /* Open a separate debug info file, using the build ID to find it.
81338fd1498Szrj    Returns an open file descriptor, or -1.
81438fd1498Szrj 
81538fd1498Szrj    The GDB manual says that the only place gdb looks for a debug file
81638fd1498Szrj    when the build ID is known is in /usr/lib/debug/.build-id.  */
81738fd1498Szrj 
81838fd1498Szrj static int
elf_open_debugfile_by_buildid(struct backtrace_state * state,const char * buildid_data,size_t buildid_size,backtrace_error_callback error_callback,void * data)81938fd1498Szrj elf_open_debugfile_by_buildid (struct backtrace_state *state,
82038fd1498Szrj 			       const char *buildid_data, size_t buildid_size,
82138fd1498Szrj 			       backtrace_error_callback error_callback,
82238fd1498Szrj 			       void *data)
82338fd1498Szrj {
82438fd1498Szrj   const char * const prefix = "/usr/lib/debug/.build-id/";
82538fd1498Szrj   const size_t prefix_len = strlen (prefix);
82638fd1498Szrj   const char * const suffix = ".debug";
82738fd1498Szrj   const size_t suffix_len = strlen (suffix);
82838fd1498Szrj   size_t len;
82938fd1498Szrj   char *bd_filename;
83038fd1498Szrj   char *t;
83138fd1498Szrj   size_t i;
83238fd1498Szrj   int ret;
83338fd1498Szrj   int does_not_exist;
83438fd1498Szrj 
83538fd1498Szrj   len = prefix_len + buildid_size * 2 + suffix_len + 2;
83638fd1498Szrj   bd_filename = backtrace_alloc (state, len, error_callback, data);
83738fd1498Szrj   if (bd_filename == NULL)
83838fd1498Szrj     return -1;
83938fd1498Szrj 
84038fd1498Szrj   t = bd_filename;
84138fd1498Szrj   memcpy (t, prefix, prefix_len);
84238fd1498Szrj   t += prefix_len;
84338fd1498Szrj   for (i = 0; i < buildid_size; i++)
84438fd1498Szrj     {
84538fd1498Szrj       unsigned char b;
84638fd1498Szrj       unsigned char nib;
84738fd1498Szrj 
84838fd1498Szrj       b = (unsigned char) buildid_data[i];
84938fd1498Szrj       nib = (b & 0xf0) >> 4;
85038fd1498Szrj       *t++ = nib < 10 ? '0' + nib : 'a' + nib - 10;
85138fd1498Szrj       nib = b & 0x0f;
85238fd1498Szrj       *t++ = nib < 10 ? '0' + nib : 'a' + nib - 10;
85338fd1498Szrj       if (i == 0)
85438fd1498Szrj 	*t++ = '/';
85538fd1498Szrj     }
85638fd1498Szrj   memcpy (t, suffix, suffix_len);
85738fd1498Szrj   t[suffix_len] = '\0';
85838fd1498Szrj 
85938fd1498Szrj   ret = backtrace_open (bd_filename, error_callback, data, &does_not_exist);
86038fd1498Szrj 
86138fd1498Szrj   backtrace_free (state, bd_filename, len, error_callback, data);
86238fd1498Szrj 
86338fd1498Szrj   /* gdb checks that the debuginfo file has the same build ID note.
86438fd1498Szrj      That seems kind of pointless to me--why would it have the right
86538fd1498Szrj      name but not the right build ID?--so skipping the check.  */
86638fd1498Szrj 
86738fd1498Szrj   return ret;
86838fd1498Szrj }
86938fd1498Szrj 
87038fd1498Szrj /* Try to open a file whose name is PREFIX (length PREFIX_LEN)
87138fd1498Szrj    concatenated with PREFIX2 (length PREFIX2_LEN) concatenated with
87238fd1498Szrj    DEBUGLINK_NAME.  Returns an open file descriptor, or -1.  */
87338fd1498Szrj 
87438fd1498Szrj static int
elf_try_debugfile(struct backtrace_state * state,const char * prefix,size_t prefix_len,const char * prefix2,size_t prefix2_len,const char * debuglink_name,backtrace_error_callback error_callback,void * data)87538fd1498Szrj elf_try_debugfile (struct backtrace_state *state, const char *prefix,
87638fd1498Szrj 		   size_t prefix_len, const char *prefix2, size_t prefix2_len,
87738fd1498Szrj 		   const char *debuglink_name,
87838fd1498Szrj 		   backtrace_error_callback error_callback, void *data)
87938fd1498Szrj {
88038fd1498Szrj   size_t debuglink_len;
88138fd1498Szrj   size_t try_len;
88238fd1498Szrj   char *try;
88338fd1498Szrj   int does_not_exist;
88438fd1498Szrj   int ret;
88538fd1498Szrj 
88638fd1498Szrj   debuglink_len = strlen (debuglink_name);
88738fd1498Szrj   try_len = prefix_len + prefix2_len + debuglink_len + 1;
88838fd1498Szrj   try = backtrace_alloc (state, try_len, error_callback, data);
88938fd1498Szrj   if (try == NULL)
89038fd1498Szrj     return -1;
89138fd1498Szrj 
89238fd1498Szrj   memcpy (try, prefix, prefix_len);
89338fd1498Szrj   memcpy (try + prefix_len, prefix2, prefix2_len);
89438fd1498Szrj   memcpy (try + prefix_len + prefix2_len, debuglink_name, debuglink_len);
89538fd1498Szrj   try[prefix_len + prefix2_len + debuglink_len] = '\0';
89638fd1498Szrj 
89738fd1498Szrj   ret = backtrace_open (try, error_callback, data, &does_not_exist);
89838fd1498Szrj 
89938fd1498Szrj   backtrace_free (state, try, try_len, error_callback, data);
90038fd1498Szrj 
90138fd1498Szrj   return ret;
90238fd1498Szrj }
90338fd1498Szrj 
90438fd1498Szrj /* Find a separate debug info file, using the debuglink section data
90538fd1498Szrj    to find it.  Returns an open file descriptor, or -1.  */
90638fd1498Szrj 
90738fd1498Szrj static int
elf_find_debugfile_by_debuglink(struct backtrace_state * state,const char * filename,const char * debuglink_name,backtrace_error_callback error_callback,void * data)90838fd1498Szrj elf_find_debugfile_by_debuglink (struct backtrace_state *state,
90938fd1498Szrj 				 const char *filename,
91038fd1498Szrj 				 const char *debuglink_name,
91138fd1498Szrj 				 backtrace_error_callback error_callback,
91238fd1498Szrj 				 void *data)
91338fd1498Szrj {
91438fd1498Szrj   int ret;
91538fd1498Szrj   char *alc;
91638fd1498Szrj   size_t alc_len;
91738fd1498Szrj   const char *slash;
91838fd1498Szrj   int ddescriptor;
91938fd1498Szrj   const char *prefix;
92038fd1498Szrj   size_t prefix_len;
92138fd1498Szrj 
92238fd1498Szrj   /* Resolve symlinks in FILENAME.  Since FILENAME is fairly likely to
92338fd1498Szrj      be /proc/self/exe, symlinks are common.  We don't try to resolve
92438fd1498Szrj      the whole path name, just the base name.  */
92538fd1498Szrj   ret = -1;
92638fd1498Szrj   alc = NULL;
92738fd1498Szrj   alc_len = 0;
92838fd1498Szrj   while (elf_is_symlink (filename))
92938fd1498Szrj     {
93038fd1498Szrj       char *new_buf;
93138fd1498Szrj       size_t new_len;
93238fd1498Szrj 
93338fd1498Szrj       new_buf = elf_readlink (state, filename, error_callback, data, &new_len);
93438fd1498Szrj       if (new_buf == NULL)
93538fd1498Szrj 	break;
93638fd1498Szrj 
93738fd1498Szrj       if (new_buf[0] == '/')
93838fd1498Szrj 	filename = new_buf;
93938fd1498Szrj       else
94038fd1498Szrj 	{
94138fd1498Szrj 	  slash = strrchr (filename, '/');
94238fd1498Szrj 	  if (slash == NULL)
94338fd1498Szrj 	    filename = new_buf;
94438fd1498Szrj 	  else
94538fd1498Szrj 	    {
94638fd1498Szrj 	      size_t clen;
94738fd1498Szrj 	      char *c;
94838fd1498Szrj 
94938fd1498Szrj 	      slash++;
95038fd1498Szrj 	      clen = slash - filename + strlen (new_buf) + 1;
95138fd1498Szrj 	      c = backtrace_alloc (state, clen, error_callback, data);
95238fd1498Szrj 	      if (c == NULL)
95338fd1498Szrj 		goto done;
95438fd1498Szrj 
95538fd1498Szrj 	      memcpy (c, filename, slash - filename);
95638fd1498Szrj 	      memcpy (c + (slash - filename), new_buf, strlen (new_buf));
95738fd1498Szrj 	      c[slash - filename + strlen (new_buf)] = '\0';
95838fd1498Szrj 	      backtrace_free (state, new_buf, new_len, error_callback, data);
95938fd1498Szrj 	      filename = c;
96038fd1498Szrj 	      new_buf = c;
96138fd1498Szrj 	      new_len = clen;
96238fd1498Szrj 	    }
96338fd1498Szrj 	}
96438fd1498Szrj 
96538fd1498Szrj       if (alc != NULL)
96638fd1498Szrj 	backtrace_free (state, alc, alc_len, error_callback, data);
96738fd1498Szrj       alc = new_buf;
96838fd1498Szrj       alc_len = new_len;
96938fd1498Szrj     }
97038fd1498Szrj 
97138fd1498Szrj   /* Look for DEBUGLINK_NAME in the same directory as FILENAME.  */
97238fd1498Szrj 
97338fd1498Szrj   slash = strrchr (filename, '/');
97438fd1498Szrj   if (slash == NULL)
97538fd1498Szrj     {
97638fd1498Szrj       prefix = "";
97738fd1498Szrj       prefix_len = 0;
97838fd1498Szrj     }
97938fd1498Szrj   else
98038fd1498Szrj     {
98138fd1498Szrj       slash++;
98238fd1498Szrj       prefix = filename;
98338fd1498Szrj       prefix_len = slash - filename;
98438fd1498Szrj     }
98538fd1498Szrj 
98638fd1498Szrj   ddescriptor = elf_try_debugfile (state, prefix, prefix_len, "", 0,
98738fd1498Szrj 				   debuglink_name, error_callback, data);
98838fd1498Szrj   if (ddescriptor >= 0)
98938fd1498Szrj     {
99038fd1498Szrj       ret = ddescriptor;
99138fd1498Szrj       goto done;
99238fd1498Szrj     }
99338fd1498Szrj 
99438fd1498Szrj   /* Look for DEBUGLINK_NAME in a .debug subdirectory of FILENAME.  */
99538fd1498Szrj 
99638fd1498Szrj   ddescriptor = elf_try_debugfile (state, prefix, prefix_len, ".debug/",
99738fd1498Szrj 				   strlen (".debug/"), debuglink_name,
99838fd1498Szrj 				   error_callback, data);
99938fd1498Szrj   if (ddescriptor >= 0)
100038fd1498Szrj     {
100138fd1498Szrj       ret = ddescriptor;
100238fd1498Szrj       goto done;
100338fd1498Szrj     }
100438fd1498Szrj 
100538fd1498Szrj   /* Look for DEBUGLINK_NAME in /usr/lib/debug.  */
100638fd1498Szrj 
100738fd1498Szrj   ddescriptor = elf_try_debugfile (state, "/usr/lib/debug/",
100838fd1498Szrj 				   strlen ("/usr/lib/debug/"), prefix,
100938fd1498Szrj 				   prefix_len, debuglink_name,
101038fd1498Szrj 				   error_callback, data);
101138fd1498Szrj   if (ddescriptor >= 0)
101238fd1498Szrj     ret = ddescriptor;
101338fd1498Szrj 
101438fd1498Szrj  done:
101538fd1498Szrj   if (alc != NULL && alc_len > 0)
101638fd1498Szrj     backtrace_free (state, alc, alc_len, error_callback, data);
101738fd1498Szrj   return ret;
101838fd1498Szrj }
101938fd1498Szrj 
102038fd1498Szrj /* Open a separate debug info file, using the debuglink section data
102138fd1498Szrj    to find it.  Returns an open file descriptor, or -1.  */
102238fd1498Szrj 
102338fd1498Szrj static int
elf_open_debugfile_by_debuglink(struct backtrace_state * state,const char * filename,const char * debuglink_name,uint32_t debuglink_crc,backtrace_error_callback error_callback,void * data)102438fd1498Szrj elf_open_debugfile_by_debuglink (struct backtrace_state *state,
102538fd1498Szrj 				 const char *filename,
102638fd1498Szrj 				 const char *debuglink_name,
102738fd1498Szrj 				 uint32_t debuglink_crc,
102838fd1498Szrj 				 backtrace_error_callback error_callback,
102938fd1498Szrj 				 void *data)
103038fd1498Szrj {
103138fd1498Szrj   int ddescriptor;
103238fd1498Szrj 
103338fd1498Szrj   ddescriptor = elf_find_debugfile_by_debuglink (state, filename,
103438fd1498Szrj 						 debuglink_name,
103538fd1498Szrj 						 error_callback, data);
103638fd1498Szrj   if (ddescriptor < 0)
103738fd1498Szrj     return -1;
103838fd1498Szrj 
103938fd1498Szrj   if (debuglink_crc != 0)
104038fd1498Szrj     {
104138fd1498Szrj       uint32_t got_crc;
104238fd1498Szrj 
104338fd1498Szrj       got_crc = elf_crc32_file (state, ddescriptor, error_callback, data);
104438fd1498Szrj       if (got_crc != debuglink_crc)
104538fd1498Szrj 	{
104638fd1498Szrj 	  backtrace_close (ddescriptor, error_callback, data);
104738fd1498Szrj 	  return -1;
104838fd1498Szrj 	}
104938fd1498Szrj     }
105038fd1498Szrj 
105138fd1498Szrj   return ddescriptor;
105238fd1498Szrj }
105338fd1498Szrj 
105438fd1498Szrj /* A function useful for setting a breakpoint for an inflation failure
105538fd1498Szrj    when this code is compiled with -g.  */
105638fd1498Szrj 
105738fd1498Szrj static void
elf_zlib_failed(void)105838fd1498Szrj elf_zlib_failed(void)
105938fd1498Szrj {
106038fd1498Szrj }
106138fd1498Szrj 
106238fd1498Szrj /* *PVAL is the current value being read from the stream, and *PBITS
106338fd1498Szrj    is the number of valid bits.  Ensure that *PVAL holds at least 15
106438fd1498Szrj    bits by reading additional bits from *PPIN, up to PINEND, as
106538fd1498Szrj    needed.  Updates *PPIN, *PVAL and *PBITS.  Returns 1 on success, 0
106638fd1498Szrj    on error.  */
106738fd1498Szrj 
106838fd1498Szrj static int
elf_zlib_fetch(const unsigned char ** ppin,const unsigned char * pinend,uint64_t * pval,unsigned int * pbits)106938fd1498Szrj elf_zlib_fetch (const unsigned char **ppin, const unsigned char *pinend,
107038fd1498Szrj 		uint64_t *pval, unsigned int *pbits)
107138fd1498Szrj {
107238fd1498Szrj   unsigned int bits;
107338fd1498Szrj   const unsigned char *pin;
107438fd1498Szrj   uint64_t val;
107538fd1498Szrj   uint32_t next;
107638fd1498Szrj 
107738fd1498Szrj   bits = *pbits;
107838fd1498Szrj   if (bits >= 15)
107938fd1498Szrj     return 1;
108038fd1498Szrj   pin = *ppin;
108138fd1498Szrj   val = *pval;
108238fd1498Szrj 
108338fd1498Szrj   if (unlikely (pinend - pin < 4))
108438fd1498Szrj     {
108538fd1498Szrj       elf_zlib_failed ();
108638fd1498Szrj       return 0;
108738fd1498Szrj     }
108838fd1498Szrj 
108938fd1498Szrj #if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) \
109038fd1498Szrj     && defined(__ORDER_BIG_ENDIAN__) \
109138fd1498Szrj     && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ \
109238fd1498Szrj         || __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
109338fd1498Szrj   /* We've ensured that PIN is aligned.  */
109438fd1498Szrj   next = *(const uint32_t *)pin;
109538fd1498Szrj 
109638fd1498Szrj #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
109738fd1498Szrj   next = __builtin_bswap32 (next);
109838fd1498Szrj #endif
109938fd1498Szrj #else
110038fd1498Szrj   next = pin[0] | (pin[1] << 8) | (pin[2] << 16) | (pin[3] << 24);
110138fd1498Szrj #endif
110238fd1498Szrj 
110338fd1498Szrj   val |= (uint64_t)next << bits;
110438fd1498Szrj   bits += 32;
110538fd1498Szrj   pin += 4;
110638fd1498Szrj 
110738fd1498Szrj   /* We will need the next four bytes soon.  */
110838fd1498Szrj   __builtin_prefetch (pin, 0, 0);
110938fd1498Szrj 
111038fd1498Szrj   *ppin = pin;
111138fd1498Szrj   *pval = val;
111238fd1498Szrj   *pbits = bits;
111338fd1498Szrj   return 1;
111438fd1498Szrj }
111538fd1498Szrj 
111638fd1498Szrj /* Huffman code tables, like the rest of the zlib format, are defined
111738fd1498Szrj    by RFC 1951.  We store a Huffman code table as a series of tables
111838fd1498Szrj    stored sequentially in memory.  Each entry in a table is 16 bits.
111938fd1498Szrj    The first, main, table has 256 entries.  It is followed by a set of
112038fd1498Szrj    secondary tables of length 2 to 128 entries.  The maximum length of
112138fd1498Szrj    a code sequence in the deflate format is 15 bits, so that is all we
112238fd1498Szrj    need.  Each secondary table has an index, which is the offset of
112338fd1498Szrj    the table in the overall memory storage.
112438fd1498Szrj 
112538fd1498Szrj    The deflate format says that all codes of a given bit length are
112638fd1498Szrj    lexicographically consecutive.  Perhaps we could have 130 values
112738fd1498Szrj    that require a 15-bit code, perhaps requiring three secondary
112838fd1498Szrj    tables of size 128.  I don't know if this is actually possible, but
112938fd1498Szrj    it suggests that the maximum size required for secondary tables is
113038fd1498Szrj    3 * 128 + 3 * 64 ... == 768.  The zlib enough program reports 660
113138fd1498Szrj    as the maximum.  We permit 768, since in addition to the 256 for
113238fd1498Szrj    the primary table, with two bytes per entry, and with the two
113338fd1498Szrj    tables we need, that gives us a page.
113438fd1498Szrj 
113538fd1498Szrj    A single table entry needs to store a value or (for the main table
113638fd1498Szrj    only) the index and size of a secondary table.  Values range from 0
113738fd1498Szrj    to 285, inclusive.  Secondary table indexes, per above, range from
113838fd1498Szrj    0 to 510.  For a value we need to store the number of bits we need
113938fd1498Szrj    to determine that value (one value may appear multiple times in the
114038fd1498Szrj    table), which is 1 to 8.  For a secondary table we need to store
114138fd1498Szrj    the number of bits used to index into the table, which is 1 to 7.
114238fd1498Szrj    And of course we need 1 bit to decide whether we have a value or a
114338fd1498Szrj    secondary table index.  So each entry needs 9 bits for value/table
114438fd1498Szrj    index, 3 bits for size, 1 bit what it is.  For simplicity we use 16
114538fd1498Szrj    bits per entry.  */
114638fd1498Szrj 
114738fd1498Szrj /* Number of entries we allocate to for one code table.  We get a page
114838fd1498Szrj    for the two code tables we need.  */
114938fd1498Szrj 
115038fd1498Szrj #define HUFFMAN_TABLE_SIZE (1024)
115138fd1498Szrj 
115238fd1498Szrj /* Bit masks and shifts for the values in the table.  */
115338fd1498Szrj 
115438fd1498Szrj #define HUFFMAN_VALUE_MASK 0x01ff
115538fd1498Szrj #define HUFFMAN_BITS_SHIFT 9
115638fd1498Szrj #define HUFFMAN_BITS_MASK 0x7
115738fd1498Szrj #define HUFFMAN_SECONDARY_SHIFT 12
115838fd1498Szrj 
115938fd1498Szrj /* For working memory while inflating we need two code tables, we need
116038fd1498Szrj    an array of code lengths (max value 15, so we use unsigned char),
116138fd1498Szrj    and an array of unsigned shorts used while building a table.  The
116238fd1498Szrj    latter two arrays must be large enough to hold the maximum number
116338fd1498Szrj    of code lengths, which RFC 1951 defines as 286 + 30.  */
116438fd1498Szrj 
116538fd1498Szrj #define ZDEBUG_TABLE_SIZE \
116638fd1498Szrj   (2 * HUFFMAN_TABLE_SIZE * sizeof (uint16_t) \
116738fd1498Szrj    + (286 + 30) * sizeof (uint16_t)	      \
116838fd1498Szrj    + (286 + 30) * sizeof (unsigned char))
116938fd1498Szrj 
117038fd1498Szrj #define ZDEBUG_TABLE_CODELEN_OFFSET \
117138fd1498Szrj   (2 * HUFFMAN_TABLE_SIZE * sizeof (uint16_t) \
117238fd1498Szrj    + (286 + 30) * sizeof (uint16_t))
117338fd1498Szrj 
117438fd1498Szrj #define ZDEBUG_TABLE_WORK_OFFSET \
117538fd1498Szrj   (2 * HUFFMAN_TABLE_SIZE * sizeof (uint16_t))
117638fd1498Szrj 
117738fd1498Szrj #ifdef BACKTRACE_GENERATE_FIXED_HUFFMAN_TABLE
117838fd1498Szrj 
117938fd1498Szrj /* Used by the main function that generates the fixed table to learn
118038fd1498Szrj    the table size.  */
118138fd1498Szrj static size_t final_next_secondary;
118238fd1498Szrj 
118338fd1498Szrj #endif
118438fd1498Szrj 
118538fd1498Szrj /* Build a Huffman code table from an array of lengths in CODES of
118638fd1498Szrj    length CODES_LEN.  The table is stored into *TABLE.  ZDEBUG_TABLE
118738fd1498Szrj    is the same as for elf_zlib_inflate, used to find some work space.
118838fd1498Szrj    Returns 1 on success, 0 on error.  */
118938fd1498Szrj 
119038fd1498Szrj static int
elf_zlib_inflate_table(unsigned char * codes,size_t codes_len,uint16_t * zdebug_table,uint16_t * table)119138fd1498Szrj elf_zlib_inflate_table (unsigned char *codes, size_t codes_len,
119238fd1498Szrj 			uint16_t *zdebug_table, uint16_t *table)
119338fd1498Szrj {
119438fd1498Szrj   uint16_t count[16];
119538fd1498Szrj   uint16_t start[16];
119638fd1498Szrj   uint16_t prev[16];
119738fd1498Szrj   uint16_t firstcode[7];
119838fd1498Szrj   uint16_t *next;
119938fd1498Szrj   size_t i;
120038fd1498Szrj   size_t j;
120138fd1498Szrj   unsigned int code;
120238fd1498Szrj   size_t next_secondary;
120338fd1498Szrj 
120438fd1498Szrj   /* Count the number of code of each length.  Set NEXT[val] to be the
120538fd1498Szrj      next value after VAL with the same bit length.  */
120638fd1498Szrj 
120738fd1498Szrj   next = (uint16_t *) (((unsigned char *) zdebug_table)
120838fd1498Szrj 		       + ZDEBUG_TABLE_WORK_OFFSET);
120938fd1498Szrj 
121038fd1498Szrj   memset (&count[0], 0, 16 * sizeof (uint16_t));
121138fd1498Szrj   for (i = 0; i < codes_len; ++i)
121238fd1498Szrj     {
121338fd1498Szrj       if (unlikely (codes[i] >= 16))
121438fd1498Szrj 	{
121538fd1498Szrj 	  elf_zlib_failed ();
121638fd1498Szrj 	  return 0;
121738fd1498Szrj 	}
121838fd1498Szrj 
121938fd1498Szrj       if (count[codes[i]] == 0)
122038fd1498Szrj 	{
122138fd1498Szrj 	  start[codes[i]] = i;
122238fd1498Szrj 	  prev[codes[i]] = i;
122338fd1498Szrj 	}
122438fd1498Szrj       else
122538fd1498Szrj 	{
122638fd1498Szrj 	  next[prev[codes[i]]] = i;
122738fd1498Szrj 	  prev[codes[i]] = i;
122838fd1498Szrj 	}
122938fd1498Szrj 
123038fd1498Szrj       ++count[codes[i]];
123138fd1498Szrj     }
123238fd1498Szrj 
123338fd1498Szrj   /* For each length, fill in the table for the codes of that
123438fd1498Szrj      length.  */
123538fd1498Szrj 
123638fd1498Szrj   memset (table, 0, HUFFMAN_TABLE_SIZE * sizeof (uint16_t));
123738fd1498Szrj 
123838fd1498Szrj   /* Handle the values that do not require a secondary table.  */
123938fd1498Szrj 
124038fd1498Szrj   code = 0;
124138fd1498Szrj   for (j = 1; j <= 8; ++j)
124238fd1498Szrj     {
124338fd1498Szrj       unsigned int jcnt;
124438fd1498Szrj       unsigned int val;
124538fd1498Szrj 
124638fd1498Szrj       jcnt = count[j];
124738fd1498Szrj       if (jcnt == 0)
124838fd1498Szrj 	continue;
124938fd1498Szrj 
125038fd1498Szrj       if (unlikely (jcnt > (1U << j)))
125138fd1498Szrj 	{
125238fd1498Szrj 	  elf_zlib_failed ();
125338fd1498Szrj 	  return 0;
125438fd1498Szrj 	}
125538fd1498Szrj 
125638fd1498Szrj       /* There are JCNT values that have this length, the values
125738fd1498Szrj 	 starting from START[j] continuing through NEXT[VAL].  Those
125838fd1498Szrj 	 values are assigned consecutive values starting at CODE.  */
125938fd1498Szrj 
126038fd1498Szrj       val = start[j];
126138fd1498Szrj       for (i = 0; i < jcnt; ++i)
126238fd1498Szrj 	{
126338fd1498Szrj 	  uint16_t tval;
126438fd1498Szrj 	  size_t ind;
126538fd1498Szrj 	  unsigned int incr;
126638fd1498Szrj 
126738fd1498Szrj 	  /* In the compressed bit stream, the value VAL is encoded as
126838fd1498Szrj 	     J bits with the value C.  */
126938fd1498Szrj 
127038fd1498Szrj 	  if (unlikely ((val & ~HUFFMAN_VALUE_MASK) != 0))
127138fd1498Szrj 	    {
127238fd1498Szrj 	      elf_zlib_failed ();
127338fd1498Szrj 	      return 0;
127438fd1498Szrj 	    }
127538fd1498Szrj 
127638fd1498Szrj 	  tval = val | ((j - 1) << HUFFMAN_BITS_SHIFT);
127738fd1498Szrj 
127838fd1498Szrj 	  /* The table lookup uses 8 bits.  If J is less than 8, we
127938fd1498Szrj 	     don't know what the other bits will be.  We need to fill
128038fd1498Szrj 	     in all possibilities in the table.  Since the Huffman
128138fd1498Szrj 	     code is unambiguous, those entries can't be used for any
128238fd1498Szrj 	     other code.  */
128338fd1498Szrj 
128438fd1498Szrj 	  for (ind = code; ind < 0x100; ind += 1 << j)
128538fd1498Szrj 	    {
128638fd1498Szrj 	      if (unlikely (table[ind] != 0))
128738fd1498Szrj 		{
128838fd1498Szrj 		  elf_zlib_failed ();
128938fd1498Szrj 		  return 0;
129038fd1498Szrj 		}
129138fd1498Szrj 	      table[ind] = tval;
129238fd1498Szrj 	    }
129338fd1498Szrj 
129438fd1498Szrj 	  /* Advance to the next value with this length.  */
129538fd1498Szrj 	  if (i + 1 < jcnt)
129638fd1498Szrj 	    val = next[val];
129738fd1498Szrj 
129838fd1498Szrj 	  /* The Huffman codes are stored in the bitstream with the
129938fd1498Szrj 	     most significant bit first, as is required to make them
130038fd1498Szrj 	     unambiguous.  The effect is that when we read them from
130138fd1498Szrj 	     the bitstream we see the bit sequence in reverse order:
130238fd1498Szrj 	     the most significant bit of the Huffman code is the least
130338fd1498Szrj 	     significant bit of the value we read from the bitstream.
130438fd1498Szrj 	     That means that to make our table lookups work, we need
130538fd1498Szrj 	     to reverse the bits of CODE.  Since reversing bits is
130638fd1498Szrj 	     tedious and in general requires using a table, we instead
130738fd1498Szrj 	     increment CODE in reverse order.  That is, if the number
130838fd1498Szrj 	     of bits we are currently using, here named J, is 3, we
130938fd1498Szrj 	     count as 000, 100, 010, 110, 001, 101, 011, 111, which is
131038fd1498Szrj 	     to say the numbers from 0 to 7 but with the bits
131138fd1498Szrj 	     reversed.  Going to more bits, aka incrementing J,
131238fd1498Szrj 	     effectively just adds more zero bits as the beginning,
131338fd1498Szrj 	     and as such does not change the numeric value of CODE.
131438fd1498Szrj 
131538fd1498Szrj 	     To increment CODE of length J in reverse order, find the
131638fd1498Szrj 	     most significant zero bit and set it to one while
131738fd1498Szrj 	     clearing all higher bits.  In other words, add 1 modulo
131838fd1498Szrj 	     2^J, only reversed.  */
131938fd1498Szrj 
132038fd1498Szrj 	  incr = 1U << (j - 1);
132138fd1498Szrj 	  while ((code & incr) != 0)
132238fd1498Szrj 	    incr >>= 1;
132338fd1498Szrj 	  if (incr == 0)
132438fd1498Szrj 	    code = 0;
132538fd1498Szrj 	  else
132638fd1498Szrj 	    {
132738fd1498Szrj 	      code &= incr - 1;
132838fd1498Szrj 	      code += incr;
132938fd1498Szrj 	    }
133038fd1498Szrj 	}
133138fd1498Szrj     }
133238fd1498Szrj 
133338fd1498Szrj   /* Handle the values that require a secondary table.  */
133438fd1498Szrj 
133538fd1498Szrj   /* Set FIRSTCODE, the number at which the codes start, for each
133638fd1498Szrj      length.  */
133738fd1498Szrj 
133838fd1498Szrj   for (j = 9; j < 16; j++)
133938fd1498Szrj     {
134038fd1498Szrj       unsigned int jcnt;
134138fd1498Szrj       unsigned int k;
134238fd1498Szrj 
134338fd1498Szrj       jcnt = count[j];
134438fd1498Szrj       if (jcnt == 0)
134538fd1498Szrj 	continue;
134638fd1498Szrj 
134738fd1498Szrj       /* There are JCNT values that have this length, the values
134838fd1498Szrj 	 starting from START[j].  Those values are assigned
134938fd1498Szrj 	 consecutive values starting at CODE.  */
135038fd1498Szrj 
135138fd1498Szrj       firstcode[j - 9] = code;
135238fd1498Szrj 
135338fd1498Szrj       /* Reverse add JCNT to CODE modulo 2^J.  */
135438fd1498Szrj       for (k = 0; k < j; ++k)
135538fd1498Szrj 	{
135638fd1498Szrj 	  if ((jcnt & (1U << k)) != 0)
135738fd1498Szrj 	    {
135838fd1498Szrj 	      unsigned int m;
135938fd1498Szrj 	      unsigned int bit;
136038fd1498Szrj 
136138fd1498Szrj 	      bit = 1U << (j - k - 1);
136238fd1498Szrj 	      for (m = 0; m < j - k; ++m, bit >>= 1)
136338fd1498Szrj 		{
136438fd1498Szrj 		  if ((code & bit) == 0)
136538fd1498Szrj 		    {
136638fd1498Szrj 		      code += bit;
136738fd1498Szrj 		      break;
136838fd1498Szrj 		    }
136938fd1498Szrj 		  code &= ~bit;
137038fd1498Szrj 		}
137138fd1498Szrj 	      jcnt &= ~(1U << k);
137238fd1498Szrj 	    }
137338fd1498Szrj 	}
137438fd1498Szrj       if (unlikely (jcnt != 0))
137538fd1498Szrj 	{
137638fd1498Szrj 	  elf_zlib_failed ();
137738fd1498Szrj 	  return 0;
137838fd1498Szrj 	}
137938fd1498Szrj     }
138038fd1498Szrj 
138138fd1498Szrj   /* For J from 9 to 15, inclusive, we store COUNT[J] consecutive
138238fd1498Szrj      values starting at START[J] with consecutive codes starting at
138338fd1498Szrj      FIRSTCODE[J - 9].  In the primary table we need to point to the
138438fd1498Szrj      secondary table, and the secondary table will be indexed by J - 9
138538fd1498Szrj      bits.  We count down from 15 so that we install the larger
138638fd1498Szrj      secondary tables first, as the smaller ones may be embedded in
138738fd1498Szrj      the larger ones.  */
138838fd1498Szrj 
138938fd1498Szrj   next_secondary = 0; /* Index of next secondary table (after primary).  */
139038fd1498Szrj   for (j = 15; j >= 9; j--)
139138fd1498Szrj     {
139238fd1498Szrj       unsigned int jcnt;
139338fd1498Szrj       unsigned int val;
139438fd1498Szrj       size_t primary; /* Current primary index.  */
139538fd1498Szrj       size_t secondary; /* Offset to current secondary table.  */
139638fd1498Szrj       size_t secondary_bits; /* Bit size of current secondary table.  */
139738fd1498Szrj 
139838fd1498Szrj       jcnt = count[j];
139938fd1498Szrj       if (jcnt == 0)
140038fd1498Szrj 	continue;
140138fd1498Szrj 
140238fd1498Szrj       val = start[j];
140338fd1498Szrj       code = firstcode[j - 9];
140438fd1498Szrj       primary = 0x100;
140538fd1498Szrj       secondary = 0;
140638fd1498Szrj       secondary_bits = 0;
140738fd1498Szrj       for (i = 0; i < jcnt; ++i)
140838fd1498Szrj 	{
140938fd1498Szrj 	  uint16_t tval;
141038fd1498Szrj 	  size_t ind;
141138fd1498Szrj 	  unsigned int incr;
141238fd1498Szrj 
141338fd1498Szrj 	  if ((code & 0xff) != primary)
141438fd1498Szrj 	    {
141538fd1498Szrj 	      uint16_t tprimary;
141638fd1498Szrj 
141738fd1498Szrj 	      /* Fill in a new primary table entry.  */
141838fd1498Szrj 
141938fd1498Szrj 	      primary = code & 0xff;
142038fd1498Szrj 
142138fd1498Szrj 	      tprimary = table[primary];
142238fd1498Szrj 	      if (tprimary == 0)
142338fd1498Szrj 		{
142438fd1498Szrj 		  /* Start a new secondary table.  */
142538fd1498Szrj 
142638fd1498Szrj 		  if (unlikely ((next_secondary & HUFFMAN_VALUE_MASK)
142738fd1498Szrj 				!= next_secondary))
142838fd1498Szrj 		    {
142938fd1498Szrj 		      elf_zlib_failed ();
143038fd1498Szrj 		      return 0;
143138fd1498Szrj 		    }
143238fd1498Szrj 
143338fd1498Szrj 		  secondary = next_secondary;
143438fd1498Szrj 		  secondary_bits = j - 8;
143538fd1498Szrj 		  next_secondary += 1 << secondary_bits;
143638fd1498Szrj 		  table[primary] = (secondary
143738fd1498Szrj 				    + ((j - 8) << HUFFMAN_BITS_SHIFT)
143838fd1498Szrj 				    + (1U << HUFFMAN_SECONDARY_SHIFT));
143938fd1498Szrj 		}
144038fd1498Szrj 	      else
144138fd1498Szrj 		{
144238fd1498Szrj 		  /* There is an existing entry.  It had better be a
144338fd1498Szrj 		     secondary table with enough bits.  */
144438fd1498Szrj 		  if (unlikely ((tprimary & (1U << HUFFMAN_SECONDARY_SHIFT))
144538fd1498Szrj 				== 0))
144638fd1498Szrj 		    {
144738fd1498Szrj 		      elf_zlib_failed ();
144838fd1498Szrj 		      return 0;
144938fd1498Szrj 		    }
145038fd1498Szrj 		  secondary = tprimary & HUFFMAN_VALUE_MASK;
145138fd1498Szrj 		  secondary_bits = ((tprimary >> HUFFMAN_BITS_SHIFT)
145238fd1498Szrj 				    & HUFFMAN_BITS_MASK);
145338fd1498Szrj 		  if (unlikely (secondary_bits < j - 8))
145438fd1498Szrj 		    {
145538fd1498Szrj 		      elf_zlib_failed ();
145638fd1498Szrj 		      return 0;
145738fd1498Szrj 		    }
145838fd1498Szrj 		}
145938fd1498Szrj 	    }
146038fd1498Szrj 
146138fd1498Szrj 	  /* Fill in secondary table entries.  */
146238fd1498Szrj 
146338fd1498Szrj 	  tval = val | ((j - 8) << HUFFMAN_BITS_SHIFT);
146438fd1498Szrj 
146538fd1498Szrj 	  for (ind = code >> 8;
146638fd1498Szrj 	       ind < (1U << secondary_bits);
146738fd1498Szrj 	       ind += 1U << (j - 8))
146838fd1498Szrj 	    {
146938fd1498Szrj 	      if (unlikely (table[secondary + 0x100 + ind] != 0))
147038fd1498Szrj 		{
147138fd1498Szrj 		  elf_zlib_failed ();
147238fd1498Szrj 		  return 0;
147338fd1498Szrj 		}
147438fd1498Szrj 	      table[secondary + 0x100 + ind] = tval;
147538fd1498Szrj 	    }
147638fd1498Szrj 
147738fd1498Szrj 	  if (i + 1 < jcnt)
147838fd1498Szrj 	    val = next[val];
147938fd1498Szrj 
148038fd1498Szrj 	  incr = 1U << (j - 1);
148138fd1498Szrj 	  while ((code & incr) != 0)
148238fd1498Szrj 	    incr >>= 1;
148338fd1498Szrj 	  if (incr == 0)
148438fd1498Szrj 	    code = 0;
148538fd1498Szrj 	  else
148638fd1498Szrj 	    {
148738fd1498Szrj 	      code &= incr - 1;
148838fd1498Szrj 	      code += incr;
148938fd1498Szrj 	    }
149038fd1498Szrj 	}
149138fd1498Szrj     }
149238fd1498Szrj 
149338fd1498Szrj #ifdef BACKTRACE_GENERATE_FIXED_HUFFMAN_TABLE
149438fd1498Szrj   final_next_secondary = next_secondary;
149538fd1498Szrj #endif
149638fd1498Szrj 
149738fd1498Szrj   return 1;
149838fd1498Szrj }
149938fd1498Szrj 
150038fd1498Szrj #ifdef BACKTRACE_GENERATE_FIXED_HUFFMAN_TABLE
150138fd1498Szrj 
150238fd1498Szrj /* Used to generate the fixed Huffman table for block type 1.  */
150338fd1498Szrj 
150438fd1498Szrj #include <stdio.h>
150538fd1498Szrj 
150638fd1498Szrj static uint16_t table[ZDEBUG_TABLE_SIZE];
150738fd1498Szrj static unsigned char codes[288];
150838fd1498Szrj 
150938fd1498Szrj int
main()151038fd1498Szrj main ()
151138fd1498Szrj {
151238fd1498Szrj   size_t i;
151338fd1498Szrj 
151438fd1498Szrj   for (i = 0; i <= 143; ++i)
151538fd1498Szrj     codes[i] = 8;
151638fd1498Szrj   for (i = 144; i <= 255; ++i)
151738fd1498Szrj     codes[i] = 9;
151838fd1498Szrj   for (i = 256; i <= 279; ++i)
151938fd1498Szrj     codes[i] = 7;
152038fd1498Szrj   for (i = 280; i <= 287; ++i)
152138fd1498Szrj     codes[i] = 8;
152238fd1498Szrj   if (!elf_zlib_inflate_table (&codes[0], 288, &table[0], &table[0]))
152338fd1498Szrj     {
152438fd1498Szrj       fprintf (stderr, "elf_zlib_inflate_table failed\n");
152538fd1498Szrj       exit (EXIT_FAILURE);
152638fd1498Szrj     }
152738fd1498Szrj 
152838fd1498Szrj   printf ("static const uint16_t elf_zlib_default_table[%#zx] =\n",
152938fd1498Szrj 	  final_next_secondary + 0x100);
153038fd1498Szrj   printf ("{\n");
153138fd1498Szrj   for (i = 0; i < final_next_secondary + 0x100; i += 8)
153238fd1498Szrj     {
153338fd1498Szrj       size_t j;
153438fd1498Szrj 
153538fd1498Szrj       printf (" ");
153638fd1498Szrj       for (j = i; j < final_next_secondary + 0x100 && j < i + 8; ++j)
153738fd1498Szrj 	printf (" %#x,", table[j]);
153838fd1498Szrj       printf ("\n");
153938fd1498Szrj     }
154038fd1498Szrj   printf ("};\n");
154138fd1498Szrj   printf ("\n");
154238fd1498Szrj 
154338fd1498Szrj   for (i = 0; i < 32; ++i)
154438fd1498Szrj     codes[i] = 5;
154538fd1498Szrj   if (!elf_zlib_inflate_table (&codes[0], 32, &table[0], &table[0]))
154638fd1498Szrj     {
154738fd1498Szrj       fprintf (stderr, "elf_zlib_inflate_table failed\n");
154838fd1498Szrj       exit (EXIT_FAILURE);
154938fd1498Szrj     }
155038fd1498Szrj 
155138fd1498Szrj   printf ("static const uint16_t elf_zlib_default_dist_table[%#zx] =\n",
155238fd1498Szrj 	  final_next_secondary + 0x100);
155338fd1498Szrj   printf ("{\n");
155438fd1498Szrj   for (i = 0; i < final_next_secondary + 0x100; i += 8)
155538fd1498Szrj     {
155638fd1498Szrj       size_t j;
155738fd1498Szrj 
155838fd1498Szrj       printf (" ");
155938fd1498Szrj       for (j = i; j < final_next_secondary + 0x100 && j < i + 8; ++j)
156038fd1498Szrj 	printf (" %#x,", table[j]);
156138fd1498Szrj       printf ("\n");
156238fd1498Szrj     }
156338fd1498Szrj   printf ("};\n");
156438fd1498Szrj 
156538fd1498Szrj   return 0;
156638fd1498Szrj }
156738fd1498Szrj 
156838fd1498Szrj #endif
156938fd1498Szrj 
157038fd1498Szrj /* The fixed tables generated by the #ifdef'ed out main function
157138fd1498Szrj    above.  */
157238fd1498Szrj 
157338fd1498Szrj static const uint16_t elf_zlib_default_table[0x170] =
157438fd1498Szrj {
157538fd1498Szrj   0xd00, 0xe50, 0xe10, 0xf18, 0xd10, 0xe70, 0xe30, 0x1230,
157638fd1498Szrj   0xd08, 0xe60, 0xe20, 0x1210, 0xe00, 0xe80, 0xe40, 0x1250,
157738fd1498Szrj   0xd04, 0xe58, 0xe18, 0x1200, 0xd14, 0xe78, 0xe38, 0x1240,
157838fd1498Szrj   0xd0c, 0xe68, 0xe28, 0x1220, 0xe08, 0xe88, 0xe48, 0x1260,
157938fd1498Szrj   0xd02, 0xe54, 0xe14, 0xf1c, 0xd12, 0xe74, 0xe34, 0x1238,
158038fd1498Szrj   0xd0a, 0xe64, 0xe24, 0x1218, 0xe04, 0xe84, 0xe44, 0x1258,
158138fd1498Szrj   0xd06, 0xe5c, 0xe1c, 0x1208, 0xd16, 0xe7c, 0xe3c, 0x1248,
158238fd1498Szrj   0xd0e, 0xe6c, 0xe2c, 0x1228, 0xe0c, 0xe8c, 0xe4c, 0x1268,
158338fd1498Szrj   0xd01, 0xe52, 0xe12, 0xf1a, 0xd11, 0xe72, 0xe32, 0x1234,
158438fd1498Szrj   0xd09, 0xe62, 0xe22, 0x1214, 0xe02, 0xe82, 0xe42, 0x1254,
158538fd1498Szrj   0xd05, 0xe5a, 0xe1a, 0x1204, 0xd15, 0xe7a, 0xe3a, 0x1244,
158638fd1498Szrj   0xd0d, 0xe6a, 0xe2a, 0x1224, 0xe0a, 0xe8a, 0xe4a, 0x1264,
158738fd1498Szrj   0xd03, 0xe56, 0xe16, 0xf1e, 0xd13, 0xe76, 0xe36, 0x123c,
158838fd1498Szrj   0xd0b, 0xe66, 0xe26, 0x121c, 0xe06, 0xe86, 0xe46, 0x125c,
158938fd1498Szrj   0xd07, 0xe5e, 0xe1e, 0x120c, 0xd17, 0xe7e, 0xe3e, 0x124c,
159038fd1498Szrj   0xd0f, 0xe6e, 0xe2e, 0x122c, 0xe0e, 0xe8e, 0xe4e, 0x126c,
159138fd1498Szrj   0xd00, 0xe51, 0xe11, 0xf19, 0xd10, 0xe71, 0xe31, 0x1232,
159238fd1498Szrj   0xd08, 0xe61, 0xe21, 0x1212, 0xe01, 0xe81, 0xe41, 0x1252,
159338fd1498Szrj   0xd04, 0xe59, 0xe19, 0x1202, 0xd14, 0xe79, 0xe39, 0x1242,
159438fd1498Szrj   0xd0c, 0xe69, 0xe29, 0x1222, 0xe09, 0xe89, 0xe49, 0x1262,
159538fd1498Szrj   0xd02, 0xe55, 0xe15, 0xf1d, 0xd12, 0xe75, 0xe35, 0x123a,
159638fd1498Szrj   0xd0a, 0xe65, 0xe25, 0x121a, 0xe05, 0xe85, 0xe45, 0x125a,
159738fd1498Szrj   0xd06, 0xe5d, 0xe1d, 0x120a, 0xd16, 0xe7d, 0xe3d, 0x124a,
159838fd1498Szrj   0xd0e, 0xe6d, 0xe2d, 0x122a, 0xe0d, 0xe8d, 0xe4d, 0x126a,
159938fd1498Szrj   0xd01, 0xe53, 0xe13, 0xf1b, 0xd11, 0xe73, 0xe33, 0x1236,
160038fd1498Szrj   0xd09, 0xe63, 0xe23, 0x1216, 0xe03, 0xe83, 0xe43, 0x1256,
160138fd1498Szrj   0xd05, 0xe5b, 0xe1b, 0x1206, 0xd15, 0xe7b, 0xe3b, 0x1246,
160238fd1498Szrj   0xd0d, 0xe6b, 0xe2b, 0x1226, 0xe0b, 0xe8b, 0xe4b, 0x1266,
160338fd1498Szrj   0xd03, 0xe57, 0xe17, 0xf1f, 0xd13, 0xe77, 0xe37, 0x123e,
160438fd1498Szrj   0xd0b, 0xe67, 0xe27, 0x121e, 0xe07, 0xe87, 0xe47, 0x125e,
160538fd1498Szrj   0xd07, 0xe5f, 0xe1f, 0x120e, 0xd17, 0xe7f, 0xe3f, 0x124e,
160638fd1498Szrj   0xd0f, 0xe6f, 0xe2f, 0x122e, 0xe0f, 0xe8f, 0xe4f, 0x126e,
160738fd1498Szrj   0x290, 0x291, 0x292, 0x293, 0x294, 0x295, 0x296, 0x297,
160838fd1498Szrj   0x298, 0x299, 0x29a, 0x29b, 0x29c, 0x29d, 0x29e, 0x29f,
160938fd1498Szrj   0x2a0, 0x2a1, 0x2a2, 0x2a3, 0x2a4, 0x2a5, 0x2a6, 0x2a7,
161038fd1498Szrj   0x2a8, 0x2a9, 0x2aa, 0x2ab, 0x2ac, 0x2ad, 0x2ae, 0x2af,
161138fd1498Szrj   0x2b0, 0x2b1, 0x2b2, 0x2b3, 0x2b4, 0x2b5, 0x2b6, 0x2b7,
161238fd1498Szrj   0x2b8, 0x2b9, 0x2ba, 0x2bb, 0x2bc, 0x2bd, 0x2be, 0x2bf,
161338fd1498Szrj   0x2c0, 0x2c1, 0x2c2, 0x2c3, 0x2c4, 0x2c5, 0x2c6, 0x2c7,
161438fd1498Szrj   0x2c8, 0x2c9, 0x2ca, 0x2cb, 0x2cc, 0x2cd, 0x2ce, 0x2cf,
161538fd1498Szrj   0x2d0, 0x2d1, 0x2d2, 0x2d3, 0x2d4, 0x2d5, 0x2d6, 0x2d7,
161638fd1498Szrj   0x2d8, 0x2d9, 0x2da, 0x2db, 0x2dc, 0x2dd, 0x2de, 0x2df,
161738fd1498Szrj   0x2e0, 0x2e1, 0x2e2, 0x2e3, 0x2e4, 0x2e5, 0x2e6, 0x2e7,
161838fd1498Szrj   0x2e8, 0x2e9, 0x2ea, 0x2eb, 0x2ec, 0x2ed, 0x2ee, 0x2ef,
161938fd1498Szrj   0x2f0, 0x2f1, 0x2f2, 0x2f3, 0x2f4, 0x2f5, 0x2f6, 0x2f7,
162038fd1498Szrj   0x2f8, 0x2f9, 0x2fa, 0x2fb, 0x2fc, 0x2fd, 0x2fe, 0x2ff,
162138fd1498Szrj };
162238fd1498Szrj 
162338fd1498Szrj static const uint16_t elf_zlib_default_dist_table[0x100] =
162438fd1498Szrj {
162538fd1498Szrj   0x800, 0x810, 0x808, 0x818, 0x804, 0x814, 0x80c, 0x81c,
162638fd1498Szrj   0x802, 0x812, 0x80a, 0x81a, 0x806, 0x816, 0x80e, 0x81e,
162738fd1498Szrj   0x801, 0x811, 0x809, 0x819, 0x805, 0x815, 0x80d, 0x81d,
162838fd1498Szrj   0x803, 0x813, 0x80b, 0x81b, 0x807, 0x817, 0x80f, 0x81f,
162938fd1498Szrj   0x800, 0x810, 0x808, 0x818, 0x804, 0x814, 0x80c, 0x81c,
163038fd1498Szrj   0x802, 0x812, 0x80a, 0x81a, 0x806, 0x816, 0x80e, 0x81e,
163138fd1498Szrj   0x801, 0x811, 0x809, 0x819, 0x805, 0x815, 0x80d, 0x81d,
163238fd1498Szrj   0x803, 0x813, 0x80b, 0x81b, 0x807, 0x817, 0x80f, 0x81f,
163338fd1498Szrj   0x800, 0x810, 0x808, 0x818, 0x804, 0x814, 0x80c, 0x81c,
163438fd1498Szrj   0x802, 0x812, 0x80a, 0x81a, 0x806, 0x816, 0x80e, 0x81e,
163538fd1498Szrj   0x801, 0x811, 0x809, 0x819, 0x805, 0x815, 0x80d, 0x81d,
163638fd1498Szrj   0x803, 0x813, 0x80b, 0x81b, 0x807, 0x817, 0x80f, 0x81f,
163738fd1498Szrj   0x800, 0x810, 0x808, 0x818, 0x804, 0x814, 0x80c, 0x81c,
163838fd1498Szrj   0x802, 0x812, 0x80a, 0x81a, 0x806, 0x816, 0x80e, 0x81e,
163938fd1498Szrj   0x801, 0x811, 0x809, 0x819, 0x805, 0x815, 0x80d, 0x81d,
164038fd1498Szrj   0x803, 0x813, 0x80b, 0x81b, 0x807, 0x817, 0x80f, 0x81f,
164138fd1498Szrj   0x800, 0x810, 0x808, 0x818, 0x804, 0x814, 0x80c, 0x81c,
164238fd1498Szrj   0x802, 0x812, 0x80a, 0x81a, 0x806, 0x816, 0x80e, 0x81e,
164338fd1498Szrj   0x801, 0x811, 0x809, 0x819, 0x805, 0x815, 0x80d, 0x81d,
164438fd1498Szrj   0x803, 0x813, 0x80b, 0x81b, 0x807, 0x817, 0x80f, 0x81f,
164538fd1498Szrj   0x800, 0x810, 0x808, 0x818, 0x804, 0x814, 0x80c, 0x81c,
164638fd1498Szrj   0x802, 0x812, 0x80a, 0x81a, 0x806, 0x816, 0x80e, 0x81e,
164738fd1498Szrj   0x801, 0x811, 0x809, 0x819, 0x805, 0x815, 0x80d, 0x81d,
164838fd1498Szrj   0x803, 0x813, 0x80b, 0x81b, 0x807, 0x817, 0x80f, 0x81f,
164938fd1498Szrj   0x800, 0x810, 0x808, 0x818, 0x804, 0x814, 0x80c, 0x81c,
165038fd1498Szrj   0x802, 0x812, 0x80a, 0x81a, 0x806, 0x816, 0x80e, 0x81e,
165138fd1498Szrj   0x801, 0x811, 0x809, 0x819, 0x805, 0x815, 0x80d, 0x81d,
165238fd1498Szrj   0x803, 0x813, 0x80b, 0x81b, 0x807, 0x817, 0x80f, 0x81f,
165338fd1498Szrj   0x800, 0x810, 0x808, 0x818, 0x804, 0x814, 0x80c, 0x81c,
165438fd1498Szrj   0x802, 0x812, 0x80a, 0x81a, 0x806, 0x816, 0x80e, 0x81e,
165538fd1498Szrj   0x801, 0x811, 0x809, 0x819, 0x805, 0x815, 0x80d, 0x81d,
165638fd1498Szrj   0x803, 0x813, 0x80b, 0x81b, 0x807, 0x817, 0x80f, 0x81f,
165738fd1498Szrj };
165838fd1498Szrj 
165938fd1498Szrj /* Inflate a zlib stream from PIN/SIN to POUT/SOUT.  Return 1 on
166038fd1498Szrj    success, 0 on some error parsing the stream.  */
166138fd1498Szrj 
166238fd1498Szrj static int
elf_zlib_inflate(const unsigned char * pin,size_t sin,uint16_t * zdebug_table,unsigned char * pout,size_t sout)166338fd1498Szrj elf_zlib_inflate (const unsigned char *pin, size_t sin, uint16_t *zdebug_table,
166438fd1498Szrj 		  unsigned char *pout, size_t sout)
166538fd1498Szrj {
166638fd1498Szrj   unsigned char *porigout;
166738fd1498Szrj   const unsigned char *pinend;
166838fd1498Szrj   unsigned char *poutend;
166938fd1498Szrj 
167038fd1498Szrj   /* We can apparently see multiple zlib streams concatenated
167138fd1498Szrj      together, so keep going as long as there is something to read.
167238fd1498Szrj      The last 4 bytes are the checksum.  */
167338fd1498Szrj   porigout = pout;
167438fd1498Szrj   pinend = pin + sin;
167538fd1498Szrj   poutend = pout + sout;
167638fd1498Szrj   while ((pinend - pin) > 4)
167738fd1498Szrj     {
167838fd1498Szrj       uint64_t val;
167938fd1498Szrj       unsigned int bits;
168038fd1498Szrj       int last;
168138fd1498Szrj 
168238fd1498Szrj       /* Read the two byte zlib header.  */
168338fd1498Szrj 
168438fd1498Szrj       if (unlikely ((pin[0] & 0xf) != 8)) /* 8 is zlib encoding.  */
168538fd1498Szrj 	{
168638fd1498Szrj 	  /* Unknown compression method.  */
168738fd1498Szrj 	  elf_zlib_failed ();
168838fd1498Szrj 	  return 0;
168938fd1498Szrj 	}
169038fd1498Szrj       if (unlikely ((pin[0] >> 4) > 7))
169138fd1498Szrj 	{
169238fd1498Szrj 	  /* Window size too large.  Other than this check, we don't
169338fd1498Szrj 	     care about the window size.  */
169438fd1498Szrj 	  elf_zlib_failed ();
169538fd1498Szrj 	  return 0;
169638fd1498Szrj 	}
169738fd1498Szrj       if (unlikely ((pin[1] & 0x20) != 0))
169838fd1498Szrj 	{
169938fd1498Szrj 	  /* Stream expects a predefined dictionary, but we have no
170038fd1498Szrj 	     dictionary.  */
170138fd1498Szrj 	  elf_zlib_failed ();
170238fd1498Szrj 	  return 0;
170338fd1498Szrj 	}
170438fd1498Szrj       val = (pin[0] << 8) | pin[1];
170538fd1498Szrj       if (unlikely (val % 31 != 0))
170638fd1498Szrj 	{
170738fd1498Szrj 	  /* Header check failure.  */
170838fd1498Szrj 	  elf_zlib_failed ();
170938fd1498Szrj 	  return 0;
171038fd1498Szrj 	}
171138fd1498Szrj       pin += 2;
171238fd1498Szrj 
171338fd1498Szrj       /* Align PIN to a 32-bit boundary.  */
171438fd1498Szrj 
171538fd1498Szrj       val = 0;
171638fd1498Szrj       bits = 0;
171738fd1498Szrj       while ((((uintptr_t) pin) & 3) != 0)
171838fd1498Szrj 	{
171938fd1498Szrj 	  val |= (uint64_t)*pin << bits;
172038fd1498Szrj 	  bits += 8;
172138fd1498Szrj 	  ++pin;
172238fd1498Szrj 	}
172338fd1498Szrj 
172438fd1498Szrj       /* Read blocks until one is marked last.  */
172538fd1498Szrj 
172638fd1498Szrj       last = 0;
172738fd1498Szrj 
172838fd1498Szrj       while (!last)
172938fd1498Szrj 	{
173038fd1498Szrj 	  unsigned int type;
173138fd1498Szrj 	  const uint16_t *tlit;
173238fd1498Szrj 	  const uint16_t *tdist;
173338fd1498Szrj 
173438fd1498Szrj 	  if (!elf_zlib_fetch (&pin, pinend, &val, &bits))
173538fd1498Szrj 	    return 0;
173638fd1498Szrj 
173738fd1498Szrj 	  last = val & 1;
173838fd1498Szrj 	  type = (val >> 1) & 3;
173938fd1498Szrj 	  val >>= 3;
174038fd1498Szrj 	  bits -= 3;
174138fd1498Szrj 
174238fd1498Szrj 	  if (unlikely (type == 3))
174338fd1498Szrj 	    {
174438fd1498Szrj 	      /* Invalid block type.  */
174538fd1498Szrj 	      elf_zlib_failed ();
174638fd1498Szrj 	      return 0;
174738fd1498Szrj 	    }
174838fd1498Szrj 
174938fd1498Szrj 	  if (type == 0)
175038fd1498Szrj 	    {
175138fd1498Szrj 	      uint16_t len;
175238fd1498Szrj 	      uint16_t lenc;
175338fd1498Szrj 
175438fd1498Szrj 	      /* An uncompressed block.  */
175538fd1498Szrj 
175638fd1498Szrj 	      /* If we've read ahead more than a byte, back up.  */
175738fd1498Szrj 	      while (bits > 8)
175838fd1498Szrj 		{
175938fd1498Szrj 		  --pin;
176038fd1498Szrj 		  bits -= 8;
176138fd1498Szrj 		}
176238fd1498Szrj 
176338fd1498Szrj 	      val = 0;
176438fd1498Szrj 	      bits = 0;
176538fd1498Szrj 	      if (unlikely ((pinend - pin) < 4))
176638fd1498Szrj 		{
176738fd1498Szrj 		  /* Missing length.  */
176838fd1498Szrj 		  elf_zlib_failed ();
176938fd1498Szrj 		  return 0;
177038fd1498Szrj 		}
177138fd1498Szrj 	      len = pin[0] | (pin[1] << 8);
177238fd1498Szrj 	      lenc = pin[2] | (pin[3] << 8);
177338fd1498Szrj 	      pin += 4;
177438fd1498Szrj 	      lenc = ~lenc;
177538fd1498Szrj 	      if (unlikely (len != lenc))
177638fd1498Szrj 		{
177738fd1498Szrj 		  /* Corrupt data.  */
177838fd1498Szrj 		  elf_zlib_failed ();
177938fd1498Szrj 		  return 0;
178038fd1498Szrj 		}
178138fd1498Szrj 	      if (unlikely (len > (unsigned int) (pinend - pin)
178238fd1498Szrj 			    || len > (unsigned int) (poutend - pout)))
178338fd1498Szrj 		{
178438fd1498Szrj 		  /* Not enough space in buffers.  */
178538fd1498Szrj 		  elf_zlib_failed ();
178638fd1498Szrj 		  return 0;
178738fd1498Szrj 		}
178838fd1498Szrj 	      memcpy (pout, pin, len);
178938fd1498Szrj 	      pout += len;
179038fd1498Szrj 	      pin += len;
179138fd1498Szrj 
179238fd1498Szrj 	      /* Align PIN.  */
179338fd1498Szrj 	      while ((((uintptr_t) pin) & 3) != 0)
179438fd1498Szrj 		{
179538fd1498Szrj 		  val |= (uint64_t)*pin << bits;
179638fd1498Szrj 		  bits += 8;
179738fd1498Szrj 		  ++pin;
179838fd1498Szrj 		}
179938fd1498Szrj 
180038fd1498Szrj 	      /* Go around to read the next block.  */
180138fd1498Szrj 	      continue;
180238fd1498Szrj 	    }
180338fd1498Szrj 
180438fd1498Szrj 	  if (type == 1)
180538fd1498Szrj 	    {
180638fd1498Szrj 	      tlit = elf_zlib_default_table;
180738fd1498Szrj 	      tdist = elf_zlib_default_dist_table;
180838fd1498Szrj 	    }
180938fd1498Szrj 	  else
181038fd1498Szrj 	    {
181138fd1498Szrj 	      unsigned int nlit;
181238fd1498Szrj 	      unsigned int ndist;
181338fd1498Szrj 	      unsigned int nclen;
181438fd1498Szrj 	      unsigned char codebits[19];
181538fd1498Szrj 	      unsigned char *plenbase;
181638fd1498Szrj 	      unsigned char *plen;
181738fd1498Szrj 	      unsigned char *plenend;
181838fd1498Szrj 
181938fd1498Szrj 	      /* Read a Huffman encoding table.  The various magic
182038fd1498Szrj 		 numbers here are from RFC 1951.  */
182138fd1498Szrj 
182238fd1498Szrj 	      if (!elf_zlib_fetch (&pin, pinend, &val, &bits))
182338fd1498Szrj 		return 0;
182438fd1498Szrj 
182538fd1498Szrj 	      nlit = (val & 0x1f) + 257;
182638fd1498Szrj 	      val >>= 5;
182738fd1498Szrj 	      ndist = (val & 0x1f) + 1;
182838fd1498Szrj 	      val >>= 5;
182938fd1498Szrj 	      nclen = (val & 0xf) + 4;
183038fd1498Szrj 	      val >>= 4;
183138fd1498Szrj 	      bits -= 14;
183238fd1498Szrj 	      if (unlikely (nlit > 286 || ndist > 30))
183338fd1498Szrj 		{
183438fd1498Szrj 		  /* Values out of range.  */
183538fd1498Szrj 		  elf_zlib_failed ();
183638fd1498Szrj 		  return 0;
183738fd1498Szrj 		}
183838fd1498Szrj 
183938fd1498Szrj 	      /* Read and build the table used to compress the
184038fd1498Szrj 		 literal, length, and distance codes.  */
184138fd1498Szrj 
184238fd1498Szrj 	      memset(&codebits[0], 0, 19);
184338fd1498Szrj 
184438fd1498Szrj 	      /* There are always at least 4 elements in the
184538fd1498Szrj 		 table.  */
184638fd1498Szrj 
184738fd1498Szrj 	      if (!elf_zlib_fetch (&pin, pinend, &val, &bits))
184838fd1498Szrj 		return 0;
184938fd1498Szrj 
185038fd1498Szrj 	      codebits[16] = val & 7;
185138fd1498Szrj 	      codebits[17] = (val >> 3) & 7;
185238fd1498Szrj 	      codebits[18] = (val >> 6) & 7;
185338fd1498Szrj 	      codebits[0] = (val >> 9) & 7;
185438fd1498Szrj 	      val >>= 12;
185538fd1498Szrj 	      bits -= 12;
185638fd1498Szrj 
185738fd1498Szrj 	      if (nclen == 4)
185838fd1498Szrj 		goto codebitsdone;
185938fd1498Szrj 
186038fd1498Szrj 	      codebits[8] = val & 7;
186138fd1498Szrj 	      val >>= 3;
186238fd1498Szrj 	      bits -= 3;
186338fd1498Szrj 
186438fd1498Szrj 	      if (nclen == 5)
186538fd1498Szrj 		goto codebitsdone;
186638fd1498Szrj 
186738fd1498Szrj 	      if (!elf_zlib_fetch (&pin, pinend, &val, &bits))
186838fd1498Szrj 		return 0;
186938fd1498Szrj 
187038fd1498Szrj 	      codebits[7] = val & 7;
187138fd1498Szrj 	      val >>= 3;
187238fd1498Szrj 	      bits -= 3;
187338fd1498Szrj 
187438fd1498Szrj 	      if (nclen == 6)
187538fd1498Szrj 		goto codebitsdone;
187638fd1498Szrj 
187738fd1498Szrj 	      codebits[9] = val & 7;
187838fd1498Szrj 	      val >>= 3;
187938fd1498Szrj 	      bits -= 3;
188038fd1498Szrj 
188138fd1498Szrj 	      if (nclen == 7)
188238fd1498Szrj 		goto codebitsdone;
188338fd1498Szrj 
188438fd1498Szrj 	      codebits[6] = val & 7;
188538fd1498Szrj 	      val >>= 3;
188638fd1498Szrj 	      bits -= 3;
188738fd1498Szrj 
188838fd1498Szrj 	      if (nclen == 8)
188938fd1498Szrj 		goto codebitsdone;
189038fd1498Szrj 
189138fd1498Szrj 	      codebits[10] = val & 7;
189238fd1498Szrj 	      val >>= 3;
189338fd1498Szrj 	      bits -= 3;
189438fd1498Szrj 
189538fd1498Szrj 	      if (nclen == 9)
189638fd1498Szrj 		goto codebitsdone;
189738fd1498Szrj 
189838fd1498Szrj 	      codebits[5] = val & 7;
189938fd1498Szrj 	      val >>= 3;
190038fd1498Szrj 	      bits -= 3;
190138fd1498Szrj 
190238fd1498Szrj 	      if (nclen == 10)
190338fd1498Szrj 		goto codebitsdone;
190438fd1498Szrj 
190538fd1498Szrj 	      if (!elf_zlib_fetch (&pin, pinend, &val, &bits))
190638fd1498Szrj 		return 0;
190738fd1498Szrj 
190838fd1498Szrj 	      codebits[11] = val & 7;
190938fd1498Szrj 	      val >>= 3;
191038fd1498Szrj 	      bits -= 3;
191138fd1498Szrj 
191238fd1498Szrj 	      if (nclen == 11)
191338fd1498Szrj 		goto codebitsdone;
191438fd1498Szrj 
191538fd1498Szrj 	      codebits[4] = val & 7;
191638fd1498Szrj 	      val >>= 3;
191738fd1498Szrj 	      bits -= 3;
191838fd1498Szrj 
191938fd1498Szrj 	      if (nclen == 12)
192038fd1498Szrj 		goto codebitsdone;
192138fd1498Szrj 
192238fd1498Szrj 	      codebits[12] = val & 7;
192338fd1498Szrj 	      val >>= 3;
192438fd1498Szrj 	      bits -= 3;
192538fd1498Szrj 
192638fd1498Szrj 	      if (nclen == 13)
192738fd1498Szrj 		goto codebitsdone;
192838fd1498Szrj 
192938fd1498Szrj 	      codebits[3] = val & 7;
193038fd1498Szrj 	      val >>= 3;
193138fd1498Szrj 	      bits -= 3;
193238fd1498Szrj 
193338fd1498Szrj 	      if (nclen == 14)
193438fd1498Szrj 		goto codebitsdone;
193538fd1498Szrj 
193638fd1498Szrj 	      codebits[13] = val & 7;
193738fd1498Szrj 	      val >>= 3;
193838fd1498Szrj 	      bits -= 3;
193938fd1498Szrj 
194038fd1498Szrj 	      if (nclen == 15)
194138fd1498Szrj 		goto codebitsdone;
194238fd1498Szrj 
194338fd1498Szrj 	      if (!elf_zlib_fetch (&pin, pinend, &val, &bits))
194438fd1498Szrj 		return 0;
194538fd1498Szrj 
194638fd1498Szrj 	      codebits[2] = val & 7;
194738fd1498Szrj 	      val >>= 3;
194838fd1498Szrj 	      bits -= 3;
194938fd1498Szrj 
195038fd1498Szrj 	      if (nclen == 16)
195138fd1498Szrj 		goto codebitsdone;
195238fd1498Szrj 
195338fd1498Szrj 	      codebits[14] = val & 7;
195438fd1498Szrj 	      val >>= 3;
195538fd1498Szrj 	      bits -= 3;
195638fd1498Szrj 
195738fd1498Szrj 	      if (nclen == 17)
195838fd1498Szrj 		goto codebitsdone;
195938fd1498Szrj 
196038fd1498Szrj 	      codebits[1] = val & 7;
196138fd1498Szrj 	      val >>= 3;
196238fd1498Szrj 	      bits -= 3;
196338fd1498Szrj 
196438fd1498Szrj 	      if (nclen == 18)
196538fd1498Szrj 		goto codebitsdone;
196638fd1498Szrj 
196738fd1498Szrj 	      codebits[15] = val & 7;
196838fd1498Szrj 	      val >>= 3;
196938fd1498Szrj 	      bits -= 3;
197038fd1498Szrj 
197138fd1498Szrj 	    codebitsdone:
197238fd1498Szrj 
197338fd1498Szrj 	      if (!elf_zlib_inflate_table (codebits, 19, zdebug_table,
197438fd1498Szrj 					   zdebug_table))
197538fd1498Szrj 		return 0;
197638fd1498Szrj 
197738fd1498Szrj 	      /* Read the compressed bit lengths of the literal,
197838fd1498Szrj 		 length, and distance codes.  We have allocated space
197938fd1498Szrj 		 at the end of zdebug_table to hold them.  */
198038fd1498Szrj 
198138fd1498Szrj 	      plenbase = (((unsigned char *) zdebug_table)
198238fd1498Szrj 			  + ZDEBUG_TABLE_CODELEN_OFFSET);
198338fd1498Szrj 	      plen = plenbase;
198438fd1498Szrj 	      plenend = plen + nlit + ndist;
198538fd1498Szrj 	      while (plen < plenend)
198638fd1498Szrj 		{
198738fd1498Szrj 		  uint16_t t;
198838fd1498Szrj 		  unsigned int b;
198938fd1498Szrj 		  uint16_t v;
199038fd1498Szrj 
199138fd1498Szrj 		  if (!elf_zlib_fetch (&pin, pinend, &val, &bits))
199238fd1498Szrj 		    return 0;
199338fd1498Szrj 
199438fd1498Szrj 		  t = zdebug_table[val & 0xff];
199538fd1498Szrj 
199638fd1498Szrj 		  /* The compression here uses bit lengths up to 7, so
199738fd1498Szrj 		     a secondary table is never necessary.  */
199838fd1498Szrj 		  if (unlikely ((t & (1U << HUFFMAN_SECONDARY_SHIFT)) != 0))
199938fd1498Szrj 		    {
200038fd1498Szrj 		      elf_zlib_failed ();
200138fd1498Szrj 		      return 0;
200238fd1498Szrj 		    }
200338fd1498Szrj 
200438fd1498Szrj 		  b = (t >> HUFFMAN_BITS_SHIFT) & HUFFMAN_BITS_MASK;
200538fd1498Szrj 		  val >>= b + 1;
200638fd1498Szrj 		  bits -= b + 1;
200738fd1498Szrj 
200838fd1498Szrj 		  v = t & HUFFMAN_VALUE_MASK;
200938fd1498Szrj 		  if (v < 16)
201038fd1498Szrj 		    *plen++ = v;
201138fd1498Szrj 		  else if (v == 16)
201238fd1498Szrj 		    {
201338fd1498Szrj 		      unsigned int c;
201438fd1498Szrj 		      unsigned int prev;
201538fd1498Szrj 
201638fd1498Szrj 		      /* Copy previous entry 3 to 6 times.  */
201738fd1498Szrj 
201838fd1498Szrj 		      if (unlikely (plen == plenbase))
201938fd1498Szrj 			{
202038fd1498Szrj 			  elf_zlib_failed ();
202138fd1498Szrj 			  return 0;
202238fd1498Szrj 			}
202338fd1498Szrj 
202438fd1498Szrj 		      /* We used up to 7 bits since the last
202538fd1498Szrj 			 elf_zlib_fetch, so we have at least 8 bits
202638fd1498Szrj 			 available here.  */
202738fd1498Szrj 
202838fd1498Szrj 		      c = 3 + (val & 0x3);
202938fd1498Szrj 		      val >>= 2;
203038fd1498Szrj 		      bits -= 2;
203138fd1498Szrj 		      if (unlikely ((unsigned int) (plenend - plen) < c))
203238fd1498Szrj 			{
203338fd1498Szrj 			  elf_zlib_failed ();
203438fd1498Szrj 			  return 0;
203538fd1498Szrj 			}
203638fd1498Szrj 
203738fd1498Szrj 		      prev = plen[-1];
203838fd1498Szrj 		      switch (c)
203938fd1498Szrj 			{
204038fd1498Szrj 			case 6:
204138fd1498Szrj 			  *plen++ = prev;
204238fd1498Szrj 			  /* fallthrough */
204338fd1498Szrj 			case 5:
204438fd1498Szrj 			  *plen++ = prev;
204538fd1498Szrj 			  /* fallthrough */
204638fd1498Szrj 			case 4:
204738fd1498Szrj 			  *plen++ = prev;
204838fd1498Szrj 			}
204938fd1498Szrj 		      *plen++ = prev;
205038fd1498Szrj 		      *plen++ = prev;
205138fd1498Szrj 		      *plen++ = prev;
205238fd1498Szrj 		    }
205338fd1498Szrj 		  else if (v == 17)
205438fd1498Szrj 		    {
205538fd1498Szrj 		      unsigned int c;
205638fd1498Szrj 
205738fd1498Szrj 		      /* Store zero 3 to 10 times.  */
205838fd1498Szrj 
205938fd1498Szrj 		      /* We used up to 7 bits since the last
206038fd1498Szrj 			 elf_zlib_fetch, so we have at least 8 bits
206138fd1498Szrj 			 available here.  */
206238fd1498Szrj 
206338fd1498Szrj 		      c = 3 + (val & 0x7);
206438fd1498Szrj 		      val >>= 3;
206538fd1498Szrj 		      bits -= 3;
206638fd1498Szrj 		      if (unlikely ((unsigned int) (plenend - plen) < c))
206738fd1498Szrj 			{
206838fd1498Szrj 			  elf_zlib_failed ();
206938fd1498Szrj 			  return 0;
207038fd1498Szrj 			}
207138fd1498Szrj 
207238fd1498Szrj 		      switch (c)
207338fd1498Szrj 			{
207438fd1498Szrj 			case 10:
207538fd1498Szrj 			  *plen++ = 0;
207638fd1498Szrj 			  /* fallthrough */
207738fd1498Szrj 			case 9:
207838fd1498Szrj 			  *plen++ = 0;
207938fd1498Szrj 			  /* fallthrough */
208038fd1498Szrj 			case 8:
208138fd1498Szrj 			  *plen++ = 0;
208238fd1498Szrj 			  /* fallthrough */
208338fd1498Szrj 			case 7:
208438fd1498Szrj 			  *plen++ = 0;
208538fd1498Szrj 			  /* fallthrough */
208638fd1498Szrj 			case 6:
208738fd1498Szrj 			  *plen++ = 0;
208838fd1498Szrj 			  /* fallthrough */
208938fd1498Szrj 			case 5:
209038fd1498Szrj 			  *plen++ = 0;
209138fd1498Szrj 			  /* fallthrough */
209238fd1498Szrj 			case 4:
209338fd1498Szrj 			  *plen++ = 0;
209438fd1498Szrj 			}
209538fd1498Szrj 		      *plen++ = 0;
209638fd1498Szrj 		      *plen++ = 0;
209738fd1498Szrj 		      *plen++ = 0;
209838fd1498Szrj 		    }
209938fd1498Szrj 		  else if (v == 18)
210038fd1498Szrj 		    {
210138fd1498Szrj 		      unsigned int c;
210238fd1498Szrj 
210338fd1498Szrj 		      /* Store zero 11 to 138 times.  */
210438fd1498Szrj 
210538fd1498Szrj 		      /* We used up to 7 bits since the last
210638fd1498Szrj 			 elf_zlib_fetch, so we have at least 8 bits
210738fd1498Szrj 			 available here.  */
210838fd1498Szrj 
210938fd1498Szrj 		      c = 11 + (val & 0x7f);
211038fd1498Szrj 		      val >>= 7;
211138fd1498Szrj 		      bits -= 7;
211238fd1498Szrj 		      if (unlikely ((unsigned int) (plenend - plen) < c))
211338fd1498Szrj 			{
211438fd1498Szrj 			  elf_zlib_failed ();
211538fd1498Szrj 			  return 0;
211638fd1498Szrj 			}
211738fd1498Szrj 
211838fd1498Szrj 		      memset (plen, 0, c);
211938fd1498Szrj 		      plen += c;
212038fd1498Szrj 		    }
212138fd1498Szrj 		  else
212238fd1498Szrj 		    {
212338fd1498Szrj 		      elf_zlib_failed ();
212438fd1498Szrj 		      return 0;
212538fd1498Szrj 		    }
212638fd1498Szrj 		}
212738fd1498Szrj 
212838fd1498Szrj 	      /* Make sure that the stop code can appear.  */
212938fd1498Szrj 
213038fd1498Szrj 	      plen = plenbase;
213138fd1498Szrj 	      if (unlikely (plen[256] == 0))
213238fd1498Szrj 		{
213338fd1498Szrj 		  elf_zlib_failed ();
213438fd1498Szrj 		  return 0;
213538fd1498Szrj 		}
213638fd1498Szrj 
213738fd1498Szrj 	      /* Build the decompression tables.  */
213838fd1498Szrj 
213938fd1498Szrj 	      if (!elf_zlib_inflate_table (plen, nlit, zdebug_table,
214038fd1498Szrj 					   zdebug_table))
214138fd1498Szrj 		return 0;
214238fd1498Szrj 	      if (!elf_zlib_inflate_table (plen + nlit, ndist, zdebug_table,
214338fd1498Szrj 					   zdebug_table + HUFFMAN_TABLE_SIZE))
214438fd1498Szrj 		return 0;
214538fd1498Szrj 	      tlit = zdebug_table;
214638fd1498Szrj 	      tdist = zdebug_table + HUFFMAN_TABLE_SIZE;
214738fd1498Szrj 	    }
214838fd1498Szrj 
214938fd1498Szrj 	  /* Inflate values until the end of the block.  This is the
215038fd1498Szrj 	     main loop of the inflation code.  */
215138fd1498Szrj 
215238fd1498Szrj 	  while (1)
215338fd1498Szrj 	    {
215438fd1498Szrj 	      uint16_t t;
215538fd1498Szrj 	      unsigned int b;
215638fd1498Szrj 	      uint16_t v;
215738fd1498Szrj 	      unsigned int lit;
215838fd1498Szrj 
215938fd1498Szrj 	      if (!elf_zlib_fetch (&pin, pinend, &val, &bits))
216038fd1498Szrj 		return 0;
216138fd1498Szrj 
216238fd1498Szrj 	      t = tlit[val & 0xff];
216338fd1498Szrj 	      b = (t >> HUFFMAN_BITS_SHIFT) & HUFFMAN_BITS_MASK;
216438fd1498Szrj 	      v = t & HUFFMAN_VALUE_MASK;
216538fd1498Szrj 
216638fd1498Szrj 	      if ((t & (1U << HUFFMAN_SECONDARY_SHIFT)) == 0)
216738fd1498Szrj 		{
216838fd1498Szrj 		  lit = v;
216938fd1498Szrj 		  val >>= b + 1;
217038fd1498Szrj 		  bits -= b + 1;
217138fd1498Szrj 		}
217238fd1498Szrj 	      else
217338fd1498Szrj 		{
217438fd1498Szrj 		  t = tlit[v + 0x100 + ((val >> 8) & ((1U << b) - 1))];
217538fd1498Szrj 		  b = (t >> HUFFMAN_BITS_SHIFT) & HUFFMAN_BITS_MASK;
217638fd1498Szrj 		  lit = t & HUFFMAN_VALUE_MASK;
217738fd1498Szrj 		  val >>= b + 8;
217838fd1498Szrj 		  bits -= b + 8;
217938fd1498Szrj 		}
218038fd1498Szrj 
218138fd1498Szrj 	      if (lit < 256)
218238fd1498Szrj 		{
218338fd1498Szrj 		  if (unlikely (pout == poutend))
218438fd1498Szrj 		    {
218538fd1498Szrj 		      elf_zlib_failed ();
218638fd1498Szrj 		      return 0;
218738fd1498Szrj 		    }
218838fd1498Szrj 
218938fd1498Szrj 		  *pout++ = lit;
219038fd1498Szrj 
219138fd1498Szrj 		  /* We will need to write the next byte soon.  We ask
219238fd1498Szrj 		     for high temporal locality because we will write
219338fd1498Szrj 		     to the whole cache line soon.  */
219438fd1498Szrj 		  __builtin_prefetch (pout, 1, 3);
219538fd1498Szrj 		}
219638fd1498Szrj 	      else if (lit == 256)
219738fd1498Szrj 		{
219838fd1498Szrj 		  /* The end of the block.  */
219938fd1498Szrj 		  break;
220038fd1498Szrj 		}
220138fd1498Szrj 	      else
220238fd1498Szrj 		{
220338fd1498Szrj 		  unsigned int dist;
220438fd1498Szrj 		  unsigned int len;
220538fd1498Szrj 
220638fd1498Szrj 		  /* Convert lit into a length.  */
220738fd1498Szrj 
220838fd1498Szrj 		  if (lit < 265)
220938fd1498Szrj 		    len = lit - 257 + 3;
221038fd1498Szrj 		  else if (lit == 285)
221138fd1498Szrj 		    len = 258;
221238fd1498Szrj 		  else if (unlikely (lit > 285))
221338fd1498Szrj 		    {
221438fd1498Szrj 		      elf_zlib_failed ();
221538fd1498Szrj 		      return 0;
221638fd1498Szrj 		    }
221738fd1498Szrj 		  else
221838fd1498Szrj 		    {
221938fd1498Szrj 		      unsigned int extra;
222038fd1498Szrj 
222138fd1498Szrj 		      if (!elf_zlib_fetch (&pin, pinend, &val, &bits))
222238fd1498Szrj 			return 0;
222338fd1498Szrj 
222438fd1498Szrj 		      /* This is an expression for the table of length
222538fd1498Szrj 			 codes in RFC 1951 3.2.5.  */
222638fd1498Szrj 		      lit -= 265;
222738fd1498Szrj 		      extra = (lit >> 2) + 1;
222838fd1498Szrj 		      len = (lit & 3) << extra;
222938fd1498Szrj 		      len += 11;
223038fd1498Szrj 		      len += ((1U << (extra - 1)) - 1) << 3;
223138fd1498Szrj 		      len += val & ((1U << extra) - 1);
223238fd1498Szrj 		      val >>= extra;
223338fd1498Szrj 		      bits -= extra;
223438fd1498Szrj 		    }
223538fd1498Szrj 
223638fd1498Szrj 		  if (!elf_zlib_fetch (&pin, pinend, &val, &bits))
223738fd1498Szrj 		    return 0;
223838fd1498Szrj 
223938fd1498Szrj 		  t = tdist[val & 0xff];
224038fd1498Szrj 		  b = (t >> HUFFMAN_BITS_SHIFT) & HUFFMAN_BITS_MASK;
224138fd1498Szrj 		  v = t & HUFFMAN_VALUE_MASK;
224238fd1498Szrj 
224338fd1498Szrj 		  if ((t & (1U << HUFFMAN_SECONDARY_SHIFT)) == 0)
224438fd1498Szrj 		    {
224538fd1498Szrj 		      dist = v;
224638fd1498Szrj 		      val >>= b + 1;
224738fd1498Szrj 		      bits -= b + 1;
224838fd1498Szrj 		    }
224938fd1498Szrj 		  else
225038fd1498Szrj 		    {
225138fd1498Szrj 		      t = tdist[v + 0x100 + ((val >> 8) & ((1U << b) - 1))];
225238fd1498Szrj 		      b = (t >> HUFFMAN_BITS_SHIFT) & HUFFMAN_BITS_MASK;
225338fd1498Szrj 		      dist = t & HUFFMAN_VALUE_MASK;
225438fd1498Szrj 		      val >>= b + 8;
225538fd1498Szrj 		      bits -= b + 8;
225638fd1498Szrj 		    }
225738fd1498Szrj 
225838fd1498Szrj 		  /* Convert dist to a distance.  */
225938fd1498Szrj 
226038fd1498Szrj 		  if (dist == 0)
226138fd1498Szrj 		    {
226238fd1498Szrj 		      /* A distance of 1.  A common case, meaning
226338fd1498Szrj 			 repeat the last character LEN times.  */
226438fd1498Szrj 
226538fd1498Szrj 		      if (unlikely (pout == porigout))
226638fd1498Szrj 			{
226738fd1498Szrj 			  elf_zlib_failed ();
226838fd1498Szrj 			  return 0;
226938fd1498Szrj 			}
227038fd1498Szrj 
227138fd1498Szrj 		      if (unlikely ((unsigned int) (poutend - pout) < len))
227238fd1498Szrj 			{
227338fd1498Szrj 			  elf_zlib_failed ();
227438fd1498Szrj 			  return 0;
227538fd1498Szrj 			}
227638fd1498Szrj 
227738fd1498Szrj 		      memset (pout, pout[-1], len);
227838fd1498Szrj 		      pout += len;
227938fd1498Szrj 		    }
228038fd1498Szrj 		  else if (unlikely (dist > 29))
228138fd1498Szrj 		    {
228238fd1498Szrj 		      elf_zlib_failed ();
228338fd1498Szrj 		      return 0;
228438fd1498Szrj 		    }
228538fd1498Szrj 		  else
228638fd1498Szrj 		    {
228738fd1498Szrj 		      if (dist < 4)
228838fd1498Szrj 			dist = dist + 1;
228938fd1498Szrj 		      else
229038fd1498Szrj 			{
229138fd1498Szrj 			  unsigned int extra;
229238fd1498Szrj 
229338fd1498Szrj 			  if (!elf_zlib_fetch (&pin, pinend, &val, &bits))
229438fd1498Szrj 			    return 0;
229538fd1498Szrj 
229638fd1498Szrj 			  /* This is an expression for the table of
229738fd1498Szrj 			     distance codes in RFC 1951 3.2.5.  */
229838fd1498Szrj 			  dist -= 4;
229938fd1498Szrj 			  extra = (dist >> 1) + 1;
230038fd1498Szrj 			  dist = (dist & 1) << extra;
230138fd1498Szrj 			  dist += 5;
230238fd1498Szrj 			  dist += ((1U << (extra - 1)) - 1) << 2;
230338fd1498Szrj 			  dist += val & ((1U << extra) - 1);
230438fd1498Szrj 			  val >>= extra;
230538fd1498Szrj 			  bits -= extra;
230638fd1498Szrj 			}
230738fd1498Szrj 
230838fd1498Szrj 		      /* Go back dist bytes, and copy len bytes from
230938fd1498Szrj 			 there.  */
231038fd1498Szrj 
231138fd1498Szrj 		      if (unlikely ((unsigned int) (pout - porigout) < dist))
231238fd1498Szrj 			{
231338fd1498Szrj 			  elf_zlib_failed ();
231438fd1498Szrj 			  return 0;
231538fd1498Szrj 			}
231638fd1498Szrj 
231738fd1498Szrj 		      if (unlikely ((unsigned int) (poutend - pout) < len))
231838fd1498Szrj 			{
231938fd1498Szrj 			  elf_zlib_failed ();
232038fd1498Szrj 			  return 0;
232138fd1498Szrj 			}
232238fd1498Szrj 
232338fd1498Szrj 		      if (dist >= len)
232438fd1498Szrj 			{
232538fd1498Szrj 			  memcpy (pout, pout - dist, len);
232638fd1498Szrj 			  pout += len;
232738fd1498Szrj 			}
232838fd1498Szrj 		      else
232938fd1498Szrj 			{
233038fd1498Szrj 			  while (len > 0)
233138fd1498Szrj 			    {
233238fd1498Szrj 			      unsigned int copy;
233338fd1498Szrj 
233438fd1498Szrj 			      copy = len < dist ? len : dist;
233538fd1498Szrj 			      memcpy (pout, pout - dist, copy);
233638fd1498Szrj 			      len -= copy;
233738fd1498Szrj 			      pout += copy;
233838fd1498Szrj 			    }
233938fd1498Szrj 			}
234038fd1498Szrj 		    }
234138fd1498Szrj 		}
234238fd1498Szrj 	    }
234338fd1498Szrj 	}
234438fd1498Szrj     }
234538fd1498Szrj 
234638fd1498Szrj   /* We should have filled the output buffer.  */
234738fd1498Szrj   if (unlikely (pout != poutend))
234838fd1498Szrj     {
234938fd1498Szrj       elf_zlib_failed ();
235038fd1498Szrj       return 0;
235138fd1498Szrj     }
235238fd1498Szrj 
235338fd1498Szrj   return 1;
235438fd1498Szrj }
235538fd1498Szrj 
235638fd1498Szrj /* Verify the zlib checksum.  The checksum is in the 4 bytes at
235738fd1498Szrj    CHECKBYTES, and the uncompressed data is at UNCOMPRESSED /
235838fd1498Szrj    UNCOMPRESSED_SIZE.  Returns 1 on success, 0 on failure.  */
235938fd1498Szrj 
236038fd1498Szrj static int
elf_zlib_verify_checksum(const unsigned char * checkbytes,const unsigned char * uncompressed,size_t uncompressed_size)236138fd1498Szrj elf_zlib_verify_checksum (const unsigned char *checkbytes,
236238fd1498Szrj 			  const unsigned char *uncompressed,
236338fd1498Szrj 			  size_t uncompressed_size)
236438fd1498Szrj {
236538fd1498Szrj   unsigned int i;
236638fd1498Szrj   unsigned int cksum;
236738fd1498Szrj   const unsigned char *p;
236838fd1498Szrj   uint32_t s1;
236938fd1498Szrj   uint32_t s2;
237038fd1498Szrj   size_t hsz;
237138fd1498Szrj 
237238fd1498Szrj   cksum = 0;
237338fd1498Szrj   for (i = 0; i < 4; i++)
237438fd1498Szrj     cksum = (cksum << 8) | checkbytes[i];
237538fd1498Szrj 
237638fd1498Szrj   s1 = 1;
237738fd1498Szrj   s2 = 0;
237838fd1498Szrj 
237938fd1498Szrj   /* Minimize modulo operations.  */
238038fd1498Szrj 
238138fd1498Szrj   p = uncompressed;
238238fd1498Szrj   hsz = uncompressed_size;
238338fd1498Szrj   while (hsz >= 5552)
238438fd1498Szrj     {
238538fd1498Szrj       for (i = 0; i < 5552; i += 16)
238638fd1498Szrj 	{
238738fd1498Szrj 	  /* Manually unroll loop 16 times.  */
238838fd1498Szrj 	  s1 = s1 + *p++;
238938fd1498Szrj 	  s2 = s2 + s1;
239038fd1498Szrj 	  s1 = s1 + *p++;
239138fd1498Szrj 	  s2 = s2 + s1;
239238fd1498Szrj 	  s1 = s1 + *p++;
239338fd1498Szrj 	  s2 = s2 + s1;
239438fd1498Szrj 	  s1 = s1 + *p++;
239538fd1498Szrj 	  s2 = s2 + s1;
239638fd1498Szrj 	  s1 = s1 + *p++;
239738fd1498Szrj 	  s2 = s2 + s1;
239838fd1498Szrj 	  s1 = s1 + *p++;
239938fd1498Szrj 	  s2 = s2 + s1;
240038fd1498Szrj 	  s1 = s1 + *p++;
240138fd1498Szrj 	  s2 = s2 + s1;
240238fd1498Szrj 	  s1 = s1 + *p++;
240338fd1498Szrj 	  s2 = s2 + s1;
240438fd1498Szrj 	  s1 = s1 + *p++;
240538fd1498Szrj 	  s2 = s2 + s1;
240638fd1498Szrj 	  s1 = s1 + *p++;
240738fd1498Szrj 	  s2 = s2 + s1;
240838fd1498Szrj 	  s1 = s1 + *p++;
240938fd1498Szrj 	  s2 = s2 + s1;
241038fd1498Szrj 	  s1 = s1 + *p++;
241138fd1498Szrj 	  s2 = s2 + s1;
241238fd1498Szrj 	  s1 = s1 + *p++;
241338fd1498Szrj 	  s2 = s2 + s1;
241438fd1498Szrj 	  s1 = s1 + *p++;
241538fd1498Szrj 	  s2 = s2 + s1;
241638fd1498Szrj 	  s1 = s1 + *p++;
241738fd1498Szrj 	  s2 = s2 + s1;
241838fd1498Szrj 	  s1 = s1 + *p++;
241938fd1498Szrj 	  s2 = s2 + s1;
242038fd1498Szrj 	}
242138fd1498Szrj       hsz -= 5552;
242238fd1498Szrj       s1 %= 65521;
242338fd1498Szrj       s2 %= 65521;
242438fd1498Szrj     }
242538fd1498Szrj 
242638fd1498Szrj   while (hsz >= 16)
242738fd1498Szrj     {
242838fd1498Szrj       /* Manually unroll loop 16 times.  */
242938fd1498Szrj       s1 = s1 + *p++;
243038fd1498Szrj       s2 = s2 + s1;
243138fd1498Szrj       s1 = s1 + *p++;
243238fd1498Szrj       s2 = s2 + s1;
243338fd1498Szrj       s1 = s1 + *p++;
243438fd1498Szrj       s2 = s2 + s1;
243538fd1498Szrj       s1 = s1 + *p++;
243638fd1498Szrj       s2 = s2 + s1;
243738fd1498Szrj       s1 = s1 + *p++;
243838fd1498Szrj       s2 = s2 + s1;
243938fd1498Szrj       s1 = s1 + *p++;
244038fd1498Szrj       s2 = s2 + s1;
244138fd1498Szrj       s1 = s1 + *p++;
244238fd1498Szrj       s2 = s2 + s1;
244338fd1498Szrj       s1 = s1 + *p++;
244438fd1498Szrj       s2 = s2 + s1;
244538fd1498Szrj       s1 = s1 + *p++;
244638fd1498Szrj       s2 = s2 + s1;
244738fd1498Szrj       s1 = s1 + *p++;
244838fd1498Szrj       s2 = s2 + s1;
244938fd1498Szrj       s1 = s1 + *p++;
245038fd1498Szrj       s2 = s2 + s1;
245138fd1498Szrj       s1 = s1 + *p++;
245238fd1498Szrj       s2 = s2 + s1;
245338fd1498Szrj       s1 = s1 + *p++;
245438fd1498Szrj       s2 = s2 + s1;
245538fd1498Szrj       s1 = s1 + *p++;
245638fd1498Szrj       s2 = s2 + s1;
245738fd1498Szrj       s1 = s1 + *p++;
245838fd1498Szrj       s2 = s2 + s1;
245938fd1498Szrj       s1 = s1 + *p++;
246038fd1498Szrj       s2 = s2 + s1;
246138fd1498Szrj 
246238fd1498Szrj       hsz -= 16;
246338fd1498Szrj     }
246438fd1498Szrj 
246538fd1498Szrj   for (i = 0; i < hsz; ++i)
246638fd1498Szrj     {
246738fd1498Szrj       s1 = s1 + *p++;
246838fd1498Szrj       s2 = s2 + s1;
246938fd1498Szrj     }
247038fd1498Szrj 
247138fd1498Szrj   s1 %= 65521;
247238fd1498Szrj   s2 %= 65521;
247338fd1498Szrj 
247438fd1498Szrj   if (unlikely ((s2 << 16) + s1 != cksum))
247538fd1498Szrj     {
247638fd1498Szrj       elf_zlib_failed ();
247738fd1498Szrj       return 0;
247838fd1498Szrj     }
247938fd1498Szrj 
248038fd1498Szrj   return 1;
248138fd1498Szrj }
248238fd1498Szrj 
248338fd1498Szrj /* Inflate a zlib stream from PIN/SIN to POUT/SOUT, and verify the
248438fd1498Szrj    checksum.  Return 1 on success, 0 on error.  */
248538fd1498Szrj 
248638fd1498Szrj static int
elf_zlib_inflate_and_verify(const unsigned char * pin,size_t sin,uint16_t * zdebug_table,unsigned char * pout,size_t sout)248738fd1498Szrj elf_zlib_inflate_and_verify (const unsigned char *pin, size_t sin,
248838fd1498Szrj 			     uint16_t *zdebug_table, unsigned char *pout,
248938fd1498Szrj 			     size_t sout)
249038fd1498Szrj {
249138fd1498Szrj   if (!elf_zlib_inflate (pin, sin, zdebug_table, pout, sout))
249238fd1498Szrj     return 0;
249338fd1498Szrj   if (!elf_zlib_verify_checksum (pin + sin - 4, pout, sout))
249438fd1498Szrj     return 0;
249538fd1498Szrj   return 1;
249638fd1498Szrj }
249738fd1498Szrj 
249838fd1498Szrj /* Uncompress the old compressed debug format, the one emitted by
249938fd1498Szrj    --compress-debug-sections=zlib-gnu.  The compressed data is in
250038fd1498Szrj    COMPRESSED / COMPRESSED_SIZE, and the function writes to
250138fd1498Szrj    *UNCOMPRESSED / *UNCOMPRESSED_SIZE.  ZDEBUG_TABLE is work space to
250238fd1498Szrj    hold Huffman tables.  Returns 0 on error, 1 on successful
250338fd1498Szrj    decompression or if something goes wrong.  In general we try to
250438fd1498Szrj    carry on, by returning 1, even if we can't decompress.  */
250538fd1498Szrj 
250638fd1498Szrj static int
elf_uncompress_zdebug(struct backtrace_state * state,const unsigned char * compressed,size_t compressed_size,uint16_t * zdebug_table,backtrace_error_callback error_callback,void * data,unsigned char ** uncompressed,size_t * uncompressed_size)250738fd1498Szrj elf_uncompress_zdebug (struct backtrace_state *state,
250838fd1498Szrj 		       const unsigned char *compressed, size_t compressed_size,
250938fd1498Szrj 		       uint16_t *zdebug_table,
251038fd1498Szrj 		       backtrace_error_callback error_callback, void *data,
251138fd1498Szrj 		       unsigned char **uncompressed, size_t *uncompressed_size)
251238fd1498Szrj {
251338fd1498Szrj   size_t sz;
251438fd1498Szrj   size_t i;
251538fd1498Szrj   unsigned char *po;
251638fd1498Szrj 
251738fd1498Szrj   *uncompressed = NULL;
251838fd1498Szrj   *uncompressed_size = 0;
251938fd1498Szrj 
252038fd1498Szrj   /* The format starts with the four bytes ZLIB, followed by the 8
252138fd1498Szrj      byte length of the uncompressed data in big-endian order,
252238fd1498Szrj      followed by a zlib stream.  */
252338fd1498Szrj 
252438fd1498Szrj   if (compressed_size < 12 || memcmp (compressed, "ZLIB", 4) != 0)
252538fd1498Szrj     return 1;
252638fd1498Szrj 
252738fd1498Szrj   sz = 0;
252838fd1498Szrj   for (i = 0; i < 8; i++)
252938fd1498Szrj     sz = (sz << 8) | compressed[i + 4];
253038fd1498Szrj 
253138fd1498Szrj   if (*uncompressed != NULL && *uncompressed_size >= sz)
253238fd1498Szrj     po = *uncompressed;
253338fd1498Szrj   else
253438fd1498Szrj     {
253538fd1498Szrj       po = (unsigned char *) backtrace_alloc (state, sz, error_callback, data);
253638fd1498Szrj       if (po == NULL)
253738fd1498Szrj 	return 0;
253838fd1498Szrj     }
253938fd1498Szrj 
254038fd1498Szrj   if (!elf_zlib_inflate_and_verify (compressed + 12, compressed_size - 12,
254138fd1498Szrj 				    zdebug_table, po, sz))
254238fd1498Szrj     return 1;
254338fd1498Szrj 
254438fd1498Szrj   *uncompressed = po;
254538fd1498Szrj   *uncompressed_size = sz;
254638fd1498Szrj 
254738fd1498Szrj   return 1;
254838fd1498Szrj }
254938fd1498Szrj 
255038fd1498Szrj /* Uncompress the new compressed debug format, the official standard
255138fd1498Szrj    ELF approach emitted by --compress-debug-sections=zlib-gabi.  The
255238fd1498Szrj    compressed data is in COMPRESSED / COMPRESSED_SIZE, and the
255338fd1498Szrj    function writes to *UNCOMPRESSED / *UNCOMPRESSED_SIZE.
255438fd1498Szrj    ZDEBUG_TABLE is work space as for elf_uncompress_zdebug.  Returns 0
255538fd1498Szrj    on error, 1 on successful decompression or if something goes wrong.
255638fd1498Szrj    In general we try to carry on, by returning 1, even if we can't
255738fd1498Szrj    decompress.  */
255838fd1498Szrj 
255938fd1498Szrj static int
elf_uncompress_chdr(struct backtrace_state * state,const unsigned char * compressed,size_t compressed_size,uint16_t * zdebug_table,backtrace_error_callback error_callback,void * data,unsigned char ** uncompressed,size_t * uncompressed_size)256038fd1498Szrj elf_uncompress_chdr (struct backtrace_state *state,
256138fd1498Szrj 		     const unsigned char *compressed, size_t compressed_size,
256238fd1498Szrj 		     uint16_t *zdebug_table,
256338fd1498Szrj 		     backtrace_error_callback error_callback, void *data,
256438fd1498Szrj 		     unsigned char **uncompressed, size_t *uncompressed_size)
256538fd1498Szrj {
256638fd1498Szrj   const b_elf_chdr *chdr;
256738fd1498Szrj   unsigned char *po;
256838fd1498Szrj 
256938fd1498Szrj   *uncompressed = NULL;
257038fd1498Szrj   *uncompressed_size = 0;
257138fd1498Szrj 
257238fd1498Szrj   /* The format starts with an ELF compression header.  */
257338fd1498Szrj   if (compressed_size < sizeof (b_elf_chdr))
257438fd1498Szrj     return 1;
257538fd1498Szrj 
257638fd1498Szrj   chdr = (const b_elf_chdr *) compressed;
257738fd1498Szrj 
257838fd1498Szrj   if (chdr->ch_type != ELFCOMPRESS_ZLIB)
257938fd1498Szrj     {
258038fd1498Szrj       /* Unsupported compression algorithm.  */
258138fd1498Szrj       return 1;
258238fd1498Szrj     }
258338fd1498Szrj 
258438fd1498Szrj   if (*uncompressed != NULL && *uncompressed_size >= chdr->ch_size)
258538fd1498Szrj     po = *uncompressed;
258638fd1498Szrj   else
258738fd1498Szrj     {
258838fd1498Szrj       po = (unsigned char *) backtrace_alloc (state, chdr->ch_size,
258938fd1498Szrj 					      error_callback, data);
259038fd1498Szrj       if (po == NULL)
259138fd1498Szrj 	return 0;
259238fd1498Szrj     }
259338fd1498Szrj 
259438fd1498Szrj   if (!elf_zlib_inflate_and_verify (compressed + sizeof (b_elf_chdr),
259538fd1498Szrj 				    compressed_size - sizeof (b_elf_chdr),
259638fd1498Szrj 				    zdebug_table, po, chdr->ch_size))
259738fd1498Szrj     return 1;
259838fd1498Szrj 
259938fd1498Szrj   *uncompressed = po;
260038fd1498Szrj   *uncompressed_size = chdr->ch_size;
260138fd1498Szrj 
260238fd1498Szrj   return 1;
260338fd1498Szrj }
260438fd1498Szrj 
260538fd1498Szrj /* This function is a hook for testing the zlib support.  It is only
260638fd1498Szrj    used by tests.  */
260738fd1498Szrj 
260838fd1498Szrj int
backtrace_uncompress_zdebug(struct backtrace_state * state,const unsigned char * compressed,size_t compressed_size,backtrace_error_callback error_callback,void * data,unsigned char ** uncompressed,size_t * uncompressed_size)260938fd1498Szrj backtrace_uncompress_zdebug (struct backtrace_state *state,
261038fd1498Szrj 			     const unsigned char *compressed,
261138fd1498Szrj 			     size_t compressed_size,
261238fd1498Szrj 			     backtrace_error_callback error_callback,
261338fd1498Szrj 			     void *data, unsigned char **uncompressed,
261438fd1498Szrj 			     size_t *uncompressed_size)
261538fd1498Szrj {
261638fd1498Szrj   uint16_t *zdebug_table;
261738fd1498Szrj   int ret;
261838fd1498Szrj 
261938fd1498Szrj   zdebug_table = ((uint16_t *) backtrace_alloc (state, ZDEBUG_TABLE_SIZE,
262038fd1498Szrj 						error_callback, data));
262138fd1498Szrj   if (zdebug_table == NULL)
262238fd1498Szrj     return 0;
262338fd1498Szrj   ret = elf_uncompress_zdebug (state, compressed, compressed_size,
262438fd1498Szrj 			       zdebug_table, error_callback, data,
262538fd1498Szrj 			       uncompressed, uncompressed_size);
262638fd1498Szrj   backtrace_free (state, zdebug_table, ZDEBUG_TABLE_SIZE,
262738fd1498Szrj 		  error_callback, data);
262838fd1498Szrj   return ret;
262938fd1498Szrj }
263038fd1498Szrj 
263138fd1498Szrj /* Add the backtrace data for one ELF file.  Returns 1 on success,
263238fd1498Szrj    0 on failure (in both cases descriptor is closed) or -1 if exe
263338fd1498Szrj    is non-zero and the ELF file is ET_DYN, which tells the caller that
263438fd1498Szrj    elf_add will need to be called on the descriptor again after
263538fd1498Szrj    base_address is determined.  */
263638fd1498Szrj 
263738fd1498Szrj static int
elf_add(struct backtrace_state * state,const char * filename,int descriptor,uintptr_t base_address,backtrace_error_callback error_callback,void * data,fileline * fileline_fn,int * found_sym,int * found_dwarf,int exe,int debuginfo)263838fd1498Szrj elf_add (struct backtrace_state *state, const char *filename, int descriptor,
263938fd1498Szrj 	 uintptr_t base_address, backtrace_error_callback error_callback,
264038fd1498Szrj 	 void *data, fileline *fileline_fn, int *found_sym, int *found_dwarf,
264138fd1498Szrj 	 int exe, int debuginfo)
264238fd1498Szrj {
264338fd1498Szrj   struct backtrace_view ehdr_view;
264438fd1498Szrj   b_elf_ehdr ehdr;
264538fd1498Szrj   off_t shoff;
264638fd1498Szrj   unsigned int shnum;
264738fd1498Szrj   unsigned int shstrndx;
264838fd1498Szrj   struct backtrace_view shdrs_view;
264938fd1498Szrj   int shdrs_view_valid;
265038fd1498Szrj   const b_elf_shdr *shdrs;
265138fd1498Szrj   const b_elf_shdr *shstrhdr;
265238fd1498Szrj   size_t shstr_size;
265338fd1498Szrj   off_t shstr_off;
265438fd1498Szrj   struct backtrace_view names_view;
265538fd1498Szrj   int names_view_valid;
265638fd1498Szrj   const char *names;
265738fd1498Szrj   unsigned int symtab_shndx;
265838fd1498Szrj   unsigned int dynsym_shndx;
265938fd1498Szrj   unsigned int i;
266038fd1498Szrj   struct debug_section_info sections[DEBUG_MAX];
266138fd1498Szrj   struct backtrace_view symtab_view;
266238fd1498Szrj   int symtab_view_valid;
266338fd1498Szrj   struct backtrace_view strtab_view;
266438fd1498Szrj   int strtab_view_valid;
266538fd1498Szrj   struct backtrace_view buildid_view;
266638fd1498Szrj   int buildid_view_valid;
266738fd1498Szrj   const char *buildid_data;
266838fd1498Szrj   uint32_t buildid_size;
266938fd1498Szrj   struct backtrace_view debuglink_view;
267038fd1498Szrj   int debuglink_view_valid;
267138fd1498Szrj   const char *debuglink_name;
267238fd1498Szrj   uint32_t debuglink_crc;
267338fd1498Szrj   off_t min_offset;
267438fd1498Szrj   off_t max_offset;
267538fd1498Szrj   struct backtrace_view debug_view;
267638fd1498Szrj   int debug_view_valid;
267738fd1498Szrj   unsigned int using_debug_view;
267838fd1498Szrj   uint16_t *zdebug_table;
267938fd1498Szrj   struct elf_ppc64_opd_data opd_data, *opd;
268038fd1498Szrj 
268138fd1498Szrj   if (!debuginfo)
268238fd1498Szrj     {
268338fd1498Szrj       *found_sym = 0;
268438fd1498Szrj       *found_dwarf = 0;
268538fd1498Szrj     }
268638fd1498Szrj 
268738fd1498Szrj   shdrs_view_valid = 0;
268838fd1498Szrj   names_view_valid = 0;
268938fd1498Szrj   symtab_view_valid = 0;
269038fd1498Szrj   strtab_view_valid = 0;
269138fd1498Szrj   buildid_view_valid = 0;
269238fd1498Szrj   buildid_data = NULL;
269338fd1498Szrj   buildid_size = 0;
269438fd1498Szrj   debuglink_view_valid = 0;
269538fd1498Szrj   debuglink_name = NULL;
269638fd1498Szrj   debuglink_crc = 0;
269738fd1498Szrj   debug_view_valid = 0;
269838fd1498Szrj   opd = NULL;
269938fd1498Szrj 
270038fd1498Szrj   if (!backtrace_get_view (state, descriptor, 0, sizeof ehdr, error_callback,
270138fd1498Szrj 			   data, &ehdr_view))
270238fd1498Szrj     goto fail;
270338fd1498Szrj 
270438fd1498Szrj   memcpy (&ehdr, ehdr_view.data, sizeof ehdr);
270538fd1498Szrj 
270638fd1498Szrj   backtrace_release_view (state, &ehdr_view, error_callback, data);
270738fd1498Szrj 
270838fd1498Szrj   if (ehdr.e_ident[EI_MAG0] != ELFMAG0
270938fd1498Szrj       || ehdr.e_ident[EI_MAG1] != ELFMAG1
271038fd1498Szrj       || ehdr.e_ident[EI_MAG2] != ELFMAG2
271138fd1498Szrj       || ehdr.e_ident[EI_MAG3] != ELFMAG3)
271238fd1498Szrj     {
271338fd1498Szrj       error_callback (data, "executable file is not ELF", 0);
271438fd1498Szrj       goto fail;
271538fd1498Szrj     }
271638fd1498Szrj   if (ehdr.e_ident[EI_VERSION] != EV_CURRENT)
271738fd1498Szrj     {
271838fd1498Szrj       error_callback (data, "executable file is unrecognized ELF version", 0);
271938fd1498Szrj       goto fail;
272038fd1498Szrj     }
272138fd1498Szrj 
272238fd1498Szrj #if BACKTRACE_ELF_SIZE == 32
272338fd1498Szrj #define BACKTRACE_ELFCLASS ELFCLASS32
272438fd1498Szrj #else
272538fd1498Szrj #define BACKTRACE_ELFCLASS ELFCLASS64
272638fd1498Szrj #endif
272738fd1498Szrj 
272838fd1498Szrj   if (ehdr.e_ident[EI_CLASS] != BACKTRACE_ELFCLASS)
272938fd1498Szrj     {
273038fd1498Szrj       error_callback (data, "executable file is unexpected ELF class", 0);
273138fd1498Szrj       goto fail;
273238fd1498Szrj     }
273338fd1498Szrj 
273438fd1498Szrj   if (ehdr.e_ident[EI_DATA] != ELFDATA2LSB
273538fd1498Szrj       && ehdr.e_ident[EI_DATA] != ELFDATA2MSB)
273638fd1498Szrj     {
273738fd1498Szrj       error_callback (data, "executable file has unknown endianness", 0);
273838fd1498Szrj       goto fail;
273938fd1498Szrj     }
274038fd1498Szrj 
274138fd1498Szrj   /* If the executable is ET_DYN, it is either a PIE, or we are running
274238fd1498Szrj      directly a shared library with .interp.  We need to wait for
274338fd1498Szrj      dl_iterate_phdr in that case to determine the actual base_address.  */
274438fd1498Szrj   if (exe && ehdr.e_type == ET_DYN)
274538fd1498Szrj     return -1;
274638fd1498Szrj 
274738fd1498Szrj   shoff = ehdr.e_shoff;
274838fd1498Szrj   shnum = ehdr.e_shnum;
274938fd1498Szrj   shstrndx = ehdr.e_shstrndx;
275038fd1498Szrj 
275138fd1498Szrj   if ((shnum == 0 || shstrndx == SHN_XINDEX)
275238fd1498Szrj       && shoff != 0)
275338fd1498Szrj     {
275438fd1498Szrj       struct backtrace_view shdr_view;
275538fd1498Szrj       const b_elf_shdr *shdr;
275638fd1498Szrj 
275738fd1498Szrj       if (!backtrace_get_view (state, descriptor, shoff, sizeof shdr,
275838fd1498Szrj 			       error_callback, data, &shdr_view))
275938fd1498Szrj 	goto fail;
276038fd1498Szrj 
276138fd1498Szrj       shdr = (const b_elf_shdr *) shdr_view.data;
276238fd1498Szrj 
276338fd1498Szrj       if (shnum == 0)
276438fd1498Szrj 	shnum = shdr->sh_size;
276538fd1498Szrj 
276638fd1498Szrj       if (shstrndx == SHN_XINDEX)
276738fd1498Szrj 	{
276838fd1498Szrj 	  shstrndx = shdr->sh_link;
276938fd1498Szrj 
277038fd1498Szrj 	  /* Versions of the GNU binutils between 2.12 and 2.18 did
277138fd1498Szrj 	     not handle objects with more than SHN_LORESERVE sections
277238fd1498Szrj 	     correctly.  All large section indexes were offset by
277338fd1498Szrj 	     0x100.  There is more information at
277438fd1498Szrj 	     http://sourceware.org/bugzilla/show_bug.cgi?id-5900 .
277538fd1498Szrj 	     Fortunately these object files are easy to detect, as the
277638fd1498Szrj 	     GNU binutils always put the section header string table
277738fd1498Szrj 	     near the end of the list of sections.  Thus if the
277838fd1498Szrj 	     section header string table index is larger than the
277938fd1498Szrj 	     number of sections, then we know we have to subtract
278038fd1498Szrj 	     0x100 to get the real section index.  */
278138fd1498Szrj 	  if (shstrndx >= shnum && shstrndx >= SHN_LORESERVE + 0x100)
278238fd1498Szrj 	    shstrndx -= 0x100;
278338fd1498Szrj 	}
278438fd1498Szrj 
278538fd1498Szrj       backtrace_release_view (state, &shdr_view, error_callback, data);
278638fd1498Szrj     }
278738fd1498Szrj 
278838fd1498Szrj   /* To translate PC to file/line when using DWARF, we need to find
278938fd1498Szrj      the .debug_info and .debug_line sections.  */
279038fd1498Szrj 
279138fd1498Szrj   /* Read the section headers, skipping the first one.  */
279238fd1498Szrj 
279338fd1498Szrj   if (!backtrace_get_view (state, descriptor, shoff + sizeof (b_elf_shdr),
279438fd1498Szrj 			   (shnum - 1) * sizeof (b_elf_shdr),
279538fd1498Szrj 			   error_callback, data, &shdrs_view))
279638fd1498Szrj     goto fail;
279738fd1498Szrj   shdrs_view_valid = 1;
279838fd1498Szrj   shdrs = (const b_elf_shdr *) shdrs_view.data;
279938fd1498Szrj 
280038fd1498Szrj   /* Read the section names.  */
280138fd1498Szrj 
280238fd1498Szrj   shstrhdr = &shdrs[shstrndx - 1];
280338fd1498Szrj   shstr_size = shstrhdr->sh_size;
280438fd1498Szrj   shstr_off = shstrhdr->sh_offset;
280538fd1498Szrj 
280638fd1498Szrj   if (!backtrace_get_view (state, descriptor, shstr_off, shstr_size,
280738fd1498Szrj 			   error_callback, data, &names_view))
280838fd1498Szrj     goto fail;
280938fd1498Szrj   names_view_valid = 1;
281038fd1498Szrj   names = (const char *) names_view.data;
281138fd1498Szrj 
281238fd1498Szrj   symtab_shndx = 0;
281338fd1498Szrj   dynsym_shndx = 0;
281438fd1498Szrj 
281538fd1498Szrj   memset (sections, 0, sizeof sections);
281638fd1498Szrj 
281738fd1498Szrj   /* Look for the symbol table.  */
281838fd1498Szrj   for (i = 1; i < shnum; ++i)
281938fd1498Szrj     {
282038fd1498Szrj       const b_elf_shdr *shdr;
282138fd1498Szrj       unsigned int sh_name;
282238fd1498Szrj       const char *name;
282338fd1498Szrj       int j;
282438fd1498Szrj 
282538fd1498Szrj       shdr = &shdrs[i - 1];
282638fd1498Szrj 
282738fd1498Szrj       if (shdr->sh_type == SHT_SYMTAB)
282838fd1498Szrj 	symtab_shndx = i;
282938fd1498Szrj       else if (shdr->sh_type == SHT_DYNSYM)
283038fd1498Szrj 	dynsym_shndx = i;
283138fd1498Szrj 
283238fd1498Szrj       sh_name = shdr->sh_name;
283338fd1498Szrj       if (sh_name >= shstr_size)
283438fd1498Szrj 	{
283538fd1498Szrj 	  error_callback (data, "ELF section name out of range", 0);
283638fd1498Szrj 	  goto fail;
283738fd1498Szrj 	}
283838fd1498Szrj 
283938fd1498Szrj       name = names + sh_name;
284038fd1498Szrj 
284138fd1498Szrj       for (j = 0; j < (int) DEBUG_MAX; ++j)
284238fd1498Szrj 	{
284338fd1498Szrj 	  if (strcmp (name, debug_section_names[j]) == 0)
284438fd1498Szrj 	    {
284538fd1498Szrj 	      sections[j].offset = shdr->sh_offset;
284638fd1498Szrj 	      sections[j].size = shdr->sh_size;
284738fd1498Szrj 	      sections[j].compressed = (shdr->sh_flags & SHF_COMPRESSED) != 0;
284838fd1498Szrj 	      break;
284938fd1498Szrj 	    }
285038fd1498Szrj 	}
285138fd1498Szrj 
285238fd1498Szrj       /* Read the build ID if present.  This could check for any
285338fd1498Szrj 	 SHT_NOTE section with the right note name and type, but gdb
285438fd1498Szrj 	 looks for a specific section name.  */
285538fd1498Szrj       if (!debuginfo
285638fd1498Szrj 	  && !buildid_view_valid
285738fd1498Szrj 	  && strcmp (name, ".note.gnu.build-id") == 0)
285838fd1498Szrj 	{
285938fd1498Szrj 	  const b_elf_note *note;
286038fd1498Szrj 
286138fd1498Szrj 	  if (!backtrace_get_view (state, descriptor, shdr->sh_offset,
286238fd1498Szrj 				   shdr->sh_size, error_callback, data,
286338fd1498Szrj 				   &buildid_view))
286438fd1498Szrj 	    goto fail;
286538fd1498Szrj 
286638fd1498Szrj 	  buildid_view_valid = 1;
286738fd1498Szrj 	  note = (const b_elf_note *) buildid_view.data;
286838fd1498Szrj 	  if (note->type == NT_GNU_BUILD_ID
286938fd1498Szrj 	      && note->namesz == 4
287038fd1498Szrj 	      && strncmp (note->name, "GNU", 4) == 0
2871*58e805e6Szrj 	      && shdr->sh_size <= 12 + ((note->namesz + 3) & ~ 3) + note->descsz)
287238fd1498Szrj 	    {
287338fd1498Szrj 	      buildid_data = &note->name[0] + ((note->namesz + 3) & ~ 3);
287438fd1498Szrj 	      buildid_size = note->descsz;
287538fd1498Szrj 	    }
287638fd1498Szrj 	}
287738fd1498Szrj 
287838fd1498Szrj       /* Read the debuglink file if present.  */
287938fd1498Szrj       if (!debuginfo
288038fd1498Szrj 	  && !debuglink_view_valid
288138fd1498Szrj 	  && strcmp (name, ".gnu_debuglink") == 0)
288238fd1498Szrj 	{
288338fd1498Szrj 	  const char *debuglink_data;
288438fd1498Szrj 	  size_t crc_offset;
288538fd1498Szrj 
288638fd1498Szrj 	  if (!backtrace_get_view (state, descriptor, shdr->sh_offset,
288738fd1498Szrj 				   shdr->sh_size, error_callback, data,
288838fd1498Szrj 				   &debuglink_view))
288938fd1498Szrj 	    goto fail;
289038fd1498Szrj 
289138fd1498Szrj 	  debuglink_view_valid = 1;
289238fd1498Szrj 	  debuglink_data = (const char *) debuglink_view.data;
289338fd1498Szrj 	  crc_offset = strnlen (debuglink_data, shdr->sh_size);
289438fd1498Szrj 	  crc_offset = (crc_offset + 3) & ~3;
289538fd1498Szrj 	  if (crc_offset + 4 <= shdr->sh_size)
289638fd1498Szrj 	    {
289738fd1498Szrj 	      debuglink_name = debuglink_data;
289838fd1498Szrj 	      debuglink_crc = *(const uint32_t*)(debuglink_data + crc_offset);
289938fd1498Szrj 	    }
290038fd1498Szrj 	}
290138fd1498Szrj 
290238fd1498Szrj       /* Read the .opd section on PowerPC64 ELFv1.  */
290338fd1498Szrj       if (ehdr.e_machine == EM_PPC64
290438fd1498Szrj 	  && (ehdr.e_flags & EF_PPC64_ABI) < 2
290538fd1498Szrj 	  && shdr->sh_type == SHT_PROGBITS
290638fd1498Szrj 	  && strcmp (name, ".opd") == 0)
290738fd1498Szrj 	{
290838fd1498Szrj 	  if (!backtrace_get_view (state, descriptor, shdr->sh_offset,
290938fd1498Szrj 				   shdr->sh_size, error_callback, data,
291038fd1498Szrj 				   &opd_data.view))
291138fd1498Szrj 	    goto fail;
291238fd1498Szrj 
291338fd1498Szrj 	  opd = &opd_data;
291438fd1498Szrj 	  opd->addr = shdr->sh_addr;
291538fd1498Szrj 	  opd->data = (const char *) opd_data.view.data;
291638fd1498Szrj 	  opd->size = shdr->sh_size;
291738fd1498Szrj 	}
291838fd1498Szrj     }
291938fd1498Szrj 
292038fd1498Szrj   if (symtab_shndx == 0)
292138fd1498Szrj     symtab_shndx = dynsym_shndx;
292238fd1498Szrj   if (symtab_shndx != 0 && !debuginfo)
292338fd1498Szrj     {
292438fd1498Szrj       const b_elf_shdr *symtab_shdr;
292538fd1498Szrj       unsigned int strtab_shndx;
292638fd1498Szrj       const b_elf_shdr *strtab_shdr;
292738fd1498Szrj       struct elf_syminfo_data *sdata;
292838fd1498Szrj 
292938fd1498Szrj       symtab_shdr = &shdrs[symtab_shndx - 1];
293038fd1498Szrj       strtab_shndx = symtab_shdr->sh_link;
293138fd1498Szrj       if (strtab_shndx >= shnum)
293238fd1498Szrj 	{
293338fd1498Szrj 	  error_callback (data,
293438fd1498Szrj 			  "ELF symbol table strtab link out of range", 0);
293538fd1498Szrj 	  goto fail;
293638fd1498Szrj 	}
293738fd1498Szrj       strtab_shdr = &shdrs[strtab_shndx - 1];
293838fd1498Szrj 
293938fd1498Szrj       if (!backtrace_get_view (state, descriptor, symtab_shdr->sh_offset,
294038fd1498Szrj 			       symtab_shdr->sh_size, error_callback, data,
294138fd1498Szrj 			       &symtab_view))
294238fd1498Szrj 	goto fail;
294338fd1498Szrj       symtab_view_valid = 1;
294438fd1498Szrj 
294538fd1498Szrj       if (!backtrace_get_view (state, descriptor, strtab_shdr->sh_offset,
294638fd1498Szrj 			       strtab_shdr->sh_size, error_callback, data,
294738fd1498Szrj 			       &strtab_view))
294838fd1498Szrj 	goto fail;
294938fd1498Szrj       strtab_view_valid = 1;
295038fd1498Szrj 
295138fd1498Szrj       sdata = ((struct elf_syminfo_data *)
295238fd1498Szrj 	       backtrace_alloc (state, sizeof *sdata, error_callback, data));
295338fd1498Szrj       if (sdata == NULL)
295438fd1498Szrj 	goto fail;
295538fd1498Szrj 
295638fd1498Szrj       if (!elf_initialize_syminfo (state, base_address,
295738fd1498Szrj 				   symtab_view.data, symtab_shdr->sh_size,
295838fd1498Szrj 				   strtab_view.data, strtab_shdr->sh_size,
295938fd1498Szrj 				   error_callback, data, sdata, opd))
296038fd1498Szrj 	{
296138fd1498Szrj 	  backtrace_free (state, sdata, sizeof *sdata, error_callback, data);
296238fd1498Szrj 	  goto fail;
296338fd1498Szrj 	}
296438fd1498Szrj 
296538fd1498Szrj       /* We no longer need the symbol table, but we hold on to the
296638fd1498Szrj 	 string table permanently.  */
296738fd1498Szrj       backtrace_release_view (state, &symtab_view, error_callback, data);
296838fd1498Szrj       symtab_view_valid = 0;
296938fd1498Szrj 
297038fd1498Szrj       *found_sym = 1;
297138fd1498Szrj 
297238fd1498Szrj       elf_add_syminfo_data (state, sdata);
297338fd1498Szrj     }
297438fd1498Szrj 
297538fd1498Szrj   backtrace_release_view (state, &shdrs_view, error_callback, data);
297638fd1498Szrj   shdrs_view_valid = 0;
297738fd1498Szrj   backtrace_release_view (state, &names_view, error_callback, data);
297838fd1498Szrj   names_view_valid = 0;
297938fd1498Szrj 
298038fd1498Szrj   /* If the debug info is in a separate file, read that one instead.  */
298138fd1498Szrj 
298238fd1498Szrj   if (buildid_data != NULL)
298338fd1498Szrj     {
298438fd1498Szrj       int d;
298538fd1498Szrj 
298638fd1498Szrj       d = elf_open_debugfile_by_buildid (state, buildid_data, buildid_size,
298738fd1498Szrj 					 error_callback, data);
298838fd1498Szrj       if (d >= 0)
298938fd1498Szrj 	{
299038fd1498Szrj 	  int ret;
299138fd1498Szrj 
299238fd1498Szrj 	  backtrace_release_view (state, &buildid_view, error_callback, data);
299338fd1498Szrj 	  if (debuglink_view_valid)
299438fd1498Szrj 	    backtrace_release_view (state, &debuglink_view, error_callback,
299538fd1498Szrj 				    data);
299638fd1498Szrj 	  ret = elf_add (state, NULL, d, base_address, error_callback, data,
299738fd1498Szrj 			 fileline_fn, found_sym, found_dwarf, 0, 1);
299838fd1498Szrj 	  if (ret < 0)
299938fd1498Szrj 	    backtrace_close (d, error_callback, data);
300038fd1498Szrj 	  else
300138fd1498Szrj 	    backtrace_close (descriptor, error_callback, data);
300238fd1498Szrj 	  return ret;
300338fd1498Szrj 	}
300438fd1498Szrj     }
300538fd1498Szrj 
300638fd1498Szrj   if (buildid_view_valid)
300738fd1498Szrj     {
300838fd1498Szrj       backtrace_release_view (state, &buildid_view, error_callback, data);
300938fd1498Szrj       buildid_view_valid = 0;
301038fd1498Szrj     }
301138fd1498Szrj 
301238fd1498Szrj   if (opd)
301338fd1498Szrj     {
301438fd1498Szrj       backtrace_release_view (state, &opd->view, error_callback, data);
301538fd1498Szrj       opd = NULL;
301638fd1498Szrj     }
301738fd1498Szrj 
301838fd1498Szrj   if (debuglink_name != NULL)
301938fd1498Szrj     {
302038fd1498Szrj       int d;
302138fd1498Szrj 
302238fd1498Szrj       d = elf_open_debugfile_by_debuglink (state, filename, debuglink_name,
302338fd1498Szrj 					   debuglink_crc, error_callback,
302438fd1498Szrj 					   data);
302538fd1498Szrj       if (d >= 0)
302638fd1498Szrj 	{
302738fd1498Szrj 	  int ret;
302838fd1498Szrj 
302938fd1498Szrj 	  backtrace_release_view (state, &debuglink_view, error_callback,
303038fd1498Szrj 				  data);
303138fd1498Szrj 	  ret = elf_add (state, NULL, d, base_address, error_callback, data,
303238fd1498Szrj 			 fileline_fn, found_sym, found_dwarf, 0, 1);
303338fd1498Szrj 	  if (ret < 0)
303438fd1498Szrj 	    backtrace_close (d, error_callback, data);
303538fd1498Szrj 	  else
303638fd1498Szrj 	    backtrace_close(descriptor, error_callback, data);
303738fd1498Szrj 	  return ret;
303838fd1498Szrj 	}
303938fd1498Szrj     }
304038fd1498Szrj 
304138fd1498Szrj   if (debuglink_view_valid)
304238fd1498Szrj     {
304338fd1498Szrj       backtrace_release_view (state, &debuglink_view, error_callback, data);
304438fd1498Szrj       debuglink_view_valid = 0;
304538fd1498Szrj     }
304638fd1498Szrj 
304738fd1498Szrj   /* Read all the debug sections in a single view, since they are
304838fd1498Szrj      probably adjacent in the file.  We never release this view.  */
304938fd1498Szrj 
305038fd1498Szrj   min_offset = 0;
305138fd1498Szrj   max_offset = 0;
305238fd1498Szrj   for (i = 0; i < (int) DEBUG_MAX; ++i)
305338fd1498Szrj     {
305438fd1498Szrj       off_t end;
305538fd1498Szrj 
305638fd1498Szrj       if (sections[i].size == 0)
305738fd1498Szrj 	continue;
305838fd1498Szrj       if (min_offset == 0 || sections[i].offset < min_offset)
305938fd1498Szrj 	min_offset = sections[i].offset;
306038fd1498Szrj       end = sections[i].offset + sections[i].size;
306138fd1498Szrj       if (end > max_offset)
306238fd1498Szrj 	max_offset = end;
306338fd1498Szrj     }
306438fd1498Szrj   if (min_offset == 0 || max_offset == 0)
306538fd1498Szrj     {
306638fd1498Szrj       if (!backtrace_close (descriptor, error_callback, data))
306738fd1498Szrj 	goto fail;
306838fd1498Szrj       return 1;
306938fd1498Szrj     }
307038fd1498Szrj 
307138fd1498Szrj   if (!backtrace_get_view (state, descriptor, min_offset,
307238fd1498Szrj 			   max_offset - min_offset,
307338fd1498Szrj 			   error_callback, data, &debug_view))
307438fd1498Szrj     goto fail;
307538fd1498Szrj   debug_view_valid = 1;
307638fd1498Szrj 
307738fd1498Szrj   /* We've read all we need from the executable.  */
307838fd1498Szrj   if (!backtrace_close (descriptor, error_callback, data))
307938fd1498Szrj     goto fail;
308038fd1498Szrj   descriptor = -1;
308138fd1498Szrj 
308238fd1498Szrj   using_debug_view = 0;
308338fd1498Szrj   for (i = 0; i < (int) DEBUG_MAX; ++i)
308438fd1498Szrj     {
308538fd1498Szrj       if (sections[i].size == 0)
308638fd1498Szrj 	sections[i].data = NULL;
308738fd1498Szrj       else
308838fd1498Szrj 	{
308938fd1498Szrj 	  sections[i].data = ((const unsigned char *) debug_view.data
309038fd1498Szrj 			      + (sections[i].offset - min_offset));
309138fd1498Szrj 	  if (i < ZDEBUG_INFO)
309238fd1498Szrj 	    ++using_debug_view;
309338fd1498Szrj 	}
309438fd1498Szrj     }
309538fd1498Szrj 
309638fd1498Szrj   /* Uncompress the old format (--compress-debug-sections=zlib-gnu).  */
309738fd1498Szrj 
309838fd1498Szrj   zdebug_table = NULL;
309938fd1498Szrj   for (i = 0; i < ZDEBUG_INFO; ++i)
310038fd1498Szrj     {
310138fd1498Szrj       struct debug_section_info *pz;
310238fd1498Szrj 
310338fd1498Szrj       pz = &sections[i + ZDEBUG_INFO - DEBUG_INFO];
310438fd1498Szrj       if (sections[i].size == 0 && pz->size > 0)
310538fd1498Szrj 	{
310638fd1498Szrj 	  unsigned char *uncompressed_data;
310738fd1498Szrj 	  size_t uncompressed_size;
310838fd1498Szrj 
310938fd1498Szrj 	  if (zdebug_table == NULL)
311038fd1498Szrj 	    {
311138fd1498Szrj 	      zdebug_table = ((uint16_t *)
311238fd1498Szrj 			      backtrace_alloc (state, ZDEBUG_TABLE_SIZE,
311338fd1498Szrj 					       error_callback, data));
311438fd1498Szrj 	      if (zdebug_table == NULL)
311538fd1498Szrj 		goto fail;
311638fd1498Szrj 	    }
311738fd1498Szrj 
311838fd1498Szrj 	  uncompressed_data = NULL;
311938fd1498Szrj 	  uncompressed_size = 0;
312038fd1498Szrj 	  if (!elf_uncompress_zdebug (state, pz->data, pz->size, zdebug_table,
312138fd1498Szrj 				      error_callback, data,
312238fd1498Szrj 				      &uncompressed_data, &uncompressed_size))
312338fd1498Szrj 	    goto fail;
312438fd1498Szrj 	  sections[i].data = uncompressed_data;
312538fd1498Szrj 	  sections[i].size = uncompressed_size;
312638fd1498Szrj 	  sections[i].compressed = 0;
312738fd1498Szrj 	}
312838fd1498Szrj     }
312938fd1498Szrj 
313038fd1498Szrj   /* Uncompress the official ELF format
313138fd1498Szrj      (--compress-debug-sections=zlib-gabi).  */
313238fd1498Szrj   for (i = 0; i < ZDEBUG_INFO; ++i)
313338fd1498Szrj     {
313438fd1498Szrj       unsigned char *uncompressed_data;
313538fd1498Szrj       size_t uncompressed_size;
313638fd1498Szrj 
313738fd1498Szrj       if (sections[i].size == 0 || !sections[i].compressed)
313838fd1498Szrj 	continue;
313938fd1498Szrj 
314038fd1498Szrj       if (zdebug_table == NULL)
314138fd1498Szrj 	{
314238fd1498Szrj 	  zdebug_table = ((uint16_t *)
314338fd1498Szrj 			  backtrace_alloc (state, ZDEBUG_TABLE_SIZE,
314438fd1498Szrj 					   error_callback, data));
314538fd1498Szrj 	  if (zdebug_table == NULL)
314638fd1498Szrj 	    goto fail;
314738fd1498Szrj 	}
314838fd1498Szrj 
314938fd1498Szrj       uncompressed_data = NULL;
315038fd1498Szrj       uncompressed_size = 0;
315138fd1498Szrj       if (!elf_uncompress_chdr (state, sections[i].data, sections[i].size,
315238fd1498Szrj 				zdebug_table, error_callback, data,
315338fd1498Szrj 				&uncompressed_data, &uncompressed_size))
315438fd1498Szrj 	goto fail;
315538fd1498Szrj       sections[i].data = uncompressed_data;
315638fd1498Szrj       sections[i].size = uncompressed_size;
315738fd1498Szrj       sections[i].compressed = 0;
315838fd1498Szrj 
315938fd1498Szrj       --using_debug_view;
316038fd1498Szrj     }
316138fd1498Szrj 
316238fd1498Szrj   if (zdebug_table != NULL)
316338fd1498Szrj     backtrace_free (state, zdebug_table, ZDEBUG_TABLE_SIZE,
316438fd1498Szrj 		    error_callback, data);
316538fd1498Szrj 
316638fd1498Szrj   if (debug_view_valid && using_debug_view == 0)
316738fd1498Szrj     {
316838fd1498Szrj       backtrace_release_view (state, &debug_view, error_callback, data);
316938fd1498Szrj       debug_view_valid = 0;
317038fd1498Szrj     }
317138fd1498Szrj 
317238fd1498Szrj   if (!backtrace_dwarf_add (state, base_address,
317338fd1498Szrj 			    sections[DEBUG_INFO].data,
317438fd1498Szrj 			    sections[DEBUG_INFO].size,
317538fd1498Szrj 			    sections[DEBUG_LINE].data,
317638fd1498Szrj 			    sections[DEBUG_LINE].size,
317738fd1498Szrj 			    sections[DEBUG_ABBREV].data,
317838fd1498Szrj 			    sections[DEBUG_ABBREV].size,
317938fd1498Szrj 			    sections[DEBUG_RANGES].data,
318038fd1498Szrj 			    sections[DEBUG_RANGES].size,
318138fd1498Szrj 			    sections[DEBUG_STR].data,
318238fd1498Szrj 			    sections[DEBUG_STR].size,
318338fd1498Szrj 			    ehdr.e_ident[EI_DATA] == ELFDATA2MSB,
318438fd1498Szrj 			    error_callback, data, fileline_fn))
318538fd1498Szrj     goto fail;
318638fd1498Szrj 
318738fd1498Szrj   *found_dwarf = 1;
318838fd1498Szrj 
318938fd1498Szrj   return 1;
319038fd1498Szrj 
319138fd1498Szrj  fail:
319238fd1498Szrj   if (shdrs_view_valid)
319338fd1498Szrj     backtrace_release_view (state, &shdrs_view, error_callback, data);
319438fd1498Szrj   if (names_view_valid)
319538fd1498Szrj     backtrace_release_view (state, &names_view, error_callback, data);
319638fd1498Szrj   if (symtab_view_valid)
319738fd1498Szrj     backtrace_release_view (state, &symtab_view, error_callback, data);
319838fd1498Szrj   if (strtab_view_valid)
319938fd1498Szrj     backtrace_release_view (state, &strtab_view, error_callback, data);
320038fd1498Szrj   if (debuglink_view_valid)
320138fd1498Szrj     backtrace_release_view (state, &debuglink_view, error_callback, data);
320238fd1498Szrj   if (buildid_view_valid)
320338fd1498Szrj     backtrace_release_view (state, &buildid_view, error_callback, data);
320438fd1498Szrj   if (debug_view_valid)
320538fd1498Szrj     backtrace_release_view (state, &debug_view, error_callback, data);
320638fd1498Szrj   if (opd)
320738fd1498Szrj     backtrace_release_view (state, &opd->view, error_callback, data);
320838fd1498Szrj   if (descriptor != -1)
320938fd1498Szrj     backtrace_close (descriptor, error_callback, data);
321038fd1498Szrj   return 0;
321138fd1498Szrj }
321238fd1498Szrj 
321338fd1498Szrj /* Data passed to phdr_callback.  */
321438fd1498Szrj 
321538fd1498Szrj struct phdr_data
321638fd1498Szrj {
321738fd1498Szrj   struct backtrace_state *state;
321838fd1498Szrj   backtrace_error_callback error_callback;
321938fd1498Szrj   void *data;
322038fd1498Szrj   fileline *fileline_fn;
322138fd1498Szrj   int *found_sym;
322238fd1498Szrj   int *found_dwarf;
322338fd1498Szrj   const char *exe_filename;
322438fd1498Szrj   int exe_descriptor;
322538fd1498Szrj };
322638fd1498Szrj 
322738fd1498Szrj /* Callback passed to dl_iterate_phdr.  Load debug info from shared
322838fd1498Szrj    libraries.  */
322938fd1498Szrj 
323038fd1498Szrj static int
323138fd1498Szrj #ifdef __i386__
323238fd1498Szrj __attribute__ ((__force_align_arg_pointer__))
323338fd1498Szrj #endif
phdr_callback(struct dl_phdr_info * info,size_t size ATTRIBUTE_UNUSED,void * pdata)323438fd1498Szrj phdr_callback (struct dl_phdr_info *info, size_t size ATTRIBUTE_UNUSED,
323538fd1498Szrj 	       void *pdata)
323638fd1498Szrj {
323738fd1498Szrj   struct phdr_data *pd = (struct phdr_data *) pdata;
323838fd1498Szrj   const char *filename;
323938fd1498Szrj   int descriptor;
324038fd1498Szrj   int does_not_exist;
324138fd1498Szrj   fileline elf_fileline_fn;
324238fd1498Szrj   int found_dwarf;
324338fd1498Szrj 
324438fd1498Szrj   /* There is not much we can do if we don't have the module name,
324538fd1498Szrj      unless executable is ET_DYN, where we expect the very first
324638fd1498Szrj      phdr_callback to be for the PIE.  */
324738fd1498Szrj   if (info->dlpi_name == NULL || info->dlpi_name[0] == '\0')
324838fd1498Szrj     {
324938fd1498Szrj       if (pd->exe_descriptor == -1)
325038fd1498Szrj 	return 0;
325138fd1498Szrj       filename = pd->exe_filename;
325238fd1498Szrj       descriptor = pd->exe_descriptor;
325338fd1498Szrj       pd->exe_descriptor = -1;
325438fd1498Szrj     }
325538fd1498Szrj   else
325638fd1498Szrj     {
325738fd1498Szrj       if (pd->exe_descriptor != -1)
325838fd1498Szrj 	{
325938fd1498Szrj 	  backtrace_close (pd->exe_descriptor, pd->error_callback, pd->data);
326038fd1498Szrj 	  pd->exe_descriptor = -1;
326138fd1498Szrj 	}
326238fd1498Szrj 
326338fd1498Szrj       filename = info->dlpi_name;
326438fd1498Szrj       descriptor = backtrace_open (info->dlpi_name, pd->error_callback,
326538fd1498Szrj 				   pd->data, &does_not_exist);
326638fd1498Szrj       if (descriptor < 0)
326738fd1498Szrj 	return 0;
326838fd1498Szrj     }
326938fd1498Szrj 
327038fd1498Szrj   if (elf_add (pd->state, filename, descriptor, info->dlpi_addr,
327138fd1498Szrj 	       pd->error_callback, pd->data, &elf_fileline_fn, pd->found_sym,
327238fd1498Szrj 	       &found_dwarf, 0, 0))
327338fd1498Szrj     {
327438fd1498Szrj       if (found_dwarf)
327538fd1498Szrj 	{
327638fd1498Szrj 	  *pd->found_dwarf = 1;
327738fd1498Szrj 	  *pd->fileline_fn = elf_fileline_fn;
327838fd1498Szrj 	}
327938fd1498Szrj     }
328038fd1498Szrj 
328138fd1498Szrj   return 0;
328238fd1498Szrj }
328338fd1498Szrj 
328438fd1498Szrj /* Initialize the backtrace data we need from an ELF executable.  At
328538fd1498Szrj    the ELF level, all we need to do is find the debug info
328638fd1498Szrj    sections.  */
328738fd1498Szrj 
328838fd1498Szrj int
backtrace_initialize(struct backtrace_state * state,const char * filename,int descriptor,backtrace_error_callback error_callback,void * data,fileline * fileline_fn)328938fd1498Szrj backtrace_initialize (struct backtrace_state *state, const char *filename,
329038fd1498Szrj 		      int descriptor, backtrace_error_callback error_callback,
329138fd1498Szrj 		      void *data, fileline *fileline_fn)
329238fd1498Szrj {
329338fd1498Szrj   int ret;
329438fd1498Szrj   int found_sym;
329538fd1498Szrj   int found_dwarf;
329638fd1498Szrj   fileline elf_fileline_fn = elf_nodebug;
329738fd1498Szrj   struct phdr_data pd;
329838fd1498Szrj 
329938fd1498Szrj   ret = elf_add (state, filename, descriptor, 0, error_callback, data,
330038fd1498Szrj 		 &elf_fileline_fn, &found_sym, &found_dwarf, 1, 0);
330138fd1498Szrj   if (!ret)
330238fd1498Szrj     return 0;
330338fd1498Szrj 
330438fd1498Szrj   pd.state = state;
330538fd1498Szrj   pd.error_callback = error_callback;
330638fd1498Szrj   pd.data = data;
330738fd1498Szrj   pd.fileline_fn = &elf_fileline_fn;
330838fd1498Szrj   pd.found_sym = &found_sym;
330938fd1498Szrj   pd.found_dwarf = &found_dwarf;
331038fd1498Szrj   pd.exe_filename = filename;
331138fd1498Szrj   pd.exe_descriptor = ret < 0 ? descriptor : -1;
331238fd1498Szrj 
331338fd1498Szrj   dl_iterate_phdr (phdr_callback, (void *) &pd);
331438fd1498Szrj 
331538fd1498Szrj   if (!state->threaded)
331638fd1498Szrj     {
331738fd1498Szrj       if (found_sym)
331838fd1498Szrj 	state->syminfo_fn = elf_syminfo;
331938fd1498Szrj       else if (state->syminfo_fn == NULL)
332038fd1498Szrj 	state->syminfo_fn = elf_nosyms;
332138fd1498Szrj     }
332238fd1498Szrj   else
332338fd1498Szrj     {
332438fd1498Szrj       if (found_sym)
332538fd1498Szrj 	backtrace_atomic_store_pointer (&state->syminfo_fn, elf_syminfo);
332638fd1498Szrj       else
332738fd1498Szrj 	(void) __sync_bool_compare_and_swap (&state->syminfo_fn, NULL,
332838fd1498Szrj 					     elf_nosyms);
332938fd1498Szrj     }
333038fd1498Szrj 
333138fd1498Szrj   if (!state->threaded)
333238fd1498Szrj     *fileline_fn = state->fileline_fn;
333338fd1498Szrj   else
333438fd1498Szrj     *fileline_fn = backtrace_atomic_load_pointer (&state->fileline_fn);
333538fd1498Szrj 
333638fd1498Szrj   if (*fileline_fn == NULL || *fileline_fn == elf_nodebug)
333738fd1498Szrj     *fileline_fn = elf_fileline_fn;
333838fd1498Szrj 
333938fd1498Szrj   return 1;
334038fd1498Szrj }
3341