summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavide Italiano <davide@freebsd.org>2016-03-22 22:31:34 +0000
committerDavide Italiano <davide@freebsd.org>2016-03-22 22:31:34 +0000
commitd4c2a03c32ad52b55c4eb2d620b3e706fba43bf4 (patch)
tree24b859555484ece34925d1cbe3e445fffe882af9
parent772bb5b65d6c4dfb3278bea6626c4946fad63bfc (diff)
downloadbcm5719-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.cpp7
-rw-r--r--lld/test/ELF/lto/Inputs/linkonce-odr.ll6
-rw-r--r--lld/test/ELF/lto/linkonce-odr.ll24
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: }
OpenPOWER on IntegriCloud