diff options
| author | Davide Italiano <davide@freebsd.org> | 2016-03-22 22:31:34 +0000 |
|---|---|---|
| committer | Davide Italiano <davide@freebsd.org> | 2016-03-22 22:31:34 +0000 |
| commit | d4c2a03c32ad52b55c4eb2d620b3e706fba43bf4 (patch) | |
| tree | 24b859555484ece34925d1cbe3e445fffe882af9 | |
| parent | 772bb5b65d6c4dfb3278bea6626c4946fad63bfc (diff) | |
| download | bcm5719-llvm-d4c2a03c32ad52b55c4eb2d620b3e706fba43bf4.tar.gz bcm5719-llvm-d4c2a03c32ad52b55c4eb2d620b3e706fba43bf4.zip | |
[LTO] Keep linkonce_odr symbols when appropriate.
Ensure we keep the symbol we need to before it reaches
the Writer (and hit an assertion), changing its linkage
from linkonce_odr to weak. For a more detailed description
of the problem, see PR19901 where a similar problem was
fixed for the gold plugin. Thanks to Rafael for providing
a testcase.
llvm-svn: 264111
| -rw-r--r-- | lld/ELF/LTO.cpp | 7 | ||||
| -rw-r--r-- | lld/test/ELF/lto/Inputs/linkonce-odr.ll | 6 | ||||
| -rw-r--r-- | lld/test/ELF/lto/linkonce-odr.ll | 24 |
3 files changed, 36 insertions, 1 deletions
diff --git a/lld/ELF/LTO.cpp b/lld/ELF/LTO.cpp index cc570f1f82e..6d2be054813 100644 --- a/lld/ELF/LTO.cpp +++ b/lld/ELF/LTO.cpp @@ -82,10 +82,15 @@ void BitcodeCompiler::add(BitcodeFile &F) { Keep.push_back(GV); continue; } - if (!BitcodeFile::shouldSkip(Sym)) + if (!BitcodeFile::shouldSkip(Sym)) { + + if (GV->getLinkage() == llvm::GlobalValue::LinkOnceODRLinkage) + GV->setLinkage(GlobalValue::WeakODRLinkage); + if (SymbolBody *B = Bodies[BodyIndex++]) if (&B->repl() == B && isa<DefinedBitcode>(B)) Keep.push_back(GV); + } } Mover.move(Obj->takeModule(), Keep, diff --git a/lld/test/ELF/lto/Inputs/linkonce-odr.ll b/lld/test/ELF/lto/Inputs/linkonce-odr.ll new file mode 100644 index 00000000000..0b3828846eb --- /dev/null +++ b/lld/test/ELF/lto/Inputs/linkonce-odr.ll @@ -0,0 +1,6 @@ +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define linkonce_odr void @f() { + ret void +} diff --git a/lld/test/ELF/lto/linkonce-odr.ll b/lld/test/ELF/lto/linkonce-odr.ll new file mode 100644 index 00000000000..470ae361db2 --- /dev/null +++ b/lld/test/ELF/lto/linkonce-odr.ll @@ -0,0 +1,24 @@ +; REQUIRES: x86 +; RUN: llvm-as %p/Inputs/linkonce-odr.ll -o %t1.o +; RUN: llc %s -o %t2.o -filetype=obj +; RUN: ld.lld %t1.o %t2.o -o %t.so -shared +; RUN: llvm-readobj -t %t.so | FileCheck %s + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" +declare void @f() + +define void @g() { + call void @f() ret void +} + +; Be sure that the linkonce_odr symbol 'f' is kept. +; CHECK: Symbol { +; CHECK: Name: f +; CHECK: Value: 0x1010 +; CHECK: Size: 1 +; CHECK: Binding: Weak +; CHECK: Type: Function +; CHECK: Other: 0 +; CHECK: Section: .text +; CHECK: } |

