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/compress-debug.c | |
parent | e122316b7ce78b999db944d7b524e11d642e2a49 (diff) | |
download | gdb-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/compress-debug.c')
-rw-r--r-- | gas/compress-debug.c | 60 |
1 files changed, 51 insertions, 9 deletions
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); |