[lld] r249998 - ELF2: Implement --as-needed.
Rui Ueyama via llvm-commits
llvm-commits at lists.llvm.org
Mon Oct 12 09:27:51 PDT 2015
Fixed in r250062.
On Sun, Oct 11, 2015 at 6:48 PM, Rafael EspĂndola <
rafael.espindola at gmail.com> wrote:
> There is something missing on the test. Everything still passes if I
> convert
>
> if (Body && Body->isUndefined() && !Body->isWeak())
>
> to just
>
> if (Body)
>
> Cheers,
> Rafael
>
>
>
> On 11 October 2015 at 16:59, Rui Ueyama via llvm-commits
> <llvm-commits at lists.llvm.org> wrote:
> > Author: ruiu
> > Date: Sun Oct 11 15:59:12 2015
> > New Revision: 249998
> >
> > URL: http://llvm.org/viewvc/llvm-project?rev=249998&view=rev
> > Log:
> > ELF2: Implement --as-needed.
> >
> > This patch adds AsNeeded and IsUsed bool fields to SharedFile. AsNeeded
> bit
> > is set if the DSO is enclosed with --as-needed and --no-as-needed. IsUsed
> > bit is off by default. When we adds a symbol to the symbol table for
> dynamic
> > linking, we set its SharedFile's IsUsed bit.
> >
> > If AsNeeded is set but IsUsed is not set, we don't want to write that
> > file's SO name to DT_NEEDED field.
> >
> > http://reviews.llvm.org/D13579
> >
> > Added:
> > lld/trunk/test/elf2/Inputs/shared2.s
> > lld/trunk/test/elf2/Inputs/shared3.s
> > lld/trunk/test/elf2/as-needed.s
> > Modified:
> > lld/trunk/ELF/Config.h
> > lld/trunk/ELF/Driver.cpp
> > lld/trunk/ELF/InputFiles.cpp
> > lld/trunk/ELF/InputFiles.h
> > lld/trunk/ELF/InputSection.cpp
> > lld/trunk/ELF/LinkerScript.cpp
> > lld/trunk/ELF/Options.td
> > lld/trunk/ELF/OutputSections.cpp
> > lld/trunk/ELF/Symbols.h
> > lld/trunk/ELF/Writer.cpp
> >
> > Modified: lld/trunk/ELF/Config.h
> > URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Config.h?rev=249998&r1=249997&r2=249998&view=diff
> >
> ==============================================================================
> > --- lld/trunk/ELF/Config.h (original)
> > +++ lld/trunk/ELF/Config.h Sun Oct 11 15:59:12 2015
> > @@ -43,6 +43,7 @@ struct Configuration {
> > std::string RPath;
> > std::vector<llvm::StringRef> SearchPaths;
> > bool AllowMultipleDefinition;
> > + bool AsNeeded = false;
> > bool DiscardAll;
> > bool DiscardLocals;
> > bool DiscardNone;
> >
> > Modified: lld/trunk/ELF/Driver.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=249998&r1=249997&r2=249998&view=diff
> >
> ==============================================================================
> > --- lld/trunk/ELF/Driver.cpp (original)
> > +++ lld/trunk/ELF/Driver.cpp Sun Oct 11 15:59:12 2015
> > @@ -100,9 +100,12 @@ void LinkerDriver::addFile(StringRef Pat
> > }
> > Files.push_back(make_unique<ArchiveFile>(MBRef));
> > return;
> > - case file_magic::elf_shared_object:
> > - Files.push_back(createELFFile<SharedFile>(MBRef));
> > + case file_magic::elf_shared_object: {
> > + std::unique_ptr<ELFFileBase> File =
> createELFFile<SharedFile>(MBRef);
> > + cast<SharedFileBase>(File.get())->AsNeeded = Config->AsNeeded;
> > + Files.push_back(std::move(File));
> > return;
> > + }
> > default:
> > Files.push_back(createELFFile<ObjectFile>(MBRef));
> > }
> > @@ -187,6 +190,12 @@ void LinkerDriver::createFiles(opt::Inpu
> > case OPT_script:
> > addFile(Arg->getValue());
> > break;
> > + case OPT_as_needed:
> > + Config->AsNeeded = true;
> > + break;
> > + case OPT_no_as_needed:
> > + Config->AsNeeded = false;
> > + break;
> > case OPT_Bstatic:
> > Config->Static = true;
> > break;
> >
> > Modified: lld/trunk/ELF/InputFiles.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=249998&r1=249997&r2=249998&view=diff
> >
> ==============================================================================
> > --- lld/trunk/ELF/InputFiles.cpp (original)
> > +++ lld/trunk/ELF/InputFiles.cpp Sun Oct 11 15:59:12 2015
> > @@ -329,7 +329,7 @@ template <class ELFT> void SharedFile<EL
> > error(NameOrErr.getError());
> > StringRef Name = *NameOrErr;
> >
> > - SymbolBodies.emplace_back(Name, Sym);
> > + SymbolBodies.emplace_back(this, Name, Sym);
> > }
> > }
> >
> >
> > Modified: lld/trunk/ELF/InputFiles.h
> > URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.h?rev=249998&r1=249997&r2=249998&view=diff
> >
> ==============================================================================
> > --- lld/trunk/ELF/InputFiles.h (original)
> > +++ lld/trunk/ELF/InputFiles.h Sun Oct 11 15:59:12 2015
> > @@ -146,7 +146,7 @@ public:
> > uint32_t FirstNonLocal = this->Symtab->sh_info;
> > if (SymbolIndex < FirstNonLocal)
> > return nullptr;
> > - return SymbolBodies[SymbolIndex - FirstNonLocal]->repl();
> > + return SymbolBodies[SymbolIndex - FirstNonLocal];
> > }
> >
> > Elf_Sym_Range getLocalSymbols();
> > @@ -198,6 +198,11 @@ public:
> > StringRef getSoName() const { return SoName; }
> > virtual void parseSoName() = 0;
> > virtual void parse() = 0;
> > +
> > + // Used for --as-needed
> > + bool AsNeeded = false;
> > + bool IsUsed = false;
> > + bool isNeeded() const { return !AsNeeded || IsUsed; }
> > };
> >
> > template <class ELFT>
> >
> > Modified: lld/trunk/ELF/InputSection.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=249998&r1=249997&r2=249998&view=diff
> >
> ==============================================================================
> > --- lld/trunk/ELF/InputSection.cpp (original)
> > +++ lld/trunk/ELF/InputSection.cpp Sun Oct 11 15:59:12 2015
> > @@ -46,7 +46,7 @@ void InputSection<ELFT>::relocate(
> > continue;
> > SymVA = getLocalSymVA(Sym, File);
> > } else {
> > - SymbolBody &Body = *File.getSymbolBody(SymIndex);
> > + SymbolBody &Body = *File.getSymbolBody(SymIndex)->repl();
> > SymVA = getSymVA<ELFT>(Body);
> > if (Target->relocNeedsPlt(Type, Body)) {
> > SymVA = Out<ELFT>::Plt->getEntryAddr(Body);
> >
> > Modified: lld/trunk/ELF/LinkerScript.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=249998&r1=249997&r2=249998&view=diff
> >
> ==============================================================================
> > --- lld/trunk/ELF/LinkerScript.cpp (original)
> > +++ lld/trunk/ELF/LinkerScript.cpp Sun Oct 11 15:59:12 2015
> > @@ -155,12 +155,15 @@ void LinkerScript::addFile(StringRef S)
> >
> > void LinkerScript::readAsNeeded() {
> > expect("(");
> > + bool Orig = Config->AsNeeded;
> > + Config->AsNeeded = true;
> > for (;;) {
> > StringRef Tok = next();
> > if (Tok == ")")
> > - return;
> > + break;
> > addFile(Tok);
> > }
> > + Config->AsNeeded = Orig;
> > }
> >
> > void LinkerScript::readEntry() {
> >
> > Modified: lld/trunk/ELF/Options.td
> > URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Options.td?rev=249998&r1=249997&r2=249998&view=diff
> >
> ==============================================================================
> > --- lld/trunk/ELF/Options.td (original)
> > +++ lld/trunk/ELF/Options.td Sun Oct 11 15:59:12 2015
> > @@ -14,6 +14,8 @@ def allow_multiple_definition: Flag<["--
> >
> > def allow_shlib_undefined : Flag<["--", "-"], "allow-shlib-undefined">;
> >
> > +def as_needed : Flag<["--"], "as-needed">;
> > +
> > def disable_new_dtags : Flag<["--"], "disable-new-dtags">,
> > HelpText<"Disable new dynamic tags">;
> >
> > @@ -52,6 +54,8 @@ def m : Separate<["-"], "m">,
> >
> > def no_allow_shlib_undefined : Flag<["--"], "no-allow-shlib-undefined">;
> >
> > +def no_as_needed : Flag<["--"], "no-as-needed">;
> > +
> > def no_whole_archive : Flag<["--"], "no-whole-archive">,
> > HelpText<"Restores the default behavior of loading archive members">;
> >
> > @@ -111,14 +115,12 @@ def alias_undefined_u : Separate<["-"],
> >
> > // Options listed below are silently ignored now.
> > def O3 : Flag<["-"], "O3">;
> > -def as_needed : Flag<["--"], "as-needed">;
> > def build_id : Flag<["--"], "build-id">;
> > def eh_frame_hdr : Flag<["--"], "eh-frame-hdr">;
> > def end_group : Flag<["--"], "end-group">;
> > def gc_sections : Flag<["--"], "gc-sections">;
> > def hash_style : Joined<["--"], "hash-style=">;
> > def no_add_needed : Flag<["--"], "no-add-needed">;
> > -def no_as_needed : Flag<["--"], "no-as-needed">;
> > def no_fatal_warnings : Flag<["--"], "no-fatal-warnings">;
> > def start_group : Flag<["--"], "start-group">;
> > def strip_all : Flag<["--"], "strip-all">;
> >
> > Modified: lld/trunk/ELF/OutputSections.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=249998&r1=249997&r2=249998&view=diff
> >
> ==============================================================================
> > --- lld/trunk/ELF/OutputSections.cpp (original)
> > +++ lld/trunk/ELF/OutputSections.cpp Sun Oct 11 15:59:12 2015
> > @@ -116,8 +116,10 @@ template <class ELFT> void RelocationSec
> > OutputSection<ELFT> *OutSec = C.getOutputSection();
> > uint32_t SymIndex = RI.getSymbol(IsMips64EL);
> > const ObjectFile<ELFT> &File = *C.getFile();
> > - const SymbolBody *Body = File.getSymbolBody(SymIndex);
> > + SymbolBody *Body = File.getSymbolBody(SymIndex);
> > const ELFFile<ELFT> &Obj = File.getObj();
> > + if (Body)
> > + Body = Body->repl();
> >
> > uint32_t Type = RI.getType(IsMips64EL);
> >
> > @@ -279,6 +281,8 @@ template <class ELFT> void DynamicSectio
> > NumEntries += 2;
> >
> > for (const std::unique_ptr<SharedFile<ELFT>> &F :
> SymTab.getSharedFiles()) {
> > + if (!F->isNeeded())
> > + continue;
> > Out<ELFT>::DynStrTab->add(F->getSoName());
> > ++NumEntries;
> > }
> > @@ -356,7 +360,8 @@ template <class ELFT> void DynamicSectio
> > WriteArray(DT_FINI_ARRAY, DT_FINI_ARRAYSZ, FiniArraySec);
> >
> > for (const std::unique_ptr<SharedFile<ELFT>> &F :
> SymTab.getSharedFiles())
> > - WriteVal(DT_NEEDED,
> Out<ELFT>::DynStrTab->getFileOff(F->getSoName()));
> > + if (F->isNeeded())
> > + WriteVal(DT_NEEDED,
> Out<ELFT>::DynStrTab->getFileOff(F->getSoName()));
> >
> > if (InitSym)
> > WritePtr(DT_INIT, getSymVA<ELFT>(*InitSym));
> >
> > Modified: lld/trunk/ELF/Symbols.h
> > URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=249998&r1=249997&r2=249998&view=diff
> >
> ==============================================================================
> > --- lld/trunk/ELF/Symbols.h (original)
> > +++ lld/trunk/ELF/Symbols.h Sun Oct 11 15:59:12 2015
> > @@ -24,6 +24,7 @@ class InputFile;
> > class SymbolBody;
> > template <class ELFT> class ObjectFile;
> > template <class ELFT> class OutputSection;
> > +template <class ELFT> class SharedFile;
> >
> > // Initializes global objects defined in this file.
> > // Called at the beginning of main().
> > @@ -263,8 +264,10 @@ public:
> > return S->kind() == Base::SharedKind;
> > }
> >
> > - SharedSymbol(StringRef Name, const Elf_Sym &Sym)
> > - : Defined<ELFT>(Base::SharedKind, Name, Sym) {}
> > + SharedSymbol(SharedFile<ELFT> *F, StringRef Name, const Elf_Sym &Sym)
> > + : Defined<ELFT>(Base::SharedKind, Name, Sym), File(F) {}
> > +
> > + SharedFile<ELFT> *File;
> > };
> >
> > // This class represents a symbol defined in an archive file. It is
> >
> > Modified: lld/trunk/ELF/Writer.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=249998&r1=249997&r2=249998&view=diff
> >
> ==============================================================================
> > --- lld/trunk/ELF/Writer.cpp (original)
> > +++ lld/trunk/ELF/Writer.cpp Sun Oct 11 15:59:12 2015
> > @@ -174,6 +174,14 @@ void Writer<ELFT>::scanRelocs(
> > uint32_t SymIndex = RI.getSymbol(IsMips64EL);
> > SymbolBody *Body = File.getSymbolBody(SymIndex);
> > uint32_t Type = RI.getType(IsMips64EL);
> > +
> > + // Set "used" bit for --as-needed.
> > + if (Body && Body->isUndefined() && !Body->isWeak())
> > + if (auto *S = dyn_cast<SharedSymbol<ELFT>>(Body->repl()))
> > + S->File->IsUsed = true;
> > +
> > + if (Body)
> > + Body = Body->repl();
> > if (Body) {
> > if (Target->relocNeedsPlt(Type, *Body)) {
> > if (Body->isInPlt())
> > @@ -186,12 +194,13 @@ void Writer<ELFT>::scanRelocs(
> > Out<ELFT>::Got->addEntry(Body);
> > }
> > }
> > - if (canBePreempted(Body)) {
> > +
> > + bool CBP = canBePreempted(Body);
> > + if (!CBP && (!Config->Shared || Target->isRelRelative(Type)))
> > + continue;
> > + if (CBP)
> > Body->setUsedInDynamicReloc();
> > - Out<ELFT>::RelaDyn->addReloc({C, RI});
> > - } else if (Config->Shared && !Target->isRelRelative(Type)) {
> > - Out<ELFT>::RelaDyn->addReloc({C, RI});
> > - }
> > + Out<ELFT>::RelaDyn->addReloc({C, RI});
> > }
> > }
> >
> >
> > Added: lld/trunk/test/elf2/Inputs/shared2.s
> > URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/Inputs/shared2.s?rev=249998&view=auto
> >
> ==============================================================================
> > --- lld/trunk/test/elf2/Inputs/shared2.s (added)
> > +++ lld/trunk/test/elf2/Inputs/shared2.s Sun Oct 11 15:59:12 2015
> > @@ -0,0 +1,6 @@
> > +.global bar2
> > +.type bar2, @function
> > +bar2:
> > +
> > +.global zed2
> > +zed2:
> >
> > Added: lld/trunk/test/elf2/Inputs/shared3.s
> > URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/Inputs/shared3.s?rev=249998&view=auto
> >
> ==============================================================================
> > --- lld/trunk/test/elf2/Inputs/shared3.s (added)
> > +++ lld/trunk/test/elf2/Inputs/shared3.s Sun Oct 11 15:59:12 2015
> > @@ -0,0 +1,3 @@
> > +.global baz
> > +.type barz, @function
> > +baz:
> >
> > Added: lld/trunk/test/elf2/as-needed.s
> > URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/as-needed.s?rev=249998&view=auto
> >
> ==============================================================================
> > --- lld/trunk/test/elf2/as-needed.s (added)
> > +++ lld/trunk/test/elf2/as-needed.s Sun Oct 11 15:59:12 2015
> > @@ -0,0 +1,43 @@
> > +// REQUIRES: x86
> > +// RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o
> > +// RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux
> %p/Inputs/shared.s -o %t2.o
> > +// RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux
> %p/Inputs/shared2.s -o %t3.o
> > +// RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux
> %p/Inputs/shared3.s -o %t4.o
> > +// RUN: ld.lld2 -shared %t2.o -soname shared1 -o %t2.so
> > +// RUN: ld.lld2 -shared %t3.o -soname shared2 -o %t3.so
> > +// RUN: ld.lld2 -shared %t4.o -soname shared3 -o %t4.so
> > +
> > +/// Check if --as-needed actually works.
> > +
> > +// RUN: ld.lld2 %t.o %t2.so %t3.so %t4.so -o %t2
> > +// RUN: llvm-readobj -dynamic-table %t2 | FileCheck %s
> > +
> > +// RUN: ld.lld2 --as-needed %t.o %t2.so %t3.so %t4.so -o %t2
> > +// RUN: llvm-readobj -dynamic-table %t2 | FileCheck
> -check-prefix=CHECK2 %s
> > +
> > +// RUN: ld.lld2 --as-needed %t.o %t2.so --no-as-needed %t3.so %t4.so -o
> %t2
> > +// RUN: llvm-readobj -dynamic-table %t2 | FileCheck %s
> > +
> > +/// GROUP directive is the same as --as-needed.
> > +
> > +// RUN: echo "GROUP(" %t2.so %t3.so %t4.so ")" > %t.script
> > +// RUN: ld.lld2 %t.o %t.script -o %t2
> > +// RUN: llvm-readobj -dynamic-table %t2 | FileCheck %s
> > +
> > +// RUN: echo "GROUP(AS_NEEDED(" %t2.so %t3.so %t4.so "))" > %t.script
> > +// RUN: ld.lld2 %t.o %t.script -o %t2
> > +// RUN: llvm-readobj -dynamic-table %t2 | FileCheck
> -check-prefix=CHECK2 %s
> > +
> > +// CHECK: NEEDED SharedLibrary (shared1)
> > +// CHECK: NEEDED SharedLibrary (shared2)
> > +// CHECK: NEEDED SharedLibrary (shared3)
> > +
> > +// CHECK2: NEEDED SharedLibrary (shared1)
> > +// CHECK2-NOT: NEEDED SharedLibrary (shared2)
> > +// CHECK2-NOT: NEEDED SharedLibrary (shared3)
> > +
> > +.global _start
> > +_start:
> > +.long bar
> > +.long zed
> > +.weak baz
> >
> >
> > _______________________________________________
> > llvm-commits mailing list
> > llvm-commits at lists.llvm.org
> > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20151012/7e014f2f/attachment.html>
More information about the llvm-commits
mailing list