Sync libbacktrace from gcc [PR31327]

Message ID 20240311172112.2435201-1-sam@gentoo.org
State New
Headers
Series Sync libbacktrace from gcc [PR31327] |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gdb_build--master-aarch64 success Testing passed
linaro-tcwg-bot/tcwg_gdb_build--master-arm success Testing passed
linaro-tcwg-bot/tcwg_gdb_check--master-arm success Testing passed
linaro-tcwg-bot/tcwg_gdb_check--master-aarch64 success Testing passed

Commit Message

Sam James March 11, 2024, 5:21 p.m. UTC
  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(-)
  

Comments

Simon Marchi March 11, 2024, 5:31 p.m. UTC | #1
On 3/11/24 13:21, Sam James wrote:
> 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.

Doing a diff between binutils-gdb/libbacktrace and gcc/libbacktrace, I
see:

    $ diff -u libbacktrace ~/src/gcc/libbacktrace
    Only in /home/smarchi/src/gcc/libbacktrace: zstdtest.c

Should that file be added in binutils-gdb/libbacktrace?

Simon
  
Tom Tromey March 11, 2024, 5:38 p.m. UTC | #2
>>>>> "Sam" == Sam James <sam@gentoo.org> writes:

Sam> Note that this includes Nick's fix from edf64cd235f5ecb3725e7cf1ff83bbdb6dd53340 which
Sam> landed upstream a bit differently as r13-1566-g9ed57796235abc in GCC.

Sam> This pulls in libbacktrace as of r14-9404-gc775a030af9cad in GCC trunk.

Thank you.  If this makes it identical to gcc then I think it's fine.
If not perhaps posting the diff would be helpful.

Approved-By: Tom Tromey <tom@tromey.com>

Tom
  
Sam James March 11, 2024, 5:43 p.m. UTC | #3
Simon Marchi <simark@simark.ca> writes:

> On 3/11/24 13:21, Sam James wrote:
>> 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.
>
> Doing a diff between binutils-gdb/libbacktrace and gcc/libbacktrace, I
> see:
>
>     $ diff -u libbacktrace ~/src/gcc/libbacktrace
>     Only in /home/smarchi/src/gcc/libbacktrace: zstdtest.c
>
> Should that file be added in binutils-gdb/libbacktrace?

Absolutely, just failed at git add.

>
> Simon

best,
sam
  
Sam James March 11, 2024, 11:12 p.m. UTC | #4
Tom Tromey <tom@tromey.com> writes:

>>>>>> "Sam" == Sam James <sam@gentoo.org> writes:
>
> Sam> Note that this includes Nick's fix from edf64cd235f5ecb3725e7cf1ff83bbdb6dd53340 which
> Sam> landed upstream a bit differently as r13-1566-g9ed57796235abc in GCC.
>
> Sam> This pulls in libbacktrace as of r14-9404-gc775a030af9cad in GCC trunk.
>
> Thank you.  If this makes it identical to gcc then I think it's fine.
> If not perhaps posting the diff would be helpful.

Thanks. I've pushed it with a tiny diff compared to gcc after discussing
it on IRC (Simon pointed out the difference):

--- a/libbacktrace/configure.ac.gcc
+++ b/libbacktrace/configure.ac.binutils
@@ -84,8 +84,6 @@ 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

.. with the corresponding regen. It's described in the commit message --
it's from a top-level Darwin change which would need other syncing that
is best done separately.

>
> Approved-By: Tom Tromey <tom@tromey.com>
>
> Tom

best,
sam
  

Patch

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  <nickc@redhat.com>
+2024-03-08  Ian Lance Taylor  <iant@golang.org>
 
-	* Makefile.am (CLEANFILES): Import patch from upstream to prevent
-	allocafail.sh from being removed when running 'make clean'.
+	* elf.c (elf_uncompress_chdr): Don't assume compressed section is
+	aligned.
+
+2024-03-02  Ian Lance Taylor  <iant@golang.org>
+
+	* Makefile.am (libbacktrace_testing_ldflags): Define.
+	(*_LDFLAGS): Add $(libbacktrace_testing_ldflags) for test
+	programs.
+	* Makefile.in: Regenerate
+
+2024-03-02  Ian Lance Taylor  <iant@golang.org>
+
+	* elf.c (elf_uncompress_lzma_block): Skip all header padding bytes
+	and verify that they are zero.
+
+2024-03-02  Ian Lance Taylor  <iant@golang.org>
+
+	PR libbacktrace/114201
+	* elf.c (elf_add): Add caller_opd parameter.  Change all callers.
+	Release opd data after all recursive calls.
+
+2024-03-01  Ian Lance Taylor  <iant@golang.org>
+
+	* elf.c (elf_add): Add the symbol table from a debuginfo file.
+	* Makefile.am (MAKETESTS): Add buildidfull and gnudebuglinkfull
+	variants of buildid and gnudebuglink tests.
+	(%_gnudebuglinkfull, %_buildidfull): New patterns.
+	* Makefile.in: Regenerate.
+
+2023-11-30  Ian Lance Taylor  <iant@golang.org>
+
+	* pecoff.c: Include <windows.h> if available.
+	(coff_add): On Windows call GetModuleHandle to get base address.
+
+2023-11-29  Ian Lance Taylor  <iant@golang.org>
+
+	* fileline.c: Include <windows.h> if available.
+	(windows_get_executable_path): New static function.
+	(fileline_initialize): Call windows_get_executable_path.
+	* configure.ac: Checked for windows.h
+	* configure: Regenerate.
+	* config.h.in: Regenerate.
+
+2023-10-22  Iain Sandoe  <iain@sandoe.co.uk>
+
+	* configure: Regenerate.
+	* configure.ac: Handle Darwin rpaths.
+
+2023-08-07  Nick Alcock  <nick.alcock@oracle.com>
+
+	* configure: Regenerate.
+
+2023-08-07  Alexander von Gluck IV  <kallisti5@unixzen.com>
+
+	* configure: Regenerate.
+
+2023-08-07  Nick Alcock  <nick.alcock@oracle.com>
+
+	* configure: Regenerate.
+
+2023-08-07  Nick Alcock  <nick.alcock@oracle.com>
+
+	* configure: Regenerate.
+
+2023-08-07  H.J. Lu  <hjl.tools@gmail.com>
+
+	* configure: Regenerate.
+
+2023-08-07  H.J. Lu  <hjl.tools@gmail.com>
+
+	* configure: Regenerate.
+
+2023-08-03  Richard Biener  <rguenther@suse.de>
+
+	* zstdtest.c (test_samples): Properly compute the allocation
+	size for the uncompressed data.
+
+2023-07-31  Ian Lance Taylor  <iant@golang.org>
+
+	* configure.ac: Check for _pgmptr declaration.
+	* fileline.c (fileline_initialize): Check for _pgmfptr before
+	/proc/self/exec.
+	* configure, config.h.in: Regenerate.
+
+2023-03-28  Ian Lance Taylor  <iant@golang.org>
+
+	* elf.c (elf_zstd_read_fse): Call elf_fetch_bits after reading
+	bits, not before.  Add unlikely for error case.
+	(elf_zstd_offset_table): Regenerate.
+	(elf_zstd_read_huff): Clear 13 entries in weight_mark, not 12.
+	(elf_zstd_read_literals): For a single stream adjust by
+	total_streams_size, not compressed_size.
+
+2023-01-20  Ian Lance Taylor  <iant@golang.org>
+
+	* dwarf.c (struct function_addrs): Change low and high fields to
+	uintptr_t.
+	(struct unit_addrs): Likewise.
+	(resolve_addr_index): Change address parameter to uintptr_t*.
+	(add_unit_addr): Change lowpc and highpc parameters to uintptr_t.
+	(add_function_range): Likewise.
+	(struct pcrange): Change lowpc and highpc fields to uintptr_t.
+	(add_low_high_range): Change add_range lowpc and highpc parameters
+	to uintptr_t.
+	(add_ranges_from_ranges): Likewise.
+	(add_ranges_from_rnglists): Likewise.
+	(add_low_high_range): Chnage lowpc and highpc variables to
+	uintpr_t.
+	(add_ranges_from_rnglists): Change some local variables to
+	uintptr_t.
+	(add_ranges_from_ranges): Change base parameter to uintptr_t.
+	(add_ranges_from_rnglists): Likewise.
+	(read_function_entry): Likewise.
+	(resolve_addr_index): Add explicit casts to uintptr_t.
+	(update_pcrange): Likewise.
+	(add_ranges_from_ranges): Likewise.
+	(add_ranges_from_rnglists): Likewise.
+	(read_function_entry): Likewise.
+
+2023-01-17  Martin Liska  <mliska@suse.cz>
+
+	* Makefile.in: Regenerate.
+
+2023-01-06  Ian Lance Taylor  <iant@golang.org>
+
+	PR libbacktrace/108297
+	* configure.ac: Test whether linker supports --build-id.
+	* Makefile.am: Only run --build-id tests if supported.
+	* configure, Makefile.in: Regenerate.
+
+2022-12-17  Ian Lance Taylor  <iant@golang.org>
+
+	* elf.c (elf_fetch_backward_init): New static function.
+	(ZSTD_TABLE_SIZE): Use huffman scratch space size rather than
+	literal size.
+	(ZSTD_TABLE_WORK_LIT_SIZE): Don't define.
+	(elf_zstd_read_huff): Use elf_fetch_backward_init.
+	(elf_zstd_read_literals): New static function.
+	(ZSTD_LIT_RAW, ZSTD_LIT_RLE, ZSTD_LIT_HUFF): Don't define.
+	(struct elf_zstd_literals): Don't define.
+	(elf_zstd_literal_output): Remove static function.
+	(elf_zstd_decompress): Use elf_fetch_backward_init and
+	elf_zstd_read_literals.  Rewrite literal copying.<
+
+2022-12-10  Ian Lance Taylor  <iant@golang.org>
+
+	* elf.c (ZSTD_TABLE_*): Use elf_zstd_fse_baseline_entry.
+	(ZSTD_ENCODE_BASELINE_BITS): Define.
+	(ZSTD_DECODE_BASELINE, ZSTD_DECODE_BASEBITS): Define.
+	(elf_zstd_literal_length_base): New static const array.
+	(elf_zstd_match_length_base): Likewise.
+	(struct elf_zstd_fse_baseline_entry): Define.
+	(elf_zstd_make_literal_baseline_fse): New static function.
+	(elf_zstd_make_offset_baseline_fse): Likewise.
+	(elf_zstd_make_match_baseline_fse): Likewise.
+	(print_table, main): Use elf_zstd_fse_baseline_entry.
+	(elf_zstd_lit_table, elf_zstd_match_table): Likewise.
+	(elf_zstd_offset_table): Likewise.
+	(struct elf_zstd_seq_decode): Likewise.  Remove use_rle and rle
+	fields.
+	(elf_zstd_unpack_seq_decode): Use elf_zstd_fse_baseline_entry,
+	taking a conversion function.  Convert RLE to FSE.
+	(elf_zstd_literal_length_baseline): Remove.
+	(elf_zstd_literal_length_bits): Remove.
+	(elf_zstd_match_length_baseline): Remove.
+	(elf_zstd_match_length_bits): Remove.
+	(elf_zstd_decompress): Use elf_zstd_fse_baseline_entry.  Rewrite
+	and simplify main loop.
+
+2022-12-08  Ian Lance Taylor  <iant@golang.org>
+
+	* configure.ac: Check for zstd library and
+	--compress-debug-sections=zstd linker option.
+	* Makefile.am (zstdtest_*): New targets.
+	(zstdtest_alloc_*, ctestzstd_*): New targets.
+	(BUILDTESTS): Add zstdtest, zstdtest_alloc, ctestzstd as
+	appropriate.
+	* elf.c (ELFCOMPRESS_ZSTD): Define.
+	(elf_fetch_bits): Rename from elf_zlib_fetch.  Update uses.
+	(elf_fetch_bits_backward): New static function.
+	(ZLIB_HUFFMAN_*): Rename from HUFFMAN_*.  Update uses.
+	(ZLIB_TABLE_*): Rename from ZDEBUG_TABLE_*.  Update uses.
+	(ZSTD_TABLE_*): Define.
+	(struct elf_zstd_fse_entry): Define.
+	(elf_zstd_read_fse): New static function.
+	(elf_zstd_build_fse): Likewise.
+	(lit): Define if BACKTRACE_GENERATE_ZSTD_FSE_TABLES.
+	(match, offset, next, print_table, main): Likewise.
+	(elf_zstd_lit_table): New static const array.
+	(elf_zstd_match_table, elf_zstd_offset_table): Likewise.
+	(elf_zstd_read_huff): New static function.
+	(struct elf_zstd_seq_decode): Define.
+	(elf_zstd_unpack_seq_decode): New static function.
+	(ZSTD_LIT_*): Define.
+	(struct elf_zstd_literals): Define.
+	(elf_zstd_literal_output): New static function.
+	(ZSTD_LITERAL_LENGTH_BASELINE_OFFSET): Define.
+	(elf_zstd_literal_length_baseline): New static const array.
+	(elf_zstd_literal_length_bits): Likewise.
+	(ZSTD_MATCH_LENGTH_BASELINE_OFFSET): Define.
+	(elf_zstd_match_length_baseline): New static const array.
+	(elf_zstd_match_length_bits): Likewise.
+	(elf_zstd_decompress): New static function.
+	(ZDEBUG_TABLE_SIZE): New definition.
+	(elf_uncompress_chdr): Support ELF_COMPRESS_ZSTD.
+	(backtrace_uncompress_zstd): New function.
+	(elf_add): Use ZLIB_TABLE_SIZE for zlib-gnu sections.
+	* internal.h (backtrace_uncompress_zstd): Declare.
+	* zstdtest.c: New file.
+	* configure, config.h.in, Makefile.in: Regenerate.
+
+2022-10-12  Martin Liska  <mliska@suse.cz>
+
+	* configure: Regenerate.
+
+2022-10-11  Olivier Hainque  <hainque@adacore.com>
+	    Olivier Hainque  <hainque@adacore.com>
+
+	* configure: Regenerate.
+
+2022-07-08  Ian Lance Taylor  <iant@golang.org>
+
+	* configure.ac: Check for sys/link.h.  Use either link.h or
+	sys/link.h when checking for dl_iterate_phdr.
+	* elf.c: Include sys/link.h if available.
+	* configure, config.h.in: Regenerate.
+
+2022-07-07  Ian Lance Taylor  <iant@golang.org>
+
+	* macho.c (backtrace_initialize) [HAVE_MACH_O_DYLD_H]: Don't exit
+	loop if we can't find debug info for one shared library.
+
+2022-07-07  Ian Lance Taylor  <iant@golang.org>
+
+	* Makefile.am (MAKETESTS): New variable split out of TESTS.
+	(CLEANFILES): Replace TESTS with BUILDTESTS and MAKETESTS.
+	* Makefile.in: Regenerate.
+
+2022-06-27  Ian Lance Taylor  <iant@golang.org>
+
+	* configure.ac: Use grep instead of fgrep.
+	* configure, Makefile.in: Regenerate.
+
+2022-05-28  Ian Lance Taylor  <iant@golang.org>
+
+	PR libbacktrace/105721
+	* README: Update.
+
+2022-04-05  Ian Lance Taylor  <iant@golang.org>
+
+	* elf.c (elf_zlib_inflate): Don't skip initial aligned byte in
+	uncompressed block.
+
+2022-02-17  Ian Lance Taylor  <iant@golang.org>
+
+	* dwarf.c (find_address_ranges): Handle skeleton units.
+	(read_function_entry): Likewise.
+
+2022-02-16  Ian Lance Taylor  <iant@golang.org>
+
+	* dwarf.c (build_address_map): Initialize DWARF 5 fields of unit.
+
+2022-02-03  David Seifert  <soap@gentoo.org>
+	    Jakub Jelinek  <jakub@redhat.com>
+
+	* configure.ac: Support --disable-werror.
+	* configure: Regenerate.
+
+2021-12-28  Francois-Xavier Coudert  <fxcoudert@gmail.com>
+
+	PR libbacktrace/103822
+	* Makefile.am: Fix newline.
+	* Makefile.in: Regenerate.
 
 2021-11-12  Martin Liska  <mliska@suse.cz>
 
@@ -1789,7 +2060,7 @@ 
 
 	* Initial implementation.
 
-Copyright (C) 2012-2021 Free Software Foundation, Inc.
+Copyright (C) 2012-2024 Free Software Foundation, Inc.
 
 Copying and distribution of this file, with or without modification,
 are permitted in any medium without royalty provided the copyright
diff --git a/libbacktrace/Makefile.am b/libbacktrace/Makefile.am
index 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 <iant@google.com>
+Initially written by Ian Lance Taylor <iant@golang.org>
 
 The libbacktrace library may be linked into a program or library and
-used to produce symbolic backtraces.  Sample uses would be to print a
-detailed backtrace when an error occurs or to gather detailed
-profiling information.
+used to produce symbolic backtraces.
+Sample uses would be to print a detailed backtrace when an error
+occurs or to gather detailed profiling information.
+In general the functions provided by this library are async-signal-safe,
+meaning that they may be safely called from a signal handler.
 
-The libbacktrace library is provided under a BSD license.  See the
-source files for the exact license text.
+The libbacktrace library is provided under a BSD license.
+See the source files for the exact license text.
 
 The public functions are declared and documented in the header file
 backtrace.h, which should be #include'd by a user of the library.
 
 Building libbacktrace will generate a file backtrace-supported.h,
 which a user of the library may use to determine whether backtraces
-will work.  See the source file backtrace-supported.h.in for the
-macros that it defines.
+will work.
+See the source file backtrace-supported.h.in for the macros that it
+defines.
 
-As of September 2012, libbacktrace only supports ELF executables with
-DWARF debugging information.  The library is written to make it
-straightforward to add support for other object file and debugging
-formats.
+As of October 2020, libbacktrace supports ELF, PE/COFF, Mach-O, and
+XCOFF executables with DWARF debugging information.
+In other words, it supports GNU/Linux, *BSD, macOS, Windows, and AIX.
+The library is written to make it straightforward to add support for
+other object file and debugging formats.
+
+The library relies on the C++ unwind API defined at
+https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html
+This API is provided by GCC and clang.
diff --git a/libbacktrace/alloc.c b/libbacktrace/alloc.c
index 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 <dlfcn.h> header file. */
 #undef HAVE_DLFCN_H
 
@@ -85,6 +89,9 @@ 
 /* Define to 1 if you have the <sys/ldr.h> header file. */
 #undef HAVE_SYS_LDR_H
 
+/* Define to 1 if you have the <sys/link.h> header file. */
+#undef HAVE_SYS_LINK_H
+
 /* Define to 1 if you have the <sys/mman.h> header file. */
 #undef HAVE_SYS_MMAN_H
 
@@ -97,9 +104,15 @@ 
 /* Define to 1 if you have the <unistd.h> header file. */
 #undef HAVE_UNISTD_H
 
+/* Define to 1 if you have the <windows.h> header file. */
+#undef HAVE_WINDOWS_H
+
 /* Define if -lz is available. */
 #undef HAVE_ZLIB
 
+/* Define if -lzstd is available. */
+#undef HAVE_ZSTD
+
 /* Define to the sub-directory in which libtool stores uninstalled libraries.
    */
 #undef LT_OBJDIR
diff --git a/libbacktrace/configure b/libbacktrace/configure
index 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 <link.h>
+#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 <unistd.h>
 
 #ifdef HAVE_DL_ITERATE_PHDR
-#include <link.h>
+ #ifdef HAVE_LINK_H
+  #include <link.h>
+ #endif
+ #ifdef HAVE_SYS_LINK_H
+  #include <sys/link.h>
+ #endif
 #endif
 
 #include "backtrace.h"
@@ -179,6 +184,7 @@  dl_iterate_phdr (int (*callback) (struct dl_phdr_info *,
 #undef STT_FUNC
 #undef NT_GNU_BUILD_ID
 #undef ELFCOMPRESS_ZLIB
+#undef ELFCOMPRESS_ZSTD
 
 /* Basic types.  */
 
@@ -336,6 +342,7 @@  typedef struct
 #endif /* BACKTRACE_ELF_SIZE != 32 */
 
 #define ELFCOMPRESS_ZLIB 1
+#define ELFCOMPRESS_ZSTD 2
 
 /* Names of sections, indexed by enum dwarf_section in internal.h.  */
 
@@ -1108,7 +1115,7 @@  elf_uncompress_failed(void)
    on error.  */
 
 static int
-elf_zlib_fetch (const unsigned char **ppin, const unsigned char *pinend,
+elf_fetch_bits (const unsigned char **ppin, const unsigned char *pinend,
 		uint64_t *pval, unsigned int *pbits)
 {
   unsigned int bits;
@@ -1155,6 +1162,118 @@  elf_zlib_fetch (const unsigned char **ppin, const unsigned char *pinend,
   return 1;
 }
 
+/* This is like elf_fetch_bits, but it fetchs the bits backward, and ensures at
+   least 16 bits.  This is for zstd.  */
+
+static int
+elf_fetch_bits_backward (const unsigned char **ppin,
+			 const unsigned char *pinend,
+			 uint64_t *pval, unsigned int *pbits)
+{
+  unsigned int bits;
+  const unsigned char *pin;
+  uint64_t val;
+  uint32_t next;
+
+  bits = *pbits;
+  if (bits >= 16)
+    return 1;
+  pin = *ppin;
+  val = *pval;
+
+  if (unlikely (pin <= pinend))
+    {
+      if (bits == 0)
+	{
+	  elf_uncompress_failed ();
+	  return 0;
+	}
+      return 1;
+    }
+
+  pin -= 4;
+
+#if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) \
+  && defined(__ORDER_BIG_ENDIAN__)				\
+  && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__			\
+      || __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
+  /* We've ensured that PIN is aligned.  */
+  next = *(const uint32_t *)pin;
+
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+  next = __builtin_bswap32 (next);
+#endif
+#else
+  next = pin[0] | (pin[1] << 8) | (pin[2] << 16) | (pin[3] << 24);
+#endif
+
+  val <<= 32;
+  val |= next;
+  bits += 32;
+
+  if (unlikely (pin < pinend))
+    {
+      val >>= (pinend - pin) * 8;
+      bits -= (pinend - pin) * 8;
+    }
+
+  *ppin = pin;
+  *pval = val;
+  *pbits = bits;
+  return 1;
+}
+
+/* Initialize backward fetching when the bitstream starts with a 1 bit in the
+   last byte in memory (which is the first one that we read).  This is used by
+   zstd decompression.  Returns 1 on success, 0 on error.  */
+
+static int
+elf_fetch_backward_init (const unsigned char **ppin,
+			 const unsigned char *pinend,
+			 uint64_t *pval, unsigned int *pbits)
+{
+  const unsigned char *pin;
+  unsigned int stream_start;
+  uint64_t val;
+  unsigned int bits;
+
+  pin = *ppin;
+  stream_start = (unsigned int)*pin;
+  if (unlikely (stream_start == 0))
+    {
+      elf_uncompress_failed ();
+      return 0;
+    }
+  val = 0;
+  bits = 0;
+
+  /* Align to a 32-bit boundary.  */
+  while ((((uintptr_t)pin) & 3) != 0)
+    {
+      val <<= 8;
+      val |= (uint64_t)*pin;
+      bits += 8;
+      --pin;
+    }
+
+  val <<= 8;
+  val |= (uint64_t)*pin;
+  bits += 8;
+
+  *ppin = pin;
+  *pval = val;
+  *pbits = bits;
+  if (!elf_fetch_bits_backward (ppin, pinend, pval, pbits))
+    return 0;
+
+  *pbits -= __builtin_clz (stream_start) - (sizeof (unsigned int) - 1) * 8 + 1;
+
+  if (!elf_fetch_bits_backward (ppin, pinend, pval, pbits))
+    return 0;
+
+  return 1;
+}
+
 /* Huffman code tables, like the rest of the zlib format, are defined
    by RFC 1951.  We store a Huffman code table as a series of tables
    stored sequentially in memory.  Each entry in a table is 16 bits.
@@ -1189,14 +1308,14 @@  elf_zlib_fetch (const unsigned char **ppin, const unsigned char *pinend,
 /* Number of entries we allocate to for one code table.  We get a page
    for the two code tables we need.  */
 
-#define HUFFMAN_TABLE_SIZE (1024)
+#define ZLIB_HUFFMAN_TABLE_SIZE (1024)
 
 /* Bit masks and shifts for the values in the table.  */
 
-#define HUFFMAN_VALUE_MASK 0x01ff
-#define HUFFMAN_BITS_SHIFT 9
-#define HUFFMAN_BITS_MASK 0x7
-#define HUFFMAN_SECONDARY_SHIFT 12
+#define ZLIB_HUFFMAN_VALUE_MASK 0x01ff
+#define ZLIB_HUFFMAN_BITS_SHIFT 9
+#define ZLIB_HUFFMAN_BITS_MASK 0x7
+#define ZLIB_HUFFMAN_SECONDARY_SHIFT 12
 
 /* For working memory while inflating we need two code tables, we need
    an array of code lengths (max value 15, so we use unsigned char),
@@ -1204,17 +1323,17 @@  elf_zlib_fetch (const unsigned char **ppin, const unsigned char *pinend,
    latter two arrays must be large enough to hold the maximum number
    of code lengths, which RFC 1951 defines as 286 + 30.  */
 
-#define ZDEBUG_TABLE_SIZE \
-  (2 * HUFFMAN_TABLE_SIZE * sizeof (uint16_t) \
+#define ZLIB_TABLE_SIZE \
+  (2 * ZLIB_HUFFMAN_TABLE_SIZE * sizeof (uint16_t) \
    + (286 + 30) * sizeof (uint16_t)	      \
    + (286 + 30) * sizeof (unsigned char))
 
-#define ZDEBUG_TABLE_CODELEN_OFFSET \
-  (2 * HUFFMAN_TABLE_SIZE * sizeof (uint16_t) \
+#define ZLIB_TABLE_CODELEN_OFFSET \
+  (2 * ZLIB_HUFFMAN_TABLE_SIZE * sizeof (uint16_t) \
    + (286 + 30) * sizeof (uint16_t))
 
-#define ZDEBUG_TABLE_WORK_OFFSET \
-  (2 * HUFFMAN_TABLE_SIZE * sizeof (uint16_t))
+#define ZLIB_TABLE_WORK_OFFSET \
+  (2 * ZLIB_HUFFMAN_TABLE_SIZE * sizeof (uint16_t))
 
 #ifdef BACKTRACE_GENERATE_FIXED_HUFFMAN_TABLE
 
@@ -1247,7 +1366,7 @@  elf_zlib_inflate_table (unsigned char *codes, size_t codes_len,
      next value after VAL with the same bit length.  */
 
   next = (uint16_t *) (((unsigned char *) zdebug_table)
-		       + ZDEBUG_TABLE_WORK_OFFSET);
+		       + ZLIB_TABLE_WORK_OFFSET);
 
   memset (&count[0], 0, 16 * sizeof (uint16_t));
   for (i = 0; i < codes_len; ++i)
@@ -1275,7 +1394,7 @@  elf_zlib_inflate_table (unsigned char *codes, size_t codes_len,
   /* For each length, fill in the table for the codes of that
      length.  */
 
-  memset (table, 0, HUFFMAN_TABLE_SIZE * sizeof (uint16_t));
+  memset (table, 0, ZLIB_HUFFMAN_TABLE_SIZE * sizeof (uint16_t));
 
   /* Handle the values that do not require a secondary table.  */
 
@@ -1309,13 +1428,13 @@  elf_zlib_inflate_table (unsigned char *codes, size_t codes_len,
 	  /* In the compressed bit stream, the value VAL is encoded as
 	     J bits with the value C.  */
 
-	  if (unlikely ((val & ~HUFFMAN_VALUE_MASK) != 0))
+	  if (unlikely ((val & ~ZLIB_HUFFMAN_VALUE_MASK) != 0))
 	    {
 	      elf_uncompress_failed ();
 	      return 0;
 	    }
 
-	  tval = val | ((j - 1) << HUFFMAN_BITS_SHIFT);
+	  tval = val | ((j - 1) << ZLIB_HUFFMAN_BITS_SHIFT);
 
 	  /* The table lookup uses 8 bits.  If J is less than 8, we
 	     don't know what the other bits will be.  We need to fill
@@ -1465,7 +1584,7 @@  elf_zlib_inflate_table (unsigned char *codes, size_t codes_len,
 		{
 		  /* Start a new secondary table.  */
 
-		  if (unlikely ((next_secondary & HUFFMAN_VALUE_MASK)
+		  if (unlikely ((next_secondary & ZLIB_HUFFMAN_VALUE_MASK)
 				!= next_secondary))
 		    {
 		      elf_uncompress_failed ();
@@ -1476,22 +1595,23 @@  elf_zlib_inflate_table (unsigned char *codes, size_t codes_len,
 		  secondary_bits = j - 8;
 		  next_secondary += 1 << secondary_bits;
 		  table[primary] = (secondary
-				    + ((j - 8) << HUFFMAN_BITS_SHIFT)
-				    + (1U << HUFFMAN_SECONDARY_SHIFT));
+				    + ((j - 8) << ZLIB_HUFFMAN_BITS_SHIFT)
+				    + (1U << ZLIB_HUFFMAN_SECONDARY_SHIFT));
 		}
 	      else
 		{
 		  /* There is an existing entry.  It had better be a
 		     secondary table with enough bits.  */
-		  if (unlikely ((tprimary & (1U << HUFFMAN_SECONDARY_SHIFT))
+		  if (unlikely ((tprimary
+				 & (1U << ZLIB_HUFFMAN_SECONDARY_SHIFT))
 				== 0))
 		    {
 		      elf_uncompress_failed ();
 		      return 0;
 		    }
-		  secondary = tprimary & HUFFMAN_VALUE_MASK;
-		  secondary_bits = ((tprimary >> HUFFMAN_BITS_SHIFT)
-				    & HUFFMAN_BITS_MASK);
+		  secondary = tprimary & ZLIB_HUFFMAN_VALUE_MASK;
+		  secondary_bits = ((tprimary >> ZLIB_HUFFMAN_BITS_SHIFT)
+				    & ZLIB_HUFFMAN_BITS_MASK);
 		  if (unlikely (secondary_bits < j - 8))
 		    {
 		      elf_uncompress_failed ();
@@ -1502,7 +1622,7 @@  elf_zlib_inflate_table (unsigned char *codes, size_t codes_len,
 
 	  /* Fill in secondary table entries.  */
 
-	  tval = val | ((j - 8) << HUFFMAN_BITS_SHIFT);
+	  tval = val | ((j - 8) << ZLIB_HUFFMAN_BITS_SHIFT);
 
 	  for (ind = code >> 8;
 	       ind < (1U << secondary_bits);
@@ -1545,7 +1665,7 @@  elf_zlib_inflate_table (unsigned char *codes, size_t codes_len,
 
 #include <stdio.h>
 
-static uint16_t table[ZDEBUG_TABLE_SIZE];
+static uint16_t table[ZLIB_TABLE_SIZE];
 static unsigned char codes[288];
 
 int
@@ -1773,7 +1893,7 @@  elf_zlib_inflate (const unsigned char *pin, size_t sin, uint16_t *zdebug_table,
 	  const uint16_t *tlit;
 	  const uint16_t *tdist;
 
-	  if (!elf_zlib_fetch (&pin, pinend, &val, &bits))
+	  if (!elf_fetch_bits (&pin, pinend, &val, &bits))
 	    return 0;
 
 	  last = val & 1;
@@ -1796,7 +1916,7 @@  elf_zlib_inflate (const unsigned char *pin, size_t sin, uint16_t *zdebug_table,
 	      /* An uncompressed block.  */
 
 	      /* If we've read ahead more than a byte, back up.  */
-	      while (bits > 8)
+	      while (bits >= 8)
 		{
 		  --pin;
 		  bits -= 8;
@@ -1861,7 +1981,7 @@  elf_zlib_inflate (const unsigned char *pin, size_t sin, uint16_t *zdebug_table,
 	      /* Read a Huffman encoding table.  The various magic
 		 numbers here are from RFC 1951.  */
 
-	      if (!elf_zlib_fetch (&pin, pinend, &val, &bits))
+	      if (!elf_fetch_bits (&pin, pinend, &val, &bits))
 		return 0;
 
 	      nlit = (val & 0x1f) + 257;
@@ -1886,7 +2006,7 @@  elf_zlib_inflate (const unsigned char *pin, size_t sin, uint16_t *zdebug_table,
 	      /* There are always at least 4 elements in the
 		 table.  */
 
-	      if (!elf_zlib_fetch (&pin, pinend, &val, &bits))
+	      if (!elf_fetch_bits (&pin, pinend, &val, &bits))
 		return 0;
 
 	      codebits[16] = val & 7;
@@ -1906,7 +2026,7 @@  elf_zlib_inflate (const unsigned char *pin, size_t sin, uint16_t *zdebug_table,
 	      if (nclen == 5)
 		goto codebitsdone;
 
-	      if (!elf_zlib_fetch (&pin, pinend, &val, &bits))
+	      if (!elf_fetch_bits (&pin, pinend, &val, &bits))
 		return 0;
 
 	      codebits[7] = val & 7;
@@ -1944,7 +2064,7 @@  elf_zlib_inflate (const unsigned char *pin, size_t sin, uint16_t *zdebug_table,
 	      if (nclen == 10)
 		goto codebitsdone;
 
-	      if (!elf_zlib_fetch (&pin, pinend, &val, &bits))
+	      if (!elf_fetch_bits (&pin, pinend, &val, &bits))
 		return 0;
 
 	      codebits[11] = val & 7;
@@ -1982,7 +2102,7 @@  elf_zlib_inflate (const unsigned char *pin, size_t sin, uint16_t *zdebug_table,
 	      if (nclen == 15)
 		goto codebitsdone;
 
-	      if (!elf_zlib_fetch (&pin, pinend, &val, &bits))
+	      if (!elf_fetch_bits (&pin, pinend, &val, &bits))
 		return 0;
 
 	      codebits[2] = val & 7;
@@ -2021,7 +2141,7 @@  elf_zlib_inflate (const unsigned char *pin, size_t sin, uint16_t *zdebug_table,
 		 at the end of zdebug_table to hold them.  */
 
 	      plenbase = (((unsigned char *) zdebug_table)
-			  + ZDEBUG_TABLE_CODELEN_OFFSET);
+			  + ZLIB_TABLE_CODELEN_OFFSET);
 	      plen = plenbase;
 	      plenend = plen + nlit + ndist;
 	      while (plen < plenend)
@@ -2030,24 +2150,25 @@  elf_zlib_inflate (const unsigned char *pin, size_t sin, uint16_t *zdebug_table,
 		  unsigned int b;
 		  uint16_t v;
 
-		  if (!elf_zlib_fetch (&pin, pinend, &val, &bits))
+		  if (!elf_fetch_bits (&pin, pinend, &val, &bits))
 		    return 0;
 
 		  t = zdebug_table[val & 0xff];
 
 		  /* The compression here uses bit lengths up to 7, so
 		     a secondary table is never necessary.  */
-		  if (unlikely ((t & (1U << HUFFMAN_SECONDARY_SHIFT)) != 0))
+		  if (unlikely ((t & (1U << ZLIB_HUFFMAN_SECONDARY_SHIFT))
+				!= 0))
 		    {
 		      elf_uncompress_failed ();
 		      return 0;
 		    }
 
-		  b = (t >> HUFFMAN_BITS_SHIFT) & HUFFMAN_BITS_MASK;
+		  b = (t >> ZLIB_HUFFMAN_BITS_SHIFT) & ZLIB_HUFFMAN_BITS_MASK;
 		  val >>= b + 1;
 		  bits -= b + 1;
 
-		  v = t & HUFFMAN_VALUE_MASK;
+		  v = t & ZLIB_HUFFMAN_VALUE_MASK;
 		  if (v < 16)
 		    *plen++ = v;
 		  else if (v == 16)
@@ -2064,7 +2185,7 @@  elf_zlib_inflate (const unsigned char *pin, size_t sin, uint16_t *zdebug_table,
 			}
 
 		      /* We used up to 7 bits since the last
-			 elf_zlib_fetch, so we have at least 8 bits
+			 elf_fetch_bits, so we have at least 8 bits
 			 available here.  */
 
 		      c = 3 + (val & 0x3);
@@ -2099,7 +2220,7 @@  elf_zlib_inflate (const unsigned char *pin, size_t sin, uint16_t *zdebug_table,
 		      /* Store zero 3 to 10 times.  */
 
 		      /* We used up to 7 bits since the last
-			 elf_zlib_fetch, so we have at least 8 bits
+			 elf_fetch_bits, so we have at least 8 bits
 			 available here.  */
 
 		      c = 3 + (val & 0x7);
@@ -2145,7 +2266,7 @@  elf_zlib_inflate (const unsigned char *pin, size_t sin, uint16_t *zdebug_table,
 		      /* Store zero 11 to 138 times.  */
 
 		      /* We used up to 7 bits since the last
-			 elf_zlib_fetch, so we have at least 8 bits
+			 elf_fetch_bits, so we have at least 8 bits
 			 available here.  */
 
 		      c = 11 + (val & 0x7f);
@@ -2182,10 +2303,11 @@  elf_zlib_inflate (const unsigned char *pin, size_t sin, uint16_t *zdebug_table,
 					   zdebug_table))
 		return 0;
 	      if (!elf_zlib_inflate_table (plen + nlit, ndist, zdebug_table,
-					   zdebug_table + HUFFMAN_TABLE_SIZE))
+					   (zdebug_table
+					    + ZLIB_HUFFMAN_TABLE_SIZE)))
 		return 0;
 	      tlit = zdebug_table;
-	      tdist = zdebug_table + HUFFMAN_TABLE_SIZE;
+	      tdist = zdebug_table + ZLIB_HUFFMAN_TABLE_SIZE;
 	    }
 
 	  /* Inflate values until the end of the block.  This is the
@@ -2198,14 +2320,14 @@  elf_zlib_inflate (const unsigned char *pin, size_t sin, uint16_t *zdebug_table,
 	      uint16_t v;
 	      unsigned int lit;
 
-	      if (!elf_zlib_fetch (&pin, pinend, &val, &bits))
+	      if (!elf_fetch_bits (&pin, pinend, &val, &bits))
 		return 0;
 
 	      t = tlit[val & 0xff];
-	      b = (t >> HUFFMAN_BITS_SHIFT) & HUFFMAN_BITS_MASK;
-	      v = t & HUFFMAN_VALUE_MASK;
+	      b = (t >> ZLIB_HUFFMAN_BITS_SHIFT) & ZLIB_HUFFMAN_BITS_MASK;
+	      v = t & ZLIB_HUFFMAN_VALUE_MASK;
 
-	      if ((t & (1U << HUFFMAN_SECONDARY_SHIFT)) == 0)
+	      if ((t & (1U << ZLIB_HUFFMAN_SECONDARY_SHIFT)) == 0)
 		{
 		  lit = v;
 		  val >>= b + 1;
@@ -2214,8 +2336,8 @@  elf_zlib_inflate (const unsigned char *pin, size_t sin, uint16_t *zdebug_table,
 	      else
 		{
 		  t = tlit[v + 0x100 + ((val >> 8) & ((1U << b) - 1))];
-		  b = (t >> HUFFMAN_BITS_SHIFT) & HUFFMAN_BITS_MASK;
-		  lit = t & HUFFMAN_VALUE_MASK;
+		  b = (t >> ZLIB_HUFFMAN_BITS_SHIFT) & ZLIB_HUFFMAN_BITS_MASK;
+		  lit = t & ZLIB_HUFFMAN_VALUE_MASK;
 		  val >>= b + 8;
 		  bits -= b + 8;
 		}
@@ -2260,7 +2382,7 @@  elf_zlib_inflate (const unsigned char *pin, size_t sin, uint16_t *zdebug_table,
 		    {
 		      unsigned int extra;
 
-		      if (!elf_zlib_fetch (&pin, pinend, &val, &bits))
+		      if (!elf_fetch_bits (&pin, pinend, &val, &bits))
 			return 0;
 
 		      /* This is an expression for the table of length
@@ -2275,14 +2397,14 @@  elf_zlib_inflate (const unsigned char *pin, size_t sin, uint16_t *zdebug_table,
 		      bits -= extra;
 		    }
 
-		  if (!elf_zlib_fetch (&pin, pinend, &val, &bits))
+		  if (!elf_fetch_bits (&pin, pinend, &val, &bits))
 		    return 0;
 
 		  t = tdist[val & 0xff];
-		  b = (t >> HUFFMAN_BITS_SHIFT) & HUFFMAN_BITS_MASK;
-		  v = t & HUFFMAN_VALUE_MASK;
+		  b = (t >> ZLIB_HUFFMAN_BITS_SHIFT) & ZLIB_HUFFMAN_BITS_MASK;
+		  v = t & ZLIB_HUFFMAN_VALUE_MASK;
 
-		  if ((t & (1U << HUFFMAN_SECONDARY_SHIFT)) == 0)
+		  if ((t & (1U << ZLIB_HUFFMAN_SECONDARY_SHIFT)) == 0)
 		    {
 		      dist = v;
 		      val >>= b + 1;
@@ -2291,8 +2413,9 @@  elf_zlib_inflate (const unsigned char *pin, size_t sin, uint16_t *zdebug_table,
 		  else
 		    {
 		      t = tdist[v + 0x100 + ((val >> 8) & ((1U << b) - 1))];
-		      b = (t >> HUFFMAN_BITS_SHIFT) & HUFFMAN_BITS_MASK;
-		      dist = t & HUFFMAN_VALUE_MASK;
+		      b = ((t >> ZLIB_HUFFMAN_BITS_SHIFT)
+			   & ZLIB_HUFFMAN_BITS_MASK);
+		      dist = t & ZLIB_HUFFMAN_VALUE_MASK;
 		      val >>= b + 8;
 		      bits -= b + 8;
 		    }
@@ -2332,7 +2455,7 @@  elf_zlib_inflate (const unsigned char *pin, size_t sin, uint16_t *zdebug_table,
 			{
 			  unsigned int extra;
 
-			  if (!elf_zlib_fetch (&pin, pinend, &val, &bits))
+			  if (!elf_fetch_bits (&pin, pinend, &val, &bits))
 			    return 0;
 
 			  /* This is an expression for the table of
@@ -2537,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 <stdio.h>
+
+/* These values are straight from RFC 8878.  */
+
+static int16_t lit[36] =
+{
+   4, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1,
+   2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 1, 1, 1, 1, 1,
+  -1,-1,-1,-1
+};
+
+static int16_t match[53] =
+{
+   1, 4, 3, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1,
+   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,-1,-1,
+  -1,-1,-1,-1,-1
+};
+
+static int16_t offset[29] =
+{
+  1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1,
+  1, 1, 1, 1, 1, 1, 1, 1,-1,-1,-1,-1,-1
+};
+
+static uint16_t next[256];
+
+static void
+print_table (const struct elf_zstd_fse_baseline_entry *table, size_t size)
+{
+  size_t i;
+
+  printf ("{\n");
+  for (i = 0; i < size; i += 3)
+    {
+      int j;
+
+      printf (" ");
+      for (j = 0; j < 3 && i + j < size; ++j)
+	printf (" { %u, %d, %d, %d },", table[i + j].baseline,
+		table[i + j].basebits, table[i + j].bits,
+		table[i + j].base);
+      printf ("\n");
+    }
+  printf ("};\n");
+}
+
+int
+main ()
+{
+  struct elf_zstd_fse_entry lit_table[64];
+  struct elf_zstd_fse_baseline_entry lit_baseline[64];
+  struct elf_zstd_fse_entry match_table[64];
+  struct elf_zstd_fse_baseline_entry match_baseline[64];
+  struct elf_zstd_fse_entry offset_table[32];
+  struct elf_zstd_fse_baseline_entry offset_baseline[32];
+
+  if (!elf_zstd_build_fse (lit, sizeof lit / sizeof lit[0], next,
+			   6, lit_table))
+    {
+      fprintf (stderr, "elf_zstd_build_fse failed\n");
+      exit (EXIT_FAILURE);
+    }
+
+  if (!elf_zstd_make_literal_baseline_fse (lit_table, 6, lit_baseline))
+    {
+      fprintf (stderr, "elf_zstd_make_literal_baseline_fse failed\n");
+      exit (EXIT_FAILURE);
+    }
+
+  printf ("static const struct elf_zstd_fse_baseline_entry "
+	  "elf_zstd_lit_table[64] =\n");
+  print_table (lit_baseline,
+	       sizeof lit_baseline / sizeof lit_baseline[0]);
+  printf ("\n");
+
+  if (!elf_zstd_build_fse (match, sizeof match / sizeof match[0], next,
+			   6, match_table))
+    {
+      fprintf (stderr, "elf_zstd_build_fse failed\n");
+      exit (EXIT_FAILURE);
+    }
+
+  if (!elf_zstd_make_match_baseline_fse (match_table, 6, match_baseline))
+    {
+      fprintf (stderr, "elf_zstd_make_match_baseline_fse failed\n");
+      exit (EXIT_FAILURE);
+    }
+
+  printf ("static const struct elf_zstd_fse_baseline_entry "
+	  "elf_zstd_match_table[64] =\n");
+  print_table (match_baseline,
+	       sizeof match_baseline / sizeof match_baseline[0]);
+  printf ("\n");
+
+  if (!elf_zstd_build_fse (offset, sizeof offset / sizeof offset[0], next,
+			   5, offset_table))
+    {
+      fprintf (stderr, "elf_zstd_build_fse failed\n");
+      exit (EXIT_FAILURE);
+    }
+
+  if (!elf_zstd_make_offset_baseline_fse (offset_table, 5, offset_baseline))
+    {
+      fprintf (stderr, "elf_zstd_make_offset_baseline_fse failed\n");
+      exit (EXIT_FAILURE);
+    }
+
+  printf ("static const struct elf_zstd_fse_baseline_entry "
+	  "elf_zstd_offset_table[32] =\n");
+  print_table (offset_baseline,
+	       sizeof offset_baseline / sizeof offset_baseline[0]);
+  printf ("\n");
+
+  return 0;
+}
+
+#endif
+
+/* The fixed tables generated by the #ifdef'ed out main function
+   above.  */
+
+static const struct elf_zstd_fse_baseline_entry elf_zstd_lit_table[64] =
+{
+  { 0, 0, 4, 0 }, { 0, 0, 4, 16 }, { 1, 0, 5, 32 },
+  { 3, 0, 5, 0 }, { 4, 0, 5, 0 }, { 6, 0, 5, 0 },
+  { 7, 0, 5, 0 }, { 9, 0, 5, 0 }, { 10, 0, 5, 0 },
+  { 12, 0, 5, 0 }, { 14, 0, 6, 0 }, { 16, 1, 5, 0 },
+  { 20, 1, 5, 0 }, { 22, 1, 5, 0 }, { 28, 2, 5, 0 },
+  { 32, 3, 5, 0 }, { 48, 4, 5, 0 }, { 64, 6, 5, 32 },
+  { 128, 7, 5, 0 }, { 256, 8, 6, 0 }, { 1024, 10, 6, 0 },
+  { 4096, 12, 6, 0 }, { 0, 0, 4, 32 }, { 1, 0, 4, 0 },
+  { 2, 0, 5, 0 }, { 4, 0, 5, 32 }, { 5, 0, 5, 0 },
+  { 7, 0, 5, 32 }, { 8, 0, 5, 0 }, { 10, 0, 5, 32 },
+  { 11, 0, 5, 0 }, { 13, 0, 6, 0 }, { 16, 1, 5, 32 },
+  { 18, 1, 5, 0 }, { 22, 1, 5, 32 }, { 24, 2, 5, 0 },
+  { 32, 3, 5, 32 }, { 40, 3, 5, 0 }, { 64, 6, 4, 0 },
+  { 64, 6, 4, 16 }, { 128, 7, 5, 32 }, { 512, 9, 6, 0 },
+  { 2048, 11, 6, 0 }, { 0, 0, 4, 48 }, { 1, 0, 4, 16 },
+  { 2, 0, 5, 32 }, { 3, 0, 5, 32 }, { 5, 0, 5, 32 },
+  { 6, 0, 5, 32 }, { 8, 0, 5, 32 }, { 9, 0, 5, 32 },
+  { 11, 0, 5, 32 }, { 12, 0, 5, 32 }, { 15, 0, 6, 0 },
+  { 18, 1, 5, 32 }, { 20, 1, 5, 32 }, { 24, 2, 5, 32 },
+  { 28, 2, 5, 32 }, { 40, 3, 5, 32 }, { 48, 4, 5, 32 },
+  { 65536, 16, 6, 0 }, { 32768, 15, 6, 0 }, { 16384, 14, 6, 0 },
+  { 8192, 13, 6, 0 },
+};
+
+static const struct elf_zstd_fse_baseline_entry elf_zstd_match_table[64] =
+{
+  { 3, 0, 6, 0 }, { 4, 0, 4, 0 }, { 5, 0, 5, 32 },
+  { 6, 0, 5, 0 }, { 8, 0, 5, 0 }, { 9, 0, 5, 0 },
+  { 11, 0, 5, 0 }, { 13, 0, 6, 0 }, { 16, 0, 6, 0 },
+  { 19, 0, 6, 0 }, { 22, 0, 6, 0 }, { 25, 0, 6, 0 },
+  { 28, 0, 6, 0 }, { 31, 0, 6, 0 }, { 34, 0, 6, 0 },
+  { 37, 1, 6, 0 }, { 41, 1, 6, 0 }, { 47, 2, 6, 0 },
+  { 59, 3, 6, 0 }, { 83, 4, 6, 0 }, { 131, 7, 6, 0 },
+  { 515, 9, 6, 0 }, { 4, 0, 4, 16 }, { 5, 0, 4, 0 },
+  { 6, 0, 5, 32 }, { 7, 0, 5, 0 }, { 9, 0, 5, 32 },
+  { 10, 0, 5, 0 }, { 12, 0, 6, 0 }, { 15, 0, 6, 0 },
+  { 18, 0, 6, 0 }, { 21, 0, 6, 0 }, { 24, 0, 6, 0 },
+  { 27, 0, 6, 0 }, { 30, 0, 6, 0 }, { 33, 0, 6, 0 },
+  { 35, 1, 6, 0 }, { 39, 1, 6, 0 }, { 43, 2, 6, 0 },
+  { 51, 3, 6, 0 }, { 67, 4, 6, 0 }, { 99, 5, 6, 0 },
+  { 259, 8, 6, 0 }, { 4, 0, 4, 32 }, { 4, 0, 4, 48 },
+  { 5, 0, 4, 16 }, { 7, 0, 5, 32 }, { 8, 0, 5, 32 },
+  { 10, 0, 5, 32 }, { 11, 0, 5, 32 }, { 14, 0, 6, 0 },
+  { 17, 0, 6, 0 }, { 20, 0, 6, 0 }, { 23, 0, 6, 0 },
+  { 26, 0, 6, 0 }, { 29, 0, 6, 0 }, { 32, 0, 6, 0 },
+  { 65539, 16, 6, 0 }, { 32771, 15, 6, 0 }, { 16387, 14, 6, 0 },
+  { 8195, 13, 6, 0 }, { 4099, 12, 6, 0 }, { 2051, 11, 6, 0 },
+  { 1027, 10, 6, 0 },
+};
+
+static const struct elf_zstd_fse_baseline_entry elf_zstd_offset_table[32] =
+{
+  { 1, 0, 5, 0 }, { 61, 6, 4, 0 }, { 509, 9, 5, 0 },
+  { 32765, 15, 5, 0 }, { 2097149, 21, 5, 0 }, { 5, 3, 5, 0 },
+  { 125, 7, 4, 0 }, { 4093, 12, 5, 0 }, { 262141, 18, 5, 0 },
+  { 8388605, 23, 5, 0 }, { 29, 5, 5, 0 }, { 253, 8, 4, 0 },
+  { 16381, 14, 5, 0 }, { 1048573, 20, 5, 0 }, { 1, 2, 5, 0 },
+  { 125, 7, 4, 16 }, { 2045, 11, 5, 0 }, { 131069, 17, 5, 0 },
+  { 4194301, 22, 5, 0 }, { 13, 4, 5, 0 }, { 253, 8, 4, 16 },
+  { 8189, 13, 5, 0 }, { 524285, 19, 5, 0 }, { 2, 1, 5, 0 },
+  { 61, 6, 4, 16 }, { 1021, 10, 5, 0 }, { 65533, 16, 5, 0 },
+  { 268435453, 28, 5, 0 }, { 134217725, 27, 5, 0 }, { 67108861, 26, 5, 0 },
+  { 33554429, 25, 5, 0 }, { 16777213, 24, 5, 0 },
+};
+
+/* Read a zstd Huffman table and build the decoding table in *TABLE, reading
+   and updating *PPIN.  This sets *PTABLE_BITS to the number of bits of the
+   table, such that the table length is 1 << *TABLE_BITS.  ZDEBUG_TABLE is
+   scratch space; it must be enough for 512 uint16_t values + 256 32-bit values
+   (2048 bytes).  Returns 1 on success, 0 on error.  */
+
+static int
+elf_zstd_read_huff (const unsigned char **ppin, const unsigned char *pinend,
+		    uint16_t *zdebug_table, uint16_t *table, int *ptable_bits)
+{
+  const unsigned char *pin;
+  unsigned char hdr;
+  unsigned char *weights;
+  size_t count;
+  uint32_t *weight_mark;
+  size_t i;
+  uint32_t weight_mask;
+  size_t table_bits;
+
+  pin = *ppin;
+  if (unlikely (pin >= pinend))
+    {
+      elf_uncompress_failed ();
+      return 0;
+    }
+  hdr = *pin;
+  ++pin;
+
+  weights = (unsigned char *) zdebug_table;
+
+  if (hdr < 128)
+    {
+      /* Table is compressed using FSE.  */
+
+      struct elf_zstd_fse_entry *fse_table;
+      int fse_table_bits;
+      uint16_t *scratch;
+      const unsigned char *pfse;
+      const unsigned char *pback;
+      uint64_t val;
+      unsigned int bits;
+      unsigned int state1, state2;
+
+      /* SCRATCH is used temporarily by elf_zstd_read_fse.  It overlaps
+	 WEIGHTS.  */
+      scratch = zdebug_table;
+      fse_table = (struct elf_zstd_fse_entry *) (scratch + 512);
+      fse_table_bits = 6;
+
+      pfse = pin;
+      if (!elf_zstd_read_fse (&pfse, pinend, scratch, 255, fse_table,
+			      &fse_table_bits))
+	return 0;
+
+      if (unlikely (pin + hdr > pinend))
+	{
+	  elf_uncompress_failed ();
+	  return 0;
+	}
+
+      /* We no longer need SCRATCH.  Start recording weights.  We need up to
+	 256 bytes of weights and 64 bytes of rank counts, so it won't overlap
+	 FSE_TABLE.  */
+
+      pback = pin + hdr - 1;
+
+      if (!elf_fetch_backward_init (&pback, pfse, &val, &bits))
+	return 0;
+
+      bits -= fse_table_bits;
+      state1 = (val >> bits) & ((1U << fse_table_bits) - 1);
+      bits -= fse_table_bits;
+      state2 = (val >> bits) & ((1U << fse_table_bits) - 1);
+
+      /* There are two independent FSE streams, tracked by STATE1 and STATE2.
+	 We decode them alternately.  */
+
+      count = 0;
+      while (1)
+	{
+	  struct elf_zstd_fse_entry *pt;
+	  uint64_t v;
+
+	  pt = &fse_table[state1];
+
+	  if (unlikely (pin < pinend) && bits < pt->bits)
+	    {
+	      if (unlikely (count >= 254))
+		{
+		  elf_uncompress_failed ();
+		  return 0;
+		}
+	      weights[count] = (unsigned char) pt->symbol;
+	      weights[count + 1] = (unsigned char) fse_table[state2].symbol;
+	      count += 2;
+	      break;
+	    }
+
+	  if (unlikely (pt->bits == 0))
+	    v = 0;
+	  else
+	    {
+	      if (!elf_fetch_bits_backward (&pback, pfse, &val, &bits))
+		return 0;
+
+	      bits -= pt->bits;
+	      v = (val >> bits) & (((uint64_t)1 << pt->bits) - 1);
+	    }
+
+	  state1 = pt->base + v;
+
+	  if (unlikely (count >= 255))
+	    {
+	      elf_uncompress_failed ();
+	      return 0;
+	    }
+
+	  weights[count] = pt->symbol;
+	  ++count;
+
+	  pt = &fse_table[state2];
+
+	  if (unlikely (pin < pinend && bits < pt->bits))
+	    {
+	      if (unlikely (count >= 254))
+		{
+		  elf_uncompress_failed ();
+		  return 0;
+		}
+	      weights[count] = (unsigned char) pt->symbol;
+	      weights[count + 1] = (unsigned char) fse_table[state1].symbol;
+	      count += 2;
+	      break;
+	    }
+
+	  if (unlikely (pt->bits == 0))
+	    v = 0;
+	  else
+	    {
+	      if (!elf_fetch_bits_backward (&pback, pfse, &val, &bits))
+		return 0;
+
+	      bits -= pt->bits;
+	      v = (val >> bits) & (((uint64_t)1 << pt->bits) - 1);
+	    }
+
+	  state2 = pt->base + v;
+
+	  if (unlikely (count >= 255))
+	    {
+	      elf_uncompress_failed ();
+	      return 0;
+	    }
+
+	  weights[count] = pt->symbol;
+	  ++count;
+	}
+
+      pin += hdr;
+    }
+  else
+    {
+      /* Table is not compressed.  Each weight is 4 bits.  */
+
+      count = hdr - 127;
+      if (unlikely (pin + ((count + 1) / 2) >= pinend))
+	{
+	  elf_uncompress_failed ();
+	  return 0;
+	}
+      for (i = 0; i < count; i += 2)
+	{
+	  unsigned char b;
+
+	  b = *pin;
+	  ++pin;
+	  weights[i] = b >> 4;
+	  weights[i + 1] = b & 0xf;
+	}
+    }
+
+  weight_mark = (uint32_t *) (weights + 256);
+  memset (weight_mark, 0, 13 * sizeof (uint32_t));
+  weight_mask = 0;
+  for (i = 0; i < count; ++i)
+    {
+      unsigned char w;
+
+      w = weights[i];
+      if (unlikely (w > 12))
+	{
+	  elf_uncompress_failed ();
+	  return 0;
+	}
+      ++weight_mark[w];
+      if (w > 0)
+	weight_mask += 1U << (w - 1);
+    }
+  if (unlikely (weight_mask == 0))
+    {
+      elf_uncompress_failed ();
+      return 0;
+    }
+
+  table_bits = 32 - __builtin_clz (weight_mask);
+  if (unlikely (table_bits > 11))
+    {
+      elf_uncompress_failed ();
+      return 0;
+    }
+
+  /* Work out the last weight value, which is omitted because the weights must
+     sum to a power of two.  */
+  {
+    uint32_t left;
+    uint32_t high_bit;
+
+    left = ((uint32_t)1 << table_bits) - weight_mask;
+    if (left == 0)
+      {
+	elf_uncompress_failed ();
+	return 0;
+      }
+    high_bit = 31 - __builtin_clz (left);
+    if (((uint32_t)1 << high_bit) != left)
+      {
+	elf_uncompress_failed ();
+	return 0;
+      }
+
+    if (unlikely (count >= 256))
+      {
+	elf_uncompress_failed ();
+	return 0;
+      }
+
+    weights[count] = high_bit + 1;
+    ++count;
+    ++weight_mark[high_bit + 1];
+  }
+
+  if (weight_mark[1] < 2 || (weight_mark[1] & 1) != 0)
+    {
+      elf_uncompress_failed ();
+      return 0;
+    }
+
+  /* Change WEIGHT_MARK from a count of weights to the index of the first
+     symbol for that weight.  We shift the indexes to also store how many we
+     have seen so far, below.  */
+  {
+    uint32_t next;
+
+    next = 0;
+    for (i = 0; i < table_bits; ++i)
+      {
+	uint32_t cur;
+
+	cur = next;
+	next += weight_mark[i + 1] << i;
+	weight_mark[i + 1] = cur;
+      }
+  }
+
+  for (i = 0; i < count; ++i)
+    {
+      unsigned char weight;
+      uint32_t length;
+      uint16_t tval;
+      size_t start;
+      uint32_t j;
+
+      weight = weights[i];
+      if (weight == 0)
+	continue;
+
+      length = 1U << (weight - 1);
+      tval = (i << 8) | (table_bits + 1 - weight);
+      start = weight_mark[weight];
+      for (j = 0; j < length; ++j)
+	table[start + j] = tval;
+      weight_mark[weight] += length;
+    }
+
+  *ppin = pin;
+  *ptable_bits = (int)table_bits;
+
+  return 1;
+}
+
+/* Read and decompress the literals and store them ending at POUTEND.  This
+   works because we are going to use all the literals in the output, so they
+   must fit into the output buffer.  HUFFMAN_TABLE, and PHUFFMAN_TABLE_BITS
+   store the Huffman table across calls.  SCRATCH is used to read a Huffman
+   table.  Store the start of the decompressed literals in *PPLIT.  Update
+   *PPIN.  Return 1 on success, 0 on error.  */
+
+static int
+elf_zstd_read_literals (const unsigned char **ppin,
+			const unsigned char *pinend,
+			unsigned char *pout,
+			unsigned char *poutend,
+			uint16_t *scratch,
+			uint16_t *huffman_table,
+			int *phuffman_table_bits,
+			unsigned char **pplit)
+{
+  const unsigned char *pin;
+  unsigned char *plit;
+  unsigned char hdr;
+  uint32_t regenerated_size;
+  uint32_t compressed_size;
+  int streams;
+  uint32_t total_streams_size;
+  unsigned int huffman_table_bits;
+  uint64_t huffman_mask;
+
+  pin = *ppin;
+  if (unlikely (pin >= pinend))
+    {
+      elf_uncompress_failed ();
+      return 0;
+    }
+  hdr = *pin;
+  ++pin;
+
+  if ((hdr & 3) == 0 || (hdr & 3) == 1)
+    {
+      int raw;
+
+      /* Raw_Literals_Block or RLE_Literals_Block */
+
+      raw = (hdr & 3) == 0;
+
+      switch ((hdr >> 2) & 3)
+	{
+	case 0: case 2:
+	  regenerated_size = hdr >> 3;
+	  break;
+	case 1:
+	  if (unlikely (pin >= pinend))
+	    {
+	      elf_uncompress_failed ();
+	      return 0;
+	    }
+	  regenerated_size = (hdr >> 4) + ((uint32_t)(*pin) << 4);
+	  ++pin;
+	  break;
+	case 3:
+	  if (unlikely (pin + 1 >= pinend))
+	    {
+	      elf_uncompress_failed ();
+	      return 0;
+	    }
+	  regenerated_size = ((hdr >> 4)
+			      + ((uint32_t)*pin << 4)
+			      + ((uint32_t)pin[1] << 12));
+	  pin += 2;
+	  break;
+	default:
+	  elf_uncompress_failed ();
+	  return 0;
+	}
+
+      if (unlikely ((size_t)(poutend - pout) < regenerated_size))
+	{
+	  elf_uncompress_failed ();
+	  return 0;
+	}
+
+      plit = poutend - regenerated_size;
+
+      if (raw)
+	{
+	  if (unlikely (pin + regenerated_size >= pinend))
+	    {
+	      elf_uncompress_failed ();
+	      return 0;
+	    }
+	  memcpy (plit, pin, regenerated_size);
+	  pin += regenerated_size;
+	}
+      else
+	{
+	  if (pin >= pinend)
+	    {
+	      elf_uncompress_failed ();
+	      return 0;
+	    }
+	  memset (plit, *pin, regenerated_size);
+	  ++pin;
+	}
+
+      *ppin = pin;
+      *pplit = plit;
+
+      return 1;
+    }
+
+  /* Compressed_Literals_Block or Treeless_Literals_Block */
+
+  switch ((hdr >> 2) & 3)
+    {
+    case 0: case 1:
+      if (unlikely (pin + 1 >= pinend))
+	{
+	  elf_uncompress_failed ();
+	  return 0;
+	}
+      regenerated_size = (hdr >> 4) | ((uint32_t)(*pin & 0x3f) << 4);
+      compressed_size = (uint32_t)*pin >> 6 | ((uint32_t)pin[1] << 2);
+      pin += 2;
+      streams = ((hdr >> 2) & 3) == 0 ? 1 : 4;
+      break;
+    case 2:
+      if (unlikely (pin + 2 >= pinend))
+	{
+	  elf_uncompress_failed ();
+	  return 0;
+	}
+      regenerated_size = (((uint32_t)hdr >> 4)
+			  | ((uint32_t)*pin << 4)
+			  | (((uint32_t)pin[1] & 3) << 12));
+      compressed_size = (((uint32_t)pin[1] >> 2)
+			 | ((uint32_t)pin[2] << 6));
+      pin += 3;
+      streams = 4;
+      break;
+    case 3:
+      if (unlikely (pin + 3 >= pinend))
+	{
+	  elf_uncompress_failed ();
+	  return 0;
+	}
+      regenerated_size = (((uint32_t)hdr >> 4)
+			  | ((uint32_t)*pin << 4)
+			  | (((uint32_t)pin[1] & 0x3f) << 12));
+      compressed_size = (((uint32_t)pin[1] >> 6)
+			 | ((uint32_t)pin[2] << 2)
+			 | ((uint32_t)pin[3] << 10));
+      pin += 4;
+      streams = 4;
+      break;
+    default:
+      elf_uncompress_failed ();
+      return 0;
+    }
+
+  if (unlikely (pin + compressed_size > pinend))
+    {
+      elf_uncompress_failed ();
+      return 0;
+    }
+
+  pinend = pin + compressed_size;
+  *ppin = pinend;
+
+  if (unlikely ((size_t)(poutend - pout) < regenerated_size))
+    {
+      elf_uncompress_failed ();
+      return 0;
+    }
+
+  plit = poutend - regenerated_size;
+
+  *pplit = plit;
+
+  total_streams_size = compressed_size;
+  if ((hdr & 3) == 2)
+    {
+      const unsigned char *ptable;
+
+      /* Compressed_Literals_Block.  Read Huffman tree.  */
+
+      ptable = pin;
+      if (!elf_zstd_read_huff (&ptable, pinend, scratch, huffman_table,
+			       phuffman_table_bits))
+	return 0;
+
+      if (unlikely (total_streams_size < (size_t)(ptable - pin)))
+	{
+	  elf_uncompress_failed ();
+	  return 0;
+	}
+
+      total_streams_size -= ptable - pin;
+      pin = ptable;
+    }
+  else
+    {
+      /* Treeless_Literals_Block.  Reuse previous Huffman tree.  */
+      if (unlikely (*phuffman_table_bits == 0))
+	{
+	  elf_uncompress_failed ();
+	  return 0;
+	}
+    }
+
+  /* Decompress COMPRESSED_SIZE bytes of data at PIN using the huffman table,
+     storing REGENERATED_SIZE bytes of decompressed data at PLIT.  */
+
+  huffman_table_bits = (unsigned int)*phuffman_table_bits;
+  huffman_mask = ((uint64_t)1 << huffman_table_bits) - 1;
+
+  if (streams == 1)
+    {
+      const unsigned char *pback;
+      const unsigned char *pbackend;
+      uint64_t val;
+      unsigned int bits;
+      uint32_t i;
+
+      pback = pin + total_streams_size - 1;
+      pbackend = pin;
+      if (!elf_fetch_backward_init (&pback, pbackend, &val, &bits))
+	return 0;
+
+      /* This is one of the inner loops of the decompression algorithm, so we
+	 put some effort into optimization.  We can't get more than 64 bytes
+	 from a single call to elf_fetch_bits_backward, and we can't subtract
+	 more than 11 bits at a time.  */
+
+      if (regenerated_size >= 64)
+	{
+	  unsigned char *plitstart;
+	  unsigned char *plitstop;
+
+	  plitstart = plit;
+	  plitstop = plit + regenerated_size - 64;
+	  while (plit < plitstop)
+	    {
+	      uint16_t t;
+
+	      if (!elf_fetch_bits_backward (&pback, pbackend, &val, &bits))
+		return 0;
+
+	      if (bits < 16)
+		break;
+
+	      while (bits >= 33)
+		{
+		  t = huffman_table[(val >> (bits - huffman_table_bits))
+				    & huffman_mask];
+		  *plit = t >> 8;
+		  ++plit;
+		  bits -= t & 0xff;
+
+		  t = huffman_table[(val >> (bits - huffman_table_bits))
+				    & huffman_mask];
+		  *plit = t >> 8;
+		  ++plit;
+		  bits -= t & 0xff;
+
+		  t = huffman_table[(val >> (bits - huffman_table_bits))
+				    & huffman_mask];
+		  *plit = t >> 8;
+		  ++plit;
+		  bits -= t & 0xff;
+		}
+
+	      while (bits > 11)
+		{
+		  t = huffman_table[(val >> (bits - huffman_table_bits))
+				    & huffman_mask];
+		  *plit = t >> 8;
+		  ++plit;
+		  bits -= t & 0xff;
+		}
+	    }
+
+	  regenerated_size -= plit - plitstart;
+	}
+
+      for (i = 0; i < regenerated_size; ++i)
+	{
+	  uint16_t t;
+
+	  if (!elf_fetch_bits_backward (&pback, pbackend, &val, &bits))
+	    return 0;
+
+	  if (unlikely (bits < huffman_table_bits))
+	    {
+	      t = huffman_table[(val << (huffman_table_bits - bits))
+				& huffman_mask];
+	      if (unlikely (bits < (t & 0xff)))
+		{
+		  elf_uncompress_failed ();
+		  return 0;
+		}
+	    }
+	  else
+	    t = huffman_table[(val >> (bits - huffman_table_bits))
+			      & huffman_mask];
+
+	  *plit = t >> 8;
+	  ++plit;
+	  bits -= t & 0xff;
+	}
+
+      return 1;
+    }
+
+  {
+    uint32_t stream_size1, stream_size2, stream_size3, stream_size4;
+    uint32_t tot;
+    const unsigned char *pback1, *pback2, *pback3, *pback4;
+    const unsigned char *pbackend1, *pbackend2, *pbackend3, *pbackend4;
+    uint64_t val1, val2, val3, val4;
+    unsigned int bits1, bits2, bits3, bits4;
+    unsigned char *plit1, *plit2, *plit3, *plit4;
+    uint32_t regenerated_stream_size;
+    uint32_t regenerated_stream_size4;
+    uint16_t t1, t2, t3, t4;
+    uint32_t i;
+    uint32_t limit;
+
+    /* Read jump table.  */
+    if (unlikely (pin + 5 >= pinend))
+      {
+	elf_uncompress_failed ();
+	return 0;
+      }
+    stream_size1 = (uint32_t)*pin | ((uint32_t)pin[1] << 8);
+    pin += 2;
+    stream_size2 = (uint32_t)*pin | ((uint32_t)pin[1] << 8);
+    pin += 2;
+    stream_size3 = (uint32_t)*pin | ((uint32_t)pin[1] << 8);
+    pin += 2;
+    tot = stream_size1 + stream_size2 + stream_size3;
+    if (unlikely (tot > total_streams_size - 6))
+      {
+	elf_uncompress_failed ();
+	return 0;
+      }
+    stream_size4 = total_streams_size - 6 - tot;
+
+    pback1 = pin + stream_size1 - 1;
+    pbackend1 = pin;
+
+    pback2 = pback1 + stream_size2;
+    pbackend2 = pback1 + 1;
+
+    pback3 = pback2 + stream_size3;
+    pbackend3 = pback2 + 1;
+
+    pback4 = pback3 + stream_size4;
+    pbackend4 = pback3 + 1;
+
+    if (!elf_fetch_backward_init (&pback1, pbackend1, &val1, &bits1))
+      return 0;
+    if (!elf_fetch_backward_init (&pback2, pbackend2, &val2, &bits2))
+      return 0;
+    if (!elf_fetch_backward_init (&pback3, pbackend3, &val3, &bits3))
+      return 0;
+    if (!elf_fetch_backward_init (&pback4, pbackend4, &val4, &bits4))
+      return 0;
+
+    regenerated_stream_size = (regenerated_size + 3) / 4;
+
+    plit1 = plit;
+    plit2 = plit1 + regenerated_stream_size;
+    plit3 = plit2 + regenerated_stream_size;
+    plit4 = plit3 + regenerated_stream_size;
+
+    regenerated_stream_size4 = regenerated_size - regenerated_stream_size * 3;
+
+    /* We can't get more than 64 literal bytes from a single call to
+       elf_fetch_bits_backward.  The fourth stream can be up to 3 bytes less,
+       so use as the limit.  */
+
+    limit = regenerated_stream_size4 <= 64 ? 0 : regenerated_stream_size4 - 64;
+    i = 0;
+    while (i < limit)
+      {
+	if (!elf_fetch_bits_backward (&pback1, pbackend1, &val1, &bits1))
+	  return 0;
+	if (!elf_fetch_bits_backward (&pback2, pbackend2, &val2, &bits2))
+	  return 0;
+	if (!elf_fetch_bits_backward (&pback3, pbackend3, &val3, &bits3))
+	  return 0;
+	if (!elf_fetch_bits_backward (&pback4, pbackend4, &val4, &bits4))
+	  return 0;
+
+	/* We can't subtract more than 11 bits at a time.  */
+
+	do
+	  {
+	    t1 = huffman_table[(val1 >> (bits1 - huffman_table_bits))
+			       & huffman_mask];
+	    t2 = huffman_table[(val2 >> (bits2 - huffman_table_bits))
+			       & huffman_mask];
+	    t3 = huffman_table[(val3 >> (bits3 - huffman_table_bits))
+			       & huffman_mask];
+	    t4 = huffman_table[(val4 >> (bits4 - huffman_table_bits))
+			       & huffman_mask];
+
+	    *plit1 = t1 >> 8;
+	    ++plit1;
+	    bits1 -= t1 & 0xff;
+
+	    *plit2 = t2 >> 8;
+	    ++plit2;
+	    bits2 -= t2 & 0xff;
+
+	    *plit3 = t3 >> 8;
+	    ++plit3;
+	    bits3 -= t3 & 0xff;
+
+	    *plit4 = t4 >> 8;
+	    ++plit4;
+	    bits4 -= t4 & 0xff;
+
+	    ++i;
+	  }
+	while (bits1 > 11 && bits2 > 11 && bits3 > 11 && bits4 > 11);
+      }
+
+    while (i < regenerated_stream_size)
+      {
+	int use4;
+
+	use4 = i < regenerated_stream_size4;
+
+	if (!elf_fetch_bits_backward (&pback1, pbackend1, &val1, &bits1))
+	  return 0;
+	if (!elf_fetch_bits_backward (&pback2, pbackend2, &val2, &bits2))
+	  return 0;
+	if (!elf_fetch_bits_backward (&pback3, pbackend3, &val3, &bits3))
+	  return 0;
+	if (use4)
+	  {
+	    if (!elf_fetch_bits_backward (&pback4, pbackend4, &val4, &bits4))
+	      return 0;
+	  }
+
+	if (unlikely (bits1 < huffman_table_bits))
+	  {
+	    t1 = huffman_table[(val1 << (huffman_table_bits - bits1))
+			       & huffman_mask];
+	    if (unlikely (bits1 < (t1 & 0xff)))
+	      {
+		elf_uncompress_failed ();
+		return 0;
+	      }
+	  }
+	else
+	  t1 = huffman_table[(val1 >> (bits1 - huffman_table_bits))
+			     & huffman_mask];
+
+	if (unlikely (bits2 < huffman_table_bits))
+	  {
+	    t2 = huffman_table[(val2 << (huffman_table_bits - bits2))
+			       & huffman_mask];
+	    if (unlikely (bits2 < (t2 & 0xff)))
+	      {
+		elf_uncompress_failed ();
+		return 0;
+	      }
+	  }
+	else
+	  t2 = huffman_table[(val2 >> (bits2 - huffman_table_bits))
+			     & huffman_mask];
+
+	if (unlikely (bits3 < huffman_table_bits))
+	  {
+	    t3 = huffman_table[(val3 << (huffman_table_bits - bits3))
+			       & huffman_mask];
+	    if (unlikely (bits3 < (t3 & 0xff)))
+	      {
+		elf_uncompress_failed ();
+		return 0;
+	      }
+	  }
+	else
+	  t3 = huffman_table[(val3 >> (bits3 - huffman_table_bits))
+			     & huffman_mask];
+
+	if (use4)
+	  {
+	    if (unlikely (bits4 < huffman_table_bits))
+	      {
+		t4 = huffman_table[(val4 << (huffman_table_bits - bits4))
+				   & huffman_mask];
+		if (unlikely (bits4 < (t4 & 0xff)))
+		  {
+		    elf_uncompress_failed ();
+		    return 0;
+		  }
+	      }
+	    else
+	      t4 = huffman_table[(val4 >> (bits4 - huffman_table_bits))
+				 & huffman_mask];
+
+	    *plit4 = t4 >> 8;
+	    ++plit4;
+	    bits4 -= t4 & 0xff;
+	  }
+
+	*plit1 = t1 >> 8;
+	++plit1;
+	bits1 -= t1 & 0xff;
+
+	*plit2 = t2 >> 8;
+	++plit2;
+	bits2 -= t2 & 0xff;
+
+	*plit3 = t3 >> 8;
+	++plit3;
+	bits3 -= t3 & 0xff;
+
+	++i;
+      }
+  }
+
+  return 1;
+}
+
+/* The information used to decompress a sequence code, which can be a literal
+   length, an offset, or a match length.  */
+
+struct elf_zstd_seq_decode
+{
+  const struct elf_zstd_fse_baseline_entry *table;
+  int table_bits;
+};
+
+/* Unpack a sequence code compression mode.  */
+
+static int
+elf_zstd_unpack_seq_decode (int mode,
+			    const unsigned char **ppin,
+			    const unsigned char *pinend,
+			    const struct elf_zstd_fse_baseline_entry *predef,
+			    int predef_bits,
+			    uint16_t *scratch,
+			    int maxidx,
+			    struct elf_zstd_fse_baseline_entry *table,
+			    int table_bits,
+			    int (*conv)(const struct elf_zstd_fse_entry *,
+					int,
+					struct elf_zstd_fse_baseline_entry *),
+			    struct elf_zstd_seq_decode *decode)
+{
+  switch (mode)
+    {
+    case 0:
+      decode->table = predef;
+      decode->table_bits = predef_bits;
+      break;
+
+    case 1:
+      {
+	struct elf_zstd_fse_entry entry;
+
+	if (unlikely (*ppin >= pinend))
+	  {
+	    elf_uncompress_failed ();
+	    return 0;
+	  }
+	entry.symbol = **ppin;
+	++*ppin;
+	entry.bits = 0;
+	entry.base = 0;
+	decode->table_bits = 0;
+	if (!conv (&entry, 0, table))
+	  return 0;
+      }
+      break;
+
+    case 2:
+      {
+	struct elf_zstd_fse_entry *fse_table;
+
+	/* We use the same space for the simple FSE table and the baseline
+	   table.  */
+	fse_table = (struct elf_zstd_fse_entry *)table;
+	decode->table_bits = table_bits;
+	if (!elf_zstd_read_fse (ppin, pinend, scratch, maxidx, fse_table,
+				&decode->table_bits))
+	  return 0;
+	if (!conv (fse_table, decode->table_bits, table))
+	  return 0;
+	decode->table = table;
+      }
+      break;
+
+    case 3:
+      if (unlikely (decode->table_bits == -1))
+	{
+	  elf_uncompress_failed ();
+	  return 0;
+	}
+      break;
+
+    default:
+      elf_uncompress_failed ();
+      return 0;
+    }
+
+  return 1;
+}
+
+/* Decompress a zstd stream from PIN/SIN to POUT/SOUT.  Code based on RFC 8878.
+   Return 1 on success, 0 on error.  */
+
+static int
+elf_zstd_decompress (const unsigned char *pin, size_t sin,
+		     unsigned char *zdebug_table, unsigned char *pout,
+		     size_t sout)
+{
+  const unsigned char *pinend;
+  unsigned char *poutstart;
+  unsigned char *poutend;
+  struct elf_zstd_seq_decode literal_decode;
+  struct elf_zstd_fse_baseline_entry *literal_fse_table;
+  struct elf_zstd_seq_decode match_decode;
+  struct elf_zstd_fse_baseline_entry *match_fse_table;
+  struct elf_zstd_seq_decode offset_decode;
+  struct elf_zstd_fse_baseline_entry *offset_fse_table;
+  uint16_t *huffman_table;
+  int huffman_table_bits;
+  uint32_t repeated_offset1;
+  uint32_t repeated_offset2;
+  uint32_t repeated_offset3;
+  uint16_t *scratch;
+  unsigned char hdr;
+  int has_checksum;
+  uint64_t content_size;
+  int last_block;
+
+  pinend = pin + sin;
+  poutstart = pout;
+  poutend = pout + sout;
+
+  literal_decode.table = NULL;
+  literal_decode.table_bits = -1;
+  literal_fse_table = ((struct elf_zstd_fse_baseline_entry *)
+		       (zdebug_table + ZSTD_TABLE_LITERAL_FSE_OFFSET));
+
+  match_decode.table = NULL;
+  match_decode.table_bits = -1;
+  match_fse_table = ((struct elf_zstd_fse_baseline_entry *)
+		     (zdebug_table + ZSTD_TABLE_MATCH_FSE_OFFSET));
+
+  offset_decode.table = NULL;
+  offset_decode.table_bits = -1;
+  offset_fse_table = ((struct elf_zstd_fse_baseline_entry *)
+		      (zdebug_table + ZSTD_TABLE_OFFSET_FSE_OFFSET));
+  huffman_table = ((uint16_t *)
+		   (zdebug_table + ZSTD_TABLE_HUFFMAN_OFFSET));
+  huffman_table_bits = 0;
+  scratch = ((uint16_t *)
+	     (zdebug_table + ZSTD_TABLE_WORK_OFFSET));
+
+  repeated_offset1 = 1;
+  repeated_offset2 = 4;
+  repeated_offset3 = 8;
+
+  if (unlikely (sin < 4))
+    {
+      elf_uncompress_failed ();
+      return 0;
+    }
+
+  /* These values are the zstd magic number.  */
+  if (unlikely (pin[0] != 0x28
+		|| pin[1] != 0xb5
+		|| pin[2] != 0x2f
+		|| pin[3] != 0xfd))
+    {
+      elf_uncompress_failed ();
+      return 0;
+    }
+
+  pin += 4;
+
+  if (unlikely (pin >= pinend))
+    {
+      elf_uncompress_failed ();
+      return 0;
+    }
+
+  hdr = *pin++;
+
+  /* We expect a single frame.  */
+  if (unlikely ((hdr & (1 << 5)) == 0))
+    {
+      elf_uncompress_failed ();
+      return 0;
+    }
+  /* Reserved bit must be zero.  */
+  if (unlikely ((hdr & (1 << 3)) != 0))
+    {
+      elf_uncompress_failed ();
+      return 0;
+    }
+  /* We do not expect a dictionary.  */
+  if (unlikely ((hdr & 3) != 0))
+    {
+      elf_uncompress_failed ();
+      return 0;
+    }
+  has_checksum = (hdr & (1 << 2)) != 0;
+  switch (hdr >> 6)
+    {
+    case 0:
+      if (unlikely (pin >= pinend))
+	{
+	  elf_uncompress_failed ();
+	  return 0;
+	}
+      content_size = (uint64_t) *pin++;
+      break;
+    case 1:
+      if (unlikely (pin + 1 >= pinend))
+	{
+	  elf_uncompress_failed ();
+	  return 0;
+	}
+      content_size = (((uint64_t) pin[0]) | (((uint64_t) pin[1]) << 8)) + 256;
+      pin += 2;
+      break;
+    case 2:
+      if (unlikely (pin + 3 >= pinend))
+	{
+	  elf_uncompress_failed ();
+	  return 0;
+	}
+      content_size = ((uint64_t) pin[0]
+		      | (((uint64_t) pin[1]) << 8)
+		      | (((uint64_t) pin[2]) << 16)
+		      | (((uint64_t) pin[3]) << 24));
+      pin += 4;
+      break;
+    case 3:
+      if (unlikely (pin + 7 >= pinend))
+	{
+	  elf_uncompress_failed ();
+	  return 0;
+	}
+      content_size = ((uint64_t) pin[0]
+		      | (((uint64_t) pin[1]) << 8)
+		      | (((uint64_t) pin[2]) << 16)
+		      | (((uint64_t) pin[3]) << 24)
+		      | (((uint64_t) pin[4]) << 32)
+		      | (((uint64_t) pin[5]) << 40)
+		      | (((uint64_t) pin[6]) << 48)
+		      | (((uint64_t) pin[7]) << 56));
+      pin += 8;
+      break;
+    default:
+      elf_uncompress_failed ();
+      return 0;
+    }
+
+  if (unlikely (content_size != (size_t) content_size
+		|| (size_t) content_size != sout))
+    {
+      elf_uncompress_failed ();
+      return 0;
+    }
+
+  last_block = 0;
+  while (!last_block)
+    {
+      uint32_t block_hdr;
+      int block_type;
+      uint32_t block_size;
+
+      if (unlikely (pin + 2 >= pinend))
+	{
+	  elf_uncompress_failed ();
+	  return 0;
+	}
+      block_hdr = ((uint32_t) pin[0]
+		   | (((uint32_t) pin[1]) << 8)
+		   | (((uint32_t) pin[2]) << 16));
+      pin += 3;
+
+      last_block = block_hdr & 1;
+      block_type = (block_hdr >> 1) & 3;
+      block_size = block_hdr >> 3;
+
+      switch (block_type)
+	{
+	case 0:
+	  /* Raw_Block */
+	  if (unlikely ((size_t) block_size > (size_t) (pinend - pin)))
+	    {
+	      elf_uncompress_failed ();
+	      return 0;
+	    }
+	  if (unlikely ((size_t) block_size > (size_t) (poutend - pout)))
+	    {
+	      elf_uncompress_failed ();
+	      return 0;
+	    }
+	  memcpy (pout, pin, block_size);
+	  pout += block_size;
+	  pin += block_size;
+	  break;
+
+	case 1:
+	  /* RLE_Block */
+	  if (unlikely (pin >= pinend))
+	    {
+	      elf_uncompress_failed ();
+	      return 0;
+	    }
+	  if (unlikely ((size_t) block_size > (size_t) (poutend - pout)))
+	    {
+	      elf_uncompress_failed ();
+	      return 0;
+	    }
+	  memset (pout, *pin, block_size);
+	  pout += block_size;
+	  pin++;
+	  break;
+
+	case 2:
+	  {
+	    const unsigned char *pblockend;
+	    unsigned char *plitstack;
+	    unsigned char *plit;
+	    uint32_t literal_count;
+	    unsigned char seq_hdr;
+	    size_t seq_count;
+	    size_t seq;
+	    const unsigned char *pback;
+	    uint64_t val;
+	    unsigned int bits;
+	    unsigned int literal_state;
+	    unsigned int offset_state;
+	    unsigned int match_state;
+
+	    /* Compressed_Block */
+	    if (unlikely ((size_t) block_size > (size_t) (pinend - pin)))
+	      {
+		elf_uncompress_failed ();
+		return 0;
+	      }
+
+	    pblockend = pin + block_size;
+
+	    /* Read the literals into the end of the output space, and leave
+	       PLIT pointing at them.  */
+
+	    if (!elf_zstd_read_literals (&pin, pblockend, pout, poutend,
+					 scratch, huffman_table,
+					 &huffman_table_bits,
+					 &plitstack))
+	      return 0;
+	    plit = plitstack;
+	    literal_count = poutend - plit;
+
+	    seq_hdr = *pin;
+	    pin++;
+	    if (seq_hdr < 128)
+	      seq_count = seq_hdr;
+	    else if (seq_hdr < 255)
+	      {
+		if (unlikely (pin >= pinend))
+		  {
+		    elf_uncompress_failed ();
+		    return 0;
+		  }
+		seq_count = ((seq_hdr - 128) << 8) + *pin;
+		pin++;
+	      }
+	    else
+	      {
+		if (unlikely (pin + 1 >= pinend))
+		  {
+		    elf_uncompress_failed ();
+		    return 0;
+		  }
+		seq_count = *pin + (pin[1] << 8) + 0x7f00;
+		pin += 2;
+	      }
+
+	    if (seq_count > 0)
+	      {
+		int (*pfn)(const struct elf_zstd_fse_entry *,
+			   int, struct elf_zstd_fse_baseline_entry *);
+
+		if (unlikely (pin >= pinend))
+		  {
+		    elf_uncompress_failed ();
+		    return 0;
+		  }
+		seq_hdr = *pin;
+		++pin;
+
+		pfn = elf_zstd_make_literal_baseline_fse;
+		if (!elf_zstd_unpack_seq_decode ((seq_hdr >> 6) & 3,
+						 &pin, pinend,
+						 &elf_zstd_lit_table[0], 6,
+						 scratch, 35,
+						 literal_fse_table, 9, pfn,
+						 &literal_decode))
+		  return 0;
+
+		pfn = elf_zstd_make_offset_baseline_fse;
+		if (!elf_zstd_unpack_seq_decode ((seq_hdr >> 4) & 3,
+						 &pin, pinend,
+						 &elf_zstd_offset_table[0], 5,
+						 scratch, 31,
+						 offset_fse_table, 8, pfn,
+						 &offset_decode))
+		  return 0;
+
+		pfn = elf_zstd_make_match_baseline_fse;
+		if (!elf_zstd_unpack_seq_decode ((seq_hdr >> 2) & 3,
+						 &pin, pinend,
+						 &elf_zstd_match_table[0], 6,
+						 scratch, 52,
+						 match_fse_table, 9, pfn,
+						 &match_decode))
+		  return 0;
+	      }
+
+	    pback = pblockend - 1;
+	    if (!elf_fetch_backward_init (&pback, pin, &val, &bits))
+	      return 0;
+
+	    bits -= literal_decode.table_bits;
+	    literal_state = ((val >> bits)
+			     & ((1U << literal_decode.table_bits) - 1));
+
+	    if (!elf_fetch_bits_backward (&pback, pin, &val, &bits))
+	      return 0;
+	    bits -= offset_decode.table_bits;
+	    offset_state = ((val >> bits)
+			    & ((1U << offset_decode.table_bits) - 1));
+
+	    if (!elf_fetch_bits_backward (&pback, pin, &val, &bits))
+	      return 0;
+	    bits -= match_decode.table_bits;
+	    match_state = ((val >> bits)
+			   & ((1U << match_decode.table_bits) - 1));
+
+	    seq = 0;
+	    while (1)
+	      {
+		const struct elf_zstd_fse_baseline_entry *pt;
+		uint32_t offset_basebits;
+		uint32_t offset_baseline;
+		uint32_t offset_bits;
+		uint32_t offset_base;
+		uint32_t offset;
+		uint32_t match_baseline;
+		uint32_t match_bits;
+		uint32_t match_base;
+		uint32_t match;
+		uint32_t literal_baseline;
+		uint32_t literal_bits;
+		uint32_t literal_base;
+		uint32_t literal;
+		uint32_t need;
+		uint32_t add;
+
+		pt = &offset_decode.table[offset_state];
+		offset_basebits = pt->basebits;
+		offset_baseline = pt->baseline;
+		offset_bits = pt->bits;
+		offset_base = pt->base;
+
+		/* This case can be more than 16 bits, which is all that
+		   elf_fetch_bits_backward promises.  */
+		need = offset_basebits;
+		add = 0;
+		if (unlikely (need > 16))
+		  {
+		    if (!elf_fetch_bits_backward (&pback, pin, &val, &bits))
+		      return 0;
+		    bits -= 16;
+		    add = (val >> bits) & ((1U << 16) - 1);
+		    need -= 16;
+		    add <<= need;
+		  }
+		if (need > 0)
+		  {
+		    if (!elf_fetch_bits_backward (&pback, pin, &val, &bits))
+		      return 0;
+		    bits -= need;
+		    add += (val >> bits) & ((1U << need) - 1);
+		  }
+
+		offset = offset_baseline + add;
+
+		pt = &match_decode.table[match_state];
+		need = pt->basebits;
+		match_baseline = pt->baseline;
+		match_bits = pt->bits;
+		match_base = pt->base;
+
+		add = 0;
+		if (need > 0)
+		  {
+		    if (!elf_fetch_bits_backward (&pback, pin, &val, &bits))
+		      return 0;
+		    bits -= need;
+		    add = (val >> bits) & ((1U << need) - 1);
+		  }
+
+		match = match_baseline + add;
+
+		pt = &literal_decode.table[literal_state];
+		need = pt->basebits;
+		literal_baseline = pt->baseline;
+		literal_bits = pt->bits;
+		literal_base = pt->base;
+
+		add = 0;
+		if (need > 0)
+		  {
+		    if (!elf_fetch_bits_backward (&pback, pin, &val, &bits))
+		      return 0;
+		    bits -= need;
+		    add = (val >> bits) & ((1U << need) - 1);
+		  }
+
+		literal = literal_baseline + add;
+
+		/* See the comment in elf_zstd_make_offset_baseline_fse.  */
+		if (offset_basebits > 1)
+		  {
+		    repeated_offset3 = repeated_offset2;
+		    repeated_offset2 = repeated_offset1;
+		    repeated_offset1 = offset;
+		  }
+		else
+		  {
+		    if (unlikely (literal == 0))
+		      ++offset;
+		    switch (offset)
+		      {
+		      case 1:
+			offset = repeated_offset1;
+			break;
+		      case 2:
+			offset = repeated_offset2;
+			repeated_offset2 = repeated_offset1;
+			repeated_offset1 = offset;
+			break;
+		      case 3:
+			offset = repeated_offset3;
+			repeated_offset3 = repeated_offset2;
+			repeated_offset2 = repeated_offset1;
+			repeated_offset1 = offset;
+			break;
+		      case 4:
+			offset = repeated_offset1 - 1;
+			repeated_offset3 = repeated_offset2;
+			repeated_offset2 = repeated_offset1;
+			repeated_offset1 = offset;
+			break;
+		      }
+		  }
+
+		++seq;
+		if (seq < seq_count)
+		  {
+		    uint32_t v;
+
+		    /* Update the three states.  */
+
+		    if (!elf_fetch_bits_backward (&pback, pin, &val, &bits))
+		      return 0;
+
+		    need = literal_bits;
+		    bits -= need;
+		    v = (val >> bits) & (((uint32_t)1 << need) - 1);
+
+		    literal_state = literal_base + v;
+
+		    if (!elf_fetch_bits_backward (&pback, pin, &val, &bits))
+		      return 0;
+
+		    need = match_bits;
+		    bits -= need;
+		    v = (val >> bits) & (((uint32_t)1 << need) - 1);
+
+		    match_state = match_base + v;
+
+		    if (!elf_fetch_bits_backward (&pback, pin, &val, &bits))
+		      return 0;
+
+		    need = offset_bits;
+		    bits -= need;
+		    v = (val >> bits) & (((uint32_t)1 << need) - 1);
+
+		    offset_state = offset_base + v;
+		  }
+
+		/* The next sequence is now in LITERAL, OFFSET, MATCH.  */
+
+		/* Copy LITERAL bytes from the literals.  */
+
+		if (unlikely ((size_t)(poutend - pout) < literal))
+		  {
+		    elf_uncompress_failed ();
+		    return 0;
+		  }
+
+		if (unlikely (literal_count < literal))
+		  {
+		    elf_uncompress_failed ();
+		    return 0;
+		  }
+
+		literal_count -= literal;
+
+		/* Often LITERAL is small, so handle small cases quickly.  */
+		switch (literal)
+		  {
+		  case 8:
+		    *pout++ = *plit++;
+		    /* FALLTHROUGH */
+		  case 7:
+		    *pout++ = *plit++;
+		    /* FALLTHROUGH */
+		  case 6:
+		    *pout++ = *plit++;
+		    /* FALLTHROUGH */
+		  case 5:
+		    *pout++ = *plit++;
+		    /* FALLTHROUGH */
+		  case 4:
+		    *pout++ = *plit++;
+		    /* FALLTHROUGH */
+		  case 3:
+		    *pout++ = *plit++;
+		    /* FALLTHROUGH */
+		  case 2:
+		    *pout++ = *plit++;
+		    /* FALLTHROUGH */
+		  case 1:
+		    *pout++ = *plit++;
+		    break;
+
+		  case 0:
+		    break;
+
+		  default:
+		    if (unlikely ((size_t)(plit - pout) < literal))
+		      {
+			uint32_t move;
+
+			move = plit - pout;
+			while (literal > move)
+			  {
+			    memcpy (pout, plit, move);
+			    pout += move;
+			    plit += move;
+			    literal -= move;
+			  }
+		      }
+
+		    memcpy (pout, plit, literal);
+		    pout += literal;
+		    plit += literal;
+		  }
+
+		if (match > 0)
+		  {
+		    /* Copy MATCH bytes from the decoded output at OFFSET.  */
+
+		    if (unlikely ((size_t)(poutend - pout) < match))
+		      {
+			elf_uncompress_failed ();
+			return 0;
+		      }
+
+		    if (unlikely ((size_t)(pout - poutstart) < offset))
+		      {
+			elf_uncompress_failed ();
+			return 0;
+		      }
+
+		    if (offset >= match)
+		      {
+			memcpy (pout, pout - offset, match);
+			pout += match;
+		      }
+		    else
+		      {
+			while (match > 0)
+			  {
+			    uint32_t copy;
+
+			    copy = match < offset ? match : offset;
+			    memcpy (pout, pout - offset, copy);
+			    match -= copy;
+			    pout += copy;
+			  }
+		      }
+		  }
+
+		if (unlikely (seq >= seq_count))
+		  {
+		    /* Copy remaining literals.  */
+		    if (literal_count > 0 && plit != pout)
+		      {
+			if (unlikely ((size_t)(poutend - pout)
+				      < literal_count))
+			  {
+			    elf_uncompress_failed ();
+			    return 0;
+			  }
+
+			if ((size_t)(plit - pout) < literal_count)
+			  {
+			    uint32_t move;
+
+			    move = plit - pout;
+			    while (literal_count > move)
+			      {
+				memcpy (pout, plit, move);
+				pout += move;
+				plit += move;
+				literal_count -= move;
+			      }
+			  }
+
+			memcpy (pout, plit, literal_count);
+		      }
+
+		    pout += literal_count;
+
+		    break;
+		  }
+	      }
+
+	    pin = pblockend;
+	  }
+	  break;
+
+	case 3:
+	default:
+	  elf_uncompress_failed ();
+	  return 0;
+	}
+    }
+
+  if (has_checksum)
+    {
+      if (unlikely (pin + 4 > pinend))
+	{
+	  elf_uncompress_failed ();
+	  return 0;
+	}
+
+      /* We don't currently verify the checksum.  Currently running GNU ld with
+	 --compress-debug-sections=zstd does not seem to generate a
+	 checksum.  */
+
+      pin += 4;
+    }
+
+  if (pin != pinend)
+    {
+      elf_uncompress_failed ();
+      return 0;
+    }
+
+  return 1;
+}
+
+#define ZDEBUG_TABLE_SIZE \
+  (ZLIB_TABLE_SIZE > ZSTD_TABLE_SIZE ? ZLIB_TABLE_SIZE : ZSTD_TABLE_SIZE)
+
+/* Uncompress the old compressed debug format, the one emitted by
+   --compress-debug-sections=zlib-gnu.  The compressed data is in
+   COMPRESSED / COMPRESSED_SIZE, and the function writes to
+   *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 <mach-o/dyld.h>
 #endif
 
+#ifdef HAVE_WINDOWS_H
+#ifndef WIN32_MEAN_AND_LEAN
+#define WIN32_MEAN_AND_LEAN
+#endif
+
+#ifndef NOMINMAX
+#define NOMINMAX
+#endif
+
+#include <windows.h>
+#endif
+
 #include "backtrace.h"
 #include "internal.h"
 
@@ -155,6 +167,47 @@  macho_get_executable_path (struct backtrace_state *state,
 
 #endif /* !defined (HAVE_MACH_O_DYLD_H) */
 
+#if HAVE_DECL__PGMPTR
+
+#define windows_executable_filename() _pgmptr
+
+#else /* !HAVE_DECL__PGMPTR */
+
+#define windows_executable_filename() NULL
+
+#endif /* !HAVE_DECL__PGMPTR */
+
+#ifdef HAVE_WINDOWS_H
+
+#define FILENAME_BUF_SIZE (MAX_PATH)
+
+static char *
+windows_get_executable_path (char *buf, backtrace_error_callback error_callback,
+			     void *data)
+{
+  size_t got;
+  int error;
+
+  got = GetModuleFileNameA (NULL, buf, FILENAME_BUF_SIZE - 1);
+  error = GetLastError ();
+  if (got == 0
+      || (got == FILENAME_BUF_SIZE - 1 && error == ERROR_INSUFFICIENT_BUFFER))
+    {
+      error_callback (data,
+		      "could not get the filename of the current executable",
+		      error);
+      return NULL;
+    }
+  return buf;
+}
+
+#else /* !defined (HAVE_WINDOWS_H) */
+
+#define windows_get_executable_path(buf, error_callback, data) NULL
+#define FILENAME_BUF_SIZE 64
+
+#endif /* !defined (HAVE_WINDOWS_H) */
+
 /* Initialize the fileline information from the executable.  Returns 1
    on success, 0 on failure.  */
 
@@ -168,7 +221,7 @@  fileline_initialize (struct backtrace_state *state,
   int called_error_callback;
   int descriptor;
   const char *filename;
-  char buf[64];
+  char buf[FILENAME_BUF_SIZE];
 
   if (!state->threaded)
     failed = state->fileline_initialization_failed;
@@ -192,7 +245,7 @@  fileline_initialize (struct backtrace_state *state,
 
   descriptor = -1;
   called_error_callback = 0;
-  for (pass = 0; pass < 8; ++pass)
+  for (pass = 0; pass < 10; ++pass)
     {
       int does_not_exist;
 
@@ -205,25 +258,33 @@  fileline_initialize (struct backtrace_state *state,
 	  filename = getexecname ();
 	  break;
 	case 2:
-	  filename = "/proc/self/exe";
+	  /* Test this before /proc/self/exe, as the latter exists but points
+	     to the wine binary (and thus doesn't work).  */
+	  filename = windows_executable_filename ();
 	  break;
 	case 3:
-	  filename = "/proc/curproc/file";
+	  filename = "/proc/self/exe";
 	  break;
 	case 4:
+	  filename = "/proc/curproc/file";
+	  break;
+	case 5:
 	  snprintf (buf, sizeof (buf), "/proc/%ld/object/a.out",
 		    (long) getpid ());
 	  filename = buf;
 	  break;
-	case 5:
+	case 6:
 	  filename = sysctl_exec_name1 (state, error_callback, data);
 	  break;
-	case 6:
+	case 7:
 	  filename = sysctl_exec_name2 (state, error_callback, data);
 	  break;
-	case 7:
+	case 8:
 	  filename = macho_get_executable_path (state, error_callback, data);
 	  break;
+	case 9:
+	  filename = windows_get_executable_path (buf, error_callback, data);
+	  break;
 	default:
 	  abort ();
 	}
diff --git a/libbacktrace/install-debuginfo-for-buildid.sh.in b/libbacktrace/install-debuginfo-for-buildid.sh.in
index 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 <windows.h>
+#endif
+
 /* Coff file header.  */
 
 typedef struct {
@@ -610,6 +622,7 @@  coff_add (struct backtrace_state *state, int descriptor,
   int debug_view_valid;
   int is_64;
   uintptr_t image_base;
+  uintptr_t base_address = 0;
   struct dwarf_sections dwarf_sections;
 
   *found_sym = 0;
@@ -856,7 +869,16 @@  coff_add (struct backtrace_state *state, int descriptor,
 				  + (sections[i].offset - min_offset));
     }
 
-  if (!backtrace_dwarf_add (state, /* base_address */ 0, &dwarf_sections,
+#ifdef HAVE_WINDOWS_H
+  {
+    uintptr_t module_handle;
+
+    module_handle = (uintptr_t) GetModuleHandle (NULL);
+    base_address = module_handle - image_base;
+  }
+#endif
+
+  if (!backtrace_dwarf_add (state, base_address, &dwarf_sections,
 			    0, /* FIXME: is_bigendian */
 			    NULL, /* altlink */
 			    error_callback, data, fileline_fn,
diff --git a/libbacktrace/posix.c b/libbacktrace/posix.c
index 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