diff options
| -rw-r--r-- | lld/ELF/SymbolTable.cpp | 8 | ||||
| -rw-r--r-- | lld/ELF/SymbolTable.h | 1 | ||||
| -rw-r--r-- | lld/ELF/SyntheticSections.cpp | 4 | ||||
| -rw-r--r-- | lld/test/ELF/init-fini.s | 17 |
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 |

