aboutsummaryrefslogtreecommitdiff
path: root/gas/write.c
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/write.c
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 'gas/write.c')
-rw-r--r--gas/write.c36
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);