[lld] r249045 - [ELF2] Add --[no-]whole-archive command line switches

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 1 11:06:40 PDT 2015


On Thu, Oct 1, 2015 at 11:02 AM, Igor Kudrin via llvm-commits <
llvm-commits at lists.llvm.org> wrote:

> Author: ikudrin
> Date: Thu Oct  1 13:02:21 2015
> New Revision: 249045
>
> URL: http://llvm.org/viewvc/llvm-project?rev=249045&view=rev
> Log:
> [ELF2] Add --[no-]whole-archive command line switches
>
> Summary:
> If --whole-archive is used, all symbols from the following archives are
> added to the output. --no-whole-archive restores default behavior. These
> switches can be used multiple times.
>
> NB. We have to keep an ArchiveFile instance within SymbolTable even if
> --whole-archive mode is active since it can be a thin archive which
> contains just names of external files. In that case actual memory buffers
> for the archive members will be stored within the File member of
> ArchiveFile class.
>
> Reviewers: rafael, ruiu
>
> Subscribers: grimar, llvm-commits
>
> Projects: #lld
>
> Differential Revision: http://reviews.llvm.org/D13286
>
>
Please line-wrap the commit message in the future. Also please remove
"Summary:", "Reviewer:", "Subscribers:" Projects:" lines because the
information is redundnat or available at Phab.

Added:
>     lld/trunk/test/elf2/Inputs/whole-archive.s
>     lld/trunk/test/elf2/whole-archive.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/Options.td
>     lld/trunk/ELF/SymbolTable.cpp
>
> Modified: lld/trunk/ELF/Config.h
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Config.h?rev=249045&r1=249044&r2=249045&view=diff
>
> ==============================================================================
> --- lld/trunk/ELF/Config.h (original)
> +++ lld/trunk/ELF/Config.h Thu Oct  1 13:02:21 2015
> @@ -32,6 +32,7 @@ struct Configuration {
>    bool NoInhibitExec;
>    bool Shared;
>    bool Static = false;
> +  bool WholeArchive = false;
>  };
>
>  extern Configuration *Config;
>
> Modified: lld/trunk/ELF/Driver.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=249045&r1=249044&r2=249045&view=diff
>
> ==============================================================================
> --- lld/trunk/ELF/Driver.cpp (original)
> +++ lld/trunk/ELF/Driver.cpp Thu Oct  1 13:02:21 2015
> @@ -139,6 +139,12 @@ void LinkerDriver::link(ArrayRef<const c
>      case OPT_Bdynamic:
>        Config->Static = false;
>        break;
> +    case OPT_whole_archive:
> +      Config->WholeArchive = true;
> +      break;
> +    case OPT_no_whole_archive:
> +      Config->WholeArchive = false;
> +      break;
>      default:
>        break;
>      }
>
> Modified: lld/trunk/ELF/InputFiles.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=249045&r1=249044&r2=249045&view=diff
>
> ==============================================================================
> --- lld/trunk/ELF/InputFiles.cpp (original)
> +++ lld/trunk/ELF/InputFiles.cpp Thu Oct  1 13:02:21 2015
> @@ -181,10 +181,14 @@ SymbolBody *elf2::ObjectFile<ELFT>::crea
>    }
>  }
>
> -void ArchiveFile::parse() {
> +static std::unique_ptr<Archive> openArchive(MemoryBufferRef MB) {
>    ErrorOr<std::unique_ptr<Archive>> ArchiveOrErr = Archive::create(MB);
>    error(ArchiveOrErr, "Failed to parse archive");
> -  File = std::move(*ArchiveOrErr);
> +  return std::move(*ArchiveOrErr);
> +}
> +
> +void ArchiveFile::parse() {
> +  File = openArchive(MB);
>
>    // Allocate a buffer for Lazy objects.
>    size_t NumSyms = File->getNumberOfSymbols();
> @@ -211,6 +215,20 @@ MemoryBufferRef ArchiveFile::getMember(c
>    return *Ret;
>  }
>
> +std::vector<MemoryBufferRef> ArchiveFile::getMembers() {
> +  File = openArchive(MB);
> +
> +  std::vector<MemoryBufferRef> Result;
> +  for (const Archive::Child &Child : File->children()) {
> +    ErrorOr<MemoryBufferRef> MbOrErr = Child.getMemoryBufferRef();
> +    error(MbOrErr,
> +          Twine("Could not get the buffer for a child of the archive ") +
> +              File->getFileName());
> +    Result.push_back(MbOrErr.get());
> +  }
> +  return Result;
> +}
> +
>  template <class ELFT>
>  SharedFile<ELFT>::SharedFile(MemoryBufferRef M)
>      : SharedFileBase(getStaticELFKind<ELFT>(), M), ELFData<ELFT>(M) {}
>
> Modified: lld/trunk/ELF/InputFiles.h
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.h?rev=249045&r1=249044&r2=249045&view=diff
>
> ==============================================================================
> --- lld/trunk/ELF/InputFiles.h (original)
> +++ lld/trunk/ELF/InputFiles.h Thu Oct  1 13:02:21 2015
> @@ -176,6 +176,7 @@ public:
>    MemoryBufferRef getMember(const Archive::Symbol *Sym);
>
>    llvm::MutableArrayRef<Lazy> getLazySymbols() { return LazySymbols; }
> +  std::vector<MemoryBufferRef> getMembers();
>
>  private:
>    std::unique_ptr<Archive> File;
>
> Modified: lld/trunk/ELF/Options.td
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Options.td?rev=249045&r1=249044&r2=249045&view=diff
>
> ==============================================================================
> --- lld/trunk/ELF/Options.td (original)
> +++ lld/trunk/ELF/Options.td Thu Oct  1 13:02:21 2015
> @@ -37,6 +37,9 @@ def l : Joined<["-"], "l">, MetaVarName<
>
>  def no_allow_shlib_undefined : Flag<["--"], "no-allow-shlib-undefined">;
>
> +def no_whole_archive : Flag<["--"], "no-whole-archive">,
> +  HelpText<"Restores the default behavior of loading archive members">;
> +
>  def noinhibit_exec : Flag<["--"], "noinhibit-exec">,
>    HelpText<"Retain the executable output file whenever it is still
> usable">;
>
> @@ -52,6 +55,9 @@ def shared : Flag<["-"], "shared">,
>  def sysroot : Joined<["--"], "sysroot=">,
>    HelpText<"Set the system root">;
>
> +def whole_archive : Flag<["--"], "whole-archive">,
> +  HelpText<"Force load of all members in a static library">;
> +
>  // Aliases
>  def alias_Bdynamic_call_shared: Flag<["-"], "call_shared">,
> Alias<Bdynamic>;
>  def alias_Bdynamic_dy: Flag<["-"], "dy">, Alias<Bdynamic>;
>
> Modified: lld/trunk/ELF/SymbolTable.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=249045&r1=249044&r2=249045&view=diff
>
> ==============================================================================
> --- lld/trunk/ELF/SymbolTable.cpp (original)
> +++ lld/trunk/ELF/SymbolTable.cpp Thu Oct  1 13:02:21 2015
> @@ -28,15 +28,21 @@ bool SymbolTable::shouldUseRela() const
>  }
>
>  void SymbolTable::addFile(std::unique_ptr<InputFile> File) {
> -  File->parse();
> -  InputFile *FileP = File.release();
> -  if (auto *AF = dyn_cast<ArchiveFile>(FileP)) {
> +  if (auto *AF = dyn_cast<ArchiveFile>(File.get())) {
> +    File.release();
>      ArchiveFiles.emplace_back(AF);
> +    if (Config->WholeArchive) {
> +      for (MemoryBufferRef &MBRef : AF->getMembers())
> +        addFile(createELFFile<ObjectFile>(MBRef));
> +      return;
> +    }
> +    AF->parse();
>      for (Lazy &Sym : AF->getLazySymbols())
>        addLazy(&Sym);
>      return;
>    }
> -  addELFFile(cast<ELFFileBase>(FileP));
> +  File->parse();
> +  addELFFile(cast<ELFFileBase>(File.release()));
>  }
>
>  static TargetInfo *createTarget(uint16_t EMachine) {
>
> Added: lld/trunk/test/elf2/Inputs/whole-archive.s
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/Inputs/whole-archive.s?rev=249045&view=auto
>
> ==============================================================================
> --- lld/trunk/test/elf2/Inputs/whole-archive.s (added)
> +++ lld/trunk/test/elf2/Inputs/whole-archive.s Thu Oct  1 13:02:21 2015
> @@ -0,0 +1,2 @@
> +.globl _bar;
> +_bar:
>
> Added: lld/trunk/test/elf2/whole-archive.s
> URL:
> http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf2/whole-archive.s?rev=249045&view=auto
>
> ==============================================================================
> --- lld/trunk/test/elf2/whole-archive.s (added)
> +++ lld/trunk/test/elf2/whole-archive.s Thu Oct  1 13:02:21 2015
> @@ -0,0 +1,34 @@
> +// REQUIRES: x86
> +
> +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
> +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
> +// RUN:   %p/Inputs/whole-archive.s -o %ta.o
> +// RUN: rm -f %t.a
> +// RUN: llvm-ar rcs %t.a %ta.o
> +
> +// Should not add symbols from the archive by default as they are not
> required
> +// RUN: lld -flavor gnu2 -o %t3 %t.o %t.a
> +// RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=NOTADDED %s
> +// NOTADDED: Symbols [
> +// NOTADDED-NOT: Name: _bar
> +// NOTADDED: ]
> +
> +// Should add symbols from the archive if --whole-archive is used
> +// RUN: lld -flavor gnu2 -o %t3 %t.o --whole-archive %t.a
> +// RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=ADDED %s
> +// ADDED: Symbols [
> +// ADDED: Name: _bar
> +// ADDED: ]
> +
> +// --no-whole-archive should restore default behaviour
> +// RUN: lld -flavor gnu2 -o %t3 %t.o --whole-archive --no-whole-archive
> %t.a
> +// RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=NOTADDED %s
> +
> +// --whole-archive and --no-whole-archive should affect only archives
> which follow them
> +// RUN: lld -flavor gnu2 -o %t3 %t.o %t.a --whole-archive
> --no-whole-archive
> +// RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=NOTADDED %s
> +// RUN: lld -flavor gnu2 -o %t3 %t.o --whole-archive %t.a
> --no-whole-archive
> +// RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=ADDED %s
> +
> +.globl _start;
> +_start:
>
>
> _______________________________________________
> 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/20151001/b7afa354/attachment.html>


More information about the llvm-commits mailing list