diff options
Diffstat (limited to 'lld/ELF')
| -rw-r--r-- | lld/ELF/Arch/AArch64.cpp | 4 | ||||
| -rw-r--r-- | lld/ELF/Config.h | 1 | ||||
| -rw-r--r-- | lld/ELF/Driver.cpp | 6 | ||||
| -rw-r--r-- | lld/ELF/Options.td | 2 | ||||
| -rw-r--r-- | lld/ELF/Relocations.cpp | 3 | ||||
| -rw-r--r-- | lld/ELF/SyntheticSections.cpp | 17 | ||||
| -rw-r--r-- | lld/ELF/SyntheticSections.h | 10 | ||||
| -rw-r--r-- | lld/ELF/Writer.cpp | 5 |
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) { |
