diff options
author | Fangrui Song <maskray@google.com> | 2022-09-26 19:50:13 -0700 |
---|---|---|
committer | Fangrui Song <i@maskray.me> | 2022-09-26 19:50:13 -0700 |
commit | 2cac01e3ffff74898c54fa5e6418817f5578adb6 (patch) | |
tree | c0209ba03d922dae339056488493fc16ebefe6d0 /gas/write.c | |
parent | e122316b7ce78b999db944d7b524e11d642e2a49 (diff) | |
download | fsf-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/write.c')
-rw-r--r-- | gas/write.c | 36 |
1 files changed, 19 insertions, 17 deletions
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); |