aboutsummaryrefslogtreecommitdiff
path: root/llvm/tools/dsymutil
diff options
context:
space:
mode:
authorJonas Devlieghere <jonas@devlieghere.com>2023-08-17 11:35:40 -0700
committerJonas Devlieghere <jonas@devlieghere.com>2023-08-17 11:37:37 -0700
commita04879ce7dd6410fca7df25c882406eacf8397f5 (patch)
treefcbf1abec822563e8eddef425c773ddbc065565d /llvm/tools/dsymutil
parent1f929aadd5e4a0810247e98dcb08bd477407d552 (diff)
downloadllvm-a04879ce7dd6410fca7df25c882406eacf8397f5.zip
llvm-a04879ce7dd6410fca7df25c882406eacf8397f5.tar.gz
llvm-a04879ce7dd6410fca7df25c882406eacf8397f5.tar.bz2
[dsymutil] Use createTemporaryFile instead of TempFile
Use createTemporaryFile in favor of the TempFile abstraction to ensure we have an on-disk file. This fixes an issue on Windows where the DWARF verifier would fail when trying to open the temporary file from disk.
Diffstat (limited to 'llvm/tools/dsymutil')
-rw-r--r--llvm/tools/dsymutil/MachOUtils.cpp47
-rw-r--r--llvm/tools/dsymutil/MachOUtils.h6
-rw-r--r--llvm/tools/dsymutil/dsymutil.cpp9
3 files changed, 39 insertions, 23 deletions
diff --git a/llvm/tools/dsymutil/MachOUtils.cpp b/llvm/tools/dsymutil/MachOUtils.cpp
index 953c7e9..44c925fc 100644
--- a/llvm/tools/dsymutil/MachOUtils.cpp
+++ b/llvm/tools/dsymutil/MachOUtils.cpp
@@ -10,6 +10,7 @@
#include "BinaryHolder.h"
#include "DebugMap.h"
#include "LinkUtils.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/CodeGen/NonRelocatableStringpool.h"
#include "llvm/MC/MCAsmLayout.h"
#include "llvm/MC/MCAssembler.h"
@@ -29,24 +30,30 @@ namespace dsymutil {
namespace MachOUtils {
llvm::Error ArchAndFile::createTempFile() {
- llvm::SmallString<128> TmpModel;
- llvm::sys::path::system_temp_directory(true, TmpModel);
- llvm::sys::path::append(TmpModel, "dsym.tmp%%%%%.dwarf");
- Expected<sys::fs::TempFile> T = sys::fs::TempFile::create(TmpModel);
+ SmallString<256> SS;
+ std::error_code EC = sys::fs::createTemporaryFile("dsym", "dwarf", FD, SS);
- if (!T)
- return T.takeError();
+ if (EC)
+ return errorCodeToError(EC);
+
+ Path = SS.str();
- File = std::make_unique<sys::fs::TempFile>(std::move(*T));
return Error::success();
}
-llvm::StringRef ArchAndFile::path() const { return File->TmpName; }
+llvm::StringRef ArchAndFile::getPath() const {
+ assert(!Path.empty() && "path called before createTempFile");
+ return Path;
+}
+
+int ArchAndFile::getFD() const {
+ assert((FD != -1) && "path called before createTempFile");
+ return FD;
+}
ArchAndFile::~ArchAndFile() {
- if (File)
- if (auto E = File->discard())
- llvm::consumeError(std::move(E));
+ if (!Path.empty())
+ sys::fs::remove(Path);
}
std::string getArchName(StringRef Arch) {
@@ -82,11 +89,17 @@ bool generateUniversalBinary(SmallVectorImpl<ArchAndFile> &ArchFiles,
bool Fat64) {
// No need to merge one file into a universal fat binary.
if (ArchFiles.size() == 1) {
- if (auto E = ArchFiles.front().File->keep(OutputFileName)) {
- WithColor::error() << "while keeping " << ArchFiles.front().path()
- << " as " << OutputFileName << ": "
- << toString(std::move(E)) << "\n";
- return false;
+ llvm::StringRef TmpPath = ArchFiles.front().getPath();
+ if (auto EC = sys::fs::rename(TmpPath, OutputFileName)) {
+ // If we can't rename, try to copy to work around cross-device link
+ // issues.
+ EC = sys::fs::copy_file(TmpPath, OutputFileName);
+ if (EC) {
+ WithColor::error() << "while keeping " << TmpPath << " as "
+ << OutputFileName << ": " << EC.message() << "\n";
+ return false;
+ }
+ sys::fs::remove(TmpPath);
}
return true;
}
@@ -96,7 +109,7 @@ bool generateUniversalBinary(SmallVectorImpl<ArchAndFile> &ArchFiles,
Args.push_back("-create");
for (auto &Thin : ArchFiles)
- Args.push_back(Thin.path());
+ Args.push_back(Thin.getPath());
// Align segments to match dsymutil-classic alignment.
for (auto &Thin : ArchFiles) {
diff --git a/llvm/tools/dsymutil/MachOUtils.h b/llvm/tools/dsymutil/MachOUtils.h
index 9d35813..059d9fd 100644
--- a/llvm/tools/dsymutil/MachOUtils.h
+++ b/llvm/tools/dsymutil/MachOUtils.h
@@ -26,10 +26,12 @@ namespace MachOUtils {
struct ArchAndFile {
std::string Arch;
- std::unique_ptr<llvm::sys::fs::TempFile> File;
+ std::string Path;
+ int FD = -1;
llvm::Error createTempFile();
- llvm::StringRef path() const;
+ llvm::StringRef getPath() const;
+ int getFD() const;
ArchAndFile(StringRef Arch) : Arch(std::string(Arch)) {}
ArchAndFile(ArchAndFile &&A) = default;
diff --git a/llvm/tools/dsymutil/dsymutil.cpp b/llvm/tools/dsymutil/dsymutil.cpp
index 20d11bc..1dffe0e 100644
--- a/llvm/tools/dsymutil/dsymutil.cpp
+++ b/llvm/tools/dsymutil/dsymutil.cpp
@@ -772,10 +772,10 @@ int main(int argc, char **argv) {
return;
}
- auto &TempFile = *(TempFiles.back().File);
- OS = std::make_shared<raw_fd_ostream>(TempFile.FD,
+ MachOUtils::ArchAndFile &AF = TempFiles.back();
+ OS = std::make_shared<raw_fd_ostream>(AF.getFD(),
/*shouldClose*/ false);
- OutputFile = TempFile.TmpName;
+ OutputFile = AF.getPath();
} else {
std::error_code EC;
OS = std::make_shared<raw_fd_ostream>(
@@ -843,7 +843,8 @@ int main(int argc, char **argv) {
uint64_t FileOffset =
MagicAndCountSize + UniversalArchInfoSize * TempFiles.size();
for (const auto &File : TempFiles) {
- ErrorOr<vfs::Status> stat = Options.LinkOpts.VFS->status(File.path());
+ ErrorOr<vfs::Status> stat =
+ Options.LinkOpts.VFS->status(File.getPath());
if (!stat)
break;
if (FileOffset > UINT32_MAX) {