From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: <3Oag3YwcKCIgym4w3mAs00sxq.o0ynuz65ux44063oq8m3q.03s@flex--maskray.bounces.google.com> Received: from mail-yb1-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49]) by sourceware.org (Postfix) with ESMTPS id 317DE3858D1E for ; Sat, 1 Oct 2022 02:38:50 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 317DE3858D1E Authentication-Results: sourceware.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=flex--maskray.bounces.google.com Received: by mail-yb1-xb49.google.com with SMTP id v17-20020a259d91000000b006b4c31c0640so5351288ybp.18 for ; Fri, 30 Sep 2022 19:38:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:message-id:mime-version:date:from:to:cc:subject :date; bh=TssL1WRJoCghnG9dgJLS5EqSblTfZ1RaJsaYbT2bnx4=; b=rmkLzoSdSSBt7gzMYlZiBNZE66l2FYiTMwXhzM6CUOBkEay7KhcV4bAm/9xots0XoX 4X4H+cMrqUvOvimPobf4iVSLy3TVZmnUjd3oOuqn8aH3y2WjaTeFWXFd7yOYqVYLfXSR I2nypRtVbAzfgrSwocUt6jOZWEs0QFHwy1cClea6qE9lZin/N3WCDvFoR+h5ruhJy5t+ /fNr6qvYrG4iz4RYa5+ZVj+ZrJTUnTPlwYgRWkPRjgIumEp3aFoAHtFvctZrAWI9FHJ2 2kOox+H7fC1eite4+VTUFzYsSY2X1gV7Gk0K45P/YZqi+BuRK4XEJoAnDkbegPgrFXNu mfCA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:message-id:mime-version:date:x-gm-message-state :from:to:cc:subject:date; bh=TssL1WRJoCghnG9dgJLS5EqSblTfZ1RaJsaYbT2bnx4=; b=1A+GFcO17ta38CMjHjEhQEPJunE5+rEE62n+TP0yjr7pRYQEc7mgE6qUn6t696Y+IY KIhSdKt9Dq8G4wGh8kY06brC9XnL11hkCGUrJP0nGdEHC62rvxJap/L2OF8DTqmDGrMP Du/p6xlQi2kPviO6VCDP67555m0k4ZTB520kJPnfoaSBawfrSrKrYfbyQ9EaNR4kxrnb ILS282woiqi4nvjcfiIz4wtD6e5lPSQgMivxSJe5h3/Ub58rdH5s6umo+s6HCSgmMVOx 5iBCspN+fDEFlslPmqBlgDqmhL8domqHEIwy+e4IOT7WwCHZKOMKu2UJEmQVNX3R28Ph lLXA== X-Gm-Message-State: ACrzQf0VEse8MWiGSRO7+Ju4NDYwHVd7y6i+s57gWRLwpzvy+m4NxNsR Xz1Ho41rhi+T5D9u8aCCeRzrR06SJ4b6 X-Google-Smtp-Source: AMsMyM4Hjn/mGR/rs0sjA632AUYjYDgujqvct2D9UcjQMa3XHM/9PnFTyNV+7oI9E2AQmUGEL+TkrMQ5dTsP X-Received: from maskray1.svl.corp.google.com ([2620:15c:2ce:200:3a85:8afb:786d:5a2a]) (user=maskray job=sendgmr) by 2002:a05:690c:812:b0:345:27dc:56e2 with SMTP id bx18-20020a05690c081200b0034527dc56e2mr10632099ywb.313.1664591929776; Fri, 30 Sep 2022 19:38:49 -0700 (PDT) Date: Fri, 30 Sep 2022 19:38:46 -0700 Mime-Version: 1.0 Message-ID: <20221001023846.590825-1-maskray@google.com> Subject: [PATCH] gold: add --compress-debug-sections=zstd [PR 29641] From: Fangrui Song To: Alan Modra , Cary Coutant Cc: binutils@sourceware.org, Fangrui Song Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-20.0 required=5.0 tests=BAYES_00,DKIMWL_WL_MED,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: --- gold/NEWS | 2 ++ gold/compressed_output.cc | 59 +++++++++++++++++++++++++++++--------- gold/options.cc | 9 ++++++ gold/options.h | 4 +-- gold/testsuite/Makefile.am | 5 ++++ gold/testsuite/Makefile.in | 27 +++++++++++++++++ 6 files changed, 90 insertions(+), 16 deletions(-) diff --git a/gold/NEWS b/gold/NEWS index f9d2f5c156b..edc0015abbd 100644 --- a/gold/NEWS +++ b/gold/NEWS @@ -1,4 +1,6 @@ * gold and dwp now support zstd compressed debug sections. +* The new option --compress-debug-sections=zstd compresses debug sections with + zstd. Changes in 1.16: diff --git a/gold/compressed_output.cc b/gold/compressed_output.cc index 99801750348..b48fcd90980 100644 --- a/gold/compressed_output.cc +++ b/gold/compressed_output.cc @@ -75,6 +75,26 @@ zlib_compress(int header_size, } } +#if HAVE_ZSTD +static bool +zstd_compress(int header_size, const unsigned char *uncompressed_data, + unsigned long uncompressed_size, + unsigned char **compressed_data, unsigned long *compressed_size) +{ + size_t size = ZSTD_compressBound(uncompressed_size); + *compressed_data = new unsigned char[size + header_size]; + size = ZSTD_compress(*compressed_data + header_size, size, uncompressed_data, + uncompressed_size, ZSTD_CLEVEL_DEFAULT); + if (ZSTD_isError(size)) + { + delete[] *compressed_data; + return false; + } + *compressed_size = header_size + size; + return true; +} +#endif + // Decompress COMPRESSED_DATA of size COMPRESSED_SIZE, into a buffer // UNCOMPRESSED_DATA of size UNCOMPRESSED_SIZE. Returns TRUE if it // decompressed successfully, false if it failed. The buffer, of @@ -226,15 +246,19 @@ Output_compressed_section::set_final_data_size() this->write_to_postprocessing_buffer(); bool success = false; - enum { none, gnu_zlib, gabi_zlib } compress; + enum { none, gnu_zlib, gabi_zlib, zstd } compress; int compression_header_size = 12; const int size = parameters->target().get_size(); if (strcmp(this->options_->compress_debug_sections(), "zlib-gnu") == 0) compress = gnu_zlib; - else if (strcmp(this->options_->compress_debug_sections(), "zlib-gabi") == 0 - || strcmp(this->options_->compress_debug_sections(), "zlib") == 0) + else if (strcmp(this->options_->compress_debug_sections(), "none") == 0) + compress = none; + else { - compress = gabi_zlib; + if (strcmp(this->options_->compress_debug_sections(), "zstd") == 0) + compress = zstd; + else + compress = gabi_zlib; if (size == 32) compression_header_size = elfcpp::Elf_sizes<32>::chdr_size; else if (size == 64) @@ -242,34 +266,41 @@ Output_compressed_section::set_final_data_size() else gold_unreachable(); } - else - compress = none; - if (compress != none) + if (compress == gnu_zlib || compress == gabi_zlib) success = zlib_compress(compression_header_size, uncompressed_data, uncompressed_size, &this->data_, &compressed_size); +#if HAVE_ZSTD + else if (compress == zstd) + success = zstd_compress(compression_header_size, uncompressed_data, + uncompressed_size, &this->data_, + &compressed_size); +#endif if (success) { elfcpp::Elf_Xword flags = this->flags(); - if (compress == gabi_zlib) + if (compress == gabi_zlib || compress == zstd) { // Set the SHF_COMPRESSED bit. flags |= elfcpp::SHF_COMPRESSED; const bool is_big_endian = parameters->target().is_big_endian(); - uint64_t addralign = this->addralign(); + const unsigned int ch_type = compress == zstd + ? elfcpp::ELFCOMPRESS_ZSTD + : elfcpp::ELFCOMPRESS_ZLIB; + uint64_t addralign = this->addralign (); if (size == 32) { if (is_big_endian) { elfcpp::Chdr_write<32, true> chdr(this->data_); - chdr.put_ch_type(elfcpp::ELFCOMPRESS_ZLIB); + chdr.put_ch_type(ch_type); chdr.put_ch_size(uncompressed_size); chdr.put_ch_addralign(addralign); } else { elfcpp::Chdr_write<32, false> chdr(this->data_); - chdr.put_ch_type(elfcpp::ELFCOMPRESS_ZLIB); + chdr.put_ch_type(ch_type); chdr.put_ch_size(uncompressed_size); chdr.put_ch_addralign(addralign); } @@ -279,7 +310,7 @@ Output_compressed_section::set_final_data_size() if (is_big_endian) { elfcpp::Chdr_write<64, true> chdr(this->data_); - chdr.put_ch_type(elfcpp::ELFCOMPRESS_ZLIB); + chdr.put_ch_type(ch_type); chdr.put_ch_size(uncompressed_size); chdr.put_ch_addralign(addralign); // Clear the reserved field. @@ -288,7 +319,7 @@ Output_compressed_section::set_final_data_size() else { elfcpp::Chdr_write<64, false> chdr(this->data_); - chdr.put_ch_type(elfcpp::ELFCOMPRESS_ZLIB); + chdr.put_ch_type(ch_type); chdr.put_ch_size(uncompressed_size); chdr.put_ch_addralign(addralign); // Clear the reserved field. @@ -317,7 +348,7 @@ Output_compressed_section::set_final_data_size() gold_assert(this->data_ == NULL); this->set_data_size(uncompressed_size); } -} + } // Write out a compressed section. If we couldn't compress, we just // write it out as normal, uncompressed data. diff --git a/gold/options.cc b/gold/options.cc index 04be98a3e39..fbd727199f1 100644 --- a/gold/options.cc +++ b/gold/options.cc @@ -1433,6 +1433,15 @@ General_options::finalize() } } +#ifndef HAVE_ZSTD + if (strcmp(this->compress_debug_sections(), "zstd") == 0) + { + gold_error(_("--compress-debug-sections=zstd: gold is not built with " + "zstd support")); + this->set_compress_debug_sections("none"); + } +#endif + // --rosegment-gap implies --rosegment. if (this->user_set_rosegment_gap()) this->set_rosegment(true); diff --git a/gold/options.h b/gold/options.h index 17236eb9cb9..7d619734ab8 100644 --- a/gold/options.h +++ b/gold/options.h @@ -770,8 +770,8 @@ class General_options DEFINE_enum(compress_debug_sections, options::TWO_DASHES, '\0', "none", N_("Compress .debug_* sections in the output file"), - ("[none,zlib,zlib-gnu,zlib-gabi]"), false, - {"none", "zlib", "zlib-gnu", "zlib-gabi"}); + ("[none,zlib,zlib-gnu,zlib-gabi,zstd]"), false, + {"none", "zlib", "zlib-gnu", "zlib-gabi", "zstd"}); DEFINE_bool(copy_dt_needed_entries, options::TWO_DASHES, '\0', false, N_("Not supported"), diff --git a/gold/testsuite/Makefile.am b/gold/testsuite/Makefile.am index 0aacfe56ddb..a73e47c30c6 100644 --- a/gold/testsuite/Makefile.am +++ b/gold/testsuite/Makefile.am @@ -1766,6 +1766,11 @@ flagstest_compress_debug_sections_gabi.cmp: flagstest_compress_debug_sections_ga flagstest_compress_debug_sections_none.stdout > $@.tmp mv -f $@.tmp $@ +check_PROGRAMS += flagstest_compress_debug_sections_zstd +flagstest_compress_debug_sections_zstd: flagstest_debug.o gcctestdir/ld + $(CXXLINK) -o $@ $< -Wl,--compress-debug-sections=zstd + test -s $@ + # The specialfile output has a tricky case when we also compress debug # sections, because it requires output-file resizing. check_PROGRAMS += flagstest_o_specialfile_and_compress_debug_sections diff --git a/gold/testsuite/Makefile.in b/gold/testsuite/Makefile.in index 02fb2f4cac3..e9e3af66cec 100644 --- a/gold/testsuite/Makefile.in +++ b/gold/testsuite/Makefile.in @@ -401,6 +401,7 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ flagstest_compress_debug_sections_and_build_id_tree \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ flagstest_compress_debug_sections_gnu \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ flagstest_compress_debug_sections_gabi \ +@GCC_TRUE@@NATIVE_LINKER_TRUE@ flagstest_compress_debug_sections_zstd \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ flagstest_o_specialfile_and_compress_debug_sections \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ flagstest_o_ttext_1 ver_test \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ ver_test_2 ver_test_6 ver_test_8 \ @@ -1272,6 +1273,7 @@ libgoldtest_a_OBJECTS = $(am_libgoldtest_a_OBJECTS) @GCC_TRUE@@NATIVE_LINKER_TRUE@ flagstest_compress_debug_sections_and_build_id_tree$(EXEEXT) \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ flagstest_compress_debug_sections_gnu$(EXEEXT) \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ flagstest_compress_debug_sections_gabi$(EXEEXT) \ +@GCC_TRUE@@NATIVE_LINKER_TRUE@ flagstest_compress_debug_sections_zstd$(EXEEXT) \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ flagstest_o_specialfile_and_compress_debug_sections$(EXEEXT) \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ flagstest_o_ttext_1$(EXEEXT) \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ ver_test$(EXEEXT) \ @@ -1560,6 +1562,11 @@ flagstest_compress_debug_sections_none_SOURCES = \ flagstest_compress_debug_sections_none_OBJECTS = \ flagstest_compress_debug_sections_none.$(OBJEXT) flagstest_compress_debug_sections_none_LDADD = $(LDADD) +flagstest_compress_debug_sections_zstd_SOURCES = \ + flagstest_compress_debug_sections_zstd.c +flagstest_compress_debug_sections_zstd_OBJECTS = \ + flagstest_compress_debug_sections_zstd.$(OBJEXT) +flagstest_compress_debug_sections_zstd_LDADD = $(LDADD) flagstest_o_specialfile_SOURCES = flagstest_o_specialfile.c flagstest_o_specialfile_OBJECTS = flagstest_o_specialfile.$(OBJEXT) flagstest_o_specialfile_LDADD = $(LDADD) @@ -2306,6 +2313,7 @@ SOURCES = $(libgoldtest_a_SOURCES) $(aarch64_pr23870_SOURCES) \ flagstest_compress_debug_sections_gabi.c \ flagstest_compress_debug_sections_gnu.c \ flagstest_compress_debug_sections_none.c \ + flagstest_compress_debug_sections_zstd.c \ flagstest_o_specialfile.c \ flagstest_o_specialfile_and_compress_debug_sections.c \ flagstest_o_ttext_1.c icf_virtual_function_folding_test.c \ @@ -3686,6 +3694,14 @@ exclude_libs_test$(EXEEXT): $(exclude_libs_test_OBJECTS) $(exclude_libs_test_DEP @NATIVE_LINKER_FALSE@ @rm -f flagstest_compress_debug_sections_none$(EXEEXT) @NATIVE_LINKER_FALSE@ $(AM_V_CCLD)$(LINK) $(flagstest_compress_debug_sections_none_OBJECTS) $(flagstest_compress_debug_sections_none_LDADD) $(LIBS) +@GCC_FALSE@flagstest_compress_debug_sections_zstd$(EXEEXT): $(flagstest_compress_debug_sections_zstd_OBJECTS) $(flagstest_compress_debug_sections_zstd_DEPENDENCIES) $(EXTRA_flagstest_compress_debug_sections_zstd_DEPENDENCIES) +@GCC_FALSE@ @rm -f flagstest_compress_debug_sections_zstd$(EXEEXT) +@GCC_FALSE@ $(AM_V_CCLD)$(LINK) $(flagstest_compress_debug_sections_zstd_OBJECTS) $(flagstest_compress_debug_sections_zstd_LDADD) $(LIBS) + +@NATIVE_LINKER_FALSE@flagstest_compress_debug_sections_zstd$(EXEEXT): $(flagstest_compress_debug_sections_zstd_OBJECTS) $(flagstest_compress_debug_sections_zstd_DEPENDENCIES) $(EXTRA_flagstest_compress_debug_sections_zstd_DEPENDENCIES) +@NATIVE_LINKER_FALSE@ @rm -f flagstest_compress_debug_sections_zstd$(EXEEXT) +@NATIVE_LINKER_FALSE@ $(AM_V_CCLD)$(LINK) $(flagstest_compress_debug_sections_zstd_OBJECTS) $(flagstest_compress_debug_sections_zstd_LDADD) $(LIBS) + @GCC_FALSE@flagstest_o_specialfile$(EXEEXT): $(flagstest_o_specialfile_OBJECTS) $(flagstest_o_specialfile_DEPENDENCIES) $(EXTRA_flagstest_o_specialfile_DEPENDENCIES) @GCC_FALSE@ @rm -f flagstest_o_specialfile$(EXEEXT) @GCC_FALSE@ $(AM_V_CCLD)$(LINK) $(flagstest_o_specialfile_OBJECTS) $(flagstest_o_specialfile_LDADD) $(LIBS) @@ -4802,6 +4818,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flagstest_compress_debug_sections_gabi.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flagstest_compress_debug_sections_gnu.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flagstest_compress_debug_sections_none.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flagstest_compress_debug_sections_zstd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flagstest_o_specialfile.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flagstest_o_specialfile_and_compress_debug_sections.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flagstest_o_ttext_1.Po@am__quote@ @@ -7123,6 +7140,13 @@ flagstest_compress_debug_sections_gabi.log: flagstest_compress_debug_sections_ga --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) +flagstest_compress_debug_sections_zstd.log: flagstest_compress_debug_sections_zstd$(EXEEXT) + @p='flagstest_compress_debug_sections_zstd$(EXEEXT)'; \ + b='flagstest_compress_debug_sections_zstd'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) flagstest_o_specialfile_and_compress_debug_sections.log: flagstest_o_specialfile_and_compress_debug_sections$(EXEEXT) @p='flagstest_o_specialfile_and_compress_debug_sections$(EXEEXT)'; \ b='flagstest_o_specialfile_and_compress_debug_sections'; \ @@ -8799,6 +8823,9 @@ uninstall-am: @GCC_TRUE@@NATIVE_LINKER_TRUE@ cmp flagstest_compress_debug_sections_gabi.stdout \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ flagstest_compress_debug_sections_none.stdout > $@.tmp @GCC_TRUE@@NATIVE_LINKER_TRUE@ mv -f $@.tmp $@ +@GCC_TRUE@@NATIVE_LINKER_TRUE@flagstest_compress_debug_sections_zstd: flagstest_debug.o gcctestdir/ld +@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXLINK) -o $@ $< -Wl,--compress-debug-sections=zstd +@GCC_TRUE@@NATIVE_LINKER_TRUE@ test -s $@ @GCC_TRUE@@NATIVE_LINKER_TRUE@flagstest_o_specialfile_and_compress_debug_sections: flagstest_debug.o \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ gcctestdir/ld @GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXLINK) -o /dev/stdout $< -Wl,--compress-debug-sections=zlib 2>&1 | cat > $@ -- 2.38.0.rc1.362.ged0d419d3c-goog