* [PATCH v3] binutils, gdb: support zstd compressed debug sections @ 2022-09-23 4:08 Fangrui Song 2022-09-23 14:32 ` Simon Marchi ` (4 more replies) 0 siblings, 5 replies; 32+ messages in thread From: Fangrui Song @ 2022-09-23 4:08 UTC (permalink / raw) To: Alan Modra, Jan Beulich, Nick Clifton, Simon Marchi Cc: binutils, gdb-patches, Fangrui Song PR29397 PR29563: The new configure option --with-zstd 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 ... ``` --- Changes from v1: * use PKG_CHECK_MODULES to check libzstd.pc Changes from v2: * Improve PKG_CHECK_MODULES, autoreconf -vf * objcopy: check --compress-debug-sections=zstd in a !HAVE_ZSTD build --- bfd/Makefile.am | 4 +- bfd/Makefile.in | 13 +- bfd/aclocal.m4 | 2 + bfd/bfd-in.h | 3 +- bfd/bfd-in2.h | 11 +- bfd/bfd.c | 26 +- bfd/compress.c | 72 +++- bfd/config.in | 3 + bfd/configure | 268 ++++++++++++- bfd/configure.ac | 3 +- bfd/elf.c | 12 + bfd/elfxx-target.h | 6 +- bfd/section.c | 3 +- binutils/Makefile.in | 5 +- binutils/aclocal.m4 | 1 + binutils/config.in | 3 + binutils/configure | 135 ++++++- binutils/configure.ac | 3 +- binutils/doc/binutils.texi | 16 +- binutils/objcopy.c | 19 +- binutils/testsuite/binutils-all/compress.exp | 44 +++ config/zstd.m4 | 24 ++ configure | 10 + configure.ac | 3 + gas/Makefile.am | 4 +- gas/Makefile.in | 13 +- gas/aclocal.m4 | 2 + gas/as.c | 13 +- gas/compress-debug.c | 60 ++- gas/compress-debug.h | 10 +- gas/config.in | 3 + gas/configure | 268 ++++++++++++- gas/configure.ac | 3 +- gas/doc/as.texi | 11 +- gas/write.c | 36 +- gdb/Makefile.in | 8 +- gdb/acinclude.m4 | 3 +- gdb/config.in | 3 + gdb/configure | 136 ++++++- gdb/configure.ac | 4 +- ld/Makefile.am | 5 +- ld/Makefile.in | 11 +- ld/aclocal.m4 | 1 + ld/config.in | 3 + ld/configure | 389 ++++++++++++------- ld/configure.ac | 7 +- ld/emultempl/elf.em | 9 + ld/ld.texi | 5 + ld/ldmain.c | 8 +- ld/lexsup.c | 4 +- ld/testsuite/ld-elf/compress.exp | 17 + 51 files changed, 1470 insertions(+), 255 deletions(-) create mode 100644 config/zstd.m4 diff --git a/bfd/Makefile.am b/bfd/Makefile.am index c23dff6cac3..cfe903c63f0 100644 --- a/bfd/Makefile.am +++ b/bfd/Makefile.am @@ -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 diff --git a/bfd/Makefile.in b/bfd/Makefile.in index 82843d2d61d..6be41a72a59 100644 --- a/bfd/Makefile.in +++ b/bfd/Makefile.in @@ -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 diff --git a/bfd/aclocal.m4 b/bfd/aclocal.m4 index 0f8aa1d4518..09b849dfc87 100644 --- a/bfd/aclocal.m4 +++ b/bfd/aclocal.m4 @@ -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]) diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h index 8605056aefe..4765ea80536 100644 --- a/bfd/bfd-in.h +++ b/bfd/bfd-in.h @@ -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 diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 79fcc4eb912..5c80956c79c 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -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); diff --git a/bfd/bfd.c b/bfd/bfd.c index 0a21db11fd6..5f2033bee7a 100644 --- 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; diff --git a/bfd/compress.c b/bfd/compress.c index b2e39826e38..95c1f4c42d1 100644 --- a/bfd/compress.c +++ b/bfd/compress.c @@ -20,18 +20,31 @@ #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)) + if (!decompress_contents (compress_status == DECOMPRESS_SECTION_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; } diff --git a/bfd/config.in b/bfd/config.in index f54a3cacbea..a59304e0a66 100644 --- a/bfd/config.in +++ b/bfd/config.in @@ -232,6 +232,9 @@ /* 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 diff --git a/bfd/configure b/bfd/configure index 075d2ee0a1b..d905a7bf7a8 100755 --- a/bfd/configure +++ b/bfd/configure @@ -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. @@ -13015,6 +13035,246 @@ 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 + + +# 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 diff --git a/bfd/configure.ac b/bfd/configure.ac index 28f3d1afce6..d1b2f76b31a 100644 --- a/bfd/configure.ac +++ b/bfd/configure.ac @@ -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 +AM_ZSTD save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Werror" diff --git a/bfd/elf.c b/bfd/elf.c index 16cea4f8aeb..e52fa458a5a 100644 --- 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) diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h index feaba84bf2e..ca600bb5ddf 100644 --- a/bfd/elfxx-target.h +++ b/bfd/elfxx-target.h @@ -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 diff --git a/bfd/section.c b/bfd/section.c index c7a02d729f2..614570e976e 100644 --- a/bfd/section.c +++ b/bfd/section.c @@ -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. *} . diff --git a/binutils/Makefile.in b/binutils/Makefile.in index 78d32b350e3..6de4e239408 100644 --- a/binutils/Makefile.in +++ b/binutils/Makefile.in @@ -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@ diff --git a/binutils/aclocal.m4 b/binutils/aclocal.m4 index a877fa7f873..28271f56279 100644 --- a/binutils/aclocal.m4 +++ b/binutils/aclocal.m4 @@ -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]) diff --git a/binutils/config.in b/binutils/config.in index c5fb919aa95..bee8c07e2f7 100644 --- a/binutils/config.in +++ b/binutils/config.in @@ -157,6 +157,9 @@ /* 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 diff --git a/binutils/configure b/binutils/configure index 1c518227f57..54d0f184da1 100755 --- a/binutils/configure +++ b/binutils/configure @@ -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). @@ -13490,6 +13499,126 @@ 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 + + + case "${host}" in *-*-msdos* | *-*-go32* | *-*-mingw32* | *-*-cygwin* | *-*-windows*) diff --git a/binutils/configure.ac b/binutils/configure.ac index ec002d3f88f..c152b7f6733 100644 --- a/binutils/configure.ac +++ b/binutils/configure.ac @@ -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 +AM_ZSTD BFD_BINARY_FOPEN diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi index 1499db5728c..34a4164eb94 100644 --- a/binutils/doc/binutils.texi +++ b/binutils/doc/binutils.texi @@ -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 diff --git a/binutils/objcopy.c b/binutils/objcopy.c index 43261756a42..fc668f00bbc 100644 --- a/binutils/objcopy.c +++ b/binutils/objcopy.c @@ -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); diff --git a/binutils/testsuite/binutils-all/compress.exp b/binutils/testsuite/binutils-all/compress.exp index c88da74a987..4e74c824664 100644 --- a/binutils/testsuite/binutils-all/compress.exp +++ b/binutils/testsuite/binutils-all/compress.exp @@ -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 index 00000000000..93ae17b89d3 --- /dev/null +++ b/config/zstd.m4 @@ -0,0 +1,24 @@ +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([AM_ZSTD], +[ +AC_ARG_WITH(zstd, + [AS_HELP_STRING([--with-zstd], [support zstd compressed debug sections (default=auto)])], + [], [with_zstd=auto]) + +if test "$with_zstd" != no; then + 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 + ]) +fi +]) diff --git a/configure b/configure index d75f47a1e95..f14e0efd675 100755 --- 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 diff --git a/configure.ac b/configure.ac index ae18d436aca..0152c69292e 100644 --- a/configure.ac +++ b/configure.ac @@ -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 diff --git a/gas/Makefile.am b/gas/Makefile.am index bd597398671..5f0f24abf8d 100644 --- a/gas/Makefile.am +++ b/gas/Makefile.am @@ -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) \ diff --git a/gas/Makefile.in b/gas/Makefile.in index c57d78f82c4..5a4dd702252 100644 --- a/gas/Makefile.in +++ b/gas/Makefile.in @@ -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) diff --git a/gas/aclocal.m4 b/gas/aclocal.m4 index 70183124da7..722030c776f 100644 --- a/gas/aclocal.m4 +++ b/gas/aclocal.m4 @@ -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]) diff --git a/gas/as.c b/gas/as.c index 6268779cf90..35ad6b3ab3b 100644 --- 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); diff --git a/gas/compress-debug.c b/gas/compress-debug.c index c80dbeec4e7..3cd175f6e57 100644 --- a/gas/compress-debug.c +++ b/gas/compress-debug.c @@ -21,14 +21,23 @@ #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); diff --git a/gas/compress-debug.h b/gas/compress-debug.h index 0183e269fef..87de0f8444e 100644 --- a/gas/compress-debug.h +++ b/gas/compress-debug.h @@ -21,19 +21,19 @@ #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 */ diff --git a/gas/config.in b/gas/config.in index e243fd277ee..0d1668a3eac 100644 --- a/gas/config.in +++ b/gas/config.in @@ -134,6 +134,9 @@ /* 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 diff --git a/gas/configure b/gas/configure index d0449a1d7ab..1833adffaa8 100755 --- a/gas/configure +++ b/gas/configure @@ -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" @@ -13964,6 +13984,246 @@ 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 + + +# 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 diff --git a/gas/configure.ac b/gas/configure.ac index 21795a82bdd..8750ea21381 100644 --- a/gas/configure.ac +++ b/gas/configure.ac @@ -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 +AM_ZSTD # Support for VMS timestamps via cross compile diff --git a/gas/doc/as.texi b/gas/doc/as.texi index e915893da86..01f49434021 100644 --- a/gas/doc/as.texi +++ b/gas/doc/as.texi @@ -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 diff --git a/gas/write.c b/gas/write.c index f76bbdb706e..0e49df7c03f 100644 --- a/gas/write.c +++ b/gas/write.c @@ -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,21 +1484,22 @@ 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 = 0; + header_size = 12; + } + else { compression_header_size = bfd_get_compression_header_size (stdoutput, NULL); header_size = compression_header_size; } - else - { - compression_header_size = 0; - header_size = 12; - } /* Create a new frag to contain the compression header. */ first_newf = frag_alloc (ob); @@ -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); diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 2598b81d205..c528ee5aa80 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -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) diff --git a/gdb/acinclude.m4 b/gdb/acinclude.m4 index 95ff2b6f35e..28846119dcb 100644 --- a/gdb/acinclude.m4 +++ b/gdb/acinclude.m4 @@ -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( diff --git a/gdb/config.in b/gdb/config.in index a4975c68aad..e13a409ec2d 100644 --- a/gdb/config.in +++ b/gdb/config.in @@ -589,6 +589,9 @@ /* 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 diff --git a/gdb/configure b/gdb/configure index 4dbd0c3b13c..57cd165088a 100755 --- a/gdb/configure +++ b/gdb/configure @@ -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,126 @@ 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 +17411,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 +17526,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 diff --git a/gdb/configure.ac b/gdb/configure.ac index 215a91c5b27..e8cf808d280 100644 --- a/gdb/configure.ac +++ b/gdb/configure.ac @@ -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 +AM_ZSTD AM_ICONV diff --git a/ld/Makefile.am b/ld/Makefile.am index d31021c13e2..bbe25f3aca2 100644 --- a/ld/Makefile.am +++ b/ld/Makefile.am @@ -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) diff --git a/ld/Makefile.in b/ld/Makefile.in index ee0c98f65b0..400eed2717e 100644 --- a/ld/Makefile.in +++ b/ld/Makefile.in @@ -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/aclocal.m4 b/ld/aclocal.m4 index d20c542eed5..893e973e4f2 100644 --- a/ld/aclocal.m4 +++ b/ld/aclocal.m4 @@ -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]) diff --git a/ld/config.in b/ld/config.in index 0ccd79d59cd..3916740eee4 100644 --- a/ld/config.in +++ b/ld/config.in @@ -162,6 +162,9 @@ /* 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 diff --git a/ld/configure b/ld/configure index a1a07005400..175dd995b2b 100755 --- a/ld/configure +++ b/ld/configure @@ -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 @@ -15586,126 +15715,6 @@ fi if test "x$enable_jansson" != "xno"; then - - - - - - - -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 -n "$PKG_CONFIG"; then : @@ -17052,8 +17061,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" @@ -17072,6 +17081,126 @@ 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 + + # 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 diff --git a/ld/configure.ac b/ld/configure.ac index eb55904c090..a491f9f1116 100644 --- a/ld/configure.ac +++ b/ld/configure.ac @@ -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 @@ -297,7 +298,6 @@ AC_ARG_ENABLE([jansson], [enable_jansson="no"]) if test "x$enable_jansson" != "xno"; then - PKG_PROG_PKG_CONFIG AS_IF([test -n "$PKG_CONFIG"], [ PKG_CHECK_MODULES(JANSSON, [jansson], @@ -386,9 +386,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 +AM_ZSTD # When converting linker scripts into strings for use in emulation # files, use astring.sed if the compiler supports ANSI string diff --git a/ld/emultempl/elf.em b/ld/emultempl/elf.em index c52484f35d3..acd66f907d1 100644 --- a/ld/emultempl/elf.em +++ b/ld/emultempl/elf.em @@ -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); diff --git a/ld/ld.texi b/ld/ld.texi index eabbec8faa9..9daed2e7e9f 100644 --- a/ld/ld.texi +++ b/ld/ld.texi @@ -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 diff --git a/ld/ldmain.c b/ld/ldmain.c index 1bbddaaad32..71af5935b74 100644 --- a/ld/ldmain.c +++ b/ld/ldmain.c @@ -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 (); diff --git a/ld/lexsup.c b/ld/lexsup.c index 9225f71b3ce..299371fb775 100644 --- a/ld/lexsup.c +++ b/ld/lexsup.c @@ -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")); diff --git a/ld/testsuite/ld-elf/compress.exp b/ld/testsuite/ld-elf/compress.exp index cfdd767b8ab..7b8a31cc41d 100644 --- a/ld/testsuite/ld-elf/compress.exp +++ b/ld/testsuite/ld-elf/compress.exp @@ -254,3 +254,20 @@ 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 ] } { + return +} +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 -- 2.37.3.998.g577e59143f-goog ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH v3] binutils, gdb: support zstd compressed debug sections 2022-09-23 4:08 [PATCH v3] binutils, gdb: support zstd compressed debug sections Fangrui Song @ 2022-09-23 14:32 ` Simon Marchi 2022-09-26 5:12 ` Alan Modra 2022-09-23 15:45 ` Nick Clifton ` (3 subsequent siblings) 4 siblings, 1 reply; 32+ messages in thread From: Simon Marchi @ 2022-09-23 14:32 UTC (permalink / raw) To: Fangrui Song, Alan Modra, Jan Beulich, Nick Clifton; +Cc: binutils, gdb-patches On 2022-09-23 00:08, Fangrui Song wrote: > PR29397 PR29563: The new configure option --with-zstd 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 > ... > ``` > --- > Changes from v1: > * use PKG_CHECK_MODULES to check libzstd.pc > > Changes from v2: > * Improve PKG_CHECK_MODULES, autoreconf -vf > * objcopy: check --compress-debug-sections=zstd in a !HAVE_ZSTD build Just one question: you moved PKG_PROG_PKG_CONFIG up in ld/configure.ac, which I think is ok. But what about the other configure.ac files, don't they need PKG_PROG_PKG_CONFIG too? gdb/configure.ac, for instance, uses pkg-config for debuginfod. So if the user passes --without-debuginfod --with-zstd, I expect things to fail, as the pkg-config will be skipped. binutils/configure.ac probably has the same problem, since it uses PKG_CHECK_MODULES for msgpack. I would suggest using PKG_PROG_PKG_CONFIG at the top of all configure.ac that use AM_ZSTD, out of precaution. Simon ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH v3] binutils, gdb: support zstd compressed debug sections 2022-09-23 14:32 ` Simon Marchi @ 2022-09-26 5:12 ` Alan Modra 2022-09-26 7:20 ` Fangrui Song 2022-09-26 14:08 ` Simon Marchi 0 siblings, 2 replies; 32+ messages in thread From: Alan Modra @ 2022-09-26 5:12 UTC (permalink / raw) To: Simon Marchi Cc: Fangrui Song, Jan Beulich, Nick Clifton, binutils, gdb-patches On Fri, Sep 23, 2022 at 10:32:43AM -0400, Simon Marchi wrote: > Just one question: you moved PKG_PROG_PKG_CONFIG up in ld/configure.ac, > which I think is ok. I'm going to fix this one another way. > But what about the other configure.ac files, don't > they need PKG_PROG_PKG_CONFIG too? gdb/configure.ac, for instance, uses > pkg-config for debuginfod. So if the user passes --without-debuginfod > --with-zstd, I expect things to fail, as the pkg-config will be skipped. No, that will be fine, I think The reason being that PKG_CHECK_MODULES AC_REQUIREs PKG_PROG_PKG_CONFIG. So the expansion of AC_DEBUGINFOD will emit an expansion of PKG_PROG_PKG_CONFIG if that has not already occurred, before the entire AC_DEBUGINFOD expansion. > binutils/configure.ac probably has the same problem, since it uses > PKG_CHECK_MODULES for msgpack. I'll fix this one even though it isn't a problem now because AC_DEBUGINFOD and AM_ZSTD preceed it. We should use AS_IF more often, particularly when autoconf macros are invoked. > I would suggest using PKG_PROG_PKG_CONFIG at the top of all configure.ac > that use AM_ZSTD, out of precaution. Better to avoid the need.. binutils/ * configure.ac (msgpack): Use "AS_IF" rather than "if". * configure: Regenerate. ld/ * configure.ac (jansson): Use "AS_IF" rather than "if". * configure: Regenerate. diff --git a/binutils/configure b/binutils/configure index 1c518227f57..4c0c391e9d5 100755 --- a/binutils/configure +++ b/binutils/configure @@ -13507,8 +13507,7 @@ else fi - -if test "$with_msgpack" != no; then +if test "$with_msgpack" != no; then : pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for msgpack" >&5 @@ -13592,29 +13591,23 @@ fi # Put the nasty error message in config.log where it belongs echo "$MSGPACK_PKG_ERRORS" >&5 - - if test "$with_msgpack" = yes; then - as_fn_error $? "--with-msgpack was given, but msgpack is missing or unusable." "$LINENO" 5 - fi - + if test "$with_msgpack" = yes; then : + as_fn_error $? "--with-msgpack was given, but msgpack is missing or unusable." "$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_msgpack" = yes; then - as_fn_error $? "--with-msgpack was given, but msgpack is missing or unusable." "$LINENO" 5 - fi - + if test "$with_msgpack" = yes; then : + as_fn_error $? "--with-msgpack was given, but msgpack is missing or unusable." "$LINENO" 5 +fi else MSGPACK_CFLAGS=$pkg_cv_MSGPACK_CFLAGS MSGPACK_LIBS=$pkg_cv_MSGPACK_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } - $as_echo "#define HAVE_MSGPACK 1" >>confdefs.h - fi fi diff --git a/binutils/configure.ac b/binutils/configure.ac index ec002d3f88f..0798d84f4d1 100644 --- a/binutils/configure.ac +++ b/binutils/configure.ac @@ -278,16 +278,11 @@ AC_ARG_WITH([msgpack], [], [with_msgpack=auto]) - -if test "$with_msgpack" != no; then - PKG_CHECK_MODULES(MSGPACK, msgpack, [ - AC_DEFINE([HAVE_MSGPACK], [1], [Define to 1 if msgpack is available.]) - ], [ - if test "$with_msgpack" = yes; then - AC_MSG_ERROR([--with-msgpack was given, but msgpack is missing or unusable.]) - fi - ]) -fi +AS_IF([test "$with_msgpack" != no], + [PKG_CHECK_MODULES(MSGPACK, msgpack, + [AC_DEFINE([HAVE_MSGPACK], [1], [Define to 1 if msgpack is available.])], + [AS_IF([test "$with_msgpack" = yes], + [AC_MSG_ERROR([--with-msgpack was given, but msgpack is missing or unusable.])])])]) # target-specific stuff: diff --git a/ld/configure b/ld/configure index a1a07005400..4efe3ef5dfc 100755 --- a/ld/configure +++ b/ld/configure @@ -15585,7 +15585,6 @@ else fi -if test "x$enable_jansson" != "xno"; then @@ -15706,8 +15705,7 @@ $as_echo "no" >&6; } PKG_CONFIG="" fi fi - if test -n "$PKG_CONFIG"; then : - +if test "x$enable_jansson" != "xno"; then : pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for jansson" >&5 @@ -15791,15 +15789,11 @@ fi # Put the nasty error message in config.log where it belongs echo "$JANSSON_PKG_ERRORS" >&5 - - as_fn_error $? "Cannot find jansson library" "$LINENO" 5 - + as_fn_error $? "Cannot find jansson library" "$LINENO" 5 elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } - - as_fn_error $? "Cannot find jansson library" "$LINENO" 5 - + as_fn_error $? "Cannot find jansson library" "$LINENO" 5 else JANSSON_CFLAGS=$pkg_cv_JANSSON_CFLAGS JANSSON_LIBS=$pkg_cv_JANSSON_LIBS @@ -15814,11 +15808,6 @@ $as_echo "#define HAVE_JANSSON 1" >>confdefs.h fi -else - - as_fn_error $? "Cannot find pkg-config" "$LINENO" 5 - -fi fi diff --git a/ld/configure.ac b/ld/configure.ac index eb55904c090..8a8bfc9a14e 100644 --- a/ld/configure.ac +++ b/ld/configure.ac @@ -296,24 +296,15 @@ AC_ARG_ENABLE([jansson], [enable_jansson=$enableval], [enable_jansson="no"]) -if test "x$enable_jansson" != "xno"; then - PKG_PROG_PKG_CONFIG - AS_IF([test -n "$PKG_CONFIG"], +AS_IF([test "x$enable_jansson" != "xno"], + [PKG_CHECK_MODULES(JANSSON, [jansson], [ - PKG_CHECK_MODULES(JANSSON, [jansson], - [ - AC_DEFINE(HAVE_JANSSON, 1, [The jansson library is to be used]) - AC_SUBST([JANSSON_CFLAGS]) - AC_SUBST([JANSSON_LIBS]) - ], - [ - AC_MSG_ERROR([Cannot find jansson library]) - ]) + AC_DEFINE(HAVE_JANSSON, 1, [The jansson library is to be used]) + AC_SUBST([JANSSON_CFLAGS]) + AC_SUBST([JANSSON_LIBS]) ], - [ - AC_MSG_ERROR([Cannot find pkg-config]) - ]) -fi + [AC_MSG_ERROR([Cannot find jansson library])]) + ]) AM_BINUTILS_WARNINGS -- Alan Modra Australia Development Lab, IBM ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH v3] binutils, gdb: support zstd compressed debug sections 2022-09-26 5:12 ` Alan Modra @ 2022-09-26 7:20 ` Fangrui Song 2022-09-26 13:30 ` Alan Modra 2022-09-26 14:08 ` Simon Marchi 1 sibling, 1 reply; 32+ messages in thread From: Fangrui Song @ 2022-09-26 7:20 UTC (permalink / raw) To: Alan Modra; +Cc: Simon Marchi, Jan Beulich, Nick Clifton, binutils, gdb-patches [-- Attachment #1: Type: text/plain, Size: 1586 bytes --] On 2022-09-26, Alan Modra wrote: >On Fri, Sep 23, 2022 at 10:32:43AM -0400, Simon Marchi wrote: >> Just one question: you moved PKG_PROG_PKG_CONFIG up in ld/configure.ac, >> which I think is ok. > >I'm going to fix this one another way. > >> But what about the other configure.ac files, don't >> they need PKG_PROG_PKG_CONFIG too? gdb/configure.ac, for instance, uses >> pkg-config for debuginfod. So if the user passes --without-debuginfod >> --with-zstd, I expect things to fail, as the pkg-config will be skipped. > >No, that will be fine, I think The reason being that >PKG_CHECK_MODULES AC_REQUIREs PKG_PROG_PKG_CONFIG. So the expansion >of AC_DEBUGINFOD will emit an expansion of PKG_PROG_PKG_CONFIG if that >has not already occurred, before the entire AC_DEBUGINFOD expansion. > >> binutils/configure.ac probably has the same problem, since it uses >> PKG_CHECK_MODULES for msgpack. > >I'll fix this one even though it isn't a problem now because >AC_DEBUGINFOD and AM_ZSTD preceed it. We should use AS_IF more often, >particularly when autoconf macros are invoked. > >> I would suggest using PKG_PROG_PKG_CONFIG at the top of all configure.ac >> that use AM_ZSTD, out of precaution. > >Better to avoid the need.. > >binutils/ > * configure.ac (msgpack): Use "AS_IF" rather than "if". > * configure: Regenerate. >ld/ > * configure.ac (jansson): Use "AS_IF" rather than "if". > * configure: Regenerate. > Thanks. I've changed the zstd patch to use AS_IF, too. BTW: I think the `!= xno` trick for ancient shells is not needed. `!= no` is used many times in binutils-gdb. [-- Attachment #2: v4-0001-binutils-gdb-support-zstd-compressed-debug-sectio.patch --] [-- Type: text/x-diff, Size: 109885 bytes --] From 1c70c807039cecab5fff2e7c09e0086d093d4042 Mon Sep 17 00:00:00 2001 From: Fangrui Song <maskray@google.com> Date: Mon, 26 Sep 2022 00:15:19 -0700 Subject: [PATCH v4] binutils, gdb: support zstd compressed debug sections PR29397 PR29563: The new configure option --with-zstd 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 ... ``` --- bfd/Makefile.am | 4 +- bfd/Makefile.in | 13 +- bfd/aclocal.m4 | 2 + bfd/bfd-in.h | 3 +- bfd/bfd-in2.h | 11 +- bfd/bfd.c | 26 +- bfd/compress.c | 72 +++- bfd/config.in | 3 + bfd/configure | 268 ++++++++++++- bfd/configure.ac | 3 +- bfd/elf.c | 12 + bfd/elfxx-target.h | 6 +- bfd/section.c | 3 +- binutils/Makefile.in | 5 +- binutils/NEWS | 6 + binutils/aclocal.m4 | 1 + binutils/config.in | 3 + binutils/configure | 136 ++++++- binutils/configure.ac | 3 +- binutils/doc/binutils.texi | 16 +- binutils/objcopy.c | 19 +- binutils/testsuite/binutils-all/compress.exp | 44 +++ config/zstd.m4 | 23 ++ configure | 10 + configure.ac | 3 + gas/Makefile.am | 4 +- gas/Makefile.in | 13 +- gas/NEWS | 3 + gas/aclocal.m4 | 2 + gas/as.c | 13 +- gas/compress-debug.c | 60 ++- gas/compress-debug.h | 10 +- gas/config.in | 3 + gas/configure | 269 ++++++++++++- gas/configure.ac | 3 +- gas/doc/as.texi | 11 +- gas/write.c | 36 +- gdb/Makefile.in | 8 +- gdb/NEWS | 2 + gdb/acinclude.m4 | 3 +- gdb/config.in | 3 + gdb/configure | 137 ++++++- gdb/configure.ac | 4 +- ld/Makefile.am | 5 +- ld/Makefile.in | 11 +- ld/NEWS | 3 + ld/aclocal.m4 | 1 + ld/config.in | 3 + ld/configure | 390 ++++++++++++------- ld/configure.ac | 6 +- ld/emultempl/elf.em | 9 + ld/ld.texi | 5 + ld/ldmain.c | 8 +- ld/lexsup.c | 4 +- ld/testsuite/ld-elf/compress.exp | 17 + 55 files changed, 1487 insertions(+), 254 deletions(-) create mode 100644 config/zstd.m4 diff --git a/bfd/Makefile.am b/bfd/Makefile.am index a5652b2a9c7..98a487b7fcd 100644 --- a/bfd/Makefile.am +++ b/bfd/Makefile.am @@ -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 diff --git a/bfd/Makefile.in b/bfd/Makefile.in index 83d686529a0..3c9ebf38f83 100644 --- a/bfd/Makefile.in +++ b/bfd/Makefile.in @@ -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 diff --git a/bfd/aclocal.m4 b/bfd/aclocal.m4 index 0f8aa1d4518..09b849dfc87 100644 --- a/bfd/aclocal.m4 +++ b/bfd/aclocal.m4 @@ -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]) diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h index 8605056aefe..4765ea80536 100644 --- a/bfd/bfd-in.h +++ b/bfd/bfd-in.h @@ -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 diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 79fcc4eb912..5c80956c79c 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -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); diff --git a/bfd/bfd.c b/bfd/bfd.c index 0a21db11fd6..5f2033bee7a 100644 --- 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; diff --git a/bfd/compress.c b/bfd/compress.c index b2e39826e38..95c1f4c42d1 100644 --- a/bfd/compress.c +++ b/bfd/compress.c @@ -20,18 +20,31 @@ #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)) + if (!decompress_contents (compress_status == DECOMPRESS_SECTION_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; } diff --git a/bfd/config.in b/bfd/config.in index f54a3cacbea..a59304e0a66 100644 --- a/bfd/config.in +++ b/bfd/config.in @@ -232,6 +232,9 @@ /* 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 diff --git a/bfd/configure b/bfd/configure index 075d2ee0a1b..d905a7bf7a8 100755 --- a/bfd/configure +++ b/bfd/configure @@ -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. @@ -13015,6 +13035,246 @@ 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 + + +# 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 diff --git a/bfd/configure.ac b/bfd/configure.ac index 28f3d1afce6..d1b2f76b31a 100644 --- a/bfd/configure.ac +++ b/bfd/configure.ac @@ -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 +AM_ZSTD save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Werror" diff --git a/bfd/elf.c b/bfd/elf.c index 9a0bc1d2740..9d34781a97c 100644 --- 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) diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h index feaba84bf2e..ca600bb5ddf 100644 --- a/bfd/elfxx-target.h +++ b/bfd/elfxx-target.h @@ -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 diff --git a/bfd/section.c b/bfd/section.c index c7a02d729f2..614570e976e 100644 --- a/bfd/section.c +++ b/bfd/section.c @@ -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. *} . diff --git a/binutils/Makefile.in b/binutils/Makefile.in index 78d32b350e3..6de4e239408 100644 --- a/binutils/Makefile.in +++ b/binutils/Makefile.in @@ -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@ diff --git a/binutils/NEWS b/binutils/NEWS index 8c2c416c17e..83c73d0660a 100644 --- a/binutils/NEWS +++ b/binutils/NEWS @@ -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 diff --git a/binutils/aclocal.m4 b/binutils/aclocal.m4 index a877fa7f873..28271f56279 100644 --- a/binutils/aclocal.m4 +++ b/binutils/aclocal.m4 @@ -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]) diff --git a/binutils/config.in b/binutils/config.in index c5fb919aa95..bee8c07e2f7 100644 --- a/binutils/config.in +++ b/binutils/config.in @@ -157,6 +157,9 @@ /* 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 diff --git a/binutils/configure b/binutils/configure index 4c0c391e9d5..5f68fed3f94 100755 --- a/binutils/configure +++ b/binutils/configure @@ -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). @@ -13490,6 +13499,127 @@ fi +# Check whether --with-zstd was given. +if test "${with_zstd+set}" = set; then : + withval=$with_zstd; +else + with_zstd=auto +fi + + +if "$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*) diff --git a/binutils/configure.ac b/binutils/configure.ac index 0798d84f4d1..01cf8882be4 100644 --- a/binutils/configure.ac +++ b/binutils/configure.ac @@ -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 +AM_ZSTD BFD_BINARY_FOPEN diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi index 1499db5728c..34a4164eb94 100644 --- a/binutils/doc/binutils.texi +++ b/binutils/doc/binutils.texi @@ -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 diff --git a/binutils/objcopy.c b/binutils/objcopy.c index 43261756a42..fc668f00bbc 100644 --- a/binutils/objcopy.c +++ b/binutils/objcopy.c @@ -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); diff --git a/binutils/testsuite/binutils-all/compress.exp b/binutils/testsuite/binutils-all/compress.exp index c88da74a987..4e74c824664 100644 --- a/binutils/testsuite/binutils-all/compress.exp +++ b/binutils/testsuite/binutils-all/compress.exp @@ -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 index 00000000000..4a20c49a2ef --- /dev/null +++ b/config/zstd.m4 @@ -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([AM_ZSTD], [ +AC_ARG_WITH(zstd, + [AS_HELP_STRING([--with-zstd], [support zstd compressed debug sections (default=auto)])], + [], [with_zstd=auto]) + +AS_IF(["$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 + ]) + ]) +]) diff --git a/configure b/configure index d75f47a1e95..f14e0efd675 100755 --- 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 diff --git a/configure.ac b/configure.ac index ae18d436aca..0152c69292e 100644 --- a/configure.ac +++ b/configure.ac @@ -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 diff --git a/gas/Makefile.am b/gas/Makefile.am index bd597398671..5f0f24abf8d 100644 --- a/gas/Makefile.am +++ b/gas/Makefile.am @@ -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) \ diff --git a/gas/Makefile.in b/gas/Makefile.in index c57d78f82c4..5a4dd702252 100644 --- a/gas/Makefile.in +++ b/gas/Makefile.in @@ -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) diff --git a/gas/NEWS b/gas/NEWS index d61cdb9edd4..9a8b726b942 100644 --- 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 diff --git a/gas/aclocal.m4 b/gas/aclocal.m4 index 70183124da7..722030c776f 100644 --- a/gas/aclocal.m4 +++ b/gas/aclocal.m4 @@ -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]) diff --git a/gas/as.c b/gas/as.c index 6268779cf90..35ad6b3ab3b 100644 --- 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); diff --git a/gas/compress-debug.c b/gas/compress-debug.c index c80dbeec4e7..3cd175f6e57 100644 --- a/gas/compress-debug.c +++ b/gas/compress-debug.c @@ -21,14 +21,23 @@ #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); diff --git a/gas/compress-debug.h b/gas/compress-debug.h index 0183e269fef..87de0f8444e 100644 --- a/gas/compress-debug.h +++ b/gas/compress-debug.h @@ -21,19 +21,19 @@ #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 */ diff --git a/gas/config.in b/gas/config.in index e243fd277ee..0d1668a3eac 100644 --- a/gas/config.in +++ b/gas/config.in @@ -134,6 +134,9 @@ /* 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 diff --git a/gas/configure b/gas/configure index d0449a1d7ab..c4d5ba6f994 100755 --- a/gas/configure +++ b/gas/configure @@ -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" @@ -13964,6 +13984,247 @@ 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 + + +# Check whether --with-zstd was given. +if test "${with_zstd+set}" = set; then : + withval=$with_zstd; +else + with_zstd=auto +fi + + +if "$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 diff --git a/gas/configure.ac b/gas/configure.ac index 21795a82bdd..8750ea21381 100644 --- a/gas/configure.ac +++ b/gas/configure.ac @@ -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 +AM_ZSTD # Support for VMS timestamps via cross compile diff --git a/gas/doc/as.texi b/gas/doc/as.texi index e915893da86..01f49434021 100644 --- a/gas/doc/as.texi +++ b/gas/doc/as.texi @@ -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 diff --git a/gas/write.c b/gas/write.c index f76bbdb706e..0e49df7c03f 100644 --- a/gas/write.c +++ b/gas/write.c @@ -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,21 +1484,22 @@ 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 = 0; + header_size = 12; + } + else { compression_header_size = bfd_get_compression_header_size (stdoutput, NULL); header_size = compression_header_size; } - else - { - compression_header_size = 0; - header_size = 12; - } /* Create a new frag to contain the compression header. */ first_newf = frag_alloc (ob); @@ -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); diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 2598b81d205..c528ee5aa80 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -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) diff --git a/gdb/NEWS b/gdb/NEWS index 9619842bc03..1457c99ff04 100644 --- 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 diff --git a/gdb/acinclude.m4 b/gdb/acinclude.m4 index 95ff2b6f35e..28846119dcb 100644 --- a/gdb/acinclude.m4 +++ b/gdb/acinclude.m4 @@ -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( diff --git a/gdb/config.in b/gdb/config.in index a4975c68aad..e13a409ec2d 100644 --- a/gdb/config.in +++ b/gdb/config.in @@ -589,6 +589,9 @@ /* 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 diff --git a/gdb/configure b/gdb/configure index 4dbd0c3b13c..5d49b3eba5a 100755 --- a/gdb/configure +++ b/gdb/configure @@ -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 "$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 diff --git a/gdb/configure.ac b/gdb/configure.ac index 215a91c5b27..e8cf808d280 100644 --- a/gdb/configure.ac +++ b/gdb/configure.ac @@ -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 +AM_ZSTD AM_ICONV diff --git a/ld/Makefile.am b/ld/Makefile.am index d31021c13e2..bbe25f3aca2 100644 --- a/ld/Makefile.am +++ b/ld/Makefile.am @@ -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) diff --git a/ld/Makefile.in b/ld/Makefile.in index ee0c98f65b0..400eed2717e 100644 --- a/ld/Makefile.in +++ b/ld/Makefile.in @@ -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 355752e6b24..dfe2690d9f2 100644 --- 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 diff --git a/ld/aclocal.m4 b/ld/aclocal.m4 index d20c542eed5..893e973e4f2 100644 --- a/ld/aclocal.m4 +++ b/ld/aclocal.m4 @@ -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]) diff --git a/ld/config.in b/ld/config.in index 0ccd79d59cd..3916740eee4 100644 --- a/ld/config.in +++ b/ld/config.in @@ -162,6 +162,9 @@ /* 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 diff --git a/ld/configure b/ld/configure index 4efe3ef5dfc..80472f9342e 100755 --- a/ld/configure +++ b/ld/configure @@ -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" @@ -17061,6 +17070,127 @@ fi + +# Check whether --with-zstd was given. +if test "${with_zstd+set}" = set; then : + withval=$with_zstd; +else + with_zstd=auto +fi + + +if "$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 diff --git a/ld/configure.ac b/ld/configure.ac index 8a8bfc9a14e..5a6e16764cc 100644 --- a/ld/configure.ac +++ b/ld/configure.ac @@ -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 +AM_ZSTD # When converting linker scripts into strings for use in emulation # files, use astring.sed if the compiler supports ANSI string diff --git a/ld/emultempl/elf.em b/ld/emultempl/elf.em index c52484f35d3..acd66f907d1 100644 --- a/ld/emultempl/elf.em +++ b/ld/emultempl/elf.em @@ -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); diff --git a/ld/ld.texi b/ld/ld.texi index eabbec8faa9..9daed2e7e9f 100644 --- a/ld/ld.texi +++ b/ld/ld.texi @@ -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 diff --git a/ld/ldmain.c b/ld/ldmain.c index 1bbddaaad32..71af5935b74 100644 --- a/ld/ldmain.c +++ b/ld/ldmain.c @@ -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 (); diff --git a/ld/lexsup.c b/ld/lexsup.c index 9225f71b3ce..299371fb775 100644 --- a/ld/lexsup.c +++ b/ld/lexsup.c @@ -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")); diff --git a/ld/testsuite/ld-elf/compress.exp b/ld/testsuite/ld-elf/compress.exp index cfdd767b8ab..7b8a31cc41d 100644 --- a/ld/testsuite/ld-elf/compress.exp +++ b/ld/testsuite/ld-elf/compress.exp @@ -254,3 +254,20 @@ 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 ] } { + return +} +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 -- 2.37.3.998.g577e59143f-goog ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH v3] binutils, gdb: support zstd compressed debug sections 2022-09-26 7:20 ` Fangrui Song @ 2022-09-26 13:30 ` Alan Modra 0 siblings, 0 replies; 32+ messages in thread From: Alan Modra @ 2022-09-26 13:30 UTC (permalink / raw) To: Fangrui Song Cc: Simon Marchi, Jan Beulich, Nick Clifton, binutils, gdb-patches On Mon, Sep 26, 2022 at 12:20:27AM -0700, Fangrui Song wrote: > On 2022-09-26, Alan Modra wrote: > > Better to avoid the need.. > > > > binutils/ > > * configure.ac (msgpack): Use "AS_IF" rather than "if". > > * configure: Regenerate. > > ld/ > > * configure.ac (jansson): Use "AS_IF" rather than "if". > > * configure: Regenerate. > > > > Thanks. I've changed the zstd patch to use AS_IF, too. It probably wasn't necessary inside AC_DEFUN, but won't hurt either. > BTW: I think the `!= xno` trick for ancient shells is not needed. `!= > no` is used many times in binutils-gdb. Quite possibly true nowadays. I'm not going to be the one that removes them all. :-) Your patch looks OK to me, apart from a few formatting nits. Here are two examples: > @@ -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); One of the formatting guidelines in https://www.gnu.org/prep/standards/html_node/Formatting.html#Formatting talks about emacs indenting of code. The above looks reasonable with your indenting by hand, but auto-indent will turn it into if (!decompress_contents ( sec->compress_status == DECOMPRESS_SECTION_ZSTD, uncompressed_buffer + orig_compression_header_size, zlib_size, buffer, buffer_size)) lining up function args with the open parenthesis. Inserting a couple of temporary vars is the nicest solution to keeping line length manageable. bool is_z = sec->compress_status == DECOMPRESS_SECTION_ZSTD; bfd_byte *p = uncompressed_buffer + orig_compression_header_size; if (!decompress_contents (is_z, p, zlib_size, buffer, buffer_size)) > @@ -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; > } The same emacs auto-indent will ruin the above. Write sec->compress_status = (ch_type == ELFCOMPRESS_ZSTD ? DECOMPRESS_SECTION_ZSTD : DECOMPRESS_SECTION_ZLIB); with unnecessary parentheses to guide indentation. OK to commit with those things fixed. -- Alan Modra Australia Development Lab, IBM ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH v3] binutils, gdb: support zstd compressed debug sections 2022-09-26 5:12 ` Alan Modra 2022-09-26 7:20 ` Fangrui Song @ 2022-09-26 14:08 ` Simon Marchi 2022-09-27 0:33 ` Alan Modra 1 sibling, 1 reply; 32+ messages in thread From: Simon Marchi @ 2022-09-26 14:08 UTC (permalink / raw) To: Alan Modra; +Cc: Fangrui Song, Jan Beulich, Nick Clifton, binutils, gdb-patches >> But what about the other configure.ac files, don't >> they need PKG_PROG_PKG_CONFIG too? gdb/configure.ac, for instance, uses >> pkg-config for debuginfod. So if the user passes --without-debuginfod >> --with-zstd, I expect things to fail, as the pkg-config will be skipped. > > No, that will be fine, I think The reason being that > PKG_CHECK_MODULES AC_REQUIREs PKG_PROG_PKG_CONFIG. So the expansion > of AC_DEBUGINFOD will emit an expansion of PKG_PROG_PKG_CONFIG if that > has not already occurred, before the entire AC_DEBUGINFOD expansion. Ah, makes sense. Thanks for the explanation Alan. > >> binutils/configure.ac probably has the same problem, since it uses >> PKG_CHECK_MODULES for msgpack. > > I'll fix this one even though it isn't a problem now because > AC_DEBUGINFOD and AM_ZSTD preceed it. We should use AS_IF more often, > particularly when autoconf macros are invoked. Silly question but... AM_ZSTD was clearly named after AM_ZLIB. But why does AM_ZLIB have the "AM" (automake, I suppose) prefix? It doesn't seem to have anything to do with automake. Ack about AS_IF, I will try to remember this for top-level configure code. Simon ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH v3] binutils, gdb: support zstd compressed debug sections 2022-09-26 14:08 ` Simon Marchi @ 2022-09-27 0:33 ` Alan Modra 0 siblings, 0 replies; 32+ messages in thread From: Alan Modra @ 2022-09-27 0:33 UTC (permalink / raw) To: Simon Marchi Cc: Fangrui Song, Jan Beulich, Nick Clifton, binutils, gdb-patches On Mon, Sep 26, 2022 at 10:08:30AM -0400, Simon Marchi wrote: > Silly question but... AM_ZSTD was clearly named after AM_ZLIB. But why > does AM_ZLIB have the "AM" (automake, I suppose) prefix? It doesn't > seem to have anything to do with automake. You'll have to ask Joel. The original patch is at https://sourceware.org/pipermail/binutils/2009-October/063904.html As far as I can see, we get to choose user-defined autoconf macro naming conventions ourselves. -- Alan Modra Australia Development Lab, IBM ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH v3] binutils, gdb: support zstd compressed debug sections 2022-09-23 4:08 [PATCH v3] binutils, gdb: support zstd compressed debug sections Fangrui Song 2022-09-23 14:32 ` Simon Marchi @ 2022-09-23 15:45 ` Nick Clifton 2022-09-23 15:58 ` Simon Marchi 2022-09-24 6:53 ` Enze Li ` (2 subsequent siblings) 4 siblings, 1 reply; 32+ messages in thread From: Nick Clifton @ 2022-09-23 15:45 UTC (permalink / raw) To: Fangrui Song, Alan Modra, Jan Beulich, Simon Marchi; +Cc: binutils, gdb-patches Hi Fangrui, > PR29397 PR29563: The new configure option --with-zstd defaults to auto. > If pkgconfig/libzstd.pc is found, define HAVE_ZSTD and support zstd > compressed debug sections for most tools. One small, but important point. Please could you add entries to the gas/NEWS binutils/NEWS and ld/NEWS files giving a brief description of this new feature. Cheers Nick ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH v3] binutils, gdb: support zstd compressed debug sections 2022-09-23 15:45 ` Nick Clifton @ 2022-09-23 15:58 ` Simon Marchi 2022-09-23 18:20 ` Fangrui Song 0 siblings, 1 reply; 32+ messages in thread From: Simon Marchi @ 2022-09-23 15:58 UTC (permalink / raw) To: Nick Clifton, Fangrui Song, Alan Modra, Jan Beulich; +Cc: binutils, gdb-patches On 2022-09-23 11:45, Nick Clifton wrote: > Hi Fangrui, > >> PR29397 PR29563: The new configure option --with-zstd defaults to auto. >> If pkgconfig/libzstd.pc is found, define HAVE_ZSTD and support zstd >> compressed debug sections for most tools. > > One small, but important point. Please could you add entries to the gas/NEWS > binutils/NEWS and ld/NEWS files giving a brief description of this new feature. I guess to gdb/NEWS, while at it :). Simon ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH v3] binutils, gdb: support zstd compressed debug sections 2022-09-23 15:58 ` Simon Marchi @ 2022-09-23 18:20 ` Fangrui Song 2022-09-23 18:57 ` Simon Marchi 0 siblings, 1 reply; 32+ messages in thread From: Fangrui Song @ 2022-09-23 18:20 UTC (permalink / raw) To: Simon Marchi, Nick Clifton; +Cc: Alan Modra, Jan Beulich, binutils, gdb-patches [-- Attachment #1: Type: text/plain, Size: 4302 bytes --] On 2022-09-23, Simon Marchi wrote: > > >On 2022-09-23 11:45, Nick Clifton wrote: >> Hi Fangrui, >> >>> PR29397 PR29563: The new configure option --with-zstd defaults to auto. >>> If pkgconfig/libzstd.pc is found, define HAVE_ZSTD and support zstd >>> compressed debug sections for most tools. Hi Simon and Nick, I have checked that `make all-gdb` works in a --enable-gdb --without-debuginfod build. I then inspected the 2020 commits adding AC_DEBUGINFOD to gdb/configure.ac and binutils/configure.ac. They come with no PKG_PROG_PKG_CONFIG and config/debuginfod.m4 does not have PKG_PROG_PKG_CONFIG, but they still work. So I think AC_ZSTD doesn't need PKG_PROG_PKG_CONFIG, either. Though I have no insight why it behaves that way:) >> One small, but important point. Please could you add entries to the gas/NEWS >> binutils/NEWS and ld/NEWS files giving a brief description of this new feature. > >I guess to gdb/NEWS, while at it :). > >Simon Here are the NEWS entries :) (As usual, it's available as the latest https://gitlab.com/MaskRay/binutils-gdb/-/commits/zstd) ---- bfd/Makefile.am | 4 +- @@ -58,2 +51,3 @@ binutils/Makefile.in | 5 +- + binutils/NEWS | 6 + binutils/aclocal.m4 | 1 + @@ -70,2 +64,3 @@ gas/Makefile.in | 13 +- + gas/NEWS | 3 + gas/aclocal.m4 | 2 + @@ -80,2 +75,3 @@ gdb/Makefile.in | 8 +- + gdb/NEWS | 2 + gdb/acinclude.m4 | 3 +- @@ -86,2 +82,3 @@ ld/Makefile.in | 11 +- + ld/NEWS | 3 + ld/aclocal.m4 | 1 + @@ -95,3 +92,3 @@ ld/testsuite/ld-elf/compress.exp | 17 + - 51 files changed, 1470 insertions(+), 255 deletions(-) + 55 files changed, 1484 insertions(+), 255 deletions(-) create mode 100644 config/zstd.m4 @@ -990,2 +987,18 @@ abs_top_builddir = @abs_top_builddir@ +diff --git a/binutils/NEWS b/binutils/NEWS +index 8c2c416c17e..073e9bc4647 100644 +--- a/binutils/NEWS ++++ b/binutils/NEWS +@@ -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 diff --git a/binutils/aclocal.m4 b/binutils/aclocal.m4 @@ -1539,2 +1552,15 @@ $(extra_objects) $(GASLIBS) $(LIBINTL_DEP) +diff --git a/gas/NEWS b/gas/NEWS +index d61cdb9edd4..9a8b726b942 100644 +--- 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 diff --git a/gas/aclocal.m4 b/gas/aclocal.m4 @@ -2262,2 +2288,15 @@ $(srcdir)/aclocal.m4: @MAINTAINER_MODE_TRUE@ $(aclocal_m4_deps) +diff --git a/gdb/NEWS b/gdb/NEWS +index 9619842bc03..1457c99ff04 100644 +--- 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 diff --git a/gdb/acinclude.m4 b/gdb/acinclude.m4 @@ -2582,2 +2621,15 @@ # Build a dummy plugin using libtool. +diff --git a/ld/NEWS b/ld/NEWS +index 355752e6b24..dfe2690d9f2 100644 +--- 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 diff --git a/ld/aclocal.m4 b/ld/aclocal.m4 [-- Attachment #2: v4-0001-binutils-gdb-support-zstd-compressed-debug-sectio.patch --] [-- Type: text/x-diff, Size: 110131 bytes --] From 5e60b8fac5190059c0c253a8241ddf9a9763afa0 Mon Sep 17 00:00:00 2001 From: Fangrui Song <maskray@google.com> Date: Fri, 23 Sep 2022 11:18:36 -0700 Subject: [PATCH v4] binutils, gdb: support zstd compressed debug sections PR29397 PR29563: The new configure option --with-zstd 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 ... ``` --- bfd/Makefile.am | 4 +- bfd/Makefile.in | 13 +- bfd/aclocal.m4 | 2 + bfd/bfd-in.h | 3 +- bfd/bfd-in2.h | 11 +- bfd/bfd.c | 26 +- bfd/compress.c | 72 +++- bfd/config.in | 3 + bfd/configure | 268 ++++++++++++- bfd/configure.ac | 3 +- bfd/elf.c | 12 + bfd/elfxx-target.h | 6 +- bfd/section.c | 3 +- binutils/Makefile.in | 5 +- binutils/NEWS | 6 + binutils/aclocal.m4 | 1 + binutils/config.in | 3 + binutils/configure | 135 ++++++- binutils/configure.ac | 3 +- binutils/doc/binutils.texi | 16 +- binutils/objcopy.c | 19 +- binutils/testsuite/binutils-all/compress.exp | 44 +++ config/zstd.m4 | 24 ++ configure | 10 + configure.ac | 3 + gas/Makefile.am | 4 +- gas/Makefile.in | 13 +- gas/NEWS | 3 + gas/aclocal.m4 | 2 + gas/as.c | 13 +- gas/compress-debug.c | 60 ++- gas/compress-debug.h | 10 +- gas/config.in | 3 + gas/configure | 268 ++++++++++++- gas/configure.ac | 3 +- gas/doc/as.texi | 11 +- gas/write.c | 36 +- gdb/Makefile.in | 8 +- gdb/NEWS | 2 + gdb/acinclude.m4 | 3 +- gdb/config.in | 3 + gdb/configure | 136 ++++++- gdb/configure.ac | 4 +- ld/Makefile.am | 5 +- ld/Makefile.in | 11 +- ld/NEWS | 3 + ld/aclocal.m4 | 1 + ld/config.in | 3 + ld/configure | 389 ++++++++++++------- ld/configure.ac | 7 +- ld/emultempl/elf.em | 9 + ld/ld.texi | 5 + ld/ldmain.c | 8 +- ld/lexsup.c | 4 +- ld/testsuite/ld-elf/compress.exp | 17 + 55 files changed, 1484 insertions(+), 255 deletions(-) create mode 100644 config/zstd.m4 diff --git a/bfd/Makefile.am b/bfd/Makefile.am index c23dff6cac3..cfe903c63f0 100644 --- a/bfd/Makefile.am +++ b/bfd/Makefile.am @@ -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 diff --git a/bfd/Makefile.in b/bfd/Makefile.in index 82843d2d61d..6be41a72a59 100644 --- a/bfd/Makefile.in +++ b/bfd/Makefile.in @@ -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 diff --git a/bfd/aclocal.m4 b/bfd/aclocal.m4 index 0f8aa1d4518..09b849dfc87 100644 --- a/bfd/aclocal.m4 +++ b/bfd/aclocal.m4 @@ -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]) diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h index 8605056aefe..4765ea80536 100644 --- a/bfd/bfd-in.h +++ b/bfd/bfd-in.h @@ -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 diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 79fcc4eb912..5c80956c79c 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -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); diff --git a/bfd/bfd.c b/bfd/bfd.c index 0a21db11fd6..5f2033bee7a 100644 --- 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; diff --git a/bfd/compress.c b/bfd/compress.c index b2e39826e38..95c1f4c42d1 100644 --- a/bfd/compress.c +++ b/bfd/compress.c @@ -20,18 +20,31 @@ #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)) + if (!decompress_contents (compress_status == DECOMPRESS_SECTION_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; } diff --git a/bfd/config.in b/bfd/config.in index f54a3cacbea..a59304e0a66 100644 --- a/bfd/config.in +++ b/bfd/config.in @@ -232,6 +232,9 @@ /* 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 diff --git a/bfd/configure b/bfd/configure index 075d2ee0a1b..d905a7bf7a8 100755 --- a/bfd/configure +++ b/bfd/configure @@ -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. @@ -13015,6 +13035,246 @@ 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 + + +# 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 diff --git a/bfd/configure.ac b/bfd/configure.ac index 28f3d1afce6..d1b2f76b31a 100644 --- a/bfd/configure.ac +++ b/bfd/configure.ac @@ -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 +AM_ZSTD save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -Werror" diff --git a/bfd/elf.c b/bfd/elf.c index 16cea4f8aeb..e52fa458a5a 100644 --- 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) diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h index feaba84bf2e..ca600bb5ddf 100644 --- a/bfd/elfxx-target.h +++ b/bfd/elfxx-target.h @@ -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 diff --git a/bfd/section.c b/bfd/section.c index c7a02d729f2..614570e976e 100644 --- a/bfd/section.c +++ b/bfd/section.c @@ -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. *} . diff --git a/binutils/Makefile.in b/binutils/Makefile.in index 78d32b350e3..6de4e239408 100644 --- a/binutils/Makefile.in +++ b/binutils/Makefile.in @@ -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@ diff --git a/binutils/NEWS b/binutils/NEWS index 8c2c416c17e..073e9bc4647 100644 --- a/binutils/NEWS +++ b/binutils/NEWS @@ -1,5 +1,11 @@ -*- text -*- +* objcopy --decompress-debug-sections now support 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 diff --git a/binutils/aclocal.m4 b/binutils/aclocal.m4 index a877fa7f873..28271f56279 100644 --- a/binutils/aclocal.m4 +++ b/binutils/aclocal.m4 @@ -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]) diff --git a/binutils/config.in b/binutils/config.in index c5fb919aa95..bee8c07e2f7 100644 --- a/binutils/config.in +++ b/binutils/config.in @@ -157,6 +157,9 @@ /* 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 diff --git a/binutils/configure b/binutils/configure index 1c518227f57..54d0f184da1 100755 --- a/binutils/configure +++ b/binutils/configure @@ -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). @@ -13490,6 +13499,126 @@ 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 + + + case "${host}" in *-*-msdos* | *-*-go32* | *-*-mingw32* | *-*-cygwin* | *-*-windows*) diff --git a/binutils/configure.ac b/binutils/configure.ac index ec002d3f88f..c152b7f6733 100644 --- a/binutils/configure.ac +++ b/binutils/configure.ac @@ -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 +AM_ZSTD BFD_BINARY_FOPEN diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi index 1499db5728c..34a4164eb94 100644 --- a/binutils/doc/binutils.texi +++ b/binutils/doc/binutils.texi @@ -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 diff --git a/binutils/objcopy.c b/binutils/objcopy.c index 43261756a42..fc668f00bbc 100644 --- a/binutils/objcopy.c +++ b/binutils/objcopy.c @@ -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); diff --git a/binutils/testsuite/binutils-all/compress.exp b/binutils/testsuite/binutils-all/compress.exp index c88da74a987..4e74c824664 100644 --- a/binutils/testsuite/binutils-all/compress.exp +++ b/binutils/testsuite/binutils-all/compress.exp @@ -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 index 00000000000..93ae17b89d3 --- /dev/null +++ b/config/zstd.m4 @@ -0,0 +1,24 @@ +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([AM_ZSTD], +[ +AC_ARG_WITH(zstd, + [AS_HELP_STRING([--with-zstd], [support zstd compressed debug sections (default=auto)])], + [], [with_zstd=auto]) + +if test "$with_zstd" != no; then + 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 + ]) +fi +]) diff --git a/configure b/configure index d75f47a1e95..f14e0efd675 100755 --- 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 diff --git a/configure.ac b/configure.ac index ae18d436aca..0152c69292e 100644 --- a/configure.ac +++ b/configure.ac @@ -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 diff --git a/gas/Makefile.am b/gas/Makefile.am index bd597398671..5f0f24abf8d 100644 --- a/gas/Makefile.am +++ b/gas/Makefile.am @@ -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) \ diff --git a/gas/Makefile.in b/gas/Makefile.in index c57d78f82c4..5a4dd702252 100644 --- a/gas/Makefile.in +++ b/gas/Makefile.in @@ -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) diff --git a/gas/NEWS b/gas/NEWS index d61cdb9edd4..9a8b726b942 100644 --- 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 diff --git a/gas/aclocal.m4 b/gas/aclocal.m4 index 70183124da7..722030c776f 100644 --- a/gas/aclocal.m4 +++ b/gas/aclocal.m4 @@ -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]) diff --git a/gas/as.c b/gas/as.c index 6268779cf90..35ad6b3ab3b 100644 --- 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); diff --git a/gas/compress-debug.c b/gas/compress-debug.c index c80dbeec4e7..3cd175f6e57 100644 --- a/gas/compress-debug.c +++ b/gas/compress-debug.c @@ -21,14 +21,23 @@ #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); diff --git a/gas/compress-debug.h b/gas/compress-debug.h index 0183e269fef..87de0f8444e 100644 --- a/gas/compress-debug.h +++ b/gas/compress-debug.h @@ -21,19 +21,19 @@ #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 */ diff --git a/gas/config.in b/gas/config.in index e243fd277ee..0d1668a3eac 100644 --- a/gas/config.in +++ b/gas/config.in @@ -134,6 +134,9 @@ /* 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 diff --git a/gas/configure b/gas/configure index d0449a1d7ab..1833adffaa8 100755 --- a/gas/configure +++ b/gas/configure @@ -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" @@ -13964,6 +13984,246 @@ 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 + + +# 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 diff --git a/gas/configure.ac b/gas/configure.ac index 21795a82bdd..8750ea21381 100644 --- a/gas/configure.ac +++ b/gas/configure.ac @@ -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 +AM_ZSTD # Support for VMS timestamps via cross compile diff --git a/gas/doc/as.texi b/gas/doc/as.texi index e915893da86..01f49434021 100644 --- a/gas/doc/as.texi +++ b/gas/doc/as.texi @@ -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 diff --git a/gas/write.c b/gas/write.c index f76bbdb706e..0e49df7c03f 100644 --- a/gas/write.c +++ b/gas/write.c @@ -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,21 +1484,22 @@ 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 = 0; + header_size = 12; + } + else { compression_header_size = bfd_get_compression_header_size (stdoutput, NULL); header_size = compression_header_size; } - else - { - compression_header_size = 0; - header_size = 12; - } /* Create a new frag to contain the compression header. */ first_newf = frag_alloc (ob); @@ -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); diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 2598b81d205..c528ee5aa80 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -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) diff --git a/gdb/NEWS b/gdb/NEWS index 9619842bc03..1457c99ff04 100644 --- 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 diff --git a/gdb/acinclude.m4 b/gdb/acinclude.m4 index 95ff2b6f35e..28846119dcb 100644 --- a/gdb/acinclude.m4 +++ b/gdb/acinclude.m4 @@ -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( diff --git a/gdb/config.in b/gdb/config.in index a4975c68aad..e13a409ec2d 100644 --- a/gdb/config.in +++ b/gdb/config.in @@ -589,6 +589,9 @@ /* 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 diff --git a/gdb/configure b/gdb/configure index 4dbd0c3b13c..57cd165088a 100755 --- a/gdb/configure +++ b/gdb/configure @@ -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,126 @@ 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 +17411,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 +17526,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 diff --git a/gdb/configure.ac b/gdb/configure.ac index 215a91c5b27..e8cf808d280 100644 --- a/gdb/configure.ac +++ b/gdb/configure.ac @@ -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 +AM_ZSTD AM_ICONV diff --git a/ld/Makefile.am b/ld/Makefile.am index d31021c13e2..bbe25f3aca2 100644 --- a/ld/Makefile.am +++ b/ld/Makefile.am @@ -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) diff --git a/ld/Makefile.in b/ld/Makefile.in index ee0c98f65b0..400eed2717e 100644 --- a/ld/Makefile.in +++ b/ld/Makefile.in @@ -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 355752e6b24..dfe2690d9f2 100644 --- 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 diff --git a/ld/aclocal.m4 b/ld/aclocal.m4 index d20c542eed5..893e973e4f2 100644 --- a/ld/aclocal.m4 +++ b/ld/aclocal.m4 @@ -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]) diff --git a/ld/config.in b/ld/config.in index 0ccd79d59cd..3916740eee4 100644 --- a/ld/config.in +++ b/ld/config.in @@ -162,6 +162,9 @@ /* 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 diff --git a/ld/configure b/ld/configure index a1a07005400..175dd995b2b 100755 --- a/ld/configure +++ b/ld/configure @@ -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 @@ -15586,126 +15715,6 @@ fi if test "x$enable_jansson" != "xno"; then - - - - - - - -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 -n "$PKG_CONFIG"; then : @@ -17052,8 +17061,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" @@ -17072,6 +17081,126 @@ 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 + + # 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 diff --git a/ld/configure.ac b/ld/configure.ac index eb55904c090..a491f9f1116 100644 --- a/ld/configure.ac +++ b/ld/configure.ac @@ -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 @@ -297,7 +298,6 @@ AC_ARG_ENABLE([jansson], [enable_jansson="no"]) if test "x$enable_jansson" != "xno"; then - PKG_PROG_PKG_CONFIG AS_IF([test -n "$PKG_CONFIG"], [ PKG_CHECK_MODULES(JANSSON, [jansson], @@ -386,9 +386,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 +AM_ZSTD # When converting linker scripts into strings for use in emulation # files, use astring.sed if the compiler supports ANSI string diff --git a/ld/emultempl/elf.em b/ld/emultempl/elf.em index c52484f35d3..acd66f907d1 100644 --- a/ld/emultempl/elf.em +++ b/ld/emultempl/elf.em @@ -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); diff --git a/ld/ld.texi b/ld/ld.texi index eabbec8faa9..9daed2e7e9f 100644 --- a/ld/ld.texi +++ b/ld/ld.texi @@ -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 diff --git a/ld/ldmain.c b/ld/ldmain.c index 1bbddaaad32..71af5935b74 100644 --- a/ld/ldmain.c +++ b/ld/ldmain.c @@ -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 (); diff --git a/ld/lexsup.c b/ld/lexsup.c index 9225f71b3ce..299371fb775 100644 --- a/ld/lexsup.c +++ b/ld/lexsup.c @@ -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")); diff --git a/ld/testsuite/ld-elf/compress.exp b/ld/testsuite/ld-elf/compress.exp index cfdd767b8ab..7b8a31cc41d 100644 --- a/ld/testsuite/ld-elf/compress.exp +++ b/ld/testsuite/ld-elf/compress.exp @@ -254,3 +254,20 @@ 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 ] } { + return +} +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 -- 2.37.3.998.g577e59143f-goog ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH v3] binutils, gdb: support zstd compressed debug sections 2022-09-23 18:20 ` Fangrui Song @ 2022-09-23 18:57 ` Simon Marchi 2022-09-23 20:34 ` Fangrui Song 0 siblings, 1 reply; 32+ messages in thread From: Simon Marchi @ 2022-09-23 18:57 UTC (permalink / raw) To: Fangrui Song, Nick Clifton; +Cc: Alan Modra, Jan Beulich, binutils, gdb-patches On 2022-09-23 14:20, Fangrui Song wrote: > On 2022-09-23, Simon Marchi wrote: >> >> >> On 2022-09-23 11:45, Nick Clifton wrote: >>> Hi Fangrui, >>> >>>> PR29397 PR29563: The new configure option --with-zstd defaults to auto. >>>> If pkgconfig/libzstd.pc is found, define HAVE_ZSTD and support zstd >>>> compressed debug sections for most tools. > > Hi Simon and Nick, > > I have checked that `make all-gdb` works in a --enable-gdb --without-debuginfod build. > > I then inspected the 2020 commits adding AC_DEBUGINFOD to > gdb/configure.ac and binutils/configure.ac. They come with no > PKG_PROG_PKG_CONFIG and config/debuginfod.m4 does not have > PKG_PROG_PKG_CONFIG, but they still work. So I think AC_ZSTD doesn't > need PKG_PROG_PKG_CONFIG, either. Though I have no insight why it > behaves that way:) Ok, I am a bit confused. Based on my comprehension, since the first call to PKG_CHECK_MODULES may not happen do to a condition: if test "x$with_debuginfod" != xno; then PKG_CHECK_MODULES([DEBUGINFOD], [libdebuginfod >= 0.179], ... fi ... the probing for pkg-config should not happen if --without-debuginfod is used. But in gdb/configure, I see that the probing for pkg-config actually appears outside the condition. Anyway, good if it works. > +diff --git a/gdb/NEWS b/gdb/NEWS > +index 9619842bc03..1457c99ff04 100644 > +--- 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. > ++ I'm not sure I understand the diff above, but I think it's missing an empty line between the previous bullet and the new bullet. Otherwise, that is OK for GDB. Simon ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH v3] binutils, gdb: support zstd compressed debug sections 2022-09-23 18:57 ` Simon Marchi @ 2022-09-23 20:34 ` Fangrui Song 2022-09-24 5:43 ` Eli Zaretskii 0 siblings, 1 reply; 32+ messages in thread From: Fangrui Song @ 2022-09-23 20:34 UTC (permalink / raw) To: Simon Marchi; +Cc: Nick Clifton, Alan Modra, Jan Beulich, binutils, gdb-patches On 2022-09-23, Simon Marchi wrote: > > >On 2022-09-23 14:20, Fangrui Song wrote: >> On 2022-09-23, Simon Marchi wrote: >>> >>> >>> On 2022-09-23 11:45, Nick Clifton wrote: >>>> Hi Fangrui, >>>> >>>>> PR29397 PR29563: The new configure option --with-zstd defaults to auto. >>>>> If pkgconfig/libzstd.pc is found, define HAVE_ZSTD and support zstd >>>>> compressed debug sections for most tools. >> >> Hi Simon and Nick, >> >> I have checked that `make all-gdb` works in a --enable-gdb --without-debuginfod build. >> >> I then inspected the 2020 commits adding AC_DEBUGINFOD to >> gdb/configure.ac and binutils/configure.ac. They come with no >> PKG_PROG_PKG_CONFIG and config/debuginfod.m4 does not have >> PKG_PROG_PKG_CONFIG, but they still work. So I think AC_ZSTD doesn't >> need PKG_PROG_PKG_CONFIG, either. Though I have no insight why it >> behaves that way:) > >Ok, I am a bit confused. Based on my comprehension, since the first >call to PKG_CHECK_MODULES may not happen do to a condition: > > if test "x$with_debuginfod" != xno; then > PKG_CHECK_MODULES([DEBUGINFOD], [libdebuginfod >= 0.179], > ... > fi > >... the probing for pkg-config should not happen if --without-debuginfod >is used. But in gdb/configure, I see that the probing for pkg-config >actually appears outside the condition. > >Anyway, good if it works. > >> +diff --git a/gdb/NEWS b/gdb/NEWS >> +index 9619842bc03..1457c99ff04 100644 >> +--- 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. >> ++ > >I'm not sure I understand the diff above, but I think it's missing an >empty line between the previous bullet and the new bullet. Otherwise, >that is OK for GDB. > >Simon Thanks! The gdb news entry looks like (immediately before "* New commands") --- 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 ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH v3] binutils, gdb: support zstd compressed debug sections 2022-09-23 20:34 ` Fangrui Song @ 2022-09-24 5:43 ` Eli Zaretskii 0 siblings, 0 replies; 32+ messages in thread From: Eli Zaretskii @ 2022-09-24 5:43 UTC (permalink / raw) To: Fangrui Song; +Cc: simon.marchi, gdb-patches, binutils, nickc, jbeulich, amodra > Date: Fri, 23 Sep 2022 13:34:17 -0700 > From: Fangrui Song via Gdb-patches <gdb-patches@sourceware.org> > Cc: gdb-patches@sourceware.org, binutils@sourceware.org, > Nick Clifton <nickc@redhat.com>, Jan Beulich <jbeulich@suse.com>, > Alan Modra <amodra@gmail.com> > > Thanks! The gdb news entry looks like (immediately before "* New commands") > > --- 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 This is OK, thanks. ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH v3] binutils, gdb: support zstd compressed debug sections 2022-09-23 4:08 [PATCH v3] binutils, gdb: support zstd compressed debug sections Fangrui Song 2022-09-23 14:32 ` Simon Marchi 2022-09-23 15:45 ` Nick Clifton @ 2022-09-24 6:53 ` Enze Li 2022-09-24 7:13 ` Fangrui Song 2022-09-27 18:08 ` Tom Tromey 2022-09-29 11:43 ` Martin Liška 4 siblings, 1 reply; 32+ messages in thread From: Enze Li @ 2022-09-24 6:53 UTC (permalink / raw) To: Fangrui Song via Gdb-patches Cc: Alan Modra, Jan Beulich, Nick Clifton, Simon Marchi, Fangrui Song, binutils Hi Fangrui, One nit, maybe not an important one. A proper committed message should include a link to the relevant bug on Bugzilla. Like this, Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29563 For more detail, see here[1]. [1] https://sourceware.org/gdb/wiki/ContributionChecklist#Properly_formatted_commit_messages Thanks, Enze On Thu, Sep 22 2022 at 09:08:37 PM -0700, Fangrui Song via Gdb-patches wrote: > PR29397 PR29563: The new configure option --with-zstd 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 > ... > ``` > --- > Changes from v1: > * use PKG_CHECK_MODULES to check libzstd.pc > > Changes from v2: > * Improve PKG_CHECK_MODULES, autoreconf -vf > * objcopy: check --compress-debug-sections=zstd in a !HAVE_ZSTD build > --- > bfd/Makefile.am | 4 +- > bfd/Makefile.in | 13 +- > bfd/aclocal.m4 | 2 + > bfd/bfd-in.h | 3 +- > bfd/bfd-in2.h | 11 +- > bfd/bfd.c | 26 +- > bfd/compress.c | 72 +++- > bfd/config.in | 3 + > bfd/configure | 268 ++++++++++++- > bfd/configure.ac | 3 +- > bfd/elf.c | 12 + > bfd/elfxx-target.h | 6 +- > bfd/section.c | 3 +- > binutils/Makefile.in | 5 +- > binutils/aclocal.m4 | 1 + > binutils/config.in | 3 + > binutils/configure | 135 ++++++- > binutils/configure.ac | 3 +- > binutils/doc/binutils.texi | 16 +- > binutils/objcopy.c | 19 +- > binutils/testsuite/binutils-all/compress.exp | 44 +++ > config/zstd.m4 | 24 ++ > configure | 10 + > configure.ac | 3 + > gas/Makefile.am | 4 +- > gas/Makefile.in | 13 +- > gas/aclocal.m4 | 2 + > gas/as.c | 13 +- > gas/compress-debug.c | 60 ++- > gas/compress-debug.h | 10 +- > gas/config.in | 3 + > gas/configure | 268 ++++++++++++- > gas/configure.ac | 3 +- > gas/doc/as.texi | 11 +- > gas/write.c | 36 +- > gdb/Makefile.in | 8 +- > gdb/acinclude.m4 | 3 +- > gdb/config.in | 3 + > gdb/configure | 136 ++++++- > gdb/configure.ac | 4 +- > ld/Makefile.am | 5 +- > ld/Makefile.in | 11 +- > ld/aclocal.m4 | 1 + > ld/config.in | 3 + > ld/configure | 389 ++++++++++++------- > ld/configure.ac | 7 +- > ld/emultempl/elf.em | 9 + > ld/ld.texi | 5 + > ld/ldmain.c | 8 +- > ld/lexsup.c | 4 +- > ld/testsuite/ld-elf/compress.exp | 17 + > 51 files changed, 1470 insertions(+), 255 deletions(-) > create mode 100644 config/zstd.m4 > > diff --git a/bfd/Makefile.am b/bfd/Makefile.am > index c23dff6cac3..cfe903c63f0 100644 > --- a/bfd/Makefile.am > +++ b/bfd/Makefile.am > @@ -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 > diff --git a/bfd/Makefile.in b/bfd/Makefile.in > index 82843d2d61d..6be41a72a59 100644 > --- a/bfd/Makefile.in > +++ b/bfd/Makefile.in > @@ -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 > diff --git a/bfd/aclocal.m4 b/bfd/aclocal.m4 > index 0f8aa1d4518..09b849dfc87 100644 > --- a/bfd/aclocal.m4 > +++ b/bfd/aclocal.m4 > @@ -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]) > diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h > index 8605056aefe..4765ea80536 100644 > --- a/bfd/bfd-in.h > +++ b/bfd/bfd-in.h > @@ -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 > diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h > index 79fcc4eb912..5c80956c79c 100644 > --- a/bfd/bfd-in2.h > +++ b/bfd/bfd-in2.h > @@ -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); > > diff --git a/bfd/bfd.c b/bfd/bfd.c > index 0a21db11fd6..5f2033bee7a 100644 > --- 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; > diff --git a/bfd/compress.c b/bfd/compress.c > index b2e39826e38..95c1f4c42d1 100644 > --- a/bfd/compress.c > +++ b/bfd/compress.c > @@ -20,18 +20,31 @@ > > #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)) > + if (!decompress_contents (compress_status == DECOMPRESS_SECTION_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; > } > diff --git a/bfd/config.in b/bfd/config.in > index f54a3cacbea..a59304e0a66 100644 > --- a/bfd/config.in > +++ b/bfd/config.in > @@ -232,6 +232,9 @@ > /* 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 > diff --git a/bfd/configure b/bfd/configure > index 075d2ee0a1b..d905a7bf7a8 100755 > --- a/bfd/configure > +++ b/bfd/configure > @@ -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. > @@ -13015,6 +13035,246 @@ 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 > + > + > +# 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 > diff --git a/bfd/configure.ac b/bfd/configure.ac > index 28f3d1afce6..d1b2f76b31a 100644 > --- a/bfd/configure.ac > +++ b/bfd/configure.ac > @@ -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 > +AM_ZSTD > > save_CFLAGS="$CFLAGS" > CFLAGS="$CFLAGS -Werror" > diff --git a/bfd/elf.c b/bfd/elf.c > index 16cea4f8aeb..e52fa458a5a 100644 > --- 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) > diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h > index feaba84bf2e..ca600bb5ddf 100644 > --- a/bfd/elfxx-target.h > +++ b/bfd/elfxx-target.h > @@ -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 > diff --git a/bfd/section.c b/bfd/section.c > index c7a02d729f2..614570e976e 100644 > --- a/bfd/section.c > +++ b/bfd/section.c > @@ -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. *} > . > diff --git a/binutils/Makefile.in b/binutils/Makefile.in > index 78d32b350e3..6de4e239408 100644 > --- a/binutils/Makefile.in > +++ b/binutils/Makefile.in > @@ -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@ > diff --git a/binutils/aclocal.m4 b/binutils/aclocal.m4 > index a877fa7f873..28271f56279 100644 > --- a/binutils/aclocal.m4 > +++ b/binutils/aclocal.m4 > @@ -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]) > diff --git a/binutils/config.in b/binutils/config.in > index c5fb919aa95..bee8c07e2f7 100644 > --- a/binutils/config.in > +++ b/binutils/config.in > @@ -157,6 +157,9 @@ > /* 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 > > diff --git a/binutils/configure b/binutils/configure > index 1c518227f57..54d0f184da1 100755 > --- a/binutils/configure > +++ b/binutils/configure > @@ -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). > > @@ -13490,6 +13499,126 @@ 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 > + > + > + > case "${host}" in > *-*-msdos* | *-*-go32* | *-*-mingw32* | *-*-cygwin* | *-*-windows*) > > diff --git a/binutils/configure.ac b/binutils/configure.ac > index ec002d3f88f..c152b7f6733 100644 > --- a/binutils/configure.ac > +++ b/binutils/configure.ac > @@ -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 > +AM_ZSTD > > BFD_BINARY_FOPEN > > diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi > index 1499db5728c..34a4164eb94 100644 > --- a/binutils/doc/binutils.texi > +++ b/binutils/doc/binutils.texi > @@ -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 > diff --git a/binutils/objcopy.c b/binutils/objcopy.c > index 43261756a42..fc668f00bbc 100644 > --- a/binutils/objcopy.c > +++ b/binutils/objcopy.c > @@ -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); > diff --git a/binutils/testsuite/binutils-all/compress.exp b/binutils/testsuite/binutils-all/compress.exp > index c88da74a987..4e74c824664 100644 > --- a/binutils/testsuite/binutils-all/compress.exp > +++ b/binutils/testsuite/binutils-all/compress.exp > @@ -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 > index 00000000000..93ae17b89d3 > --- /dev/null > +++ b/config/zstd.m4 > @@ -0,0 +1,24 @@ > +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([AM_ZSTD], > +[ > +AC_ARG_WITH(zstd, > + [AS_HELP_STRING([--with-zstd], [support zstd compressed debug sections (default=auto)])], > + [], [with_zstd=auto]) > + > +if test "$with_zstd" != no; then > + 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 > + ]) > +fi > +]) > diff --git a/configure b/configure > index d75f47a1e95..f14e0efd675 100755 > --- 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 > diff --git a/configure.ac b/configure.ac > index ae18d436aca..0152c69292e 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -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 > diff --git a/gas/Makefile.am b/gas/Makefile.am > index bd597398671..5f0f24abf8d 100644 > --- a/gas/Makefile.am > +++ b/gas/Makefile.am > @@ -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) \ > diff --git a/gas/Makefile.in b/gas/Makefile.in > index c57d78f82c4..5a4dd702252 100644 > --- a/gas/Makefile.in > +++ b/gas/Makefile.in > @@ -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) > diff --git a/gas/aclocal.m4 b/gas/aclocal.m4 > index 70183124da7..722030c776f 100644 > --- a/gas/aclocal.m4 > +++ b/gas/aclocal.m4 > @@ -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]) > diff --git a/gas/as.c b/gas/as.c > index 6268779cf90..35ad6b3ab3b 100644 > --- 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); > diff --git a/gas/compress-debug.c b/gas/compress-debug.c > index c80dbeec4e7..3cd175f6e57 100644 > --- a/gas/compress-debug.c > +++ b/gas/compress-debug.c > @@ -21,14 +21,23 @@ > #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); > diff --git a/gas/compress-debug.h b/gas/compress-debug.h > index 0183e269fef..87de0f8444e 100644 > --- a/gas/compress-debug.h > +++ b/gas/compress-debug.h > @@ -21,19 +21,19 @@ > #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 */ > diff --git a/gas/config.in b/gas/config.in > index e243fd277ee..0d1668a3eac 100644 > --- a/gas/config.in > +++ b/gas/config.in > @@ -134,6 +134,9 @@ > /* 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 > > diff --git a/gas/configure b/gas/configure > index d0449a1d7ab..1833adffaa8 100755 > --- a/gas/configure > +++ b/gas/configure > @@ -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" > @@ -13964,6 +13984,246 @@ 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 > + > + > +# 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 > diff --git a/gas/configure.ac b/gas/configure.ac > index 21795a82bdd..8750ea21381 100644 > --- a/gas/configure.ac > +++ b/gas/configure.ac > @@ -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 > +AM_ZSTD > > # Support for VMS timestamps via cross compile > > diff --git a/gas/doc/as.texi b/gas/doc/as.texi > index e915893da86..01f49434021 100644 > --- a/gas/doc/as.texi > +++ b/gas/doc/as.texi > @@ -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 > > diff --git a/gas/write.c b/gas/write.c > index f76bbdb706e..0e49df7c03f 100644 > --- a/gas/write.c > +++ b/gas/write.c > @@ -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,21 +1484,22 @@ 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 = 0; > + header_size = 12; > + } > + else > { > compression_header_size > = bfd_get_compression_header_size (stdoutput, NULL); > header_size = compression_header_size; > } > - else > - { > - compression_header_size = 0; > - header_size = 12; > - } > > /* Create a new frag to contain the compression header. */ > first_newf = frag_alloc (ob); > @@ -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); > diff --git a/gdb/Makefile.in b/gdb/Makefile.in > index 2598b81d205..c528ee5aa80 100644 > --- a/gdb/Makefile.in > +++ b/gdb/Makefile.in > @@ -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) > diff --git a/gdb/acinclude.m4 b/gdb/acinclude.m4 > index 95ff2b6f35e..28846119dcb 100644 > --- a/gdb/acinclude.m4 > +++ b/gdb/acinclude.m4 > @@ -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( > diff --git a/gdb/config.in b/gdb/config.in > index a4975c68aad..e13a409ec2d 100644 > --- a/gdb/config.in > +++ b/gdb/config.in > @@ -589,6 +589,9 @@ > /* 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 > > diff --git a/gdb/configure b/gdb/configure > index 4dbd0c3b13c..57cd165088a 100755 > --- a/gdb/configure > +++ b/gdb/configure > @@ -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,126 @@ 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 +17411,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 +17526,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 > diff --git a/gdb/configure.ac b/gdb/configure.ac > index 215a91c5b27..e8cf808d280 100644 > --- a/gdb/configure.ac > +++ b/gdb/configure.ac > @@ -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 > +AM_ZSTD > > AM_ICONV > > diff --git a/ld/Makefile.am b/ld/Makefile.am > index d31021c13e2..bbe25f3aca2 100644 > --- a/ld/Makefile.am > +++ b/ld/Makefile.am > @@ -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) > diff --git a/ld/Makefile.in b/ld/Makefile.in > index ee0c98f65b0..400eed2717e 100644 > --- a/ld/Makefile.in > +++ b/ld/Makefile.in > @@ -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/aclocal.m4 b/ld/aclocal.m4 > index d20c542eed5..893e973e4f2 100644 > --- a/ld/aclocal.m4 > +++ b/ld/aclocal.m4 > @@ -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]) > diff --git a/ld/config.in b/ld/config.in > index 0ccd79d59cd..3916740eee4 100644 > --- a/ld/config.in > +++ b/ld/config.in > @@ -162,6 +162,9 @@ > /* 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 > diff --git a/ld/configure b/ld/configure > index a1a07005400..175dd995b2b 100755 > --- a/ld/configure > +++ b/ld/configure > @@ -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 > @@ -15586,126 +15715,6 @@ fi > > > if test "x$enable_jansson" != "xno"; then > - > - > - > - > - > - > - > -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 -n "$PKG_CONFIG"; then : > > > @@ -17052,8 +17061,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" > @@ -17072,6 +17081,126 @@ 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 > + > + > # 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 > diff --git a/ld/configure.ac b/ld/configure.ac > index eb55904c090..a491f9f1116 100644 > --- a/ld/configure.ac > +++ b/ld/configure.ac > @@ -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 > @@ -297,7 +298,6 @@ AC_ARG_ENABLE([jansson], > [enable_jansson="no"]) > > if test "x$enable_jansson" != "xno"; then > - PKG_PROG_PKG_CONFIG > AS_IF([test -n "$PKG_CONFIG"], > [ > PKG_CHECK_MODULES(JANSSON, [jansson], > @@ -386,9 +386,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 > +AM_ZSTD > > # When converting linker scripts into strings for use in emulation > # files, use astring.sed if the compiler supports ANSI string > diff --git a/ld/emultempl/elf.em b/ld/emultempl/elf.em > index c52484f35d3..acd66f907d1 100644 > --- a/ld/emultempl/elf.em > +++ b/ld/emultempl/elf.em > @@ -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); > diff --git a/ld/ld.texi b/ld/ld.texi > index eabbec8faa9..9daed2e7e9f 100644 > --- a/ld/ld.texi > +++ b/ld/ld.texi > @@ -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 > diff --git a/ld/ldmain.c b/ld/ldmain.c > index 1bbddaaad32..71af5935b74 100644 > --- a/ld/ldmain.c > +++ b/ld/ldmain.c > @@ -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 (); > diff --git a/ld/lexsup.c b/ld/lexsup.c > index 9225f71b3ce..299371fb775 100644 > --- a/ld/lexsup.c > +++ b/ld/lexsup.c > @@ -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")); > diff --git a/ld/testsuite/ld-elf/compress.exp b/ld/testsuite/ld-elf/compress.exp > index cfdd767b8ab..7b8a31cc41d 100644 > --- a/ld/testsuite/ld-elf/compress.exp > +++ b/ld/testsuite/ld-elf/compress.exp > @@ -254,3 +254,20 @@ 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 ] } { > + return > +} > +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 ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH v3] binutils, gdb: support zstd compressed debug sections 2022-09-24 6:53 ` Enze Li @ 2022-09-24 7:13 ` Fangrui Song 2022-09-27 18:06 ` Tom Tromey 0 siblings, 1 reply; 32+ messages in thread From: Fangrui Song @ 2022-09-24 7:13 UTC (permalink / raw) To: Enze Li Cc: Fangrui Song via Gdb-patches, Alan Modra, Jan Beulich, Nick Clifton, Simon Marchi, binutils On 2022-09-24, Enze Li wrote: >Hi Fangrui, > >One nit, maybe not an important one. > >A proper committed message should include a link to the relevant bug on >Bugzilla. Like this, > > Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29563 > >For more detail, see here[1]. > >[1] https://sourceware.org/gdb/wiki/ContributionChecklist#Properly_formatted_commit_messages > >Thanks, >Enze Hi Enze, Thanks for the notice. I see that gdb started to use "Bug:" since 2021-07. In binutils, there isn't such a convention and there is no commit using "Bug:". So I will keep using the umbrella link PR29397. I am on the fence whether the gdb one needs to use "Bug:" but I'll probably not use it this time. Ideally the gdb patch should be separate, but since the bfd's zstd dependency needs gdb build system's cooperation it is placed in the same patch:) I am still waiting for an approval from binutils side. Relatedly, I believe ChangeLog is no longer strictly enforced. There are many recent commits don't using ChangeLog. I intentionally skip ChangeLog for this patch since I believe it would provide little value. (I see "ANNOUNCEMENT: ChangeLog policy change after GDB 11".) ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH v3] binutils, gdb: support zstd compressed debug sections 2022-09-24 7:13 ` Fangrui Song @ 2022-09-27 18:06 ` Tom Tromey 0 siblings, 0 replies; 32+ messages in thread From: Tom Tromey @ 2022-09-27 18:06 UTC (permalink / raw) To: Fangrui Song via Gdb-patches Cc: Enze Li, Fangrui Song, Nick Clifton, Alan Modra, binutils, Jan Beulich > In binutils, there isn't such a convention and there is no commit using > "Bug:". So I will keep using the umbrella link PR29397. I think the commit script only looks for strings matching "PR name/NUM", like "PR binutils/29397" in this case. Just "PR29397" may not end up putting the commit info into the bug. Tom ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH v3] binutils, gdb: support zstd compressed debug sections 2022-09-23 4:08 [PATCH v3] binutils, gdb: support zstd compressed debug sections Fangrui Song ` (2 preceding siblings ...) 2022-09-24 6:53 ` Enze Li @ 2022-09-27 18:08 ` Tom Tromey 2022-09-27 18:53 ` Fangrui Song 2022-09-29 11:43 ` Martin Liška 4 siblings, 1 reply; 32+ messages in thread From: Tom Tromey @ 2022-09-27 18:08 UTC (permalink / raw) To: Fangrui Song via Gdb-patches Cc: Alan Modra, Jan Beulich, Nick Clifton, Simon Marchi, Fangrui Song, binutils >>>>> Fangrui Song via Gdb-patches <gdb-patches@sourceware.org> writes: > PR29397 PR29563: The new configure option --with-zstd 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. This also needs some change to the sims. I see failures like this with git master: make[4]: Entering directory '/home/tromey/gdb/build/sim/bpf' CCLD run ../../bfd/libbfd.a(compress.o):compress.c:function decompress_contents: error: undefined reference to 'ZSTD_decompress' ../../bfd/libbfd.a(compress.o):compress.c:function decompress_contents: error: undefined reference to 'ZSTD_isError' (unknown):176: error: undefined reference to 'ZSTD_compress' (unknown):179: error: undefined reference to 'ZSTD_isError' collect2: error: ld returned 1 exit status You'll see them all if you do a build with all sims enabled. thanks, Tom ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH v3] binutils, gdb: support zstd compressed debug sections 2022-09-27 18:08 ` Tom Tromey @ 2022-09-27 18:53 ` Fangrui Song 0 siblings, 0 replies; 32+ messages in thread From: Fangrui Song @ 2022-09-27 18:53 UTC (permalink / raw) To: Tom Tromey Cc: Fangrui Song via Gdb-patches, Alan Modra, Jan Beulich, Nick Clifton, Simon Marchi, binutils On Tue, Sep 27, 2022 at 11:08 AM Tom Tromey <tom@tromey.com> wrote: > > >>>>> Fangrui Song via Gdb-patches <gdb-patches@sourceware.org> writes: > > > PR29397 PR29563: The new configure option --with-zstd 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. > > This also needs some change to the sims. > I see failures like this with git master: > > make[4]: Entering directory '/home/tromey/gdb/build/sim/bpf' > CCLD run > ../../bfd/libbfd.a(compress.o):compress.c:function decompress_contents: error: undefined reference to 'ZSTD_decompress' > ../../bfd/libbfd.a(compress.o):compress.c:function decompress_contents: error: undefined reference to 'ZSTD_isError' > (unknown):176: error: undefined reference to 'ZSTD_compress' > (unknown):179: error: undefined reference to 'ZSTD_isError' > collect2: error: ld returned 1 exit status > > You'll see them all if you do a build with all sims enabled. > > thanks, > Tom Thanks for the report and Tom's IRC chat with me about the `../../configure --enable-targets --enable-sim; make all-gdb` build. Tom confirmed that the latest commit `sim: Link ZSTD_LIBS` has fixed the problem. ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH v3] binutils, gdb: support zstd compressed debug sections 2022-09-23 4:08 [PATCH v3] binutils, gdb: support zstd compressed debug sections Fangrui Song ` (3 preceding siblings ...) 2022-09-27 18:08 ` Tom Tromey @ 2022-09-29 11:43 ` Martin Liška 2022-09-29 20:17 ` Fangrui Song 4 siblings, 1 reply; 32+ messages in thread From: Martin Liška @ 2022-09-29 11:43 UTC (permalink / raw) To: Fangrui Song, Alan Modra, Jan Beulich, Nick Clifton, Simon Marchi Cc: binutils, gdb-patches, Richard Biener, Michael Matz Hello. Thanks for the patch set. Right now, we configure our binutils package with: --enable-compressed-debug-sections=gas and we would appreciate a new configure option that will selected default compression algorithm. Having that, we will proudly switch to zstd. Can you please prepare such patch? Thanks, Martin ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH v3] binutils, gdb: support zstd compressed debug sections 2022-09-29 11:43 ` Martin Liška @ 2022-09-29 20:17 ` Fangrui Song 2022-09-30 9:48 ` [PATCH][RFC] add --enable-zstd-compressed-debug-sections configure option Martin Liška 0 siblings, 1 reply; 32+ messages in thread From: Fangrui Song @ 2022-09-29 20:17 UTC (permalink / raw) To: Martin Liška Cc: Alan Modra, Jan Beulich, Nick Clifton, Simon Marchi, binutils, gdb-patches, Richard Biener, Michael Matz On 2022-09-29, Martin Liška wrote: >Hello. > >Thanks for the patch set. Right now, we configure our binutils package with: >--enable-compressed-debug-sections=gas and we would appreciate a new configure >option that will selected default compression algorithm. Having that, we will >proudly switch to zstd. > >Can you please prepare such patch? > >Thanks, >Martin > I left a comment on https://sourceware.org/bugzilla/show_bug.cgi?id=19109 that the --enable-compressed-debug-sections=gas syntax needs extension to support zstd. Perhaps the easiest solution (and circumvents the syntax problem) is to add a new option: --enable-zstd-compressed-debug-sections, but then there is some duplication... ^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH][RFC] add --enable-zstd-compressed-debug-sections configure option 2022-09-29 20:17 ` Fangrui Song @ 2022-09-30 9:48 ` Martin Liška 2022-09-30 11:25 ` Pedro Alves 0 siblings, 1 reply; 32+ messages in thread From: Martin Liška @ 2022-09-30 9:48 UTC (permalink / raw) To: binutils; +Cc: Fangrui Song Hello. The patch can set up default compression algorithm as zstd instead of the default zlib-gabi. The patch is lightly tested as readelf can't decompress debug sections: https://sourceware.org/bugzilla/show_bug.cgi?id=29640 Thoughts? ChangeLog: * configure.ac: Add --enable-zstd-compressed-debug-sections configure option. * configure: Regenerate. gas/ChangeLog: * NEWS: Mention --enable-zstd-compressed-debug-sections. * as.c: Respect FLAG_ZSTD_COMPRESS_DEBUG and should it in --help. * configure.ac: Add --enable-zstd-compressed-debug-sections configure option. * configure: Regenerate. * config.in: Regenerate. ld/ChangeLog: * NEWS: Mention --enable-zstd-compressed-debug-sections. * configure.ac: Add --enable-zstd-compressed-debug-sections configure option. * configure: Regenerate. * config.in: Regenerate. * ldmain.c: Respenct FLAG_ZSTD_COMPRESS_DEBUG. * lexsup.c: Likewise. --- configure | 17 +++++++++++++++++ configure.ac | 6 ++++++ gas/NEWS | 3 +++ gas/as.c | 24 ++++++++++++++++-------- gas/config.in | 3 +++ gas/configure | 20 ++++++++++++++++++-- gas/configure.ac | 10 ++++++++++ ld/NEWS | 3 +++ ld/config.in | 3 +++ ld/configure | 20 ++++++++++++++++++-- ld/configure.ac | 10 ++++++++++ ld/ldmain.c | 4 ++++ ld/lexsup.c | 5 +++++ 13 files changed, 116 insertions(+), 12 deletions(-) diff --git a/configure b/configure index f14e0efd675..03c26c455c7 100755 --- a/configure +++ b/configure @@ -792,6 +792,7 @@ enable_gold enable_ld enable_gprofng enable_compressed_debug_sections +enable_zstd_compressed_debug_sections enable_year2038 enable_libquadmath enable_libquadmath_support @@ -1523,6 +1524,9 @@ Optional Features: --enable-compressed-debug-sections={all,gas,gold,ld,none} Enable compressed debug sections for gas, gold or ld by default + --enable-zstd-compressed-debug-sections + Use zstd for debug info sections compression by + default. --enable-year2038 enable support for timestamps past the year 2038 --disable-libquadmath do not build libquadmath directory --disable-libquadmath-support @@ -3119,6 +3123,19 @@ else fi + +# Check whether --enable-zstd_compressed_debug_sections was given. +if test "${enable_zstd_compressed_debug_sections+set}" = set; then : + enableval=$enable_zstd_compressed_debug_sections; + if test x"$enable_compressed_debug_sections" = xyes; then + as_fn_error $? "no program with compressed debug sections specified" "$LINENO" 5 + fi + +else + zstd_compressed_debug_sections= +fi + + # Configure extra directories which are host specific case "${host}" in diff --git a/configure.ac b/configure.ac index 0152c69292e..1728991ab8a 100644 --- a/configure.ac +++ b/configure.ac @@ -422,6 +422,12 @@ AC_ARG_ENABLE(compressed_debug_sections, fi ], [enable_compressed_debug_sections=]) + +AC_ARG_ENABLE(zstd_compressed_debug_sections, +[AS_HELP_STRING([--enable-zstd-compressed-debug-sections], + [Use zstd for debug info sections compression by default.])], +[], [zstd_compressed_debug_sections=]) + # Configure extra directories which are host specific case "${host}" in diff --git a/gas/NEWS b/gas/NEWS index 9a8b726b942..8f509f3aebf 100644 --- a/gas/NEWS +++ b/gas/NEWS @@ -2,6 +2,9 @@ * gas now supports --compress-debug-sections=zstd to compress debug sections with zstd. +* Add a configure option --enable-zstd-compressed-debug-sections + in order to use zstd as a default compression algorithm when + --compress-debug-sections is used (or enabled by default). Changes in 2.39: diff --git a/gas/as.c b/gas/as.c index 9ce3d622f95..8c9c1d7abfd 100644 --- a/gas/as.c +++ b/gas/as.c @@ -226,8 +226,12 @@ print_version_id (void) #ifdef DEFAULT_FLAG_COMPRESS_DEBUG enum compressed_debug_section_type flag_compress_debug +#if FLAG_ZSTD_COMPRESS_DEBUG + = COMPRESS_DEBUG_ZSTD; +#else = COMPRESS_DEBUG_GABI_ZLIB; #endif +#endif static void show_usage (FILE * stream) @@ -250,21 +254,25 @@ Options:\n\ fprintf (stream, _("\ --alternate initially turn on alternate macro syntax\n")); -#ifdef DEFAULT_FLAG_COMPRESS_DEBUG fprintf (stream, _("\ --compress-debug-sections[={none|zlib|zlib-gnu|zlib-gabi|zstd}]\n\ - compress DWARF debug sections using zlib [default]\n")); + compress DWARF debug sections\n")); +#ifdef DEFAULT_FLAG_COMPRESS_DEBUG +#if FLAG_ZSTD_COMPRESS_DEBUG fprintf (stream, _("\ - --nocompress-debug-sections\n\ - don't compress DWARF debug sections\n")); + Default: zstd\n")); #else fprintf (stream, _("\ - --compress-debug-sections[={none|zlib|zlib-gnu|zlib-gabi|zstd}]\n\ - compress DWARF debug sections using zlib\n")); + Default: zlib-gabi\n")); +#endif +#else fprintf (stream, _("\ - --nocompress-debug-sections\n\ - don't compress DWARF debug sections [default]\n")); + Default: none\n")); #endif + + fprintf (stream, _("\ + --nocompress-debug-sections\n\ + don't compress DWARF debug sections\n")); fprintf (stream, _("\ -D produce assembler debugging messages\n")); fprintf (stream, _("\ diff --git a/gas/config.in b/gas/config.in index 0d1668a3eac..35b8c0cc26a 100644 --- a/gas/config.in +++ b/gas/config.in @@ -71,6 +71,9 @@ language is requested. */ #undef ENABLE_NLS +/* Define to 1 if you want compressed debug sections with zstd by default. */ +#undef FLAG_ZSTD_COMPRESS_DEBUG + /* Define to 1 if you have the declaration of `asprintf', and to 0 if you don't. */ #undef HAVE_DECL_ASPRINTF diff --git a/gas/configure b/gas/configure index 02cded59b6a..10a095f89c7 100755 --- a/gas/configure +++ b/gas/configure @@ -810,6 +810,7 @@ enable_largefile enable_targets enable_checking enable_compressed_debug_sections +enable_zstd_compressed_debug_sections enable_x86_relax_relocations enable_elf_stt_common enable_generate_build_notes @@ -1476,6 +1477,9 @@ Optional Features: --enable-checking enable run-time checks --enable-compressed-debug-sections={all,gas,none} compress debug sections by default + --enable-zstd-compressed-debug-sections + Use zstd for debug info sections compression by + default --enable-x86-relax-relocations generate x86 relax relocations by default --enable-elf-stt-common generate ELF common symbols with STT_COMMON type by @@ -10722,7 +10726,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 10725 "configure" +#line 10729 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -10828,7 +10832,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 10831 "configure" +#line 10835 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11502,6 +11506,12 @@ if test "${enable_compressed_debug_sections+set}" = set; then : esac fi +# Use zstd compression algorithm by default. +# Check whether --enable-zstd_compressed_debug_sections was given. +if test "${enable_zstd_compressed_debug_sections+set}" = set; then : + enableval=$enable_zstd_compressed_debug_sections; ac_zstd_compressed_debug_sections=$enableval +fi + # PR gas/19520 # Decide if x86 assembler should generate relax relocations. ac_default_x86_relax_relocations=unset @@ -12671,6 +12681,12 @@ $as_echo "#define DEFAULT_FLAG_COMPRESS_DEBUG 1" >>confdefs.h fi +if test x$ac_zstd_compressed_debug_sections = xyes ; then + +$as_echo "#define FLAG_ZSTD_COMPRESS_DEBUG 1" >>confdefs.h + +fi + # Turn on all targets if possible if test ${all_targets} = "yes"; then case ${target_cpu_type} in diff --git a/gas/configure.ac b/gas/configure.ac index e6f3298cb3e..b46acfe9033 100644 --- a/gas/configure.ac +++ b/gas/configure.ac @@ -76,6 +76,12 @@ AC_ARG_ENABLE(compressed_debug_sections, *) ac_default_compressed_debug_sections=unset ;; esac])dnl +# Use zstd compression algorithm by default. +AC_ARG_ENABLE(zstd_compressed_debug_sections, + AS_HELP_STRING([--enable-zstd-compressed-debug-sections], + [Use zstd for debug info sections compression by default]), +[ac_zstd_compressed_debug_sections=$enableval])dnl + # PR gas/19520 # Decide if x86 assembler should generate relax relocations. ac_default_x86_relax_relocations=unset @@ -755,6 +761,10 @@ if test x$ac_default_compressed_debug_sections = xyes ; then AC_DEFINE(DEFAULT_FLAG_COMPRESS_DEBUG, 1, [Define if you want compressed debug sections by default.]) fi +if test x$ac_zstd_compressed_debug_sections = xyes ; then + AC_DEFINE(FLAG_ZSTD_COMPRESS_DEBUG, 1, [Define to 1 if you want compressed debug sections with zstd by default.]) +fi + # Turn on all targets if possible if test ${all_targets} = "yes"; then case ${target_cpu_type} in diff --git a/ld/NEWS b/ld/NEWS index dfe2690d9f2..82619b3625e 100644 --- a/ld/NEWS +++ b/ld/NEWS @@ -2,6 +2,9 @@ * ld now supports zstd compressed debug sections. The new option --compress-debug-sections=zstd compresses debug sections with zstd. +* Add a configure option --enable-zstd-compressed-debug-sections + in order to use zstd as a default compression algorithm when + --compress-debug-sections is used (or enabled by default). Changes in 2.39: diff --git a/ld/config.in b/ld/config.in index 3916740eee4..93ec9cee232 100644 --- a/ld/config.in +++ b/ld/config.in @@ -58,6 +58,9 @@ /* Additional extension a shared object might have. */ #undef EXTRA_SHLIB_EXTENSION +/* Define to 1 if you want compressed debug sections with zstd by default. */ +#undef FLAG_ZSTD_COMPRESS_DEBUG + /* Define to choose default GOT handling scheme */ #undef GOT_HANDLING_DEFAULT diff --git a/ld/configure b/ld/configure index 9dd3ed5f1e7..fa21b5de04e 100755 --- a/ld/configure +++ b/ld/configure @@ -841,6 +841,7 @@ with_sysroot enable_gold enable_got enable_compressed_debug_sections +enable_zstd_compressed_debug_sections enable_new_dtags enable_relro enable_textrel_check @@ -1524,6 +1525,9 @@ Optional Features: multigot) --enable-compressed-debug-sections={all,ld,none} compress debug sections by default] + --enable-zstd-compressed-debug-sections + Use zstd for debug info sections compression by + default --enable-new-dtags set DT_RUNPATH instead of DT_RPATH by default] --enable-relro enable -z relro in ELF linker by default --enable-textrel-check=[yes|no|warning|error] @@ -11620,7 +11624,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11623 "configure" +#line 11627 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11726,7 +11730,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11729 "configure" +#line 11733 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -15544,6 +15548,12 @@ if test "${enable_compressed_debug_sections+set}" = set; then : esac fi +# Use zstd compression algorithm by default. +# Check whether --enable-zstd_compressed_debug_sections was given. +if test "${enable_zstd_compressed_debug_sections+set}" = set; then : + enableval=$enable_zstd_compressed_debug_sections; ac_zstd_compressed_debug_sections=$enableval +fi + # Decide setting DT_RUNPATH instead of DT_RPATH by default ac_default_new_dtags=unset # Provide a configure time option to override our default. @@ -17340,6 +17350,12 @@ $as_echo "#define DEFAULT_FLAG_COMPRESS_DEBUG 1" >>confdefs.h fi +if test x$ac_zstd_compressed_debug_sections = xyes ; then + +$as_echo "#define FLAG_ZSTD_COMPRESS_DEBUG 1" >>confdefs.h + +fi + if test "${ac_default_new_dtags}" = unset; then ac_default_new_dtags=0 fi diff --git a/ld/configure.ac b/ld/configure.ac index f1b2f9897f8..729f07343aa 100644 --- a/ld/configure.ac +++ b/ld/configure.ac @@ -163,6 +163,12 @@ AC_ARG_ENABLE(compressed_debug_sections, ,no, | ,none,) ac_default_compressed_debug_sections=no ;; esac])dnl +# Use zstd compression algorithm by default. +AC_ARG_ENABLE(zstd_compressed_debug_sections, + AS_HELP_STRING([--enable-zstd-compressed-debug-sections], + [Use zstd for debug info sections compression by default]), +[ac_zstd_compressed_debug_sections=$enableval])dnl + # Decide setting DT_RUNPATH instead of DT_RPATH by default ac_default_new_dtags=unset # Provide a configure time option to override our default. @@ -510,6 +516,10 @@ if test x$ac_default_compressed_debug_sections = xyes ; then AC_DEFINE(DEFAULT_FLAG_COMPRESS_DEBUG, 1, [Define if you want compressed debug sections by default.]) fi +if test x$ac_zstd_compressed_debug_sections = xyes ; then + AC_DEFINE(FLAG_ZSTD_COMPRESS_DEBUG, 1, [Define to 1 if you want compressed debug sections with zstd by default.]) +fi + if test "${ac_default_new_dtags}" = unset; then ac_default_new_dtags=0 fi diff --git a/ld/ldmain.c b/ld/ldmain.c index d63002c994a..d0ad5f3d797 100644 --- a/ld/ldmain.c +++ b/ld/ldmain.c @@ -352,8 +352,12 @@ main (int argc, char **argv) link_info.spare_dynamic_tags = 5; link_info.path_separator = ':'; #ifdef DEFAULT_FLAG_COMPRESS_DEBUG +#if FLAG_ZSTD_COMPRESS_DEBUG + link_info.compress_debug = COMPRESS_DEBUG_ZSTD; +#else link_info.compress_debug = COMPRESS_DEBUG_GABI_ZLIB; #endif +#endif #ifdef DEFAULT_NEW_DTAGS link_info.new_dtags = DEFAULT_NEW_DTAGS; #endif diff --git a/ld/lexsup.c b/ld/lexsup.c index 299371fb775..c46f1f822a8 100644 --- a/ld/lexsup.c +++ b/ld/lexsup.c @@ -2149,8 +2149,13 @@ elf_static_list_options (FILE *file) --compress-debug-sections=[none|zlib|zlib-gnu|zlib-gabi|zstd]\n\ Compress DWARF debug sections\n")); #ifdef DEFAULT_FLAG_COMPRESS_DEBUG +#if FLAG_ZSTD_COMPRESS_DEBUG + fprintf (file, _("\ + Default: zstd\n")); +#else fprintf (file, _("\ Default: zlib-gabi\n")); +#endif #else fprintf (file, _("\ Default: none\n")); -- 2.37.3 ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH][RFC] add --enable-zstd-compressed-debug-sections configure option 2022-09-30 9:48 ` [PATCH][RFC] add --enable-zstd-compressed-debug-sections configure option Martin Liška @ 2022-09-30 11:25 ` Pedro Alves 2022-09-30 12:42 ` Martin Liška 0 siblings, 1 reply; 32+ messages in thread From: Pedro Alves @ 2022-09-30 11:25 UTC (permalink / raw) To: Martin Liška, binutils; +Cc: Fangrui Song On 2022-09-30 10:48 a.m., Martin Liška wrote: > Hello. > > The patch can set up default compression algorithm as zstd instead of the > default zlib-gabi. > > The patch is lightly tested as readelf can't decompress debug sections: > https://sourceware.org/bugzilla/show_bug.cgi?id=29640 > > Thoughts? > > ChangeLog: > > * configure.ac: Add --enable-zstd-compressed-debug-sections > configure option. > * configure: Regenerate. This may become a bit awkward in the future when other better format appears, and you want to switch to use it by default. Like, imagine zstd2 is invented. At that point we'd have to decide whether to add code to error out if the user specifies both "--enable-zstd-compressed-debug-sections --enable-zstd2-compressed-debug-sections", or always pick the latter option, or some such. IMHO, it seems cleaner and more future proof to add instead: --enable-default-compressed-debug-sections=zlib|zlib-gnu|zlib-gabi|zstd WDYT? Pedro Alves ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH][RFC] add --enable-zstd-compressed-debug-sections configure option 2022-09-30 11:25 ` Pedro Alves @ 2022-09-30 12:42 ` Martin Liška 2022-10-01 7:31 ` Fangrui Song 0 siblings, 1 reply; 32+ messages in thread From: Martin Liška @ 2022-09-30 12:42 UTC (permalink / raw) To: Pedro Alves, binutils; +Cc: Fangrui Song On 9/30/22 13:25, Pedro Alves wrote: > On 2022-09-30 10:48 a.m., Martin Liška wrote: >> Hello. >> >> The patch can set up default compression algorithm as zstd instead of the >> default zlib-gabi. >> >> The patch is lightly tested as readelf can't decompress debug sections: >> https://sourceware.org/bugzilla/show_bug.cgi?id=29640 >> >> Thoughts? >> >> ChangeLog: >> >> * configure.ac: Add --enable-zstd-compressed-debug-sections >> configure option. >> * configure: Regenerate. > > This may become a bit awkward in the future when other better format appears, and you want to > switch to use it by default. Like, imagine zstd2 is invented. At that point we'd have to decide > whether to add code to error out if the user specifies both > "--enable-zstd-compressed-debug-sections --enable-zstd2-compressed-debug-sections", > or always pick the latter option, or some such. Understood. > > IMHO, it seems cleaner and more future proof to add instead: > > --enable-default-compressed-debug-sections=zlib|zlib-gnu|zlib-gabi|zstd > > WDYT? Yep, it's much nicer. Anyway, lemme try preparing a patch that does a bit of refactoring before I introduce such a patch. Martin > > Pedro Alves ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH][RFC] add --enable-zstd-compressed-debug-sections configure option 2022-09-30 12:42 ` Martin Liška @ 2022-10-01 7:31 ` Fangrui Song 2022-10-03 7:49 ` Martin Liška 0 siblings, 1 reply; 32+ messages in thread From: Fangrui Song @ 2022-10-01 7:31 UTC (permalink / raw) To: Martin Liška; +Cc: Pedro Alves, binutils On 2022-09-30, Martin Liška wrote: >On 9/30/22 13:25, Pedro Alves wrote: >> On 2022-09-30 10:48 a.m., Martin Liška wrote: >>> Hello. >>> >>> The patch can set up default compression algorithm as zstd instead of the >>> default zlib-gabi. >>> >>> The patch is lightly tested as readelf can't decompress debug sections: >>> https://sourceware.org/bugzilla/show_bug.cgi?id=29640 >>> >>> Thoughts? >>> >>> ChangeLog: >>> >>> * configure.ac: Add --enable-zstd-compressed-debug-sections >>> configure option. >>> * configure: Regenerate. >> >> This may become a bit awkward in the future when other better format appears, and you want to >> switch to use it by default. Like, imagine zstd2 is invented. At that point we'd have to decide >> whether to add code to error out if the user specifies both >> "--enable-zstd-compressed-debug-sections --enable-zstd2-compressed-debug-sections", >> or always pick the latter option, or some such. > >Understood. > >> >> IMHO, it seems cleaner and more future proof to add instead: >> >> --enable-default-compressed-debug-sections=zlib|zlib-gnu|zlib-gabi|zstd >> >> WDYT? > >Yep, it's much nicer. Anyway, lemme try preparing a patch that does a bit of refactoring >before I introduce such a patch. > >Martin Personally I'll prefer that the compiler drivers (GCC and Clang) pass the default options to ld/as, and they have good infrastructure for customization... (Clang recently got better configuration file (https://clang.llvm.org/docs/UsersManual.html#configuration-files) support which enables more convenient default driver options.) Setting default options in ld/as allow very few projects which bypass the compiler driver to use zstd compressed debug sections but the benefit is probably low... ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH][RFC] add --enable-zstd-compressed-debug-sections configure option 2022-10-01 7:31 ` Fangrui Song @ 2022-10-03 7:49 ` Martin Liška 2022-10-03 7:50 ` [PATCH 1/2] refactor usage of compressed_debug_section_type Martin Liška 2022-10-03 7:50 ` [PATCH 2/2] add --enable-default-compressed-debug-sections-algorithm configure option Martin Liška 0 siblings, 2 replies; 32+ messages in thread From: Martin Liška @ 2022-10-03 7:49 UTC (permalink / raw) To: Fangrui Song; +Cc: Pedro Alves, binutils On 10/1/22 09:31, Fangrui Song wrote: > On 2022-09-30, Martin Liška wrote: >> On 9/30/22 13:25, Pedro Alves wrote: >>> On 2022-09-30 10:48 a.m., Martin Liška wrote: >>>> Hello. >>>> >>>> The patch can set up default compression algorithm as zstd instead of the >>>> default zlib-gabi. >>>> >>>> The patch is lightly tested as readelf can't decompress debug sections: >>>> https://sourceware.org/bugzilla/show_bug.cgi?id=29640 >>>> >>>> Thoughts? >>>> >>>> ChangeLog: >>>> >>>> * configure.ac: Add --enable-zstd-compressed-debug-sections >>>> configure option. >>>> * configure: Regenerate. >>> >>> This may become a bit awkward in the future when other better format appears, and you want to >>> switch to use it by default. Like, imagine zstd2 is invented. At that point we'd have to decide >>> whether to add code to error out if the user specifies both >>> "--enable-zstd-compressed-debug-sections --enable-zstd2-compressed-debug-sections", >>> or always pick the latter option, or some such. >> >> Understood. >> >>> >>> IMHO, it seems cleaner and more future proof to add instead: >>> >>> --enable-default-compressed-debug-sections=zlib|zlib-gnu|zlib-gabi|zstd >>> >>> WDYT? >> >> Yep, it's much nicer. Anyway, lemme try preparing a patch that does a bit of refactoring >> before I introduce such a patch. >> >> Martin > > Personally I'll prefer that the compiler drivers (GCC and Clang) pass > the default options to ld/as, and they have good infrastructure for > customization... (Clang recently got better configuration file > (https://clang.llvm.org/docs/UsersManual.html#configuration-files) > support which enables more convenient default driver options.) > > Setting default options in ld/as allow very few projects which bypass > the compiler driver to use zstd compressed debug sections but the > benefit is probably low... Well, I would prefer having the configure option, similar to --enable-compressed-debug-sections, we as openSUSE rely on that where we select the corresponding option value in binutils package. Martin ^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH 1/2] refactor usage of compressed_debug_section_type 2022-10-03 7:49 ` Martin Liška @ 2022-10-03 7:50 ` Martin Liška 2022-10-11 7:14 ` Martin Liška 2022-10-03 7:50 ` [PATCH 2/2] add --enable-default-compressed-debug-sections-algorithm configure option Martin Liška 1 sibling, 1 reply; 32+ messages in thread From: Martin Liška @ 2022-10-03 7:50 UTC (permalink / raw) To: binutils; +Cc: Fangrui Song bfd/ChangeLog: * bfd-in.h (bfd_hash_set_default_size): Add COMPRESS_UNKNOWN enum value. (struct compressed_type_tuple): New. * bfd-in2.h (bfd_hash_set_default_size): Regenerate. (struct compressed_type_tuple): Likewise. * libbfd.c (ARRAY_SIZE): New macro. (bfd_get_compression_algorithm): New function. (bfd_get_compression_algorithm_name): Likewise. gas/ChangeLog: * as.c: Do not special-case, use the new functions. ld/ChangeLog: * emultempl/elf.em: Do not special-case, use the new functions. * lexsup.c (elf_static_list_options): Likewise. --- bfd/bfd-in.h | 20 +++++++++++++++++--- bfd/bfd-in2.h | 20 +++++++++++++++++--- bfd/libbfd.c | 36 ++++++++++++++++++++++++++++++++++++ gas/as.c | 34 +++++++++------------------------- ld/emultempl/elf.em | 22 +++++++--------------- ld/lexsup.c | 8 ++------ 6 files changed, 88 insertions(+), 52 deletions(-) diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h index 4765ea80536..82e33d400f3 100644 --- a/bfd/bfd-in.h +++ b/bfd/bfd-in.h @@ -335,15 +335,23 @@ extern void bfd_hash_traverse this size. */ extern unsigned long bfd_hash_set_default_size (unsigned long); -/* Types of compressed DWARF debug sections. We currently support - zlib. */ +/* Types of compressed DWARF debug sections. */ 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_ZSTD = COMPRESS_DEBUG | 1 << 3 + COMPRESS_DEBUG_ZSTD = COMPRESS_DEBUG | 1 << 3, + COMPRESS_UNKNOWN = 1 << 4 +}; + +/* Tuple for compressed_debug_section_type and their name. */ + +struct compressed_type_tuple +{ + enum compressed_debug_section_type type; + const char *name; }; /* This structure is used to keep track of stabs in sections @@ -456,6 +464,12 @@ extern void bfd_free_window (bfd_window *); extern bool bfd_get_file_window (bfd *, file_ptr, bfd_size_type, bfd_window *, bool); + + +extern enum compressed_debug_section_type bfd_get_compression_algorithm + (const char *); +extern const char *bfd_get_compression_algorithm_name + (enum compressed_debug_section_type); \f /* Externally visible ELF routines. */ diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 5c80956c79c..39f925362e0 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -342,15 +342,23 @@ extern void bfd_hash_traverse this size. */ extern unsigned long bfd_hash_set_default_size (unsigned long); -/* Types of compressed DWARF debug sections. We currently support - zlib. */ +/* Types of compressed DWARF debug sections. */ 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_ZSTD = COMPRESS_DEBUG | 1 << 3 + COMPRESS_DEBUG_ZSTD = COMPRESS_DEBUG | 1 << 3, + COMPRESS_UNKNOWN = 1 << 4 +}; + +/* Tuple for compressed_debug_section_type and their name. */ + +struct compressed_type_tuple +{ + enum compressed_debug_section_type type; + const char *name; }; /* This structure is used to keep track of stabs in sections @@ -463,6 +471,12 @@ extern void bfd_free_window (bfd_window *); extern bool bfd_get_file_window (bfd *, file_ptr, bfd_size_type, bfd_window *, bool); + + +extern enum compressed_debug_section_type bfd_get_compression_algorithm + (const char *); +extern const char *bfd_get_compression_algorithm_name + (enum compressed_debug_section_type); \f /* Externally visible ELF routines. */ diff --git a/bfd/libbfd.c b/bfd/libbfd.c index d33f3416206..14e7d8ef34f 100644 --- a/bfd/libbfd.c +++ b/bfd/libbfd.c @@ -1244,3 +1244,39 @@ _bfd_generic_init_private_section_data (bfd *ibfd ATTRIBUTE_UNUSED, { return true; } + +/* Display texts for type of compressed DWARF debug sections. */ +static const struct compressed_type_tuple compressed_debug_section_names[] = +{ + { COMPRESS_DEBUG_NONE, "none" }, + { COMPRESS_DEBUG, "zlib" }, + { COMPRESS_DEBUG_GNU_ZLIB, "zlib-gnu" }, + { COMPRESS_DEBUG_GABI_ZLIB, "zlib-gabi" }, + { COMPRESS_DEBUG_ZSTD, "zstd" }, +}; + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0])) +#endif + +/* Return compressed_debug_section_type from a string representation. */ +enum compressed_debug_section_type +bfd_get_compression_algorithm (const char *name) +{ + for (unsigned i = 0; i < ARRAY_SIZE (compressed_debug_section_names); ++i) + if (strcasecmp (compressed_debug_section_names[i].name, name) == 0) + return compressed_debug_section_names[i].type; + + return COMPRESS_UNKNOWN; +} + +/* Return compression algorithm name based on the type. */ +const char * +bfd_get_compression_algorithm_name (enum compressed_debug_section_type type) +{ + for (unsigned i = 0; i < ARRAY_SIZE (compressed_debug_section_names); ++i) + if (type == compressed_debug_section_names[i].type) + return compressed_debug_section_names[i].name; + + return NULL; +} diff --git a/gas/as.c b/gas/as.c index 9ce3d622f95..a5c2d2459f7 100644 --- a/gas/as.c +++ b/gas/as.c @@ -250,21 +250,16 @@ Options:\n\ fprintf (stream, _("\ --alternate initially turn on alternate macro syntax\n")); -#ifdef DEFAULT_FLAG_COMPRESS_DEBUG fprintf (stream, _("\ --compress-debug-sections[={none|zlib|zlib-gnu|zlib-gabi|zstd}]\n\ - compress DWARF debug sections using zlib [default]\n")); + compress DWARF debug sections\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|zstd}]\n\ - compress DWARF debug sections using zlib\n")); + Default: %s\n"), + bfd_get_compression_algorithm_name (flag_compress_debug)); + fprintf (stream, _("\ --nocompress-debug-sections\n\ - don't compress DWARF debug sections [default]\n")); -#endif + don't compress DWARF debug sections\n")); fprintf (stream, _("\ -D produce assembler debugging messages\n")); fprintf (stream, _("\ @@ -741,24 +736,13 @@ This program has absolutely no warranty.\n")); if (optarg) { #if defined OBJ_ELF || defined OBJ_MAYBE_ELF - if (strcasecmp (optarg, "none") == 0) - flag_compress_debug = COMPRESS_DEBUG_NONE; - else if (strcasecmp (optarg, "zlib") == 0) - flag_compress_debug = COMPRESS_DEBUG_GABI_ZLIB; - else if (strcasecmp (optarg, "zlib-gnu") == 0) - 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 + flag_compress_debug = bfd_get_compression_algorithm (optarg); +#ifndef HAVE_ZSTD + if (flag_compress_debug == COMPRESS_DEBUG_ZSTD) as_fatal (_ ("--compress-debug-sections=zstd: gas is not " "built with zstd support")); #endif - } - else + if (flag_compress_debug == COMPRESS_UNKNOWN) as_fatal (_("Invalid --compress-debug-sections option: `%s'"), optarg); #else diff --git a/ld/emultempl/elf.em b/ld/emultempl/elf.em index acd66f907d1..5dfc03a740c 100644 --- a/ld/emultempl/elf.em +++ b/ld/emultempl/elf.em @@ -660,24 +660,16 @@ gld${EMULATION_NAME}_handle_option (int optc) break; case OPTION_COMPRESS_DEBUG: - if (strcasecmp (optarg, "none") == 0) - link_info.compress_debug = COMPRESS_DEBUG_NONE; - else if (strcasecmp (optarg, "zlib") == 0) - link_info.compress_debug = COMPRESS_DEBUG_GABI_ZLIB; - else if (strcasecmp (optarg, "zlib-gnu") == 0) - 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) + link_info.compress_debug = bfd_get_compression_algorithm (optarg); + 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")); +#ifndef HAVE_ZSTD + if (link_info.compress_debug == COMPRESS_DEBUG_ZSTD) + einfo (_ ("%F%P: --compress-debug-sections=zstd: ld is not built " + "with zstd support\n")); #endif } - else + if (link_info.compress_debug == COMPRESS_UNKNOWN) einfo (_("%F%P: invalid --compress-debug-sections option: \`%s'\n"), optarg); break; diff --git a/ld/lexsup.c b/ld/lexsup.c index 299371fb775..0c01c9966e0 100644 --- a/ld/lexsup.c +++ b/ld/lexsup.c @@ -2148,13 +2148,9 @@ elf_static_list_options (FILE *file) fprintf (file, _("\ --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")); -#else - fprintf (file, _("\ - Default: none\n")); -#endif + Default: %s\n"), + bfd_get_compression_algorithm_name (link_info.compress_debug)); fprintf (file, _("\ -z common-page-size=SIZE Set common page size to SIZE\n")); fprintf (file, _("\ -- 2.37.3 ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 1/2] refactor usage of compressed_debug_section_type 2022-10-03 7:50 ` [PATCH 1/2] refactor usage of compressed_debug_section_type Martin Liška @ 2022-10-11 7:14 ` Martin Liška 2022-10-11 12:06 ` Nick Clifton 0 siblings, 1 reply; 32+ messages in thread From: Martin Liška @ 2022-10-11 7:14 UTC (permalink / raw) To: binutils; +Cc: Fangrui Song PING^1 On 10/3/22 09:50, Martin Liška wrote: > bfd/ChangeLog: > > * bfd-in.h (bfd_hash_set_default_size): Add COMPRESS_UNKNOWN > enum value. > (struct compressed_type_tuple): New. > * bfd-in2.h (bfd_hash_set_default_size): Regenerate. > (struct compressed_type_tuple): Likewise. > * libbfd.c (ARRAY_SIZE): New macro. > (bfd_get_compression_algorithm): New function. > (bfd_get_compression_algorithm_name): Likewise. > > gas/ChangeLog: > > * as.c: Do not special-case, use the new functions. > > ld/ChangeLog: > > * emultempl/elf.em: Do not special-case, use the new functions. > * lexsup.c (elf_static_list_options): Likewise. > --- > bfd/bfd-in.h | 20 +++++++++++++++++--- > bfd/bfd-in2.h | 20 +++++++++++++++++--- > bfd/libbfd.c | 36 ++++++++++++++++++++++++++++++++++++ > gas/as.c | 34 +++++++++------------------------- > ld/emultempl/elf.em | 22 +++++++--------------- > ld/lexsup.c | 8 ++------ > 6 files changed, 88 insertions(+), 52 deletions(-) > > diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h > index 4765ea80536..82e33d400f3 100644 > --- a/bfd/bfd-in.h > +++ b/bfd/bfd-in.h > @@ -335,15 +335,23 @@ extern void bfd_hash_traverse > this size. */ > extern unsigned long bfd_hash_set_default_size (unsigned long); > > -/* Types of compressed DWARF debug sections. We currently support > - zlib. */ > +/* Types of compressed DWARF debug sections. */ > 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_ZSTD = COMPRESS_DEBUG | 1 << 3 > + COMPRESS_DEBUG_ZSTD = COMPRESS_DEBUG | 1 << 3, > + COMPRESS_UNKNOWN = 1 << 4 > +}; > + > +/* Tuple for compressed_debug_section_type and their name. */ > + > +struct compressed_type_tuple > +{ > + enum compressed_debug_section_type type; > + const char *name; > }; > > /* This structure is used to keep track of stabs in sections > @@ -456,6 +464,12 @@ extern void bfd_free_window > (bfd_window *); > extern bool bfd_get_file_window > (bfd *, file_ptr, bfd_size_type, bfd_window *, bool); > + > + > +extern enum compressed_debug_section_type bfd_get_compression_algorithm > + (const char *); > +extern const char *bfd_get_compression_algorithm_name > + (enum compressed_debug_section_type); > \f > /* Externally visible ELF routines. */ > > diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h > index 5c80956c79c..39f925362e0 100644 > --- a/bfd/bfd-in2.h > +++ b/bfd/bfd-in2.h > @@ -342,15 +342,23 @@ extern void bfd_hash_traverse > this size. */ > extern unsigned long bfd_hash_set_default_size (unsigned long); > > -/* Types of compressed DWARF debug sections. We currently support > - zlib. */ > +/* Types of compressed DWARF debug sections. */ > 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_ZSTD = COMPRESS_DEBUG | 1 << 3 > + COMPRESS_DEBUG_ZSTD = COMPRESS_DEBUG | 1 << 3, > + COMPRESS_UNKNOWN = 1 << 4 > +}; > + > +/* Tuple for compressed_debug_section_type and their name. */ > + > +struct compressed_type_tuple > +{ > + enum compressed_debug_section_type type; > + const char *name; > }; > > /* This structure is used to keep track of stabs in sections > @@ -463,6 +471,12 @@ extern void bfd_free_window > (bfd_window *); > extern bool bfd_get_file_window > (bfd *, file_ptr, bfd_size_type, bfd_window *, bool); > + > + > +extern enum compressed_debug_section_type bfd_get_compression_algorithm > + (const char *); > +extern const char *bfd_get_compression_algorithm_name > + (enum compressed_debug_section_type); > \f > /* Externally visible ELF routines. */ > > diff --git a/bfd/libbfd.c b/bfd/libbfd.c > index d33f3416206..14e7d8ef34f 100644 > --- a/bfd/libbfd.c > +++ b/bfd/libbfd.c > @@ -1244,3 +1244,39 @@ _bfd_generic_init_private_section_data (bfd *ibfd ATTRIBUTE_UNUSED, > { > return true; > } > + > +/* Display texts for type of compressed DWARF debug sections. */ > +static const struct compressed_type_tuple compressed_debug_section_names[] = > +{ > + { COMPRESS_DEBUG_NONE, "none" }, > + { COMPRESS_DEBUG, "zlib" }, > + { COMPRESS_DEBUG_GNU_ZLIB, "zlib-gnu" }, > + { COMPRESS_DEBUG_GABI_ZLIB, "zlib-gabi" }, > + { COMPRESS_DEBUG_ZSTD, "zstd" }, > +}; > + > +#ifndef ARRAY_SIZE > +#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0])) > +#endif > + > +/* Return compressed_debug_section_type from a string representation. */ > +enum compressed_debug_section_type > +bfd_get_compression_algorithm (const char *name) > +{ > + for (unsigned i = 0; i < ARRAY_SIZE (compressed_debug_section_names); ++i) > + if (strcasecmp (compressed_debug_section_names[i].name, name) == 0) > + return compressed_debug_section_names[i].type; > + > + return COMPRESS_UNKNOWN; > +} > + > +/* Return compression algorithm name based on the type. */ > +const char * > +bfd_get_compression_algorithm_name (enum compressed_debug_section_type type) > +{ > + for (unsigned i = 0; i < ARRAY_SIZE (compressed_debug_section_names); ++i) > + if (type == compressed_debug_section_names[i].type) > + return compressed_debug_section_names[i].name; > + > + return NULL; > +} > diff --git a/gas/as.c b/gas/as.c > index 9ce3d622f95..a5c2d2459f7 100644 > --- a/gas/as.c > +++ b/gas/as.c > @@ -250,21 +250,16 @@ Options:\n\ > > fprintf (stream, _("\ > --alternate initially turn on alternate macro syntax\n")); > -#ifdef DEFAULT_FLAG_COMPRESS_DEBUG > fprintf (stream, _("\ > --compress-debug-sections[={none|zlib|zlib-gnu|zlib-gabi|zstd}]\n\ > - compress DWARF debug sections using zlib [default]\n")); > + compress DWARF debug sections\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|zstd}]\n\ > - compress DWARF debug sections using zlib\n")); > + Default: %s\n"), > + bfd_get_compression_algorithm_name (flag_compress_debug)); > + > fprintf (stream, _("\ > --nocompress-debug-sections\n\ > - don't compress DWARF debug sections [default]\n")); > -#endif > + don't compress DWARF debug sections\n")); > fprintf (stream, _("\ > -D produce assembler debugging messages\n")); > fprintf (stream, _("\ > @@ -741,24 +736,13 @@ This program has absolutely no warranty.\n")); > if (optarg) > { > #if defined OBJ_ELF || defined OBJ_MAYBE_ELF > - if (strcasecmp (optarg, "none") == 0) > - flag_compress_debug = COMPRESS_DEBUG_NONE; > - else if (strcasecmp (optarg, "zlib") == 0) > - flag_compress_debug = COMPRESS_DEBUG_GABI_ZLIB; > - else if (strcasecmp (optarg, "zlib-gnu") == 0) > - 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 > + flag_compress_debug = bfd_get_compression_algorithm (optarg); > +#ifndef HAVE_ZSTD > + if (flag_compress_debug == COMPRESS_DEBUG_ZSTD) > as_fatal (_ ("--compress-debug-sections=zstd: gas is not " > "built with zstd support")); > #endif > - } > - else > + if (flag_compress_debug == COMPRESS_UNKNOWN) > as_fatal (_("Invalid --compress-debug-sections option: `%s'"), > optarg); > #else > diff --git a/ld/emultempl/elf.em b/ld/emultempl/elf.em > index acd66f907d1..5dfc03a740c 100644 > --- a/ld/emultempl/elf.em > +++ b/ld/emultempl/elf.em > @@ -660,24 +660,16 @@ gld${EMULATION_NAME}_handle_option (int optc) > break; > > case OPTION_COMPRESS_DEBUG: > - if (strcasecmp (optarg, "none") == 0) > - link_info.compress_debug = COMPRESS_DEBUG_NONE; > - else if (strcasecmp (optarg, "zlib") == 0) > - link_info.compress_debug = COMPRESS_DEBUG_GABI_ZLIB; > - else if (strcasecmp (optarg, "zlib-gnu") == 0) > - 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) > + link_info.compress_debug = bfd_get_compression_algorithm (optarg); > + 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")); > +#ifndef HAVE_ZSTD > + if (link_info.compress_debug == COMPRESS_DEBUG_ZSTD) > + einfo (_ ("%F%P: --compress-debug-sections=zstd: ld is not built " > + "with zstd support\n")); > #endif > } > - else > + if (link_info.compress_debug == COMPRESS_UNKNOWN) > einfo (_("%F%P: invalid --compress-debug-sections option: \`%s'\n"), > optarg); > break; > diff --git a/ld/lexsup.c b/ld/lexsup.c > index 299371fb775..0c01c9966e0 100644 > --- a/ld/lexsup.c > +++ b/ld/lexsup.c > @@ -2148,13 +2148,9 @@ elf_static_list_options (FILE *file) > fprintf (file, _("\ > --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")); > -#else > - fprintf (file, _("\ > - Default: none\n")); > -#endif > + Default: %s\n"), > + bfd_get_compression_algorithm_name (link_info.compress_debug)); > fprintf (file, _("\ > -z common-page-size=SIZE Set common page size to SIZE\n")); > fprintf (file, _("\ ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 1/2] refactor usage of compressed_debug_section_type 2022-10-11 7:14 ` Martin Liška @ 2022-10-11 12:06 ` Nick Clifton 2022-10-11 13:27 ` Martin Liška 0 siblings, 1 reply; 32+ messages in thread From: Nick Clifton @ 2022-10-11 12:06 UTC (permalink / raw) To: Martin Liška, binutils; +Cc: Fangrui Song Hi Martin, > PING^1 Sorry! > On 10/3/22 09:50, Martin Liška wrote: >> bfd/ChangeLog: >> >> * bfd-in.h (bfd_hash_set_default_size): Add COMPRESS_UNKNOWN >> enum value. >> (struct compressed_type_tuple): New. >> * bfd-in2.h (bfd_hash_set_default_size): Regenerate. >> (struct compressed_type_tuple): Likewise. >> * libbfd.c (ARRAY_SIZE): New macro. >> (bfd_get_compression_algorithm): New function. >> (bfd_get_compression_algorithm_name): Likewise. >> >> gas/ChangeLog: >> >> * as.c: Do not special-case, use the new functions. >> >> ld/ChangeLog: >> >> * emultempl/elf.em: Do not special-case, use the new functions. >> * lexsup.c (elf_static_list_options): Likewise. Approved - please apply. Cheers Nick ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 1/2] refactor usage of compressed_debug_section_type 2022-10-11 12:06 ` Nick Clifton @ 2022-10-11 13:27 ` Martin Liška 0 siblings, 0 replies; 32+ messages in thread From: Martin Liška @ 2022-10-11 13:27 UTC (permalink / raw) To: Nick Clifton, binutils; +Cc: Fangrui Song [-- Attachment #1: Type: text/plain, Size: 1024 bytes --] On 10/11/22 14:06, Nick Clifton wrote: > Hi Martin, > >> PING^1 > Sorry! > > >> On 10/3/22 09:50, Martin Liška wrote: >>> bfd/ChangeLog: >>> >>> * bfd-in.h (bfd_hash_set_default_size): Add COMPRESS_UNKNOWN >>> enum value. >>> (struct compressed_type_tuple): New. >>> * bfd-in2.h (bfd_hash_set_default_size): Regenerate. >>> (struct compressed_type_tuple): Likewise. >>> * libbfd.c (ARRAY_SIZE): New macro. >>> (bfd_get_compression_algorithm): New function. >>> (bfd_get_compression_algorithm_name): Likewise. >>> >>> gas/ChangeLog: >>> >>> * as.c: Do not special-case, use the new functions. >>> >>> ld/ChangeLog: >>> >>> * emultempl/elf.em: Do not special-case, use the new functions. >>> * lexsup.c (elf_static_list_options): Likewise. > > Approved - please apply. > > Cheers > Nick > > Hello. Thanks, I've installed the patches and noticed the following obvious fix is needed. I'm going to install it. Cheers, Martin [-- Attachment #2: 0001-fix-compressed_debug_section_names-definition-for-zl.patch --] [-- Type: text/x-patch, Size: 903 bytes --] From 735fab23d68d66678eaa19e5751c49091c3bd299 Mon Sep 17 00:00:00 2001 From: Martin Liska <mliska@suse.cz> Date: Tue, 11 Oct 2022 15:25:06 +0200 Subject: [PATCH] fix compressed_debug_section_names definition for "zlib" bfd/ChangeLog: * libbfd.c: Set COMPRESS_DEBUG_GABI_ZLIB for "zlib" value. --- bfd/libbfd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bfd/libbfd.c b/bfd/libbfd.c index 14e7d8ef34f..3090e0ae64b 100644 --- a/bfd/libbfd.c +++ b/bfd/libbfd.c @@ -1249,7 +1249,7 @@ _bfd_generic_init_private_section_data (bfd *ibfd ATTRIBUTE_UNUSED, static const struct compressed_type_tuple compressed_debug_section_names[] = { { COMPRESS_DEBUG_NONE, "none" }, - { COMPRESS_DEBUG, "zlib" }, + { COMPRESS_DEBUG_GABI_ZLIB, "zlib" }, { COMPRESS_DEBUG_GNU_ZLIB, "zlib-gnu" }, { COMPRESS_DEBUG_GABI_ZLIB, "zlib-gabi" }, { COMPRESS_DEBUG_ZSTD, "zstd" }, -- 2.37.3 ^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH 2/2] add --enable-default-compressed-debug-sections-algorithm configure option 2022-10-03 7:49 ` Martin Liška 2022-10-03 7:50 ` [PATCH 1/2] refactor usage of compressed_debug_section_type Martin Liška @ 2022-10-03 7:50 ` Martin Liška 2022-10-11 7:14 ` Martin Liška 1 sibling, 1 reply; 32+ messages in thread From: Martin Liška @ 2022-10-03 7:50 UTC (permalink / raw) To: binutils; +Cc: Fangrui Song ChangeLog: * configure.ac: Add --enable-default-compressed-debug-sections-algorithm. * configure: Regenerate. gas/ChangeLog: * NEWS: Document the new option. * as.c (flag_compress_debug): Set default algorithm based on the configure option. * configure.ac: Add --enable-default-compressed-debug-sections-algorithm. * configure: Regenerate. * config.in: Likewise. ld/ChangeLog: * NEWS: Document the new option. * configure.ac: Add --enable-default-compressed-debug-sections-algorithm. * configure: Regenerate. * config.in: Likewise. * ldmain.c: Set default algorithm based on the configure option. --- configure | 13 +++++++++++++ configure.ac | 6 ++++++ gas/NEWS | 3 +++ gas/as.c | 2 +- gas/config.in | 3 +++ gas/configure | 23 +++++++++++++++++++++-- gas/configure.ac | 12 ++++++++++++ ld/NEWS | 3 +++ ld/config.in | 3 +++ ld/configure | 23 +++++++++++++++++++++-- ld/configure.ac | 12 ++++++++++++ ld/ldmain.c | 2 +- 12 files changed, 99 insertions(+), 6 deletions(-) diff --git a/configure b/configure index f14e0efd675..a430e625c75 100755 --- a/configure +++ b/configure @@ -792,6 +792,7 @@ enable_gold enable_ld enable_gprofng enable_compressed_debug_sections +enable_default_compressed_debug_sections_algorithm enable_year2038 enable_libquadmath enable_libquadmath_support @@ -1523,6 +1524,9 @@ Optional Features: --enable-compressed-debug-sections={all,gas,gold,ld,none} Enable compressed debug sections for gas, gold or ld by default + --enable-default-compressed-debug-sections-algorithm={zlib,zstd} + Default compression algorithm for + --enable-compressed-debug-sections. --enable-year2038 enable support for timestamps past the year 2038 --disable-libquadmath do not build libquadmath directory --disable-libquadmath-support @@ -3119,6 +3123,15 @@ else fi +# Select default compression algorithm. +# Check whether --enable-default_compressed_debug_sections_algorithm was given. +if test "${enable_default_compressed_debug_sections_algorithm+set}" = set; then : + enableval=$enable_default_compressed_debug_sections_algorithm; +else + default_compressed_debug_sections_algorithm= +fi + + # Configure extra directories which are host specific case "${host}" in diff --git a/configure.ac b/configure.ac index 0152c69292e..9c4c9e13907 100644 --- a/configure.ac +++ b/configure.ac @@ -422,6 +422,12 @@ AC_ARG_ENABLE(compressed_debug_sections, fi ], [enable_compressed_debug_sections=]) +# Select default compression algorithm. +AC_ARG_ENABLE(default_compressed_debug_sections_algorithm, +[AS_HELP_STRING([--enable-default-compressed-debug-sections-algorithm={zlib,zstd}], + [Default compression algorithm for --enable-compressed-debug-sections.])], +[], [default_compressed_debug_sections_algorithm=]) + # Configure extra directories which are host specific case "${host}" in diff --git a/gas/NEWS b/gas/NEWS index 9a8b726b942..d9043d9d469 100644 --- a/gas/NEWS +++ b/gas/NEWS @@ -2,6 +2,9 @@ * gas now supports --compress-debug-sections=zstd to compress debug sections with zstd. +* Add --enable-default-compressed-debug-sections-algorithm={zlib,zstd} + that selects the default compression algorithm + for --enable-compressed-debug-sections. Changes in 2.39: diff --git a/gas/as.c b/gas/as.c index a5c2d2459f7..d42dd5394b5 100644 --- a/gas/as.c +++ b/gas/as.c @@ -226,7 +226,7 @@ print_version_id (void) #ifdef DEFAULT_FLAG_COMPRESS_DEBUG enum compressed_debug_section_type flag_compress_debug - = COMPRESS_DEBUG_GABI_ZLIB; + = DEFAULT_COMPRESSED_DEBUG_ALGORITHM; #endif static void diff --git a/gas/config.in b/gas/config.in index 0d1668a3eac..232bc350759 100644 --- a/gas/config.in +++ b/gas/config.in @@ -22,6 +22,9 @@ /* Default architecture. */ #undef DEFAULT_ARCH +/* Default compression algorithm for --enable-compressed-debug-sections. */ +#undef DEFAULT_COMPRESSED_DEBUG_ALGORITHM + /* Default CRIS architecture. */ #undef DEFAULT_CRIS_ARCH diff --git a/gas/configure b/gas/configure index 02cded59b6a..cae14c066d2 100755 --- a/gas/configure +++ b/gas/configure @@ -810,6 +810,7 @@ enable_largefile enable_targets enable_checking enable_compressed_debug_sections +enable_default_compressed_debug_sections_algorithm enable_x86_relax_relocations enable_elf_stt_common enable_generate_build_notes @@ -1476,6 +1477,9 @@ Optional Features: --enable-checking enable run-time checks --enable-compressed-debug-sections={all,gas,none} compress debug sections by default + --enable-default-compressed-debug-sections-algorithm={zlib,zstd} + Default compression algorithm for + --enable-compressed-debug-sections. --enable-x86-relax-relocations generate x86 relax relocations by default --enable-elf-stt-common generate ELF common symbols with STT_COMMON type by @@ -10722,7 +10726,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 10725 "configure" +#line 10729 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -10828,7 +10832,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 10831 "configure" +#line 10835 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11502,6 +11506,15 @@ if test "${enable_compressed_debug_sections+set}" = set; then : esac fi +# Select default compression algorithm. +ac_default_compressed_debug_sections_algorithm=COMPRESS_DEBUG_GABI_ZLIB +# Check whether --enable-default_compressed_debug_sections_algorithm was given. +if test "${enable_default_compressed_debug_sections_algorithm+set}" = set; then : + enableval=$enable_default_compressed_debug_sections_algorithm; case "${enableval}" in + zstd) ac_default_compressed_debug_sections_algorithm=COMPRESS_DEBUG_ZSTD ;; +esac +fi + # PR gas/19520 # Decide if x86 assembler should generate relax relocations. ac_default_x86_relax_relocations=unset @@ -12671,6 +12684,12 @@ $as_echo "#define DEFAULT_FLAG_COMPRESS_DEBUG 1" >>confdefs.h fi + +cat >>confdefs.h <<_ACEOF +#define DEFAULT_COMPRESSED_DEBUG_ALGORITHM $ac_default_compressed_debug_sections_algorithm +_ACEOF + + # Turn on all targets if possible if test ${all_targets} = "yes"; then case ${target_cpu_type} in diff --git a/gas/configure.ac b/gas/configure.ac index e6f3298cb3e..feb43399ce8 100644 --- a/gas/configure.ac +++ b/gas/configure.ac @@ -76,6 +76,15 @@ AC_ARG_ENABLE(compressed_debug_sections, *) ac_default_compressed_debug_sections=unset ;; esac])dnl +# Select default compression algorithm. +ac_default_compressed_debug_sections_algorithm=COMPRESS_DEBUG_GABI_ZLIB +AC_ARG_ENABLE(default_compressed_debug_sections_algorithm, + AS_HELP_STRING([--enable-default-compressed-debug-sections-algorithm={zlib,zstd}], + [Default compression algorithm for --enable-compressed-debug-sections.]), +[case "${enableval}" in + zstd) ac_default_compressed_debug_sections_algorithm=COMPRESS_DEBUG_ZSTD ;; +esac])dnl + # PR gas/19520 # Decide if x86 assembler should generate relax relocations. ac_default_x86_relax_relocations=unset @@ -755,6 +764,9 @@ if test x$ac_default_compressed_debug_sections = xyes ; then AC_DEFINE(DEFAULT_FLAG_COMPRESS_DEBUG, 1, [Define if you want compressed debug sections by default.]) fi +AC_DEFINE_UNQUOTED(DEFAULT_COMPRESSED_DEBUG_ALGORITHM, $ac_default_compressed_debug_sections_algorithm, + [Default compression algorithm for --enable-compressed-debug-sections.]) + # Turn on all targets if possible if test ${all_targets} = "yes"; then case ${target_cpu_type} in diff --git a/ld/NEWS b/ld/NEWS index dfe2690d9f2..d7ceb0c68b6 100644 --- a/ld/NEWS +++ b/ld/NEWS @@ -2,6 +2,9 @@ * ld now supports zstd compressed debug sections. The new option --compress-debug-sections=zstd compresses debug sections with zstd. +* Add --enable-default-compressed-debug-sections-algorithm={zlib,zstd} + that selects the default compression algorithm + for --enable-compressed-debug-sections. Changes in 2.39: diff --git a/ld/config.in b/ld/config.in index 3916740eee4..ad0dc6a106c 100644 --- a/ld/config.in +++ b/ld/config.in @@ -7,6 +7,9 @@ #endif #define __CONFIG_H__ 1 +/* Default compression algorithm for --enable-compressed-debug-sections. */ +#undef DEFAULT_COMPRESSED_DEBUG_ALGORITHM + /* Define to 1 if you want to emit gnu hash in the ELF linker by default. */ #undef DEFAULT_EMIT_GNU_HASH diff --git a/ld/configure b/ld/configure index 9dd3ed5f1e7..7906f52aadf 100755 --- a/ld/configure +++ b/ld/configure @@ -841,6 +841,7 @@ with_sysroot enable_gold enable_got enable_compressed_debug_sections +enable_default_compressed_debug_sections_algorithm enable_new_dtags enable_relro enable_textrel_check @@ -1524,6 +1525,9 @@ Optional Features: multigot) --enable-compressed-debug-sections={all,ld,none} compress debug sections by default] + --enable-default-compressed-debug-sections-algorithm={zlib,zstd} + Default compression algorithm for + --enable-compressed-debug-sections. --enable-new-dtags set DT_RUNPATH instead of DT_RPATH by default] --enable-relro enable -z relro in ELF linker by default --enable-textrel-check=[yes|no|warning|error] @@ -11620,7 +11624,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11623 "configure" +#line 11627 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11726,7 +11730,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11729 "configure" +#line 11733 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -15544,6 +15548,15 @@ if test "${enable_compressed_debug_sections+set}" = set; then : esac fi +# Select default compression algorithm. +ac_default_compressed_debug_sections_algorithm=COMPRESS_DEBUG_GABI_ZLIB +# Check whether --enable-default_compressed_debug_sections_algorithm was given. +if test "${enable_default_compressed_debug_sections_algorithm+set}" = set; then : + enableval=$enable_default_compressed_debug_sections_algorithm; case "${enableval}" in + zstd) ac_default_compressed_debug_sections_algorithm=COMPRESS_DEBUG_ZSTD ;; +esac +fi + # Decide setting DT_RUNPATH instead of DT_RPATH by default ac_default_new_dtags=unset # Provide a configure time option to override our default. @@ -17340,6 +17353,12 @@ $as_echo "#define DEFAULT_FLAG_COMPRESS_DEBUG 1" >>confdefs.h fi + +cat >>confdefs.h <<_ACEOF +#define DEFAULT_COMPRESSED_DEBUG_ALGORITHM $ac_default_compressed_debug_sections_algorithm +_ACEOF + + if test "${ac_default_new_dtags}" = unset; then ac_default_new_dtags=0 fi diff --git a/ld/configure.ac b/ld/configure.ac index f1b2f9897f8..6123ea78611 100644 --- a/ld/configure.ac +++ b/ld/configure.ac @@ -163,6 +163,15 @@ AC_ARG_ENABLE(compressed_debug_sections, ,no, | ,none,) ac_default_compressed_debug_sections=no ;; esac])dnl +# Select default compression algorithm. +ac_default_compressed_debug_sections_algorithm=COMPRESS_DEBUG_GABI_ZLIB +AC_ARG_ENABLE(default_compressed_debug_sections_algorithm, + AS_HELP_STRING([--enable-default-compressed-debug-sections-algorithm={zlib,zstd}], + [Default compression algorithm for --enable-compressed-debug-sections.]), +[case "${enableval}" in + zstd) ac_default_compressed_debug_sections_algorithm=COMPRESS_DEBUG_ZSTD ;; +esac])dnl + # Decide setting DT_RUNPATH instead of DT_RPATH by default ac_default_new_dtags=unset # Provide a configure time option to override our default. @@ -510,6 +519,9 @@ if test x$ac_default_compressed_debug_sections = xyes ; then AC_DEFINE(DEFAULT_FLAG_COMPRESS_DEBUG, 1, [Define if you want compressed debug sections by default.]) fi +AC_DEFINE_UNQUOTED(DEFAULT_COMPRESSED_DEBUG_ALGORITHM, $ac_default_compressed_debug_sections_algorithm, + [Default compression algorithm for --enable-compressed-debug-sections.]) + if test "${ac_default_new_dtags}" = unset; then ac_default_new_dtags=0 fi diff --git a/ld/ldmain.c b/ld/ldmain.c index d63002c994a..10f7a0538aa 100644 --- a/ld/ldmain.c +++ b/ld/ldmain.c @@ -352,7 +352,7 @@ main (int argc, char **argv) link_info.spare_dynamic_tags = 5; link_info.path_separator = ':'; #ifdef DEFAULT_FLAG_COMPRESS_DEBUG - link_info.compress_debug = COMPRESS_DEBUG_GABI_ZLIB; + link_info.compress_debug = DEFAULT_COMPRESSED_DEBUG_ALGORITHM; #endif #ifdef DEFAULT_NEW_DTAGS link_info.new_dtags = DEFAULT_NEW_DTAGS; -- 2.37.3 ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 2/2] add --enable-default-compressed-debug-sections-algorithm configure option 2022-10-03 7:50 ` [PATCH 2/2] add --enable-default-compressed-debug-sections-algorithm configure option Martin Liška @ 2022-10-11 7:14 ` Martin Liška 2022-10-11 12:08 ` Nick Clifton 0 siblings, 1 reply; 32+ messages in thread From: Martin Liška @ 2022-10-11 7:14 UTC (permalink / raw) To: binutils; +Cc: Fangrui Song PING^1 On 10/3/22 09:50, Martin Liška wrote: > ChangeLog: > > * configure.ac: Add --enable-default-compressed-debug-sections-algorithm. > * configure: Regenerate. > > gas/ChangeLog: > > * NEWS: Document the new option. > * as.c (flag_compress_debug): Set default algorithm based > on the configure option. > * configure.ac: Add --enable-default-compressed-debug-sections-algorithm. > * configure: Regenerate. > * config.in: Likewise. > > ld/ChangeLog: > > * NEWS: Document the new option. > * configure.ac: Add --enable-default-compressed-debug-sections-algorithm. > * configure: Regenerate. > * config.in: Likewise. > * ldmain.c: Set default algorithm based > on the configure option. > --- > configure | 13 +++++++++++++ > configure.ac | 6 ++++++ > gas/NEWS | 3 +++ > gas/as.c | 2 +- > gas/config.in | 3 +++ > gas/configure | 23 +++++++++++++++++++++-- > gas/configure.ac | 12 ++++++++++++ > ld/NEWS | 3 +++ > ld/config.in | 3 +++ > ld/configure | 23 +++++++++++++++++++++-- > ld/configure.ac | 12 ++++++++++++ > ld/ldmain.c | 2 +- > 12 files changed, 99 insertions(+), 6 deletions(-) > > diff --git a/configure b/configure > index f14e0efd675..a430e625c75 100755 > --- a/configure > +++ b/configure > @@ -792,6 +792,7 @@ enable_gold > enable_ld > enable_gprofng > enable_compressed_debug_sections > +enable_default_compressed_debug_sections_algorithm > enable_year2038 > enable_libquadmath > enable_libquadmath_support > @@ -1523,6 +1524,9 @@ Optional Features: > --enable-compressed-debug-sections={all,gas,gold,ld,none} > Enable compressed debug sections for gas, gold or ld > by default > + --enable-default-compressed-debug-sections-algorithm={zlib,zstd} > + Default compression algorithm for > + --enable-compressed-debug-sections. > --enable-year2038 enable support for timestamps past the year 2038 > --disable-libquadmath do not build libquadmath directory > --disable-libquadmath-support > @@ -3119,6 +3123,15 @@ else > fi > > > +# Select default compression algorithm. > +# Check whether --enable-default_compressed_debug_sections_algorithm was given. > +if test "${enable_default_compressed_debug_sections_algorithm+set}" = set; then : > + enableval=$enable_default_compressed_debug_sections_algorithm; > +else > + default_compressed_debug_sections_algorithm= > +fi > + > + > # Configure extra directories which are host specific > > case "${host}" in > diff --git a/configure.ac b/configure.ac > index 0152c69292e..9c4c9e13907 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -422,6 +422,12 @@ AC_ARG_ENABLE(compressed_debug_sections, > fi > ], [enable_compressed_debug_sections=]) > > +# Select default compression algorithm. > +AC_ARG_ENABLE(default_compressed_debug_sections_algorithm, > +[AS_HELP_STRING([--enable-default-compressed-debug-sections-algorithm={zlib,zstd}], > + [Default compression algorithm for --enable-compressed-debug-sections.])], > +[], [default_compressed_debug_sections_algorithm=]) > + > # Configure extra directories which are host specific > > case "${host}" in > diff --git a/gas/NEWS b/gas/NEWS > index 9a8b726b942..d9043d9d469 100644 > --- a/gas/NEWS > +++ b/gas/NEWS > @@ -2,6 +2,9 @@ > > * gas now supports --compress-debug-sections=zstd to compress > debug sections with zstd. > +* Add --enable-default-compressed-debug-sections-algorithm={zlib,zstd} > + that selects the default compression algorithm > + for --enable-compressed-debug-sections. > > Changes in 2.39: > > diff --git a/gas/as.c b/gas/as.c > index a5c2d2459f7..d42dd5394b5 100644 > --- a/gas/as.c > +++ b/gas/as.c > @@ -226,7 +226,7 @@ print_version_id (void) > > #ifdef DEFAULT_FLAG_COMPRESS_DEBUG > enum compressed_debug_section_type flag_compress_debug > - = COMPRESS_DEBUG_GABI_ZLIB; > + = DEFAULT_COMPRESSED_DEBUG_ALGORITHM; > #endif > > static void > diff --git a/gas/config.in b/gas/config.in > index 0d1668a3eac..232bc350759 100644 > --- a/gas/config.in > +++ b/gas/config.in > @@ -22,6 +22,9 @@ > /* Default architecture. */ > #undef DEFAULT_ARCH > > +/* Default compression algorithm for --enable-compressed-debug-sections. */ > +#undef DEFAULT_COMPRESSED_DEBUG_ALGORITHM > + > /* Default CRIS architecture. */ > #undef DEFAULT_CRIS_ARCH > > diff --git a/gas/configure b/gas/configure > index 02cded59b6a..cae14c066d2 100755 > --- a/gas/configure > +++ b/gas/configure > @@ -810,6 +810,7 @@ enable_largefile > enable_targets > enable_checking > enable_compressed_debug_sections > +enable_default_compressed_debug_sections_algorithm > enable_x86_relax_relocations > enable_elf_stt_common > enable_generate_build_notes > @@ -1476,6 +1477,9 @@ Optional Features: > --enable-checking enable run-time checks > --enable-compressed-debug-sections={all,gas,none} > compress debug sections by default > + --enable-default-compressed-debug-sections-algorithm={zlib,zstd} > + Default compression algorithm for > + --enable-compressed-debug-sections. > --enable-x86-relax-relocations > generate x86 relax relocations by default > --enable-elf-stt-common generate ELF common symbols with STT_COMMON type by > @@ -10722,7 +10726,7 @@ else > lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 > lt_status=$lt_dlunknown > cat > conftest.$ac_ext <<_LT_EOF > -#line 10725 "configure" > +#line 10729 "configure" > #include "confdefs.h" > > #if HAVE_DLFCN_H > @@ -10828,7 +10832,7 @@ else > lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 > lt_status=$lt_dlunknown > cat > conftest.$ac_ext <<_LT_EOF > -#line 10831 "configure" > +#line 10835 "configure" > #include "confdefs.h" > > #if HAVE_DLFCN_H > @@ -11502,6 +11506,15 @@ if test "${enable_compressed_debug_sections+set}" = set; then : > esac > fi > > +# Select default compression algorithm. > +ac_default_compressed_debug_sections_algorithm=COMPRESS_DEBUG_GABI_ZLIB > +# Check whether --enable-default_compressed_debug_sections_algorithm was given. > +if test "${enable_default_compressed_debug_sections_algorithm+set}" = set; then : > + enableval=$enable_default_compressed_debug_sections_algorithm; case "${enableval}" in > + zstd) ac_default_compressed_debug_sections_algorithm=COMPRESS_DEBUG_ZSTD ;; > +esac > +fi > + > # PR gas/19520 > # Decide if x86 assembler should generate relax relocations. > ac_default_x86_relax_relocations=unset > @@ -12671,6 +12684,12 @@ $as_echo "#define DEFAULT_FLAG_COMPRESS_DEBUG 1" >>confdefs.h > > fi > > + > +cat >>confdefs.h <<_ACEOF > +#define DEFAULT_COMPRESSED_DEBUG_ALGORITHM $ac_default_compressed_debug_sections_algorithm > +_ACEOF > + > + > # Turn on all targets if possible > if test ${all_targets} = "yes"; then > case ${target_cpu_type} in > diff --git a/gas/configure.ac b/gas/configure.ac > index e6f3298cb3e..feb43399ce8 100644 > --- a/gas/configure.ac > +++ b/gas/configure.ac > @@ -76,6 +76,15 @@ AC_ARG_ENABLE(compressed_debug_sections, > *) ac_default_compressed_debug_sections=unset ;; > esac])dnl > > +# Select default compression algorithm. > +ac_default_compressed_debug_sections_algorithm=COMPRESS_DEBUG_GABI_ZLIB > +AC_ARG_ENABLE(default_compressed_debug_sections_algorithm, > + AS_HELP_STRING([--enable-default-compressed-debug-sections-algorithm={zlib,zstd}], > + [Default compression algorithm for --enable-compressed-debug-sections.]), > +[case "${enableval}" in > + zstd) ac_default_compressed_debug_sections_algorithm=COMPRESS_DEBUG_ZSTD ;; > +esac])dnl > + > # PR gas/19520 > # Decide if x86 assembler should generate relax relocations. > ac_default_x86_relax_relocations=unset > @@ -755,6 +764,9 @@ if test x$ac_default_compressed_debug_sections = xyes ; then > AC_DEFINE(DEFAULT_FLAG_COMPRESS_DEBUG, 1, [Define if you want compressed debug sections by default.]) > fi > > +AC_DEFINE_UNQUOTED(DEFAULT_COMPRESSED_DEBUG_ALGORITHM, $ac_default_compressed_debug_sections_algorithm, > + [Default compression algorithm for --enable-compressed-debug-sections.]) > + > # Turn on all targets if possible > if test ${all_targets} = "yes"; then > case ${target_cpu_type} in > diff --git a/ld/NEWS b/ld/NEWS > index dfe2690d9f2..d7ceb0c68b6 100644 > --- a/ld/NEWS > +++ b/ld/NEWS > @@ -2,6 +2,9 @@ > > * ld now supports zstd compressed debug sections. The new option > --compress-debug-sections=zstd compresses debug sections with zstd. > +* Add --enable-default-compressed-debug-sections-algorithm={zlib,zstd} > + that selects the default compression algorithm > + for --enable-compressed-debug-sections. > > Changes in 2.39: > > diff --git a/ld/config.in b/ld/config.in > index 3916740eee4..ad0dc6a106c 100644 > --- a/ld/config.in > +++ b/ld/config.in > @@ -7,6 +7,9 @@ > #endif > #define __CONFIG_H__ 1 > > +/* Default compression algorithm for --enable-compressed-debug-sections. */ > +#undef DEFAULT_COMPRESSED_DEBUG_ALGORITHM > + > /* Define to 1 if you want to emit gnu hash in the ELF linker by default. */ > #undef DEFAULT_EMIT_GNU_HASH > > diff --git a/ld/configure b/ld/configure > index 9dd3ed5f1e7..7906f52aadf 100755 > --- a/ld/configure > +++ b/ld/configure > @@ -841,6 +841,7 @@ with_sysroot > enable_gold > enable_got > enable_compressed_debug_sections > +enable_default_compressed_debug_sections_algorithm > enable_new_dtags > enable_relro > enable_textrel_check > @@ -1524,6 +1525,9 @@ Optional Features: > multigot) > --enable-compressed-debug-sections={all,ld,none} > compress debug sections by default] > + --enable-default-compressed-debug-sections-algorithm={zlib,zstd} > + Default compression algorithm for > + --enable-compressed-debug-sections. > --enable-new-dtags set DT_RUNPATH instead of DT_RPATH by default] > --enable-relro enable -z relro in ELF linker by default > --enable-textrel-check=[yes|no|warning|error] > @@ -11620,7 +11624,7 @@ else > lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 > lt_status=$lt_dlunknown > cat > conftest.$ac_ext <<_LT_EOF > -#line 11623 "configure" > +#line 11627 "configure" > #include "confdefs.h" > > #if HAVE_DLFCN_H > @@ -11726,7 +11730,7 @@ else > lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 > lt_status=$lt_dlunknown > cat > conftest.$ac_ext <<_LT_EOF > -#line 11729 "configure" > +#line 11733 "configure" > #include "confdefs.h" > > #if HAVE_DLFCN_H > @@ -15544,6 +15548,15 @@ if test "${enable_compressed_debug_sections+set}" = set; then : > esac > fi > > +# Select default compression algorithm. > +ac_default_compressed_debug_sections_algorithm=COMPRESS_DEBUG_GABI_ZLIB > +# Check whether --enable-default_compressed_debug_sections_algorithm was given. > +if test "${enable_default_compressed_debug_sections_algorithm+set}" = set; then : > + enableval=$enable_default_compressed_debug_sections_algorithm; case "${enableval}" in > + zstd) ac_default_compressed_debug_sections_algorithm=COMPRESS_DEBUG_ZSTD ;; > +esac > +fi > + > # Decide setting DT_RUNPATH instead of DT_RPATH by default > ac_default_new_dtags=unset > # Provide a configure time option to override our default. > @@ -17340,6 +17353,12 @@ $as_echo "#define DEFAULT_FLAG_COMPRESS_DEBUG 1" >>confdefs.h > > fi > > + > +cat >>confdefs.h <<_ACEOF > +#define DEFAULT_COMPRESSED_DEBUG_ALGORITHM $ac_default_compressed_debug_sections_algorithm > +_ACEOF > + > + > if test "${ac_default_new_dtags}" = unset; then > ac_default_new_dtags=0 > fi > diff --git a/ld/configure.ac b/ld/configure.ac > index f1b2f9897f8..6123ea78611 100644 > --- a/ld/configure.ac > +++ b/ld/configure.ac > @@ -163,6 +163,15 @@ AC_ARG_ENABLE(compressed_debug_sections, > ,no, | ,none,) ac_default_compressed_debug_sections=no ;; > esac])dnl > > +# Select default compression algorithm. > +ac_default_compressed_debug_sections_algorithm=COMPRESS_DEBUG_GABI_ZLIB > +AC_ARG_ENABLE(default_compressed_debug_sections_algorithm, > + AS_HELP_STRING([--enable-default-compressed-debug-sections-algorithm={zlib,zstd}], > + [Default compression algorithm for --enable-compressed-debug-sections.]), > +[case "${enableval}" in > + zstd) ac_default_compressed_debug_sections_algorithm=COMPRESS_DEBUG_ZSTD ;; > +esac])dnl > + > # Decide setting DT_RUNPATH instead of DT_RPATH by default > ac_default_new_dtags=unset > # Provide a configure time option to override our default. > @@ -510,6 +519,9 @@ if test x$ac_default_compressed_debug_sections = xyes ; then > AC_DEFINE(DEFAULT_FLAG_COMPRESS_DEBUG, 1, [Define if you want compressed debug sections by default.]) > fi > > +AC_DEFINE_UNQUOTED(DEFAULT_COMPRESSED_DEBUG_ALGORITHM, $ac_default_compressed_debug_sections_algorithm, > + [Default compression algorithm for --enable-compressed-debug-sections.]) > + > if test "${ac_default_new_dtags}" = unset; then > ac_default_new_dtags=0 > fi > diff --git a/ld/ldmain.c b/ld/ldmain.c > index d63002c994a..10f7a0538aa 100644 > --- a/ld/ldmain.c > +++ b/ld/ldmain.c > @@ -352,7 +352,7 @@ main (int argc, char **argv) > link_info.spare_dynamic_tags = 5; > link_info.path_separator = ':'; > #ifdef DEFAULT_FLAG_COMPRESS_DEBUG > - link_info.compress_debug = COMPRESS_DEBUG_GABI_ZLIB; > + link_info.compress_debug = DEFAULT_COMPRESSED_DEBUG_ALGORITHM; > #endif > #ifdef DEFAULT_NEW_DTAGS > link_info.new_dtags = DEFAULT_NEW_DTAGS; ^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 2/2] add --enable-default-compressed-debug-sections-algorithm configure option 2022-10-11 7:14 ` Martin Liška @ 2022-10-11 12:08 ` Nick Clifton 0 siblings, 0 replies; 32+ messages in thread From: Nick Clifton @ 2022-10-11 12:08 UTC (permalink / raw) To: Martin Liška, binutils; +Cc: Fangrui Song Hi Martin, > PING^1 Sorry! > On 10/3/22 09:50, Martin Liška wrote: >> ChangeLog: >> >> * configure.ac: Add --enable-default-compressed-debug-sections-algorithm. >> * configure: Regenerate. >> >> gas/ChangeLog: >> >> * NEWS: Document the new option. >> * as.c (flag_compress_debug): Set default algorithm based >> on the configure option. >> * configure.ac: Add --enable-default-compressed-debug-sections-algorithm. >> * configure: Regenerate. >> * config.in: Likewise. >> >> ld/ChangeLog: >> >> * NEWS: Document the new option. >> * configure.ac: Add --enable-default-compressed-debug-sections-algorithm. >> * configure: Regenerate. >> * config.in: Likewise. >> * ldmain.c: Set default algorithm based >> on the configure option. Approved - please apply. Cheers Nick ^ permalink raw reply [flat|nested] 32+ messages in thread
end of thread, other threads:[~2022-10-11 13:27 UTC | newest] Thread overview: 32+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2022-09-23 4:08 [PATCH v3] binutils, gdb: support zstd compressed debug sections Fangrui Song 2022-09-23 14:32 ` Simon Marchi 2022-09-26 5:12 ` Alan Modra 2022-09-26 7:20 ` Fangrui Song 2022-09-26 13:30 ` Alan Modra 2022-09-26 14:08 ` Simon Marchi 2022-09-27 0:33 ` Alan Modra 2022-09-23 15:45 ` Nick Clifton 2022-09-23 15:58 ` Simon Marchi 2022-09-23 18:20 ` Fangrui Song 2022-09-23 18:57 ` Simon Marchi 2022-09-23 20:34 ` Fangrui Song 2022-09-24 5:43 ` Eli Zaretskii 2022-09-24 6:53 ` Enze Li 2022-09-24 7:13 ` Fangrui Song 2022-09-27 18:06 ` Tom Tromey 2022-09-27 18:08 ` Tom Tromey 2022-09-27 18:53 ` Fangrui Song 2022-09-29 11:43 ` Martin Liška 2022-09-29 20:17 ` Fangrui Song 2022-09-30 9:48 ` [PATCH][RFC] add --enable-zstd-compressed-debug-sections configure option Martin Liška 2022-09-30 11:25 ` Pedro Alves 2022-09-30 12:42 ` Martin Liška 2022-10-01 7:31 ` Fangrui Song 2022-10-03 7:49 ` Martin Liška 2022-10-03 7:50 ` [PATCH 1/2] refactor usage of compressed_debug_section_type Martin Liška 2022-10-11 7:14 ` Martin Liška 2022-10-11 12:06 ` Nick Clifton 2022-10-11 13:27 ` Martin Liška 2022-10-03 7:50 ` [PATCH 2/2] add --enable-default-compressed-debug-sections-algorithm configure option Martin Liška 2022-10-11 7:14 ` Martin Liška 2022-10-11 12:08 ` Nick Clifton
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).