v / thirdparty / libbacktrace
Raw file | 3865 loc (3263 sloc) | 110.87 KB | Latest commit hash 76a735450
1// elf.c:
2#include <errno.h>
3#include <stdlib.h>
4#include <string.h>
5#include <sys/stat.h>
6#include <sys/types.h>
7#include <unistd.h>
8
9#ifdef HAVE_DL_ITERATE_PHDR
10#include <link.h>
11#endif
12
13#ifndef S_ISLNK
14#ifndef S_IFLNK
15#define S_IFLNK 0120000
16#endif
17#ifndef S_IFMT
18#define S_IFMT 0170000
19#endif
20#define S_ISLNK(m) (((m)&S_IFMT) == S_IFLNK)
21#endif
22
23#ifndef __GNUC__
24#define __builtin_prefetch(p, r, l)
25#define unlikely(x) (x)
26#else
27#define unlikely(x) __builtin_expect(!!(x), 0)
28#endif
29
30#if !defined(HAVE_DECL_STRNLEN) || !HAVE_DECL_STRNLEN
31
32static size_t xstrnlen(const char *s, size_t maxlen) {
33 size_t i;
34
35 for (i = 0; i < maxlen; ++i)
36 if (s[i] == '\0') break;
37 return i;
38}
39
40#define strnlen xstrnlen
41
42#endif
43
44#ifndef HAVE_LSTAT
45
46static int xlstat(const char *path ATTRIBUTE_UNUSED,
47 struct stat *st ATTRIBUTE_UNUSED) {
48 return -1;
49}
50
51#define lstat xlstat
52
53#endif
54
55#ifndef HAVE_READLINK
56
57static ssize_t xreadlink(const char *path ATTRIBUTE_UNUSED,
58 char *buf ATTRIBUTE_UNUSED,
59 size_t bufsz ATTRIBUTE_UNUSED) {
60 return -1;
61}
62
63#define readlink xreadlink
64
65#endif
66
67#ifndef HAVE_DL_ITERATE_PHDR
68
69#define dl_phdr_info x_dl_phdr_info
70#define dl_iterate_phdr x_dl_iterate_phdr
71
72struct dl_phdr_info {
73 uintptr_t dlpi_addr;
74 const char *dlpi_name;
75};
76
77static int dl_iterate_phdr(int (*callback)(struct dl_phdr_info *, size_t,
78 void *) ATTRIBUTE_UNUSED,
79 void *data ATTRIBUTE_UNUSED) {
80 return 0;
81}
82
83#endif
84
85#if BACKTRACE_ELF_SIZE != 32 && BACKTRACE_ELF_SIZE != 64
86#error "Unknown BACKTRACE_ELF_SIZE"
87#endif
88
89#undef EI_NIDENT
90#undef EI_MAG0
91#undef EI_MAG1
92#undef EI_MAG2
93#undef EI_MAG3
94#undef EI_CLASS
95#undef EI_DATA
96#undef EI_VERSION
97#undef ELF_MAG0
98#undef ELF_MAG1
99#undef ELF_MAG2
100#undef ELF_MAG3
101#undef ELFCLASS32
102#undef ELFCLASS64
103#undef ELFDATA2LSB
104#undef ELFDATA2MSB
105#undef EV_CURRENT
106#undef ET_DYN
107#undef EM_PPC64
108#undef EF_PPC64_ABI
109#undef SHN_LORESERVE
110#undef SHN_XINDEX
111#undef SHN_UNDEF
112#undef SHT_PROGBITS
113#undef SHT_SYMTAB
114#undef SHT_STRTAB
115#undef SHT_DYNSYM
116#undef SHF_COMPRESSED
117#undef STT_OBJECT
118#undef STT_FUNC
119#undef NT_GNU_BUILD_ID
120#undef ELFCOMPRESS_ZLIB
121
122typedef uint16_t b_elf_half;
123typedef uint32_t b_elf_word;
124typedef int32_t b_elf_sword;
125#if BACKTRACE_ELF_SIZE == 32
126
127typedef uint32_t b_elf_addr;
128typedef uint32_t b_elf_off;
129typedef uint32_t b_elf_wxword;
130#else
131
132typedef uint64_t b_elf_addr;
133typedef uint64_t b_elf_off;
134typedef uint64_t b_elf_xword;
135typedef int64_t b_elf_sxword;
136typedef uint64_t b_elf_wxword;
137#endif
138
139#define EI_NIDENT 16
140
141typedef struct {
142 unsigned char e_ident[EI_NIDENT];
143 b_elf_half e_type;
144 b_elf_half e_machine;
145 b_elf_word e_version;
146 b_elf_addr e_entry;
147 b_elf_off e_phoff;
148 b_elf_off e_shoff;
149 b_elf_word e_flags;
150 b_elf_half e_ehsize;
151 b_elf_half e_phentsize;
152 b_elf_half e_phnum;
153 b_elf_half e_shentsize;
154 b_elf_half e_shnum;
155 b_elf_half e_shstrndx;
156} b_elf_ehdr;
157#define EI_MAG0 0
158#define EI_MAG1 1
159#define EI_MAG2 2
160#define EI_MAG3 3
161#define EI_CLASS 4
162#define EI_DATA 5
163#define EI_VERSION 6
164
165#define ELFMAG0 0x7f
166#define ELFMAG1 'E'
167#define ELFMAG2 'L'
168#define ELFMAG3 'F'
169
170#define ELFCLASS32 1
171#define ELFCLASS64 2
172
173#define ELFDATA2LSB 1
174#define ELFDATA2MSB 2
175
176#define EV_CURRENT 1
177
178#define ET_DYN 3
179
180#define EM_PPC64 21
181#define EF_PPC64_ABI 3
182
183typedef struct {
184 b_elf_word sh_name;
185 b_elf_word sh_type;
186 b_elf_wxword sh_flags;
187 b_elf_addr sh_addr;
188 b_elf_off sh_offset;
189 b_elf_wxword sh_size;
190 b_elf_word sh_link;
191 b_elf_word sh_info;
192 b_elf_wxword sh_addralign;
193 b_elf_wxword sh_entsize;
194} b_elf_shdr;
195#define SHN_UNDEF 0x0000
196#define SHN_LORESERVE 0xFF00
197#define SHN_XINDEX 0xFFFF
198#define SHT_PROGBITS 1
199#define SHT_SYMTAB 2
200#define SHT_STRTAB 3
201#define SHT_DYNSYM 11
202
203#define SHF_COMPRESSED 0x800
204
205#if BACKTRACE_ELF_SIZE == 32
206
207typedef struct {
208 b_elf_word st_name;
209 b_elf_addr st_value;
210 b_elf_word st_size;
211 unsigned char st_info;
212 unsigned char st_other;
213 b_elf_half st_shndx;
214} b_elf_sym;
215#else
216typedef struct {
217 b_elf_word st_name;
218 unsigned char st_info;
219 unsigned char st_other;
220 b_elf_half st_shndx;
221 b_elf_addr st_value;
222 b_elf_xword st_size;
223} b_elf_sym;
224#endif
225#define STT_OBJECT 1
226#define STT_FUNC 2
227
228typedef struct {
229 uint32_t namesz;
230 uint32_t descsz;
231 uint32_t type;
232 char name[1];
233} b_elf_note;
234
235#define NT_GNU_BUILD_ID 3
236
237#if BACKTRACE_ELF_SIZE == 32
238
239typedef struct {
240 b_elf_word ch_type;
241 b_elf_word ch_size;
242 b_elf_word ch_addralign;
243} b_elf_chdr;
244#else
245typedef struct {
246 b_elf_word ch_type;
247 b_elf_word ch_reserved;
248 b_elf_xword ch_size;
249 b_elf_xword ch_addralign;
250} b_elf_chdr;
251#endif
252#define ELFCOMPRESS_ZLIB 1
253
254static const char *const dwarf_section_names[DEBUG_MAX] = {
255 ".debug_info", ".debug_line", ".debug_abbrev",
256 ".debug_ranges", ".debug_str", ".debug_addr",
257 ".debug_str_offsets", ".debug_line_str", ".debug_rnglists"};
258
259struct debug_section_info {
260 off_t offset;
261
262 size_t size;
263
264 const unsigned char *data;
265
266 int compressed;
267};
268
269struct elf_symbol {
270 const char *name;
271
272 uintptr_t address;
273
274 size_t size;
275};
276
277struct elf_syminfo_data {
278 struct elf_syminfo_data *next;
279
280 struct elf_symbol *symbols;
281
282 size_t count;
283};
284
285struct elf_view {
286 struct backtrace_view view;
287 int release;
288};
289
290struct elf_ppc64_opd_data {
291 b_elf_addr addr;
292
293 const char *data;
294
295 size_t size;
296
297 struct elf_view view;
298};
299
300static int elf_get_view(struct backtrace_state *state, int descriptor,
301 const unsigned char *memory, size_t memory_size,
302 off_t offset, uint64_t size,
303 backtrace_error_callback error_callback, void *data,
304 struct elf_view *view) {
305 if (memory == NULL) {
306 view->release = 1;
307 return backtrace_get_view(state, descriptor, offset, size, error_callback,
308 data, &view->view);
309 } else {
310 if ((uint64_t)offset + size > (uint64_t)memory_size) {
311 error_callback(data, "out of range for in-memory file", 0);
312 return 0;
313 }
314 view->view.data = (const void *)(memory + offset);
315 view->view.base = NULL;
316 view->view.len = size;
317 view->release = 0;
318 return 1;
319 }
320}
321
322static void elf_release_view(struct backtrace_state *state,
323 struct elf_view *view,
324 backtrace_error_callback error_callback,
325 void *data) {
326 if (view->release)
327 backtrace_release_view(state, &view->view, error_callback, data);
328}
329
330static uint32_t elf_crc32(uint32_t crc, const unsigned char *buf, size_t len) {
331 static const uint32_t crc32_table[256] = {
332 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
333 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
334 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
335 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
336 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
337 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
338 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
339 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
340 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
341 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
342 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
343 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
344 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
345 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
346 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
347 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
348 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
349 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
350 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
351 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
352 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
353 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
354 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
355 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
356 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
357 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
358 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
359 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
360 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
361 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
362 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
363 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
364 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
365 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
366 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
367 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
368 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
369 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
370 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
371 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
372 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
373 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
374 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d};
375 const unsigned char *end;
376
377 crc = ~crc;
378 for (end = buf + len; buf < end; ++buf)
379 crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8);
380 return ~crc;
381}
382
383static uint32_t elf_crc32_file(struct backtrace_state *state, int descriptor,
384 backtrace_error_callback error_callback,
385 void *data) {
386 struct stat st;
387 struct backtrace_view file_view;
388 uint32_t ret;
389
390 if (fstat(descriptor, &st) < 0) {
391 error_callback(data, "fstat", errno);
392 return 0;
393 }
394
395 if (!backtrace_get_view(state, descriptor, 0, st.st_size, error_callback,
396 data, &file_view))
397 return 0;
398
399 ret = elf_crc32(0, (const unsigned char *)file_view.data, st.st_size);
400
401 backtrace_release_view(state, &file_view, error_callback, data);
402
403 return ret;
404}
405
406static void elf_nosyms(struct backtrace_state *state ATTRIBUTE_UNUSED,
407 uintptr_t addr ATTRIBUTE_UNUSED,
408 backtrace_syminfo_callback callback ATTRIBUTE_UNUSED,
409 backtrace_error_callback error_callback, void *data) {
410 error_callback(data, "no symbol table in ELF executable", -1);
411}
412
413static int elf_nodebug(struct backtrace_state *state, uintptr_t pc,
414 backtrace_full_callback callback,
415 backtrace_error_callback error_callback, void *data) {
416 if (state->syminfo_fn != NULL && state->syminfo_fn != elf_nosyms) {
417 struct backtrace_call_full bdata;
418
419 bdata.full_callback = callback;
420 bdata.full_error_callback = error_callback;
421 bdata.full_data = data;
422 bdata.ret = 0;
423 state->syminfo_fn(state, pc, backtrace_syminfo_to_full_callback,
424 backtrace_syminfo_to_full_error_callback, &bdata);
425 return bdata.ret;
426 }
427
428 error_callback(data, "no debug info in ELF executable", -1);
429 return 0;
430}
431
432static int elf_symbol_compare(const void *v1, const void *v2) {
433 const struct elf_symbol *e1 = (const struct elf_symbol *)v1;
434 const struct elf_symbol *e2 = (const struct elf_symbol *)v2;
435
436 if (e1->address < e2->address)
437 return -1;
438 else if (e1->address > e2->address)
439 return 1;
440 else
441 return 0;
442}
443
444static int elf_symbol_search(const void *vkey, const void *ventry) {
445 const uintptr_t *key = (const uintptr_t *)vkey;
446 const struct elf_symbol *entry = (const struct elf_symbol *)ventry;
447 uintptr_t addr;
448
449 addr = *key;
450 if (addr < entry->address)
451 return -1;
452 else if (addr >= entry->address + entry->size)
453 return 1;
454 else
455 return 0;
456}
457
458static int elf_initialize_syminfo(
459 struct backtrace_state *state, uintptr_t base_address,
460 const unsigned char *symtab_data, size_t symtab_size,
461 const unsigned char *strtab, size_t strtab_size,
462 backtrace_error_callback error_callback, void *data,
463 struct elf_syminfo_data *sdata, struct elf_ppc64_opd_data *opd) {
464 size_t sym_count;
465 const b_elf_sym *sym;
466 size_t elf_symbol_count;
467 size_t elf_symbol_size;
468 struct elf_symbol *elf_symbols;
469 size_t i;
470 unsigned int j;
471
472 sym_count = symtab_size / sizeof(b_elf_sym);
473
474 sym = (const b_elf_sym *)symtab_data;
475 elf_symbol_count = 0;
476 for (i = 0; i < sym_count; ++i, ++sym) {
477 int info;
478
479 info = sym->st_info & 0xf;
480 if ((info == STT_FUNC || info == STT_OBJECT) && sym->st_shndx != SHN_UNDEF)
481 ++elf_symbol_count;
482 }
483
484 elf_symbol_size = elf_symbol_count * sizeof(struct elf_symbol);
485 elf_symbols = ((struct elf_symbol *)backtrace_alloc(state, elf_symbol_size,
486 error_callback, data));
487 if (elf_symbols == NULL) return 0;
488
489 sym = (const b_elf_sym *)symtab_data;
490 j = 0;
491 for (i = 0; i < sym_count; ++i, ++sym) {
492 int info;
493
494 info = sym->st_info & 0xf;
495 if (info != STT_FUNC && info != STT_OBJECT) continue;
496 if (sym->st_shndx == SHN_UNDEF) continue;
497 if (sym->st_name >= strtab_size) {
498 error_callback(data, "symbol string index out of range", 0);
499 backtrace_free(state, elf_symbols, elf_symbol_size, error_callback, data);
500 return 0;
501 }
502 elf_symbols[j].name = (const char *)strtab + sym->st_name;
503
504 if (opd && sym->st_value >= opd->addr &&
505 sym->st_value < opd->addr + opd->size)
506 elf_symbols[j].address =
507 *(const b_elf_addr *)(opd->data + (sym->st_value - opd->addr));
508 else
509 elf_symbols[j].address = sym->st_value;
510 elf_symbols[j].address += base_address;
511 elf_symbols[j].size = sym->st_size;
512 ++j;
513 }
514
515 backtrace_qsort(elf_symbols, elf_symbol_count, sizeof(struct elf_symbol),
516 elf_symbol_compare);
517
518 sdata->next = NULL;
519 sdata->symbols = elf_symbols;
520 sdata->count = elf_symbol_count;
521
522 return 1;
523}
524
525static void elf_add_syminfo_data(struct backtrace_state *state,
526 struct elf_syminfo_data *edata) {
527 if (!state->threaded) {
528 struct elf_syminfo_data **pp;
529
530 for (pp = (struct elf_syminfo_data **)(void *)&state->syminfo_data;
531 *pp != NULL; pp = &(*pp)->next)
532 ;
533 *pp = edata;
534 } else {
535 while (1) {
536 struct elf_syminfo_data **pp;
537
538 pp = (struct elf_syminfo_data **)(void *)&state->syminfo_data;
539
540 while (1) {
541 struct elf_syminfo_data *p;
542
543 p = backtrace_atomic_load_pointer(pp);
544
545 if (p == NULL) break;
546
547 pp = &p->next;
548 }
549
550 if (__sync_bool_compare_and_swap(pp, NULL, edata)) break;
551 }
552 }
553}
554
555static void elf_syminfo(
556 struct backtrace_state *state, uintptr_t addr,
557 backtrace_syminfo_callback callback,
558 backtrace_error_callback error_callback ATTRIBUTE_UNUSED, void *data) {
559 struct elf_syminfo_data *edata;
560 struct elf_symbol *sym = NULL;
561
562 if (!state->threaded) {
563 for (edata = (struct elf_syminfo_data *)state->syminfo_data; edata != NULL;
564 edata = edata->next) {
565 sym = ((struct elf_symbol *)bsearch(&addr, edata->symbols, edata->count,
566 sizeof(struct elf_symbol),
567 elf_symbol_search));
568 if (sym != NULL) break;
569 }
570 } else {
571 struct elf_syminfo_data **pp;
572
573 pp = (struct elf_syminfo_data **)(void *)&state->syminfo_data;
574 while (1) {
575 edata = backtrace_atomic_load_pointer(pp);
576 if (edata == NULL) break;
577
578 sym = ((struct elf_symbol *)bsearch(&addr, edata->symbols, edata->count,
579 sizeof(struct elf_symbol),
580 elf_symbol_search));
581 if (sym != NULL) break;
582
583 pp = &edata->next;
584 }
585 }
586
587 if (sym == NULL)
588 callback(data, addr, NULL, 0, 0);
589 else
590 callback(data, addr, sym->name, sym->address, sym->size);
591}
592
593static int elf_is_symlink(const char *filename) {
594 struct stat st;
595
596 if (lstat(filename, &st) < 0) return 0;
597 return S_ISLNK(st.st_mode);
598}
599
600static char *elf_readlink(struct backtrace_state *state, const char *filename,
601 backtrace_error_callback error_callback, void *data,
602 size_t *plen) {
603 size_t len;
604 char *buf;
605
606 len = 128;
607 while (1) {
608 ssize_t rl;
609
610 buf = backtrace_alloc(state, len, error_callback, data);
611 if (buf == NULL) return NULL;
612 rl = readlink(filename, buf, len);
613 if (rl < 0) {
614 backtrace_free(state, buf, len, error_callback, data);
615 return NULL;
616 }
617 if ((size_t)rl < len - 1) {
618 buf[rl] = '\0';
619 *plen = len;
620 return buf;
621 }
622 backtrace_free(state, buf, len, error_callback, data);
623 len *= 2;
624 }
625}
626
627#define SYSTEM_BUILD_ID_DIR "/usr/lib/debug/.build-id/"
628
629static int elf_open_debugfile_by_buildid(
630 struct backtrace_state *state, const char *buildid_data,
631 size_t buildid_size, backtrace_error_callback error_callback, void *data) {
632 const char *const prefix = SYSTEM_BUILD_ID_DIR;
633 const size_t prefix_len = strlen(prefix);
634 const char *const suffix = ".debug";
635 const size_t suffix_len = strlen(suffix);
636 size_t len;
637 char *bd_filename;
638 char *t;
639 size_t i;
640 int ret;
641 int does_not_exist;
642
643 len = prefix_len + buildid_size * 2 + suffix_len + 2;
644 bd_filename = backtrace_alloc(state, len, error_callback, data);
645 if (bd_filename == NULL) return -1;
646
647 t = bd_filename;
648 memcpy(t, prefix, prefix_len);
649 t += prefix_len;
650 for (i = 0; i < buildid_size; i++) {
651 unsigned char b;
652 unsigned char nib;
653
654 b = (unsigned char)buildid_data[i];
655 nib = (b & 0xf0) >> 4;
656 *t++ = nib < 10 ? '0' + nib : 'a' + nib - 10;
657 nib = b & 0x0f;
658 *t++ = nib < 10 ? '0' + nib : 'a' + nib - 10;
659 if (i == 0) *t++ = '/';
660 }
661 memcpy(t, suffix, suffix_len);
662 t[suffix_len] = '\0';
663
664 ret = backtrace_open(bd_filename, error_callback, data, &does_not_exist);
665
666 backtrace_free(state, bd_filename, len, error_callback, data);
667
668 return ret;
669}
670
671static int elf_try_debugfile(struct backtrace_state *state, const char *prefix,
672 size_t prefix_len, const char *prefix2,
673 size_t prefix2_len, const char *debuglink_name,
674 backtrace_error_callback error_callback,
675 void *data) {
676 size_t debuglink_len;
677 size_t try_len;
678 char *try;
679 int does_not_exist;
680 int ret;
681
682 debuglink_len = strlen(debuglink_name);
683 try_len = prefix_len + prefix2_len + debuglink_len + 1;
684 try = backtrace_alloc(state, try_len, error_callback, data);
685 if (try == NULL) return -1;
686
687 memcpy(try, prefix, prefix_len);
688 memcpy(try + prefix_len, prefix2, prefix2_len);
689 memcpy(try + prefix_len + prefix2_len, debuglink_name, debuglink_len);
690 try[prefix_len + prefix2_len + debuglink_len] = '\0';
691
692 ret = backtrace_open(try, error_callback, data, &does_not_exist);
693
694 backtrace_free(state, try, try_len, error_callback, data);
695
696 return ret;
697}
698
699static int elf_find_debugfile_by_debuglink(
700 struct backtrace_state *state, const char *filename,
701 const char *debuglink_name, backtrace_error_callback error_callback,
702 void *data) {
703 int ret;
704 char *alc;
705 size_t alc_len;
706 const char *slash;
707 int ddescriptor;
708 const char *prefix;
709 size_t prefix_len;
710
711 ret = -1;
712 alc = NULL;
713 alc_len = 0;
714 while (elf_is_symlink(filename)) {
715 char *new_buf;
716 size_t new_len;
717
718 new_buf = elf_readlink(state, filename, error_callback, data, &new_len);
719 if (new_buf == NULL) break;
720
721 if (new_buf[0] == '/')
722 filename = new_buf;
723 else {
724 slash = strrchr(filename, '/');
725 if (slash == NULL)
726 filename = new_buf;
727 else {
728 size_t clen;
729 char *c;
730
731 slash++;
732 clen = slash - filename + strlen(new_buf) + 1;
733 c = backtrace_alloc(state, clen, error_callback, data);
734 if (c == NULL) goto done;
735
736 memcpy(c, filename, slash - filename);
737 memcpy(c + (slash - filename), new_buf, strlen(new_buf));
738 c[slash - filename + strlen(new_buf)] = '\0';
739 backtrace_free(state, new_buf, new_len, error_callback, data);
740 filename = c;
741 new_buf = c;
742 new_len = clen;
743 }
744 }
745
746 if (alc != NULL) backtrace_free(state, alc, alc_len, error_callback, data);
747 alc = new_buf;
748 alc_len = new_len;
749 }
750
751 slash = strrchr(filename, '/');
752 if (slash == NULL) {
753 prefix = "";
754 prefix_len = 0;
755 } else {
756 slash++;
757 prefix = filename;
758 prefix_len = slash - filename;
759 }
760
761 ddescriptor = elf_try_debugfile(state, prefix, prefix_len, "", 0,
762 debuglink_name, error_callback, data);
763 if (ddescriptor >= 0) {
764 ret = ddescriptor;
765 goto done;
766 }
767
768 ddescriptor =
769 elf_try_debugfile(state, prefix, prefix_len, ".debug/", strlen(".debug/"),
770 debuglink_name, error_callback, data);
771 if (ddescriptor >= 0) {
772 ret = ddescriptor;
773 goto done;
774 }
775
776 ddescriptor = elf_try_debugfile(state, "/usr/lib/debug/",
777 strlen("/usr/lib/debug/"), prefix, prefix_len,
778 debuglink_name, error_callback, data);
779 if (ddescriptor >= 0) ret = ddescriptor;
780
781done:
782 if (alc != NULL && alc_len > 0)
783 backtrace_free(state, alc, alc_len, error_callback, data);
784 return ret;
785}
786
787static int elf_open_debugfile_by_debuglink(
788 struct backtrace_state *state, const char *filename,
789 const char *debuglink_name, uint32_t debuglink_crc,
790 backtrace_error_callback error_callback, void *data) {
791 int ddescriptor;
792
793 ddescriptor = elf_find_debugfile_by_debuglink(state, filename, debuglink_name,
794 error_callback, data);
795 if (ddescriptor < 0) return -1;
796
797 if (debuglink_crc != 0) {
798 uint32_t got_crc;
799
800 got_crc = elf_crc32_file(state, ddescriptor, error_callback, data);
801 if (got_crc != debuglink_crc) {
802 backtrace_close(ddescriptor, error_callback, data);
803 return -1;
804 }
805 }
806
807 return ddescriptor;
808}
809
810static void elf_uncompress_failed(void) {}
811
812static int elf_zlib_fetch(const unsigned char **ppin,
813 const unsigned char *pinend, uint64_t *pval,
814 unsigned int *pbits) {
815 unsigned int bits;
816 const unsigned char *pin;
817 uint64_t val;
818 uint32_t next;
819
820 bits = *pbits;
821 if (bits >= 15) return 1;
822 pin = *ppin;
823 val = *pval;
824
825 if (unlikely(pinend - pin < 4)) {
826 elf_uncompress_failed();
827 return 0;
828 }
829
830#if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \
831 defined(__ORDER_BIG_ENDIAN__) && \
832 (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ || \
833 __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
834
835 next = *(const uint32_t *)pin;
836
837#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
838 next = __builtin_bswap32(next);
839#endif
840#else
841 next = pin[0] | (pin[1] << 8) | (pin[2] << 16) | (pin[3] << 24);
842#endif
843
844 val |= (uint64_t)next << bits;
845 bits += 32;
846 pin += 4;
847
848 __builtin_prefetch(pin, 0, 0);
849
850 *ppin = pin;
851 *pval = val;
852 *pbits = bits;
853 return 1;
854}
855
856#define HUFFMAN_TABLE_SIZE (1024)
857
858#define HUFFMAN_VALUE_MASK 0x01ff
859#define HUFFMAN_BITS_SHIFT 9
860#define HUFFMAN_BITS_MASK 0x7
861#define HUFFMAN_SECONDARY_SHIFT 12
862
863#define ZDEBUG_TABLE_SIZE \
864 (2 * HUFFMAN_TABLE_SIZE * sizeof(uint16_t) + (286 + 30) * sizeof(uint16_t) + \
865 (286 + 30) * sizeof(unsigned char))
866
867#define ZDEBUG_TABLE_CODELEN_OFFSET \
868 (2 * HUFFMAN_TABLE_SIZE * sizeof(uint16_t) + (286 + 30) * sizeof(uint16_t))
869
870#define ZDEBUG_TABLE_WORK_OFFSET (2 * HUFFMAN_TABLE_SIZE * sizeof(uint16_t))
871
872#ifdef BACKTRACE_GENERATE_FIXED_HUFFMAN_TABLE
873
874static size_t final_next_secondary;
875
876#endif
877
878static int elf_zlib_inflate_table(unsigned char *codes, size_t codes_len,
879 uint16_t *zdebug_table, uint16_t *table) {
880 uint16_t count[16];
881 uint16_t start[16];
882 uint16_t prev[16];
883 uint16_t firstcode[7];
884 uint16_t *next;
885 size_t i;
886 size_t j;
887 unsigned int code;
888 size_t next_secondary;
889
890 next =
891 (uint16_t *)(((unsigned char *)zdebug_table) + ZDEBUG_TABLE_WORK_OFFSET);
892
893 memset(&count[0], 0, 16 * sizeof(uint16_t));
894 for (i = 0; i < codes_len; ++i) {
895 if (unlikely(codes[i] >= 16)) {
896 elf_uncompress_failed();
897 return 0;
898 }
899
900 if (count[codes[i]] == 0) {
901 start[codes[i]] = i;
902 prev[codes[i]] = i;
903 } else {
904 next[prev[codes[i]]] = i;
905 prev[codes[i]] = i;
906 }
907
908 ++count[codes[i]];
909 }
910
911 memset(table, 0, HUFFMAN_TABLE_SIZE * sizeof(uint16_t));
912
913 code = 0;
914 for (j = 1; j <= 8; ++j) {
915 unsigned int jcnt;
916 unsigned int val;
917
918 jcnt = count[j];
919 if (jcnt == 0) continue;
920
921 if (unlikely(jcnt > (1U << j))) {
922 elf_uncompress_failed();
923 return 0;
924 }
925
926 val = start[j];
927 for (i = 0; i < jcnt; ++i) {
928 uint16_t tval;
929 size_t ind;
930 unsigned int incr;
931
932 if (unlikely((val & ~HUFFMAN_VALUE_MASK) != 0)) {
933 elf_uncompress_failed();
934 return 0;
935 }
936
937 tval = val | ((j - 1) << HUFFMAN_BITS_SHIFT);
938
939 for (ind = code; ind < 0x100; ind += 1 << j) {
940 if (unlikely(table[ind] != 0)) {
941 elf_uncompress_failed();
942 return 0;
943 }
944 table[ind] = tval;
945 }
946
947 if (i + 1 < jcnt) val = next[val];
948
949 incr = 1U << (j - 1);
950 while ((code & incr) != 0) incr >>= 1;
951 if (incr == 0)
952 code = 0;
953 else {
954 code &= incr - 1;
955 code += incr;
956 }
957 }
958 }
959
960 for (j = 9; j < 16; j++) {
961 unsigned int jcnt;
962 unsigned int k;
963
964 jcnt = count[j];
965 if (jcnt == 0) continue;
966
967 firstcode[j - 9] = code;
968
969 for (k = 0; k < j; ++k) {
970 if ((jcnt & (1U << k)) != 0) {
971 unsigned int m;
972 unsigned int bit;
973
974 bit = 1U << (j - k - 1);
975 for (m = 0; m < j - k; ++m, bit >>= 1) {
976 if ((code & bit) == 0) {
977 code += bit;
978 break;
979 }
980 code &= ~bit;
981 }
982 jcnt &= ~(1U << k);
983 }
984 }
985 if (unlikely(jcnt != 0)) {
986 elf_uncompress_failed();
987 return 0;
988 }
989 }
990
991 next_secondary = 0;
992 for (j = 15; j >= 9; j--) {
993 unsigned int jcnt;
994 unsigned int val;
995 size_t primary;
996 size_t secondary;
997 size_t secondary_bits;
998 jcnt = count[j];
999 if (jcnt == 0) continue;
1000
1001 val = start[j];
1002 code = firstcode[j - 9];
1003 primary = 0x100;
1004 secondary = 0;
1005 secondary_bits = 0;
1006 for (i = 0; i < jcnt; ++i) {
1007 uint16_t tval;
1008 size_t ind;
1009 unsigned int incr;
1010
1011 if ((code & 0xff) != primary) {
1012 uint16_t tprimary;
1013
1014 primary = code & 0xff;
1015
1016 tprimary = table[primary];
1017 if (tprimary == 0) {
1018 if (unlikely((next_secondary & HUFFMAN_VALUE_MASK) !=
1019 next_secondary)) {
1020 elf_uncompress_failed();
1021 return 0;
1022 }
1023
1024 secondary = next_secondary;
1025 secondary_bits = j - 8;
1026 next_secondary += 1 << secondary_bits;
1027 table[primary] = (secondary + ((j - 8) << HUFFMAN_BITS_SHIFT) +
1028 (1U << HUFFMAN_SECONDARY_SHIFT));
1029 } else {
1030 if (unlikely((tprimary & (1U << HUFFMAN_SECONDARY_SHIFT)) == 0)) {
1031 elf_uncompress_failed();
1032 return 0;
1033 }
1034 secondary = tprimary & HUFFMAN_VALUE_MASK;
1035 secondary_bits =
1036 ((tprimary >> HUFFMAN_BITS_SHIFT) & HUFFMAN_BITS_MASK);
1037 if (unlikely(secondary_bits < j - 8)) {
1038 elf_uncompress_failed();
1039 return 0;
1040 }
1041 }
1042 }
1043
1044 tval = val | ((j - 8) << HUFFMAN_BITS_SHIFT);
1045
1046 for (ind = code >> 8; ind < (1U << secondary_bits);
1047 ind += 1U << (j - 8)) {
1048 if (unlikely(table[secondary + 0x100 + ind] != 0)) {
1049 elf_uncompress_failed();
1050 return 0;
1051 }
1052 table[secondary + 0x100 + ind] = tval;
1053 }
1054
1055 if (i + 1 < jcnt) val = next[val];
1056
1057 incr = 1U << (j - 1);
1058 while ((code & incr) != 0) incr >>= 1;
1059 if (incr == 0)
1060 code = 0;
1061 else {
1062 code &= incr - 1;
1063 code += incr;
1064 }
1065 }
1066 }
1067
1068#ifdef BACKTRACE_GENERATE_FIXED_HUFFMAN_TABLE
1069 final_next_secondary = next_secondary;
1070#endif
1071
1072 return 1;
1073}
1074
1075static const uint16_t elf_zlib_default_table[0x170] = {
1076 0xd00, 0xe50, 0xe10, 0xf18, 0xd10, 0xe70, 0xe30, 0x1230, 0xd08, 0xe60,
1077 0xe20, 0x1210, 0xe00, 0xe80, 0xe40, 0x1250, 0xd04, 0xe58, 0xe18, 0x1200,
1078 0xd14, 0xe78, 0xe38, 0x1240, 0xd0c, 0xe68, 0xe28, 0x1220, 0xe08, 0xe88,
1079 0xe48, 0x1260, 0xd02, 0xe54, 0xe14, 0xf1c, 0xd12, 0xe74, 0xe34, 0x1238,
1080 0xd0a, 0xe64, 0xe24, 0x1218, 0xe04, 0xe84, 0xe44, 0x1258, 0xd06, 0xe5c,
1081 0xe1c, 0x1208, 0xd16, 0xe7c, 0xe3c, 0x1248, 0xd0e, 0xe6c, 0xe2c, 0x1228,
1082 0xe0c, 0xe8c, 0xe4c, 0x1268, 0xd01, 0xe52, 0xe12, 0xf1a, 0xd11, 0xe72,
1083 0xe32, 0x1234, 0xd09, 0xe62, 0xe22, 0x1214, 0xe02, 0xe82, 0xe42, 0x1254,
1084 0xd05, 0xe5a, 0xe1a, 0x1204, 0xd15, 0xe7a, 0xe3a, 0x1244, 0xd0d, 0xe6a,
1085 0xe2a, 0x1224, 0xe0a, 0xe8a, 0xe4a, 0x1264, 0xd03, 0xe56, 0xe16, 0xf1e,
1086 0xd13, 0xe76, 0xe36, 0x123c, 0xd0b, 0xe66, 0xe26, 0x121c, 0xe06, 0xe86,
1087 0xe46, 0x125c, 0xd07, 0xe5e, 0xe1e, 0x120c, 0xd17, 0xe7e, 0xe3e, 0x124c,
1088 0xd0f, 0xe6e, 0xe2e, 0x122c, 0xe0e, 0xe8e, 0xe4e, 0x126c, 0xd00, 0xe51,
1089 0xe11, 0xf19, 0xd10, 0xe71, 0xe31, 0x1232, 0xd08, 0xe61, 0xe21, 0x1212,
1090 0xe01, 0xe81, 0xe41, 0x1252, 0xd04, 0xe59, 0xe19, 0x1202, 0xd14, 0xe79,
1091 0xe39, 0x1242, 0xd0c, 0xe69, 0xe29, 0x1222, 0xe09, 0xe89, 0xe49, 0x1262,
1092 0xd02, 0xe55, 0xe15, 0xf1d, 0xd12, 0xe75, 0xe35, 0x123a, 0xd0a, 0xe65,
1093 0xe25, 0x121a, 0xe05, 0xe85, 0xe45, 0x125a, 0xd06, 0xe5d, 0xe1d, 0x120a,
1094 0xd16, 0xe7d, 0xe3d, 0x124a, 0xd0e, 0xe6d, 0xe2d, 0x122a, 0xe0d, 0xe8d,
1095 0xe4d, 0x126a, 0xd01, 0xe53, 0xe13, 0xf1b, 0xd11, 0xe73, 0xe33, 0x1236,
1096 0xd09, 0xe63, 0xe23, 0x1216, 0xe03, 0xe83, 0xe43, 0x1256, 0xd05, 0xe5b,
1097 0xe1b, 0x1206, 0xd15, 0xe7b, 0xe3b, 0x1246, 0xd0d, 0xe6b, 0xe2b, 0x1226,
1098 0xe0b, 0xe8b, 0xe4b, 0x1266, 0xd03, 0xe57, 0xe17, 0xf1f, 0xd13, 0xe77,
1099 0xe37, 0x123e, 0xd0b, 0xe67, 0xe27, 0x121e, 0xe07, 0xe87, 0xe47, 0x125e,
1100 0xd07, 0xe5f, 0xe1f, 0x120e, 0xd17, 0xe7f, 0xe3f, 0x124e, 0xd0f, 0xe6f,
1101 0xe2f, 0x122e, 0xe0f, 0xe8f, 0xe4f, 0x126e, 0x290, 0x291, 0x292, 0x293,
1102 0x294, 0x295, 0x296, 0x297, 0x298, 0x299, 0x29a, 0x29b, 0x29c, 0x29d,
1103 0x29e, 0x29f, 0x2a0, 0x2a1, 0x2a2, 0x2a3, 0x2a4, 0x2a5, 0x2a6, 0x2a7,
1104 0x2a8, 0x2a9, 0x2aa, 0x2ab, 0x2ac, 0x2ad, 0x2ae, 0x2af, 0x2b0, 0x2b1,
1105 0x2b2, 0x2b3, 0x2b4, 0x2b5, 0x2b6, 0x2b7, 0x2b8, 0x2b9, 0x2ba, 0x2bb,
1106 0x2bc, 0x2bd, 0x2be, 0x2bf, 0x2c0, 0x2c1, 0x2c2, 0x2c3, 0x2c4, 0x2c5,
1107 0x2c6, 0x2c7, 0x2c8, 0x2c9, 0x2ca, 0x2cb, 0x2cc, 0x2cd, 0x2ce, 0x2cf,
1108 0x2d0, 0x2d1, 0x2d2, 0x2d3, 0x2d4, 0x2d5, 0x2d6, 0x2d7, 0x2d8, 0x2d9,
1109 0x2da, 0x2db, 0x2dc, 0x2dd, 0x2de, 0x2df, 0x2e0, 0x2e1, 0x2e2, 0x2e3,
1110 0x2e4, 0x2e5, 0x2e6, 0x2e7, 0x2e8, 0x2e9, 0x2ea, 0x2eb, 0x2ec, 0x2ed,
1111 0x2ee, 0x2ef, 0x2f0, 0x2f1, 0x2f2, 0x2f3, 0x2f4, 0x2f5, 0x2f6, 0x2f7,
1112 0x2f8, 0x2f9, 0x2fa, 0x2fb, 0x2fc, 0x2fd, 0x2fe, 0x2ff,
1113};
1114
1115static const uint16_t elf_zlib_default_dist_table[0x100] = {
1116 0x800, 0x810, 0x808, 0x818, 0x804, 0x814, 0x80c, 0x81c, 0x802, 0x812, 0x80a,
1117 0x81a, 0x806, 0x816, 0x80e, 0x81e, 0x801, 0x811, 0x809, 0x819, 0x805, 0x815,
1118 0x80d, 0x81d, 0x803, 0x813, 0x80b, 0x81b, 0x807, 0x817, 0x80f, 0x81f, 0x800,
1119 0x810, 0x808, 0x818, 0x804, 0x814, 0x80c, 0x81c, 0x802, 0x812, 0x80a, 0x81a,
1120 0x806, 0x816, 0x80e, 0x81e, 0x801, 0x811, 0x809, 0x819, 0x805, 0x815, 0x80d,
1121 0x81d, 0x803, 0x813, 0x80b, 0x81b, 0x807, 0x817, 0x80f, 0x81f, 0x800, 0x810,
1122 0x808, 0x818, 0x804, 0x814, 0x80c, 0x81c, 0x802, 0x812, 0x80a, 0x81a, 0x806,
1123 0x816, 0x80e, 0x81e, 0x801, 0x811, 0x809, 0x819, 0x805, 0x815, 0x80d, 0x81d,
1124 0x803, 0x813, 0x80b, 0x81b, 0x807, 0x817, 0x80f, 0x81f, 0x800, 0x810, 0x808,
1125 0x818, 0x804, 0x814, 0x80c, 0x81c, 0x802, 0x812, 0x80a, 0x81a, 0x806, 0x816,
1126 0x80e, 0x81e, 0x801, 0x811, 0x809, 0x819, 0x805, 0x815, 0x80d, 0x81d, 0x803,
1127 0x813, 0x80b, 0x81b, 0x807, 0x817, 0x80f, 0x81f, 0x800, 0x810, 0x808, 0x818,
1128 0x804, 0x814, 0x80c, 0x81c, 0x802, 0x812, 0x80a, 0x81a, 0x806, 0x816, 0x80e,
1129 0x81e, 0x801, 0x811, 0x809, 0x819, 0x805, 0x815, 0x80d, 0x81d, 0x803, 0x813,
1130 0x80b, 0x81b, 0x807, 0x817, 0x80f, 0x81f, 0x800, 0x810, 0x808, 0x818, 0x804,
1131 0x814, 0x80c, 0x81c, 0x802, 0x812, 0x80a, 0x81a, 0x806, 0x816, 0x80e, 0x81e,
1132 0x801, 0x811, 0x809, 0x819, 0x805, 0x815, 0x80d, 0x81d, 0x803, 0x813, 0x80b,
1133 0x81b, 0x807, 0x817, 0x80f, 0x81f, 0x800, 0x810, 0x808, 0x818, 0x804, 0x814,
1134 0x80c, 0x81c, 0x802, 0x812, 0x80a, 0x81a, 0x806, 0x816, 0x80e, 0x81e, 0x801,
1135 0x811, 0x809, 0x819, 0x805, 0x815, 0x80d, 0x81d, 0x803, 0x813, 0x80b, 0x81b,
1136 0x807, 0x817, 0x80f, 0x81f, 0x800, 0x810, 0x808, 0x818, 0x804, 0x814, 0x80c,
1137 0x81c, 0x802, 0x812, 0x80a, 0x81a, 0x806, 0x816, 0x80e, 0x81e, 0x801, 0x811,
1138 0x809, 0x819, 0x805, 0x815, 0x80d, 0x81d, 0x803, 0x813, 0x80b, 0x81b, 0x807,
1139 0x817, 0x80f, 0x81f,
1140};
1141
1142static int elf_zlib_inflate(const unsigned char *pin, size_t sin,
1143 uint16_t *zdebug_table, unsigned char *pout,
1144 size_t sout) {
1145 unsigned char *porigout;
1146 const unsigned char *pinend;
1147 unsigned char *poutend;
1148
1149 porigout = pout;
1150 pinend = pin + sin;
1151 poutend = pout + sout;
1152 while ((pinend - pin) > 4) {
1153 uint64_t val;
1154 unsigned int bits;
1155 int last;
1156
1157 if (unlikely((pin[0] & 0xf) != 8)) {
1158 elf_uncompress_failed();
1159 return 0;
1160 }
1161 if (unlikely((pin[0] >> 4) > 7)) {
1162 elf_uncompress_failed();
1163 return 0;
1164 }
1165 if (unlikely((pin[1] & 0x20) != 0)) {
1166 elf_uncompress_failed();
1167 return 0;
1168 }
1169 val = (pin[0] << 8) | pin[1];
1170 if (unlikely(val % 31 != 0)) {
1171 elf_uncompress_failed();
1172 return 0;
1173 }
1174 pin += 2;
1175
1176 val = 0;
1177 bits = 0;
1178 while ((((uintptr_t)pin) & 3) != 0) {
1179 val |= (uint64_t)*pin << bits;
1180 bits += 8;
1181 ++pin;
1182 }
1183
1184 last = 0;
1185
1186 while (!last) {
1187 unsigned int type;
1188 const uint16_t *tlit;
1189 const uint16_t *tdist;
1190
1191 if (!elf_zlib_fetch(&pin, pinend, &val, &bits)) return 0;
1192
1193 last = val & 1;
1194 type = (val >> 1) & 3;
1195 val >>= 3;
1196 bits -= 3;
1197
1198 if (unlikely(type == 3)) {
1199 elf_uncompress_failed();
1200 return 0;
1201 }
1202
1203 if (type == 0) {
1204 uint16_t len;
1205 uint16_t lenc;
1206
1207 while (bits >= 8) {
1208 --pin;
1209 bits -= 8;
1210 }
1211
1212 val = 0;
1213 bits = 0;
1214 if (unlikely((pinend - pin) < 4)) {
1215 elf_uncompress_failed();
1216 return 0;
1217 }
1218 len = pin[0] | (pin[1] << 8);
1219 lenc = pin[2] | (pin[3] << 8);
1220 pin += 4;
1221 lenc = ~lenc;
1222 if (unlikely(len != lenc)) {
1223 elf_uncompress_failed();
1224 return 0;
1225 }
1226 if (unlikely(len > (unsigned int)(pinend - pin) ||
1227 len > (unsigned int)(poutend - pout))) {
1228 elf_uncompress_failed();
1229 return 0;
1230 }
1231 memcpy(pout, pin, len);
1232 pout += len;
1233 pin += len;
1234
1235 while ((((uintptr_t)pin) & 3) != 0) {
1236 val |= (uint64_t)*pin << bits;
1237 bits += 8;
1238 ++pin;
1239 }
1240
1241 continue;
1242 }
1243
1244 if (type == 1) {
1245 tlit = elf_zlib_default_table;
1246 tdist = elf_zlib_default_dist_table;
1247 } else {
1248 unsigned int nlit;
1249 unsigned int ndist;
1250 unsigned int nclen;
1251 unsigned char codebits[19];
1252 unsigned char *plenbase;
1253 unsigned char *plen;
1254 unsigned char *plenend;
1255
1256 if (!elf_zlib_fetch(&pin, pinend, &val, &bits)) return 0;
1257
1258 nlit = (val & 0x1f) + 257;
1259 val >>= 5;
1260 ndist = (val & 0x1f) + 1;
1261 val >>= 5;
1262 nclen = (val & 0xf) + 4;
1263 val >>= 4;
1264 bits -= 14;
1265 if (unlikely(nlit > 286 || ndist > 30)) {
1266 elf_uncompress_failed();
1267 return 0;
1268 }
1269
1270 memset(&codebits[0], 0, 19);
1271
1272 if (!elf_zlib_fetch(&pin, pinend, &val, &bits)) return 0;
1273
1274 codebits[16] = val & 7;
1275 codebits[17] = (val >> 3) & 7;
1276 codebits[18] = (val >> 6) & 7;
1277 codebits[0] = (val >> 9) & 7;
1278 val >>= 12;
1279 bits -= 12;
1280
1281 if (nclen == 4) goto codebitsdone;
1282
1283 codebits[8] = val & 7;
1284 val >>= 3;
1285 bits -= 3;
1286
1287 if (nclen == 5) goto codebitsdone;
1288
1289 if (!elf_zlib_fetch(&pin, pinend, &val, &bits)) return 0;
1290
1291 codebits[7] = val & 7;
1292 val >>= 3;
1293 bits -= 3;
1294
1295 if (nclen == 6) goto codebitsdone;
1296
1297 codebits[9] = val & 7;
1298 val >>= 3;
1299 bits -= 3;
1300
1301 if (nclen == 7) goto codebitsdone;
1302
1303 codebits[6] = val & 7;
1304 val >>= 3;
1305 bits -= 3;
1306
1307 if (nclen == 8) goto codebitsdone;
1308
1309 codebits[10] = val & 7;
1310 val >>= 3;
1311 bits -= 3;
1312
1313 if (nclen == 9) goto codebitsdone;
1314
1315 codebits[5] = val & 7;
1316 val >>= 3;
1317 bits -= 3;
1318
1319 if (nclen == 10) goto codebitsdone;
1320
1321 if (!elf_zlib_fetch(&pin, pinend, &val, &bits)) return 0;
1322
1323 codebits[11] = val & 7;
1324 val >>= 3;
1325 bits -= 3;
1326
1327 if (nclen == 11) goto codebitsdone;
1328
1329 codebits[4] = val & 7;
1330 val >>= 3;
1331 bits -= 3;
1332
1333 if (nclen == 12) goto codebitsdone;
1334
1335 codebits[12] = val & 7;
1336 val >>= 3;
1337 bits -= 3;
1338
1339 if (nclen == 13) goto codebitsdone;
1340
1341 codebits[3] = val & 7;
1342 val >>= 3;
1343 bits -= 3;
1344
1345 if (nclen == 14) goto codebitsdone;
1346
1347 codebits[13] = val & 7;
1348 val >>= 3;
1349 bits -= 3;
1350
1351 if (nclen == 15) goto codebitsdone;
1352
1353 if (!elf_zlib_fetch(&pin, pinend, &val, &bits)) return 0;
1354
1355 codebits[2] = val & 7;
1356 val >>= 3;
1357 bits -= 3;
1358
1359 if (nclen == 16) goto codebitsdone;
1360
1361 codebits[14] = val & 7;
1362 val >>= 3;
1363 bits -= 3;
1364
1365 if (nclen == 17) goto codebitsdone;
1366
1367 codebits[1] = val & 7;
1368 val >>= 3;
1369 bits -= 3;
1370
1371 if (nclen == 18) goto codebitsdone;
1372
1373 codebits[15] = val & 7;
1374 val >>= 3;
1375 bits -= 3;
1376
1377 codebitsdone:
1378
1379 if (!elf_zlib_inflate_table(codebits, 19, zdebug_table, zdebug_table))
1380 return 0;
1381
1382 plenbase =
1383 (((unsigned char *)zdebug_table) + ZDEBUG_TABLE_CODELEN_OFFSET);
1384 plen = plenbase;
1385 plenend = plen + nlit + ndist;
1386 while (plen < plenend) {
1387 uint16_t t;
1388 unsigned int b;
1389 uint16_t v;
1390
1391 if (!elf_zlib_fetch(&pin, pinend, &val, &bits)) return 0;
1392
1393 t = zdebug_table[val & 0xff];
1394
1395 if (unlikely((t & (1U << HUFFMAN_SECONDARY_SHIFT)) != 0)) {
1396 elf_uncompress_failed();
1397 return 0;
1398 }
1399
1400 b = (t >> HUFFMAN_BITS_SHIFT) & HUFFMAN_BITS_MASK;
1401 val >>= b + 1;
1402 bits -= b + 1;
1403
1404 v = t & HUFFMAN_VALUE_MASK;
1405 if (v < 16)
1406 *plen++ = v;
1407 else if (v == 16) {
1408 unsigned int c;
1409 unsigned int prev;
1410
1411 if (unlikely(plen == plenbase)) {
1412 elf_uncompress_failed();
1413 return 0;
1414 }
1415
1416 c = 3 + (val & 0x3);
1417 val >>= 2;
1418 bits -= 2;
1419 if (unlikely((unsigned int)(plenend - plen) < c)) {
1420 elf_uncompress_failed();
1421 return 0;
1422 }
1423
1424 prev = plen[-1];
1425 switch (c) {
1426 case 6:
1427 *plen++ = prev;
1428 ATTRIBUTE_FALLTHROUGH;
1429 case 5:
1430 *plen++ = prev;
1431 ATTRIBUTE_FALLTHROUGH;
1432 case 4:
1433 *plen++ = prev;
1434 }
1435 *plen++ = prev;
1436 *plen++ = prev;
1437 *plen++ = prev;
1438 } else if (v == 17) {
1439 unsigned int c;
1440
1441 c = 3 + (val & 0x7);
1442 val >>= 3;
1443 bits -= 3;
1444 if (unlikely((unsigned int)(plenend - plen) < c)) {
1445 elf_uncompress_failed();
1446 return 0;
1447 }
1448
1449 switch (c) {
1450 case 10:
1451 *plen++ = 0;
1452 ATTRIBUTE_FALLTHROUGH;
1453 case 9:
1454 *plen++ = 0;
1455 ATTRIBUTE_FALLTHROUGH;
1456 case 8:
1457 *plen++ = 0;
1458 ATTRIBUTE_FALLTHROUGH;
1459 case 7:
1460 *plen++ = 0;
1461 ATTRIBUTE_FALLTHROUGH;
1462 case 6:
1463 *plen++ = 0;
1464 ATTRIBUTE_FALLTHROUGH;
1465 case 5:
1466 *plen++ = 0;
1467 ATTRIBUTE_FALLTHROUGH;
1468 case 4:
1469 *plen++ = 0;
1470 }
1471 *plen++ = 0;
1472 *plen++ = 0;
1473 *plen++ = 0;
1474 } else if (v == 18) {
1475 unsigned int c;
1476
1477 c = 11 + (val & 0x7f);
1478 val >>= 7;
1479 bits -= 7;
1480 if (unlikely((unsigned int)(plenend - plen) < c)) {
1481 elf_uncompress_failed();
1482 return 0;
1483 }
1484
1485 memset(plen, 0, c);
1486 plen += c;
1487 } else {
1488 elf_uncompress_failed();
1489 return 0;
1490 }
1491 }
1492
1493 plen = plenbase;
1494 if (unlikely(plen[256] == 0)) {
1495 elf_uncompress_failed();
1496 return 0;
1497 }
1498
1499 if (!elf_zlib_inflate_table(plen, nlit, zdebug_table, zdebug_table))
1500 return 0;
1501 if (!elf_zlib_inflate_table(plen + nlit, ndist, zdebug_table,
1502 zdebug_table + HUFFMAN_TABLE_SIZE))
1503 return 0;
1504 tlit = zdebug_table;
1505 tdist = zdebug_table + HUFFMAN_TABLE_SIZE;
1506 }
1507
1508 while (1) {
1509 uint16_t t;
1510 unsigned int b;
1511 uint16_t v;
1512 unsigned int lit;
1513
1514 if (!elf_zlib_fetch(&pin, pinend, &val, &bits)) return 0;
1515
1516 t = tlit[val & 0xff];
1517 b = (t >> HUFFMAN_BITS_SHIFT) & HUFFMAN_BITS_MASK;
1518 v = t & HUFFMAN_VALUE_MASK;
1519
1520 if ((t & (1U << HUFFMAN_SECONDARY_SHIFT)) == 0) {
1521 lit = v;
1522 val >>= b + 1;
1523 bits -= b + 1;
1524 } else {
1525 t = tlit[v + 0x100 + ((val >> 8) & ((1U << b) - 1))];
1526 b = (t >> HUFFMAN_BITS_SHIFT) & HUFFMAN_BITS_MASK;
1527 lit = t & HUFFMAN_VALUE_MASK;
1528 val >>= b + 8;
1529 bits -= b + 8;
1530 }
1531
1532 if (lit < 256) {
1533 if (unlikely(pout == poutend)) {
1534 elf_uncompress_failed();
1535 return 0;
1536 }
1537
1538 *pout++ = lit;
1539
1540 __builtin_prefetch(pout, 1, 3);
1541 } else if (lit == 256) {
1542 break;
1543 } else {
1544 unsigned int dist;
1545 unsigned int len;
1546
1547 if (lit < 265)
1548 len = lit - 257 + 3;
1549 else if (lit == 285)
1550 len = 258;
1551 else if (unlikely(lit > 285)) {
1552 elf_uncompress_failed();
1553 return 0;
1554 } else {
1555 unsigned int extra;
1556
1557 if (!elf_zlib_fetch(&pin, pinend, &val, &bits)) return 0;
1558
1559 lit -= 265;
1560 extra = (lit >> 2) + 1;
1561 len = (lit & 3) << extra;
1562 len += 11;
1563 len += ((1U << (extra - 1)) - 1) << 3;
1564 len += val & ((1U << extra) - 1);
1565 val >>= extra;
1566 bits -= extra;
1567 }
1568
1569 if (!elf_zlib_fetch(&pin, pinend, &val, &bits)) return 0;
1570
1571 t = tdist[val & 0xff];
1572 b = (t >> HUFFMAN_BITS_SHIFT) & HUFFMAN_BITS_MASK;
1573 v = t & HUFFMAN_VALUE_MASK;
1574
1575 if ((t & (1U << HUFFMAN_SECONDARY_SHIFT)) == 0) {
1576 dist = v;
1577 val >>= b + 1;
1578 bits -= b + 1;
1579 } else {
1580 t = tdist[v + 0x100 + ((val >> 8) & ((1U << b) - 1))];
1581 b = (t >> HUFFMAN_BITS_SHIFT) & HUFFMAN_BITS_MASK;
1582 dist = t & HUFFMAN_VALUE_MASK;
1583 val >>= b + 8;
1584 bits -= b + 8;
1585 }
1586
1587 if (dist == 0) {
1588 if (unlikely(pout == porigout)) {
1589 elf_uncompress_failed();
1590 return 0;
1591 }
1592
1593 if (unlikely((unsigned int)(poutend - pout) < len)) {
1594 elf_uncompress_failed();
1595 return 0;
1596 }
1597
1598 memset(pout, pout[-1], len);
1599 pout += len;
1600 } else if (unlikely(dist > 29)) {
1601 elf_uncompress_failed();
1602 return 0;
1603 } else {
1604 if (dist < 4)
1605 dist = dist + 1;
1606 else {
1607 unsigned int extra;
1608
1609 if (!elf_zlib_fetch(&pin, pinend, &val, &bits)) return 0;
1610
1611 dist -= 4;
1612 extra = (dist >> 1) + 1;
1613 dist = (dist & 1) << extra;
1614 dist += 5;
1615 dist += ((1U << (extra - 1)) - 1) << 2;
1616 dist += val & ((1U << extra) - 1);
1617 val >>= extra;
1618 bits -= extra;
1619 }
1620
1621 if (unlikely((unsigned int)(pout - porigout) < dist)) {
1622 elf_uncompress_failed();
1623 return 0;
1624 }
1625
1626 if (unlikely((unsigned int)(poutend - pout) < len)) {
1627 elf_uncompress_failed();
1628 return 0;
1629 }
1630
1631 if (dist >= len) {
1632 memcpy(pout, pout - dist, len);
1633 pout += len;
1634 } else {
1635 while (len > 0) {
1636 unsigned int copy;
1637
1638 copy = len < dist ? len : dist;
1639 memcpy(pout, pout - dist, copy);
1640 len -= copy;
1641 pout += copy;
1642 }
1643 }
1644 }
1645 }
1646 }
1647 }
1648 }
1649
1650 if (unlikely(pout != poutend)) {
1651 elf_uncompress_failed();
1652 return 0;
1653 }
1654
1655 return 1;
1656}
1657
1658static int elf_zlib_verify_checksum(const unsigned char *checkbytes,
1659 const unsigned char *uncompressed,
1660 size_t uncompressed_size) {
1661 unsigned int i;
1662 unsigned int cksum;
1663 const unsigned char *p;
1664 uint32_t s1;
1665 uint32_t s2;
1666 size_t hsz;
1667
1668 cksum = 0;
1669 for (i = 0; i < 4; i++) cksum = (cksum << 8) | checkbytes[i];
1670
1671 s1 = 1;
1672 s2 = 0;
1673
1674 p = uncompressed;
1675 hsz = uncompressed_size;
1676 while (hsz >= 5552) {
1677 for (i = 0; i < 5552; i += 16) {
1678 s1 = s1 + *p++;
1679 s2 = s2 + s1;
1680 s1 = s1 + *p++;
1681 s2 = s2 + s1;
1682 s1 = s1 + *p++;
1683 s2 = s2 + s1;
1684 s1 = s1 + *p++;
1685 s2 = s2 + s1;
1686 s1 = s1 + *p++;
1687 s2 = s2 + s1;
1688 s1 = s1 + *p++;
1689 s2 = s2 + s1;
1690 s1 = s1 + *p++;
1691 s2 = s2 + s1;
1692 s1 = s1 + *p++;
1693 s2 = s2 + s1;
1694 s1 = s1 + *p++;
1695 s2 = s2 + s1;
1696 s1 = s1 + *p++;
1697 s2 = s2 + s1;
1698 s1 = s1 + *p++;
1699 s2 = s2 + s1;
1700 s1 = s1 + *p++;
1701 s2 = s2 + s1;
1702 s1 = s1 + *p++;
1703 s2 = s2 + s1;
1704 s1 = s1 + *p++;
1705 s2 = s2 + s1;
1706 s1 = s1 + *p++;
1707 s2 = s2 + s1;
1708 s1 = s1 + *p++;
1709 s2 = s2 + s1;
1710 }
1711 hsz -= 5552;
1712 s1 %= 65521;
1713 s2 %= 65521;
1714 }
1715
1716 while (hsz >= 16) {
1717 s1 = s1 + *p++;
1718 s2 = s2 + s1;
1719 s1 = s1 + *p++;
1720 s2 = s2 + s1;
1721 s1 = s1 + *p++;
1722 s2 = s2 + s1;
1723 s1 = s1 + *p++;
1724 s2 = s2 + s1;
1725 s1 = s1 + *p++;
1726 s2 = s2 + s1;
1727 s1 = s1 + *p++;
1728 s2 = s2 + s1;
1729 s1 = s1 + *p++;
1730 s2 = s2 + s1;
1731 s1 = s1 + *p++;
1732 s2 = s2 + s1;
1733 s1 = s1 + *p++;
1734 s2 = s2 + s1;
1735 s1 = s1 + *p++;
1736 s2 = s2 + s1;
1737 s1 = s1 + *p++;
1738 s2 = s2 + s1;
1739 s1 = s1 + *p++;
1740 s2 = s2 + s1;
1741 s1 = s1 + *p++;
1742 s2 = s2 + s1;
1743 s1 = s1 + *p++;
1744 s2 = s2 + s1;
1745 s1 = s1 + *p++;
1746 s2 = s2 + s1;
1747 s1 = s1 + *p++;
1748 s2 = s2 + s1;
1749
1750 hsz -= 16;
1751 }
1752
1753 for (i = 0; i < hsz; ++i) {
1754 s1 = s1 + *p++;
1755 s2 = s2 + s1;
1756 }
1757
1758 s1 %= 65521;
1759 s2 %= 65521;
1760
1761 if (unlikely((s2 << 16) + s1 != cksum)) {
1762 elf_uncompress_failed();
1763 return 0;
1764 }
1765
1766 return 1;
1767}
1768
1769static int elf_zlib_inflate_and_verify(const unsigned char *pin, size_t sin,
1770 uint16_t *zdebug_table,
1771 unsigned char *pout, size_t sout) {
1772 if (!elf_zlib_inflate(pin, sin, zdebug_table, pout, sout)) return 0;
1773 if (!elf_zlib_verify_checksum(pin + sin - 4, pout, sout)) return 0;
1774 return 1;
1775}
1776
1777static int elf_uncompress_zdebug(struct backtrace_state *state,
1778 const unsigned char *compressed,
1779 size_t compressed_size, uint16_t *zdebug_table,
1780 backtrace_error_callback error_callback,
1781 void *data, unsigned char **uncompressed,
1782 size_t *uncompressed_size) {
1783 size_t sz;
1784 size_t i;
1785 unsigned char *po;
1786
1787 *uncompressed = NULL;
1788 *uncompressed_size = 0;
1789
1790 if (compressed_size < 12 || memcmp(compressed, "ZLIB", 4) != 0) return 1;
1791
1792 sz = 0;
1793 for (i = 0; i < 8; i++) sz = (sz << 8) | compressed[i + 4];
1794
1795 if (*uncompressed != NULL && *uncompressed_size >= sz)
1796 po = *uncompressed;
1797 else {
1798 po = (unsigned char *)backtrace_alloc(state, sz, error_callback, data);
1799 if (po == NULL) return 0;
1800 }
1801
1802 if (!elf_zlib_inflate_and_verify(compressed + 12, compressed_size - 12,
1803 zdebug_table, po, sz))
1804 return 1;
1805
1806 *uncompressed = po;
1807 *uncompressed_size = sz;
1808
1809 return 1;
1810}
1811
1812static int elf_uncompress_chdr(struct backtrace_state *state,
1813 const unsigned char *compressed,
1814 size_t compressed_size, uint16_t *zdebug_table,
1815 backtrace_error_callback error_callback,
1816 void *data, unsigned char **uncompressed,
1817 size_t *uncompressed_size) {
1818 const b_elf_chdr *chdr;
1819 unsigned char *po;
1820
1821 *uncompressed = NULL;
1822 *uncompressed_size = 0;
1823
1824 if (compressed_size < sizeof(b_elf_chdr)) return 1;
1825
1826 chdr = (const b_elf_chdr *)compressed;
1827
1828 if (chdr->ch_type != ELFCOMPRESS_ZLIB) {
1829 return 1;
1830 }
1831
1832 if (*uncompressed != NULL && *uncompressed_size >= chdr->ch_size)
1833 po = *uncompressed;
1834 else {
1835 po = (unsigned char *)backtrace_alloc(state, chdr->ch_size, error_callback,
1836 data);
1837 if (po == NULL) return 0;
1838 }
1839
1840 if (!elf_zlib_inflate_and_verify(compressed + sizeof(b_elf_chdr),
1841 compressed_size - sizeof(b_elf_chdr),
1842 zdebug_table, po, chdr->ch_size))
1843 return 1;
1844
1845 *uncompressed = po;
1846 *uncompressed_size = chdr->ch_size;
1847
1848 return 1;
1849}
1850
1851int backtrace_uncompress_zdebug(struct backtrace_state *state,
1852 const unsigned char *compressed,
1853 size_t compressed_size,
1854 backtrace_error_callback error_callback,
1855 void *data, unsigned char **uncompressed,
1856 size_t *uncompressed_size) {
1857 uint16_t *zdebug_table;
1858 int ret;
1859
1860 zdebug_table = ((uint16_t *)backtrace_alloc(state, ZDEBUG_TABLE_SIZE,
1861 error_callback, data));
1862 if (zdebug_table == NULL) return 0;
1863 ret = elf_uncompress_zdebug(state, compressed, compressed_size, zdebug_table,
1864 error_callback, data, uncompressed,
1865 uncompressed_size);
1866 backtrace_free(state, zdebug_table, ZDEBUG_TABLE_SIZE, error_callback, data);
1867 return ret;
1868}
1869
1870#define LZMA_STATES (12)
1871
1872#define LZMA_POS_STATES (16)
1873
1874#define LZMA_DIST_STATES (4)
1875
1876#define LZMA_DIST_SLOTS (64)
1877
1878#define LZMA_DIST_MODEL_START (4)
1879
1880#define LZMA_DIST_MODEL_END (14)
1881
1882#define LZMA_FULL_DISTANCES (128)
1883
1884#define LZMA_ALIGN_SIZE (16)
1885
1886#define LZMA_LEN_LOW_SYMBOLS (8)
1887#define LZMA_LEN_MID_SYMBOLS (8)
1888#define LZMA_LEN_HIGH_SYMBOLS (256)
1889
1890#define LZMA_LITERAL_CODERS_MAX (16)
1891#define LZMA_LITERAL_CODER_SIZE (0x300)
1892
1893#define LZMA_PROB_IS_MATCH_LEN (LZMA_STATES * LZMA_POS_STATES)
1894#define LZMA_PROB_IS_REP_LEN LZMA_STATES
1895#define LZMA_PROB_IS_REP0_LEN LZMA_STATES
1896#define LZMA_PROB_IS_REP1_LEN LZMA_STATES
1897#define LZMA_PROB_IS_REP2_LEN LZMA_STATES
1898#define LZMA_PROB_IS_REP0_LONG_LEN (LZMA_STATES * LZMA_POS_STATES)
1899#define LZMA_PROB_DIST_SLOT_LEN (LZMA_DIST_STATES * LZMA_DIST_SLOTS)
1900#define LZMA_PROB_DIST_SPECIAL_LEN (LZMA_FULL_DISTANCES - LZMA_DIST_MODEL_END)
1901#define LZMA_PROB_DIST_ALIGN_LEN LZMA_ALIGN_SIZE
1902#define LZMA_PROB_MATCH_LEN_CHOICE_LEN 1
1903#define LZMA_PROB_MATCH_LEN_CHOICE2_LEN 1
1904#define LZMA_PROB_MATCH_LEN_LOW_LEN (LZMA_POS_STATES * LZMA_LEN_LOW_SYMBOLS)
1905#define LZMA_PROB_MATCH_LEN_MID_LEN (LZMA_POS_STATES * LZMA_LEN_MID_SYMBOLS)
1906#define LZMA_PROB_MATCH_LEN_HIGH_LEN LZMA_LEN_HIGH_SYMBOLS
1907#define LZMA_PROB_REP_LEN_CHOICE_LEN 1
1908#define LZMA_PROB_REP_LEN_CHOICE2_LEN 1
1909#define LZMA_PROB_REP_LEN_LOW_LEN (LZMA_POS_STATES * LZMA_LEN_LOW_SYMBOLS)
1910#define LZMA_PROB_REP_LEN_MID_LEN (LZMA_POS_STATES * LZMA_LEN_MID_SYMBOLS)
1911#define LZMA_PROB_REP_LEN_HIGH_LEN LZMA_LEN_HIGH_SYMBOLS
1912#define LZMA_PROB_LITERAL_LEN \
1913 (LZMA_LITERAL_CODERS_MAX * LZMA_LITERAL_CODER_SIZE)
1914
1915#define LZMA_PROB_IS_MATCH_OFFSET 0
1916#define LZMA_PROB_IS_REP_OFFSET \
1917 (LZMA_PROB_IS_MATCH_OFFSET + LZMA_PROB_IS_MATCH_LEN)
1918#define LZMA_PROB_IS_REP0_OFFSET \
1919 (LZMA_PROB_IS_REP_OFFSET + LZMA_PROB_IS_REP_LEN)
1920#define LZMA_PROB_IS_REP1_OFFSET \
1921 (LZMA_PROB_IS_REP0_OFFSET + LZMA_PROB_IS_REP0_LEN)
1922#define LZMA_PROB_IS_REP2_OFFSET \
1923 (LZMA_PROB_IS_REP1_OFFSET + LZMA_PROB_IS_REP1_LEN)
1924#define LZMA_PROB_IS_REP0_LONG_OFFSET \
1925 (LZMA_PROB_IS_REP2_OFFSET + LZMA_PROB_IS_REP2_LEN)
1926#define LZMA_PROB_DIST_SLOT_OFFSET \
1927 (LZMA_PROB_IS_REP0_LONG_OFFSET + LZMA_PROB_IS_REP0_LONG_LEN)
1928#define LZMA_PROB_DIST_SPECIAL_OFFSET \
1929 (LZMA_PROB_DIST_SLOT_OFFSET + LZMA_PROB_DIST_SLOT_LEN)
1930#define LZMA_PROB_DIST_ALIGN_OFFSET \
1931 (LZMA_PROB_DIST_SPECIAL_OFFSET + LZMA_PROB_DIST_SPECIAL_LEN)
1932#define LZMA_PROB_MATCH_LEN_CHOICE_OFFSET \
1933 (LZMA_PROB_DIST_ALIGN_OFFSET + LZMA_PROB_DIST_ALIGN_LEN)
1934#define LZMA_PROB_MATCH_LEN_CHOICE2_OFFSET \
1935 (LZMA_PROB_MATCH_LEN_CHOICE_OFFSET + LZMA_PROB_MATCH_LEN_CHOICE_LEN)
1936#define LZMA_PROB_MATCH_LEN_LOW_OFFSET \
1937 (LZMA_PROB_MATCH_LEN_CHOICE2_OFFSET + LZMA_PROB_MATCH_LEN_CHOICE2_LEN)
1938#define LZMA_PROB_MATCH_LEN_MID_OFFSET \
1939 (LZMA_PROB_MATCH_LEN_LOW_OFFSET + LZMA_PROB_MATCH_LEN_LOW_LEN)
1940#define LZMA_PROB_MATCH_LEN_HIGH_OFFSET \
1941 (LZMA_PROB_MATCH_LEN_MID_OFFSET + LZMA_PROB_MATCH_LEN_MID_LEN)
1942#define LZMA_PROB_REP_LEN_CHOICE_OFFSET \
1943 (LZMA_PROB_MATCH_LEN_HIGH_OFFSET + LZMA_PROB_MATCH_LEN_HIGH_LEN)
1944#define LZMA_PROB_REP_LEN_CHOICE2_OFFSET \
1945 (LZMA_PROB_REP_LEN_CHOICE_OFFSET + LZMA_PROB_REP_LEN_CHOICE_LEN)
1946#define LZMA_PROB_REP_LEN_LOW_OFFSET \
1947 (LZMA_PROB_REP_LEN_CHOICE2_OFFSET + LZMA_PROB_REP_LEN_CHOICE2_LEN)
1948#define LZMA_PROB_REP_LEN_MID_OFFSET \
1949 (LZMA_PROB_REP_LEN_LOW_OFFSET + LZMA_PROB_REP_LEN_LOW_LEN)
1950#define LZMA_PROB_REP_LEN_HIGH_OFFSET \
1951 (LZMA_PROB_REP_LEN_MID_OFFSET + LZMA_PROB_REP_LEN_MID_LEN)
1952#define LZMA_PROB_LITERAL_OFFSET \
1953 (LZMA_PROB_REP_LEN_HIGH_OFFSET + LZMA_PROB_REP_LEN_HIGH_LEN)
1954
1955#define LZMA_PROB_TOTAL_COUNT (LZMA_PROB_LITERAL_OFFSET + LZMA_PROB_LITERAL_LEN)
1956
1957#if LZMA_PROB_TOTAL_COUNT != 1846 + (1 << 4) * 0x300
1958#error Wrong number of LZMA probabilities
1959#endif
1960
1961#define LZMA_IS_MATCH(state, pos) \
1962 (LZMA_PROB_IS_MATCH_OFFSET + (state)*LZMA_POS_STATES + (pos))
1963#define LZMA_IS_REP(state) (LZMA_PROB_IS_REP_OFFSET + (state))
1964#define LZMA_IS_REP0(state) (LZMA_PROB_IS_REP0_OFFSET + (state))
1965#define LZMA_IS_REP1(state) (LZMA_PROB_IS_REP1_OFFSET + (state))
1966#define LZMA_IS_REP2(state) (LZMA_PROB_IS_REP2_OFFSET + (state))
1967#define LZMA_IS_REP0_LONG(state, pos) \
1968 (LZMA_PROB_IS_REP0_LONG_OFFSET + (state)*LZMA_POS_STATES + (pos))
1969#define LZMA_DIST_SLOT(dist, slot) \
1970 (LZMA_PROB_DIST_SLOT_OFFSET + (dist)*LZMA_DIST_SLOTS + (slot))
1971#define LZMA_DIST_SPECIAL(dist) (LZMA_PROB_DIST_SPECIAL_OFFSET + (dist))
1972#define LZMA_DIST_ALIGN(dist) (LZMA_PROB_DIST_ALIGN_OFFSET + (dist))
1973#define LZMA_MATCH_LEN_CHOICE LZMA_PROB_MATCH_LEN_CHOICE_OFFSET
1974#define LZMA_MATCH_LEN_CHOICE2 LZMA_PROB_MATCH_LEN_CHOICE2_OFFSET
1975#define LZMA_MATCH_LEN_LOW(pos, sym) \
1976 (LZMA_PROB_MATCH_LEN_LOW_OFFSET + (pos)*LZMA_LEN_LOW_SYMBOLS + (sym))
1977#define LZMA_MATCH_LEN_MID(pos, sym) \
1978 (LZMA_PROB_MATCH_LEN_MID_OFFSET + (pos)*LZMA_LEN_MID_SYMBOLS + (sym))
1979#define LZMA_MATCH_LEN_HIGH(sym) (LZMA_PROB_MATCH_LEN_HIGH_OFFSET + (sym))
1980#define LZMA_REP_LEN_CHOICE LZMA_PROB_REP_LEN_CHOICE_OFFSET
1981#define LZMA_REP_LEN_CHOICE2 LZMA_PROB_REP_LEN_CHOICE2_OFFSET
1982#define LZMA_REP_LEN_LOW(pos, sym) \
1983 (LZMA_PROB_REP_LEN_LOW_OFFSET + (pos)*LZMA_LEN_LOW_SYMBOLS + (sym))
1984#define LZMA_REP_LEN_MID(pos, sym) \
1985 (LZMA_PROB_REP_LEN_MID_OFFSET + (pos)*LZMA_LEN_MID_SYMBOLS + (sym))
1986#define LZMA_REP_LEN_HIGH(sym) (LZMA_PROB_REP_LEN_HIGH_OFFSET + (sym))
1987#define LZMA_LITERAL(code, size) \
1988 (LZMA_PROB_LITERAL_OFFSET + (code)*LZMA_LITERAL_CODER_SIZE + (size))
1989
1990static int elf_lzma_varint(const unsigned char *compressed,
1991 size_t compressed_size, size_t *poffset,
1992 uint64_t *val) {
1993 size_t off;
1994 int i;
1995 uint64_t v;
1996 unsigned char b;
1997
1998 off = *poffset;
1999 i = 0;
2000 v = 0;
2001 while (1) {
2002 if (unlikely(off >= compressed_size)) {
2003 elf_uncompress_failed();
2004 return 0;
2005 }
2006 b = compressed[off];
2007 v |= (b & 0x7f) << (i * 7);
2008 ++off;
2009 if ((b & 0x80) == 0) {
2010 *poffset = off;
2011 *val = v;
2012 return 1;
2013 }
2014 ++i;
2015 if (unlikely(i >= 9)) {
2016 elf_uncompress_failed();
2017 return 0;
2018 }
2019 }
2020}
2021
2022static void elf_lzma_range_normalize(const unsigned char *compressed,
2023 size_t compressed_size, size_t *poffset,
2024 uint32_t *prange, uint32_t *pcode) {
2025 if (*prange < (1U << 24)) {
2026 if (unlikely(*poffset >= compressed_size)) {
2027 elf_uncompress_failed();
2028 return;
2029 }
2030 *prange <<= 8;
2031 *pcode <<= 8;
2032 *pcode += compressed[*poffset];
2033 ++*poffset;
2034 }
2035}
2036
2037static int elf_lzma_bit(const unsigned char *compressed, size_t compressed_size,
2038 uint16_t *prob, size_t *poffset, uint32_t *prange,
2039 uint32_t *pcode) {
2040 uint32_t bound;
2041
2042 elf_lzma_range_normalize(compressed, compressed_size, poffset, prange, pcode);
2043 bound = (*prange >> 11) * (uint32_t)*prob;
2044 if (*pcode < bound) {
2045 *prange = bound;
2046 *prob += ((1U << 11) - *prob) >> 5;
2047 return 0;
2048 } else {
2049 *prange -= bound;
2050 *pcode -= bound;
2051 *prob -= *prob >> 5;
2052 return 1;
2053 }
2054}
2055
2056static uint32_t elf_lzma_integer(const unsigned char *compressed,
2057 size_t compressed_size, uint16_t *probs,
2058 uint32_t bits, size_t *poffset,
2059 uint32_t *prange, uint32_t *pcode) {
2060 uint32_t sym;
2061 uint32_t i;
2062
2063 sym = 1;
2064 for (i = 0; i < bits; i++) {
2065 int bit;
2066
2067 bit = elf_lzma_bit(compressed, compressed_size, probs + sym, poffset,
2068 prange, pcode);
2069 sym <<= 1;
2070 sym += bit;
2071 }
2072 return sym - (1 << bits);
2073}
2074
2075static uint32_t elf_lzma_reverse_integer(const unsigned char *compressed,
2076 size_t compressed_size,
2077 uint16_t *probs, uint32_t bits,
2078 size_t *poffset, uint32_t *prange,
2079 uint32_t *pcode) {
2080 uint32_t sym;
2081 uint32_t val;
2082 uint32_t i;
2083
2084 sym = 1;
2085 val = 0;
2086 for (i = 0; i < bits; i++) {
2087 int bit;
2088
2089 bit = elf_lzma_bit(compressed, compressed_size, probs + sym, poffset,
2090 prange, pcode);
2091 sym <<= 1;
2092 sym += bit;
2093 val += bit << i;
2094 }
2095 return val;
2096}
2097
2098static uint32_t elf_lzma_len(const unsigned char *compressed,
2099 size_t compressed_size, uint16_t *probs,
2100 int is_rep, unsigned int pos_state,
2101 size_t *poffset, uint32_t *prange,
2102 uint32_t *pcode) {
2103 uint16_t *probs_choice;
2104 uint16_t *probs_sym;
2105 uint32_t bits;
2106 uint32_t len;
2107
2108 probs_choice = probs + (is_rep ? LZMA_REP_LEN_CHOICE : LZMA_MATCH_LEN_CHOICE);
2109 if (elf_lzma_bit(compressed, compressed_size, probs_choice, poffset, prange,
2110 pcode)) {
2111 probs_choice =
2112 probs + (is_rep ? LZMA_REP_LEN_CHOICE2 : LZMA_MATCH_LEN_CHOICE2);
2113 if (elf_lzma_bit(compressed, compressed_size, probs_choice, poffset, prange,
2114 pcode)) {
2115 probs_sym =
2116 probs + (is_rep ? LZMA_REP_LEN_HIGH(0) : LZMA_MATCH_LEN_HIGH(0));
2117 bits = 8;
2118 len = 2 + 8 + 8;
2119 } else {
2120 probs_sym = probs + (is_rep ? LZMA_REP_LEN_MID(pos_state, 0)
2121 : LZMA_MATCH_LEN_MID(pos_state, 0));
2122 bits = 3;
2123 len = 2 + 8;
2124 }
2125 } else {
2126 probs_sym = probs + (is_rep ? LZMA_REP_LEN_LOW(pos_state, 0)
2127 : LZMA_MATCH_LEN_LOW(pos_state, 0));
2128 bits = 3;
2129 len = 2;
2130 }
2131
2132 len += elf_lzma_integer(compressed, compressed_size, probs_sym, bits, poffset,
2133 prange, pcode);
2134 return len;
2135}
2136
2137static int elf_uncompress_lzma_block(const unsigned char *compressed,
2138 size_t compressed_size,
2139 unsigned char check, uint16_t *probs,
2140 unsigned char *uncompressed,
2141 size_t uncompressed_size,
2142 size_t *poffset) {
2143 size_t off;
2144 size_t block_header_offset;
2145 size_t block_header_size;
2146 unsigned char block_flags;
2147 uint64_t header_compressed_size;
2148 uint64_t header_uncompressed_size;
2149 unsigned char lzma2_properties;
2150 uint32_t computed_crc;
2151 uint32_t stream_crc;
2152 size_t uncompressed_offset;
2153 size_t dict_start_offset;
2154 unsigned int lc;
2155 unsigned int lp;
2156 unsigned int pb;
2157 uint32_t range;
2158 uint32_t code;
2159 uint32_t lstate;
2160 uint32_t dist[4];
2161
2162 off = *poffset;
2163 block_header_offset = off;
2164
2165 if (unlikely(off >= compressed_size)) {
2166 elf_uncompress_failed();
2167 return 0;
2168 }
2169 block_header_size = (compressed[off] + 1) * 4;
2170 if (unlikely(off + block_header_size > compressed_size)) {
2171 elf_uncompress_failed();
2172 return 0;
2173 }
2174
2175 block_flags = compressed[off + 1];
2176 if (unlikely((block_flags & 0x3c) != 0)) {
2177 elf_uncompress_failed();
2178 return 0;
2179 }
2180
2181 off += 2;
2182
2183 header_compressed_size = 0;
2184 if ((block_flags & 0x40) != 0) {
2185 *poffset = off;
2186 if (!elf_lzma_varint(compressed, compressed_size, poffset,
2187 &header_compressed_size))
2188 return 0;
2189 off = *poffset;
2190 }
2191
2192 header_uncompressed_size = 0;
2193 if ((block_flags & 0x80) != 0) {
2194 *poffset = off;
2195 if (!elf_lzma_varint(compressed, compressed_size, poffset,
2196 &header_uncompressed_size))
2197 return 0;
2198 off = *poffset;
2199 }
2200
2201 if (unlikely((block_flags & 0x3) != 0)) {
2202 elf_uncompress_failed();
2203 return 0;
2204 }
2205
2206 if (unlikely(off + 2 >= block_header_offset + block_header_size)) {
2207 elf_uncompress_failed();
2208 return 0;
2209 }
2210
2211 if (unlikely(compressed[off] != 0x21)) {
2212 elf_uncompress_failed();
2213 return 0;
2214 }
2215 ++off;
2216
2217 if (unlikely(compressed[off] != 1)) {
2218 elf_uncompress_failed();
2219 return 0;
2220 }
2221 ++off;
2222
2223 lzma2_properties = compressed[off];
2224 ++off;
2225
2226 if (unlikely(lzma2_properties > 40)) {
2227 elf_uncompress_failed();
2228 return 0;
2229 }
2230
2231 if (unlikely(off + 4 > compressed_size)) {
2232 elf_uncompress_failed();
2233 return 0;
2234 }
2235
2236 off = (off + 3) & ~(size_t)3;
2237
2238 if (unlikely(off + 4 > compressed_size)) {
2239 elf_uncompress_failed();
2240 return 0;
2241 }
2242
2243 computed_crc =
2244 elf_crc32(0, compressed + block_header_offset, block_header_size - 4);
2245 stream_crc = (compressed[off] | (compressed[off + 1] << 8) |
2246 (compressed[off + 2] << 16) | (compressed[off + 3] << 24));
2247 if (unlikely(computed_crc != stream_crc)) {
2248 elf_uncompress_failed();
2249 return 0;
2250 }
2251 off += 4;
2252
2253 uncompressed_offset = 0;
2254 dict_start_offset = 0;
2255 lc = 0;
2256 lp = 0;
2257 pb = 0;
2258 lstate = 0;
2259 while (off < compressed_size) {
2260 unsigned char control;
2261
2262 range = 0xffffffff;
2263 code = 0;
2264
2265 control = compressed[off];
2266 ++off;
2267 if (unlikely(control == 0)) {
2268 break;
2269 }
2270
2271 if (control == 1 || control >= 0xe0) {
2272 dict_start_offset = uncompressed_offset;
2273 }
2274
2275 if (control < 0x80) {
2276 size_t chunk_size;
2277
2278 if (unlikely(control > 2)) {
2279 elf_uncompress_failed();
2280 return 0;
2281 }
2282
2283 if (unlikely(off + 2 > compressed_size)) {
2284 elf_uncompress_failed();
2285 return 0;
2286 }
2287
2288 chunk_size = compressed[off] << 8;
2289 chunk_size += compressed[off + 1];
2290 ++chunk_size;
2291
2292 off += 2;
2293
2294 if (unlikely(off + chunk_size > compressed_size)) {
2295 elf_uncompress_failed();
2296 return 0;
2297 }
2298 if (unlikely(uncompressed_offset + chunk_size > uncompressed_size)) {
2299 elf_uncompress_failed();
2300 return 0;
2301 }
2302
2303 memcpy(uncompressed + uncompressed_offset, compressed + off, chunk_size);
2304 uncompressed_offset += chunk_size;
2305 off += chunk_size;
2306 } else {
2307 size_t uncompressed_chunk_start;
2308 size_t uncompressed_chunk_size;
2309 size_t compressed_chunk_size;
2310 size_t limit;
2311
2312 if (unlikely(off + 4 >= compressed_size)) {
2313 elf_uncompress_failed();
2314 return 0;
2315 }
2316
2317 uncompressed_chunk_start = uncompressed_offset;
2318
2319 uncompressed_chunk_size = (control & 0x1f) << 16;
2320 uncompressed_chunk_size += compressed[off] << 8;
2321 uncompressed_chunk_size += compressed[off + 1];
2322 ++uncompressed_chunk_size;
2323
2324 compressed_chunk_size = compressed[off + 2] << 8;
2325 compressed_chunk_size += compressed[off + 3];
2326 ++compressed_chunk_size;
2327
2328 off += 4;
2329
2330 if (control >= 0xc0) {
2331 unsigned char props;
2332
2333 if (unlikely(off >= compressed_size)) {
2334 elf_uncompress_failed();
2335 return 0;
2336 }
2337 props = compressed[off];
2338 ++off;
2339 if (unlikely(props > (4 * 5 + 4) * 9 + 8)) {
2340 elf_uncompress_failed();
2341 return 0;
2342 }
2343 pb = 0;
2344 while (props >= 9 * 5) {
2345 props -= 9 * 5;
2346 ++pb;
2347 }
2348 lp = 0;
2349 while (props > 9) {
2350 props -= 9;
2351 ++lp;
2352 }
2353 lc = props;
2354 if (unlikely(lc + lp > 4)) {
2355 elf_uncompress_failed();
2356 return 0;
2357 }
2358 }
2359
2360 if (control >= 0xa0) {
2361 size_t i;
2362
2363 lstate = 0;
2364 memset(&dist, 0, sizeof dist);
2365 for (i = 0; i < LZMA_PROB_TOTAL_COUNT; i++) probs[i] = 1 << 10;
2366 range = 0xffffffff;
2367 code = 0;
2368 }
2369
2370 if (unlikely(off + 5 > compressed_size)) {
2371 elf_uncompress_failed();
2372 return 0;
2373 }
2374
2375 code = ((compressed[off + 1] << 24) + (compressed[off + 2] << 16) +
2376 (compressed[off + 3] << 8) + compressed[off + 4]);
2377 off += 5;
2378
2379 limit = off + compressed_chunk_size;
2380 *poffset = off;
2381 while (*poffset < limit) {
2382 unsigned int pos_state;
2383
2384 if (unlikely(uncompressed_offset ==
2385 (uncompressed_chunk_start + uncompressed_chunk_size))) {
2386 break;
2387 }
2388
2389 pos_state =
2390 ((uncompressed_offset - dict_start_offset) & ((1 << pb) - 1));
2391
2392 if (elf_lzma_bit(compressed, compressed_size,
2393 probs + LZMA_IS_MATCH(lstate, pos_state), poffset,
2394 &range, &code)) {
2395 uint32_t len;
2396
2397 if (elf_lzma_bit(compressed, compressed_size,
2398 probs + LZMA_IS_REP(lstate), poffset, &range,
2399 &code)) {
2400 int short_rep;
2401 uint32_t next_dist;
2402
2403 short_rep = 0;
2404 if (elf_lzma_bit(compressed, compressed_size,
2405 probs + LZMA_IS_REP0(lstate), poffset, &range,
2406 &code)) {
2407 if (elf_lzma_bit(compressed, compressed_size,
2408 probs + LZMA_IS_REP1(lstate), poffset, &range,
2409 &code)) {
2410 if (elf_lzma_bit(compressed, compressed_size,
2411 probs + LZMA_IS_REP2(lstate), poffset, &range,
2412 &code)) {
2413 next_dist = dist[3];
2414 dist[3] = dist[2];
2415 } else {
2416 next_dist = dist[2];
2417 }
2418 dist[2] = dist[1];
2419 } else {
2420 next_dist = dist[1];
2421 }
2422
2423 dist[1] = dist[0];
2424 dist[0] = next_dist;
2425 } else {
2426 if (!elf_lzma_bit(compressed, compressed_size,
2427 (probs + LZMA_IS_REP0_LONG(lstate, pos_state)),
2428 poffset, &range, &code))
2429 short_rep = 1;
2430 }
2431
2432 if (lstate < 7)
2433 lstate = short_rep ? 9 : 8;
2434 else
2435 lstate = 11;
2436
2437 if (short_rep)
2438 len = 1;
2439 else
2440 len = elf_lzma_len(compressed, compressed_size, probs, 1,
2441 pos_state, poffset, &range, &code);
2442 } else {
2443 uint32_t dist_state;
2444 uint32_t dist_slot;
2445 uint16_t *probs_dist;
2446
2447 if (lstate < 7)
2448 lstate = 7;
2449 else
2450 lstate = 10;
2451 dist[3] = dist[2];
2452 dist[2] = dist[1];
2453 dist[1] = dist[0];
2454 len = elf_lzma_len(compressed, compressed_size, probs, 0, pos_state,
2455 poffset, &range, &code);
2456
2457 if (len < 4 + 2)
2458 dist_state = len - 2;
2459 else
2460 dist_state = 3;
2461 probs_dist = probs + LZMA_DIST_SLOT(dist_state, 0);
2462 dist_slot = elf_lzma_integer(compressed, compressed_size,
2463 probs_dist, 6, poffset, &range, &code);
2464 if (dist_slot < LZMA_DIST_MODEL_START)
2465 dist[0] = dist_slot;
2466 else {
2467 uint32_t limit;
2468
2469 limit = (dist_slot >> 1) - 1;
2470 dist[0] = 2 + (dist_slot & 1);
2471 if (dist_slot < LZMA_DIST_MODEL_END) {
2472 dist[0] <<= limit;
2473 probs_dist =
2474 (probs + LZMA_DIST_SPECIAL(dist[0] - dist_slot - 1));
2475 dist[0] += elf_lzma_reverse_integer(compressed, compressed_size,
2476 probs_dist, limit, poffset,
2477 &range, &code);
2478 } else {
2479 uint32_t dist0;
2480 uint32_t i;
2481
2482 dist0 = dist[0];
2483 for (i = 0; i < limit - 4; i++) {
2484 uint32_t mask;
2485
2486 elf_lzma_range_normalize(compressed, compressed_size, poffset,
2487 &range, &code);
2488 range >>= 1;
2489 code -= range;
2490 mask = -(code >> 31);
2491 code += range & mask;
2492 dist0 <<= 1;
2493 dist0 += mask + 1;
2494 }
2495 dist0 <<= 4;
2496 probs_dist = probs + LZMA_DIST_ALIGN(0);
2497 dist0 += elf_lzma_reverse_integer(compressed, compressed_size,
2498 probs_dist, 4, poffset,
2499 &range, &code);
2500 dist[0] = dist0;
2501 }
2502 }
2503 }
2504
2505 if (unlikely(uncompressed_offset - dict_start_offset < dist[0] + 1)) {
2506 elf_uncompress_failed();
2507 return 0;
2508 }
2509 if (unlikely(uncompressed_offset + len > uncompressed_size)) {
2510 elf_uncompress_failed();
2511 return 0;
2512 }
2513
2514 if (dist[0] == 0) {
2515 memset(uncompressed + uncompressed_offset,
2516 uncompressed[uncompressed_offset - 1], len);
2517 uncompressed_offset += len;
2518 } else if (dist[0] + 1 >= len) {
2519 memcpy(uncompressed + uncompressed_offset,
2520 uncompressed + uncompressed_offset - dist[0] - 1, len);
2521 uncompressed_offset += len;
2522 } else {
2523 while (len > 0) {
2524 uint32_t copy;
2525
2526 copy = len < dist[0] + 1 ? len : dist[0] + 1;
2527 memcpy(uncompressed + uncompressed_offset,
2528 (uncompressed + uncompressed_offset - dist[0] - 1), copy);
2529 len -= copy;
2530 uncompressed_offset += copy;
2531 }
2532 }
2533 } else {
2534 unsigned char prev;
2535 unsigned char low;
2536 size_t high;
2537 uint16_t *lit_probs;
2538 unsigned int sym;
2539
2540 if (uncompressed_offset > 0)
2541 prev = uncompressed[uncompressed_offset - 1];
2542 else
2543 prev = 0;
2544 low = prev >> (8 - lc);
2545 high = (((uncompressed_offset - dict_start_offset) & ((1 << lp) - 1))
2546 << lc);
2547 lit_probs = probs + LZMA_LITERAL(low + high, 0);
2548 if (lstate < 7)
2549 sym = elf_lzma_integer(compressed, compressed_size, lit_probs, 8,
2550 poffset, &range, &code);
2551 else {
2552 unsigned int match;
2553 unsigned int bit;
2554 unsigned int match_bit;
2555 unsigned int idx;
2556
2557 sym = 1;
2558 if (uncompressed_offset >= dist[0] + 1)
2559 match = uncompressed[uncompressed_offset - dist[0] - 1];
2560 else
2561 match = 0;
2562 match <<= 1;
2563 bit = 0x100;
2564 do {
2565 match_bit = match & bit;
2566 match <<= 1;
2567 idx = bit + match_bit + sym;
2568 sym <<= 1;
2569 if (elf_lzma_bit(compressed, compressed_size, lit_probs + idx,
2570 poffset, &range, &code)) {
2571 ++sym;
2572 bit &= match_bit;
2573 } else {
2574 bit &= ~match_bit;
2575 }
2576 } while (sym < 0x100);
2577 }
2578
2579 if (unlikely(uncompressed_offset >= uncompressed_size)) {
2580 elf_uncompress_failed();
2581 return 0;
2582 }
2583
2584 uncompressed[uncompressed_offset] = (unsigned char)sym;
2585 ++uncompressed_offset;
2586 if (lstate <= 3)
2587 lstate = 0;
2588 else if (lstate <= 9)
2589 lstate -= 3;
2590 else
2591 lstate -= 6;
2592 }
2593 }
2594
2595 elf_lzma_range_normalize(compressed, compressed_size, poffset, &range,
2596 &code);
2597
2598 off = *poffset;
2599 }
2600 }
2601
2602 off = (off + 3) & ~(size_t)3;
2603 if (unlikely(off > compressed_size)) {
2604 elf_uncompress_failed();
2605 return 0;
2606 }
2607
2608 switch (check) {
2609 case 0:
2610
2611 break;
2612
2613 case 1:
2614
2615 if (unlikely(off + 4 > compressed_size)) {
2616 elf_uncompress_failed();
2617 return 0;
2618 }
2619 computed_crc = elf_crc32(0, uncompressed, uncompressed_offset);
2620 stream_crc = (compressed[off] | (compressed[off + 1] << 8) |
2621 (compressed[off + 2] << 16) | (compressed[off + 3] << 24));
2622 if (computed_crc != stream_crc) {
2623 elf_uncompress_failed();
2624 return 0;
2625 }
2626 off += 4;
2627 break;
2628
2629 case 4:
2630
2631 if (unlikely(off + 8 > compressed_size)) {
2632 elf_uncompress_failed();
2633 return 0;
2634 }
2635 off += 8;
2636 break;
2637
2638 case 10:
2639
2640 if (unlikely(off + 32 > compressed_size)) {
2641 elf_uncompress_failed();
2642 return 0;
2643 }
2644 off += 32;
2645 break;
2646
2647 default:
2648 elf_uncompress_failed();
2649 return 0;
2650 }
2651
2652 *poffset = off;
2653
2654 return 1;
2655}
2656
2657static int elf_uncompress_lzma(struct backtrace_state *state,
2658 const unsigned char *compressed,
2659 size_t compressed_size,
2660 backtrace_error_callback error_callback,
2661 void *data, unsigned char **uncompressed,
2662 size_t *uncompressed_size) {
2663 size_t header_size;
2664 size_t footer_size;
2665 unsigned char check;
2666 uint32_t computed_crc;
2667 uint32_t stream_crc;
2668 size_t offset;
2669 size_t index_size;
2670 size_t footer_offset;
2671 size_t index_offset;
2672 uint64_t index_compressed_size;
2673 uint64_t index_uncompressed_size;
2674 unsigned char *mem;
2675 uint16_t *probs;
2676 size_t compressed_block_size;
2677
2678 header_size = 12;
2679 footer_size = 12;
2680 if (unlikely(compressed_size < header_size + footer_size)) {
2681 elf_uncompress_failed();
2682 return 0;
2683 }
2684
2685 if (unlikely(memcmp(compressed,
2686 "\375"
2687 "7zXZ\0",
2688 6) != 0)) {
2689 elf_uncompress_failed();
2690 return 0;
2691 }
2692
2693 if (unlikely(compressed[6] != 0)) {
2694 elf_uncompress_failed();
2695 return 0;
2696 }
2697 check = compressed[7];
2698 if (unlikely((check & 0xf8) != 0)) {
2699 elf_uncompress_failed();
2700 return 0;
2701 }
2702
2703 computed_crc = elf_crc32(0, compressed + 6, 2);
2704 stream_crc = (compressed[8] | (compressed[9] << 8) | (compressed[10] << 16) |
2705 (compressed[11] << 24));
2706 if (unlikely(computed_crc != stream_crc)) {
2707 elf_uncompress_failed();
2708 return 0;
2709 }
2710
2711 offset = compressed_size;
2712 if (unlikely(memcmp(compressed + offset - 2, "YZ", 2) != 0)) {
2713 elf_uncompress_failed();
2714 return 0;
2715 }
2716 offset -= 2;
2717
2718 if (unlikely(compressed[offset - 2] != 0 ||
2719 compressed[offset - 1] != check)) {
2720 elf_uncompress_failed();
2721 return 0;
2722 }
2723 offset -= 2;
2724
2725 index_size =
2726 (compressed[offset - 4] | (compressed[offset - 3] << 8) |
2727 (compressed[offset - 2] << 16) | (compressed[offset - 1] << 24));
2728 index_size = (index_size + 1) * 4;
2729 offset -= 4;
2730
2731 computed_crc = elf_crc32(0, compressed + offset, 6);
2732 stream_crc =
2733 (compressed[offset - 4] | (compressed[offset - 3] << 8) |
2734 (compressed[offset - 2] << 16) | (compressed[offset - 1] << 24));
2735 if (unlikely(computed_crc != stream_crc)) {
2736 elf_uncompress_failed();
2737 return 0;
2738 }
2739 offset -= 4;
2740
2741 if (unlikely(offset < index_size + header_size)) {
2742 elf_uncompress_failed();
2743 return 0;
2744 }
2745
2746 footer_offset = offset;
2747 offset -= index_size;
2748 index_offset = offset;
2749
2750 if (unlikely(compressed[offset] != 0)) {
2751 elf_uncompress_failed();
2752 return 0;
2753 }
2754 ++offset;
2755
2756 if (unlikely(compressed[offset] == 0)) {
2757 *uncompressed = NULL;
2758 *uncompressed_size = 0;
2759 return 1;
2760 }
2761 if (unlikely(compressed[offset] != 1)) {
2762 elf_uncompress_failed();
2763 return 0;
2764 }
2765 ++offset;
2766
2767 if (!elf_lzma_varint(compressed, compressed_size, &offset,
2768 &index_compressed_size))
2769 return 0;
2770 if (!elf_lzma_varint(compressed, compressed_size, &offset,
2771 &index_uncompressed_size))
2772 return 0;
2773
2774 offset = (offset + 3) & ~(size_t)3;
2775
2776 computed_crc = elf_crc32(0, compressed + index_offset, offset - index_offset);
2777 stream_crc =
2778 (compressed[offset] | (compressed[offset + 1] << 8) |
2779 (compressed[offset + 2] << 16) | (compressed[offset + 3] << 24));
2780 if (unlikely(computed_crc != stream_crc)) {
2781 elf_uncompress_failed();
2782 return 0;
2783 }
2784 offset += 4;
2785
2786 if (unlikely(offset != footer_offset)) {
2787 elf_uncompress_failed();
2788 return 0;
2789 }
2790
2791 mem = (unsigned char *)backtrace_alloc(state, index_uncompressed_size,
2792 error_callback, data);
2793 if (unlikely(mem == NULL)) return 0;
2794 *uncompressed = mem;
2795 *uncompressed_size = index_uncompressed_size;
2796
2797 probs = ((uint16_t *)backtrace_alloc(
2798 state, LZMA_PROB_TOTAL_COUNT * sizeof(uint16_t), error_callback, data));
2799 if (unlikely(probs == NULL)) {
2800 backtrace_free(state, mem, index_uncompressed_size, error_callback, data);
2801 return 0;
2802 }
2803
2804 offset = 12;
2805 if (!elf_uncompress_lzma_block(compressed, compressed_size, check, probs, mem,
2806 index_uncompressed_size, &offset)) {
2807 backtrace_free(state, mem, index_uncompressed_size, error_callback, data);
2808 return 0;
2809 }
2810
2811 compressed_block_size = offset - 12;
2812 if (unlikely(compressed_block_size !=
2813 ((index_compressed_size + 3) & ~(size_t)3))) {
2814 elf_uncompress_failed();
2815 backtrace_free(state, mem, index_uncompressed_size, error_callback, data);
2816 return 0;
2817 }
2818
2819 offset = (offset + 3) & ~(size_t)3;
2820 if (unlikely(offset != index_offset)) {
2821 elf_uncompress_failed();
2822 backtrace_free(state, mem, index_uncompressed_size, error_callback, data);
2823 return 0;
2824 }
2825
2826 return 1;
2827}
2828
2829int backtrace_uncompress_lzma(struct backtrace_state *state,
2830 const unsigned char *compressed,
2831 size_t compressed_size,
2832 backtrace_error_callback error_callback,
2833 void *data, unsigned char **uncompressed,
2834 size_t *uncompressed_size) {
2835 return elf_uncompress_lzma(state, compressed, compressed_size, error_callback,
2836 data, uncompressed, uncompressed_size);
2837}
2838
2839static int elf_add(struct backtrace_state *state, const char *filename,
2840 int descriptor, const unsigned char *memory,
2841 size_t memory_size, uintptr_t base_address,
2842 backtrace_error_callback error_callback, void *data,
2843 fileline *fileline_fn, int *found_sym, int *found_dwarf,
2844 struct dwarf_data **fileline_entry, int exe, int debuginfo,
2845 const char *with_buildid_data, uint32_t with_buildid_size) {
2846 struct elf_view ehdr_view;
2847 b_elf_ehdr ehdr;
2848 off_t shoff;
2849 unsigned int shnum;
2850 unsigned int shstrndx;
2851 struct elf_view shdrs_view;
2852 int shdrs_view_valid;
2853 const b_elf_shdr *shdrs;
2854 const b_elf_shdr *shstrhdr;
2855 size_t shstr_size;
2856 off_t shstr_off;
2857 struct elf_view names_view;
2858 int names_view_valid;
2859 const char *names;
2860 unsigned int symtab_shndx;
2861 unsigned int dynsym_shndx;
2862 unsigned int i;
2863 struct debug_section_info sections[DEBUG_MAX];
2864 struct debug_section_info zsections[DEBUG_MAX];
2865 struct elf_view symtab_view;
2866 int symtab_view_valid;
2867 struct elf_view strtab_view;
2868 int strtab_view_valid;
2869 struct elf_view buildid_view;
2870 int buildid_view_valid;
2871 const char *buildid_data;
2872 uint32_t buildid_size;
2873 struct elf_view debuglink_view;
2874 int debuglink_view_valid;
2875 const char *debuglink_name;
2876 uint32_t debuglink_crc;
2877 struct elf_view debugaltlink_view;
2878 int debugaltlink_view_valid;
2879 const char *debugaltlink_name;
2880 const char *debugaltlink_buildid_data;
2881 uint32_t debugaltlink_buildid_size;
2882 struct elf_view gnu_debugdata_view;
2883 int gnu_debugdata_view_valid;
2884 size_t gnu_debugdata_size;
2885 unsigned char *gnu_debugdata_uncompressed;
2886 size_t gnu_debugdata_uncompressed_size;
2887 off_t min_offset;
2888 off_t max_offset;
2889 off_t debug_size;
2890 struct elf_view debug_view;
2891 int debug_view_valid;
2892 unsigned int using_debug_view;
2893 uint16_t *zdebug_table;
2894 struct elf_view split_debug_view[DEBUG_MAX];
2895 unsigned char split_debug_view_valid[DEBUG_MAX];
2896 struct elf_ppc64_opd_data opd_data, *opd;
2897 struct dwarf_sections dwarf_sections;
2898
2899 if (!debuginfo) {
2900 *found_sym = 0;
2901 *found_dwarf = 0;
2902 }
2903
2904 shdrs_view_valid = 0;
2905 names_view_valid = 0;
2906 symtab_view_valid = 0;
2907 strtab_view_valid = 0;
2908 buildid_view_valid = 0;
2909 buildid_data = NULL;
2910 buildid_size = 0;
2911 debuglink_view_valid = 0;
2912 debuglink_name = NULL;
2913 debuglink_crc = 0;
2914 debugaltlink_view_valid = 0;
2915 debugaltlink_name = NULL;
2916 debugaltlink_buildid_data = NULL;
2917 debugaltlink_buildid_size = 0;
2918 gnu_debugdata_view_valid = 0;
2919 gnu_debugdata_size = 0;
2920 debug_view_valid = 0;
2921 memset(&split_debug_view_valid[0], 0, sizeof split_debug_view_valid);
2922 opd = NULL;
2923
2924 if (!elf_get_view(state, descriptor, memory, memory_size, 0, sizeof ehdr,
2925 error_callback, data, &ehdr_view))
2926 goto fail;
2927
2928 memcpy(&ehdr, ehdr_view.view.data, sizeof ehdr);
2929
2930 elf_release_view(state, &ehdr_view, error_callback, data);
2931
2932 if (ehdr.e_ident[EI_MAG0] != ELFMAG0 || ehdr.e_ident[EI_MAG1] != ELFMAG1 ||
2933 ehdr.e_ident[EI_MAG2] != ELFMAG2 || ehdr.e_ident[EI_MAG3] != ELFMAG3) {
2934 error_callback(data, "executable file is not ELF", 0);
2935 goto fail;
2936 }
2937 if (ehdr.e_ident[EI_VERSION] != EV_CURRENT) {
2938 error_callback(data, "executable file is unrecognized ELF version", 0);
2939 goto fail;
2940 }
2941
2942#if BACKTRACE_ELF_SIZE == 32
2943#define BACKTRACE_ELFCLASS ELFCLASS32
2944#else
2945#define BACKTRACE_ELFCLASS ELFCLASS64
2946#endif
2947
2948 if (ehdr.e_ident[EI_CLASS] != BACKTRACE_ELFCLASS) {
2949 error_callback(data, "executable file is unexpected ELF class", 0);
2950 goto fail;
2951 }
2952
2953 if (ehdr.e_ident[EI_DATA] != ELFDATA2LSB &&
2954 ehdr.e_ident[EI_DATA] != ELFDATA2MSB) {
2955 error_callback(data, "executable file has unknown endianness", 0);
2956 goto fail;
2957 }
2958
2959 if (exe && ehdr.e_type == ET_DYN) return -1;
2960
2961 shoff = ehdr.e_shoff;
2962 shnum = ehdr.e_shnum;
2963 shstrndx = ehdr.e_shstrndx;
2964
2965 if ((shnum == 0 || shstrndx == SHN_XINDEX) && shoff != 0) {
2966 struct elf_view shdr_view;
2967 const b_elf_shdr *shdr;
2968
2969 if (!elf_get_view(state, descriptor, memory, memory_size, shoff,
2970 sizeof shdr, error_callback, data, &shdr_view))
2971 goto fail;
2972
2973 shdr = (const b_elf_shdr *)shdr_view.view.data;
2974
2975 if (shnum == 0) shnum = shdr->sh_size;
2976
2977 if (shstrndx == SHN_XINDEX) {
2978 shstrndx = shdr->sh_link;
2979
2980 if (shstrndx >= shnum && shstrndx >= SHN_LORESERVE + 0x100)
2981 shstrndx -= 0x100;
2982 }
2983
2984 elf_release_view(state, &shdr_view, error_callback, data);
2985 }
2986
2987 if (shnum == 0 || shstrndx == 0) goto fail;
2988
2989 if (!elf_get_view(
2990 state, descriptor, memory, memory_size, shoff + sizeof(b_elf_shdr),
2991 (shnum - 1) * sizeof(b_elf_shdr), error_callback, data, &shdrs_view))
2992 goto fail;
2993 shdrs_view_valid = 1;
2994 shdrs = (const b_elf_shdr *)shdrs_view.view.data;
2995
2996 shstrhdr = &shdrs[shstrndx - 1];
2997 shstr_size = shstrhdr->sh_size;
2998 shstr_off = shstrhdr->sh_offset;
2999
3000 if (!elf_get_view(state, descriptor, memory, memory_size, shstr_off,
3001 shstrhdr->sh_size, error_callback, data, &names_view))
3002 goto fail;
3003 names_view_valid = 1;
3004 names = (const char *)names_view.view.data;
3005
3006 symtab_shndx = 0;
3007 dynsym_shndx = 0;
3008
3009 memset(sections, 0, sizeof sections);
3010 memset(zsections, 0, sizeof zsections);
3011
3012 for (i = 1; i < shnum; ++i) {
3013 const b_elf_shdr *shdr;
3014 unsigned int sh_name;
3015 const char *name;
3016 int j;
3017
3018 shdr = &shdrs[i - 1];
3019
3020 if (shdr->sh_type == SHT_SYMTAB)
3021 symtab_shndx = i;
3022 else if (shdr->sh_type == SHT_DYNSYM)
3023 dynsym_shndx = i;
3024
3025 sh_name = shdr->sh_name;
3026 if (sh_name >= shstr_size) {
3027 error_callback(data, "ELF section name out of range", 0);
3028 goto fail;
3029 }
3030
3031 name = names + sh_name;
3032
3033 for (j = 0; j < (int)DEBUG_MAX; ++j) {
3034 if (strcmp(name, dwarf_section_names[j]) == 0) {
3035 sections[j].offset = shdr->sh_offset;
3036 sections[j].size = shdr->sh_size;
3037 sections[j].compressed = (shdr->sh_flags & SHF_COMPRESSED) != 0;
3038 break;
3039 }
3040 }
3041
3042 if (name[0] == '.' && name[1] == 'z') {
3043 for (j = 0; j < (int)DEBUG_MAX; ++j) {
3044 if (strcmp(name + 2, dwarf_section_names[j] + 1) == 0) {
3045 zsections[j].offset = shdr->sh_offset;
3046 zsections[j].size = shdr->sh_size;
3047 break;
3048 }
3049 }
3050 }
3051
3052 if ((!debuginfo || with_buildid_data != NULL) && !buildid_view_valid &&
3053 strcmp(name, ".note.gnu.build-id") == 0) {
3054 const b_elf_note *note;
3055
3056 if (!elf_get_view(state, descriptor, memory, memory_size, shdr->sh_offset,
3057 shdr->sh_size, error_callback, data, &buildid_view))
3058 goto fail;
3059
3060 buildid_view_valid = 1;
3061 note = (const b_elf_note *)buildid_view.view.data;
3062 if (note->type == NT_GNU_BUILD_ID && note->namesz == 4 &&
3063 strncmp(note->name, "GNU", 4) == 0 &&
3064 shdr->sh_size <= 12 + ((note->namesz + 3) & ~3) + note->descsz) {
3065 buildid_data = ¬e->name[0] + ((note->namesz + 3) & ~3);
3066 buildid_size = note->descsz;
3067 }
3068
3069 if (with_buildid_size != 0) {
3070 if (buildid_size != with_buildid_size) goto fail;
3071
3072 if (memcmp(buildid_data, with_buildid_data, buildid_size) != 0)
3073 goto fail;
3074 }
3075 }
3076
3077 if (!debuginfo && !debuglink_view_valid &&
3078 strcmp(name, ".gnu_debuglink") == 0) {
3079 const char *debuglink_data;
3080 size_t crc_offset;
3081
3082 if (!elf_get_view(state, descriptor, memory, memory_size, shdr->sh_offset,
3083 shdr->sh_size, error_callback, data, &debuglink_view))
3084 goto fail;
3085
3086 debuglink_view_valid = 1;
3087 debuglink_data = (const char *)debuglink_view.view.data;
3088 crc_offset = strnlen(debuglink_data, shdr->sh_size);
3089 crc_offset = (crc_offset + 3) & ~3;
3090 if (crc_offset + 4 <= shdr->sh_size) {
3091 debuglink_name = debuglink_data;
3092 debuglink_crc = *(const uint32_t *)(debuglink_data + crc_offset);
3093 }
3094 }
3095
3096 if (!debugaltlink_view_valid && strcmp(name, ".gnu_debugaltlink") == 0) {
3097 const char *debugaltlink_data;
3098 size_t debugaltlink_name_len;
3099
3100 if (!elf_get_view(state, descriptor, memory, memory_size, shdr->sh_offset,
3101 shdr->sh_size, error_callback, data,
3102 &debugaltlink_view))
3103 goto fail;
3104
3105 debugaltlink_view_valid = 1;
3106 debugaltlink_data = (const char *)debugaltlink_view.view.data;
3107 debugaltlink_name = debugaltlink_data;
3108 debugaltlink_name_len = strnlen(debugaltlink_data, shdr->sh_size);
3109 if (debugaltlink_name_len < shdr->sh_size) {
3110 debugaltlink_name_len += 1;
3111
3112 debugaltlink_buildid_data = debugaltlink_data + debugaltlink_name_len;
3113 debugaltlink_buildid_size = shdr->sh_size - debugaltlink_name_len;
3114 }
3115 }
3116
3117 if (!gnu_debugdata_view_valid && strcmp(name, ".gnu_debugdata") == 0) {
3118 if (!elf_get_view(state, descriptor, memory, memory_size, shdr->sh_offset,
3119 shdr->sh_size, error_callback, data,
3120 &gnu_debugdata_view))
3121 goto fail;
3122
3123 gnu_debugdata_size = shdr->sh_size;
3124 gnu_debugdata_view_valid = 1;
3125 }
3126
3127 if (ehdr.e_machine == EM_PPC64 && (ehdr.e_flags & EF_PPC64_ABI) < 2 &&
3128 shdr->sh_type == SHT_PROGBITS && strcmp(name, ".opd") == 0) {
3129 if (!elf_get_view(state, descriptor, memory, memory_size, shdr->sh_offset,
3130 shdr->sh_size, error_callback, data, &opd_data.view))
3131 goto fail;
3132
3133 opd = &opd_data;
3134 opd->addr = shdr->sh_addr;
3135 opd->data = (const char *)opd_data.view.view.data;
3136 opd->size = shdr->sh_size;
3137 }
3138 }
3139
3140 if (symtab_shndx == 0) symtab_shndx = dynsym_shndx;
3141 if (symtab_shndx != 0 && !debuginfo) {
3142 const b_elf_shdr *symtab_shdr;
3143 unsigned int strtab_shndx;
3144 const b_elf_shdr *strtab_shdr;
3145 struct elf_syminfo_data *sdata;
3146
3147 symtab_shdr = &shdrs[symtab_shndx - 1];
3148 strtab_shndx = symtab_shdr->sh_link;
3149 if (strtab_shndx >= shnum) {
3150 error_callback(data, "ELF symbol table strtab link out of range", 0);
3151 goto fail;
3152 }
3153 strtab_shdr = &shdrs[strtab_shndx - 1];
3154
3155 if (!elf_get_view(state, descriptor, memory, memory_size,
3156 symtab_shdr->sh_offset, symtab_shdr->sh_size,
3157 error_callback, data, &symtab_view))
3158 goto fail;
3159 symtab_view_valid = 1;
3160
3161 if (!elf_get_view(state, descriptor, memory, memory_size,
3162 strtab_shdr->sh_offset, strtab_shdr->sh_size,
3163 error_callback, data, &strtab_view))
3164 goto fail;
3165 strtab_view_valid = 1;
3166
3167 sdata = ((struct elf_syminfo_data *)backtrace_alloc(state, sizeof *sdata,
3168 error_callback, data));
3169 if (sdata == NULL) goto fail;
3170
3171 if (!elf_initialize_syminfo(state, base_address, symtab_view.view.data,
3172 symtab_shdr->sh_size, strtab_view.view.data,
3173 strtab_shdr->sh_size, error_callback, data,
3174 sdata, opd)) {
3175 backtrace_free(state, sdata, sizeof *sdata, error_callback, data);
3176 goto fail;
3177 }
3178
3179 elf_release_view(state, &symtab_view, error_callback, data);
3180 symtab_view_valid = 0;
3181 strtab_view_valid = 0;
3182
3183 *found_sym = 1;
3184
3185 elf_add_syminfo_data(state, sdata);
3186 }
3187
3188 elf_release_view(state, &shdrs_view, error_callback, data);
3189 shdrs_view_valid = 0;
3190 elf_release_view(state, &names_view, error_callback, data);
3191 names_view_valid = 0;
3192
3193 if (buildid_data != NULL) {
3194 int d;
3195
3196 d = elf_open_debugfile_by_buildid(state, buildid_data, buildid_size,
3197 error_callback, data);
3198 if (d >= 0) {
3199 int ret;
3200
3201 elf_release_view(state, &buildid_view, error_callback, data);
3202 if (debuglink_view_valid)
3203 elf_release_view(state, &debuglink_view, error_callback, data);
3204 if (debugaltlink_view_valid)
3205 elf_release_view(state, &debugaltlink_view, error_callback, data);
3206 ret = elf_add(state, "", d, NULL, 0, base_address, error_callback, data,
3207 fileline_fn, found_sym, found_dwarf, NULL, 0, 1, NULL, 0);
3208 if (ret < 0)
3209 backtrace_close(d, error_callback, data);
3210 else if (descriptor >= 0)
3211 backtrace_close(descriptor, error_callback, data);
3212 return ret;
3213 }
3214 }
3215
3216 if (buildid_view_valid) {
3217 elf_release_view(state, &buildid_view, error_callback, data);
3218 buildid_view_valid = 0;
3219 }
3220
3221 if (opd) {
3222 elf_release_view(state, &opd->view, error_callback, data);
3223 opd = NULL;
3224 }
3225
3226 if (debuglink_name != NULL) {
3227 int d;
3228
3229 d = elf_open_debugfile_by_debuglink(state, filename, debuglink_name,
3230 debuglink_crc, error_callback, data);
3231 if (d >= 0) {
3232 int ret;
3233
3234 elf_release_view(state, &debuglink_view, error_callback, data);
3235 if (debugaltlink_view_valid)
3236 elf_release_view(state, &debugaltlink_view, error_callback, data);
3237 ret = elf_add(state, "", d, NULL, 0, base_address, error_callback, data,
3238 fileline_fn, found_sym, found_dwarf, NULL, 0, 1, NULL, 0);
3239 if (ret < 0)
3240 backtrace_close(d, error_callback, data);
3241 else if (descriptor >= 0)
3242 backtrace_close(descriptor, error_callback, data);
3243 return ret;
3244 }
3245 }
3246
3247 if (debuglink_view_valid) {
3248 elf_release_view(state, &debuglink_view, error_callback, data);
3249 debuglink_view_valid = 0;
3250 }
3251
3252 struct dwarf_data *fileline_altlink = NULL;
3253 if (debugaltlink_name != NULL) {
3254 int d;
3255
3256 d = elf_open_debugfile_by_debuglink(state, filename, debugaltlink_name, 0,
3257 error_callback, data);
3258 if (d >= 0) {
3259 int ret;
3260
3261 ret =
3262 elf_add(state, filename, d, NULL, 0, base_address, error_callback,
3263 data, fileline_fn, found_sym, found_dwarf, &fileline_altlink,
3264 0, 1, debugaltlink_buildid_data, debugaltlink_buildid_size);
3265 elf_release_view(state, &debugaltlink_view, error_callback, data);
3266 debugaltlink_view_valid = 0;
3267 if (ret < 0) {
3268 backtrace_close(d, error_callback, data);
3269 return ret;
3270 }
3271 }
3272 }
3273
3274 if (debugaltlink_view_valid) {
3275 elf_release_view(state, &debugaltlink_view, error_callback, data);
3276 debugaltlink_view_valid = 0;
3277 }
3278
3279 if (gnu_debugdata_view_valid) {
3280 int ret;
3281
3282 ret = elf_uncompress_lzma(
3283 state, ((const unsigned char *)gnu_debugdata_view.view.data),
3284 gnu_debugdata_size, error_callback, data, &gnu_debugdata_uncompressed,
3285 &gnu_debugdata_uncompressed_size);
3286
3287 elf_release_view(state, &gnu_debugdata_view, error_callback, data);
3288 gnu_debugdata_view_valid = 0;
3289
3290 if (ret) {
3291 ret = elf_add(state, filename, -1, gnu_debugdata_uncompressed,
3292 gnu_debugdata_uncompressed_size, base_address,
3293 error_callback, data, fileline_fn, found_sym, found_dwarf,
3294 NULL, 0, 0, NULL, 0);
3295 if (ret >= 0 && descriptor >= 0)
3296 backtrace_close(descriptor, error_callback, data);
3297 return ret;
3298 }
3299 }
3300
3301 min_offset = 0;
3302 max_offset = 0;
3303 debug_size = 0;
3304 for (i = 0; i < (int)DEBUG_MAX; ++i) {
3305 off_t end;
3306
3307 if (sections[i].size != 0) {
3308 if (min_offset == 0 || sections[i].offset < min_offset)
3309 min_offset = sections[i].offset;
3310 end = sections[i].offset + sections[i].size;
3311 if (end > max_offset) max_offset = end;
3312 debug_size += sections[i].size;
3313 }
3314 if (zsections[i].size != 0) {
3315 if (min_offset == 0 || zsections[i].offset < min_offset)
3316 min_offset = zsections[i].offset;
3317 end = zsections[i].offset + zsections[i].size;
3318 if (end > max_offset) max_offset = end;
3319 debug_size += zsections[i].size;
3320 }
3321 }
3322 if (min_offset == 0 || max_offset == 0) {
3323 if (descriptor >= 0) {
3324 if (!backtrace_close(descriptor, error_callback, data)) goto fail;
3325 }
3326 return 1;
3327 }
3328
3329 if (max_offset - min_offset < 0x20000000 ||
3330 max_offset - min_offset < debug_size + 0x10000) {
3331 if (!elf_get_view(state, descriptor, memory, memory_size, min_offset,
3332 max_offset - min_offset, error_callback, data,
3333 &debug_view))
3334 goto fail;
3335 debug_view_valid = 1;
3336 } else {
3337 memset(&split_debug_view[0], 0, sizeof split_debug_view);
3338 for (i = 0; i < (int)DEBUG_MAX; ++i) {
3339 struct debug_section_info *dsec;
3340
3341 if (sections[i].size != 0)
3342 dsec = §ions[i];
3343 else if (zsections[i].size != 0)
3344 dsec = &zsections[i];
3345 else
3346 continue;
3347
3348 if (!elf_get_view(state, descriptor, memory, memory_size, dsec->offset,
3349 dsec->size, error_callback, data, &split_debug_view[i]))
3350 goto fail;
3351 split_debug_view_valid[i] = 1;
3352
3353 if (sections[i].size != 0)
3354 sections[i].data =
3355 ((const unsigned char *)split_debug_view[i].view.data);
3356 else
3357 zsections[i].data =
3358 ((const unsigned char *)split_debug_view[i].view.data);
3359 }
3360 }
3361
3362 if (descriptor >= 0) {
3363 if (!backtrace_close(descriptor, error_callback, data)) goto fail;
3364 descriptor = -1;
3365 }
3366
3367 using_debug_view = 0;
3368 if (debug_view_valid) {
3369 for (i = 0; i < (int)DEBUG_MAX; ++i) {
3370 if (sections[i].size == 0)
3371 sections[i].data = NULL;
3372 else {
3373 sections[i].data = ((const unsigned char *)debug_view.view.data +
3374 (sections[i].offset - min_offset));
3375 ++using_debug_view;
3376 }
3377
3378 if (zsections[i].size == 0)
3379 zsections[i].data = NULL;
3380 else
3381 zsections[i].data = ((const unsigned char *)debug_view.view.data +
3382 (zsections[i].offset - min_offset));
3383 }
3384 }
3385
3386 zdebug_table = NULL;
3387 for (i = 0; i < (int)DEBUG_MAX; ++i) {
3388 if (sections[i].size == 0 && zsections[i].size > 0) {
3389 unsigned char *uncompressed_data;
3390 size_t uncompressed_size;
3391
3392 if (zdebug_table == NULL) {
3393 zdebug_table = ((uint16_t *)backtrace_alloc(state, ZDEBUG_TABLE_SIZE,
3394 error_callback, data));
3395 if (zdebug_table == NULL) goto fail;
3396 }
3397
3398 uncompressed_data = NULL;
3399 uncompressed_size = 0;
3400 if (!elf_uncompress_zdebug(state, zsections[i].data, zsections[i].size,
3401 zdebug_table, error_callback, data,
3402 &uncompressed_data, &uncompressed_size))
3403 goto fail;
3404 sections[i].data = uncompressed_data;
3405 sections[i].size = uncompressed_size;
3406 sections[i].compressed = 0;
3407
3408 if (split_debug_view_valid[i]) {
3409 elf_release_view(state, &split_debug_view[i], error_callback, data);
3410 split_debug_view_valid[i] = 0;
3411 }
3412 }
3413 }
3414
3415 for (i = 0; i < (int)DEBUG_MAX; ++i) {
3416 unsigned char *uncompressed_data;
3417 size_t uncompressed_size;
3418
3419 if (sections[i].size == 0 || !sections[i].compressed) continue;
3420
3421 if (zdebug_table == NULL) {
3422 zdebug_table = ((uint16_t *)backtrace_alloc(state, ZDEBUG_TABLE_SIZE,
3423 error_callback, data));
3424 if (zdebug_table == NULL) goto fail;
3425 }
3426
3427 uncompressed_data = NULL;
3428 uncompressed_size = 0;
3429 if (!elf_uncompress_chdr(state, sections[i].data, sections[i].size,
3430 zdebug_table, error_callback, data,
3431 &uncompressed_data, &uncompressed_size))
3432 goto fail;
3433 sections[i].data = uncompressed_data;
3434 sections[i].size = uncompressed_size;
3435 sections[i].compressed = 0;
3436
3437 if (debug_view_valid)
3438 --using_debug_view;
3439 else if (split_debug_view_valid[i]) {
3440 elf_release_view(state, &split_debug_view[i], error_callback, data);
3441 split_debug_view_valid[i] = 0;
3442 }
3443 }
3444
3445 if (zdebug_table != NULL)
3446 backtrace_free(state, zdebug_table, ZDEBUG_TABLE_SIZE, error_callback,
3447 data);
3448
3449 if (debug_view_valid && using_debug_view == 0) {
3450 elf_release_view(state, &debug_view, error_callback, data);
3451 debug_view_valid = 0;
3452 }
3453
3454 for (i = 0; i < (int)DEBUG_MAX; ++i) {
3455 dwarf_sections.data[i] = sections[i].data;
3456 dwarf_sections.size[i] = sections[i].size;
3457 }
3458
3459 if (!backtrace_dwarf_add(state, base_address, &dwarf_sections,
3460 ehdr.e_ident[EI_DATA] == ELFDATA2MSB,
3461 fileline_altlink, error_callback, data, fileline_fn,
3462 fileline_entry))
3463 goto fail;
3464
3465 *found_dwarf = 1;
3466
3467 return 1;
3468
3469fail:
3470 if (shdrs_view_valid)
3471 elf_release_view(state, &shdrs_view, error_callback, data);
3472 if (names_view_valid)
3473 elf_release_view(state, &names_view, error_callback, data);
3474 if (symtab_view_valid)
3475 elf_release_view(state, &symtab_view, error_callback, data);
3476 if (strtab_view_valid)
3477 elf_release_view(state, &strtab_view, error_callback, data);
3478 if (debuglink_view_valid)
3479 elf_release_view(state, &debuglink_view, error_callback, data);
3480 if (debugaltlink_view_valid)
3481 elf_release_view(state, &debugaltlink_view, error_callback, data);
3482 if (gnu_debugdata_view_valid)
3483 elf_release_view(state, &gnu_debugdata_view, error_callback, data);
3484 if (buildid_view_valid)
3485 elf_release_view(state, &buildid_view, error_callback, data);
3486 if (debug_view_valid)
3487 elf_release_view(state, &debug_view, error_callback, data);
3488 for (i = 0; i < (int)DEBUG_MAX; ++i) {
3489 if (split_debug_view_valid[i])
3490 elf_release_view(state, &split_debug_view[i], error_callback, data);
3491 }
3492 if (opd) elf_release_view(state, &opd->view, error_callback, data);
3493 if (descriptor >= 0) backtrace_close(descriptor, error_callback, data);
3494 return 0;
3495}
3496
3497struct phdr_data {
3498 struct backtrace_state *state;
3499 backtrace_error_callback error_callback;
3500 void *data;
3501 fileline *fileline_fn;
3502 int *found_sym;
3503 int *found_dwarf;
3504 const char *exe_filename;
3505 int exe_descriptor;
3506};
3507
3508static int
3509#ifdef __i386__
3510 __attribute__((__force_align_arg_pointer__))
3511#endif
3512 phdr_callback(struct dl_phdr_info *info, size_t size ATTRIBUTE_UNUSED,
3513 void *pdata) {
3514 struct phdr_data *pd = (struct phdr_data *)pdata;
3515 const char *filename;
3516 int descriptor;
3517 int does_not_exist;
3518 fileline elf_fileline_fn;
3519 int found_dwarf;
3520
3521 if (info->dlpi_name == NULL || info->dlpi_name[0] == '\0') {
3522 if (pd->exe_descriptor == -1) return 0;
3523 filename = pd->exe_filename;
3524 descriptor = pd->exe_descriptor;
3525 pd->exe_descriptor = -1;
3526 } else {
3527 if (pd->exe_descriptor != -1) {
3528 backtrace_close(pd->exe_descriptor, pd->error_callback, pd->data);
3529 pd->exe_descriptor = -1;
3530 }
3531
3532 filename = info->dlpi_name;
3533 descriptor = backtrace_open(info->dlpi_name, pd->error_callback, pd->data,
3534 &does_not_exist);
3535 if (descriptor < 0) return 0;
3536 }
3537
3538 if (elf_add(pd->state, filename, descriptor, NULL, 0, info->dlpi_addr,
3539 pd->error_callback, pd->data, &elf_fileline_fn, pd->found_sym,
3540 &found_dwarf, NULL, 0, 0, NULL, 0)) {
3541 if (found_dwarf) {
3542 *pd->found_dwarf = 1;
3543 *pd->fileline_fn = elf_fileline_fn;
3544 }
3545 }
3546
3547 return 0;
3548}
3549
3550int backtrace_initialize(struct backtrace_state *state, const char *filename,
3551 int descriptor,
3552 backtrace_error_callback error_callback, void *data,
3553 fileline *fileline_fn) {
3554 int ret;
3555 int found_sym;
3556 int found_dwarf;
3557 fileline elf_fileline_fn = elf_nodebug;
3558 struct phdr_data pd;
3559
3560 ret =
3561 elf_add(state, filename, descriptor, NULL, 0, 0, error_callback, data,
3562 &elf_fileline_fn, &found_sym, &found_dwarf, NULL, 1, 0, NULL, 0);
3563 if (!ret) return 0;
3564
3565 pd.state = state;
3566 pd.error_callback = error_callback;
3567 pd.data = data;
3568 pd.fileline_fn = &elf_fileline_fn;
3569 pd.found_sym = &found_sym;
3570 pd.found_dwarf = &found_dwarf;
3571 pd.exe_filename = filename;
3572 pd.exe_descriptor = ret < 0 ? descriptor : -1;
3573
3574 dl_iterate_phdr(phdr_callback, (void *)&pd);
3575
3576 if (!state->threaded) {
3577 if (found_sym)
3578 state->syminfo_fn = elf_syminfo;
3579 else if (state->syminfo_fn == NULL)
3580 state->syminfo_fn = elf_nosyms;
3581 } else {
3582 if (found_sym)
3583 backtrace_atomic_store_pointer(&state->syminfo_fn, elf_syminfo);
3584 else
3585 (void)__sync_bool_compare_and_swap(&state->syminfo_fn, NULL, elf_nosyms);
3586 }
3587
3588 if (!state->threaded)
3589 *fileline_fn = state->fileline_fn;
3590 else
3591 *fileline_fn = backtrace_atomic_load_pointer(&state->fileline_fn);
3592
3593 if (*fileline_fn == NULL || *fileline_fn == elf_nodebug)
3594 *fileline_fn = elf_fileline_fn;
3595
3596 return 1;
3597}
3598
3599// mmapio.c:
3600#include <errno.h>
3601#include <sys/mman.h>
3602#include <sys/types.h>
3603#include <unistd.h>
3604
3605#ifndef HAVE_DECL_GETPAGESIZE
3606extern int getpagesize(void);
3607#endif
3608
3609#ifndef MAP_FAILED
3610#define MAP_FAILED ((void *)-1)
3611#endif
3612
3613int backtrace_get_view(struct backtrace_state *state ATTRIBUTE_UNUSED,
3614 int descriptor, off_t offset, uint64_t size,
3615 backtrace_error_callback error_callback, void *data,
3616 struct backtrace_view *view) {
3617 size_t pagesize;
3618 unsigned int inpage;
3619 off_t pageoff;
3620 void *map;
3621
3622 if ((uint64_t)(size_t)size != size) {
3623 error_callback(data, "file size too large", 0);
3624 return 0;
3625 }
3626
3627 pagesize = getpagesize();
3628 inpage = offset % pagesize;
3629 pageoff = offset - inpage;
3630
3631 size += inpage;
3632 size = (size + (pagesize - 1)) & ~(pagesize - 1);
3633
3634 map = mmap(NULL, size, PROT_READ, MAP_PRIVATE, descriptor, pageoff);
3635 if (map == MAP_FAILED) {
3636 error_callback(data, "mmap", errno);
3637 return 0;
3638 }
3639
3640 view->data = (char *)map + inpage;
3641 view->base = map;
3642 view->len = size;
3643
3644 return 1;
3645}
3646
3647void backtrace_release_view(struct backtrace_state *state ATTRIBUTE_UNUSED,
3648 struct backtrace_view *view,
3649 backtrace_error_callback error_callback,
3650 void *data) {
3651 union {
3652 const void *cv;
3653 void *v;
3654 } const_cast;
3655
3656 const_cast.cv = view->base;
3657 if (munmap(const_cast.v, view->len) < 0)
3658 error_callback(data, "munmap", errno);
3659}
3660
3661// mmap.c:
3662#include <errno.h>
3663#include <stdlib.h>
3664#include <string.h>
3665#include <sys/mman.h>
3666#include <sys/types.h>
3667#include <unistd.h>
3668
3669#ifndef HAVE_DECL_GETPAGESIZE
3670extern int getpagesize(void);
3671#endif
3672
3673#ifndef MAP_ANONYMOUS
3674#define MAP_ANONYMOUS MAP_ANON
3675#endif
3676
3677#ifndef MAP_FAILED
3678#define MAP_FAILED ((void *)-1)
3679#endif
3680
3681struct backtrace_freelist_struct {
3682 struct backtrace_freelist_struct *next;
3683
3684 size_t size;
3685};
3686
3687static void backtrace_free_locked(struct backtrace_state *state, void *addr,
3688 size_t size) {
3689 if (size >= sizeof(struct backtrace_freelist_struct)) {
3690 size_t c;
3691 struct backtrace_freelist_struct **ppsmall;
3692 struct backtrace_freelist_struct **pp;
3693 struct backtrace_freelist_struct *p;
3694
3695 c = 0;
3696 ppsmall = NULL;
3697 for (pp = &state->freelist; *pp != NULL; pp = &(*pp)->next) {
3698 if (ppsmall == NULL || (*pp)->size < (*ppsmall)->size) ppsmall = pp;
3699 ++c;
3700 }
3701 if (c >= 16) {
3702 if (size <= (*ppsmall)->size) return;
3703 *ppsmall = (*ppsmall)->next;
3704 }
3705
3706 p = (struct backtrace_freelist_struct *)addr;
3707 p->next = state->freelist;
3708 p->size = size;
3709 state->freelist = p;
3710 }
3711}
3712
3713void *backtrace_alloc(struct backtrace_state *state, size_t size,
3714 backtrace_error_callback error_callback, void *data) {
3715 void *ret;
3716 int locked;
3717 struct backtrace_freelist_struct **pp;
3718 size_t pagesize;
3719 size_t asksize;
3720 void *page;
3721
3722 ret = NULL;
3723
3724 if (!state->threaded)
3725 locked = 1;
3726 else
3727 locked = __sync_lock_test_and_set(&state->lock_alloc, 1) == 0;
3728
3729 if (locked) {
3730 for (pp = &state->freelist; *pp != NULL; pp = &(*pp)->next) {
3731 if ((*pp)->size >= size) {
3732 struct backtrace_freelist_struct *p;
3733
3734 p = *pp;
3735 *pp = p->next;
3736
3737 size = (size + 7) & ~(size_t)7;
3738 if (size < p->size)
3739 backtrace_free_locked(state, (char *)p + size, p->size - size);
3740
3741 ret = (void *)p;
3742
3743 break;
3744 }
3745 }
3746
3747 if (state->threaded) __sync_lock_release(&state->lock_alloc);
3748 }
3749
3750 if (ret == NULL) {
3751 pagesize = getpagesize();
3752 asksize = (size + pagesize - 1) & ~(pagesize - 1);
3753 page = mmap(NULL, asksize, PROT_READ | PROT_WRITE,
3754 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
3755 if (page == MAP_FAILED) {
3756 if (error_callback) error_callback(data, "mmap", errno);
3757 } else {
3758 size = (size + 7) & ~(size_t)7;
3759 if (size < asksize)
3760 backtrace_free(state, (char *)page + size, asksize - size,
3761 error_callback, data);
3762
3763 ret = page;
3764 }
3765 }
3766
3767 return ret;
3768}
3769
3770void backtrace_free(struct backtrace_state *state, void *addr, size_t size,
3771 backtrace_error_callback error_callback ATTRIBUTE_UNUSED,
3772 void *data ATTRIBUTE_UNUSED) {
3773 int locked;
3774
3775 if (size >= 16 * 4096) {
3776 size_t pagesize;
3777
3778 pagesize = getpagesize();
3779 if (((uintptr_t)addr & (pagesize - 1)) == 0 &&
3780 (size & (pagesize - 1)) == 0) {
3781 if (munmap(addr, size) == 0) return;
3782 }
3783 }
3784
3785 if (!state->threaded)
3786 locked = 1;
3787 else
3788 locked = __sync_lock_test_and_set(&state->lock_alloc, 1) == 0;
3789
3790 if (locked) {
3791 backtrace_free_locked(state, addr, size);
3792
3793 if (state->threaded) __sync_lock_release(&state->lock_alloc);
3794 }
3795}
3796
3797void *backtrace_vector_grow(struct backtrace_state *state, size_t size,
3798 backtrace_error_callback error_callback, void *data,
3799 struct backtrace_vector *vec) {
3800 void *ret;
3801
3802 if (size > vec->alc) {
3803 size_t pagesize;
3804 size_t alc;
3805 void *base;
3806
3807 pagesize = getpagesize();
3808 alc = vec->size + size;
3809 if (vec->size == 0)
3810 alc = 16 * size;
3811 else if (alc < pagesize) {
3812 alc *= 2;
3813 if (alc > pagesize) alc = pagesize;
3814 } else {
3815 alc *= 2;
3816 alc = (alc + pagesize - 1) & ~(pagesize - 1);
3817 }
3818 base = backtrace_alloc(state, alc, error_callback, data);
3819 if (base == NULL) return NULL;
3820 if (vec->base != NULL) {
3821 memcpy(base, vec->base, vec->size);
3822 backtrace_free(state, vec->base, vec->size + vec->alc, error_callback,
3823 data);
3824 }
3825 vec->base = base;
3826 vec->alc = alc - vec->size;
3827 }
3828
3829 ret = (char *)vec->base + vec->size;
3830 vec->size += size;
3831 vec->alc -= size;
3832 return ret;
3833}
3834
3835void *backtrace_vector_finish(struct backtrace_state *state ATTRIBUTE_UNUSED,
3836 struct backtrace_vector *vec,
3837 backtrace_error_callback error_callback
3838 ATTRIBUTE_UNUSED,
3839 void *data ATTRIBUTE_UNUSED) {
3840 void *ret;
3841
3842 ret = vec->base;
3843 vec->base = (char *)vec->base + vec->size;
3844 vec->size = 0;
3845 return ret;
3846}
3847
3848int backtrace_vector_release(struct backtrace_state *state,
3849 struct backtrace_vector *vec,
3850 backtrace_error_callback error_callback,
3851 void *data) {
3852 size_t size;
3853 size_t alc;
3854 size_t aligned;
3855
3856 size = vec->size;
3857 alc = vec->alc;
3858 aligned = (size + 7) & ~(size_t)7;
3859 alc -= aligned - size;
3860
3861 backtrace_free(state, (char *)vec->base + aligned, alc, error_callback, data);
3862 vec->alc = 0;
3863 if (vec->size == 0) vec->base = NULL;
3864 return 1;
3865}