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