binutils, gdb: support zstd compressed debug sections
authorFangrui Song <maskray@google.com>
Tue, 27 Sep 2022 02:50:13 +0000 (19:50 -0700)
committerFangrui Song <i@maskray.me>
Tue, 27 Sep 2022 02:50:13 +0000 (19:50 -0700)
PR29397 PR29563: Add new configure option --with-zstd which defaults to
auto.  If pkgconfig/libzstd.pc is found, define HAVE_ZSTD and support
zstd compressed debug sections for most tools.

* bfd: for addr2line, objdump --dwarf, gdb, etc
* gas: support --compress-debug-sections=zstd
* ld: support ELFCOMPRESS_ZSTD input and --compress-debug-sections=zstd
* objcopy: support ELFCOMPRESS_ZSTD input for
  --decompress-debug-sections and --compress-debug-sections=zstd
* gdb: support ELFCOMPRESS_ZSTD input.  The bfd change references zstd
  symbols, so gdb has to link against -lzstd in this patch.

If zstd is not supported, ELFCOMPRESS_ZSTD input triggers an error.  We
can avoid HAVE_ZSTD if binutils-gdb imports zstd/ like zlib/, but this
is too heavyweight, so don't do it for now.

```
% ld/ld-new a.o
ld/ld-new: a.o: section .debug_abbrev is compressed with zstd, but BFD is not built with zstd support
...

% ld/ld-new a.o --compress-debug-sections=zstd
ld/ld-new: --compress-debug-sections=zstd: ld is not built with zstd support

% binutils/objcopy --compress-debug-sections=zstd a.o b.o
binutils/objcopy: --compress-debug-sections=zstd: binutils is not built with zstd support

% binutils/objcopy b.o --decompress-debug-sections
binutils/objcopy: zstd.o: section .debug_abbrev is compressed with zstd, but BFD is not built with zstd support
...
```

56 files changed:
bfd/Makefile.am
bfd/Makefile.in
bfd/aclocal.m4
bfd/bfd-in.h
bfd/bfd-in2.h
bfd/bfd.c
bfd/compress.c
bfd/config.in
bfd/configure
bfd/configure.ac
bfd/elf.c
bfd/elfxx-target.h
bfd/section.c
binutils/Makefile.in
binutils/NEWS
binutils/aclocal.m4
binutils/config.in
binutils/configure
binutils/configure.ac
binutils/doc/binutils.texi
binutils/objcopy.c
binutils/testsuite/binutils-all/compress.exp
config/zstd.m4 [new file with mode: 0644]
configure
configure.ac
gas/Makefile.am
gas/Makefile.in
gas/NEWS
gas/aclocal.m4
gas/as.c
gas/compress-debug.c
gas/compress-debug.h
gas/config.in
gas/configure
gas/configure.ac
gas/doc/as.texi
gas/write.c
gdb/Makefile.in
gdb/NEWS
gdb/acinclude.m4
gdb/config.in
gdb/configure
gdb/configure.ac
ld/Makefile.am
ld/Makefile.in
ld/NEWS
ld/aclocal.m4
ld/config.in
ld/configure
ld/configure.ac
ld/emultempl/elf.em
ld/ld.texi
ld/ldmain.c
ld/lexsup.c
ld/testsuite/ld-bootstrap/bootstrap.exp
ld/testsuite/ld-elf/compress.exp

index a5652b2a9c774c7e72d1b2e8738a3e8b9967ead2..98a487b7fcd4cefdfa214b02a7733a63186c4f39 100644 (file)
@@ -57,7 +57,7 @@ ZLIBINC = @zlibinc@
 
 WARN_CFLAGS = @WARN_CFLAGS@
 NO_WERROR = @NO_WERROR@
-AM_CFLAGS = $(WARN_CFLAGS) $(ZLIBINC)
+AM_CFLAGS = $(WARN_CFLAGS) $(ZLIBINC) $(ZSTD_CFLAGS)
 AM_CPPFLAGS = -DBINDIR='"$(bindir)"' -DLIBDIR='"$(libdir)"' @LARGEFILE_CPPFLAGS@
 if PLUGINS
 bfdinclude_HEADERS += $(INCDIR)/plugin-api.h
@@ -776,7 +776,7 @@ ofiles: stamp-ofiles ; @true
 libbfd_la_SOURCES = $(BFD32_LIBS_CFILES)
 EXTRA_libbfd_la_SOURCES = $(CFILES)
 libbfd_la_DEPENDENCIES = $(OFILES) ofiles
-libbfd_la_LIBADD = `cat ofiles` @SHARED_LIBADD@ $(LIBDL) $(ZLIB)
+libbfd_la_LIBADD = `cat ofiles` @SHARED_LIBADD@ $(LIBDL) $(ZLIB) $(ZSTD_LIBS)
 libbfd_la_LDFLAGS += -release `cat libtool-soversion` @SHARED_LDFLAGS@
 
 # libtool will build .libs/libbfd.a.  We create libbfd.a in the build
index 83d686529a0c45cb1bc5bc30e31f7fceee6162de..3c9ebf38f839aa8b53b26e53281af66df0db8197 100644 (file)
@@ -122,10 +122,12 @@ am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
        $(top_srcdir)/../config/lead-dot.m4 \
        $(top_srcdir)/../config/nls.m4 \
        $(top_srcdir)/../config/override.m4 \
+       $(top_srcdir)/../config/pkg.m4 \
        $(top_srcdir)/../config/plugins.m4 \
        $(top_srcdir)/../config/po.m4 \
        $(top_srcdir)/../config/progtest.m4 \
-       $(top_srcdir)/../config/zlib.m4 $(top_srcdir)/../libtool.m4 \
+       $(top_srcdir)/../config/zlib.m4 \
+       $(top_srcdir)/../config/zstd.m4 $(top_srcdir)/../libtool.m4 \
        $(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \
        $(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \
        $(top_srcdir)/bfd.m4 $(top_srcdir)/warning.m4 \
@@ -399,6 +401,9 @@ PACKAGE_URL = @PACKAGE_URL@
 PACKAGE_VERSION = @PACKAGE_VERSION@
 PATH_SEPARATOR = @PATH_SEPARATOR@
 PKGVERSION = @PKGVERSION@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 POSUB = @POSUB@
 RANLIB = @RANLIB@
 REPORT_BUGS_TEXI = @REPORT_BUGS_TEXI@
@@ -416,6 +421,8 @@ WARN_CFLAGS = @WARN_CFLAGS@
 WARN_CFLAGS_FOR_BUILD = @WARN_CFLAGS_FOR_BUILD@
 WARN_WRITE_STRINGS = @WARN_WRITE_STRINGS@
 XGETTEXT = @XGETTEXT@
+ZSTD_CFLAGS = @ZSTD_CFLAGS@
+ZSTD_LIBS = @ZSTD_LIBS@
 abs_builddir = @abs_builddir@
 abs_srcdir = @abs_srcdir@
 abs_top_builddir = @abs_top_builddir@
@@ -520,7 +527,7 @@ libbfd_la_LDFLAGS = $(am__append_1) -release `cat libtool-soversion` \
 # case both are empty.
 ZLIB = @zlibdir@ -lz
 ZLIBINC = @zlibinc@
-AM_CFLAGS = $(WARN_CFLAGS) $(ZLIBINC)
+AM_CFLAGS = $(WARN_CFLAGS) $(ZLIBINC) $(ZSTD_CFLAGS)
 AM_CPPFLAGS = -DBINDIR='"$(bindir)"' -DLIBDIR='"$(libdir)"' \
        @LARGEFILE_CPPFLAGS@ @HDEFINES@ @COREFLAG@ @TDEFINES@ \
        $(CSEARCH) $(CSWITCHES) $(HAVEVECS) @INCINTL@
@@ -1199,7 +1206,7 @@ OFILES = $(BFD_BACKENDS) $(BFD_MACHINES) @COREFILE@ @bfd64_libs@
 libbfd_la_SOURCES = $(BFD32_LIBS_CFILES)
 EXTRA_libbfd_la_SOURCES = $(CFILES)
 libbfd_la_DEPENDENCIES = $(OFILES) ofiles
-libbfd_la_LIBADD = `cat ofiles` @SHARED_LIBADD@ $(LIBDL) $(ZLIB)
+libbfd_la_LIBADD = `cat ofiles` @SHARED_LIBADD@ $(LIBDL) $(ZLIB) $(ZSTD_LIBS)
 
 # libtool will build .libs/libbfd.a.  We create libbfd.a in the build
 # directory so that we don't have to convert all the programs that use
index 0f8aa1d4518b629810c44de0a549f2c62c554ae1..09b849dfc87fc4b4eedf16d2bb9c72d4db51ed6c 100644 (file)
@@ -1176,10 +1176,12 @@ m4_include([../config/largefile.m4])
 m4_include([../config/lead-dot.m4])
 m4_include([../config/nls.m4])
 m4_include([../config/override.m4])
+m4_include([../config/pkg.m4])
 m4_include([../config/plugins.m4])
 m4_include([../config/po.m4])
 m4_include([../config/progtest.m4])
 m4_include([../config/zlib.m4])
+m4_include([../config/zstd.m4])
 m4_include([../libtool.m4])
 m4_include([../ltoptions.m4])
 m4_include([../ltsugar.m4])
index 8605056aefe6837efbbaeaabd56564082506d1ed..4765ea8053604ccd9713b00f91d132ba67ecc1a7 100644 (file)
@@ -342,7 +342,8 @@ enum compressed_debug_section_type
   COMPRESS_DEBUG_NONE = 0,
   COMPRESS_DEBUG = 1 << 0,
   COMPRESS_DEBUG_GNU_ZLIB = COMPRESS_DEBUG | 1 << 1,
-  COMPRESS_DEBUG_GABI_ZLIB = COMPRESS_DEBUG | 1 << 2
+  COMPRESS_DEBUG_GABI_ZLIB = COMPRESS_DEBUG | 1 << 2,
+  COMPRESS_DEBUG_ZSTD = COMPRESS_DEBUG | 1 << 3
 };
 
 /* This structure is used to keep track of stabs in sections
index 79fcc4eb912cae7057afa238e67798f54a18d9ff..5c80956c79c09492b27771a4429ca1264d837e64 100644 (file)
@@ -349,7 +349,8 @@ enum compressed_debug_section_type
   COMPRESS_DEBUG_NONE = 0,
   COMPRESS_DEBUG = 1 << 0,
   COMPRESS_DEBUG_GNU_ZLIB = COMPRESS_DEBUG | 1 << 1,
-  COMPRESS_DEBUG_GABI_ZLIB = COMPRESS_DEBUG | 1 << 2
+  COMPRESS_DEBUG_GABI_ZLIB = COMPRESS_DEBUG | 1 << 2,
+  COMPRESS_DEBUG_ZSTD = COMPRESS_DEBUG | 1 << 3
 };
 
 /* This structure is used to keep track of stabs in sections
@@ -962,7 +963,8 @@ typedef struct bfd_section
   unsigned int compress_status : 2;
 #define COMPRESS_SECTION_NONE    0
 #define COMPRESS_SECTION_DONE    1
-#define DECOMPRESS_SECTION_SIZED 2
+#define DECOMPRESS_SECTION_ZLIB  2
+#define DECOMPRESS_SECTION_ZSTD  3
 
   /* The following flags are used by the ELF linker. */
 
@@ -6637,12 +6639,14 @@ struct bfd
 #define BFD_ARCHIVE_FULL_PATH  0x100000
 
 #define BFD_CLOSED_BY_CACHE    0x200000
+  /* Compress sections in this BFD with SHF_COMPRESSED zstd.  */
+#define BFD_COMPRESS_ZSTD      0x400000
 
   /* Flags bits to be saved in bfd_preserve_save.  */
 #define BFD_FLAGS_SAVED \
   (BFD_IN_MEMORY | BFD_COMPRESS | BFD_DECOMPRESS | BFD_LINKER_CREATED \
    | BFD_PLUGIN | BFD_COMPRESS_GABI | BFD_CONVERT_ELF_COMMON \
-   | BFD_USE_ELF_STT_COMMON)
+   | BFD_USE_ELF_STT_COMMON | BFD_COMPRESS_ZSTD)
 
   /* Flags bits which are for BFD use only.  */
 #define BFD_FLAGS_FOR_BFD_USE_MASK \
@@ -7271,6 +7275,7 @@ void bfd_update_compression_header
 
 bool bfd_check_compression_header
    (bfd *abfd, bfd_byte *contents, asection *sec,
+    unsigned int *ch_type,
     bfd_size_type *uncompressed_size,
     unsigned int *uncompressed_alignment_power);
 
index 0a21db11fd65d043be185d97bf9dea41380e5a7f..5f2033bee7a1500fdc0219c2af87726551ba2173 100644 (file)
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -177,12 +177,15 @@ CODE_FRAGMENT
 .#define BFD_ARCHIVE_FULL_PATH  0x100000
 .
 .#define BFD_CLOSED_BY_CACHE    0x200000
+
+.  {* Compress sections in this BFD with SHF_COMPRESSED zstd.  *}
+.#define BFD_COMPRESS_ZSTD      0x400000
 .
 .  {* Flags bits to be saved in bfd_preserve_save.  *}
 .#define BFD_FLAGS_SAVED \
 .  (BFD_IN_MEMORY | BFD_COMPRESS | BFD_DECOMPRESS | BFD_LINKER_CREATED \
 .   | BFD_PLUGIN | BFD_COMPRESS_GABI | BFD_CONVERT_ELF_COMMON \
-.   | BFD_USE_ELF_STT_COMMON)
+.   | BFD_USE_ELF_STT_COMMON | BFD_COMPRESS_ZSTD)
 .
 .  {* Flags bits which are for BFD use only.  *}
 .#define BFD_FLAGS_FOR_BFD_USE_MASK \
@@ -2500,6 +2503,9 @@ bfd_update_compression_header (bfd *abfd, bfd_byte *contents,
        {
          const struct elf_backend_data *bed = get_elf_backend_data (abfd);
          struct bfd_elf_section_data * esd = elf_section_data (sec);
+         const unsigned int ch_type = abfd->flags & BFD_COMPRESS_ZSTD
+                                          ? ELFCOMPRESS_ZSTD
+                                          : ELFCOMPRESS_ZLIB;
 
          /* Set the SHF_COMPRESSED bit.  */
          elf_section_flags (sec) |= SHF_COMPRESSED;
@@ -2507,7 +2513,7 @@ bfd_update_compression_header (bfd *abfd, bfd_byte *contents,
          if (bed->s->elfclass == ELFCLASS32)
            {
              Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) contents;
-             bfd_put_32 (abfd, ELFCOMPRESS_ZLIB, &echdr->ch_type);
+             bfd_put_32 (abfd, ch_type, &echdr->ch_type);
              bfd_put_32 (abfd, sec->size, &echdr->ch_size);
              bfd_put_32 (abfd, 1u << sec->alignment_power,
                          &echdr->ch_addralign);
@@ -2518,7 +2524,7 @@ bfd_update_compression_header (bfd *abfd, bfd_byte *contents,
          else
            {
              Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) contents;
-             bfd_put_32 (abfd, ELFCOMPRESS_ZLIB, &echdr->ch_type);
+             bfd_put_32 (abfd, ch_type, &echdr->ch_type);
              bfd_put_32 (abfd, 0, &echdr->ch_reserved);
              bfd_put_64 (abfd, sec->size, &echdr->ch_size);
              bfd_put_64 (abfd, UINT64_C (1) << sec->alignment_power,
@@ -2553,14 +2559,15 @@ bfd_update_compression_header (bfd *abfd, bfd_byte *contents,
    SYNOPSIS
        bool bfd_check_compression_header
          (bfd *abfd, bfd_byte *contents, asection *sec,
+         unsigned int *ch_type,
          bfd_size_type *uncompressed_size,
          unsigned int *uncompressed_alignment_power);
 
 DESCRIPTION
-       Check the compression header at CONTENTS of SEC in ABFD and
-       store the uncompressed size in UNCOMPRESSED_SIZE and the
-       uncompressed data alignment in UNCOMPRESSED_ALIGNMENT_POWER
-       if the compression header is valid.
+       Check the compression header at CONTENTS of SEC in ABFD and store the
+       ch_type in CH_TYPE, uncompressed size in UNCOMPRESSED_SIZE, and the
+       uncompressed data alignment in UNCOMPRESSED_ALIGNMENT_POWER if the
+       compression header is valid.
 
 RETURNS
        Return TRUE if the compression header is valid.
@@ -2569,6 +2576,7 @@ RETURNS
 bool
 bfd_check_compression_header (bfd *abfd, bfd_byte *contents,
                              asection *sec,
+                             unsigned int *ch_type,
                              bfd_size_type *uncompressed_size,
                              unsigned int *uncompressed_alignment_power)
 {
@@ -2591,7 +2599,9 @@ bfd_check_compression_header (bfd *abfd, bfd_byte *contents,
          chdr.ch_size = bfd_get_64 (abfd, &echdr->ch_size);
          chdr.ch_addralign = bfd_get_64 (abfd, &echdr->ch_addralign);
        }
-      if (chdr.ch_type == ELFCOMPRESS_ZLIB
+      *ch_type = chdr.ch_type;
+      if ((chdr.ch_type == ELFCOMPRESS_ZLIB
+          || chdr.ch_type == ELFCOMPRESS_ZSTD)
          && chdr.ch_addralign == (chdr.ch_addralign & -chdr.ch_addralign))
        {
          *uncompressed_size = chdr.ch_size;
index b2e39826e385b0884aa773274f603f234c05e236..0e75b6870137d3eeab71837cf43d5a5ddd47b720 100644 (file)
 
 #include "sysdep.h"
 #include <zlib.h>
+#ifdef HAVE_ZSTD
+#include <zstd.h>
+#endif
 #include "bfd.h"
+#include "elf-bfd.h"
 #include "libbfd.h"
 #include "safe-ctype.h"
 
 #define MAX_COMPRESSION_HEADER_SIZE 24
 
 static bool
-decompress_contents (bfd_byte *compressed_buffer,
+decompress_contents (bool is_zstd, bfd_byte *compressed_buffer,
                     bfd_size_type compressed_size,
                     bfd_byte *uncompressed_buffer,
                     bfd_size_type uncompressed_size)
 {
+  if (is_zstd)
+    {
+#ifdef HAVE_ZSTD
+      size_t ret = ZSTD_decompress (uncompressed_buffer, uncompressed_size,
+                                   compressed_buffer, compressed_size);
+      return !ZSTD_isError (ret);
+#endif
+    }
+
   z_stream strm;
   int rc;
 
@@ -69,7 +82,7 @@ decompress_contents (bfd_byte *compressed_buffer,
 }
 
 /* Compress data of the size specified in @var{uncompressed_size}
-   and pointed to by @var{uncompressed_buffer} using zlib and store
+   and pointed to by @var{uncompressed_buffer} using zlib/zstd and store
    as the contents field.  This function assumes the contents
    field was allocated using bfd_malloc() or equivalent.
 
@@ -150,9 +163,10 @@ bfd_compress_section_contents (bfd *abfd, sec_ptr sec,
       sec->size = orig_uncompressed_size;
       if (decompress)
        {
-         if (!decompress_contents (uncompressed_buffer
-                                   + orig_compression_header_size,
-                                   zlib_size, buffer, buffer_size))
+         if (!decompress_contents (
+                 sec->compress_status == DECOMPRESS_SECTION_ZSTD,
+                 uncompressed_buffer + orig_compression_header_size,
+                 zlib_size, buffer, buffer_size))
            {
              bfd_set_error (bfd_error_bad_value);
              bfd_release (abfd, buffer);
@@ -175,10 +189,23 @@ bfd_compress_section_contents (bfd *abfd, sec_ptr sec,
     }
   else
     {
-      if (compress ((Bytef*) buffer + header_size,
-                   &compressed_size,
-                   (const Bytef*) uncompressed_buffer,
-                   uncompressed_size) != Z_OK)
+      if (abfd->flags & BFD_COMPRESS_ZSTD)
+       {
+#if HAVE_ZSTD
+         compressed_size = ZSTD_compress (
+                 buffer + header_size, compressed_size, uncompressed_buffer,
+                 uncompressed_size, ZSTD_CLEVEL_DEFAULT);
+         if (ZSTD_isError (compressed_size))
+           {
+             bfd_release (abfd, buffer);
+             bfd_set_error (bfd_error_bad_value);
+             return 0;
+           }
+#endif
+       }
+      else if (compress ((Bytef *)buffer + header_size, &compressed_size,
+                        (const Bytef *)uncompressed_buffer, uncompressed_size)
+              != Z_OK)
        {
          bfd_release (abfd, buffer);
          bfd_set_error (bfd_error_bad_value);
@@ -237,6 +264,7 @@ bfd_get_full_section_contents (bfd *abfd, sec_ptr sec, bfd_byte **ptr)
   bfd_size_type save_rawsize;
   bfd_byte *compressed_buffer;
   unsigned int compression_header_size;
+  const unsigned int compress_status = sec->compress_status;
 
   if (abfd->direction != write_direction && sec->rawsize != 0)
     sz = sec->rawsize;
@@ -248,7 +276,7 @@ bfd_get_full_section_contents (bfd *abfd, sec_ptr sec, bfd_byte **ptr)
       return true;
     }
 
-  switch (sec->compress_status)
+  switch (compress_status)
     {
     case COMPRESS_SECTION_NONE:
       if (p == NULL)
@@ -298,7 +326,8 @@ bfd_get_full_section_contents (bfd *abfd, sec_ptr sec, bfd_byte **ptr)
       *ptr = p;
       return true;
 
-    case DECOMPRESS_SECTION_SIZED:
+    case DECOMPRESS_SECTION_ZLIB:
+    case DECOMPRESS_SECTION_ZSTD:
       /* Read in the full compressed section contents.  */
       compressed_buffer = (bfd_byte *) bfd_malloc (sec->compressed_size);
       if (compressed_buffer == NULL)
@@ -316,7 +345,7 @@ bfd_get_full_section_contents (bfd *abfd, sec_ptr sec, bfd_byte **ptr)
       /* Restore rawsize and size.  */
       sec->rawsize = save_rawsize;
       sec->size = save_size;
-      sec->compress_status = DECOMPRESS_SECTION_SIZED;
+      sec->compress_status = compress_status;
       if (!ret)
        goto fail_compressed;
 
@@ -330,8 +359,10 @@ bfd_get_full_section_contents (bfd *abfd, sec_ptr sec, bfd_byte **ptr)
        /* Set header size to the zlib header size if it is a
           SHF_COMPRESSED section.  */
        compression_header_size = 12;
-      if (!decompress_contents (compressed_buffer + compression_header_size,
-                               sec->compressed_size - compression_header_size, p, sz))
+      bool is_zstd = compress_status == DECOMPRESS_SECTION_ZSTD;
+      if (!decompress_contents (
+             is_zstd, compressed_buffer + compression_header_size,
+             sec->compressed_size - compression_header_size, p, sz))
        {
          bfd_set_error (bfd_error_bad_value);
          if (p != *ptr)
@@ -381,7 +412,8 @@ DESCRIPTION
 void
 bfd_cache_section_contents (asection *sec, void *contents)
 {
-  if (sec->compress_status == DECOMPRESS_SECTION_SIZED)
+  if (sec->compress_status == DECOMPRESS_SECTION_ZLIB
+      || sec->compress_status == DECOMPRESS_SECTION_ZSTD)
     sec->compress_status = COMPRESS_SECTION_DONE;
   sec->contents = contents;
   sec->flags |= SEC_IN_MEMORY;
@@ -418,6 +450,7 @@ bfd_is_section_compressed_with_header (bfd *abfd, sec_ptr sec,
   int compression_header_size;
   int header_size;
   unsigned int saved = sec->compress_status;
+  unsigned int ch_type;
   bool compressed;
 
   *uncompressed_align_pow_p = 0;
@@ -448,7 +481,7 @@ bfd_is_section_compressed_with_header (bfd *abfd, sec_ptr sec,
     {
       if (compression_header_size != 0)
        {
-         if (!bfd_check_compression_header (abfd, header, sec,
+         if (!bfd_check_compression_header (abfd, header, sec, &ch_type,
                                             uncompressed_size_p,
                                             uncompressed_align_pow_p))
            compression_header_size = -1;
@@ -507,7 +540,7 @@ SYNOPSIS
 DESCRIPTION
        Record compressed section size, update section size with
        decompressed size and set compress_status to
-       DECOMPRESS_SECTION_SIZED.
+       DECOMPRESS_SECTION_{ZLIB,ZSTD}.
 
        Return @code{FALSE} if the section is not a valid compressed
        section.  Otherwise, return @code{TRUE}.
@@ -521,6 +554,7 @@ bfd_init_section_decompress_status (bfd *abfd, sec_ptr sec)
   int header_size;
   bfd_size_type uncompressed_size;
   unsigned int uncompressed_alignment_power = 0;
+  unsigned int ch_type;
   z_stream strm;
 
   compression_header_size = bfd_get_compression_header_size (abfd, sec);
@@ -550,6 +584,7 @@ bfd_init_section_decompress_status (bfd *abfd, sec_ptr sec)
       uncompressed_size = bfd_getb64 (header + 4);
     }
   else if (!bfd_check_compression_header (abfd, header, sec,
+                                         &ch_type,
                                          &uncompressed_size,
                                          &uncompressed_alignment_power))
     {
@@ -569,7 +604,8 @@ bfd_init_section_decompress_status (bfd *abfd, sec_ptr sec)
   sec->compressed_size = sec->size;
   sec->size = uncompressed_size;
   bfd_set_section_alignment (sec, uncompressed_alignment_power);
-  sec->compress_status = DECOMPRESS_SECTION_SIZED;
+  sec->compress_status = (ch_type == ELFCOMPRESS_ZSTD
+                         ? DECOMPRESS_SECTION_ZSTD : DECOMPRESS_SECTION_ZLIB);
 
   return true;
 }
index f54a3cacbea7eeba286d363ee9dfcb1a55efccd1..a59304e0a66a6c089168e9f1cbb48be067d56d33 100644 (file)
 /* Define to 1 if you have the <windows.h> header file. */
 #undef HAVE_WINDOWS_H
 
+/* Define to 1 if zstd is enabled. */
+#undef HAVE_ZSTD
+
 /* Define to the sub-directory in which libtool stores uninstalled libraries.
    */
 #undef LT_OBJDIR
index 075d2ee0a1b88578dbad56dd5a2182ac4e0542c4..d905a7bf7a8405ff45492f76faf671c5e2e99dd0 100755 (executable)
@@ -652,6 +652,11 @@ TDEFINES
 SHARED_LIBADD
 SHARED_LDFLAGS
 LIBM
+ZSTD_LIBS
+ZSTD_CFLAGS
+PKG_CONFIG_LIBDIR
+PKG_CONFIG_PATH
+PKG_CONFIG
 zlibinc
 zlibdir
 EXEEXT_FOR_BUILD
@@ -839,6 +844,7 @@ enable_maintainer_mode
 enable_install_libbfd
 enable_nls
 with_system_zlib
+with_zstd
 '
       ac_precious_vars='build_alias
 host_alias
@@ -848,7 +854,12 @@ CFLAGS
 LDFLAGS
 LIBS
 CPPFLAGS
-CPP'
+CPP
+PKG_CONFIG
+PKG_CONFIG_PATH
+PKG_CONFIG_LIBDIR
+ZSTD_CFLAGS
+ZSTD_LIBS'
 
 
 # Initialize some variables set by options.
@@ -1511,6 +1522,8 @@ Optional Packages:
                           Binutils"
   --with-bugurl=URL       Direct users to URL to report a bug
   --with-system-zlib      use installed libz
+  --with-zstd             support zstd compressed debug sections
+                          (default=auto)
 
 Some influential environment variables:
   CC          C compiler command
@@ -1521,6 +1534,13 @@ Some influential environment variables:
   CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
               you have headers in a nonstandard directory <include dir>
   CPP         C preprocessor
+  PKG_CONFIG  path to pkg-config utility
+  PKG_CONFIG_PATH
+              directories to add to pkg-config's search path
+  PKG_CONFIG_LIBDIR
+              path overriding pkg-config's built-in search path
+  ZSTD_CFLAGS C compiler flags for ZSTD, overriding pkg-config
+  ZSTD_LIBS   linker flags for ZSTD, overriding pkg-config
 
 Use these variables to override the choices made by `configure' or to help
 it to find libraries and programs with nonstandard names/locations.
@@ -11086,7 +11106,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11089 "configure"
+#line 11109 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11192,7 +11212,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11195 "configure"
+#line 11215 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -12995,7 +13015,7 @@ $as_echo "#define USE_BINARY_FOPEN 1" >>confdefs.h
  ;;
 esac
 
-# Link in zlib if we can.  This allows us to read compressed debug sections.
+# Link in zlib/zstd if we can.  This allows us to read compressed debug sections.
 # This is used only by compress.c.
 
   # Use the system's zlib library.
 
 
 
+
+
+
+
+
+
+if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
+       if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
+set dummy ${ac_tool_prefix}pkg-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_PKG_CONFIG+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $PKG_CONFIG in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+PKG_CONFIG=$ac_cv_path_PKG_CONFIG
+if test -n "$PKG_CONFIG"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5
+$as_echo "$PKG_CONFIG" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_path_PKG_CONFIG"; then
+  ac_pt_PKG_CONFIG=$PKG_CONFIG
+  # Extract the first word of "pkg-config", so it can be a program name with args.
+set dummy pkg-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $ac_pt_PKG_CONFIG in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG
+if test -n "$ac_pt_PKG_CONFIG"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5
+$as_echo "$ac_pt_PKG_CONFIG" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_pt_PKG_CONFIG" = x; then
+    PKG_CONFIG=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    PKG_CONFIG=$ac_pt_PKG_CONFIG
+  fi
+else
+  PKG_CONFIG="$ac_cv_path_PKG_CONFIG"
+fi
+
+fi
+if test -n "$PKG_CONFIG"; then
+       _pkg_min_version=0.9.0
+       { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5
+$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; }
+       if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
+               { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+       else
+               { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+               PKG_CONFIG=""
+       fi
+fi
+
+
+# Check whether --with-zstd was given.
+if test "${with_zstd+set}" = set; then :
+  withval=$with_zstd;
+else
+  with_zstd=auto
+fi
+
+
+if test "$with_zstd" != no; then
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libzstd" >&5
+$as_echo_n "checking for libzstd... " >&6; }
+
+if test -n "$ZSTD_CFLAGS"; then
+    pkg_cv_ZSTD_CFLAGS="$ZSTD_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libzstd\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libzstd") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_ZSTD_CFLAGS=`$PKG_CONFIG --cflags "libzstd" 2>/dev/null`
+                     test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+if test -n "$ZSTD_LIBS"; then
+    pkg_cv_ZSTD_LIBS="$ZSTD_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libzstd\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libzstd") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_ZSTD_LIBS=`$PKG_CONFIG --libs "libzstd" 2>/dev/null`
+                     test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+
+if test $pkg_failed = no; then
+  pkg_save_LDFLAGS="$LDFLAGS"
+  LDFLAGS="$LDFLAGS $pkg_cv_ZSTD_LIBS"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+else
+  pkg_failed=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  LDFLAGS=$pkg_save_LDFLAGS
+fi
+
+
+
+if test $pkg_failed = yes; then
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi
+        if test $_pkg_short_errors_supported = yes; then
+               ZSTD_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libzstd" 2>&1`
+        else
+               ZSTD_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libzstd" 2>&1`
+        fi
+       # Put the nasty error message in config.log where it belongs
+       echo "$ZSTD_PKG_ERRORS" >&5
+
+
+    if test "$with_zstd" = yes; then
+      as_fn_error $? "--with-zstd was given, but pkgconfig/libzstd.pc is not found" "$LINENO" 5
+    fi
+
+elif test $pkg_failed = untried; then
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+    if test "$with_zstd" = yes; then
+      as_fn_error $? "--with-zstd was given, but pkgconfig/libzstd.pc is not found" "$LINENO" 5
+    fi
+
+else
+       ZSTD_CFLAGS=$pkg_cv_ZSTD_CFLAGS
+       ZSTD_LIBS=$pkg_cv_ZSTD_LIBS
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+
+$as_echo "#define HAVE_ZSTD 1" >>confdefs.h
+
+
+fi
+fi
+
+
 save_CFLAGS="$CFLAGS"
 CFLAGS="$CFLAGS -Werror"
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking compiler support for hidden visibility" >&5
index 28f3d1afce6965b6bf17573433092d9181151ea4..7a0ad0ffe331cd0bdc76b297a384994af0213fc0 100644 (file)
@@ -230,9 +230,10 @@ AC_CHECK_DECLS([basename, ffs, stpcpy, asprintf, vasprintf, strnlen])
 
 BFD_BINARY_FOPEN
 
-# Link in zlib if we can.  This allows us to read compressed debug sections.
+# Link in zlib/zstd if we can.  This allows us to read compressed debug sections.
 # This is used only by compress.c.
 AM_ZLIB
+AC_ZSTD
 
 save_CFLAGS="$CFLAGS"
 CFLAGS="$CFLAGS -Werror"
index 396b56db024b52573a6010aa0810093c55c388c7..d496c1b2983b0ebaf9c8a6082ce42ec2a6a869d4 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -1260,6 +1260,18 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
                 abfd, name);
              return false;
            }
+#ifndef HAVE_ZSTD
+         if (newsect->compress_status == DECOMPRESS_SECTION_ZSTD)
+           {
+             _bfd_error_handler
+                 /* xgettext:c-format */
+                 (_ ("%pB: section %s is compressed with zstd, but BFD "
+                     "is not built with zstd support"),
+                  abfd, name);
+             newsect->compress_status = COMPRESS_SECTION_NONE;
+             return false;
+           }
+#endif
        }
 
       if (abfd->is_linker_input)
index feaba84bf2ed22a4c885bd95ccba9c750bda5c97..ca600bb5ddf891886d1c43c3e2c9fe3691685b72 100644 (file)
@@ -989,7 +989,8 @@ const bfd_target TARGET_BIG_SYM =
   /* object_flags: mask of all file flags */
   (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS
    | DYNAMIC | WP_TEXT | D_PAGED | BFD_COMPRESS | BFD_DECOMPRESS
-   | BFD_COMPRESS_GABI | BFD_CONVERT_ELF_COMMON | BFD_USE_ELF_STT_COMMON),
+   | BFD_COMPRESS_GABI | BFD_COMPRESS_ZSTD | BFD_CONVERT_ELF_COMMON
+   | BFD_USE_ELF_STT_COMMON),
 
   /* section_flags: mask of all section flags */
   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY
@@ -1093,7 +1094,8 @@ const bfd_target TARGET_LITTLE_SYM =
   /* object_flags: mask of all file flags */
   (HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS
    | DYNAMIC | WP_TEXT | D_PAGED | BFD_COMPRESS | BFD_DECOMPRESS
-   | BFD_COMPRESS_GABI | BFD_CONVERT_ELF_COMMON | BFD_USE_ELF_STT_COMMON),
+   | BFD_COMPRESS_GABI | BFD_COMPRESS_ZSTD | BFD_CONVERT_ELF_COMMON
+   | BFD_USE_ELF_STT_COMMON),
 
   /* section_flags: mask of all section flags */
   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY
index c7a02d729f26965148ece9478346b14e6c8c7fb1..614570e976e793cc9e6d943508b49c53673c04a6 100644 (file)
@@ -392,7 +392,8 @@ CODE_FRAGMENT
 .  unsigned int compress_status : 2;
 .#define COMPRESS_SECTION_NONE    0
 .#define COMPRESS_SECTION_DONE    1
-.#define DECOMPRESS_SECTION_SIZED 2
+.#define DECOMPRESS_SECTION_ZLIB  2
+.#define DECOMPRESS_SECTION_ZSTD  3
 .
 .  {* The following flags are used by the ELF linker. *}
 .
index 78d32b350e38227559c006eafecf1641bb552587..6de4e239408b8608609a93812fda13f89be519f9 100644 (file)
@@ -156,7 +156,8 @@ am__aclocal_m4_deps = $(top_srcdir)/../bfd/acinclude.m4 \
        $(top_srcdir)/../config/plugins.m4 \
        $(top_srcdir)/../config/po.m4 \
        $(top_srcdir)/../config/progtest.m4 \
-       $(top_srcdir)/../config/zlib.m4 $(top_srcdir)/../libtool.m4 \
+       $(top_srcdir)/../config/zlib.m4 \
+       $(top_srcdir)/../config/zstd.m4 $(top_srcdir)/../libtool.m4 \
        $(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \
        $(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \
        $(top_srcdir)/../bfd/version.m4 \
@@ -575,6 +576,8 @@ WARN_WRITE_STRINGS = @WARN_WRITE_STRINGS@
 XGETTEXT = @XGETTEXT@
 YACC = `if [ -f ../bison/bison ]; then echo ../bison/bison -y -L$(srcdir)/../bison/; else echo @YACC@; fi`
 YFLAGS = -d
+ZSTD_CFLAGS = @ZSTD_CFLAGS@
+ZSTD_LIBS = @ZSTD_LIBS@
 abs_builddir = @abs_builddir@
 abs_srcdir = @abs_srcdir@
 abs_top_builddir = @abs_top_builddir@
index 8c2c416c17e4fb8a453a501c3bc27deec94e6c7d..83c73d0660a1abf70814b6bbb14ad082574ce1ad 100644 (file)
@@ -1,5 +1,11 @@
 -*- text -*-
 
+* objcopy --decompress-debug-sections now supports zstd compressed debug
+  sections.  The new option --compress-debug-sections=zstd compresses debug
+  sections with zstd.
+
+* addr2line and objdump --dwarf now support zstd compressed debug sections.
+
 * The dlltool program now accepts --deterministic-libraries and
   --non-deterministic-libraries as command line options to control whether or
   not it generates deterministic output libraries.  If neither of these options
index a877fa7f873d345528289703150cf1ef1899cd38..28271f562795f2030a099b72a255bd7809caad16 100644 (file)
@@ -1205,6 +1205,7 @@ m4_include([../config/plugins.m4])
 m4_include([../config/po.m4])
 m4_include([../config/progtest.m4])
 m4_include([../config/zlib.m4])
+m4_include([../config/zstd.m4])
 m4_include([../libtool.m4])
 m4_include([../ltoptions.m4])
 m4_include([../ltsugar.m4])
index c5fb919aa954e4673798b99a89b134855a9bb661..bee8c07e2f778c39c7dfc5a52abe89001069b877 100644 (file)
 /* Define to 1 if you have the <windows.h> header file. */
 #undef HAVE_WINDOWS_H
 
+/* Define to 1 if zstd is enabled. */
+#undef HAVE_ZSTD
+
 /* Define as const if the declaration of iconv() needs const. */
 #undef ICONV_CONST
 
index 4c0c391e9d5113c37028f83b361968ab5af08061..0d6bde7b4a5db08387f7c64c61eb7e59eed49eac 100755 (executable)
@@ -650,6 +650,8 @@ LTLIBICONV
 LIBICONV
 MSGPACK_LIBS
 MSGPACK_CFLAGS
+ZSTD_LIBS
+ZSTD_CFLAGS
 zlibinc
 zlibdir
 DEMANGLER_NAME
@@ -832,6 +834,7 @@ enable_build_warnings
 enable_nls
 enable_maintainer_mode
 with_system_zlib
+with_zstd
 with_msgpack
 enable_rpath
 with_libiconv_prefix
@@ -853,6 +856,8 @@ DEBUGINFOD_CFLAGS
 DEBUGINFOD_LIBS
 YACC
 YFLAGS
+ZSTD_CFLAGS
+ZSTD_LIBS
 MSGPACK_CFLAGS
 MSGPACK_LIBS'
 
@@ -1517,6 +1522,8 @@ Optional Packages:
   --with-debuginfod       Enable debuginfo lookups with debuginfod
                           (auto/yes/no)
   --with-system-zlib      use installed libz
+  --with-zstd             support zstd compressed debug sections
+                          (default=auto)
   --with-msgpack          Enable msgpack support (auto/yes/no)
   --with-gnu-ld           assume the C compiler uses GNU ld default=no
   --with-libiconv-prefix[=DIR]  search for libiconv in DIR/include and DIR/lib
@@ -1547,6 +1554,8 @@ Some influential environment variables:
   YFLAGS      The list of arguments that will be passed by default to $YACC.
               This script will default YFLAGS to the empty string to avoid a
               default value of `-d' given by some make applications.
+  ZSTD_CFLAGS C compiler flags for ZSTD, overriding pkg-config
+  ZSTD_LIBS   linker flags for ZSTD, overriding pkg-config
   MSGPACK_CFLAGS
               C compiler flags for MSGPACK, overriding pkg-config
   MSGPACK_LIBS
@@ -10804,7 +10813,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 10807 "configure"
+#line 10816 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -10910,7 +10919,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 10913 "configure"
+#line 10922 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -13468,7 +13477,7 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
-# Link in zlib if we can.  This allows us to read compressed debug
+# Link in zlib/zstd if we can.  This allows us to read compressed debug
 # sections.  This is used only by readelf.c (objdump uses bfd for
 # reading compressed sections).
 
 
 
 
+# Check whether --with-zstd was given.
+if test "${with_zstd+set}" = set; then :
+  withval=$with_zstd;
+else
+  with_zstd=auto
+fi
+
+
+if test "$with_zstd" != no; then :
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libzstd" >&5
+$as_echo_n "checking for libzstd... " >&6; }
+
+if test -n "$ZSTD_CFLAGS"; then
+    pkg_cv_ZSTD_CFLAGS="$ZSTD_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libzstd\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libzstd") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_ZSTD_CFLAGS=`$PKG_CONFIG --cflags "libzstd" 2>/dev/null`
+                     test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+if test -n "$ZSTD_LIBS"; then
+    pkg_cv_ZSTD_LIBS="$ZSTD_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libzstd\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libzstd") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_ZSTD_LIBS=`$PKG_CONFIG --libs "libzstd" 2>/dev/null`
+                     test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+
+if test $pkg_failed = no; then
+  pkg_save_LDFLAGS="$LDFLAGS"
+  LDFLAGS="$LDFLAGS $pkg_cv_ZSTD_LIBS"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+else
+  pkg_failed=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  LDFLAGS=$pkg_save_LDFLAGS
+fi
+
+
+
+if test $pkg_failed = yes; then
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi
+        if test $_pkg_short_errors_supported = yes; then
+               ZSTD_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libzstd" 2>&1`
+        else
+               ZSTD_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libzstd" 2>&1`
+        fi
+       # Put the nasty error message in config.log where it belongs
+       echo "$ZSTD_PKG_ERRORS" >&5
+
+
+    if test "$with_zstd" = yes; then
+      as_fn_error $? "--with-zstd was given, but pkgconfig/libzstd.pc is not found" "$LINENO" 5
+    fi
+
+elif test $pkg_failed = untried; then
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+    if test "$with_zstd" = yes; then
+      as_fn_error $? "--with-zstd was given, but pkgconfig/libzstd.pc is not found" "$LINENO" 5
+    fi
+
+else
+       ZSTD_CFLAGS=$pkg_cv_ZSTD_CFLAGS
+       ZSTD_LIBS=$pkg_cv_ZSTD_LIBS
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+
+$as_echo "#define HAVE_ZSTD 1" >>confdefs.h
+
+
+fi
+
+fi
+
+
+
 case "${host}" in
 *-*-msdos* | *-*-go32* | *-*-mingw32* | *-*-cygwin* | *-*-windows*)
 
index 0798d84f4d14041db8becd1a0a8feba888564d51..9b75396d07e58c2bdd2d2e0acc8daad5e5697ee9 100644 (file)
@@ -265,10 +265,11 @@ fi
 
 AC_CHECK_DECLS([asprintf, environ, getc_unlocked, stpcpy, strnlen])
 
-# Link in zlib if we can.  This allows us to read compressed debug
+# Link in zlib/zstd if we can.  This allows us to read compressed debug
 # sections.  This is used only by readelf.c (objdump uses bfd for
 # reading compressed sections).
 AM_ZLIB
+AC_ZSTD
 
 BFD_BINARY_FOPEN
 
index 1499db5728cd141bf14f2d6838aa742131b675f1..34a4164eb94769760dffecbde9da94b00dd6ee54 100644 (file)
@@ -2159,21 +2159,23 @@ ELF ABI.  Note - if compression would actually make a section
 @itemx --compress-debug-sections=zlib
 @itemx --compress-debug-sections=zlib-gnu
 @itemx --compress-debug-sections=zlib-gabi
+@itemx --compress-debug-sections=zstd
 For ELF files, these options control how DWARF debug sections are
 compressed.  @option{--compress-debug-sections=none} is equivalent
 to @option{--decompress-debug-sections}.
 @option{--compress-debug-sections=zlib} and
 @option{--compress-debug-sections=zlib-gabi} are equivalent to
 @option{--compress-debug-sections}.
-@option{--compress-debug-sections=zlib-gnu} compresses DWARF debug
-sections using zlib.  The debug sections are renamed to begin with
-@samp{.zdebug} instead of @samp{.debug}.  Note - if compression would
-actually make a section @emph{larger}, then it is not compressed nor
-renamed.
+@option{--compress-debug-sections=zlib-gnu} compresses DWARF debug sections
+using the obsoleted zlib-gnu format.  The debug sections are renamed to begin
+with @samp{.zdebug}.
+@option{--compress-debug-sections=zstd} compresses DWARF debug
+sections using zstd.  Note - if compression would actually make a section
+@emph{larger}, then it is not compressed nor renamed.
 
 @item --decompress-debug-sections
-Decompress DWARF debug sections using zlib.  The original section
-names of the compressed sections are restored.
+Decompress DWARF debug sections.  For a @samp{.zdebug} section, the original
+name is restored.
 
 @item --elf-stt-common=yes
 @itemx --elf-stt-common=no
index 43261756a428d82279a2db4770276fd32b00d3fc..fc668f00bbc0e519137d09c169855330c0c8f03c 100644 (file)
@@ -232,7 +232,8 @@ static enum
   compress_zlib = compress | 1 << 1,
   compress_gnu_zlib = compress | 1 << 2,
   compress_gabi_zlib = compress | 1 << 3,
-  decompress = 1 << 4
+  compress_zstd = compress | 1 << 4,
+  decompress = 1 << 5
 } do_debug_sections = nothing;
 
 /* Whether to generate ELF common symbols with the STT_COMMON type.  */
@@ -678,8 +679,8 @@ copy_usage (FILE *stream, int exit_status)
                                    <commit>\n\
      --subsystem <name>[:<version>]\n\
                                    Set PE subsystem to <name> [& <version>]\n\
-     --compress-debug-sections[={none|zlib|zlib-gnu|zlib-gabi}]\n\
-                                   Compress DWARF debug sections using zlib\n\
+     --compress-debug-sections[={none|zlib|zlib-gnu|zlib-gabi|zstd}]\n\
+                                  Compress DWARF debug sections\n\
      --decompress-debug-sections   Decompress DWARF debug sections using zlib\n\
      --elf-stt-common=[yes|no]     Generate ELF common symbols with STT_COMMON\n\
                                      type\n\
@@ -2659,7 +2660,8 @@ copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch)
       if ((do_debug_sections & compress) != 0
          && do_debug_sections != compress)
        {
-         non_fatal (_("--compress-debug-sections=[zlib|zlib-gnu|zlib-gabi] is unsupported on `%s'"),
+         non_fatal (_ ("--compress-debug-sections=[zlib|zlib-gnu|zlib-gabi|"
+                       "zstd] is unsupported on `%s'"),
                     bfd_get_archive_filename (ibfd));
          return false;
        }
@@ -3807,6 +3809,13 @@ copy_file (const char *input_filename, const char *output_filename, int ofd,
       if (do_debug_sections != compress_gnu_zlib)
        ibfd->flags |= BFD_COMPRESS_GABI;
       break;
+    case compress_zstd:
+      ibfd->flags |= BFD_COMPRESS | BFD_COMPRESS_GABI | BFD_COMPRESS_ZSTD;
+#ifndef HAVE_ZSTD
+      fatal (_ ("--compress-debug-sections=zstd: binutils is not built with "
+               "zstd support"));
+#endif
+      break;
     case decompress:
       ibfd->flags |= BFD_DECOMPRESS;
       break;
@@ -5469,6 +5478,8 @@ copy_main (int argc, char *argv[])
                do_debug_sections = compress_gnu_zlib;
              else if (strcasecmp (optarg, "zlib-gabi") == 0)
                do_debug_sections = compress_gabi_zlib;
+             else if (strcasecmp (optarg, "zstd") == 0)
+               do_debug_sections = compress_zstd;
              else
                fatal (_("unrecognized --compress-debug-sections type `%s'"),
                       optarg);
index c88da74a9875a1c8062e79e5dea5d08e7e1ea113..4e74c824664a14edfbf43b43bac9c008be7fc172 100644 (file)
@@ -576,6 +576,50 @@ if { [regexp_diff objdump.out $srcdir/$subdir/dw2-3gabi.W] } then {
     pass "$testname"
 }
 
+if { [binutils_assemble_flags $srcdir/$subdir/dw2-1.S ${compressedfile}zstd.o --compress-debug-sections=zstd] } then {
+    set testname "objcopy compress debug sections with zstd"
+    set got [binutils_run $OBJCOPY "--compress-debug-sections=zstd ${testfile}.o ${copyfile}zstd.o"]
+    if ![string match "" $got] then {
+       fail "objcopy ($testname)"
+       return
+    }
+    send_log "cmp ${compressedfile}zstd.o ${copyfile}zstd.o\n"
+    verbose "cmp ${compressedfile}zstd.o ${copyfile}zstd.o"
+    set src1 ${compressedfile}zstd.o
+    set src2 ${copyfile}zstd.o
+    set status [remote_exec build cmp "${src1} ${src2}"]
+    set exec_output [lindex $status 1]
+    set exec_output [prune_warnings $exec_output]
+    if ![string match "" $exec_output] then {
+       send_log "$exec_output\n"
+       verbose "$exec_output" 1
+       fail "objcopy ($testname)"
+    } else {
+       pass "objcopy ($testname)"
+    }
+
+    set testname "objcopy decompress compressed debug sections with zstd"
+    set got [binutils_run $OBJCOPY "--decompress-debug-sections ${compressedfile}zstd.o ${copyfile}zstd.o"]
+    if ![string match "" $got] then {
+       fail "objcopy ($testname)"
+       return
+    }
+    send_log "cmp ${testfile}.o ${copyfile}zstd.o\n"
+    verbose "cmp ${testfile}.o ${copyfile}zstd.o"
+    set src1 ${testfile}.o
+    set src2 ${copyfile}zstd.o
+    set status [remote_exec build cmp "${src1} ${src2}"]
+    set exec_output [lindex $status 1]
+    set exec_output [prune_warnings $exec_output]
+    if ![string match "" $exec_output] then {
+       send_log "$exec_output\n"
+       verbose "$exec_output" 1
+       fail "objcopy ($testname)"
+    } else {
+       pass "objcopy ($testname)"
+    }
+}
+
 proc convert_test { testname  as_flags  objcop_flags } {
     global srcdir
     global subdir
diff --git a/config/zstd.m4 b/config/zstd.m4
new file mode 100644 (file)
index 0000000..6da4db6
--- /dev/null
@@ -0,0 +1,23 @@
+dnl Copyright (C) 2022 Free Software Foundation, Inc.
+dnl This file is free software, distributed under the terms of the GNU
+dnl General Public License.  As a special exception to the GNU General
+dnl Public License, this file may be distributed as part of a program
+dnl that contains a configuration script generated by Autoconf, under
+dnl the same distribution terms as the rest of that program.
+
+dnl Enable features using the zstd library.
+AC_DEFUN([AC_ZSTD], [
+AC_ARG_WITH(zstd,
+  [AS_HELP_STRING([--with-zstd], [support zstd compressed debug sections (default=auto)])],
+  [], [with_zstd=auto])
+
+AS_IF([test "$with_zstd" != no],
+  [PKG_CHECK_MODULES(ZSTD, [libzstd], [
+    AC_DEFINE(HAVE_ZSTD, 1, [Define to 1 if zstd is enabled.])
+  ], [
+    if test "$with_zstd" = yes; then
+      AC_MSG_ERROR([--with-zstd was given, but pkgconfig/libzstd.pc is not found])
+    fi
+  ])
+  ])
+])
index d75f47a1e9557514e2c86a9fa135a122ce12798d..f14e0efd675eaff3ac292ef6997ebdb9f616bb65 100755 (executable)
--- a/configure
+++ b/configure
@@ -785,6 +785,7 @@ ac_user_opts='
 enable_option_checking
 with_build_libsubdir
 with_system_zlib
+with_zstd
 enable_as_accelerator_for
 enable_offload_targets
 enable_gold
@@ -1567,6 +1568,8 @@ Optional Packages:
   --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
   --with-build-libsubdir=DIR  Directory where to find libraries for build system
   --with-system-zlib      use installed libz
+  --with-zstd             Support zstd compressed debug sections
+                          (default=auto)
   --with-mpc=PATH         specify prefix directory for installed MPC package.
                           Equivalent to --with-mpc-include=PATH/include plus
                           --with-mpc-lib=PATH/lib
@@ -2925,6 +2928,13 @@ if test x$with_system_zlib = xyes ; then
   noconfigdirs="$noconfigdirs zlib"
 fi
 
+
+# Check whether --with-zstd was given.
+if test "${with_zstd+set}" = set; then :
+  withval=$with_zstd;
+fi
+
+
 # Don't compile the bundled readline/libreadline.a if --with-system-readline
 # is provided.
 if test x$with_system_readline = xyes ; then
index ae18d436acace0395adb5fbf5ffcac729bfee4be..0152c69292ed63addfe34131001a57ffc79cf60a 100644 (file)
@@ -246,6 +246,9 @@ if test x$with_system_zlib = xyes ; then
   noconfigdirs="$noconfigdirs zlib"
 fi
 
+AC_ARG_WITH(zstd,
+[AS_HELP_STRING([--with-zstd], [Support zstd compressed debug sections (default=auto)])])
+
 # Don't compile the bundled readline/libreadline.a if --with-system-readline
 # is provided.
 if test x$with_system_readline = xyes ; then
index bd5973986718caf86867e0995e8b9a2230b352ec..5f0f24abf8de0757e8591eae317e2c29c7243336 100644 (file)
@@ -42,7 +42,7 @@ am__skipyacc =
 
 WARN_CFLAGS = @WARN_CFLAGS@ @WARN_WRITE_STRINGS@
 NO_WERROR = @NO_WERROR@
-AM_CFLAGS = $(WARN_CFLAGS) $(ZLIBINC)
+AM_CFLAGS = $(WARN_CFLAGS) $(ZLIBINC) $(ZSTD_CFLAGS)
 
 TARG_CPU = @target_cpu_type@
 TARG_CPU_C = $(srcdir)/config/tc-@target_cpu_type@.c
@@ -407,7 +407,7 @@ STAGESTUFF = *.@OBJEXT@ $(noinst_PROGRAMS)
 
 as_new_SOURCES = $(GAS_CFILES)
 as_new_LDADD = $(TARG_CPU_O) $(OBJ_FORMAT_O) $(ATOF_TARG_O) \
-       $(extra_objects) $(GASLIBS) $(LIBINTL) $(LIBM) $(ZLIB)
+       $(extra_objects) $(GASLIBS) $(LIBINTL) $(LIBM) $(ZLIB) $(ZSTD_LIBS)
 as_new_DEPENDENCIES = $(TARG_CPU_O) $(OBJ_FORMAT_O) $(ATOF_TARG_O) \
        $(extra_objects) $(GASLIBS) $(LIBINTL_DEP)
 EXTRA_as_new_SOURCES = $(CFILES) $(HFILES) $(TARGET_CPU_CFILES) \
index c57d78f82c4631e7c13d1d3842cf8a9143dc17e9..5a4dd7022528c9a0cbae23867b14d3db3c451729 100644 (file)
@@ -140,10 +140,12 @@ am__aclocal_m4_deps = $(top_srcdir)/../bfd/acinclude.m4 \
        $(top_srcdir)/../config/lead-dot.m4 \
        $(top_srcdir)/../config/nls.m4 \
        $(top_srcdir)/../config/override.m4 \
+       $(top_srcdir)/../config/pkg.m4 \
        $(top_srcdir)/../config/plugins.m4 \
        $(top_srcdir)/../config/po.m4 \
        $(top_srcdir)/../config/progtest.m4 \
-       $(top_srcdir)/../config/zlib.m4 $(top_srcdir)/../libtool.m4 \
+       $(top_srcdir)/../config/zlib.m4 \
+       $(top_srcdir)/../config/zstd.m4 $(top_srcdir)/../libtool.m4 \
        $(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \
        $(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \
        $(top_srcdir)/acinclude.m4 $(top_srcdir)/../bfd/version.m4 \
@@ -429,6 +431,9 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@
 PACKAGE_URL = @PACKAGE_URL@
 PACKAGE_VERSION = @PACKAGE_VERSION@
 PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
 POSUB = @POSUB@
 RANLIB = @RANLIB@
 SED = @SED@
@@ -443,6 +448,8 @@ WARN_WRITE_STRINGS = @WARN_WRITE_STRINGS@
 XGETTEXT = @XGETTEXT@
 YACC = `if [ -f ../bison/bison ] ; then echo ../bison/bison -y -L../bison/bison ; else echo @YACC@ ; fi`
 YFLAGS = @YFLAGS@
+ZSTD_CFLAGS = @ZSTD_CFLAGS@
+ZSTD_LIBS = @ZSTD_LIBS@
 abs_builddir = @abs_builddir@
 abs_srcdir = @abs_srcdir@
 abs_top_builddir = @abs_top_builddir@
@@ -524,7 +531,7 @@ ZLIBINC = @zlibinc@
 # maintainer mode is disabled.  Avoid this.
 am__skiplex = 
 am__skipyacc = 
-AM_CFLAGS = $(WARN_CFLAGS) $(ZLIBINC)
+AM_CFLAGS = $(WARN_CFLAGS) $(ZLIBINC) $(ZSTD_CFLAGS)
 TARG_CPU = @target_cpu_type@
 TARG_CPU_C = $(srcdir)/config/tc-@target_cpu_type@.c
 TARG_CPU_O = config/tc-@target_cpu_type@.@OBJEXT@
@@ -874,7 +881,7 @@ GASLIBS = @OPCODES_LIB@ ../bfd/libbfd.la ../libiberty/libiberty.a
 STAGESTUFF = *.@OBJEXT@ $(noinst_PROGRAMS)
 as_new_SOURCES = $(GAS_CFILES)
 as_new_LDADD = $(TARG_CPU_O) $(OBJ_FORMAT_O) $(ATOF_TARG_O) \
-       $(extra_objects) $(GASLIBS) $(LIBINTL) $(LIBM) $(ZLIB)
+       $(extra_objects) $(GASLIBS) $(LIBINTL) $(LIBM) $(ZLIB) $(ZSTD_LIBS)
 
 as_new_DEPENDENCIES = $(TARG_CPU_O) $(OBJ_FORMAT_O) $(ATOF_TARG_O) \
        $(extra_objects) $(GASLIBS) $(LIBINTL_DEP)
index d61cdb9edd4a148fd41629c8322cf31556e9d06c..9a8b726b9426655f486b508b51de7e5a0a3730b0 100644 (file)
--- a/gas/NEWS
+++ b/gas/NEWS
@@ -1,5 +1,8 @@
 -*- text -*-
 
+* gas now supports --compress-debug-sections=zstd to compress
+  debug sections with zstd.
+
 Changes in 2.39:
 
 * Remove (rudimentary) support for the x86-64 sub-architectures Intel L1OM and
index 70183124da70c4c0b6bd907275c7bdda870e9814..722030c776f282233c766c9fa35a42e33971d728 100644 (file)
@@ -1196,10 +1196,12 @@ m4_include([../config/lcmessage.m4])
 m4_include([../config/lead-dot.m4])
 m4_include([../config/nls.m4])
 m4_include([../config/override.m4])
+m4_include([../config/pkg.m4])
 m4_include([../config/plugins.m4])
 m4_include([../config/po.m4])
 m4_include([../config/progtest.m4])
 m4_include([../config/zlib.m4])
+m4_include([../config/zstd.m4])
 m4_include([../libtool.m4])
 m4_include([../ltoptions.m4])
 m4_include([../ltsugar.m4])
index 6268779cf903ef97d1e0b144fa5b0fab6ab8e868..35ad6b3ab3be98073714689d52728248fb2fbb7d 100644 (file)
--- a/gas/as.c
+++ b/gas/as.c
@@ -252,14 +252,14 @@ Options:\n\
   --alternate             initially turn on alternate macro syntax\n"));
 #ifdef DEFAULT_FLAG_COMPRESS_DEBUG
   fprintf (stream, _("\
-  --compress-debug-sections[={none|zlib|zlib-gnu|zlib-gabi}]\n\
+  --compress-debug-sections[={none|zlib|zlib-gnu|zlib-gabi|zstd}]\n\
                           compress DWARF debug sections using zlib [default]\n"));
   fprintf (stream, _("\
   --nocompress-debug-sections\n\
                           don't compress DWARF debug sections\n"));
 #else
   fprintf (stream, _("\
-  --compress-debug-sections[={none|zlib|zlib-gnu|zlib-gabi}]\n\
+  --compress-debug-sections[={none|zlib|zlib-gnu|zlib-gabi|zstd}]\n\
                           compress DWARF debug sections using zlib\n"));
   fprintf (stream, _("\
   --nocompress-debug-sections\n\
@@ -736,6 +736,15 @@ This program has absolutely no warranty.\n"));
                flag_compress_debug = COMPRESS_DEBUG_GNU_ZLIB;
              else if (strcasecmp (optarg, "zlib-gabi") == 0)
                flag_compress_debug = COMPRESS_DEBUG_GABI_ZLIB;
+             else if (strcasecmp (optarg, "zstd") == 0)
+               {
+#ifdef HAVE_ZSTD
+                 flag_compress_debug = COMPRESS_DEBUG_ZSTD;
+#else
+                 as_fatal (_ ("--compress-debug-sections=zstd: gas is not "
+                              "built with zstd support"));
+#endif
+               }
              else
                as_fatal (_("Invalid --compress-debug-sections option: `%s'"),
                          optarg);
index c80dbeec4e79a72a7746a77db59947fd6844ba92..3cd175f6e571257f66860a9f1b42397c98882019 100644 (file)
 #include "config.h"
 #include <stdio.h>
 #include <zlib.h>
+#if HAVE_ZSTD
+#include <zstd.h>
+#endif
 #include "ansidecl.h"
 #include "compress-debug.h"
 
 /* Initialize the compression engine.  */
 
-struct z_stream_s *
-compress_init (void)
+void *
+compress_init (bool use_zstd)
 {
+  if (use_zstd) {
+#if HAVE_ZSTD
+    return ZSTD_createCCtx ();
+#endif
+  }
+
   static struct z_stream_s strm;
 
   strm.zalloc = NULL;
@@ -42,22 +51,37 @@ compress_init (void)
    from the engine goes into the current frag on the obstack.  */
 
 int
-compress_data (struct z_stream_s *strm, const char **next_in,
-              int *avail_in, char **next_out, int *avail_out)
+compress_data (bool use_zstd, void *ctx, const char **next_in, int *avail_in,
+              char **next_out, int *avail_out)
 {
-  int out_size = 0;
-  int x;
+  if (use_zstd)
+    {
+#if HAVE_ZSTD
+      ZSTD_outBuffer ob = { *next_out, *avail_out, 0 };
+      ZSTD_inBuffer ib = { *next_in, *avail_in, 0 };
+      size_t ret = ZSTD_compressStream2 (ctx, &ob, &ib, ZSTD_e_continue);
+      *next_in += ib.pos;
+      *avail_in -= ib.pos;
+      *next_out += ob.pos;
+      *avail_out -= ob.pos;
+      if (ZSTD_isError (ret))
+       return -1;
+      return (int)ob.pos;
+#endif
+    }
+
+  struct z_stream_s *strm = ctx;
 
   strm->next_in = (Bytef *) (*next_in);
   strm->avail_in = *avail_in;
   strm->next_out = (Bytef *) (*next_out);
   strm->avail_out = *avail_out;
 
-  x = deflate (strm, Z_NO_FLUSH);
+  int x = deflate (strm, Z_NO_FLUSH);
   if (x != Z_OK)
     return -1;
 
-  out_size = *avail_out - strm->avail_out;
+  int out_size = *avail_out - strm->avail_out;
   *next_in = (char *) (strm->next_in);
   *avail_in = strm->avail_in;
   *next_out = (char *) (strm->next_out);
@@ -71,10 +95,28 @@ compress_data (struct z_stream_s *strm, const char **next_in,
    needed.  */
 
 int
-compress_finish (struct z_stream_s *strm, char **next_out,
+compress_finish (bool use_zstd, void *ctx, char **next_out,
                 int *avail_out, int *out_size)
 {
+  if (use_zstd)
+    {
+#if HAVE_ZSTD
+      ZSTD_outBuffer ob = { *next_out, *avail_out, 0 };
+      ZSTD_inBuffer ib = { 0 };
+      size_t ret = ZSTD_compressStream2 (ctx, &ob, &ib, ZSTD_e_end);
+      *out_size = ob.pos;
+      *next_out += ob.pos;
+      *avail_out -= ob.pos;
+      if (ZSTD_isError (ret))
+       return -1;
+      if (ret == 0)
+       ZSTD_freeCCtx (ctx);
+      return ret ? 1 : 0;
+#endif
+    }
+
   int x;
+  struct z_stream_s *strm = ctx;
 
   strm->avail_in = 0;
   strm->next_out = (Bytef *) (*next_out);
index 0183e269feff04d01b014a6593e05bce1d4cc974..87de0f8444e7b198b9a6fcea26ddab6bca29cbd9 100644 (file)
 #ifndef COMPRESS_DEBUG_H
 #define COMPRESS_DEBUG_H
 
+#include <stdbool.h>
+
 struct z_stream_s;
 
 /* Initialize the compression engine.  */
-extern struct z_stream_s *
-compress_init (void);
+extern void *compress_init (bool);
 
 /* Stream the contents of a frag to the compression engine.  Output
    from the engine goes into the current frag on the obstack.  */
-extern int
-compress_data (struct z_stream_s *, const char **, int *, char **, int *);
+extern int compress_data (bool, void *, const char **, int *, char **, int *);
 
 /* Finish the compression and consume the remaining compressed output.  */
 extern int
-compress_finish (struct z_stream_s *, char **, int *, int *);
+compress_finish (bool, void *, char **, int *, int *);
 
 #endif /* COMPRESS_DEBUG_H */
index e243fd277eebfd236ed291e301b02dc4608c9e81..0d1668a3eacf4b9d3795f16482288795dde54cb3 100644 (file)
 /* Define to 1 if you have the <windows.h> header file. */
 #undef HAVE_WINDOWS_H
 
+/* Define to 1 if zstd is enabled. */
+#undef HAVE_ZSTD
+
 /* Using i386 COFF? */
 #undef I386COFF
 
index d0449a1d7ab1f776aa439644a42e84785ecec6fa..02cded59b6a492fce5cc6d21de571d9c7da58c6f 100755 (executable)
@@ -633,6 +633,11 @@ ac_subst_vars='am__EXEEXT_FALSE
 am__EXEEXT_TRUE
 LTLIBOBJS
 LIBOBJS
+ZSTD_LIBS
+ZSTD_CFLAGS
+PKG_CONFIG_LIBDIR
+PKG_CONFIG_PATH
+PKG_CONFIG
 zlibinc
 zlibdir
 LIBM
@@ -817,6 +822,7 @@ with_cpu
 enable_nls
 enable_maintainer_mode
 with_system_zlib
+with_zstd
 '
       ac_precious_vars='build_alias
 host_alias
@@ -828,7 +834,12 @@ LIBS
 CPPFLAGS
 CPP
 YACC
-YFLAGS'
+YFLAGS
+PKG_CONFIG
+PKG_CONFIG_PATH
+PKG_CONFIG_LIBDIR
+ZSTD_CFLAGS
+ZSTD_LIBS'
 
 
 # Initialize some variables set by options.
@@ -1493,6 +1504,8 @@ Optional Packages:
   --with-cpu=CPU          default cpu variant is CPU (currently only supported
                           on ARC)
   --with-system-zlib      use installed libz
+  --with-zstd             support zstd compressed debug sections
+                          (default=auto)
 
 Some influential environment variables:
   CC          C compiler command
@@ -1509,6 +1522,13 @@ Some influential environment variables:
   YFLAGS      The list of arguments that will be passed by default to $YACC.
               This script will default YFLAGS to the empty string to avoid a
               default value of `-d' given by some make applications.
+  PKG_CONFIG  path to pkg-config utility
+  PKG_CONFIG_PATH
+              directories to add to pkg-config's search path
+  PKG_CONFIG_LIBDIR
+              path overriding pkg-config's built-in search path
+  ZSTD_CFLAGS C compiler flags for ZSTD, overriding pkg-config
+  ZSTD_LIBS   linker flags for ZSTD, overriding pkg-config
 
 Use these variables to override the choices made by `configure' or to help
 it to find libraries and programs with nonstandard names/locations.
@@ -10702,7 +10722,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 10705 "configure"
+#line 10725 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -10808,7 +10828,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 10811 "configure"
+#line 10831 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -13945,7 +13965,7 @@ $as_echo "#define USE_BINARY_FOPEN 1" >>confdefs.h
  ;;
 esac
 
-# Link in zlib if we can.  This allows us to write compressed debug sections.
+# Link in zlib/zstd if we can.  This allows us to write compressed debug sections.
 
   # Use the system's zlib library.
   zlibdir="-L\$(top_builddir)/../zlib"
 
 
 
+
+
+
+
+
+
+if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
+       if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
+set dummy ${ac_tool_prefix}pkg-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_PKG_CONFIG+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $PKG_CONFIG in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+PKG_CONFIG=$ac_cv_path_PKG_CONFIG
+if test -n "$PKG_CONFIG"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5
+$as_echo "$PKG_CONFIG" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_path_PKG_CONFIG"; then
+  ac_pt_PKG_CONFIG=$PKG_CONFIG
+  # Extract the first word of "pkg-config", so it can be a program name with args.
+set dummy pkg-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $ac_pt_PKG_CONFIG in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG
+if test -n "$ac_pt_PKG_CONFIG"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5
+$as_echo "$ac_pt_PKG_CONFIG" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_pt_PKG_CONFIG" = x; then
+    PKG_CONFIG=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    PKG_CONFIG=$ac_pt_PKG_CONFIG
+  fi
+else
+  PKG_CONFIG="$ac_cv_path_PKG_CONFIG"
+fi
+
+fi
+if test -n "$PKG_CONFIG"; then
+       _pkg_min_version=0.9.0
+       { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5
+$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; }
+       if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
+               { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+       else
+               { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+               PKG_CONFIG=""
+       fi
+fi
+
+
+# Check whether --with-zstd was given.
+if test "${with_zstd+set}" = set; then :
+  withval=$with_zstd;
+else
+  with_zstd=auto
+fi
+
+
+if test "$with_zstd" != no; then :
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libzstd" >&5
+$as_echo_n "checking for libzstd... " >&6; }
+
+if test -n "$ZSTD_CFLAGS"; then
+    pkg_cv_ZSTD_CFLAGS="$ZSTD_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libzstd\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libzstd") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_ZSTD_CFLAGS=`$PKG_CONFIG --cflags "libzstd" 2>/dev/null`
+                     test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+if test -n "$ZSTD_LIBS"; then
+    pkg_cv_ZSTD_LIBS="$ZSTD_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libzstd\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libzstd") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_ZSTD_LIBS=`$PKG_CONFIG --libs "libzstd" 2>/dev/null`
+                     test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+
+if test $pkg_failed = no; then
+  pkg_save_LDFLAGS="$LDFLAGS"
+  LDFLAGS="$LDFLAGS $pkg_cv_ZSTD_LIBS"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+else
+  pkg_failed=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  LDFLAGS=$pkg_save_LDFLAGS
+fi
+
+
+
+if test $pkg_failed = yes; then
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi
+        if test $_pkg_short_errors_supported = yes; then
+               ZSTD_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libzstd" 2>&1`
+        else
+               ZSTD_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libzstd" 2>&1`
+        fi
+       # Put the nasty error message in config.log where it belongs
+       echo "$ZSTD_PKG_ERRORS" >&5
+
+
+    if test "$with_zstd" = yes; then
+      as_fn_error $? "--with-zstd was given, but pkgconfig/libzstd.pc is not found" "$LINENO" 5
+    fi
+
+elif test $pkg_failed = untried; then
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+    if test "$with_zstd" = yes; then
+      as_fn_error $? "--with-zstd was given, but pkgconfig/libzstd.pc is not found" "$LINENO" 5
+    fi
+
+else
+       ZSTD_CFLAGS=$pkg_cv_ZSTD_CFLAGS
+       ZSTD_LIBS=$pkg_cv_ZSTD_LIBS
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+
+$as_echo "#define HAVE_ZSTD 1" >>confdefs.h
+
+
+fi
+
+fi
+
+
 # Support for VMS timestamps via cross compile
 
 if test "$ac_cv_header_time_h" = yes; then
index 21795a82bdd11fedd1a06de5b756963eb734928a..e6f3298cb3ec2188434e896794c10d342011b20e 100644 (file)
@@ -1004,8 +1004,9 @@ AC_CHECK_DECLS([asprintf, mempcpy, stpcpy])
 
 BFD_BINARY_FOPEN
 
-# Link in zlib if we can.  This allows us to write compressed debug sections.
+# Link in zlib/zstd if we can.  This allows us to write compressed debug sections.
 AM_ZLIB
+AC_ZSTD
 
 # Support for VMS timestamps via cross compile
 
index e915893da86958c17c08507ad56a89a93d937b65..01f49434021f5fb2dc163c84b8a1823711db20ac 100644 (file)
@@ -711,16 +711,19 @@ given section @emph{larger} then it is not compressed.
 @itemx --compress-debug-sections=zlib
 @itemx --compress-debug-sections=zlib-gnu
 @itemx --compress-debug-sections=zlib-gabi
+@itemx --compress-debug-sections=zstd
 These options control how DWARF debug sections are compressed.
 @option{--compress-debug-sections=none} is equivalent to
 @option{--nocompress-debug-sections}.
 @option{--compress-debug-sections=zlib} and
 @option{--compress-debug-sections=zlib-gabi} are equivalent to
 @option{--compress-debug-sections}.
-@option{--compress-debug-sections=zlib-gnu} compresses DWARF debug
-sections using zlib.  The debug sections are renamed to begin with
-@samp{.zdebug}.  Note if compression would make a given section
-@emph{larger} then it is not compressed nor renamed.
+@option{--compress-debug-sections=zlib-gnu} compresses DWARF debug sections
+using the obsoleted zlib-gnu format.  The debug sections are renamed to begin
+with @samp{.zdebug}.
+@option{--compress-debug-sections=zstd} compresses DWARF debug
+sections using zstd.  Note - if compression would actually make a section
+@emph{larger}, then it is not compressed nor renamed.
 
 @end ifset
 
index f76bbdb706e7b9fe07e05229e568fe26ca783ef8..0e49df7c03f110abf75e6f3357c5d336b74ef995 100644 (file)
@@ -1413,7 +1413,7 @@ write_relocs (bfd *abfd ATTRIBUTE_UNUSED, asection *sec,
 }
 
 static int
-compress_frag (struct z_stream_s *strm, const char *contents, int in_size,
+compress_frag (bool use_zstd, void *ctx, const char *contents, int in_size,
               fragS **last_newf, struct obstack *ob)
 {
   int out_size;
@@ -1442,10 +1442,10 @@ compress_frag (struct z_stream_s *strm, const char *contents, int in_size,
        as_fatal (_("can't extend frag"));
       next_out = obstack_next_free (ob);
       obstack_blank_fast (ob, avail_out);
-      out_size = compress_data (strm, &contents, &in_size,
-                               &next_out, &avail_out);
+      out_size = compress_data (use_zstd, ctx, &contents, &in_size, &next_out,
+                               &avail_out);
       if (out_size < 0)
-        return -1;
+       return -1;
 
       f->fr_fix += out_size;
       total_out_size += out_size;
@@ -1471,7 +1471,6 @@ compress_debug (bfd *abfd, asection *sec, void *xxx ATTRIBUTE_UNUSED)
   const char *section_name;
   char *compressed_name;
   char *header;
-  struct z_stream_s *strm;
   int x;
   flagword flags = bfd_section_flags (sec);
   unsigned int header_size, compression_header_size;
@@ -1485,20 +1484,21 @@ compress_debug (bfd *abfd, asection *sec, void *xxx ATTRIBUTE_UNUSED)
   if (!startswith (section_name, ".debug_"))
     return;
 
-  strm = compress_init ();
-  if (strm == NULL)
+  bool use_zstd = abfd->flags & BFD_COMPRESS_ZSTD;
+  void *ctx = compress_init (use_zstd);
+  if (ctx == NULL)
     return;
 
-  if (flag_compress_debug == COMPRESS_DEBUG_GABI_ZLIB)
+  if (flag_compress_debug == COMPRESS_DEBUG_GNU_ZLIB)
     {
-      compression_header_size
-       = bfd_get_compression_header_size (stdoutput, NULL);
-      header_size = compression_header_size;
+      compression_header_size = 0;
+      header_size = 12;
     }
   else
     {
-      compression_header_size = 0;
-      header_size = 12;
+      compression_header_size
+       = bfd_get_compression_header_size (stdoutput, NULL);
+      header_size = compression_header_size;
     }
 
   /* Create a new frag to contain the compression header.  */
@@ -1531,7 +1531,7 @@ compress_debug (bfd *abfd, asection *sec, void *xxx ATTRIBUTE_UNUSED)
       gas_assert (f->fr_type == rs_fill);
       if (f->fr_fix)
        {
-         out_size = compress_frag (strm, f->fr_literal, f->fr_fix,
+         out_size = compress_frag (use_zstd, ctx, f->fr_literal, f->fr_fix,
                                    &last_newf, ob);
          if (out_size < 0)
            return;
@@ -1545,8 +1545,8 @@ compress_debug (bfd *abfd, asection *sec, void *xxx ATTRIBUTE_UNUSED)
        {
          while (count--)
            {
-             out_size = compress_frag (strm, fill_literal, (int) fill_size,
-                                       &last_newf, ob);
+             out_size = compress_frag (use_zstd, ctx, fill_literal,
+                                       (int)fill_size, &last_newf, ob);
              if (out_size < 0)
                return;
              compressed_size += out_size;
@@ -1579,7 +1579,7 @@ compress_debug (bfd *abfd, asection *sec, void *xxx ATTRIBUTE_UNUSED)
        as_fatal (_("can't extend frag"));
       next_out = obstack_next_free (ob);
       obstack_blank_fast (ob, avail_out);
-      x = compress_finish (strm, &next_out, &avail_out, &out_size);
+      x = compress_finish (use_zstd, ctx, &next_out, &avail_out, &out_size);
       if (x < 0)
        return;
 
@@ -2540,6 +2540,8 @@ write_object_file (void)
     {
       if (flag_compress_debug == COMPRESS_DEBUG_GABI_ZLIB)
        stdoutput->flags |= BFD_COMPRESS | BFD_COMPRESS_GABI;
+      else if (flag_compress_debug == COMPRESS_DEBUG_ZSTD)
+       stdoutput->flags |= BFD_COMPRESS | BFD_COMPRESS_GABI | BFD_COMPRESS_ZSTD;
       else
        stdoutput->flags |= BFD_COMPRESS;
       bfd_map_over_sections (stdoutput, compress_debug, (char *) 0);
index 2598b81d2054d073d56f0edb5778fc5917712180..c528ee5aa806fb46c79bfc76b42590635aa96e07 100644 (file)
@@ -173,6 +173,9 @@ BFD_CFLAGS = -I$(BFD_DIR) -I$(BFD_SRC)
 ZLIB = @zlibdir@ -lz
 ZLIBINC = @zlibinc@
 
+ZSTD_CFLAGS = @ZSTD_CFLAGS@
+ZSTD_LIBS = @ZSTD_LIBS@
+
 # Where is the decnumber library?  Typically in ../libdecnumber.
 LIBDECNUMBER_DIR = ../libdecnumber
 LIBDECNUMBER = $(LIBDECNUMBER_DIR)/libdecnumber.a
@@ -625,7 +628,7 @@ INTERNAL_CPPFLAGS = $(CPPFLAGS) @GUILE_CPPFLAGS@ @PYTHON_CPPFLAGS@ \
 INTERNAL_CFLAGS_BASE = \
        $(GLOBAL_CFLAGS) $(PROFILE_CFLAGS) \
        $(GDB_CFLAGS) $(OPCODES_CFLAGS) $(READLINE_CFLAGS) $(ZLIBINC) \
-       $(BFD_CFLAGS) $(INCLUDE_CFLAGS) $(LIBDECNUMBER_CFLAGS) \
+       $(ZSTD_CFLAGS) $(BFD_CFLAGS) $(INCLUDE_CFLAGS) $(LIBDECNUMBER_CFLAGS) \
        $(INTL_CFLAGS) $(INCGNU) $(INCSUPPORT) $(LIBBACKTRACE_INC) \
        $(ENABLE_CFLAGS) $(INTERNAL_CPPFLAGS) $(SRCHIGH_CFLAGS) \
        $(TOP_CFLAGS) $(PTHREAD_CFLAGS) $(DEBUGINFOD_CFLAGS)
@@ -647,7 +650,7 @@ INTERNAL_LDFLAGS = \
 # Libraries and corresponding dependencies for compiling gdb.
 # XM_CLIBS, defined in *config files, have host-dependent libs.
 # LIBIBERTY appears twice on purpose.
-CLIBS = $(SIM) $(READLINE) $(OPCODES) $(LIBCTF) $(BFD) $(ZLIB) \
+CLIBS = $(SIM) $(READLINE) $(OPCODES) $(LIBCTF) $(BFD) $(ZLIB) $(ZSTD_LIBS) \
         $(LIBSUPPORT) $(INTL) $(LIBIBERTY) $(LIBDECNUMBER) \
        $(XM_CLIBS) $(GDBTKLIBS)  $(LIBBACKTRACE_LIB) \
        @LIBS@ @GUILE_LIBS@ @PYTHON_LIBS@ \
@@ -2298,6 +2301,7 @@ aclocal_m4_deps = \
        ../config/lcmessage.m4 \
        ../config/codeset.m4 \
        ../config/zlib.m4 \
+       ../config/zstd.m4 \
        ../config/ax_pthread.m4
 
 $(srcdir)/aclocal.m4: @MAINTAINER_MODE_TRUE@ $(aclocal_m4_deps)
index 9619842bc0333d20089accbb163926c449b4d298..1457c99ff04a6a3a005c1cd1b01d6461fc754899 100644 (file)
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -57,6 +57,8 @@
 
 * The Windows native target now supports target async.
 
+* gdb now supports zstd compressed debug sections (ELFCOMPRESS_ZSTD) for ELF.
+
 * New commands
 
 maintenance set ignore-prologue-end-flag on|off
index 95ff2b6f35e12fa3a4ed1153e73bdc5322000197..28846119dcb82a52761cfc5bd33855ad67f8663a 100644 (file)
@@ -43,6 +43,7 @@ m4_include([../config/lib-link.m4])
 m4_include([../config/iconv.m4])
 
 m4_include([../config/zlib.m4])
+m4_include([../config/zstd.m4])
 
 m4_include([../gdbsupport/common.m4])
 
@@ -233,7 +234,7 @@ AC_DEFUN([GDB_AC_CHECK_BFD], [
   # always want our bfd.
   CFLAGS="-I${srcdir}/../include -I../bfd -I${srcdir}/../bfd $CFLAGS"
   ZLIBDIR=`echo $zlibdir | sed 's,\$(top_builddir)/,,g'`
-  LDFLAGS="-L../bfd -L../libiberty $ZLIBDIR $LDFLAGS"
+  LDFLAGS="-L../bfd -L../libiberty $ZLIBDIR $ZSTD_LIBS $LDFLAGS"
   intl=`echo $LIBINTL | sed 's,${top_builddir}/,,g'`
   LIBS="-lbfd -liberty -lz $intl $LIBS"
   AC_CACHE_CHECK(
index a4975c68aad11507838ba2a1fda3b840bcdf5923..e13a409ec2d3874b5544e885fd6ab2ece4b227e0 100644 (file)
 /* Define to 1 if you have the `XML_StopParser' function. */
 #undef HAVE_XML_STOPPARSER
 
+/* Define to 1 if zstd is enabled. */
+#undef HAVE_ZSTD
+
 /* Define to 1 if your system has the _etext variable. */
 #undef HAVE__ETEXT
 
index 4dbd0c3b13ceeb94a3e50d246a481eb981be5eff..9c7a37a623e82f8135f11ac7f959d3bd5f3356d4 100755 (executable)
@@ -747,6 +747,8 @@ READLINE_DEPS
 READLINE
 LTLIBICONV
 LIBICONV
+ZSTD_LIBS
+ZSTD_CFLAGS
 zlibinc
 zlibdir
 MIG
@@ -893,6 +895,7 @@ enable_codesign
 with_pkgversion
 with_bugurl
 with_system_zlib
+with_zstd
 with_gnu_ld
 enable_rpath
 with_libiconv_prefix
@@ -961,6 +964,8 @@ DEBUGINFOD_CFLAGS
 DEBUGINFOD_LIBS
 YACC
 YFLAGS
+ZSTD_CFLAGS
+ZSTD_LIBS
 XMKMF'
 ac_subdirs_all='testsuite
 gdbtk'
@@ -1641,6 +1646,8 @@ Optional Packages:
   --with-pkgversion=PKG   Use PKG in the version string in place of "GDB"
   --with-bugurl=URL       Direct users to URL to report a bug
   --with-system-zlib      use installed libz
+  --with-zstd             support zstd compressed debug sections
+                          (default=auto)
   --with-gnu-ld           assume the C compiler uses GNU ld default=no
   --with-libiconv-prefix[=DIR]  search for libiconv in DIR/include and DIR/lib
   --without-libiconv-prefix     don't search for libiconv in includedir and libdir
@@ -1721,6 +1728,8 @@ Some influential environment variables:
   YFLAGS      The list of arguments that will be passed by default to $YACC.
               This script will default YFLAGS to the empty string to avoid a
               default value of `-d' given by some make applications.
+  ZSTD_CFLAGS C compiler flags for ZSTD, overriding pkg-config
+  ZSTD_LIBS   linker flags for ZSTD, overriding pkg-config
   XMKMF       Path to xmkmf, Makefile generator for X Window System
 
 Use these variables to override the choices made by `configure' or to help
@@ -8242,7 +8251,8 @@ if test "$ac_res" != no; then :
 fi
 
 
-# Link in zlib if we can.  This allows us to read compressed debug sections.
+# Link in zlib/zstd if we can.  This allows us to read compressed debug
+# sections.
 
   # Use the system's zlib library.
   zlibdir="-L\$(top_builddir)/../zlib"
@@ -8262,6 +8272,127 @@ fi
 
 
 
+# Check whether --with-zstd was given.
+if test "${with_zstd+set}" = set; then :
+  withval=$with_zstd;
+else
+  with_zstd=auto
+fi
+
+
+if test "$with_zstd" != no; then :
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libzstd" >&5
+$as_echo_n "checking for libzstd... " >&6; }
+
+if test -n "$ZSTD_CFLAGS"; then
+    pkg_cv_ZSTD_CFLAGS="$ZSTD_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libzstd\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libzstd") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_ZSTD_CFLAGS=`$PKG_CONFIG --cflags "libzstd" 2>/dev/null`
+                     test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+if test -n "$ZSTD_LIBS"; then
+    pkg_cv_ZSTD_LIBS="$ZSTD_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libzstd\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libzstd") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_ZSTD_LIBS=`$PKG_CONFIG --libs "libzstd" 2>/dev/null`
+                     test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+
+if test $pkg_failed = no; then
+  pkg_save_LDFLAGS="$LDFLAGS"
+  LDFLAGS="$LDFLAGS $pkg_cv_ZSTD_LIBS"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+else
+  pkg_failed=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  LDFLAGS=$pkg_save_LDFLAGS
+fi
+
+
+
+if test $pkg_failed = yes; then
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi
+        if test $_pkg_short_errors_supported = yes; then
+               ZSTD_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libzstd" 2>&1`
+        else
+               ZSTD_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libzstd" 2>&1`
+        fi
+       # Put the nasty error message in config.log where it belongs
+       echo "$ZSTD_PKG_ERRORS" >&5
+
+
+    if test "$with_zstd" = yes; then
+      as_fn_error $? "--with-zstd was given, but pkgconfig/libzstd.pc is not found" "$LINENO" 5
+    fi
+
+elif test $pkg_failed = untried; then
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+    if test "$with_zstd" = yes; then
+      as_fn_error $? "--with-zstd was given, but pkgconfig/libzstd.pc is not found" "$LINENO" 5
+    fi
+
+else
+       ZSTD_CFLAGS=$pkg_cv_ZSTD_CFLAGS
+       ZSTD_LIBS=$pkg_cv_ZSTD_LIBS
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+
+$as_echo "#define HAVE_ZSTD 1" >>confdefs.h
+
+
+fi
+
+fi
+
+
+
       if test "X$prefix" = "XNONE"; then
     acl_final_prefix="$ac_default_prefix"
   else
@@ -17281,7 +17412,7 @@ WIN32LIBS="$WIN32LIBS $WIN32APILIBS"
   # always want our bfd.
   CFLAGS="-I${srcdir}/../include -I../bfd -I${srcdir}/../bfd $CFLAGS"
   ZLIBDIR=`echo $zlibdir | sed 's,\$(top_builddir)/,,g'`
-  LDFLAGS="-L../bfd -L../libiberty $ZLIBDIR $LDFLAGS"
+  LDFLAGS="-L../bfd -L../libiberty $ZLIBDIR $ZSTD_LIBS $LDFLAGS"
   intl=`echo $LIBINTL | sed 's,${top_builddir}/,,g'`
   LIBS="-lbfd -liberty -lz $intl $LIBS"
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ELF support in BFD" >&5
@@ -17396,7 +17527,7 @@ fi
   # always want our bfd.
   CFLAGS="-I${srcdir}/../include -I../bfd -I${srcdir}/../bfd $CFLAGS"
   ZLIBDIR=`echo $zlibdir | sed 's,\$(top_builddir)/,,g'`
-  LDFLAGS="-L../bfd -L../libiberty $ZLIBDIR $LDFLAGS"
+  LDFLAGS="-L../bfd -L../libiberty $ZLIBDIR $ZSTD_LIBS $LDFLAGS"
   intl=`echo $LIBINTL | sed 's,${top_builddir}/,,g'`
   LIBS="-lbfd -liberty -lz $intl $LIBS"
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Mach-O support in BFD" >&5
index 215a91c5b278f5fce363e24d1b8e409f9137adf2..fceb80e8c9d782ae94aca4d88286a7075dc6cbed 100644 (file)
@@ -460,8 +460,10 @@ AC_SEARCH_LIBS(gethostbyname, nsl)
 # Some systems (e.g. Solaris) have `socketpair' in libsocket.
 AC_SEARCH_LIBS(socketpair, socket)
 
-# Link in zlib if we can.  This allows us to read compressed debug sections.
+# Link in zlib/zstd if we can.  This allows us to read compressed debug
+# sections.
 AM_ZLIB
+AC_ZSTD
 
 AM_ICONV
 
index d31021c13e2e342cc82c2d49ac9c178f3a723d38..bbe25f3aca2b15d5fe0d2c4f8948f90918331c74 100644 (file)
@@ -45,7 +45,7 @@ ELF_CLFAGS=-DELF_LIST_OPTIONS=@elf_list_options@ \
           -DELF_PLT_UNWIND_LIST_OPTIONS=@elf_plt_unwind_list_options@
 WARN_CFLAGS = @WARN_CFLAGS@
 NO_WERROR = @NO_WERROR@
-AM_CFLAGS = $(WARN_CFLAGS) $(ELF_CLFAGS) $(JANSSON_CFLAGS)
+AM_CFLAGS = $(WARN_CFLAGS) $(ELF_CLFAGS) $(JANSSON_CFLAGS) $(ZSTD_CFLAGS)
 
 # We put the scripts in the directory $(scriptdir)/ldscripts.
 # We can't put the scripts in $(datadir) because the SEARCH_DIR
@@ -959,7 +959,8 @@ ld_new_SOURCES = ldgram.y ldlex-wrapper.c lexsup.c ldlang.c mri.c ldctor.c ldmai
        ldbuildid.c
 ld_new_DEPENDENCIES = $(EMULATION_OFILES) $(EMUL_EXTRA_OFILES) \
                      $(BFDLIB) $(LIBCTF) $(LIBIBERTY) $(LIBINTL_DEP) $(JANSSON_LIBS)
-ld_new_LDADD = $(EMULATION_OFILES) $(EMUL_EXTRA_OFILES) $(BFDLIB) $(LIBCTF) $(LIBIBERTY) $(LIBINTL) $(ZLIB) $(JANSSON_LIBS)
+ld_new_LDADD = $(EMULATION_OFILES) $(EMUL_EXTRA_OFILES) $(BFDLIB) $(LIBCTF) \
+              $(LIBIBERTY) $(LIBINTL) $(ZLIB) $(ZSTD_LIBS) $(JANSSON_LIBS)
 
 # Dependency tracking for the generated emulation files.
 EXTRA_ld_new_SOURCES += $(ALL_EMULATION_SOURCES) $(ALL_64_EMULATION_SOURCES)
index ee0c98f65b0ff2dc9a1d4e8118e5bc8bea22ff68..400eed2717e7d7a4d6ccf626c678cece30b73385 100644 (file)
@@ -126,7 +126,8 @@ am__aclocal_m4_deps = $(top_srcdir)/../bfd/acinclude.m4 \
        $(top_srcdir)/../config/plugins.m4 \
        $(top_srcdir)/../config/po.m4 \
        $(top_srcdir)/../config/progtest.m4 \
-       $(top_srcdir)/../config/zlib.m4 $(top_srcdir)/../libtool.m4 \
+       $(top_srcdir)/../config/zlib.m4 \
+       $(top_srcdir)/../config/zstd.m4 $(top_srcdir)/../libtool.m4 \
        $(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \
        $(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \
        $(top_srcdir)/../bfd/version.m4 $(top_srcdir)/configure.ac
@@ -477,6 +478,8 @@ WARN_WRITE_STRINGS = @WARN_WRITE_STRINGS@
 XGETTEXT = @XGETTEXT@
 YACC = `if [ -f ../bison/bison ]; then echo ../bison/bison -y -L$(srcdir)/../bison/; else echo @YACC@; fi`
 YFLAGS = -d
+ZSTD_CFLAGS = @ZSTD_CFLAGS@
+ZSTD_LIBS = @ZSTD_LIBS@
 abs_builddir = @abs_builddir@
 abs_srcdir = @abs_srcdir@
 abs_top_builddir = @abs_top_builddir@
@@ -564,7 +567,7 @@ ELF_CLFAGS = -DELF_LIST_OPTIONS=@elf_list_options@ \
           -DELF_SHLIB_LIST_OPTIONS=@elf_shlib_list_options@ \
           -DELF_PLT_UNWIND_LIST_OPTIONS=@elf_plt_unwind_list_options@
 
-AM_CFLAGS = $(WARN_CFLAGS) $(ELF_CLFAGS) $(JANSSON_CFLAGS)
+AM_CFLAGS = $(WARN_CFLAGS) $(ELF_CLFAGS) $(JANSSON_CFLAGS) $(ZSTD_CFLAGS)
 
 # We put the scripts in the directory $(scriptdir)/ldscripts.
 # We can't put the scripts in $(datadir) because the SEARCH_DIR
@@ -1011,7 +1014,9 @@ ld_new_SOURCES = ldgram.y ldlex-wrapper.c lexsup.c ldlang.c mri.c ldctor.c ldmai
 ld_new_DEPENDENCIES = $(EMULATION_OFILES) $(EMUL_EXTRA_OFILES) \
                      $(BFDLIB) $(LIBCTF) $(LIBIBERTY) $(LIBINTL_DEP) $(JANSSON_LIBS)
 
-ld_new_LDADD = $(EMULATION_OFILES) $(EMUL_EXTRA_OFILES) $(BFDLIB) $(LIBCTF) $(LIBIBERTY) $(LIBINTL) $(ZLIB) $(JANSSON_LIBS)
+ld_new_LDADD = $(EMULATION_OFILES) $(EMUL_EXTRA_OFILES) $(BFDLIB) $(LIBCTF) \
+              $(LIBIBERTY) $(LIBINTL) $(ZLIB) $(ZSTD_LIBS) $(JANSSON_LIBS)
+
 #
 #
 # Build a dummy plugin using libtool.
diff --git a/ld/NEWS b/ld/NEWS
index 355752e6b24b77dc503716f57ffc2f13154048ab..dfe2690d9f2a6e1973762d1c8c404e1f3fbb99bc 100644 (file)
--- a/ld/NEWS
+++ b/ld/NEWS
@@ -1,5 +1,8 @@
 -*- text -*-
 
+* ld now supports zstd compressed debug sections.  The new option
+  --compress-debug-sections=zstd compresses debug sections with zstd.
+
 Changes in 2.39:
 
 * The ELF linker will now generate a warning message if the stack is made
index d20c542eed5b16dd4edb03f447c4fa07bd021f35..893e973e4f25d3ef7524d1739c3a60aa01b30057 100644 (file)
@@ -1203,6 +1203,7 @@ m4_include([../config/plugins.m4])
 m4_include([../config/po.m4])
 m4_include([../config/progtest.m4])
 m4_include([../config/zlib.m4])
+m4_include([../config/zstd.m4])
 m4_include([../libtool.m4])
 m4_include([../ltoptions.m4])
 m4_include([../ltsugar.m4])
index 0ccd79d59cd026375a0a052358b81c6d684c3de5..3916740eee43466a76641a77e8ccf4abe632ec49 100644 (file)
 /* Define to 1 if you have the <windows.h> header file. */
 #undef HAVE_WINDOWS_H
 
+/* Define to 1 if zstd is enabled. */
+#undef HAVE_ZSTD
+
 /* Define to the sub-directory in which libtool stores uninstalled libraries.
    */
 #undef LT_OBJDIR
index 4efe3ef5dfc024d04642da01b4aa0ac3f1b5b54f..9dd3ed5f1e76b4312b9b0b063b0b07e1e645d517 100755 (executable)
@@ -646,6 +646,8 @@ elf_plt_unwind_list_options
 elf_shlib_list_options
 elf_list_options
 STRINGIFY
+ZSTD_LIBS
+ZSTD_CFLAGS
 zlibinc
 zlibdir
 NATIVE_LIB_DIRS
@@ -679,9 +681,6 @@ WARN_CFLAGS_FOR_BUILD
 WARN_CFLAGS
 JANSSON_LIBS
 JANSSON_CFLAGS
-PKG_CONFIG_LIBDIR
-PKG_CONFIG_PATH
-PKG_CONFIG
 enable_libctf
 ENABLE_LIBCTF_FALSE
 ENABLE_LIBCTF_TRUE
@@ -711,6 +710,9 @@ LD
 FGREP
 SED
 LIBTOOL
+PKG_CONFIG_LIBDIR
+PKG_CONFIG_PATH
+PKG_CONFIG
 EGREP
 CPP
 GREP
@@ -855,6 +857,7 @@ enable_werror
 enable_build_warnings
 enable_nls
 with_system_zlib
+with_zstd
 '
       ac_precious_vars='build_alias
 host_alias
@@ -868,14 +871,16 @@ CXX
 CXXFLAGS
 CCC
 CPP
-CXXCPP
 PKG_CONFIG
 PKG_CONFIG_PATH
 PKG_CONFIG_LIBDIR
+CXXCPP
 JANSSON_CFLAGS
 JANSSON_LIBS
 YACC
-YFLAGS'
+YFLAGS
+ZSTD_CFLAGS
+ZSTD_LIBS'
 
 
 # Initialize some variables set by options.
@@ -1552,6 +1557,8 @@ Optional Packages:
   --with-lib-path=dir1:dir2...  set default LIB_PATH
   --with-sysroot=DIR Search for usr/lib et al within DIR.
   --with-system-zlib      use installed libz
+  --with-zstd             support zstd compressed debug sections
+                          (default=auto)
 
 Some influential environment variables:
   CC          C compiler command
@@ -1564,12 +1571,12 @@ Some influential environment variables:
   CXX         C++ compiler command
   CXXFLAGS    C++ compiler flags
   CPP         C preprocessor
-  CXXCPP      C++ preprocessor
   PKG_CONFIG  path to pkg-config utility
   PKG_CONFIG_PATH
               directories to add to pkg-config's search path
   PKG_CONFIG_LIBDIR
               path overriding pkg-config's built-in search path
+  CXXCPP      C++ preprocessor
   JANSSON_CFLAGS
               C compiler flags for JANSSON, overriding pkg-config
   JANSSON_LIBS
@@ -1580,6 +1587,8 @@ Some influential environment variables:
   YFLAGS      The list of arguments that will be passed by default to $YACC.
               This script will default YFLAGS to the empty string to avoid a
               default value of `-d' given by some make applications.
+  ZSTD_CFLAGS C compiler flags for ZSTD, overriding pkg-config
+  ZSTD_LIBS   linker flags for ZSTD, overriding pkg-config
 
 Use these variables to override the choices made by `configure' or to help
 it to find libraries and programs with nonstandard names/locations.
@@ -5388,6 +5397,126 @@ $as_echo "$ac_cv_safe_to_define___extensions__" >&6; }
 
 
 
+
+
+
+
+
+
+if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
+       if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
+set dummy ${ac_tool_prefix}pkg-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_PKG_CONFIG+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $PKG_CONFIG in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+PKG_CONFIG=$ac_cv_path_PKG_CONFIG
+if test -n "$PKG_CONFIG"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5
+$as_echo "$PKG_CONFIG" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_path_PKG_CONFIG"; then
+  ac_pt_PKG_CONFIG=$PKG_CONFIG
+  # Extract the first word of "pkg-config", so it can be a program name with args.
+set dummy pkg-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $ac_pt_PKG_CONFIG in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG
+if test -n "$ac_pt_PKG_CONFIG"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5
+$as_echo "$ac_pt_PKG_CONFIG" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_pt_PKG_CONFIG" = x; then
+    PKG_CONFIG=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    PKG_CONFIG=$ac_pt_PKG_CONFIG
+  fi
+else
+  PKG_CONFIG="$ac_cv_path_PKG_CONFIG"
+fi
+
+fi
+if test -n "$PKG_CONFIG"; then
+       _pkg_min_version=0.9.0
+       { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5
+$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; }
+       if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
+               { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+       else
+               { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+               PKG_CONFIG=""
+       fi
+fi
+
 case `pwd` in
   *\ * | *\    *)
     { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5
@@ -11491,7 +11620,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11494 "configure"
+#line 11623 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11597,7 +11726,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11600 "configure"
+#line 11729 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -15585,126 +15714,6 @@ else
 fi
 
 
-
-
-
-
-
-
-
-if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
-       if test -n "$ac_tool_prefix"; then
-  # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
-set dummy ${ac_tool_prefix}pkg-config; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_PKG_CONFIG+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  case $PKG_CONFIG in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.
-  ;;
-  *)
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-  ;;
-esac
-fi
-PKG_CONFIG=$ac_cv_path_PKG_CONFIG
-if test -n "$PKG_CONFIG"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5
-$as_echo "$PKG_CONFIG" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-if test -z "$ac_cv_path_PKG_CONFIG"; then
-  ac_pt_PKG_CONFIG=$PKG_CONFIG
-  # Extract the first word of "pkg-config", so it can be a program name with args.
-set dummy pkg-config; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  case $ac_pt_PKG_CONFIG in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path.
-  ;;
-  *)
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-  ;;
-esac
-fi
-ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG
-if test -n "$ac_pt_PKG_CONFIG"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5
-$as_echo "$ac_pt_PKG_CONFIG" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-  if test "x$ac_pt_PKG_CONFIG" = x; then
-    PKG_CONFIG=""
-  else
-    case $cross_compiling:$ac_tool_warned in
-yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
-    PKG_CONFIG=$ac_pt_PKG_CONFIG
-  fi
-else
-  PKG_CONFIG="$ac_cv_path_PKG_CONFIG"
-fi
-
-fi
-if test -n "$PKG_CONFIG"; then
-       _pkg_min_version=0.9.0
-       { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5
-$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; }
-       if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
-               { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-       else
-               { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-               PKG_CONFIG=""
-       fi
-fi
 if test "x$enable_jansson" != "xno"; then :
 
 pkg_failed=no
@@ -17041,8 +17050,8 @@ $as_echo "#define HAVE_DECL_GETOPT 1" >>confdefs.h
 
 fi
 
-# Link in zlib if we can.  This allows us to read and write
-# compressed CTF sections.
+# Link in zlib/zstd if we can.  This allows us to read and write
+# compressed debug sections.
 
   # Use the system's zlib library.
   zlibdir="-L\$(top_builddir)/../zlib"
 
 
 
+
+# Check whether --with-zstd was given.
+if test "${with_zstd+set}" = set; then :
+  withval=$with_zstd;
+else
+  with_zstd=auto
+fi
+
+
+if test "$with_zstd" != no; then :
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libzstd" >&5
+$as_echo_n "checking for libzstd... " >&6; }
+
+if test -n "$ZSTD_CFLAGS"; then
+    pkg_cv_ZSTD_CFLAGS="$ZSTD_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libzstd\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libzstd") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_ZSTD_CFLAGS=`$PKG_CONFIG --cflags "libzstd" 2>/dev/null`
+                     test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+if test -n "$ZSTD_LIBS"; then
+    pkg_cv_ZSTD_LIBS="$ZSTD_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+    if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libzstd\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "libzstd") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_ZSTD_LIBS=`$PKG_CONFIG --libs "libzstd" 2>/dev/null`
+                     test "x$?" != "x0" && pkg_failed=yes
+else
+  pkg_failed=yes
+fi
+ else
+    pkg_failed=untried
+fi
+
+if test $pkg_failed = no; then
+  pkg_save_LDFLAGS="$LDFLAGS"
+  LDFLAGS="$LDFLAGS $pkg_cv_ZSTD_LIBS"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+else
+  pkg_failed=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  LDFLAGS=$pkg_save_LDFLAGS
+fi
+
+
+
+if test $pkg_failed = yes; then
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi
+        if test $_pkg_short_errors_supported = yes; then
+               ZSTD_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libzstd" 2>&1`
+        else
+               ZSTD_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libzstd" 2>&1`
+        fi
+       # Put the nasty error message in config.log where it belongs
+       echo "$ZSTD_PKG_ERRORS" >&5
+
+
+    if test "$with_zstd" = yes; then
+      as_fn_error $? "--with-zstd was given, but pkgconfig/libzstd.pc is not found" "$LINENO" 5
+    fi
+
+elif test $pkg_failed = untried; then
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+    if test "$with_zstd" = yes; then
+      as_fn_error $? "--with-zstd was given, but pkgconfig/libzstd.pc is not found" "$LINENO" 5
+    fi
+
+else
+       ZSTD_CFLAGS=$pkg_cv_ZSTD_CFLAGS
+       ZSTD_LIBS=$pkg_cv_ZSTD_LIBS
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+
+$as_echo "#define HAVE_ZSTD 1" >>confdefs.h
+
+
+fi
+
+fi
+
+
 # When converting linker scripts into strings for use in emulation
 # files, use astring.sed if the compiler supports ANSI string
 # concatenation, or ostring.sed otherwise.  This is to support the
index 8a8bfc9a14e7536b367f862f8ed7f8f28c581326..f1b2f9897f823d0732529707eeebc01cc6458f29 100644 (file)
@@ -34,6 +34,7 @@ AC_PROG_GREP
 AC_GNU_SOURCE
 AC_USE_SYSTEM_EXTENSIONS
 AC_PROG_INSTALL
+PKG_PROG_PKG_CONFIG
 
 LT_INIT
 ACX_LARGEFILE
@@ -377,9 +378,10 @@ if test $ld_cv_decl_getopt_unistd_h = yes; then
            [Is the prototype for getopt in <unistd.h> in the expected format?])
 fi
 
-# Link in zlib if we can.  This allows us to read and write
-# compressed CTF sections.
+# Link in zlib/zstd if we can.  This allows us to read and write
+# compressed debug sections.
 AM_ZLIB
+AC_ZSTD
 
 # When converting linker scripts into strings for use in emulation
 # files, use astring.sed if the compiler supports ANSI string
index c52484f35d3fb2859787a06aec53496c9dd6e2e5..acd66f907d1f958dd000d1adf247cfa7a797314d 100644 (file)
@@ -668,6 +668,15 @@ gld${EMULATION_NAME}_handle_option (int optc)
        link_info.compress_debug = COMPRESS_DEBUG_GNU_ZLIB;
       else if (strcasecmp (optarg, "zlib-gabi") == 0)
        link_info.compress_debug = COMPRESS_DEBUG_GABI_ZLIB;
+      else if (strcasecmp (optarg, "zstd") == 0)
+       {
+#ifdef HAVE_ZSTD
+         link_info.compress_debug = COMPRESS_DEBUG_ZSTD;
+#else
+         einfo (_ ("%F%P: --compress-debug-sections=zstd: ld is not built "
+                   "with zstd support\n"));
+#endif
+       }
       else
        einfo (_("%F%P: invalid --compress-debug-sections option: \`%s'\n"),
               optarg);
index eabbec8faa90137ec0cc382d5c6ae1ef810cb599..9daed2e7e9f09241c2b6a6dd73e1b0661e753849 100644 (file)
@@ -2863,10 +2863,12 @@ but for most Linux based systems it will be @code{both}.
 @kindex --compress-debug-sections=zlib
 @kindex --compress-debug-sections=zlib-gnu
 @kindex --compress-debug-sections=zlib-gabi
+@kindex --compress-debug-sections=zstd
 @item --compress-debug-sections=none
 @itemx --compress-debug-sections=zlib
 @itemx --compress-debug-sections=zlib-gnu
 @itemx --compress-debug-sections=zlib-gabi
+@itemx --compress-debug-sections=zstd
 On ELF platforms, these options control how DWARF debug sections are
 compressed using zlib.
 
@@ -2880,6 +2882,9 @@ sets the SHF_COMPRESSED flag in the sections' headers.
 The @option{--compress-debug-sections=zlib} option is an alias for
 @option{--compress-debug-sections=zlib-gabi}.
 
+@option{--compress-debug-sections=zstd} compresses DWARF debug sections using
+zstd.
+
 Note that this option overrides any compression in input debug
 sections, so if a binary is linked with @option{--compress-debug-sections=none}
 for example, then any compressed debug sections in input files will be
index e676c3786a2fc5d1b5a6135fda589b064431d482..d63002c994a23d6ed41acf73aed33007335c2245 100644 (file)
@@ -506,8 +506,12 @@ main (int argc, char **argv)
   if ((link_info.compress_debug & COMPRESS_DEBUG))
     {
       link_info.output_bfd->flags |= BFD_COMPRESS;
-      if (link_info.compress_debug == COMPRESS_DEBUG_GABI_ZLIB)
-       link_info.output_bfd->flags |= BFD_COMPRESS_GABI;
+      if (link_info.compress_debug != COMPRESS_DEBUG_GNU_ZLIB)
+       {
+         link_info.output_bfd->flags |= BFD_COMPRESS_GABI;
+         if (link_info.compress_debug == COMPRESS_DEBUG_ZSTD)
+           link_info.output_bfd->flags |= BFD_COMPRESS_ZSTD;
+       }
     }
 
   ldwrite ();
index 9225f71b3ce8a1f6741e82f3e923fd1d6f3d2669..299371fb775b3a2b0503ffebc5e11be99ac47b40 100644 (file)
@@ -2146,8 +2146,8 @@ elf_static_list_options (FILE *file)
   fprintf (file, _("\
   --package-metadata[=JSON]   Generate package metadata note\n"));
   fprintf (file, _("\
-  --compress-debug-sections=[none|zlib|zlib-gnu|zlib-gabi]\n\
-                              Compress DWARF debug sections using zlib\n"));
+  --compress-debug-sections=[none|zlib|zlib-gnu|zlib-gabi|zstd]\n\
+                             Compress DWARF debug sections\n"));
 #ifdef DEFAULT_FLAG_COMPRESS_DEBUG
   fprintf (file, _("\
                                 Default: zlib-gabi\n"));
index 52a91fc554e8da9321bdf65970f34116bedd33ff..99a11090ee766456b343066a9255f8c1953ef967 100644 (file)
@@ -161,6 +161,10 @@ foreach flags $test_flags {
        set extralibs "$extralibs -lz"
     }
 
+    if { [lindex [remote_exec build grep "-q \"HAVE_ZSTD 1\" config.h" ] 0] == 0 } then {
+       set extralibs "$extralibs -lzstd"
+    }
+
     # Check if the system's jansson library is used. If so, the object files will
     # be using symbols from it, so link to it.
     if { [lindex [remote_exec build grep "-q \"HAVE_JANSSON 1\" config.h" ] 0] == 0 } then {
index cfdd767b8abf7e3b74d4040cd93761b92eacdf5a..28a848619bfcb809dd4ee0bb0cb2ec09331cc795 100644 (file)
@@ -254,3 +254,19 @@ if { [regexp_diff tmpdir/$test.out $srcdir/$subdir/$test.rt] } then {
 } else {
     pass "$test_name"
 }
+
+if { [ld_assemble $as "--compress-debug-sections=zstd $srcdir/$subdir/empty.s" tmpdir/emptyzstd.o ] } {
+    set build_tests {
+      {"Build libzstdfoo.so with zstd compressed debug sections"
+       "-shared" "-fPIC -g -Wa,--compress-debug-sections=zstd -Wl,--compress-debug-sections=zstd"
+       {foo.c} {} "libzstdfoo.so"}
+    }
+    set run_tests {
+       {"Run zstdnormal with libzstdfoo.so with zstd compressed debug sections"
+        "tmpdir/begin.o tmpdir/libzstdfoo.so tmpdir/end.o -Wl,--compress-debug-sections=zstd" ""
+        {main.c} "zstdnormal" "normal.out" "-Wa,--compress-debug-sections=zstd"}
+    }
+
+    run_cc_link_tests $build_tests
+    run_ld_link_exec_tests $run_tests
+}