[lld] r291944 - Don't add DT_INIT/DT_FINI for undef and shared symbols.

Rafael Avila de Espindola via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 18 10:53:49 PST 2017


This should probably be ported to 4.0. I can take care of porting it if
it is OK.

Cheers,
Rafael

Rafael Espindola via llvm-commits <llvm-commits at lists.llvm.org> writes:

> Author: rafael
> Date: Fri Jan 13 13:18:11 2017
> New Revision: 291944
>
> URL: http://llvm.org/viewvc/llvm-project?rev=291944&view=rev
> Log:
> Don't add DT_INIT/DT_FINI for undef and shared symbols.
>
> The freebsd dynamic linker doesn't check if the value is null (and it
> is reasonable for it to do that). That means that producing a .so with
> a null DT_INIT/DT_FINI causes the base address to be called.
>
> This should fix the libreoffice build.
>
> Modified:
>     lld/trunk/ELF/SymbolTable.cpp
>     lld/trunk/ELF/SymbolTable.h
>     lld/trunk/ELF/SyntheticSections.cpp
>     lld/trunk/test/ELF/init-fini.s
>
> Modified: lld/trunk/ELF/SymbolTable.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=291944&r1=291943&r2=291944&view=diff
> ==============================================================================
> --- lld/trunk/ELF/SymbolTable.cpp (original)
> +++ lld/trunk/ELF/SymbolTable.cpp Fri Jan 13 13:18:11 2017
> @@ -468,6 +468,14 @@ template <class ELFT> SymbolBody *Symbol
>  }
>  
>  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;
>
> Modified: lld/trunk/ELF/SymbolTable.h
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.h?rev=291944&r1=291943&r2=291944&view=diff
> ==============================================================================
> --- lld/trunk/ELF/SymbolTable.h (original)
> +++ lld/trunk/ELF/SymbolTable.h Fri Jan 13 13:18:11 2017
> @@ -82,6 +82,7 @@ public:
>    void scanVersionScript();
>  
>    SymbolBody *find(StringRef Name);
> +  SymbolBody *findDefined(StringRef Name);
>  
>    void trace(StringRef Name);
>    void wrap(StringRef Name);
>
> Modified: lld/trunk/ELF/SyntheticSections.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=291944&r1=291943&r2=291944&view=diff
> ==============================================================================
> --- lld/trunk/ELF/SyntheticSections.cpp (original)
> +++ lld/trunk/ELF/SyntheticSections.cpp Fri Jan 13 13:18:11 2017
> @@ -883,9 +883,9 @@ template <class ELFT> void DynamicSectio
>      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;
>
> Modified: lld/trunk/test/ELF/init-fini.s
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/init-fini.s?rev=291944&r1=291943&r2=291944&view=diff
> ==============================================================================
> --- lld/trunk/test/ELF/init-fini.s (original)
> +++ lld/trunk/test/ELF/init-fini.s Fri Jan 13 13:18:11 2017
> @@ -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
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits


More information about the llvm-commits mailing list