Index: lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.cpp =================================================================== --- lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.cpp +++ lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.cpp @@ -33,10 +33,13 @@ for (auto sec : this->_layout.sections()) { if (auto section = dyn_cast>(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)) + this->_dynamicSymbolTable->addSymbol(atom->_atom, + section->ordinal(), + atom->_virtualAddr, atom); } } } Index: lib/ReaderWriter/ELF/AArch64/AArch64RelocationPass.cpp =================================================================== --- lib/ReaderWriter/ELF/AArch64/AArch64RelocationPass.cpp +++ lib/ReaderWriter/ELF/AArch64/AArch64RelocationPass.cpp @@ -288,7 +288,8 @@ } std::error_code handleTLSDESC(const Reference &ref) { - if (isa(ref.target())) { + if (isa(ref.target()) || + isa(ref.target())) { const_cast(ref).setTarget(getTLSDESCPLTEntry(ref.target())); } return std::error_code(); Index: lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.h =================================================================== --- lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.h +++ lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.h @@ -17,7 +17,8 @@ class AArch64GOTSection : public AtomSection { public: - AArch64GOTSection(const ELFLinkingContext &ctx); + AArch64GOTSection(const ELFLinkingContext &ctx, StringRef name, + int32_t order); bool hasGlobalGOTEntry(const Atom *a) const { return _tlsMap.count(a); Index: lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.cpp =================================================================== --- lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.cpp +++ lib/ReaderWriter/ELF/AArch64/AArch64SectionChunks.cpp @@ -13,10 +13,10 @@ namespace lld { namespace elf { -AArch64GOTSection::AArch64GOTSection(const ELFLinkingContext &ctx) - : AtomSection(ctx, ".got", DefinedAtom::typeGOT, DefinedAtom::permRW_, - TargetLayout::ORDER_GOT) -{ +AArch64GOTSection::AArch64GOTSection(const ELFLinkingContext &ctx, + StringRef name, int32_t order) + : AtomSection(ctx, name, DefinedAtom::typeGOT, DefinedAtom::permRW_, + order) { this->_alignment = 8; } Index: lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.h =================================================================== --- lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.h +++ lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.h @@ -32,7 +32,9 @@ DefinedAtom::ContentPermissions permissions, TargetLayout::SectionOrder order) override; - const AArch64GOTSection &getGOTSection() const { return *_gotSection; } + const std::vector &getGOTSections() const { + return _gotSections; + } uint64_t getTPOffset() { std::call_once(_tpOffOnce, [this]() { @@ -53,7 +55,7 @@ }; private: - AArch64GOTSection *_gotSection; + std::vector _gotSections; uint64_t _tpOff = 0; std::once_flag _tpOffOnce; }; Index: lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.cpp =================================================================== --- lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.cpp +++ lib/ReaderWriter/ELF/AArch64/AArch64TargetHandler.cpp @@ -18,14 +18,17 @@ using namespace elf; AArch64TargetLayout::AArch64TargetLayout(ELFLinkingContext &ctx) : - TargetLayout(ctx), - _gotSection(new (this->_allocator) AArch64GOTSection(ctx)) {} + TargetLayout(ctx) {} AtomSection *AArch64TargetLayout::createSection( StringRef name, int32_t type, DefinedAtom::ContentPermissions permissions, TargetLayout::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::createSection(name, type, permissions, order); } Index: test/elf/AArch64/general-dyn-tls-0.test =================================================================== --- test/elf/AArch64/general-dyn-tls-0.test +++ 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)