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 = ¬e->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 = §ions[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