[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