diff options
7 files changed, 29 insertions, 20 deletions
diff --git a/lld/lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.cpp b/lld/lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.cpp index ba4259479a8..9a9ec6cba12 100644 --- a/lld/lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.cpp +++ b/lld/lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.cpp @@ -33,10 +33,12 @@ void AArch64ExecutableWriter::buildDynamicSymbolTable(const File &file) { for (auto sec : this->_layout.sections()) { if (auto section = dyn_cast<AtomSection<ELF64LE>>(sec)) { for (const auto &atom : section->atoms()) { - if (_targetLayout.getGOTSection().hasGlobalGOTEntry(atom->_atom)) { - this->_dynamicSymbolTable->addSymbol(atom->_atom, section->ordinal(), - atom->_virtualAddr, atom); - continue; + // Add all globals GOT symbols (in both .got and .got.plt sections) + // on dynamic symbol table. + for (const auto §ion : _targetLayout.getGOTSections()) { + if (section->hasGlobalGOTEntry(atom->_atom)) + _dynamicSymbolTable->addSymbol(atom->_atom, section->ordinal(), + atom->_virtualAddr, atom); } } } diff --git a/lld/lib/ReaderWriter/ELF/AArch64/AArch64RelocationPass.cpp b/lld/lib/ReaderWriter/ELF/AArch64/AArch64RelocationPass.cpp index e2ec319601f..4d94a793665 100644 --- a/lld/lib/ReaderWriter/ELF/AArch64/AArch64RelocationPass.cpp +++ b/lld/lib/ReaderWriter/ELF/AArch64/AArch64RelocationPass.cpp @@ -288,7 +288,8 @@ protected: } std::error_code handleTLSDESC(const Reference &ref) { - if (isa<DefinedAtom>(ref.target())) { + if (isa<DefinedAtom>(ref.target()) || + isa<SharedLibraryAtom>(ref.target())) { const_cast<Reference &>(ref).setTarget(getTLSDESCPLTEntry(ref.target())); } return std::error_code(); diff --git a/lld/lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.cpp b/lld/lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.cpp index b06a8262ef6..2734bcdbda5 100644 --- a/lld/lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.cpp +++ b/lld/lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.cpp @@ -13,11 +13,11 @@ namespace lld { namespace elf { -AArch64GOTSection::AArch64GOTSection(const ELFLinkingContext &ctx) - : AtomSection<ELF64LE>(ctx, ".got", DefinedAtom::typeGOT, DefinedAtom::permRW_, - TargetLayout<ELF64LE>::ORDER_GOT) -{ - this->_alignment = 8; +AArch64GOTSection::AArch64GOTSection(const ELFLinkingContext &ctx, + StringRef name, int32_t order) + : AtomSection<ELF64LE>(ctx, name, DefinedAtom::typeGOT, DefinedAtom::permRW_, + order) { + _alignment = 8; } const AtomLayout *AArch64GOTSection::appendAtom(const Atom *atom) { diff --git a/lld/lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.h b/lld/lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.h index 84533dd7c93..2b7594c2db8 100644 --- a/lld/lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.h +++ b/lld/lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.h @@ -17,7 +17,8 @@ namespace elf { class AArch64GOTSection : public AtomSection<ELF64LE> { public: - AArch64GOTSection(const ELFLinkingContext &ctx); + AArch64GOTSection(const ELFLinkingContext &ctx, StringRef name, + int32_t order); bool hasGlobalGOTEntry(const Atom *a) const { return _tlsMap.count(a); diff --git a/lld/lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.cpp b/lld/lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.cpp index de071d25f9c..083b492c160 100644 --- a/lld/lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.cpp +++ b/lld/lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.cpp @@ -18,14 +18,17 @@ using namespace lld; using namespace elf; AArch64TargetLayout::AArch64TargetLayout(ELFLinkingContext &ctx) : - TargetLayout(ctx), - _gotSection(new (this->_allocator) AArch64GOTSection(ctx)) {} + TargetLayout(ctx) {} AtomSection<ELF64LE> *AArch64TargetLayout::createSection( StringRef name, int32_t type, DefinedAtom::ContentPermissions permissions, TargetLayout<ELF64LE>::SectionOrder order) { - if (type == DefinedAtom::typeGOT && name == ".got") - return _gotSection; + if (type == DefinedAtom::typeGOT && (name == ".got" || name == ".got.plt")) { + auto section = new (this->_allocator) AArch64GOTSection(this->_ctx, name, + order); + _gotSections.push_back(section); + return section; + } return TargetLayout<ELF64LE>::createSection(name, type, permissions, order); } diff --git a/lld/lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.h b/lld/lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.h index 905cfb0d0d7..c0ecbfa9e44 100644 --- a/lld/lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.h +++ b/lld/lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.h @@ -32,7 +32,9 @@ public: DefinedAtom::ContentPermissions permissions, TargetLayout<ELF64LE>::SectionOrder order) override; - const AArch64GOTSection &getGOTSection() const { return *_gotSection; } + const std::vector<AArch64GOTSection *> &getGOTSections() const { + return _gotSections; + } uint64_t getTPOffset() { std::call_once(_tpOffOnce, [this]() { @@ -53,7 +55,7 @@ private: }; private: - AArch64GOTSection *_gotSection; + std::vector<AArch64GOTSection *> _gotSections; uint64_t _tpOff = 0; std::once_flag _tpOffOnce; }; diff --git a/lld/test/elf/AArch64/general-dyn-tls-0.test b/lld/test/elf/AArch64/general-dyn-tls-0.test index 72750c1181a..306cf7ca044 100644 --- a/lld/test/elf/AArch64/general-dyn-tls-0.test +++ b/lld/test/elf/AArch64/general-dyn-tls-0.test @@ -31,13 +31,13 @@ #CHECKRELOCATION: Relocations [ #CHECKRELOCATION: .rela.dyn { -#CHECKRELOCATION: 0x401090 R_AARCH64_TLSDESC - 0x0 +#CHECKRELOCATION: 0x401090 R_AARCH64_TLSDESC var 0x0 #CHECKRELOCATION: } #CHECK: Contents of section .text: -#CHECK: 400230 a8c31fb8 40018052 0b000094 000000b0 ....@..R........ +#CHECK: 400250 a8c31fb8 40018052 0b000094 000000b0 ....@..R........ # \_ adrp x0, 401000 <_DYNAMIC> (R_AARCH64_TLSDESC_ADR_PAGE21) -#CHECK-NEXT: 400240 014840f9 00400291 20003fd6 49d03bd5 .H@..@.. .?.I.;. +#CHECK-NEXT: 400260 014840f9 00400291 20003fd6 49d03bd5 .H@..@.. .?.I.;. # \_ | | ldr x1, [x0,#144] (R_AARCH64_TLSDESC_LD64_LO12_NC) # \_ | add x0, x0, #0x90 (R_AARCH64_TLSDESC_ADD_LO12_NC) # \_ blr x1 (R_AARCH64_TLSDESC_CALL) |

