diff options
author | Alex Brachet <abrachet@google.com> | 2022-08-08 21:31:58 +0000 |
---|---|---|
committer | Tobias Hieta <tobias@hieta.se> | 2022-08-10 10:49:39 +0200 |
commit | 525ffb05aa2c070f01a2760370c76a53a62cfd78 (patch) | |
tree | 41beca1a86b29161dd0c70413c15698f6c687921 /lld | |
parent | bab8af8ea062f6332b5c5d13ae688bb8900f244a (diff) | |
download | llvm-525ffb05aa2c070f01a2760370c76a53a62cfd78.zip llvm-525ffb05aa2c070f01a2760370c76a53a62cfd78.tar.gz llvm-525ffb05aa2c070f01a2760370c76a53a62cfd78.tar.bz2 |
[ELF] Support --package-metadata
This was recently introduced in GNU linkers and it makes sense for
ld.lld to have the same support. This implementation omits checking if
the input string is valid json to reduce size bloat.
Differential Revision: https://reviews.llvm.org/D131439
(cherry picked from commit dbd04b853b680b0a383e5f58edf3643364f67bdf)
Diffstat (limited to 'lld')
-rw-r--r-- | lld/ELF/Config.h | 1 | ||||
-rw-r--r-- | lld/ELF/Driver.cpp | 1 | ||||
-rw-r--r-- | lld/ELF/Options.td | 2 | ||||
-rw-r--r-- | lld/ELF/SyntheticSections.cpp | 14 | ||||
-rw-r--r-- | lld/ELF/SyntheticSections.h | 10 | ||||
-rw-r--r-- | lld/ELF/Writer.cpp | 5 | ||||
-rw-r--r-- | lld/docs/ReleaseNotes.rst | 2 | ||||
-rw-r--r-- | lld/test/ELF/package-metadata.s | 19 |
8 files changed, 54 insertions, 0 deletions
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h index 39723f0..af976e3 100644 --- a/lld/ELF/Config.h +++ b/lld/ELF/Config.h @@ -290,6 +290,7 @@ struct Configuration { StringRef thinLTOJobs; unsigned timeTraceGranularity; int32_t splitStackAdjustSize; + StringRef packageMetadata; // The following config options do not directly correspond to any // particular command line options. diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index dc2d4ad..296fb42 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -1145,6 +1145,7 @@ static void readConfigs(opt::InputArgList &args) { config->optimize = args::getInteger(args, OPT_O, 1); config->orphanHandling = getOrphanHandling(args); config->outputFile = args.getLastArgValue(OPT_o); + config->packageMetadata = args.getLastArgValue(OPT_package_metadata); config->pie = args.hasFlag(OPT_pie, OPT_no_pie, false); config->printIcfSections = args.hasFlag(OPT_print_icf_sections, OPT_no_print_icf_sections, false); diff --git a/lld/ELF/Options.td b/lld/ELF/Options.td index 80c0ff9f..d9266e5 100644 --- a/lld/ELF/Options.td +++ b/lld/ELF/Options.td @@ -503,6 +503,8 @@ def z: JoinedOrSeparate<["-"], "z">, MetaVarName<"<option>">, def visual_studio_diagnostics_format : FF<"vs-diagnostics">, HelpText<"Format diagnostics for Visual Studio compatibility">; +def package_metadata: JJ<"package-metadata=">, HelpText<"Emit package metadata note">; + // Aliases def: Separate<["-"], "f">, Alias<auxiliary>, HelpText<"Alias for --auxiliary">; def: F<"call_shared">, Alias<Bdynamic>, HelpText<"Alias for --Bdynamic">; diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index aa5e867..b359c2e 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -3887,6 +3887,20 @@ size_t MemtagAndroidNote::getSize() const { /*descsz=*/sizeof(uint32_t); } +void PackageMetadataNote::writeTo(uint8_t *buf) { + write32(buf, 4); + write32(buf + 4, config->packageMetadata.size() + 1); + write32(buf + 8, FDO_PACKAGING_METADATA); + memcpy(buf + 12, "FDO", 4); + memcpy(buf + 16, config->packageMetadata.data(), + config->packageMetadata.size()); +} + +size_t PackageMetadataNote::getSize() const { + return sizeof(llvm::ELF::Elf64_Nhdr) + 4 + + alignTo(config->packageMetadata.size() + 1, 4); +} + InStruct elf::in; std::vector<Partition> elf::partitions; diff --git a/lld/ELF/SyntheticSections.h b/lld/ELF/SyntheticSections.h index 9e95d3f..987c046 100644 --- a/lld/ELF/SyntheticSections.h +++ b/lld/ELF/SyntheticSections.h @@ -1199,6 +1199,15 @@ public: size_t getSize() const override; }; +class PackageMetadataNote : public SyntheticSection { +public: + PackageMetadataNote() + : SyntheticSection(llvm::ELF::SHF_ALLOC, llvm::ELF::SHT_NOTE, + /*alignment=*/4, ".note.package") {} + void writeTo(uint8_t *buf) override; + size_t getSize() const override; +}; + InputSection *createInterpSection(); MergeInputSection *createCommentSection(); template <class ELFT> void splitSections(); @@ -1230,6 +1239,7 @@ struct Partition { std::unique_ptr<GnuHashTableSection> gnuHashTab; std::unique_ptr<HashTableSection> hashTab; std::unique_ptr<MemtagAndroidNote> memtagAndroidNote; + std::unique_ptr<PackageMetadataNote> packageMetadataNote; std::unique_ptr<RelocationBaseSection> relaDyn; std::unique_ptr<RelrBaseSection> relrDyn; std::unique_ptr<VersionDefinitionSection> verDef; diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index c9345d8..ad80d43 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -425,6 +425,11 @@ template <class ELFT> void elf::createSyntheticSections() { part.armExidx = std::make_unique<ARMExidxSyntheticSection>(); add(*part.armExidx); } + + if (!config->packageMetadata.empty()) { + part.packageMetadataNote = std::make_unique<PackageMetadataNote>(); + add(*part.packageMetadataNote); + } } if (partitions.size() != 1) { diff --git a/lld/docs/ReleaseNotes.rst b/lld/docs/ReleaseNotes.rst index 5784703..7759c14 100644 --- a/lld/docs/ReleaseNotes.rst +++ b/lld/docs/ReleaseNotes.rst @@ -25,6 +25,8 @@ Non-comprehensive list of changes in this release ELF Improvements ---------------- +* ``--package-metadata=`` has been added to create package metadata notes + (`D131439 <https://reviews.llvm.org/D131439>`_) * ``-z pack-relative-relocs`` is now available to support ``DT_RELR`` for glibc 2.36+. (`D120701 <https://reviews.llvm.org/D120701>`_) diff --git a/lld/test/ELF/package-metadata.s b/lld/test/ELF/package-metadata.s new file mode 100644 index 0000000..29df499d --- /dev/null +++ b/lld/test/ELF/package-metadata.s @@ -0,0 +1,19 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o + +# RUN: ld.lld %t.o -o %t --package-metadata='{}' +# RUN: llvm-readelf -n %t | FileCheck %s --check-prefixes=NOTE,FIRST + +# RUN: ld.lld %t.o -o %t --package-metadata='{"abc":123}' +# RUN: llvm-readelf -n %t | FileCheck %s --check-prefixes=NOTE,SECOND + +# NOTE: .note.package +# NOTE-NEXT: Owner +# NOTE-NEXT: FDO 0x{{.*}} Unknown note type: (0xcafe1a7e) +# FIRST-NEXT: description data: 7b 7d 00 +# SECOND-NEXT: description data: 7b 22 61 62 63 22 3a 31 32 33 7d 00 + +.globl _start +_start: + ret |