aboutsummaryrefslogtreecommitdiffstats
path: root/source/Host
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-01-19 10:06:29 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-01-19 10:06:29 +0000
commit94994d372d014ce4c8758b9605d63fae651bd8aa (patch)
tree51c0b708bd59f205d6b35cb2a8c24d62f0c33d77 /source/Host
parent39be7ce23363d12ae3e49aeb1fdb2bfeb892e836 (diff)
downloadsrc-94994d372d014ce4c8758b9605d63fae651bd8aa.tar.gz
src-94994d372d014ce4c8758b9605d63fae651bd8aa.zip
Vendor import of lldb trunk r351319 (just before the release_80 branchvendor/lldb/lldb-trunk-r351319
Notes
Notes: svn path=/vendor/lldb/dist/; revision=343181 svn path=/vendor/lldb/lldb-trunk-r351319/; revision=343182; tag=vendor/lldb/lldb-trunk-r351319
Diffstat (limited to 'source/Host')
-rw-r--r--source/Host/CMakeLists.txt13
-rw-r--r--source/Host/android/HostInfoAndroid.cpp21
-rw-r--r--source/Host/common/Editline.cpp58
-rw-r--r--source/Host/common/File.cpp132
-rw-r--r--source/Host/common/FileCache.cpp8
-rw-r--r--source/Host/common/FileSystem.cpp390
-rw-r--r--source/Host/common/Host.cpp19
-rw-r--r--source/Host/common/HostInfoBase.cpp7
-rw-r--r--source/Host/common/HostNativeThreadBase.cpp4
-rw-r--r--source/Host/common/HostThread.cpp2
-rw-r--r--source/Host/common/MainLoop.cpp4
-rw-r--r--source/Host/common/MonitoringProcessLauncher.cpp20
-rw-r--r--source/Host/common/NativeBreakpoint.cpp109
-rw-r--r--source/Host/common/NativeBreakpointList.cpp229
-rw-r--r--source/Host/common/NativeProcessProtocol.cpp312
-rw-r--r--source/Host/common/NativeRegisterContext.cpp2
-rw-r--r--source/Host/common/NativeThreadProtocol.cpp1
-rw-r--r--source/Host/common/ProcessRunLock.cpp2
-rw-r--r--source/Host/common/PseudoTerminal.cpp31
-rw-r--r--source/Host/common/SocketAddress.cpp4
-rw-r--r--source/Host/common/SoftwareBreakpoint.cpp350
-rw-r--r--source/Host/common/StringConvert.cpp4
-rw-r--r--source/Host/common/Symbols.cpp256
-rw-r--r--source/Host/common/TaskPool.cpp6
-rw-r--r--source/Host/common/XML.cpp11
-rw-r--r--source/Host/freebsd/Host.cpp10
-rw-r--r--source/Host/freebsd/HostInfoFreeBSD.cpp2
-rw-r--r--source/Host/linux/Host.cpp11
-rw-r--r--source/Host/linux/HostInfoLinux.cpp12
-rw-r--r--source/Host/macosx/Symbols.cpp72
-rw-r--r--source/Host/macosx/cfcpp/CFCMutableArray.cpp6
-rw-r--r--source/Host/macosx/cfcpp/CFCMutableSet.cpp6
-rw-r--r--source/Host/macosx/objcxx/Host.mm58
-rw-r--r--source/Host/macosx/objcxx/HostInfoMacOSX.mm20
-rw-r--r--source/Host/netbsd/Host.cpp6
-rw-r--r--source/Host/netbsd/HostInfoNetBSD.cpp2
-rw-r--r--source/Host/openbsd/Host.cpp4
-rw-r--r--source/Host/posix/ConnectionFileDescriptorPosix.cpp4
-rw-r--r--source/Host/posix/FileSystem.cpp9
-rw-r--r--source/Host/posix/HostInfoPosix.cpp4
-rw-r--r--source/Host/posix/HostProcessPosix.cpp2
-rw-r--r--source/Host/posix/PipePosix.cpp9
-rw-r--r--source/Host/posix/ProcessLauncherPosixFork.cpp2
-rw-r--r--source/Host/windows/FileSystem.cpp11
-rw-r--r--source/Host/windows/Host.cpp18
-rw-r--r--source/Host/windows/HostInfoWindows.cpp8
-rw-r--r--source/Host/windows/HostProcessWindows.cpp2
-rw-r--r--source/Host/windows/HostThreadWindows.cpp4
-rw-r--r--source/Host/windows/PipeWindows.cpp79
-rw-r--r--source/Host/windows/ProcessLauncherWindows.cpp3
50 files changed, 1175 insertions, 1184 deletions
diff --git a/source/Host/CMakeLists.txt b/source/Host/CMakeLists.txt
index 5a92447edf30..333f109a9a26 100644
--- a/source/Host/CMakeLists.txt
+++ b/source/Host/CMakeLists.txt
@@ -11,7 +11,9 @@ endmacro()
# Objective-C++ files in lldb (which slows down the build process).
macro(remove_module_flags)
string(REGEX REPLACE "-fmodules-cache-path=[^ ]+" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
+ string(REGEX REPLACE "-fmodules-local-submodule-visibility" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
string(REGEX REPLACE "-fmodules" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
+ string(REGEX REPLACE "-gmodules" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
string(REGEX REPLACE "-fcxx-modules" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
endmacro()
@@ -28,8 +30,6 @@ add_host_subdirectory(common
common/LockFileBase.cpp
common/MainLoop.cpp
common/MonitoringProcessLauncher.cpp
- common/NativeBreakpoint.cpp
- common/NativeBreakpointList.cpp
common/NativeWatchpointList.cpp
common/NativeProcessProtocol.cpp
common/NativeRegisterContext.cpp
@@ -40,7 +40,6 @@ add_host_subdirectory(common
common/PseudoTerminal.cpp
common/Socket.cpp
common/SocketAddress.cpp
- common/SoftwareBreakpoint.cpp
common/StringConvert.cpp
common/Symbols.cpp
common/TaskPool.cpp
@@ -92,7 +91,7 @@ else()
include_directories(SYSTEM ${LIBXML2_INCLUDE_DIR})
add_subdirectory(macosx/objcxx)
set(LLDBObjCLibs lldbHostMacOSXObjCXX)
- add_host_subdirectory(maqcosx
+ add_host_subdirectory(macosx
macosx/Symbols.cpp
macosx/cfcpp/CFCBundle.cpp
macosx/cfcpp/CFCData.cpp
@@ -156,7 +155,7 @@ if (HAVE_LIBDL)
list(APPEND EXTRA_LIBS ${CMAKE_DL_LIBS})
endif()
if (NOT LLDB_DISABLE_LIBEDIT)
- list(APPEND EXTRA_LIBS edit)
+ list(APPEND EXTRA_LIBS ${libedit_LIBRARIES})
endif()
add_lldb_library(lldbHost
@@ -174,3 +173,7 @@ add_lldb_library(lldbHost
Object
Support
)
+
+if (NOT LLDB_DISABLE_LIBEDIT)
+ target_include_directories(lldbHost PUBLIC ${libedit_INCLUDE_DIRS})
+endif()
diff --git a/source/Host/android/HostInfoAndroid.cpp b/source/Host/android/HostInfoAndroid.cpp
index a96033283212..3dea01f8240d 100644
--- a/source/Host/android/HostInfoAndroid.cpp
+++ b/source/Host/android/HostInfoAndroid.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "lldb/Host/android/HostInfoAndroid.h"
+#include "lldb/Host/FileSystem.h"
#include "lldb/Host/linux/HostInfoLinux.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
@@ -28,7 +29,7 @@ void HostInfoAndroid::ComputeHostArchitectureSupport(ArchSpec &arch_32,
}
FileSpec HostInfoAndroid::GetDefaultShell() {
- return FileSpec("/system/bin/sh", false);
+ return FileSpec("/system/bin/sh");
}
FileSpec HostInfoAndroid::ResolveLibraryPath(const std::string &module_path,
@@ -39,8 +40,11 @@ FileSpec HostInfoAndroid::ResolveLibraryPath(const std::string &module_path,
static const char *const default_lib64_path[] = {"/vendor/lib64",
"/system/lib64", nullptr};
- if (module_path.empty() || module_path[0] == '/')
- return FileSpec(module_path.c_str(), true);
+ if (module_path.empty() || module_path[0] == '/') {
+ FileSpec file_spec(module_path.c_str());
+ FileSystem::Instance().Resolve(file_spec);
+ return file_spec;
+ }
SmallVector<StringRef, 4> ld_paths;
@@ -65,10 +69,11 @@ FileSpec HostInfoAndroid::ResolveLibraryPath(const std::string &module_path,
ld_paths.push_back(StringRef(*it));
for (const StringRef &path : ld_paths) {
- FileSpec file_candidate(path.str().c_str(), true);
+ FileSpec file_candidate(path.str().c_str());
+ FileSystem::Instance().Resolve(file_candidate);
file_candidate.AppendPathComponent(module_path.c_str());
- if (file_candidate.Exists())
+ if (FileSystem::Instance().Exists(file_candidate))
return file_candidate;
}
@@ -83,8 +88,8 @@ bool HostInfoAndroid::ComputeTempFileBaseDirectory(FileSpec &file_spec) {
// algorithm will deduce /tmp, which is plain wrong. In that case we have an
// invalid directory, we substitute the path with /data/local/tmp, which is
// correct at least in some cases (i.e., when running as shell user).
- if (!success || !file_spec.Exists())
- file_spec = FileSpec("/data/local/tmp", false);
+ if (!success || !FileSystem::Instance().Exists(file_spec))
+ file_spec = FileSpec("/data/local/tmp");
- return file_spec.Exists();
+ return FileSystem::Instance().Exists(file_spec);
}
diff --git a/source/Host/common/Editline.cpp b/source/Host/common/Editline.cpp
index 329c0c1f3b70..f7ba4b5822ff 100644
--- a/source/Host/common/Editline.cpp
+++ b/source/Host/common/Editline.cpp
@@ -13,6 +13,7 @@
#include "lldb/Host/ConnectionFileDescriptor.h"
#include "lldb/Host/Editline.h"
+#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/LLDBAssert.h"
@@ -172,7 +173,8 @@ private:
const char *GetHistoryFilePath() {
if (m_path.empty() && m_history && !m_prefix.empty()) {
- FileSpec parent_path{"~/.lldb", true};
+ FileSpec parent_path("~/.lldb");
+ FileSystem::Instance().Resolve(parent_path);
char history_path[PATH_MAX];
if (!llvm::sys::fs::create_directory(parent_path.GetPath())) {
snprintf(history_path, sizeof(history_path), "~/.lldb/%s-history",
@@ -181,7 +183,9 @@ private:
snprintf(history_path, sizeof(history_path), "~/%s-widehistory",
m_prefix.c_str());
}
- m_path = FileSpec(history_path, true).GetPath();
+ auto file_spec = FileSpec(history_path);
+ FileSystem::Instance().Resolve(file_spec);
+ m_path = file_spec.GetPath();
}
if (m_path.empty())
return NULL;
@@ -426,7 +430,7 @@ unsigned char Editline::RecallHistory(bool earlier) {
// Treat moving from the "live" entry differently
if (!m_in_history) {
- if (earlier == false)
+ if (!earlier)
return CC_ERROR; // Can't go newer than the "live" entry
if (history_w(pHistory, &history_event, H_FIRST) == -1)
return CC_ERROR;
@@ -439,7 +443,7 @@ unsigned char Editline::RecallHistory(bool earlier) {
m_live_history_lines = m_input_lines;
m_in_history = true;
} else {
- if (history_w(pHistory, &history_event, earlier ? H_NEXT : H_PREV) == -1) {
+ if (history_w(pHistory, &history_event, earlier ? H_PREV : H_NEXT) == -1) {
// Can't move earlier than the earliest entry
if (earlier)
return CC_ERROR;
@@ -526,7 +530,7 @@ int Editline::GetCharacter(EditLineGetCharType *c) {
break;
case lldb::eConnectionStatusInterrupted:
- lldbassert(0 && "Interrupts should have been handled above.");
+ llvm_unreachable("Interrupts should have been handled above.");
case lldb::eConnectionStatusError: // Check GetError() for details
case lldb::eConnectionStatusTimedOut: // Request timed out
@@ -853,19 +857,45 @@ unsigned char Editline::BufferEndCommand(int ch) {
return CC_NEWLINE;
}
+//------------------------------------------------------------------------------
+/// Prints completions and their descriptions to the given file. Only the
+/// completions in the interval [start, end) are printed.
+//------------------------------------------------------------------------------
+static void PrintCompletion(FILE *output_file, size_t start, size_t end,
+ StringList &completions, StringList &descriptions) {
+ // This is an 'int' because of printf.
+ int max_len = 0;
+
+ for (size_t i = start; i < end; i++) {
+ const char *completion_str = completions.GetStringAtIndex(i);
+ max_len = std::max((int)strlen(completion_str), max_len);
+ }
+
+ for (size_t i = start; i < end; i++) {
+ const char *completion_str = completions.GetStringAtIndex(i);
+ const char *description_str = descriptions.GetStringAtIndex(i);
+
+ fprintf(output_file, "\n\t%-*s", max_len, completion_str);
+
+ // Print the description if we got one.
+ if (strlen(description_str))
+ fprintf(output_file, " -- %s", description_str);
+ }
+}
+
unsigned char Editline::TabCommand(int ch) {
if (m_completion_callback == nullptr)
return CC_ERROR;
const LineInfo *line_info = el_line(m_editline);
- StringList completions;
+ StringList completions, descriptions;
int page_size = 40;
const int num_completions = m_completion_callback(
line_info->buffer, line_info->cursor, line_info->lastchar,
0, // Don't skip any matches (start at match zero)
-1, // Get all the matches
- completions, m_completion_callback_baton);
+ completions, descriptions, m_completion_callback_baton);
if (num_completions == 0)
return CC_ERROR;
@@ -893,10 +923,8 @@ unsigned char Editline::TabCommand(int ch) {
int num_elements = num_completions + 1;
fprintf(m_output_file, "\n" ANSI_CLEAR_BELOW "Available completions:");
if (num_completions < page_size) {
- for (int i = 1; i < num_elements; i++) {
- completion_str = completions.GetStringAtIndex(i);
- fprintf(m_output_file, "\n\t%s", completion_str);
- }
+ PrintCompletion(m_output_file, 1, num_elements, completions,
+ descriptions);
fprintf(m_output_file, "\n");
} else {
int cur_pos = 1;
@@ -906,10 +934,10 @@ unsigned char Editline::TabCommand(int ch) {
int endpoint = cur_pos + page_size;
if (endpoint > num_elements)
endpoint = num_elements;
- for (; cur_pos < endpoint; cur_pos++) {
- completion_str = completions.GetStringAtIndex(cur_pos);
- fprintf(m_output_file, "\n\t%s", completion_str);
- }
+
+ PrintCompletion(m_output_file, cur_pos, endpoint, completions,
+ descriptions);
+ cur_pos = endpoint;
if (cur_pos >= num_elements) {
fprintf(m_output_file, "\n");
diff --git a/source/Host/common/File.cpp b/source/Host/common/File.cpp
index 3c3d55df2207..810c15588402 100644
--- a/source/Host/common/File.cpp
+++ b/source/Host/common/File.cpp
@@ -27,9 +27,10 @@
#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/Errno.h"
#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/Process.h" // for llvm::sys::Process::FileDescriptorHasColors()
+#include "llvm/Support/Process.h"
#include "lldb/Host/Config.h"
+#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/FileSpec.h"
@@ -71,26 +72,6 @@ static const char *GetStreamOpenModeFromOptions(uint32_t options) {
int File::kInvalidDescriptor = -1;
FILE *File::kInvalidStream = NULL;
-File::File(const char *path, uint32_t options, uint32_t permissions)
- : IOObject(eFDTypeFile, false), m_descriptor(kInvalidDescriptor),
- m_stream(kInvalidStream), m_options(), m_own_stream(false),
- m_is_interactive(eLazyBoolCalculate),
- m_is_real_terminal(eLazyBoolCalculate) {
- Open(path, options, permissions);
-}
-
-File::File(const FileSpec &filespec, uint32_t options, uint32_t permissions)
- : IOObject(eFDTypeFile, false), m_descriptor(kInvalidDescriptor),
- m_stream(kInvalidStream), m_options(0), m_own_stream(false),
- m_is_interactive(eLazyBoolCalculate),
- m_is_real_terminal(eLazyBoolCalculate)
-
-{
- if (filespec) {
- Open(filespec.GetPath().c_str(), options, permissions);
- }
-}
-
File::~File() { Close(); }
int File::GetDescriptor() const {
@@ -159,108 +140,6 @@ void File::SetStream(FILE *fh, bool transfer_ownership) {
m_own_stream = transfer_ownership;
}
-static int DoOpen(const char *path, int flags, int mode) {
-#ifdef _MSC_VER
- std::wstring wpath;
- if (!llvm::ConvertUTF8toWide(path, wpath))
- return -1;
- int result;
- ::_wsopen_s(&result, wpath.c_str(), flags, _SH_DENYNO, mode);
- return result;
-#else
- return ::open(path, flags, mode);
-#endif
-}
-
-Status File::Open(const char *path, uint32_t options, uint32_t permissions) {
- Status error;
- if (IsValid())
- Close();
-
- int oflag = 0;
- const bool read = options & eOpenOptionRead;
- const bool write = options & eOpenOptionWrite;
- if (write) {
- if (read)
- oflag |= O_RDWR;
- else
- oflag |= O_WRONLY;
-
- if (options & eOpenOptionAppend)
- oflag |= O_APPEND;
-
- if (options & eOpenOptionTruncate)
- oflag |= O_TRUNC;
-
- if (options & eOpenOptionCanCreate)
- oflag |= O_CREAT;
-
- if (options & eOpenOptionCanCreateNewOnly)
- oflag |= O_CREAT | O_EXCL;
- } else if (read) {
- oflag |= O_RDONLY;
-
-#ifndef _WIN32
- if (options & eOpenOptionDontFollowSymlinks)
- oflag |= O_NOFOLLOW;
-#endif
- }
-
-#ifndef _WIN32
- if (options & eOpenOptionNonBlocking)
- oflag |= O_NONBLOCK;
- if (options & eOpenOptionCloseOnExec)
- oflag |= O_CLOEXEC;
-#else
- oflag |= O_BINARY;
-#endif
-
- mode_t mode = 0;
- if (oflag & O_CREAT) {
- if (permissions & lldb::eFilePermissionsUserRead)
- mode |= S_IRUSR;
- if (permissions & lldb::eFilePermissionsUserWrite)
- mode |= S_IWUSR;
- if (permissions & lldb::eFilePermissionsUserExecute)
- mode |= S_IXUSR;
- if (permissions & lldb::eFilePermissionsGroupRead)
- mode |= S_IRGRP;
- if (permissions & lldb::eFilePermissionsGroupWrite)
- mode |= S_IWGRP;
- if (permissions & lldb::eFilePermissionsGroupExecute)
- mode |= S_IXGRP;
- if (permissions & lldb::eFilePermissionsWorldRead)
- mode |= S_IROTH;
- if (permissions & lldb::eFilePermissionsWorldWrite)
- mode |= S_IWOTH;
- if (permissions & lldb::eFilePermissionsWorldExecute)
- mode |= S_IXOTH;
- }
-
- m_descriptor = llvm::sys::RetryAfterSignal(-1, DoOpen, path, oflag, mode);
- if (!DescriptorIsValid())
- error.SetErrorToErrno();
- else {
- m_should_close_fd = true;
- m_options = options;
- }
-
- return error;
-}
-
-uint32_t File::GetPermissions(const FileSpec &file_spec, Status &error) {
- if (file_spec) {
- error.Clear();
- auto Perms = llvm::sys::fs::getPermissions(file_spec.GetPath());
- if (Perms)
- return *Perms;
- error = Status(Perms.getError());
- return 0;
- } else
- error.SetErrorString("empty file spec");
- return 0;
-}
-
uint32_t File::GetPermissions(Status &error) const {
int fd = GetDescriptor();
if (fd != kInvalidDescriptor) {
@@ -315,7 +194,7 @@ Status File::GetFileSpec(FileSpec &file_spec) const {
if (::fcntl(GetDescriptor(), F_GETPATH, path) == -1)
error.SetErrorToErrno();
else
- file_spec.SetFile(path, false, FileSpec::Style::native);
+ file_spec.SetFile(path, FileSpec::Style::native);
} else {
error.SetErrorString("invalid file handle");
}
@@ -330,7 +209,7 @@ Status File::GetFileSpec(FileSpec &file_spec) const {
error.SetErrorToErrno();
else {
path[len] = '\0';
- file_spec.SetFile(path, false, FileSpec::Style::native);
+ file_spec.SetFile(path, FileSpec::Style::native);
}
}
#else
@@ -806,6 +685,9 @@ void File::CalculateInteractiveAndTerminal() {
if (_isatty(fd)) {
m_is_interactive = eLazyBoolYes;
m_is_real_terminal = eLazyBoolYes;
+#if defined(ENABLE_VIRTUAL_TERMINAL_PROCESSING)
+ m_supports_colors = eLazyBoolYes;
+#endif
}
#else
if (isatty(fd)) {
diff --git a/source/Host/common/FileCache.cpp b/source/Host/common/FileCache.cpp
index b4629255c852..17833ef2cbb3 100644
--- a/source/Host/common/FileCache.cpp
+++ b/source/Host/common/FileCache.cpp
@@ -10,6 +10,7 @@
#include "lldb/Host/FileCache.h"
#include "lldb/Host/File.h"
+#include "lldb/Host/FileSystem.h"
using namespace lldb;
using namespace lldb_private;
@@ -25,14 +26,13 @@ FileCache &FileCache::GetInstance() {
lldb::user_id_t FileCache::OpenFile(const FileSpec &file_spec, uint32_t flags,
uint32_t mode, Status &error) {
- std::string path(file_spec.GetPath());
- if (path.empty()) {
+ if (!file_spec) {
error.SetErrorString("empty path");
return UINT64_MAX;
}
FileSP file_sp(new File());
- error = file_sp->Open(path.c_str(), flags, mode);
- if (file_sp->IsValid() == false)
+ error = FileSystem::Instance().Open(*file_sp, file_spec, flags, mode);
+ if (!file_sp->IsValid())
return UINT64_MAX;
lldb::user_id_t fd = file_sp->GetDescriptor();
m_cache[fd] = file_sp;
diff --git a/source/Host/common/FileSystem.cpp b/source/Host/common/FileSystem.cpp
index 4472aece1daa..7191c9db9b2e 100644
--- a/source/Host/common/FileSystem.cpp
+++ b/source/Host/common/FileSystem.cpp
@@ -9,7 +9,29 @@
#include "lldb/Host/FileSystem.h"
+#include "lldb/Utility/LLDBAssert.h"
+#include "lldb/Utility/TildeExpressionResolver.h"
+
+#include "llvm/Support/Errno.h"
#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/Program.h"
+#include "llvm/Support/Threading.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdarg.h>
+#include <stdio.h>
+
+#ifdef _WIN32
+#include "lldb/Host/windows/windows.h"
+#else
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <termios.h>
+#include <unistd.h>
+#endif
#include <algorithm>
#include <fstream>
@@ -17,12 +39,366 @@
using namespace lldb;
using namespace lldb_private;
+using namespace llvm;
+
+FileSystem &FileSystem::Instance() { return *InstanceImpl(); }
+
+void FileSystem::Initialize() {
+ lldbassert(!InstanceImpl() && "Already initialized.");
+ InstanceImpl().emplace();
+}
+
+void FileSystem::Initialize(IntrusiveRefCntPtr<vfs::FileSystem> fs) {
+ lldbassert(!InstanceImpl() && "Already initialized.");
+ InstanceImpl().emplace(fs);
+}
+
+void FileSystem::Terminate() {
+ lldbassert(InstanceImpl() && "Already terminated.");
+ InstanceImpl().reset();
+}
+
+Optional<FileSystem> &FileSystem::InstanceImpl() {
+ static Optional<FileSystem> g_fs;
+ return g_fs;
+}
+
+vfs::directory_iterator FileSystem::DirBegin(const FileSpec &file_spec,
+ std::error_code &ec) {
+ return DirBegin(file_spec.GetPath(), ec);
+}
+
+vfs::directory_iterator FileSystem::DirBegin(const Twine &dir,
+ std::error_code &ec) {
+ return m_fs->dir_begin(dir, ec);
+}
+
+llvm::ErrorOr<vfs::Status>
+FileSystem::GetStatus(const FileSpec &file_spec) const {
+ return GetStatus(file_spec.GetPath());
+}
+
+llvm::ErrorOr<vfs::Status> FileSystem::GetStatus(const Twine &path) const {
+ return m_fs->status(path);
+}
+
+sys::TimePoint<>
+FileSystem::GetModificationTime(const FileSpec &file_spec) const {
+ return GetModificationTime(file_spec.GetPath());
+}
+
+sys::TimePoint<> FileSystem::GetModificationTime(const Twine &path) const {
+ ErrorOr<vfs::Status> status = m_fs->status(path);
+ if (!status)
+ return sys::TimePoint<>();
+ return status->getLastModificationTime();
+}
+
+uint64_t FileSystem::GetByteSize(const FileSpec &file_spec) const {
+ return GetByteSize(file_spec.GetPath());
+}
+
+uint64_t FileSystem::GetByteSize(const Twine &path) const {
+ ErrorOr<vfs::Status> status = m_fs->status(path);
+ if (!status)
+ return 0;
+ return status->getSize();
+}
+
+uint32_t FileSystem::GetPermissions(const FileSpec &file_spec) const {
+ return GetPermissions(file_spec.GetPath());
+}
+
+uint32_t FileSystem::GetPermissions(const FileSpec &file_spec,
+ std::error_code &ec) const {
+ return GetPermissions(file_spec.GetPath(), ec);
+}
+
+uint32_t FileSystem::GetPermissions(const Twine &path) const {
+ std::error_code ec;
+ return GetPermissions(path, ec);
+}
+
+uint32_t FileSystem::GetPermissions(const Twine &path,
+ std::error_code &ec) const {
+ ErrorOr<vfs::Status> status = m_fs->status(path);
+ if (!status) {
+ ec = status.getError();
+ return sys::fs::perms::perms_not_known;
+ }
+ return status->getPermissions();
+}
+
+bool FileSystem::Exists(const Twine &path) const { return m_fs->exists(path); }
+
+bool FileSystem::Exists(const FileSpec &file_spec) const {
+ return Exists(file_spec.GetPath());
+}
+
+bool FileSystem::Readable(const Twine &path) const {
+ return GetPermissions(path) & sys::fs::perms::all_read;
+}
+
+bool FileSystem::Readable(const FileSpec &file_spec) const {
+ return Readable(file_spec.GetPath());
+}
+
+bool FileSystem::IsDirectory(const Twine &path) const {
+ ErrorOr<vfs::Status> status = m_fs->status(path);
+ if (!status)
+ return false;
+ return status->isDirectory();
+}
+
+bool FileSystem::IsDirectory(const FileSpec &file_spec) const {
+ return IsDirectory(file_spec.GetPath());
+}
+
+bool FileSystem::IsLocal(const Twine &path) const {
+ bool b = false;
+ m_fs->isLocal(path, b);
+ return b;
+}
+
+bool FileSystem::IsLocal(const FileSpec &file_spec) const {
+ return IsLocal(file_spec.GetPath());
+}
+
+void FileSystem::EnumerateDirectory(Twine path, bool find_directories,
+ bool find_files, bool find_other,
+ EnumerateDirectoryCallbackType callback,
+ void *callback_baton) {
+ std::error_code EC;
+ vfs::recursive_directory_iterator Iter(*m_fs, path, EC);
+ vfs::recursive_directory_iterator End;
+ for (; Iter != End && !EC; Iter.increment(EC)) {
+ const auto &Item = *Iter;
+ ErrorOr<vfs::Status> Status = m_fs->status(Item.path());
+ if (!Status)
+ break;
+ if (!find_files && Status->isRegularFile())
+ continue;
+ if (!find_directories && Status->isDirectory())
+ continue;
+ if (!find_other && Status->isOther())
+ continue;
+
+ auto Result = callback(callback_baton, Status->getType(), Item.path());
+ if (Result == eEnumerateDirectoryResultQuit)
+ return;
+ if (Result == eEnumerateDirectoryResultNext) {
+ // Default behavior is to recurse. Opt out if the callback doesn't want
+ // this behavior.
+ Iter.no_push();
+ }
+ }
+}
+
+std::error_code FileSystem::MakeAbsolute(SmallVectorImpl<char> &path) const {
+ return m_fs->makeAbsolute(path);
+}
+
+std::error_code FileSystem::MakeAbsolute(FileSpec &file_spec) const {
+ SmallString<128> path;
+ file_spec.GetPath(path, false);
+
+ auto EC = MakeAbsolute(path);
+ if (EC)
+ return EC;
+
+ FileSpec new_file_spec(path, file_spec.GetPathStyle());
+ file_spec = new_file_spec;
+ return {};
+}
+
+std::error_code FileSystem::GetRealPath(const Twine &path,
+ SmallVectorImpl<char> &output) const {
+ return m_fs->getRealPath(path, output);
+}
+
+void FileSystem::Resolve(SmallVectorImpl<char> &path) {
+ if (path.empty())
+ return;
+
+ // Resolve tilde.
+ SmallString<128> original_path(path.begin(), path.end());
+ StandardTildeExpressionResolver Resolver;
+ Resolver.ResolveFullPath(original_path, path);
+
+ // 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());
+ }
+}
+
+void FileSystem::Resolve(FileSpec &file_spec) {
+ // Extract path from the FileSpec.
+ SmallString<128> path;
+ file_spec.GetPath(path);
+
+ // Resolve the path.
+ Resolve(path);
+
+ // Update the FileSpec with the resolved path.
+ file_spec.SetPath(path);
+ file_spec.SetIsResolved(true);
+}
+
+std::shared_ptr<DataBufferLLVM>
+FileSystem::CreateDataBuffer(const llvm::Twine &path, uint64_t size,
+ uint64_t offset) {
+ const bool is_volatile = !IsLocal(path);
+
+ std::unique_ptr<llvm::WritableMemoryBuffer> buffer;
+ if (size == 0) {
+ auto buffer_or_error =
+ llvm::WritableMemoryBuffer::getFile(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);
+ if (!buffer_or_error)
+ return nullptr;
+ buffer = std::move(*buffer_or_error);
+ }
+ return std::shared_ptr<DataBufferLLVM>(new DataBufferLLVM(std::move(buffer)));
+}
+
+std::shared_ptr<DataBufferLLVM>
+FileSystem::CreateDataBuffer(const FileSpec &file_spec, uint64_t size,
+ uint64_t offset) {
+ return CreateDataBuffer(file_spec.GetPath(), size, offset);
+}
+
+bool FileSystem::ResolveExecutableLocation(FileSpec &file_spec) {
+ // If the directory is set there's nothing to do.
+ const 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();
+ if (!filename)
+ return false;
+
+ // Search for the file on the host.
+ const std::string filename_str(filename.GetCString());
+ llvm::ErrorOr<std::string> error_or_path =
+ llvm::sys::findProgramByName(filename_str);
+ if (!error_or_path)
+ return false;
+
+ // findProgramByName returns "." if it can't find the file.
+ llvm::StringRef path = *error_or_path;
+ llvm::StringRef parent = llvm::sys::path::parent_path(path);
+ if (parent.empty() || parent == ".")
+ return false;
+
+ // Make sure that the result exists.
+ FileSpec result(*error_or_path);
+ if (!Exists(result))
+ return false;
+
+ file_spec = result;
+ return true;
+}
+
+static int OpenWithFS(const FileSystem &fs, const char *path, int flags,
+ int mode) {
+ return const_cast<FileSystem &>(fs).Open(path, flags, mode);
+}
+
+static int GetOpenFlags(uint32_t options) {
+ const bool read = options & File::eOpenOptionRead;
+ const bool write = options & File::eOpenOptionWrite;
+
+ int open_flags = 0;
+ if (write) {
+ if (read)
+ open_flags |= O_RDWR;
+ else
+ open_flags |= O_WRONLY;
+
+ if (options & File::eOpenOptionAppend)
+ open_flags |= O_APPEND;
+
+ if (options & File::eOpenOptionTruncate)
+ open_flags |= O_TRUNC;
+
+ if (options & File::eOpenOptionCanCreate)
+ open_flags |= O_CREAT;
+
+ if (options & File::eOpenOptionCanCreateNewOnly)
+ open_flags |= O_CREAT | O_EXCL;
+ } else if (read) {
+ open_flags |= O_RDONLY;
+
+#ifndef _WIN32
+ if (options & File::eOpenOptionDontFollowSymlinks)
+ open_flags |= O_NOFOLLOW;
+#endif
+ }
+
+#ifndef _WIN32
+ if (options & File::eOpenOptionNonBlocking)
+ open_flags |= O_NONBLOCK;
+ if (options & File::eOpenOptionCloseOnExec)
+ open_flags |= O_CLOEXEC;
+#else
+ open_flags |= O_BINARY;
+#endif
+
+ return open_flags;
+}
+
+static mode_t GetOpenMode(uint32_t permissions) {
+ mode_t mode = 0;
+ if (permissions & lldb::eFilePermissionsUserRead)
+ mode |= S_IRUSR;
+ if (permissions & lldb::eFilePermissionsUserWrite)
+ mode |= S_IWUSR;
+ if (permissions & lldb::eFilePermissionsUserExecute)
+ mode |= S_IXUSR;
+ if (permissions & lldb::eFilePermissionsGroupRead)
+ mode |= S_IRGRP;
+ if (permissions & lldb::eFilePermissionsGroupWrite)
+ mode |= S_IWGRP;
+ if (permissions & lldb::eFilePermissionsGroupExecute)
+ mode |= S_IXGRP;
+ if (permissions & lldb::eFilePermissionsWorldRead)
+ mode |= S_IROTH;
+ if (permissions & lldb::eFilePermissionsWorldWrite)
+ mode |= S_IWOTH;
+ if (permissions & lldb::eFilePermissionsWorldExecute)
+ mode |= S_IXOTH;
+ return mode;
+}
+
+Status FileSystem::Open(File &File, const FileSpec &file_spec, uint32_t options,
+ uint32_t permissions) {
+ 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();
+
+ int descriptor = llvm::sys::RetryAfterSignal(
+ -1, OpenWithFS, *this, path.c_str(), open_flags, open_mode);
-llvm::sys::TimePoint<>
-FileSystem::GetModificationTime(const FileSpec &file_spec) {
- llvm::sys::fs::file_status status;
- std::error_code ec = llvm::sys::fs::status(file_spec.GetPath(), status);
- if (ec)
- return llvm::sys::TimePoint<>();
- return status.getLastModificationTime();
+ Status error;
+ if (!File::DescriptorIsValid(descriptor)) {
+ File.SetDescriptor(descriptor, false);
+ error.SetErrorToErrno();
+ } else {
+ File.SetDescriptor(descriptor, true);
+ File.SetOptions(options);
+ }
+ return error;
}
diff --git a/source/Host/common/Host.cpp b/source/Host/common/Host.cpp
index d2848254779e..62b936aadef1 100644
--- a/source/Host/common/Host.cpp
+++ b/source/Host/common/Host.cpp
@@ -45,14 +45,13 @@
#include <lwp.h>
#endif
-// C++ Includes
#include <csignal>
+#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/HostProcess.h"
#include "lldb/Host/MonitoringProcessLauncher.h"
-#include "lldb/Host/Predicate.h"
#include "lldb/Host/ProcessLauncher.h"
#include "lldb/Host/ThreadLauncher.h"
#include "lldb/Host/posix/ConnectionFileDescriptorPosix.h"
@@ -62,6 +61,7 @@
#include "lldb/Utility/DataBufferLLVM.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/Predicate.h"
#include "lldb/Utility/Status.h"
#include "lldb/lldb-private-forward.h"
#include "llvm/ADT/SmallString.h"
@@ -419,8 +419,10 @@ FileSpec Host::GetModuleFileSpecForHostAddress(const void *host_addr) {
#if !defined(__ANDROID__)
Dl_info info;
if (::dladdr(host_addr, &info)) {
- if (info.dli_fname)
- module_filespec.SetFile(info.dli_fname, true, FileSpec::Style::native);
+ if (info.dli_fname) {
+ module_filespec.SetFile(info.dli_fname, FileSpec::Style::native);
+ FileSystem::Instance().Resolve(module_filespec);
+ }
}
#endif
return module_filespec;
@@ -494,7 +496,7 @@ Status Host::RunShellCommand(const Args &args, const FileSpec &working_dir,
if (working_dir)
launch_info.SetWorkingDirectory(working_dir);
- llvm::SmallString<PATH_MAX> output_file_path;
+ llvm::SmallString<64> output_file_path;
if (command_output_ptr) {
// Create a temporary file to get the stdout/stderr and redirect the output
@@ -510,7 +512,7 @@ Status Host::RunShellCommand(const Args &args, const FileSpec &working_dir,
}
}
- FileSpec output_file_spec{output_file_path.c_str(), false};
+ FileSpec output_file_spec(output_file_path.c_str());
launch_info.AppendSuppressFileAction(STDIN_FILENO, true, false);
if (output_file_spec) {
@@ -554,14 +556,15 @@ Status Host::RunShellCommand(const Args &args, const FileSpec &working_dir,
if (command_output_ptr) {
command_output_ptr->clear();
- uint64_t file_size = output_file_spec.GetByteSize();
+ uint64_t file_size =
+ FileSystem::Instance().GetByteSize(output_file_spec);
if (file_size > 0) {
if (file_size > command_output_ptr->max_size()) {
error.SetErrorStringWithFormat(
"shell command output is too large to fit into a std::string");
} else {
auto Buffer =
- DataBufferLLVM::CreateFromPath(output_file_spec.GetPath());
+ FileSystem::Instance().CreateDataBuffer(output_file_spec);
if (error.Success())
command_output_ptr->assign(Buffer->GetChars(),
Buffer->GetByteSize());
diff --git a/source/Host/common/HostInfoBase.cpp b/source/Host/common/HostInfoBase.cpp
index 4de6953a91e3..34c362efc9e0 100644
--- a/source/Host/common/HostInfoBase.cpp
+++ b/source/Host/common/HostInfoBase.cpp
@@ -42,7 +42,7 @@ namespace {
struct HostInfoBaseFields {
~HostInfoBaseFields() {
- if (m_lldb_process_tmp_dir.Exists()) {
+ if (FileSystem::Instance().Exists(m_lldb_process_tmp_dir)) {
// Remove the LLDB temporary directory if we have one. Set "recurse" to
// true to all files that were created for the LLDB process can be
// cleaned up.
@@ -226,7 +226,7 @@ bool HostInfoBase::ComputeSharedLibraryDirectory(FileSpec &file_spec) {
// This is necessary because when running the testsuite the shlib might be a
// symbolic link inside the Python resource dir.
- FileSystem::ResolveSymbolicLink(lldb_file_spec, lldb_file_spec);
+ FileSystem::Instance().ResolveSymbolicLink(lldb_file_spec, lldb_file_spec);
// Remove the filename so that this FileSpec only represents the directory.
file_spec.GetDirectory() = lldb_file_spec.GetDirectory();
@@ -256,7 +256,8 @@ bool HostInfoBase::ComputeProcessTempFileDirectory(FileSpec &file_spec) {
bool HostInfoBase::ComputeTempFileBaseDirectory(FileSpec &file_spec) {
llvm::SmallVector<char, 16> tmpdir;
llvm::sys::path::system_temp_directory(/*ErasedOnReboot*/ true, tmpdir);
- file_spec = FileSpec(std::string(tmpdir.data(), tmpdir.size()), true);
+ file_spec = FileSpec(std::string(tmpdir.data(), tmpdir.size()));
+ FileSystem::Instance().Resolve(file_spec);
return true;
}
diff --git a/source/Host/common/HostNativeThreadBase.cpp b/source/Host/common/HostNativeThreadBase.cpp
index 402d3caacfcb..25c8066bb1a3 100644
--- a/source/Host/common/HostNativeThreadBase.cpp
+++ b/source/Host/common/HostNativeThreadBase.cpp
@@ -41,6 +41,10 @@ void HostNativeThreadBase::Reset() {
m_result = 0;
}
+bool HostNativeThreadBase::EqualsThread(lldb::thread_t thread) const {
+ return m_thread == thread;
+}
+
lldb::thread_t HostNativeThreadBase::Release() {
lldb::thread_t result = m_thread;
m_thread = LLDB_INVALID_HOST_THREAD;
diff --git a/source/Host/common/HostThread.cpp b/source/Host/common/HostThread.cpp
index 02882c523908..2bf6f0a933d8 100644
--- a/source/Host/common/HostThread.cpp
+++ b/source/Host/common/HostThread.cpp
@@ -43,5 +43,5 @@ lldb::thread_result_t HostThread::GetResult() const {
}
bool HostThread::EqualsThread(lldb::thread_t thread) const {
- return m_native_thread->GetSystemHandle() == thread;
+ return m_native_thread->EqualsThread(thread);
}
diff --git a/source/Host/common/MainLoop.cpp b/source/Host/common/MainLoop.cpp
index 65158c942934..39c353e6717e 100644
--- a/source/Host/common/MainLoop.cpp
+++ b/source/Host/common/MainLoop.cpp
@@ -309,7 +309,7 @@ MainLoop::RegisterSignal(int signo, const Callback &callback, Status &error) {
g_signal_flags[signo] = 0;
// Even if using kqueue, the signal handler will still be invoked, so it's
- // important to replace it with our "bening" handler.
+ // important to replace it with our "benign" handler.
int ret = sigaction(signo, &new_action, &info.old_action);
assert(ret == 0 && "sigaction failed");
@@ -321,7 +321,7 @@ MainLoop::RegisterSignal(int signo, const Callback &callback, Status &error) {
#endif
// If we're using kqueue, the signal needs to be unblocked in order to
- // recieve it. If using pselect/ppoll, we need to block it, and later unblock
+ // receive it. If using pselect/ppoll, we need to block it, and later unblock
// it as a part of the system call.
ret = pthread_sigmask(HAVE_SYS_EVENT_H ? SIG_UNBLOCK : SIG_BLOCK,
&new_action.sa_mask, &old_set);
diff --git a/source/Host/common/MonitoringProcessLauncher.cpp b/source/Host/common/MonitoringProcessLauncher.cpp
index 76c11454f573..f6f772cb3679 100644
--- a/source/Host/common/MonitoringProcessLauncher.cpp
+++ b/source/Host/common/MonitoringProcessLauncher.cpp
@@ -8,10 +8,10 @@
//===----------------------------------------------------------------------===//
#include "lldb/Host/MonitoringProcessLauncher.h"
+#include "lldb/Host/FileSystem.h"
#include "lldb/Host/HostProcess.h"
#include "lldb/Target/ProcessLaunchInfo.h"
#include "lldb/Utility/Log.h"
-#include "lldb/Utility/Status.h"
#include "llvm/Support/FileSystem.h"
@@ -29,20 +29,16 @@ MonitoringProcessLauncher::LaunchProcess(const ProcessLaunchInfo &launch_info,
error.Clear();
+ FileSystem &fs = FileSystem::Instance();
FileSpec exe_spec(resolved_info.GetExecutableFile());
- llvm::sys::fs::file_status stats;
- status(exe_spec.GetPath(), stats);
- if (!exists(stats)) {
- exe_spec.ResolvePath();
- status(exe_spec.GetPath(), stats);
- }
- if (!exists(stats)) {
- exe_spec.ResolveExecutableLocation();
- status(exe_spec.GetPath(), stats);
- }
+ if (!fs.Exists(exe_spec))
+ FileSystem::Instance().Resolve(exe_spec);
+
+ if (!fs.Exists(exe_spec))
+ FileSystem::Instance().ResolveExecutableLocation(exe_spec);
- if (!exists(stats)) {
+ if (!fs.Exists(exe_spec)) {
error.SetErrorStringWithFormatv("executable doesn't exist: '{0}'",
exe_spec);
return HostProcess();
diff --git a/source/Host/common/NativeBreakpoint.cpp b/source/Host/common/NativeBreakpoint.cpp
deleted file mode 100644
index 5eee3de482c1..000000000000
--- a/source/Host/common/NativeBreakpoint.cpp
+++ /dev/null
@@ -1,109 +0,0 @@
-//===-- NativeBreakpoint.cpp ------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/Host/common/NativeBreakpoint.h"
-
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/Status.h"
-#include "lldb/lldb-defines.h"
-
-using namespace lldb_private;
-
-NativeBreakpoint::NativeBreakpoint(lldb::addr_t addr)
- : m_addr(addr), m_ref_count(1), m_enabled(true) {
- assert(addr != LLDB_INVALID_ADDRESS && "breakpoint set for invalid address");
-}
-
-NativeBreakpoint::~NativeBreakpoint() {}
-
-void NativeBreakpoint::AddRef() {
- ++m_ref_count;
-
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
- if (log)
- log->Printf("NativeBreakpoint::%s addr = 0x%" PRIx64
- " bumped up, new ref count %" PRIu32,
- __FUNCTION__, m_addr, m_ref_count);
-}
-
-int32_t NativeBreakpoint::DecRef() {
- --m_ref_count;
-
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
- if (log)
- log->Printf("NativeBreakpoint::%s addr = 0x%" PRIx64
- " ref count decremented, new ref count %" PRIu32,
- __FUNCTION__, m_addr, m_ref_count);
-
- return m_ref_count;
-}
-
-Status NativeBreakpoint::Enable() {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
-
- if (m_enabled) {
- // We're already enabled. Just log and exit.
- if (log)
- log->Printf("NativeBreakpoint::%s addr = 0x%" PRIx64
- " already enabled, ignoring.",
- __FUNCTION__, m_addr);
- return Status();
- }
-
- // Log and enable.
- if (log)
- log->Printf("NativeBreakpoint::%s addr = 0x%" PRIx64 " enabling...",
- __FUNCTION__, m_addr);
-
- Status error = DoEnable();
- if (error.Success()) {
- m_enabled = true;
- if (log)
- log->Printf("NativeBreakpoint::%s addr = 0x%" PRIx64 " enable SUCCESS.",
- __FUNCTION__, m_addr);
- } else {
- if (log)
- log->Printf("NativeBreakpoint::%s addr = 0x%" PRIx64 " enable FAIL: %s",
- __FUNCTION__, m_addr, error.AsCString());
- }
-
- return error;
-}
-
-Status NativeBreakpoint::Disable() {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
-
- if (!m_enabled) {
- // We're already disabled. Just log and exit.
- if (log)
- log->Printf("NativeBreakpoint::%s addr = 0x%" PRIx64
- " already disabled, ignoring.",
- __FUNCTION__, m_addr);
- return Status();
- }
-
- // Log and disable.
- if (log)
- log->Printf("NativeBreakpoint::%s addr = 0x%" PRIx64 " disabling...",
- __FUNCTION__, m_addr);
-
- Status error = DoDisable();
- if (error.Success()) {
- m_enabled = false;
- if (log)
- log->Printf("NativeBreakpoint::%s addr = 0x%" PRIx64 " disable SUCCESS.",
- __FUNCTION__, m_addr);
- } else {
- if (log)
- log->Printf("NativeBreakpoint::%s addr = 0x%" PRIx64 " disable FAIL: %s",
- __FUNCTION__, m_addr, error.AsCString());
- }
-
- return error;
-}
diff --git a/source/Host/common/NativeBreakpointList.cpp b/source/Host/common/NativeBreakpointList.cpp
deleted file mode 100644
index cfcbe0831064..000000000000
--- a/source/Host/common/NativeBreakpointList.cpp
+++ /dev/null
@@ -1,229 +0,0 @@
-//===-- NativeBreakpointList.cpp --------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/Host/common/NativeBreakpointList.h"
-
-#include "lldb/Utility/Log.h"
-
-#include "lldb/Host/common/NativeBreakpoint.h"
-#include "lldb/Host/common/SoftwareBreakpoint.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-NativeBreakpointList::NativeBreakpointList() : m_mutex() {}
-
-Status NativeBreakpointList::AddRef(lldb::addr_t addr, size_t size_hint,
- bool hardware,
- CreateBreakpointFunc create_func) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
- if (log)
- log->Printf("NativeBreakpointList::%s addr = 0x%" PRIx64
- ", size_hint = %zu, hardware = %s",
- __FUNCTION__, addr, size_hint, hardware ? "true" : "false");
-
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
-
- // Check if the breakpoint is already set.
- auto iter = m_breakpoints.find(addr);
- if (iter != m_breakpoints.end()) {
- // Yes - bump up ref count.
- if (log)
- log->Printf("NativeBreakpointList::%s addr = 0x%" PRIx64
- " -- already enabled, upping ref count",
- __FUNCTION__, addr);
-
- iter->second->AddRef();
- return Status();
- }
-
- // Create a new breakpoint using the given create func.
- if (log)
- log->Printf(
- "NativeBreakpointList::%s creating breakpoint for addr = 0x%" PRIx64
- ", size_hint = %zu, hardware = %s",
- __FUNCTION__, addr, size_hint, hardware ? "true" : "false");
-
- NativeBreakpointSP breakpoint_sp;
- Status error = create_func(addr, size_hint, hardware, breakpoint_sp);
- if (error.Fail()) {
- if (log)
- log->Printf(
- "NativeBreakpointList::%s creating breakpoint for addr = 0x%" PRIx64
- ", size_hint = %zu, hardware = %s -- FAILED: %s",
- __FUNCTION__, addr, size_hint, hardware ? "true" : "false",
- error.AsCString());
- return error;
- }
-
- // Remember the breakpoint.
- assert(breakpoint_sp && "NativeBreakpoint create function succeeded but "
- "returned NULL breakpoint");
- m_breakpoints.insert(BreakpointMap::value_type(addr, breakpoint_sp));
-
- return error;
-}
-
-Status NativeBreakpointList::DecRef(lldb::addr_t addr) {
- Status error;
-
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
- if (log)
- log->Printf("NativeBreakpointList::%s addr = 0x%" PRIx64, __FUNCTION__,
- addr);
-
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
-
- // Check if the breakpoint is already set.
- auto iter = m_breakpoints.find(addr);
- if (iter == m_breakpoints.end()) {
- // Not found!
- if (log)
- log->Printf("NativeBreakpointList::%s addr = 0x%" PRIx64 " -- NOT FOUND",
- __FUNCTION__, addr);
- error.SetErrorString("breakpoint not found");
- return error;
- }
-
- // Decrement ref count.
- const int32_t new_ref_count = iter->second->DecRef();
- assert(new_ref_count >= 0 && "NativeBreakpoint ref count went negative");
-
- if (new_ref_count > 0) {
- // Still references to this breakpoint. Leave it alone.
- if (log)
- log->Printf("NativeBreakpointList::%s addr = 0x%" PRIx64
- " -- new breakpoint ref count %" PRIu32,
- __FUNCTION__, addr, new_ref_count);
- return error;
- }
-
- // Breakpoint has no more references. Disable it if it's not already
- // disabled.
- if (log)
- log->Printf("NativeBreakpointList::%s addr = 0x%" PRIx64
- " -- removing due to no remaining references",
- __FUNCTION__, addr);
-
- // If it's enabled, we need to disable it.
- if (iter->second->IsEnabled()) {
- if (log)
- log->Printf("NativeBreakpointList::%s addr = 0x%" PRIx64
- " -- currently enabled, now disabling",
- __FUNCTION__, addr);
- error = iter->second->Disable();
- if (error.Fail()) {
- if (log)
- log->Printf("NativeBreakpointList::%s addr = 0x%" PRIx64
- " -- removal FAILED: %s",
- __FUNCTION__, addr, error.AsCString());
- // Continue since we still want to take it out of the breakpoint list.
- }
- } else {
- if (log)
- log->Printf("NativeBreakpointList::%s addr = 0x%" PRIx64
- " -- already disabled, nothing to do",
- __FUNCTION__, addr);
- }
-
- // Take the breakpoint out of the list.
- if (log)
- log->Printf("NativeBreakpointList::%s addr = 0x%" PRIx64
- " -- removed from breakpoint map",
- __FUNCTION__, addr);
-
- m_breakpoints.erase(iter);
- return error;
-}
-
-Status NativeBreakpointList::EnableBreakpoint(lldb::addr_t addr) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
- if (log)
- log->Printf("NativeBreakpointList::%s addr = 0x%" PRIx64, __FUNCTION__,
- addr);
-
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
-
- // Ensure we have said breakpoint.
- auto iter = m_breakpoints.find(addr);
- if (iter == m_breakpoints.end()) {
- // Not found!
- if (log)
- log->Printf("NativeBreakpointList::%s addr = 0x%" PRIx64 " -- NOT FOUND",
- __FUNCTION__, addr);
- return Status("breakpoint not found");
- }
-
- // Enable it.
- return iter->second->Enable();
-}
-
-Status NativeBreakpointList::DisableBreakpoint(lldb::addr_t addr) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
- if (log)
- log->Printf("NativeBreakpointList::%s addr = 0x%" PRIx64, __FUNCTION__,
- addr);
-
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
-
- // Ensure we have said breakpoint.
- auto iter = m_breakpoints.find(addr);
- if (iter == m_breakpoints.end()) {
- // Not found!
- if (log)
- log->Printf("NativeBreakpointList::%s addr = 0x%" PRIx64 " -- NOT FOUND",
- __FUNCTION__, addr);
- return Status("breakpoint not found");
- }
-
- // Disable it.
- return iter->second->Disable();
-}
-
-Status NativeBreakpointList::GetBreakpoint(lldb::addr_t addr,
- NativeBreakpointSP &breakpoint_sp) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
- if (log)
- log->Printf("NativeBreakpointList::%s addr = 0x%" PRIx64, __FUNCTION__,
- addr);
-
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
-
- // Ensure we have said breakpoint.
- auto iter = m_breakpoints.find(addr);
- if (iter == m_breakpoints.end()) {
- // Not found!
- breakpoint_sp.reset();
- return Status("breakpoint not found");
- }
-
- // Disable it.
- breakpoint_sp = iter->second;
- return Status();
-}
-
-Status NativeBreakpointList::RemoveTrapsFromBuffer(lldb::addr_t addr, void *buf,
- size_t size) const {
- for (const auto &map : m_breakpoints) {
- lldb::addr_t bp_addr = map.first;
- // Breapoint not in range, ignore
- if (bp_addr < addr || addr + size <= bp_addr)
- continue;
- const auto &bp_sp = map.second;
- // Not software breakpoint, ignore
- if (!bp_sp->IsSoftwareBreakpoint())
- continue;
- auto software_bp_sp = std::static_pointer_cast<SoftwareBreakpoint>(bp_sp);
- auto opcode_addr = static_cast<char *>(buf) + bp_addr - addr;
- auto saved_opcodes = software_bp_sp->m_saved_opcodes;
- auto opcode_size = software_bp_sp->m_opcode_size;
- ::memcpy(opcode_addr, saved_opcodes, opcode_size);
- }
- return Status();
-}
diff --git a/source/Host/common/NativeProcessProtocol.cpp b/source/Host/common/NativeProcessProtocol.cpp
index 3e8648f81473..e3c81f6c147b 100644
--- a/source/Host/common/NativeProcessProtocol.cpp
+++ b/source/Host/common/NativeProcessProtocol.cpp
@@ -8,13 +8,13 @@
//===----------------------------------------------------------------------===//
#include "lldb/Host/common/NativeProcessProtocol.h"
-#include "lldb/Core/State.h"
#include "lldb/Host/Host.h"
+#include "lldb/Host/common/NativeBreakpointList.h"
#include "lldb/Host/common/NativeRegisterContext.h"
#include "lldb/Host/common/NativeThreadProtocol.h"
-#include "lldb/Host/common/SoftwareBreakpoint.h"
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/State.h"
#include "lldb/lldb-enumerations.h"
using namespace lldb;
@@ -359,17 +359,271 @@ void NativeProcessProtocol::NotifyDidExec() {
Status NativeProcessProtocol::SetSoftwareBreakpoint(lldb::addr_t addr,
uint32_t size_hint) {
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
- if (log)
- log->Printf("NativeProcessProtocol::%s addr = 0x%" PRIx64, __FUNCTION__,
- addr);
+ LLDB_LOG(log, "addr = {0:x}, size_hint = {1}", addr, size_hint);
+
+ auto it = m_software_breakpoints.find(addr);
+ if (it != m_software_breakpoints.end()) {
+ ++it->second.ref_count;
+ return Status();
+ }
+ auto expected_bkpt = EnableSoftwareBreakpoint(addr, size_hint);
+ if (!expected_bkpt)
+ return Status(expected_bkpt.takeError());
+
+ m_software_breakpoints.emplace(addr, std::move(*expected_bkpt));
+ return Status();
+}
+
+Status NativeProcessProtocol::RemoveSoftwareBreakpoint(lldb::addr_t addr) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+ LLDB_LOG(log, "addr = {0:x}", addr);
+ auto it = m_software_breakpoints.find(addr);
+ if (it == m_software_breakpoints.end())
+ return Status("Breakpoint not found.");
+ assert(it->second.ref_count > 0);
+ if (--it->second.ref_count > 0)
+ return Status();
+
+ // This is the last reference. Let's remove the breakpoint.
+ Status error;
+
+ // Clear a software breakpoint instruction
+ llvm::SmallVector<uint8_t, 4> curr_break_op(
+ it->second.breakpoint_opcodes.size(), 0);
+
+ // Read the breakpoint opcode
+ size_t bytes_read = 0;
+ error =
+ ReadMemory(addr, curr_break_op.data(), curr_break_op.size(), bytes_read);
+ if (error.Fail() || bytes_read < curr_break_op.size()) {
+ return Status("addr=0x%" PRIx64
+ ": tried to read %zu bytes but only read %zu",
+ addr, curr_break_op.size(), bytes_read);
+ }
+ const auto &saved = it->second.saved_opcodes;
+ // Make sure the breakpoint opcode exists at this address
+ if (makeArrayRef(curr_break_op) != it->second.breakpoint_opcodes) {
+ if (curr_break_op != it->second.saved_opcodes)
+ return Status("Original breakpoint trap is no longer in memory.");
+ LLDB_LOG(log,
+ "Saved opcodes ({0:@[x]}) have already been restored at {1:x}.",
+ llvm::make_range(saved.begin(), saved.end()), addr);
+ } else {
+ // We found a valid breakpoint opcode at this address, now restore the
+ // saved opcode.
+ size_t bytes_written = 0;
+ error = WriteMemory(addr, saved.data(), saved.size(), bytes_written);
+ if (error.Fail() || bytes_written < saved.size()) {
+ return Status("addr=0x%" PRIx64
+ ": tried to write %zu bytes but only wrote %zu",
+ addr, saved.size(), bytes_written);
+ }
+
+ // Verify that our original opcode made it back to the inferior
+ llvm::SmallVector<uint8_t, 4> verify_opcode(saved.size(), 0);
+ size_t verify_bytes_read = 0;
+ error = ReadMemory(addr, verify_opcode.data(), verify_opcode.size(),
+ verify_bytes_read);
+ if (error.Fail() || verify_bytes_read < verify_opcode.size()) {
+ return Status("addr=0x%" PRIx64
+ ": tried to read %zu verification bytes but only read %zu",
+ addr, verify_opcode.size(), verify_bytes_read);
+ }
+ if (verify_opcode != saved)
+ LLDB_LOG(log, "Restoring bytes at {0:x}: {1:@[x]}", addr,
+ llvm::make_range(saved.begin(), saved.end()));
+ }
+
+ m_software_breakpoints.erase(it);
+ return Status();
+}
+
+llvm::Expected<NativeProcessProtocol::SoftwareBreakpoint>
+NativeProcessProtocol::EnableSoftwareBreakpoint(lldb::addr_t addr,
+ uint32_t size_hint) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+
+ auto expected_trap = GetSoftwareBreakpointTrapOpcode(size_hint);
+ if (!expected_trap)
+ return expected_trap.takeError();
+
+ llvm::SmallVector<uint8_t, 4> saved_opcode_bytes(expected_trap->size(), 0);
+ // Save the original opcodes by reading them so we can restore later.
+ size_t bytes_read = 0;
+ Status error = ReadMemory(addr, saved_opcode_bytes.data(),
+ saved_opcode_bytes.size(), bytes_read);
+ if (error.Fail())
+ return error.ToError();
+
+ // Ensure we read as many bytes as we expected.
+ if (bytes_read != saved_opcode_bytes.size()) {
+ return llvm::createStringError(
+ llvm::inconvertibleErrorCode(),
+ "Failed to read memory while attempting to set breakpoint: attempted "
+ "to read {0} bytes but only read {1}.",
+ saved_opcode_bytes.size(), bytes_read);
+ }
+
+ LLDB_LOG(
+ log, "Overwriting bytes at {0:x}: {1:@[x]}", addr,
+ llvm::make_range(saved_opcode_bytes.begin(), saved_opcode_bytes.end()));
+
+ // Write a software breakpoint in place of the original opcode.
+ size_t bytes_written = 0;
+ error = WriteMemory(addr, expected_trap->data(), expected_trap->size(),
+ bytes_written);
+ if (error.Fail())
+ return error.ToError();
+
+ // Ensure we wrote as many bytes as we expected.
+ if (bytes_written != expected_trap->size()) {
+ return llvm::createStringError(
+ llvm::inconvertibleErrorCode(),
+ "Failed write memory while attempting to set "
+ "breakpoint: attempted to write {0} bytes but only wrote {1}",
+ expected_trap->size(), bytes_written);
+ }
+
+ llvm::SmallVector<uint8_t, 4> verify_bp_opcode_bytes(expected_trap->size(),
+ 0);
+ size_t verify_bytes_read = 0;
+ error = ReadMemory(addr, verify_bp_opcode_bytes.data(),
+ verify_bp_opcode_bytes.size(), verify_bytes_read);
+ if (error.Fail())
+ return error.ToError();
+
+ // Ensure we read as many verification bytes as we expected.
+ if (verify_bytes_read != verify_bp_opcode_bytes.size()) {
+ return llvm::createStringError(
+ llvm::inconvertibleErrorCode(),
+ "Failed to read memory while "
+ "attempting to verify breakpoint: attempted to read {0} bytes "
+ "but only read {1}",
+ verify_bp_opcode_bytes.size(), verify_bytes_read);
+ }
+
+ if (llvm::makeArrayRef(verify_bp_opcode_bytes.data(), verify_bytes_read) !=
+ *expected_trap) {
+ return llvm::createStringError(
+ llvm::inconvertibleErrorCode(),
+ "Verification of software breakpoint "
+ "writing failed - trap opcodes not successfully read back "
+ "after writing when setting breakpoint at {0:x}",
+ addr);
+ }
+
+ LLDB_LOG(log, "addr = {0:x}: SUCCESS", addr);
+ return SoftwareBreakpoint{1, saved_opcode_bytes, *expected_trap};
+}
+
+llvm::Expected<llvm::ArrayRef<uint8_t>>
+NativeProcessProtocol::GetSoftwareBreakpointTrapOpcode(size_t size_hint) {
+ static const uint8_t g_aarch64_opcode[] = {0x00, 0x00, 0x20, 0xd4};
+ static const uint8_t g_i386_opcode[] = {0xCC};
+ static const uint8_t g_mips64_opcode[] = {0x00, 0x00, 0x00, 0x0d};
+ static const uint8_t g_mips64el_opcode[] = {0x0d, 0x00, 0x00, 0x00};
+ static const uint8_t g_s390x_opcode[] = {0x00, 0x01};
+ static const uint8_t g_ppc64le_opcode[] = {0x08, 0x00, 0xe0, 0x7f}; // trap
+
+ switch (GetArchitecture().GetMachine()) {
+ case llvm::Triple::aarch64:
+ return llvm::makeArrayRef(g_aarch64_opcode);
+
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ return llvm::makeArrayRef(g_i386_opcode);
+
+ case llvm::Triple::mips:
+ case llvm::Triple::mips64:
+ return llvm::makeArrayRef(g_mips64_opcode);
+
+ case llvm::Triple::mipsel:
+ case llvm::Triple::mips64el:
+ return llvm::makeArrayRef(g_mips64el_opcode);
+
+ case llvm::Triple::systemz:
+ return llvm::makeArrayRef(g_s390x_opcode);
+
+ case llvm::Triple::ppc64le:
+ return llvm::makeArrayRef(g_ppc64le_opcode);
- return m_breakpoint_list.AddRef(
- addr, size_hint, false,
- [this](lldb::addr_t addr, size_t size_hint, bool /* hardware */,
- NativeBreakpointSP &breakpoint_sp) -> Status {
- return SoftwareBreakpoint::CreateSoftwareBreakpoint(
- *this, addr, size_hint, breakpoint_sp);
- });
+ default:
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "CPU type not supported!");
+ }
+}
+
+size_t NativeProcessProtocol::GetSoftwareBreakpointPCOffset() {
+ switch (GetArchitecture().GetMachine()) {
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ case llvm::Triple::systemz:
+ // These architectures report increment the PC after breakpoint is hit.
+ return cantFail(GetSoftwareBreakpointTrapOpcode(0)).size();
+
+ case llvm::Triple::arm:
+ case llvm::Triple::aarch64:
+ case llvm::Triple::mips64:
+ case llvm::Triple::mips64el:
+ case llvm::Triple::mips:
+ case llvm::Triple::mipsel:
+ case llvm::Triple::ppc64le:
+ // On these architectures the PC doesn't get updated for breakpoint hits.
+ return 0;
+
+ default:
+ llvm_unreachable("CPU type not supported!");
+ }
+}
+
+void NativeProcessProtocol::FixupBreakpointPCAsNeeded(
+ NativeThreadProtocol &thread) {
+ Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS);
+
+ Status error;
+
+ // Find out the size of a breakpoint (might depend on where we are in the
+ // code).
+ NativeRegisterContext &context = thread.GetRegisterContext();
+
+ uint32_t breakpoint_size = GetSoftwareBreakpointPCOffset();
+ LLDB_LOG(log, "breakpoint size: {0}", breakpoint_size);
+ if (breakpoint_size == 0)
+ return;
+
+ // First try probing for a breakpoint at a software breakpoint location: PC -
+ // breakpoint size.
+ const lldb::addr_t initial_pc_addr = context.GetPCfromBreakpointLocation();
+ lldb::addr_t breakpoint_addr = initial_pc_addr;
+ // Do not allow breakpoint probe to wrap around.
+ if (breakpoint_addr >= breakpoint_size)
+ breakpoint_addr -= breakpoint_size;
+
+ if (m_software_breakpoints.count(breakpoint_addr) == 0) {
+ // We didn't find one at a software probe location. Nothing to do.
+ LLDB_LOG(log,
+ "pid {0} no lldb software breakpoint found at current pc with "
+ "adjustment: {1}",
+ GetID(), breakpoint_addr);
+ return;
+ }
+
+ //
+ // We have a software breakpoint and need to adjust the PC.
+ //
+
+ // Change the program counter.
+ LLDB_LOG(log, "pid {0} tid {1}: changing PC from {2:x} to {3:x}", GetID(),
+ thread.GetID(), initial_pc_addr, breakpoint_addr);
+
+ error = context.SetPC(breakpoint_addr);
+ if (error.Fail()) {
+ // This can happen in case the process was killed between the time we read
+ // the PC and when we are updating it. There's nothing better to do than to
+ // swallow the error.
+ LLDB_LOG(log, "pid {0} tid {1}: failed to set PC: {2}", GetID(),
+ thread.GetID(), error);
+ }
}
Status NativeProcessProtocol::RemoveBreakpoint(lldb::addr_t addr,
@@ -377,15 +631,35 @@ Status NativeProcessProtocol::RemoveBreakpoint(lldb::addr_t addr,
if (hardware)
return RemoveHardwareBreakpoint(addr);
else
- return m_breakpoint_list.DecRef(addr);
-}
-
-Status NativeProcessProtocol::EnableBreakpoint(lldb::addr_t addr) {
- return m_breakpoint_list.EnableBreakpoint(addr);
+ return RemoveSoftwareBreakpoint(addr);
}
-Status NativeProcessProtocol::DisableBreakpoint(lldb::addr_t addr) {
- return m_breakpoint_list.DisableBreakpoint(addr);
+Status NativeProcessProtocol::ReadMemoryWithoutTrap(lldb::addr_t addr,
+ void *buf, size_t size,
+ size_t &bytes_read) {
+ Status error = ReadMemory(addr, buf, size, bytes_read);
+ if (error.Fail())
+ return error;
+
+ auto data =
+ llvm::makeMutableArrayRef(static_cast<uint8_t *>(buf), bytes_read);
+ for (const auto &pair : m_software_breakpoints) {
+ lldb::addr_t bp_addr = pair.first;
+ auto saved_opcodes = makeArrayRef(pair.second.saved_opcodes);
+
+ if (bp_addr + saved_opcodes.size() < addr || addr + bytes_read <= bp_addr)
+ continue; // Breapoint not in range, ignore
+
+ if (bp_addr < addr) {
+ saved_opcodes = saved_opcodes.drop_front(addr - bp_addr);
+ bp_addr = addr;
+ }
+ auto bp_data = data.drop_front(bp_addr - addr);
+ std::copy_n(saved_opcodes.begin(),
+ std::min(saved_opcodes.size(), bp_data.size()),
+ bp_data.begin());
+ }
+ return Status();
}
lldb::StateType NativeProcessProtocol::GetState() const {
diff --git a/source/Host/common/NativeRegisterContext.cpp b/source/Host/common/NativeRegisterContext.cpp
index 49b8284da970..6e6632aa710f 100644
--- a/source/Host/common/NativeRegisterContext.cpp
+++ b/source/Host/common/NativeRegisterContext.cpp
@@ -9,8 +9,8 @@
#include "lldb/Host/common/NativeRegisterContext.h"
-#include "lldb/Core/RegisterValue.h"
#include "lldb/Utility/Log.h"
+#include "lldb/Utility/RegisterValue.h"
#include "lldb/Host/PosixApi.h"
#include "lldb/Host/common/NativeProcessProtocol.h"
diff --git a/source/Host/common/NativeThreadProtocol.cpp b/source/Host/common/NativeThreadProtocol.cpp
index 0c648e40eb5c..af43683295b0 100644
--- a/source/Host/common/NativeThreadProtocol.cpp
+++ b/source/Host/common/NativeThreadProtocol.cpp
@@ -11,7 +11,6 @@
#include "lldb/Host/common/NativeProcessProtocol.h"
#include "lldb/Host/common/NativeRegisterContext.h"
-#include "lldb/Host/common/SoftwareBreakpoint.h"
using namespace lldb;
using namespace lldb_private;
diff --git a/source/Host/common/ProcessRunLock.cpp b/source/Host/common/ProcessRunLock.cpp
index 48dcd62bb939..e0ba2ecfd3e9 100644
--- a/source/Host/common/ProcessRunLock.cpp
+++ b/source/Host/common/ProcessRunLock.cpp
@@ -30,7 +30,7 @@ ProcessRunLock::~ProcessRunLock() {
bool ProcessRunLock::ReadTryLock() {
::pthread_rwlock_rdlock(&m_rwlock);
- if (m_running == false) {
+ if (!m_running) {
return true;
}
::pthread_rwlock_unlock(&m_rwlock);
diff --git a/source/Host/common/PseudoTerminal.cpp b/source/Host/common/PseudoTerminal.cpp
index c9b290078e18..08d4fa218968 100644
--- a/source/Host/common/PseudoTerminal.cpp
+++ b/source/Host/common/PseudoTerminal.cpp
@@ -10,7 +10,8 @@
#include "lldb/Host/PseudoTerminal.h"
#include "lldb/Host/Config.h"
-#include <errno.h>
+#include "llvm/Support/Errno.h"
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -27,6 +28,14 @@ int posix_openpt(int flags);
using namespace lldb_private;
//----------------------------------------------------------------------
+// Write string describing error number
+//----------------------------------------------------------------------
+static void ErrnoToStr(char *error_str, size_t error_len) {
+ std::string strerror = llvm::sys::StrError();
+ ::snprintf(error_str, error_len, "%s", strerror.c_str());
+}
+
+//----------------------------------------------------------------------
// PseudoTerminal constructor
//----------------------------------------------------------------------
PseudoTerminal::PseudoTerminal()
@@ -88,14 +97,14 @@ bool PseudoTerminal::OpenFirstAvailableMaster(int oflag, char *error_str,
m_master_fd = ::posix_openpt(oflag);
if (m_master_fd < 0) {
if (error_str)
- ::strerror_r(errno, error_str, error_len);
+ ErrnoToStr(error_str, error_len);
return false;
}
// Grant access to the slave pseudo terminal
if (::grantpt(m_master_fd) < 0) {
if (error_str)
- ::strerror_r(errno, error_str, error_len);
+ ErrnoToStr(error_str, error_len);
CloseMasterFileDescriptor();
return false;
}
@@ -103,7 +112,7 @@ bool PseudoTerminal::OpenFirstAvailableMaster(int oflag, char *error_str,
// Clear the lock flag on the slave pseudo terminal
if (::unlockpt(m_master_fd) < 0) {
if (error_str)
- ::strerror_r(errno, error_str, error_len);
+ ErrnoToStr(error_str, error_len);
CloseMasterFileDescriptor();
return false;
}
@@ -143,7 +152,7 @@ bool PseudoTerminal::OpenSlave(int oflag, char *error_str, size_t error_len) {
if (m_slave_fd < 0) {
if (error_str)
- ::strerror_r(errno, error_str, error_len);
+ ErrnoToStr(error_str, error_len);
return false;
}
@@ -175,7 +184,7 @@ const char *PseudoTerminal::GetSlaveName(char *error_str,
const char *slave_name = ::ptsname(m_master_fd);
if (error_str && slave_name == nullptr)
- ::strerror_r(errno, error_str, error_len);
+ ErrnoToStr(error_str, error_len);
return slave_name;
}
@@ -213,7 +222,7 @@ lldb::pid_t PseudoTerminal::Fork(char *error_str, size_t error_len) {
if (pid < 0) {
// Fork failed
if (error_str)
- ::strerror_r(errno, error_str, error_len);
+ ErrnoToStr(error_str, error_len);
} else if (pid == 0) {
// Child Process
::setsid();
@@ -229,23 +238,23 @@ lldb::pid_t PseudoTerminal::Fork(char *error_str, size_t error_len) {
// Acquire the controlling terminal
if (::ioctl(m_slave_fd, TIOCSCTTY, (char *)0) < 0) {
if (error_str)
- ::strerror_r(errno, error_str, error_len);
+ ErrnoToStr(error_str, error_len);
}
#endif
// Duplicate all stdio file descriptors to the slave pseudo terminal
if (::dup2(m_slave_fd, STDIN_FILENO) != STDIN_FILENO) {
if (error_str && !error_str[0])
- ::strerror_r(errno, error_str, error_len);
+ ErrnoToStr(error_str, error_len);
}
if (::dup2(m_slave_fd, STDOUT_FILENO) != STDOUT_FILENO) {
if (error_str && !error_str[0])
- ::strerror_r(errno, error_str, error_len);
+ ErrnoToStr(error_str, error_len);
}
if (::dup2(m_slave_fd, STDERR_FILENO) != STDERR_FILENO) {
if (error_str && !error_str[0])
- ::strerror_r(errno, error_str, error_len);
+ ErrnoToStr(error_str, error_len);
}
}
} else {
diff --git a/source/Host/common/SocketAddress.cpp b/source/Host/common/SocketAddress.cpp
index def3e0359f01..172cb06a5819 100644
--- a/source/Host/common/SocketAddress.cpp
+++ b/source/Host/common/SocketAddress.cpp
@@ -21,7 +21,6 @@
#include <stddef.h>
#include <stdio.h>
-// C Includes
#if !defined(_WIN32)
#include <arpa/inet.h>
#endif
@@ -29,9 +28,6 @@
#include <assert.h>
#include <string.h>
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Host/PosixApi.h"
// WindowsXP needs an inet_ntop implementation
diff --git a/source/Host/common/SoftwareBreakpoint.cpp b/source/Host/common/SoftwareBreakpoint.cpp
deleted file mode 100644
index 353dadf6ce6d..000000000000
--- a/source/Host/common/SoftwareBreakpoint.cpp
+++ /dev/null
@@ -1,350 +0,0 @@
-//===-- SoftwareBreakpoint.cpp ----------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/Host/common/SoftwareBreakpoint.h"
-
-#include "lldb/Host/Debug.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/Status.h"
-
-#include "lldb/Host/common/NativeProcessProtocol.h"
-
-using namespace lldb_private;
-
-// ------------------------------------------------------------------- static
-// members -------------------------------------------------------------------
-
-Status SoftwareBreakpoint::CreateSoftwareBreakpoint(
- NativeProcessProtocol &process, lldb::addr_t addr, size_t size_hint,
- NativeBreakpointSP &breakpoint_sp) {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
- if (log)
- log->Printf("SoftwareBreakpoint::%s addr = 0x%" PRIx64, __FUNCTION__, addr);
-
- // Validate the address.
- if (addr == LLDB_INVALID_ADDRESS)
- return Status("SoftwareBreakpoint::%s invalid load address specified.",
- __FUNCTION__);
-
- // Ask the NativeProcessProtocol subclass to fill in the correct software
- // breakpoint trap for the breakpoint site.
- size_t bp_opcode_size = 0;
- const uint8_t *bp_opcode_bytes = NULL;
- Status error = process.GetSoftwareBreakpointTrapOpcode(
- size_hint, bp_opcode_size, bp_opcode_bytes);
-
- if (error.Fail()) {
- if (log)
- log->Printf("SoftwareBreakpoint::%s failed to retrieve software "
- "breakpoint trap opcode: %s",
- __FUNCTION__, error.AsCString());
- return error;
- }
-
- // Validate size of trap opcode.
- if (bp_opcode_size == 0) {
- if (log)
- log->Printf("SoftwareBreakpoint::%s failed to retrieve any trap opcodes",
- __FUNCTION__);
- return Status("SoftwareBreakpoint::GetSoftwareBreakpointTrapOpcode() "
- "returned zero, unable to get breakpoint trap for address "
- "0x%" PRIx64,
- addr);
- }
-
- if (bp_opcode_size > MAX_TRAP_OPCODE_SIZE) {
- if (log)
- log->Printf("SoftwareBreakpoint::%s cannot support %zu trapcode bytes, "
- "max size is %zu",
- __FUNCTION__, bp_opcode_size, MAX_TRAP_OPCODE_SIZE);
- return Status("SoftwareBreakpoint::GetSoftwareBreakpointTrapOpcode() "
- "returned too many trap opcode bytes: requires %zu but we "
- "only support a max of %zu",
- bp_opcode_size, MAX_TRAP_OPCODE_SIZE);
- }
-
- // Validate that we received opcodes.
- if (!bp_opcode_bytes) {
- if (log)
- log->Printf("SoftwareBreakpoint::%s failed to retrieve trap opcode bytes",
- __FUNCTION__);
- return Status("SoftwareBreakpoint::GetSoftwareBreakpointTrapOpcode() "
- "returned NULL trap opcode bytes, unable to get breakpoint "
- "trap for address 0x%" PRIx64,
- addr);
- }
-
- // Enable the breakpoint.
- uint8_t saved_opcode_bytes[MAX_TRAP_OPCODE_SIZE];
- error = EnableSoftwareBreakpoint(process, addr, bp_opcode_size,
- bp_opcode_bytes, saved_opcode_bytes);
- if (error.Fail()) {
- if (log)
- log->Printf("SoftwareBreakpoint::%s: failed to enable new breakpoint at "
- "0x%" PRIx64 ": %s",
- __FUNCTION__, addr, error.AsCString());
- return error;
- }
-
- if (log)
- log->Printf("SoftwareBreakpoint::%s addr = 0x%" PRIx64 " -- SUCCESS",
- __FUNCTION__, addr);
-
- // Set the breakpoint and verified it was written properly. Now create a
- // breakpoint remover that understands how to undo this breakpoint.
- breakpoint_sp.reset(new SoftwareBreakpoint(process, addr, saved_opcode_bytes,
- bp_opcode_bytes, bp_opcode_size));
- return Status();
-}
-
-Status SoftwareBreakpoint::EnableSoftwareBreakpoint(
- NativeProcessProtocol &process, lldb::addr_t addr, size_t bp_opcode_size,
- const uint8_t *bp_opcode_bytes, uint8_t *saved_opcode_bytes) {
- assert(bp_opcode_size <= MAX_TRAP_OPCODE_SIZE &&
- "bp_opcode_size out of valid range");
- assert(bp_opcode_bytes && "bp_opcode_bytes is NULL");
- assert(saved_opcode_bytes && "saved_opcode_bytes is NULL");
-
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
- if (log)
- log->Printf("SoftwareBreakpoint::%s addr = 0x%" PRIx64, __FUNCTION__, addr);
-
- // Save the original opcodes by reading them so we can restore later.
- size_t bytes_read = 0;
-
- Status error =
- process.ReadMemory(addr, saved_opcode_bytes, bp_opcode_size, bytes_read);
- if (error.Fail()) {
- if (log)
- log->Printf("SoftwareBreakpoint::%s failed to read memory while "
- "attempting to set breakpoint: %s",
- __FUNCTION__, error.AsCString());
- return error;
- }
-
- // Ensure we read as many bytes as we expected.
- if (bytes_read != bp_opcode_size) {
- if (log)
- log->Printf("SoftwareBreakpoint::%s failed to read memory while "
- "attempting to set breakpoint: attempted to read %zu bytes "
- "but only read %zu",
- __FUNCTION__, bp_opcode_size, bytes_read);
- return Status("SoftwareBreakpoint::%s failed to read memory while "
- "attempting to set breakpoint: attempted to read %zu bytes "
- "but only read %zu",
- __FUNCTION__, bp_opcode_size, bytes_read);
- }
-
- // Log what we read.
- if (log) {
- int i = 0;
- for (const uint8_t *read_byte = saved_opcode_bytes;
- read_byte < saved_opcode_bytes + bp_opcode_size; ++read_byte) {
- log->Printf("SoftwareBreakpoint::%s addr = 0x%" PRIx64
- " ovewriting byte index %d (was 0x%hhx)",
- __FUNCTION__, addr, i++, *read_byte);
- }
- }
-
- // Write a software breakpoint in place of the original opcode.
- size_t bytes_written = 0;
- error =
- process.WriteMemory(addr, bp_opcode_bytes, bp_opcode_size, bytes_written);
- if (error.Fail()) {
- if (log)
- log->Printf("SoftwareBreakpoint::%s failed to write memory while "
- "attempting to set breakpoint: %s",
- __FUNCTION__, error.AsCString());
- return error;
- }
-
- // Ensure we wrote as many bytes as we expected.
- if (bytes_written != bp_opcode_size) {
- error.SetErrorStringWithFormat(
- "SoftwareBreakpoint::%s failed write memory while attempting to set "
- "breakpoint: attempted to write %zu bytes but only wrote %zu",
- __FUNCTION__, bp_opcode_size, bytes_written);
- if (log)
- log->PutCString(error.AsCString());
- return error;
- }
-
- uint8_t verify_bp_opcode_bytes[MAX_TRAP_OPCODE_SIZE];
- size_t verify_bytes_read = 0;
- error = process.ReadMemory(addr, verify_bp_opcode_bytes, bp_opcode_size,
- verify_bytes_read);
- if (error.Fail()) {
- if (log)
- log->Printf("SoftwareBreakpoint::%s failed to read memory while "
- "attempting to verify the breakpoint set: %s",
- __FUNCTION__, error.AsCString());
- return error;
- }
-
- // Ensure we read as many verification bytes as we expected.
- if (verify_bytes_read != bp_opcode_size) {
- if (log)
- log->Printf("SoftwareBreakpoint::%s failed to read memory while "
- "attempting to verify breakpoint: attempted to read %zu "
- "bytes but only read %zu",
- __FUNCTION__, bp_opcode_size, verify_bytes_read);
- return Status(
- "SoftwareBreakpoint::%s failed to read memory while "
- "attempting to verify breakpoint: attempted to read %zu bytes "
- "but only read %zu",
- __FUNCTION__, bp_opcode_size, verify_bytes_read);
- }
-
- if (::memcmp(bp_opcode_bytes, verify_bp_opcode_bytes, bp_opcode_size) != 0) {
- if (log)
- log->Printf("SoftwareBreakpoint::%s: verification of software breakpoint "
- "writing failed - trap opcodes not successfully read back "
- "after writing when setting breakpoint at 0x%" PRIx64,
- __FUNCTION__, addr);
- return Status("SoftwareBreakpoint::%s: verification of software breakpoint "
- "writing failed - trap opcodes not successfully read back "
- "after writing when setting breakpoint at 0x%" PRIx64,
- __FUNCTION__, addr);
- }
-
- if (log)
- log->Printf("SoftwareBreakpoint::%s addr = 0x%" PRIx64 " -- SUCCESS",
- __FUNCTION__, addr);
-
- return Status();
-}
-
-// -------------------------------------------------------------------
-// instance-level members
-// -------------------------------------------------------------------
-
-SoftwareBreakpoint::SoftwareBreakpoint(NativeProcessProtocol &process,
- lldb::addr_t addr,
- const uint8_t *saved_opcodes,
- const uint8_t *trap_opcodes,
- size_t opcode_size)
- : NativeBreakpoint(addr), m_process(process), m_saved_opcodes(),
- m_trap_opcodes(), m_opcode_size(opcode_size) {
- assert(opcode_size > 0 && "setting software breakpoint with no trap opcodes");
- assert(opcode_size <= MAX_TRAP_OPCODE_SIZE && "trap opcode size too large");
-
- ::memcpy(m_saved_opcodes, saved_opcodes, opcode_size);
- ::memcpy(m_trap_opcodes, trap_opcodes, opcode_size);
-}
-
-Status SoftwareBreakpoint::DoEnable() {
- return EnableSoftwareBreakpoint(m_process, m_addr, m_opcode_size,
- m_trap_opcodes, m_saved_opcodes);
-}
-
-Status SoftwareBreakpoint::DoDisable() {
- Status error;
- assert(m_addr && (m_addr != LLDB_INVALID_ADDRESS) &&
- "can't remove a software breakpoint for an invalid address");
-
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
- if (log)
- log->Printf("SoftwareBreakpoint::%s addr = 0x%" PRIx64, __FUNCTION__,
- m_addr);
-
- assert((m_opcode_size > 0) &&
- "cannot restore opcodes when there are no opcodes");
-
- if (m_opcode_size > 0) {
- // Clear a software breakpoint instruction
- uint8_t curr_break_op[MAX_TRAP_OPCODE_SIZE];
- bool break_op_found = false;
- assert(m_opcode_size <= sizeof(curr_break_op));
-
- // Read the breakpoint opcode
- size_t bytes_read = 0;
- error =
- m_process.ReadMemory(m_addr, curr_break_op, m_opcode_size, bytes_read);
- if (error.Success() && bytes_read < m_opcode_size) {
- error.SetErrorStringWithFormat(
- "SoftwareBreakpointr::%s addr=0x%" PRIx64
- ": tried to read %zu bytes but only read %zu",
- __FUNCTION__, m_addr, m_opcode_size, bytes_read);
- }
- if (error.Success()) {
- bool verify = false;
- // Make sure the breakpoint opcode exists at this address
- if (::memcmp(curr_break_op, m_trap_opcodes, m_opcode_size) == 0) {
- break_op_found = true;
- // We found a valid breakpoint opcode at this address, now restore the
- // saved opcode.
- size_t bytes_written = 0;
- error = m_process.WriteMemory(m_addr, m_saved_opcodes, m_opcode_size,
- bytes_written);
- if (error.Success() && bytes_written < m_opcode_size) {
- error.SetErrorStringWithFormat(
- "SoftwareBreakpoint::%s addr=0x%" PRIx64
- ": tried to write %zu bytes but only wrote %zu",
- __FUNCTION__, m_addr, m_opcode_size, bytes_written);
- }
- if (error.Success()) {
- verify = true;
- }
- } else {
- error.SetErrorString(
- "Original breakpoint trap is no longer in memory.");
- // Set verify to true and so we can check if the original opcode has
- // already been restored
- verify = true;
- }
-
- if (verify) {
- uint8_t verify_opcode[MAX_TRAP_OPCODE_SIZE];
- assert(m_opcode_size <= sizeof(verify_opcode));
- // Verify that our original opcode made it back to the inferior
-
- size_t verify_bytes_read = 0;
- error = m_process.ReadMemory(m_addr, verify_opcode, m_opcode_size,
- verify_bytes_read);
- if (error.Success() && verify_bytes_read < m_opcode_size) {
- error.SetErrorStringWithFormat(
- "SoftwareBreakpoint::%s addr=0x%" PRIx64
- ": tried to read %zu verification bytes but only read %zu",
- __FUNCTION__, m_addr, m_opcode_size, verify_bytes_read);
- }
- if (error.Success()) {
- // compare the memory we just read with the original opcode
- if (::memcmp(m_saved_opcodes, verify_opcode, m_opcode_size) == 0) {
- // SUCCESS
- if (log) {
- int i = 0;
- for (const uint8_t *verify_byte = verify_opcode;
- verify_byte < verify_opcode + m_opcode_size; ++verify_byte) {
- log->Printf("SoftwareBreakpoint::%s addr = 0x%" PRIx64
- " replaced byte index %d with 0x%hhx",
- __FUNCTION__, m_addr, i++, *verify_byte);
- }
- log->Printf("SoftwareBreakpoint::%s addr = 0x%" PRIx64
- " -- SUCCESS",
- __FUNCTION__, m_addr);
- }
- return error;
- } else {
- if (break_op_found)
- error.SetErrorString("Failed to restore original opcode.");
- }
- } else
- error.SetErrorString("Failed to read memory to verify that "
- "breakpoint trap was restored.");
- }
- }
- }
-
- if (log && error.Fail())
- log->Printf("SoftwareBreakpoint::%s addr = 0x%" PRIx64 " -- FAILED: %s",
- __FUNCTION__, m_addr, error.AsCString());
- return error;
-}
-
-bool SoftwareBreakpoint::IsSoftwareBreakpoint() const { return true; }
diff --git a/source/Host/common/StringConvert.cpp b/source/Host/common/StringConvert.cpp
index b4171437b7e2..8f4e1956fc28 100644
--- a/source/Host/common/StringConvert.cpp
+++ b/source/Host/common/StringConvert.cpp
@@ -7,12 +7,8 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
#include <stdlib.h>
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Host/StringConvert.h"
namespace lldb_private {
diff --git a/source/Host/common/Symbols.cpp b/source/Host/common/Symbols.cpp
index d7e0c13112aa..ed1677cbcb58 100644
--- a/source/Host/common/Symbols.cpp
+++ b/source/Host/common/Symbols.cpp
@@ -16,7 +16,6 @@
#include "lldb/Utility/DataBuffer.h"
#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/Log.h"
-#include "lldb/Utility/SafeMachO.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/Timer.h"
#include "lldb/Utility/UUID.h"
@@ -29,7 +28,6 @@ typedef int cpu_subtype_t;
using namespace lldb;
using namespace lldb_private;
-using namespace llvm::MachO;
#if defined(__APPLE__)
@@ -67,96 +65,133 @@ static bool FileAtPathContainsArchAndUUID(const FileSpec &file_fspec,
return false;
}
+// Given a binary exec_fspec, and a ModuleSpec with an architecture/uuid,
+// return true if there is a matching dSYM bundle next to the exec_fspec,
+// and return that value in dsym_fspec.
+// If there is a .dSYM.yaa compressed archive next to the exec_fspec,
+// call through Symbols::DownloadObjectAndSymbolFile to download the
+// expanded/uncompressed dSYM and return that filepath in dsym_fspec.
+
+static bool LookForDsymNextToExecutablePath(const ModuleSpec &mod_spec,
+ const FileSpec &exec_fspec,
+ FileSpec &dsym_fspec) {
+ ConstString filename = exec_fspec.GetFilename();
+ FileSpec dsym_directory = exec_fspec;
+ dsym_directory.RemoveLastPathComponent();
+
+ std::string dsym_filename = filename.AsCString();
+ dsym_filename += ".dSYM";
+ dsym_directory.AppendPathComponent(dsym_filename);
+ dsym_directory.AppendPathComponent("Contents");
+ dsym_directory.AppendPathComponent("Resources");
+ dsym_directory.AppendPathComponent("DWARF");
+
+ if (FileSystem::Instance().Exists(dsym_directory)) {
+
+ // See if the binary name exists in the dSYM DWARF
+ // subdir.
+ dsym_fspec = dsym_directory;
+ dsym_fspec.AppendPathComponent(filename.AsCString());
+ if (FileSystem::Instance().Exists(dsym_fspec) &&
+ FileAtPathContainsArchAndUUID(dsym_fspec, mod_spec.GetArchitecturePtr(),
+ mod_spec.GetUUIDPtr())) {
+ return true;
+ }
+
+ // See if we have "../CF.framework" - so we'll look for
+ // CF.framework.dSYM/Contents/Resources/DWARF/CF
+ // We need to drop the last suffix after '.' to match
+ // 'CF' in the DWARF subdir.
+ std::string binary_name (filename.AsCString());
+ auto last_dot = binary_name.find_last_of('.');
+ if (last_dot != std::string::npos) {
+ binary_name.erase(last_dot);
+ dsym_fspec = dsym_directory;
+ dsym_fspec.AppendPathComponent(binary_name);
+ if (FileSystem::Instance().Exists(dsym_fspec) &&
+ FileAtPathContainsArchAndUUID(dsym_fspec,
+ mod_spec.GetArchitecturePtr(),
+ mod_spec.GetUUIDPtr())) {
+ return true;
+ }
+ }
+ }
+
+ // See if we have a .dSYM.yaa next to this executable path.
+ FileSpec dsym_yaa_fspec = exec_fspec;
+ dsym_yaa_fspec.RemoveLastPathComponent();
+ std::string dsym_yaa_filename = filename.AsCString();
+ dsym_yaa_filename += ".dSYM.yaa";
+ dsym_yaa_fspec.AppendPathComponent(dsym_yaa_filename);
+
+ if (FileSystem::Instance().Exists(dsym_yaa_fspec)) {
+ ModuleSpec mutable_mod_spec = mod_spec;
+ if (Symbols::DownloadObjectAndSymbolFile(mutable_mod_spec, true) &&
+ FileSystem::Instance().Exists(mutable_mod_spec.GetSymbolFileSpec())) {
+ dsym_fspec = mutable_mod_spec.GetSymbolFileSpec();
+ return true;
+ }
+ }
+
+ return false;
+}
+
+// Given a ModuleSpec with a FileSpec and optionally uuid/architecture
+// filled in, look for a .dSYM bundle next to that binary. Returns true
+// if a .dSYM bundle is found, and that path is returned in the dsym_fspec
+// FileSpec.
+//
+// This routine looks a few directory layers above the given exec_path -
+// exec_path might be /System/Library/Frameworks/CF.framework/CF and the
+// dSYM might be /System/Library/Frameworks/CF.framework.dSYM.
+//
+// If there is a .dSYM.yaa compressed archive found next to the binary,
+// we'll call DownloadObjectAndSymbolFile to expand it into a plain .dSYM
+
static bool LocateDSYMInVincinityOfExecutable(const ModuleSpec &module_spec,
FileSpec &dsym_fspec) {
Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
+ const FileSpec &exec_fspec = module_spec.GetFileSpec();
if (exec_fspec) {
- char path[PATH_MAX];
- if (exec_fspec->GetPath(path, sizeof(path))) {
- // Make sure the module isn't already just a dSYM file...
- if (strcasestr(path, ".dSYM/Contents/Resources/DWARF") == NULL) {
+ if (::LookForDsymNextToExecutablePath (module_spec, exec_fspec, dsym_fspec)) {
if (log) {
- if (module_spec.GetUUIDPtr() && module_spec.GetUUIDPtr()->IsValid()) {
- log->Printf(
- "Searching for dSYM bundle next to executable %s, UUID %s",
- path, module_spec.GetUUIDPtr()->GetAsString().c_str());
- } else {
- log->Printf("Searching for dSYM bundle next to executable %s",
- path);
- }
+ log->Printf("dSYM with matching UUID & arch found at %s", dsym_fspec.GetPath().c_str());
}
- ::strncat(path, ".dSYM/Contents/Resources/DWARF/",
- sizeof(path) - strlen(path) - 1);
- ::strncat(path, exec_fspec->GetFilename().AsCString(),
- sizeof(path) - strlen(path) - 1);
-
- dsym_fspec.SetFile(path, false, FileSpec::Style::native);
-
- ModuleSpecList module_specs;
- ModuleSpec matched_module_spec;
- if (dsym_fspec.Exists() &&
- FileAtPathContainsArchAndUUID(dsym_fspec,
- module_spec.GetArchitecturePtr(),
- module_spec.GetUUIDPtr())) {
- if (log) {
- log->Printf("dSYM with matching UUID & arch found at %s", path);
- }
- return true;
- } else {
- FileSpec parent_dirs = exec_fspec;
-
- // Remove the binary name from the FileSpec
- parent_dirs.RemoveLastPathComponent();
-
- // Add a ".dSYM" name to each directory component of the path,
- // stripping off components. e.g. we may have a binary like
- // /S/L/F/Foundation.framework/Versions/A/Foundation and
- // /S/L/F/Foundation.framework.dSYM
- //
- // so we'll need to start with
- // /S/L/F/Foundation.framework/Versions/A, add the .dSYM part to the
- // "A", and if that doesn't exist, strip off the "A" and try it again
- // with "Versions", etc., until we find a dSYM bundle or we've
- // stripped off enough path components that there's no need to
- // continue.
-
- for (int i = 0; i < 4; i++) {
- // Does this part of the path have a "." character - could it be a
- // bundle's top level directory?
- const char *fn = parent_dirs.GetFilename().AsCString();
- if (fn == nullptr)
- break;
- if (::strchr(fn, '.') != nullptr) {
- dsym_fspec = parent_dirs;
- dsym_fspec.RemoveLastPathComponent();
-
- // If the current directory name is "Foundation.framework", see
- // if
- // "Foundation.framework.dSYM/Contents/Resources/DWARF/Foundation"
- // exists & has the right uuid.
- std::string dsym_fn = fn;
- dsym_fn += ".dSYM";
- dsym_fspec.AppendPathComponent(dsym_fn.c_str());
- dsym_fspec.AppendPathComponent("Contents");
- dsym_fspec.AppendPathComponent("Resources");
- dsym_fspec.AppendPathComponent("DWARF");
- dsym_fspec.AppendPathComponent(
- exec_fspec->GetFilename().AsCString());
- if (dsym_fspec.Exists() &&
- FileAtPathContainsArchAndUUID(
- dsym_fspec, module_spec.GetArchitecturePtr(),
- module_spec.GetUUIDPtr())) {
- if (log) {
- log->Printf("dSYM with matching UUID & arch found at %s",
- dsym_fspec.GetPath().c_str());
- }
- return true;
- }
+ return true;
+ } else {
+ FileSpec parent_dirs = exec_fspec;
+
+ // Remove the binary name from the FileSpec
+ parent_dirs.RemoveLastPathComponent();
+
+ // Add a ".dSYM" name to each directory component of the path,
+ // stripping off components. e.g. we may have a binary like
+ // /S/L/F/Foundation.framework/Versions/A/Foundation and
+ // /S/L/F/Foundation.framework.dSYM
+ //
+ // so we'll need to start with
+ // /S/L/F/Foundation.framework/Versions/A, add the .dSYM part to the
+ // "A", and if that doesn't exist, strip off the "A" and try it again
+ // with "Versions", etc., until we find a dSYM bundle or we've
+ // stripped off enough path components that there's no need to
+ // continue.
+
+ for (int i = 0; i < 4; i++) {
+ // Does this part of the path have a "." character - could it be a
+ // bundle's top level directory?
+ const char *fn = parent_dirs.GetFilename().AsCString();
+ if (fn == nullptr)
+ break;
+ if (::strchr(fn, '.') != nullptr) {
+ if (::LookForDsymNextToExecutablePath (module_spec, parent_dirs, dsym_fspec)) {
+ if (log) {
+ log->Printf("dSYM with matching UUID & arch found at %s",
+ dsym_fspec.GetPath().c_str());
}
- parent_dirs.RemoveLastPathComponent();
+ return true;
}
}
+ parent_dirs.RemoveLastPathComponent();
}
}
}
@@ -164,7 +199,7 @@ static bool LocateDSYMInVincinityOfExecutable(const ModuleSpec &module_spec,
return false;
}
-FileSpec LocateExecutableSymbolFileDsym(const ModuleSpec &module_spec) {
+static FileSpec LocateExecutableSymbolFileDsym(const ModuleSpec &module_spec) {
const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
const ArchSpec *arch = module_spec.GetArchitecturePtr();
const UUID *uuid = module_spec.GetUUIDPtr();
@@ -180,7 +215,7 @@ FileSpec LocateExecutableSymbolFileDsym(const ModuleSpec &module_spec) {
ModuleSpec dsym_module_spec;
// First try and find the dSYM in the same directory as the executable or in
// an appropriate parent directory
- if (LocateDSYMInVincinityOfExecutable(module_spec, symbol_fspec) == false) {
+ if (!LocateDSYMInVincinityOfExecutable(module_spec, symbol_fspec)) {
// We failed to easily find the dSYM above, so use DebugSymbols
LocateMacOSXFilesUsingDebugSymbols(module_spec, dsym_module_spec);
} else {
@@ -212,9 +247,12 @@ ModuleSpec Symbols::LocateExecutableObjectFile(const ModuleSpec &module_spec) {
return result;
}
+// Keep "symbols.enable-external-lookup" description in sync with this function.
+
FileSpec Symbols::LocateExecutableSymbolFile(const ModuleSpec &module_spec) {
FileSpec symbol_file_spec = module_spec.GetSymbolFileSpec();
- if (symbol_file_spec.IsAbsolute() && symbol_file_spec.Exists())
+ if (symbol_file_spec.IsAbsolute() &&
+ FileSystem::Instance().Exists(symbol_file_spec))
return symbol_file_spec;
const char *symbol_filename = symbol_file_spec.GetFilename().AsCString();
@@ -225,25 +263,42 @@ FileSpec Symbols::LocateExecutableSymbolFile(const ModuleSpec &module_spec) {
// Add module directory.
FileSpec module_file_spec = module_spec.GetFileSpec();
// We keep the unresolved pathname if it fails.
- FileSystem::ResolveSymbolicLink(module_file_spec, module_file_spec);
+ FileSystem::Instance().ResolveSymbolicLink(module_file_spec, module_file_spec);
const ConstString &file_dir = module_file_spec.GetDirectory();
- debug_file_search_paths.AppendIfUnique(
- FileSpec(file_dir.AsCString("."), true));
+ {
+ FileSpec file_spec(file_dir.AsCString("."));
+ FileSystem::Instance().Resolve(file_spec);
+ debug_file_search_paths.AppendIfUnique(file_spec);
+ }
+
+ if (ModuleList::GetGlobalModuleListProperties().GetEnableExternalLookup()) {
- // Add current working directory.
- debug_file_search_paths.AppendIfUnique(FileSpec(".", true));
+ // Add current working directory.
+ {
+ FileSpec file_spec(".");
+ FileSystem::Instance().Resolve(file_spec);
+ debug_file_search_paths.AppendIfUnique(file_spec);
+ }
#ifndef _WIN32
#if defined(__NetBSD__)
- // Add /usr/libdata/debug directory.
- debug_file_search_paths.AppendIfUnique(
- FileSpec("/usr/libdata/debug", true));
+ // Add /usr/libdata/debug directory.
+ {
+ FileSpec file_spec("/usr/libdata/debug");
+ FileSystem::Instance().Resolve(file_spec);
+ debug_file_search_paths.AppendIfUnique(file_spec);
+ }
#else
- // Add /usr/lib/debug directory.
- debug_file_search_paths.AppendIfUnique(FileSpec("/usr/lib/debug", true));
+ // Add /usr/lib/debug directory.
+ {
+ FileSpec file_spec("/usr/lib/debug");
+ FileSystem::Instance().Resolve(file_spec);
+ debug_file_search_paths.AppendIfUnique(file_spec);
+ }
#endif
#endif // _WIN32
+ }
std::string uuid_str;
const UUID &module_uuid = module_spec.GetUUID();
@@ -260,8 +315,8 @@ FileSpec Symbols::LocateExecutableSymbolFile(const ModuleSpec &module_spec) {
size_t num_directories = debug_file_search_paths.GetSize();
for (size_t idx = 0; idx < num_directories; ++idx) {
FileSpec dirspec = debug_file_search_paths.GetFileSpecAtIndex(idx);
- dirspec.ResolvePath();
- if (!llvm::sys::fs::is_directory(dirspec.GetPath()))
+ FileSystem::Instance().Resolve(dirspec);
+ if (!FileSystem::Instance().IsDirectory(dirspec))
continue;
std::vector<std::string> files;
@@ -279,13 +334,14 @@ FileSpec Symbols::LocateExecutableSymbolFile(const ModuleSpec &module_spec) {
const uint32_t num_files = files.size();
for (size_t idx_file = 0; idx_file < num_files; ++idx_file) {
const std::string &filename = files[idx_file];
- FileSpec file_spec(filename, true);
+ FileSpec file_spec(filename);
+ FileSystem::Instance().Resolve(file_spec);
if (llvm::sys::fs::equivalent(file_spec.GetPath(),
module_file_spec.GetPath()))
continue;
- if (file_spec.Exists()) {
+ if (FileSystem::Instance().Exists(file_spec)) {
lldb_private::ModuleSpecList specs;
const size_t num_specs =
ObjectFile::GetModuleSpecifications(file_spec, 0, 0, specs);
diff --git a/source/Host/common/TaskPool.cpp b/source/Host/common/TaskPool.cpp
index c54b9a8ae56b..ba1362a46f33 100644
--- a/source/Host/common/TaskPool.cpp
+++ b/source/Host/common/TaskPool.cpp
@@ -10,9 +10,9 @@
#include "lldb/Host/TaskPool.h"
#include "lldb/Host/ThreadLauncher.h"
-#include <cstdint> // for uint32_t
-#include <queue> // for queue
-#include <thread> // for thread
+#include <cstdint>
+#include <queue>
+#include <thread>
namespace lldb_private {
diff --git a/source/Host/common/XML.cpp b/source/Host/common/XML.cpp
index 7468a3d7ac65..967a294cbf72 100644
--- a/source/Host/common/XML.cpp
+++ b/source/Host/common/XML.cpp
@@ -201,8 +201,7 @@ void XMLNode::ForEachAttribute(AttributeCallback const &callback) const {
llvm::StringRef attr_value;
if (child->content)
attr_value = llvm::StringRef((const char *)child->content);
- if (callback(llvm::StringRef((const char *)attr->name), attr_value) ==
- false)
+ if (!callback(llvm::StringRef((const char *)attr->name), attr_value))
return;
}
}
@@ -217,7 +216,7 @@ void XMLNode::ForEachSiblingNode(NodeCallback const &callback) const {
if (IsValid()) {
// iterate through all siblings
for (xmlNodePtr node = m_node; node; node = node->next) {
- if (callback(XMLNode(node)) == false)
+ if (!callback(XMLNode(node)))
return;
}
}
@@ -234,7 +233,7 @@ void XMLNode::ForEachSiblingElement(NodeCallback const &callback) const {
if (node->type != XML_ELEMENT_NODE)
continue;
- if (callback(XMLNode(node)) == false)
+ if (!callback(XMLNode(node)))
return;
}
}
@@ -263,7 +262,7 @@ void XMLNode::ForEachSiblingElementWithName(
// ignore this one
}
- if (callback(XMLNode(node)) == false)
+ if (!callback(XMLNode(node)))
return;
}
}
@@ -439,7 +438,7 @@ XMLNode ApplePropertyList::GetValueNode(const char *key) const {
"key", [key, &value_node](const XMLNode &key_node) -> bool {
std::string key_name;
if (key_node.GetElementText(key_name)) {
- if (key_name.compare(key) == 0) {
+ if (key_name == key) {
value_node = key_node.GetSibling();
while (value_node && !value_node.IsElement())
value_node = value_node.GetSibling();
diff --git a/source/Host/freebsd/Host.cpp b/source/Host/freebsd/Host.cpp
index 87552bc2a27e..7bf959aee982 100644
--- a/source/Host/freebsd/Host.cpp
+++ b/source/Host/freebsd/Host.cpp
@@ -8,7 +8,6 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
#include <sys/types.h>
#include <sys/exec.h>
@@ -23,9 +22,6 @@
#include <execinfo.h>
#include <stdio.h>
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Target/Process.h"
@@ -75,11 +71,9 @@ GetFreeBSDProcessArgs(const ProcessInstanceInfoMatch *match_info_ptr,
size_t pathname_len = sizeof(pathname);
mib[2] = KERN_PROC_PATHNAME;
if (::sysctl(mib, 4, pathname, &pathname_len, NULL, 0) == 0)
- process_info.GetExecutableFile().SetFile(pathname, false,
- FileSpec::Style::native);
+ process_info.GetExecutableFile().SetFile(pathname, FileSpec::Style::native);
else
- process_info.GetExecutableFile().SetFile(cstr, false,
- FileSpec::Style::native);
+ process_info.GetExecutableFile().SetFile(cstr, FileSpec::Style::native);
if (!(match_info_ptr == NULL ||
NameMatches(process_info.GetExecutableFile().GetFilename().GetCString(),
diff --git a/source/Host/freebsd/HostInfoFreeBSD.cpp b/source/Host/freebsd/HostInfoFreeBSD.cpp
index 18eae3eb7606..d123936b3668 100644
--- a/source/Host/freebsd/HostInfoFreeBSD.cpp
+++ b/source/Host/freebsd/HostInfoFreeBSD.cpp
@@ -69,7 +69,7 @@ FileSpec HostInfoFreeBSD::GetProgramFileSpec() {
if (sysctl(exe_path_mib, 4, NULL, &exe_path_size, NULL, 0) == 0) {
char *exe_path = new char[exe_path_size];
if (sysctl(exe_path_mib, 4, exe_path, &exe_path_size, NULL, 0) == 0)
- g_program_filespec.SetFile(exe_path, false, FileSpec::Style::native);
+ g_program_filespec.SetFile(exe_path, FileSpec::Style::native);
delete[] exe_path;
}
}
diff --git a/source/Host/linux/Host.cpp b/source/Host/linux/Host.cpp
index 1a0eb767eb34..bd596f8cbfe0 100644
--- a/source/Host/linux/Host.cpp
+++ b/source/Host/linux/Host.cpp
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
@@ -18,20 +17,17 @@
#include <sys/utsname.h>
#include <unistd.h>
-// C++ Includes
-// Other libraries and framework includes
#include "llvm/Object/ELF.h"
#include "llvm/Support/ScopedPrinter.h"
-// Project includes
#include "lldb/Target/Process.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Status.h"
+#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/linux/Support.h"
-#include "lldb/Utility/DataBufferLLVM.h"
#include "lldb/Utility/DataExtractor.h"
using namespace lldb;
@@ -125,7 +121,7 @@ static bool IsDirNumeric(const char *dname) {
static ArchSpec GetELFProcessCPUType(llvm::StringRef exe_path) {
Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- auto buffer_sp = DataBufferLLVM::CreateSliceFromPath(exe_path, 0x20, 0);
+ auto buffer_sp = FileSystem::Instance().CreateDataBuffer(exe_path, 0x20, 0);
if (!buffer_sp)
return ArchSpec();
@@ -190,8 +186,7 @@ static bool GetProcessAndStatInfo(::pid_t pid,
return false;
process_info.SetProcessID(pid);
- process_info.GetExecutableFile().SetFile(PathRef, false,
- FileSpec::Style::native);
+ process_info.GetExecutableFile().SetFile(PathRef, FileSpec::Style::native);
llvm::StringRef Rest = Environ->getBuffer();
while (!Rest.empty()) {
diff --git a/source/Host/linux/HostInfoLinux.cpp b/source/Host/linux/HostInfoLinux.cpp
index 1d95010e2f73..f5a6b2c97a0d 100644
--- a/source/Host/linux/HostInfoLinux.cpp
+++ b/source/Host/linux/HostInfoLinux.cpp
@@ -7,8 +7,9 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/Host/Config.h"
#include "lldb/Host/linux/HostInfoLinux.h"
+#include "lldb/Host/Config.h"
+#include "lldb/Host/FileSystem.h"
#include "lldb/Utility/Log.h"
#include "llvm/Support/Threading.h"
@@ -20,7 +21,7 @@
#include <unistd.h>
#include <algorithm>
-#include <mutex> // std::once
+#include <mutex>
using namespace lldb_private;
@@ -170,7 +171,7 @@ FileSpec HostInfoLinux::GetProgramFileSpec() {
ssize_t len = readlink("/proc/self/exe", exe_path, sizeof(exe_path) - 1);
if (len > 0) {
exe_path[len] = 0;
- g_program_filespec.SetFile(exe_path, false, FileSpec::Style::native);
+ g_program_filespec.SetFile(exe_path, FileSpec::Style::native);
}
}
@@ -179,14 +180,15 @@ FileSpec HostInfoLinux::GetProgramFileSpec() {
bool HostInfoLinux::ComputeSupportExeDirectory(FileSpec &file_spec) {
if (HostInfoPosix::ComputeSupportExeDirectory(file_spec) &&
- file_spec.IsAbsolute() && file_spec.Exists())
+ file_spec.IsAbsolute() && FileSystem::Instance().Exists(file_spec))
return true;
file_spec.GetDirectory() = GetProgramFileSpec().GetDirectory();
return !file_spec.GetDirectory().IsEmpty();
}
bool HostInfoLinux::ComputeSystemPluginsDirectory(FileSpec &file_spec) {
- FileSpec temp_file("/usr/lib" LLDB_LIBDIR_SUFFIX "/lldb/plugins", true);
+ FileSpec temp_file("/usr/lib" LLDB_LIBDIR_SUFFIX "/lldb/plugins");
+ FileSystem::Instance().Resolve(temp_file);
file_spec.GetDirectory().SetCString(temp_file.GetPath().c_str());
return true;
}
diff --git a/source/Host/macosx/Symbols.cpp b/source/Host/macosx/Symbols.cpp
index b01c48e51d90..980bbc34449c 100644
--- a/source/Host/macosx/Symbols.cpp
+++ b/source/Host/macosx/Symbols.cpp
@@ -9,16 +9,11 @@
#include "lldb/Host/Symbols.h"
-// C Includes
-#include "lldb/Utility/SafeMachO.h"
#include <dirent.h>
#include <pwd.h>
-// C++ Includes
-// Other libraries and framework includes
#include <CoreFoundation/CoreFoundation.h>
-// Project includes
#include "Host/macosx/cfcpp/CFCBundle.h"
#include "Host/macosx/cfcpp/CFCData.h"
#include "Host/macosx/cfcpp/CFCReleaser.h"
@@ -42,7 +37,6 @@
using namespace lldb;
using namespace lldb_private;
-using namespace llvm::MachO;
#if !defined(__arm__) && !defined(__arm64__) && \
!defined(__aarch64__) // No DebugSymbols on the iOS devices
@@ -107,9 +101,11 @@ int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec,
"UUID %s -- looking for the dSYM",
path, uuid->GetAsString().c_str());
}
- FileSpec dsym_filespec(path, path[0] == '~');
+ FileSpec dsym_filespec(path);
+ if (path[0] == '~')
+ FileSystem::Instance().Resolve(dsym_filespec);
- if (llvm::sys::fs::is_directory(dsym_filespec.GetPath())) {
+ if (FileSystem::Instance().IsDirectory(dsym_filespec)) {
dsym_filespec =
Symbols::FindSymbolFileInBundle(dsym_filespec, uuid, arch);
++items_found;
@@ -148,8 +144,10 @@ int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec,
path, uuid->GetAsString().c_str());
}
++items_found;
- FileSpec exec_filespec(path, path[0] == '~');
- if (exec_filespec.Exists()) {
+ FileSpec exec_filespec(path);
+ if (path[0] == '~')
+ FileSystem::Instance().Resolve(exec_filespec);
+ if (FileSystem::Instance().Exists(exec_filespec)) {
success = true;
return_module_spec.GetFileSpec() = exec_filespec;
}
@@ -169,7 +167,8 @@ int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec,
"bundle with name with name %s",
path);
}
- FileSpec file_spec(path, true);
+ FileSpec file_spec(path);
+ FileSystem::Instance().Resolve(file_spec);
ModuleSpecList module_specs;
ModuleSpec matched_module_spec;
using namespace llvm::sys::fs;
@@ -184,7 +183,8 @@ int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec,
if (::CFURLGetFileSystemRepresentation(bundle_exe_url.get(),
true, (UInt8 *)path,
sizeof(path) - 1)) {
- FileSpec bundle_exe_file_spec(path, true);
+ FileSpec bundle_exe_file_spec(path);
+ FileSystem::Instance().Resolve(bundle_exe_file_spec);
if (ObjectFile::GetModuleSpecifications(
bundle_exe_file_spec, 0, 0, module_specs) &&
module_specs.FindMatchingModuleSpec(
@@ -309,8 +309,8 @@ static bool GetModuleSpecInfoFromUUIDDictionary(CFDictionaryRef uuid_dict,
(CFDictionaryRef)uuid_dict, CFSTR("DBGSymbolRichExecutable"));
if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
if (CFCString::FileSystemRepresentation(cf_str, str)) {
- module_spec.GetFileSpec().SetFile(str.c_str(), true,
- FileSpec::Style::native);
+ module_spec.GetFileSpec().SetFile(str.c_str(), FileSpec::Style::native);
+ FileSystem::Instance().Resolve(module_spec.GetFileSpec());
if (log) {
log->Printf(
"From dsymForUUID plist: Symbol rich executable is at '%s'",
@@ -323,8 +323,9 @@ static bool GetModuleSpecInfoFromUUIDDictionary(CFDictionaryRef uuid_dict,
CFSTR("DBGDSYMPath"));
if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
if (CFCString::FileSystemRepresentation(cf_str, str)) {
- module_spec.GetSymbolFileSpec().SetFile(str.c_str(), true,
+ module_spec.GetSymbolFileSpec().SetFile(str.c_str(),
FileSpec::Style::native);
+ FileSystem::Instance().Resolve(module_spec.GetFileSpec());
success = true;
if (log) {
log->Printf("From dsymForUUID plist: dSYM is at '%s'", str.c_str());
@@ -398,12 +399,13 @@ static bool GetModuleSpecInfoFromUUIDDictionary(CFDictionaryRef uuid_dict,
// DBGSourcePath values (the "values" half of key-value path pairs)
// were wrong. Ignore them and use the universal DBGSourcePath
// string from earlier.
- if (new_style_source_remapping_dictionary == true &&
+ if (new_style_source_remapping_dictionary &&
!original_DBGSourcePath_value.empty()) {
DBGSourcePath = original_DBGSourcePath_value;
}
if (DBGSourcePath[0] == '~') {
- FileSpec resolved_source_path(DBGSourcePath.c_str(), true);
+ FileSpec resolved_source_path(DBGSourcePath.c_str());
+ FileSystem::Instance().Resolve(resolved_source_path);
DBGSourcePath = resolved_source_path.GetPath();
}
// With version 2 of DBGSourcePathRemapping, we can chop off the
@@ -414,8 +416,8 @@ static bool GetModuleSpecInfoFromUUIDDictionary(CFDictionaryRef uuid_dict,
ConstString(DBGBuildSourcePath.c_str()),
ConstString(DBGSourcePath.c_str()), true);
if (do_truncate_remapping_names) {
- FileSpec build_path(DBGBuildSourcePath.c_str(), false);
- FileSpec source_path(DBGSourcePath.c_str(), false);
+ FileSpec build_path(DBGBuildSourcePath.c_str());
+ FileSpec source_path(DBGSourcePath.c_str());
build_path.RemoveLastPathComponent();
build_path.RemoveLastPathComponent();
source_path.RemoveLastPathComponent();
@@ -451,7 +453,8 @@ static bool GetModuleSpecInfoFromUUIDDictionary(CFDictionaryRef uuid_dict,
if (!DBGBuildSourcePath.empty() && !DBGSourcePath.empty()) {
if (DBGSourcePath[0] == '~') {
- FileSpec resolved_source_path(DBGSourcePath.c_str(), true);
+ FileSpec resolved_source_path(DBGSourcePath.c_str());
+ FileSystem::Instance().Resolve(resolved_source_path);
DBGSourcePath = resolved_source_path.GetPath();
}
module_spec.GetSourceMappingList().Append(
@@ -472,7 +475,7 @@ bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec,
// it once per lldb run and cache the result.
static bool g_have_checked_for_dbgshell_command = false;
static const char *g_dbgshell_command = NULL;
- if (g_have_checked_for_dbgshell_command == false) {
+ if (!g_have_checked_for_dbgshell_command) {
g_have_checked_for_dbgshell_command = true;
CFTypeRef defaults_setting = CFPreferencesCopyAppValue(
CFSTR("DBGShellCommands"), CFSTR("com.apple.DebugSymbols"));
@@ -492,11 +495,12 @@ bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec,
// When g_dbgshell_command is NULL, the user has not enabled the use of an
// external program to find the symbols, don't run it for them.
- if (force_lookup == false && g_dbgshell_command == NULL) {
+ if (!force_lookup && g_dbgshell_command == NULL) {
return false;
}
- if (uuid_ptr || (file_spec_ptr && file_spec_ptr->Exists())) {
+ if (uuid_ptr ||
+ (file_spec_ptr && FileSystem::Instance().Exists(*file_spec_ptr))) {
static bool g_located_dsym_for_uuid_exe = false;
static bool g_dsym_for_uuid_exe_exists = false;
static char g_dsym_for_uuid_exe_path[PATH_MAX];
@@ -506,15 +510,18 @@ bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec,
getenv("LLDB_APPLE_DSYMFORUUID_EXECUTABLE");
FileSpec dsym_for_uuid_exe_spec;
if (dsym_for_uuid_exe_path_cstr) {
- dsym_for_uuid_exe_spec.SetFile(dsym_for_uuid_exe_path_cstr, true,
+ dsym_for_uuid_exe_spec.SetFile(dsym_for_uuid_exe_path_cstr,
FileSpec::Style::native);
- g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists();
+ FileSystem::Instance().Resolve(dsym_for_uuid_exe_spec);
+ g_dsym_for_uuid_exe_exists =
+ FileSystem::Instance().Exists(dsym_for_uuid_exe_spec);
}
if (!g_dsym_for_uuid_exe_exists) {
- dsym_for_uuid_exe_spec.SetFile("/usr/local/bin/dsymForUUID", false,
+ dsym_for_uuid_exe_spec.SetFile("/usr/local/bin/dsymForUUID",
FileSpec::Style::native);
- g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists();
+ g_dsym_for_uuid_exe_exists =
+ FileSystem::Instance().Exists(dsym_for_uuid_exe_spec);
if (!g_dsym_for_uuid_exe_exists) {
long bufsize;
if ((bufsize = sysconf(_SC_GETPW_R_SIZE_MAX)) != -1) {
@@ -527,17 +534,20 @@ bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec,
tilde_rc && tilde_rc->pw_dir) {
std::string dsymforuuid_path(tilde_rc->pw_dir);
dsymforuuid_path += "/bin/dsymForUUID";
- dsym_for_uuid_exe_spec.SetFile(dsymforuuid_path.c_str(), false,
+ dsym_for_uuid_exe_spec.SetFile(dsymforuuid_path.c_str(),
FileSpec::Style::native);
- g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists();
+ g_dsym_for_uuid_exe_exists =
+ FileSystem::Instance().Exists(dsym_for_uuid_exe_spec);
}
}
}
}
if (!g_dsym_for_uuid_exe_exists && g_dbgshell_command != NULL) {
- dsym_for_uuid_exe_spec.SetFile(g_dbgshell_command, true,
+ dsym_for_uuid_exe_spec.SetFile(g_dbgshell_command,
FileSpec::Style::native);
- g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists();
+ FileSystem::Instance().Resolve(dsym_for_uuid_exe_spec);
+ g_dsym_for_uuid_exe_exists =
+ FileSystem::Instance().Exists(dsym_for_uuid_exe_spec);
}
if (g_dsym_for_uuid_exe_exists)
diff --git a/source/Host/macosx/cfcpp/CFCMutableArray.cpp b/source/Host/macosx/cfcpp/CFCMutableArray.cpp
index 0b6258315eb0..f426e9c13a59 100644
--- a/source/Host/macosx/cfcpp/CFCMutableArray.cpp
+++ b/source/Host/macosx/cfcpp/CFCMutableArray.cpp
@@ -88,7 +88,7 @@ bool CFCMutableArray::SetValueAtIndex(CFIndex idx, const void *value) {
bool CFCMutableArray::AppendValue(const void *value, bool can_create) {
CFMutableArrayRef array = get();
if (array == NULL) {
- if (can_create == false)
+ if (!can_create)
return false;
array =
::CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
@@ -106,7 +106,7 @@ bool CFCMutableArray::AppendCStringAsCFString(const char *s,
bool can_create) {
CFMutableArrayRef array = get();
if (array == NULL) {
- if (can_create == false)
+ if (!can_create)
return false;
array =
::CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
@@ -124,7 +124,7 @@ bool CFCMutableArray::AppendFileSystemRepresentationAsCFString(
const char *s, bool can_create) {
CFMutableArrayRef array = get();
if (array == NULL) {
- if (can_create == false)
+ if (!can_create)
return false;
array =
::CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
diff --git a/source/Host/macosx/cfcpp/CFCMutableSet.cpp b/source/Host/macosx/cfcpp/CFCMutableSet.cpp
index c339e950674b..b8bf81e1b52e 100644
--- a/source/Host/macosx/cfcpp/CFCMutableSet.cpp
+++ b/source/Host/macosx/cfcpp/CFCMutableSet.cpp
@@ -9,10 +9,6 @@
#include "CFCMutableSet.h"
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
//----------------------------------------------------------------------
// CFCString constructor
@@ -64,7 +60,7 @@ const void *CFCMutableSet::GetValue(const void *value) const {
const void *CFCMutableSet::AddValue(const void *value, bool can_create) {
CFMutableSetRef set = get();
if (set == NULL) {
- if (can_create == false)
+ if (!can_create)
return NULL;
set = ::CFSetCreateMutable(kCFAllocatorDefault, 0, &kCFTypeSetCallBacks);
reset(set);
diff --git a/source/Host/macosx/objcxx/Host.mm b/source/Host/macosx/objcxx/Host.mm
index a70bf0421ec4..3cf44c4cb65f 100644
--- a/source/Host/macosx/objcxx/Host.mm
+++ b/source/Host/macosx/objcxx/Host.mm
@@ -55,10 +55,11 @@
#include <unistd.h>
#include "lldb/Host/ConnectionFileDescriptor.h"
+#include "lldb/Host/FileSystem.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/ThreadLauncher.h"
-#include "lldb/Target/ProcessLaunchInfo.h"
#include "lldb/Target/Process.h"
+#include "lldb/Target/ProcessLaunchInfo.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/CleanUp.h"
#include "lldb/Utility/DataBufferHeap.h"
@@ -100,12 +101,12 @@ using namespace lldb_private;
bool Host::GetBundleDirectory(const FileSpec &file,
FileSpec &bundle_directory) {
#if defined(__APPLE__)
- if (llvm::sys::fs::is_directory(file.GetPath())) {
+ if (FileSystem::Instance().IsDirectory(file)) {
char path[PATH_MAX];
if (file.GetPath(path, sizeof(path))) {
CFCBundle bundle(path);
if (bundle.GetPath(path, sizeof(path))) {
- bundle_directory.SetFile(path, false, FileSpec::Style::native);
+ bundle_directory.SetFile(path, FileSpec::Style::native);
return true;
}
}
@@ -117,7 +118,7 @@ bool Host::GetBundleDirectory(const FileSpec &file,
bool Host::ResolveExecutableInBundle(FileSpec &file) {
#if defined(__APPLE__)
- if (llvm::sys::fs::is_directory(file.GetPath())) {
+ if (FileSystem::Instance().IsDirectory(file)) {
char path[PATH_MAX];
if (file.GetPath(path, sizeof(path))) {
CFCBundle bundle(path);
@@ -125,7 +126,7 @@ bool Host::ResolveExecutableInBundle(FileSpec &file) {
if (url.get()) {
if (::CFURLGetFileSystemRepresentation(url.get(), YES, (UInt8 *)path,
sizeof(path))) {
- file.SetFile(path, false, FileSpec::Style::native);
+ file.SetFile(path, FileSpec::Style::native);
return true;
}
}
@@ -225,7 +226,7 @@ LaunchInNewTerminalWithAppleScript(const char *exe_path,
darwin_debug_file_spec.GetFilename().SetCString("darwin-debug");
- if (!darwin_debug_file_spec.Exists()) {
+ if (!FileSystem::Instance().Exists(darwin_debug_file_spec)) {
error.SetErrorStringWithFormat(
"the 'darwin-debug' executable doesn't exists at '%s'",
darwin_debug_file_spec.GetPath().c_str());
@@ -485,11 +486,9 @@ static bool GetMacOSXProcessCPUType(ProcessInstanceInfo &process_info) {
bool host_cpu_is_64bit;
uint32_t is64bit_capable;
size_t is64bit_capable_len = sizeof(is64bit_capable);
- if (sysctlbyname("hw.cpu64bit_capable", &is64bit_capable,
- &is64bit_capable_len, NULL, 0) == 0)
- host_cpu_is_64bit = true;
- else
- host_cpu_is_64bit = false;
+ host_cpu_is_64bit =
+ sysctlbyname("hw.cpu64bit_capable", &is64bit_capable,
+ &is64bit_capable_len, NULL, 0) == 0;
// if the host is an armv8 device, its cpusubtype will be in
// CPU_SUBTYPE_ARM64 numbering
@@ -541,8 +540,7 @@ static bool GetMacOSXProcessArgs(const ProcessInstanceInfoMatch *match_info_ptr,
triple_arch == llvm::Triple::x86_64);
const char *cstr = data.GetCStr(&offset);
if (cstr) {
- process_info.GetExecutableFile().SetFile(cstr, false,
- FileSpec::Style::native);
+ process_info.GetExecutableFile().SetFile(cstr, FileSpec::Style::native);
if (match_info_ptr == NULL ||
NameMatches(
@@ -629,7 +627,7 @@ uint32_t Host::FindProcesses(const ProcessInstanceInfoMatch &match_info,
int mib[3] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL};
size_t pid_data_size = 0;
- if (::sysctl(mib, 4, NULL, &pid_data_size, NULL, 0) != 0)
+ if (::sysctl(mib, 3, nullptr, &pid_data_size, nullptr, 0) != 0)
return 0;
// Add a few extra in case a few more show up
@@ -639,7 +637,7 @@ uint32_t Host::FindProcesses(const ProcessInstanceInfoMatch &match_info,
kinfos.resize(estimated_pid_count);
pid_data_size = kinfos.size() * sizeof(struct kinfo_proc);
- if (::sysctl(mib, 4, &kinfos[0], &pid_data_size, NULL, 0) != 0)
+ if (::sysctl(mib, 3, &kinfos[0], &pid_data_size, nullptr, 0) != 0)
return 0;
const size_t actual_pid_count = (pid_data_size / sizeof(struct kinfo_proc));
@@ -660,7 +658,7 @@ uint32_t Host::FindProcesses(const ProcessInstanceInfoMatch &match_info,
if (our_uid == 0)
kinfo_user_matches = true;
- if (kinfo_user_matches == false || // Make sure the user is acceptable
+ if (!kinfo_user_matches || // Make sure the user is acceptable
static_cast<lldb::pid_t>(kinfo.kp_proc.p_pid) ==
our_pid || // Skip this process
kinfo.kp_proc.p_pid == 0 || // Skip kernel (kernel pid is zero)
@@ -1273,21 +1271,19 @@ static bool ShouldLaunchUsingXPC(ProcessLaunchInfo &launch_info) {
Status Host::LaunchProcess(ProcessLaunchInfo &launch_info) {
Status error;
+
+ FileSystem &fs = FileSystem::Instance();
FileSpec exe_spec(launch_info.GetExecutableFile());
- llvm::sys::fs::file_status stats;
- status(exe_spec.GetPath(), stats);
- if (!exists(stats)) {
- exe_spec.ResolvePath();
- status(exe_spec.GetPath(), stats);
- }
- if (!exists(stats)) {
- exe_spec.ResolveExecutableLocation();
- status(exe_spec.GetPath(), stats);
- }
- if (!exists(stats)) {
+ if (!fs.Exists(exe_spec))
+ FileSystem::Instance().Resolve(exe_spec);
+
+ if (!fs.Exists(exe_spec))
+ FileSystem::Instance().ResolveExecutableLocation(exe_spec);
+
+ if (!fs.Exists(exe_spec)) {
error.SetErrorStringWithFormatv("executable doesn't exist: '{0}'",
- launch_info.GetExecutableFile());
+ exe_spec);
return error;
}
@@ -1337,7 +1333,7 @@ Status Host::ShellExpandArguments(ProcessLaunchInfo &launch_info) {
return error;
}
expand_tool_spec.AppendPathComponent("lldb-argdumper");
- if (!expand_tool_spec.Exists()) {
+ if (!FileSystem::Instance().Exists(expand_tool_spec)) {
error.SetErrorStringWithFormat(
"could not find the lldb-argdumper tool: %s",
expand_tool_spec.GetPath().c_str());
@@ -1354,14 +1350,14 @@ Status Host::ShellExpandArguments(ProcessLaunchInfo &launch_info) {
int status;
std::string output;
FileSpec cwd(launch_info.GetWorkingDirectory());
- if (!cwd.Exists()) {
+ if (!FileSystem::Instance().Exists(cwd)) {
char *wd = getcwd(nullptr, 0);
if (wd == nullptr) {
error.SetErrorStringWithFormat(
"cwd does not exist; cannot launch with shell argument expansion");
return error;
} else {
- FileSpec working_dir(wd, false);
+ FileSpec working_dir(wd);
free(wd);
launch_info.SetWorkingDirectory(working_dir);
}
diff --git a/source/Host/macosx/objcxx/HostInfoMacOSX.mm b/source/Host/macosx/objcxx/HostInfoMacOSX.mm
index a39d26aa31ae..165e87e8bed4 100644
--- a/source/Host/macosx/objcxx/HostInfoMacOSX.mm
+++ b/source/Host/macosx/objcxx/HostInfoMacOSX.mm
@@ -7,11 +7,11 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/Host/HostInfo.h"
#include "lldb/Host/macosx/HostInfoMacOSX.h"
+#include "lldb/Host/FileSystem.h"
+#include "lldb/Host/HostInfo.h"
#include "lldb/Utility/Args.h"
#include "lldb/Utility/Log.h"
-#include "lldb/Utility/SafeMachO.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/FileSystem.h"
@@ -97,14 +97,13 @@ FileSpec HostInfoMacOSX::GetProgramFileSpec() {
uint32_t len = sizeof(program_fullpath);
int err = _NSGetExecutablePath(program_fullpath, &len);
if (err == 0)
- g_program_filespec.SetFile(program_fullpath, false,
- FileSpec::Style::native);
+ g_program_filespec.SetFile(program_fullpath, FileSpec::Style::native);
else if (err == -1) {
char *large_program_fullpath = (char *)::malloc(len + 1);
err = _NSGetExecutablePath(large_program_fullpath, &len);
if (err == 0)
- g_program_filespec.SetFile(large_program_fullpath, false,
+ g_program_filespec.SetFile(large_program_fullpath,
FileSpec::Style::native);
::free(large_program_fullpath);
@@ -140,8 +139,9 @@ bool HostInfoMacOSX::ComputeSupportExeDirectory(FileSpec &file_spec) {
// as in the case of a python script, the executable is python, not
// the lldb driver.
raw_path.append("/../bin");
- FileSpec support_dir_spec(raw_path, true);
- if (!llvm::sys::fs::is_directory(support_dir_spec.GetPath())) {
+ FileSpec support_dir_spec(raw_path);
+ FileSystem::Instance().Resolve(support_dir_spec);
+ if (!FileSystem::Instance().IsDirectory(support_dir_spec)) {
Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
if (log)
log->Printf("HostInfoMacOSX::%s(): failed to find support directory",
@@ -204,7 +204,8 @@ bool HostInfoMacOSX::ComputeSystemPluginsDirectory(FileSpec &file_spec) {
}
bool HostInfoMacOSX::ComputeUserPluginsDirectory(FileSpec &file_spec) {
- FileSpec temp_file("~/Library/Application Support/LLDB/PlugIns", true);
+ FileSpec temp_file("~/Library/Application Support/LLDB/PlugIns");
+ FileSystem::Instance().Resolve(temp_file);
file_spec.GetDirectory().SetCString(temp_file.GetPath().c_str());
return true;
}
@@ -254,6 +255,9 @@ void HostInfoMacOSX::ComputeHostArchitectureSupport(ArchSpec &arch_32,
#if defined(TARGET_OS_TV) && TARGET_OS_TV == 1
arch_32.GetTriple().setOS(llvm::Triple::TvOS);
arch_64.GetTriple().setOS(llvm::Triple::TvOS);
+#elif defined(TARGET_OS_BRIDGE) && TARGET_OS_BRIDGE == 1
+ arch_32.GetTriple().setOS(llvm::Triple::BridgeOS);
+ arch_64.GetTriple().setOS(llvm::Triple::BridgeOS);
#else
arch_32.GetTriple().setOS(llvm::Triple::IOS);
arch_64.GetTriple().setOS(llvm::Triple::IOS);
diff --git a/source/Host/netbsd/Host.cpp b/source/Host/netbsd/Host.cpp
index bfd5a74ffcc2..4d50363c72e0 100644
--- a/source/Host/netbsd/Host.cpp
+++ b/source/Host/netbsd/Host.cpp
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
#include <dlfcn.h>
#include <execinfo.h>
#include <stdio.h>
@@ -22,9 +21,6 @@
#include <sys/exec.h>
#include <sys/ptrace.h>
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Target/Process.h"
@@ -70,7 +66,7 @@ static bool GetNetBSDProcessArgs(const ProcessInstanceInfoMatch *match_info_ptr,
if (!cstr)
return false;
- process_info.GetExecutableFile().SetFile(cstr, false,
+ process_info.GetExecutableFile().SetFile(cstr,
FileSpec::Style::native);
if (!(match_info_ptr == NULL ||
diff --git a/source/Host/netbsd/HostInfoNetBSD.cpp b/source/Host/netbsd/HostInfoNetBSD.cpp
index dfbce310509d..a54483fcc55b 100644
--- a/source/Host/netbsd/HostInfoNetBSD.cpp
+++ b/source/Host/netbsd/HostInfoNetBSD.cpp
@@ -85,7 +85,7 @@ FileSpec HostInfoNetBSD::GetProgramFileSpec() {
len = sizeof(path);
if (sysctl(name, __arraycount(name), path, &len, NULL, 0) != -1) {
- g_program_filespec.SetFile(path, false, FileSpec::Style::native);
+ g_program_filespec.SetFile(path, FileSpec::Style::native);
}
}
return g_program_filespec;
diff --git a/source/Host/openbsd/Host.cpp b/source/Host/openbsd/Host.cpp
index 49e9c290a027..cba1f4ee6b7c 100644
--- a/source/Host/openbsd/Host.cpp
+++ b/source/Host/openbsd/Host.cpp
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
#include <sys/types.h>
#include <sys/signal.h>
@@ -19,9 +18,6 @@
#include <stdio.h>
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Target/Process.h"
diff --git a/source/Host/posix/ConnectionFileDescriptorPosix.cpp b/source/Host/posix/ConnectionFileDescriptorPosix.cpp
index c21bb786a896..deac3844d4a2 100644
--- a/source/Host/posix/ConnectionFileDescriptorPosix.cpp
+++ b/source/Host/posix/ConnectionFileDescriptorPosix.cpp
@@ -21,7 +21,6 @@
#include "lldb/Utility/SelectHelper.h"
#include "lldb/Utility/Timeout.h"
-// C Includes
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
@@ -33,16 +32,13 @@
#include <unistd.h>
#endif
-// C++ Includes
#include <sstream>
-// Other libraries and framework includes
#include "llvm/Support/Errno.h"
#include "llvm/Support/ErrorHandling.h"
#if defined(__APPLE__)
#include "llvm/ADT/SmallVector.h"
#endif
-// Project includes
#include "lldb/Host/Host.h"
#include "lldb/Host/Socket.h"
#include "lldb/Host/common/TCPSocket.h"
diff --git a/source/Host/posix/FileSystem.cpp b/source/Host/posix/FileSystem.cpp
index 60be642df608..d7045ff99919 100644
--- a/source/Host/posix/FileSystem.cpp
+++ b/source/Host/posix/FileSystem.cpp
@@ -11,6 +11,7 @@
// C includes
#include <dirent.h>
+#include <fcntl.h>
#include <sys/mount.h>
#include <sys/param.h>
#include <sys/stat.h>
@@ -47,7 +48,7 @@ Status FileSystem::Readlink(const FileSpec &src, FileSpec &dst) {
error.SetErrorToErrno();
else {
buf[count] = '\0'; // Success
- dst.SetFile(buf, false, FileSpec::Style::native);
+ dst.SetFile(buf, FileSpec::Style::native);
}
return error;
}
@@ -65,7 +66,7 @@ Status FileSystem::ResolveSymbolicLink(const FileSpec &src, FileSpec &dst) {
return err;
}
- dst = FileSpec(real_path, false);
+ dst = FileSpec(real_path);
return Status();
}
@@ -73,3 +74,7 @@ Status FileSystem::ResolveSymbolicLink(const FileSpec &src, FileSpec &dst) {
FILE *FileSystem::Fopen(const char *path, const char *mode) {
return ::fopen(path, mode);
}
+
+int FileSystem::Open(const char *path, int flags, int mode) {
+ return ::open(path, flags, mode);
+}
diff --git a/source/Host/posix/HostInfoPosix.cpp b/source/Host/posix/HostInfoPosix.cpp
index 62c70fa3edc1..4763ebc9b9d4 100644
--- a/source/Host/posix/HostInfoPosix.cpp
+++ b/source/Host/posix/HostInfoPosix.cpp
@@ -119,7 +119,7 @@ uint32_t HostInfoPosix::GetEffectiveUserID() { return geteuid(); }
uint32_t HostInfoPosix::GetEffectiveGroupID() { return getegid(); }
-FileSpec HostInfoPosix::GetDefaultShell() { return FileSpec("/bin/sh", false); }
+FileSpec HostInfoPosix::GetDefaultShell() { return FileSpec("/bin/sh"); }
bool HostInfoPosix::ComputePathRelativeToLibrary(FileSpec &file_spec,
llvm::StringRef dir) {
@@ -163,7 +163,7 @@ bool HostInfoPosix::ComputeSupportExeDirectory(FileSpec &file_spec) {
}
bool HostInfoPosix::ComputeHeaderDirectory(FileSpec &file_spec) {
- FileSpec temp_file("/opt/local/include/lldb", false);
+ FileSpec temp_file("/opt/local/include/lldb");
file_spec.GetDirectory().SetCString(temp_file.GetPath().c_str());
return true;
}
diff --git a/source/Host/posix/HostProcessPosix.cpp b/source/Host/posix/HostProcessPosix.cpp
index 3c5273f4bd3f..f431e0c72de1 100644
--- a/source/Host/posix/HostProcessPosix.cpp
+++ b/source/Host/posix/HostProcessPosix.cpp
@@ -62,7 +62,7 @@ Status HostProcessPosix::GetMainModule(FileSpec &file_spec) const {
return error;
}
- error = FileSystem::Readlink(FileSpec{link_path, false}, file_spec);
+ error = FileSystem::Instance().Readlink(FileSpec(link_path), file_spec);
if (!error.Success())
return error;
diff --git a/source/Host/posix/PipePosix.cpp b/source/Host/posix/PipePosix.cpp
index b321cad64275..866a9897ee43 100644
--- a/source/Host/posix/PipePosix.cpp
+++ b/source/Host/posix/PipePosix.cpp
@@ -61,12 +61,13 @@ bool SetCloexecFlag(int fd) {
std::chrono::time_point<std::chrono::steady_clock> Now() {
return std::chrono::steady_clock::now();
}
-}
+} // namespace
PipePosix::PipePosix()
: m_fds{PipePosix::kInvalidDescriptor, PipePosix::kInvalidDescriptor} {}
-PipePosix::PipePosix(int read_fd, int write_fd) : m_fds{read_fd, write_fd} {}
+PipePosix::PipePosix(lldb::pipe_t read, lldb::pipe_t write)
+ : m_fds{read, write} {}
PipePosix::PipePosix(PipePosix &&pipe_posix)
: PipeBase{std::move(pipe_posix)},
@@ -125,8 +126,8 @@ Status PipePosix::CreateNew(llvm::StringRef name, bool child_process_inherit) {
Status PipePosix::CreateWithUniqueName(llvm::StringRef prefix,
bool child_process_inherit,
llvm::SmallVectorImpl<char> &name) {
- llvm::SmallString<PATH_MAX> named_pipe_path;
- llvm::SmallString<PATH_MAX> pipe_spec((prefix + ".%%%%%%").str());
+ llvm::SmallString<128> named_pipe_path;
+ llvm::SmallString<128> pipe_spec((prefix + ".%%%%%%").str());
FileSpec tmpdir_file_spec = HostInfo::GetProcessTempDir();
if (!tmpdir_file_spec)
tmpdir_file_spec.AppendPathComponent("/tmp");
diff --git a/source/Host/posix/ProcessLauncherPosixFork.cpp b/source/Host/posix/ProcessLauncherPosixFork.cpp
index 46ce3e3d224f..6bf78463d060 100644
--- a/source/Host/posix/ProcessLauncherPosixFork.cpp
+++ b/source/Host/posix/ProcessLauncherPosixFork.cpp
@@ -157,7 +157,7 @@ static void LLVM_ATTRIBUTE_NORETURN ChildFunc(int error_fd,
#if defined(__linux__)
if (errno == ETXTBSY) {
- // On android M and earlier we can get this error because the adb deamon
+ // On android M and earlier we can get this error because the adb daemon
// can hold a write handle on the executable even after it has finished
// uploading it. This state lasts only a short time and happens only when
// there are many concurrent adb commands being issued, such as when
diff --git a/source/Host/windows/FileSystem.cpp b/source/Host/windows/FileSystem.cpp
index 9309b89f2baf..3217cdc8480a 100644
--- a/source/Host/windows/FileSystem.cpp
+++ b/source/Host/windows/FileSystem.cpp
@@ -75,7 +75,7 @@ Status FileSystem::Readlink(const FileSpec &src, FileSpec &dst) {
else if (!llvm::convertWideToUTF8(buf.data(), path))
error.SetErrorString(PATH_CONVERSION_ERROR);
else
- dst.SetFile(path, false, FileSpec::Style::native);
+ dst.SetFile(path, FileSpec::Style::native);
::CloseHandle(h);
return error;
@@ -96,3 +96,12 @@ FILE *FileSystem::Fopen(const char *path, const char *mode) {
return nullptr;
return file;
}
+
+int FileSystem::Open(const char *path, int flags, int mode) {
+ std::wstring wpath;
+ if (!llvm::ConvertUTF8toWide(path, wpath))
+ return -1;
+ int result;
+ ::_wsopen_s(&result, wpath.c_str(), flags, _SH_DENYNO, mode);
+ return result;
+}
diff --git a/source/Host/windows/Host.cpp b/source/Host/windows/Host.cpp
index cc6c454d36b1..3ac16a42286a 100644
--- a/source/Host/windows/Host.cpp
+++ b/source/Host/windows/Host.cpp
@@ -7,14 +7,11 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
#include "lldb/Host/windows/AutoHandle.h"
#include "lldb/Host/windows/windows.h"
#include <stdio.h>
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
+#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Target/Process.h"
@@ -36,8 +33,9 @@ namespace {
bool GetTripleForProcess(const FileSpec &executable, llvm::Triple &triple) {
// Open the PE File as a binary file, and parse just enough information to
// determine the machine type.
- File imageBinary(executable.GetPath().c_str(), File::eOpenOptionRead,
- lldb::eFilePermissionsUserRead);
+ File imageBinary;
+ FileSystem::Instance().Open(imageBinary, executable, File::eOpenOptionRead,
+ lldb::eFilePermissionsUserRead);
imageBinary.SeekFromStart(0x3c);
int32_t peOffset = 0;
uint32_t peHead = 0;
@@ -83,7 +81,7 @@ void GetProcessExecutableAndTriple(const AutoHandle &handle,
triple.setOS(llvm::Triple::Win32);
triple.setArch(llvm::Triple::UnknownArch);
if (GetExecutableForProcess(handle, executable)) {
- FileSpec executableFile(executable.c_str(), false);
+ FileSpec executableFile(executable.c_str());
process.SetExecutableFile(executableFile, true);
GetTripleForProcess(executableFile, triple);
}
@@ -122,7 +120,7 @@ FileSpec Host::GetModuleFileSpecForHostAddress(const void *host_addr) {
std::string path;
if (!llvm::convertWideToUTF8(buffer.data(), path))
return module_filespec;
- module_filespec.SetFile(path, false, FileSpec::Style::native);
+ module_filespec.SetFile(path, FileSpec::Style::native);
return module_filespec;
}
@@ -145,7 +143,7 @@ uint32_t Host::FindProcesses(const ProcessInstanceInfoMatch &match_info,
ProcessInstanceInfo process;
std::string exeFile;
llvm::convertWideToUTF8(pe.szExeFile, exeFile);
- process.SetExecutableFile(FileSpec(exeFile, false), true);
+ process.SetExecutableFile(FileSpec(exeFile), true);
process.SetProcessID(pe.th32ProcessID);
process.SetParentProcessID(pe.th32ParentProcessID);
GetProcessExecutableAndTriple(handle, process);
@@ -189,7 +187,7 @@ Status Host::ShellExpandArguments(ProcessLaunchInfo &launch_info) {
return error;
}
expand_tool_spec.AppendPathComponent("lldb-argdumper.exe");
- if (!expand_tool_spec.Exists()) {
+ if (!FileSystem::Instance().Exists(expand_tool_spec)) {
error.SetErrorString("could not find the lldb-argdumper tool");
return error;
}
diff --git a/source/Host/windows/HostInfoWindows.cpp b/source/Host/windows/HostInfoWindows.cpp
index bd3f74f2e2f3..81392d9a85b3 100644
--- a/source/Host/windows/HostInfoWindows.cpp
+++ b/source/Host/windows/HostInfoWindows.cpp
@@ -11,7 +11,7 @@
#include <objbase.h>
-#include <mutex> // std::once
+#include <mutex>
#include "lldb/Host/windows/HostInfoWindows.h"
#include "lldb/Host/windows/PosixApi.h"
@@ -92,7 +92,7 @@ FileSpec HostInfoWindows::GetProgramFileSpec() {
::GetModuleFileNameW(NULL, buffer.data(), buffer.size());
std::string path;
llvm::convertWideToUTF8(buffer.data(), path);
- m_program_filespec.SetFile(path, false, FileSpec::Style::native);
+ m_program_filespec.SetFile(path, FileSpec::Style::native);
});
return m_program_filespec;
}
@@ -103,9 +103,9 @@ FileSpec HostInfoWindows::GetDefaultShell() {
std::string shell;
if (GetEnvironmentVar("ComSpec", shell))
- return FileSpec(shell, false);
+ return FileSpec(shell);
- return FileSpec("C:\\Windows\\system32\\cmd.exe", false);
+ return FileSpec("C:\\Windows\\system32\\cmd.exe");
}
bool HostInfoWindows::GetEnvironmentVar(const std::string &var_name,
diff --git a/source/Host/windows/HostProcessWindows.cpp b/source/Host/windows/HostProcessWindows.cpp
index ce75c14cdcf4..701167ff6fea 100644
--- a/source/Host/windows/HostProcessWindows.cpp
+++ b/source/Host/windows/HostProcessWindows.cpp
@@ -57,7 +57,7 @@ Status HostProcessWindows::GetMainModule(FileSpec &file_spec) const {
if (::GetProcessImageFileNameW(m_process, wpath.data(), wpath.size())) {
std::string path;
if (llvm::convertWideToUTF8(wpath.data(), path))
- file_spec.SetFile(path, false, FileSpec::Style::native);
+ file_spec.SetFile(path, FileSpec::Style::native);
else
error.SetErrorString("Error converting path to UTF-8");
} else
diff --git a/source/Host/windows/HostThreadWindows.cpp b/source/Host/windows/HostThreadWindows.cpp
index 3d603ff61663..b516230e7fa4 100644
--- a/source/Host/windows/HostThreadWindows.cpp
+++ b/source/Host/windows/HostThreadWindows.cpp
@@ -69,3 +69,7 @@ void HostThreadWindows::Reset() {
HostNativeThreadBase::Reset();
}
+
+bool HostThreadWindows::EqualsThread(lldb::thread_t thread) const {
+ return GetThreadId() == ::GetThreadId(thread);
+}
diff --git a/source/Host/windows/PipeWindows.cpp b/source/Host/windows/PipeWindows.cpp
index 1951c9ca193a..57221a72899c 100644
--- a/source/Host/windows/PipeWindows.cpp
+++ b/source/Host/windows/PipeWindows.cpp
@@ -25,14 +25,41 @@ using namespace lldb_private;
namespace {
std::atomic<uint32_t> g_pipe_serial(0);
+constexpr llvm::StringLiteral g_pipe_name_prefix = "\\\\.\\Pipe\\";
+} // namespace
+
+PipeWindows::PipeWindows()
+ : m_read(INVALID_HANDLE_VALUE), m_write(INVALID_HANDLE_VALUE),
+ m_read_fd(PipeWindows::kInvalidDescriptor),
+ m_write_fd(PipeWindows::kInvalidDescriptor) {
+ ZeroMemory(&m_read_overlapped, sizeof(m_read_overlapped));
+ ZeroMemory(&m_write_overlapped, sizeof(m_write_overlapped));
}
-PipeWindows::PipeWindows() {
- m_read = INVALID_HANDLE_VALUE;
- m_write = INVALID_HANDLE_VALUE;
+PipeWindows::PipeWindows(pipe_t read, pipe_t write)
+ : m_read((HANDLE)read), m_write((HANDLE)write),
+ m_read_fd(PipeWindows::kInvalidDescriptor),
+ m_write_fd(PipeWindows::kInvalidDescriptor) {
+ assert(read != LLDB_INVALID_PIPE || write != LLDB_INVALID_PIPE);
+
+ // Don't risk in passing file descriptors and getting handles from them by
+ // _get_osfhandle since the retrieved handles are highly likely unrecognized
+ // in the current process and usually crashes the program. Pass handles
+ // instead since the handle can be inherited.
+
+ if (read != LLDB_INVALID_PIPE) {
+ m_read_fd = _open_osfhandle((intptr_t)read, _O_RDONLY);
+ // Make sure the fd and native handle are consistent.
+ if (m_read_fd < 0)
+ m_read = INVALID_HANDLE_VALUE;
+ }
+
+ if (write != LLDB_INVALID_PIPE) {
+ m_write_fd = _open_osfhandle((intptr_t)write, _O_WRONLY);
+ if (m_write_fd < 0)
+ m_write = INVALID_HANDLE_VALUE;
+ }
- m_read_fd = -1;
- m_write_fd = -1;
ZeroMemory(&m_read_overlapped, sizeof(m_read_overlapped));
ZeroMemory(&m_write_overlapped, sizeof(m_write_overlapped));
}
@@ -40,6 +67,24 @@ PipeWindows::PipeWindows() {
PipeWindows::~PipeWindows() { Close(); }
Status PipeWindows::CreateNew(bool child_process_inherit) {
+ // Create an anonymous pipe with the specified inheritance.
+ SECURITY_ATTRIBUTES sa{sizeof(SECURITY_ATTRIBUTES), 0,
+ child_process_inherit ? TRUE : FALSE};
+ BOOL result = ::CreatePipe(&m_read, &m_write, &sa, 1024);
+ if (result == FALSE)
+ return Status(::GetLastError(), eErrorTypeWin32);
+
+ m_read_fd = _open_osfhandle((intptr_t)m_read, _O_RDONLY);
+ ZeroMemory(&m_read_overlapped, sizeof(m_read_overlapped));
+ m_read_overlapped.hEvent = ::CreateEventA(nullptr, TRUE, FALSE, nullptr);
+
+ m_write_fd = _open_osfhandle((intptr_t)m_write, _O_WRONLY);
+ ZeroMemory(&m_write_overlapped, sizeof(m_write_overlapped));
+
+ return Status();
+}
+
+Status PipeWindows::CreateNewNamed(bool child_process_inherit) {
// Even for anonymous pipes, we open a named pipe. This is because you
// cannot get overlapped i/o on Windows without using a named pipe. So we
// synthesize a unique name.
@@ -60,7 +105,7 @@ Status PipeWindows::CreateNew(llvm::StringRef name,
if (CanRead() || CanWrite())
return Status(ERROR_ALREADY_EXISTS, eErrorTypeWin32);
- std::string pipe_path = "\\\\.\\Pipe\\";
+ std::string pipe_path = g_pipe_name_prefix;
pipe_path.append(name);
// Always open for overlapped i/o. We implement blocking manually in Read
@@ -75,7 +120,8 @@ Status PipeWindows::CreateNew(llvm::StringRef name,
ZeroMemory(&m_read_overlapped, sizeof(m_read_overlapped));
m_read_overlapped.hEvent = ::CreateEvent(nullptr, TRUE, FALSE, nullptr);
- // Open the write end of the pipe.
+ // Open the write end of the pipe. Note that closing either the read or
+ // write end of the pipe could directly close the pipe itself.
Status result = OpenNamedPipe(name, child_process_inherit, false);
if (!result.Success()) {
CloseReadFileDescriptor();
@@ -111,7 +157,7 @@ Status PipeWindows::CreateWithUniqueName(llvm::StringRef prefix,
Status PipeWindows::OpenAsReader(llvm::StringRef name,
bool child_process_inherit) {
- if (CanRead() || CanWrite())
+ if (CanRead())
return Status(ERROR_ALREADY_EXISTS, eErrorTypeWin32);
return OpenNamedPipe(name, child_process_inherit, true);
@@ -121,7 +167,7 @@ Status
PipeWindows::OpenAsWriterWithTimeout(llvm::StringRef name,
bool child_process_inherit,
const std::chrono::microseconds &timeout) {
- if (CanRead() || CanWrite())
+ if (CanWrite())
return Status(ERROR_ALREADY_EXISTS, eErrorTypeWin32);
return OpenNamedPipe(name, child_process_inherit, false);
@@ -137,7 +183,7 @@ Status PipeWindows::OpenNamedPipe(llvm::StringRef name,
SECURITY_ATTRIBUTES attributes = {};
attributes.bInheritHandle = child_process_inherit;
- std::string pipe_path = "\\\\.\\Pipe\\";
+ std::string pipe_path = g_pipe_name_prefix;
pipe_path.append(name);
if (is_read) {
@@ -170,9 +216,9 @@ int PipeWindows::GetWriteFileDescriptor() const { return m_write_fd; }
int PipeWindows::ReleaseReadFileDescriptor() {
if (!CanRead())
- return -1;
+ return PipeWindows::kInvalidDescriptor;
int result = m_read_fd;
- m_read_fd = -1;
+ m_read_fd = PipeWindows::kInvalidDescriptor;
if (m_read_overlapped.hEvent)
::CloseHandle(m_read_overlapped.hEvent);
m_read = INVALID_HANDLE_VALUE;
@@ -182,9 +228,9 @@ int PipeWindows::ReleaseReadFileDescriptor() {
int PipeWindows::ReleaseWriteFileDescriptor() {
if (!CanWrite())
- return -1;
+ return PipeWindows::kInvalidDescriptor;
int result = m_write_fd;
- m_write_fd = -1;
+ m_write_fd = PipeWindows::kInvalidDescriptor;
m_write = INVALID_HANDLE_VALUE;
ZeroMemory(&m_write_overlapped, sizeof(m_write_overlapped));
return result;
@@ -196,9 +242,10 @@ void PipeWindows::CloseReadFileDescriptor() {
if (m_read_overlapped.hEvent)
::CloseHandle(m_read_overlapped.hEvent);
+
_close(m_read_fd);
m_read = INVALID_HANDLE_VALUE;
- m_read_fd = -1;
+ m_read_fd = PipeWindows::kInvalidDescriptor;
ZeroMemory(&m_read_overlapped, sizeof(m_read_overlapped));
}
@@ -208,7 +255,7 @@ void PipeWindows::CloseWriteFileDescriptor() {
_close(m_write_fd);
m_write = INVALID_HANDLE_VALUE;
- m_write_fd = -1;
+ m_write_fd = PipeWindows::kInvalidDescriptor;
ZeroMemory(&m_write_overlapped, sizeof(m_write_overlapped));
}
diff --git a/source/Host/windows/ProcessLauncherWindows.cpp b/source/Host/windows/ProcessLauncherWindows.cpp
index 553dd9d286da..a186c7177fdf 100644
--- a/source/Host/windows/ProcessLauncherWindows.cpp
+++ b/source/Host/windows/ProcessLauncherWindows.cpp
@@ -76,6 +76,9 @@ ProcessLauncherWindows::LaunchProcess(const ProcessLaunchInfo &launch_info,
if (launch_info.GetFlags().Test(eLaunchFlagDebug))
flags |= DEBUG_ONLY_THIS_PROCESS;
+ if (launch_info.GetFlags().Test(eLaunchFlagDisableSTDIO))
+ flags &= ~CREATE_NEW_CONSOLE;
+
LPVOID env_block = nullptr;
::CreateEnvironmentBuffer(launch_info.GetEnvironment(), environment);
if (!environment.empty())