<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Apr 25, 2016 at 5:22 PM, Davide Italiano 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: davide<br>
Date: Mon Apr 25 19:22:24 2016<br>
New Revision: 267497<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=267497&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=267497&view=rev</a><br>
Log:<br>
[ELF] Introduce --reproduce flag.<br>
<br>
--reproduce dumps the object files in a directory chosen<br>
(preserving the file system layout) and the linker invocation<br>
so that people can create an archive and upload for debugging.<br>
<br>
Differential Revision:  <a href="http://reviews.llvm.org/D19494" rel="noreferrer" target="_blank">http://reviews.llvm.org/D19494</a><br>
<br>
Added:<br>
    lld/trunk/test/ELF/reproduce.s<br>
Modified:<br>
    lld/trunk/ELF/Config.h<br>
    lld/trunk/ELF/Driver.cpp<br>
    lld/trunk/ELF/Options.td<br>
<br>
Modified: lld/trunk/ELF/Config.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Config.h?rev=267497&r1=267496&r2=267497&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Config.h?rev=267497&r1=267496&r2=267497&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/ELF/Config.h (original)<br>
+++ lld/trunk/ELF/Config.h Mon Apr 25 19:22:24 2016<br>
@@ -48,6 +48,7 @@ struct Configuration {<br>
   llvm::StringRef SoName;<br>
   llvm::StringRef Sysroot;<br>
   std::string RPath;<br>
+  std::string Reproduce;<br>
   std::vector<llvm::StringRef> DynamicList;<br>
   std::vector<llvm::StringRef> SearchPaths;<br>
   std::vector<llvm::StringRef> Undefined;<br>
<br>
Modified: lld/trunk/ELF/Driver.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=267497&r1=267496&r2=267497&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=267497&r1=267496&r2=267497&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/ELF/Driver.cpp (original)<br>
+++ lld/trunk/ELF/Driver.cpp Mon Apr 25 19:22:24 2016<br>
@@ -19,6 +19,7 @@<br>
 #include "Writer.h"<br>
 #include "lld/Driver/Driver.h"<br>
 #include "llvm/ADT/StringExtras.h"<br>
+#include "llvm/Support/Path.h"<br>
 #include "llvm/Support/TargetSelect.h"<br>
 #include "llvm/Support/raw_ostream.h"<br>
 #include <utility><br>
@@ -97,12 +98,29 @@ LinkerDriver::getArchiveMembers(MemoryBu<br>
   return V;<br>
 }<br>
<br>
+static void dumpFile(StringRef SrcPath) {<br>
+  SmallString<128> DirName;<br>
+  sys::path::append(DirName, Config->Reproduce, sys::path::parent_path(SrcPath));<br>
+  if (std::error_code EC = sys::fs::create_directories(DirName)) {<br>
+    error(EC, "--reproduce: can't create directory");<br>
+    return;<br>
+  }<br>
+<br>
+  SmallString<128> DestPathName;<br>
+  sys::path::append(DestPathName, Config->Reproduce, SrcPath);<br>
+  if (std::error_code EC = sys::fs::copy_file(SrcPath, DestPathName))<br>
+    error(EC, "--reproduce: can't copy file");<br>
+}<br>
+<br>
 // Opens and parses a file. Path has to be resolved already.<br>
 // Newly created memory buffers are owned by this driver.<br>
 void LinkerDriver::addFile(StringRef Path) {<br>
   using namespace llvm::sys::fs;<br>
   if (Config->Verbose)<br>
     llvm::outs() << Path << "\n";<br>
+  if (!Config->Reproduce.empty())<br>
+    dumpFile(Path);<br>
+<br>
   Optional<MemoryBufferRef> Buffer = readFile(Path);<br>
   if (!Buffer.hasValue())<br>
     return;<br>
@@ -223,6 +241,25 @@ static bool hasZOption(opt::InputArgList<br>
   return false;<br>
 }<br>
<br>
+static void dumpLinkerInvocation(ArrayRef<const char *> Args) {<br>
+  std::error_code EC = sys::fs::create_directories(Config->Reproduce,<br>
+    false /* IgnoreExisting */);<br>
+  if (EC) {<br>
+    error(EC, "--reproduce: can't create directory");<br>
+    return;<br>
+  }<br>
+<br>
+  SmallString<128> InvocationPath;<br>
+  sys::path::append(InvocationPath, Config->Reproduce, "invocation.txt");<br>
+  raw_fd_ostream OS(InvocationPath, EC, sys::fs::OpenFlags::F_None);<br>
+  check(EC);<br>
+<br>
+  OS << Args[0];<br>
+  for (unsigned I = 1, E = Args.size(); I < E; ++I)<br>
+    OS << " " << Args[I];<br>
+  OS << "\n";<br>
+}<br>
+<br>
 void LinkerDriver::main(ArrayRef<const char *> ArgsArr) {<br>
   ELFOptTable Parser;<br>
   opt::InputArgList Args = Parser.parse(ArgsArr.slice(1));<br>
@@ -237,6 +274,10 @@ void LinkerDriver::main(ArrayRef<const c<br>
<br>
   initLLVM(Args);<br>
   readConfigs(Args);<br>
+<br>
+  if (!Config->Reproduce.empty())<br>
+    dumpLinkerInvocation(ArgsArr);<br>
+<br>
   createFiles(Args);<br>
   checkOptions(Args);<br>
   if (HasError)<br>
@@ -311,6 +352,8 @@ void LinkerDriver::readConfigs(opt::Inpu<br>
   Config->Fini = getString(Args, OPT_fini, "_fini");<br>
   Config->Init = getString(Args, OPT_init, "_init");<br>
   Config->OutputFile = getString(Args, OPT_o);<br>
+  if (auto *Arg = Args.getLastArg(OPT_reproduce))<br>
+    Config->Reproduce = Arg->getValue();<br>
   Config->SoName = getString(Args, OPT_soname);<br>
   Config->Sysroot = getString(Args, OPT_sysroot);<br>
<br>
<br>
Modified: lld/trunk/ELF/Options.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Options.td?rev=267497&r1=267496&r2=267497&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Options.td?rev=267497&r1=267496&r2=267497&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/ELF/Options.td (original)<br>
+++ lld/trunk/ELF/Options.td Mon Apr 25 19:22:24 2016<br>
@@ -120,6 +120,9 @@ def pie : Flag<["-"], "pie">,<br>
 def print_gc_sections: Flag<["--"], "print-gc-sections">,<br>
   HelpText<"List removed unused sections">;<br>
<br>
+def reproduce : Separate<["--"], "reproduce">,<br>
+  HelpText<"Dump linker invocation and input files for debugging">;<br>
+<br>
 def rpath : Separate<["-"], "rpath">,<br>
   HelpText<"Add a DT_RUNPATH to the output">;<br>
<br>
<br>
Added: lld/trunk/test/ELF/reproduce.s<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/reproduce.s?rev=267497&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/reproduce.s?rev=267497&view=auto</a><br>
==============================================================================<br>
--- lld/trunk/test/ELF/reproduce.s (added)<br>
+++ lld/trunk/test/ELF/reproduce.s Mon Apr 25 19:22:24 2016<br>
@@ -0,0 +1,26 @@<br>
+# REQUIRES: x86<br>
+<br>
+# RUN: rm -rf %S/repro<br>
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t<br>
+# RUN: ld.lld %t -o %t2 -shared --as-needed --reproduce %S/repro<br>
+# RUN: llvm-objdump -d %S/repro/%t | FileCheck %s --check-prefix=DUMP<br>
+# RUN: cat %S/repro/invocation.txt | FileCheck %s --check-prefix=INVOCATION<br>
+<br>
+.globl _start;<br>
+_start:<br>
+  mov $60, %rax<br>
+  mov $42, %rdi<br>
+  syscall<br>
+<br>
+# DUMP: Disassembly of section .text:<br>
+# DUMP: _start:<br>
+# DUMP:        0:       48 c7 c0 3c 00 00 00    movq    $60, %rax<br>
+# DUMP:        7:       48 c7 c7 2a 00 00 00    movq    $42, %rdi<br>
+# DUMP:        e:       0f 05   syscall<br>
+<br>
+# INVOCATION: lld {{.*}}reproduce.s{{.*}} -o {{.*}} -shared --as-needed --reproduce<br>
+<br>
+# RUN: rm -rf %S/repro2<br>
+# RUN: mkdir %S/repro2<br></blockquote><div><br></div><div>You probably want `%t.dir` or something like that instead of `%S` so that you avoid littering files in the source directory.</div><div><br></div><div>-- Sean Silva</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+# RUN: not ld.lld %t -o %t2 --reproduce %S/repro2 2>&1 | FileCheck --check-prefix=EDIR %s<br>
+# EDIR: --reproduce: can't create directory<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>