[lld] 2b2e858 - [lld-macho] Handle filename being passed in -lto_object_path
Daniel Bertalan via llvm-commits
llvm-commits at lists.llvm.org
Sat Jul 16 12:57:42 PDT 2022
Author: Daniel Bertalan
Date: 2022-07-16T21:46:47+02:00
New Revision: 2b2e858e9cbb1d459804f8e393ac6b90459ccb7a
URL: https://github.com/llvm/llvm-project/commit/2b2e858e9cbb1d459804f8e393ac6b90459ccb7a
DIFF: https://github.com/llvm/llvm-project/commit/2b2e858e9cbb1d459804f8e393ac6b90459ccb7a.diff
LOG: [lld-macho] Handle filename being passed in -lto_object_path
Clang passes a filename rather than a directory in -lto_object_path when
using FullLTO. Previously, it was always treated it as a directory, so
lld would crash when it attempted to create temporary files inside it.
Fixes #54805
Differential Revision: https://reviews.llvm.org/D129705
Added:
lld/test/MachO/invalid/invalid-lto-object-path.ll
Modified:
lld/MachO/LTO.cpp
lld/test/MachO/lto-object-path.ll
Removed:
################################################################################
diff --git a/lld/MachO/LTO.cpp b/lld/MachO/LTO.cpp
index e87c4c4131069..0b76216d24b5b 100644
--- a/lld/MachO/LTO.cpp
+++ b/lld/MachO/LTO.cpp
@@ -138,8 +138,22 @@ std::vector<ObjFile *> BitcodeCompiler::compile() {
saveBuffer(buf[i], config->outputFile + Twine(i) + ".lto.o");
}
- if (!config->ltoObjPath.empty())
- fs::create_directories(config->ltoObjPath);
+ // In ThinLTO mode, Clang passes a temporary directory in -object_path_lto,
+ // while the argument is a single file in FullLTO mode.
+ bool objPathIsDir = true;
+ if (!config->ltoObjPath.empty()) {
+ if (std::error_code ec = fs::create_directories(config->ltoObjPath))
+ fatal("cannot create LTO object path " + config->ltoObjPath + ": " +
+ ec.message());
+
+ if (!fs::is_directory(config->ltoObjPath)) {
+ objPathIsDir = false;
+ unsigned objCount =
+ count_if(buf, [](const SmallString<0> &b) { return !b.empty(); });
+ if (objCount > 1)
+ fatal("-object_path_lto must specify a directory when using ThinLTO");
+ }
+ }
std::vector<ObjFile *> ret;
for (unsigned i = 0; i != maxTasks; ++i) {
@@ -149,9 +163,10 @@ std::vector<ObjFile *> BitcodeCompiler::compile() {
uint32_t modTime = 0;
if (!config->ltoObjPath.empty()) {
filePath = config->ltoObjPath;
- path::append(filePath, Twine(i) + "." +
- getArchitectureName(config->arch()) +
- ".lto.o");
+ if (objPathIsDir)
+ path::append(filePath, Twine(i) + "." +
+ getArchitectureName(config->arch()) +
+ ".lto.o");
saveBuffer(buf[i], filePath);
modTime = getModTime(filePath);
}
diff --git a/lld/test/MachO/invalid/invalid-lto-object-path.ll b/lld/test/MachO/invalid/invalid-lto-object-path.ll
new file mode 100644
index 0000000000000..75c6a97e446fb
--- /dev/null
+++ b/lld/test/MachO/invalid/invalid-lto-object-path.ll
@@ -0,0 +1,27 @@
+; REQUIRES: x86
+
+;; Creating read-only directories with `chmod 400` isn't supported on Windows
+; UNSUPPORTED: system-windows
+
+;; -object_path_lto specifies a directory that cannot be created
+; RUN: rm -rf %t && mkdir %t && mkdir %t/dir
+; RUN: chmod 400 %t/dir
+; RUN: llvm-as %s -o %t/full.o
+; RUN: not %lld %t/full.o -o /dev/null -object_path_lto %t/dir/dir2 2>&1 | FileCheck %s --check-prefix=READONLY -DDIR=%t/dir/dir2
+
+; READONLY: error: cannot create LTO object path [[DIR]]: {{.*}}
+
+;; Multiple objects need to be created, but -object_path_lto doesn't point to a directory
+; RUN: touch %t/out.o
+; RUN: opt -module-summary %s -o %t/thin.o
+; RUN: not %lld %t/full.o %t/thin.o -o /dev/null -object_path_lto %t/out.o 2>&1 | FileCheck %s --check-prefix=MULTIPLE
+
+; MULTIPLE: error: -object_path_lto must specify a directory when using ThinLTO
+
+
+target triple = "x86_64-apple-macosx10.15.0"
+target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+
+define void @main() {
+ ret void
+}
diff --git a/lld/test/MachO/lto-object-path.ll b/lld/test/MachO/lto-object-path.ll
index b21b38f23527e..d61dc2d1eb953 100644
--- a/lld/test/MachO/lto-object-path.ll
+++ b/lld/test/MachO/lto-object-path.ll
@@ -8,16 +8,23 @@
; RUN: llvm-nm -pa %t/test | FileCheck %s --check-prefixes CHECK,NOOBJPATH
; RUN: %lld %t/test.o -o %t/test -object_path_lto %t/lto-temps
-; RUN: llvm-nm -pa %t/test | FileCheck %s --check-prefixes CHECK,OBJPATH -DDIR=%t/lto-temps
+; RUN: llvm-nm -pa %t/test | FileCheck %s --check-prefixes CHECK,OBJPATH-DIR -DDIR=%t/lto-temps
-; CHECK: 0000000000000000 - 00 0000 SO /tmp/test.cpp
-; NOOBJPATH-NEXT: 0000000000000000 - 03 0001 OSO /tmp/lto.tmp
+;; check that the object path can be an existing file
+; RUN: touch %t/lto-tmp.o
+; RUN: %lld %t/test.o -o %t/test -object_path_lto %t/lto-tmp.o
+; RUN: llvm-nm -pa %t/test | FileCheck %s --check-prefixes CHECK,OBJPATH-FILE -DFILE=%t/lto-tmp.o
+
+
+; CHECK: 0000000000000000 - 00 0000 SO /tmp/test.cpp
+; NOOBJPATH-NEXT: 0000000000000000 - 03 0001 OSO /tmp/lto.tmp
;; check that modTime is nonzero when `-object_path_lto` is provided
-; OBJPATH-NEXT: {{[0-9a-f]*[1-9a-f]+[0-9a-f]*}} - 03 0001 OSO [[DIR]]/0.x86_64.lto.o
-; CHECK-NEXT: {{[0-9a-f]+}} - 01 0000 FUN _main
-; CHECK-NEXT: 0000000000000001 - 00 0000 FUN
-; CHECK-NEXT: 0000000000000000 - 01 0000 SO
-; CHECK-NEXT: {{[0-9a-f]+}} T _main
+; OBJPATH-DIR-NEXT: {{[0-9a-f]*[1-9a-f]+[0-9a-f]*}} - 03 0001 OSO [[DIR]]/0.x86_64.lto.o
+; OBJPATH-FILE-NEXT: {{[0-9a-f]*[1-9a-f]+[0-9a-f]*}} - 03 0001 OSO [[FILE]]
+; CHECK-NEXT: {{[0-9a-f]+}} - 01 0000 FUN _main
+; CHECK-NEXT: 0000000000000001 - 00 0000 FUN
+; CHECK-NEXT: 0000000000000000 - 01 0000 SO
+; CHECK-NEXT: {{[0-9a-f]+}} T _main
target triple = "x86_64-apple-macosx10.15.0"
target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
More information about the llvm-commits
mailing list