summaryrefslogtreecommitdiff
path: root/ld
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 /ld
parente122316b7ce78b999db944d7b524e11d642e2a49 (diff)
downloadbinutils-gdb-2cac01e3ffff74898c54fa5e6418817f5578adb6.tar.gz
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 'ld')
-rw-r--r--ld/Makefile.am5
-rw-r--r--ld/Makefile.in11
-rw-r--r--ld/NEWS3
-rw-r--r--ld/aclocal.m41
-rw-r--r--ld/config.in3
-rwxr-xr-xld/configure390
-rw-r--r--ld/configure.ac6
-rw-r--r--ld/emultempl/elf.em9
-rw-r--r--ld/ld.texi5
-rw-r--r--ld/ldmain.c8
-rw-r--r--ld/lexsup.c4
-rw-r--r--ld/testsuite/ld-bootstrap/bootstrap.exp4
-rw-r--r--ld/testsuite/ld-elf/compress.exp16
13 files changed, 324 insertions, 141 deletions
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..9dd3ed5f1e7 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 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 8a8bfc9a14e..f1b2f9897f8 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
+AC_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 e676c3786a2..d63002c994a 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-bootstrap/bootstrap.exp b/ld/testsuite/ld-bootstrap/bootstrap.exp
index 52a91fc554e..99a11090ee7 100644
--- a/ld/testsuite/ld-bootstrap/bootstrap.exp
+++ b/ld/testsuite/ld-bootstrap/bootstrap.exp
@@ -161,6 +161,10 @@ foreach flags $test_flags {
set extralibs "$extralibs -lz"
}
+ if { [lindex [remote_exec build grep "-q \"HAVE_ZSTD 1\" config.h" ] 0] == 0 } then {
+ set extralibs "$extralibs -lzstd"
+ }
+
# Check if the system's jansson library is used. If so, the object files will
# be using symbols from it, so link to it.
if { [lindex [remote_exec build grep "-q \"HAVE_JANSSON 1\" config.h" ] 0] == 0 } then {
diff --git a/ld/testsuite/ld-elf/compress.exp b/ld/testsuite/ld-elf/compress.exp
index cfdd767b8ab..28a848619bf 100644
--- a/ld/testsuite/ld-elf/compress.exp
+++ b/ld/testsuite/ld-elf/compress.exp
@@ -254,3 +254,19 @@ if { [regexp_diff tmpdir/$test.out $srcdir/$subdir/$test.rt] } then {
} else {
pass "$test_name"
}
+
+if { [ld_assemble $as "--compress-debug-sections=zstd $srcdir/$subdir/empty.s" tmpdir/emptyzstd.o ] } {
+ set build_tests {
+ {"Build libzstdfoo.so with zstd compressed debug sections"
+ "-shared" "-fPIC -g -Wa,--compress-debug-sections=zstd -Wl,--compress-debug-sections=zstd"
+ {foo.c} {} "libzstdfoo.so"}
+ }
+ set run_tests {
+ {"Run zstdnormal with libzstdfoo.so with zstd compressed debug sections"
+ "tmpdir/begin.o tmpdir/libzstdfoo.so tmpdir/end.o -Wl,--compress-debug-sections=zstd" ""
+ {main.c} "zstdnormal" "normal.out" "-Wa,--compress-debug-sections=zstd"}
+ }
+
+ run_cc_link_tests $build_tests
+ run_ld_link_exec_tests $run_tests
+}