diff options
| author | Rafael Espindola <rafael.espindola@gmail.com> | 2016-04-26 13:56:26 +0000 |
|---|---|---|
| committer | Rafael Espindola <rafael.espindola@gmail.com> | 2016-04-26 13:56:26 +0000 |
| commit | 0baa73f3175f7f8f86954fad67efd9110ff9c6b2 (patch) | |
| tree | ef6d02914bc1bcbe918f7c97146160fd5b2bb6ac | |
| parent | 75f0b3fe86e856a332fa60ee256e84eb4061dcc6 (diff) | |
| download | bcm5719-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.cpp | 15 | ||||
| -rw-r--r-- | lld/test/ELF/as-needed-no-reloc.s | 23 |
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 |

