[lld] r326176 - [ELF] Create and export symbols provided by a linker script if they referenced by DSOs.
Igor Kudrin via llvm-commits
llvm-commits at lists.llvm.org
Mon Feb 26 23:18:07 PST 2018
Author: ikudrin
Date: Mon Feb 26 23:18:07 2018
New Revision: 326176
URL: http://llvm.org/viewvc/llvm-project?rev=326176&view=rev
Log:
[ELF] Create and export symbols provided by a linker script if they referenced by DSOs.
It should be possible to resolve undefined symbols in dynamic libraries
using symbols defined in a linker script.
Differential Revision: https://reviews.llvm.org/D43011
Added:
lld/trunk/test/ELF/linkerscript/Inputs/provide-shared2.s
lld/trunk/test/ELF/linkerscript/provide-shared2.s
Modified:
lld/trunk/ELF/Driver.cpp
lld/trunk/ELF/InputFiles.cpp
lld/trunk/ELF/InputFiles.h
lld/trunk/ELF/LinkerScript.cpp
lld/trunk/ELF/SymbolTable.cpp
Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=326176&r1=326175&r2=326176&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Mon Feb 26 23:18:07 2018
@@ -1080,6 +1080,11 @@ template <class ELFT> void LinkerDriver:
if (errorCount())
return;
+ // We want to declare linker script's symbols early,
+ // so that we can version them.
+ // They also might be exported if referenced by DSOs.
+ Script->declareSymbols();
+
// Handle undefined symbols in DSOs.
if (!Config->Shared)
Symtab->scanShlibUndefined<ELFT>();
@@ -1097,10 +1102,6 @@ template <class ELFT> void LinkerDriver:
if (!Config->Relocatable)
addReservedSymbols();
- // We want to declare linker script's symbols early,
- // so that we can version them.
- Script->declareSymbols();
-
// Apply version scripts.
//
// For a relocatable output, version scripts don't make sense, and
Modified: lld/trunk/ELF/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=326176&r1=326175&r2=326176&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.cpp (original)
+++ lld/trunk/ELF/InputFiles.cpp Mon Feb 26 23:18:07 2018
@@ -851,7 +851,7 @@ template <class ELFT> void SharedFile<EL
StringRef Name = CHECK(Sym.getName(this->StringTable), this);
if (Sym.isUndefined()) {
- Undefs.push_back(Name);
+ this->Undefs.insert(Name);
continue;
}
Modified: lld/trunk/ELF/InputFiles.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.h?rev=326176&r1=326175&r2=326176&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.h (original)
+++ lld/trunk/ELF/InputFiles.h Mon Feb 26 23:18:07 2018
@@ -93,6 +93,13 @@ public:
return Symbols;
}
+ // Returns undefined symbols of a shared library.
+ // It is a runtime error to call this function on files of other types.
+ const llvm::DenseSet<StringRef> &getUndefinedSymbols() {
+ assert(FileKind == SharedKind);
+ return Undefs;
+ }
+
// Filename of .a which contained this file. If this file was
// not in an archive file, it is the empty string. We use this
// string for creating error messages.
@@ -114,6 +121,7 @@ protected:
InputFile(Kind K, MemoryBufferRef M);
std::vector<InputSectionBase *> Sections;
std::vector<Symbol *> Symbols;
+ llvm::DenseSet<StringRef> Undefs;
private:
const Kind FileKind;
@@ -288,7 +296,6 @@ template <class ELFT> class SharedFile :
typedef typename ELFT::Verdef Elf_Verdef;
typedef typename ELFT::Versym Elf_Versym;
- std::vector<StringRef> Undefs;
const Elf_Shdr *VersymSec = nullptr;
const Elf_Shdr *VerdefSec = nullptr;
@@ -296,8 +303,6 @@ public:
std::vector<const Elf_Verdef *> Verdefs;
std::string SoName;
- llvm::ArrayRef<StringRef> getUndefinedSymbols() { return Undefs; }
-
static bool classof(const InputFile *F) {
return F->kind() == Base::SharedKind;
}
Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=326176&r1=326175&r2=326176&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Mon Feb 26 23:18:07 2018
@@ -127,9 +127,13 @@ static bool shouldDefineSym(SymbolAssign
// If a symbol was in PROVIDE(), we need to define it only
// when it is a referenced undefined symbol.
Symbol *B = Symtab->find(Cmd->Name);
- if (!B || B->isDefined())
- return false;
- return true;
+ if (B && !B->isDefined())
+ return true;
+ // It might also be referenced by a DSO.
+ for (InputFile *F : SharedFiles)
+ if (F->getUndefinedSymbols().count(Cmd->Name))
+ return true;
+ return false;
}
// This function is called from processSectionCommands,
Modified: lld/trunk/ELF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=326176&r1=326175&r2=326176&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.cpp (original)
+++ lld/trunk/ELF/SymbolTable.cpp Mon Feb 26 23:18:07 2018
@@ -597,7 +597,7 @@ template <class ELFT> void SymbolTable::
// Except this, we ignore undefined symbols in DSOs.
template <class ELFT> void SymbolTable::scanShlibUndefined() {
for (InputFile *F : SharedFiles) {
- for (StringRef U : cast<SharedFile<ELFT>>(F)->getUndefinedSymbols()) {
+ for (StringRef U : F->getUndefinedSymbols()) {
Symbol *Sym = find(U);
if (!Sym)
continue;
Added: lld/trunk/test/ELF/linkerscript/Inputs/provide-shared2.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/Inputs/provide-shared2.s?rev=326176&view=auto
==============================================================================
--- lld/trunk/test/ELF/linkerscript/Inputs/provide-shared2.s (added)
+++ lld/trunk/test/ELF/linkerscript/Inputs/provide-shared2.s Mon Feb 26 23:18:07 2018
@@ -0,0 +1,3 @@
+.global foo
+.data
+.dc.a foo
Added: lld/trunk/test/ELF/linkerscript/provide-shared2.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/provide-shared2.s?rev=326176&view=auto
==============================================================================
--- lld/trunk/test/ELF/linkerscript/provide-shared2.s (added)
+++ lld/trunk/test/ELF/linkerscript/provide-shared2.s Mon Feb 26 23:18:07 2018
@@ -0,0 +1,13 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/provide-shared2.s -o %t2.o
+# RUN: ld.lld %t2.o -o %t2.so -shared
+# RUN: echo "SECTIONS { . = . + SIZEOF_HEADERS; PROVIDE(foo = 42); }" > %t.script
+# RUN: ld.lld -o %t --script %t.script %t.o %t2.so
+# RUN: llvm-readelf --dyn-symbols %t | FileCheck %s
+
+# CHECK: 1 1: 000000000000002a 0 NOTYPE GLOBAL DEFAULT ABS foo@
+
+.global _start
+_start:
+ nop
More information about the llvm-commits
mailing list