Index: include/lld/ReaderWriter/ELFLinkingContext.h =================================================================== --- include/lld/ReaderWriter/ELFLinkingContext.h +++ include/lld/ReaderWriter/ELFLinkingContext.h @@ -262,8 +262,8 @@ void setCreateSeparateROSegment() { _mergeRODataToTextSegment = false; } - bool hasCoalescedSharedLibPair(StringRef name) const { - return _sharedLibCoalescedSymbols.count(name) != 0; + bool isDynamicallyExportedSymbol(StringRef name) const { + return _dynamicallyExportedSymbols.count(name) != 0; } private: @@ -300,7 +300,7 @@ StringRefVector _rpathList; StringRefVector _rpathLinkList; std::map _absoluteSymbols; - llvm::StringSet<> _sharedLibCoalescedSymbols; + llvm::StringSet<> _dynamicallyExportedSymbols; }; } // end namespace lld Index: lib/ReaderWriter/ELF/AArch64/AArch64DynamicLibraryWriter.h =================================================================== --- lib/ReaderWriter/ELF/AArch64/AArch64DynamicLibraryWriter.h +++ lib/ReaderWriter/ELF/AArch64/AArch64DynamicLibraryWriter.h @@ -57,7 +57,6 @@ std::vector> &result) { DynamicLibraryWriter::createImplicitFiles(result); _gotFile->addAtom(*new (_gotFile->_alloc) GLOBAL_OFFSET_TABLEAtom(*_gotFile)); - _gotFile->addAtom(*new (_gotFile->_alloc) TLSGETADDRAtom(*_gotFile)); _gotFile->addAtom(*new (_gotFile->_alloc) DYNAMICAtom(*_gotFile)); result.push_back(std::move(_gotFile)); return true; Index: lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.h =================================================================== --- lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.h +++ lib/ReaderWriter/ELF/AArch64/AArch64ExecutableWriter.h @@ -56,7 +56,6 @@ std::vector> &result) { ExecutableWriter::createImplicitFiles(result); _gotFile->addAtom(*new (_gotFile->_alloc) GLOBAL_OFFSET_TABLEAtom(*_gotFile)); - _gotFile->addAtom(*new (_gotFile->_alloc) TLSGETADDRAtom(*_gotFile)); if (_context.isDynamic()) _gotFile->addAtom(*new (_gotFile->_alloc) DYNAMICAtom(*_gotFile)); result.push_back(std::move(_gotFile)); Index: lib/ReaderWriter/ELF/Atoms.h =================================================================== --- lib/ReaderWriter/ELF/Atoms.h +++ lib/ReaderWriter/ELF/Atoms.h @@ -649,6 +649,13 @@ const Elf_Sym *_symbol; }; +class SimpleELFDynamicAtom : public SharedLibraryAtom { +public: + SimpleELFDynamicAtom() : SharedLibraryAtom() {} + + virtual Scope scope() const = 0; +}; + class SimpleELFDefinedAtom : public SimpleDefinedAtom { public: SimpleELFDefinedAtom(const File &f) : SimpleDefinedAtom(f) {} @@ -820,29 +827,29 @@ ArrayRef rawContent() const override { return ArrayRef(); } }; -class TLSGETADDRAtom : public SimpleELFDefinedAtom { +class TLSGETADDRAtom : public SimpleELFDynamicAtom { public: - TLSGETADDRAtom(const File &f) : SimpleELFDefinedAtom(f) {} + TLSGETADDRAtom(const File &f) : SimpleELFDynamicAtom(), _owningFile(f) {} - StringRef name() const override { return "__tls_get_addr"; } + const File &file() const override { return _owningFile; } - Scope scope() const override { return scopeGlobal; } + StringRef name() const override { return "__tls_get_addr"; } - Merge merge() const override { return mergeAsWeak; } + StringRef loadName() const override { + return "_ld_so"; + } - SectionChoice sectionChoice() const override { return sectionCustomRequired; } + Scope scope() const override { return scopeGlobal; } - StringRef customSectionName() const override { return ".text"; } + bool canBeNullAtRuntime() const override { return true; } - ContentType contentType() const override { return typeCode; } + Type type() const override { + return Type::Code; + } uint64_t size() const override { return 0; } - - ContentPermissions permissions() const override { return permR_X; } - - Alignment alignment() const override { return Alignment(0); } - - ArrayRef rawContent() const override { return ArrayRef(); } +private: + const File &_owningFile; }; class DYNAMICAtom : public SimpleELFDefinedAtom { Index: lib/ReaderWriter/ELF/DefaultLayout.h =================================================================== --- lib/ReaderWriter/ELF/DefaultLayout.h +++ lib/ReaderWriter/ELF/DefaultLayout.h @@ -21,6 +21,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/DenseSet.h" #include "llvm/ADT/Hashing.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" @@ -296,6 +297,10 @@ return 0; } + bool isReferencedByDefinedAtom(const SharedLibraryAtom *sla) const { + return _referencedDynAtoms.count(sla); + } + protected: /// \brief Allocate a new section. virtual AtomSection *createSection( @@ -317,6 +322,7 @@ LLD_UNIQUE_BUMP_PTR(RelocationTable) _dynamicRelocationTable; LLD_UNIQUE_BUMP_PTR(RelocationTable) _pltRelocationTable; std::vector _absoluteAtoms; + llvm::DenseSet _referencedDynAtoms; const ELFLinkingContext &_context; }; @@ -556,11 +562,14 @@ AtomSection *section = getSection(sectionName, contentType, permissions); // Add runtime relocations to the .rela section. - for (const auto &reloc : *definedAtom) + for (const auto &reloc : *definedAtom) { if (_context.isDynamicRelocation(*definedAtom, *reloc)) getDynamicRelocationTable()->addRelocation(*definedAtom, *reloc); else if (_context.isPLTRelocation(*definedAtom, *reloc)) getPLTRelocationTable()->addRelocation(*definedAtom, *reloc); + if (const auto *sla = dyn_cast(reloc->target())) + _referencedDynAtoms.insert(sla); + } return section->appendAtom(atom); } else if (const AbsoluteAtom *absoluteAtom = dyn_cast(atom)) { // Absolute atoms are not part of any section, they are global for the whole Index: lib/ReaderWriter/ELF/DynamicLibraryWriter.h =================================================================== --- lib/ReaderWriter/ELF/DynamicLibraryWriter.h +++ lib/ReaderWriter/ELF/DynamicLibraryWriter.h @@ -28,7 +28,8 @@ DynamicLibraryWriter(const ELFLinkingContext &context, TargetLayout &layout) : OutputELFWriter(context, layout), - _runtimeFile(new CRuntimeFile(context)) {} + _runtimeFile(new CRuntimeFile(context)), + _dynamicInterpreterFile(new SimpleFile(context.getInterpreter())) {} protected: virtual void buildDynamicSymbolTable(const File &file); @@ -38,6 +39,7 @@ protected: std::unique_ptr > _runtimeFile; + std::unique_ptr _dynamicInterpreterFile; }; //===----------------------------------------------------------------------===// @@ -65,6 +67,8 @@ template void DynamicLibraryWriter::addDefaultAtoms() { _runtimeFile->addAbsoluteAtom("_end"); + _dynamicInterpreterFile->addAtom(*new (this->_alloc) + TLSGETADDRAtom(*_dynamicInterpreterFile)); } /// \brief Hook in lld to add CRuntime file @@ -75,6 +79,7 @@ DynamicLibraryWriter::addDefaultAtoms(); OutputELFWriter::createImplicitFiles(result); result.push_back(std::move(_runtimeFile)); + result.push_back(std::move(_dynamicInterpreterFile)); return true; } Index: lib/ReaderWriter/ELF/ELFLinkingContext.cpp =================================================================== --- lib/ReaderWriter/ELF/ELFLinkingContext.cpp +++ lib/ReaderWriter/ELF/ELFLinkingContext.cpp @@ -259,7 +259,7 @@ // If strong defined atom coalesces away an atom declared // in the shared object the strong atom needs to be dynamically exported. // Save its name. - _sharedLibCoalescedSymbols.insert(ua->name()); + _dynamicallyExportedSymbols.insert(ua->name()); } } // end namespace lld Index: lib/ReaderWriter/ELF/ExecutableWriter.h =================================================================== --- lib/ReaderWriter/ELF/ExecutableWriter.h +++ lib/ReaderWriter/ELF/ExecutableWriter.h @@ -27,7 +27,8 @@ public: ExecutableWriter(const ELFLinkingContext &context, TargetLayout &layout) : OutputELFWriter(context, layout), - _runtimeFile(new CRuntimeFile(context)) {} + _runtimeFile(new CRuntimeFile(context)), + _dynamicInterpreterFile(new SimpleFile(context.getInterpreter())) {} protected: virtual void addDefaultAtoms(); @@ -36,6 +37,7 @@ virtual void createDefaultSections(); LLD_UNIQUE_BUMP_PTR(InterpSection) _interpSection; std::unique_ptr > _runtimeFile; + std::unique_ptr _dynamicInterpreterFile; }; //===----------------------------------------------------------------------===// @@ -64,6 +66,9 @@ } _runtimeFile->addAbsoluteAtom("__fini_array_start"); _runtimeFile->addAbsoluteAtom("__fini_array_end"); + if (this->_context.isDynamic()) + _dynamicInterpreterFile->addAtom( + *new (this->_alloc) TLSGETADDRAtom(*_dynamicInterpreterFile)); } /// \brief Hook in lld to add CRuntime file @@ -74,6 +79,7 @@ ExecutableWriter::addDefaultAtoms(); OutputELFWriter::createImplicitFiles(result); result.push_back(std::move(_runtimeFile)); + result.push_back(std::move(_dynamicInterpreterFile)); return true; } Index: lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h =================================================================== --- lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h +++ lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h @@ -68,9 +68,6 @@ // 2. Set of shared library atoms have corresponding R_MIPS_COPY copies. if (const auto *da = dyn_cast(atom)) for (const Reference *ref : *da) { - if (const auto *sla = dyn_cast(ref->target())) - _referencedDynAtoms.insert(sla); - if (ref->kindNamespace() == lld::Reference::KindNamespace::ELF) { assert(ref->kindArch() == Reference::KindArch::Mips); if (ref->kindValue() == llvm::ELF::R_MIPS_COPY) @@ -81,10 +78,6 @@ return TargetLayout::addAtom(atom); } - bool isReferencedByDefinedAtom(const SharedLibraryAtom *sla) const { - return _referencedDynAtoms.count(sla); - } - bool isCopied(const SharedLibraryAtom *sla) const { return _copiedDynSymNames.count(sla->name()); } @@ -116,7 +109,6 @@ MipsPLTSection *_pltSection; llvm::Optional _gpAtom; llvm::Optional _gpDispAtom; - llvm::DenseSet _referencedDynAtoms; llvm::StringSet<> _copiedDynSymNames; }; Index: lib/ReaderWriter/ELF/OutputELFWriter.h =================================================================== --- lib/ReaderWriter/ELF/OutputELFWriter.h +++ lib/ReaderWriter/ELF/OutputELFWriter.h @@ -110,11 +110,14 @@ /// \brief Create entry in the dynamic symbols table for this atom. virtual bool isDynSymEntryRequired(const SharedLibraryAtom *sla) const { - return true; + return _layout.isReferencedByDefinedAtom(sla); } /// \brief Create DT_NEEDED dynamic tage for the shared library. virtual bool isNeededTagRequired(const SharedLibraryAtom *sla) const { + // No need to mark dynamic interpreter's own atoms as needed + if (sla->loadName() == "_ld_so") + return false; return true; } @@ -183,7 +186,7 @@ for (const auto &atom : section->atoms()) { const DefinedAtom *da = dyn_cast(atom->_atom); if (da && (da->dynamicExport() == DefinedAtom::dynamicExportAlways || - _context.hasCoalescedSharedLibPair(da->name()))) + _context.isDynamicallyExportedSymbol(da->name()))) _dynamicSymbolTable->addSymbol(atom->_atom, section->ordinal(), atom->_virtualAddr, atom); } Index: lib/ReaderWriter/ELF/X86_64/X86_64DynamicLibraryWriter.h =================================================================== --- lib/ReaderWriter/ELF/X86_64/X86_64DynamicLibraryWriter.h +++ lib/ReaderWriter/ELF/X86_64/X86_64DynamicLibraryWriter.h @@ -57,7 +57,6 @@ std::vector> &result) { DynamicLibraryWriter::createImplicitFiles(result); _gotFile->addAtom(*new (_gotFile->_alloc) GLOBAL_OFFSET_TABLEAtom(*_gotFile)); - _gotFile->addAtom(*new (_gotFile->_alloc) TLSGETADDRAtom(*_gotFile)); _gotFile->addAtom(*new (_gotFile->_alloc) DYNAMICAtom(*_gotFile)); result.push_back(std::move(_gotFile)); return true; Index: lib/ReaderWriter/ELF/X86_64/X86_64ExecutableWriter.h =================================================================== --- lib/ReaderWriter/ELF/X86_64/X86_64ExecutableWriter.h +++ lib/ReaderWriter/ELF/X86_64/X86_64ExecutableWriter.h @@ -56,7 +56,6 @@ std::vector> &result) { ExecutableWriter::createImplicitFiles(result); _gotFile->addAtom(*new (_gotFile->_alloc) GLOBAL_OFFSET_TABLEAtom(*_gotFile)); - _gotFile->addAtom(*new (_gotFile->_alloc) TLSGETADDRAtom(*_gotFile)); if (_context.isDynamic()) _gotFile->addAtom(*new (_gotFile->_alloc) DYNAMICAtom(*_gotFile)); result.push_back(std::move(_gotFile)); Index: lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h =================================================================== --- lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h +++ lib/ReaderWriter/ELF/X86_64/X86_64LinkingContext.h @@ -50,6 +50,8 @@ case llvm::ELF::R_X86_64_RELATIVE: case llvm::ELF::R_X86_64_GLOB_DAT: case llvm::ELF::R_X86_64_COPY: + case llvm::ELF::R_X86_64_DTPMOD64: + case llvm::ELF::R_X86_64_DTPOFF64: return true; default: return false; Index: lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.cpp =================================================================== --- lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.cpp +++ lib/ReaderWriter/ELF/X86_64/X86_64RelocationHandler.cpp @@ -88,6 +88,10 @@ } break; } + case R_X86_64_TLSGD: { + relocPC32(location, relocVAddress, targetVAddress, ref.addend()); + break; + } case R_X86_64_TLSLD: { // Rewrite to move %fs:0 into %rax. Technically we should verify that the // next relocation is a PC32 to __tls_get_addr... @@ -115,6 +119,8 @@ case R_X86_64_IRELATIVE: case R_X86_64_JUMP_SLOT: case R_X86_64_GLOB_DAT: + case R_X86_64_DTPMOD64: + case R_X86_64_DTPOFF64: break; default: { std::string str; Index: lib/ReaderWriter/ELF/X86_64/X86_64RelocationPass.cpp =================================================================== --- lib/ReaderWriter/ELF/X86_64/X86_64RelocationPass.cpp +++ lib/ReaderWriter/ELF/X86_64/X86_64RelocationPass.cpp @@ -50,6 +50,12 @@ 0xe9, 0x00, 0x00, 0x00, 0x00 // jmpq plt[-1] }; +// TLS GD Entry +static const uint8_t x86_64GotTlsGdAtomContent[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + /// \brief Atoms that are used by X86_64 dynamic linking class X86_64GOTAtom : public GOTAtom { public: @@ -60,6 +66,16 @@ } }; +/// \brief X86_64 GOT TLS GD entry. +class GOTTLSGdAtom : public X86_64GOTAtom { +public: + GOTTLSGdAtom(const File &f, StringRef secName) : X86_64GOTAtom(f, secName) {} + + ArrayRef rawContent() const override { + return llvm::makeArrayRef(x86_64GotTlsGdAtomContent); + } +}; + class X86_64PLT0Atom : public PLT0Atom { public: X86_64PLT0Atom(const File &f) : PLT0Atom(f) { @@ -117,6 +133,9 @@ case R_X86_64_GOTTPOFF: // GOT Thread Pointer Offset static_cast(this)->handleGOTTPOFF(ref); break; + case R_X86_64_TLSGD: + static_cast(this)->handleTLSGd(ref); + break; } } @@ -180,6 +199,11 @@ const_cast(ref).setKindValue(R_X86_64_PC32); } + /// \brief Create a TLS GOT entry with DTPMOD64/DTPOFF64 dynamic relocations. + void handleTLSGd(const Reference &ref) { + const_cast(ref).setTarget(getTLSGdGOTEntry(ref.target())); + } + /// \brief Create a GOT entry containing 0. const GOTAtom *getNullGOT() { if (!_null) { @@ -207,6 +231,21 @@ return got->second; } + const GOTAtom *getTLSGdGOTEntry(const Atom *a) { + auto got = _gotTLSGdMap.find(a); + if (got != _gotTLSGdMap.end()) + return got->second; + + auto ga = new (_file._alloc) GOTTLSGdAtom(_file, ".got"); + _gotTLSGdMap[a] = ga; + + _tlsGotVector.push_back(ga); + ga->addReferenceELF_x86_64(R_X86_64_DTPMOD64, 0, a, 0); + ga->addReferenceELF_x86_64(R_X86_64_DTPOFF64, 8, a, 0); + + return ga; + } + public: RelocationPass(const ELFLinkingContext &ctx) : _file(ctx), _ctx(ctx), _null(nullptr), _PLT0(nullptr), _got0(nullptr), @@ -251,6 +290,10 @@ got->setOrdinal(ordinal++); mf->addAtom(*got); } + for (auto &got : _tlsGotVector) { + got->setOrdinal(ordinal++); + mf->addAtom(*got); + } for (auto obj : _objectVector) { obj->setOrdinal(ordinal++); mf->addAtom(*obj); @@ -268,6 +311,9 @@ /// \brief Map Atoms to their PLT entries. llvm::DenseMap _pltMap; + /// \brief Map Atoms to TLS GD GOT entries. + llvm::DenseMap _gotTLSGdMap; + /// \brief Map Atoms to their Object entries. llvm::DenseMap _objectMap; @@ -276,6 +322,9 @@ std::vector _pltVector; std::vector _objectVector; + /// \brief the list of TLS GOT atoms. + std::vector _tlsGotVector; + /// \brief GOT entry that is always 0. Used for undefined weaks. GOTAtom *_null; Index: test/elf/X86_64/Inputs/generaltls-so.o.yaml =================================================================== --- /dev/null +++ test/elf/X86_64/Inputs/generaltls-so.o.yaml @@ -0,0 +1,68 @@ +--- +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + OSABI: ELFOSABI_GNU + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x0000000000000010 + Content: 554889E566488D3D00000000666648E8000000008B005DC3 + - Name: .rela.text + Type: SHT_RELA + Link: .symtab + AddressAlign: 0x0000000000000008 + Info: .text + Relocations: + - Offset: 0x0000000000000008 + Symbol: mynumber + Type: R_X86_64_TLSGD + Addend: -4 + - Offset: 0x0000000000000010 + Symbol: __tls_get_addr + Type: R_X86_64_PLT32 + Addend: -4 + - Name: .data + Type: SHT_PROGBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + AddressAlign: 0x0000000000000004 + Content: '' + - Name: .bss + Type: SHT_NOBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + AddressAlign: 0x0000000000000004 + Content: '' + - Name: .tdata + Type: SHT_PROGBITS + Flags: [ SHF_WRITE, SHF_ALLOC, SHF_TLS ] + AddressAlign: 0x0000000000000004 + Content: '21000000' +Symbols: + Local: + - Name: .text + Type: STT_SECTION + Section: .text + - Name: .data + Type: STT_SECTION + Section: .data + - Name: .bss + Type: STT_SECTION + Section: .bss + - Name: .tdata + Type: STT_SECTION + Section: .tdata + Global: + - Name: getnumber + Type: STT_FUNC + Section: .text + Size: 0x0000000000000018 + - Name: mynumber + Type: STT_TLS + Section: .tdata + Size: 0x0000000000000004 + - Name: _GLOBAL_OFFSET_TABLE_ + - Name: __tls_get_addr +... Index: test/elf/X86_64/general-dynamic-tls.test =================================================================== --- /dev/null +++ test/elf/X86_64/general-dynamic-tls.test @@ -0,0 +1,126 @@ +# This test exercises a simple general dynamic TLS access model in X86_64. +# +# It is composed of two parts: a program and a shared library. The shared +# library uses TLS, but the program does not. +# +# The shared library should import __tls_get_addr, since it uses the general +# dynamic TLS access mode (see www.akkadia.org/drepper/tls.pdf). Notice that +# once we support TLS strength reduction, this test should be updated, since +# this can be converted into a local dynamic TLS model. + +# Prepare inputs +#RUN: yaml2obj -format=elf %p/Inputs/generaltls-so.o.yaml -o=%t.o.so +#RUN: lld -flavor gnu -target x86_64 -shared %t.o.so -o %T/libgeneraltls.so +#RUN: yaml2obj -format=elf %s -o=%t.o + +# Link +#RUN: lld -flavor gnu -target x86_64 -e main %t.o -L%T -lgeneraltls -o %t1 + +# Check +#RUN: llvm-readobj -dyn-symbols %t1 | FileCheck -check-prefix CHECKPROG %s +#RUN: llvm-readobj -relocations -dyn-symbols %T/libgeneraltls.so | FileCheck \ +#RUN: -check-prefix CHECKDSO %s + +# Test case generated with the following code: +# +# DSO: (file %p/Inputs/generaltls-so.o.yaml) +# +# __thread int mynumber=33; +# +# int getnumber() { +# return mynumber; +# } +# +# Program: (this file). Note: The printf() relocation was removed to simplify +# this test and allow us to test this without libc. +# +# #include +# int getnumber(); +# +# int main() { +# printf("getnumber() = %d\n", getnumber()); +# return 0; +# } +# +--- +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + OSABI: ELFOSABI_GNU + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x0000000000000010 + Content: 554889E54883EC10C745FC00000000B000E80000000048BF000000000000000089C6B000E80000000031F68945F889F04883C4105DC3 + - Name: .rela.text + Type: SHT_RELA + Link: .symtab + AddressAlign: 0x0000000000000008 + Info: .text + Relocations: + - Offset: 0x0000000000000012 + Symbol: getnumber + Type: R_X86_64_PC32 + Addend: -4 + - Offset: 0x0000000000000018 + Symbol: .rodata.str1.1 + Type: R_X86_64_64 + Addend: 0 + - Name: .data + Type: SHT_PROGBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + AddressAlign: 0x0000000000000004 + Content: '' + - Name: .bss + Type: SHT_NOBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + AddressAlign: 0x0000000000000004 + Content: '' + - Name: .rodata.str1.1 + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_MERGE, SHF_STRINGS ] + AddressAlign: 0x0000000000000001 + Content: 6765746E756D6265722829203D2025640A00 +Symbols: + Local: + - Name: .text + Type: STT_SECTION + Section: .text + - Name: .data + Type: STT_SECTION + Section: .data + - Name: .bss + Type: STT_SECTION + Section: .bss + - Name: .rodata.str1.1 + Type: STT_SECTION + Section: .rodata.str1.1 + Global: + - Name: main + Type: STT_FUNC + Section: .text + Size: 0x0000000000000036 + - Name: getnumber + +# Program should import the function defined in the shared library +#CHECKPROG: getnumber@ +# Program should not import __tls_get_addr, since it does not directly use TLS +#CHECKPROG-NOT: __tls_get_addr@ + +# Check for the presence of X86_64 TLS relocations in the shared library +#CHECKDSO: R_X86_64_DTPMOD64 +#CHECKDSO: R_X86_64_DTPOFF64 + +# The shared library should import __tls_get_addr, since it uses the general +# dynamic TLS access mode. +#CHECKDSO: Name: __tls_get_addr@ +#CHECKDSO-NEXT: Value: 0x0 +#CHECKDSO-NEXT: Size: 0 +#CHECKDSO-NEXT: Binding: Global +#CHECKDSO-NEXT: Type: Function +#CHECKDSO-NEXT: Other: 0 +#CHECKDSO-NEXT: Section: Undefined + Index: test/elf/X86_64/omagic.test =================================================================== --- test/elf/X86_64/omagic.test +++ test/elf/X86_64/omagic.test @@ -185,7 +185,7 @@ OMAGICSECTIONS: ] OMAGICSECTIONS: Address: 0x0 OMAGICSECTIONS: Offset: 0x1E8 -OMAGICSECTIONS: Size: 528 +OMAGICSECTIONS: Size: 504 OMAGICSECTIONS: Link: 13 OMAGICSECTIONS: Info: 2 OMAGICSECTIONS: AddressAlignment: 8 @@ -197,8 +197,8 @@ OMAGICSECTIONS: Flags [ (0x0) OMAGICSECTIONS: ] OMAGICSECTIONS: Address: 0x0 -OMAGICSECTIONS: Offset: 0x3F8 -OMAGICSECTIONS: Size: 246 +OMAGICSECTIONS: Offset: 0x3E0 +OMAGICSECTIONS: Size: 231 OMAGICSECTIONS: Link: 0 OMAGICSECTIONS: Info: 0 OMAGICSECTIONS: AddressAlignment: 1 Index: test/elf/X86_64/undef.test =================================================================== --- test/elf/X86_64/undef.test +++ test/elf/X86_64/undef.test @@ -7,7 +7,7 @@ RUN: llvm-readobj -symbols %t | FileCheck %s SYMFROMARCHIVE: Symbol { -SYMFROMARCHIVE: Name: fn (16) +SYMFROMARCHIVE: Name: fn ({{[0-9]+}} SYMFROMARCHIVE: Size: 11 SYMFROMARCHIVE: Binding: Global (0x1) SYMFROMARCHIVE: Type: Function (0x2) Index: test/elf/X86_64/underscore-end.test =================================================================== --- test/elf/X86_64/underscore-end.test +++ test/elf/X86_64/underscore-end.test @@ -7,7 +7,7 @@ RUN: llvm-readobj -symbols %t | FileCheck -check-prefix=OMAGICABSSYMBOLS %s NMAGICABSSYMBOLS: Symbol { -NMAGICABSSYMBOLS: Name: __bss_start (51) +NMAGICABSSYMBOLS: Name: __bss_start ({{[0-9]+}} NMAGICABSSYMBOLS: Value: 0x40100C NMAGICABSSYMBOLS: Size: 0 NMAGICABSSYMBOLS: Binding: Global (0x1) @@ -16,7 +16,7 @@ NMAGICABSSYMBOLS: Section: Absolute (0xFFF1) NMAGICABSSYMBOLS: } NMAGICABSSYMBOLS: Symbol { -NMAGICABSSYMBOLS: Name: __bss_end (63) +NMAGICABSSYMBOLS: Name: __bss_end ({{[0-9]+}} NMAGICABSSYMBOLS: Value: 0x40100C NMAGICABSSYMBOLS: Size: 0 NMAGICABSSYMBOLS: Binding: Global (0x1) @@ -25,7 +25,7 @@ NMAGICABSSYMBOLS: Section: Absolute (0xFFF1) NMAGICABSSYMBOLS: } NMAGICABSSYMBOLS: Symbol { -NMAGICABSSYMBOLS: Name: _end (73) +NMAGICABSSYMBOLS: Name: _end ({{[0-9]+}} NMAGICABSSYMBOLS: Value: 0x40100C NMAGICABSSYMBOLS: Size: 0 NMAGICABSSYMBOLS: Binding: Global (0x1) @@ -34,7 +34,7 @@ NMAGICABSSYMBOLS: Section: Absolute (0xFFF1) NMAGICABSSYMBOLS: } NMAGICABSSYMBOLS: Symbol { -NMAGICABSSYMBOLS: Name: end (78) +NMAGICABSSYMBOLS: Name: end ({{[0-9]+}} NMAGICABSSYMBOLS: Value: 0x40100C NMAGICABSSYMBOLS: Size: 0 NMAGICABSSYMBOLS: Binding: Global (0x1) @@ -44,7 +44,7 @@ NMAGICABSSYMBOLS: } OMAGICABSSYMBOLS: Symbol { -OMAGICABSSYMBOLS: Name: __bss_start (51) +OMAGICABSSYMBOLS: Name: __bss_start ({{[0-9]+}}) OMAGICABSSYMBOLS: Value: 0x400144 OMAGICABSSYMBOLS: Size: 0 OMAGICABSSYMBOLS: Binding: Global (0x1) @@ -53,7 +53,7 @@ OMAGICABSSYMBOLS: Section: Absolute (0xFFF1) OMAGICABSSYMBOLS: } OMAGICABSSYMBOLS: Symbol { -OMAGICABSSYMBOLS: Name: __bss_end (63) +OMAGICABSSYMBOLS: Name: __bss_end ({{[0-9]+}} OMAGICABSSYMBOLS: Value: 0x400144 OMAGICABSSYMBOLS: Size: 0 OMAGICABSSYMBOLS: Binding: Global (0x1) @@ -62,7 +62,7 @@ OMAGICABSSYMBOLS: Section: Absolute (0xFFF1) OMAGICABSSYMBOLS: } OMAGICABSSYMBOLS: Symbol { -OMAGICABSSYMBOLS: Name: _end (73) +OMAGICABSSYMBOLS: Name: _end ({{[0-9]+}} OMAGICABSSYMBOLS: Value: 0x400144 OMAGICABSSYMBOLS: Size: 0 OMAGICABSSYMBOLS: Binding: Global (0x1) @@ -71,7 +71,7 @@ OMAGICABSSYMBOLS: Section: Absolute (0xFFF1) OMAGICABSSYMBOLS: } OMAGICABSSYMBOLS: Symbol { -OMAGICABSSYMBOLS: Name: end (78) +OMAGICABSSYMBOLS: Name: end ({{[0-9]+}} OMAGICABSSYMBOLS: Value: 0x400144 OMAGICABSSYMBOLS: Size: 0 OMAGICABSSYMBOLS: Binding: Global (0x1) Index: test/elf/undef-from-main-dso.test =================================================================== --- test/elf/undef-from-main-dso.test +++ test/elf/undef-from-main-dso.test @@ -41,4 +41,3 @@ CHECK-NEXT: Other: 0 CHECK-NEXT: Section: .bss -CHECK: Name: x@ ({{[0-9]+}}