From patchwork Mon Mar 11 17:21:07 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sam James X-Patchwork-Id: 87050 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id EAD05385828B for ; Mon, 11 Mar 2024 17:22:32 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from smtp.gentoo.org (mail.gentoo.org [IPv6:2001:470:ea4a:1:5054:ff:fec7:86e4]) by sourceware.org (Postfix) with ESMTP id 9BC21385841E; Mon, 11 Mar 2024 17:21:26 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 9BC21385841E Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gentoo.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gentoo.org ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 9BC21385841E Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2001:470:ea4a:1:5054:ff:fec7:86e4 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1710177694; cv=none; b=G6Y2Dn5J3T7Kqv6zqu/NZgg0WO5P4NiIWUanRFrcl8ZFh+wSFyBAe4o+KP/RgHc9KDDP6wRqLog4D9LzLDPxtxKpcnLZqXK9j82vtlHpeg3I8r3GcKE39ewVDjMj8cG6rr2i1/X1VB+gtTeeqyrCMTxCcvK+/dL6/Ft8ls7wv3s= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1710177694; c=relaxed/simple; bh=zy9bn2/ZNiaJ1UoVMO0Rt04K1RoBGZzx/pitMDYJixI=; h=From:To:Subject:Date:Message-ID:MIME-Version; b=wFSlb7dlSVcJsAcrbsRzj2mfWOHtsS5pELuzoUc/mx8++oozpa8ueDi70JpV7kLxqe1QC2YPCdqXGcoYU7/fRE4ymkYHr6mv6W49Xh6IaA7RJq37065CrUO5CYGJtJw3gu3JZMYyo6MpXt3HLqz145uBRRdN2snfgCBx3vjsujY= ARC-Authentication-Results: i=1; server2.sourceware.org From: Sam James To: gdb-patches@sourceware.org Cc: binutils@sourceware.org, Sam James Subject: [PATCH] Sync libbacktrace from gcc [PR31327] Date: Mon, 11 Mar 2024 17:21:07 +0000 Message-ID: <20240311172112.2435201-1-sam@gentoo.org> X-Mailer: git-send-email 2.44.0 MIME-Version: 1.0 X-Spam-Status: No, score=-10.5 required=5.0 tests=BAYES_00, GIT_PATCH_0, JMQ_SPF_NEUTRAL, KAM_DMARC_STATUS, RCVD_IN_DNSWL_LOW, SPF_HELO_PASS, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Note that this includes Nick's fix from edf64cd235f5ecb3725e7cf1ff83bbdb6dd53340 which landed upstream a bit differently as r13-1566-g9ed57796235abc in GCC. This pulls in libbacktrace as of r14-9404-gc775a030af9cad in GCC trunk. --- libbacktrace/ChangeLog | 279 +- libbacktrace/Makefile.am | 124 +- libbacktrace/Makefile.in | 379 ++- libbacktrace/README | 32 +- libbacktrace/alloc.c | 2 +- libbacktrace/allocfail.c | 2 +- libbacktrace/allocfail.sh | 2 +- libbacktrace/atomic.c | 2 +- libbacktrace/backtrace-supported.h.in | 2 +- libbacktrace/backtrace.c | 2 +- libbacktrace/backtrace.h | 2 +- libbacktrace/btest.c | 2 +- libbacktrace/config.h.in | 13 + libbacktrace/configure | 276 +- libbacktrace/configure.ac | 57 +- libbacktrace/dwarf.c | 124 +- libbacktrace/edtest.c | 2 +- libbacktrace/edtest2.c | 2 +- libbacktrace/elf.c | 2997 +++++++++++++++-- libbacktrace/fileline.c | 77 +- .../install-debuginfo-for-buildid.sh.in | 2 +- libbacktrace/instrumented_alloc.c | 2 +- libbacktrace/internal.h | 11 +- libbacktrace/macho.c | 4 +- libbacktrace/mmap.c | 2 +- libbacktrace/mmapio.c | 2 +- libbacktrace/mtest.c | 2 +- libbacktrace/nounwind.c | 2 +- libbacktrace/pecoff.c | 26 +- libbacktrace/posix.c | 2 +- libbacktrace/print.c | 2 +- libbacktrace/read.c | 2 +- libbacktrace/simple.c | 2 +- libbacktrace/sort.c | 2 +- libbacktrace/state.c | 2 +- libbacktrace/stest.c | 2 +- libbacktrace/test_format.c | 2 +- libbacktrace/testlib.c | 2 +- libbacktrace/testlib.h | 2 +- libbacktrace/ttest.c | 2 +- libbacktrace/unittest.c | 2 +- libbacktrace/unknown.c | 2 +- libbacktrace/xcoff.c | 2 +- libbacktrace/xztest.c | 2 +- libbacktrace/ztest.c | 2 +- 45 files changed, 3976 insertions(+), 487 deletions(-) diff --git a/libbacktrace/ChangeLog b/libbacktrace/ChangeLog index 14df45e7072..5f131146882 100644 --- a/libbacktrace/ChangeLog +++ b/libbacktrace/ChangeLog @@ -1,7 +1,278 @@ -2023-01-12 Nick Clifton +2024-03-08 Ian Lance Taylor - * 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 + + * Makefile.am (libbacktrace_testing_ldflags): Define. + (*_LDFLAGS): Add $(libbacktrace_testing_ldflags) for test + programs. + * Makefile.in: Regenerate + +2024-03-02 Ian Lance Taylor + + * elf.c (elf_uncompress_lzma_block): Skip all header padding bytes + and verify that they are zero. + +2024-03-02 Ian Lance Taylor + + 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 + + * 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 + + * pecoff.c: Include if available. + (coff_add): On Windows call GetModuleHandle to get base address. + +2023-11-29 Ian Lance Taylor + + * fileline.c: Include 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 + + * configure: Regenerate. + * configure.ac: Handle Darwin rpaths. + +2023-08-07 Nick Alcock + + * configure: Regenerate. + +2023-08-07 Alexander von Gluck IV + + * configure: Regenerate. + +2023-08-07 Nick Alcock + + * configure: Regenerate. + +2023-08-07 Nick Alcock + + * configure: Regenerate. + +2023-08-07 H.J. Lu + + * configure: Regenerate. + +2023-08-07 H.J. Lu + + * configure: Regenerate. + +2023-08-03 Richard Biener + + * zstdtest.c (test_samples): Properly compute the allocation + size for the uncompressed data. + +2023-07-31 Ian Lance Taylor + + * 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 + + * 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 + + * 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 + + * Makefile.in: Regenerate. + +2023-01-06 Ian Lance Taylor + + 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 + + * 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 + + * 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 + + * 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 + + * configure: Regenerate. + +2022-10-11 Olivier Hainque + Olivier Hainque + + * configure: Regenerate. + +2022-07-08 Ian Lance Taylor + + * 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 + + * 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 + + * 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 + + * configure.ac: Use grep instead of fgrep. + * configure, Makefile.in: Regenerate. + +2022-05-28 Ian Lance Taylor + + PR libbacktrace/105721 + * README: Update. + +2022-04-05 Ian Lance Taylor + + * elf.c (elf_zlib_inflate): Don't skip initial aligned byte in + uncompressed block. + +2022-02-17 Ian Lance Taylor + + * dwarf.c (find_address_ranges): Handle skeleton units. + (read_function_entry): Likewise. + +2022-02-16 Ian Lance Taylor + + * dwarf.c (build_address_map): Initialize DWARF 5 fields of unit. + +2022-02-03 David Seifert + Jakub Jelinek + + * configure.ac: Support --disable-werror. + * configure: Regenerate. + +2021-12-28 Francois-Xavier Coudert + + PR libbacktrace/103822 + * Makefile.am: Fix newline. + * Makefile.in: Regenerate. 2021-11-12 Martin Liska @@ -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 e4f34b5fbd7..5677ecd8865 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 0a61880ba67..49852a21d37 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 e8b225745c9..6225f92b855 100644 --- a/libbacktrace/README +++ b/libbacktrace/README @@ -1,23 +1,31 @@ The libbacktrace library -Initially written by Ian Lance Taylor +Initially written by Ian Lance Taylor 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 ff2c8677c06..193e770526b 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 bd0fbb658a9..fb92821f3f0 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 1f9894fd2e8..06326765b39 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 fcac485b237..21785a19e87 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 2035c853a62..d9f3030f55d 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 7b629008525..3e6b81e9a3f 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 caaa66d3686..b73e27e06cd 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 7ef6d320497..d9fc372d33d 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 cdb416e6406..ee2616335c7 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 header file. */ #undef HAVE_DLFCN_H @@ -85,6 +89,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYS_LDR_H +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_LINK_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_MMAN_H @@ -97,9 +104,15 @@ /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H +/* Define to 1 if you have the 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 e5ca8ad9379..7ade966b54d 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 @@ -675,6 +681,8 @@ PIC_FLAG WARN_FLAGS EXTRA_FLAGS BACKTRACE_FILE +ENABLE_DARWIN_AT_RPATH_FALSE +ENABLE_DARWIN_AT_RPATH_TRUE OTOOL64 OTOOL LIPO @@ -799,8 +807,10 @@ with_pic enable_fast_install with_gnu_ld enable_libtool_lock +enable_darwin_at_rpath enable_largefile enable_cet +enable_werror with_system_libunwind enable_host_shared ' @@ -1446,8 +1456,12 @@ Optional Features: --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) + --enable-darwin-at-rpath + install libraries with @rpath/library-name, requires + rpaths to be added to executables --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] @@ -8040,7 +8054,7 @@ $as_echo "$lt_cv_ld_force_load" >&6; } # darwin 5.x (macOS 10.1) onwards we only need to adjust when the # deployment target is forced to an earlier version. case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host in - UNSET,*-darwin[89]*|UNSET,*-darwin[12][0123456789]*) + UNSET,*-darwin[89]*|UNSET,*-darwin[12][0-9]*) ;; 10.[012][,.]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' @@ -9746,6 +9760,49 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi darwin* | rhapsody*) + + # Publish an arg to allow the user to select that Darwin host (and target) + # libraries should be given install-names like @rpath/libfoo.dylib. This + # requires that the user of the library then adds an 'rpath' to the DSO that + # needs access. + # NOTE: there are defaults below, for systems that support rpaths. The person + # configuring can override the defaults for any system version that supports + # them - they are, however, forced off for system versions without support. + # Check whether --enable-darwin-at-rpath was given. +if test "${enable_darwin_at_rpath+set}" = set; then : + enableval=$enable_darwin_at_rpath; if test "x$enable_darwin_at_rpath" = "xyes"; then + # This is not supported before macOS 10.5 / Darwin9. + case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in + UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&5 +$as_echo "$as_me: WARNING: Darwin @rpath library names are incompatible with OSX versions earlier than 10.5 (rpaths disabled)" >&2;} + enable_darwin_at_rpath=no + ;; + esac + fi +else + case ${MACOSX_DEPLOYMENT_TARGET-UNSET},$host_os in + # As above, before 10.5 / Darwin9 this does not work. + UNSET,darwin[4-8]*|UNSET,rhapsody*|10.[0-4][,.]*) + enable_darwin_at_rpath=no + ;; + + # We cannot build and test reliably on macOS 10.11+ (Darwin15+) without use + # of rpaths, since runpaths set via DYLD_LIBRARY_PATH are elided by key + # system executables (e.g. /bin/sh). Force rpaths on for these systems. + UNSET,darwin1[5-9]*|UNSET,darwin2*|10.1[1-9][,.]*|1[1-9].*[,.]* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&5 +$as_echo "$as_me: @rpath library names are needed on macOS versions later than 10.11 (rpaths have been enabled)" >&6;} + enable_darwin_at_rpath=yes + ;; + # NOTE: we are not (yet) doing anything for 10.5 .. 10.10, since they can + # work with either DYLD_LIBRARY_PATH or embedded rpaths. + + esac + +fi + + archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes @@ -9763,9 +9820,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all - archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + _lt_install_name='\$rpath/\$soname' + if test "x$enable_darwin_at_rpath" = "xyes"; then + _lt_install_name='@rpath/\$soname' + fi + archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dsymutil}" module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" - archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name ${_lt_install_name} \$verstring ${_lt_dar_export_syms}${_lt_dsymutil}" module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" else @@ -11571,7 +11632,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 11635 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11677,7 +11738,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 11741 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11916,6 +11977,15 @@ CC="$lt_save_CC" + if test x$enable_darwin_at_rpath = xyes; then + ENABLE_DARWIN_AT_RPATH_TRUE= + ENABLE_DARWIN_AT_RPATH_FALSE='#' +else + ENABLE_DARWIN_AT_RPATH_TRUE='#' + ENABLE_DARWIN_AT_RPATH_FALSE= +fi + + # Check whether --enable-largefile was given. if test "${enable_largefile+set}" = set; then : enableval=$enable_largefile; @@ -12362,10 +12432,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 +13397,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 +#include <$link_h> _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | @@ -13430,6 +13509,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 +13598,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 +13870,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 +13946,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 +14119,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 @@ -14329,6 +14561,10 @@ if test -z "${HAVE_DWZ_TRUE}" && test -z "${HAVE_DWZ_FALSE}"; then as_fn_error $? "conditional \"HAVE_DWZ\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${ENABLE_DARWIN_AT_RPATH_TRUE}" && test -z "${ENABLE_DARWIN_AT_RPATH_FALSE}"; then + as_fn_error $? "conditional \"ENABLE_DARWIN_AT_RPATH\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${HAVE_ELF_TRUE}" && test -z "${HAVE_ELF_FALSE}"; then as_fn_error $? "conditional \"HAVE_ELF\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -14345,10 +14581,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 43a33a66b82..0f61f2b28ab 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 @@ -84,6 +84,8 @@ AM_CONDITIONAL(HAVE_DWZ, test "$DWZ" != "") LT_INIT AM_PROG_LIBTOOL +AM_CONDITIONAL([ENABLE_DARWIN_AT_RPATH], [test x$enable_darwin_at_rpath = xyes]) + AC_SYS_LARGEFILE backtrace_supported=yes @@ -145,10 +147,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 +337,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 +379,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 +411,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 +491,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 +513,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 +537,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 e6b1f238cd3..ed0672964c2 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 c5ced130c32..d99b8a60295 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 cffb4fdb6d9..29e93a7f76a 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 8b87b2dd6b9..3cd87020b03 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 #ifdef HAVE_DL_ITERATE_PHDR -#include + #ifdef HAVE_LINK_H + #include + #endif + #ifdef HAVE_SYS_LINK_H + #include + #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 -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,186 +2660,2583 @@ elf_zlib_inflate_and_verify (const unsigned char *pin, size_t sin, return 1; } -/* 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 - *UNCOMPRESSED / *UNCOMPRESSED_SIZE. ZDEBUG_TABLE is work space to - hold Huffman tables. Returns 0 on error, 1 on successful - decompression or if something goes wrong. In general we try to - carry on, by returning 1, even if we can't decompress. */ +/* 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 +*/ -static int -elf_uncompress_zdebug (struct backtrace_state *state, - const unsigned char *compressed, size_t compressed_size, - uint16_t *zdebug_table, - backtrace_error_callback error_callback, void *data, - unsigned char **uncompressed, size_t *uncompressed_size) -{ - size_t sz; - size_t i; - unsigned char *po; +#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)) - *uncompressed = NULL; - *uncompressed_size = 0; +#define ZSTD_TABLE_LITERAL_FSE_OFFSET (0) - /* The format starts with the four bytes ZLIB, followed by the 8 - byte length of the uncompressed data in big-endian order, - followed by a zlib stream. */ +#define ZSTD_TABLE_MATCH_FSE_OFFSET \ + (512 * sizeof (struct elf_zstd_fse_baseline_entry)) - if (compressed_size < 12 || memcmp (compressed, "ZLIB", 4) != 0) - return 1; +#define ZSTD_TABLE_OFFSET_FSE_OFFSET \ + (ZSTD_TABLE_MATCH_FSE_OFFSET \ + + 512 * sizeof (struct elf_zstd_fse_baseline_entry)) - sz = 0; - for (i = 0; i < 8; i++) - sz = (sz << 8) | compressed[i + 4]; +#define ZSTD_TABLE_HUFFMAN_OFFSET \ + (ZSTD_TABLE_OFFSET_FSE_OFFSET \ + + 256 * sizeof (struct elf_zstd_fse_baseline_entry)) - if (*uncompressed != NULL && *uncompressed_size >= sz) - po = *uncompressed; - else - { - po = (unsigned char *) backtrace_alloc (state, sz, error_callback, data); - if (po == NULL) - return 0; - } +#define ZSTD_TABLE_WORK_OFFSET \ + (ZSTD_TABLE_HUFFMAN_OFFSET + 2048 * sizeof (uint16_t)) - if (!elf_zlib_inflate_and_verify (compressed + 12, compressed_size - 12, - zdebug_table, po, sz)) - return 1; +/* An entry in a zstd FSE table. */ - *uncompressed = po; - *uncompressed_size = sz; +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; +}; - return 1; -} +static int +elf_zstd_build_fse (const int16_t *, int, uint16_t *, int, + struct elf_zstd_fse_entry *); -/* Uncompress the new compressed debug format, the official standard - ELF approach emitted by --compress-debug-sections=zlib-gabi. The - compressed data is in COMPRESSED / COMPRESSED_SIZE, and the - function writes to *UNCOMPRESSED / *UNCOMPRESSED_SIZE. - ZDEBUG_TABLE is work space as for elf_uncompress_zdebug. Returns 0 - on error, 1 on successful decompression or if something goes wrong. - In general we try to carry on, by returning 1, even if we can't - decompress. */ +/* 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_uncompress_chdr (struct backtrace_state *state, - const unsigned char *compressed, size_t compressed_size, - uint16_t *zdebug_table, - backtrace_error_callback error_callback, void *data, - unsigned char **uncompressed, size_t *uncompressed_size) +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 b_elf_chdr *chdr; - unsigned char *po; + 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; - *uncompressed = NULL; - *uncompressed_size = 0; + pin = *ppin; - /* The format starts with an ELF compression header. */ - if (compressed_size < sizeof (b_elf_chdr)) - return 1; + norm = (int16_t *) zdebug_table; + next = zdebug_table + 256; + + if (unlikely (pin + 3 >= pinend)) + { + elf_uncompress_failed (); + return 0; + } - chdr = (const b_elf_chdr *) compressed; + /* Align PIN to a 32-bit boundary. */ - if (chdr->ch_type != ELFCOMPRESS_ZLIB) + val = 0; + bits = 0; + while ((((uintptr_t) pin) & 3) != 0) { - /* Unsupported compression algorithm. */ - return 1; + val |= (uint64_t)*pin << bits; + bits += 8; + ++pin; } - if (*uncompressed != NULL && *uncompressed_size >= chdr->ch_size) - po = *uncompressed; - else + if (!elf_fetch_bits (&pin, pinend, &val, &bits)) + return 0; + + accuracy_log = (val & 0xf) + 5; + if (accuracy_log > *table_bits) { - po = (unsigned char *) backtrace_alloc (state, chdr->ch_size, - error_callback, data); - if (po == NULL) - return 0; + elf_uncompress_failed (); + return 0; } + *table_bits = accuracy_log; + val >>= 4; + bits -= 4; - 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; + /* This code is mostly copied from the reference implementation. */ - *uncompressed = po; - *uncompressed_size = chdr->ch_size; + /* 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; - return 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; -/* This function is a hook for testing the zlib support. It is only - used by tests. */ + /* The number of bits used to compute threshold. */ + bits_needed = accuracy_log + 1; -int -backtrace_uncompress_zdebug (struct backtrace_state *state, - const unsigned char *compressed, - size_t compressed_size, - backtrace_error_callback error_callback, - void *data, unsigned char **uncompressed, - size_t *uncompressed_size) -{ - uint16_t *zdebug_table; - int ret; + /* The next character value. */ + idx = 0; - zdebug_table = ((uint16_t *) backtrace_alloc (state, ZDEBUG_TABLE_SIZE, - error_callback, data)); - if (zdebug_table == NULL) - return 0; - ret = elf_uncompress_zdebug (state, compressed, compressed_size, - zdebug_table, error_callback, data, - uncompressed, uncompressed_size); - backtrace_free (state, zdebug_table, ZDEBUG_TABLE_SIZE, - error_callback, data); - return ret; -} + /* Whether the last count was 0. */ + prev0 = 0; -/* Number of LZMA states. */ -#define LZMA_STATES (12) + while (remaining > 1 && idx <= maxidx) + { + uint32_t max; + int32_t count; -/* Number of LZMA position states. The pb value of the property byte - is the number of bits to include in these states, and the maximum - value of pb is 4. */ -#define LZMA_POS_STATES (16) + if (!elf_fetch_bits (&pin, pinend, &val, &bits)) + return 0; -/* Number of LZMA distance states. These are used match distances - with a short match length: up to 4 bytes. */ -#define LZMA_DIST_STATES (4) + if (prev0) + { + int zidx; -/* Number of LZMA distance slots. LZMA uses six bits to encode larger - match lengths, so 1 << 6 possible probabilities. */ -#define LZMA_DIST_SLOTS (64) + /* 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; -/* LZMA distances 0 to 3 are encoded directly, larger values use a - probability model. */ -#define LZMA_DIST_MODEL_START (4) + if (unlikely (zidx > maxidx)) + { + elf_uncompress_failed (); + return 0; + } -/* The LZMA probability model ends at 14. */ -#define LZMA_DIST_MODEL_END (14) + for (; idx < zidx; idx++) + norm[idx] = 0; -/* LZMA distance slots for distances less than 127. */ -#define LZMA_FULL_DISTANCES (128) + prev0 = 0; + continue; + } -/* LZMA uses four alignment bits. */ -#define LZMA_ALIGN_SIZE (16) + 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; + } -/* LZMA match length is encoded with 4, 5, or 10 bits, some of which - are already known. */ -#define LZMA_LEN_LOW_SYMBOLS (8) -#define LZMA_LEN_MID_SYMBOLS (8) -#define LZMA_LEN_HIGH_SYMBOLS (256) + count--; + if (count >= 0) + remaining -= count; + else + remaining--; + if (unlikely (idx >= 256)) + { + elf_uncompress_failed (); + return 0; + } + norm[idx] = (int16_t) count; + ++idx; -/* LZMA literal encoding. */ -#define LZMA_LITERAL_CODERS_MAX (16) -#define LZMA_LITERAL_CODER_SIZE (0x300) + prev0 = count == 0; -/* LZMA is based on a large set of probabilities, each managed - independently. Each probability is an 11 bit number that we store - in a uint16_t. We use a single large array of probabilities. */ + while (remaining < threshold) + { + bits_needed--; + threshold >>= 1; + } + } -/* Lengths of entries in the LZMA probabilities array. The names used - here are copied from the Linux kernel implementation. */ + if (unlikely (remaining != 1)) + { + elf_uncompress_failed (); + return 0; + } -#define LZMA_PROB_IS_MATCH_LEN (LZMA_STATES * LZMA_POS_STATES) + /* 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 + +/* 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 + *UNCOMPRESSED / *UNCOMPRESSED_SIZE. ZDEBUG_TABLE is work space to + hold Huffman tables. Returns 0 on error, 1 on successful + decompression or if something goes wrong. In general we try to + carry on, by returning 1, even if we can't decompress. */ + +static int +elf_uncompress_zdebug (struct backtrace_state *state, + const unsigned char *compressed, size_t compressed_size, + uint16_t *zdebug_table, + backtrace_error_callback error_callback, void *data, + unsigned char **uncompressed, size_t *uncompressed_size) +{ + size_t sz; + size_t i; + unsigned char *po; + + *uncompressed = NULL; + *uncompressed_size = 0; + + /* The format starts with the four bytes ZLIB, followed by the 8 + byte length of the uncompressed data in big-endian order, + followed by a zlib stream. */ + + if (compressed_size < 12 || memcmp (compressed, "ZLIB", 4) != 0) + return 1; + + sz = 0; + for (i = 0; i < 8; i++) + sz = (sz << 8) | compressed[i + 4]; + + if (*uncompressed != NULL && *uncompressed_size >= sz) + po = *uncompressed; + else + { + po = (unsigned char *) backtrace_alloc (state, sz, error_callback, data); + if (po == NULL) + return 0; + } + + if (!elf_zlib_inflate_and_verify (compressed + 12, compressed_size - 12, + zdebug_table, po, sz)) + return 1; + + *uncompressed = po; + *uncompressed_size = sz; + + return 1; +} + +/* Uncompress the new compressed debug format, the official standard + ELF approach emitted by --compress-debug-sections=zlib-gabi. The + compressed data is in COMPRESSED / COMPRESSED_SIZE, and the + function writes to *UNCOMPRESSED / *UNCOMPRESSED_SIZE. + ZDEBUG_TABLE is work space as for elf_uncompress_zdebug. Returns 0 + on error, 1 on successful decompression or if something goes wrong. + In general we try to carry on, by returning 1, even if we can't + decompress. */ + +static int +elf_uncompress_chdr (struct backtrace_state *state, + const unsigned char *compressed, size_t compressed_size, + uint16_t *zdebug_table, + backtrace_error_callback error_callback, void *data, + unsigned char **uncompressed, size_t *uncompressed_size) +{ + b_elf_chdr chdr; + char *alc; + size_t alc_len; + unsigned char *po; + + *uncompressed = NULL; + *uncompressed_size = 0; + + /* The format starts with an ELF compression header. */ + if (compressed_size < sizeof (b_elf_chdr)) + return 1; + + /* 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)); + + alc = NULL; + alc_len = 0; + if (*uncompressed != NULL && *uncompressed_size >= chdr.ch_size) + po = *uncompressed; + else + { + alc_len = chdr.ch_size; + alc = backtrace_alloc (state, alc_len, error_callback, data); + if (alc == NULL) + return 0; + po = (unsigned char *) alc; + } + + 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; + + 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 + used by tests. */ + +int +backtrace_uncompress_zdebug (struct backtrace_state *state, + const unsigned char *compressed, + size_t compressed_size, + backtrace_error_callback error_callback, + void *data, unsigned char **uncompressed, + size_t *uncompressed_size) +{ + uint16_t *zdebug_table; + int ret; + + zdebug_table = ((uint16_t *) backtrace_alloc (state, ZDEBUG_TABLE_SIZE, + error_callback, data)); + if (zdebug_table == NULL) + return 0; + ret = elf_uncompress_zdebug (state, compressed, compressed_size, + zdebug_table, error_callback, data, + uncompressed, uncompressed_size); + backtrace_free (state, zdebug_table, ZDEBUG_TABLE_SIZE, + error_callback, data); + 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) + +/* Number of LZMA position states. The pb value of the property byte + is the number of bits to include in these states, and the maximum + value of pb is 4. */ +#define LZMA_POS_STATES (16) + +/* Number of LZMA distance states. These are used match distances + with a short match length: up to 4 bytes. */ +#define LZMA_DIST_STATES (4) + +/* Number of LZMA distance slots. LZMA uses six bits to encode larger + match lengths, so 1 << 6 possible probabilities. */ +#define LZMA_DIST_SLOTS (64) + +/* LZMA distances 0 to 3 are encoded directly, larger values use a + probability model. */ +#define LZMA_DIST_MODEL_START (4) + +/* The LZMA probability model ends at 14. */ +#define LZMA_DIST_MODEL_END (14) + +/* LZMA distance slots for distances less than 127. */ +#define LZMA_FULL_DISTANCES (128) + +/* LZMA uses four alignment bits. */ +#define LZMA_ALIGN_SIZE (16) + +/* LZMA match length is encoded with 4, 5, or 10 bits, some of which + are already known. */ +#define LZMA_LEN_LOW_SYMBOLS (8) +#define LZMA_LEN_MID_SYMBOLS (8) +#define LZMA_LEN_HIGH_SYMBOLS (256) + +/* LZMA literal encoding. */ +#define LZMA_LITERAL_CODERS_MAX (16) +#define LZMA_LITERAL_CODER_SIZE (0x300) + +/* LZMA is based on a large set of probabilities, each managed + independently. Each probability is an 11 bit number that we store + in a uint16_t. We use a single large array of probabilities. */ + +/* Lengths of entries in the LZMA probabilities array. The names used + here are copied from the Linux kernel implementation. */ + +#define LZMA_PROB_IS_MATCH_LEN (LZMA_STATES * LZMA_POS_STATES) #define LZMA_PROB_IS_REP_LEN LZMA_STATES #define LZMA_PROB_IS_REP0_LEN LZMA_STATES #define LZMA_PROB_IS_REP1_LEN LZMA_STATES @@ -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 0472f4721ab..68e80c6d274 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 #endif +#ifdef HAVE_WINDOWS_H +#ifndef WIN32_MEAN_AND_LEAN +#define WIN32_MEAN_AND_LEAN +#endif + +#ifndef NOMINMAX +#define NOMINMAX +#endif + +#include +#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 91dfdfe89a4..0b83a366023 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 13af81a6dcb..4a520bf8770 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 bb481f373bf..4fa0af8cb6c 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 66e101e0a4b..b4856346ccc 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 d7313be73f7..322ed945669 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 7f6fa8d2748..b780c3d07df 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 7e0189a2899..9afe7089514 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 0eea7139b69..ba1b06b6241 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 720251900b4..9e437d810c7 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 +#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 924631d2e61..79f4950f84b 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 93d0d3abb49..3e61f02ebbc 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 1811c8d2e08..7af66602fd9 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 785e726e6be..fd3fac688fa 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 a60a980e65e..fedfe21cbdf 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 0f368a23907..b564a18b548 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 19a204de195..f695596aa29 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 9deb6f5b2a7..10bd24b9fc5 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 3d24c19e702..a73984fb3e9 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 29542a5886d..f4759543d61 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 3758b33f025..5401a2a9207 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 3c85623048a..2fd1c9b0fca 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 a62cbf11eb3..23e4cc95990 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 2ded8f0024f..e22f15dd5ce 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 6c60ff50159..5b3b811c38e 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/ztest.c b/libbacktrace/ztest.c index 4e79c09517d..02b83acb5b8 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