[lld] e6d1f26 - [lld-link] Add /reproduce: support for several flags
Nico Weber via llvm-commits
llvm-commits at lists.llvm.org
Mon Feb 22 13:53:10 PST 2021
Author: Nico Weber
Date: 2021-02-22T16:52:49-05:00
New Revision: e6d1f261a5a08d4c05b25509a6f4217a8a1c2188
URL: https://github.com/llvm/llvm-project/commit/e6d1f261a5a08d4c05b25509a6f4217a8a1c2188
DIFF: https://github.com/llvm/llvm-project/commit/e6d1f261a5a08d4c05b25509a6f4217a8a1c2188.diff
LOG: [lld-link] Add /reproduce: support for several flags
/reproduce: now works correctly with:
- /call-graph-ordering-file:
- /def:
- /natvis:
- /order:
- /pdbstream:
I went through all instances of MemoryBuffer::getFile() and made sure
everything that didn't already do so called takeBuffer().
For natvis, that wasn't possible since DebugInfo/PDB wants to take
owernship of the natvis buffer. For that case, I'm manually adding the
tar file entry.
/natvis: and /pdbstream: is slightly awkward, since createResponseFile()
always adds these flags to the response file but createPDB() (which
ultimately adds the files referenced by the flags) is only called if
/debug is also passed. So when using /natvis: without /debug with
/reproduce:, lld won't warn, but when linking using the response
file from the archive, it won't find the natvis file since it's not
in the tar. This isn't a new issue though, and after this patch things
at least work with using /natvis: _with_ debug with /reproduce:.
(Same for /pdbstream:)
Differential Revison: https://reviews.llvm.org/D97212
Added:
Modified:
lld/COFF/Driver.cpp
lld/COFF/Driver.h
lld/COFF/PDB.cpp
lld/test/COFF/linkrepro-manifest.test
lld/test/COFF/linkrepro-pdb.test
lld/test/COFF/linkrepro.test
Removed:
################################################################################
diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index 96ac7957f557..07fa7cc14f4c 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -54,7 +54,7 @@
using namespace llvm;
using namespace llvm::object;
using namespace llvm::COFF;
-using llvm::sys::Process;
+using namespace llvm::sys;
namespace lld {
namespace coff {
@@ -622,6 +622,14 @@ static uint64_t getDefaultImageBase() {
return config->dll ? 0x10000000 : 0x400000;
}
+static std::string rewritePath(StringRef s) {
+ if (fs::exists(s))
+ return relativeToRoot(s);
+ return std::string(s);
+}
+
+// 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,
ArrayRef<StringRef> filePaths,
ArrayRef<StringRef> searchPaths) {
@@ -642,6 +650,24 @@ static std::string createResponseFile(const opt::InputArgList &args,
case OPT_manifestinput:
case OPT_manifestuac:
break;
+ case OPT_call_graph_ordering_file:
+ case OPT_deffile:
+ case OPT_natvis:
+ os << arg->getSpelling() << quote(rewritePath(arg->getValue())) << '\n';
+ break;
+ case OPT_order: {
+ StringRef orderFile = arg->getValue();
+ orderFile.consume_front("@");
+ os << arg->getSpelling() << '@' << quote(rewritePath(orderFile)) << '\n';
+ break;
+ }
+ case OPT_pdbstream: {
+ const std::pair<StringRef, StringRef> nameFile =
+ StringRef(arg->getValue()).split("=");
+ os << arg->getSpelling() << nameFile.first << '='
+ << quote(rewritePath(nameFile.second)) << '\n';
+ break;
+ }
case OPT_implib:
case OPT_pdb:
case OPT_pdbstripped:
@@ -838,6 +864,9 @@ static void parseModuleDefs(StringRef path) {
COFFModuleDefinition m = check(parseCOFFModuleDefinition(
mb->getMemBufferRef(), config->machine, config->mingw));
+ // Include in /reproduce: output if applicable.
+ driver->takeBuffer(std::move(mb));
+
if (config->outputFile.empty())
config->outputFile = std::string(saver.save(m.OutputFile));
config->importName = std::string(saver.save(m.ImportName));
@@ -938,6 +967,9 @@ static void parseOrderFile(StringRef arg) {
else
config->order[s] = INT_MIN + config->order.size();
}
+
+ // Include in /reproduce: output if applicable.
+ driver->takeBuffer(std::move(mb));
}
static void parseCallGraphFile(StringRef path) {
@@ -978,6 +1010,9 @@ static void parseCallGraphFile(StringRef path) {
if (SectionChunk *to = findSection(fields[1]))
config->callGraphProfile[{from, to}] += count;
}
+
+ // Include in /reproduce: output if applicable.
+ driver->takeBuffer(std::move(mb));
}
static void readCallGraphsFromObjectFiles() {
diff --git a/lld/COFF/Driver.h b/lld/COFF/Driver.h
index 6f71a37f729f..5729bed69528 100644
--- a/lld/COFF/Driver.h
+++ b/lld/COFF/Driver.h
@@ -93,9 +93,9 @@ class LinkerDriver {
void enqueuePath(StringRef path, bool wholeArchive, bool lazy);
-private:
std::unique_ptr<llvm::TarWriter> tar; // for /linkrepro
+private:
// Searches a file from search paths.
Optional<StringRef> findFile(StringRef filename);
Optional<StringRef> findLib(StringRef filename);
diff --git a/lld/COFF/PDB.cpp b/lld/COFF/PDB.cpp
index 36526de7796c..e6ad60087395 100644
--- a/lld/COFF/PDB.cpp
+++ b/lld/COFF/PDB.cpp
@@ -1093,7 +1093,14 @@ void PDBLinker::addNatvisFiles() {
warn("Cannot open input file: " + file);
continue;
}
- builder.addInjectedSource(file, std::move(*dataOrErr));
+ std::unique_ptr<MemoryBuffer> data = std::move(*dataOrErr);
+
+ // Can't use takeBuffer() here since addInjectedSource() takes ownership.
+ if (driver->tar)
+ driver->tar->append(relativeToRoot(data->getBufferIdentifier()),
+ data->getBuffer());
+
+ builder.addInjectedSource(file, std::move(data));
}
}
@@ -1106,7 +1113,9 @@ void PDBLinker::addNamedStreams() {
warn("Cannot open input file: " + file);
continue;
}
- exitOnErr(builder.addNamedStream(stream, (*dataOrErr)->getBuffer()));
+ std::unique_ptr<MemoryBuffer> data = std::move(*dataOrErr);
+ exitOnErr(builder.addNamedStream(stream, data->getBuffer()));
+ driver->takeBuffer(std::move(data));
}
}
diff --git a/lld/test/COFF/linkrepro-manifest.test b/lld/test/COFF/linkrepro-manifest.test
index a938ab590b2e..2640588bc5ca 100644
--- a/lld/test/COFF/linkrepro-manifest.test
+++ b/lld/test/COFF/linkrepro-manifest.test
@@ -1,7 +1,13 @@
REQUIRES: x86, gnutar, manifest_tool
+manifest-related files are compiled to a .res file and the .res file is
+added to the repro archive, instead of adding the inputs.
+
RUN: rm -rf %t && mkdir %t && cd %t
-RUN: lld-link -entry:__ImageBase -nodefaultlib -linkrepro:%t -manifest:embed %p/Inputs/std32.lib -subsystem:console
+RUN: lld-link -entry:__ImageBase -nodefaultlib -linkrepro:%t \
+RUN: -manifest:embed %p/Inputs/std32.lib -subsystem:console \
+RUN: -manifestinput:%p/Inputs/manifestinput.test
+
RUN: tar tf repro.tar | FileCheck --check-prefix=LIST %s
RUN: tar xOf repro.tar repro/response.txt | FileCheck %s
diff --git a/lld/test/COFF/linkrepro-pdb.test b/lld/test/COFF/linkrepro-pdb.test
index 34152a459077..838f07447d73 100644
--- a/lld/test/COFF/linkrepro-pdb.test
+++ b/lld/test/COFF/linkrepro-pdb.test
@@ -4,19 +4,31 @@ RUN: rm -rf %t && mkdir -p %t && cd %t
RUN: yaml2obj %S/Inputs/pdb-type-server-simple-a.yaml -o a.obj
RUN: yaml2obj %S/Inputs/pdb-type-server-simple-b.yaml -o b.obj
RUN: llvm-pdbutil yaml2pdb %S/Inputs/pdb-type-server-simple-ts.yaml -pdb ts.pdb
-RUN: lld-link a.obj b.obj -entry:main -debug -out:%t.exe -pdb:%t.pdb -nodefaultlib -linkrepro:.
-RUN: tar xOf repro.tar repro/%:t/ts.pdb > repro-ts.pdb
-RUN:
diff ts.pdb repro-ts.pdb
-
+RUN: cp %p/Inputs/natvis-1.natvis %t.natvis
+RUN: cp %p/Inputs/stream.txt %t.txt
+RUN: lld-link a.obj b.obj -entry:main -debug -out:%t.exe -pdb:%t.pdb \
+RUN: -nodefaultlib -linkrepro:. -natvis:%t.natvis \
+RUN: -pdbstream:srcsrv=%t.txt
+RUN: tar tf repro.tar | FileCheck --check-prefix=LIST %s
RUN: tar xf repro.tar
-RUN: cat repro/response.txt | FileCheck -check-prefix=PDB %s
+RUN:
diff ts.pdb repro/%:t/ts.pdb
+RUN:
diff %t.natvis repro/%:t.natvis
+RUN:
diff %t.txt repro/%:t.txt
+RUN: cat repro/response.txt | FileCheck -check-prefix=RSP %s
+
+LIST: .obj
+LIST: response.txt
+LIST: .natvis
-PDB: -out:linkrepro-pdb.test.tmp.exe
-PDB-NEXT: -pdb:linkrepro-pdb.test.tmp.pdb
+RSP: -out:linkrepro-pdb.test.tmp.exe
+RSP-NEXT: -pdb:linkrepro-pdb.test.tmp.pdb
+RSP-NEXT: -nodefaultlib
+RSP-NOT: -natvis:/
+RSP-NOT: -pdbstream:srcsrv=/
RUN: yaml2obj %p/Inputs/export.yaml -o %t1.obj
-RUN: lld-link /out:%t1.dll /dll %t1.obj /implib:%t1.lib /export:exportfn1 /export:exportfn2 /linkrepro:.
-RUN: tar xf repro.tar
-RUN: cat repro/response.txt | FileCheck -check-prefix=IMP %s
+RUN: lld-link /out:%t1.dll /dll %t1.obj /implib:%t1.lib /export:exportfn1 /export:exportfn2 /reproduce:repro2.tar
+RUN: tar xf repro2.tar
+RUN: cat repro2/response.txt | FileCheck -check-prefix=IMP %s
IMP: /implib:linkrepro-pdb.test.tmp1.lib
diff --git a/lld/test/COFF/linkrepro.test b/lld/test/COFF/linkrepro.test
index 29208fd6652a..d5a34a201a5d 100644
--- a/lld/test/COFF/linkrepro.test
+++ b/lld/test/COFF/linkrepro.test
@@ -1,9 +1,13 @@
# REQUIRES: x86, shell
# RUN: rm -rf %t.dir
-# RUN: mkdir -p %t.dir/build1 %t.dir/build2 %t.dir/build3 %t.dir/build4
# RUN: yaml2obj %p/Inputs/hello32.yaml -o %t.obj
+# RUN: echo '_main at 0' > %t.order
+# RUN: touch %t.def
+# RUN: touch %t.cg
+Test link.exe-style /linkrepro: flag.
+# RUN: mkdir -p %t.dir/build1
# RUN: cd %t.dir/build1
# RUN: lld-link %t.obj %p/Inputs/std32.lib /subsystem:console \
# RUN: /entry:main at 0 /linkrepro:. /out:%t.exe
@@ -12,7 +16,7 @@
# RUN:
diff %p/Inputs/std32.lib repro/%:p/Inputs/std32.lib
# RUN: FileCheck %s --check-prefix=RSP < repro/response.txt
-# RUN: cd %t.dir/build1
+Test lld-style /reproduce: flag.
# RUN: lld-link %t.obj %p/Inputs/std32.lib /subsystem:console \
# RUN: /entry:main at 0 /reproduce:repro2.tar /out:%t.exe
# RUN: tar xf repro2.tar
@@ -20,6 +24,8 @@
# RUN:
diff %p/Inputs/std32.lib repro2/%:p/Inputs/std32.lib
# RUN: FileCheck %s --check-prefix=RSP < repro2/response.txt
+Test LLD_REPRODUCE env var.
+# RUN: mkdir -p %t.dir/build2
# RUN: cd %t.dir/build2
# RUN: env LLD_REPRODUCE=repro.tar lld-link %t.obj %p/Inputs/std32.lib \
# RUN: /subsystem:console /entry:main at 0 /out:%t.exe
@@ -28,26 +34,65 @@
# RUN:
diff %p/Inputs/std32.lib repro/%:p/Inputs/std32.lib
# RUN: FileCheck %s --check-prefix=RSP < repro/response.txt
+Test adding .lib files with /libpath: to repro archive,
+and various other flags.
+# RUN: mkdir -p %t.dir/build3
# RUN: cd %t.dir/build3
# RUN: lld-link %t.obj /libpath:%p/Inputs /defaultlib:std32 /subsystem:console \
-# RUN: /entry:main at 0 /linkrepro:. /out:%t.exe
+# RUN: /entry:main at 0 /linkrepro:. /out:%t.exe /order:@%t.order /def:%t.def
+# RUN: tar tf repro.tar | FileCheck --check-prefix=LIST %s
# RUN: tar xf repro.tar
# RUN:
diff %t.obj repro/%:t.obj
+# RUN:
diff %t.order repro/%:t.order
+# RUN:
diff %t.def repro/%:t.def
# RUN:
diff %p/Inputs/std32.lib repro/%:p/Inputs/std32.lib
# RUN: FileCheck %s --check-prefix=RSP < repro/response.txt
+# RUN: cd repro; lld-link @response.txt
+Test adding .lib files with LIB env var to repro archive,
+and various other flags.
+# RUN: mkdir -p %t.dir/build4
# RUN: cd %t.dir/build4
# RUN: env LIB=%p/Inputs lld-link %t.obj /defaultlib:std32 /subsystem:console \
-# RUN: /entry:main at 0 /linkrepro:. /out:%t.exe
+# RUN: /entry:main at 0 /linkrepro:. /out:%t.exe /order:@%t.order /def:%t.def
+# RUN: tar tf repro.tar | FileCheck --check-prefix=LIST %s
# RUN: tar xf repro.tar
# RUN:
diff %t.obj repro/%:t.obj
+# RUN:
diff %t.order repro/%:t.order
+# RUN:
diff %t.def repro/%:t.def
# RUN:
diff %p/Inputs/std32.lib repro/%:p/Inputs/std32.lib
# RUN: FileCheck %s --check-prefix=RSP < repro/response.txt
+# RUN: cd repro; lld-link @response.txt
+
+# LIST: .obj
+# LIST: std32.lib
+# LIST: response.txt
+# LIST: .def
+# LIST: .order
# RSP: /subsystem:console
# RSP: /entry:main at 0
-# RSP-NOT: /linkrepro:
# RSP: /out:
+# RSP-NOT: /order:@/
+# RSP-NOT: /def:/
# RSP: linkrepro.test.tmp.obj
# RSP-NOT: defaultlib
# RSP: std32.lib
+
+Test /call-graph-ordering-file (can't be used with /order:, needs separate test)
+# RUN: mkdir -p %t.dir/build5
+# RUN: cd %t.dir/build5
+# RUN: lld-link %t.obj %p/Inputs/std32.lib /subsystem:console \
+# RUN: /entry:main at 0 /linkrepro:. /out:%t.exe /call-graph-ordering-file:%t.cg
+# RUN: tar tf repro.tar | FileCheck --check-prefix=LISTCG %s
+# RUN: tar xf repro.tar
+# RUN:
diff %t.obj repro/%:t.obj
+# RUN:
diff %t.cg repro/%:t.cg
+# RUN: FileCheck %s --check-prefix=RSPCG < repro/response.txt
+# RUN: cd repro; lld-link @response.txt
+
+# LISTCG: .obj
+# LISTCG: response.txt
+# LISTCG: .cg
+
+# RSPCG-NOT: /call-graph-ordering-file:/
More information about the llvm-commits
mailing list