diff options
46 files changed, 4306 insertions, 362 deletions
diff --git a/libbacktrace/ChangeLog b/libbacktrace/ChangeLog index 14df45e..5f13114 100644 --- a/libbacktrace/ChangeLog +++ b/libbacktrace/ChangeLog @@ -1,7 +1,278 @@ -2023-01-12 Nick Clifton <nickc@redhat.com> +2024-03-08 Ian Lance Taylor <iant@golang.org> - * Makefile.am (CLEANFILES): Import patch from upstream to prevent - allocafail.sh from being removed when running 'make clean'. + * elf.c (elf_uncompress_chdr): Don't assume compressed section is + aligned. + +2024-03-02 Ian Lance Taylor <iant@golang.org> + + * Makefile.am (libbacktrace_testing_ldflags): Define. + (*_LDFLAGS): Add $(libbacktrace_testing_ldflags) for test + programs. + * Makefile.in: Regenerate + +2024-03-02 Ian Lance Taylor <iant@golang.org> + + * elf.c (elf_uncompress_lzma_block): Skip all header padding bytes + and verify that they are zero. + +2024-03-02 Ian Lance Taylor <iant@golang.org> + + PR libbacktrace/114201 + * elf.c (elf_add): Add caller_opd parameter. Change all callers. + Release opd data after all recursive calls. + +2024-03-01 Ian Lance Taylor <iant@golang.org> + + * elf.c (elf_add): Add the symbol table from a debuginfo file. + * Makefile.am (MAKETESTS): Add buildidfull and gnudebuglinkfull + variants of buildid and gnudebuglink tests. + (%_gnudebuglinkfull, %_buildidfull): New patterns. + * Makefile.in: Regenerate. + +2023-11-30 Ian Lance Taylor <iant@golang.org> + + * pecoff.c: Include <windows.h> if available. + (coff_add): On Windows call GetModuleHandle to get base address. + +2023-11-29 Ian Lance Taylor <iant@golang.org> + + * fileline.c: Include <windows.h> if available. + (windows_get_executable_path): New static function. + (fileline_initialize): Call windows_get_executable_path. + * configure.ac: Checked for windows.h + * configure: Regenerate. + * config.h.in: Regenerate. + +2023-10-22 Iain Sandoe <iain@sandoe.co.uk> + + * configure: Regenerate. + * configure.ac: Handle Darwin rpaths. + +2023-08-07 Nick Alcock <nick.alcock@oracle.com> + + * configure: Regenerate. + +2023-08-07 Alexander von Gluck IV <kallisti5@unixzen.com> + + * configure: Regenerate. + +2023-08-07 Nick Alcock <nick.alcock@oracle.com> + + * configure: Regenerate. + +2023-08-07 Nick Alcock <nick.alcock@oracle.com> + + * configure: Regenerate. + +2023-08-07 H.J. Lu <hjl.tools@gmail.com> + + * configure: Regenerate. + +2023-08-07 H.J. Lu <hjl.tools@gmail.com> + + * configure: Regenerate. + +2023-08-03 Richard Biener <rguenther@suse.de> + + * zstdtest.c (test_samples): Properly compute the allocation + size for the uncompressed data. + +2023-07-31 Ian Lance Taylor <iant@golang.org> + + * configure.ac: Check for _pgmptr declaration. + * fileline.c (fileline_initialize): Check for _pgmfptr before + /proc/self/exec. + * configure, config.h.in: Regenerate. + +2023-03-28 Ian Lance Taylor <iant@golang.org> + + * elf.c (elf_zstd_read_fse): Call elf_fetch_bits after reading + bits, not before. Add unlikely for error case. + (elf_zstd_offset_table): Regenerate. + (elf_zstd_read_huff): Clear 13 entries in weight_mark, not 12. + (elf_zstd_read_literals): For a single stream adjust by + total_streams_size, not compressed_size. + +2023-01-20 Ian Lance Taylor <iant@golang.org> + + * dwarf.c (struct function_addrs): Change low and high fields to + uintptr_t. + (struct unit_addrs): Likewise. + (resolve_addr_index): Change address parameter to uintptr_t*. + (add_unit_addr): Change lowpc and highpc parameters to uintptr_t. + (add_function_range): Likewise. + (struct pcrange): Change lowpc and highpc fields to uintptr_t. + (add_low_high_range): Change add_range lowpc and highpc parameters + to uintptr_t. + (add_ranges_from_ranges): Likewise. + (add_ranges_from_rnglists): Likewise. + (add_low_high_range): Chnage lowpc and highpc variables to + uintpr_t. + (add_ranges_from_rnglists): Change some local variables to + uintptr_t. + (add_ranges_from_ranges): Change base parameter to uintptr_t. + (add_ranges_from_rnglists): Likewise. + (read_function_entry): Likewise. + (resolve_addr_index): Add explicit casts to uintptr_t. + (update_pcrange): Likewise. + (add_ranges_from_ranges): Likewise. + (add_ranges_from_rnglists): Likewise. + (read_function_entry): Likewise. + +2023-01-17 Martin Liska <mliska@suse.cz> + + * Makefile.in: Regenerate. + +2023-01-06 Ian Lance Taylor <iant@golang.org> + + PR libbacktrace/108297 + * configure.ac: Test whether linker supports --build-id. + * Makefile.am: Only run --build-id tests if supported. + * configure, Makefile.in: Regenerate. + +2022-12-17 Ian Lance Taylor <iant@golang.org> + + * elf.c (elf_fetch_backward_init): New static function. + (ZSTD_TABLE_SIZE): Use huffman scratch space size rather than + literal size. + (ZSTD_TABLE_WORK_LIT_SIZE): Don't define. + (elf_zstd_read_huff): Use elf_fetch_backward_init. + (elf_zstd_read_literals): New static function. + (ZSTD_LIT_RAW, ZSTD_LIT_RLE, ZSTD_LIT_HUFF): Don't define. + (struct elf_zstd_literals): Don't define. + (elf_zstd_literal_output): Remove static function. + (elf_zstd_decompress): Use elf_fetch_backward_init and + elf_zstd_read_literals. Rewrite literal copying.< + +2022-12-10 Ian Lance Taylor <iant@golang.org> + + * elf.c (ZSTD_TABLE_*): Use elf_zstd_fse_baseline_entry. + (ZSTD_ENCODE_BASELINE_BITS): Define. + (ZSTD_DECODE_BASELINE, ZSTD_DECODE_BASEBITS): Define. + (elf_zstd_literal_length_base): New static const array. + (elf_zstd_match_length_base): Likewise. + (struct elf_zstd_fse_baseline_entry): Define. + (elf_zstd_make_literal_baseline_fse): New static function. + (elf_zstd_make_offset_baseline_fse): Likewise. + (elf_zstd_make_match_baseline_fse): Likewise. + (print_table, main): Use elf_zstd_fse_baseline_entry. + (elf_zstd_lit_table, elf_zstd_match_table): Likewise. + (elf_zstd_offset_table): Likewise. + (struct elf_zstd_seq_decode): Likewise. Remove use_rle and rle + fields. + (elf_zstd_unpack_seq_decode): Use elf_zstd_fse_baseline_entry, + taking a conversion function. Convert RLE to FSE. + (elf_zstd_literal_length_baseline): Remove. + (elf_zstd_literal_length_bits): Remove. + (elf_zstd_match_length_baseline): Remove. + (elf_zstd_match_length_bits): Remove. + (elf_zstd_decompress): Use elf_zstd_fse_baseline_entry. Rewrite + and simplify main loop. + +2022-12-08 Ian Lance Taylor <iant@golang.org> + + * configure.ac: Check for zstd library and + --compress-debug-sections=zstd linker option. + * Makefile.am (zstdtest_*): New targets. + (zstdtest_alloc_*, ctestzstd_*): New targets. + (BUILDTESTS): Add zstdtest, zstdtest_alloc, ctestzstd as + appropriate. + * elf.c (ELFCOMPRESS_ZSTD): Define. + (elf_fetch_bits): Rename from elf_zlib_fetch. Update uses. + (elf_fetch_bits_backward): New static function. + (ZLIB_HUFFMAN_*): Rename from HUFFMAN_*. Update uses. + (ZLIB_TABLE_*): Rename from ZDEBUG_TABLE_*. Update uses. + (ZSTD_TABLE_*): Define. + (struct elf_zstd_fse_entry): Define. + (elf_zstd_read_fse): New static function. + (elf_zstd_build_fse): Likewise. + (lit): Define if BACKTRACE_GENERATE_ZSTD_FSE_TABLES. + (match, offset, next, print_table, main): Likewise. + (elf_zstd_lit_table): New static const array. + (elf_zstd_match_table, elf_zstd_offset_table): Likewise. + (elf_zstd_read_huff): New static function. + (struct elf_zstd_seq_decode): Define. + (elf_zstd_unpack_seq_decode): New static function. + (ZSTD_LIT_*): Define. + (struct elf_zstd_literals): Define. + (elf_zstd_literal_output): New static function. + (ZSTD_LITERAL_LENGTH_BASELINE_OFFSET): Define. + (elf_zstd_literal_length_baseline): New static const array. + (elf_zstd_literal_length_bits): Likewise. + (ZSTD_MATCH_LENGTH_BASELINE_OFFSET): Define. + (elf_zstd_match_length_baseline): New static const array. + (elf_zstd_match_length_bits): Likewise. + (elf_zstd_decompress): New static function. + (ZDEBUG_TABLE_SIZE): New definition. + (elf_uncompress_chdr): Support ELF_COMPRESS_ZSTD. + (backtrace_uncompress_zstd): New function. + (elf_add): Use ZLIB_TABLE_SIZE for zlib-gnu sections. + * internal.h (backtrace_uncompress_zstd): Declare. + * zstdtest.c: New file. + * configure, config.h.in, Makefile.in: Regenerate. + +2022-10-12 Martin Liska <mliska@suse.cz> + + * configure: Regenerate. + +2022-10-11 Olivier Hainque <hainque@adacore.com> + Olivier Hainque <hainque@adacore.com> + + * configure: Regenerate. + +2022-07-08 Ian Lance Taylor <iant@golang.org> + + * configure.ac: Check for sys/link.h. Use either link.h or + sys/link.h when checking for dl_iterate_phdr. + * elf.c: Include sys/link.h if available. + * configure, config.h.in: Regenerate. + +2022-07-07 Ian Lance Taylor <iant@golang.org> + + * macho.c (backtrace_initialize) [HAVE_MACH_O_DYLD_H]: Don't exit + loop if we can't find debug info for one shared library. + +2022-07-07 Ian Lance Taylor <iant@golang.org> + + * Makefile.am (MAKETESTS): New variable split out of TESTS. + (CLEANFILES): Replace TESTS with BUILDTESTS and MAKETESTS. + * Makefile.in: Regenerate. + +2022-06-27 Ian Lance Taylor <iant@golang.org> + + * configure.ac: Use grep instead of fgrep. + * configure, Makefile.in: Regenerate. + +2022-05-28 Ian Lance Taylor <iant@golang.org> + + PR libbacktrace/105721 + * README: Update. + +2022-04-05 Ian Lance Taylor <iant@golang.org> + + * elf.c (elf_zlib_inflate): Don't skip initial aligned byte in + uncompressed block. + +2022-02-17 Ian Lance Taylor <iant@golang.org> + + * dwarf.c (find_address_ranges): Handle skeleton units. + (read_function_entry): Likewise. + +2022-02-16 Ian Lance Taylor <iant@golang.org> + + * dwarf.c (build_address_map): Initialize DWARF 5 fields of unit. + +2022-02-03 David Seifert <soap@gentoo.org> + Jakub Jelinek <jakub@redhat.com> + + * configure.ac: Support --disable-werror. + * configure: Regenerate. + +2021-12-28 Francois-Xavier Coudert <fxcoudert@gmail.com> + + PR libbacktrace/103822 + * Makefile.am: Fix newline. + * Makefile.in: Regenerate. 2021-11-12 Martin Liska <mliska@suse.cz> @@ -1789,7 +2060,7 @@ * Initial implementation. -Copyright (C) 2012-2021 Free Software Foundation, Inc. +Copyright (C) 2012-2024 Free Software Foundation, Inc. Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright diff --git a/libbacktrace/Makefile.am b/libbacktrace/Makefile.am index e4f34b5..5677ecd 100644 --- a/libbacktrace/Makefile.am +++ b/libbacktrace/Makefile.am @@ -1,5 +1,5 @@ # Makefile.am -- Backtrace Makefile. -# Copyright (C) 2012-2021 Free Software Foundation, Inc. +# Copyright (C) 2012-2024 Free Software Foundation, Inc. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are @@ -85,13 +85,19 @@ libbacktrace_la_DEPENDENCIES = $(libbacktrace_la_LIBADD) # Testsuite. -# Add a test to this variable if you want it to be built. +# Add a test to this variable if you want it to be built as a program, +# with SOURCES, etc. check_PROGRAMS = # Add a test to this variable if you want it to be run. TESTS = -# Add a test to this variable if you want it to be built and run. +# Add a test to this variable if you want it to be built as a Makefile +# target and run. +MAKETESTS = + +# Add a test to this variable if you want it to be built as a program, +# with SOURCES, etc., and run. BUILDTESTS = # Add a file to this variable if you want it to be built for testing. @@ -100,6 +106,10 @@ check_DATA = # Flags to use when compiling test programs. libbacktrace_TEST_CFLAGS = $(EXTRA_FLAGS) $(WARN_FLAGS) -g +# Flags to use when linking test programs. +# This avoids generating a shell script when configured with --enable-shared. +libbacktrace_testing_ldflags = -no-install + if USE_DSYMUTIL %.dSYM: % @@ -145,18 +155,18 @@ endif HAVE_OBJCOPY_DEBUGLINK endif HAVE_ELF elf_%.c: elf.c + nlinit=`echo 'nl="'; echo '"'`; eval "$$nlinit"; \ SEARCH='#error "Unknown BACKTRACE_ELF_SIZE"'; \ - REPLACE='#undef BACKTRACE_ELF_SIZE\ - #define BACKTRACE_ELF_SIZE'; \ + REPLACE="#undef BACKTRACE_ELF_SIZE\\$${nl}#define BACKTRACE_ELF_SIZE"; \ $(SED) "s/^$$SEARCH\$$/$$REPLACE $*/" \ $< \ > $@.tmp mv $@.tmp $@ xcoff_%.c: xcoff.c + nlinit=`echo 'nl="'; echo '"'`; eval "$$nlinit"; \ SEARCH='#error "Unknown BACKTRACE_XCOFF_SIZE"'; \ - REPLACE='#undef BACKTRACE_XCOFF_SIZE\ - #define BACKTRACE_XCOFF_SIZE'; \ + REPLACE="#undef BACKTRACE_XCOFF_SIZE\\$${nl}#define BACKTRACE_XCOFF_SIZE"; \ $(SED) "s/^$$SEARCH\$$/$$REPLACE $*/" \ $< \ > $@.tmp @@ -164,54 +174,63 @@ xcoff_%.c: xcoff.c test_elf_32_SOURCES = test_format.c testlib.c test_elf_32_CFLAGS = $(libbacktrace_TEST_CFLAGS) +test_elf_32_LDFLAGS = $(libbacktrace_testing_ldflags) test_elf_32_LDADD = libbacktrace_noformat.la elf_32.lo BUILDTESTS += test_elf_32 test_elf_64_SOURCES = test_format.c testlib.c test_elf_64_CFLAGS = $(libbacktrace_TEST_CFLAGS) +test_elf_64_LDFLAGS = $(libbacktrace_testing_ldflags) test_elf_64_LDADD = libbacktrace_noformat.la elf_64.lo BUILDTESTS += test_elf_64 test_macho_SOURCES = test_format.c testlib.c test_macho_CFLAGS = $(libbacktrace_TEST_CFLAGS) +test_macho_LDFLAGS = $(libbacktrace_testing_ldflags) test_macho_LDADD = libbacktrace_noformat.la macho.lo BUILDTESTS += test_macho test_xcoff_32_SOURCES = test_format.c testlib.c test_xcoff_32_CFLAGS = $(libbacktrace_TEST_CFLAGS) +test_xcoff_32_LDFLAGS = $(libbacktrace_testing_ldflags) test_xcoff_32_LDADD = libbacktrace_noformat.la xcoff_32.lo BUILDTESTS += test_xcoff_32 test_xcoff_64_SOURCES = test_format.c testlib.c test_xcoff_64_CFLAGS = $(libbacktrace_TEST_CFLAGS) +test_xcoff_64_LDFLAGS = $(libbacktrace_testing_ldflags) test_xcoff_64_LDADD = libbacktrace_noformat.la xcoff_64.lo BUILDTESTS += test_xcoff_64 test_pecoff_SOURCES = test_format.c testlib.c test_pecoff_CFLAGS = $(libbacktrace_TEST_CFLAGS) +test_pecoff_LDFLAGS = $(libbacktrace_testing_ldflags) test_pecoff_LDADD = libbacktrace_noformat.la pecoff.lo BUILDTESTS += test_pecoff test_unknown_SOURCES = test_format.c testlib.c test_unknown_CFLAGS = $(libbacktrace_TEST_CFLAGS) +test_unknown_LDFLAGS = $(libbacktrace_testing_ldflags) test_unknown_LDADD = libbacktrace_noformat.la unknown.lo BUILDTESTS += test_unknown unittest_SOURCES = unittest.c testlib.c unittest_CFLAGS = $(libbacktrace_TEST_CFLAGS) +unittest_LDFLAGS = $(libbacktrace_testing_ldflags) unittest_LDADD = libbacktrace.la BUILDTESTS += unittest unittest_alloc_SOURCES = $(unittest_SOURCES) unittest_alloc_CFLAGS = $(libbacktrace_TEST_CFLAGS) +unittest_alloc_LDFLAGS = $(libbacktrace_testing_ldflags) unittest_alloc_LDADD = libbacktrace_alloc.la BUILDTESTS += unittest_alloc @@ -242,33 +261,36 @@ check_DATA += allocfail.dSYM endif USE_DSYMUTIL if HAVE_ELF +if HAVE_BUILDID if HAVE_OBJCOPY_DEBUGLINK b2test_SOURCES = $(btest_SOURCES) b2test_CFLAGS = $(libbacktrace_TEST_CFLAGS) -b2test_LDFLAGS = -Wl,--build-id +b2test_LDFLAGS = -Wl,--build-id $(libbacktrace_testing_ldflags) b2test_LDADD = libbacktrace_elf_for_test.la check_PROGRAMS += b2test -TESTS += b2test_buildid +MAKETESTS += b2test_buildid b2test_buildidfull if HAVE_DWZ b3test_SOURCES = $(btest_SOURCES) b3test_CFLAGS = $(libbacktrace_TEST_CFLAGS) -b3test_LDFLAGS = -Wl,--build-id +b3test_LDFLAGS = -Wl,--build-id $(libbacktrace_testing_ldflags) b3test_LDADD = libbacktrace_elf_for_test.la check_PROGRAMS += b3test -TESTS += b3test_dwz_buildid +MAKETESTS += b3test_dwz_buildid b3test_dwz_buildidfull endif HAVE_DWZ endif HAVE_OBJCOPY_DEBUGLINK +endif HAVE_BUILDID endif HAVE_ELF btest_SOURCES = btest.c testlib.c btest_CFLAGS = $(libbacktrace_TEST_CFLAGS) -O +btest_LDFLAGS = $(libbacktrace_testing_ldflags) btest_LDADD = libbacktrace.la BUILDTESTS += btest @@ -281,6 +303,7 @@ if HAVE_ELF btest_lto_SOURCES = btest.c testlib.c btest_lto_CFLAGS = $(libbacktrace_TEST_CFLAGS) -O -flto +btest_lto_LDFLAGS = $(libbacktrace_testing_ldflags) btest_lto_LDADD = libbacktrace.la BUILDTESTS += btest_lto @@ -289,6 +312,7 @@ endif HAVE_ELF btest_alloc_SOURCES = $(btest_SOURCES) btest_alloc_CFLAGS = $(libbacktrace_TEST_CFLAGS) +btest_alloc_LDFLAGS = $(libbacktrace_testing_ldflags) btest_alloc_LDADD = libbacktrace_alloc.la BUILDTESTS += btest_alloc @@ -311,11 +335,11 @@ if HAVE_DWZ cp $< $@; \ fi -TESTS += btest_dwz +MAKETESTS += btest_dwz if HAVE_OBJCOPY_DEBUGLINK -TESTS += btest_dwz_gnudebuglink +MAKETESTS += btest_dwz_gnudebuglink endif HAVE_OBJCOPY_DEBUGLINK @@ -323,6 +347,7 @@ endif HAVE_DWZ stest_SOURCES = stest.c stest_CFLAGS = $(libbacktrace_TEST_CFLAGS) +stest_LDFLAGS = $(libbacktrace_testing_ldflags) stest_LDADD = libbacktrace.la BUILDTESTS += stest @@ -333,6 +358,7 @@ endif USE_DSYMUTIL stest_alloc_SOURCES = $(stest_SOURCES) stest_alloc_CFLAGS = $(libbacktrace_TEST_CFLAGS) +stest_alloc_LDFLAGS = $(libbacktrace_testing_ldflags) stest_alloc_LDADD = libbacktrace_alloc.la BUILDTESTS += stest_alloc @@ -345,6 +371,7 @@ if HAVE_ELF ztest_SOURCES = ztest.c testlib.c ztest_CFLAGS = $(libbacktrace_TEST_CFLAGS) -DSRCDIR=\"$(srcdir)\" +ztest_LDFLAGS = $(libbacktrace_testing_ldflags) ztest_LDADD = libbacktrace.la ztest_alloc_LDADD = libbacktrace_alloc.la @@ -359,13 +386,36 @@ BUILDTESTS += ztest ztest_alloc_SOURCES = $(ztest_SOURCES) ztest_alloc_CFLAGS = $(ztest_CFLAGS) +ztest_alloc_LDFLAGS = $(libbacktrace_testing_ldflags) BUILDTESTS += ztest_alloc +zstdtest_SOURCES = zstdtest.c testlib.c +zstdtest_CFLAGS = $(libbacktrace_TEST_CFLAGS) -DSRCDIR=\"$(srcdir)\" +zstdtest_LDFLAGS = $(libbacktrace_testing_ldflags) +zstdtest_LDADD = libbacktrace.la +zstdtest_alloc_LDADD = libbacktrace_alloc.la + +if HAVE_ZSTD +zstdtest_LDADD += -lzstd +zstdtest_alloc_LDADD += -lzstd +endif +zstdtest_LDADD += $(CLOCK_GETTIME_LINK) +zstdtest_alloc_LDADD += $(CLOCK_GETTIME_LINK) + +BUILDTESTS += zstdtest + +zstdtest_alloc_SOURCES = $(zstdtest_SOURCES) +zstdtest_alloc_CFLAGS = $(zstdtest_CFLAGS) +zstdtest_alloc_LDFLAGS = $(libbacktrace_testing_ldflags) + +BUILDTESTS += zstdtest_alloc + endif HAVE_ELF edtest_SOURCES = edtest.c edtest2_build.c testlib.c edtest_CFLAGS = $(libbacktrace_TEST_CFLAGS) +edtest_LDFLAGS = $(libbacktrace_testing_ldflags) edtest_LDADD = libbacktrace.la BUILDTESTS += edtest @@ -376,6 +426,7 @@ endif USE_DSYMUTIL edtest_alloc_SOURCES = $(edtest_SOURCES) edtest_alloc_CFLAGS = $(libbacktrace_TEST_CFLAGS) +edtest_alloc_LDFLAGS = $(libbacktrace_testing_ldflags) edtest_alloc_LDADD = libbacktrace_alloc.la if USE_DSYMUTIL @@ -396,6 +447,7 @@ BUILDTESTS += ttest ttest_SOURCES = ttest.c testlib.c ttest_CFLAGS = $(libbacktrace_TEST_CFLAGS) -pthread +ttest_LDFLAGS = $(libbacktrace_testing_ldflags) ttest_LDADD = libbacktrace.la if USE_DSYMUTIL @@ -406,6 +458,7 @@ BUILDTESTS += ttest_alloc ttest_alloc_SOURCES = $(ttest_SOURCES) ttest_alloc_CFLAGS = $(ttest_CFLAGS) +ttest_alloc_LDFLAGS = $(libbacktrace_testing_ldflags) ttest_alloc_LDADD = libbacktrace_alloc.la if USE_DSYMUTIL @@ -416,12 +469,16 @@ endif HAVE_PTHREAD if HAVE_OBJCOPY_DEBUGLINK -TESTS += btest_gnudebuglink +MAKETESTS += btest_gnudebuglink btest_gnudebuglinkfull %_gnudebuglink: % $(OBJCOPY) --only-keep-debug $< $@.debug $(OBJCOPY) --strip-debug --add-gnu-debuglink=$@.debug $< $@ +%_gnudebuglinkfull: % + $(OBJCOPY) --only-keep-debug $< $@.debug + $(OBJCOPY) --strip-all --add-gnu-debuglink=$@.debug $< $@ + endif HAVE_OBJCOPY_DEBUGLINK %_buildid: % @@ -430,28 +487,45 @@ endif HAVE_OBJCOPY_DEBUGLINK $< $(OBJCOPY) --strip-debug $< $@ +%_buildidfull: % + ./install-debuginfo-for-buildid.sh \ + "$(TEST_BUILD_ID_DIR)" \ + $< + $(OBJCOPY) --strip-all $< $@ + if HAVE_COMPRESSED_DEBUG ctestg_SOURCES = btest.c testlib.c ctestg_CFLAGS = $(libbacktrace_TEST_CFLAGS) -ctestg_LDFLAGS = -Wl,--compress-debug-sections=zlib-gnu +ctestg_LDFLAGS = -Wl,--compress-debug-sections=zlib-gnu $(libbacktrace_testing_ldflags) ctestg_LDADD = libbacktrace.la ctesta_SOURCES = btest.c testlib.c ctesta_CFLAGS = $(libbacktrace_TEST_CFLAGS) -ctesta_LDFLAGS = -Wl,--compress-debug-sections=zlib-gabi +ctesta_LDFLAGS = -Wl,--compress-debug-sections=zlib-gabi $(libbacktrace_testing_ldflags) ctesta_LDADD = libbacktrace.la BUILDTESTS += ctestg ctesta +if HAVE_COMPRESSED_DEBUG_ZSTD + +ctestzstd_SOURCES = btest.c testlib.c +ctestzstd_CFLAGS = $(libbacktrace_TEST_CFLAGS) +ctestzstd_LDFLAGS = -Wl,--compress-debug-sections=zstd $(libbacktrace_testing_ldflags) +ctestzstd_LDADD = libbacktrace.la + +BUILDTESTS += ctestzstd + +endif + ctestg_alloc_SOURCES = $(ctestg_SOURCES) ctestg_alloc_CFLAGS = $(ctestg_CFLAGS) -ctestg_alloc_LDFLAGS = $(ctestg_LDFLAGS) +ctestg_alloc_LDFLAGS = $(ctestg_LDFLAGS) $(libbacktrace_testing_ldflags) ctestg_alloc_LDADD = libbacktrace_alloc.la ctesta_alloc_SOURCES = $(ctesta_SOURCES) ctesta_alloc_CFLAGS = $(ctesta_CFLAGS) -ctesta_alloc_LDFLAGS = $(ctesta_LDFLAGS) +ctesta_alloc_LDFLAGS = $(ctesta_LDFLAGS) $(libbacktrace_testing_ldflags) ctesta_alloc_LDADD = libbacktrace_alloc.la BUILDTESTS += ctestg_alloc ctesta_alloc @@ -462,6 +536,7 @@ if HAVE_DWARF5 dwarf5_SOURCES = btest.c testlib.c dwarf5_CFLAGS = $(libbacktrace_TEST_CFLAGS) -gdwarf-5 +dwarf5_LDFLAGS = $(libbacktrace_testing_ldflags) dwarf5_LDADD = libbacktrace.la BUILDTESTS += dwarf5 @@ -472,6 +547,7 @@ endif USE_DSYMUTIL dwarf5_alloc_SOURCES = $(dwarf5_SOURCES) dwarf5_alloc_CFLAGS = $(dwarf5_CFLAGS) +dwarf5_alloc_LDFLAGS = $(libbacktrace_testing_ldflags) dwarf5_alloc_LDADD = libbacktrace_alloc.la BUILDTESTS += dwarf5_alloc @@ -484,6 +560,7 @@ endif mtest_SOURCES = mtest.c testlib.c mtest_CFLAGS = $(libbacktrace_TEST_CFLAGS) -O +mtest_LDFLAGS = $(libbacktrace_testing_ldflags) mtest_LDADD = libbacktrace.la BUILDTESTS += mtest @@ -494,11 +571,11 @@ endif USE_DSYMUTIL if HAVE_MINIDEBUG -TESTS += mtest_minidebug +MAKETESTS += mtest_minidebug %_minidebug: % $(NM) -D $< -P --defined-only | $(AWK) '{ print $$1 }' | sort > $<.dsyms - $(NM) $< -P --defined-only | $(AWK) '{ if ($$2 == "T" || $$2 == "t" || $$2 == "D" || $$2 == "d") print $$1 }' | sort > $<.fsyms + $(NM) $< -P --defined-only | $(AWK) '{ if ($$2 == "T" || $$2 == "t" || $$2 == "D") print $$1 }' | sort > $<.fsyms $(COMM) -13 $<.dsyms $<.fsyms > $<.keepsyms $(OBJCOPY) --only-keep-debug $< $<.dbg $(OBJCOPY) -S --remove-section .gdb_index --remove-section .comment --keep-symbols=$<.keepsyms $<.dbg $<.mdbg @@ -516,10 +593,12 @@ if HAVE_ELF xztest_SOURCES = xztest.c testlib.c xztest_CFLAGS = $(libbacktrace_TEST_CFLAGS) -DSRCDIR=\"$(srcdir)\" +xztest_LDFLAGS = $(libbacktrace_testing_ldflags) xztest_LDADD = libbacktrace.la xztest_alloc_SOURCES = $(xztest_SOURCES) xztest_alloc_CFLAGS = $(xztest_CFLAGS) +xztest_alloc_LDFLAGS = $(libbacktrace_testing_ldflags) xztest_alloc_LDADD = libbacktrace_alloc.la if HAVE_LIBLZMA @@ -536,10 +615,11 @@ endif HAVE_ELF check_PROGRAMS += $(BUILDTESTS) -TESTS += $(BUILDTESTS) +TESTS += $(MAKETESTS) $(BUILDTESTS) CLEANFILES = \ - $(filter-out allocfail.sh,$(TESTS)) *.debug elf_for_test.c edtest2_build.c gen_edtest2_build \ + $(MAKETESTS) $(BUILDTESTS) *.debug elf_for_test.c edtest2_build.c \ + gen_edtest2_build \ *.dsyms *.fsyms *.keepsyms *.dbg *.mdbg *.mdbg.xz *.strip clean-local: diff --git a/libbacktrace/Makefile.in b/libbacktrace/Makefile.in index 0a61880..49852a2 100644 --- a/libbacktrace/Makefile.in +++ b/libbacktrace/Makefile.in @@ -15,7 +15,7 @@ @SET_MAKE@ # Makefile.am -- Backtrace Makefile. -# Copyright (C) 2012-2021 Free Software Foundation, Inc. +# Copyright (C) 2012-2024 Free Software Foundation, Inc. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are @@ -121,10 +121,8 @@ build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \ - $(am__EXEEXT_14) -TESTS = $(am__append_4) $(am__append_7) $(am__append_9) \ - $(am__append_12) $(am__append_13) $(am__append_20) \ - $(am__append_26) $(am__EXEEXT_14) + $(am__EXEEXT_16) +TESTS = $(am__append_4) $(MAKETESTS) $(am__EXEEXT_16) @HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@am__append_1 = libbacktrace_elf_for_test.la @NATIVE_TRUE@am__append_2 = test_elf_32 test_elf_64 test_macho \ @NATIVE_TRUE@ test_xcoff_32 test_xcoff_64 test_pecoff \ @@ -135,36 +133,39 @@ TESTS = $(am__append_4) $(am__append_7) $(am__append_9) \ @NATIVE_TRUE@@USE_DSYMUTIL_TRUE@ btest.dSYM btest_alloc.dSYM \ @NATIVE_TRUE@@USE_DSYMUTIL_TRUE@ stest.dSYM stest_alloc.dSYM \ @NATIVE_TRUE@@USE_DSYMUTIL_TRUE@ edtest.dSYM edtest_alloc.dSYM -@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@am__append_6 = b2test -@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@am__append_7 = b2test_buildid -@HAVE_DWZ_TRUE@@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@am__append_8 = b3test -@HAVE_DWZ_TRUE@@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@am__append_9 = b3test_dwz_buildid +@HAVE_BUILDID_TRUE@@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@am__append_6 = b2test +@HAVE_BUILDID_TRUE@@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@am__append_7 = b2test_buildid b2test_buildidfull +@HAVE_BUILDID_TRUE@@HAVE_DWZ_TRUE@@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@am__append_8 = b3test +@HAVE_BUILDID_TRUE@@HAVE_DWZ_TRUE@@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@am__append_9 = b3test_dwz_buildid b3test_dwz_buildidfull @HAVE_ELF_TRUE@@NATIVE_TRUE@am__append_10 = btest_lto @NATIVE_TRUE@am__append_11 = btest_alloc stest stest_alloc @HAVE_DWZ_TRUE@@NATIVE_TRUE@am__append_12 = btest_dwz @HAVE_DWZ_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@am__append_13 = btest_dwz_gnudebuglink @HAVE_ELF_TRUE@@HAVE_ZLIB_TRUE@@NATIVE_TRUE@am__append_14 = -lz @HAVE_ELF_TRUE@@HAVE_ZLIB_TRUE@@NATIVE_TRUE@am__append_15 = -lz -@HAVE_ELF_TRUE@@NATIVE_TRUE@am__append_16 = ztest ztest_alloc -@NATIVE_TRUE@am__append_17 = edtest edtest_alloc -@HAVE_PTHREAD_TRUE@@NATIVE_TRUE@am__append_18 = ttest ttest_alloc -@HAVE_PTHREAD_TRUE@@NATIVE_TRUE@@USE_DSYMUTIL_TRUE@am__append_19 = \ +@HAVE_ELF_TRUE@@NATIVE_TRUE@am__append_16 = ztest ztest_alloc zstdtest \ +@HAVE_ELF_TRUE@@NATIVE_TRUE@ zstdtest_alloc +@HAVE_ELF_TRUE@@HAVE_ZSTD_TRUE@@NATIVE_TRUE@am__append_17 = -lzstd +@HAVE_ELF_TRUE@@HAVE_ZSTD_TRUE@@NATIVE_TRUE@am__append_18 = -lzstd +@NATIVE_TRUE@am__append_19 = edtest edtest_alloc +@HAVE_PTHREAD_TRUE@@NATIVE_TRUE@am__append_20 = ttest ttest_alloc +@HAVE_PTHREAD_TRUE@@NATIVE_TRUE@@USE_DSYMUTIL_TRUE@am__append_21 = \ @HAVE_PTHREAD_TRUE@@NATIVE_TRUE@@USE_DSYMUTIL_TRUE@ ttest.dSYM \ @HAVE_PTHREAD_TRUE@@NATIVE_TRUE@@USE_DSYMUTIL_TRUE@ ttest_alloc.dSYM -@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@am__append_20 = btest_gnudebuglink -@HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@am__append_21 = ctestg ctesta \ -@HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@ ctestg_alloc \ -@HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@ ctesta_alloc -@HAVE_DWARF5_TRUE@@NATIVE_TRUE@am__append_22 = dwarf5 dwarf5_alloc -@HAVE_DWARF5_TRUE@@NATIVE_TRUE@@USE_DSYMUTIL_TRUE@am__append_23 = \ +@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@am__append_22 = btest_gnudebuglink btest_gnudebuglinkfull +@HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@am__append_23 = ctestg ctesta +@HAVE_COMPRESSED_DEBUG_TRUE@@HAVE_COMPRESSED_DEBUG_ZSTD_TRUE@@NATIVE_TRUE@am__append_24 = ctestzstd +@HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@am__append_25 = ctestg_alloc ctesta_alloc +@HAVE_DWARF5_TRUE@@NATIVE_TRUE@am__append_26 = dwarf5 dwarf5_alloc +@HAVE_DWARF5_TRUE@@NATIVE_TRUE@@USE_DSYMUTIL_TRUE@am__append_27 = \ @HAVE_DWARF5_TRUE@@NATIVE_TRUE@@USE_DSYMUTIL_TRUE@ dwarf5.dSYM \ @HAVE_DWARF5_TRUE@@NATIVE_TRUE@@USE_DSYMUTIL_TRUE@ dwarf5_alloc.dSYM -@NATIVE_TRUE@am__append_24 = mtest -@NATIVE_TRUE@@USE_DSYMUTIL_TRUE@am__append_25 = mtest.dSYM -@HAVE_MINIDEBUG_TRUE@@NATIVE_TRUE@am__append_26 = mtest_minidebug -@HAVE_ELF_TRUE@@HAVE_LIBLZMA_TRUE@am__append_27 = -llzma -@HAVE_ELF_TRUE@@HAVE_LIBLZMA_TRUE@am__append_28 = -llzma -@HAVE_ELF_TRUE@am__append_29 = xztest xztest_alloc +@NATIVE_TRUE@am__append_28 = mtest +@NATIVE_TRUE@@USE_DSYMUTIL_TRUE@am__append_29 = mtest.dSYM +@HAVE_MINIDEBUG_TRUE@@NATIVE_TRUE@am__append_30 = mtest_minidebug +@HAVE_ELF_TRUE@@HAVE_LIBLZMA_TRUE@am__append_31 = -llzma +@HAVE_ELF_TRUE@@HAVE_LIBLZMA_TRUE@am__append_32 = -llzma +@HAVE_ELF_TRUE@am__append_33 = xztest xztest_alloc subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/../config/cet.m4 \ @@ -221,8 +222,8 @@ libbacktrace_noformat_la_OBJECTS = \ $(am_libbacktrace_noformat_la_OBJECTS) @NATIVE_TRUE@am_libbacktrace_noformat_la_rpath = @NATIVE_TRUE@am__EXEEXT_1 = allocfail$(EXEEXT) -@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@am__EXEEXT_2 = b2test$(EXEEXT) -@HAVE_DWZ_TRUE@@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@am__EXEEXT_3 = b3test$(EXEEXT) +@HAVE_BUILDID_TRUE@@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@am__EXEEXT_2 = b2test$(EXEEXT) +@HAVE_BUILDID_TRUE@@HAVE_DWZ_TRUE@@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@am__EXEEXT_3 = b3test$(EXEEXT) @NATIVE_TRUE@am__EXEEXT_4 = test_elf_32$(EXEEXT) test_elf_64$(EXEEXT) \ @NATIVE_TRUE@ test_macho$(EXEEXT) test_xcoff_32$(EXEEXT) \ @NATIVE_TRUE@ test_xcoff_64$(EXEEXT) test_pecoff$(EXEEXT) \ @@ -232,23 +233,26 @@ libbacktrace_noformat_la_OBJECTS = \ @NATIVE_TRUE@am__EXEEXT_6 = btest_alloc$(EXEEXT) stest$(EXEEXT) \ @NATIVE_TRUE@ stest_alloc$(EXEEXT) @HAVE_ELF_TRUE@@NATIVE_TRUE@am__EXEEXT_7 = ztest$(EXEEXT) \ -@HAVE_ELF_TRUE@@NATIVE_TRUE@ ztest_alloc$(EXEEXT) +@HAVE_ELF_TRUE@@NATIVE_TRUE@ ztest_alloc$(EXEEXT) \ +@HAVE_ELF_TRUE@@NATIVE_TRUE@ zstdtest$(EXEEXT) \ +@HAVE_ELF_TRUE@@NATIVE_TRUE@ zstdtest_alloc$(EXEEXT) @NATIVE_TRUE@am__EXEEXT_8 = edtest$(EXEEXT) edtest_alloc$(EXEEXT) @HAVE_PTHREAD_TRUE@@NATIVE_TRUE@am__EXEEXT_9 = ttest$(EXEEXT) \ @HAVE_PTHREAD_TRUE@@NATIVE_TRUE@ ttest_alloc$(EXEEXT) @HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@am__EXEEXT_10 = \ @HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@ ctestg$(EXEEXT) \ -@HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@ ctesta$(EXEEXT) \ -@HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@ ctestg_alloc$(EXEEXT) \ +@HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@ ctesta$(EXEEXT) +@HAVE_COMPRESSED_DEBUG_TRUE@@HAVE_COMPRESSED_DEBUG_ZSTD_TRUE@@NATIVE_TRUE@am__EXEEXT_11 = ctestzstd$(EXEEXT) +@HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@am__EXEEXT_12 = ctestg_alloc$(EXEEXT) \ @HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@ ctesta_alloc$(EXEEXT) -@HAVE_DWARF5_TRUE@@NATIVE_TRUE@am__EXEEXT_11 = dwarf5$(EXEEXT) \ +@HAVE_DWARF5_TRUE@@NATIVE_TRUE@am__EXEEXT_13 = dwarf5$(EXEEXT) \ @HAVE_DWARF5_TRUE@@NATIVE_TRUE@ dwarf5_alloc$(EXEEXT) -@NATIVE_TRUE@am__EXEEXT_12 = mtest$(EXEEXT) -@HAVE_ELF_TRUE@am__EXEEXT_13 = xztest$(EXEEXT) xztest_alloc$(EXEEXT) -am__EXEEXT_14 = $(am__EXEEXT_4) $(am__EXEEXT_5) $(am__EXEEXT_6) \ +@NATIVE_TRUE@am__EXEEXT_14 = mtest$(EXEEXT) +@HAVE_ELF_TRUE@am__EXEEXT_15 = xztest$(EXEEXT) xztest_alloc$(EXEEXT) +am__EXEEXT_16 = $(am__EXEEXT_4) $(am__EXEEXT_5) $(am__EXEEXT_6) \ $(am__EXEEXT_7) $(am__EXEEXT_8) $(am__EXEEXT_9) \ $(am__EXEEXT_10) $(am__EXEEXT_11) $(am__EXEEXT_12) \ - $(am__EXEEXT_13) + $(am__EXEEXT_13) $(am__EXEEXT_14) $(am__EXEEXT_15) @NATIVE_TRUE@am_allocfail_OBJECTS = allocfail-allocfail.$(OBJEXT) \ @NATIVE_TRUE@ allocfail-testlib.$(OBJEXT) allocfail_OBJECTS = $(am_allocfail_OBJECTS) @@ -259,17 +263,17 @@ allocfail_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ @NATIVE_TRUE@am__objects_2 = b2test-btest.$(OBJEXT) \ @NATIVE_TRUE@ b2test-testlib.$(OBJEXT) -@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@am_b2test_OBJECTS = $(am__objects_2) +@HAVE_BUILDID_TRUE@@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@am_b2test_OBJECTS = $(am__objects_2) b2test_OBJECTS = $(am_b2test_OBJECTS) -@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@b2test_DEPENDENCIES = libbacktrace_elf_for_test.la +@HAVE_BUILDID_TRUE@@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@b2test_DEPENDENCIES = libbacktrace_elf_for_test.la b2test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(b2test_CFLAGS) $(CFLAGS) \ $(b2test_LDFLAGS) $(LDFLAGS) -o $@ @NATIVE_TRUE@am__objects_3 = b3test-btest.$(OBJEXT) \ @NATIVE_TRUE@ b3test-testlib.$(OBJEXT) -@HAVE_DWZ_TRUE@@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@am_b3test_OBJECTS = $(am__objects_3) +@HAVE_BUILDID_TRUE@@HAVE_DWZ_TRUE@@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@am_b3test_OBJECTS = $(am__objects_3) b3test_OBJECTS = $(am_b3test_OBJECTS) -@HAVE_DWZ_TRUE@@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@b3test_DEPENDENCIES = libbacktrace_elf_for_test.la +@HAVE_BUILDID_TRUE@@HAVE_DWZ_TRUE@@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@b3test_DEPENDENCIES = libbacktrace_elf_for_test.la b3test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(b3test_CFLAGS) $(CFLAGS) \ $(b3test_LDFLAGS) $(LDFLAGS) -o $@ @@ -279,7 +283,7 @@ btest_OBJECTS = $(am_btest_OBJECTS) @NATIVE_TRUE@btest_DEPENDENCIES = libbacktrace.la btest_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(btest_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ + $(btest_LDFLAGS) $(LDFLAGS) -o $@ @NATIVE_TRUE@am__objects_4 = btest_alloc-btest.$(OBJEXT) \ @NATIVE_TRUE@ btest_alloc-testlib.$(OBJEXT) @NATIVE_TRUE@am_btest_alloc_OBJECTS = $(am__objects_4) @@ -287,7 +291,7 @@ btest_alloc_OBJECTS = $(am_btest_alloc_OBJECTS) @NATIVE_TRUE@btest_alloc_DEPENDENCIES = libbacktrace_alloc.la btest_alloc_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(btest_alloc_CFLAGS) \ - $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ + $(CFLAGS) $(btest_alloc_LDFLAGS) $(LDFLAGS) -o $@ @HAVE_ELF_TRUE@@NATIVE_TRUE@am_btest_lto_OBJECTS = \ @HAVE_ELF_TRUE@@NATIVE_TRUE@ btest_lto-btest.$(OBJEXT) \ @HAVE_ELF_TRUE@@NATIVE_TRUE@ btest_lto-testlib.$(OBJEXT) @@ -295,7 +299,7 @@ btest_lto_OBJECTS = $(am_btest_lto_OBJECTS) @HAVE_ELF_TRUE@@NATIVE_TRUE@btest_lto_DEPENDENCIES = libbacktrace.la btest_lto_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(btest_lto_CFLAGS) \ - $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ + $(CFLAGS) $(btest_lto_LDFLAGS) $(LDFLAGS) -o $@ @HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@am_ctesta_OBJECTS = ctesta-btest.$(OBJEXT) \ @HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@ ctesta-testlib.$(OBJEXT) ctesta_OBJECTS = $(am_ctesta_OBJECTS) @@ -330,6 +334,13 @@ ctestg_alloc_OBJECTS = $(am_ctestg_alloc_OBJECTS) ctestg_alloc_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(ctestg_alloc_CFLAGS) \ $(CFLAGS) $(ctestg_alloc_LDFLAGS) $(LDFLAGS) -o $@ +@HAVE_COMPRESSED_DEBUG_TRUE@@HAVE_COMPRESSED_DEBUG_ZSTD_TRUE@@NATIVE_TRUE@am_ctestzstd_OBJECTS = ctestzstd-btest.$(OBJEXT) \ +@HAVE_COMPRESSED_DEBUG_TRUE@@HAVE_COMPRESSED_DEBUG_ZSTD_TRUE@@NATIVE_TRUE@ ctestzstd-testlib.$(OBJEXT) +ctestzstd_OBJECTS = $(am_ctestzstd_OBJECTS) +@HAVE_COMPRESSED_DEBUG_TRUE@@HAVE_COMPRESSED_DEBUG_ZSTD_TRUE@@NATIVE_TRUE@ctestzstd_DEPENDENCIES = libbacktrace.la +ctestzstd_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(ctestzstd_CFLAGS) \ + $(CFLAGS) $(ctestzstd_LDFLAGS) $(LDFLAGS) -o $@ @HAVE_DWARF5_TRUE@@NATIVE_TRUE@am_dwarf5_OBJECTS = \ @HAVE_DWARF5_TRUE@@NATIVE_TRUE@ dwarf5-btest.$(OBJEXT) \ @HAVE_DWARF5_TRUE@@NATIVE_TRUE@ dwarf5-testlib.$(OBJEXT) @@ -337,7 +348,7 @@ dwarf5_OBJECTS = $(am_dwarf5_OBJECTS) @HAVE_DWARF5_TRUE@@NATIVE_TRUE@dwarf5_DEPENDENCIES = libbacktrace.la dwarf5_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(dwarf5_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ + $(dwarf5_LDFLAGS) $(LDFLAGS) -o $@ @HAVE_DWARF5_TRUE@@NATIVE_TRUE@am__objects_7 = \ @HAVE_DWARF5_TRUE@@NATIVE_TRUE@ dwarf5_alloc-btest.$(OBJEXT) \ @HAVE_DWARF5_TRUE@@NATIVE_TRUE@ dwarf5_alloc-testlib.$(OBJEXT) @@ -348,7 +359,7 @@ dwarf5_alloc_OBJECTS = $(am_dwarf5_alloc_OBJECTS) @HAVE_DWARF5_TRUE@@NATIVE_TRUE@ libbacktrace_alloc.la dwarf5_alloc_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(dwarf5_alloc_CFLAGS) \ - $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ + $(CFLAGS) $(dwarf5_alloc_LDFLAGS) $(LDFLAGS) -o $@ @NATIVE_TRUE@am_edtest_OBJECTS = edtest-edtest.$(OBJEXT) \ @NATIVE_TRUE@ edtest-edtest2_build.$(OBJEXT) \ @NATIVE_TRUE@ edtest-testlib.$(OBJEXT) @@ -356,7 +367,7 @@ edtest_OBJECTS = $(am_edtest_OBJECTS) @NATIVE_TRUE@edtest_DEPENDENCIES = libbacktrace.la edtest_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(edtest_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ + $(edtest_LDFLAGS) $(LDFLAGS) -o $@ @NATIVE_TRUE@am__objects_8 = edtest_alloc-edtest.$(OBJEXT) \ @NATIVE_TRUE@ edtest_alloc-edtest2_build.$(OBJEXT) \ @NATIVE_TRUE@ edtest_alloc-testlib.$(OBJEXT) @@ -365,27 +376,27 @@ edtest_alloc_OBJECTS = $(am_edtest_alloc_OBJECTS) @NATIVE_TRUE@edtest_alloc_DEPENDENCIES = libbacktrace_alloc.la edtest_alloc_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(edtest_alloc_CFLAGS) \ - $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ + $(CFLAGS) $(edtest_alloc_LDFLAGS) $(LDFLAGS) -o $@ @NATIVE_TRUE@am_mtest_OBJECTS = mtest-mtest.$(OBJEXT) \ @NATIVE_TRUE@ mtest-testlib.$(OBJEXT) mtest_OBJECTS = $(am_mtest_OBJECTS) @NATIVE_TRUE@mtest_DEPENDENCIES = libbacktrace.la mtest_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(mtest_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ + $(mtest_LDFLAGS) $(LDFLAGS) -o $@ @NATIVE_TRUE@am_stest_OBJECTS = stest-stest.$(OBJEXT) stest_OBJECTS = $(am_stest_OBJECTS) @NATIVE_TRUE@stest_DEPENDENCIES = libbacktrace.la stest_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(stest_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ + $(stest_LDFLAGS) $(LDFLAGS) -o $@ @NATIVE_TRUE@am__objects_9 = stest_alloc-stest.$(OBJEXT) @NATIVE_TRUE@am_stest_alloc_OBJECTS = $(am__objects_9) stest_alloc_OBJECTS = $(am_stest_alloc_OBJECTS) @NATIVE_TRUE@stest_alloc_DEPENDENCIES = libbacktrace_alloc.la stest_alloc_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(stest_alloc_CFLAGS) \ - $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ + $(CFLAGS) $(stest_alloc_LDFLAGS) $(LDFLAGS) -o $@ @NATIVE_TRUE@am_test_elf_32_OBJECTS = \ @NATIVE_TRUE@ test_elf_32-test_format.$(OBJEXT) \ @NATIVE_TRUE@ test_elf_32-testlib.$(OBJEXT) @@ -394,7 +405,7 @@ test_elf_32_OBJECTS = $(am_test_elf_32_OBJECTS) @NATIVE_TRUE@ elf_32.lo test_elf_32_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(test_elf_32_CFLAGS) \ - $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ + $(CFLAGS) $(test_elf_32_LDFLAGS) $(LDFLAGS) -o $@ @NATIVE_TRUE@am_test_elf_64_OBJECTS = \ @NATIVE_TRUE@ test_elf_64-test_format.$(OBJEXT) \ @NATIVE_TRUE@ test_elf_64-testlib.$(OBJEXT) @@ -403,7 +414,7 @@ test_elf_64_OBJECTS = $(am_test_elf_64_OBJECTS) @NATIVE_TRUE@ elf_64.lo test_elf_64_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(test_elf_64_CFLAGS) \ - $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ + $(CFLAGS) $(test_elf_64_LDFLAGS) $(LDFLAGS) -o $@ @NATIVE_TRUE@am_test_macho_OBJECTS = test_macho-test_format.$(OBJEXT) \ @NATIVE_TRUE@ test_macho-testlib.$(OBJEXT) test_macho_OBJECTS = $(am_test_macho_OBJECTS) @@ -411,7 +422,7 @@ test_macho_OBJECTS = $(am_test_macho_OBJECTS) @NATIVE_TRUE@ macho.lo test_macho_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(test_macho_CFLAGS) \ - $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ + $(CFLAGS) $(test_macho_LDFLAGS) $(LDFLAGS) -o $@ @NATIVE_TRUE@am_test_pecoff_OBJECTS = \ @NATIVE_TRUE@ test_pecoff-test_format.$(OBJEXT) \ @NATIVE_TRUE@ test_pecoff-testlib.$(OBJEXT) @@ -420,7 +431,7 @@ test_pecoff_OBJECTS = $(am_test_pecoff_OBJECTS) @NATIVE_TRUE@ pecoff.lo test_pecoff_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(test_pecoff_CFLAGS) \ - $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ + $(CFLAGS) $(test_pecoff_LDFLAGS) $(LDFLAGS) -o $@ @NATIVE_TRUE@am_test_unknown_OBJECTS = \ @NATIVE_TRUE@ test_unknown-test_format.$(OBJEXT) \ @NATIVE_TRUE@ test_unknown-testlib.$(OBJEXT) @@ -429,7 +440,7 @@ test_unknown_OBJECTS = $(am_test_unknown_OBJECTS) @NATIVE_TRUE@ unknown.lo test_unknown_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(test_unknown_CFLAGS) \ - $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ + $(CFLAGS) $(test_unknown_LDFLAGS) $(LDFLAGS) -o $@ @NATIVE_TRUE@am_test_xcoff_32_OBJECTS = \ @NATIVE_TRUE@ test_xcoff_32-test_format.$(OBJEXT) \ @NATIVE_TRUE@ test_xcoff_32-testlib.$(OBJEXT) @@ -438,7 +449,7 @@ test_xcoff_32_OBJECTS = $(am_test_xcoff_32_OBJECTS) @NATIVE_TRUE@ xcoff_32.lo test_xcoff_32_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(test_xcoff_32_CFLAGS) \ - $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ + $(CFLAGS) $(test_xcoff_32_LDFLAGS) $(LDFLAGS) -o $@ @NATIVE_TRUE@am_test_xcoff_64_OBJECTS = \ @NATIVE_TRUE@ test_xcoff_64-test_format.$(OBJEXT) \ @NATIVE_TRUE@ test_xcoff_64-testlib.$(OBJEXT) @@ -447,7 +458,7 @@ test_xcoff_64_OBJECTS = $(am_test_xcoff_64_OBJECTS) @NATIVE_TRUE@ xcoff_64.lo test_xcoff_64_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(test_xcoff_64_CFLAGS) \ - $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ + $(CFLAGS) $(test_xcoff_64_LDFLAGS) $(LDFLAGS) -o $@ @HAVE_PTHREAD_TRUE@@NATIVE_TRUE@am_ttest_OBJECTS = \ @HAVE_PTHREAD_TRUE@@NATIVE_TRUE@ ttest-ttest.$(OBJEXT) \ @HAVE_PTHREAD_TRUE@@NATIVE_TRUE@ ttest-testlib.$(OBJEXT) @@ -455,7 +466,7 @@ ttest_OBJECTS = $(am_ttest_OBJECTS) @HAVE_PTHREAD_TRUE@@NATIVE_TRUE@ttest_DEPENDENCIES = libbacktrace.la ttest_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(ttest_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ + $(ttest_LDFLAGS) $(LDFLAGS) -o $@ @HAVE_PTHREAD_TRUE@@NATIVE_TRUE@am__objects_10 = \ @HAVE_PTHREAD_TRUE@@NATIVE_TRUE@ ttest_alloc-ttest.$(OBJEXT) \ @HAVE_PTHREAD_TRUE@@NATIVE_TRUE@ ttest_alloc-testlib.$(OBJEXT) @@ -466,14 +477,14 @@ ttest_alloc_OBJECTS = $(am_ttest_alloc_OBJECTS) @HAVE_PTHREAD_TRUE@@NATIVE_TRUE@ libbacktrace_alloc.la ttest_alloc_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(ttest_alloc_CFLAGS) \ - $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ + $(CFLAGS) $(ttest_alloc_LDFLAGS) $(LDFLAGS) -o $@ @NATIVE_TRUE@am_unittest_OBJECTS = unittest-unittest.$(OBJEXT) \ @NATIVE_TRUE@ unittest-testlib.$(OBJEXT) unittest_OBJECTS = $(am_unittest_OBJECTS) @NATIVE_TRUE@unittest_DEPENDENCIES = libbacktrace.la unittest_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(unittest_CFLAGS) \ - $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ + $(CFLAGS) $(unittest_LDFLAGS) $(LDFLAGS) -o $@ @NATIVE_TRUE@am__objects_11 = unittest_alloc-unittest.$(OBJEXT) \ @NATIVE_TRUE@ unittest_alloc-testlib.$(OBJEXT) @NATIVE_TRUE@am_unittest_alloc_OBJECTS = $(am__objects_11) @@ -481,8 +492,8 @@ unittest_alloc_OBJECTS = $(am_unittest_alloc_OBJECTS) @NATIVE_TRUE@unittest_alloc_DEPENDENCIES = libbacktrace_alloc.la unittest_alloc_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(unittest_alloc_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o \ - $@ + $(unittest_alloc_CFLAGS) $(CFLAGS) $(unittest_alloc_LDFLAGS) \ + $(LDFLAGS) -o $@ @HAVE_ELF_TRUE@am_xztest_OBJECTS = xztest-xztest.$(OBJEXT) \ @HAVE_ELF_TRUE@ xztest-testlib.$(OBJEXT) xztest_OBJECTS = $(am_xztest_OBJECTS) @@ -490,7 +501,7 @@ xztest_OBJECTS = $(am_xztest_OBJECTS) @HAVE_ELF_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) xztest_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(xztest_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ + $(xztest_LDFLAGS) $(LDFLAGS) -o $@ @HAVE_ELF_TRUE@am__objects_12 = xztest_alloc-xztest.$(OBJEXT) \ @HAVE_ELF_TRUE@ xztest_alloc-testlib.$(OBJEXT) @HAVE_ELF_TRUE@am_xztest_alloc_OBJECTS = $(am__objects_12) @@ -499,7 +510,31 @@ xztest_alloc_OBJECTS = $(am_xztest_alloc_OBJECTS) @HAVE_ELF_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) xztest_alloc_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(xztest_alloc_CFLAGS) \ - $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ + $(CFLAGS) $(xztest_alloc_LDFLAGS) $(LDFLAGS) -o $@ +@HAVE_ELF_TRUE@@NATIVE_TRUE@am_zstdtest_OBJECTS = \ +@HAVE_ELF_TRUE@@NATIVE_TRUE@ zstdtest-zstdtest.$(OBJEXT) \ +@HAVE_ELF_TRUE@@NATIVE_TRUE@ zstdtest-testlib.$(OBJEXT) +zstdtest_OBJECTS = $(am_zstdtest_OBJECTS) +@HAVE_ELF_TRUE@@NATIVE_TRUE@zstdtest_DEPENDENCIES = libbacktrace.la \ +@HAVE_ELF_TRUE@@NATIVE_TRUE@ $(am__DEPENDENCIES_1) \ +@HAVE_ELF_TRUE@@NATIVE_TRUE@ $(am__DEPENDENCIES_1) +zstdtest_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(zstdtest_CFLAGS) \ + $(CFLAGS) $(zstdtest_LDFLAGS) $(LDFLAGS) -o $@ +@HAVE_ELF_TRUE@@NATIVE_TRUE@am__objects_13 = \ +@HAVE_ELF_TRUE@@NATIVE_TRUE@ zstdtest_alloc-zstdtest.$(OBJEXT) \ +@HAVE_ELF_TRUE@@NATIVE_TRUE@ zstdtest_alloc-testlib.$(OBJEXT) +@HAVE_ELF_TRUE@@NATIVE_TRUE@am_zstdtest_alloc_OBJECTS = \ +@HAVE_ELF_TRUE@@NATIVE_TRUE@ $(am__objects_13) +zstdtest_alloc_OBJECTS = $(am_zstdtest_alloc_OBJECTS) +@HAVE_ELF_TRUE@@NATIVE_TRUE@zstdtest_alloc_DEPENDENCIES = \ +@HAVE_ELF_TRUE@@NATIVE_TRUE@ libbacktrace_alloc.la \ +@HAVE_ELF_TRUE@@NATIVE_TRUE@ $(am__DEPENDENCIES_1) \ +@HAVE_ELF_TRUE@@NATIVE_TRUE@ $(am__DEPENDENCIES_1) +zstdtest_alloc_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(zstdtest_alloc_CFLAGS) $(CFLAGS) $(zstdtest_alloc_LDFLAGS) \ + $(LDFLAGS) -o $@ @HAVE_ELF_TRUE@@NATIVE_TRUE@am_ztest_OBJECTS = ztest-ztest.$(OBJEXT) \ @HAVE_ELF_TRUE@@NATIVE_TRUE@ ztest-testlib.$(OBJEXT) ztest_OBJECTS = $(am_ztest_OBJECTS) @@ -508,12 +543,12 @@ ztest_OBJECTS = $(am_ztest_OBJECTS) @HAVE_ELF_TRUE@@NATIVE_TRUE@ $(am__DEPENDENCIES_1) ztest_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(ztest_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -@HAVE_ELF_TRUE@@NATIVE_TRUE@am__objects_13 = \ + $(ztest_LDFLAGS) $(LDFLAGS) -o $@ +@HAVE_ELF_TRUE@@NATIVE_TRUE@am__objects_14 = \ @HAVE_ELF_TRUE@@NATIVE_TRUE@ ztest_alloc-ztest.$(OBJEXT) \ @HAVE_ELF_TRUE@@NATIVE_TRUE@ ztest_alloc-testlib.$(OBJEXT) @HAVE_ELF_TRUE@@NATIVE_TRUE@am_ztest_alloc_OBJECTS = \ -@HAVE_ELF_TRUE@@NATIVE_TRUE@ $(am__objects_13) +@HAVE_ELF_TRUE@@NATIVE_TRUE@ $(am__objects_14) ztest_alloc_OBJECTS = $(am_ztest_alloc_OBJECTS) @HAVE_ELF_TRUE@@NATIVE_TRUE@ztest_alloc_DEPENDENCIES = \ @HAVE_ELF_TRUE@@NATIVE_TRUE@ libbacktrace_alloc.la \ @@ -521,7 +556,7 @@ ztest_alloc_OBJECTS = $(am_ztest_alloc_OBJECTS) @HAVE_ELF_TRUE@@NATIVE_TRUE@ $(am__DEPENDENCIES_1) ztest_alloc_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(ztest_alloc_CFLAGS) \ - $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ + $(CFLAGS) $(ztest_alloc_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false @@ -563,7 +598,7 @@ SOURCES = $(libbacktrace_la_SOURCES) $(EXTRA_libbacktrace_la_SOURCES) \ $(b2test_SOURCES) $(b3test_SOURCES) $(btest_SOURCES) \ $(btest_alloc_SOURCES) $(btest_lto_SOURCES) $(ctesta_SOURCES) \ $(ctesta_alloc_SOURCES) $(ctestg_SOURCES) \ - $(ctestg_alloc_SOURCES) $(dwarf5_SOURCES) \ + $(ctestg_alloc_SOURCES) $(ctestzstd_SOURCES) $(dwarf5_SOURCES) \ $(dwarf5_alloc_SOURCES) $(edtest_SOURCES) \ $(edtest_alloc_SOURCES) $(mtest_SOURCES) $(stest_SOURCES) \ $(stest_alloc_SOURCES) $(test_elf_32_SOURCES) \ @@ -572,7 +607,8 @@ SOURCES = $(libbacktrace_la_SOURCES) $(EXTRA_libbacktrace_la_SOURCES) \ $(test_xcoff_32_SOURCES) $(test_xcoff_64_SOURCES) \ $(ttest_SOURCES) $(ttest_alloc_SOURCES) $(unittest_SOURCES) \ $(unittest_alloc_SOURCES) $(xztest_SOURCES) \ - $(xztest_alloc_SOURCES) $(ztest_SOURCES) \ + $(xztest_alloc_SOURCES) $(zstdtest_SOURCES) \ + $(zstdtest_alloc_SOURCES) $(ztest_SOURCES) \ $(ztest_alloc_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ @@ -988,18 +1024,28 @@ libbacktrace_la_LIBADD = \ libbacktrace_la_DEPENDENCIES = $(libbacktrace_la_LIBADD) -# Add a test to this variable if you want it to be built and run. +# Add a test to this variable if you want it to be built as a Makefile +# target and run. +MAKETESTS = $(am__append_7) $(am__append_9) $(am__append_12) \ + $(am__append_13) $(am__append_22) $(am__append_30) + +# Add a test to this variable if you want it to be built as a program, +# with SOURCES, etc., and run. BUILDTESTS = $(am__append_2) $(am__append_10) $(am__append_11) \ - $(am__append_16) $(am__append_17) $(am__append_18) \ - $(am__append_21) $(am__append_22) $(am__append_24) \ - $(am__append_29) + $(am__append_16) $(am__append_19) $(am__append_20) \ + $(am__append_23) $(am__append_24) $(am__append_25) \ + $(am__append_26) $(am__append_28) $(am__append_33) # Add a file to this variable if you want it to be built for testing. -check_DATA = $(am__append_5) $(am__append_19) $(am__append_23) \ - $(am__append_25) +check_DATA = $(am__append_5) $(am__append_21) $(am__append_27) \ + $(am__append_29) # Flags to use when compiling test programs. libbacktrace_TEST_CFLAGS = $(EXTRA_FLAGS) $(WARN_FLAGS) -g + +# Flags to use when linking test programs. +# This avoids generating a shell script when configured with --enable-shared. +libbacktrace_testing_ldflags = -no-install @NATIVE_TRUE@check_LTLIBRARIES = libbacktrace_alloc.la \ @NATIVE_TRUE@ libbacktrace_noformat.la $(am__append_1) \ @NATIVE_TRUE@ libbacktrace_instrumented_alloc.la @@ -1016,30 +1062,39 @@ libbacktrace_TEST_CFLAGS = $(EXTRA_FLAGS) $(WARN_FLAGS) -g @NATIVE_TRUE@test_elf_32_SOURCES = test_format.c testlib.c @NATIVE_TRUE@test_elf_32_CFLAGS = $(libbacktrace_TEST_CFLAGS) +@NATIVE_TRUE@test_elf_32_LDFLAGS = $(libbacktrace_testing_ldflags) @NATIVE_TRUE@test_elf_32_LDADD = libbacktrace_noformat.la elf_32.lo @NATIVE_TRUE@test_elf_64_SOURCES = test_format.c testlib.c @NATIVE_TRUE@test_elf_64_CFLAGS = $(libbacktrace_TEST_CFLAGS) +@NATIVE_TRUE@test_elf_64_LDFLAGS = $(libbacktrace_testing_ldflags) @NATIVE_TRUE@test_elf_64_LDADD = libbacktrace_noformat.la elf_64.lo @NATIVE_TRUE@test_macho_SOURCES = test_format.c testlib.c @NATIVE_TRUE@test_macho_CFLAGS = $(libbacktrace_TEST_CFLAGS) +@NATIVE_TRUE@test_macho_LDFLAGS = $(libbacktrace_testing_ldflags) @NATIVE_TRUE@test_macho_LDADD = libbacktrace_noformat.la macho.lo @NATIVE_TRUE@test_xcoff_32_SOURCES = test_format.c testlib.c @NATIVE_TRUE@test_xcoff_32_CFLAGS = $(libbacktrace_TEST_CFLAGS) +@NATIVE_TRUE@test_xcoff_32_LDFLAGS = $(libbacktrace_testing_ldflags) @NATIVE_TRUE@test_xcoff_32_LDADD = libbacktrace_noformat.la xcoff_32.lo @NATIVE_TRUE@test_xcoff_64_SOURCES = test_format.c testlib.c @NATIVE_TRUE@test_xcoff_64_CFLAGS = $(libbacktrace_TEST_CFLAGS) +@NATIVE_TRUE@test_xcoff_64_LDFLAGS = $(libbacktrace_testing_ldflags) @NATIVE_TRUE@test_xcoff_64_LDADD = libbacktrace_noformat.la xcoff_64.lo @NATIVE_TRUE@test_pecoff_SOURCES = test_format.c testlib.c @NATIVE_TRUE@test_pecoff_CFLAGS = $(libbacktrace_TEST_CFLAGS) +@NATIVE_TRUE@test_pecoff_LDFLAGS = $(libbacktrace_testing_ldflags) @NATIVE_TRUE@test_pecoff_LDADD = libbacktrace_noformat.la pecoff.lo @NATIVE_TRUE@test_unknown_SOURCES = test_format.c testlib.c @NATIVE_TRUE@test_unknown_CFLAGS = $(libbacktrace_TEST_CFLAGS) +@NATIVE_TRUE@test_unknown_LDFLAGS = $(libbacktrace_testing_ldflags) @NATIVE_TRUE@test_unknown_LDADD = libbacktrace_noformat.la unknown.lo @NATIVE_TRUE@unittest_SOURCES = unittest.c testlib.c @NATIVE_TRUE@unittest_CFLAGS = $(libbacktrace_TEST_CFLAGS) +@NATIVE_TRUE@unittest_LDFLAGS = $(libbacktrace_testing_ldflags) @NATIVE_TRUE@unittest_LDADD = libbacktrace.la @NATIVE_TRUE@unittest_alloc_SOURCES = $(unittest_SOURCES) @NATIVE_TRUE@unittest_alloc_CFLAGS = $(libbacktrace_TEST_CFLAGS) +@NATIVE_TRUE@unittest_alloc_LDFLAGS = $(libbacktrace_testing_ldflags) @NATIVE_TRUE@unittest_alloc_LDADD = libbacktrace_alloc.la @NATIVE_TRUE@libbacktrace_instrumented_alloc_la_SOURCES = $(libbacktrace_la_SOURCES) @NATIVE_TRUE@libbacktrace_instrumented_alloc_la_LIBADD = $(BACKTRACE_FILE) $(FORMAT_FILE) \ @@ -1051,31 +1106,37 @@ libbacktrace_TEST_CFLAGS = $(EXTRA_FLAGS) $(WARN_FLAGS) -g @NATIVE_TRUE@allocfail_SOURCES = allocfail.c testlib.c @NATIVE_TRUE@allocfail_CFLAGS = $(libbacktrace_TEST_CFLAGS) @NATIVE_TRUE@allocfail_LDADD = libbacktrace_instrumented_alloc.la -@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@b2test_SOURCES = $(btest_SOURCES) -@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@b2test_CFLAGS = $(libbacktrace_TEST_CFLAGS) -@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@b2test_LDFLAGS = -Wl,--build-id -@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@b2test_LDADD = libbacktrace_elf_for_test.la -@HAVE_DWZ_TRUE@@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@b3test_SOURCES = $(btest_SOURCES) -@HAVE_DWZ_TRUE@@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@b3test_CFLAGS = $(libbacktrace_TEST_CFLAGS) -@HAVE_DWZ_TRUE@@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@b3test_LDFLAGS = -Wl,--build-id -@HAVE_DWZ_TRUE@@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@b3test_LDADD = libbacktrace_elf_for_test.la +@HAVE_BUILDID_TRUE@@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@b2test_SOURCES = $(btest_SOURCES) +@HAVE_BUILDID_TRUE@@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@b2test_CFLAGS = $(libbacktrace_TEST_CFLAGS) +@HAVE_BUILDID_TRUE@@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@b2test_LDFLAGS = -Wl,--build-id $(libbacktrace_testing_ldflags) +@HAVE_BUILDID_TRUE@@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@b2test_LDADD = libbacktrace_elf_for_test.la +@HAVE_BUILDID_TRUE@@HAVE_DWZ_TRUE@@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@b3test_SOURCES = $(btest_SOURCES) +@HAVE_BUILDID_TRUE@@HAVE_DWZ_TRUE@@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@b3test_CFLAGS = $(libbacktrace_TEST_CFLAGS) +@HAVE_BUILDID_TRUE@@HAVE_DWZ_TRUE@@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@b3test_LDFLAGS = -Wl,--build-id $(libbacktrace_testing_ldflags) +@HAVE_BUILDID_TRUE@@HAVE_DWZ_TRUE@@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@b3test_LDADD = libbacktrace_elf_for_test.la @NATIVE_TRUE@btest_SOURCES = btest.c testlib.c @NATIVE_TRUE@btest_CFLAGS = $(libbacktrace_TEST_CFLAGS) -O +@NATIVE_TRUE@btest_LDFLAGS = $(libbacktrace_testing_ldflags) @NATIVE_TRUE@btest_LDADD = libbacktrace.la @HAVE_ELF_TRUE@@NATIVE_TRUE@btest_lto_SOURCES = btest.c testlib.c @HAVE_ELF_TRUE@@NATIVE_TRUE@btest_lto_CFLAGS = $(libbacktrace_TEST_CFLAGS) -O -flto +@HAVE_ELF_TRUE@@NATIVE_TRUE@btest_lto_LDFLAGS = $(libbacktrace_testing_ldflags) @HAVE_ELF_TRUE@@NATIVE_TRUE@btest_lto_LDADD = libbacktrace.la @NATIVE_TRUE@btest_alloc_SOURCES = $(btest_SOURCES) @NATIVE_TRUE@btest_alloc_CFLAGS = $(libbacktrace_TEST_CFLAGS) +@NATIVE_TRUE@btest_alloc_LDFLAGS = $(libbacktrace_testing_ldflags) @NATIVE_TRUE@btest_alloc_LDADD = libbacktrace_alloc.la @NATIVE_TRUE@stest_SOURCES = stest.c @NATIVE_TRUE@stest_CFLAGS = $(libbacktrace_TEST_CFLAGS) +@NATIVE_TRUE@stest_LDFLAGS = $(libbacktrace_testing_ldflags) @NATIVE_TRUE@stest_LDADD = libbacktrace.la @NATIVE_TRUE@stest_alloc_SOURCES = $(stest_SOURCES) @NATIVE_TRUE@stest_alloc_CFLAGS = $(libbacktrace_TEST_CFLAGS) +@NATIVE_TRUE@stest_alloc_LDFLAGS = $(libbacktrace_testing_ldflags) @NATIVE_TRUE@stest_alloc_LDADD = libbacktrace_alloc.la @HAVE_ELF_TRUE@@NATIVE_TRUE@ztest_SOURCES = ztest.c testlib.c @HAVE_ELF_TRUE@@NATIVE_TRUE@ztest_CFLAGS = $(libbacktrace_TEST_CFLAGS) -DSRCDIR=\"$(srcdir)\" +@HAVE_ELF_TRUE@@NATIVE_TRUE@ztest_LDFLAGS = $(libbacktrace_testing_ldflags) @HAVE_ELF_TRUE@@NATIVE_TRUE@ztest_LDADD = libbacktrace.la \ @HAVE_ELF_TRUE@@NATIVE_TRUE@ $(am__append_14) \ @HAVE_ELF_TRUE@@NATIVE_TRUE@ $(CLOCK_GETTIME_LINK) @@ -1084,53 +1145,81 @@ libbacktrace_TEST_CFLAGS = $(EXTRA_FLAGS) $(WARN_FLAGS) -g @HAVE_ELF_TRUE@@NATIVE_TRUE@ $(CLOCK_GETTIME_LINK) @HAVE_ELF_TRUE@@NATIVE_TRUE@ztest_alloc_SOURCES = $(ztest_SOURCES) @HAVE_ELF_TRUE@@NATIVE_TRUE@ztest_alloc_CFLAGS = $(ztest_CFLAGS) +@HAVE_ELF_TRUE@@NATIVE_TRUE@ztest_alloc_LDFLAGS = $(libbacktrace_testing_ldflags) +@HAVE_ELF_TRUE@@NATIVE_TRUE@zstdtest_SOURCES = zstdtest.c testlib.c +@HAVE_ELF_TRUE@@NATIVE_TRUE@zstdtest_CFLAGS = $(libbacktrace_TEST_CFLAGS) -DSRCDIR=\"$(srcdir)\" +@HAVE_ELF_TRUE@@NATIVE_TRUE@zstdtest_LDFLAGS = $(libbacktrace_testing_ldflags) +@HAVE_ELF_TRUE@@NATIVE_TRUE@zstdtest_LDADD = libbacktrace.la \ +@HAVE_ELF_TRUE@@NATIVE_TRUE@ $(am__append_17) \ +@HAVE_ELF_TRUE@@NATIVE_TRUE@ $(CLOCK_GETTIME_LINK) +@HAVE_ELF_TRUE@@NATIVE_TRUE@zstdtest_alloc_LDADD = \ +@HAVE_ELF_TRUE@@NATIVE_TRUE@ libbacktrace_alloc.la \ +@HAVE_ELF_TRUE@@NATIVE_TRUE@ $(am__append_18) \ +@HAVE_ELF_TRUE@@NATIVE_TRUE@ $(CLOCK_GETTIME_LINK) +@HAVE_ELF_TRUE@@NATIVE_TRUE@zstdtest_alloc_SOURCES = $(zstdtest_SOURCES) +@HAVE_ELF_TRUE@@NATIVE_TRUE@zstdtest_alloc_CFLAGS = $(zstdtest_CFLAGS) +@HAVE_ELF_TRUE@@NATIVE_TRUE@zstdtest_alloc_LDFLAGS = $(libbacktrace_testing_ldflags) @NATIVE_TRUE@edtest_SOURCES = edtest.c edtest2_build.c testlib.c @NATIVE_TRUE@edtest_CFLAGS = $(libbacktrace_TEST_CFLAGS) +@NATIVE_TRUE@edtest_LDFLAGS = $(libbacktrace_testing_ldflags) @NATIVE_TRUE@edtest_LDADD = libbacktrace.la @NATIVE_TRUE@edtest_alloc_SOURCES = $(edtest_SOURCES) @NATIVE_TRUE@edtest_alloc_CFLAGS = $(libbacktrace_TEST_CFLAGS) +@NATIVE_TRUE@edtest_alloc_LDFLAGS = $(libbacktrace_testing_ldflags) @NATIVE_TRUE@edtest_alloc_LDADD = libbacktrace_alloc.la @HAVE_PTHREAD_TRUE@@NATIVE_TRUE@ttest_SOURCES = ttest.c testlib.c @HAVE_PTHREAD_TRUE@@NATIVE_TRUE@ttest_CFLAGS = $(libbacktrace_TEST_CFLAGS) -pthread +@HAVE_PTHREAD_TRUE@@NATIVE_TRUE@ttest_LDFLAGS = $(libbacktrace_testing_ldflags) @HAVE_PTHREAD_TRUE@@NATIVE_TRUE@ttest_LDADD = libbacktrace.la @HAVE_PTHREAD_TRUE@@NATIVE_TRUE@ttest_alloc_SOURCES = $(ttest_SOURCES) @HAVE_PTHREAD_TRUE@@NATIVE_TRUE@ttest_alloc_CFLAGS = $(ttest_CFLAGS) +@HAVE_PTHREAD_TRUE@@NATIVE_TRUE@ttest_alloc_LDFLAGS = $(libbacktrace_testing_ldflags) @HAVE_PTHREAD_TRUE@@NATIVE_TRUE@ttest_alloc_LDADD = libbacktrace_alloc.la @HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@ctestg_SOURCES = btest.c testlib.c @HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@ctestg_CFLAGS = $(libbacktrace_TEST_CFLAGS) -@HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@ctestg_LDFLAGS = -Wl,--compress-debug-sections=zlib-gnu +@HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@ctestg_LDFLAGS = -Wl,--compress-debug-sections=zlib-gnu $(libbacktrace_testing_ldflags) @HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@ctestg_LDADD = libbacktrace.la @HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@ctesta_SOURCES = btest.c testlib.c @HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@ctesta_CFLAGS = $(libbacktrace_TEST_CFLAGS) -@HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@ctesta_LDFLAGS = -Wl,--compress-debug-sections=zlib-gabi +@HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@ctesta_LDFLAGS = -Wl,--compress-debug-sections=zlib-gabi $(libbacktrace_testing_ldflags) @HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@ctesta_LDADD = libbacktrace.la +@HAVE_COMPRESSED_DEBUG_TRUE@@HAVE_COMPRESSED_DEBUG_ZSTD_TRUE@@NATIVE_TRUE@ctestzstd_SOURCES = btest.c testlib.c +@HAVE_COMPRESSED_DEBUG_TRUE@@HAVE_COMPRESSED_DEBUG_ZSTD_TRUE@@NATIVE_TRUE@ctestzstd_CFLAGS = $(libbacktrace_TEST_CFLAGS) +@HAVE_COMPRESSED_DEBUG_TRUE@@HAVE_COMPRESSED_DEBUG_ZSTD_TRUE@@NATIVE_TRUE@ctestzstd_LDFLAGS = -Wl,--compress-debug-sections=zstd $(libbacktrace_testing_ldflags) +@HAVE_COMPRESSED_DEBUG_TRUE@@HAVE_COMPRESSED_DEBUG_ZSTD_TRUE@@NATIVE_TRUE@ctestzstd_LDADD = libbacktrace.la @HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@ctestg_alloc_SOURCES = $(ctestg_SOURCES) @HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@ctestg_alloc_CFLAGS = $(ctestg_CFLAGS) -@HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@ctestg_alloc_LDFLAGS = $(ctestg_LDFLAGS) +@HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@ctestg_alloc_LDFLAGS = $(ctestg_LDFLAGS) $(libbacktrace_testing_ldflags) @HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@ctestg_alloc_LDADD = libbacktrace_alloc.la @HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@ctesta_alloc_SOURCES = $(ctesta_SOURCES) @HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@ctesta_alloc_CFLAGS = $(ctesta_CFLAGS) -@HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@ctesta_alloc_LDFLAGS = $(ctesta_LDFLAGS) +@HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@ctesta_alloc_LDFLAGS = $(ctesta_LDFLAGS) $(libbacktrace_testing_ldflags) @HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@ctesta_alloc_LDADD = libbacktrace_alloc.la @HAVE_DWARF5_TRUE@@NATIVE_TRUE@dwarf5_SOURCES = btest.c testlib.c @HAVE_DWARF5_TRUE@@NATIVE_TRUE@dwarf5_CFLAGS = $(libbacktrace_TEST_CFLAGS) -gdwarf-5 +@HAVE_DWARF5_TRUE@@NATIVE_TRUE@dwarf5_LDFLAGS = $(libbacktrace_testing_ldflags) @HAVE_DWARF5_TRUE@@NATIVE_TRUE@dwarf5_LDADD = libbacktrace.la @HAVE_DWARF5_TRUE@@NATIVE_TRUE@dwarf5_alloc_SOURCES = $(dwarf5_SOURCES) @HAVE_DWARF5_TRUE@@NATIVE_TRUE@dwarf5_alloc_CFLAGS = $(dwarf5_CFLAGS) +@HAVE_DWARF5_TRUE@@NATIVE_TRUE@dwarf5_alloc_LDFLAGS = $(libbacktrace_testing_ldflags) @HAVE_DWARF5_TRUE@@NATIVE_TRUE@dwarf5_alloc_LDADD = libbacktrace_alloc.la @NATIVE_TRUE@mtest_SOURCES = mtest.c testlib.c @NATIVE_TRUE@mtest_CFLAGS = $(libbacktrace_TEST_CFLAGS) -O +@NATIVE_TRUE@mtest_LDFLAGS = $(libbacktrace_testing_ldflags) @NATIVE_TRUE@mtest_LDADD = libbacktrace.la @HAVE_ELF_TRUE@xztest_SOURCES = xztest.c testlib.c @HAVE_ELF_TRUE@xztest_CFLAGS = $(libbacktrace_TEST_CFLAGS) -DSRCDIR=\"$(srcdir)\" -@HAVE_ELF_TRUE@xztest_LDADD = libbacktrace.la $(am__append_27) \ +@HAVE_ELF_TRUE@xztest_LDFLAGS = $(libbacktrace_testing_ldflags) +@HAVE_ELF_TRUE@xztest_LDADD = libbacktrace.la $(am__append_31) \ @HAVE_ELF_TRUE@ $(CLOCK_GETTIME_LINK) @HAVE_ELF_TRUE@xztest_alloc_SOURCES = $(xztest_SOURCES) @HAVE_ELF_TRUE@xztest_alloc_CFLAGS = $(xztest_CFLAGS) +@HAVE_ELF_TRUE@xztest_alloc_LDFLAGS = $(libbacktrace_testing_ldflags) @HAVE_ELF_TRUE@xztest_alloc_LDADD = libbacktrace_alloc.la \ -@HAVE_ELF_TRUE@ $(am__append_28) $(CLOCK_GETTIME_LINK) +@HAVE_ELF_TRUE@ $(am__append_32) $(CLOCK_GETTIME_LINK) CLEANFILES = \ - $(filter-out allocfail.sh,$(TESTS)) *.debug elf_for_test.c edtest2_build.c gen_edtest2_build \ + $(MAKETESTS) $(BUILDTESTS) *.debug elf_for_test.c edtest2_build.c \ + gen_edtest2_build \ *.dsyms *.fsyms *.keepsyms *.dbg *.mdbg *.mdbg.xz *.strip @@ -1297,6 +1386,10 @@ ctestg_alloc$(EXEEXT): $(ctestg_alloc_OBJECTS) $(ctestg_alloc_DEPENDENCIES) $(EX @rm -f ctestg_alloc$(EXEEXT) $(AM_V_CCLD)$(ctestg_alloc_LINK) $(ctestg_alloc_OBJECTS) $(ctestg_alloc_LDADD) $(LIBS) +ctestzstd$(EXEEXT): $(ctestzstd_OBJECTS) $(ctestzstd_DEPENDENCIES) $(EXTRA_ctestzstd_DEPENDENCIES) + @rm -f ctestzstd$(EXEEXT) + $(AM_V_CCLD)$(ctestzstd_LINK) $(ctestzstd_OBJECTS) $(ctestzstd_LDADD) $(LIBS) + dwarf5$(EXEEXT): $(dwarf5_OBJECTS) $(dwarf5_DEPENDENCIES) $(EXTRA_dwarf5_DEPENDENCIES) @rm -f dwarf5$(EXEEXT) $(AM_V_CCLD)$(dwarf5_LINK) $(dwarf5_OBJECTS) $(dwarf5_LDADD) $(LIBS) @@ -1377,6 +1470,14 @@ xztest_alloc$(EXEEXT): $(xztest_alloc_OBJECTS) $(xztest_alloc_DEPENDENCIES) $(EX @rm -f xztest_alloc$(EXEEXT) $(AM_V_CCLD)$(xztest_alloc_LINK) $(xztest_alloc_OBJECTS) $(xztest_alloc_LDADD) $(LIBS) +zstdtest$(EXEEXT): $(zstdtest_OBJECTS) $(zstdtest_DEPENDENCIES) $(EXTRA_zstdtest_DEPENDENCIES) + @rm -f zstdtest$(EXEEXT) + $(AM_V_CCLD)$(zstdtest_LINK) $(zstdtest_OBJECTS) $(zstdtest_LDADD) $(LIBS) + +zstdtest_alloc$(EXEEXT): $(zstdtest_alloc_OBJECTS) $(zstdtest_alloc_DEPENDENCIES) $(EXTRA_zstdtest_alloc_DEPENDENCIES) + @rm -f zstdtest_alloc$(EXEEXT) + $(AM_V_CCLD)$(zstdtest_alloc_LINK) $(zstdtest_alloc_OBJECTS) $(zstdtest_alloc_LDADD) $(LIBS) + ztest$(EXEEXT): $(ztest_OBJECTS) $(ztest_DEPENDENCIES) $(EXTRA_ztest_DEPENDENCIES) @rm -f ztest$(EXEEXT) $(AM_V_CCLD)$(ztest_LINK) $(ztest_OBJECTS) $(ztest_LDADD) $(LIBS) @@ -1520,6 +1621,18 @@ ctestg_alloc-testlib.o: testlib.c ctestg_alloc-testlib.obj: testlib.c $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ctestg_alloc_CFLAGS) $(CFLAGS) -c -o ctestg_alloc-testlib.obj `if test -f 'testlib.c'; then $(CYGPATH_W) 'testlib.c'; else $(CYGPATH_W) '$(srcdir)/testlib.c'; fi` +ctestzstd-btest.o: btest.c + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ctestzstd_CFLAGS) $(CFLAGS) -c -o ctestzstd-btest.o `test -f 'btest.c' || echo '$(srcdir)/'`btest.c + +ctestzstd-btest.obj: btest.c + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ctestzstd_CFLAGS) $(CFLAGS) -c -o ctestzstd-btest.obj `if test -f 'btest.c'; then $(CYGPATH_W) 'btest.c'; else $(CYGPATH_W) '$(srcdir)/btest.c'; fi` + +ctestzstd-testlib.o: testlib.c + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ctestzstd_CFLAGS) $(CFLAGS) -c -o ctestzstd-testlib.o `test -f 'testlib.c' || echo '$(srcdir)/'`testlib.c + +ctestzstd-testlib.obj: testlib.c + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ctestzstd_CFLAGS) $(CFLAGS) -c -o ctestzstd-testlib.obj `if test -f 'testlib.c'; then $(CYGPATH_W) 'testlib.c'; else $(CYGPATH_W) '$(srcdir)/testlib.c'; fi` + dwarf5-btest.o: btest.c $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dwarf5_CFLAGS) $(CFLAGS) -c -o dwarf5-btest.o `test -f 'btest.c' || echo '$(srcdir)/'`btest.c @@ -1760,6 +1873,30 @@ xztest_alloc-testlib.o: testlib.c xztest_alloc-testlib.obj: testlib.c $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xztest_alloc_CFLAGS) $(CFLAGS) -c -o xztest_alloc-testlib.obj `if test -f 'testlib.c'; then $(CYGPATH_W) 'testlib.c'; else $(CYGPATH_W) '$(srcdir)/testlib.c'; fi` +zstdtest-zstdtest.o: zstdtest.c + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(zstdtest_CFLAGS) $(CFLAGS) -c -o zstdtest-zstdtest.o `test -f 'zstdtest.c' || echo '$(srcdir)/'`zstdtest.c + +zstdtest-zstdtest.obj: zstdtest.c + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(zstdtest_CFLAGS) $(CFLAGS) -c -o zstdtest-zstdtest.obj `if test -f 'zstdtest.c'; then $(CYGPATH_W) 'zstdtest.c'; else $(CYGPATH_W) '$(srcdir)/zstdtest.c'; fi` + +zstdtest-testlib.o: testlib.c + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(zstdtest_CFLAGS) $(CFLAGS) -c -o zstdtest-testlib.o `test -f 'testlib.c' || echo '$(srcdir)/'`testlib.c + +zstdtest-testlib.obj: testlib.c + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(zstdtest_CFLAGS) $(CFLAGS) -c -o zstdtest-testlib.obj `if test -f 'testlib.c'; then $(CYGPATH_W) 'testlib.c'; else $(CYGPATH_W) '$(srcdir)/testlib.c'; fi` + +zstdtest_alloc-zstdtest.o: zstdtest.c + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(zstdtest_alloc_CFLAGS) $(CFLAGS) -c -o zstdtest_alloc-zstdtest.o `test -f 'zstdtest.c' || echo '$(srcdir)/'`zstdtest.c + +zstdtest_alloc-zstdtest.obj: zstdtest.c + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(zstdtest_alloc_CFLAGS) $(CFLAGS) -c -o zstdtest_alloc-zstdtest.obj `if test -f 'zstdtest.c'; then $(CYGPATH_W) 'zstdtest.c'; else $(CYGPATH_W) '$(srcdir)/zstdtest.c'; fi` + +zstdtest_alloc-testlib.o: testlib.c + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(zstdtest_alloc_CFLAGS) $(CFLAGS) -c -o zstdtest_alloc-testlib.o `test -f 'testlib.c' || echo '$(srcdir)/'`testlib.c + +zstdtest_alloc-testlib.obj: testlib.c + $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(zstdtest_alloc_CFLAGS) $(CFLAGS) -c -o zstdtest_alloc-testlib.obj `if test -f 'testlib.c'; then $(CYGPATH_W) 'testlib.c'; else $(CYGPATH_W) '$(srcdir)/testlib.c'; fi` + ztest-ztest.o: ztest.c $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ztest_CFLAGS) $(CFLAGS) -c -o ztest-ztest.o `test -f 'ztest.c' || echo '$(srcdir)/'`ztest.c @@ -2007,6 +2144,13 @@ b2test_buildid.log: b2test_buildid --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) +b2test_buildidfull.log: b2test_buildidfull + @p='b2test_buildidfull'; \ + b='b2test_buildidfull'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) b3test_dwz_buildid.log: b3test_dwz_buildid @p='b3test_dwz_buildid'; \ b='b3test_dwz_buildid'; \ @@ -2014,6 +2158,13 @@ b3test_dwz_buildid.log: b3test_dwz_buildid --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) +b3test_dwz_buildidfull.log: b3test_dwz_buildidfull + @p='b3test_dwz_buildidfull'; \ + b='b3test_dwz_buildidfull'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) btest_dwz.log: btest_dwz @p='btest_dwz'; \ b='btest_dwz'; \ @@ -2035,6 +2186,13 @@ btest_gnudebuglink.log: btest_gnudebuglink --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) +btest_gnudebuglinkfull.log: btest_gnudebuglinkfull + @p='btest_gnudebuglinkfull'; \ + b='btest_gnudebuglinkfull'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) mtest_minidebug.log: mtest_minidebug @p='mtest_minidebug'; \ b='mtest_minidebug'; \ @@ -2154,6 +2312,20 @@ ztest_alloc.log: ztest_alloc$(EXEEXT) --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) +zstdtest.log: zstdtest$(EXEEXT) + @p='zstdtest$(EXEEXT)'; \ + b='zstdtest'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +zstdtest_alloc.log: zstdtest_alloc$(EXEEXT) + @p='zstdtest_alloc$(EXEEXT)'; \ + b='zstdtest_alloc'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) edtest.log: edtest$(EXEEXT) @p='edtest$(EXEEXT)'; \ b='edtest'; \ @@ -2196,6 +2368,13 @@ ctesta.log: ctesta$(EXEEXT) --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) +ctestzstd.log: ctestzstd$(EXEEXT) + @p='ctestzstd$(EXEEXT)'; \ + b='ctestzstd'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) ctestg_alloc.log: ctestg_alloc$(EXEEXT) @p='ctestg_alloc$(EXEEXT)'; \ b='ctestg_alloc'; \ @@ -2408,18 +2587,18 @@ uninstall-am: @HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@ mv $@.tmp $@ @NATIVE_TRUE@elf_%.c: elf.c +@NATIVE_TRUE@ nlinit=`echo 'nl="'; echo '"'`; eval "$$nlinit"; \ @NATIVE_TRUE@ SEARCH='#error "Unknown BACKTRACE_ELF_SIZE"'; \ -@NATIVE_TRUE@ REPLACE='#undef BACKTRACE_ELF_SIZE\ -@NATIVE_TRUE@ #define BACKTRACE_ELF_SIZE'; \ +@NATIVE_TRUE@ REPLACE="#undef BACKTRACE_ELF_SIZE\\$${nl}#define BACKTRACE_ELF_SIZE"; \ @NATIVE_TRUE@ $(SED) "s/^$$SEARCH\$$/$$REPLACE $*/" \ @NATIVE_TRUE@ $< \ @NATIVE_TRUE@ > $@.tmp @NATIVE_TRUE@ mv $@.tmp $@ @NATIVE_TRUE@xcoff_%.c: xcoff.c +@NATIVE_TRUE@ nlinit=`echo 'nl="'; echo '"'`; eval "$$nlinit"; \ @NATIVE_TRUE@ SEARCH='#error "Unknown BACKTRACE_XCOFF_SIZE"'; \ -@NATIVE_TRUE@ REPLACE='#undef BACKTRACE_XCOFF_SIZE\ -@NATIVE_TRUE@ #define BACKTRACE_XCOFF_SIZE'; \ +@NATIVE_TRUE@ REPLACE="#undef BACKTRACE_XCOFF_SIZE\\$${nl}#define BACKTRACE_XCOFF_SIZE"; \ @NATIVE_TRUE@ $(SED) "s/^$$SEARCH\$$/$$REPLACE $*/" \ @NATIVE_TRUE@ $< \ @NATIVE_TRUE@ > $@.tmp @@ -2451,15 +2630,25 @@ uninstall-am: @HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@ $(OBJCOPY) --only-keep-debug $< $@.debug @HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@ $(OBJCOPY) --strip-debug --add-gnu-debuglink=$@.debug $< $@ +@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@%_gnudebuglinkfull: % +@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@ $(OBJCOPY) --only-keep-debug $< $@.debug +@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@ $(OBJCOPY) --strip-all --add-gnu-debuglink=$@.debug $< $@ + @NATIVE_TRUE@%_buildid: % @NATIVE_TRUE@ ./install-debuginfo-for-buildid.sh \ @NATIVE_TRUE@ "$(TEST_BUILD_ID_DIR)" \ @NATIVE_TRUE@ $< @NATIVE_TRUE@ $(OBJCOPY) --strip-debug $< $@ +@NATIVE_TRUE@%_buildidfull: % +@NATIVE_TRUE@ ./install-debuginfo-for-buildid.sh \ +@NATIVE_TRUE@ "$(TEST_BUILD_ID_DIR)" \ +@NATIVE_TRUE@ $< +@NATIVE_TRUE@ $(OBJCOPY) --strip-all $< $@ + @HAVE_MINIDEBUG_TRUE@@NATIVE_TRUE@%_minidebug: % @HAVE_MINIDEBUG_TRUE@@NATIVE_TRUE@ $(NM) -D $< -P --defined-only | $(AWK) '{ print $$1 }' | sort > $<.dsyms -@HAVE_MINIDEBUG_TRUE@@NATIVE_TRUE@ $(NM) $< -P --defined-only | $(AWK) '{ if ($$2 == "T" || $$2 == "t" || $$2 == "D" || $$2 == "d") print $$1 }' | sort > $<.fsyms +@HAVE_MINIDEBUG_TRUE@@NATIVE_TRUE@ $(NM) $< -P --defined-only | $(AWK) '{ if ($$2 == "T" || $$2 == "t" || $$2 == "D") print $$1 }' | sort > $<.fsyms @HAVE_MINIDEBUG_TRUE@@NATIVE_TRUE@ $(COMM) -13 $<.dsyms $<.fsyms > $<.keepsyms @HAVE_MINIDEBUG_TRUE@@NATIVE_TRUE@ $(OBJCOPY) --only-keep-debug $< $<.dbg @HAVE_MINIDEBUG_TRUE@@NATIVE_TRUE@ $(OBJCOPY) -S --remove-section .gdb_index --remove-section .comment --keep-symbols=$<.keepsyms $<.dbg $<.mdbg diff --git a/libbacktrace/README b/libbacktrace/README index e8b2257..6225f92 100644 --- a/libbacktrace/README +++ b/libbacktrace/README @@ -1,23 +1,31 @@ The libbacktrace library -Initially written by Ian Lance Taylor <iant@google.com> +Initially written by Ian Lance Taylor <iant@golang.org> The libbacktrace library may be linked into a program or library and -used to produce symbolic backtraces. Sample uses would be to print a -detailed backtrace when an error occurs or to gather detailed -profiling information. +used to produce symbolic backtraces. +Sample uses would be to print a detailed backtrace when an error +occurs or to gather detailed profiling information. +In general the functions provided by this library are async-signal-safe, +meaning that they may be safely called from a signal handler. -The libbacktrace library is provided under a BSD license. See the -source files for the exact license text. +The libbacktrace library is provided under a BSD license. +See the source files for the exact license text. The public functions are declared and documented in the header file backtrace.h, which should be #include'd by a user of the library. Building libbacktrace will generate a file backtrace-supported.h, which a user of the library may use to determine whether backtraces -will work. See the source file backtrace-supported.h.in for the -macros that it defines. +will work. +See the source file backtrace-supported.h.in for the macros that it +defines. -As of September 2012, libbacktrace only supports ELF executables with -DWARF debugging information. The library is written to make it -straightforward to add support for other object file and debugging -formats. +As of October 2020, libbacktrace supports ELF, PE/COFF, Mach-O, and +XCOFF executables with DWARF debugging information. +In other words, it supports GNU/Linux, *BSD, macOS, Windows, and AIX. +The library is written to make it straightforward to add support for +other object file and debugging formats. + +The library relies on the C++ unwind API defined at +https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html +This API is provided by GCC and clang. diff --git a/libbacktrace/alloc.c b/libbacktrace/alloc.c index ff2c867..193e770 100644 --- a/libbacktrace/alloc.c +++ b/libbacktrace/alloc.c @@ -1,5 +1,5 @@ /* alloc.c -- Memory allocation without mmap. - Copyright (C) 2012-2021 Free Software Foundation, Inc. + Copyright (C) 2012-2024 Free Software Foundation, Inc. Written by Ian Lance Taylor, Google. Redistribution and use in source and binary forms, with or without diff --git a/libbacktrace/allocfail.c b/libbacktrace/allocfail.c index bd0fbb6..fb92821 100644 --- a/libbacktrace/allocfail.c +++ b/libbacktrace/allocfail.c @@ -1,5 +1,5 @@ /* allocfail.c -- Test for libbacktrace library - Copyright (C) 2018-2021 Free Software Foundation, Inc. + Copyright (C) 2018-2024 Free Software Foundation, Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are diff --git a/libbacktrace/allocfail.sh b/libbacktrace/allocfail.sh index 1f9894f..0632676 100755 --- a/libbacktrace/allocfail.sh +++ b/libbacktrace/allocfail.sh @@ -1,7 +1,7 @@ #!/bin/sh # allocfail.sh -- Test for libbacktrace library. -# Copyright (C) 2018-2021 Free Software Foundation, Inc. +# Copyright (C) 2018-2024 Free Software Foundation, Inc. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are diff --git a/libbacktrace/atomic.c b/libbacktrace/atomic.c index fcac485..21785a1 100644 --- a/libbacktrace/atomic.c +++ b/libbacktrace/atomic.c @@ -1,5 +1,5 @@ /* atomic.c -- Support for atomic functions if not present. - Copyright (C) 2013-2021 Free Software Foundation, Inc. + Copyright (C) 2013-2024 Free Software Foundation, Inc. Written by Ian Lance Taylor, Google. Redistribution and use in source and binary forms, with or without diff --git a/libbacktrace/backtrace-supported.h.in b/libbacktrace/backtrace-supported.h.in index 2035c85..d9f3030 100644 --- a/libbacktrace/backtrace-supported.h.in +++ b/libbacktrace/backtrace-supported.h.in @@ -1,5 +1,5 @@ /* backtrace-supported.h.in -- Whether stack backtrace is supported. - Copyright (C) 2012-2021 Free Software Foundation, Inc. + Copyright (C) 2012-2024 Free Software Foundation, Inc. Written by Ian Lance Taylor, Google. Redistribution and use in source and binary forms, with or without diff --git a/libbacktrace/backtrace.c b/libbacktrace/backtrace.c index 7b62900..3e6b81e 100644 --- a/libbacktrace/backtrace.c +++ b/libbacktrace/backtrace.c @@ -1,5 +1,5 @@ /* backtrace.c -- Entry point for stack backtrace library. - Copyright (C) 2012-2021 Free Software Foundation, Inc. + Copyright (C) 2012-2024 Free Software Foundation, Inc. Written by Ian Lance Taylor, Google. Redistribution and use in source and binary forms, with or without diff --git a/libbacktrace/backtrace.h b/libbacktrace/backtrace.h index caaa66d..b73e27e 100644 --- a/libbacktrace/backtrace.h +++ b/libbacktrace/backtrace.h @@ -1,5 +1,5 @@ /* backtrace.h -- Public header file for stack backtrace library. - Copyright (C) 2012-2021 Free Software Foundation, Inc. + Copyright (C) 2012-2024 Free Software Foundation, Inc. Written by Ian Lance Taylor, Google. Redistribution and use in source and binary forms, with or without diff --git a/libbacktrace/btest.c b/libbacktrace/btest.c index 7ef6d32..d9fc372 100644 --- a/libbacktrace/btest.c +++ b/libbacktrace/btest.c @@ -1,5 +1,5 @@ /* btest.c -- Test for libbacktrace library - Copyright (C) 2012-2021 Free Software Foundation, Inc. + Copyright (C) 2012-2024 Free Software Foundation, Inc. Written by Ian Lance Taylor, Google. Redistribution and use in source and binary forms, with or without diff --git a/libbacktrace/config.h.in b/libbacktrace/config.h.in index cdb416e..ee26163 100644 --- a/libbacktrace/config.h.in +++ b/libbacktrace/config.h.in @@ -20,6 +20,10 @@ don't. */ #undef HAVE_DECL_STRNLEN +/* Define to 1 if you have the declaration of `_pgmptr', and to 0 if you + don't. */ +#undef HAVE_DECL__PGMPTR + /* Define to 1 if you have the <dlfcn.h> header file. */ #undef HAVE_DLFCN_H @@ -85,6 +89,9 @@ /* Define to 1 if you have the <sys/ldr.h> header file. */ #undef HAVE_SYS_LDR_H +/* Define to 1 if you have the <sys/link.h> header file. */ +#undef HAVE_SYS_LINK_H + /* Define to 1 if you have the <sys/mman.h> header file. */ #undef HAVE_SYS_MMAN_H @@ -97,9 +104,15 @@ /* Define to 1 if you have the <unistd.h> header file. */ #undef HAVE_UNISTD_H +/* Define to 1 if you have the <windows.h> header file. */ +#undef HAVE_WINDOWS_H + /* Define if -lz is available. */ #undef HAVE_ZLIB +/* Define if -lzstd is available. */ +#undef HAVE_ZSTD + /* Define to the sub-directory in which libtool stores uninstalled libraries. */ #undef LT_OBJDIR diff --git a/libbacktrace/configure b/libbacktrace/configure index e5ca8ad..9d22b74 100755 --- a/libbacktrace/configure +++ b/libbacktrace/configure @@ -651,8 +651,14 @@ HAVE_OBJCOPY_DEBUGLINK_FALSE HAVE_OBJCOPY_DEBUGLINK_TRUE READELF OBJCOPY +HAVE_COMPRESSED_DEBUG_ZSTD_FALSE +HAVE_COMPRESSED_DEBUG_ZSTD_TRUE +HAVE_ZSTD_FALSE +HAVE_ZSTD_TRUE HAVE_COMPRESSED_DEBUG_FALSE HAVE_COMPRESSED_DEBUG_TRUE +HAVE_BUILDID_FALSE +HAVE_BUILDID_TRUE HAVE_ZLIB_FALSE HAVE_ZLIB_TRUE HAVE_DWARF5_FALSE @@ -801,6 +807,7 @@ with_gnu_ld enable_libtool_lock enable_largefile enable_cet +enable_werror with_system_libunwind enable_host_shared ' @@ -1448,6 +1455,7 @@ Optional Features: --disable-libtool-lock avoid locking (might break parallel builds) --disable-largefile omit support for large files --enable-cet enable Intel CET in target libraries [default=auto] + --disable-werror disable building with -Werror --enable-host-shared build host code as shared libraries --enable-cet enable Intel CET in host libraries [default=auto] @@ -11571,7 +11579,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11574 "configure" +#line 11582 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11677,7 +11685,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11680 "configure" +#line 11688 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -12362,10 +12370,14 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu -if test -n "${with_target_subdir}"; then - WARN_FLAGS="$WARN_FLAGS -Werror" +# Check whether --enable-werror was given. +if test "${enable_werror+set}" = set; then : + enableval=$enable_werror; fi +if test "x$enable_werror" != "xno" && test -n "${with_target_subdir}"; then : + WARN_FLAGS="$WARN_FLAGS -Werror" +fi if test -n "${with_target_subdir}"; then @@ -13323,26 +13335,31 @@ fi # Check for dl_iterate_phdr. -for ac_header in link.h +for ac_header in link.h sys/link.h do : - ac_fn_c_check_header_mongrel "$LINENO" "link.h" "ac_cv_header_link_h" "$ac_includes_default" -if test "x$ac_cv_header_link_h" = xyes; then : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF -#define HAVE_LINK_H 1 +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done -if test "$ac_cv_header_link_h" = "no"; then +if test "$ac_cv_header_link_h" = "no" -a "$ac_cv_header_sys_link_h" = "no"; then have_dl_iterate_phdr=no else if test -n "${with_target_subdir}"; then + link_h=link.h + if test "$ac_cv_header_link_h" = "no"; then + link_h=sys/link.h + fi # When built as a GCC target library, we can't do a link test. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include <link.h> +#include <$link_h> _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | @@ -13430,6 +13447,19 @@ $as_echo "#define HAVE_LOADQUERY 1" >>confdefs.h fi +for ac_header in windows.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "windows.h" "ac_cv_header_windows_h" "$ac_includes_default" +if test "x$ac_cv_header_windows_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_WINDOWS_H 1 +_ACEOF + +fi + +done + + # Check for the fcntl function. if test -n "${with_target_subdir}"; then case "${host}" in @@ -13506,6 +13536,19 @@ $as_echo "#define HAVE_GETEXECNAME 1" >>confdefs.h fi +# Check for _pgmptr variable, contains the executable filename on windows +ac_fn_c_check_decl "$LINENO" "_pgmptr" "ac_cv_have_decl__pgmptr" "$ac_includes_default" +if test "x$ac_cv_have_decl__pgmptr" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL__PGMPTR $ac_have_decl +_ACEOF + + # Check for sysctl definitions. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for KERN_PROC" >&5 @@ -13765,6 +13808,44 @@ else fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether --build-id is supported" >&5 +$as_echo_n "checking whether --build-id is supported... " >&6; } +if ${libbacktrace_cv_ld_buildid+:} false; then : + $as_echo_n "(cached) " >&6 +else + LDFLAGS_hold=$LDFLAGS +LDFLAGS="$LDFLAGS -Wl,--build-id" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + libbacktrace_cv_ld_buildid=yes +else + libbacktrace_cv_ld_buildid=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LDFLAGS=$LDFLAGS_hold +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libbacktrace_cv_ld_buildid" >&5 +$as_echo "$libbacktrace_cv_ld_buildid" >&6; } + if test "$libbacktrace_cv_ld_buildid" = yes; then + HAVE_BUILDID_TRUE= + HAVE_BUILDID_FALSE='#' +else + HAVE_BUILDID_TRUE='#' + HAVE_BUILDID_FALSE= +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether --compress-debug-sections is supported" >&5 $as_echo_n "checking whether --compress-debug-sections is supported... " >&6; } if ${libgo_cv_ld_compress+:} false; then : @@ -13803,6 +13884,95 @@ else fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ZSTD_compress in -lzstd" >&5 +$as_echo_n "checking for ZSTD_compress in -lzstd... " >&6; } +if ${ac_cv_lib_zstd_ZSTD_compress+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lzstd $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char ZSTD_compress (); +int +main () +{ +return ZSTD_compress (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_zstd_ZSTD_compress=yes +else + ac_cv_lib_zstd_ZSTD_compress=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_zstd_ZSTD_compress" >&5 +$as_echo "$ac_cv_lib_zstd_ZSTD_compress" >&6; } +if test "x$ac_cv_lib_zstd_ZSTD_compress" = xyes; then : + +$as_echo "#define HAVE_ZSTD 1" >>confdefs.h + +fi + + if test "$ac_cv_lib_zstd_ZSTD_compress" = yes; then + HAVE_ZSTD_TRUE= + HAVE_ZSTD_FALSE='#' +else + HAVE_ZSTD_TRUE='#' + HAVE_ZSTD_FALSE= +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether --compress-debug-sections=zstd is supported" >&5 +$as_echo_n "checking whether --compress-debug-sections=zstd is supported... " >&6; } +if ${libgo_cv_ld_compress_zstd+:} false; then : + $as_echo_n "(cached) " >&6 +else + LDFLAGS_hold=$LDFLAGS +LDFLAGS="$LDFLAGS -Wl,--compress-debug-sections=zstd" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + libgo_cv_ld_compress_zstd=yes +else + libgo_cv_ld_compress_zstd=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LDFLAGS=$LDFLAGS_hold +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libgo_cv_ld_compress_zstd" >&5 +$as_echo "$libgo_cv_ld_compress_zstd" >&6; } + if test "$libgo_cv_ld_compress_zstd" = yes; then + HAVE_COMPRESSED_DEBUG_ZSTD_TRUE= + HAVE_COMPRESSED_DEBUG_ZSTD_FALSE='#' +else + HAVE_COMPRESSED_DEBUG_ZSTD_TRUE='#' + HAVE_COMPRESSED_DEBUG_ZSTD_FALSE= +fi + + # Extract the first word of "objcopy", so it can be a program name with args. set dummy objcopy; ac_word=$2 @@ -13887,7 +14057,7 @@ else libbacktrace_cv_objcopy_debuglink=no elif ! test -n "${OBJCOPY}"; then libbacktrace_cv_objcopy_debuglink=no -elif ${OBJCOPY} --help | fgrep add-gnu-debuglink >/dev/null 2>&1; then +elif ${OBJCOPY} --help | grep add-gnu-debuglink >/dev/null 2>&1; then libbacktrace_cv_objcopy_debuglink=yes else libbacktrace_cv_objcopy_debuglink=no @@ -14345,10 +14515,22 @@ if test -z "${HAVE_ZLIB_TRUE}" && test -z "${HAVE_ZLIB_FALSE}"; then as_fn_error $? "conditional \"HAVE_ZLIB\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${HAVE_BUILDID_TRUE}" && test -z "${HAVE_BUILDID_FALSE}"; then + as_fn_error $? "conditional \"HAVE_BUILDID\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${HAVE_COMPRESSED_DEBUG_TRUE}" && test -z "${HAVE_COMPRESSED_DEBUG_FALSE}"; then as_fn_error $? "conditional \"HAVE_COMPRESSED_DEBUG\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${HAVE_ZSTD_TRUE}" && test -z "${HAVE_ZSTD_FALSE}"; then + as_fn_error $? "conditional \"HAVE_ZSTD\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_COMPRESSED_DEBUG_ZSTD_TRUE}" && test -z "${HAVE_COMPRESSED_DEBUG_ZSTD_FALSE}"; then + as_fn_error $? "conditional \"HAVE_COMPRESSED_DEBUG_ZSTD\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${HAVE_OBJCOPY_DEBUGLINK_TRUE}" && test -z "${HAVE_OBJCOPY_DEBUGLINK_FALSE}"; then as_fn_error $? "conditional \"HAVE_OBJCOPY_DEBUGLINK\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 diff --git a/libbacktrace/configure.ac b/libbacktrace/configure.ac index 43a33a6..da61eff 100644 --- a/libbacktrace/configure.ac +++ b/libbacktrace/configure.ac @@ -1,5 +1,5 @@ # configure.ac -- Backtrace configure script. -# Copyright (C) 2012-2021 Free Software Foundation, Inc. +# Copyright (C) 2012-2024 Free Software Foundation, Inc. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are @@ -145,10 +145,10 @@ ACX_PROG_CC_WARNING_OPTS([-W -Wall -Wwrite-strings -Wstrict-prototypes \ -Wmissing-format-attribute -Wcast-qual], [WARN_FLAGS]) -if test -n "${with_target_subdir}"; then - WARN_FLAGS="$WARN_FLAGS -Werror" -fi - +AC_ARG_ENABLE([werror], + [AS_HELP_STRING([--disable-werror], [disable building with -Werror])]) +AS_IF([test "x$enable_werror" != "xno" && test -n "${with_target_subdir}"], + [WARN_FLAGS="$WARN_FLAGS -Werror"]) AC_SUBST(WARN_FLAGS) if test -n "${with_target_subdir}"; then @@ -335,13 +335,17 @@ fi AC_SUBST(BACKTRACE_USES_MALLOC) # Check for dl_iterate_phdr. -AC_CHECK_HEADERS(link.h) -if test "$ac_cv_header_link_h" = "no"; then +AC_CHECK_HEADERS(link.h sys/link.h) +if test "$ac_cv_header_link_h" = "no" -a "$ac_cv_header_sys_link_h" = "no"; then have_dl_iterate_phdr=no else if test -n "${with_target_subdir}"; then + link_h=link.h + if test "$ac_cv_header_link_h" = "no"; then + link_h=sys/link.h + fi # When built as a GCC target library, we can't do a link test. - AC_EGREP_HEADER([dl_iterate_phdr], [link.h], [have_dl_iterate_phdr=yes], + AC_EGREP_HEADER([dl_iterate_phdr], [$link_h], [have_dl_iterate_phdr=yes], [have_dl_iterate_phdr=no]) else AC_CHECK_FUNC([dl_iterate_phdr], [have_dl_iterate_phdr=yes], @@ -373,6 +377,8 @@ if test "$have_loadquery" = "yes"; then AC_DEFINE(HAVE_LOADQUERY, 1, [Define if AIX loadquery is available.]) fi +AC_CHECK_HEADERS(windows.h) + # Check for the fcntl function. if test -n "${with_target_subdir}"; then case "${host}" in @@ -403,6 +409,9 @@ if test "$have_getexecname" = "yes"; then AC_DEFINE(HAVE_GETEXECNAME, 1, [Define if getexecname is available.]) fi +# Check for _pgmptr variable, contains the executable filename on windows +AC_CHECK_DECLS([_pgmptr]) + # Check for sysctl definitions. AC_CACHE_CHECK([for KERN_PROC], @@ -480,7 +489,18 @@ AC_CHECK_LIB([z], [compress], [AC_DEFINE(HAVE_ZLIB, 1, [Define if -lz is available.])]) AM_CONDITIONAL(HAVE_ZLIB, test "$ac_cv_lib_z_compress" = yes) -dnl Test whether the linker supports the --compress_debug_sections option. +dnl Test whether the linker supports the --build-id option. +AC_CACHE_CHECK([whether --build-id is supported], +[libbacktrace_cv_ld_buildid], +[LDFLAGS_hold=$LDFLAGS +LDFLAGS="$LDFLAGS -Wl,--build-id" +AC_LINK_IFELSE([AC_LANG_PROGRAM(,)], +[libbacktrace_cv_ld_buildid=yes], +[libbacktrace_cv_ld_buildid=no]) +LDFLAGS=$LDFLAGS_hold]) +AM_CONDITIONAL(HAVE_BUILDID, test "$libbacktrace_cv_ld_buildid" = yes) + +dnl Test whether the linker supports the --compress-debug-sections option. AC_CACHE_CHECK([whether --compress-debug-sections is supported], [libgo_cv_ld_compress], [LDFLAGS_hold=$LDFLAGS @@ -491,6 +511,21 @@ AC_LINK_IFELSE([AC_LANG_PROGRAM(,)], LDFLAGS=$LDFLAGS_hold]) AM_CONDITIONAL(HAVE_COMPRESSED_DEBUG, test "$libgo_cv_ld_compress" = yes) +AC_CHECK_LIB([zstd], [ZSTD_compress], + [AC_DEFINE(HAVE_ZSTD, 1, [Define if -lzstd is available.])]) +AM_CONDITIONAL(HAVE_ZSTD, test "$ac_cv_lib_zstd_ZSTD_compress" = yes) + +dnl Test whether the linker supports --compress-debug-sections=zstd option. +AC_CACHE_CHECK([whether --compress-debug-sections=zstd is supported], +[libgo_cv_ld_compress_zstd], +[LDFLAGS_hold=$LDFLAGS +LDFLAGS="$LDFLAGS -Wl,--compress-debug-sections=zstd" +AC_LINK_IFELSE([AC_LANG_PROGRAM(,)], +[libgo_cv_ld_compress_zstd=yes], +[libgo_cv_ld_compress_zstd=no]) +LDFLAGS=$LDFLAGS_hold]) +AM_CONDITIONAL(HAVE_COMPRESSED_DEBUG_ZSTD, test "$libgo_cv_ld_compress_zstd" = yes) + AC_ARG_VAR(OBJCOPY, [location of objcopy]) AC_CHECK_PROG(OBJCOPY, objcopy, objcopy,) AC_CHECK_PROG(READELF, readelf, readelf) @@ -500,7 +535,7 @@ AC_CACHE_CHECK([whether objcopy supports debuglink], libbacktrace_cv_objcopy_debuglink=no elif ! test -n "${OBJCOPY}"; then libbacktrace_cv_objcopy_debuglink=no -elif ${OBJCOPY} --help | fgrep add-gnu-debuglink >/dev/null 2>&1; then +elif ${OBJCOPY} --help | grep add-gnu-debuglink >/dev/null 2>&1; then libbacktrace_cv_objcopy_debuglink=yes else libbacktrace_cv_objcopy_debuglink=no diff --git a/libbacktrace/dwarf.c b/libbacktrace/dwarf.c index e6b1f23..ed06729 100644 --- a/libbacktrace/dwarf.c +++ b/libbacktrace/dwarf.c @@ -1,5 +1,5 @@ /* dwarf.c -- Get file/line information from DWARF for backtraces. - Copyright (C) 2012-2021 Free Software Foundation, Inc. + Copyright (C) 2012-2024 Free Software Foundation, Inc. Written by Ian Lance Taylor, Google. Redistribution and use in source and binary forms, with or without @@ -136,7 +136,7 @@ enum attr_val_encoding /* An address. */ ATTR_VAL_ADDRESS, /* An index into the .debug_addr section, whose value is relative to - * the DW_AT_addr_base attribute of the compilation unit. */ + the DW_AT_addr_base attribute of the compilation unit. */ ATTR_VAL_ADDRESS_INDEX, /* A unsigned integer. */ ATTR_VAL_UINT, @@ -274,8 +274,8 @@ struct function struct function_addrs { /* Range is LOW <= PC < HIGH. */ - uint64_t low; - uint64_t high; + uintptr_t low; + uintptr_t high; /* Function for this address range. */ struct function *function; }; @@ -356,8 +356,8 @@ struct unit struct unit_addrs { /* Range is LOW <= PC < HIGH. */ - uint64_t low; - uint64_t high; + uintptr_t low; + uintptr_t high; /* Compilation unit for this address range. */ struct unit *u; }; @@ -1094,7 +1094,7 @@ resolve_addr_index (const struct dwarf_sections *dwarf_sections, uint64_t addr_base, int addrsize, int is_bigendian, uint64_t addr_index, backtrace_error_callback error_callback, void *data, - uint64_t *address) + uintptr_t *address) { uint64_t offset; struct dwarf_buf addr_buf; @@ -1115,7 +1115,7 @@ resolve_addr_index (const struct dwarf_sections *dwarf_sections, addr_buf.data = data; addr_buf.reported_underflow = 0; - *address = read_address (&addr_buf, addrsize); + *address = (uintptr_t) read_address (&addr_buf, addrsize); return 1; } @@ -1194,7 +1194,7 @@ function_addrs_search (const void *vkey, const void *ventry) static int add_unit_addr (struct backtrace_state *state, void *rdata, - uint64_t lowpc, uint64_t highpc, + uintptr_t lowpc, uintptr_t highpc, backtrace_error_callback error_callback, void *data, void *pvec) { @@ -1530,10 +1530,10 @@ lookup_abbrev (struct abbrevs *abbrevs, uint64_t code, lowpc/highpc is set or ranges is set. */ struct pcrange { - uint64_t lowpc; /* The low PC value. */ + uintptr_t lowpc; /* The low PC value. */ int have_lowpc; /* Whether a low PC value was found. */ int lowpc_is_addr_index; /* Whether lowpc is in .debug_addr. */ - uint64_t highpc; /* The high PC value. */ + uintptr_t highpc; /* The high PC value. */ int have_highpc; /* Whether a high PC value was found. */ int highpc_is_relative; /* Whether highpc is relative to lowpc. */ int highpc_is_addr_index; /* Whether highpc is in .debug_addr. */ @@ -1553,12 +1553,12 @@ update_pcrange (const struct attr* attr, const struct attr_val* val, case DW_AT_low_pc: if (val->encoding == ATTR_VAL_ADDRESS) { - pcrange->lowpc = val->u.uint; + pcrange->lowpc = (uintptr_t) val->u.uint; pcrange->have_lowpc = 1; } else if (val->encoding == ATTR_VAL_ADDRESS_INDEX) { - pcrange->lowpc = val->u.uint; + pcrange->lowpc = (uintptr_t) val->u.uint; pcrange->have_lowpc = 1; pcrange->lowpc_is_addr_index = 1; } @@ -1567,18 +1567,18 @@ update_pcrange (const struct attr* attr, const struct attr_val* val, case DW_AT_high_pc: if (val->encoding == ATTR_VAL_ADDRESS) { - pcrange->highpc = val->u.uint; + pcrange->highpc = (uintptr_t) val->u.uint; pcrange->have_highpc = 1; } else if (val->encoding == ATTR_VAL_UINT) { - pcrange->highpc = val->u.uint; + pcrange->highpc = (uintptr_t) val->u.uint; pcrange->have_highpc = 1; pcrange->highpc_is_relative = 1; } else if (val->encoding == ATTR_VAL_ADDRESS_INDEX) { - pcrange->highpc = val->u.uint; + pcrange->highpc = (uintptr_t) val->u.uint; pcrange->have_highpc = 1; pcrange->highpc_is_addr_index = 1; } @@ -1613,16 +1613,16 @@ add_low_high_range (struct backtrace_state *state, uintptr_t base_address, int is_bigendian, struct unit *u, const struct pcrange *pcrange, int (*add_range) (struct backtrace_state *state, - void *rdata, uint64_t lowpc, - uint64_t highpc, + void *rdata, uintptr_t lowpc, + uintptr_t highpc, backtrace_error_callback error_callback, void *data, void *vec), void *rdata, backtrace_error_callback error_callback, void *data, void *vec) { - uint64_t lowpc; - uint64_t highpc; + uintptr_t lowpc; + uintptr_t highpc; lowpc = pcrange->lowpc; if (pcrange->lowpc_is_addr_index) @@ -1660,10 +1660,10 @@ add_ranges_from_ranges ( struct backtrace_state *state, const struct dwarf_sections *dwarf_sections, uintptr_t base_address, int is_bigendian, - struct unit *u, uint64_t base, + struct unit *u, uintptr_t base, const struct pcrange *pcrange, int (*add_range) (struct backtrace_state *state, void *rdata, - uint64_t lowpc, uint64_t highpc, + uintptr_t lowpc, uintptr_t highpc, backtrace_error_callback error_callback, void *data, void *vec), void *rdata, @@ -1702,12 +1702,12 @@ add_ranges_from_ranges ( break; if (is_highest_address (low, u->addrsize)) - base = high; + base = (uintptr_t) high; else { if (!add_range (state, rdata, - low + base + base_address, - high + base + base_address, + (uintptr_t) low + base + base_address, + (uintptr_t) high + base + base_address, error_callback, data, vec)) return 0; } @@ -1727,10 +1727,10 @@ add_ranges_from_rnglists ( struct backtrace_state *state, const struct dwarf_sections *dwarf_sections, uintptr_t base_address, int is_bigendian, - struct unit *u, uint64_t base, + struct unit *u, uintptr_t base, const struct pcrange *pcrange, int (*add_range) (struct backtrace_state *state, void *rdata, - uint64_t lowpc, uint64_t highpc, + uintptr_t lowpc, uintptr_t highpc, backtrace_error_callback error_callback, void *data, void *vec), void *rdata, @@ -1796,8 +1796,8 @@ add_ranges_from_rnglists ( case DW_RLE_startx_endx: { uint64_t index; - uint64_t low; - uint64_t high; + uintptr_t low; + uintptr_t high; index = read_uleb128 (&rnglists_buf); if (!resolve_addr_index (dwarf_sections, u->addr_base, @@ -1819,8 +1819,8 @@ add_ranges_from_rnglists ( case DW_RLE_startx_length: { uint64_t index; - uint64_t low; - uint64_t length; + uintptr_t low; + uintptr_t length; index = read_uleb128 (&rnglists_buf); if (!resolve_addr_index (dwarf_sections, u->addr_base, @@ -1850,16 +1850,16 @@ add_ranges_from_rnglists ( break; case DW_RLE_base_address: - base = read_address (&rnglists_buf, u->addrsize); + base = (uintptr_t) read_address (&rnglists_buf, u->addrsize); break; case DW_RLE_start_end: { - uint64_t low; - uint64_t high; + uintptr_t low; + uintptr_t high; - low = read_address (&rnglists_buf, u->addrsize); - high = read_address (&rnglists_buf, u->addrsize); + low = (uintptr_t) read_address (&rnglists_buf, u->addrsize); + high = (uintptr_t) read_address (&rnglists_buf, u->addrsize); if (!add_range (state, rdata, low + base_address, high + base_address, error_callback, data, vec)) @@ -1869,11 +1869,11 @@ add_ranges_from_rnglists ( case DW_RLE_start_length: { - uint64_t low; - uint64_t length; + uintptr_t low; + uintptr_t length; - low = read_address (&rnglists_buf, u->addrsize); - length = read_uleb128 (&rnglists_buf); + low = (uintptr_t) read_address (&rnglists_buf, u->addrsize); + length = (uintptr_t) read_uleb128 (&rnglists_buf); low += base_address; if (!add_range (state, rdata, low, low + length, error_callback, data, vec)) @@ -1903,9 +1903,9 @@ static int add_ranges (struct backtrace_state *state, const struct dwarf_sections *dwarf_sections, uintptr_t base_address, int is_bigendian, - struct unit *u, uint64_t base, const struct pcrange *pcrange, + struct unit *u, uintptr_t base, const struct pcrange *pcrange, int (*add_range) (struct backtrace_state *state, void *rdata, - uint64_t lowpc, uint64_t highpc, + uintptr_t lowpc, uintptr_t highpc, backtrace_error_callback error_callback, void *data, void *vec), void *rdata, @@ -1989,14 +1989,16 @@ find_address_ranges (struct backtrace_state *state, uintptr_t base_address, break; case DW_AT_stmt_list: - if (abbrev->tag == DW_TAG_compile_unit + if ((abbrev->tag == DW_TAG_compile_unit + || abbrev->tag == DW_TAG_skeleton_unit) && (val.encoding == ATTR_VAL_UINT || val.encoding == ATTR_VAL_REF_SECTION)) u->lineoff = val.u.uint; break; case DW_AT_name: - if (abbrev->tag == DW_TAG_compile_unit) + if (abbrev->tag == DW_TAG_compile_unit + || abbrev->tag == DW_TAG_skeleton_unit) { name_val = val; have_name_val = 1; @@ -2004,7 +2006,8 @@ find_address_ranges (struct backtrace_state *state, uintptr_t base_address, break; case DW_AT_comp_dir: - if (abbrev->tag == DW_TAG_compile_unit) + if (abbrev->tag == DW_TAG_compile_unit + || abbrev->tag == DW_TAG_skeleton_unit) { comp_dir_val = val; have_comp_dir_val = 1; @@ -2012,19 +2015,22 @@ find_address_ranges (struct backtrace_state *state, uintptr_t base_address, break; case DW_AT_str_offsets_base: - if (abbrev->tag == DW_TAG_compile_unit + if ((abbrev->tag == DW_TAG_compile_unit + || abbrev->tag == DW_TAG_skeleton_unit) && val.encoding == ATTR_VAL_REF_SECTION) u->str_offsets_base = val.u.uint; break; case DW_AT_addr_base: - if (abbrev->tag == DW_TAG_compile_unit + if ((abbrev->tag == DW_TAG_compile_unit + || abbrev->tag == DW_TAG_skeleton_unit) && val.encoding == ATTR_VAL_REF_SECTION) u->addr_base = val.u.uint; break; case DW_AT_rnglists_base: - if (abbrev->tag == DW_TAG_compile_unit + if ((abbrev->tag == DW_TAG_compile_unit + || abbrev->tag == DW_TAG_skeleton_unit) && val.encoding == ATTR_VAL_REF_SECTION) u->rnglists_base = val.u.uint; break; @@ -2052,7 +2058,8 @@ find_address_ranges (struct backtrace_state *state, uintptr_t base_address, } if (abbrev->tag == DW_TAG_compile_unit - || abbrev->tag == DW_TAG_subprogram) + || abbrev->tag == DW_TAG_subprogram + || abbrev->tag == DW_TAG_skeleton_unit) { if (!add_ranges (state, dwarf_sections, base_address, is_bigendian, u, pcrange.lowpc, &pcrange, @@ -2060,9 +2067,10 @@ find_address_ranges (struct backtrace_state *state, uintptr_t base_address, (void *) addrs)) return 0; - /* If we found the PC range in the DW_TAG_compile_unit, we - can stop now. */ - if (abbrev->tag == DW_TAG_compile_unit + /* If we found the PC range in the DW_TAG_compile_unit or + DW_TAG_skeleton_unit, we can stop now. */ + if ((abbrev->tag == DW_TAG_compile_unit + || abbrev->tag == DW_TAG_skeleton_unit) && (pcrange.have_ranges || (pcrange.have_lowpc && pcrange.have_highpc))) return 1; @@ -2221,6 +2229,9 @@ build_address_map (struct backtrace_state *state, uintptr_t base_address, u->comp_dir = NULL; u->abs_filename = NULL; u->lineoff = 0; + u->str_offsets_base = 0; + u->addr_base = 0; + u->rnglists_base = 0; /* The actual line number mappings will be read as needed. */ u->lines = NULL; @@ -3172,7 +3183,7 @@ read_referenced_name (struct dwarf_data *ddata, struct unit *u, static int add_function_range (struct backtrace_state *state, void *rdata, - uint64_t lowpc, uint64_t highpc, + uintptr_t lowpc, uintptr_t highpc, backtrace_error_callback error_callback, void *data, void *pvec) { @@ -3212,7 +3223,7 @@ add_function_range (struct backtrace_state *state, void *rdata, static int read_function_entry (struct backtrace_state *state, struct dwarf_data *ddata, - struct unit *u, uint64_t base, struct dwarf_buf *unit_buf, + struct unit *u, uintptr_t base, struct dwarf_buf *unit_buf, const struct line_header *lhdr, backtrace_error_callback error_callback, void *data, struct function_vector *vec_function, @@ -3271,11 +3282,12 @@ read_function_entry (struct backtrace_state *state, struct dwarf_data *ddata, /* The compile unit sets the base address for any address ranges in the function entries. */ - if (abbrev->tag == DW_TAG_compile_unit + if ((abbrev->tag == DW_TAG_compile_unit + || abbrev->tag == DW_TAG_skeleton_unit) && abbrev->attrs[i].name == DW_AT_low_pc) { if (val.encoding == ATTR_VAL_ADDRESS) - base = val.u.uint; + base = (uintptr_t) val.u.uint; else if (val.encoding == ATTR_VAL_ADDRESS_INDEX) { if (!resolve_addr_index (&ddata->dwarf_sections, diff --git a/libbacktrace/edtest.c b/libbacktrace/edtest.c index c5ced13..d99b8a6 100644 --- a/libbacktrace/edtest.c +++ b/libbacktrace/edtest.c @@ -1,5 +1,5 @@ /* edtest.c -- Test for libbacktrace storage allocation stress handling - Copyright (C) 2017-2021 Free Software Foundation, Inc. + Copyright (C) 2017-2024 Free Software Foundation, Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are diff --git a/libbacktrace/edtest2.c b/libbacktrace/edtest2.c index cffb4fd..29e93a7 100644 --- a/libbacktrace/edtest2.c +++ b/libbacktrace/edtest2.c @@ -1,5 +1,5 @@ /* edtest2.c -- Test for libbacktrace storage allocation stress handling (p2) - Copyright (C) 2017-2021 Free Software Foundation, Inc. + Copyright (C) 2017-2024 Free Software Foundation, Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are diff --git a/libbacktrace/elf.c b/libbacktrace/elf.c index 8b87b2d..3cd8702 100644 --- a/libbacktrace/elf.c +++ b/libbacktrace/elf.c @@ -1,5 +1,5 @@ /* elf.c -- Get debug data from an ELF file for backtraces. - Copyright (C) 2012-2021 Free Software Foundation, Inc. + Copyright (C) 2012-2024 Free Software Foundation, Inc. Written by Ian Lance Taylor, Google. Redistribution and use in source and binary forms, with or without @@ -40,7 +40,12 @@ POSSIBILITY OF SUCH DAMAGE. */ #include <unistd.h> #ifdef HAVE_DL_ITERATE_PHDR -#include <link.h> + #ifdef HAVE_LINK_H + #include <link.h> + #endif + #ifdef HAVE_SYS_LINK_H + #include <sys/link.h> + #endif #endif #include "backtrace.h" @@ -179,6 +184,7 @@ dl_iterate_phdr (int (*callback) (struct dl_phdr_info *, #undef STT_FUNC #undef NT_GNU_BUILD_ID #undef ELFCOMPRESS_ZLIB +#undef ELFCOMPRESS_ZSTD /* Basic types. */ @@ -336,6 +342,7 @@ typedef struct #endif /* BACKTRACE_ELF_SIZE != 32 */ #define ELFCOMPRESS_ZLIB 1 +#define ELFCOMPRESS_ZSTD 2 /* Names of sections, indexed by enum dwarf_section in internal.h. */ @@ -1108,7 +1115,7 @@ elf_uncompress_failed(void) on error. */ static int -elf_zlib_fetch (const unsigned char **ppin, const unsigned char *pinend, +elf_fetch_bits (const unsigned char **ppin, const unsigned char *pinend, uint64_t *pval, unsigned int *pbits) { unsigned int bits; @@ -1155,6 +1162,118 @@ elf_zlib_fetch (const unsigned char **ppin, const unsigned char *pinend, return 1; } +/* This is like elf_fetch_bits, but it fetchs the bits backward, and ensures at + least 16 bits. This is for zstd. */ + +static int +elf_fetch_bits_backward (const unsigned char **ppin, + const unsigned char *pinend, + uint64_t *pval, unsigned int *pbits) +{ + unsigned int bits; + const unsigned char *pin; + uint64_t val; + uint32_t next; + + bits = *pbits; + if (bits >= 16) + return 1; + pin = *ppin; + val = *pval; + + if (unlikely (pin <= pinend)) + { + if (bits == 0) + { + elf_uncompress_failed (); + return 0; + } + return 1; + } + + pin -= 4; + +#if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) \ + && defined(__ORDER_BIG_ENDIAN__) \ + && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ \ + || __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) + /* We've ensured that PIN is aligned. */ + next = *(const uint32_t *)pin; + +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + next = __builtin_bswap32 (next); +#endif +#else + next = pin[0] | (pin[1] << 8) | (pin[2] << 16) | (pin[3] << 24); +#endif + + val <<= 32; + val |= next; + bits += 32; + + if (unlikely (pin < pinend)) + { + val >>= (pinend - pin) * 8; + bits -= (pinend - pin) * 8; + } + + *ppin = pin; + *pval = val; + *pbits = bits; + return 1; +} + +/* Initialize backward fetching when the bitstream starts with a 1 bit in the + last byte in memory (which is the first one that we read). This is used by + zstd decompression. Returns 1 on success, 0 on error. */ + +static int +elf_fetch_backward_init (const unsigned char **ppin, + const unsigned char *pinend, + uint64_t *pval, unsigned int *pbits) +{ + const unsigned char *pin; + unsigned int stream_start; + uint64_t val; + unsigned int bits; + + pin = *ppin; + stream_start = (unsigned int)*pin; + if (unlikely (stream_start == 0)) + { + elf_uncompress_failed (); + return 0; + } + val = 0; + bits = 0; + + /* Align to a 32-bit boundary. */ + while ((((uintptr_t)pin) & 3) != 0) + { + val <<= 8; + val |= (uint64_t)*pin; + bits += 8; + --pin; + } + + val <<= 8; + val |= (uint64_t)*pin; + bits += 8; + + *ppin = pin; + *pval = val; + *pbits = bits; + if (!elf_fetch_bits_backward (ppin, pinend, pval, pbits)) + return 0; + + *pbits -= __builtin_clz (stream_start) - (sizeof (unsigned int) - 1) * 8 + 1; + + if (!elf_fetch_bits_backward (ppin, pinend, pval, pbits)) + return 0; + + return 1; +} + /* Huffman code tables, like the rest of the zlib format, are defined by RFC 1951. We store a Huffman code table as a series of tables stored sequentially in memory. Each entry in a table is 16 bits. @@ -1189,14 +1308,14 @@ elf_zlib_fetch (const unsigned char **ppin, const unsigned char *pinend, /* Number of entries we allocate to for one code table. We get a page for the two code tables we need. */ -#define HUFFMAN_TABLE_SIZE (1024) +#define ZLIB_HUFFMAN_TABLE_SIZE (1024) /* Bit masks and shifts for the values in the table. */ -#define HUFFMAN_VALUE_MASK 0x01ff -#define HUFFMAN_BITS_SHIFT 9 -#define HUFFMAN_BITS_MASK 0x7 -#define HUFFMAN_SECONDARY_SHIFT 12 +#define ZLIB_HUFFMAN_VALUE_MASK 0x01ff +#define ZLIB_HUFFMAN_BITS_SHIFT 9 +#define ZLIB_HUFFMAN_BITS_MASK 0x7 +#define ZLIB_HUFFMAN_SECONDARY_SHIFT 12 /* For working memory while inflating we need two code tables, we need an array of code lengths (max value 15, so we use unsigned char), @@ -1204,17 +1323,17 @@ elf_zlib_fetch (const unsigned char **ppin, const unsigned char *pinend, latter two arrays must be large enough to hold the maximum number of code lengths, which RFC 1951 defines as 286 + 30. */ -#define ZDEBUG_TABLE_SIZE \ - (2 * HUFFMAN_TABLE_SIZE * sizeof (uint16_t) \ +#define ZLIB_TABLE_SIZE \ + (2 * ZLIB_HUFFMAN_TABLE_SIZE * sizeof (uint16_t) \ + (286 + 30) * sizeof (uint16_t) \ + (286 + 30) * sizeof (unsigned char)) -#define ZDEBUG_TABLE_CODELEN_OFFSET \ - (2 * HUFFMAN_TABLE_SIZE * sizeof (uint16_t) \ +#define ZLIB_TABLE_CODELEN_OFFSET \ + (2 * ZLIB_HUFFMAN_TABLE_SIZE * sizeof (uint16_t) \ + (286 + 30) * sizeof (uint16_t)) -#define ZDEBUG_TABLE_WORK_OFFSET \ - (2 * HUFFMAN_TABLE_SIZE * sizeof (uint16_t)) +#define ZLIB_TABLE_WORK_OFFSET \ + (2 * ZLIB_HUFFMAN_TABLE_SIZE * sizeof (uint16_t)) #ifdef BACKTRACE_GENERATE_FIXED_HUFFMAN_TABLE @@ -1247,7 +1366,7 @@ elf_zlib_inflate_table (unsigned char *codes, size_t codes_len, next value after VAL with the same bit length. */ next = (uint16_t *) (((unsigned char *) zdebug_table) - + ZDEBUG_TABLE_WORK_OFFSET); + + ZLIB_TABLE_WORK_OFFSET); memset (&count[0], 0, 16 * sizeof (uint16_t)); for (i = 0; i < codes_len; ++i) @@ -1275,7 +1394,7 @@ elf_zlib_inflate_table (unsigned char *codes, size_t codes_len, /* For each length, fill in the table for the codes of that length. */ - memset (table, 0, HUFFMAN_TABLE_SIZE * sizeof (uint16_t)); + memset (table, 0, ZLIB_HUFFMAN_TABLE_SIZE * sizeof (uint16_t)); /* Handle the values that do not require a secondary table. */ @@ -1309,13 +1428,13 @@ elf_zlib_inflate_table (unsigned char *codes, size_t codes_len, /* In the compressed bit stream, the value VAL is encoded as J bits with the value C. */ - if (unlikely ((val & ~HUFFMAN_VALUE_MASK) != 0)) + if (unlikely ((val & ~ZLIB_HUFFMAN_VALUE_MASK) != 0)) { elf_uncompress_failed (); return 0; } - tval = val | ((j - 1) << HUFFMAN_BITS_SHIFT); + tval = val | ((j - 1) << ZLIB_HUFFMAN_BITS_SHIFT); /* The table lookup uses 8 bits. If J is less than 8, we don't know what the other bits will be. We need to fill @@ -1465,7 +1584,7 @@ elf_zlib_inflate_table (unsigned char *codes, size_t codes_len, { /* Start a new secondary table. */ - if (unlikely ((next_secondary & HUFFMAN_VALUE_MASK) + if (unlikely ((next_secondary & ZLIB_HUFFMAN_VALUE_MASK) != next_secondary)) { elf_uncompress_failed (); @@ -1476,22 +1595,23 @@ elf_zlib_inflate_table (unsigned char *codes, size_t codes_len, secondary_bits = j - 8; next_secondary += 1 << secondary_bits; table[primary] = (secondary - + ((j - 8) << HUFFMAN_BITS_SHIFT) - + (1U << HUFFMAN_SECONDARY_SHIFT)); + + ((j - 8) << ZLIB_HUFFMAN_BITS_SHIFT) + + (1U << ZLIB_HUFFMAN_SECONDARY_SHIFT)); } else { /* There is an existing entry. It had better be a secondary table with enough bits. */ - if (unlikely ((tprimary & (1U << HUFFMAN_SECONDARY_SHIFT)) + if (unlikely ((tprimary + & (1U << ZLIB_HUFFMAN_SECONDARY_SHIFT)) == 0)) { elf_uncompress_failed (); return 0; } - secondary = tprimary & HUFFMAN_VALUE_MASK; - secondary_bits = ((tprimary >> HUFFMAN_BITS_SHIFT) - & HUFFMAN_BITS_MASK); + secondary = tprimary & ZLIB_HUFFMAN_VALUE_MASK; + secondary_bits = ((tprimary >> ZLIB_HUFFMAN_BITS_SHIFT) + & ZLIB_HUFFMAN_BITS_MASK); if (unlikely (secondary_bits < j - 8)) { elf_uncompress_failed (); @@ -1502,7 +1622,7 @@ elf_zlib_inflate_table (unsigned char *codes, size_t codes_len, /* Fill in secondary table entries. */ - tval = val | ((j - 8) << HUFFMAN_BITS_SHIFT); + tval = val | ((j - 8) << ZLIB_HUFFMAN_BITS_SHIFT); for (ind = code >> 8; ind < (1U << secondary_bits); @@ -1545,7 +1665,7 @@ elf_zlib_inflate_table (unsigned char *codes, size_t codes_len, #include <stdio.h> -static uint16_t table[ZDEBUG_TABLE_SIZE]; +static uint16_t table[ZLIB_TABLE_SIZE]; static unsigned char codes[288]; int @@ -1773,7 +1893,7 @@ elf_zlib_inflate (const unsigned char *pin, size_t sin, uint16_t *zdebug_table, const uint16_t *tlit; const uint16_t *tdist; - if (!elf_zlib_fetch (&pin, pinend, &val, &bits)) + if (!elf_fetch_bits (&pin, pinend, &val, &bits)) return 0; last = val & 1; @@ -1796,7 +1916,7 @@ elf_zlib_inflate (const unsigned char *pin, size_t sin, uint16_t *zdebug_table, /* An uncompressed block. */ /* If we've read ahead more than a byte, back up. */ - while (bits > 8) + while (bits >= 8) { --pin; bits -= 8; @@ -1861,7 +1981,7 @@ elf_zlib_inflate (const unsigned char *pin, size_t sin, uint16_t *zdebug_table, /* Read a Huffman encoding table. The various magic numbers here are from RFC 1951. */ - if (!elf_zlib_fetch (&pin, pinend, &val, &bits)) + if (!elf_fetch_bits (&pin, pinend, &val, &bits)) return 0; nlit = (val & 0x1f) + 257; @@ -1886,7 +2006,7 @@ elf_zlib_inflate (const unsigned char *pin, size_t sin, uint16_t *zdebug_table, /* There are always at least 4 elements in the table. */ - if (!elf_zlib_fetch (&pin, pinend, &val, &bits)) + if (!elf_fetch_bits (&pin, pinend, &val, &bits)) return 0; codebits[16] = val & 7; @@ -1906,7 +2026,7 @@ elf_zlib_inflate (const unsigned char *pin, size_t sin, uint16_t *zdebug_table, if (nclen == 5) goto codebitsdone; - if (!elf_zlib_fetch (&pin, pinend, &val, &bits)) + if (!elf_fetch_bits (&pin, pinend, &val, &bits)) return 0; codebits[7] = val & 7; @@ -1944,7 +2064,7 @@ elf_zlib_inflate (const unsigned char *pin, size_t sin, uint16_t *zdebug_table, if (nclen == 10) goto codebitsdone; - if (!elf_zlib_fetch (&pin, pinend, &val, &bits)) + if (!elf_fetch_bits (&pin, pinend, &val, &bits)) return 0; codebits[11] = val & 7; @@ -1982,7 +2102,7 @@ elf_zlib_inflate (const unsigned char *pin, size_t sin, uint16_t *zdebug_table, if (nclen == 15) goto codebitsdone; - if (!elf_zlib_fetch (&pin, pinend, &val, &bits)) + if (!elf_fetch_bits (&pin, pinend, &val, &bits)) return 0; codebits[2] = val & 7; @@ -2021,7 +2141,7 @@ elf_zlib_inflate (const unsigned char *pin, size_t sin, uint16_t *zdebug_table, at the end of zdebug_table to hold them. */ plenbase = (((unsigned char *) zdebug_table) - + ZDEBUG_TABLE_CODELEN_OFFSET); + + ZLIB_TABLE_CODELEN_OFFSET); plen = plenbase; plenend = plen + nlit + ndist; while (plen < plenend) @@ -2030,24 +2150,25 @@ elf_zlib_inflate (const unsigned char *pin, size_t sin, uint16_t *zdebug_table, unsigned int b; uint16_t v; - if (!elf_zlib_fetch (&pin, pinend, &val, &bits)) + if (!elf_fetch_bits (&pin, pinend, &val, &bits)) return 0; t = zdebug_table[val & 0xff]; /* The compression here uses bit lengths up to 7, so a secondary table is never necessary. */ - if (unlikely ((t & (1U << HUFFMAN_SECONDARY_SHIFT)) != 0)) + if (unlikely ((t & (1U << ZLIB_HUFFMAN_SECONDARY_SHIFT)) + != 0)) { elf_uncompress_failed (); return 0; } - b = (t >> HUFFMAN_BITS_SHIFT) & HUFFMAN_BITS_MASK; + b = (t >> ZLIB_HUFFMAN_BITS_SHIFT) & ZLIB_HUFFMAN_BITS_MASK; val >>= b + 1; bits -= b + 1; - v = t & HUFFMAN_VALUE_MASK; + v = t & ZLIB_HUFFMAN_VALUE_MASK; if (v < 16) *plen++ = v; else if (v == 16) @@ -2064,7 +2185,7 @@ elf_zlib_inflate (const unsigned char *pin, size_t sin, uint16_t *zdebug_table, } /* We used up to 7 bits since the last - elf_zlib_fetch, so we have at least 8 bits + elf_fetch_bits, so we have at least 8 bits available here. */ c = 3 + (val & 0x3); @@ -2099,7 +2220,7 @@ elf_zlib_inflate (const unsigned char *pin, size_t sin, uint16_t *zdebug_table, /* Store zero 3 to 10 times. */ /* We used up to 7 bits since the last - elf_zlib_fetch, so we have at least 8 bits + elf_fetch_bits, so we have at least 8 bits available here. */ c = 3 + (val & 0x7); @@ -2145,7 +2266,7 @@ elf_zlib_inflate (const unsigned char *pin, size_t sin, uint16_t *zdebug_table, /* Store zero 11 to 138 times. */ /* We used up to 7 bits since the last - elf_zlib_fetch, so we have at least 8 bits + elf_fetch_bits, so we have at least 8 bits available here. */ c = 11 + (val & 0x7f); @@ -2182,10 +2303,11 @@ elf_zlib_inflate (const unsigned char *pin, size_t sin, uint16_t *zdebug_table, zdebug_table)) return 0; if (!elf_zlib_inflate_table (plen + nlit, ndist, zdebug_table, - zdebug_table + HUFFMAN_TABLE_SIZE)) + (zdebug_table + + ZLIB_HUFFMAN_TABLE_SIZE))) return 0; tlit = zdebug_table; - tdist = zdebug_table + HUFFMAN_TABLE_SIZE; + tdist = zdebug_table + ZLIB_HUFFMAN_TABLE_SIZE; } /* Inflate values until the end of the block. This is the @@ -2198,14 +2320,14 @@ elf_zlib_inflate (const unsigned char *pin, size_t sin, uint16_t *zdebug_table, uint16_t v; unsigned int lit; - if (!elf_zlib_fetch (&pin, pinend, &val, &bits)) + if (!elf_fetch_bits (&pin, pinend, &val, &bits)) return 0; t = tlit[val & 0xff]; - b = (t >> HUFFMAN_BITS_SHIFT) & HUFFMAN_BITS_MASK; - v = t & HUFFMAN_VALUE_MASK; + b = (t >> ZLIB_HUFFMAN_BITS_SHIFT) & ZLIB_HUFFMAN_BITS_MASK; + v = t & ZLIB_HUFFMAN_VALUE_MASK; - if ((t & (1U << HUFFMAN_SECONDARY_SHIFT)) == 0) + if ((t & (1U << ZLIB_HUFFMAN_SECONDARY_SHIFT)) == 0) { lit = v; val >>= b + 1; @@ -2214,8 +2336,8 @@ elf_zlib_inflate (const unsigned char *pin, size_t sin, uint16_t *zdebug_table, else { t = tlit[v + 0x100 + ((val >> 8) & ((1U << b) - 1))]; - b = (t >> HUFFMAN_BITS_SHIFT) & HUFFMAN_BITS_MASK; - lit = t & HUFFMAN_VALUE_MASK; + b = (t >> ZLIB_HUFFMAN_BITS_SHIFT) & ZLIB_HUFFMAN_BITS_MASK; + lit = t & ZLIB_HUFFMAN_VALUE_MASK; val >>= b + 8; bits -= b + 8; } @@ -2260,7 +2382,7 @@ elf_zlib_inflate (const unsigned char *pin, size_t sin, uint16_t *zdebug_table, { unsigned int extra; - if (!elf_zlib_fetch (&pin, pinend, &val, &bits)) + if (!elf_fetch_bits (&pin, pinend, &val, &bits)) return 0; /* This is an expression for the table of length @@ -2275,14 +2397,14 @@ elf_zlib_inflate (const unsigned char *pin, size_t sin, uint16_t *zdebug_table, bits -= extra; } - if (!elf_zlib_fetch (&pin, pinend, &val, &bits)) + if (!elf_fetch_bits (&pin, pinend, &val, &bits)) return 0; t = tdist[val & 0xff]; - b = (t >> HUFFMAN_BITS_SHIFT) & HUFFMAN_BITS_MASK; - v = t & HUFFMAN_VALUE_MASK; + b = (t >> ZLIB_HUFFMAN_BITS_SHIFT) & ZLIB_HUFFMAN_BITS_MASK; + v = t & ZLIB_HUFFMAN_VALUE_MASK; - if ((t & (1U << HUFFMAN_SECONDARY_SHIFT)) == 0) + if ((t & (1U << ZLIB_HUFFMAN_SECONDARY_SHIFT)) == 0) { dist = v; val >>= b + 1; @@ -2291,8 +2413,9 @@ elf_zlib_inflate (const unsigned char *pin, size_t sin, uint16_t *zdebug_table, else { t = tdist[v + 0x100 + ((val >> 8) & ((1U << b) - 1))]; - b = (t >> HUFFMAN_BITS_SHIFT) & HUFFMAN_BITS_MASK; - dist = t & HUFFMAN_VALUE_MASK; + b = ((t >> ZLIB_HUFFMAN_BITS_SHIFT) + & ZLIB_HUFFMAN_BITS_MASK); + dist = t & ZLIB_HUFFMAN_VALUE_MASK; val >>= b + 8; bits -= b + 8; } @@ -2332,7 +2455,7 @@ elf_zlib_inflate (const unsigned char *pin, size_t sin, uint16_t *zdebug_table, { unsigned int extra; - if (!elf_zlib_fetch (&pin, pinend, &val, &bits)) + if (!elf_fetch_bits (&pin, pinend, &val, &bits)) return 0; /* This is an expression for the table of @@ -2537,6 +2660,2354 @@ elf_zlib_inflate_and_verify (const unsigned char *pin, size_t sin, return 1; } +/* For working memory during zstd compression, we need + - a literal length FSE table: 512 64-bit values == 4096 bytes + - a match length FSE table: 512 64-bit values == 4096 bytes + - a offset FSE table: 256 64-bit values == 2048 bytes + - a Huffman tree: 2048 uint16_t values == 4096 bytes + - scratch space, one of + - to build an FSE table: 512 uint16_t values == 1024 bytes + - to build a Huffman tree: 512 uint16_t + 256 uint32_t == 2048 bytes +*/ + +#define ZSTD_TABLE_SIZE \ + (2 * 512 * sizeof (struct elf_zstd_fse_baseline_entry) \ + + 256 * sizeof (struct elf_zstd_fse_baseline_entry) \ + + 2048 * sizeof (uint16_t) \ + + 512 * sizeof (uint16_t) + 256 * sizeof (uint32_t)) + +#define ZSTD_TABLE_LITERAL_FSE_OFFSET (0) + +#define ZSTD_TABLE_MATCH_FSE_OFFSET \ + (512 * sizeof (struct elf_zstd_fse_baseline_entry)) + +#define ZSTD_TABLE_OFFSET_FSE_OFFSET \ + (ZSTD_TABLE_MATCH_FSE_OFFSET \ + + 512 * sizeof (struct elf_zstd_fse_baseline_entry)) + +#define ZSTD_TABLE_HUFFMAN_OFFSET \ + (ZSTD_TABLE_OFFSET_FSE_OFFSET \ + + 256 * sizeof (struct elf_zstd_fse_baseline_entry)) + +#define ZSTD_TABLE_WORK_OFFSET \ + (ZSTD_TABLE_HUFFMAN_OFFSET + 2048 * sizeof (uint16_t)) + +/* An entry in a zstd FSE table. */ + +struct elf_zstd_fse_entry +{ + /* The value that this FSE entry represents. */ + unsigned char symbol; + /* The number of bits to read to determine the next state. */ + unsigned char bits; + /* Add the bits to this base to get the next state. */ + uint16_t base; +}; + +static int +elf_zstd_build_fse (const int16_t *, int, uint16_t *, int, + struct elf_zstd_fse_entry *); + +/* Read a zstd FSE table and build the decoding table in *TABLE, updating *PPIN + as it reads. ZDEBUG_TABLE is scratch space; it must be enough for 512 + uint16_t values (1024 bytes). MAXIDX is the maximum number of symbols + permitted. *TABLE_BITS is the maximum number of bits for symbols in the + table: the size of *TABLE is at least 1 << *TABLE_BITS. This updates + *TABLE_BITS to the actual number of bits. Returns 1 on success, 0 on + error. */ + +static int +elf_zstd_read_fse (const unsigned char **ppin, const unsigned char *pinend, + uint16_t *zdebug_table, int maxidx, + struct elf_zstd_fse_entry *table, int *table_bits) +{ + const unsigned char *pin; + int16_t *norm; + uint16_t *next; + uint64_t val; + unsigned int bits; + int accuracy_log; + uint32_t remaining; + uint32_t threshold; + int bits_needed; + int idx; + int prev0; + + pin = *ppin; + + norm = (int16_t *) zdebug_table; + next = zdebug_table + 256; + + if (unlikely (pin + 3 >= pinend)) + { + elf_uncompress_failed (); + return 0; + } + + /* Align PIN to a 32-bit boundary. */ + + val = 0; + bits = 0; + while ((((uintptr_t) pin) & 3) != 0) + { + val |= (uint64_t)*pin << bits; + bits += 8; + ++pin; + } + + if (!elf_fetch_bits (&pin, pinend, &val, &bits)) + return 0; + + accuracy_log = (val & 0xf) + 5; + if (accuracy_log > *table_bits) + { + elf_uncompress_failed (); + return 0; + } + *table_bits = accuracy_log; + val >>= 4; + bits -= 4; + + /* This code is mostly copied from the reference implementation. */ + + /* The number of remaining probabilities, plus 1. This sets the number of + bits that need to be read for the next value. */ + remaining = (1 << accuracy_log) + 1; + + /* The current difference between small and large values, which depends on + the number of remaining values. Small values use one less bit. */ + threshold = 1 << accuracy_log; + + /* The number of bits used to compute threshold. */ + bits_needed = accuracy_log + 1; + + /* The next character value. */ + idx = 0; + + /* Whether the last count was 0. */ + prev0 = 0; + + while (remaining > 1 && idx <= maxidx) + { + uint32_t max; + int32_t count; + + if (!elf_fetch_bits (&pin, pinend, &val, &bits)) + return 0; + + if (prev0) + { + int zidx; + + /* Previous count was 0, so there is a 2-bit repeat flag. If the + 2-bit flag is 0b11, it adds 3 and then there is another repeat + flag. */ + zidx = idx; + while ((val & 0xfff) == 0xfff) + { + zidx += 3 * 6; + val >>= 12; + bits -= 12; + if (!elf_fetch_bits (&pin, pinend, &val, &bits)) + return 0; + } + while ((val & 3) == 3) + { + zidx += 3; + val >>= 2; + bits -= 2; + if (!elf_fetch_bits (&pin, pinend, &val, &bits)) + return 0; + } + /* We have at least 13 bits here, don't need to fetch. */ + zidx += val & 3; + val >>= 2; + bits -= 2; + + if (unlikely (zidx > maxidx)) + { + elf_uncompress_failed (); + return 0; + } + + for (; idx < zidx; idx++) + norm[idx] = 0; + + prev0 = 0; + continue; + } + + max = (2 * threshold - 1) - remaining; + if ((val & (threshold - 1)) < max) + { + /* A small value. */ + count = (int32_t) ((uint32_t) val & (threshold - 1)); + val >>= bits_needed - 1; + bits -= bits_needed - 1; + } + else + { + /* A large value. */ + count = (int32_t) ((uint32_t) val & (2 * threshold - 1)); + if (count >= (int32_t) threshold) + count -= (int32_t) max; + val >>= bits_needed; + bits -= bits_needed; + } + + count--; + if (count >= 0) + remaining -= count; + else + remaining--; + if (unlikely (idx >= 256)) + { + elf_uncompress_failed (); + return 0; + } + norm[idx] = (int16_t) count; + ++idx; + + prev0 = count == 0; + + while (remaining < threshold) + { + bits_needed--; + threshold >>= 1; + } + } + + if (unlikely (remaining != 1)) + { + elf_uncompress_failed (); + return 0; + } + + /* If we've read ahead more than a byte, back up. */ + while (bits >= 8) + { + --pin; + bits -= 8; + } + + *ppin = pin; + + for (; idx <= maxidx; idx++) + norm[idx] = 0; + + return elf_zstd_build_fse (norm, idx, next, *table_bits, table); +} + +/* Build the FSE decoding table from a list of probabilities. This reads from + NORM of length IDX, uses NEXT as scratch space, and writes to *TABLE, whose + size is TABLE_BITS. */ + +static int +elf_zstd_build_fse (const int16_t *norm, int idx, uint16_t *next, + int table_bits, struct elf_zstd_fse_entry *table) +{ + int table_size; + int high_threshold; + int i; + int pos; + int step; + int mask; + + table_size = 1 << table_bits; + high_threshold = table_size - 1; + for (i = 0; i < idx; i++) + { + int16_t n; + + n = norm[i]; + if (n >= 0) + next[i] = (uint16_t) n; + else + { + table[high_threshold].symbol = (unsigned char) i; + high_threshold--; + next[i] = 1; + } + } + + pos = 0; + step = (table_size >> 1) + (table_size >> 3) + 3; + mask = table_size - 1; + for (i = 0; i < idx; i++) + { + int n; + int j; + + n = (int) norm[i]; + for (j = 0; j < n; j++) + { + table[pos].symbol = (unsigned char) i; + pos = (pos + step) & mask; + while (unlikely (pos > high_threshold)) + pos = (pos + step) & mask; + } + } + if (unlikely (pos != 0)) + { + elf_uncompress_failed (); + return 0; + } + + for (i = 0; i < table_size; i++) + { + unsigned char sym; + uint16_t next_state; + int high_bit; + int bits; + + sym = table[i].symbol; + next_state = next[sym]; + ++next[sym]; + + if (next_state == 0) + { + elf_uncompress_failed (); + return 0; + } + high_bit = 31 - __builtin_clz (next_state); + + bits = table_bits - high_bit; + table[i].bits = (unsigned char) bits; + table[i].base = (uint16_t) ((next_state << bits) - table_size); + } + + return 1; +} + +/* Encode the baseline and bits into a single 32-bit value. */ + +#define ZSTD_ENCODE_BASELINE_BITS(baseline, basebits) \ + ((uint32_t)(baseline) | ((uint32_t)(basebits) << 24)) + +#define ZSTD_DECODE_BASELINE(baseline_basebits) \ + ((uint32_t)(baseline_basebits) & 0xffffff) + +#define ZSTD_DECODE_BASEBITS(baseline_basebits) \ + ((uint32_t)(baseline_basebits) >> 24) + +/* Given a literal length code, we need to read a number of bits and add that + to a baseline. For states 0 to 15 the baseline is the state and the number + of bits is zero. */ + +#define ZSTD_LITERAL_LENGTH_BASELINE_OFFSET (16) + +static const uint32_t elf_zstd_literal_length_base[] = +{ + ZSTD_ENCODE_BASELINE_BITS(16, 1), + ZSTD_ENCODE_BASELINE_BITS(18, 1), + ZSTD_ENCODE_BASELINE_BITS(20, 1), + ZSTD_ENCODE_BASELINE_BITS(22, 1), + ZSTD_ENCODE_BASELINE_BITS(24, 2), + ZSTD_ENCODE_BASELINE_BITS(28, 2), + ZSTD_ENCODE_BASELINE_BITS(32, 3), + ZSTD_ENCODE_BASELINE_BITS(40, 3), + ZSTD_ENCODE_BASELINE_BITS(48, 4), + ZSTD_ENCODE_BASELINE_BITS(64, 6), + ZSTD_ENCODE_BASELINE_BITS(128, 7), + ZSTD_ENCODE_BASELINE_BITS(256, 8), + ZSTD_ENCODE_BASELINE_BITS(512, 9), + ZSTD_ENCODE_BASELINE_BITS(1024, 10), + ZSTD_ENCODE_BASELINE_BITS(2048, 11), + ZSTD_ENCODE_BASELINE_BITS(4096, 12), + ZSTD_ENCODE_BASELINE_BITS(8192, 13), + ZSTD_ENCODE_BASELINE_BITS(16384, 14), + ZSTD_ENCODE_BASELINE_BITS(32768, 15), + ZSTD_ENCODE_BASELINE_BITS(65536, 16) +}; + +/* The same applies to match length codes. For states 0 to 31 the baseline is + the state + 3 and the number of bits is zero. */ + +#define ZSTD_MATCH_LENGTH_BASELINE_OFFSET (32) + +static const uint32_t elf_zstd_match_length_base[] = +{ + ZSTD_ENCODE_BASELINE_BITS(35, 1), + ZSTD_ENCODE_BASELINE_BITS(37, 1), + ZSTD_ENCODE_BASELINE_BITS(39, 1), + ZSTD_ENCODE_BASELINE_BITS(41, 1), + ZSTD_ENCODE_BASELINE_BITS(43, 2), + ZSTD_ENCODE_BASELINE_BITS(47, 2), + ZSTD_ENCODE_BASELINE_BITS(51, 3), + ZSTD_ENCODE_BASELINE_BITS(59, 3), + ZSTD_ENCODE_BASELINE_BITS(67, 4), + ZSTD_ENCODE_BASELINE_BITS(83, 4), + ZSTD_ENCODE_BASELINE_BITS(99, 5), + ZSTD_ENCODE_BASELINE_BITS(131, 7), + ZSTD_ENCODE_BASELINE_BITS(259, 8), + ZSTD_ENCODE_BASELINE_BITS(515, 9), + ZSTD_ENCODE_BASELINE_BITS(1027, 10), + ZSTD_ENCODE_BASELINE_BITS(2051, 11), + ZSTD_ENCODE_BASELINE_BITS(4099, 12), + ZSTD_ENCODE_BASELINE_BITS(8195, 13), + ZSTD_ENCODE_BASELINE_BITS(16387, 14), + ZSTD_ENCODE_BASELINE_BITS(32771, 15), + ZSTD_ENCODE_BASELINE_BITS(65539, 16) +}; + +/* An entry in an FSE table used for literal/match/length values. For these we + have to map the symbol to a baseline value, and we have to read zero or more + bits and add that value to the baseline value. Rather than look the values + up in a separate table, we grow the FSE table so that we get better memory + caching. */ + +struct elf_zstd_fse_baseline_entry +{ + /* The baseline for the value that this FSE entry represents.. */ + uint32_t baseline; + /* The number of bits to read to add to the baseline. */ + unsigned char basebits; + /* The number of bits to read to determine the next state. */ + unsigned char bits; + /* Add the bits to this base to get the next state. */ + uint16_t base; +}; + +/* Convert the literal length FSE table FSE_TABLE to an FSE baseline table at + BASELINE_TABLE. Note that FSE_TABLE and BASELINE_TABLE will overlap. */ + +static int +elf_zstd_make_literal_baseline_fse ( + const struct elf_zstd_fse_entry *fse_table, + int table_bits, + struct elf_zstd_fse_baseline_entry *baseline_table) +{ + size_t count; + const struct elf_zstd_fse_entry *pfse; + struct elf_zstd_fse_baseline_entry *pbaseline; + + /* Convert backward to avoid overlap. */ + + count = 1U << table_bits; + pfse = fse_table + count; + pbaseline = baseline_table + count; + while (pfse > fse_table) + { + unsigned char symbol; + unsigned char bits; + uint16_t base; + + --pfse; + --pbaseline; + symbol = pfse->symbol; + bits = pfse->bits; + base = pfse->base; + if (symbol < ZSTD_LITERAL_LENGTH_BASELINE_OFFSET) + { + pbaseline->baseline = (uint32_t)symbol; + pbaseline->basebits = 0; + } + else + { + unsigned int idx; + uint32_t basebits; + + if (unlikely (symbol > 35)) + { + elf_uncompress_failed (); + return 0; + } + idx = symbol - ZSTD_LITERAL_LENGTH_BASELINE_OFFSET; + basebits = elf_zstd_literal_length_base[idx]; + pbaseline->baseline = ZSTD_DECODE_BASELINE(basebits); + pbaseline->basebits = ZSTD_DECODE_BASEBITS(basebits); + } + pbaseline->bits = bits; + pbaseline->base = base; + } + + return 1; +} + +/* Convert the offset length FSE table FSE_TABLE to an FSE baseline table at + BASELINE_TABLE. Note that FSE_TABLE and BASELINE_TABLE will overlap. */ + +static int +elf_zstd_make_offset_baseline_fse ( + const struct elf_zstd_fse_entry *fse_table, + int table_bits, + struct elf_zstd_fse_baseline_entry *baseline_table) +{ + size_t count; + const struct elf_zstd_fse_entry *pfse; + struct elf_zstd_fse_baseline_entry *pbaseline; + + /* Convert backward to avoid overlap. */ + + count = 1U << table_bits; + pfse = fse_table + count; + pbaseline = baseline_table + count; + while (pfse > fse_table) + { + unsigned char symbol; + unsigned char bits; + uint16_t base; + + --pfse; + --pbaseline; + symbol = pfse->symbol; + bits = pfse->bits; + base = pfse->base; + if (unlikely (symbol > 31)) + { + elf_uncompress_failed (); + return 0; + } + + /* The simple way to write this is + + pbaseline->baseline = (uint32_t)1 << symbol; + pbaseline->basebits = symbol; + + That will give us an offset value that corresponds to the one + described in the RFC. However, for offset values > 3, we have to + subtract 3. And for offset values 1, 2, 3 we use a repeated offset. + The baseline is always a power of 2, and is never 0, so for these low + values we will see one entry that is baseline 1, basebits 0, and one + entry that is baseline 2, basebits 1. All other entries will have + baseline >= 4 and basebits >= 2. + + So we can check for RFC offset <= 3 by checking for basebits <= 1. + And that means that we can subtract 3 here and not worry about doing + it in the hot loop. */ + + pbaseline->baseline = (uint32_t)1 << symbol; + if (symbol >= 2) + pbaseline->baseline -= 3; + pbaseline->basebits = symbol; + pbaseline->bits = bits; + pbaseline->base = base; + } + + return 1; +} + +/* Convert the match length FSE table FSE_TABLE to an FSE baseline table at + BASELINE_TABLE. Note that FSE_TABLE and BASELINE_TABLE will overlap. */ + +static int +elf_zstd_make_match_baseline_fse ( + const struct elf_zstd_fse_entry *fse_table, + int table_bits, + struct elf_zstd_fse_baseline_entry *baseline_table) +{ + size_t count; + const struct elf_zstd_fse_entry *pfse; + struct elf_zstd_fse_baseline_entry *pbaseline; + + /* Convert backward to avoid overlap. */ + + count = 1U << table_bits; + pfse = fse_table + count; + pbaseline = baseline_table + count; + while (pfse > fse_table) + { + unsigned char symbol; + unsigned char bits; + uint16_t base; + + --pfse; + --pbaseline; + symbol = pfse->symbol; + bits = pfse->bits; + base = pfse->base; + if (symbol < ZSTD_MATCH_LENGTH_BASELINE_OFFSET) + { + pbaseline->baseline = (uint32_t)symbol + 3; + pbaseline->basebits = 0; + } + else + { + unsigned int idx; + uint32_t basebits; + + if (unlikely (symbol > 52)) + { + elf_uncompress_failed (); + return 0; + } + idx = symbol - ZSTD_MATCH_LENGTH_BASELINE_OFFSET; + basebits = elf_zstd_match_length_base[idx]; + pbaseline->baseline = ZSTD_DECODE_BASELINE(basebits); + pbaseline->basebits = ZSTD_DECODE_BASEBITS(basebits); + } + pbaseline->bits = bits; + pbaseline->base = base; + } + + return 1; +} + +#ifdef BACKTRACE_GENERATE_ZSTD_FSE_TABLES + +/* Used to generate the predefined FSE decoding tables for zstd. */ + +#include <stdio.h> + +/* These values are straight from RFC 8878. */ + +static int16_t lit[36] = +{ + 4, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 1, 1, 1, 1, 1, + -1,-1,-1,-1 +}; + +static int16_t match[53] = +{ + 1, 4, 3, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,-1,-1, + -1,-1,-1,-1,-1 +}; + +static int16_t offset[29] = +{ + 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1,-1,-1,-1,-1,-1 +}; + +static uint16_t next[256]; + +static void +print_table (const struct elf_zstd_fse_baseline_entry *table, size_t size) +{ + size_t i; + + printf ("{\n"); + for (i = 0; i < size; i += 3) + { + int j; + + printf (" "); + for (j = 0; j < 3 && i + j < size; ++j) + printf (" { %u, %d, %d, %d },", table[i + j].baseline, + table[i + j].basebits, table[i + j].bits, + table[i + j].base); + printf ("\n"); + } + printf ("};\n"); +} + +int +main () +{ + struct elf_zstd_fse_entry lit_table[64]; + struct elf_zstd_fse_baseline_entry lit_baseline[64]; + struct elf_zstd_fse_entry match_table[64]; + struct elf_zstd_fse_baseline_entry match_baseline[64]; + struct elf_zstd_fse_entry offset_table[32]; + struct elf_zstd_fse_baseline_entry offset_baseline[32]; + + if (!elf_zstd_build_fse (lit, sizeof lit / sizeof lit[0], next, + 6, lit_table)) + { + fprintf (stderr, "elf_zstd_build_fse failed\n"); + exit (EXIT_FAILURE); + } + + if (!elf_zstd_make_literal_baseline_fse (lit_table, 6, lit_baseline)) + { + fprintf (stderr, "elf_zstd_make_literal_baseline_fse failed\n"); + exit (EXIT_FAILURE); + } + + printf ("static const struct elf_zstd_fse_baseline_entry " + "elf_zstd_lit_table[64] =\n"); + print_table (lit_baseline, + sizeof lit_baseline / sizeof lit_baseline[0]); + printf ("\n"); + + if (!elf_zstd_build_fse (match, sizeof match / sizeof match[0], next, + 6, match_table)) + { + fprintf (stderr, "elf_zstd_build_fse failed\n"); + exit (EXIT_FAILURE); + } + + if (!elf_zstd_make_match_baseline_fse (match_table, 6, match_baseline)) + { + fprintf (stderr, "elf_zstd_make_match_baseline_fse failed\n"); + exit (EXIT_FAILURE); + } + + printf ("static const struct elf_zstd_fse_baseline_entry " + "elf_zstd_match_table[64] =\n"); + print_table (match_baseline, + sizeof match_baseline / sizeof match_baseline[0]); + printf ("\n"); + + if (!elf_zstd_build_fse (offset, sizeof offset / sizeof offset[0], next, + 5, offset_table)) + { + fprintf (stderr, "elf_zstd_build_fse failed\n"); + exit (EXIT_FAILURE); + } + + if (!elf_zstd_make_offset_baseline_fse (offset_table, 5, offset_baseline)) + { + fprintf (stderr, "elf_zstd_make_offset_baseline_fse failed\n"); + exit (EXIT_FAILURE); + } + + printf ("static const struct elf_zstd_fse_baseline_entry " + "elf_zstd_offset_table[32] =\n"); + print_table (offset_baseline, + sizeof offset_baseline / sizeof offset_baseline[0]); + printf ("\n"); + + return 0; +} + +#endif + +/* The fixed tables generated by the #ifdef'ed out main function + above. */ + +static const struct elf_zstd_fse_baseline_entry elf_zstd_lit_table[64] = +{ + { 0, 0, 4, 0 }, { 0, 0, 4, 16 }, { 1, 0, 5, 32 }, + { 3, 0, 5, 0 }, { 4, 0, 5, 0 }, { 6, 0, 5, 0 }, + { 7, 0, 5, 0 }, { 9, 0, 5, 0 }, { 10, 0, 5, 0 }, + { 12, 0, 5, 0 }, { 14, 0, 6, 0 }, { 16, 1, 5, 0 }, + { 20, 1, 5, 0 }, { 22, 1, 5, 0 }, { 28, 2, 5, 0 }, + { 32, 3, 5, 0 }, { 48, 4, 5, 0 }, { 64, 6, 5, 32 }, + { 128, 7, 5, 0 }, { 256, 8, 6, 0 }, { 1024, 10, 6, 0 }, + { 4096, 12, 6, 0 }, { 0, 0, 4, 32 }, { 1, 0, 4, 0 }, + { 2, 0, 5, 0 }, { 4, 0, 5, 32 }, { 5, 0, 5, 0 }, + { 7, 0, 5, 32 }, { 8, 0, 5, 0 }, { 10, 0, 5, 32 }, + { 11, 0, 5, 0 }, { 13, 0, 6, 0 }, { 16, 1, 5, 32 }, + { 18, 1, 5, 0 }, { 22, 1, 5, 32 }, { 24, 2, 5, 0 }, + { 32, 3, 5, 32 }, { 40, 3, 5, 0 }, { 64, 6, 4, 0 }, + { 64, 6, 4, 16 }, { 128, 7, 5, 32 }, { 512, 9, 6, 0 }, + { 2048, 11, 6, 0 }, { 0, 0, 4, 48 }, { 1, 0, 4, 16 }, + { 2, 0, 5, 32 }, { 3, 0, 5, 32 }, { 5, 0, 5, 32 }, + { 6, 0, 5, 32 }, { 8, 0, 5, 32 }, { 9, 0, 5, 32 }, + { 11, 0, 5, 32 }, { 12, 0, 5, 32 }, { 15, 0, 6, 0 }, + { 18, 1, 5, 32 }, { 20, 1, 5, 32 }, { 24, 2, 5, 32 }, + { 28, 2, 5, 32 }, { 40, 3, 5, 32 }, { 48, 4, 5, 32 }, + { 65536, 16, 6, 0 }, { 32768, 15, 6, 0 }, { 16384, 14, 6, 0 }, + { 8192, 13, 6, 0 }, +}; + +static const struct elf_zstd_fse_baseline_entry elf_zstd_match_table[64] = +{ + { 3, 0, 6, 0 }, { 4, 0, 4, 0 }, { 5, 0, 5, 32 }, + { 6, 0, 5, 0 }, { 8, 0, 5, 0 }, { 9, 0, 5, 0 }, + { 11, 0, 5, 0 }, { 13, 0, 6, 0 }, { 16, 0, 6, 0 }, + { 19, 0, 6, 0 }, { 22, 0, 6, 0 }, { 25, 0, 6, 0 }, + { 28, 0, 6, 0 }, { 31, 0, 6, 0 }, { 34, 0, 6, 0 }, + { 37, 1, 6, 0 }, { 41, 1, 6, 0 }, { 47, 2, 6, 0 }, + { 59, 3, 6, 0 }, { 83, 4, 6, 0 }, { 131, 7, 6, 0 }, + { 515, 9, 6, 0 }, { 4, 0, 4, 16 }, { 5, 0, 4, 0 }, + { 6, 0, 5, 32 }, { 7, 0, 5, 0 }, { 9, 0, 5, 32 }, + { 10, 0, 5, 0 }, { 12, 0, 6, 0 }, { 15, 0, 6, 0 }, + { 18, 0, 6, 0 }, { 21, 0, 6, 0 }, { 24, 0, 6, 0 }, + { 27, 0, 6, 0 }, { 30, 0, 6, 0 }, { 33, 0, 6, 0 }, + { 35, 1, 6, 0 }, { 39, 1, 6, 0 }, { 43, 2, 6, 0 }, + { 51, 3, 6, 0 }, { 67, 4, 6, 0 }, { 99, 5, 6, 0 }, + { 259, 8, 6, 0 }, { 4, 0, 4, 32 }, { 4, 0, 4, 48 }, + { 5, 0, 4, 16 }, { 7, 0, 5, 32 }, { 8, 0, 5, 32 }, + { 10, 0, 5, 32 }, { 11, 0, 5, 32 }, { 14, 0, 6, 0 }, + { 17, 0, 6, 0 }, { 20, 0, 6, 0 }, { 23, 0, 6, 0 }, + { 26, 0, 6, 0 }, { 29, 0, 6, 0 }, { 32, 0, 6, 0 }, + { 65539, 16, 6, 0 }, { 32771, 15, 6, 0 }, { 16387, 14, 6, 0 }, + { 8195, 13, 6, 0 }, { 4099, 12, 6, 0 }, { 2051, 11, 6, 0 }, + { 1027, 10, 6, 0 }, +}; + +static const struct elf_zstd_fse_baseline_entry elf_zstd_offset_table[32] = +{ + { 1, 0, 5, 0 }, { 61, 6, 4, 0 }, { 509, 9, 5, 0 }, + { 32765, 15, 5, 0 }, { 2097149, 21, 5, 0 }, { 5, 3, 5, 0 }, + { 125, 7, 4, 0 }, { 4093, 12, 5, 0 }, { 262141, 18, 5, 0 }, + { 8388605, 23, 5, 0 }, { 29, 5, 5, 0 }, { 253, 8, 4, 0 }, + { 16381, 14, 5, 0 }, { 1048573, 20, 5, 0 }, { 1, 2, 5, 0 }, + { 125, 7, 4, 16 }, { 2045, 11, 5, 0 }, { 131069, 17, 5, 0 }, + { 4194301, 22, 5, 0 }, { 13, 4, 5, 0 }, { 253, 8, 4, 16 }, + { 8189, 13, 5, 0 }, { 524285, 19, 5, 0 }, { 2, 1, 5, 0 }, + { 61, 6, 4, 16 }, { 1021, 10, 5, 0 }, { 65533, 16, 5, 0 }, + { 268435453, 28, 5, 0 }, { 134217725, 27, 5, 0 }, { 67108861, 26, 5, 0 }, + { 33554429, 25, 5, 0 }, { 16777213, 24, 5, 0 }, +}; + +/* Read a zstd Huffman table and build the decoding table in *TABLE, reading + and updating *PPIN. This sets *PTABLE_BITS to the number of bits of the + table, such that the table length is 1 << *TABLE_BITS. ZDEBUG_TABLE is + scratch space; it must be enough for 512 uint16_t values + 256 32-bit values + (2048 bytes). Returns 1 on success, 0 on error. */ + +static int +elf_zstd_read_huff (const unsigned char **ppin, const unsigned char *pinend, + uint16_t *zdebug_table, uint16_t *table, int *ptable_bits) +{ + const unsigned char *pin; + unsigned char hdr; + unsigned char *weights; + size_t count; + uint32_t *weight_mark; + size_t i; + uint32_t weight_mask; + size_t table_bits; + + pin = *ppin; + if (unlikely (pin >= pinend)) + { + elf_uncompress_failed (); + return 0; + } + hdr = *pin; + ++pin; + + weights = (unsigned char *) zdebug_table; + + if (hdr < 128) + { + /* Table is compressed using FSE. */ + + struct elf_zstd_fse_entry *fse_table; + int fse_table_bits; + uint16_t *scratch; + const unsigned char *pfse; + const unsigned char *pback; + uint64_t val; + unsigned int bits; + unsigned int state1, state2; + + /* SCRATCH is used temporarily by elf_zstd_read_fse. It overlaps + WEIGHTS. */ + scratch = zdebug_table; + fse_table = (struct elf_zstd_fse_entry *) (scratch + 512); + fse_table_bits = 6; + + pfse = pin; + if (!elf_zstd_read_fse (&pfse, pinend, scratch, 255, fse_table, + &fse_table_bits)) + return 0; + + if (unlikely (pin + hdr > pinend)) + { + elf_uncompress_failed (); + return 0; + } + + /* We no longer need SCRATCH. Start recording weights. We need up to + 256 bytes of weights and 64 bytes of rank counts, so it won't overlap + FSE_TABLE. */ + + pback = pin + hdr - 1; + + if (!elf_fetch_backward_init (&pback, pfse, &val, &bits)) + return 0; + + bits -= fse_table_bits; + state1 = (val >> bits) & ((1U << fse_table_bits) - 1); + bits -= fse_table_bits; + state2 = (val >> bits) & ((1U << fse_table_bits) - 1); + + /* There are two independent FSE streams, tracked by STATE1 and STATE2. + We decode them alternately. */ + + count = 0; + while (1) + { + struct elf_zstd_fse_entry *pt; + uint64_t v; + + pt = &fse_table[state1]; + + if (unlikely (pin < pinend) && bits < pt->bits) + { + if (unlikely (count >= 254)) + { + elf_uncompress_failed (); + return 0; + } + weights[count] = (unsigned char) pt->symbol; + weights[count + 1] = (unsigned char) fse_table[state2].symbol; + count += 2; + break; + } + + if (unlikely (pt->bits == 0)) + v = 0; + else + { + if (!elf_fetch_bits_backward (&pback, pfse, &val, &bits)) + return 0; + + bits -= pt->bits; + v = (val >> bits) & (((uint64_t)1 << pt->bits) - 1); + } + + state1 = pt->base + v; + + if (unlikely (count >= 255)) + { + elf_uncompress_failed (); + return 0; + } + + weights[count] = pt->symbol; + ++count; + + pt = &fse_table[state2]; + + if (unlikely (pin < pinend && bits < pt->bits)) + { + if (unlikely (count >= 254)) + { + elf_uncompress_failed (); + return 0; + } + weights[count] = (unsigned char) pt->symbol; + weights[count + 1] = (unsigned char) fse_table[state1].symbol; + count += 2; + break; + } + + if (unlikely (pt->bits == 0)) + v = 0; + else + { + if (!elf_fetch_bits_backward (&pback, pfse, &val, &bits)) + return 0; + + bits -= pt->bits; + v = (val >> bits) & (((uint64_t)1 << pt->bits) - 1); + } + + state2 = pt->base + v; + + if (unlikely (count >= 255)) + { + elf_uncompress_failed (); + return 0; + } + + weights[count] = pt->symbol; + ++count; + } + + pin += hdr; + } + else + { + /* Table is not compressed. Each weight is 4 bits. */ + + count = hdr - 127; + if (unlikely (pin + ((count + 1) / 2) >= pinend)) + { + elf_uncompress_failed (); + return 0; + } + for (i = 0; i < count; i += 2) + { + unsigned char b; + + b = *pin; + ++pin; + weights[i] = b >> 4; + weights[i + 1] = b & 0xf; + } + } + + weight_mark = (uint32_t *) (weights + 256); + memset (weight_mark, 0, 13 * sizeof (uint32_t)); + weight_mask = 0; + for (i = 0; i < count; ++i) + { + unsigned char w; + + w = weights[i]; + if (unlikely (w > 12)) + { + elf_uncompress_failed (); + return 0; + } + ++weight_mark[w]; + if (w > 0) + weight_mask += 1U << (w - 1); + } + if (unlikely (weight_mask == 0)) + { + elf_uncompress_failed (); + return 0; + } + + table_bits = 32 - __builtin_clz (weight_mask); + if (unlikely (table_bits > 11)) + { + elf_uncompress_failed (); + return 0; + } + + /* Work out the last weight value, which is omitted because the weights must + sum to a power of two. */ + { + uint32_t left; + uint32_t high_bit; + + left = ((uint32_t)1 << table_bits) - weight_mask; + if (left == 0) + { + elf_uncompress_failed (); + return 0; + } + high_bit = 31 - __builtin_clz (left); + if (((uint32_t)1 << high_bit) != left) + { + elf_uncompress_failed (); + return 0; + } + + if (unlikely (count >= 256)) + { + elf_uncompress_failed (); + return 0; + } + + weights[count] = high_bit + 1; + ++count; + ++weight_mark[high_bit + 1]; + } + + if (weight_mark[1] < 2 || (weight_mark[1] & 1) != 0) + { + elf_uncompress_failed (); + return 0; + } + + /* Change WEIGHT_MARK from a count of weights to the index of the first + symbol for that weight. We shift the indexes to also store how many we + have seen so far, below. */ + { + uint32_t next; + + next = 0; + for (i = 0; i < table_bits; ++i) + { + uint32_t cur; + + cur = next; + next += weight_mark[i + 1] << i; + weight_mark[i + 1] = cur; + } + } + + for (i = 0; i < count; ++i) + { + unsigned char weight; + uint32_t length; + uint16_t tval; + size_t start; + uint32_t j; + + weight = weights[i]; + if (weight == 0) + continue; + + length = 1U << (weight - 1); + tval = (i << 8) | (table_bits + 1 - weight); + start = weight_mark[weight]; + for (j = 0; j < length; ++j) + table[start + j] = tval; + weight_mark[weight] += length; + } + + *ppin = pin; + *ptable_bits = (int)table_bits; + + return 1; +} + +/* Read and decompress the literals and store them ending at POUTEND. This + works because we are going to use all the literals in the output, so they + must fit into the output buffer. HUFFMAN_TABLE, and PHUFFMAN_TABLE_BITS + store the Huffman table across calls. SCRATCH is used to read a Huffman + table. Store the start of the decompressed literals in *PPLIT. Update + *PPIN. Return 1 on success, 0 on error. */ + +static int +elf_zstd_read_literals (const unsigned char **ppin, + const unsigned char *pinend, + unsigned char *pout, + unsigned char *poutend, + uint16_t *scratch, + uint16_t *huffman_table, + int *phuffman_table_bits, + unsigned char **pplit) +{ + const unsigned char *pin; + unsigned char *plit; + unsigned char hdr; + uint32_t regenerated_size; + uint32_t compressed_size; + int streams; + uint32_t total_streams_size; + unsigned int huffman_table_bits; + uint64_t huffman_mask; + + pin = *ppin; + if (unlikely (pin >= pinend)) + { + elf_uncompress_failed (); + return 0; + } + hdr = *pin; + ++pin; + + if ((hdr & 3) == 0 || (hdr & 3) == 1) + { + int raw; + + /* Raw_Literals_Block or RLE_Literals_Block */ + + raw = (hdr & 3) == 0; + + switch ((hdr >> 2) & 3) + { + case 0: case 2: + regenerated_size = hdr >> 3; + break; + case 1: + if (unlikely (pin >= pinend)) + { + elf_uncompress_failed (); + return 0; + } + regenerated_size = (hdr >> 4) + ((uint32_t)(*pin) << 4); + ++pin; + break; + case 3: + if (unlikely (pin + 1 >= pinend)) + { + elf_uncompress_failed (); + return 0; + } + regenerated_size = ((hdr >> 4) + + ((uint32_t)*pin << 4) + + ((uint32_t)pin[1] << 12)); + pin += 2; + break; + default: + elf_uncompress_failed (); + return 0; + } + + if (unlikely ((size_t)(poutend - pout) < regenerated_size)) + { + elf_uncompress_failed (); + return 0; + } + + plit = poutend - regenerated_size; + + if (raw) + { + if (unlikely (pin + regenerated_size >= pinend)) + { + elf_uncompress_failed (); + return 0; + } + memcpy (plit, pin, regenerated_size); + pin += regenerated_size; + } + else + { + if (pin >= pinend) + { + elf_uncompress_failed (); + return 0; + } + memset (plit, *pin, regenerated_size); + ++pin; + } + + *ppin = pin; + *pplit = plit; + + return 1; + } + + /* Compressed_Literals_Block or Treeless_Literals_Block */ + + switch ((hdr >> 2) & 3) + { + case 0: case 1: + if (unlikely (pin + 1 >= pinend)) + { + elf_uncompress_failed (); + return 0; + } + regenerated_size = (hdr >> 4) | ((uint32_t)(*pin & 0x3f) << 4); + compressed_size = (uint32_t)*pin >> 6 | ((uint32_t)pin[1] << 2); + pin += 2; + streams = ((hdr >> 2) & 3) == 0 ? 1 : 4; + break; + case 2: + if (unlikely (pin + 2 >= pinend)) + { + elf_uncompress_failed (); + return 0; + } + regenerated_size = (((uint32_t)hdr >> 4) + | ((uint32_t)*pin << 4) + | (((uint32_t)pin[1] & 3) << 12)); + compressed_size = (((uint32_t)pin[1] >> 2) + | ((uint32_t)pin[2] << 6)); + pin += 3; + streams = 4; + break; + case 3: + if (unlikely (pin + 3 >= pinend)) + { + elf_uncompress_failed (); + return 0; + } + regenerated_size = (((uint32_t)hdr >> 4) + | ((uint32_t)*pin << 4) + | (((uint32_t)pin[1] & 0x3f) << 12)); + compressed_size = (((uint32_t)pin[1] >> 6) + | ((uint32_t)pin[2] << 2) + | ((uint32_t)pin[3] << 10)); + pin += 4; + streams = 4; + break; + default: + elf_uncompress_failed (); + return 0; + } + + if (unlikely (pin + compressed_size > pinend)) + { + elf_uncompress_failed (); + return 0; + } + + pinend = pin + compressed_size; + *ppin = pinend; + + if (unlikely ((size_t)(poutend - pout) < regenerated_size)) + { + elf_uncompress_failed (); + return 0; + } + + plit = poutend - regenerated_size; + + *pplit = plit; + + total_streams_size = compressed_size; + if ((hdr & 3) == 2) + { + const unsigned char *ptable; + + /* Compressed_Literals_Block. Read Huffman tree. */ + + ptable = pin; + if (!elf_zstd_read_huff (&ptable, pinend, scratch, huffman_table, + phuffman_table_bits)) + return 0; + + if (unlikely (total_streams_size < (size_t)(ptable - pin))) + { + elf_uncompress_failed (); + return 0; + } + + total_streams_size -= ptable - pin; + pin = ptable; + } + else + { + /* Treeless_Literals_Block. Reuse previous Huffman tree. */ + if (unlikely (*phuffman_table_bits == 0)) + { + elf_uncompress_failed (); + return 0; + } + } + + /* Decompress COMPRESSED_SIZE bytes of data at PIN using the huffman table, + storing REGENERATED_SIZE bytes of decompressed data at PLIT. */ + + huffman_table_bits = (unsigned int)*phuffman_table_bits; + huffman_mask = ((uint64_t)1 << huffman_table_bits) - 1; + + if (streams == 1) + { + const unsigned char *pback; + const unsigned char *pbackend; + uint64_t val; + unsigned int bits; + uint32_t i; + + pback = pin + total_streams_size - 1; + pbackend = pin; + if (!elf_fetch_backward_init (&pback, pbackend, &val, &bits)) + return 0; + + /* This is one of the inner loops of the decompression algorithm, so we + put some effort into optimization. We can't get more than 64 bytes + from a single call to elf_fetch_bits_backward, and we can't subtract + more than 11 bits at a time. */ + + if (regenerated_size >= 64) + { + unsigned char *plitstart; + unsigned char *plitstop; + + plitstart = plit; + plitstop = plit + regenerated_size - 64; + while (plit < plitstop) + { + uint16_t t; + + if (!elf_fetch_bits_backward (&pback, pbackend, &val, &bits)) + return 0; + + if (bits < 16) + break; + + while (bits >= 33) + { + t = huffman_table[(val >> (bits - huffman_table_bits)) + & huffman_mask]; + *plit = t >> 8; + ++plit; + bits -= t & 0xff; + + t = huffman_table[(val >> (bits - huffman_table_bits)) + & huffman_mask]; + *plit = t >> 8; + ++plit; + bits -= t & 0xff; + + t = huffman_table[(val >> (bits - huffman_table_bits)) + & huffman_mask]; + *plit = t >> 8; + ++plit; + bits -= t & 0xff; + } + + while (bits > 11) + { + t = huffman_table[(val >> (bits - huffman_table_bits)) + & huffman_mask]; + *plit = t >> 8; + ++plit; + bits -= t & 0xff; + } + } + + regenerated_size -= plit - plitstart; + } + + for (i = 0; i < regenerated_size; ++i) + { + uint16_t t; + + if (!elf_fetch_bits_backward (&pback, pbackend, &val, &bits)) + return 0; + + if (unlikely (bits < huffman_table_bits)) + { + t = huffman_table[(val << (huffman_table_bits - bits)) + & huffman_mask]; + if (unlikely (bits < (t & 0xff))) + { + elf_uncompress_failed (); + return 0; + } + } + else + t = huffman_table[(val >> (bits - huffman_table_bits)) + & huffman_mask]; + + *plit = t >> 8; + ++plit; + bits -= t & 0xff; + } + + return 1; + } + + { + uint32_t stream_size1, stream_size2, stream_size3, stream_size4; + uint32_t tot; + const unsigned char *pback1, *pback2, *pback3, *pback4; + const unsigned char *pbackend1, *pbackend2, *pbackend3, *pbackend4; + uint64_t val1, val2, val3, val4; + unsigned int bits1, bits2, bits3, bits4; + unsigned char *plit1, *plit2, *plit3, *plit4; + uint32_t regenerated_stream_size; + uint32_t regenerated_stream_size4; + uint16_t t1, t2, t3, t4; + uint32_t i; + uint32_t limit; + + /* Read jump table. */ + if (unlikely (pin + 5 >= pinend)) + { + elf_uncompress_failed (); + return 0; + } + stream_size1 = (uint32_t)*pin | ((uint32_t)pin[1] << 8); + pin += 2; + stream_size2 = (uint32_t)*pin | ((uint32_t)pin[1] << 8); + pin += 2; + stream_size3 = (uint32_t)*pin | ((uint32_t)pin[1] << 8); + pin += 2; + tot = stream_size1 + stream_size2 + stream_size3; + if (unlikely (tot > total_streams_size - 6)) + { + elf_uncompress_failed (); + return 0; + } + stream_size4 = total_streams_size - 6 - tot; + + pback1 = pin + stream_size1 - 1; + pbackend1 = pin; + + pback2 = pback1 + stream_size2; + pbackend2 = pback1 + 1; + + pback3 = pback2 + stream_size3; + pbackend3 = pback2 + 1; + + pback4 = pback3 + stream_size4; + pbackend4 = pback3 + 1; + + if (!elf_fetch_backward_init (&pback1, pbackend1, &val1, &bits1)) + return 0; + if (!elf_fetch_backward_init (&pback2, pbackend2, &val2, &bits2)) + return 0; + if (!elf_fetch_backward_init (&pback3, pbackend3, &val3, &bits3)) + return 0; + if (!elf_fetch_backward_init (&pback4, pbackend4, &val4, &bits4)) + return 0; + + regenerated_stream_size = (regenerated_size + 3) / 4; + + plit1 = plit; + plit2 = plit1 + regenerated_stream_size; + plit3 = plit2 + regenerated_stream_size; + plit4 = plit3 + regenerated_stream_size; + + regenerated_stream_size4 = regenerated_size - regenerated_stream_size * 3; + + /* We can't get more than 64 literal bytes from a single call to + elf_fetch_bits_backward. The fourth stream can be up to 3 bytes less, + so use as the limit. */ + + limit = regenerated_stream_size4 <= 64 ? 0 : regenerated_stream_size4 - 64; + i = 0; + while (i < limit) + { + if (!elf_fetch_bits_backward (&pback1, pbackend1, &val1, &bits1)) + return 0; + if (!elf_fetch_bits_backward (&pback2, pbackend2, &val2, &bits2)) + return 0; + if (!elf_fetch_bits_backward (&pback3, pbackend3, &val3, &bits3)) + return 0; + if (!elf_fetch_bits_backward (&pback4, pbackend4, &val4, &bits4)) + return 0; + + /* We can't subtract more than 11 bits at a time. */ + + do + { + t1 = huffman_table[(val1 >> (bits1 - huffman_table_bits)) + & huffman_mask]; + t2 = huffman_table[(val2 >> (bits2 - huffman_table_bits)) + & huffman_mask]; + t3 = huffman_table[(val3 >> (bits3 - huffman_table_bits)) + & huffman_mask]; + t4 = huffman_table[(val4 >> (bits4 - huffman_table_bits)) + & huffman_mask]; + + *plit1 = t1 >> 8; + ++plit1; + bits1 -= t1 & 0xff; + + *plit2 = t2 >> 8; + ++plit2; + bits2 -= t2 & 0xff; + + *plit3 = t3 >> 8; + ++plit3; + bits3 -= t3 & 0xff; + + *plit4 = t4 >> 8; + ++plit4; + bits4 -= t4 & 0xff; + + ++i; + } + while (bits1 > 11 && bits2 > 11 && bits3 > 11 && bits4 > 11); + } + + while (i < regenerated_stream_size) + { + int use4; + + use4 = i < regenerated_stream_size4; + + if (!elf_fetch_bits_backward (&pback1, pbackend1, &val1, &bits1)) + return 0; + if (!elf_fetch_bits_backward (&pback2, pbackend2, &val2, &bits2)) + return 0; + if (!elf_fetch_bits_backward (&pback3, pbackend3, &val3, &bits3)) + return 0; + if (use4) + { + if (!elf_fetch_bits_backward (&pback4, pbackend4, &val4, &bits4)) + return 0; + } + + if (unlikely (bits1 < huffman_table_bits)) + { + t1 = huffman_table[(val1 << (huffman_table_bits - bits1)) + & huffman_mask]; + if (unlikely (bits1 < (t1 & 0xff))) + { + elf_uncompress_failed (); + return 0; + } + } + else + t1 = huffman_table[(val1 >> (bits1 - huffman_table_bits)) + & huffman_mask]; + + if (unlikely (bits2 < huffman_table_bits)) + { + t2 = huffman_table[(val2 << (huffman_table_bits - bits2)) + & huffman_mask]; + if (unlikely (bits2 < (t2 & 0xff))) + { + elf_uncompress_failed (); + return 0; + } + } + else + t2 = huffman_table[(val2 >> (bits2 - huffman_table_bits)) + & huffman_mask]; + + if (unlikely (bits3 < huffman_table_bits)) + { + t3 = huffman_table[(val3 << (huffman_table_bits - bits3)) + & huffman_mask]; + if (unlikely (bits3 < (t3 & 0xff))) + { + elf_uncompress_failed (); + return 0; + } + } + else + t3 = huffman_table[(val3 >> (bits3 - huffman_table_bits)) + & huffman_mask]; + + if (use4) + { + if (unlikely (bits4 < huffman_table_bits)) + { + t4 = huffman_table[(val4 << (huffman_table_bits - bits4)) + & huffman_mask]; + if (unlikely (bits4 < (t4 & 0xff))) + { + elf_uncompress_failed (); + return 0; + } + } + else + t4 = huffman_table[(val4 >> (bits4 - huffman_table_bits)) + & huffman_mask]; + + *plit4 = t4 >> 8; + ++plit4; + bits4 -= t4 & 0xff; + } + + *plit1 = t1 >> 8; + ++plit1; + bits1 -= t1 & 0xff; + + *plit2 = t2 >> 8; + ++plit2; + bits2 -= t2 & 0xff; + + *plit3 = t3 >> 8; + ++plit3; + bits3 -= t3 & 0xff; + + ++i; + } + } + + return 1; +} + +/* The information used to decompress a sequence code, which can be a literal + length, an offset, or a match length. */ + +struct elf_zstd_seq_decode +{ + const struct elf_zstd_fse_baseline_entry *table; + int table_bits; +}; + +/* Unpack a sequence code compression mode. */ + +static int +elf_zstd_unpack_seq_decode (int mode, + const unsigned char **ppin, + const unsigned char *pinend, + const struct elf_zstd_fse_baseline_entry *predef, + int predef_bits, + uint16_t *scratch, + int maxidx, + struct elf_zstd_fse_baseline_entry *table, + int table_bits, + int (*conv)(const struct elf_zstd_fse_entry *, + int, + struct elf_zstd_fse_baseline_entry *), + struct elf_zstd_seq_decode *decode) +{ + switch (mode) + { + case 0: + decode->table = predef; + decode->table_bits = predef_bits; + break; + + case 1: + { + struct elf_zstd_fse_entry entry; + + if (unlikely (*ppin >= pinend)) + { + elf_uncompress_failed (); + return 0; + } + entry.symbol = **ppin; + ++*ppin; + entry.bits = 0; + entry.base = 0; + decode->table_bits = 0; + if (!conv (&entry, 0, table)) + return 0; + } + break; + + case 2: + { + struct elf_zstd_fse_entry *fse_table; + + /* We use the same space for the simple FSE table and the baseline + table. */ + fse_table = (struct elf_zstd_fse_entry *)table; + decode->table_bits = table_bits; + if (!elf_zstd_read_fse (ppin, pinend, scratch, maxidx, fse_table, + &decode->table_bits)) + return 0; + if (!conv (fse_table, decode->table_bits, table)) + return 0; + decode->table = table; + } + break; + + case 3: + if (unlikely (decode->table_bits == -1)) + { + elf_uncompress_failed (); + return 0; + } + break; + + default: + elf_uncompress_failed (); + return 0; + } + + return 1; +} + +/* Decompress a zstd stream from PIN/SIN to POUT/SOUT. Code based on RFC 8878. + Return 1 on success, 0 on error. */ + +static int +elf_zstd_decompress (const unsigned char *pin, size_t sin, + unsigned char *zdebug_table, unsigned char *pout, + size_t sout) +{ + const unsigned char *pinend; + unsigned char *poutstart; + unsigned char *poutend; + struct elf_zstd_seq_decode literal_decode; + struct elf_zstd_fse_baseline_entry *literal_fse_table; + struct elf_zstd_seq_decode match_decode; + struct elf_zstd_fse_baseline_entry *match_fse_table; + struct elf_zstd_seq_decode offset_decode; + struct elf_zstd_fse_baseline_entry *offset_fse_table; + uint16_t *huffman_table; + int huffman_table_bits; + uint32_t repeated_offset1; + uint32_t repeated_offset2; + uint32_t repeated_offset3; + uint16_t *scratch; + unsigned char hdr; + int has_checksum; + uint64_t content_size; + int last_block; + + pinend = pin + sin; + poutstart = pout; + poutend = pout + sout; + + literal_decode.table = NULL; + literal_decode.table_bits = -1; + literal_fse_table = ((struct elf_zstd_fse_baseline_entry *) + (zdebug_table + ZSTD_TABLE_LITERAL_FSE_OFFSET)); + + match_decode.table = NULL; + match_decode.table_bits = -1; + match_fse_table = ((struct elf_zstd_fse_baseline_entry *) + (zdebug_table + ZSTD_TABLE_MATCH_FSE_OFFSET)); + + offset_decode.table = NULL; + offset_decode.table_bits = -1; + offset_fse_table = ((struct elf_zstd_fse_baseline_entry *) + (zdebug_table + ZSTD_TABLE_OFFSET_FSE_OFFSET)); + huffman_table = ((uint16_t *) + (zdebug_table + ZSTD_TABLE_HUFFMAN_OFFSET)); + huffman_table_bits = 0; + scratch = ((uint16_t *) + (zdebug_table + ZSTD_TABLE_WORK_OFFSET)); + + repeated_offset1 = 1; + repeated_offset2 = 4; + repeated_offset3 = 8; + + if (unlikely (sin < 4)) + { + elf_uncompress_failed (); + return 0; + } + + /* These values are the zstd magic number. */ + if (unlikely (pin[0] != 0x28 + || pin[1] != 0xb5 + || pin[2] != 0x2f + || pin[3] != 0xfd)) + { + elf_uncompress_failed (); + return 0; + } + + pin += 4; + + if (unlikely (pin >= pinend)) + { + elf_uncompress_failed (); + return 0; + } + + hdr = *pin++; + + /* We expect a single frame. */ + if (unlikely ((hdr & (1 << 5)) == 0)) + { + elf_uncompress_failed (); + return 0; + } + /* Reserved bit must be zero. */ + if (unlikely ((hdr & (1 << 3)) != 0)) + { + elf_uncompress_failed (); + return 0; + } + /* We do not expect a dictionary. */ + if (unlikely ((hdr & 3) != 0)) + { + elf_uncompress_failed (); + return 0; + } + has_checksum = (hdr & (1 << 2)) != 0; + switch (hdr >> 6) + { + case 0: + if (unlikely (pin >= pinend)) + { + elf_uncompress_failed (); + return 0; + } + content_size = (uint64_t) *pin++; + break; + case 1: + if (unlikely (pin + 1 >= pinend)) + { + elf_uncompress_failed (); + return 0; + } + content_size = (((uint64_t) pin[0]) | (((uint64_t) pin[1]) << 8)) + 256; + pin += 2; + break; + case 2: + if (unlikely (pin + 3 >= pinend)) + { + elf_uncompress_failed (); + return 0; + } + content_size = ((uint64_t) pin[0] + | (((uint64_t) pin[1]) << 8) + | (((uint64_t) pin[2]) << 16) + | (((uint64_t) pin[3]) << 24)); + pin += 4; + break; + case 3: + if (unlikely (pin + 7 >= pinend)) + { + elf_uncompress_failed (); + return 0; + } + content_size = ((uint64_t) pin[0] + | (((uint64_t) pin[1]) << 8) + | (((uint64_t) pin[2]) << 16) + | (((uint64_t) pin[3]) << 24) + | (((uint64_t) pin[4]) << 32) + | (((uint64_t) pin[5]) << 40) + | (((uint64_t) pin[6]) << 48) + | (((uint64_t) pin[7]) << 56)); + pin += 8; + break; + default: + elf_uncompress_failed (); + return 0; + } + + if (unlikely (content_size != (size_t) content_size + || (size_t) content_size != sout)) + { + elf_uncompress_failed (); + return 0; + } + + last_block = 0; + while (!last_block) + { + uint32_t block_hdr; + int block_type; + uint32_t block_size; + + if (unlikely (pin + 2 >= pinend)) + { + elf_uncompress_failed (); + return 0; + } + block_hdr = ((uint32_t) pin[0] + | (((uint32_t) pin[1]) << 8) + | (((uint32_t) pin[2]) << 16)); + pin += 3; + + last_block = block_hdr & 1; + block_type = (block_hdr >> 1) & 3; + block_size = block_hdr >> 3; + + switch (block_type) + { + case 0: + /* Raw_Block */ + if (unlikely ((size_t) block_size > (size_t) (pinend - pin))) + { + elf_uncompress_failed (); + return 0; + } + if (unlikely ((size_t) block_size > (size_t) (poutend - pout))) + { + elf_uncompress_failed (); + return 0; + } + memcpy (pout, pin, block_size); + pout += block_size; + pin += block_size; + break; + + case 1: + /* RLE_Block */ + if (unlikely (pin >= pinend)) + { + elf_uncompress_failed (); + return 0; + } + if (unlikely ((size_t) block_size > (size_t) (poutend - pout))) + { + elf_uncompress_failed (); + return 0; + } + memset (pout, *pin, block_size); + pout += block_size; + pin++; + break; + + case 2: + { + const unsigned char *pblockend; + unsigned char *plitstack; + unsigned char *plit; + uint32_t literal_count; + unsigned char seq_hdr; + size_t seq_count; + size_t seq; + const unsigned char *pback; + uint64_t val; + unsigned int bits; + unsigned int literal_state; + unsigned int offset_state; + unsigned int match_state; + + /* Compressed_Block */ + if (unlikely ((size_t) block_size > (size_t) (pinend - pin))) + { + elf_uncompress_failed (); + return 0; + } + + pblockend = pin + block_size; + + /* Read the literals into the end of the output space, and leave + PLIT pointing at them. */ + + if (!elf_zstd_read_literals (&pin, pblockend, pout, poutend, + scratch, huffman_table, + &huffman_table_bits, + &plitstack)) + return 0; + plit = plitstack; + literal_count = poutend - plit; + + seq_hdr = *pin; + pin++; + if (seq_hdr < 128) + seq_count = seq_hdr; + else if (seq_hdr < 255) + { + if (unlikely (pin >= pinend)) + { + elf_uncompress_failed (); + return 0; + } + seq_count = ((seq_hdr - 128) << 8) + *pin; + pin++; + } + else + { + if (unlikely (pin + 1 >= pinend)) + { + elf_uncompress_failed (); + return 0; + } + seq_count = *pin + (pin[1] << 8) + 0x7f00; + pin += 2; + } + + if (seq_count > 0) + { + int (*pfn)(const struct elf_zstd_fse_entry *, + int, struct elf_zstd_fse_baseline_entry *); + + if (unlikely (pin >= pinend)) + { + elf_uncompress_failed (); + return 0; + } + seq_hdr = *pin; + ++pin; + + pfn = elf_zstd_make_literal_baseline_fse; + if (!elf_zstd_unpack_seq_decode ((seq_hdr >> 6) & 3, + &pin, pinend, + &elf_zstd_lit_table[0], 6, + scratch, 35, + literal_fse_table, 9, pfn, + &literal_decode)) + return 0; + + pfn = elf_zstd_make_offset_baseline_fse; + if (!elf_zstd_unpack_seq_decode ((seq_hdr >> 4) & 3, + &pin, pinend, + &elf_zstd_offset_table[0], 5, + scratch, 31, + offset_fse_table, 8, pfn, + &offset_decode)) + return 0; + + pfn = elf_zstd_make_match_baseline_fse; + if (!elf_zstd_unpack_seq_decode ((seq_hdr >> 2) & 3, + &pin, pinend, + &elf_zstd_match_table[0], 6, + scratch, 52, + match_fse_table, 9, pfn, + &match_decode)) + return 0; + } + + pback = pblockend - 1; + if (!elf_fetch_backward_init (&pback, pin, &val, &bits)) + return 0; + + bits -= literal_decode.table_bits; + literal_state = ((val >> bits) + & ((1U << literal_decode.table_bits) - 1)); + + if (!elf_fetch_bits_backward (&pback, pin, &val, &bits)) + return 0; + bits -= offset_decode.table_bits; + offset_state = ((val >> bits) + & ((1U << offset_decode.table_bits) - 1)); + + if (!elf_fetch_bits_backward (&pback, pin, &val, &bits)) + return 0; + bits -= match_decode.table_bits; + match_state = ((val >> bits) + & ((1U << match_decode.table_bits) - 1)); + + seq = 0; + while (1) + { + const struct elf_zstd_fse_baseline_entry *pt; + uint32_t offset_basebits; + uint32_t offset_baseline; + uint32_t offset_bits; + uint32_t offset_base; + uint32_t offset; + uint32_t match_baseline; + uint32_t match_bits; + uint32_t match_base; + uint32_t match; + uint32_t literal_baseline; + uint32_t literal_bits; + uint32_t literal_base; + uint32_t literal; + uint32_t need; + uint32_t add; + + pt = &offset_decode.table[offset_state]; + offset_basebits = pt->basebits; + offset_baseline = pt->baseline; + offset_bits = pt->bits; + offset_base = pt->base; + + /* This case can be more than 16 bits, which is all that + elf_fetch_bits_backward promises. */ + need = offset_basebits; + add = 0; + if (unlikely (need > 16)) + { + if (!elf_fetch_bits_backward (&pback, pin, &val, &bits)) + return 0; + bits -= 16; + add = (val >> bits) & ((1U << 16) - 1); + need -= 16; + add <<= need; + } + if (need > 0) + { + if (!elf_fetch_bits_backward (&pback, pin, &val, &bits)) + return 0; + bits -= need; + add += (val >> bits) & ((1U << need) - 1); + } + + offset = offset_baseline + add; + + pt = &match_decode.table[match_state]; + need = pt->basebits; + match_baseline = pt->baseline; + match_bits = pt->bits; + match_base = pt->base; + + add = 0; + if (need > 0) + { + if (!elf_fetch_bits_backward (&pback, pin, &val, &bits)) + return 0; + bits -= need; + add = (val >> bits) & ((1U << need) - 1); + } + + match = match_baseline + add; + + pt = &literal_decode.table[literal_state]; + need = pt->basebits; + literal_baseline = pt->baseline; + literal_bits = pt->bits; + literal_base = pt->base; + + add = 0; + if (need > 0) + { + if (!elf_fetch_bits_backward (&pback, pin, &val, &bits)) + return 0; + bits -= need; + add = (val >> bits) & ((1U << need) - 1); + } + + literal = literal_baseline + add; + + /* See the comment in elf_zstd_make_offset_baseline_fse. */ + if (offset_basebits > 1) + { + repeated_offset3 = repeated_offset2; + repeated_offset2 = repeated_offset1; + repeated_offset1 = offset; + } + else + { + if (unlikely (literal == 0)) + ++offset; + switch (offset) + { + case 1: + offset = repeated_offset1; + break; + case 2: + offset = repeated_offset2; + repeated_offset2 = repeated_offset1; + repeated_offset1 = offset; + break; + case 3: + offset = repeated_offset3; + repeated_offset3 = repeated_offset2; + repeated_offset2 = repeated_offset1; + repeated_offset1 = offset; + break; + case 4: + offset = repeated_offset1 - 1; + repeated_offset3 = repeated_offset2; + repeated_offset2 = repeated_offset1; + repeated_offset1 = offset; + break; + } + } + + ++seq; + if (seq < seq_count) + { + uint32_t v; + + /* Update the three states. */ + + if (!elf_fetch_bits_backward (&pback, pin, &val, &bits)) + return 0; + + need = literal_bits; + bits -= need; + v = (val >> bits) & (((uint32_t)1 << need) - 1); + + literal_state = literal_base + v; + + if (!elf_fetch_bits_backward (&pback, pin, &val, &bits)) + return 0; + + need = match_bits; + bits -= need; + v = (val >> bits) & (((uint32_t)1 << need) - 1); + + match_state = match_base + v; + + if (!elf_fetch_bits_backward (&pback, pin, &val, &bits)) + return 0; + + need = offset_bits; + bits -= need; + v = (val >> bits) & (((uint32_t)1 << need) - 1); + + offset_state = offset_base + v; + } + + /* The next sequence is now in LITERAL, OFFSET, MATCH. */ + + /* Copy LITERAL bytes from the literals. */ + + if (unlikely ((size_t)(poutend - pout) < literal)) + { + elf_uncompress_failed (); + return 0; + } + + if (unlikely (literal_count < literal)) + { + elf_uncompress_failed (); + return 0; + } + + literal_count -= literal; + + /* Often LITERAL is small, so handle small cases quickly. */ + switch (literal) + { + case 8: + *pout++ = *plit++; + /* FALLTHROUGH */ + case 7: + *pout++ = *plit++; + /* FALLTHROUGH */ + case 6: + *pout++ = *plit++; + /* FALLTHROUGH */ + case 5: + *pout++ = *plit++; + /* FALLTHROUGH */ + case 4: + *pout++ = *plit++; + /* FALLTHROUGH */ + case 3: + *pout++ = *plit++; + /* FALLTHROUGH */ + case 2: + *pout++ = *plit++; + /* FALLTHROUGH */ + case 1: + *pout++ = *plit++; + break; + + case 0: + break; + + default: + if (unlikely ((size_t)(plit - pout) < literal)) + { + uint32_t move; + + move = plit - pout; + while (literal > move) + { + memcpy (pout, plit, move); + pout += move; + plit += move; + literal -= move; + } + } + + memcpy (pout, plit, literal); + pout += literal; + plit += literal; + } + + if (match > 0) + { + /* Copy MATCH bytes from the decoded output at OFFSET. */ + + if (unlikely ((size_t)(poutend - pout) < match)) + { + elf_uncompress_failed (); + return 0; + } + + if (unlikely ((size_t)(pout - poutstart) < offset)) + { + elf_uncompress_failed (); + return 0; + } + + if (offset >= match) + { + memcpy (pout, pout - offset, match); + pout += match; + } + else + { + while (match > 0) + { + uint32_t copy; + + copy = match < offset ? match : offset; + memcpy (pout, pout - offset, copy); + match -= copy; + pout += copy; + } + } + } + + if (unlikely (seq >= seq_count)) + { + /* Copy remaining literals. */ + if (literal_count > 0 && plit != pout) + { + if (unlikely ((size_t)(poutend - pout) + < literal_count)) + { + elf_uncompress_failed (); + return 0; + } + + if ((size_t)(plit - pout) < literal_count) + { + uint32_t move; + + move = plit - pout; + while (literal_count > move) + { + memcpy (pout, plit, move); + pout += move; + plit += move; + literal_count -= move; + } + } + + memcpy (pout, plit, literal_count); + } + + pout += literal_count; + + break; + } + } + + pin = pblockend; + } + break; + + case 3: + default: + elf_uncompress_failed (); + return 0; + } + } + + if (has_checksum) + { + if (unlikely (pin + 4 > pinend)) + { + elf_uncompress_failed (); + return 0; + } + + /* We don't currently verify the checksum. Currently running GNU ld with + --compress-debug-sections=zstd does not seem to generate a + checksum. */ + + pin += 4; + } + + if (pin != pinend) + { + elf_uncompress_failed (); + return 0; + } + + return 1; +} + +#define ZDEBUG_TABLE_SIZE \ + (ZLIB_TABLE_SIZE > ZSTD_TABLE_SIZE ? ZLIB_TABLE_SIZE : ZSTD_TABLE_SIZE) + /* Uncompress the old compressed debug format, the one emitted by --compress-debug-sections=zlib-gnu. The compressed data is in COMPRESSED / COMPRESSED_SIZE, and the function writes to @@ -2605,7 +5076,9 @@ elf_uncompress_chdr (struct backtrace_state *state, backtrace_error_callback error_callback, void *data, unsigned char **uncompressed, size_t *uncompressed_size) { - const b_elf_chdr *chdr; + b_elf_chdr chdr; + char *alc; + size_t alc_len; unsigned char *po; *uncompressed = NULL; @@ -2615,33 +5088,55 @@ elf_uncompress_chdr (struct backtrace_state *state, if (compressed_size < sizeof (b_elf_chdr)) return 1; - chdr = (const b_elf_chdr *) compressed; + /* The lld linker can misalign a compressed section, so we can't safely read + the fields directly as we can for other ELF sections. See + https://github.com/ianlancetaylor/libbacktrace/pull/120. */ + memcpy (&chdr, compressed, sizeof (b_elf_chdr)); - if (chdr->ch_type != ELFCOMPRESS_ZLIB) - { - /* Unsupported compression algorithm. */ - return 1; - } - - if (*uncompressed != NULL && *uncompressed_size >= chdr->ch_size) + alc = NULL; + alc_len = 0; + if (*uncompressed != NULL && *uncompressed_size >= chdr.ch_size) po = *uncompressed; else { - po = (unsigned char *) backtrace_alloc (state, chdr->ch_size, - error_callback, data); - if (po == NULL) + alc_len = chdr.ch_size; + alc = backtrace_alloc (state, alc_len, error_callback, data); + if (alc == NULL) return 0; + po = (unsigned char *) alc; } - if (!elf_zlib_inflate_and_verify (compressed + sizeof (b_elf_chdr), - compressed_size - sizeof (b_elf_chdr), - zdebug_table, po, chdr->ch_size)) - return 1; + switch (chdr.ch_type) + { + case ELFCOMPRESS_ZLIB: + if (!elf_zlib_inflate_and_verify (compressed + sizeof (b_elf_chdr), + compressed_size - sizeof (b_elf_chdr), + zdebug_table, po, chdr.ch_size)) + goto skip; + break; + + case ELFCOMPRESS_ZSTD: + if (!elf_zstd_decompress (compressed + sizeof (b_elf_chdr), + compressed_size - sizeof (b_elf_chdr), + (unsigned char *)zdebug_table, po, + chdr.ch_size)) + goto skip; + break; + + default: + /* Unsupported compression algorithm. */ + goto skip; + } *uncompressed = po; - *uncompressed_size = chdr->ch_size; + *uncompressed_size = chdr.ch_size; return 1; + + skip: + if (alc != NULL && alc_len > 0) + backtrace_free (state, alc, alc_len, error_callback, data); + return 1; } /* This function is a hook for testing the zlib support. It is only @@ -2670,6 +5165,31 @@ backtrace_uncompress_zdebug (struct backtrace_state *state, return ret; } +/* This function is a hook for testing the zstd support. It is only used by + tests. */ + +int +backtrace_uncompress_zstd (struct backtrace_state *state, + const unsigned char *compressed, + size_t compressed_size, + backtrace_error_callback error_callback, + void *data, unsigned char *uncompressed, + size_t uncompressed_size) +{ + unsigned char *zdebug_table; + int ret; + + zdebug_table = ((unsigned char *) backtrace_alloc (state, ZDEBUG_TABLE_SIZE, + error_callback, data)); + if (zdebug_table == NULL) + return 0; + ret = elf_zstd_decompress (compressed, compressed_size, + zdebug_table, uncompressed, uncompressed_size); + backtrace_free (state, zdebug_table, ZDEBUG_TABLE_SIZE, + error_callback, data); + return ret; +} + /* Number of LZMA states. */ #define LZMA_STATES (12) @@ -3051,6 +5571,7 @@ elf_uncompress_lzma_block (const unsigned char *compressed, uint64_t header_compressed_size; uint64_t header_uncompressed_size; unsigned char lzma2_properties; + size_t crc_offset; uint32_t computed_crc; uint32_t stream_crc; size_t uncompressed_offset; @@ -3154,19 +5675,20 @@ elf_uncompress_lzma_block (const unsigned char *compressed, /* The properties describe the dictionary size, but we don't care what that is. */ - /* Block header padding. */ - if (unlikely (off + 4 > compressed_size)) + /* Skip to just before CRC, verifying zero bytes in between. */ + crc_offset = block_header_offset + block_header_size - 4; + if (unlikely (crc_offset + 4 > compressed_size)) { elf_uncompress_failed (); return 0; } - - off = (off + 3) &~ (size_t) 3; - - if (unlikely (off + 4 > compressed_size)) + for (; off < crc_offset; off++) { - elf_uncompress_failed (); - return 0; + if (compressed[off] != 0) + { + elf_uncompress_failed (); + return 0; + } } /* Block header CRC. */ @@ -3984,8 +6506,9 @@ backtrace_uncompress_lzma (struct backtrace_state *state, static int elf_add (struct backtrace_state *state, const char *filename, int descriptor, const unsigned char *memory, size_t memory_size, - uintptr_t base_address, backtrace_error_callback error_callback, - void *data, fileline *fileline_fn, int *found_sym, int *found_dwarf, + uintptr_t base_address, struct elf_ppc64_opd_data *caller_opd, + backtrace_error_callback error_callback, void *data, + fileline *fileline_fn, int *found_sym, int *found_dwarf, struct dwarf_data **fileline_entry, int exe, int debuginfo, const char *with_buildid_data, uint32_t with_buildid_size) { @@ -4040,6 +6563,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor, struct elf_view split_debug_view[DEBUG_MAX]; unsigned char split_debug_view_valid[DEBUG_MAX]; struct elf_ppc64_opd_data opd_data, *opd; + int opd_view_valid; struct dwarf_sections dwarf_sections; if (!debuginfo) @@ -4067,6 +6591,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor, debug_view_valid = 0; memset (&split_debug_view_valid[0], 0, sizeof split_debug_view_valid); opd = NULL; + opd_view_valid = 0; if (!elf_get_view (state, descriptor, memory, memory_size, 0, sizeof ehdr, error_callback, data, &ehdr_view)) @@ -4350,12 +6875,18 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor, opd->addr = shdr->sh_addr; opd->data = (const char *) opd_data.view.view.data; opd->size = shdr->sh_size; + opd_view_valid = 1; } } + /* A debuginfo file may not have a useful .opd section, but we can use the + one from the original executable. */ + if (opd == NULL) + opd = caller_opd; + if (symtab_shndx == 0) symtab_shndx = dynsym_shndx; - if (symtab_shndx != 0 && !debuginfo) + if (symtab_shndx != 0) { const b_elf_shdr *symtab_shdr; unsigned int strtab_shndx; @@ -4431,9 +6962,9 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor, elf_release_view (state, &debuglink_view, error_callback, data); if (debugaltlink_view_valid) elf_release_view (state, &debugaltlink_view, error_callback, data); - ret = elf_add (state, "", d, NULL, 0, base_address, error_callback, - data, fileline_fn, found_sym, found_dwarf, NULL, 0, - 1, NULL, 0); + ret = elf_add (state, "", d, NULL, 0, base_address, opd, + error_callback, data, fileline_fn, found_sym, + found_dwarf, NULL, 0, 1, NULL, 0); if (ret < 0) backtrace_close (d, error_callback, data); else if (descriptor >= 0) @@ -4448,12 +6979,6 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor, buildid_view_valid = 0; } - if (opd) - { - elf_release_view (state, &opd->view, error_callback, data); - opd = NULL; - } - if (debuglink_name != NULL) { int d; @@ -4468,9 +6993,9 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor, elf_release_view (state, &debuglink_view, error_callback, data); if (debugaltlink_view_valid) elf_release_view (state, &debugaltlink_view, error_callback, data); - ret = elf_add (state, "", d, NULL, 0, base_address, error_callback, - data, fileline_fn, found_sym, found_dwarf, NULL, 0, - 1, NULL, 0); + ret = elf_add (state, "", d, NULL, 0, base_address, opd, + error_callback, data, fileline_fn, found_sym, + found_dwarf, NULL, 0, 1, NULL, 0); if (ret < 0) backtrace_close (d, error_callback, data); else if (descriptor >= 0) @@ -4496,7 +7021,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor, { int ret; - ret = elf_add (state, filename, d, NULL, 0, base_address, + ret = elf_add (state, filename, d, NULL, 0, base_address, opd, error_callback, data, fileline_fn, found_sym, found_dwarf, &fileline_altlink, 0, 1, debugaltlink_buildid_data, debugaltlink_buildid_size); @@ -4533,7 +7058,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor, if (ret) { ret = elf_add (state, filename, -1, gnu_debugdata_uncompressed, - gnu_debugdata_uncompressed_size, base_address, + gnu_debugdata_uncompressed_size, base_address, opd, error_callback, data, fileline_fn, found_sym, found_dwarf, NULL, 0, 0, NULL, 0); if (ret >= 0 && descriptor >= 0) @@ -4542,6 +7067,13 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor, } } + if (opd_view_valid) + { + elf_release_view (state, &opd->view, error_callback, data); + opd_view_valid = 0; + opd = NULL; + } + /* Read all the debug sections in a single view, since they are probably adjacent in the file. If any of sections are uncompressed, we never release this view. */ @@ -4666,7 +7198,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor, if (zdebug_table == NULL) { zdebug_table = ((uint16_t *) - backtrace_alloc (state, ZDEBUG_TABLE_SIZE, + backtrace_alloc (state, ZLIB_TABLE_SIZE, error_callback, data)); if (zdebug_table == NULL) goto fail; @@ -4692,8 +7224,15 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor, } } + if (zdebug_table != NULL) + { + backtrace_free (state, zdebug_table, ZLIB_TABLE_SIZE, + error_callback, data); + zdebug_table = NULL; + } + /* Uncompress the official ELF format - (--compress-debug-sections=zlib-gabi). */ + (--compress-debug-sections=zlib-gabi, --compress-debug-sections=zstd). */ for (i = 0; i < (int) DEBUG_MAX; ++i) { unsigned char *uncompressed_data; @@ -4781,7 +7320,7 @@ elf_add (struct backtrace_state *state, const char *filename, int descriptor, if (split_debug_view_valid[i]) elf_release_view (state, &split_debug_view[i], error_callback, data); } - if (opd) + if (opd_view_valid) elf_release_view (state, &opd->view, error_callback, data); if (descriptor >= 0) backtrace_close (descriptor, error_callback, data); @@ -4845,7 +7384,7 @@ phdr_callback (struct dl_phdr_info *info, size_t size ATTRIBUTE_UNUSED, return 0; } - if (elf_add (pd->state, filename, descriptor, NULL, 0, info->dlpi_addr, + if (elf_add (pd->state, filename, descriptor, NULL, 0, info->dlpi_addr, NULL, pd->error_callback, pd->data, &elf_fileline_fn, pd->found_sym, &found_dwarf, NULL, 0, 0, NULL, 0)) { @@ -4874,9 +7413,9 @@ backtrace_initialize (struct backtrace_state *state, const char *filename, fileline elf_fileline_fn = elf_nodebug; struct phdr_data pd; - ret = elf_add (state, filename, descriptor, NULL, 0, 0, error_callback, data, - &elf_fileline_fn, &found_sym, &found_dwarf, NULL, 1, 0, NULL, - 0); + ret = elf_add (state, filename, descriptor, NULL, 0, 0, NULL, error_callback, + data, &elf_fileline_fn, &found_sym, &found_dwarf, NULL, 1, 0, + NULL, 0); if (!ret) return 0; diff --git a/libbacktrace/fileline.c b/libbacktrace/fileline.c index 0472f47..68e80c6 100644 --- a/libbacktrace/fileline.c +++ b/libbacktrace/fileline.c @@ -1,5 +1,5 @@ /* fileline.c -- Get file and line number information in a backtrace. - Copyright (C) 2012-2021 Free Software Foundation, Inc. + Copyright (C) 2012-2024 Free Software Foundation, Inc. Written by Ian Lance Taylor, Google. Redistribution and use in source and binary forms, with or without @@ -47,6 +47,18 @@ POSSIBILITY OF SUCH DAMAGE. */ #include <mach-o/dyld.h> #endif +#ifdef HAVE_WINDOWS_H +#ifndef WIN32_MEAN_AND_LEAN +#define WIN32_MEAN_AND_LEAN +#endif + +#ifndef NOMINMAX +#define NOMINMAX +#endif + +#include <windows.h> +#endif + #include "backtrace.h" #include "internal.h" @@ -155,6 +167,47 @@ macho_get_executable_path (struct backtrace_state *state, #endif /* !defined (HAVE_MACH_O_DYLD_H) */ +#if HAVE_DECL__PGMPTR + +#define windows_executable_filename() _pgmptr + +#else /* !HAVE_DECL__PGMPTR */ + +#define windows_executable_filename() NULL + +#endif /* !HAVE_DECL__PGMPTR */ + +#ifdef HAVE_WINDOWS_H + +#define FILENAME_BUF_SIZE (MAX_PATH) + +static char * +windows_get_executable_path (char *buf, backtrace_error_callback error_callback, + void *data) +{ + size_t got; + int error; + + got = GetModuleFileNameA (NULL, buf, FILENAME_BUF_SIZE - 1); + error = GetLastError (); + if (got == 0 + || (got == FILENAME_BUF_SIZE - 1 && error == ERROR_INSUFFICIENT_BUFFER)) + { + error_callback (data, + "could not get the filename of the current executable", + error); + return NULL; + } + return buf; +} + +#else /* !defined (HAVE_WINDOWS_H) */ + +#define windows_get_executable_path(buf, error_callback, data) NULL +#define FILENAME_BUF_SIZE 64 + +#endif /* !defined (HAVE_WINDOWS_H) */ + /* Initialize the fileline information from the executable. Returns 1 on success, 0 on failure. */ @@ -168,7 +221,7 @@ fileline_initialize (struct backtrace_state *state, int called_error_callback; int descriptor; const char *filename; - char buf[64]; + char buf[FILENAME_BUF_SIZE]; if (!state->threaded) failed = state->fileline_initialization_failed; @@ -192,7 +245,7 @@ fileline_initialize (struct backtrace_state *state, descriptor = -1; called_error_callback = 0; - for (pass = 0; pass < 8; ++pass) + for (pass = 0; pass < 10; ++pass) { int does_not_exist; @@ -205,25 +258,33 @@ fileline_initialize (struct backtrace_state *state, filename = getexecname (); break; case 2: - filename = "/proc/self/exe"; + /* Test this before /proc/self/exe, as the latter exists but points + to the wine binary (and thus doesn't work). */ + filename = windows_executable_filename (); break; case 3: - filename = "/proc/curproc/file"; + filename = "/proc/self/exe"; break; case 4: + filename = "/proc/curproc/file"; + break; + case 5: snprintf (buf, sizeof (buf), "/proc/%ld/object/a.out", (long) getpid ()); filename = buf; break; - case 5: + case 6: filename = sysctl_exec_name1 (state, error_callback, data); break; - case 6: + case 7: filename = sysctl_exec_name2 (state, error_callback, data); break; - case 7: + case 8: filename = macho_get_executable_path (state, error_callback, data); break; + case 9: + filename = windows_get_executable_path (buf, error_callback, data); + break; default: abort (); } diff --git a/libbacktrace/install-debuginfo-for-buildid.sh.in b/libbacktrace/install-debuginfo-for-buildid.sh.in index 91dfdfe..0b83a36 100644 --- a/libbacktrace/install-debuginfo-for-buildid.sh.in +++ b/libbacktrace/install-debuginfo-for-buildid.sh.in @@ -2,7 +2,7 @@ # install-debug-info-for-buildid.sh -- Helper script for libbacktrace library # testing. -# Copyright (C) 2019-2021 Free Software Foundation, Inc. +# Copyright (C) 2019-2024 Free Software Foundation, Inc. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are diff --git a/libbacktrace/instrumented_alloc.c b/libbacktrace/instrumented_alloc.c index 13af81a..4a520bf 100644 --- a/libbacktrace/instrumented_alloc.c +++ b/libbacktrace/instrumented_alloc.c @@ -1,6 +1,6 @@ /* instrumented_alloc.c -- Memory allocation instrumented to fail when requested, for testing purposes. - Copyright (C) 2018-2021 Free Software Foundation, Inc. + Copyright (C) 2018-2024 Free Software Foundation, Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are diff --git a/libbacktrace/internal.h b/libbacktrace/internal.h index bb481f3..4fa0af8 100644 --- a/libbacktrace/internal.h +++ b/libbacktrace/internal.h @@ -1,5 +1,5 @@ /* internal.h -- Internal header file for stack backtrace library. - Copyright (C) 2012-2021 Free Software Foundation, Inc. + Copyright (C) 2012-2024 Free Software Foundation, Inc. Written by Ian Lance Taylor, Google. Redistribution and use in source and binary forms, with or without @@ -368,6 +368,15 @@ extern int backtrace_uncompress_zdebug (struct backtrace_state *, unsigned char **uncompressed, size_t *uncompressed_size); +/* A test-only hook for elf_zstd_decompress. */ + +extern int backtrace_uncompress_zstd (struct backtrace_state *, + const unsigned char *compressed, + size_t compressed_size, + backtrace_error_callback, void *data, + unsigned char *uncompressed, + size_t uncompressed_size); + /* A test-only hook for elf_uncompress_lzma. */ extern int backtrace_uncompress_lzma (struct backtrace_state *, diff --git a/libbacktrace/macho.c b/libbacktrace/macho.c index 66e101e..b485634 100644 --- a/libbacktrace/macho.c +++ b/libbacktrace/macho.c @@ -1,5 +1,5 @@ /* elf.c -- Get debug data from a Mach-O file for backtraces. - Copyright (C) 2020-2021 Free Software Foundation, Inc. + Copyright (C) 2020-2024 Free Software Foundation, Inc. Written by Ian Lance Taylor, Google. Redistribution and use in source and binary forms, with or without @@ -1268,7 +1268,7 @@ backtrace_initialize (struct backtrace_state *state, const char *filename, mff = macho_nodebug; if (!macho_add (state, name, d, 0, NULL, base_address, 0, error_callback, data, &mff, &mfs)) - return 0; + continue; if (mff != macho_nodebug) macho_fileline_fn = mff; diff --git a/libbacktrace/mmap.c b/libbacktrace/mmap.c index d7313be..322ed94 100644 --- a/libbacktrace/mmap.c +++ b/libbacktrace/mmap.c @@ -1,5 +1,5 @@ /* mmap.c -- Memory allocation with mmap. - Copyright (C) 2012-2021 Free Software Foundation, Inc. + Copyright (C) 2012-2024 Free Software Foundation, Inc. Written by Ian Lance Taylor, Google. Redistribution and use in source and binary forms, with or without diff --git a/libbacktrace/mmapio.c b/libbacktrace/mmapio.c index 7f6fa8d..b780c3d 100644 --- a/libbacktrace/mmapio.c +++ b/libbacktrace/mmapio.c @@ -1,5 +1,5 @@ /* mmapio.c -- File views using mmap. - Copyright (C) 2012-2021 Free Software Foundation, Inc. + Copyright (C) 2012-2024 Free Software Foundation, Inc. Written by Ian Lance Taylor, Google. Redistribution and use in source and binary forms, with or without diff --git a/libbacktrace/mtest.c b/libbacktrace/mtest.c index 7e0189a..9afe708 100644 --- a/libbacktrace/mtest.c +++ b/libbacktrace/mtest.c @@ -1,5 +1,5 @@ /* mtest.c -- Minidebug test for libbacktrace library - Copyright (C) 2020-2021 Free Software Foundation, Inc. + Copyright (C) 2020-2024 Free Software Foundation, Inc. Written by Ian Lance Taylor, Google. Redistribution and use in source and binary forms, with or without diff --git a/libbacktrace/nounwind.c b/libbacktrace/nounwind.c index 0eea713..ba1b06b 100644 --- a/libbacktrace/nounwind.c +++ b/libbacktrace/nounwind.c @@ -1,5 +1,5 @@ /* backtrace.c -- Entry point for stack backtrace library. - Copyright (C) 2012-2021 Free Software Foundation, Inc. + Copyright (C) 2012-2024 Free Software Foundation, Inc. Written by Ian Lance Taylor, Google. Redistribution and use in source and binary forms, with or without diff --git a/libbacktrace/pecoff.c b/libbacktrace/pecoff.c index 7202519..9e437d8 100644 --- a/libbacktrace/pecoff.c +++ b/libbacktrace/pecoff.c @@ -1,5 +1,5 @@ /* pecoff.c -- Get debug data from a PE/COFFF file for backtraces. - Copyright (C) 2015-2021 Free Software Foundation, Inc. + Copyright (C) 2015-2024 Free Software Foundation, Inc. Adapted from elf.c by Tristan Gingold, AdaCore. Redistribution and use in source and binary forms, with or without @@ -39,6 +39,18 @@ POSSIBILITY OF SUCH DAMAGE. */ #include "backtrace.h" #include "internal.h" +#ifdef HAVE_WINDOWS_H +#ifndef WIN32_MEAN_AND_LEAN +#define WIN32_MEAN_AND_LEAN +#endif + +#ifndef NOMINMAX +#define NOMINMAX +#endif + +#include <windows.h> +#endif + /* Coff file header. */ typedef struct { @@ -610,6 +622,7 @@ coff_add (struct backtrace_state *state, int descriptor, int debug_view_valid; int is_64; uintptr_t image_base; + uintptr_t base_address = 0; struct dwarf_sections dwarf_sections; *found_sym = 0; @@ -856,7 +869,16 @@ coff_add (struct backtrace_state *state, int descriptor, + (sections[i].offset - min_offset)); } - if (!backtrace_dwarf_add (state, /* base_address */ 0, &dwarf_sections, +#ifdef HAVE_WINDOWS_H + { + uintptr_t module_handle; + + module_handle = (uintptr_t) GetModuleHandle (NULL); + base_address = module_handle - image_base; + } +#endif + + if (!backtrace_dwarf_add (state, base_address, &dwarf_sections, 0, /* FIXME: is_bigendian */ NULL, /* altlink */ error_callback, data, fileline_fn, diff --git a/libbacktrace/posix.c b/libbacktrace/posix.c index 924631d..79f4950 100644 --- a/libbacktrace/posix.c +++ b/libbacktrace/posix.c @@ -1,5 +1,5 @@ /* posix.c -- POSIX file I/O routines for the backtrace library. - Copyright (C) 2012-2021 Free Software Foundation, Inc. + Copyright (C) 2012-2024 Free Software Foundation, Inc. Written by Ian Lance Taylor, Google. Redistribution and use in source and binary forms, with or without diff --git a/libbacktrace/print.c b/libbacktrace/print.c index 93d0d3a..3e61f02 100644 --- a/libbacktrace/print.c +++ b/libbacktrace/print.c @@ -1,5 +1,5 @@ /* print.c -- Print the current backtrace. - Copyright (C) 2012-2021 Free Software Foundation, Inc. + Copyright (C) 2012-2024 Free Software Foundation, Inc. Written by Ian Lance Taylor, Google. Redistribution and use in source and binary forms, with or without diff --git a/libbacktrace/read.c b/libbacktrace/read.c index 1811c8d..7af6660 100644 --- a/libbacktrace/read.c +++ b/libbacktrace/read.c @@ -1,5 +1,5 @@ /* read.c -- File views without mmap. - Copyright (C) 2012-2021 Free Software Foundation, Inc. + Copyright (C) 2012-2024 Free Software Foundation, Inc. Written by Ian Lance Taylor, Google. Redistribution and use in source and binary forms, with or without diff --git a/libbacktrace/simple.c b/libbacktrace/simple.c index 785e726e..fd3fac6 100644 --- a/libbacktrace/simple.c +++ b/libbacktrace/simple.c @@ -1,5 +1,5 @@ /* simple.c -- The backtrace_simple function. - Copyright (C) 2012-2021 Free Software Foundation, Inc. + Copyright (C) 2012-2024 Free Software Foundation, Inc. Written by Ian Lance Taylor, Google. Redistribution and use in source and binary forms, with or without diff --git a/libbacktrace/sort.c b/libbacktrace/sort.c index a60a980..fedfe21 100644 --- a/libbacktrace/sort.c +++ b/libbacktrace/sort.c @@ -1,5 +1,5 @@ /* sort.c -- Sort without allocating memory - Copyright (C) 2012-2021 Free Software Foundation, Inc. + Copyright (C) 2012-2024 Free Software Foundation, Inc. Written by Ian Lance Taylor, Google. Redistribution and use in source and binary forms, with or without diff --git a/libbacktrace/state.c b/libbacktrace/state.c index 0f368a2..b564a18 100644 --- a/libbacktrace/state.c +++ b/libbacktrace/state.c @@ -1,5 +1,5 @@ /* state.c -- Create the backtrace state. - Copyright (C) 2012-2021 Free Software Foundation, Inc. + Copyright (C) 2012-2024 Free Software Foundation, Inc. Written by Ian Lance Taylor, Google. Redistribution and use in source and binary forms, with or without diff --git a/libbacktrace/stest.c b/libbacktrace/stest.c index 19a204d..f695596 100644 --- a/libbacktrace/stest.c +++ b/libbacktrace/stest.c @@ -1,5 +1,5 @@ /* stest.c -- Test for libbacktrace internal sort function - Copyright (C) 2012-2021 Free Software Foundation, Inc. + Copyright (C) 2012-2024 Free Software Foundation, Inc. Written by Ian Lance Taylor, Google. Redistribution and use in source and binary forms, with or without diff --git a/libbacktrace/test_format.c b/libbacktrace/test_format.c index 9deb6f5..10bd24b 100644 --- a/libbacktrace/test_format.c +++ b/libbacktrace/test_format.c @@ -1,5 +1,5 @@ /* test_format.c -- Test for libbacktrace library - Copyright (C) 2018-2021 Free Software Foundation, Inc. + Copyright (C) 2018-2024 Free Software Foundation, Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are diff --git a/libbacktrace/testlib.c b/libbacktrace/testlib.c index 3d24c19..a73984f 100644 --- a/libbacktrace/testlib.c +++ b/libbacktrace/testlib.c @@ -1,5 +1,5 @@ /* testlib.c -- test functions for libbacktrace library - Copyright (C) 2012-2021 Free Software Foundation, Inc. + Copyright (C) 2012-2024 Free Software Foundation, Inc. Written by Ian Lance Taylor, Google. Redistribution and use in source and binary forms, with or without diff --git a/libbacktrace/testlib.h b/libbacktrace/testlib.h index 29542a5..f475954 100644 --- a/libbacktrace/testlib.h +++ b/libbacktrace/testlib.h @@ -1,5 +1,5 @@ /* testlib.h -- Header for test functions for libbacktrace library - Copyright (C) 2012-2021 Free Software Foundation, Inc. + Copyright (C) 2012-2024 Free Software Foundation, Inc. Written by Ian Lance Taylor, Google. Redistribution and use in source and binary forms, with or without diff --git a/libbacktrace/ttest.c b/libbacktrace/ttest.c index 3758b33..5401a2a 100644 --- a/libbacktrace/ttest.c +++ b/libbacktrace/ttest.c @@ -1,5 +1,5 @@ /* ttest.c -- Test for libbacktrace library - Copyright (C) 2017-2021 Free Software Foundation, Inc. + Copyright (C) 2017-2024 Free Software Foundation, Inc. Written by Ian Lance Taylor, Google. Redistribution and use in source and binary forms, with or without diff --git a/libbacktrace/unittest.c b/libbacktrace/unittest.c index 3c85623..2fd1c9b 100644 --- a/libbacktrace/unittest.c +++ b/libbacktrace/unittest.c @@ -1,5 +1,5 @@ /* unittest.c -- Test for libbacktrace library - Copyright (C) 2018-2021 Free Software Foundation, Inc. + Copyright (C) 2018-2024 Free Software Foundation, Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are diff --git a/libbacktrace/unknown.c b/libbacktrace/unknown.c index a62cbf1..23e4cc9 100644 --- a/libbacktrace/unknown.c +++ b/libbacktrace/unknown.c @@ -1,5 +1,5 @@ /* unknown.c -- used when backtrace configury does not know file format. - Copyright (C) 2012-2021 Free Software Foundation, Inc. + Copyright (C) 2012-2024 Free Software Foundation, Inc. Written by Ian Lance Taylor, Google. Redistribution and use in source and binary forms, with or without diff --git a/libbacktrace/xcoff.c b/libbacktrace/xcoff.c index 2ded8f0..e22f15d 100644 --- a/libbacktrace/xcoff.c +++ b/libbacktrace/xcoff.c @@ -1,5 +1,5 @@ /* xcoff.c -- Get debug data from an XCOFF file for backtraces. - Copyright (C) 2012-2021 Free Software Foundation, Inc. + Copyright (C) 2012-2024 Free Software Foundation, Inc. Adapted from elf.c. Redistribution and use in source and binary forms, with or without diff --git a/libbacktrace/xztest.c b/libbacktrace/xztest.c index 6c60ff5..5b3b811 100644 --- a/libbacktrace/xztest.c +++ b/libbacktrace/xztest.c @@ -1,5 +1,5 @@ /* xztest.c -- Test for libbacktrace LZMA decoder. - Copyright (C) 2020-2021 Free Software Foundation, Inc. + Copyright (C) 2020-2024 Free Software Foundation, Inc. Written by Ian Lance Taylor, Google. Redistribution and use in source and binary forms, with or without diff --git a/libbacktrace/zstdtest.c b/libbacktrace/zstdtest.c new file mode 100644 index 0000000..b9552ab --- /dev/null +++ b/libbacktrace/zstdtest.c @@ -0,0 +1,523 @@ +/* ztest.c -- Test for libbacktrace zstd code. + Copyright (C) 2022-2024 Free Software Foundation, Inc. + Written by Ian Lance Taylor, Google. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + (1) Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + (2) Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + (3) The name of the author may not be used to + endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. */ + +#include "config.h" + +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <sys/types.h> +#include <sys/stat.h> + +#ifdef HAVE_ZSTD +#include <zstd.h> +#endif + +#include "backtrace.h" +#include "backtrace-supported.h" + +#include "internal.h" +#include "testlib.h" + +#ifndef HAVE_CLOCK_GETTIME + +typedef int xclockid_t; + +static int +xclock_gettime (xclockid_t id ATTRIBUTE_UNUSED, + struct timespec *ts ATTRIBUTE_UNUSED) +{ + errno = EINVAL; + return -1; +} + +#define clockid_t xclockid_t +#define clock_gettime xclock_gettime +#undef CLOCK_REALTIME +#define CLOCK_REALTIME 0 + +#endif /* !defined(HAVE_CLOCK_GETTIME) */ + +#ifdef CLOCK_PROCESS_CPUTIME_ID +#define ZSTD_CLOCK_GETTIME_ARG CLOCK_PROCESS_CPUTIME_ID +#else +#define ZSTD_CLOCK_GETTIME_ARG CLOCK_REALTIME +#endif + +/* Some tests for the local zstd inflation code. */ + +struct zstd_test +{ + const char *name; + const char *uncompressed; + size_t uncompressed_len; + const char *compressed; + size_t compressed_len; +}; + +/* Error callback. */ + +static void +error_callback_compress (void *vdata ATTRIBUTE_UNUSED, const char *msg, + int errnum) +{ + fprintf (stderr, "%s", msg); + if (errnum > 0) + fprintf (stderr, ": %s", strerror (errnum)); + fprintf (stderr, "\n"); + exit (EXIT_FAILURE); +} + +static const struct zstd_test tests[] = +{ + { + "empty", + "", + 0, + "\x28\xb5\x2f\xfd\x24\x00\x01\x00\x00\x99\xe9\xd8\x51", + 13, + }, + { + "hello", + "hello, world\n", + 0, + ("\x28\xb5\x2f\xfd\x24\x0d\x69\x00\x00\x68\x65\x6c\x6c\x6f\x2c\x20" + "\x77\x6f\x72\x6c\x64\x0a\x4c\x1f\xf9\xf1"), + 26, + }, + { + "goodbye", + "goodbye, world", + 0, + ("\x28\xb5\x2f\xfd\x24\x0e\x71\x00\x00\x67\x6f\x6f\x64\x62\x79\x65" + "\x2c\x20\x77\x6f\x72\x6c\x64\x61\x7b\x4b\x83"), + 27, + }, + { + "ranges", + ("\xcc\x11\x00\x00\x00\x00\x00\x00\xd5\x13\x00\x00\x00\x00\x00\x00" + "\x1c\x14\x00\x00\x00\x00\x00\x00\x72\x14\x00\x00\x00\x00\x00\x00" + "\x9d\x14\x00\x00\x00\x00\x00\x00\xd5\x14\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\xfb\x12\x00\x00\x00\x00\x00\x00\x09\x13\x00\x00\x00\x00\x00\x00" + "\x0c\x13\x00\x00\x00\x00\x00\x00\xcb\x13\x00\x00\x00\x00\x00\x00" + "\x29\x14\x00\x00\x00\x00\x00\x00\x4e\x14\x00\x00\x00\x00\x00\x00" + "\x9d\x14\x00\x00\x00\x00\x00\x00\xd5\x14\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\xfb\x12\x00\x00\x00\x00\x00\x00\x09\x13\x00\x00\x00\x00\x00\x00" + "\x67\x13\x00\x00\x00\x00\x00\x00\xcb\x13\x00\x00\x00\x00\x00\x00" + "\x9d\x14\x00\x00\x00\x00\x00\x00\xd5\x14\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x5f\x0b\x00\x00\x00\x00\x00\x00\x6c\x0b\x00\x00\x00\x00\x00\x00" + "\x7d\x0b\x00\x00\x00\x00\x00\x00\x7e\x0c\x00\x00\x00\x00\x00\x00" + "\x38\x0f\x00\x00\x00\x00\x00\x00\x5c\x0f\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x83\x0c\x00\x00\x00\x00\x00\x00\xfa\x0c\x00\x00\x00\x00\x00\x00" + "\xfd\x0d\x00\x00\x00\x00\x00\x00\xef\x0e\x00\x00\x00\x00\x00\x00" + "\x14\x0f\x00\x00\x00\x00\x00\x00\x38\x0f\x00\x00\x00\x00\x00\x00" + "\x9f\x0f\x00\x00\x00\x00\x00\x00\xac\x0f\x00\x00\x00\x00\x00\x00" + "\xdb\x0f\x00\x00\x00\x00\x00\x00\xff\x0f\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\xfd\x0d\x00\x00\x00\x00\x00\x00\xd8\x0e\x00\x00\x00\x00\x00\x00" + "\x9f\x0f\x00\x00\x00\x00\x00\x00\xac\x0f\x00\x00\x00\x00\x00\x00" + "\xdb\x0f\x00\x00\x00\x00\x00\x00\xff\x0f\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\xfa\x0c\x00\x00\x00\x00\x00\x00\xea\x0d\x00\x00\x00\x00\x00\x00" + "\xef\x0e\x00\x00\x00\x00\x00\x00\x14\x0f\x00\x00\x00\x00\x00\x00" + "\x5c\x0f\x00\x00\x00\x00\x00\x00\x9f\x0f\x00\x00\x00\x00\x00\x00" + "\xac\x0f\x00\x00\x00\x00\x00\x00\xdb\x0f\x00\x00\x00\x00\x00\x00" + "\xff\x0f\x00\x00\x00\x00\x00\x00\x2c\x10\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x60\x11\x00\x00\x00\x00\x00\x00\xd1\x16\x00\x00\x00\x00\x00\x00" + "\x40\x0b\x00\x00\x00\x00\x00\x00\x2c\x10\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x7a\x00\x00\x00\x00\x00\x00\x00\xb6\x00\x00\x00\x00\x00\x00\x00" + "\x9f\x01\x00\x00\x00\x00\x00\x00\xa7\x01\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x7a\x00\x00\x00\x00\x00\x00\x00\xa9\x00\x00\x00\x00\x00\x00\x00" + "\x9f\x01\x00\x00\x00\x00\x00\x00\xa7\x01\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"), + 672, + ("\x28\xb5\x2f\xfd\x64\xa0\x01\x2d\x05\x00\xc4\x04\xcc\x11\x00\xd5" + "\x13\x00\x1c\x14\x00\x72\x9d\xd5\xfb\x12\x00\x09\x0c\x13\xcb\x13" + "\x29\x4e\x67\x5f\x0b\x6c\x0b\x7d\x0b\x7e\x0c\x38\x0f\x5c\x0f\x83" + "\x0c\xfa\x0c\xfd\x0d\xef\x0e\x14\x38\x9f\x0f\xac\x0f\xdb\x0f\xff" + "\x0f\xd8\x9f\xac\xdb\xff\xea\x5c\x2c\x10\x60\xd1\x16\x40\x0b\x7a" + "\x00\xb6\x00\x9f\x01\xa7\x01\xa9\x36\x20\xa0\x83\x14\x34\x63\x4a" + "\x21\x70\x8c\x07\x46\x03\x4e\x10\x62\x3c\x06\x4e\xc8\x8c\xb0\x32" + "\x2a\x59\xad\xb2\xf1\x02\x82\x7c\x33\xcb\x92\x6f\x32\x4f\x9b\xb0" + "\xa2\x30\xf0\xc0\x06\x1e\x98\x99\x2c\x06\x1e\xd8\xc0\x03\x56\xd8" + "\xc0\x03\x0f\x6c\xe0\x01\xf1\xf0\xee\x9a\xc6\xc8\x97\x99\xd1\x6c" + "\xb4\x21\x45\x3b\x10\xe4\x7b\x99\x4d\x8a\x36\x64\x5c\x77\x08\x02" + "\xcb\xe0\xce"), + 179, + } +}; + +/* Test the hand coded samples. */ + +static void +test_samples (struct backtrace_state *state) +{ + size_t i; + + for (i = 0; i < sizeof tests / sizeof tests[0]; ++i) + { + unsigned char *uncompressed; + size_t uncompressed_len; + + uncompressed_len = tests[i].uncompressed_len; + if (uncompressed_len == 0) + uncompressed_len = strlen (tests[i].uncompressed); + + uncompressed = (unsigned char *) malloc (uncompressed_len); + if (uncompressed == NULL) + { + perror ("malloc"); + fprintf (stderr, "test %s: uncompress failed\n", tests[i].name); + ++failures; + continue; + } + + if (!backtrace_uncompress_zstd (state, + ((const unsigned char *) + tests[i].compressed), + tests[i].compressed_len, + error_callback_compress, NULL, + uncompressed, uncompressed_len)) + { + fprintf (stderr, "test %s: uncompress failed\n", tests[i].name); + ++failures; + } + else + { + if (memcmp (tests[i].uncompressed, uncompressed, uncompressed_len) + != 0) + { + size_t j; + + fprintf (stderr, "test %s: uncompressed data mismatch\n", + tests[i].name); + for (j = 0; j < uncompressed_len; ++j) + if (tests[i].uncompressed[j] != uncompressed[j]) + fprintf (stderr, " %zu: got %#x want %#x\n", j, + uncompressed[j], tests[i].uncompressed[j]); + ++failures; + } + else + printf ("PASS: uncompress %s\n", tests[i].name); + } + + free (uncompressed); + } +} + +#ifdef HAVE_ZSTD + +/* Given a set of TRIALS timings, discard the lowest and highest + values and return the mean average of the rest. */ + +static size_t +average_time (const size_t *times, size_t trials) +{ + size_t imax; + size_t max; + size_t imin; + size_t min; + size_t i; + size_t sum; + + imin = 0; + imax = 0; + min = times[0]; + max = times[0]; + for (i = 1; i < trials; ++i) + { + if (times[i] < min) + { + imin = i; + min = times[i]; + } + if (times[i] > max) + { + imax = i; + max = times[i]; + } + } + + sum = 0; + for (i = 0; i < trials; ++i) + { + if (i != imax && i != imin) + sum += times[i]; + } + return sum / (trials - 2); +} + +#endif + +/* Test a larger text, if available. */ + +static void +test_large (struct backtrace_state *state ATTRIBUTE_UNUSED) +{ +#ifdef HAVE_ZSTD + unsigned char *orig_buf; + size_t orig_bufsize; + size_t i; + char *compressed_buf; + size_t compressed_bufsize; + size_t compressed_size; + unsigned char *uncompressed_buf; + size_t r; + clockid_t cid; + struct timespec ts1; + struct timespec ts2; + size_t ctime; + size_t ztime; + const size_t trials = 16; + size_t ctimes[16]; + size_t ztimes[16]; + static const char * const names[] = { + "Isaac.Newton-Opticks.txt", + "../libgo/go/testdata/Isaac.Newton-Opticks.txt", + }; + + orig_buf = NULL; + orig_bufsize = 0; + uncompressed_buf = NULL; + compressed_buf = NULL; + + for (i = 0; i < sizeof names / sizeof names[0]; ++i) + { + size_t len; + char *namebuf; + FILE *e; + struct stat st; + char *rbuf; + size_t got; + + len = strlen (SRCDIR) + strlen (names[i]) + 2; + namebuf = malloc (len); + if (namebuf == NULL) + { + perror ("malloc"); + goto fail; + } + snprintf (namebuf, len, "%s/%s", SRCDIR, names[i]); + e = fopen (namebuf, "r"); + free (namebuf); + if (e == NULL) + continue; + if (fstat (fileno (e), &st) < 0) + { + perror ("fstat"); + fclose (e); + continue; + } + rbuf = malloc (st.st_size); + if (rbuf == NULL) + { + perror ("malloc"); + goto fail; + } + got = fread (rbuf, 1, st.st_size, e); + fclose (e); + if (got > 0) + { + orig_buf = (unsigned char *) rbuf; + orig_bufsize = got; + break; + } + free (rbuf); + } + + if (orig_buf == NULL) + { + /* We couldn't find an input file. */ + printf ("UNSUPPORTED: zstd large\n"); + return; + } + + compressed_bufsize = ZSTD_compressBound (orig_bufsize); + compressed_buf = malloc (compressed_bufsize); + if (compressed_buf == NULL) + { + perror ("malloc"); + goto fail; + } + + r = ZSTD_compress (compressed_buf, compressed_bufsize, + orig_buf, orig_bufsize, + ZSTD_CLEVEL_DEFAULT); + if (ZSTD_isError (r)) + { + fprintf (stderr, "zstd compress failed: %s\n", ZSTD_getErrorName (r)); + goto fail; + } + compressed_size = r; + + uncompressed_buf = malloc (orig_bufsize); + if (uncompressed_buf == NULL) + { + perror ("malloc"); + goto fail; + } + + if (!backtrace_uncompress_zstd (state, (unsigned char *) compressed_buf, + compressed_size, + error_callback_compress, NULL, + uncompressed_buf, orig_bufsize)) + { + fprintf (stderr, "zstd large: backtrace_uncompress_zstd failed\n"); + goto fail; + } + + if (memcmp (uncompressed_buf, orig_buf, orig_bufsize) != 0) + { + size_t j; + + fprintf (stderr, "zstd large: uncompressed data mismatch\n"); + for (j = 0; j < orig_bufsize; ++j) + if (orig_buf[j] != uncompressed_buf[j]) + fprintf (stderr, " %zu: got %#x want %#x\n", j, + uncompressed_buf[j], orig_buf[j]); + goto fail; + } + + printf ("PASS: zstd large\n"); + + for (i = 0; i < trials; ++i) + { + cid = ZSTD_CLOCK_GETTIME_ARG; + if (clock_gettime (cid, &ts1) < 0) + { + if (errno == EINVAL) + return; + perror ("clock_gettime"); + return; + } + + if (!backtrace_uncompress_zstd (state, + (unsigned char *) compressed_buf, + compressed_size, + error_callback_compress, NULL, + uncompressed_buf, + orig_bufsize)) + { + fprintf (stderr, + ("zstd large: " + "benchmark backtrace_uncompress_zstd failed\n")); + return; + } + + if (clock_gettime (cid, &ts2) < 0) + { + perror ("clock_gettime"); + return; + } + + ctime = (ts2.tv_sec - ts1.tv_sec) * 1000000000; + ctime += ts2.tv_nsec - ts1.tv_nsec; + ctimes[i] = ctime; + + if (clock_gettime (cid, &ts1) < 0) + { + perror("clock_gettime"); + return; + } + + r = ZSTD_decompress (uncompressed_buf, orig_bufsize, + compressed_buf, compressed_size); + + if (clock_gettime (cid, &ts2) < 0) + { + perror ("clock_gettime"); + return; + } + + if (ZSTD_isError (r)) + { + fprintf (stderr, + "zstd large: benchmark zlib uncompress failed: %s\n", + ZSTD_getErrorName (r)); + return; + } + + ztime = (ts2.tv_sec - ts1.tv_sec) * 1000000000; + ztime += ts2.tv_nsec - ts1.tv_nsec; + ztimes[i] = ztime; + } + + /* Toss the highest and lowest times and average the rest. */ + ctime = average_time (ctimes, trials); + ztime = average_time (ztimes, trials); + + printf ("backtrace: %zu ns\n", ctime); + printf ("zstd : %zu ns\n", ztime); + printf ("ratio : %g\n", (double) ztime / (double) ctime); + + return; + + fail: + printf ("FAIL: zstd large\n"); + ++failures; + + if (orig_buf != NULL) + free (orig_buf); + if (compressed_buf != NULL) + free (compressed_buf); + if (uncompressed_buf != NULL) + free (uncompressed_buf); + +#else /* !HAVE_ZSTD */ + + printf ("UNSUPPORTED: zstd large\n"); + +#endif /* !HAVE_ZSTD */ +} + +int +main (int argc ATTRIBUTE_UNUSED, char **argv) +{ + struct backtrace_state *state; + + state = backtrace_create_state (argv[0], BACKTRACE_SUPPORTS_THREADS, + error_callback_create, NULL); + + test_samples (state); + test_large (state); + + exit (failures != 0 ? EXIT_FAILURE : EXIT_SUCCESS); +} diff --git a/libbacktrace/ztest.c b/libbacktrace/ztest.c index 4e79c09..02b83ac 100644 --- a/libbacktrace/ztest.c +++ b/libbacktrace/ztest.c @@ -1,5 +1,5 @@ /* ztest.c -- Test for libbacktrace inflate code. - Copyright (C) 2017-2021 Free Software Foundation, Inc. + Copyright (C) 2017-2024 Free Software Foundation, Inc. Written by Ian Lance Taylor, Google. Redistribution and use in source and binary forms, with or without |