[lld] 34a44b2 - [lld/COFF] Handle -start-lib / -end-lib better in /reproduce: output (#119752)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Dec 17 08:30:17 PST 2024
Author: Nico Weber
Date: 2024-12-17T11:30:13-05:00
New Revision: 34a44b20888479cf934014e3aa85c563725df69a
URL: https://github.com/llvm/llvm-project/commit/34a44b20888479cf934014e3aa85c563725df69a
DIFF: https://github.com/llvm/llvm-project/commit/34a44b20888479cf934014e3aa85c563725df69a.diff
LOG: [lld/COFF] Handle -start-lib / -end-lib better in /reproduce: output (#119752)
Previously, we'd collect all input files in Driver::filePaths, and then
write filePaths after all other flags in
createResponseFile(). This meant that `-start-lib foo.obj -end-lib`
would be written as `-start-lib -end-lib foo.obj`, changing semantics.
Instead, remove Driver::filePaths, and handle things that fed into it
directly:
* OPT_INPUT is now handled in the same way as other flags, so that we
now get `-start-lib foo.obj -end-lib` in response.txt as desired. Add a
test for -start-lib / -end-lib and /reproduce:.
* OPT_wholearchive_file needs explicit handling now -- but before, this
was buggy as well: We'd put the flag without a rewritten path in
response.txt, but also the rewritten input file without wholearchive
semantics via filePaths. So this commit makes --whole-archive work with
/reproduce: too, and adds test coverage.
* /defaultlib:foo is now written as /defaultlib:foo into response.txt,
instead of writing the resolved path previously. While response.txt
looks slightly differently, both should have the same semantics, and
this should be mostly a no-op. (It does require updating a test.)
* /defaultlib: from .drectve sections are no longer recorded in
response.txt. This seems like a progression -- in the non-repro case
they come from .obj files, so they should come (only) from there in the
repro case too. This adds test coverage for this case.
Makes createResponseFile() look more like the versions in the ELF and
MachO ports too.
Added:
Modified:
lld/COFF/Driver.cpp
lld/COFF/Driver.h
lld/test/COFF/linkrepro.test
Removed:
################################################################################
diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index 0705f1c1be9992..0eb73cef660175 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -204,7 +204,6 @@ void LinkerDriver::addBuffer(std::unique_ptr<MemoryBuffer> mb,
StringRef filename = mb->getBufferIdentifier();
MemoryBufferRef mbref = takeBuffer(std::move(mb));
- filePaths.push_back(filename);
// File type is detected by contents, not by file extension.
switch (identify_magic(mbref.getBuffer())) {
@@ -866,7 +865,6 @@ static std::string rewritePath(StringRef 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) {
SmallString<0> data;
raw_svector_ostream os(data);
@@ -875,11 +873,15 @@ static std::string createResponseFile(const opt::InputArgList &args,
switch (arg->getOption().getID()) {
case OPT_linkrepro:
case OPT_reproduce:
- case OPT_INPUT:
- case OPT_defaultlib:
case OPT_libpath:
case OPT_winsysroot:
break;
+ case OPT_INPUT:
+ os << quote(rewritePath(arg->getValue())) << "\n";
+ break;
+ case OPT_wholearchive_file:
+ os << arg->getSpelling() << quote(rewritePath(arg->getValue())) << "\n";
+ break;
case OPT_call_graph_ordering_file:
case OPT_deffile:
case OPT_manifestinput:
@@ -916,9 +918,6 @@ static std::string createResponseFile(const opt::InputArgList &args,
os << "/libpath:" << quote(relPath) << "\n";
}
- for (StringRef path : filePaths)
- os << quote(relativeToRoot(path)) << "\n";
-
return std::string(data);
}
@@ -2355,9 +2354,9 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
if (tar) {
llvm::TimeTraceScope timeScope("Reproducer: response file");
- tar->append("response.txt",
- createResponseFile(args, filePaths,
- ArrayRef<StringRef>(searchPaths).slice(1)));
+ tar->append(
+ "response.txt",
+ createResponseFile(args, ArrayRef<StringRef>(searchPaths).slice(1)));
}
// Handle /largeaddressaware
diff --git a/lld/COFF/Driver.h b/lld/COFF/Driver.h
index e94a961953581f..c2b92f61dcf4b5 100644
--- a/lld/COFF/Driver.h
+++ b/lld/COFF/Driver.h
@@ -197,7 +197,6 @@ class LinkerDriver {
bool run();
std::list<std::function<void()>> taskQueue;
- std::vector<StringRef> filePaths;
std::vector<MemoryBufferRef> resources;
llvm::DenseSet<StringRef> directivesExports;
diff --git a/lld/test/COFF/linkrepro.test b/lld/test/COFF/linkrepro.test
index d5a34a201a5da4..a5779a9ec82e16 100644
--- a/lld/test/COFF/linkrepro.test
+++ b/lld/test/COFF/linkrepro.test
@@ -1,7 +1,10 @@
# REQUIRES: x86, shell
# RUN: rm -rf %t.dir
+# RUN: split-file %s %t.dir
+
# RUN: yaml2obj %p/Inputs/hello32.yaml -o %t.obj
+# RUN: llvm-mc -filetype=obj -triple=i386-windows %t.dir/drectve.s -o %t.dir/drectve.obj
# RUN: echo '_main at 0' > %t.order
# RUN: touch %t.def
# RUN: touch %t.cg
@@ -46,7 +49,7 @@ and various other flags.
# 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: FileCheck %s --check-prefix=RSP-DEFAULTLIB < repro/response.txt
# RUN: cd repro; lld-link @response.txt
Test adding .lib files with LIB env var to repro archive,
@@ -61,7 +64,7 @@ and various other flags.
# 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: FileCheck %s --check-prefix=RSP-DEFAULTLIB < repro/response.txt
# RUN: cd repro; lld-link @response.txt
# LIST: .obj
@@ -70,14 +73,21 @@ and various other flags.
# LIST: .def
# LIST: .order
+# RSP: linkrepro.test.tmp.obj
+# RSP: std32.lib
# RSP: /subsystem:console
# RSP: /entry:main at 0
# RSP: /out:
# RSP-NOT: /order:@/
# RSP-NOT: /def:/
-# RSP: linkrepro.test.tmp.obj
-# RSP-NOT: defaultlib
-# RSP: std32.lib
+
+# RSP-DEFAULTLIB: linkrepro.test.tmp.obj
+# RSP-DEFAULTLIB: /defaultlib:std32
+# RSP-DEFAULTLIB: /subsystem:console
+# RSP-DEFAULTLIB: /entry:main at 0
+# RSP-DEFAULTLIB: /out:
+# RSP-DEFAULTLIB-NOT: /order:@/
+# RSP-DEFAULTLIB-NOT: /def:/
Test /call-graph-ordering-file (can't be used with /order:, needs separate test)
# RUN: mkdir -p %t.dir/build5
@@ -96,3 +106,90 @@ Test /call-graph-ordering-file (can't be used with /order:, needs separate test)
# LISTCG: .cg
# RSPCG-NOT: /call-graph-ordering-file:/
+
+Test /defaultlib: from a .drectve section
+# RUN: mkdir -p %t.dir/build6
+# RUN: cd %t.dir/build6
+# RUN: lld-link %t.obj %t.dir/drectve.obj /libpath:%p/Inputs /subsystem:console \
+# RUN: /entry:main at 0 /linkrepro:. -safeseh:no /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-DRECTVE < repro/response.txt
+# RUN: cd repro; lld-link @response.txt
+
+# RSP-DRECTVE: linkrepro.test.tmp.obj
+# RSP-DRECTVE: drectve.obj
+# RSP-DRECTVE: /subsystem:console
+# RSP-DRECTVE: /entry:main at 0
+# RSP-DRECTVE: -safeseh:no
+# RSP-DRECTVE: /out:
+
+Test /wholearchive: with /linkrepro:
+# RUN: llvm-mc -filetype=obj -triple=i386-windows %t.dir/archive.s -o %t.dir/archive.obj
+# RUN: rm -f %t.dir/build7/archive.lib
+# RUN: llvm-ar rcs %t.dir/archive.lib %t.dir/archive.obj
+# RUN: mkdir -p %t.dir/build7
+# RUN: cd %t.dir/build7
+ RUN: lld-link %t.obj /defaultlib:std32 /libpath:%p/Inputs /subsystem:console \
+# RUN: /entry:main at 0 /linkrepro:. -safeseh:no /wholearchive:%t.dir/archive.lib \
+# RUN: /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-WHOLEARCHIVE < repro/response.txt
+# RUN: cd repro; lld-link @response.txt
+
+# RSP-WHOLEARCHIVE: linkrepro.test.tmp.obj
+# RSP-WHOLEARCHIVE: /defaultlib:std32
+# RSP-WHOLEARCHIVE: /subsystem:console
+# RSP-WHOLEARCHIVE: /entry:main at 0
+# RSP-WHOLEARCHIVE: -safeseh:no
+# RSP-WHOLEARCHIVE: /wholearchive:{{.*}}archive.lib
+# RSP-WHOLEARCHIVE: /out:
+
+Test /start-lib / /end-lib with /linkrepro:
+# RUN: mkdir -p %t.dir/build8
+# RUN: cd %t.dir/build8
+# RUN: lld-link %t.obj /defaultlib:std32 /libpath:%p/Inputs /subsystem:console \
+# RUN: /entry:main at 0 /linkrepro:. -safeseh:no /start-lib %t.dir/drectve.obj /end-lib \
+# RUN: /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-STARTLIB < repro/response.txt
+# RUN: cd repro; lld-link @response.txt
+
+# RSP-STARTLIB: linkrepro.test.tmp.obj
+# RSP-STARTLIB: /defaultlib:std32
+# RSP-STARTLIB: /subsystem:console
+# RSP-STARTLIB: /entry:main at 0
+# RSP-STARTLIB: -safeseh:no
+# RSP-STARTLIB: /start-lib
+# RSP-STARTLIB-NEXT: drectve.obj
+# RSP-STARTLIB-NEXT: /end-lib
+# RSP-STARTLIB: /out:
+
+#--- drectve.s
+ .section .drectve, "yn"
+ .ascii "/defaultlib:std32"
+
+#--- archive.s
+ .text
+ .intel_syntax noprefix
+ .globl exportfn3
+ .p2align 4
+exportfn3:
+ ret
+
+ .section .drectve,"yni"
+ .ascii " /EXPORT:exportfn3"
More information about the llvm-commits
mailing list