[lld] r361244 - [WebAssembly] Add --reproduce.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Tue May 21 04:52:14 PDT 2019


Author: ruiu
Date: Tue May 21 04:52:14 2019
New Revision: 361244

URL: http://llvm.org/viewvc/llvm-project?rev=361244&view=rev
Log:
[WebAssembly] Add --reproduce.

--reproduce is a convenient option for debugging. If you invoke lld
with `--reproduce=repro.tar`, it creates `repro.tar` with all input
files and the command line options given to the linker, so that it is
very easy to run lld with the exact same inputs.

ELF and Windows lld have this option.

This patch add that option to lld/wasm.

Differential Revision: https://reviews.llvm.org/D62170

Added:
    lld/trunk/test/wasm/reproduce.ll
Modified:
    lld/trunk/wasm/Driver.cpp
    lld/trunk/wasm/InputFiles.cpp
    lld/trunk/wasm/InputFiles.h
    lld/trunk/wasm/Options.td

Added: lld/trunk/test/wasm/reproduce.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/reproduce.ll?rev=361244&view=auto
==============================================================================
--- lld/trunk/test/wasm/reproduce.ll (added)
+++ lld/trunk/test/wasm/reproduce.ll Tue May 21 04:52:14 2019
@@ -0,0 +1,27 @@
+; REQUIRES: shell
+; RUN: rm -rf %t.dir
+; RUN: mkdir -p %t.dir
+; RUN: llc -filetype=obj %s -o %t.dir/foo.o
+; RUN: wasm-ld --reproduce=%t.dir/repro.tar -o out.wasm %t.dir/foo.o
+
+; RUN: cd %t.dir
+; RUN: tar tf repro.tar | FileCheck --check-prefix=TAR
+
+; TAR: repro/response.txt
+; TAR: repro/version.txt
+; TAR: repro/{{.*}}/foo.o
+
+; RUN: tar xf repro.tar
+; RUN: FileCheck --check-prefix=RSP %s < repro/response.txt
+
+; RSP: -o out.wasm
+; RSP: {{.*}}/foo.o
+
+; RUN: FileCheck %s --check-prefix=VERSION < repro/version.txt
+; VERSION: LLD
+
+target triple = "wasm32-unknown-unknown"
+
+define void @_start() {
+  ret void
+}

Modified: lld/trunk/wasm/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/Driver.cpp?rev=361244&r1=361243&r2=361244&view=diff
==============================================================================
--- lld/trunk/wasm/Driver.cpp (original)
+++ lld/trunk/wasm/Driver.cpp Tue May 21 04:52:14 2019
@@ -16,6 +16,7 @@
 #include "lld/Common/Args.h"
 #include "lld/Common/ErrorHandler.h"
 #include "lld/Common/Memory.h"
+#include "lld/Common/Reproduce.h"
 #include "lld/Common/Strings.h"
 #include "lld/Common/Threads.h"
 #include "lld/Common/Version.h"
@@ -26,6 +27,7 @@
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/Process.h"
+#include "llvm/Support/TarWriter.h"
 #include "llvm/Support/TargetSelect.h"
 
 #define DEBUG_TYPE "lld"
@@ -504,6 +506,34 @@ static void createSyntheticSymbols() {
       "__dso_handle", WASM_SYMBOL_VISIBILITY_HIDDEN);
 }
 
+// Reconstructs command line arguments so that so that you can re-run
+// the same command with the same inputs. This is for --reproduce.
+static std::string createResponseFile(const opt::InputArgList &Args) {
+  SmallString<0> Data;
+  raw_svector_ostream OS(Data);
+
+  // Copy the command line to the output while rewriting paths.
+  for (auto *Arg : Args) {
+    switch (Arg->getOption().getUnaliasedOption().getID()) {
+    case OPT_reproduce:
+      break;
+    case OPT_INPUT:
+      OS << quote(relativeToRoot(Arg->getValue())) << "\n";
+      break;
+    case OPT_o:
+      // If -o path contains directories, "lld @response.txt" will likely
+      // fail because the archive we are creating doesn't contain empty
+      // directories for the output path (-o doesn't create directories).
+      // Strip directories to prevent the issue.
+      OS << "-o " << quote(sys::path::filename(Arg->getValue())) << "\n";
+      break;
+    default:
+      OS << toString(*Arg) << "\n";
+    }
+  }
+  return Data.str();
+}
+
 void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
   WasmOptTable Parser;
   opt::InputArgList Args = Parser.parse(ArgsArr.slice(1));
@@ -522,6 +552,20 @@ void LinkerDriver::link(ArrayRef<const c
     return;
   }
 
+  // Handle --reproduce
+  if (auto *Arg = Args.getLastArg(OPT_reproduce)) {
+    StringRef Path = Arg->getValue();
+    Expected<std::unique_ptr<TarWriter>> ErrOrWriter =
+        TarWriter::create(Path, path::stem(Path));
+    if (ErrOrWriter) {
+      Tar = std::move(*ErrOrWriter);
+      Tar->append("response.txt", createResponseFile(Args));
+      Tar->append("version.txt", getLLDVersion() + "\n");
+    } else {
+      error("--reproduce: " + toString(ErrOrWriter.takeError()));
+    }
+  }
+
   // Parse and evaluate -mllvm options.
   std::vector<const char *> V;
   V.push_back("wasm-ld (LLVM option parsing)");

Modified: lld/trunk/wasm/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/InputFiles.cpp?rev=361244&r1=361243&r2=361244&view=diff
==============================================================================
--- lld/trunk/wasm/InputFiles.cpp (original)
+++ lld/trunk/wasm/InputFiles.cpp Tue May 21 04:52:14 2019
@@ -14,8 +14,10 @@
 #include "SymbolTable.h"
 #include "lld/Common/ErrorHandler.h"
 #include "lld/Common/Memory.h"
+#include "lld/Common/Reproduce.h"
 #include "llvm/Object/Binary.h"
 #include "llvm/Object/Wasm.h"
+#include "llvm/Support/TarWriter.h"
 #include "llvm/Support/raw_ostream.h"
 
 #define DEBUG_TYPE "lld"
@@ -27,6 +29,8 @@ using namespace llvm;
 using namespace llvm::object;
 using namespace llvm::wasm;
 
+std::unique_ptr<llvm::TarWriter> lld::wasm::Tar;
+
 Optional<MemoryBufferRef> lld::wasm::readFile(StringRef Path) {
   log("Loading: " + Path);
 
@@ -39,6 +43,8 @@ Optional<MemoryBufferRef> lld::wasm::rea
   MemoryBufferRef MBRef = MB->getMemBufferRef();
   make<std::unique_ptr<MemoryBuffer>>(std::move(MB)); // take MB ownership
 
+  if (Tar)
+    Tar->append(relativeToRoot(Path), MBRef.getBuffer());
   return MBRef;
 }
 

Modified: lld/trunk/wasm/InputFiles.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/InputFiles.h?rev=361244&r1=361243&r2=361244&view=diff
==============================================================================
--- lld/trunk/wasm/InputFiles.h (original)
+++ lld/trunk/wasm/InputFiles.h Tue May 21 04:52:14 2019
@@ -19,6 +19,10 @@
 #include "llvm/Support/MemoryBuffer.h"
 #include <vector>
 
+namespace llvm {
+class TarWriter;
+}
+
 namespace lld {
 namespace wasm {
 
@@ -29,6 +33,10 @@ class InputGlobal;
 class InputEvent;
 class InputSection;
 
+// If --reproduce option is given, all input files are written
+// to this tar archive.
+extern std::unique_ptr<llvm::TarWriter> Tar;
+
 class InputFile {
 public:
   enum Kind {

Modified: lld/trunk/wasm/Options.td
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/Options.td?rev=361244&r1=361243&r2=361244&view=diff
==============================================================================
--- lld/trunk/wasm/Options.td (original)
+++ lld/trunk/wasm/Options.td Tue May 21 04:52:14 2019
@@ -85,6 +85,8 @@ defm print_gc_sections: B<"print-gc-sect
 
 def relocatable: F<"relocatable">, HelpText<"Create relocatable object file">;
 
+defm reproduce: Eq<"reproduce", "Dump linker invocation and input files for debugging">;
+
 def shared: F<"shared">, HelpText<"Build a shared object">;
 
 def strip_all: F<"strip-all">, HelpText<"Strip all symbols">;




More information about the llvm-commits mailing list