diff options
author | Peter Collingbourne <peter@pcc.me.uk> | 2016-04-05 00:47:55 +0000 |
---|---|---|
committer | Peter Collingbourne <peter@pcc.me.uk> | 2016-04-05 00:47:55 +0000 |
commit | e8afa4971cb4815a0d9640c1c4faa45325c500dd (patch) | |
tree | a1ee79f12f20797255b4f9ed29e9a9036bde473e | |
parent | fb7c7644965d5d28b5bea1d3061c1703ce925a07 (diff) | |
download | bcm5719-llvm-e8afa4971cb4815a0d9640c1c4faa45325c500dd.tar.gz bcm5719-llvm-e8afa4971cb4815a0d9640c1c4faa45325c500dd.zip |
ELF: Preserve MustBeInDynSym for bitcode symbols.
Make sure to copy the MustBeInDynSym field when replacing shared symbols with
bitcode symbols, and when replacing bitcode symbols with regular symbols
in addCombinedLtoObject. Fixes interposition of DSO symbols with bitcode
symbols in the main executable.
Differential Revision: http://reviews.llvm.org/D18780
llvm-svn: 265371
-rw-r--r-- | lld/ELF/SymbolTable.cpp | 2 | ||||
-rw-r--r-- | lld/ELF/Symbols.cpp | 4 | ||||
-rw-r--r-- | lld/test/ELF/lto/Inputs/dynsym.s | 3 | ||||
-rw-r--r-- | lld/test/ELF/lto/dynsym.ll | 25 |
4 files changed, 33 insertions, 1 deletions
diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp index 06160dbe367..5bda2870ac9 100644 --- a/lld/ELF/SymbolTable.cpp +++ b/lld/ELF/SymbolTable.cpp @@ -112,6 +112,8 @@ template <class ELFT> void SymbolTable<ELFT>::addCombinedLtoObject() { Sym->Body->setUsedInRegularObj(); if (!Sym->Body->isUndefined() && Body->isUndefined()) continue; + if (Sym->Body->MustBeInDynSym) + Body->MustBeInDynSym = true; Sym->Body = Body; } ObjectFiles.emplace_back(Obj); diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp index b754c974efe..9136b90bca4 100644 --- a/lld/ELF/Symbols.cpp +++ b/lld/ELF/Symbols.cpp @@ -205,8 +205,10 @@ template <class ELFT> int SymbolBody::compare(SymbolBody *Other) { // and in DSOs, so that the symbols in the executable can interrupt // symbols in the DSO at runtime. if (isShared() != Other->isShared()) - if (isa<DefinedRegular<ELFT>>(isShared() ? Other : this)) + if (isa<Defined>(isShared() ? Other : this)) { + IsUsedInRegularObj = Other->IsUsedInRegularObj = true; MustBeInDynSym = Other->MustBeInDynSym = true; + } if (L != R) return -1; diff --git a/lld/test/ELF/lto/Inputs/dynsym.s b/lld/test/ELF/lto/Inputs/dynsym.s new file mode 100644 index 00000000000..a69f870a1b6 --- /dev/null +++ b/lld/test/ELF/lto/Inputs/dynsym.s @@ -0,0 +1,3 @@ +.globl foo +foo: +ret diff --git a/lld/test/ELF/lto/dynsym.ll b/lld/test/ELF/lto/dynsym.ll new file mode 100644 index 00000000000..b1ba842c94d --- /dev/null +++ b/lld/test/ELF/lto/dynsym.ll @@ -0,0 +1,25 @@ +; REQUIRES: x86 +; RUN: llvm-mc -filetype=obj -o %t.o %p/Inputs/dynsym.s +; RUN: ld.lld -m elf_x86_64 %t.o -o %t.so -shared +; RUN: llvm-as %s -o %t2.o +; RUN: ld.lld -m elf_x86_64 %t2.o %t.so -o %t +; RUN: llvm-readobj -dyn-symbols %t | FileCheck %s + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define void @_start() { + call void @foo() + ret void +} + +; CHECK: Name: foo +; CHECK-NEXT: Value: +; CHECK-NEXT: Size: +; CHECK-NEXT: Binding: +; CHECK-NEXT: Type: +; CHECK-NEXT: Other: +; CHECK-NEXT: Section: .text +define void @foo() { + ret void +} |