aboutsummaryrefslogtreecommitdiff
path: root/binutils
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 /binutils
parente122316b7ce78b999db944d7b524e11d642e2a49 (diff)
downloadgdb-2cac01e3ffff74898c54fa5e6418817f5578adb6.zip
gdb-2cac01e3ffff74898c54fa5e6418817f5578adb6.tar.gz
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 'binutils')
-rw-r--r--binutils/Makefile.in5
-rw-r--r--binutils/NEWS6
-rw-r--r--binutils/aclocal.m41
-rw-r--r--binutils/config.in3
-rwxr-xr-xbinutils/configure136
-rw-r--r--binutils/configure.ac3
-rw-r--r--binutils/doc/binutils.texi16
-rw-r--r--binutils/objcopy.c19
-rw-r--r--binutils/testsuite/binutils-all/compress.exp44
9 files changed, 217 insertions, 16 deletions
diff --git a/binutils/Makefile.in b/binutils/Makefile.in
index 78d32b3..6de4e23 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 8c2c416..83c73d0 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 a877fa7..28271f5 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 c5fb919..bee8c07 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 4c0c391..0d6bde7 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 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 0798d84..9b75396 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
+AC_ZSTD
BFD_BINARY_FOPEN
diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi
index 1499db5..34a4164 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 4326175..fc668f0 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 c88da74..4e74c82 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