summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2016-04-26 13:56:26 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2016-04-26 13:56:26 +0000
commit0baa73f3175f7f8f86954fad67efd9110ff9c6b2 (patch)
treeef6d02914bc1bcbe918f7c97146160fd5b2bb6ac
parent75f0b3fe86e856a332fa60ee256e84eb4061dcc6 (diff)
downloadbcm5719-llvm-0baa73f3175f7f8f86954fad67efd9110ff9c6b2.tar.gz
bcm5719-llvm-0baa73f3175f7f8f86954fad67efd9110ff9c6b2.zip
Handle --as-needed with symbols, not relocations.
This matches the behavior of both gold and bfd. llvm-svn: 267558
-rw-r--r--lld/ELF/Writer.cpp15
-rw-r--r--lld/test/ELF/as-needed-no-reloc.s23
2 files changed, 30 insertions, 8 deletions
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 9ee44dcc55a..bf2a4dc2ce8 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -521,9 +521,7 @@ void Writer<ELFT>::scanRelocs(InputSectionBase<ELFT> &C, ArrayRef<RelTy> Rels) {
for (auto I = Rels.begin(), E = Rels.end(); I != E; ++I) {
const RelTy &RI = *I;
uint32_t SymIndex = RI.getSymbol(Config->Mips64EL);
- SymbolBody &OrigBody = File.getSymbolBody(SymIndex);
- Symbol *Sym = OrigBody.Backref;
- SymbolBody &Body = Sym ? *Sym->Body : OrigBody;
+ SymbolBody &Body = File.getSymbolBody(SymIndex).repl();
uint32_t Type = RI.getType(Config->Mips64EL);
// Ignore "hint" relocation because it is for optional code optimization.
@@ -534,11 +532,6 @@ void Writer<ELFT>::scanRelocs(InputSectionBase<ELFT> &C, ArrayRef<RelTy> Rels) {
if (Offset == (uintX_t)-1)
continue;
- // Set "used" bit for --as-needed.
- if (OrigBody.isUndefined() && Sym && !Sym->isWeak())
- if (auto *S = dyn_cast<SharedSymbol<ELFT>>(&Body))
- S->File->IsUsed = true;
-
RelExpr Expr = Target->getRelExpr(Type, Body);
// This relocation does not require got entry, but it is relative to got and
@@ -1344,6 +1337,12 @@ template <class ELFT> void Writer<ELFT>::createSections() {
std::vector<DefinedCommon *> CommonSymbols;
for (Symbol *S : Symtab.getSymbols()) {
SymbolBody *Body = S->Body;
+
+ // Set "used" bit for --as-needed.
+ if (S->IsUsedInRegularObj && !S->isWeak())
+ if (auto *SS = dyn_cast<SharedSymbol<ELFT>>(Body))
+ SS->File->IsUsed = true;
+
if (Body->isUndefined() && !S->isWeak()) {
auto *U = dyn_cast<UndefinedElf<ELFT>>(Body);
if (!U || !U->canKeepUndefined())
diff --git a/lld/test/ELF/as-needed-no-reloc.s b/lld/test/ELF/as-needed-no-reloc.s
new file mode 100644
index 00000000000..0706ca0a932
--- /dev/null
+++ b/lld/test/ELF/as-needed-no-reloc.s
@@ -0,0 +1,23 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/shared.s -o %t2.o
+# RUN: ld.lld -shared %t2.o -o %t2.so
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: ld.lld -o %t %t.o --as-needed %t2.so
+# RUN: llvm-readobj --dynamic-table --dyn-symbols %t | FileCheck %s
+
+
+# There must be a NEEDED entry for each undefined
+
+# CHECK: Name: bar
+# CHECK-NEXT: Value: 0x0
+# CHECK-NEXT: Size: 0
+# CHECK-NEXT: Binding: Global
+# CHECK-NEXT: Type: Function
+# CHECK-NEXT: Other: 0
+# CHECK-NEXT: Section: Undefined
+
+# CHECK: NEEDED SharedLibrary ({{.*}}2.so)
+
+ .globl _start
+_start:
+ .global bar
OpenPOWER on IntegriCloud