summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/SymbolTable.cpp8
-rw-r--r--lld/ELF/SymbolTable.h1
-rw-r--r--lld/ELF/SyntheticSections.cpp4
-rw-r--r--lld/test/ELF/init-fini.s17
4 files changed, 25 insertions, 5 deletions
diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp
index 6afe3dde9ba..eceb6dc96e1 100644
--- a/lld/ELF/SymbolTable.cpp
+++ b/lld/ELF/SymbolTable.cpp
@@ -468,6 +468,14 @@ template <class ELFT> SymbolBody *SymbolTable<ELFT>::find(StringRef Name) {
}
template <class ELFT>
+SymbolBody *SymbolTable<ELFT>::findDefined(StringRef Name) {
+ if (SymbolBody *S = find(Name))
+ if (S->isDefined() && !S->isShared())
+ return S;
+ return nullptr;
+}
+
+template <class ELFT>
void SymbolTable<ELFT>::addLazyArchive(ArchiveFile *F,
const object::Archive::Symbol Sym) {
Symbol *S;
diff --git a/lld/ELF/SymbolTable.h b/lld/ELF/SymbolTable.h
index 1e5a335acc1..bfed1a79829 100644
--- a/lld/ELF/SymbolTable.h
+++ b/lld/ELF/SymbolTable.h
@@ -82,6 +82,7 @@ public:
void scanVersionScript();
SymbolBody *find(StringRef Name);
+ SymbolBody *findDefined(StringRef Name);
void trace(StringRef Name);
void wrap(StringRef Name);
diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index 5486b38eec1..302a6ee51fc 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -883,9 +883,9 @@ template <class ELFT> void DynamicSection<ELFT>::finalize() {
add({DT_FINI_ARRAYSZ, Out<ELFT>::FiniArray, Entry::SecSize});
}
- if (SymbolBody *B = Symtab<ELFT>::X->find(Config->Init))
+ if (SymbolBody *B = Symtab<ELFT>::X->findDefined(Config->Init))
add({DT_INIT, B});
- if (SymbolBody *B = Symtab<ELFT>::X->find(Config->Fini))
+ if (SymbolBody *B = Symtab<ELFT>::X->findDefined(Config->Fini))
add({DT_FINI, B});
bool HasVerNeed = In<ELFT>::VerNeed->getNeedNum() != 0;
diff --git a/lld/test/ELF/init-fini.s b/lld/test/ELF/init-fini.s
index 40067906663..37d8b014907 100644
--- a/lld/test/ELF/init-fini.s
+++ b/lld/test/ELF/init-fini.s
@@ -17,11 +17,22 @@
// RUN: ld.lld -shared %t -o %t2 -init=_foo -fini=_bar
// RUN: llvm-readobj -dynamic-table %t2 | FileCheck --check-prefix=OVR %s
-// Should add a dynamic table entry even if a given symbol stay undefined
+// Don't add an entry for undef. The freebsd dynamic linker doesn't
+// check if the value is null. If it is, it will just call the
+// load address.
// RUN: ld.lld -shared %t -o %t2 -init=_undef -fini=_undef
// RUN: llvm-readobj -dynamic-table %t2 | FileCheck --check-prefix=UNDEF %s
-// UNDEF: INIT 0x0
-// UNDEF: FINI 0x0
+// UNDEF-NOT: INIT
+// UNDEF-NOT: FINI
+
+// Don't add an entry for shared. For the same reason as undef.
+// RUN: ld.lld -shared %t -o %t.so
+// RUN: echo > %t.s
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %t.s -o %t2.o
+// RUN: ld.lld -shared %t2.o %t.so -o %t2
+// RUN: llvm-readobj -dynamic-table %t2 | FileCheck --check-prefix=SHARED %s
+// SHARED-NOT: INIT
+// SHARED-NOT: FINI
// Should not add new entries to the symbol table
// and should not require given symbols to be resolved
OpenPOWER on IntegriCloud