[lld] r267497 - [ELF] Introduce --reproduce flag.

Davide Italiano via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 25 17:22:24 PDT 2016


Author: davide
Date: Mon Apr 25 19:22:24 2016
New Revision: 267497

URL: http://llvm.org/viewvc/llvm-project?rev=267497&view=rev
Log:
[ELF] Introduce --reproduce flag.

--reproduce dumps the object files in a directory chosen
(preserving the file system layout) and the linker invocation
so that people can create an archive and upload for debugging.

Differential Revision:  http://reviews.llvm.org/D19494

Added:
    lld/trunk/test/ELF/reproduce.s
Modified:
    lld/trunk/ELF/Config.h
    lld/trunk/ELF/Driver.cpp
    lld/trunk/ELF/Options.td

Modified: lld/trunk/ELF/Config.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Config.h?rev=267497&r1=267496&r2=267497&view=diff
==============================================================================
--- lld/trunk/ELF/Config.h (original)
+++ lld/trunk/ELF/Config.h Mon Apr 25 19:22:24 2016
@@ -48,6 +48,7 @@ struct Configuration {
   llvm::StringRef SoName;
   llvm::StringRef Sysroot;
   std::string RPath;
+  std::string Reproduce;
   std::vector<llvm::StringRef> DynamicList;
   std::vector<llvm::StringRef> SearchPaths;
   std::vector<llvm::StringRef> Undefined;

Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=267497&r1=267496&r2=267497&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Mon Apr 25 19:22:24 2016
@@ -19,6 +19,7 @@
 #include "Writer.h"
 #include "lld/Driver/Driver.h"
 #include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/Path.h"
 #include "llvm/Support/TargetSelect.h"
 #include "llvm/Support/raw_ostream.h"
 #include <utility>
@@ -97,12 +98,29 @@ LinkerDriver::getArchiveMembers(MemoryBu
   return V;
 }
 
+static void dumpFile(StringRef SrcPath) {
+  SmallString<128> DirName;
+  sys::path::append(DirName, Config->Reproduce, sys::path::parent_path(SrcPath));
+  if (std::error_code EC = sys::fs::create_directories(DirName)) {
+    error(EC, "--reproduce: can't create directory");
+    return;
+  }
+
+  SmallString<128> DestPathName;
+  sys::path::append(DestPathName, Config->Reproduce, SrcPath);
+  if (std::error_code EC = sys::fs::copy_file(SrcPath, DestPathName))
+    error(EC, "--reproduce: can't copy file");
+}
+
 // Opens and parses a file. Path has to be resolved already.
 // Newly created memory buffers are owned by this driver.
 void LinkerDriver::addFile(StringRef Path) {
   using namespace llvm::sys::fs;
   if (Config->Verbose)
     llvm::outs() << Path << "\n";
+  if (!Config->Reproduce.empty())
+    dumpFile(Path);
+
   Optional<MemoryBufferRef> Buffer = readFile(Path);
   if (!Buffer.hasValue())
     return;
@@ -223,6 +241,25 @@ static bool hasZOption(opt::InputArgList
   return false;
 }
 
+static void dumpLinkerInvocation(ArrayRef<const char *> Args) {
+  std::error_code EC = sys::fs::create_directories(Config->Reproduce,
+    false /* IgnoreExisting */);
+  if (EC) {
+    error(EC, "--reproduce: can't create directory");
+    return;
+  }
+
+  SmallString<128> InvocationPath;
+  sys::path::append(InvocationPath, Config->Reproduce, "invocation.txt");
+  raw_fd_ostream OS(InvocationPath, EC, sys::fs::OpenFlags::F_None);
+  check(EC);
+
+  OS << Args[0];
+  for (unsigned I = 1, E = Args.size(); I < E; ++I)
+    OS << " " << Args[I];
+  OS << "\n";
+}
+
 void LinkerDriver::main(ArrayRef<const char *> ArgsArr) {
   ELFOptTable Parser;
   opt::InputArgList Args = Parser.parse(ArgsArr.slice(1));
@@ -237,6 +274,10 @@ void LinkerDriver::main(ArrayRef<const c
 
   initLLVM(Args);
   readConfigs(Args);
+
+  if (!Config->Reproduce.empty())
+    dumpLinkerInvocation(ArgsArr);
+
   createFiles(Args);
   checkOptions(Args);
   if (HasError)
@@ -311,6 +352,8 @@ void LinkerDriver::readConfigs(opt::Inpu
   Config->Fini = getString(Args, OPT_fini, "_fini");
   Config->Init = getString(Args, OPT_init, "_init");
   Config->OutputFile = getString(Args, OPT_o);
+  if (auto *Arg = Args.getLastArg(OPT_reproduce))
+    Config->Reproduce = Arg->getValue();
   Config->SoName = getString(Args, OPT_soname);
   Config->Sysroot = getString(Args, OPT_sysroot);
 

Modified: lld/trunk/ELF/Options.td
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Options.td?rev=267497&r1=267496&r2=267497&view=diff
==============================================================================
--- lld/trunk/ELF/Options.td (original)
+++ lld/trunk/ELF/Options.td Mon Apr 25 19:22:24 2016
@@ -120,6 +120,9 @@ def pie : Flag<["-"], "pie">,
 def print_gc_sections: Flag<["--"], "print-gc-sections">,
   HelpText<"List removed unused sections">;
 
+def reproduce : Separate<["--"], "reproduce">,
+  HelpText<"Dump linker invocation and input files for debugging">;
+
 def rpath : Separate<["-"], "rpath">,
   HelpText<"Add a DT_RUNPATH to the output">;
 

Added: lld/trunk/test/ELF/reproduce.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/reproduce.s?rev=267497&view=auto
==============================================================================
--- lld/trunk/test/ELF/reproduce.s (added)
+++ lld/trunk/test/ELF/reproduce.s Mon Apr 25 19:22:24 2016
@@ -0,0 +1,26 @@
+# REQUIRES: x86
+
+# RUN: rm -rf %S/repro
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+# RUN: ld.lld %t -o %t2 -shared --as-needed --reproduce %S/repro
+# RUN: llvm-objdump -d %S/repro/%t | FileCheck %s --check-prefix=DUMP
+# RUN: cat %S/repro/invocation.txt | FileCheck %s --check-prefix=INVOCATION
+
+.globl _start;
+_start:
+  mov $60, %rax
+  mov $42, %rdi
+  syscall
+
+# DUMP: Disassembly of section .text:
+# DUMP: _start:
+# DUMP:        0:       48 c7 c0 3c 00 00 00    movq    $60, %rax
+# DUMP:        7:       48 c7 c7 2a 00 00 00    movq    $42, %rdi
+# DUMP:        e:       0f 05   syscall
+
+# INVOCATION: lld {{.*}}reproduce.s{{.*}} -o {{.*}} -shared --as-needed --reproduce
+
+# RUN: rm -rf %S/repro2
+# RUN: mkdir %S/repro2
+# RUN: not ld.lld %t -o %t2 --reproduce %S/repro2 2>&1 | FileCheck --check-prefix=EDIR %s
+# EDIR: --reproduce: can't create directory




More information about the llvm-commits mailing list