aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChih-Hung Hsieh <chh@google.com>2018-03-13 23:16:53 -0700
committerYi Kong <yikong@google.com>2019-03-01 10:37:33 -0800
commit3ee225094a683a0f52ad9a00299a7f2004a2c997 (patch)
tree709edd9eed789e36e5501d4db10add8cc4d03f86
parent35c021c49f44cd4e06875c4b1398a2b3464132bb (diff)
downloadlld-main.tar.gz
Revert two changes that break Android builds.HEADmastermainllvm-r353983
* Earlier versions of lld were able to replace Android's lld.gold and link most files. * With two recent lld changes, debuggerd_test64 and some other files failed to link because libunwindstack.a is linked like --whole-archive. We need to revert the following two changes: * "Put undefined symbols from shared libraries in the symbol table." lld/trunk@326242 * "Make undefined symbol in DSO to pull out object files from archive files." lld/trunk@325849 Bug: 74755833 Change-Id: I21b0df5e3c19bdfff4ea6c0ff9e9e562bd73f921
-rw-r--r--ELF/Driver.cpp4
-rw-r--r--ELF/InputFiles.cpp5
-rw-r--r--ELF/InputFiles.h8
-rw-r--r--ELF/LinkerScript.cpp4
-rw-r--r--ELF/SymbolTable.cpp24
-rw-r--r--ELF/SymbolTable.h1
-rw-r--r--test/ELF/shlib-undefined-archive.s19
-rw-r--r--test/ELF/trace-symbols.s2
8 files changed, 43 insertions, 24 deletions
diff --git a/ELF/Driver.cpp b/ELF/Driver.cpp
index e2aa7e944..ad4d549ec 100644
--- a/ELF/Driver.cpp
+++ b/ELF/Driver.cpp
@@ -1544,6 +1544,10 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
// They also might be exported if referenced by DSOs.
Script->declareSymbols();
+ // Handle undefined symbols in DSOs.
+ if (!Config->Shared)
+ Symtab->scanShlibUndefined<ELFT>();
+
// Handle the -exclude-libs option.
if (Args.hasArg(OPT_exclude_libs))
excludeLibs<ELFT>(Args);
diff --git a/ELF/InputFiles.cpp b/ELF/InputFiles.cpp
index c3e5b2f48..edeb80cc0 100644
--- a/ELF/InputFiles.cpp
+++ b/ELF/InputFiles.cpp
@@ -1018,10 +1018,7 @@ template <class ELFT> void SharedFile<ELFT>::parseRest() {
}
if (Sym.isUndefined()) {
- Symbol *S = Symtab->addUndefined<ELFT>(Name, Sym.getBinding(),
- Sym.st_other, Sym.getType(),
- /*CanOmitFromDynSym=*/false, this);
- S->ExportDynamic = true;
+ this->Undefs.insert(Name);
continue;
}
diff --git a/ELF/InputFiles.h b/ELF/InputFiles.h
index 105e5ecbd..1d7081bca 100644
--- a/ELF/InputFiles.h
+++ b/ELF/InputFiles.h
@@ -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.
@@ -139,6 +146,7 @@ protected:
InputFile(Kind K, MemoryBufferRef M);
std::vector<InputSectionBase *> Sections;
std::vector<Symbol *> Symbols;
+ llvm::DenseSet<StringRef> Undefs;
private:
const Kind FileKind;
diff --git a/ELF/LinkerScript.cpp b/ELF/LinkerScript.cpp
index 2341938a1..4beb5b2c4 100644
--- a/ELF/LinkerScript.cpp
+++ b/ELF/LinkerScript.cpp
@@ -156,6 +156,10 @@ static bool shouldDefineSym(SymbolAssignment *Cmd) {
Symbol *B = Symtab->find(Cmd->Name);
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;
}
diff --git a/ELF/SymbolTable.cpp b/ELF/SymbolTable.cpp
index e25682f80..f5fb41ce1 100644
--- a/ELF/SymbolTable.cpp
+++ b/ELF/SymbolTable.cpp
@@ -599,6 +599,24 @@ template <class ELFT> void SymbolTable::fetchLazy(Symbol *Sym) {
addFile<ELFT>(File);
}
+// This function takes care of the case in which shared libraries depend on
+// the user program (not the other way, which is usual). Shared libraries
+// may have undefined symbols, expecting that the user program provides
+// the definitions for them. An example is BSD's __progname symbol.
+// We need to put such symbols to the main program's .dynsym so that
+// shared libraries can find them.
+// Except this, we ignore undefined symbols in DSOs.
+template <class ELFT> void SymbolTable::scanShlibUndefined() {
+ for (InputFile *F : SharedFiles) {
+ for (StringRef U : F->getUndefinedSymbols()) {
+ Symbol *Sym = find(U);
+ if (!Sym || !Sym->isDefined())
+ continue;
+ Sym->ExportDynamic = true;
+ }
+ }
+}
+
// Initialize DemangledSyms with a map from demangled symbols to symbol
// objects. Used to handle "extern C++" directive in version scripts.
//
@@ -814,3 +832,9 @@ template void SymbolTable::addShared<ELF64LE>(StringRef, SharedFile<ELF64LE> &,
template void SymbolTable::addShared<ELF64BE>(StringRef, SharedFile<ELF64BE> &,
const typename ELF64BE::Sym &,
uint32_t Alignment, uint32_t);
+
+template void SymbolTable::scanShlibUndefined<ELF32LE>();
+template void SymbolTable::scanShlibUndefined<ELF32BE>();
+template void SymbolTable::scanShlibUndefined<ELF64LE>();
+template void SymbolTable::scanShlibUndefined<ELF64BE>();
+
diff --git a/ELF/SymbolTable.h b/ELF/SymbolTable.h
index 9822ed75c..654e362f1 100644
--- a/ELF/SymbolTable.h
+++ b/ELF/SymbolTable.h
@@ -71,6 +71,7 @@ public:
template <class ELFT> void fetchLazy(Symbol *Sym);
+ template <class ELFT> void scanShlibUndefined();
void scanVersionScript();
Symbol *find(StringRef Name);
diff --git a/test/ELF/shlib-undefined-archive.s b/test/ELF/shlib-undefined-archive.s
deleted file mode 100644
index 940d8d7bc..000000000
--- a/test/ELF/shlib-undefined-archive.s
+++ /dev/null
@@ -1,19 +0,0 @@
-# REQUIRES: x86
-
-# Undefined symbols in a DSO should pull out object files from archives
-# to resolve them.
-
-# RUN: echo '.globl foo' | llvm-mc -filetype=obj -triple=x86_64-linux-gnu -o %t1.o -
-# RUN: ld.lld -shared -o %t.so %t1.o
-
-# RUN: llvm-mc -filetype=obj -triple=x86_64-linux-gnu -o %t2.o %s
-# RUN: rm -f %t.a
-# RUN: llvm-ar cru %t.a %t2.o
-# RUN: ld.lld -o %t.exe %t.so %t.a
-# RUN: llvm-nm -D %t.exe | FileCheck %s
-
-# CHECK: T foo
-
-.globl foo
-foo:
- ret
diff --git a/test/ELF/trace-symbols.s b/test/ELF/trace-symbols.s
index 63004b7c1..58aeb5d3d 100644
--- a/test/ELF/trace-symbols.s
+++ b/test/ELF/trace-symbols.s
@@ -72,7 +72,7 @@
# RUN: ld.lld -y foo -y bar %t %t1.so %t2.so -o %t3 | \
# RUN: FileCheck -check-prefix=SHLIBRBAR %s
-# SHLIBRBAR: trace-symbols.s.tmp1.so: reference to bar
+# SHLIBRBAR-NOT: trace-symbols.s.tmp1.so: reference to bar
# RUN: ld.lld -y foo -y bar %t -u bar --start-lib %t1 %t2 --end-lib -o %t3 | \
# RUN: FileCheck -check-prefix=STARTLIB %s