summaryrefslogtreecommitdiff
path: root/source/Host/common/FileSystem.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Host/common/FileSystem.cpp')
-rw-r--r--source/Host/common/FileSystem.cpp109
1 files changed, 88 insertions, 21 deletions
diff --git a/source/Host/common/FileSystem.cpp b/source/Host/common/FileSystem.cpp
index 7191c9db9b2e6..d5ac05bd447c4 100644
--- a/source/Host/common/FileSystem.cpp
+++ b/source/Host/common/FileSystem.cpp
@@ -1,9 +1,8 @@
//===-- FileSystem.cpp ------------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -12,7 +11,9 @@
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/TildeExpressionResolver.h"
+#include "llvm/Support/Errc.h"
#include "llvm/Support/Errno.h"
+#include "llvm/Support/Error.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Program.h"
@@ -48,6 +49,27 @@ void FileSystem::Initialize() {
InstanceImpl().emplace();
}
+void FileSystem::Initialize(FileCollector &collector) {
+ lldbassert(!InstanceImpl() && "Already initialized.");
+ InstanceImpl().emplace(collector);
+}
+
+llvm::Error FileSystem::Initialize(const FileSpec &mapping) {
+ lldbassert(!InstanceImpl() && "Already initialized.");
+
+ llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> buffer =
+ llvm::vfs::getRealFileSystem()->getBufferForFile(mapping.GetPath());
+
+ if (!buffer)
+ return llvm::errorCodeToError(buffer.getError());
+
+ InstanceImpl().emplace(llvm::vfs::getVFSFromYAML(std::move(buffer.get()),
+ nullptr, mapping.GetPath()),
+ true);
+
+ return llvm::Error::success();
+}
+
void FileSystem::Initialize(IntrusiveRefCntPtr<vfs::FileSystem> fs) {
lldbassert(!InstanceImpl() && "Already initialized.");
InstanceImpl().emplace(fs);
@@ -220,17 +242,21 @@ void FileSystem::Resolve(SmallVectorImpl<char> &path) {
if (path.empty())
return;
- // Resolve tilde.
- SmallString<128> original_path(path.begin(), path.end());
+ // Resolve tilde in path.
+ SmallString<128> resolved(path.begin(), path.end());
StandardTildeExpressionResolver Resolver;
- Resolver.ResolveFullPath(original_path, path);
+ Resolver.ResolveFullPath(llvm::StringRef(path.begin(), path.size()),
+ resolved);
// Try making the path absolute if it exists.
- SmallString<128> absolute_path(path.begin(), path.end());
- MakeAbsolute(path);
- if (!Exists(path)) {
- path.clear();
- path.append(original_path.begin(), original_path.end());
+ SmallString<128> absolute(resolved.begin(), resolved.end());
+ MakeAbsolute(absolute);
+
+ path.clear();
+ if (Exists(absolute)) {
+ path.append(absolute.begin(), absolute.end());
+ } else {
+ path.append(resolved.begin(), resolved.end());
}
}
@@ -243,25 +269,35 @@ void FileSystem::Resolve(FileSpec &file_spec) {
Resolve(path);
// Update the FileSpec with the resolved path.
- file_spec.SetPath(path);
+ if (file_spec.GetFilename().IsEmpty())
+ file_spec.GetDirectory().SetString(path);
+ else
+ file_spec.SetPath(path);
file_spec.SetIsResolved(true);
}
std::shared_ptr<DataBufferLLVM>
FileSystem::CreateDataBuffer(const llvm::Twine &path, uint64_t size,
uint64_t offset) {
+ if (m_collector)
+ m_collector->AddFile(path);
+
const bool is_volatile = !IsLocal(path);
+ const ErrorOr<std::string> external_path = GetExternalPath(path);
+
+ if (!external_path)
+ return nullptr;
std::unique_ptr<llvm::WritableMemoryBuffer> buffer;
if (size == 0) {
auto buffer_or_error =
- llvm::WritableMemoryBuffer::getFile(path, -1, is_volatile);
+ llvm::WritableMemoryBuffer::getFile(*external_path, -1, is_volatile);
if (!buffer_or_error)
return nullptr;
buffer = std::move(*buffer_or_error);
} else {
auto buffer_or_error = llvm::WritableMemoryBuffer::getFileSlice(
- path, size, offset, is_volatile);
+ *external_path, size, offset, is_volatile);
if (!buffer_or_error)
return nullptr;
buffer = std::move(*buffer_or_error);
@@ -277,12 +313,12 @@ FileSystem::CreateDataBuffer(const FileSpec &file_spec, uint64_t size,
bool FileSystem::ResolveExecutableLocation(FileSpec &file_spec) {
// If the directory is set there's nothing to do.
- const ConstString &directory = file_spec.GetDirectory();
+ ConstString directory = file_spec.GetDirectory();
if (directory)
return false;
// We cannot look for a file if there's no file name.
- const ConstString &filename = file_spec.GetFilename();
+ ConstString filename = file_spec.GetFilename();
if (!filename)
return false;
@@ -380,25 +416,56 @@ static mode_t GetOpenMode(uint32_t permissions) {
}
Status FileSystem::Open(File &File, const FileSpec &file_spec, uint32_t options,
- uint32_t permissions) {
+ uint32_t permissions, bool should_close_fd) {
+ if (m_collector)
+ m_collector->AddFile(file_spec);
+
if (File.IsValid())
File.Close();
const int open_flags = GetOpenFlags(options);
const mode_t open_mode =
(open_flags & O_CREAT) ? GetOpenMode(permissions) : 0;
- const std::string path = file_spec.GetPath();
+
+ auto path = GetExternalPath(file_spec);
+ if (!path)
+ return Status(path.getError());
int descriptor = llvm::sys::RetryAfterSignal(
- -1, OpenWithFS, *this, path.c_str(), open_flags, open_mode);
+ -1, OpenWithFS, *this, path->c_str(), open_flags, open_mode);
Status error;
if (!File::DescriptorIsValid(descriptor)) {
File.SetDescriptor(descriptor, false);
error.SetErrorToErrno();
} else {
- File.SetDescriptor(descriptor, true);
+ File.SetDescriptor(descriptor, should_close_fd);
File.SetOptions(options);
}
return error;
}
+
+ErrorOr<std::string> FileSystem::GetExternalPath(const llvm::Twine &path) {
+ if (!m_mapped)
+ return path.str();
+
+ // If VFS mapped we know the underlying FS is a RedirectingFileSystem.
+ ErrorOr<vfs::RedirectingFileSystem::Entry *> E =
+ static_cast<vfs::RedirectingFileSystem &>(*m_fs).lookupPath(path);
+ if (!E) {
+ if (E.getError() == llvm::errc::no_such_file_or_directory) {
+ return path.str();
+ }
+ return E.getError();
+ }
+
+ auto *F = dyn_cast<vfs::RedirectingFileSystem::RedirectingFileEntry>(*E);
+ if (!F)
+ return make_error_code(llvm::errc::not_supported);
+
+ return F->getExternalContentsPath().str();
+}
+
+ErrorOr<std::string> FileSystem::GetExternalPath(const FileSpec &file_spec) {
+ return GetExternalPath(file_spec.GetPath());
+}