forked from OSchip/llvm-project
[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 llvm-svn: 361244
This commit is contained in:
parent
bc03bee66b
commit
35150bb534
|
@ -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
|
||||
}
|
|
@ -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 char *> ArgsArr) {
|
|||
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)");
|
||||
|
|
|
@ -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::readFile(StringRef Path) {
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -85,6 +85,8 @@ defm print_gc_sections: B<"print-gc-sections",
|
|||
|
||||
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">;
|
||||
|
|
Loading…
Reference in New Issue