aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorFangrui Song <maskray@google.com>2022-09-26 19:50:13 -0700
committerFangrui Song <i@maskray.me>2022-09-26 19:50:13 -0700
commit2cac01e3ffff74898c54fa5e6418817f5578adb6 (patch)
treec0209ba03d922dae339056488493fc16ebefe6d0 /gas
parente122316b7ce78b999db944d7b524e11d642e2a49 (diff)
downloadfsf-binutils-gdb-2cac01e3ffff74898c54fa5e6418817f5578adb6.zip
fsf-binutils-gdb-2cac01e3ffff74898c54fa5e6418817f5578adb6.tar.gz
fsf-binutils-gdb-2cac01e3ffff74898c54fa5e6418817f5578adb6.tar.bz2
binutils, gdb: support zstd compressed debug sections
PR29397 PR29563: Add new configure option --with-zstd which defaults to auto. If pkgconfig/libzstd.pc is found, define HAVE_ZSTD and support zstd compressed debug sections for most tools. * bfd: for addr2line, objdump --dwarf, gdb, etc * gas: support --compress-debug-sections=zstd * ld: support ELFCOMPRESS_ZSTD input and --compress-debug-sections=zstd * objcopy: support ELFCOMPRESS_ZSTD input for --decompress-debug-sections and --compress-debug-sections=zstd * gdb: support ELFCOMPRESS_ZSTD input. The bfd change references zstd symbols, so gdb has to link against -lzstd in this patch. If zstd is not supported, ELFCOMPRESS_ZSTD input triggers an error. We can avoid HAVE_ZSTD if binutils-gdb imports zstd/ like zlib/, but this is too heavyweight, so don't do it for now. ``` % ld/ld-new a.o ld/ld-new: a.o: section .debug_abbrev is compressed with zstd, but BFD is not built with zstd support ... % ld/ld-new a.o --compress-debug-sections=zstd ld/ld-new: --compress-debug-sections=zstd: ld is not built with zstd support % binutils/objcopy --compress-debug-sections=zstd a.o b.o binutils/objcopy: --compress-debug-sections=zstd: binutils is not built with zstd support % binutils/objcopy b.o --decompress-debug-sections binutils/objcopy: zstd.o: section .debug_abbrev is compressed with zstd, but BFD is not built with zstd support ... ```
Diffstat (limited to 'gas')
-rw-r--r--gas/Makefile.am4
-rw-r--r--gas/Makefile.in13
-rw-r--r--gas/NEWS3
-rw-r--r--gas/aclocal.m42
-rw-r--r--gas/as.c13
-rw-r--r--gas/compress-debug.c60
-rw-r--r--gas/compress-debug.h10
-rw-r--r--gas/config.in3
-rwxr-xr-xgas/configure269
-rw-r--r--gas/configure.ac3
-rw-r--r--gas/doc/as.texi11
-rw-r--r--gas/write.c36
12 files changed, 380 insertions, 47 deletions
diff --git a/gas/Makefile.am b/gas/Makefile.am
index bd59739..5f0f24a 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 c57d78f..5a4dd70 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 d61cdb9..9a8b726 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 7018312..722030c 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 6268779..35ad6b3 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 c80dbee..3cd175f 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 0183e26..87de0f8 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 e243fd2..0d1668a 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 d0449a1..02cded5 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 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 21795a8..e6f3298 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
+AC_ZSTD
# Support for VMS timestamps via cross compile
diff --git a/gas/doc/as.texi b/gas/doc/as.texi
index e915893..01f4943 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 f76bbdb..0e49df7 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,20 +1484,21 @@ compress_debug (bfd *abfd, asection *sec, void *xxx ATTRIBUTE_UNUSED)
if (!startswith (section_name, ".debug_"))
return;
- strm = compress_init ();
- if (strm == NULL)
+ bool use_zstd = abfd->flags & BFD_COMPRESS_ZSTD;
+ void *ctx = compress_init (use_zstd);
+ if (ctx == NULL)
return;
- if (flag_compress_debug == COMPRESS_DEBUG_GABI_ZLIB)
+ if (flag_compress_debug == COMPRESS_DEBUG_GNU_ZLIB)
{
- compression_header_size
- = bfd_get_compression_header_size (stdoutput, NULL);
- header_size = compression_header_size;
+ compression_header_size = 0;
+ header_size = 12;
}
else
{
- compression_header_size = 0;
- header_size = 12;
+ compression_header_size
+ = bfd_get_compression_header_size (stdoutput, NULL);
+ header_size = compression_header_size;
}
/* Create a new frag to contain the compression header. */
@@ -1531,7 +1531,7 @@ compress_debug (bfd *abfd, asection *sec, void *xxx ATTRIBUTE_UNUSED)
gas_assert (f->fr_type == rs_fill);
if (f->fr_fix)
{
- out_size = compress_frag (strm, f->fr_literal, f->fr_fix,
+ out_size = compress_frag (use_zstd, ctx, f->fr_literal, f->fr_fix,
&last_newf, ob);
if (out_size < 0)
return;
@@ -1545,8 +1545,8 @@ compress_debug (bfd *abfd, asection *sec, void *xxx ATTRIBUTE_UNUSED)
{
while (count--)
{
- out_size = compress_frag (strm, fill_literal, (int) fill_size,
- &last_newf, ob);
+ out_size = compress_frag (use_zstd, ctx, fill_literal,
+ (int)fill_size, &last_newf, ob);
if (out_size < 0)
return;
compressed_size += out_size;
@@ -1579,7 +1579,7 @@ compress_debug (bfd *abfd, asection *sec, void *xxx ATTRIBUTE_UNUSED)
as_fatal (_("can't extend frag"));
next_out = obstack_next_free (ob);
obstack_blank_fast (ob, avail_out);
- x = compress_finish (strm, &next_out, &avail_out, &out_size);
+ x = compress_finish (use_zstd, ctx, &next_out, &avail_out, &out_size);
if (x < 0)
return;
@@ -2540,6 +2540,8 @@ write_object_file (void)
{
if (flag_compress_debug == COMPRESS_DEBUG_GABI_ZLIB)
stdoutput->flags |= BFD_COMPRESS | BFD_COMPRESS_GABI;
+ else if (flag_compress_debug == COMPRESS_DEBUG_ZSTD)
+ stdoutput->flags |= BFD_COMPRESS | BFD_COMPRESS_GABI | BFD_COMPRESS_ZSTD;
else
stdoutput->flags |= BFD_COMPRESS;
bfd_map_over_sections (stdoutput, compress_debug, (char *) 0);