summaryrefslogtreecommitdiff
path: root/lld/ELF
diff options
context:
space:
mode:
Diffstat (limited to 'lld/ELF')
-rw-r--r--lld/ELF/Arch/AArch64.cpp4
-rw-r--r--lld/ELF/Config.h1
-rw-r--r--lld/ELF/Driver.cpp6
-rw-r--r--lld/ELF/Options.td2
-rw-r--r--lld/ELF/Relocations.cpp3
-rw-r--r--lld/ELF/SyntheticSections.cpp17
-rw-r--r--lld/ELF/SyntheticSections.h10
-rw-r--r--lld/ELF/Writer.cpp5
8 files changed, 40 insertions, 8 deletions
diff --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp
index 1949169d6447..b23684819a23 100644
--- a/lld/ELF/Arch/AArch64.cpp
+++ b/lld/ELF/Arch/AArch64.cpp
@@ -873,8 +873,8 @@ void AArch64BtiPac::writePlt(uint8_t *buf, const Symbol &sym,
}
static TargetInfo *getTargetInfo() {
- if (config->andFeatures & (GNU_PROPERTY_AARCH64_FEATURE_1_BTI |
- GNU_PROPERTY_AARCH64_FEATURE_1_PAC)) {
+ if ((config->andFeatures & GNU_PROPERTY_AARCH64_FEATURE_1_BTI) ||
+ config->zPacPlt) {
static AArch64BtiPac t;
return &t;
}
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index 39723f092784..af976e39147d 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 6c0fd3139e87..296fb4220012 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -590,11 +590,6 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
if (errorCount())
return;
- // The Target instance handles target-specific stuff, such as applying
- // relocations or writing a PLT section. It also contains target-dependent
- // values such as a default image base address.
- target = getTarget();
-
link(args);
}
@@ -1150,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 80c0ff9fe1b8..d9266e595887 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/Relocations.cpp b/lld/ELF/Relocations.cpp
index e54e1ebd41bb..53af34ef2085 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -1705,7 +1705,8 @@ static bool mergeCmp(const InputSection *a, const InputSection *b) {
if (a->outSecOff < b->outSecOff)
return true;
- if (a->outSecOff == b->outSecOff) {
+ // FIXME dyn_cast<ThunkSection> is non-null for any SyntheticSection.
+ if (a->outSecOff == b->outSecOff && a != b) {
auto *ta = dyn_cast<ThunkSection>(a);
auto *tb = dyn_cast<ThunkSection>(b);
diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index 919afc7a6e0e..b359c2e7bcea 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -712,6 +712,9 @@ bool GotSection::isNeeded() const {
}
void GotSection::writeTo(uint8_t *buf) {
+ // On PPC64 .got may be needed but empty. Skip the write.
+ if (size == 0)
+ return;
target->writeGotHeader(buf);
relocateAlloc(buf, buf + size);
}
@@ -3884,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 9e95d3f3f65a..987c0461ec07 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 c9345d812270..ad80d4344e36 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) {