Skip to content

Commit

Permalink
[lld-macho] Handle filename being passed in -lto_object_path
Browse files Browse the repository at this point in the history
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
  • Loading branch information
BertalanD committed Jul 16, 2022
1 parent deac0ac commit 2b2e858
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 13 deletions.
25 changes: 20 additions & 5 deletions lld/MachO/LTO.cpp
Expand Up @@ -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) {
Expand All @@ -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);
}
Expand Down
27 changes: 27 additions & 0 deletions 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
}
23 changes: 15 additions & 8 deletions lld/test/MachO/lto-object-path.ll
Expand Up @@ -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"
Expand Down

0 comments on commit 2b2e858

Please sign in to comment.