[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