171 lines
6.1 KiB
Diff
171 lines
6.1 KiB
Diff
From 2a5f3345e72b2c1a66d3714eaae37e7b05ef5c65 Mon Sep 17 00:00:00 2001
|
|
From: Alex Brachet <abrachet@google.com>
|
|
Date: Mon, 8 Aug 2022 21:31:58 +0000
|
|
Subject: [PATCH] [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
|
|
---
|
|
lld/ELF/Config.h | 1 +
|
|
lld/ELF/Driver.cpp | 1 +
|
|
lld/ELF/Options.td | 2 ++
|
|
lld/ELF/SyntheticSections.cpp | 14 ++++++++++++++
|
|
lld/ELF/SyntheticSections.h | 11 +++++++++++
|
|
lld/ELF/Writer.cpp | 5 +++++
|
|
lld/docs/ReleaseNotes.rst | 2 ++
|
|
lld/test/ELF/package-metadata.s | 19 +++++++++++++++++++
|
|
8 files changed, 55 insertions(+)
|
|
create mode 100644 lld/test/ELF/package-metadata.s
|
|
|
|
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h
|
|
index 72b7be8165e0..38545d257a2b 100644
|
|
--- a/lld/ELF/Config.h
|
|
+++ b/lld/ELF/Config.h
|
|
@@ -281,6 +281,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 54b487bdc243..39adc5d707d7 100644
|
|
--- a/lld/ELF/Driver.cpp
|
|
+++ b/lld/ELF/Driver.cpp
|
|
@@ -1092,6 +1092,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 cf2013a5f820..52f5485af1f4 100644
|
|
--- a/lld/ELF/Options.td
|
|
+++ b/lld/ELF/Options.td
|
|
@@ -505,6 +505,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 7778ae5f78e6..5e5495540215 100644
|
|
--- a/lld/ELF/SyntheticSections.cpp
|
|
+++ b/lld/ELF/SyntheticSections.cpp
|
|
@@ -3844,6 +3844,20 @@ void InStruct::reset() {
|
|
symTabShndx.reset();
|
|
}
|
|
|
|
+void PackageMetadataNote::writeTo(uint8_t *buf) {
|
|
+ write32(buf, 4);
|
|
+ write32(buf + 4, config->packageMetadata.size() + 1);
|
|
+ write32(buf + 8, 0xcafe1a7e);
|
|
+ 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 3161785988f6..7b31b5e97731 100644
|
|
--- a/lld/ELF/SyntheticSections.h
|
|
+++ b/lld/ELF/SyntheticSections.h
|
|
@@ -1185,6 +1185,16 @@ public:
|
|
void writeTo(uint8_t *buf) 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();
|
|
@@ -1215,6 +1225,7 @@ struct Partition {
|
|
std::unique_ptr<EhFrameSection> ehFrame;
|
|
std::unique_ptr<GnuHashTableSection> gnuHashTab;
|
|
std::unique_ptr<HashTableSection> hashTab;
|
|
+ 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 5794f048c990..fa6353db8c6d 100644
|
|
--- a/lld/ELF/Writer.cpp
|
|
+++ b/lld/ELF/Writer.cpp
|
|
@@ -417,6 +417,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 672759fdf6b3..b94b73c4aea7 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>`_)
|
|
|
|
* ``--export-dynamic-symbol-list`` has been added.
|
|
(`D107317 <https://reviews.llvm.org/D107317>`_)
|
|
diff --git a/lld/test/ELF/package-metadata.s b/lld/test/ELF/package-metadata.s
|
|
new file mode 100644
|
|
index 000000000000..29df499d7e98
|
|
--- /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
|
|
--
|
|
2.37.1
|
|
|