diff options
| -rw-r--r-- | lld/include/lld/ReaderWriter/ELFLinkingContext.h | 6 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp | 14 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/OutputELFWriter.h | 2 | ||||
| -rw-r--r-- | lld/test/elf/Inputs/undef2-so.o.yaml | 50 | ||||
| -rw-r--r-- | lld/test/elf/undef-from-dso-to-main.test | 52 |
5 files changed, 111 insertions, 13 deletions
diff --git a/lld/include/lld/ReaderWriter/ELFLinkingContext.h b/lld/include/lld/ReaderWriter/ELFLinkingContext.h index 577b59866e9..51727fb89c3 100644 --- a/lld/include/lld/ReaderWriter/ELFLinkingContext.h +++ b/lld/include/lld/ReaderWriter/ELFLinkingContext.h @@ -262,8 +262,8 @@ public: void setCreateSeparateROSegment() { _mergeRODataToTextSegment = false; } - bool hasCoalescedWeakPair(StringRef name) const { - return _weakCoalescedSymbols.count(name) != 0; + bool hasCoalescedSharedLibPair(StringRef name) const { + return _sharedLibCoalescedSymbols.count(name) != 0; } private: @@ -300,7 +300,7 @@ protected: StringRefVector _rpathList; StringRefVector _rpathLinkList; std::map<std::string, uint64_t> _absoluteSymbols; - llvm::StringSet<> _weakCoalescedSymbols; + llvm::StringSet<> _sharedLibCoalescedSymbols; }; } // end namespace lld diff --git a/lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp b/lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp index 08f2b8c8f48..003901abf7c 100644 --- a/lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp +++ b/lld/lib/ReaderWriter/ELF/ELFLinkingContext.cpp @@ -241,11 +241,6 @@ std::unique_ptr<File> ELFLinkingContext::createUndefinedSymbolFile() const { return std::move(undefinedSymFile); } -static bool isSharedWeakAtom(const UndefinedAtom *ua) { - return ua->canBeNull() != UndefinedAtom::canBeNullNever && - isa<SharedLibraryFile>(ua->file()); -} - void ELFLinkingContext::notifySymbolTableCoalesce(const Atom *existingAtom, const Atom *newAtom, bool &useNew) { @@ -259,11 +254,12 @@ void ELFLinkingContext::notifySymbolTableCoalesce(const Atom *existingAtom, ua = dyn_cast<UndefinedAtom>(existingAtom); } - if (da && ua && da->scope() == Atom::scopeGlobal && isSharedWeakAtom(ua)) - // If strong defined atom coalesces away weak atom declared - // in the shared object the strong atom needs to be dynamicaly exported. + if (da && ua && da->scope() == Atom::scopeGlobal && + isa<SharedLibraryFile>(ua->file())) + // If strong defined atom coalesces away an atom declared + // in the shared object the strong atom needs to be dynamically exported. // Save its name. - _weakCoalescedSymbols.insert(ua->name()); + _sharedLibCoalescedSymbols.insert(ua->name()); } } // end namespace lld diff --git a/lld/lib/ReaderWriter/ELF/OutputELFWriter.h b/lld/lib/ReaderWriter/ELF/OutputELFWriter.h index bd0af968598..9ed766083bd 100644 --- a/lld/lib/ReaderWriter/ELF/OutputELFWriter.h +++ b/lld/lib/ReaderWriter/ELF/OutputELFWriter.h @@ -183,7 +183,7 @@ void OutputELFWriter<ELFT>::buildDynamicSymbolTable(const File &file) { for (const auto &atom : section->atoms()) { const DefinedAtom *da = dyn_cast<const DefinedAtom>(atom->_atom); if (da && (da->dynamicExport() == DefinedAtom::dynamicExportAlways || - _context.hasCoalescedWeakPair(da->name()))) + _context.hasCoalescedSharedLibPair(da->name()))) _dynamicSymbolTable->addSymbol(atom->_atom, section->ordinal(), atom->_virtualAddr, atom); } diff --git a/lld/test/elf/Inputs/undef2-so.o.yaml b/lld/test/elf/Inputs/undef2-so.o.yaml new file mode 100644 index 00000000000..9ecf374ced1 --- /dev/null +++ b/lld/test/elf/Inputs/undef2-so.o.yaml @@ -0,0 +1,50 @@ +--- +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x0000000000000001 + Content: 554889E5488B05000000008B005DC3 + - Name: .rela.text + Type: SHT_RELA + Link: .symtab + AddressAlign: 0x0000000000000008 + Info: .text + Relocations: + - Offset: 0x0000000000000007 + Symbol: myexportedsymbol + Type: R_X86_64_GOTPCREL + Addend: -4 + - Name: .data + Type: SHT_PROGBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + AddressAlign: 0x0000000000000001 + Content: '' + - Name: .bss + Type: SHT_NOBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + AddressAlign: 0x0000000000000001 + Content: '' +Symbols: + Local: + - Name: .text + Type: STT_SECTION + Section: .text + - Name: .data + Type: STT_SECTION + Section: .data + - Name: .bss + Type: STT_SECTION + Section: .bss + Global: + - Name: func + Type: STT_FUNC + Section: .text + Size: 0x000000000000000F + - Name: _GLOBAL_OFFSET_TABLE_ + - Name: myexportedsymbol diff --git a/lld/test/elf/undef-from-dso-to-main.test b/lld/test/elf/undef-from-dso-to-main.test new file mode 100644 index 00000000000..71d0b51499d --- /dev/null +++ b/lld/test/elf/undef-from-dso-to-main.test @@ -0,0 +1,52 @@ +# Tests that a reference from a DSO to a regular object +# forces the final executable to export the symbol. + +#RUN: yaml2obj -format=elf %p/Inputs/undef2-so.o.yaml -o=%t.o.so +#RUN: lld -flavor gnu -target x86_64 -shared %t.o.so -o %T/libundef2.so +#RUN: yaml2obj -format=elf %s -o=%t.o +#RUN: lld -flavor gnu -target x86_64 %t.o -L%T -lundef2 -o %t1 +#RUN: llvm-readobj -dyn-symbols %t1 | FileCheck -check-prefix CHECKSYMS %s + +--- +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x0000000000000001 + Content: C3 + - Name: .data + Type: SHT_PROGBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + AddressAlign: 0x0000000000000001 + Content: '' + - Name: .bss + Type: SHT_NOBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + AddressAlign: 0x0000000000000004 + Content: '002E7379' +Symbols: + Local: + - Name: .text + Type: STT_SECTION + Section: .text + - Name: .data + Type: STT_SECTION + Section: .data + - Name: .bss + Type: STT_SECTION + Section: .bss + Global: + - Name: myexportedsymbol + Type: STT_OBJECT + Section: .bss + Size: 0x0000000000000004 + - Name: _start + Section: .text + Size: 0x0000000000000001 + +#CHECKSYMS: myexportedsymbol |

