aboutsummaryrefslogtreecommitdiffstats
path: root/source/Host
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-04-16 16:04:10 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-04-16 16:04:10 +0000
commit74a628f776edb588bff8f8f5cc16eac947c9d631 (patch)
treedc32e010ac4902621e5a279bfeb48628f7f0e166 /source/Host
parentafed7be32164a598f8172282c249af7266c48b46 (diff)
downloadsrc-74a628f776edb588bff8f8f5cc16eac947c9d631.tar.gz
src-74a628f776edb588bff8f8f5cc16eac947c9d631.zip
Vendor import of lldb trunk r300422:vendor/lldb/lldb-trunk-r300422
Notes
Notes: svn path=/vendor/lldb/dist/; revision=317027 svn path=/vendor/lldb/lldb-trunk-r300422/; revision=317028; tag=vendor/lldb/lldb-trunk-r300422
Diffstat (limited to 'source/Host')
-rw-r--r--source/Host/CMakeLists.txt63
-rw-r--r--source/Host/common/Editline.cpp21
-rw-r--r--source/Host/common/File.cpp27
-rw-r--r--source/Host/common/FileSpec.cpp1431
-rw-r--r--source/Host/common/FileSystem.cpp74
-rw-r--r--source/Host/common/Host.cpp156
-rw-r--r--source/Host/common/HostInfoBase.cpp92
-rw-r--r--source/Host/common/HostNativeThreadBase.cpp7
-rw-r--r--source/Host/common/MonitoringProcessLauncher.cpp17
-rw-r--r--source/Host/common/NativeBreakpoint.cpp4
-rw-r--r--source/Host/common/NativeBreakpointList.cpp2
-rw-r--r--source/Host/common/NativeProcessProtocol.cpp118
-rw-r--r--source/Host/common/NativeRegisterContext.cpp12
-rw-r--r--source/Host/common/NativeRegisterContextRegisterInfo.cpp43
-rw-r--r--source/Host/common/NativeWatchpointList.cpp2
-rw-r--r--source/Host/common/PseudoTerminal.cpp310
-rw-r--r--source/Host/common/Socket.cpp26
-rw-r--r--source/Host/common/SocketAddress.cpp48
-rw-r--r--source/Host/common/SoftwareBreakpoint.cpp4
-rw-r--r--source/Host/common/Symbols.cpp21
-rw-r--r--source/Host/common/TCPSocket.cpp2
-rw-r--r--source/Host/common/ThisThread.cpp50
-rw-r--r--source/Host/common/ThreadLauncher.cpp3
-rw-r--r--source/Host/common/UDPSocket.cpp58
-rw-r--r--source/Host/freebsd/Host.cpp48
-rw-r--r--source/Host/freebsd/HostInfoFreeBSD.cpp3
-rw-r--r--source/Host/freebsd/HostThreadFreeBSD.cpp70
-rw-r--r--source/Host/freebsd/ThisThread.cpp35
-rw-r--r--source/Host/linux/Host.cpp405
-rw-r--r--source/Host/linux/HostInfoLinux.cpp14
-rw-r--r--source/Host/linux/HostThreadLinux.cpp45
-rw-r--r--source/Host/linux/ProcessLauncherLinux.cpp216
-rw-r--r--source/Host/linux/Support.cpp34
-rw-r--r--source/Host/linux/ThisThread.cpp25
-rw-r--r--source/Host/macosx/Host.mm53
-rw-r--r--source/Host/macosx/HostInfoMacOSX.mm7
-rw-r--r--source/Host/macosx/Symbols.cpp42
-rw-r--r--source/Host/macosx/ThisThread.cpp25
-rw-r--r--source/Host/netbsd/Host.cpp37
-rw-r--r--source/Host/netbsd/HostInfoNetBSD.cpp22
-rw-r--r--source/Host/netbsd/HostThreadNetBSD.cpp43
-rw-r--r--source/Host/netbsd/ThisThread.cpp26
-rw-r--r--source/Host/openbsd/Host.cpp225
-rw-r--r--source/Host/openbsd/HostInfoOpenBSD.cpp65
-rw-r--r--source/Host/posix/ConnectionFileDescriptorPosix.cpp21
-rw-r--r--source/Host/posix/DomainSocket.cpp4
-rw-r--r--source/Host/posix/FileSystem.cpp191
-rw-r--r--source/Host/posix/HostInfoPosix.cpp2
-rw-r--r--source/Host/posix/HostThreadPosix.cpp2
-rw-r--r--source/Host/posix/MainLoopPosix.cpp4
-rw-r--r--source/Host/posix/PipePosix.cpp3
-rw-r--r--source/Host/posix/ProcessLauncherPosixFork.cpp231
-rw-r--r--source/Host/windows/ConnectionGenericFileWindows.cpp5
-rw-r--r--source/Host/windows/FileSystem.cpp165
-rw-r--r--source/Host/windows/Host.cpp16
-rw-r--r--source/Host/windows/HostInfoWindows.cpp6
-rw-r--r--source/Host/windows/HostProcessWindows.cpp2
-rw-r--r--source/Host/windows/HostThreadWindows.cpp2
-rw-r--r--source/Host/windows/ThisThread.cpp63
-rw-r--r--source/Host/windows/Windows.cpp32
60 files changed, 1561 insertions, 3219 deletions
diff --git a/source/Host/CMakeLists.txt b/source/Host/CMakeLists.txt
index 0e4a8a533e5f..f00d67420fa3 100644
--- a/source/Host/CMakeLists.txt
+++ b/source/Host/CMakeLists.txt
@@ -6,7 +6,6 @@ endmacro()
add_host_subdirectory(common
common/File.cpp
common/FileCache.cpp
- common/FileSpec.cpp
common/FileSystem.cpp
common/GetOptInc.cpp
common/Host.cpp
@@ -22,11 +21,11 @@ add_host_subdirectory(common
common/NativeWatchpointList.cpp
common/NativeProcessProtocol.cpp
common/NativeRegisterContext.cpp
- common/NativeRegisterContextRegisterInfo.cpp
common/NativeThreadProtocol.cpp
common/OptionParser.cpp
common/PipeBase.cpp
common/ProcessRunLock.cpp
+ common/PseudoTerminal.cpp
common/Socket.cpp
common/SocketAddress.cpp
common/SoftwareBreakpoint.cpp
@@ -34,7 +33,6 @@ add_host_subdirectory(common
common/Symbols.cpp
common/TCPSocket.cpp
common/Terminal.cpp
- common/ThisThread.cpp
common/ThreadLauncher.cpp
common/XML.cpp
common/UDPSocket.cpp
@@ -55,6 +53,10 @@ add_host_subdirectory(posix
posix/ConnectionFileDescriptorPosix.cpp
)
+if(NOT LLDB_DISABLE_PYTHON)
+ list(APPEND LLDB_PLUGINS lldbPluginScriptInterpreterPython)
+endif()
+
if (CMAKE_SYSTEM_NAME MATCHES "Windows")
add_host_subdirectory(windows
windows/ConnectionGenericFileWindows.cpp
@@ -68,7 +70,6 @@ if (CMAKE_SYSTEM_NAME MATCHES "Windows")
windows/PipeWindows.cpp
windows/ProcessLauncherWindows.cpp
windows/ProcessRunLock.cpp
- windows/ThisThread.cpp
windows/Windows.cpp
)
else()
@@ -86,9 +87,10 @@ else()
posix/LockFilePosix.cpp
posix/MainLoopPosix.cpp
posix/PipePosix.cpp
+ posix/ProcessLauncherPosixFork.cpp
)
- if (NOT __ANDROID_NDK__)
+ if (NOT (CMAKE_SYSTEM_NAME MATCHES "Android"))
add_host_subdirectory(posix
posix/ProcessLauncherPosix.cpp
)
@@ -101,7 +103,6 @@ else()
macosx/HostInfoMacOSX.mm
macosx/HostThreadMacOSX.mm
macosx/Symbols.cpp
- macosx/ThisThread.cpp
macosx/cfcpp/CFCBundle.cpp
macosx/cfcpp/CFCData.cpp
macosx/cfcpp/CFCMutableArray.cpp
@@ -110,37 +111,37 @@ else()
macosx/cfcpp/CFCString.cpp
)
- elseif (CMAKE_SYSTEM_NAME MATCHES "Linux")
- if (__ANDROID_NDK__)
- add_host_subdirectory(android
- android/HostInfoAndroid.cpp
- android/LibcGlue.cpp
- )
- endif()
+
+ elseif (CMAKE_SYSTEM_NAME MATCHES "Linux|Android")
add_host_subdirectory(linux
linux/AbstractSocket.cpp
linux/Host.cpp
linux/HostInfoLinux.cpp
- linux/HostThreadLinux.cpp
linux/LibcGlue.cpp
- linux/ProcessLauncherLinux.cpp
- linux/ThisThread.cpp
+ linux/Support.cpp
)
-
+ if (CMAKE_SYSTEM_NAME MATCHES "Android")
+ add_host_subdirectory(android
+ android/HostInfoAndroid.cpp
+ android/LibcGlue.cpp
+ )
+ endif()
elseif (CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
add_host_subdirectory(freebsd
freebsd/Host.cpp
freebsd/HostInfoFreeBSD.cpp
- freebsd/HostThreadFreeBSD.cpp
- freebsd/ThisThread.cpp
)
elseif (CMAKE_SYSTEM_NAME MATCHES "NetBSD")
add_host_subdirectory(netbsd
netbsd/Host.cpp
netbsd/HostInfoNetBSD.cpp
- netbsd/HostThreadNetBSD.cpp
- netbsd/ThisThread.cpp
+ )
+
+ elseif (CMAKE_SYSTEM_NAME MATCHES "OpenBSD")
+ add_host_subdirectory(openbsd
+ openbsd/Host.cpp
+ openbsd/HostInfoOpenBSD.cpp
)
endif()
endif()
@@ -158,8 +159,22 @@ if (${get_python_libdir})
endif()
endif()
-add_lldb_library(lldbHost ${HOST_SOURCES})
-
if (CMAKE_SYSTEM_NAME MATCHES "NetBSD")
-target_link_libraries(lldbHost kvm)
+ set(EXTRA_LIBS kvm)
endif ()
+
+add_lldb_library(lldbHost
+ ${HOST_SOURCES}
+
+ LINK_LIBS
+ lldbCore
+ lldbInterpreter
+ lldbSymbol
+ lldbTarget
+ lldbUtility
+ ${LLDB_PLUGINS}
+ ${EXTRA_LIBS}
+
+ LINK_COMPONENTS
+ Support
+ )
diff --git a/source/Host/common/Editline.cpp b/source/Host/common/Editline.cpp
index 1c5c0ffe902b..b157cdb7c110 100644
--- a/source/Host/common/Editline.cpp
+++ b/source/Host/common/Editline.cpp
@@ -11,16 +11,19 @@
#include <iostream>
#include <limits.h>
-#include "lldb/Core/Error.h"
-#include "lldb/Core/StreamString.h"
-#include "lldb/Core/StringList.h"
#include "lldb/Host/ConnectionFileDescriptor.h"
#include "lldb/Host/Editline.h"
-#include "lldb/Host/FileSpec.h"
-#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
+#include "lldb/Utility/Error.h"
+#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/SelectHelper.h"
+#include "lldb/Utility/StreamString.h"
+#include "lldb/Utility/StringList.h"
+#include "lldb/Utility/Timeout.h"
+
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Threading.h"
using namespace lldb_private;
using namespace lldb_private::line_editor;
@@ -176,9 +179,7 @@ private:
if (m_path.empty() && m_history && !m_prefix.empty()) {
FileSpec parent_path{"~/.lldb", true};
char history_path[PATH_MAX];
- if (FileSystem::MakeDirectory(parent_path,
- lldb::eFilePermissionsDirectoryDefault)
- .Success()) {
+ if (!llvm::sys::fs::create_directory(parent_path.GetPath())) {
snprintf(history_path, sizeof(history_path), "~/.lldb/%s-history",
m_prefix.c_str());
} else {
@@ -1151,8 +1152,8 @@ Editline::Editline(const char *editline_name, FILE *input_file,
if (term_fd != -1) {
static std::mutex *g_init_terminal_fds_mutex_ptr = nullptr;
static std::set<int> *g_init_terminal_fds_ptr = nullptr;
- static std::once_flag g_once_flag;
- std::call_once(g_once_flag, [&]() {
+ static llvm::once_flag g_once_flag;
+ llvm::call_once(g_once_flag, [&]() {
g_init_terminal_fds_mutex_ptr =
new std::mutex(); // NOTE: Leak to avoid C++ destructor chain issues
g_init_terminal_fds_ptr = new std::set<int>(); // NOTE: Leak to avoid
diff --git a/source/Host/common/File.cpp b/source/Host/common/File.cpp
index 4eb9ae15f069..1869a6db49c9 100644
--- a/source/Host/common/File.cpp
+++ b/source/Host/common/File.cpp
@@ -19,17 +19,18 @@
#include "lldb/Host/windows/windows.h"
#else
#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <termios.h>
#endif
#include "llvm/Support/ConvertUTF.h"
+#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Process.h" // for llvm::sys::Process::FileDescriptorHasColors()
-#include "lldb/Core/DataBufferHeap.h"
-#include "lldb/Core/Error.h"
-#include "lldb/Core/Log.h"
#include "lldb/Host/Config.h"
-#include "lldb/Host/FileSpec.h"
-#include "lldb/Host/FileSystem.h"
+#include "lldb/Utility/DataBufferHeap.h"
+#include "lldb/Utility/FileSpec.h"
+#include "lldb/Utility/Log.h"
using namespace lldb;
using namespace lldb_private;
@@ -247,14 +248,12 @@ Error File::Open(const char *path, uint32_t options, uint32_t permissions) {
uint32_t File::GetPermissions(const FileSpec &file_spec, Error &error) {
if (file_spec) {
- struct stat file_stats;
- int stat_result = FileSystem::Stat(file_spec.GetCString(), &file_stats);
- if (stat_result == -1)
- error.SetErrorToErrno();
- else {
- error.Clear();
- return file_stats.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
- }
+ error.Clear();
+ auto Perms = llvm::sys::fs::getPermissions(file_spec.GetPath());
+ if (Perms)
+ return *Perms;
+ error = Error(Perms.getError());
+ return 0;
} else
error.SetErrorString("empty file spec");
return 0;
@@ -308,7 +307,7 @@ void File::Clear() {
Error File::GetFileSpec(FileSpec &file_spec) const {
Error error;
-#ifdef LLDB_CONFIG_FCNTL_GETPATH_SUPPORTED
+#ifdef F_GETPATH
if (IsValid()) {
char path[PATH_MAX];
if (::fcntl(GetDescriptor(), F_GETPATH, path) == -1)
diff --git a/source/Host/common/FileSpec.cpp b/source/Host/common/FileSpec.cpp
deleted file mode 100644
index 7f46d303a5d8..000000000000
--- a/source/Host/common/FileSpec.cpp
+++ /dev/null
@@ -1,1431 +0,0 @@
-//===-- FileSpec.cpp --------------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _WIN32
-#include <dirent.h>
-#else
-#include "lldb/Host/windows/windows.h"
-#endif
-#include <fcntl.h>
-#ifndef _MSC_VER
-#include <libgen.h>
-#endif
-#include <fstream>
-#include <set>
-#include <string.h>
-
-#include "lldb/Host/Config.h" // Have to include this before we test the define...
-#ifdef LLDB_CONFIG_TILDE_RESOLVES_TO_USER
-#include <pwd.h>
-#endif
-
-#include "lldb/Core/ArchSpec.h"
-#include "lldb/Core/DataBufferHeap.h"
-#include "lldb/Core/DataBufferMemoryMap.h"
-#include "lldb/Core/RegularExpression.h"
-#include "lldb/Core/Stream.h"
-#include "lldb/Core/StreamString.h"
-#include "lldb/Host/File.h"
-#include "lldb/Host/FileSpec.h"
-#include "lldb/Host/FileSystem.h"
-#include "lldb/Host/Host.h"
-#include "lldb/Utility/CleanUp.h"
-
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/ConvertUTF.h"
-#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/Path.h"
-#include "llvm/Support/Program.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-namespace {
-
-bool PathSyntaxIsPosix(FileSpec::PathSyntax syntax) {
- return (syntax == FileSpec::ePathSyntaxPosix ||
- (syntax == FileSpec::ePathSyntaxHostNative &&
- FileSystem::GetNativePathSyntax() == FileSpec::ePathSyntaxPosix));
-}
-
-const char *GetPathSeparators(FileSpec::PathSyntax syntax) {
- return PathSyntaxIsPosix(syntax) ? "/" : "\\/";
-}
-
-char GetPreferredPathSeparator(FileSpec::PathSyntax syntax) {
- return GetPathSeparators(syntax)[0];
-}
-
-bool IsPathSeparator(char value, FileSpec::PathSyntax syntax) {
- return value == '/' || (!PathSyntaxIsPosix(syntax) && value == '\\');
-}
-
-void Normalize(llvm::SmallVectorImpl<char> &path, FileSpec::PathSyntax syntax) {
- if (PathSyntaxIsPosix(syntax))
- return;
-
- std::replace(path.begin(), path.end(), '\\', '/');
- // Windows path can have \\ slashes which can be changed by replace
- // call above to //. Here we remove the duplicate.
- auto iter = std::unique(path.begin(), path.end(), [](char &c1, char &c2) {
- return (c1 == '/' && c2 == '/');
- });
- path.erase(iter, path.end());
-}
-
-void Denormalize(llvm::SmallVectorImpl<char> &path,
- FileSpec::PathSyntax syntax) {
- if (PathSyntaxIsPosix(syntax))
- return;
-
- std::replace(path.begin(), path.end(), '/', '\\');
-}
-
-bool GetFileStats(const FileSpec *file_spec, struct stat *stats_ptr) {
- char resolved_path[PATH_MAX];
- if (file_spec->GetPath(resolved_path, sizeof(resolved_path)))
- return FileSystem::Stat(resolved_path, stats_ptr) == 0;
- return false;
-}
-
-size_t FilenamePos(llvm::StringRef str, FileSpec::PathSyntax syntax) {
- if (str.size() == 2 && IsPathSeparator(str[0], syntax) && str[0] == str[1])
- return 0;
-
- if (str.size() > 0 && IsPathSeparator(str.back(), syntax))
- return str.size() - 1;
-
- size_t pos = str.find_last_of(GetPathSeparators(syntax), str.size() - 1);
-
- if (!PathSyntaxIsPosix(syntax) && pos == llvm::StringRef::npos)
- pos = str.find_last_of(':', str.size() - 2);
-
- if (pos == llvm::StringRef::npos ||
- (pos == 1 && IsPathSeparator(str[0], syntax)))
- return 0;
-
- return pos + 1;
-}
-
-size_t RootDirStart(llvm::StringRef str, FileSpec::PathSyntax syntax) {
- // case "c:/"
- if (!PathSyntaxIsPosix(syntax) &&
- (str.size() > 2 && str[1] == ':' && IsPathSeparator(str[2], syntax)))
- return 2;
-
- // case "//"
- if (str.size() == 2 && IsPathSeparator(str[0], syntax) && str[0] == str[1])
- return llvm::StringRef::npos;
-
- // case "//net"
- if (str.size() > 3 && IsPathSeparator(str[0], syntax) && str[0] == str[1] &&
- !IsPathSeparator(str[2], syntax))
- return str.find_first_of(GetPathSeparators(syntax), 2);
-
- // case "/"
- if (str.size() > 0 && IsPathSeparator(str[0], syntax))
- return 0;
-
- return llvm::StringRef::npos;
-}
-
-size_t ParentPathEnd(llvm::StringRef path, FileSpec::PathSyntax syntax) {
- size_t end_pos = FilenamePos(path, syntax);
-
- bool filename_was_sep =
- path.size() > 0 && IsPathSeparator(path[end_pos], syntax);
-
- // Skip separators except for root dir.
- size_t root_dir_pos = RootDirStart(path.substr(0, end_pos), syntax);
-
- while (end_pos > 0 && (end_pos - 1) != root_dir_pos &&
- IsPathSeparator(path[end_pos - 1], syntax))
- --end_pos;
-
- if (end_pos == 1 && root_dir_pos == 0 && filename_was_sep)
- return llvm::StringRef::npos;
-
- return end_pos;
-}
-
-} // end anonymous namespace
-
-// Resolves the username part of a path of the form ~user/other/directories, and
-// writes the result into dst_path. This will also resolve "~" to the current
-// user.
-// If you want to complete "~" to the list of users, pass it to
-// ResolvePartialUsername.
-void FileSpec::ResolveUsername(llvm::SmallVectorImpl<char> &path) {
-#if LLDB_CONFIG_TILDE_RESOLVES_TO_USER
- if (path.empty() || path[0] != '~')
- return;
-
- llvm::StringRef path_str(path.data(), path.size());
- size_t slash_pos = path_str.find('/', 1);
- if (slash_pos == 1 || path.size() == 1) {
- // A path of ~/ resolves to the current user's home dir
- llvm::SmallString<64> home_dir;
- // llvm::sys::path::home_directory() only checks if "HOME" is set in the
- // environment and does nothing else to locate the user home directory
- if (!llvm::sys::path::home_directory(home_dir)) {
- struct passwd *pw = getpwuid(getuid());
- if (pw && pw->pw_dir && pw->pw_dir[0]) {
- // Update our environemnt so llvm::sys::path::home_directory() works
- // next time
- setenv("HOME", pw->pw_dir, 0);
- home_dir.assign(llvm::StringRef(pw->pw_dir));
- } else {
- return;
- }
- }
-
- // Overwrite the ~ with the first character of the homedir, and insert
- // the rest. This way we only trigger one move, whereas an insert
- // followed by a delete (or vice versa) would trigger two.
- path[0] = home_dir[0];
- path.insert(path.begin() + 1, home_dir.begin() + 1, home_dir.end());
- return;
- }
-
- auto username_begin = path.begin() + 1;
- auto username_end = (slash_pos == llvm::StringRef::npos)
- ? path.end()
- : (path.begin() + slash_pos);
- size_t replacement_length = std::distance(path.begin(), username_end);
-
- llvm::SmallString<20> username(username_begin, username_end);
- struct passwd *user_entry = ::getpwnam(username.c_str());
- if (user_entry != nullptr) {
- // Copy over the first n characters of the path, where n is the smaller of
- // the length
- // of the home directory and the slash pos.
- llvm::StringRef homedir(user_entry->pw_dir);
- size_t initial_copy_length = std::min(homedir.size(), replacement_length);
- auto src_begin = homedir.begin();
- auto src_end = src_begin + initial_copy_length;
- std::copy(src_begin, src_end, path.begin());
- if (replacement_length > homedir.size()) {
- // We copied the entire home directory, but the ~username portion of the
- // path was
- // longer, so there's characters that need to be removed.
- path.erase(path.begin() + initial_copy_length, username_end);
- } else if (replacement_length < homedir.size()) {
- // We copied all the way up to the slash in the destination, but there's
- // still more
- // characters that need to be inserted.
- path.insert(username_end, src_end, homedir.end());
- }
- } else {
- // Unable to resolve username (user doesn't exist?)
- path.clear();
- }
-#endif
-}
-
-size_t FileSpec::ResolvePartialUsername(llvm::StringRef partial_name,
- StringList &matches) {
-#ifdef LLDB_CONFIG_TILDE_RESOLVES_TO_USER
- size_t extant_entries = matches.GetSize();
-
- setpwent();
- struct passwd *user_entry;
- partial_name = partial_name.drop_front();
- std::set<std::string> name_list;
-
- while ((user_entry = getpwent()) != NULL) {
- if (llvm::StringRef(user_entry->pw_name).startswith(partial_name)) {
- std::string tmp_buf("~");
- tmp_buf.append(user_entry->pw_name);
- tmp_buf.push_back('/');
- name_list.insert(tmp_buf);
- }
- }
-
- for (auto &name : name_list) {
- matches.AppendString(name);
- }
- return matches.GetSize() - extant_entries;
-#else
- // Resolving home directories is not supported, just copy the path...
- return 0;
-#endif // #ifdef LLDB_CONFIG_TILDE_RESOLVES_TO_USER
-}
-
-void FileSpec::Resolve(llvm::SmallVectorImpl<char> &path) {
- if (path.empty())
- return;
-
-#ifdef LLDB_CONFIG_TILDE_RESOLVES_TO_USER
- if (path[0] == '~')
- ResolveUsername(path);
-#endif // #ifdef LLDB_CONFIG_TILDE_RESOLVES_TO_USER
-
- // Save a copy of the original path that's passed in
- llvm::SmallString<128> original_path(path.begin(), path.end());
-
- llvm::sys::fs::make_absolute(path);
- if (!llvm::sys::fs::exists(path)) {
- path.clear();
- path.append(original_path.begin(), original_path.end());
- }
-}
-
-FileSpec::FileSpec() : m_syntax(FileSystem::GetNativePathSyntax()) {}
-
-//------------------------------------------------------------------
-// Default constructor that can take an optional full path to a
-// file on disk.
-//------------------------------------------------------------------
-FileSpec::FileSpec(llvm::StringRef path, bool resolve_path, PathSyntax syntax)
- : m_syntax(syntax) {
- SetFile(path, resolve_path, syntax);
-}
-
-FileSpec::FileSpec(llvm::StringRef path, bool resolve_path, ArchSpec arch)
- : FileSpec{path, resolve_path, arch.GetTriple().isOSWindows()
- ? ePathSyntaxWindows
- : ePathSyntaxPosix} {}
-
-//------------------------------------------------------------------
-// Copy constructor
-//------------------------------------------------------------------
-FileSpec::FileSpec(const FileSpec &rhs)
- : m_directory(rhs.m_directory), m_filename(rhs.m_filename),
- m_is_resolved(rhs.m_is_resolved), m_syntax(rhs.m_syntax) {}
-
-//------------------------------------------------------------------
-// Copy constructor
-//------------------------------------------------------------------
-FileSpec::FileSpec(const FileSpec *rhs) : m_directory(), m_filename() {
- if (rhs)
- *this = *rhs;
-}
-
-//------------------------------------------------------------------
-// Virtual destructor in case anyone inherits from this class.
-//------------------------------------------------------------------
-FileSpec::~FileSpec() {}
-
-//------------------------------------------------------------------
-// Assignment operator.
-//------------------------------------------------------------------
-const FileSpec &FileSpec::operator=(const FileSpec &rhs) {
- if (this != &rhs) {
- m_directory = rhs.m_directory;
- m_filename = rhs.m_filename;
- m_is_resolved = rhs.m_is_resolved;
- m_syntax = rhs.m_syntax;
- }
- return *this;
-}
-
-//------------------------------------------------------------------
-// Update the contents of this object with a new path. The path will
-// be split up into a directory and filename and stored as uniqued
-// string values for quick comparison and efficient memory usage.
-//------------------------------------------------------------------
-void FileSpec::SetFile(llvm::StringRef pathname, bool resolve,
- PathSyntax syntax) {
- // CLEANUP: Use StringRef for string handling. This function is kind of a
- // mess and the unclear semantics of RootDirStart and ParentPathEnd make
- // it very difficult to understand this function. There's no reason this
- // function should be particularly complicated or difficult to understand.
- m_filename.Clear();
- m_directory.Clear();
- m_is_resolved = false;
- m_syntax = (syntax == ePathSyntaxHostNative)
- ? FileSystem::GetNativePathSyntax()
- : syntax;
-
- if (pathname.empty())
- return;
-
- llvm::SmallString<64> resolved(pathname);
-
- if (resolve) {
- FileSpec::Resolve(resolved);
- m_is_resolved = true;
- }
-
- Normalize(resolved, m_syntax);
-
- llvm::StringRef resolve_path_ref(resolved.c_str());
- size_t dir_end = ParentPathEnd(resolve_path_ref, m_syntax);
- if (dir_end == 0) {
- m_filename.SetString(resolve_path_ref);
- return;
- }
-
- m_directory.SetString(resolve_path_ref.substr(0, dir_end));
-
- size_t filename_begin = dir_end;
- size_t root_dir_start = RootDirStart(resolve_path_ref, m_syntax);
- while (filename_begin != llvm::StringRef::npos &&
- filename_begin < resolve_path_ref.size() &&
- filename_begin != root_dir_start &&
- IsPathSeparator(resolve_path_ref[filename_begin], m_syntax))
- ++filename_begin;
- m_filename.SetString((filename_begin == llvm::StringRef::npos ||
- filename_begin >= resolve_path_ref.size())
- ? "."
- : resolve_path_ref.substr(filename_begin));
-}
-
-void FileSpec::SetFile(llvm::StringRef path, bool resolve, ArchSpec arch) {
- return SetFile(path, resolve, arch.GetTriple().isOSWindows()
- ? ePathSyntaxWindows
- : ePathSyntaxPosix);
-}
-
-//----------------------------------------------------------------------
-// Convert to pointer operator. This allows code to check any FileSpec
-// objects to see if they contain anything valid using code such as:
-//
-// if (file_spec)
-// {}
-//----------------------------------------------------------------------
-FileSpec::operator bool() const { return m_filename || m_directory; }
-
-//----------------------------------------------------------------------
-// Logical NOT operator. This allows code to check any FileSpec
-// objects to see if they are invalid using code such as:
-//
-// if (!file_spec)
-// {}
-//----------------------------------------------------------------------
-bool FileSpec::operator!() const { return !m_directory && !m_filename; }
-
-bool FileSpec::DirectoryEquals(const FileSpec &rhs) const {
- const bool case_sensitive = IsCaseSensitive() || rhs.IsCaseSensitive();
- return ConstString::Equals(m_directory, rhs.m_directory, case_sensitive);
-}
-
-bool FileSpec::FileEquals(const FileSpec &rhs) const {
- const bool case_sensitive = IsCaseSensitive() || rhs.IsCaseSensitive();
- return ConstString::Equals(m_filename, rhs.m_filename, case_sensitive);
-}
-
-//------------------------------------------------------------------
-// Equal to operator
-//------------------------------------------------------------------
-bool FileSpec::operator==(const FileSpec &rhs) const {
- if (!FileEquals(rhs))
- return false;
- if (DirectoryEquals(rhs))
- return true;
-
- // TODO: determine if we want to keep this code in here.
- // The code below was added to handle a case where we were
- // trying to set a file and line breakpoint and one path
- // was resolved, and the other not and the directory was
- // in a mount point that resolved to a more complete path:
- // "/tmp/a.c" == "/private/tmp/a.c". I might end up pulling
- // this out...
- if (IsResolved() && rhs.IsResolved()) {
- // Both paths are resolved, no need to look further...
- return false;
- }
-
- FileSpec resolved_lhs(*this);
-
- // If "this" isn't resolved, resolve it
- if (!IsResolved()) {
- if (resolved_lhs.ResolvePath()) {
- // This path wasn't resolved but now it is. Check if the resolved
- // directory is the same as our unresolved directory, and if so,
- // we can mark this object as resolved to avoid more future resolves
- m_is_resolved = (m_directory == resolved_lhs.m_directory);
- } else
- return false;
- }
-
- FileSpec resolved_rhs(rhs);
- if (!rhs.IsResolved()) {
- if (resolved_rhs.ResolvePath()) {
- // rhs's path wasn't resolved but now it is. Check if the resolved
- // directory is the same as rhs's unresolved directory, and if so,
- // we can mark this object as resolved to avoid more future resolves
- rhs.m_is_resolved = (rhs.m_directory == resolved_rhs.m_directory);
- } else
- return false;
- }
-
- // If we reach this point in the code we were able to resolve both paths
- // and since we only resolve the paths if the basenames are equal, then
- // we can just check if both directories are equal...
- return DirectoryEquals(rhs);
-}
-
-//------------------------------------------------------------------
-// Not equal to operator
-//------------------------------------------------------------------
-bool FileSpec::operator!=(const FileSpec &rhs) const { return !(*this == rhs); }
-
-//------------------------------------------------------------------
-// Less than operator
-//------------------------------------------------------------------
-bool FileSpec::operator<(const FileSpec &rhs) const {
- return FileSpec::Compare(*this, rhs, true) < 0;
-}
-
-//------------------------------------------------------------------
-// Dump a FileSpec object to a stream
-//------------------------------------------------------------------
-Stream &lldb_private::operator<<(Stream &s, const FileSpec &f) {
- f.Dump(&s);
- return s;
-}
-
-//------------------------------------------------------------------
-// Clear this object by releasing both the directory and filename
-// string values and making them both the empty string.
-//------------------------------------------------------------------
-void FileSpec::Clear() {
- m_directory.Clear();
- m_filename.Clear();
-}
-
-//------------------------------------------------------------------
-// Compare two FileSpec objects. If "full" is true, then both
-// the directory and the filename must match. If "full" is false,
-// then the directory names for "a" and "b" are only compared if
-// they are both non-empty. This allows a FileSpec object to only
-// contain a filename and it can match FileSpec objects that have
-// matching filenames with different paths.
-//
-// Return -1 if the "a" is less than "b", 0 if "a" is equal to "b"
-// and "1" if "a" is greater than "b".
-//------------------------------------------------------------------
-int FileSpec::Compare(const FileSpec &a, const FileSpec &b, bool full) {
- int result = 0;
-
- // case sensitivity of compare
- const bool case_sensitive = a.IsCaseSensitive() || b.IsCaseSensitive();
-
- // If full is true, then we must compare both the directory and filename.
-
- // If full is false, then if either directory is empty, then we match on
- // the basename only, and if both directories have valid values, we still
- // do a full compare. This allows for matching when we just have a filename
- // in one of the FileSpec objects.
-
- if (full || (a.m_directory && b.m_directory)) {
- result = ConstString::Compare(a.m_directory, b.m_directory, case_sensitive);
- if (result)
- return result;
- }
- return ConstString::Compare(a.m_filename, b.m_filename, case_sensitive);
-}
-
-bool FileSpec::Equal(const FileSpec &a, const FileSpec &b, bool full,
- bool remove_backups) {
- // case sensitivity of equality test
- const bool case_sensitive = a.IsCaseSensitive() || b.IsCaseSensitive();
-
- if (!full && (a.GetDirectory().IsEmpty() || b.GetDirectory().IsEmpty()))
- return ConstString::Equals(a.m_filename, b.m_filename, case_sensitive);
-
- if (remove_backups == false)
- return a == b;
-
- if (a == b)
- return true;
-
- return Equal(a.GetNormalizedPath(), b.GetNormalizedPath(), full, false);
-}
-
-FileSpec FileSpec::GetNormalizedPath() const {
- // Fast path. Do nothing if the path is not interesting.
- if (!m_directory.GetStringRef().contains(".") &&
- !m_directory.GetStringRef().contains("//") &&
- m_filename.GetStringRef() != ".." && m_filename.GetStringRef() != ".")
- return *this;
-
- llvm::SmallString<64> path, result;
- const bool normalize = false;
- GetPath(path, normalize);
- llvm::StringRef rest(path);
-
- // We will not go below root dir.
- size_t root_dir_start = RootDirStart(path, m_syntax);
- const bool absolute = root_dir_start != llvm::StringRef::npos;
- if (absolute) {
- result += rest.take_front(root_dir_start + 1);
- rest = rest.drop_front(root_dir_start + 1);
- } else {
- if (m_syntax == ePathSyntaxWindows && path.size() > 2 && path[1] == ':') {
- result += rest.take_front(2);
- rest = rest.drop_front(2);
- }
- }
-
- bool anything_added = false;
- llvm::SmallVector<llvm::StringRef, 0> components, processed;
- rest.split(components, '/', -1, false);
- processed.reserve(components.size());
- for (auto component : components) {
- if (component == ".")
- continue; // Skip these.
- if (component != "..") {
- processed.push_back(component);
- continue; // Regular file name.
- }
- if (!processed.empty()) {
- processed.pop_back();
- continue; // Dots. Go one level up if we can.
- }
- if (absolute)
- continue; // We're at the top level. Cannot go higher than that. Skip.
-
- result += component; // We're a relative path. We need to keep these.
- result += '/';
- anything_added = true;
- }
- for (auto component : processed) {
- result += component;
- result += '/';
- anything_added = true;
- }
- if (anything_added)
- result.pop_back(); // Pop last '/'.
- else if (result.empty())
- result = ".";
-
- return FileSpec(result, false, m_syntax);
-}
-
-//------------------------------------------------------------------
-// Dump the object to the supplied stream. If the object contains
-// a valid directory name, it will be displayed followed by a
-// directory delimiter, and the filename.
-//------------------------------------------------------------------
-void FileSpec::Dump(Stream *s) const {
- if (s) {
- std::string path{GetPath(true)};
- s->PutCString(path);
- char path_separator = GetPreferredPathSeparator(m_syntax);
- if (!m_filename && !path.empty() && path.back() != path_separator)
- s->PutChar(path_separator);
- }
-}
-
-//------------------------------------------------------------------
-// Returns true if the file exists.
-//------------------------------------------------------------------
-bool FileSpec::Exists() const {
- struct stat file_stats;
- return GetFileStats(this, &file_stats);
-}
-
-bool FileSpec::Readable() const {
- const uint32_t permissions = GetPermissions();
- if (permissions & eFilePermissionsEveryoneR)
- return true;
- return false;
-}
-
-bool FileSpec::ResolveExecutableLocation() {
- // CLEANUP: Use StringRef for string handling.
- if (!m_directory) {
- const char *file_cstr = m_filename.GetCString();
- if (file_cstr) {
- const std::string file_str(file_cstr);
- llvm::ErrorOr<std::string> error_or_path =
- llvm::sys::findProgramByName(file_str);
- if (!error_or_path)
- return false;
- std::string path = error_or_path.get();
- llvm::StringRef dir_ref = llvm::sys::path::parent_path(path);
- if (!dir_ref.empty()) {
- // FindProgramByName returns "." if it can't find the file.
- if (strcmp(".", dir_ref.data()) == 0)
- return false;
-
- m_directory.SetCString(dir_ref.data());
- if (Exists())
- return true;
- else {
- // If FindProgramByName found the file, it returns the directory +
- // filename in its return results.
- // We need to separate them.
- FileSpec tmp_file(dir_ref.data(), false);
- if (tmp_file.Exists()) {
- m_directory = tmp_file.m_directory;
- return true;
- }
- }
- }
- }
- }
-
- return false;
-}
-
-bool FileSpec::ResolvePath() {
- if (m_is_resolved)
- return true; // We have already resolved this path
-
- char path_buf[PATH_MAX];
- if (!GetPath(path_buf, PATH_MAX, false))
- return false;
- // SetFile(...) will set m_is_resolved correctly if it can resolve the path
- SetFile(path_buf, true);
- return m_is_resolved;
-}
-
-uint64_t FileSpec::GetByteSize() const {
- struct stat file_stats;
- if (GetFileStats(this, &file_stats))
- return file_stats.st_size;
- return 0;
-}
-
-FileSpec::PathSyntax FileSpec::GetPathSyntax() const { return m_syntax; }
-
-FileSpec::FileType FileSpec::GetFileType() const {
- struct stat file_stats;
- if (GetFileStats(this, &file_stats)) {
- mode_t file_type = file_stats.st_mode & S_IFMT;
- switch (file_type) {
- case S_IFDIR:
- return eFileTypeDirectory;
- case S_IFREG:
- return eFileTypeRegular;
-#ifndef _WIN32
- case S_IFIFO:
- return eFileTypePipe;
- case S_IFSOCK:
- return eFileTypeSocket;
- case S_IFLNK:
- return eFileTypeSymbolicLink;
-#endif
- default:
- break;
- }
- return eFileTypeUnknown;
- }
- return eFileTypeInvalid;
-}
-
-bool FileSpec::IsSymbolicLink() const {
- char resolved_path[PATH_MAX];
- if (!GetPath(resolved_path, sizeof(resolved_path)))
- return false;
-
-#ifdef _WIN32
- std::wstring wpath;
- if (!llvm::ConvertUTF8toWide(resolved_path, wpath))
- return false;
- auto attrs = ::GetFileAttributesW(wpath.c_str());
- if (attrs == INVALID_FILE_ATTRIBUTES)
- return false;
-
- return (attrs & FILE_ATTRIBUTE_REPARSE_POINT);
-#else
- struct stat file_stats;
- if (::lstat(resolved_path, &file_stats) != 0)
- return false;
-
- return (file_stats.st_mode & S_IFMT) == S_IFLNK;
-#endif
-}
-
-uint32_t FileSpec::GetPermissions() const {
- uint32_t file_permissions = 0;
- if (*this)
- FileSystem::GetFilePermissions(*this, file_permissions);
- return file_permissions;
-}
-
-//------------------------------------------------------------------
-// Directory string get accessor.
-//------------------------------------------------------------------
-ConstString &FileSpec::GetDirectory() { return m_directory; }
-
-//------------------------------------------------------------------
-// Directory string const get accessor.
-//------------------------------------------------------------------
-const ConstString &FileSpec::GetDirectory() const { return m_directory; }
-
-//------------------------------------------------------------------
-// Filename string get accessor.
-//------------------------------------------------------------------
-ConstString &FileSpec::GetFilename() { return m_filename; }
-
-//------------------------------------------------------------------
-// Filename string const get accessor.
-//------------------------------------------------------------------
-const ConstString &FileSpec::GetFilename() const { return m_filename; }
-
-//------------------------------------------------------------------
-// Extract the directory and path into a fixed buffer. This is
-// needed as the directory and path are stored in separate string
-// values.
-//------------------------------------------------------------------
-size_t FileSpec::GetPath(char *path, size_t path_max_len,
- bool denormalize) const {
- if (!path)
- return 0;
-
- std::string result = GetPath(denormalize);
- ::snprintf(path, path_max_len, "%s", result.c_str());
- return std::min(path_max_len - 1, result.length());
-}
-
-std::string FileSpec::GetPath(bool denormalize) const {
- llvm::SmallString<64> result;
- GetPath(result, denormalize);
- return std::string(result.begin(), result.end());
-}
-
-const char *FileSpec::GetCString(bool denormalize) const {
- return ConstString{GetPath(denormalize)}.AsCString(NULL);
-}
-
-void FileSpec::GetPath(llvm::SmallVectorImpl<char> &path,
- bool denormalize) const {
- path.append(m_directory.GetStringRef().begin(),
- m_directory.GetStringRef().end());
- if (m_directory && m_filename &&
- !IsPathSeparator(m_directory.GetStringRef().back(), m_syntax))
- path.insert(path.end(), GetPreferredPathSeparator(m_syntax));
- path.append(m_filename.GetStringRef().begin(),
- m_filename.GetStringRef().end());
- Normalize(path, m_syntax);
- if (denormalize && !path.empty())
- Denormalize(path, m_syntax);
-}
-
-ConstString FileSpec::GetFileNameExtension() const {
- if (m_filename) {
- const char *filename = m_filename.GetCString();
- const char *dot_pos = strrchr(filename, '.');
- if (dot_pos && dot_pos[1] != '\0')
- return ConstString(dot_pos + 1);
- }
- return ConstString();
-}
-
-ConstString FileSpec::GetFileNameStrippingExtension() const {
- const char *filename = m_filename.GetCString();
- if (filename == NULL)
- return ConstString();
-
- const char *dot_pos = strrchr(filename, '.');
- if (dot_pos == NULL)
- return m_filename;
-
- return ConstString(filename, dot_pos - filename);
-}
-
-//------------------------------------------------------------------
-// Returns a shared pointer to a data buffer that contains all or
-// part of the contents of a file. The data is memory mapped and
-// will lazily page in data from the file as memory is accessed.
-// The data that is mapped will start "file_offset" bytes into the
-// file, and "file_size" bytes will be mapped. If "file_size" is
-// greater than the number of bytes available in the file starting
-// at "file_offset", the number of bytes will be appropriately
-// truncated. The final number of bytes that get mapped can be
-// verified using the DataBuffer::GetByteSize() function.
-//------------------------------------------------------------------
-DataBufferSP FileSpec::MemoryMapFileContents(off_t file_offset,
- size_t file_size) const {
- DataBufferSP data_sp;
- std::unique_ptr<DataBufferMemoryMap> mmap_data(new DataBufferMemoryMap());
- if (mmap_data.get()) {
- const size_t mapped_length =
- mmap_data->MemoryMapFromFileSpec(this, file_offset, file_size);
- if (((file_size == SIZE_MAX) && (mapped_length > 0)) ||
- (mapped_length >= file_size))
- data_sp.reset(mmap_data.release());
- }
- return data_sp;
-}
-
-DataBufferSP FileSpec::MemoryMapFileContentsIfLocal(off_t file_offset,
- size_t file_size) const {
- if (FileSystem::IsLocal(*this))
- return MemoryMapFileContents(file_offset, file_size);
- else
- return ReadFileContents(file_offset, file_size, NULL);
-}
-
-//------------------------------------------------------------------
-// Return the size in bytes that this object takes in memory. This
-// returns the size in bytes of this object, not any shared string
-// values it may refer to.
-//------------------------------------------------------------------
-size_t FileSpec::MemorySize() const {
- return m_filename.MemorySize() + m_directory.MemorySize();
-}
-
-size_t FileSpec::ReadFileContents(off_t file_offset, void *dst, size_t dst_len,
- Error *error_ptr) const {
- Error error;
- size_t bytes_read = 0;
- char resolved_path[PATH_MAX];
- if (GetPath(resolved_path, sizeof(resolved_path))) {
- File file;
- error = file.Open(resolved_path, File::eOpenOptionRead);
- if (error.Success()) {
- off_t file_offset_after_seek = file_offset;
- bytes_read = dst_len;
- error = file.Read(dst, bytes_read, file_offset_after_seek);
- }
- } else {
- error.SetErrorString("invalid file specification");
- }
- if (error_ptr)
- *error_ptr = error;
- return bytes_read;
-}
-
-//------------------------------------------------------------------
-// Returns a shared pointer to a data buffer that contains all or
-// part of the contents of a file. The data copies into a heap based
-// buffer that lives in the DataBuffer shared pointer object returned.
-// The data that is cached will start "file_offset" bytes into the
-// file, and "file_size" bytes will be mapped. If "file_size" is
-// greater than the number of bytes available in the file starting
-// at "file_offset", the number of bytes will be appropriately
-// truncated. The final number of bytes that get mapped can be
-// verified using the DataBuffer::GetByteSize() function.
-//------------------------------------------------------------------
-DataBufferSP FileSpec::ReadFileContents(off_t file_offset, size_t file_size,
- Error *error_ptr) const {
- Error error;
- DataBufferSP data_sp;
- char resolved_path[PATH_MAX];
- if (GetPath(resolved_path, sizeof(resolved_path))) {
- File file;
- error = file.Open(resolved_path, File::eOpenOptionRead);
- if (error.Success()) {
- const bool null_terminate = false;
- error = file.Read(file_size, file_offset, null_terminate, data_sp);
- }
- } else {
- error.SetErrorString("invalid file specification");
- }
- if (error_ptr)
- *error_ptr = error;
- return data_sp;
-}
-
-DataBufferSP FileSpec::ReadFileContentsAsCString(Error *error_ptr) {
- Error error;
- DataBufferSP data_sp;
- char resolved_path[PATH_MAX];
- if (GetPath(resolved_path, sizeof(resolved_path))) {
- File file;
- error = file.Open(resolved_path, File::eOpenOptionRead);
- if (error.Success()) {
- off_t offset = 0;
- size_t length = SIZE_MAX;
- const bool null_terminate = true;
- error = file.Read(length, offset, null_terminate, data_sp);
- }
- } else {
- error.SetErrorString("invalid file specification");
- }
- if (error_ptr)
- *error_ptr = error;
- return data_sp;
-}
-
-size_t FileSpec::ReadFileLines(STLStringArray &lines) {
- lines.clear();
- char path[PATH_MAX];
- if (GetPath(path, sizeof(path))) {
- std::ifstream file_stream(path);
-
- if (file_stream) {
- std::string line;
- while (getline(file_stream, line))
- lines.push_back(line);
- }
- }
- return lines.size();
-}
-
-FileSpec::EnumerateDirectoryResult
-FileSpec::ForEachItemInDirectory(llvm::StringRef dir_path,
- DirectoryCallback const &callback) {
- if (dir_path.empty())
- return eEnumerateDirectoryResultNext;
-
-#ifdef _WIN32
- std::string szDir(dir_path);
- szDir += "\\*";
-
- std::wstring wszDir;
- if (!llvm::ConvertUTF8toWide(szDir, wszDir)) {
- return eEnumerateDirectoryResultNext;
- }
-
- WIN32_FIND_DATAW ffd;
- HANDLE hFind = FindFirstFileW(wszDir.c_str(), &ffd);
-
- if (hFind == INVALID_HANDLE_VALUE) {
- return eEnumerateDirectoryResultNext;
- }
-
- do {
- FileSpec::FileType file_type = eFileTypeUnknown;
- if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
- size_t len = wcslen(ffd.cFileName);
-
- if (len == 1 && ffd.cFileName[0] == L'.')
- continue;
-
- if (len == 2 && ffd.cFileName[0] == L'.' && ffd.cFileName[1] == L'.')
- continue;
-
- file_type = eFileTypeDirectory;
- } else if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DEVICE) {
- file_type = eFileTypeOther;
- } else {
- file_type = eFileTypeRegular;
- }
-
- std::string fileName;
- if (!llvm::convertWideToUTF8(ffd.cFileName, fileName)) {
- continue;
- }
-
- std::string child_path = llvm::join_items("\\", dir_path, fileName);
- // Don't resolve the file type or path
- FileSpec child_path_spec(child_path.data(), false);
-
- EnumerateDirectoryResult result = callback(file_type, child_path_spec);
-
- switch (result) {
- case eEnumerateDirectoryResultNext:
- // Enumerate next entry in the current directory. We just
- // exit this switch and will continue enumerating the
- // current directory as we currently are...
- break;
-
- case eEnumerateDirectoryResultEnter: // Recurse into the current entry
- // if it is a directory or symlink,
- // or next if not
- if (FileSpec::ForEachItemInDirectory(child_path.data(), callback) ==
- eEnumerateDirectoryResultQuit) {
- // The subdirectory returned Quit, which means to
- // stop all directory enumerations at all levels.
- return eEnumerateDirectoryResultQuit;
- }
- break;
-
- case eEnumerateDirectoryResultExit: // Exit from the current directory
- // at the current level.
- // Exit from this directory level and tell parent to
- // keep enumerating.
- return eEnumerateDirectoryResultNext;
-
- case eEnumerateDirectoryResultQuit: // Stop directory enumerations at
- // any level
- return eEnumerateDirectoryResultQuit;
- }
- } while (FindNextFileW(hFind, &ffd) != 0);
-
- FindClose(hFind);
-#else
- std::string dir_string(dir_path);
- lldb_utility::CleanUp<DIR *, int> dir_path_dir(opendir(dir_string.c_str()),
- NULL, closedir);
- if (dir_path_dir.is_valid()) {
- char dir_path_last_char = dir_path.back();
-
- long path_max = fpathconf(dirfd(dir_path_dir.get()), _PC_NAME_MAX);
-#if defined(__APPLE_) && defined(__DARWIN_MAXPATHLEN)
- if (path_max < __DARWIN_MAXPATHLEN)
- path_max = __DARWIN_MAXPATHLEN;
-#endif
- struct dirent *buf, *dp;
- buf = (struct dirent *)malloc(offsetof(struct dirent, d_name) + path_max +
- 1);
-
- while (buf && readdir_r(dir_path_dir.get(), buf, &dp) == 0 && dp) {
- // Only search directories
- if (dp->d_type == DT_DIR || dp->d_type == DT_UNKNOWN) {
- size_t len = strlen(dp->d_name);
-
- if (len == 1 && dp->d_name[0] == '.')
- continue;
-
- if (len == 2 && dp->d_name[0] == '.' && dp->d_name[1] == '.')
- continue;
- }
-
- FileSpec::FileType file_type = eFileTypeUnknown;
-
- switch (dp->d_type) {
- default:
- case DT_UNKNOWN:
- file_type = eFileTypeUnknown;
- break;
- case DT_FIFO:
- file_type = eFileTypePipe;
- break;
- case DT_CHR:
- file_type = eFileTypeOther;
- break;
- case DT_DIR:
- file_type = eFileTypeDirectory;
- break;
- case DT_BLK:
- file_type = eFileTypeOther;
- break;
- case DT_REG:
- file_type = eFileTypeRegular;
- break;
- case DT_LNK:
- file_type = eFileTypeSymbolicLink;
- break;
- case DT_SOCK:
- file_type = eFileTypeSocket;
- break;
-#if !defined(__OpenBSD__)
- case DT_WHT:
- file_type = eFileTypeOther;
- break;
-#endif
- }
-
- std::string child_path;
- // Don't make paths with "/foo//bar", that just confuses everybody.
- if (dir_path_last_char == '/')
- child_path = llvm::join_items("", dir_path, dp->d_name);
- else
- child_path = llvm::join_items('/', dir_path, dp->d_name);
-
- // Don't resolve the file type or path
- FileSpec child_path_spec(child_path, false);
-
- EnumerateDirectoryResult result =
- callback(file_type, child_path_spec);
-
- switch (result) {
- case eEnumerateDirectoryResultNext:
- // Enumerate next entry in the current directory. We just
- // exit this switch and will continue enumerating the
- // current directory as we currently are...
- break;
-
- case eEnumerateDirectoryResultEnter: // Recurse into the current entry
- // if it is a directory or
- // symlink, or next if not
- if (FileSpec::ForEachItemInDirectory(child_path, callback) ==
- eEnumerateDirectoryResultQuit) {
- // The subdirectory returned Quit, which means to
- // stop all directory enumerations at all levels.
- if (buf)
- free(buf);
- return eEnumerateDirectoryResultQuit;
- }
- break;
-
- case eEnumerateDirectoryResultExit: // Exit from the current directory
- // at the current level.
- // Exit from this directory level and tell parent to
- // keep enumerating.
- if (buf)
- free(buf);
- return eEnumerateDirectoryResultNext;
-
- case eEnumerateDirectoryResultQuit: // Stop directory enumerations at
- // any level
- if (buf)
- free(buf);
- return eEnumerateDirectoryResultQuit;
- }
- }
- if (buf) {
- free(buf);
- }
- }
-#endif
- // By default when exiting a directory, we tell the parent enumeration
- // to continue enumerating.
- return eEnumerateDirectoryResultNext;
-}
-
-FileSpec::EnumerateDirectoryResult
-FileSpec::EnumerateDirectory(llvm::StringRef dir_path, bool find_directories,
- bool find_files, bool find_other,
- EnumerateDirectoryCallbackType callback,
- void *callback_baton) {
- return ForEachItemInDirectory(
- dir_path,
- [&find_directories, &find_files, &find_other, &callback,
- &callback_baton](FileType file_type, const FileSpec &file_spec) {
- switch (file_type) {
- case FileType::eFileTypeDirectory:
- if (find_directories)
- return callback(callback_baton, file_type, file_spec);
- break;
- case FileType::eFileTypeRegular:
- if (find_files)
- return callback(callback_baton, file_type, file_spec);
- break;
- default:
- if (find_other)
- return callback(callback_baton, file_type, file_spec);
- break;
- }
- return eEnumerateDirectoryResultNext;
- });
-}
-
-FileSpec
-FileSpec::CopyByAppendingPathComponent(llvm::StringRef component) const {
- FileSpec ret = *this;
- ret.AppendPathComponent(component);
- return ret;
-}
-
-FileSpec FileSpec::CopyByRemovingLastPathComponent() const {
- // CLEANUP: Use StringRef for string handling.
- const bool resolve = false;
- if (m_filename.IsEmpty() && m_directory.IsEmpty())
- return FileSpec("", resolve);
- if (m_directory.IsEmpty())
- return FileSpec("", resolve);
- if (m_filename.IsEmpty()) {
- const char *dir_cstr = m_directory.GetCString();
- const char *last_slash_ptr = ::strrchr(dir_cstr, '/');
-
- // check for obvious cases before doing the full thing
- if (!last_slash_ptr)
- return FileSpec("", resolve);
- if (last_slash_ptr == dir_cstr)
- return FileSpec("/", resolve);
-
- size_t last_slash_pos = last_slash_ptr - dir_cstr + 1;
- ConstString new_path(dir_cstr, last_slash_pos);
- return FileSpec(new_path.GetCString(), resolve);
- } else
- return FileSpec(m_directory.GetCString(), resolve);
-}
-
-ConstString FileSpec::GetLastPathComponent() const {
- // CLEANUP: Use StringRef for string handling.
- if (m_filename)
- return m_filename;
- if (m_directory) {
- const char *dir_cstr = m_directory.GetCString();
- const char *last_slash_ptr = ::strrchr(dir_cstr, '/');
- if (last_slash_ptr == NULL)
- return m_directory;
- if (last_slash_ptr == dir_cstr) {
- if (last_slash_ptr[1] == 0)
- return ConstString(last_slash_ptr);
- else
- return ConstString(last_slash_ptr + 1);
- }
- if (last_slash_ptr[1] != 0)
- return ConstString(last_slash_ptr + 1);
- const char *penultimate_slash_ptr = last_slash_ptr;
- while (*penultimate_slash_ptr) {
- --penultimate_slash_ptr;
- if (penultimate_slash_ptr == dir_cstr)
- break;
- if (*penultimate_slash_ptr == '/')
- break;
- }
- ConstString result(penultimate_slash_ptr + 1,
- last_slash_ptr - penultimate_slash_ptr);
- return result;
- }
- return ConstString();
-}
-
-void FileSpec::PrependPathComponent(llvm::StringRef component) {
- if (component.empty())
- return;
-
- const bool resolve = false;
- if (m_filename.IsEmpty() && m_directory.IsEmpty()) {
- SetFile(component, resolve);
- return;
- }
-
- char sep = GetPreferredPathSeparator(m_syntax);
- std::string result;
- if (m_filename.IsEmpty())
- result = llvm::join_items(sep, component, m_directory.GetStringRef());
- else if (m_directory.IsEmpty())
- result = llvm::join_items(sep, component, m_filename.GetStringRef());
- else
- result = llvm::join_items(sep, component, m_directory.GetStringRef(),
- m_filename.GetStringRef());
-
- SetFile(result, resolve);
-}
-
-void FileSpec::PrependPathComponent(const FileSpec &new_path) {
- return PrependPathComponent(new_path.GetPath(false));
-}
-
-void FileSpec::AppendPathComponent(llvm::StringRef component) {
- if (component.empty())
- return;
-
- std::string result;
- if (!m_directory.IsEmpty()) {
- result += m_directory.GetStringRef();
- if (!IsPathSeparator(m_directory.GetStringRef().back(), m_syntax))
- result += GetPreferredPathSeparator(m_syntax);
- }
-
- if (!m_filename.IsEmpty()) {
- result += m_filename.GetStringRef();
- if (!IsPathSeparator(m_filename.GetStringRef().back(), m_syntax))
- result += GetPreferredPathSeparator(m_syntax);
- }
-
- component = component.drop_while(
- [this](char c) { return IsPathSeparator(c, m_syntax); });
-
- result += component;
-
- SetFile(result, false, m_syntax);
-}
-
-void FileSpec::AppendPathComponent(const FileSpec &new_path) {
- return AppendPathComponent(new_path.GetPath(false));
-}
-
-void FileSpec::RemoveLastPathComponent() {
- // CLEANUP: Use StringRef for string handling.
-
- const bool resolve = false;
- if (m_filename.IsEmpty() && m_directory.IsEmpty()) {
- SetFile("", resolve);
- return;
- }
- if (m_directory.IsEmpty()) {
- SetFile("", resolve);
- return;
- }
- if (m_filename.IsEmpty()) {
- const char *dir_cstr = m_directory.GetCString();
- const char *last_slash_ptr = ::strrchr(dir_cstr, '/');
-
- // check for obvious cases before doing the full thing
- if (!last_slash_ptr) {
- SetFile("", resolve);
- return;
- }
- if (last_slash_ptr == dir_cstr) {
- SetFile("/", resolve);
- return;
- }
- size_t last_slash_pos = last_slash_ptr - dir_cstr + 1;
- ConstString new_path(dir_cstr, last_slash_pos);
- SetFile(new_path.GetCString(), resolve);
- } else
- SetFile(m_directory.GetCString(), resolve);
-}
-//------------------------------------------------------------------
-/// Returns true if the filespec represents an implementation source
-/// file (files with a ".c", ".cpp", ".m", ".mm" (many more)
-/// extension).
-///
-/// @return
-/// \b true if the filespec represents an implementation source
-/// file, \b false otherwise.
-//------------------------------------------------------------------
-bool FileSpec::IsSourceImplementationFile() const {
- ConstString extension(GetFileNameExtension());
- if (!extension)
- return false;
-
- static RegularExpression g_source_file_regex(llvm::StringRef(
- "^([cC]|[mM]|[mM][mM]|[cC][pP][pP]|[cC]\\+\\+|[cC][xX][xX]|[cC][cC]|["
- "cC][pP]|[sS]|[aA][sS][mM]|[fF]|[fF]77|[fF]90|[fF]95|[fF]03|[fF][oO]["
- "rR]|[fF][tT][nN]|[fF][pP][pP]|[aA][dD][aA]|[aA][dD][bB]|[aA][dD][sS])"
- "$"));
- return g_source_file_regex.Execute(extension.GetStringRef());
-}
-
-bool FileSpec::IsRelative() const {
- const char *dir = m_directory.GetCString();
- llvm::StringRef directory(dir ? dir : "");
-
- if (directory.size() > 0) {
- if (PathSyntaxIsPosix(m_syntax)) {
- // If the path doesn't start with '/' or '~', return true
- switch (directory[0]) {
- case '/':
- case '~':
- return false;
- default:
- return true;
- }
- } else {
- if (directory.size() >= 2 && directory[1] == ':')
- return false;
- if (directory[0] == '/')
- return false;
- return true;
- }
- } else if (m_filename) {
- // No directory, just a basename, return true
- return true;
- }
- return false;
-}
-
-bool FileSpec::IsAbsolute() const { return !FileSpec::IsRelative(); }
-
-void llvm::format_provider<FileSpec>::format(const FileSpec &F,
- raw_ostream &Stream,
- StringRef Style) {
- assert(
- (Style.empty() || Style.equals_lower("F") || Style.equals_lower("D")) &&
- "Invalid FileSpec style!");
-
- StringRef dir = F.GetDirectory().GetStringRef();
- StringRef file = F.GetFilename().GetStringRef();
-
- if (dir.empty() && file.empty()) {
- Stream << "(empty)";
- return;
- }
-
- if (Style.equals_lower("F")) {
- Stream << (file.empty() ? "(empty)" : file);
- return;
- }
-
- // Style is either D or empty, either way we need to print the directory.
- if (!dir.empty()) {
- // Directory is stored in normalized form, which might be different
- // than preferred form. In order to handle this, we need to cut off
- // the filename, then denormalize, then write the entire denorm'ed
- // directory.
- llvm::SmallString<64> denormalized_dir = dir;
- Denormalize(denormalized_dir, F.GetPathSyntax());
- Stream << denormalized_dir;
- Stream << GetPreferredPathSeparator(F.GetPathSyntax());
- }
-
- if (Style.equals_lower("D")) {
- // We only want to print the directory, so now just exit.
- if (dir.empty())
- Stream << "(empty)";
- return;
- }
-
- if (!file.empty())
- Stream << file;
-}
diff --git a/source/Host/common/FileSystem.cpp b/source/Host/common/FileSystem.cpp
index 88f29b46f360..4472aece1daa 100644
--- a/source/Host/common/FileSystem.cpp
+++ b/source/Host/common/FileSystem.cpp
@@ -10,7 +10,6 @@
#include "lldb/Host/FileSystem.h"
#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/MD5.h"
#include <algorithm>
#include <fstream>
@@ -19,79 +18,6 @@
using namespace lldb;
using namespace lldb_private;
-namespace {
-
-bool CalcMD5(const FileSpec &file_spec, uint64_t offset, uint64_t length,
- llvm::MD5::MD5Result &md5_result) {
- llvm::MD5 md5_hash;
- std::ifstream file(file_spec.GetPath(), std::ios::binary);
- if (!file.is_open())
- return false;
-
- if (offset > 0)
- file.seekg(offset, file.beg);
-
- std::vector<char> read_buf(4096);
- uint64_t total_read_bytes = 0;
- while (!file.eof()) {
- const uint64_t to_read =
- (length > 0) ? std::min(static_cast<uint64_t>(read_buf.size()),
- length - total_read_bytes)
- : read_buf.size();
- if (to_read == 0)
- break;
-
- file.read(&read_buf[0], to_read);
- const auto read_bytes = file.gcount();
- if (read_bytes == 0)
- break;
-
- md5_hash.update(llvm::StringRef(&read_buf[0], read_bytes));
- total_read_bytes += read_bytes;
- }
-
- md5_hash.final(md5_result);
- return true;
-}
-
-} // namespace
-
-bool FileSystem::CalculateMD5(const FileSpec &file_spec, uint64_t &low,
- uint64_t &high) {
- return CalculateMD5(file_spec, 0, 0, low, high);
-}
-
-bool FileSystem::CalculateMD5(const FileSpec &file_spec, uint64_t offset,
- uint64_t length, uint64_t &low, uint64_t &high) {
- llvm::MD5::MD5Result md5_result;
- if (!CalcMD5(file_spec, offset, length, md5_result))
- return false;
-
- const auto uint64_res = reinterpret_cast<const uint64_t *>(md5_result);
- high = uint64_res[0];
- low = uint64_res[1];
-
- return true;
-}
-
-bool FileSystem::CalculateMD5AsString(const FileSpec &file_spec,
- std::string &digest_str) {
- return CalculateMD5AsString(file_spec, 0, 0, digest_str);
-}
-
-bool FileSystem::CalculateMD5AsString(const FileSpec &file_spec,
- uint64_t offset, uint64_t length,
- std::string &digest_str) {
- llvm::MD5::MD5Result md5_result;
- if (!CalcMD5(file_spec, offset, length, md5_result))
- return false;
-
- llvm::SmallString<32> result_str;
- llvm::MD5::stringifyResult(md5_result, result_str);
- digest_str = result_str.c_str();
- return true;
-}
-
llvm::sys::TimePoint<>
FileSystem::GetModificationTime(const FileSpec &file_spec) {
llvm::sys::fs::file_status status;
diff --git a/source/Host/common/Host.cpp b/source/Host/common/Host.cpp
index 6d0ad0175fd8..7754d96ad331 100644
--- a/source/Host/common/Host.cpp
+++ b/source/Host/common/Host.cpp
@@ -28,7 +28,8 @@
#endif
#if defined(__linux__) || defined(__FreeBSD__) || \
- defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__NetBSD__)
+ defined(__FreeBSD_kernel__) || defined(__APPLE__) || \
+ defined(__NetBSD__) || defined(__OpenBSD__)
#if !defined(__ANDROID__)
#include <spawn.h>
#endif
@@ -40,16 +41,16 @@
#include <pthread_np.h>
#endif
+#if defined(__NetBSD__)
+#include <lwp.h>
+#endif
+
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Core/ArchSpec.h"
-#include "lldb/Core/Error.h"
-#include "lldb/Core/Log.h"
-#include "lldb/Host/FileSpec.h"
-#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/HostProcess.h"
@@ -61,14 +62,18 @@
#include "lldb/Target/ProcessLaunchInfo.h"
#include "lldb/Target/UnixSignals.h"
#include "lldb/Utility/CleanUp.h"
+#include "lldb/Utility/DataBufferLLVM.h"
+#include "lldb/Utility/Error.h"
+#include "lldb/Utility/FileSpec.h"
+#include "lldb/Utility/Log.h"
#include "lldb/lldb-private-forward.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/FileSystem.h"
#if defined(_WIN32)
#include "lldb/Host/windows/ProcessLauncherWindows.h"
-#elif defined(__linux__)
-#include "lldb/Host/linux/ProcessLauncherLinux.h"
+#elif defined(__linux__) || defined(__NetBSD__)
+#include "lldb/Host/posix/ProcessLauncherPosixFork.h"
#else
#include "lldb/Host/posix/ProcessLauncherPosix.h"
#endif
@@ -180,7 +185,7 @@ static thread_result_t MonitorChildProcessThreadFunction(void *arg) {
delete info;
int status = -1;
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__)
#define __WALL 0
#endif
const int options = __WALL;
@@ -310,25 +315,6 @@ lldb::pid_t Host::GetCurrentProcessID() { return ::getpid(); }
#ifndef _WIN32
-lldb::tid_t Host::GetCurrentThreadID() {
-#if defined(__APPLE__)
- // Calling "mach_thread_self()" bumps the reference count on the thread
- // port, so we need to deallocate it. mach_task_self() doesn't bump the ref
- // count.
- thread_port_t thread_self = mach_thread_self();
- mach_port_deallocate(mach_task_self(), thread_self);
- return thread_self;
-#elif defined(__FreeBSD__)
- return lldb::tid_t(pthread_getthreadid_np());
-#elif defined(__ANDROID__)
- return lldb::tid_t(gettid());
-#elif defined(__linux__)
- return lldb::tid_t(syscall(SYS_gettid));
-#else
- return lldb::tid_t(pthread_self());
-#endif
-}
-
lldb::thread_t Host::GetCurrentThread() {
return lldb::thread_t(pthread_self());
}
@@ -601,23 +587,22 @@ Error Host::RunShellCommand(const Args &args, const FileSpec &working_dir,
error.SetErrorStringWithFormat(
"shell command output is too large to fit into a std::string");
} else {
- std::vector<char> command_output(file_size);
- output_file_spec.ReadFileContents(0, command_output.data(),
- file_size, &error);
+ auto Buffer =
+ DataBufferLLVM::CreateFromPath(output_file_spec.GetPath());
if (error.Success())
- command_output_ptr->assign(command_output.data(), file_size);
+ command_output_ptr->assign(Buffer->GetChars(),
+ Buffer->GetByteSize());
}
}
}
}
}
- if (FileSystem::GetFileExists(output_file_spec))
- FileSystem::Unlink(output_file_spec);
+ llvm::sys::fs::remove(output_file_spec.GetPath());
return error;
}
-// LaunchProcessPosixSpawn for Apple, Linux, FreeBSD and other GLIBC
+// LaunchProcessPosixSpawn for Apple, Linux, FreeBSD, NetBSD and other GLIBC
// systems
#if defined(__APPLE__) || defined(__linux__) || defined(__FreeBSD__) || \
@@ -679,10 +664,10 @@ Error Host::LaunchProcessPosixSpawn(const char *exe_path,
posix_spawnattr_t attr;
error.SetError(::posix_spawnattr_init(&attr), eErrorTypePOSIX);
- if (error.Fail() || log)
- error.PutToLog(log, "::posix_spawnattr_init ( &attr )");
- if (error.Fail())
+ if (error.Fail()) {
+ LLDB_LOG(log, "error: {0}, ::posix_spawnattr_init ( &attr )", error);
return error;
+ }
// Make a quick class that will cleanup the posix spawn attributes in case
// we return in the middle of this function.
@@ -694,7 +679,7 @@ Error Host::LaunchProcessPosixSpawn(const char *exe_path,
sigemptyset(&no_signals);
sigfillset(&all_signals);
::posix_spawnattr_setsigmask(&attr, &no_signals);
-#if defined(__linux__) || defined(__FreeBSD__)
+#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__)
::posix_spawnattr_setsigdefault(&attr, &no_signals);
#else
::posix_spawnattr_setsigdefault(&attr, &all_signals);
@@ -703,11 +688,12 @@ Error Host::LaunchProcessPosixSpawn(const char *exe_path,
short flags = GetPosixspawnFlags(launch_info);
error.SetError(::posix_spawnattr_setflags(&attr, flags), eErrorTypePOSIX);
- if (error.Fail() || log)
- error.PutToLog(log, "::posix_spawnattr_setflags ( &attr, flags=0x%8.8x )",
- flags);
- if (error.Fail())
+ if (error.Fail()) {
+ LLDB_LOG(log,
+ "error: {0}, ::posix_spawnattr_setflags ( &attr, flags={1:x} )",
+ error, flags);
return error;
+ }
// posix_spawnattr_setbinpref_np appears to be an Apple extension per:
// http://www.unix.com/man-page/OSX/3/posix_spawnattr_setbinpref_np/
@@ -734,10 +720,10 @@ Error Host::LaunchProcessPosixSpawn(const char *exe_path,
size_t ocount = 0;
error.SetError(::posix_spawnattr_setbinpref_np(&attr, 1, &cpu, &ocount),
eErrorTypePOSIX);
- if (error.Fail() || log)
- error.PutToLog(log, "::posix_spawnattr_setbinpref_np ( &attr, 1, "
- "cpu_type = 0x%8.8x, count => %llu )",
- cpu, (uint64_t)ocount);
+ if (error.Fail())
+ LLDB_LOG(log, "error: {0}, ::posix_spawnattr_setbinpref_np ( &attr, 1, "
+ "cpu_type = {1:x}, count => {2} )",
+ error, cpu, ocount);
if (error.Fail() || ocount != 1)
return error;
@@ -788,14 +774,14 @@ Error Host::LaunchProcessPosixSpawn(const char *exe_path,
#else
if (::getcwd(current_dir, sizeof(current_dir)) == NULL) {
error.SetError(errno, eErrorTypePOSIX);
- error.LogIfError(log, "unable to save the current directory");
+ LLDB_LOG(log, "error: {0}, unable to save the current directory", error);
return error;
}
if (::chdir(working_dir.GetCString()) == -1) {
error.SetError(errno, eErrorTypePOSIX);
- error.LogIfError(log, "unable to change working directory to %s",
- working_dir.GetCString());
+ LLDB_LOG(log, "error: {0}, unable to change working directory to {1}",
+ error, working_dir);
return error;
}
#endif
@@ -807,10 +793,12 @@ Error Host::LaunchProcessPosixSpawn(const char *exe_path,
posix_spawn_file_actions_t file_actions;
error.SetError(::posix_spawn_file_actions_init(&file_actions),
eErrorTypePOSIX);
- if (error.Fail() || log)
- error.PutToLog(log, "::posix_spawn_file_actions_init ( &file_actions )");
- if (error.Fail())
+ if (error.Fail()) {
+ LLDB_LOG(log,
+ "error: {0}, ::posix_spawn_file_actions_init ( &file_actions )",
+ error);
return error;
+ }
// Make a quick class that will cleanup the posix spawn attributes in case
// we return in the middle of this function.
@@ -832,16 +820,14 @@ Error Host::LaunchProcessPosixSpawn(const char *exe_path,
::posix_spawnp(&result_pid, exe_path, &file_actions, &attr, argv, envp),
eErrorTypePOSIX);
- if (error.Fail() || log) {
- error.PutToLog(
- log, "::posix_spawnp ( pid => %i, path = '%s', file_actions = %p, "
- "attr = %p, argv = %p, envp = %p )",
- result_pid, exe_path, static_cast<void *>(&file_actions),
- static_cast<void *>(&attr), reinterpret_cast<const void *>(argv),
- reinterpret_cast<const void *>(envp));
+ if (error.Fail()) {
+ LLDB_LOG(log, "error: {0}, ::posix_spawnp(pid => {1}, path = '{2}', "
+ "file_actions = {3}, "
+ "attr = {4}, argv = {5}, envp = {6} )",
+ error, result_pid, exe_path, &file_actions, &attr, argv, envp);
if (log) {
for (int ii = 0; argv[ii]; ++ii)
- log->Printf("argv[%i] = '%s'", ii, argv[ii]);
+ LLDB_LOG(log, "argv[{0}] = '{1}'", ii, argv[ii]);
}
}
@@ -850,16 +836,13 @@ Error Host::LaunchProcessPosixSpawn(const char *exe_path,
::posix_spawnp(&result_pid, exe_path, NULL, &attr, argv, envp),
eErrorTypePOSIX);
- if (error.Fail() || log) {
- error.PutToLog(log, "::posix_spawnp ( pid => %i, path = '%s', "
- "file_actions = NULL, attr = %p, argv = %p, envp = "
- "%p )",
- result_pid, exe_path, static_cast<void *>(&attr),
- reinterpret_cast<const void *>(argv),
- reinterpret_cast<const void *>(envp));
+ if (error.Fail()) {
+ LLDB_LOG(log, "error: {0}, ::posix_spawnp ( pid => {1}, path = '{2}', "
+ "file_actions = NULL, attr = {3}, argv = {4}, envp = {5} )",
+ error, result_pid, exe_path, &attr, argv, envp);
if (log) {
for (int ii = 0; argv[ii]; ++ii)
- log->Printf("argv[%i] = '%s'", ii, argv[ii]);
+ LLDB_LOG(log, "argv[{0}] = '{1}'", ii, argv[ii]);
}
}
}
@@ -872,8 +855,9 @@ Error Host::LaunchProcessPosixSpawn(const char *exe_path,
#else
if (::chdir(current_dir) == -1 && error.Success()) {
error.SetError(errno, eErrorTypePOSIX);
- error.LogIfError(log, "unable to change current directory back to %s",
- current_dir);
+ LLDB_LOG(log,
+ "error: {0}, unable to change current directory back to {1}",
+ error, current_dir);
}
#endif
}
@@ -902,10 +886,10 @@ bool Host::AddPosixSpawnFileAction(void *_file_actions, const FileAction *info,
error.SetError(
::posix_spawn_file_actions_addclose(file_actions, info->GetFD()),
eErrorTypePOSIX);
- if (log && (error.Fail() || log))
- error.PutToLog(log,
- "posix_spawn_file_actions_addclose (action=%p, fd=%i)",
- static_cast<void *>(file_actions), info->GetFD());
+ if (error.Fail())
+ LLDB_LOG(log, "error: {0}, posix_spawn_file_actions_addclose "
+ "(action={1}, fd={2})",
+ error, file_actions, info->GetFD());
}
break;
@@ -921,12 +905,10 @@ bool Host::AddPosixSpawnFileAction(void *_file_actions, const FileAction *info,
::posix_spawn_file_actions_adddup2(file_actions, info->GetFD(),
info->GetActionArgument()),
eErrorTypePOSIX);
- if (log && (error.Fail() || log))
- error.PutToLog(
- log,
- "posix_spawn_file_actions_adddup2 (action=%p, fd=%i, dup_fd=%i)",
- static_cast<void *>(file_actions), info->GetFD(),
- info->GetActionArgument());
+ if (error.Fail())
+ LLDB_LOG(log, "error: {0}, posix_spawn_file_actions_adddup2 "
+ "(action={1}, fd={2}, dup_fd={3})",
+ error, file_actions, info->GetFD(), info->GetActionArgument());
}
break;
@@ -946,11 +928,11 @@ bool Host::AddPosixSpawnFileAction(void *_file_actions, const FileAction *info,
file_actions, info->GetFD(),
info->GetPath().str().c_str(), oflag, mode),
eErrorTypePOSIX);
- if (error.Fail() || log)
- error.PutToLog(log, "posix_spawn_file_actions_addopen (action=%p, "
- "fd=%i, path='%s', oflag=%i, mode=%i)",
- static_cast<void *>(file_actions), info->GetFD(),
- info->GetPath().str().c_str(), oflag, mode);
+ if (error.Fail())
+ LLDB_LOG(
+ log, "error: {0}, posix_spawn_file_actions_addopen (action={1}, "
+ "fd={2}, path='{3}', oflag={4}, mode={5})",
+ error, file_actions, info->GetFD(), info->GetPath(), oflag, mode);
}
break;
}
@@ -969,8 +951,8 @@ Error Host::LaunchProcess(ProcessLaunchInfo &launch_info) {
std::unique_ptr<ProcessLauncher> delegate_launcher;
#if defined(_WIN32)
delegate_launcher.reset(new ProcessLauncherWindows());
-#elif defined(__linux__)
- delegate_launcher.reset(new ProcessLauncherLinux());
+#elif defined(__linux__) || defined(__NetBSD__)
+ delegate_launcher.reset(new ProcessLauncherPosixFork());
#else
delegate_launcher.reset(new ProcessLauncherPosix());
#endif
diff --git a/source/Host/common/HostInfoBase.cpp b/source/Host/common/HostInfoBase.cpp
index 01ac87047c5d..a6c9e91a98e8 100644
--- a/source/Host/common/HostInfoBase.cpp
+++ b/source/Host/common/HostInfoBase.cpp
@@ -10,21 +10,22 @@
#include "lldb/Host/Config.h"
#include "lldb/Core/ArchSpec.h"
-#include "lldb/Core/Log.h"
-#include "lldb/Core/StreamString.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/HostInfoBase.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/StreamString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/ScopedPrinter.h"
+#include "llvm/Support/Threading.h"
#include "llvm/Support/raw_ostream.h"
-#include <mutex> // std::once
+#include <mutex>
#include <thread>
using namespace lldb;
@@ -45,13 +46,10 @@ struct HostInfoBaseFields {
// 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.
- FileSystem::DeleteDirectory(m_lldb_process_tmp_dir, true);
+ llvm::sys::fs::remove_directories(m_lldb_process_tmp_dir.GetPath());
}
}
- uint32_t m_number_cpus;
- std::string m_vendor_string;
- std::string m_os_string;
std::string m_host_triple;
ArchSpec m_host_arch_32;
@@ -78,37 +76,9 @@ void HostInfoBase::Terminate() {
g_fields = nullptr;
}
-uint32_t HostInfoBase::GetNumberCPUS() {
- static std::once_flag g_once_flag;
- std::call_once(g_once_flag, []() {
- g_fields->m_number_cpus = std::thread::hardware_concurrency();
- });
- return g_fields->m_number_cpus;
-}
-
-uint32_t HostInfoBase::GetMaxThreadNameLength() { return 0; }
-
-llvm::StringRef HostInfoBase::GetVendorString() {
- static std::once_flag g_once_flag;
- std::call_once(g_once_flag, []() {
- g_fields->m_vendor_string =
- HostInfo::GetArchitecture().GetTriple().getVendorName().str();
- });
- return g_fields->m_vendor_string;
-}
-
-llvm::StringRef HostInfoBase::GetOSString() {
- static std::once_flag g_once_flag;
- std::call_once(g_once_flag, []() {
- g_fields->m_os_string =
- std::move(HostInfo::GetArchitecture().GetTriple().getOSName());
- });
- return g_fields->m_os_string;
-}
-
llvm::StringRef HostInfoBase::GetTargetTriple() {
- static std::once_flag g_once_flag;
- std::call_once(g_once_flag, []() {
+ static llvm::once_flag g_once_flag;
+ llvm::call_once(g_once_flag, []() {
g_fields->m_host_triple =
HostInfo::GetArchitecture().GetTriple().getTriple();
});
@@ -116,8 +86,8 @@ llvm::StringRef HostInfoBase::GetTargetTriple() {
}
const ArchSpec &HostInfoBase::GetArchitecture(ArchitectureKind arch_kind) {
- static std::once_flag g_once_flag;
- std::call_once(g_once_flag, []() {
+ static llvm::once_flag g_once_flag;
+ llvm::call_once(g_once_flag, []() {
HostInfo::ComputeHostArchitectureSupport(g_fields->m_host_arch_32,
g_fields->m_host_arch_64);
});
@@ -144,9 +114,9 @@ bool HostInfoBase::GetLLDBPath(lldb::PathType type, FileSpec &file_spec) {
FileSpec *result = nullptr;
switch (type) {
case lldb::ePathTypeLLDBShlibDir: {
- static std::once_flag g_once_flag;
+ static llvm::once_flag g_once_flag;
static bool success = false;
- std::call_once(g_once_flag, []() {
+ llvm::call_once(g_once_flag, []() {
success =
HostInfo::ComputeSharedLibraryDirectory(g_fields->m_lldb_so_dir);
Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
@@ -158,9 +128,9 @@ bool HostInfoBase::GetLLDBPath(lldb::PathType type, FileSpec &file_spec) {
result = &g_fields->m_lldb_so_dir;
} break;
case lldb::ePathTypeSupportExecutableDir: {
- static std::once_flag g_once_flag;
+ static llvm::once_flag g_once_flag;
static bool success = false;
- std::call_once(g_once_flag, []() {
+ llvm::call_once(g_once_flag, []() {
success = HostInfo::ComputeSupportExeDirectory(
g_fields->m_lldb_support_exe_dir);
Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
@@ -173,9 +143,9 @@ bool HostInfoBase::GetLLDBPath(lldb::PathType type, FileSpec &file_spec) {
result = &g_fields->m_lldb_support_exe_dir;
} break;
case lldb::ePathTypeHeaderDir: {
- static std::once_flag g_once_flag;
+ static llvm::once_flag g_once_flag;
static bool success = false;
- std::call_once(g_once_flag, []() {
+ llvm::call_once(g_once_flag, []() {
success = HostInfo::ComputeHeaderDirectory(g_fields->m_lldb_headers_dir);
Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
if (log)
@@ -186,9 +156,9 @@ bool HostInfoBase::GetLLDBPath(lldb::PathType type, FileSpec &file_spec) {
result = &g_fields->m_lldb_headers_dir;
} break;
case lldb::ePathTypePythonDir: {
- static std::once_flag g_once_flag;
+ static llvm::once_flag g_once_flag;
static bool success = false;
- std::call_once(g_once_flag, []() {
+ llvm::call_once(g_once_flag, []() {
success = HostInfo::ComputePythonDirectory(g_fields->m_lldb_python_dir);
Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
if (log)
@@ -199,9 +169,9 @@ bool HostInfoBase::GetLLDBPath(lldb::PathType type, FileSpec &file_spec) {
result = &g_fields->m_lldb_python_dir;
} break;
case lldb::ePathTypeClangDir: {
- static std::once_flag g_once_flag;
+ static llvm::once_flag g_once_flag;
static bool success = false;
- std::call_once(g_once_flag, []() {
+ llvm::call_once(g_once_flag, []() {
success =
HostInfo::ComputeClangDirectory(g_fields->m_lldb_clang_resource_dir);
Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
@@ -214,9 +184,9 @@ bool HostInfoBase::GetLLDBPath(lldb::PathType type, FileSpec &file_spec) {
result = &g_fields->m_lldb_clang_resource_dir;
} break;
case lldb::ePathTypeLLDBSystemPlugins: {
- static std::once_flag g_once_flag;
+ static llvm::once_flag g_once_flag;
static bool success = false;
- std::call_once(g_once_flag, []() {
+ llvm::call_once(g_once_flag, []() {
success = HostInfo::ComputeSystemPluginsDirectory(
g_fields->m_lldb_system_plugin_dir);
Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
@@ -229,9 +199,9 @@ bool HostInfoBase::GetLLDBPath(lldb::PathType type, FileSpec &file_spec) {
result = &g_fields->m_lldb_system_plugin_dir;
} break;
case lldb::ePathTypeLLDBUserPlugins: {
- static std::once_flag g_once_flag;
+ static llvm::once_flag g_once_flag;
static bool success = false;
- std::call_once(g_once_flag, []() {
+ llvm::call_once(g_once_flag, []() {
success = HostInfo::ComputeUserPluginsDirectory(
g_fields->m_lldb_user_plugin_dir);
Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
@@ -244,9 +214,9 @@ bool HostInfoBase::GetLLDBPath(lldb::PathType type, FileSpec &file_spec) {
result = &g_fields->m_lldb_user_plugin_dir;
} break;
case lldb::ePathTypeLLDBTempSystemDir: {
- static std::once_flag g_once_flag;
+ static llvm::once_flag g_once_flag;
static bool success = false;
- std::call_once(g_once_flag, []() {
+ llvm::call_once(g_once_flag, []() {
success = HostInfo::ComputeProcessTempFileDirectory(
g_fields->m_lldb_process_tmp_dir);
Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
@@ -259,9 +229,9 @@ bool HostInfoBase::GetLLDBPath(lldb::PathType type, FileSpec &file_spec) {
result = &g_fields->m_lldb_process_tmp_dir;
} break;
case lldb::ePathTypeGlobalLLDBTempSystemDir: {
- static std::once_flag g_once_flag;
+ static llvm::once_flag g_once_flag;
static bool success = false;
- std::call_once(g_once_flag, []() {
+ llvm::call_once(g_once_flag, []() {
success = HostInfo::ComputeGlobalTempFileDirectory(
g_fields->m_lldb_global_tmp_dir);
Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
@@ -313,9 +283,7 @@ bool HostInfoBase::ComputeProcessTempFileDirectory(FileSpec &file_spec) {
std::string pid_str{llvm::to_string(Host::GetCurrentProcessID())};
temp_file_spec.AppendPathComponent(pid_str);
- if (!FileSystem::MakeDirectory(temp_file_spec,
- eFilePermissionsDirectoryDefault)
- .Success())
+ if (llvm::sys::fs::create_directory(temp_file_spec.GetPath()))
return false;
file_spec.GetDirectory().SetCString(temp_file_spec.GetCString());
@@ -337,9 +305,7 @@ bool HostInfoBase::ComputeGlobalTempFileDirectory(FileSpec &file_spec) {
return false;
temp_file_spec.AppendPathComponent("lldb");
- if (!FileSystem::MakeDirectory(temp_file_spec,
- eFilePermissionsDirectoryDefault)
- .Success())
+ if (llvm::sys::fs::create_directory(temp_file_spec.GetPath()))
return false;
file_spec.GetDirectory().SetCString(temp_file_spec.GetCString());
diff --git a/source/Host/common/HostNativeThreadBase.cpp b/source/Host/common/HostNativeThreadBase.cpp
index fd39e0d1e2fe..402d3caacfcb 100644
--- a/source/Host/common/HostNativeThreadBase.cpp
+++ b/source/Host/common/HostNativeThreadBase.cpp
@@ -8,11 +8,12 @@
//===----------------------------------------------------------------------===//
#include "lldb/Host/HostNativeThreadBase.h"
-#include "lldb/Core/Log.h"
#include "lldb/Host/HostInfo.h"
-#include "lldb/Host/ThisThread.h"
#include "lldb/Host/ThreadLauncher.h"
+#include "lldb/Utility/Log.h"
+
#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/Threading.h"
using namespace lldb;
using namespace lldb_private;
@@ -52,7 +53,7 @@ lldb::thread_result_t
HostNativeThreadBase::ThreadCreateTrampoline(lldb::thread_arg_t arg) {
ThreadLauncher::HostThreadCreateInfo *info =
(ThreadLauncher::HostThreadCreateInfo *)arg;
- ThisThread::SetName(info->thread_name, HostInfo::GetMaxThreadNameLength());
+ llvm::set_thread_name(info->thread_name);
thread_func_t thread_fptr = info->thread_fptr;
thread_arg_t thread_arg = info->thread_arg;
diff --git a/source/Host/common/MonitoringProcessLauncher.cpp b/source/Host/common/MonitoringProcessLauncher.cpp
index ae98cc83379d..2aa6c7f50b66 100644
--- a/source/Host/common/MonitoringProcessLauncher.cpp
+++ b/source/Host/common/MonitoringProcessLauncher.cpp
@@ -8,14 +8,16 @@
//===----------------------------------------------------------------------===//
#include "lldb/Host/MonitoringProcessLauncher.h"
-#include "lldb/Core/Error.h"
-#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Host/HostProcess.h"
#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/ProcessLaunchInfo.h"
+#include "lldb/Utility/Error.h"
+#include "lldb/Utility/Log.h"
+
+#include "llvm/Support/FileSystem.h"
using namespace lldb;
using namespace lldb_private;
@@ -38,8 +40,9 @@ MonitoringProcessLauncher::LaunchProcess(const ProcessLaunchInfo &launch_info,
FileSpec exe_spec(resolved_info.GetExecutableFile());
- FileSpec::FileType file_type = exe_spec.GetFileType();
- if (file_type != FileSpec::eFileTypeRegular) {
+ llvm::sys::fs::file_status stats;
+ status(exe_spec.GetPath(), stats);
+ if (!is_regular_file(stats)) {
ModuleSpec module_spec(exe_spec, arch_spec);
lldb::ModuleSP exe_module_sp;
error =
@@ -48,11 +51,13 @@ MonitoringProcessLauncher::LaunchProcess(const ProcessLaunchInfo &launch_info,
if (error.Fail())
return HostProcess();
- if (exe_module_sp)
+ if (exe_module_sp) {
exe_spec = exe_module_sp->GetFileSpec();
+ status(exe_spec.GetPath(), stats);
+ }
}
- if (exe_spec.Exists()) {
+ if (exists(stats)) {
exe_spec.GetPath(exe_path, sizeof(exe_path));
} else {
resolved_info.GetExecutableFile().GetPath(exe_path, sizeof(exe_path));
diff --git a/source/Host/common/NativeBreakpoint.cpp b/source/Host/common/NativeBreakpoint.cpp
index d61a2f531ac3..8a3ee72179c3 100644
--- a/source/Host/common/NativeBreakpoint.cpp
+++ b/source/Host/common/NativeBreakpoint.cpp
@@ -9,8 +9,8 @@
#include "lldb/Host/common/NativeBreakpoint.h"
-#include "lldb/Core/Error.h"
-#include "lldb/Core/Log.h"
+#include "lldb/Utility/Error.h"
+#include "lldb/Utility/Log.h"
#include "lldb/lldb-defines.h"
using namespace lldb_private;
diff --git a/source/Host/common/NativeBreakpointList.cpp b/source/Host/common/NativeBreakpointList.cpp
index df5bce8079e0..60608a0bbc55 100644
--- a/source/Host/common/NativeBreakpointList.cpp
+++ b/source/Host/common/NativeBreakpointList.cpp
@@ -9,7 +9,7 @@
#include "lldb/Host/common/NativeBreakpointList.h"
-#include "lldb/Core/Log.h"
+#include "lldb/Utility/Log.h"
#include "lldb/Host/common/NativeBreakpoint.h"
#include "lldb/Host/common/SoftwareBreakpoint.h"
diff --git a/source/Host/common/NativeProcessProtocol.cpp b/source/Host/common/NativeProcessProtocol.cpp
index d77b8b2e9746..9d4149d700ba 100644
--- a/source/Host/common/NativeProcessProtocol.cpp
+++ b/source/Host/common/NativeProcessProtocol.cpp
@@ -10,7 +10,6 @@
#include "lldb/Host/common/NativeProcessProtocol.h"
#include "lldb/Core/ArchSpec.h"
-#include "lldb/Core/Log.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/State.h"
#include "lldb/Host/Host.h"
@@ -20,6 +19,7 @@
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/Process.h"
#include "lldb/Utility/LLDBAssert.h"
+#include "lldb/Utility/Log.h"
#include "lldb/lldb-enumerations.h"
using namespace lldb;
@@ -46,6 +46,12 @@ lldb_private::Error NativeProcessProtocol::Interrupt() {
#endif
}
+Error NativeProcessProtocol::IgnoreSignals(llvm::ArrayRef<int> signals) {
+ m_signals_to_ignore.clear();
+ m_signals_to_ignore.insert(signals.begin(), signals.end());
+ return Error();
+}
+
lldb_private::Error
NativeProcessProtocol::GetMemoryRegionInfo(lldb::addr_t load_addr,
MemoryRegionInfo &range_info) {
@@ -139,11 +145,8 @@ NativeProcessProtocol::GetWatchpointMap() const {
return m_watchpoint_list.GetWatchpointMap();
}
-uint32_t NativeProcessProtocol::GetMaxWatchpoints() const {
- // This default implementation will return the number of
- // *hardware* breakpoints available. MacOSX and other OS
- // implementations that support software breakpoints will want to
- // override this correctly for their implementation.
+llvm::Optional<std::pair<uint32_t, uint32_t>>
+NativeProcessProtocol::GetHardwareDebugSupportInfo() const {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
// get any thread
@@ -154,7 +157,7 @@ uint32_t NativeProcessProtocol::GetMaxWatchpoints() const {
log->Warning("NativeProcessProtocol::%s (): failed to find a thread to "
"grab a NativeRegisterContext!",
__FUNCTION__);
- return 0;
+ return llvm::None;
}
NativeRegisterContextSP reg_ctx_sp(thread_sp->GetRegisterContext());
@@ -163,10 +166,11 @@ uint32_t NativeProcessProtocol::GetMaxWatchpoints() const {
log->Warning("NativeProcessProtocol::%s (): failed to get a "
"RegisterContextNativeProcess from the first thread!",
__FUNCTION__);
- return 0;
+ return llvm::None;
}
- return reg_ctx_sp->NumSupportedHardwareWatchpoints();
+ return std::make_pair(reg_ctx_sp->NumSupportedHardwareBreakpoints(),
+ reg_ctx_sp->NumSupportedHardwareWatchpoints());
}
Error NativeProcessProtocol::SetWatchpoint(lldb::addr_t addr, size_t size,
@@ -263,6 +267,92 @@ Error NativeProcessProtocol::RemoveWatchpoint(lldb::addr_t addr) {
return overall_error.Fail() ? overall_error : error;
}
+const HardwareBreakpointMap &
+NativeProcessProtocol::GetHardwareBreakpointMap() const {
+ return m_hw_breakpoints_map;
+}
+
+Error NativeProcessProtocol::SetHardwareBreakpoint(lldb::addr_t addr,
+ size_t size) {
+ // This default implementation assumes setting a hardware breakpoint for
+ // this process will require setting same hardware breakpoint for each
+ // of its existing threads. New thread will do the same once created.
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ // Update the thread list
+ UpdateThreads();
+
+ // Exit here if target does not have required hardware breakpoint capability.
+ auto hw_debug_cap = GetHardwareDebugSupportInfo();
+
+ if (hw_debug_cap == llvm::None || hw_debug_cap->first == 0 ||
+ hw_debug_cap->first <= m_hw_breakpoints_map.size())
+ return Error("Target does not have required no of hardware breakpoints");
+
+ // Vector below stores all thread pointer for which we have we successfully
+ // set this hardware breakpoint. If any of the current process threads fails
+ // to set this hardware breakpoint then roll back and remove this breakpoint
+ // for all the threads that had already set it successfully.
+ std::vector<NativeThreadProtocolSP> breakpoint_established_threads;
+
+ // Request to set a hardware breakpoint for each of current process threads.
+ std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);
+ for (auto thread_sp : m_threads) {
+ assert(thread_sp && "thread list should not have a NULL thread!");
+ if (!thread_sp)
+ continue;
+
+ Error thread_error = thread_sp->SetHardwareBreakpoint(addr, size);
+ if (thread_error.Success()) {
+ // Remember that we set this breakpoint successfully in
+ // case we need to clear it later.
+ breakpoint_established_threads.push_back(thread_sp);
+ } else {
+ // Unset the breakpoint for each thread we successfully
+ // set so that we get back to a consistent state of "not
+ // set" for this hardware breakpoint.
+ for (auto rollback_thread_sp : breakpoint_established_threads) {
+ Error remove_error = rollback_thread_sp->RemoveHardwareBreakpoint(addr);
+ if (remove_error.Fail() && log) {
+ log->Warning("NativeProcessProtocol::%s (): RemoveHardwareBreakpoint"
+ " failed for pid=%" PRIu64 ", tid=%" PRIu64 ": %s",
+ __FUNCTION__, GetID(), rollback_thread_sp->GetID(),
+ remove_error.AsCString());
+ }
+ }
+
+ return thread_error;
+ }
+ }
+
+ // Register new hardware breakpoint into hardware breakpoints map of current
+ // process.
+ m_hw_breakpoints_map[addr] = {addr, size};
+
+ return Error();
+}
+
+Error NativeProcessProtocol::RemoveHardwareBreakpoint(lldb::addr_t addr) {
+ // Update the thread list
+ UpdateThreads();
+
+ Error error;
+
+ std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);
+ for (auto thread_sp : m_threads) {
+ assert(thread_sp && "thread list should not have a NULL thread!");
+ if (!thread_sp)
+ continue;
+
+ error = thread_sp->RemoveHardwareBreakpoint(addr);
+ }
+
+ // Also remove from hardware breakpoint map of current process.
+ m_hw_breakpoints_map.erase(addr);
+
+ return error;
+}
+
bool NativeProcessProtocol::RegisterNativeDelegate(
NativeDelegate &native_delegate) {
std::lock_guard<std::recursive_mutex> guard(m_delegates_mutex);
@@ -339,8 +429,12 @@ Error NativeProcessProtocol::SetSoftwareBreakpoint(lldb::addr_t addr,
});
}
-Error NativeProcessProtocol::RemoveBreakpoint(lldb::addr_t addr) {
- return m_breakpoint_list.DecRef(addr);
+Error NativeProcessProtocol::RemoveBreakpoint(lldb::addr_t addr,
+ bool hardware) {
+ if (hardware)
+ return RemoveHardwareBreakpoint(addr);
+ else
+ return m_breakpoint_list.DecRef(addr);
}
Error NativeProcessProtocol::EnableBreakpoint(lldb::addr_t addr) {
@@ -410,7 +504,7 @@ Error NativeProcessProtocol::ResolveProcessArchitecture(lldb::pid_t pid,
return Error("failed to retrieve a valid architecture from the exe module");
}
-#ifndef __linux__
+#if !defined(__linux__) && !defined(__NetBSD__)
// These need to be implemented to support lldb-gdb-server on a given platform.
// Stubs are
// provided to make the rest of the code link on non-supported platforms.
diff --git a/source/Host/common/NativeRegisterContext.cpp b/source/Host/common/NativeRegisterContext.cpp
index 73b2629c57c1..3bc0a0d9705c 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/Log.h"
#include "lldb/Core/RegisterValue.h"
+#include "lldb/Utility/Log.h"
#include "lldb/Host/PosixApi.h"
#include "lldb/Host/common/NativeProcessProtocol.h"
@@ -246,10 +246,20 @@ uint32_t NativeRegisterContext::SetHardwareBreakpoint(lldb::addr_t addr,
return LLDB_INVALID_INDEX32;
}
+Error NativeRegisterContext::ClearAllHardwareBreakpoints() {
+ return Error("not implemented");
+}
+
bool NativeRegisterContext::ClearHardwareBreakpoint(uint32_t hw_idx) {
return false;
}
+Error NativeRegisterContext::GetHardwareBreakHitIndex(uint32_t &bp_index,
+ lldb::addr_t trap_addr) {
+ bp_index = LLDB_INVALID_INDEX32;
+ return Error("not implemented");
+}
+
uint32_t NativeRegisterContext::NumSupportedHardwareWatchpoints() { return 0; }
uint32_t NativeRegisterContext::SetHardwareWatchpoint(lldb::addr_t addr,
diff --git a/source/Host/common/NativeRegisterContextRegisterInfo.cpp b/source/Host/common/NativeRegisterContextRegisterInfo.cpp
deleted file mode 100644
index 5ff596b57693..000000000000
--- a/source/Host/common/NativeRegisterContextRegisterInfo.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-//===-- NativeRegisterContextRegisterInfo.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/NativeRegisterContextRegisterInfo.h"
-#include "lldb/lldb-private-forward.h"
-#include "lldb/lldb-types.h"
-
-using namespace lldb_private;
-
-NativeRegisterContextRegisterInfo::NativeRegisterContextRegisterInfo(
- NativeThreadProtocol &thread, uint32_t concrete_frame_idx,
- RegisterInfoInterface *register_info_interface)
- : NativeRegisterContext(thread, concrete_frame_idx),
- m_register_info_interface_up(register_info_interface) {
- assert(register_info_interface && "null register_info_interface");
-}
-
-uint32_t NativeRegisterContextRegisterInfo::GetRegisterCount() const {
- return m_register_info_interface_up->GetRegisterCount();
-}
-
-uint32_t NativeRegisterContextRegisterInfo::GetUserRegisterCount() const {
- return m_register_info_interface_up->GetUserRegisterCount();
-}
-
-const RegisterInfo *NativeRegisterContextRegisterInfo::GetRegisterInfoAtIndex(
- uint32_t reg_index) const {
- if (reg_index <= GetRegisterCount())
- return m_register_info_interface_up->GetRegisterInfo() + reg_index;
- else
- return nullptr;
-}
-
-const RegisterInfoInterface &
-NativeRegisterContextRegisterInfo::GetRegisterInfoInterface() const {
- return *m_register_info_interface_up;
-}
diff --git a/source/Host/common/NativeWatchpointList.cpp b/source/Host/common/NativeWatchpointList.cpp
index 5948adf3c8d1..168e5b42b961 100644
--- a/source/Host/common/NativeWatchpointList.cpp
+++ b/source/Host/common/NativeWatchpointList.cpp
@@ -9,7 +9,7 @@
#include "lldb/Host/common/NativeWatchpointList.h"
-#include "lldb/Core/Log.h"
+#include "lldb/Utility/Log.h"
using namespace lldb;
using namespace lldb_private;
diff --git a/source/Host/common/PseudoTerminal.cpp b/source/Host/common/PseudoTerminal.cpp
new file mode 100644
index 000000000000..58c32e4a1c4b
--- /dev/null
+++ b/source/Host/common/PseudoTerminal.cpp
@@ -0,0 +1,310 @@
+//===-- PseudoTerminal.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/PseudoTerminal.h"
+#include "lldb/Host/Config.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#if defined(TIOCSCTTY)
+#include <sys/ioctl.h>
+#endif
+
+#include "lldb/Host/PosixApi.h"
+
+#if defined(__ANDROID__)
+int posix_openpt(int flags);
+#endif
+
+using namespace lldb_utility;
+
+//----------------------------------------------------------------------
+// PseudoTerminal constructor
+//----------------------------------------------------------------------
+PseudoTerminal::PseudoTerminal()
+ : m_master_fd(invalid_fd), m_slave_fd(invalid_fd) {}
+
+//----------------------------------------------------------------------
+// Destructor
+//
+// The destructor will close the master and slave file descriptors
+// if they are valid and ownership has not been released using the
+// ReleaseMasterFileDescriptor() or the ReleaseSaveFileDescriptor()
+// member functions.
+//----------------------------------------------------------------------
+PseudoTerminal::~PseudoTerminal() {
+ CloseMasterFileDescriptor();
+ CloseSlaveFileDescriptor();
+}
+
+//----------------------------------------------------------------------
+// Close the master file descriptor if it is valid.
+//----------------------------------------------------------------------
+void PseudoTerminal::CloseMasterFileDescriptor() {
+ if (m_master_fd >= 0) {
+ ::close(m_master_fd);
+ m_master_fd = invalid_fd;
+ }
+}
+
+//----------------------------------------------------------------------
+// Close the slave file descriptor if it is valid.
+//----------------------------------------------------------------------
+void PseudoTerminal::CloseSlaveFileDescriptor() {
+ if (m_slave_fd >= 0) {
+ ::close(m_slave_fd);
+ m_slave_fd = invalid_fd;
+ }
+}
+
+//----------------------------------------------------------------------
+// Open the first available pseudo terminal with OFLAG as the
+// permissions. The file descriptor is stored in this object and can
+// be accessed with the MasterFileDescriptor() accessor. The
+// ownership of the master file descriptor can be released using
+// the ReleaseMasterFileDescriptor() accessor. If this object has
+// a valid master files descriptor when its destructor is called, it
+// will close the master file descriptor, therefore clients must
+// call ReleaseMasterFileDescriptor() if they wish to use the master
+// file descriptor after this object is out of scope or destroyed.
+//
+// RETURNS:
+// True when successful, false indicating an error occurred.
+//----------------------------------------------------------------------
+bool PseudoTerminal::OpenFirstAvailableMaster(int oflag, char *error_str,
+ size_t error_len) {
+ if (error_str)
+ error_str[0] = '\0';
+
+#if !defined(LLDB_DISABLE_POSIX)
+ // Open the master side of a pseudo terminal
+ m_master_fd = ::posix_openpt(oflag);
+ if (m_master_fd < 0) {
+ if (error_str)
+ ::strerror_r(errno, 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);
+ CloseMasterFileDescriptor();
+ return false;
+ }
+
+ // 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);
+ CloseMasterFileDescriptor();
+ return false;
+ }
+
+ return true;
+#else
+ if (error_str)
+ ::snprintf(error_str, error_len, "%s", "pseudo terminal not supported");
+ return false;
+#endif
+}
+
+//----------------------------------------------------------------------
+// Open the slave pseudo terminal for the current master pseudo
+// terminal. A master pseudo terminal should already be valid prior to
+// calling this function (see OpenFirstAvailableMaster()).
+// The file descriptor is stored this object's member variables and can
+// be accessed via the GetSlaveFileDescriptor(), or released using the
+// ReleaseSlaveFileDescriptor() member function.
+//
+// RETURNS:
+// True when successful, false indicating an error occurred.
+//----------------------------------------------------------------------
+bool PseudoTerminal::OpenSlave(int oflag, char *error_str, size_t error_len) {
+ if (error_str)
+ error_str[0] = '\0';
+
+ CloseSlaveFileDescriptor();
+
+ // Open the master side of a pseudo terminal
+ const char *slave_name = GetSlaveName(error_str, error_len);
+
+ if (slave_name == nullptr)
+ return false;
+
+ m_slave_fd = ::open(slave_name, oflag);
+
+ if (m_slave_fd < 0) {
+ if (error_str)
+ ::strerror_r(errno, error_str, error_len);
+ return false;
+ }
+
+ return true;
+}
+
+//----------------------------------------------------------------------
+// Get the name of the slave pseudo terminal. A master pseudo terminal
+// should already be valid prior to calling this function (see
+// OpenFirstAvailableMaster()).
+//
+// RETURNS:
+// NULL if no valid master pseudo terminal or if ptsname() fails.
+// The name of the slave pseudo terminal as a NULL terminated C string
+// that comes from static memory, so a copy of the string should be
+// made as subsequent calls can change this value.
+//----------------------------------------------------------------------
+const char *PseudoTerminal::GetSlaveName(char *error_str,
+ size_t error_len) const {
+ if (error_str)
+ error_str[0] = '\0';
+
+ if (m_master_fd < 0) {
+ if (error_str)
+ ::snprintf(error_str, error_len, "%s",
+ "master file descriptor is invalid");
+ return nullptr;
+ }
+ const char *slave_name = ::ptsname(m_master_fd);
+
+ if (error_str && slave_name == nullptr)
+ ::strerror_r(errno, error_str, error_len);
+
+ return slave_name;
+}
+
+//----------------------------------------------------------------------
+// Fork a child process and have its stdio routed to a pseudo terminal.
+//
+// In the parent process when a valid pid is returned, the master file
+// descriptor can be used as a read/write access to stdio of the
+// child process.
+//
+// In the child process the stdin/stdout/stderr will already be routed
+// to the slave pseudo terminal and the master file descriptor will be
+// closed as it is no longer needed by the child process.
+//
+// This class will close the file descriptors for the master/slave
+// when the destructor is called, so be sure to call
+// ReleaseMasterFileDescriptor() or ReleaseSlaveFileDescriptor() if any
+// file descriptors are going to be used past the lifespan of this
+// object.
+//
+// RETURNS:
+// in the parent process: the pid of the child, or -1 if fork fails
+// in the child process: zero
+//----------------------------------------------------------------------
+lldb::pid_t PseudoTerminal::Fork(char *error_str, size_t error_len) {
+ if (error_str)
+ error_str[0] = '\0';
+ pid_t pid = LLDB_INVALID_PROCESS_ID;
+#if !defined(LLDB_DISABLE_POSIX)
+ int flags = O_RDWR;
+ flags |= O_CLOEXEC;
+ if (OpenFirstAvailableMaster(flags, error_str, error_len)) {
+ // Successfully opened our master pseudo terminal
+
+ pid = ::fork();
+ if (pid < 0) {
+ // Fork failed
+ if (error_str)
+ ::strerror_r(errno, error_str, error_len);
+ } else if (pid == 0) {
+ // Child Process
+ ::setsid();
+
+ if (OpenSlave(O_RDWR, error_str, error_len)) {
+ // Successfully opened slave
+
+ // Master FD should have O_CLOEXEC set, but let's close it just in
+ // case...
+ CloseMasterFileDescriptor();
+
+#if defined(TIOCSCTTY)
+ // Acquire the controlling terminal
+ if (::ioctl(m_slave_fd, TIOCSCTTY, (char *)0) < 0) {
+ if (error_str)
+ ::strerror_r(errno, 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);
+ }
+
+ if (::dup2(m_slave_fd, STDOUT_FILENO) != STDOUT_FILENO) {
+ if (error_str && !error_str[0])
+ ::strerror_r(errno, 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);
+ }
+ }
+ } else {
+ // Parent Process
+ // Do nothing and let the pid get returned!
+ }
+ }
+#endif
+ return pid;
+}
+
+//----------------------------------------------------------------------
+// The master file descriptor accessor. This object retains ownership
+// of the master file descriptor when this accessor is used. Use
+// ReleaseMasterFileDescriptor() if you wish this object to release
+// ownership of the master file descriptor.
+//
+// Returns the master file descriptor, or -1 if the master file
+// descriptor is not currently valid.
+//----------------------------------------------------------------------
+int PseudoTerminal::GetMasterFileDescriptor() const { return m_master_fd; }
+
+//----------------------------------------------------------------------
+// The slave file descriptor accessor.
+//
+// Returns the slave file descriptor, or -1 if the slave file
+// descriptor is not currently valid.
+//----------------------------------------------------------------------
+int PseudoTerminal::GetSlaveFileDescriptor() const { return m_slave_fd; }
+
+//----------------------------------------------------------------------
+// Release ownership of the master pseudo terminal file descriptor
+// without closing it. The destructor for this class will close the
+// master file descriptor if the ownership isn't released using this
+// call and the master file descriptor has been opened.
+//----------------------------------------------------------------------
+int PseudoTerminal::ReleaseMasterFileDescriptor() {
+ // Release ownership of the master pseudo terminal file
+ // descriptor without closing it. (the destructor for this
+ // class will close it otherwise!)
+ int fd = m_master_fd;
+ m_master_fd = invalid_fd;
+ return fd;
+}
+
+//----------------------------------------------------------------------
+// Release ownership of the slave pseudo terminal file descriptor
+// without closing it. The destructor for this class will close the
+// slave file descriptor if the ownership isn't released using this
+// call and the slave file descriptor has been opened.
+//----------------------------------------------------------------------
+int PseudoTerminal::ReleaseSlaveFileDescriptor() {
+ // Release ownership of the slave pseudo terminal file
+ // descriptor without closing it (the destructor for this
+ // class will close it otherwise!)
+ int fd = m_slave_fd;
+ m_slave_fd = invalid_fd;
+ return fd;
+}
diff --git a/source/Host/common/Socket.cpp b/source/Host/common/Socket.cpp
index 79777c88fa46..2a665ddacb64 100644
--- a/source/Host/common/Socket.cpp
+++ b/source/Host/common/Socket.cpp
@@ -9,14 +9,14 @@
#include "lldb/Host/Socket.h"
-#include "lldb/Core/Log.h"
-#include "lldb/Core/RegularExpression.h"
#include "lldb/Host/Config.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/SocketAddress.h"
#include "lldb/Host/StringConvert.h"
#include "lldb/Host/common/TCPSocket.h"
#include "lldb/Host/common/UDPSocket.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/RegularExpression.h"
#ifndef LLDB_DISABLE_POSIX
#include "lldb/Host/posix/DomainSocket.h"
@@ -38,11 +38,9 @@
#include <asm-generic/errno-base.h>
#include <errno.h>
#include <linux/tcp.h>
-#if defined(ANDROID_ARM_BUILD_STATIC) || defined(ANDROID_MIPS_BUILD_STATIC)
#include <fcntl.h>
#include <sys/syscall.h>
#include <unistd.h>
-#endif // ANDROID_ARM_BUILD_STATIC || ANDROID_MIPS_BUILD_STATIC
#endif // __ANDROID__
using namespace lldb;
@@ -174,15 +172,13 @@ Error Socket::TcpListen(llvm::StringRef host_and_port,
}
Error Socket::UdpConnect(llvm::StringRef host_and_port,
- bool child_processes_inherit, Socket *&send_socket,
- Socket *&recv_socket) {
+ bool child_processes_inherit, Socket *&socket) {
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION));
if (log)
log->Printf("Socket::%s (host/port = %s)", __FUNCTION__,
host_and_port.data());
- return UDPSocket::Connect(host_and_port, child_processes_inherit, send_socket,
- recv_socket);
+ return UDPSocket::Connect(host_and_port, child_processes_inherit, socket);
}
Error Socket::UnixDomainConnect(llvm::StringRef name,
@@ -424,9 +420,13 @@ NativeSocket Socket::AcceptSocket(NativeSocket sockfd, struct sockaddr *addr,
socklen_t *addrlen,
bool child_processes_inherit, Error &error) {
error.Clear();
-#if defined(ANDROID_ARM_BUILD_STATIC) || defined(ANDROID_MIPS_BUILD_STATIC)
- // Temporary workaround for statically linking Android lldb-server with the
- // latest API.
+#if defined(ANDROID_USE_ACCEPT_WORKAROUND)
+ // Hack:
+ // This enables static linking lldb-server to an API 21 libc, but still having
+ // it run on older devices. It is necessary because API 21 libc's
+ // implementation of accept() uses the accept4 syscall(), which is not
+ // available in older kernels. Using an older libc would fix this issue, but
+ // introduce other ones, as the old libraries were quite buggy.
int fd = syscall(__NR_accept, sockfd, addr, addrlen);
if (fd >= 0 && !child_processes_inherit) {
int flags = ::fcntl(fd, F_GETFD);
@@ -441,11 +441,7 @@ NativeSocket Socket::AcceptSocket(NativeSocket sockfd, struct sockaddr *addr,
if (!child_processes_inherit) {
flags |= SOCK_CLOEXEC;
}
-#if defined(__NetBSD__)
- NativeSocket fd = ::paccept(sockfd, addr, addrlen, nullptr, flags);
-#else
NativeSocket fd = ::accept4(sockfd, addr, addrlen, flags);
-#endif
#else
NativeSocket fd = ::accept(sockfd, addr, addrlen);
#endif
diff --git a/source/Host/common/SocketAddress.cpp b/source/Host/common/SocketAddress.cpp
index 1f5de2e5df18..48c3ec1c48ed 100644
--- a/source/Host/common/SocketAddress.cpp
+++ b/source/Host/common/SocketAddress.cpp
@@ -89,6 +89,10 @@ SocketAddress::SocketAddress(const struct sockaddr_storage &s) {
m_socket_addr.sa_storage = s;
}
+SocketAddress::SocketAddress(const struct addrinfo *addr_info) {
+ *this = addr_info;
+}
+
//----------------------------------------------------------------------
// SocketAddress copy constructor
//----------------------------------------------------------------------
@@ -244,6 +248,24 @@ bool SocketAddress::getaddrinfo(const char *host, const char *service,
return result;
}
+std::vector<SocketAddress> SocketAddress::GetAddressInfo(const char *hostname,
+ const char *servname) {
+ std::vector<SocketAddress> addr_list;
+
+ struct addrinfo *service_info_list = NULL;
+ int err = ::getaddrinfo(hostname, servname, NULL, &service_info_list);
+ if (err == 0 && service_info_list) {
+ for (struct addrinfo *service_ptr = service_info_list; service_ptr != NULL;
+ service_ptr = service_ptr->ai_next) {
+ addr_list.emplace_back(SocketAddress(service_ptr));
+ }
+ }
+
+ if (service_info_list)
+ ::freeaddrinfo(service_info_list);
+ return addr_list;
+}
+
bool SocketAddress::SetToLocalhost(sa_family_t family, uint16_t port) {
switch (family) {
case AF_INET:
@@ -287,3 +309,29 @@ bool SocketAddress::SetToAnyAddress(sa_family_t family, uint16_t port) {
Clear();
return false;
}
+
+bool SocketAddress::IsAnyAddr() const {
+ return (GetFamily() == AF_INET)
+ ? m_socket_addr.sa_ipv4.sin_addr.s_addr == htonl(INADDR_ANY)
+ : 0 == memcmp(&m_socket_addr.sa_ipv6.sin6_addr, &in6addr_any, 16);
+}
+
+bool SocketAddress::operator==(const SocketAddress &rhs) const {
+ if (GetFamily() != rhs.GetFamily())
+ return false;
+ if (GetLength() != rhs.GetLength())
+ return false;
+ switch (GetFamily()) {
+ case AF_INET:
+ return m_socket_addr.sa_ipv4.sin_addr.s_addr ==
+ rhs.m_socket_addr.sa_ipv4.sin_addr.s_addr;
+ case AF_INET6:
+ return 0 == memcmp(&m_socket_addr.sa_ipv6.sin6_addr,
+ &rhs.m_socket_addr.sa_ipv6.sin6_addr, 16);
+ }
+ return false;
+}
+
+bool SocketAddress::operator!=(const SocketAddress &rhs) const {
+ return !(*this == rhs);
+}
diff --git a/source/Host/common/SoftwareBreakpoint.cpp b/source/Host/common/SoftwareBreakpoint.cpp
index 3d57b7dd6b88..436cb2bb112e 100644
--- a/source/Host/common/SoftwareBreakpoint.cpp
+++ b/source/Host/common/SoftwareBreakpoint.cpp
@@ -9,9 +9,9 @@
#include "lldb/Host/common/SoftwareBreakpoint.h"
-#include "lldb/Core/Error.h"
-#include "lldb/Core/Log.h"
#include "lldb/Host/Debug.h"
+#include "lldb/Utility/Error.h"
+#include "lldb/Utility/Log.h"
#include "lldb/Host/common/NativeProcessProtocol.h"
diff --git a/source/Host/common/Symbols.cpp b/source/Host/common/Symbols.cpp
index 461b15a07f84..9e0a3b5bf4df 100644
--- a/source/Host/common/Symbols.cpp
+++ b/source/Host/common/Symbols.cpp
@@ -9,17 +9,17 @@
#include "lldb/Host/Symbols.h"
#include "lldb/Core/ArchSpec.h"
-#include "lldb/Core/DataBuffer.h"
-#include "lldb/Core/DataExtractor.h"
-#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Core/StreamString.h"
#include "lldb/Core/Timer.h"
-#include "lldb/Core/UUID.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/Target.h"
+#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/UUID.h"
#include "llvm/Support/FileSystem.h"
@@ -54,7 +54,9 @@ static bool FileAtPathContainsArchAndUUID(const FileSpec &file_fspec,
if (ObjectFile::GetModuleSpecifications(file_fspec, 0, 0, module_specs)) {
ModuleSpec spec;
for (size_t i = 0; i < module_specs.GetSize(); ++i) {
- assert(module_specs.GetModuleSpecAtIndex(i, spec));
+ bool got_spec = module_specs.GetModuleSpecAtIndex(i, spec);
+ UNUSED_IF_ASSERT_DISABLED(got_spec);
+ assert(got_spec);
if ((uuid == NULL || (spec.GetUUIDPtr() && spec.GetUUID() == *uuid)) &&
(arch == NULL || (spec.GetArchitecturePtr() &&
spec.GetArchitecture().IsCompatibleMatch(*arch)))) {
@@ -210,8 +212,13 @@ FileSpec Symbols::LocateExecutableSymbolFile(const ModuleSpec &module_spec) {
debug_file_search_paths.AppendIfUnique(FileSpec(".", true));
#ifndef LLVM_ON_WIN32
+#if defined(__NetBSD__)
+ // Add /usr/libdata/debug directory.
+ debug_file_search_paths.AppendIfUnique(FileSpec("/usr/libdata/debug", true));
+#else
// Add /usr/lib/debug directory.
debug_file_search_paths.AppendIfUnique(FileSpec("/usr/lib/debug", true));
+#endif
#endif // LLVM_ON_WIN32
std::string uuid_str;
@@ -228,7 +235,7 @@ FileSpec Symbols::LocateExecutableSymbolFile(const ModuleSpec &module_spec) {
for (size_t idx = 0; idx < num_directories; ++idx) {
FileSpec dirspec = debug_file_search_paths.GetFileSpecAtIndex(idx);
dirspec.ResolvePath();
- if (!dirspec.Exists() || !dirspec.IsDirectory())
+ if (!llvm::sys::fs::is_directory(dirspec.GetPath()))
continue;
std::vector<std::string> files;
diff --git a/source/Host/common/TCPSocket.cpp b/source/Host/common/TCPSocket.cpp
index 9685ceeeadf1..9a009280a904 100644
--- a/source/Host/common/TCPSocket.cpp
+++ b/source/Host/common/TCPSocket.cpp
@@ -13,8 +13,8 @@
#include "lldb/Host/common/TCPSocket.h"
-#include "lldb/Core/Log.h"
#include "lldb/Host/Config.h"
+#include "lldb/Utility/Log.h"
#ifndef LLDB_DISABLE_POSIX
#include <arpa/inet.h>
diff --git a/source/Host/common/ThisThread.cpp b/source/Host/common/ThisThread.cpp
deleted file mode 100644
index b3f9edee2e16..000000000000
--- a/source/Host/common/ThisThread.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-//===-- ThisThread.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/ThisThread.h"
-#include "lldb/Core/Error.h"
-#include "lldb/Host/HostInfo.h"
-
-#include "llvm/ADT/STLExtras.h"
-
-#include <algorithm>
-
-using namespace lldb;
-using namespace lldb_private;
-
-void ThisThread::SetName(llvm::StringRef name, int max_length) {
- std::string truncated_name(name.data());
-
- // Thread names are coming in like '<lldb.comm.debugger.edit>' and
- // '<lldb.comm.debugger.editline>'. So just chopping the end of the string
- // off leads to a lot of similar named threads. Go through the thread name
- // and search for the last dot and use that.
-
- if (max_length > 0 &&
- truncated_name.length() > static_cast<size_t>(max_length)) {
- // First see if we can get lucky by removing any initial or final braces.
- std::string::size_type begin = truncated_name.find_first_not_of("(<");
- std::string::size_type end = truncated_name.find_last_not_of(")>.");
- if (end - begin > static_cast<size_t>(max_length)) {
- // We're still too long. Since this is a dotted component, use everything
- // after the last
- // dot, up to a maximum of |length| characters.
- std::string::size_type last_dot = truncated_name.rfind('.');
- if (last_dot != std::string::npos)
- begin = last_dot + 1;
-
- end = std::min(end, begin + max_length);
- }
-
- std::string::size_type count = end - begin + 1;
- truncated_name = truncated_name.substr(begin, count);
- }
-
- SetName(truncated_name);
-}
diff --git a/source/Host/common/ThreadLauncher.cpp b/source/Host/common/ThreadLauncher.cpp
index b91c2fe9baab..32641efe408a 100644
--- a/source/Host/common/ThreadLauncher.cpp
+++ b/source/Host/common/ThreadLauncher.cpp
@@ -10,10 +10,9 @@
// lldb Includes
#include "lldb/Host/ThreadLauncher.h"
-#include "lldb/Core/Log.h"
#include "lldb/Host/HostNativeThread.h"
#include "lldb/Host/HostThread.h"
-#include "lldb/Host/ThisThread.h"
+#include "lldb/Utility/Log.h"
#if defined(_WIN32)
#include "lldb/Host/windows/windows.h"
diff --git a/source/Host/common/UDPSocket.cpp b/source/Host/common/UDPSocket.cpp
index 972f87eb73d8..7ca62e7496ba 100644
--- a/source/Host/common/UDPSocket.cpp
+++ b/source/Host/common/UDPSocket.cpp
@@ -9,8 +9,8 @@
#include "lldb/Host/common/UDPSocket.h"
-#include "lldb/Core/Log.h"
#include "lldb/Host/Config.h"
+#include "lldb/Utility/Log.h"
#ifndef LLDB_DISABLE_POSIX
#include <arpa/inet.h>
@@ -38,7 +38,7 @@ UDPSocket::UDPSocket(bool child_processes_inherit, Error &error)
size_t UDPSocket::Send(const void *buf, const size_t num_bytes) {
return ::sendto(m_socket, static_cast<const char *>(buf), num_bytes, 0,
- m_send_sockaddr, m_send_sockaddr.GetLength());
+ m_sockaddr, m_sockaddr.GetLength());
}
Error UDPSocket::Connect(llvm::StringRef name) {
@@ -55,9 +55,8 @@ Error UDPSocket::Accept(llvm::StringRef name, bool child_processes_inherit,
}
Error UDPSocket::Connect(llvm::StringRef name, bool child_processes_inherit,
- Socket *&send_socket, Socket *&recv_socket) {
- std::unique_ptr<UDPSocket> final_send_socket;
- std::unique_ptr<UDPSocket> final_recv_socket;
+ Socket *&socket) {
+ std::unique_ptr<UDPSocket> final_socket;
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION));
if (log)
@@ -70,25 +69,6 @@ Error UDPSocket::Connect(llvm::StringRef name, bool child_processes_inherit,
if (!DecodeHostAndPort(name, host_str, port_str, port, &error))
return error;
- // Setup the receiving end of the UDP connection on this localhost
- // on port zero. After we bind to port zero we can read the port.
- final_recv_socket.reset(new UDPSocket(child_processes_inherit, error));
- if (error.Success()) {
- // Socket was created, now lets bind to the requested port
- SocketAddress addr;
- addr.SetToAnyAddress(AF_INET, 0);
-
- if (::bind(final_recv_socket->GetNativeSocket(), addr, addr.GetLength()) ==
- -1) {
- // Bind failed...
- SetLastError(error);
- }
- }
-
- assert(error.Fail() == !(final_recv_socket && final_recv_socket->IsValid()));
- if (error.Fail())
- return error;
-
// At this point we have setup the receive port, now we need to
// setup the UDP send socket
@@ -118,8 +98,8 @@ Error UDPSocket::Connect(llvm::StringRef name, bool child_processes_inherit,
service_info_ptr->ai_family, service_info_ptr->ai_socktype,
service_info_ptr->ai_protocol, child_processes_inherit, error);
if (error.Success()) {
- final_send_socket.reset(new UDPSocket(send_fd));
- final_send_socket->m_send_sockaddr = service_info_ptr;
+ final_socket.reset(new UDPSocket(send_fd));
+ final_socket->m_sockaddr = service_info_ptr;
break;
} else
continue;
@@ -127,11 +107,31 @@ Error UDPSocket::Connect(llvm::StringRef name, bool child_processes_inherit,
::freeaddrinfo(service_info_list);
- if (!final_send_socket)
+ if (!final_socket)
+ return error;
+
+ SocketAddress bind_addr;
+
+ // Only bind to the loopback address if we are expecting a connection from
+ // localhost to avoid any firewall issues.
+ const bool bind_addr_success = (host_str == "127.0.0.1" || host_str == "localhost")
+ ? bind_addr.SetToLocalhost(kDomain, port)
+ : bind_addr.SetToAnyAddress(kDomain, port);
+
+ if (!bind_addr_success) {
+ error.SetErrorString("Failed to get hostspec to bind for");
return error;
+ }
+
+ bind_addr.SetPort(0); // Let the source port # be determined dynamically
+
+ err = ::bind(final_socket->GetNativeSocket(), bind_addr, bind_addr.GetLength());
+
+ struct sockaddr_in source_info;
+ socklen_t address_len = sizeof (struct sockaddr_in);
+ err = ::getsockname(final_socket->GetNativeSocket(), (struct sockaddr *) &source_info, &address_len);
- send_socket = final_send_socket.release();
- recv_socket = final_recv_socket.release();
+ socket = final_socket.release();
error.Clear();
return error;
}
diff --git a/source/Host/freebsd/Host.cpp b/source/Host/freebsd/Host.cpp
index aeab780ac453..9415b2bb3fd0 100644
--- a/source/Host/freebsd/Host.cpp
+++ b/source/Host/freebsd/Host.cpp
@@ -26,21 +26,21 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Core/DataExtractor.h"
-#include "lldb/Core/Error.h"
-#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/StreamFile.h"
-#include "lldb/Core/StreamString.h"
-#include "lldb/Host/Endian.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
+#include "lldb/Utility/DataExtractor.h"
+#include "lldb/Utility/Endian.h"
+#include "lldb/Utility/Error.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/StreamString.h"
-#include "lldb/Core/DataBufferHeap.h"
-#include "lldb/Core/DataExtractor.h"
#include "lldb/Utility/CleanUp.h"
+#include "lldb/Utility/DataBufferHeap.h"
+#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/NameMatches.h"
#include "llvm/Support/Host.h"
@@ -52,18 +52,6 @@ extern char **environ;
using namespace lldb;
using namespace lldb_private;
-size_t Host::GetEnvironment(StringList &env) {
- char *v;
- char **var = environ;
- for (; var != NULL && *var != NULL; ++var) {
- v = strchr(*var, (int)'-');
- if (v == NULL)
- continue;
- env.AppendString(v);
- }
- return env.GetSize();
-}
-
static bool
GetFreeBSDProcessArgs(const ProcessInstanceInfoMatch *match_info_ptr,
ProcessInstanceInfo &process_info) {
@@ -243,21 +231,13 @@ bool Host::GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &process_info) {
return false;
}
-lldb::DataBufferSP Host::GetAuxvData(lldb_private::Process *process) {
- int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_AUXV, 0};
- size_t auxv_size = AT_COUNT * sizeof(Elf_Auxinfo);
- DataBufferSP buf_sp;
-
- std::unique_ptr<DataBufferHeap> buf_ap(new DataBufferHeap(auxv_size, 0));
-
- mib[3] = process->GetID();
- if (::sysctl(mib, 4, buf_ap->GetBytes(), &auxv_size, NULL, 0) == 0) {
- buf_sp.reset(buf_ap.release());
- } else {
- perror("sysctl failed on auxv");
- }
-
- return buf_sp;
+size_t Host::GetEnvironment(StringList &env) {
+ char **host_env = environ;
+ char *env_entry;
+ size_t i;
+ for (i = 0; (env_entry = host_env[i]) != NULL; ++i)
+ env.AppendString(env_entry);
+ return i;
}
Error Host::ShellExpandArguments(ProcessLaunchInfo &launch_info) {
diff --git a/source/Host/freebsd/HostInfoFreeBSD.cpp b/source/Host/freebsd/HostInfoFreeBSD.cpp
index fb9d86678dbb..9c82fcca7563 100644
--- a/source/Host/freebsd/HostInfoFreeBSD.cpp
+++ b/source/Host/freebsd/HostInfoFreeBSD.cpp
@@ -14,11 +14,10 @@
#include <sys/sysctl.h>
#include <sys/types.h>
#include <sys/utsname.h>
+#include <unistd.h>
using namespace lldb_private;
-uint32_t HostInfoFreeBSD::GetMaxThreadNameLength() { return 16; }
-
bool HostInfoFreeBSD::GetOSVersion(uint32_t &major, uint32_t &minor,
uint32_t &update) {
struct utsname un;
diff --git a/source/Host/freebsd/HostThreadFreeBSD.cpp b/source/Host/freebsd/HostThreadFreeBSD.cpp
deleted file mode 100644
index 97d4d9d05b66..000000000000
--- a/source/Host/freebsd/HostThreadFreeBSD.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-//===-- HostThreadFreeBSD.cpp -----------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// lldb Includes
-#include "lldb/Host/freebsd/HostThreadFreeBSD.h"
-#include "lldb/Host/Host.h"
-
-// C includes
-#include <errno.h>
-#include <pthread.h>
-#if defined(__FreeBSD__)
-#include <pthread_np.h>
-#endif
-#include <stdlib.h>
-#include <sys/sysctl.h>
-#include <sys/user.h>
-
-// C++ includes
-#include <string>
-
-using namespace lldb_private;
-
-HostThreadFreeBSD::HostThreadFreeBSD() {}
-
-HostThreadFreeBSD::HostThreadFreeBSD(lldb::thread_t thread)
- : HostThreadPosix(thread) {}
-
-void HostThreadFreeBSD::GetName(lldb::tid_t tid,
- llvm::SmallVectorImpl<char> &name) {
- name.clear();
- int pid = Host::GetCurrentProcessID();
-
- struct kinfo_proc *kp = nullptr, *nkp;
- size_t len = 0;
- int error;
- int ctl[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID | KERN_PROC_INC_THREAD,
- (int)pid};
-
- while (1) {
- error = sysctl(ctl, 4, kp, &len, nullptr, 0);
- if (kp == nullptr || (error != 0 && errno == ENOMEM)) {
- // Add extra space in case threads are added before next call.
- len += sizeof(*kp) + len / 10;
- nkp = (struct kinfo_proc *)realloc(kp, len);
- if (nkp == nullptr) {
- free(kp);
- return;
- }
- kp = nkp;
- continue;
- }
- if (error != 0)
- len = 0;
- break;
- }
-
- for (size_t i = 0; i < len / sizeof(*kp); i++) {
- if (kp[i].ki_tid == (lwpid_t)tid) {
- name.append(kp[i].ki_tdname, kp[i].ki_tdname + strlen(kp[i].ki_tdname));
- break;
- }
- }
- free(kp);
-}
diff --git a/source/Host/freebsd/ThisThread.cpp b/source/Host/freebsd/ThisThread.cpp
deleted file mode 100644
index da0f2379a870..000000000000
--- a/source/Host/freebsd/ThisThread.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-//===-- ThisThread.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/ThisThread.h"
-#include "lldb/Host/HostNativeThread.h"
-
-#include "llvm/ADT/SmallVector.h"
-
-#include <pthread.h>
-#if defined(__FreeBSD__)
-#include <pthread_np.h>
-#endif
-
-using namespace lldb_private;
-
-void ThisThread::SetName(llvm::StringRef name) {
-#if defined(__FreeBSD__) // Kfreebsd does not have a simple alternative
- ::pthread_set_name_np(::pthread_self(), name.data());
-#endif
-}
-
-void ThisThread::GetName(llvm::SmallVectorImpl<char> &name) {
-#if defined(__FreeBSD__)
- HostNativeThread::GetName(::pthread_getthreadid_np(), name);
-#else
- // Kfreebsd
- HostNativeThread::GetName((unsigned)pthread_self(), name);
-#endif
-}
diff --git a/source/Host/linux/Host.cpp b/source/Host/linux/Host.cpp
index 8acf4a94e5bf..810222cbbf2f 100644
--- a/source/Host/linux/Host.cpp
+++ b/source/Host/linux/Host.cpp
@@ -21,150 +21,195 @@
// Other libraries and framework includes
#include "llvm/Support/ScopedPrinter.h"
// Project includes
-#include "lldb/Core/Error.h"
-#include "lldb/Core/Log.h"
#include "lldb/Target/Process.h"
+#include "lldb/Utility/Error.h"
+#include "lldb/Utility/Log.h"
-#include "lldb/Core/DataBufferHeap.h"
-#include "lldb/Core/DataExtractor.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
+#include "lldb/Host/linux/Support.h"
+#include "lldb/Utility/DataBufferHeap.h"
+#include "lldb/Utility/DataExtractor.h"
-#include "Plugins/Process/Linux/ProcFileReader.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Symbol/ObjectFile.h"
using namespace lldb;
using namespace lldb_private;
-typedef enum ProcessStateFlags {
- eProcessStateRunning = (1u << 0), // Running
- eProcessStateSleeping = (1u << 1), // Sleeping in an interruptible wait
- eProcessStateWaiting = (1u << 2), // Waiting in an uninterruptible disk sleep
- eProcessStateZombie = (1u << 3), // Zombie
- eProcessStateTracedOrStopped = (1u << 4), // Traced or stopped (on a signal)
- eProcessStatePaging = (1u << 5) // Paging
-} ProcessStateFlags;
-
-typedef struct ProcessStatInfo {
- lldb::pid_t ppid; // Parent Process ID
- uint32_t fProcessState; // ProcessStateFlags
-} ProcessStatInfo;
-
-// Get the process info with additional information from /proc/$PID/stat (like
-// process state, and tracer pid).
-static bool GetProcessAndStatInfo(lldb::pid_t pid,
- ProcessInstanceInfo &process_info,
- ProcessStatInfo &stat_info,
- lldb::pid_t &tracerpid);
-
-static bool ReadProcPseudoFileStat(lldb::pid_t pid,
- ProcessStatInfo &stat_info) {
- // Read the /proc/$PID/stat file.
- lldb::DataBufferSP buf_sp =
- process_linux::ProcFileReader::ReadIntoDataBuffer(pid, "stat");
-
- // The filename of the executable is stored in parenthesis right after the
- // pid. We look for the closing
- // parenthesis for the filename and work from there in case the name has
- // something funky like ')' in it.
- const char *filename_end = strrchr((const char *)buf_sp->GetBytes(), ')');
- if (filename_end) {
- char state = '\0';
- int ppid = LLDB_INVALID_PROCESS_ID;
-
- // Read state and ppid.
- sscanf(filename_end + 1, " %c %d", &state, &ppid);
-
- stat_info.ppid = ppid;
-
- switch (state) {
- case 'R':
- stat_info.fProcessState |= eProcessStateRunning;
- break;
- case 'S':
- stat_info.fProcessState |= eProcessStateSleeping;
- break;
- case 'D':
- stat_info.fProcessState |= eProcessStateWaiting;
- break;
- case 'Z':
- stat_info.fProcessState |= eProcessStateZombie;
- break;
- case 'T':
- stat_info.fProcessState |= eProcessStateTracedOrStopped;
- break;
- case 'W':
- stat_info.fProcessState |= eProcessStatePaging;
- break;
+namespace {
+enum class ProcessState {
+ Unknown,
+ DiskSleep,
+ Paging,
+ Running,
+ Sleeping,
+ TracedOrStopped,
+ Zombie,
+};
+}
+
+static bool GetStatusInfo(::pid_t Pid, ProcessInstanceInfo &ProcessInfo,
+ ProcessState &State, ::pid_t &TracerPid) {
+ auto BufferOrError = getProcFile(Pid, "status");
+ if (!BufferOrError)
+ return false;
+
+ llvm::StringRef Rest = BufferOrError.get()->getBuffer();
+ while(!Rest.empty()) {
+ llvm::StringRef Line;
+ std::tie(Line, Rest) = Rest.split('\n');
+
+ if (Line.consume_front("Gid:")) {
+ // Real, effective, saved set, and file system GIDs. Read the first two.
+ Line = Line.ltrim();
+ uint32_t RGid, EGid;
+ Line.consumeInteger(10, RGid);
+ Line = Line.ltrim();
+ Line.consumeInteger(10, EGid);
+
+ ProcessInfo.SetGroupID(RGid);
+ ProcessInfo.SetEffectiveGroupID(EGid);
+ } else if (Line.consume_front("Uid:")) {
+ // Real, effective, saved set, and file system UIDs. Read the first two.
+ Line = Line.ltrim();
+ uint32_t RUid, EUid;
+ Line.consumeInteger(10, RUid);
+ Line = Line.ltrim();
+ Line.consumeInteger(10, EUid);
+
+ ProcessInfo.SetUserID(RUid);
+ ProcessInfo.SetEffectiveUserID(EUid);
+ } else if (Line.consume_front("PPid:")) {
+ ::pid_t PPid;
+ Line.ltrim().consumeInteger(10, PPid);
+ ProcessInfo.SetParentProcessID(PPid);
+ } else if (Line.consume_front("State:")) {
+ char S = Line.ltrim().front();
+ switch (S) {
+ case 'R':
+ State = ProcessState::Running;
+ break;
+ case 'S':
+ State = ProcessState::Sleeping;
+ break;
+ case 'D':
+ State = ProcessState::DiskSleep;
+ break;
+ case 'Z':
+ State = ProcessState::Zombie;
+ break;
+ case 'T':
+ State = ProcessState::TracedOrStopped;
+ break;
+ case 'W':
+ State = ProcessState::Paging;
+ break;
+ }
+ } else if (Line.consume_front("TracerPid:")) {
+ Line = Line.ltrim();
+ Line.consumeInteger(10, TracerPid);
}
+ }
+ return true;
+}
- return true;
+static bool IsDirNumeric(const char *dname) {
+ for (; *dname; dname++) {
+ if (!isdigit(*dname))
+ return false;
}
+ return true;
+}
+static bool GetELFProcessCPUType(llvm::StringRef exe_path,
+ ProcessInstanceInfo &process_info) {
+ // Clear the architecture.
+ process_info.GetArchitecture().Clear();
+
+ ModuleSpecList specs;
+ FileSpec filespec(exe_path, false);
+ const size_t num_specs =
+ ObjectFile::GetModuleSpecifications(filespec, 0, 0, specs);
+ // GetModuleSpecifications() could fail if the executable has been deleted or
+ // is locked.
+ // But it shouldn't return more than 1 architecture.
+ assert(num_specs <= 1 && "Linux plugin supports only a single architecture");
+ if (num_specs == 1) {
+ ModuleSpec module_spec;
+ if (specs.GetModuleSpecAtIndex(0, module_spec) &&
+ module_spec.GetArchitecture().IsValid()) {
+ process_info.GetArchitecture() = module_spec.GetArchitecture();
+ return true;
+ }
+ }
return false;
}
-static void GetLinuxProcessUserAndGroup(lldb::pid_t pid,
- ProcessInstanceInfo &process_info,
- lldb::pid_t &tracerpid) {
+static bool GetProcessAndStatInfo(::pid_t pid,
+ ProcessInstanceInfo &process_info,
+ ProcessState &State, ::pid_t &tracerpid) {
tracerpid = 0;
- uint32_t rUid = UINT32_MAX; // Real User ID
- uint32_t eUid = UINT32_MAX; // Effective User ID
- uint32_t rGid = UINT32_MAX; // Real Group ID
- uint32_t eGid = UINT32_MAX; // Effective Group ID
-
- // Read the /proc/$PID/status file and parse the Uid:, Gid:, and TracerPid:
- // fields.
- lldb::DataBufferSP buf_sp =
- process_linux::ProcFileReader::ReadIntoDataBuffer(pid, "status");
-
- static const char uid_token[] = "Uid:";
- char *buf_uid = strstr((char *)buf_sp->GetBytes(), uid_token);
- if (buf_uid) {
- // Real, effective, saved set, and file system UIDs. Read the first two.
- buf_uid += sizeof(uid_token);
- rUid = strtol(buf_uid, &buf_uid, 10);
- eUid = strtol(buf_uid, &buf_uid, 10);
- }
+ process_info.Clear();
- static const char gid_token[] = "Gid:";
- char *buf_gid = strstr((char *)buf_sp->GetBytes(), gid_token);
- if (buf_gid) {
- // Real, effective, saved set, and file system GIDs. Read the first two.
- buf_gid += sizeof(gid_token);
- rGid = strtol(buf_gid, &buf_gid, 10);
- eGid = strtol(buf_gid, &buf_gid, 10);
- }
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ // We can't use getProcFile here because proc/[pid]/exe is a symbolic link.
+ llvm::SmallString<64> ProcExe;
+ (llvm::Twine("/proc/") + llvm::Twine(pid) + "/exe").toVector(ProcExe);
+ std::string ExePath(PATH_MAX, '\0');
- static const char tracerpid_token[] = "TracerPid:";
- char *buf_tracerpid = strstr((char *)buf_sp->GetBytes(), tracerpid_token);
- if (buf_tracerpid) {
- // Tracer PID. 0 if we're not being debugged.
- buf_tracerpid += sizeof(tracerpid_token);
- tracerpid = strtol(buf_tracerpid, &buf_tracerpid, 10);
+ ssize_t len = readlink(ProcExe.c_str(), &ExePath[0], PATH_MAX);
+ if (len <= 0) {
+ LLDB_LOG(log, "failed to read link exe link for {0}: {1}", pid,
+ Error(errno, eErrorTypePOSIX));
+ return false;
}
+ ExePath.resize(len);
- process_info.SetUserID(rUid);
- process_info.SetEffectiveUserID(eUid);
- process_info.SetGroupID(rGid);
- process_info.SetEffectiveGroupID(eGid);
-}
+ // If the binary has been deleted, the link name has " (deleted)" appended.
+ // Remove if there.
+ llvm::StringRef PathRef = ExePath;
+ PathRef.consume_back(" (deleted)");
-lldb::DataBufferSP Host::GetAuxvData(lldb_private::Process *process) {
- return process_linux::ProcFileReader::ReadIntoDataBuffer(process->GetID(),
- "auxv");
-}
+ GetELFProcessCPUType(PathRef, process_info);
-lldb::DataBufferSP Host::GetAuxvData(lldb::pid_t pid) {
- return process_linux::ProcFileReader::ReadIntoDataBuffer(pid, "auxv");
-}
+ // Get the process environment.
+ auto BufferOrError = getProcFile(pid, "environ");
+ if (!BufferOrError)
+ return false;
+ std::unique_ptr<llvm::MemoryBuffer> Environ = std::move(*BufferOrError);
-static bool IsDirNumeric(const char *dname) {
- for (; *dname; dname++) {
- if (!isdigit(*dname))
- return false;
+ // Get the command line used to start the process.
+ BufferOrError = getProcFile(pid, "cmdline");
+ if (!BufferOrError)
+ return false;
+ std::unique_ptr<llvm::MemoryBuffer> Cmdline = std::move(*BufferOrError);
+
+ // Get User and Group IDs and get tracer pid.
+ if (!GetStatusInfo(pid, process_info, State, tracerpid))
+ return false;
+
+ process_info.SetProcessID(pid);
+ process_info.GetExecutableFile().SetFile(PathRef, false);
+ process_info.GetArchitecture().MergeFrom(HostInfo::GetArchitecture());
+
+ llvm::StringRef Rest = Environ->getBuffer();
+ while (!Rest.empty()) {
+ llvm::StringRef Var;
+ std::tie(Var, Rest) = Rest.split('\0');
+ process_info.GetEnvironmentEntries().AppendArgument(Var);
}
+
+ llvm::StringRef Arg0;
+ std::tie(Arg0, Rest) = Cmdline->getBuffer().split('\0');
+ process_info.SetArg0(Arg0);
+ while (!Rest.empty()) {
+ llvm::StringRef Arg;
+ std::tie(Arg, Rest) = Rest.split('\0');
+ process_info.GetArguments().AppendArgument(Arg);
+ }
+
return true;
}
@@ -189,19 +234,18 @@ uint32_t Host::FindProcesses(const ProcessInstanceInfoMatch &match_info,
if (pid == our_pid)
continue;
- lldb::pid_t tracerpid;
- ProcessStatInfo stat_info;
+ ::pid_t tracerpid;
+ ProcessState State;
ProcessInstanceInfo process_info;
- if (!GetProcessAndStatInfo(pid, process_info, stat_info, tracerpid))
+ if (!GetProcessAndStatInfo(pid, process_info, State, tracerpid))
continue;
// Skip if process is being debugged.
if (tracerpid != 0)
continue;
- // Skip zombies.
- if (stat_info.fProcessState & eProcessStateZombie)
+ if (State == ProcessState::Zombie)
continue;
// Check for user match if we're not matching all users and not running as
@@ -246,121 +290,10 @@ bool Host::FindProcessThreads(const lldb::pid_t pid, TidMap &tids_to_attach) {
return tids_changed;
}
-static bool GetELFProcessCPUType(const char *exe_path,
- ProcessInstanceInfo &process_info) {
- // Clear the architecture.
- process_info.GetArchitecture().Clear();
-
- ModuleSpecList specs;
- FileSpec filespec(exe_path, false);
- const size_t num_specs =
- ObjectFile::GetModuleSpecifications(filespec, 0, 0, specs);
- // GetModuleSpecifications() could fail if the executable has been deleted or
- // is locked.
- // But it shouldn't return more than 1 architecture.
- assert(num_specs <= 1 && "Linux plugin supports only a single architecture");
- if (num_specs == 1) {
- ModuleSpec module_spec;
- if (specs.GetModuleSpecAtIndex(0, module_spec) &&
- module_spec.GetArchitecture().IsValid()) {
- process_info.GetArchitecture() = module_spec.GetArchitecture();
- return true;
- }
- }
- return false;
-}
-
-static bool GetProcessAndStatInfo(lldb::pid_t pid,
- ProcessInstanceInfo &process_info,
- ProcessStatInfo &stat_info,
- lldb::pid_t &tracerpid) {
- tracerpid = 0;
- process_info.Clear();
- ::memset(&stat_info, 0, sizeof(stat_info));
- stat_info.ppid = LLDB_INVALID_PROCESS_ID;
-
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
-
- // Use special code here because proc/[pid]/exe is a symbolic link.
- char link_path[PATH_MAX];
- char exe_path[PATH_MAX] = "";
- if (snprintf(link_path, PATH_MAX, "/proc/%" PRIu64 "/exe", pid) <= 0) {
- if (log)
- log->Printf("%s: failed to sprintf pid %" PRIu64, __FUNCTION__, pid);
- return false;
- }
-
- ssize_t len = readlink(link_path, exe_path, sizeof(exe_path) - 1);
- if (len <= 0) {
- if (log)
- log->Printf("%s: failed to read link %s: %s", __FUNCTION__, link_path,
- strerror(errno));
- return false;
- }
-
- // readlink does not append a null byte.
- exe_path[len] = 0;
-
- // If the binary has been deleted, the link name has " (deleted)" appended.
- // Remove if there.
- static const ssize_t deleted_len = strlen(" (deleted)");
- if (len > deleted_len &&
- !strcmp(exe_path + len - deleted_len, " (deleted)")) {
- exe_path[len - deleted_len] = 0;
- } else {
- GetELFProcessCPUType(exe_path, process_info);
- }
-
- process_info.SetProcessID(pid);
- process_info.GetExecutableFile().SetFile(exe_path, false);
- process_info.GetArchitecture().MergeFrom(HostInfo::GetArchitecture());
-
- lldb::DataBufferSP buf_sp;
-
- // Get the process environment.
- buf_sp = process_linux::ProcFileReader::ReadIntoDataBuffer(pid, "environ");
- Args &info_env = process_info.GetEnvironmentEntries();
- char *next_var = (char *)buf_sp->GetBytes();
- char *end_buf = next_var + buf_sp->GetByteSize();
- while (next_var < end_buf && 0 != *next_var) {
- info_env.AppendArgument(llvm::StringRef(next_var));
- next_var += strlen(next_var) + 1;
- }
-
- // Get the command line used to start the process.
- buf_sp = process_linux::ProcFileReader::ReadIntoDataBuffer(pid, "cmdline");
-
- // Grab Arg0 first, if there is one.
- char *cmd = (char *)buf_sp->GetBytes();
- if (cmd) {
- process_info.SetArg0(cmd);
-
- // Now process any remaining arguments.
- Args &info_args = process_info.GetArguments();
- char *next_arg = cmd + strlen(cmd) + 1;
- end_buf = cmd + buf_sp->GetByteSize();
- while (next_arg < end_buf && 0 != *next_arg) {
- info_args.AppendArgument(llvm::StringRef(next_arg));
- next_arg += strlen(next_arg) + 1;
- }
- }
-
- // Read /proc/$PID/stat to get our parent pid.
- if (ReadProcPseudoFileStat(pid, stat_info)) {
- process_info.SetParentProcessID(stat_info.ppid);
- }
-
- // Get User and Group IDs and get tracer pid.
- GetLinuxProcessUserAndGroup(pid, process_info, tracerpid);
-
- return true;
-}
-
bool Host::GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &process_info) {
- lldb::pid_t tracerpid;
- ProcessStatInfo stat_info;
-
- return GetProcessAndStatInfo(pid, process_info, stat_info, tracerpid);
+ ::pid_t tracerpid;
+ ProcessState State;
+ return GetProcessAndStatInfo(pid, process_info, State, tracerpid);
}
size_t Host::GetEnvironment(StringList &env) {
diff --git a/source/Host/linux/HostInfoLinux.cpp b/source/Host/linux/HostInfoLinux.cpp
index 2a01f0676142..3ff722d5c109 100644
--- a/source/Host/linux/HostInfoLinux.cpp
+++ b/source/Host/linux/HostInfoLinux.cpp
@@ -8,7 +8,9 @@
//===----------------------------------------------------------------------===//
#include "lldb/Host/linux/HostInfoLinux.h"
-#include "lldb/Core/Log.h"
+#include "lldb/Utility/Log.h"
+
+#include "llvm/Support/Threading.h"
#include <limits.h>
#include <stdio.h>
@@ -39,13 +41,11 @@ void HostInfoLinux::Initialize() {
g_fields = new HostInfoLinuxFields();
}
-uint32_t HostInfoLinux::GetMaxThreadNameLength() { return 16; }
-
bool HostInfoLinux::GetOSVersion(uint32_t &major, uint32_t &minor,
uint32_t &update) {
static bool success = false;
- static std::once_flag g_once_flag;
- std::call_once(g_once_flag, []() {
+ static llvm::once_flag g_once_flag;
+ llvm::call_once(g_once_flag, []() {
struct utsname un;
if (uname(&un) == 0) {
@@ -100,8 +100,8 @@ bool HostInfoLinux::GetOSKernelDescription(std::string &s) {
llvm::StringRef HostInfoLinux::GetDistributionId() {
// Try to run 'lbs_release -i', and use that response
// for the distribution id.
- static std::once_flag g_once_flag;
- std::call_once(g_once_flag, []() {
+ static llvm::once_flag g_once_flag;
+ llvm::call_once(g_once_flag, []() {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST));
if (log)
diff --git a/source/Host/linux/HostThreadLinux.cpp b/source/Host/linux/HostThreadLinux.cpp
deleted file mode 100644
index 625f05d0e9d8..000000000000
--- a/source/Host/linux/HostThreadLinux.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-//===-- HostThreadLinux.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/linux/HostThreadLinux.h"
-#include "Plugins/Process/Linux/ProcFileReader.h"
-#include "lldb/Core/DataBuffer.h"
-
-#include "llvm/ADT/SmallVector.h"
-
-#include <pthread.h>
-
-using namespace lldb_private;
-
-HostThreadLinux::HostThreadLinux() : HostThreadPosix() {}
-
-HostThreadLinux::HostThreadLinux(lldb::thread_t thread)
- : HostThreadPosix(thread) {}
-
-void HostThreadLinux::SetName(lldb::thread_t thread, llvm::StringRef name) {
-#if (defined(__GLIBC__) && defined(_GNU_SOURCE)) || defined(__ANDROID__)
- ::pthread_setname_np(thread, name.data());
-#else
- (void)thread;
- (void)name;
-#endif
-}
-
-void HostThreadLinux::GetName(lldb::thread_t thread,
- llvm::SmallVectorImpl<char> &name) {
- // Read /proc/$TID/comm file.
- lldb::DataBufferSP buf_sp =
- process_linux::ProcFileReader::ReadIntoDataBuffer(thread, "comm");
- const char *comm_str = (const char *)buf_sp->GetBytes();
- const char *cr_str = ::strchr(comm_str, '\n');
- size_t length = cr_str ? (cr_str - comm_str) : strlen(comm_str);
-
- name.clear();
- name.append(comm_str, comm_str + length);
-}
diff --git a/source/Host/linux/ProcessLauncherLinux.cpp b/source/Host/linux/ProcessLauncherLinux.cpp
index 27a6329da067..e69de29bb2d1 100644
--- a/source/Host/linux/ProcessLauncherLinux.cpp
+++ b/source/Host/linux/ProcessLauncherLinux.cpp
@@ -1,216 +0,0 @@
-//===-- ProcessLauncherLinux.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/linux/ProcessLauncherLinux.h"
-#include "lldb/Core/Log.h"
-#include "lldb/Host/FileSpec.h"
-#include "lldb/Host/Host.h"
-#include "lldb/Host/HostProcess.h"
-#include "lldb/Host/Pipe.h"
-#include "lldb/Target/ProcessLaunchInfo.h"
-
-#include <limits.h>
-#include <sys/personality.h>
-#include <sys/ptrace.h>
-#include <sys/wait.h>
-
-#include <sstream>
-
-using namespace lldb;
-using namespace lldb_private;
-
-static void FixupEnvironment(Args &env) {
-#ifdef __ANDROID__
- // If there is no PATH variable specified inside the environment then set the
- // path to /system/bin. It is required because the default path used by
- // execve() is wrong on android.
- static const char *path = "PATH=";
- for (auto &entry : env.entries()) {
- if (entry.ref.startswith(path))
- return;
- }
- env.AppendArgument(llvm::StringRef("PATH=/system/bin"));
-#endif
-}
-
-static void LLVM_ATTRIBUTE_NORETURN ExitWithError(int error_fd,
- const char *operation) {
- std::ostringstream os;
- os << operation << " failed: " << strerror(errno);
- write(error_fd, os.str().data(), os.str().size());
- close(error_fd);
- _exit(1);
-}
-
-static void DupDescriptor(int error_fd, const FileSpec &file_spec, int fd,
- int flags) {
- int target_fd = ::open(file_spec.GetCString(), flags, 0666);
-
- if (target_fd == -1)
- ExitWithError(error_fd, "DupDescriptor-open");
-
- if (target_fd == fd)
- return;
-
- if (::dup2(target_fd, fd) == -1)
- ExitWithError(error_fd, "DupDescriptor-dup2");
-
- ::close(target_fd);
- return;
-}
-
-static void LLVM_ATTRIBUTE_NORETURN ChildFunc(int error_fd,
- const ProcessLaunchInfo &info) {
- // First, make sure we disable all logging. If we are logging to stdout, our
- // logs can be
- // mistaken for inferior output.
- Log::DisableAllLogChannels(nullptr);
-
- // Do not inherit setgid powers.
- if (setgid(getgid()) != 0)
- ExitWithError(error_fd, "setgid");
-
- if (info.GetFlags().Test(eLaunchFlagLaunchInSeparateProcessGroup)) {
- if (setpgid(0, 0) != 0)
- ExitWithError(error_fd, "setpgid");
- }
-
- for (size_t i = 0; i < info.GetNumFileActions(); ++i) {
- const FileAction &action = *info.GetFileActionAtIndex(i);
- switch (action.GetAction()) {
- case FileAction::eFileActionClose:
- if (close(action.GetFD()) != 0)
- ExitWithError(error_fd, "close");
- break;
- case FileAction::eFileActionDuplicate:
- if (dup2(action.GetFD(), action.GetActionArgument()) == -1)
- ExitWithError(error_fd, "dup2");
- break;
- case FileAction::eFileActionOpen:
- DupDescriptor(error_fd, action.GetFileSpec(), action.GetFD(),
- action.GetActionArgument());
- break;
- case FileAction::eFileActionNone:
- break;
- }
- }
-
- const char **argv = info.GetArguments().GetConstArgumentVector();
-
- // Change working directory
- if (info.GetWorkingDirectory() &&
- 0 != ::chdir(info.GetWorkingDirectory().GetCString()))
- ExitWithError(error_fd, "chdir");
-
- // Disable ASLR if requested.
- if (info.GetFlags().Test(lldb::eLaunchFlagDisableASLR)) {
- const unsigned long personality_get_current = 0xffffffff;
- int value = personality(personality_get_current);
- if (value == -1)
- ExitWithError(error_fd, "personality get");
-
- value = personality(ADDR_NO_RANDOMIZE | value);
- if (value == -1)
- ExitWithError(error_fd, "personality set");
- }
-
- Args env = info.GetEnvironmentEntries();
- FixupEnvironment(env);
- const char **envp = env.GetConstArgumentVector();
-
- // Clear the signal mask to prevent the child from being affected by
- // any masking done by the parent.
- sigset_t set;
- if (sigemptyset(&set) != 0 ||
- pthread_sigmask(SIG_SETMASK, &set, nullptr) != 0)
- ExitWithError(error_fd, "pthread_sigmask");
-
- if (info.GetFlags().Test(eLaunchFlagDebug)) {
- // HACK:
- // Close everything besides stdin, stdout, and stderr that has no file
- // action to avoid leaking. Only do this when debugging, as elsewhere we
- // actually rely on
- // passing open descriptors to child processes.
- for (int fd = 3; fd < sysconf(_SC_OPEN_MAX); ++fd)
- if (!info.GetFileActionForFD(fd) && fd != error_fd)
- close(fd);
-
- // Start tracing this child that is about to exec.
- if (ptrace(PTRACE_TRACEME, 0, nullptr, nullptr) == -1)
- ExitWithError(error_fd, "ptrace");
- }
-
- // Execute. We should never return...
- execve(argv[0], const_cast<char *const *>(argv),
- const_cast<char *const *>(envp));
-
- if (errno == ETXTBSY) {
- // On android M and earlier we can get this error because the adb deamon 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 running the test suite. (The file remains open when
- // someone does
- // an "adb shell" command in the fork() child before it has had a chance to
- // exec.) Since
- // this state should clear up quickly, wait a while and then give it one
- // more go.
- usleep(50000);
- execve(argv[0], const_cast<char *const *>(argv),
- const_cast<char *const *>(envp));
- }
-
- // ...unless exec fails. In which case we definitely need to end the child
- // here.
- ExitWithError(error_fd, "execve");
-}
-
-HostProcess
-ProcessLauncherLinux::LaunchProcess(const ProcessLaunchInfo &launch_info,
- Error &error) {
- char exe_path[PATH_MAX];
- launch_info.GetExecutableFile().GetPath(exe_path, sizeof(exe_path));
-
- // A pipe used by the child process to report errors.
- PipePosix pipe;
- const bool child_processes_inherit = false;
- error = pipe.CreateNew(child_processes_inherit);
- if (error.Fail())
- return HostProcess();
-
- ::pid_t pid = ::fork();
- if (pid == -1) {
- // Fork failed
- error.SetErrorStringWithFormat("Fork failed with error message: %s",
- strerror(errno));
- return HostProcess(LLDB_INVALID_PROCESS_ID);
- }
- if (pid == 0) {
- // child process
- pipe.CloseReadFileDescriptor();
- ChildFunc(pipe.ReleaseWriteFileDescriptor(), launch_info);
- }
-
- // parent process
-
- pipe.CloseWriteFileDescriptor();
- char buf[1000];
- int r = read(pipe.GetReadFileDescriptor(), buf, sizeof buf);
-
- if (r == 0)
- return HostProcess(pid); // No error. We're done.
-
- error.SetErrorString(buf);
-
- waitpid(pid, nullptr, 0);
-
- return HostProcess();
-}
diff --git a/source/Host/linux/Support.cpp b/source/Host/linux/Support.cpp
new file mode 100644
index 000000000000..8fbb60052e3f
--- /dev/null
+++ b/source/Host/linux/Support.cpp
@@ -0,0 +1,34 @@
+//===-- Support.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/linux/Support.h"
+#include "lldb/Utility/Log.h"
+#include "llvm/Support/MemoryBuffer.h"
+
+llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
+lldb_private::getProcFile(::pid_t pid, ::pid_t tid, const llvm::Twine &file) {
+ Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+ std::string File =
+ ("/proc/" + llvm::Twine(pid) + "/task/" + llvm::Twine(tid) + "/" + file)
+ .str();
+ auto Ret = llvm::MemoryBuffer::getFileAsStream(File);
+ if (!Ret)
+ LLDB_LOG(log, "Failed to open {0}: {1}", File, Ret.getError().message());
+ return Ret;
+}
+
+llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
+lldb_private::getProcFile(::pid_t pid, const llvm::Twine &file) {
+ Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+ std::string File = ("/proc/" + llvm::Twine(pid) + "/" + file).str();
+ auto Ret = llvm::MemoryBuffer::getFileAsStream(File);
+ if (!Ret)
+ LLDB_LOG(log, "Failed to open {0}: {1}", File, Ret.getError().message());
+ return Ret;
+}
diff --git a/source/Host/linux/ThisThread.cpp b/source/Host/linux/ThisThread.cpp
deleted file mode 100644
index f65440b9d778..000000000000
--- a/source/Host/linux/ThisThread.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-//===-- ThisThread.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/ThisThread.h"
-#include "lldb/Host/HostNativeThread.h"
-
-#include "llvm/ADT/SmallVector.h"
-
-#include <pthread.h>
-
-using namespace lldb_private;
-
-void ThisThread::SetName(llvm::StringRef name) {
- HostNativeThread::SetName(::pthread_self(), name);
-}
-
-void ThisThread::GetName(llvm::SmallVectorImpl<char> &name) {
- HostNativeThread::GetName(::pthread_self(), name);
-}
diff --git a/source/Host/macosx/Host.mm b/source/Host/macosx/Host.mm
index 99bc7ec8ff15..4c51e8ff154b 100644
--- a/source/Host/macosx/Host.mm
+++ b/source/Host/macosx/Host.mm
@@ -56,24 +56,25 @@
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Communication.h"
-#include "lldb/Core/DataBufferHeap.h"
-#include "lldb/Core/DataExtractor.h"
-#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/StreamFile.h"
-#include "lldb/Core/StreamString.h"
#include "lldb/Core/StructuredData.h"
#include "lldb/Host/ConnectionFileDescriptor.h"
-#include "lldb/Host/Endian.h"
-#include "lldb/Host/FileSpec.h"
-#include "lldb/Host/FileSystem.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/ThreadLauncher.h"
#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
#include "lldb/Utility/CleanUp.h"
+#include "lldb/Utility/DataBufferHeap.h"
+#include "lldb/Utility/DataExtractor.h"
+#include "lldb/Utility/Endian.h"
+#include "lldb/Utility/FileSpec.h"
+#include "lldb/Utility/Log.h"
#include "lldb/Utility/NameMatches.h"
+#include "lldb/Utility/StreamString.h"
+
+#include "llvm/Support/FileSystem.h"
#include "cfcpp/CFCBundle.h"
#include "cfcpp/CFCMutableArray.h"
@@ -101,7 +102,7 @@ using namespace lldb_private;
bool Host::GetBundleDirectory(const FileSpec &file,
FileSpec &bundle_directory) {
#if defined(__APPLE__)
- if (file.GetFileType() == FileSpec::eFileTypeDirectory) {
+ if (llvm::sys::fs::is_directory(file.GetPath())) {
char path[PATH_MAX];
if (file.GetPath(path, sizeof(path))) {
CFCBundle bundle(path);
@@ -118,7 +119,7 @@ bool Host::GetBundleDirectory(const FileSpec &file,
bool Host::ResolveExecutableInBundle(FileSpec &file) {
#if defined(__APPLE__)
- if (file.GetFileType() == FileSpec::eFileTypeDirectory) {
+ if (llvm::sys::fs::is_directory(file.GetPath())) {
char path[PATH_MAX];
if (file.GetPath(path, sizeof(path))) {
CFCBundle bundle(path);
@@ -528,7 +529,7 @@ LaunchInNewTerminalWithAppleScript(const char *exe_path,
WaitForProcessToSIGSTOP(pid, 5);
}
- FileSystem::Unlink(FileSpec{unix_socket_name, false});
+ llvm::sys::fs::remove(unix_socket_name);
[applescript release];
if (pid != LLDB_INVALID_PROCESS_ID)
launch_info.SetProcessID(pid);
@@ -957,9 +958,7 @@ static Error getXPCAuthorization(ProcessLaunchInfo &launch_info) {
if (createStatus != errAuthorizationSuccess) {
error.SetError(1, eErrorTypeGeneric);
error.SetErrorString("Can't create authorizationRef.");
- if (log) {
- error.PutToLog(log, "%s", error.AsCString());
- }
+ LLDB_LOG(log, "error: {0}", error);
return error;
}
@@ -1012,9 +1011,7 @@ static Error getXPCAuthorization(ProcessLaunchInfo &launch_info) {
error.SetError(2, eErrorTypeGeneric);
error.SetErrorStringWithFormat(
"Launching as root needs root authorization.");
- if (log) {
- error.PutToLog(log, "%s", error.AsCString());
- }
+ LLDB_LOG(log, "error: {0}", error);
if (authorizationRef) {
AuthorizationFree(authorizationRef, kAuthorizationFlagDefaults);
@@ -1050,9 +1047,7 @@ static Error LaunchProcessXPC(const char *exe_path,
error.SetError(3, eErrorTypeGeneric);
error.SetErrorStringWithFormat("Launching root via XPC needs to "
"externalize authorization reference.");
- if (log) {
- error.PutToLog(log, "%s", error.AsCString());
- }
+ LLDB_LOG(log, "error: {0}", error);
return error;
}
xpc_service = LaunchUsingXPCRightName;
@@ -1060,9 +1055,7 @@ static Error LaunchProcessXPC(const char *exe_path,
error.SetError(4, eErrorTypeGeneric);
error.SetErrorStringWithFormat(
"Launching via XPC is only currently available for root.");
- if (log) {
- error.PutToLog(log, "%s", error.AsCString());
- }
+ LLDB_LOG(log, "error: {0}", error);
return error;
}
@@ -1146,9 +1139,7 @@ static Error LaunchProcessXPC(const char *exe_path,
error.SetErrorStringWithFormat(
"Problems with launching via XPC. Error type : %i, code : %i",
errorType, errorCode);
- if (log) {
- error.PutToLog(log, "%s", error.AsCString());
- }
+ LLDB_LOG(log, "error: {0}", error);
if (authorizationRef) {
AuthorizationFree(authorizationRef, kAuthorizationFlagDefaults);
@@ -1160,9 +1151,7 @@ static Error LaunchProcessXPC(const char *exe_path,
error.SetErrorStringWithFormat(
"Problems with launching via XPC. XPC error : %s",
xpc_dictionary_get_string(reply, XPC_ERROR_KEY_DESCRIPTION));
- if (log) {
- error.PutToLog(log, "%s", error.AsCString());
- }
+ LLDB_LOG(log, "error: {0}", error);
}
return error;
@@ -1196,8 +1185,8 @@ Error Host::LaunchProcess(ProcessLaunchInfo &launch_info) {
ModuleSpec exe_module_spec(launch_info.GetExecutableFile(),
launch_info.GetArchitecture());
- FileSpec::FileType file_type = exe_module_spec.GetFileSpec().GetFileType();
- if (file_type != FileSpec::eFileTypeRegular) {
+ if (!llvm::sys::fs::is_regular_file(
+ exe_module_spec.GetFileSpec().GetPath())) {
lldb::ModuleSP exe_module_sp;
error = host_platform_sp->ResolveExecutable(exe_module_spec, exe_module_sp,
NULL);
@@ -1458,7 +1447,3 @@ void Host::SystemLog(SystemLogType type, const char *format, va_list args) {
::asl_vlog(NULL, g_aslmsg, asl_level, format, args);
}
}
-
-lldb::DataBufferSP Host::GetAuxvData(lldb_private::Process *process) {
- return lldb::DataBufferSP();
-}
diff --git a/source/Host/macosx/HostInfoMacOSX.mm b/source/Host/macosx/HostInfoMacOSX.mm
index 1c526c6ecccb..8774c76ef2da 100644
--- a/source/Host/macosx/HostInfoMacOSX.mm
+++ b/source/Host/macosx/HostInfoMacOSX.mm
@@ -11,13 +11,14 @@
#include "Plugins/ScriptInterpreter/Python/lldb-python.h"
#endif
-#include "lldb/Core/Log.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/macosx/HostInfoMacOSX.h"
#include "lldb/Interpreter/Args.h"
+#include "lldb/Utility/Log.h"
#include "lldb/Utility/SafeMachO.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/FileSystem.h"
#include "llvm/Support/raw_ostream.h"
// C++ Includes
@@ -152,7 +153,7 @@ bool HostInfoMacOSX::ComputeSupportExeDirectory(FileSpec &file_spec) {
// the lldb driver.
raw_path.append("/../bin");
FileSpec support_dir_spec(raw_path, true);
- if (!support_dir_spec.Exists() || !support_dir_spec.IsDirectory()) {
+ if (!llvm::sys::fs::is_directory(support_dir_spec.GetPath())) {
Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
if (log)
log->Printf("HostInfoMacOSX::%s(): failed to find support directory",
@@ -334,5 +335,3 @@ void HostInfoMacOSX::ComputeHostArchitectureSupport(ArchSpec &arch_32,
}
}
}
-
-uint32_t HostInfoMacOSX::GetMaxThreadNameLength() { return 64; }
diff --git a/source/Host/macosx/Symbols.cpp b/source/Host/macosx/Symbols.cpp
index c428377eb7d2..a5085681495d 100644
--- a/source/Host/macosx/Symbols.cpp
+++ b/source/Host/macosx/Symbols.cpp
@@ -24,20 +24,22 @@
#include "Host/macosx/cfcpp/CFCReleaser.h"
#include "Host/macosx/cfcpp/CFCString.h"
#include "lldb/Core/ArchSpec.h"
-#include "lldb/Core/DataBuffer.h"
-#include "lldb/Core/DataExtractor.h"
-#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Core/StreamString.h"
#include "lldb/Core/Timer.h"
-#include "lldb/Core/UUID.h"
-#include "lldb/Host/Endian.h"
#include "lldb/Host/Host.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Utility/CleanUp.h"
+#include "lldb/Utility/DataBuffer.h"
+#include "lldb/Utility/DataExtractor.h"
+#include "lldb/Utility/Endian.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/StreamString.h"
+#include "lldb/Utility/UUID.h"
#include "mach/machine.h"
+#include "llvm/Support/FileSystem.h"
+
using namespace lldb;
using namespace lldb_private;
using namespace llvm::MachO;
@@ -101,7 +103,7 @@ int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec,
}
FileSpec dsym_filespec(path, path[0] == '~');
- if (dsym_filespec.GetFileType() == FileSpec::eFileTypeDirectory) {
+ if (llvm::sys::fs::is_directory(dsym_filespec.GetPath())) {
dsym_filespec =
Symbols::FindSymbolFileInBundle(dsym_filespec, uuid, arch);
++items_found;
@@ -164,8 +166,10 @@ int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec,
FileSpec file_spec(path, true);
ModuleSpecList module_specs;
ModuleSpec matched_module_spec;
- switch (file_spec.GetFileType()) {
- case FileSpec::eFileTypeDirectory: // Bundle directory?
+ using namespace llvm::sys::fs;
+ switch (get_file_type(file_spec.GetPath())) {
+
+ case file_type::directory_file: // Bundle directory?
{
CFCBundle bundle(path);
CFCReleaser<CFURLRef> bundle_exe_url(
@@ -193,15 +197,17 @@ int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec,
}
} break;
- case FileSpec::eFileTypePipe: // Forget pipes
- case FileSpec::eFileTypeSocket: // We can't process socket files
- case FileSpec::eFileTypeInvalid: // File doesn't exist...
+ case file_type::fifo_file: // Forget pipes
+ case file_type::socket_file: // We can't process socket files
+ case file_type::file_not_found: // File doesn't exist...
+ case file_type::status_error:
break;
- case FileSpec::eFileTypeUnknown:
- case FileSpec::eFileTypeRegular:
- case FileSpec::eFileTypeSymbolicLink:
- case FileSpec::eFileTypeOther:
+ case file_type::type_unknown:
+ case file_type::regular_file:
+ case file_type::symlink_file:
+ case file_type::block_file:
+ case file_type::character_file:
if (ObjectFile::GetModuleSpecifications(file_spec, 0, 0,
module_specs) &&
module_specs.FindMatchingModuleSpec(module_spec,
@@ -263,7 +269,9 @@ FileSpec Symbols::FindSymbolFileInBundle(const FileSpec &dsym_bundle_fspec,
module_specs)) {
ModuleSpec spec;
for (size_t i = 0; i < module_specs.GetSize(); ++i) {
- assert(module_specs.GetModuleSpecAtIndex(i, spec));
+ bool got_spec = module_specs.GetModuleSpecAtIndex(i, spec);
+ UNUSED_IF_ASSERT_DISABLED(got_spec);
+ assert(got_spec);
if ((uuid == NULL ||
(spec.GetUUIDPtr() && spec.GetUUID() == *uuid)) &&
(arch == NULL ||
diff --git a/source/Host/macosx/ThisThread.cpp b/source/Host/macosx/ThisThread.cpp
deleted file mode 100644
index 5244ba014121..000000000000
--- a/source/Host/macosx/ThisThread.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-//===-- ThisThread.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/ThisThread.h"
-
-#include "llvm/ADT/SmallVector.h"
-#include <pthread.h>
-
-using namespace lldb_private;
-
-void ThisThread::SetName(llvm::StringRef name) {
-#if defined(__APPLE__)
- ::pthread_setname_np(name.str().c_str());
-#endif
-}
-
-void ThisThread::GetName(llvm::SmallVectorImpl<char> &name) {
- // FIXME - implement this.
-}
diff --git a/source/Host/netbsd/Host.cpp b/source/Host/netbsd/Host.cpp
index 717af9b20aeb..6a6b8ab51a17 100644
--- a/source/Host/netbsd/Host.cpp
+++ b/source/Host/netbsd/Host.cpp
@@ -1,5 +1,4 @@
-//===-- source/Host/netbsd/Host.cpp ------------------------------*- C++
-//-*-===//
+//===-- source/Host/netbsd/Host.cpp -----------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,7 +14,6 @@
#include <sys/proc.h>
#include <sys/sysctl.h>
#include <sys/types.h>
-#include <sys/user.h>
#include <limits.h>
@@ -27,21 +25,21 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Core/DataExtractor.h"
-#include "lldb/Core/Error.h"
-#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/StreamFile.h"
-#include "lldb/Core/StreamString.h"
-#include "lldb/Host/Endian.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
+#include "lldb/Utility/DataExtractor.h"
+#include "lldb/Utility/Endian.h"
+#include "lldb/Utility/Error.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/StreamString.h"
-#include "lldb/Core/DataBufferHeap.h"
-#include "lldb/Core/DataExtractor.h"
#include "lldb/Utility/CleanUp.h"
+#include "lldb/Utility/DataBufferHeap.h"
+#include "lldb/Utility/DataExtractor.h"
#include "lldb/Utility/NameMatches.h"
#include "llvm/Support/Host.h"
@@ -54,15 +52,12 @@ using namespace lldb;
using namespace lldb_private;
size_t Host::GetEnvironment(StringList &env) {
- char *v;
- char **var = environ;
- for (; var != NULL && *var != NULL; ++var) {
- v = ::strchr(*var, (int)'-');
- if (v == NULL)
- continue;
- env.AppendString(v);
- }
- return env.GetSize();
+ char **host_env = environ;
+ char *env_entry;
+ size_t i;
+ for (i = 0; (env_entry = host_env[i]) != NULL; ++i)
+ env.AppendString(env_entry);
+ return i;
}
static bool GetNetBSDProcessArgs(const ProcessInstanceInfoMatch *match_info_ptr,
@@ -259,10 +254,6 @@ bool Host::GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &process_info) {
return false;
}
-lldb::DataBufferSP Host::GetAuxvData(lldb_private::Process *process) {
- return lldb::DataBufferSP();
-}
-
Error Host::ShellExpandArguments(ProcessLaunchInfo &launch_info) {
return Error("unimplemented");
}
diff --git a/source/Host/netbsd/HostInfoNetBSD.cpp b/source/Host/netbsd/HostInfoNetBSD.cpp
index 3c1385ab562f..428183bbe2c3 100644
--- a/source/Host/netbsd/HostInfoNetBSD.cpp
+++ b/source/Host/netbsd/HostInfoNetBSD.cpp
@@ -21,10 +21,6 @@
using namespace lldb_private;
-uint32_t HostInfoNetBSD::GetMaxThreadNameLength() {
- return PTHREAD_MAX_NAMELEN_NP;
-}
-
bool HostInfoNetBSD::GetOSVersion(uint32_t &major, uint32_t &minor,
uint32_t &update) {
struct utsname un;
@@ -85,15 +81,15 @@ FileSpec HostInfoNetBSD::GetProgramFileSpec() {
static FileSpec g_program_filespec;
if (!g_program_filespec) {
- ssize_t len;
- static char buf[PATH_MAX];
- char name[PATH_MAX];
-
- ::snprintf(name, PATH_MAX, "/proc/%d/exe", ::getpid());
- len = ::readlink(name, buf, PATH_MAX - 1);
- if (len != -1) {
- buf[len] = '\0';
- g_program_filespec.SetFile(buf, false);
+ static const int name[] = {
+ CTL_KERN, KERN_PROC_ARGS, -1, KERN_PROC_PATHNAME,
+ };
+ char path[MAXPATHLEN];
+ size_t len;
+
+ len = sizeof(path);
+ if (sysctl(name, __arraycount(name), path, &len, NULL, 0) != -1) {
+ g_program_filespec.SetFile(path, false);
}
}
return g_program_filespec;
diff --git a/source/Host/netbsd/HostThreadNetBSD.cpp b/source/Host/netbsd/HostThreadNetBSD.cpp
deleted file mode 100644
index e8c106b7f229..000000000000
--- a/source/Host/netbsd/HostThreadNetBSD.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-//===-- HostThreadNetBSD.cpp -----------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// lldb Includes
-#include "lldb/Host/netbsd/HostThreadNetBSD.h"
-#include "lldb/Host/Host.h"
-
-// C includes
-#include <errno.h>
-#include <pthread.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/sysctl.h>
-#include <sys/user.h>
-
-// C++ includes
-#include <string>
-
-using namespace lldb_private;
-
-HostThreadNetBSD::HostThreadNetBSD() {}
-
-HostThreadNetBSD::HostThreadNetBSD(lldb::thread_t thread)
- : HostThreadPosix(thread) {}
-
-void HostThreadNetBSD::SetName(lldb::thread_t thread, llvm::StringRef &name) {
- ::pthread_setname_np(thread, "%s", const_cast<char *>(name.data()));
-}
-
-void HostThreadNetBSD::GetName(lldb::thread_t thread,
- llvm::SmallVectorImpl<char> &name) {
- char buf[PTHREAD_MAX_NAMELEN_NP];
- ::pthread_getname_np(thread, buf, PTHREAD_MAX_NAMELEN_NP);
-
- name.clear();
- name.append(buf, buf + strlen(buf));
-}
diff --git a/source/Host/netbsd/ThisThread.cpp b/source/Host/netbsd/ThisThread.cpp
deleted file mode 100644
index ea16981ef257..000000000000
--- a/source/Host/netbsd/ThisThread.cpp
+++ /dev/null
@@ -1,26 +0,0 @@
-//===-- ThisThread.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/ThisThread.h"
-#include "lldb/Host/HostNativeThread.h"
-
-#include "llvm/ADT/SmallVector.h"
-
-#include <pthread.h>
-#include <string.h>
-
-using namespace lldb_private;
-
-void ThisThread::SetName(llvm::StringRef name) {
- HostNativeThread::SetName(::pthread_self(), name);
-}
-
-void ThisThread::GetName(llvm::SmallVectorImpl<char> &name) {
- HostNativeThread::GetName(::pthread_self(), name);
-}
diff --git a/source/Host/openbsd/Host.cpp b/source/Host/openbsd/Host.cpp
new file mode 100644
index 000000000000..c9ff69366c2f
--- /dev/null
+++ b/source/Host/openbsd/Host.cpp
@@ -0,0 +1,225 @@
+//===-- source/Host/openbsd/Host.cpp ----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// C Includes
+#include <sys/types.h>
+
+#include <sys/signal.h>
+#include <sys/exec.h>
+#include <sys/proc.h>
+#include <sys/ptrace.h>
+#include <sys/sysctl.h>
+#include <sys/user.h>
+
+#include <stdio.h>
+
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/Module.h"
+#include "lldb/Core/StreamFile.h"
+#include "lldb/Host/Host.h"
+#include "lldb/Host/HostInfo.h"
+#include "lldb/Target/Platform.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Utility/DataExtractor.h"
+#include "lldb/Utility/Endian.h"
+#include "lldb/Utility/Error.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/StreamString.h"
+
+#include "lldb/Utility/CleanUp.h"
+#include "lldb/Utility/DataBufferHeap.h"
+#include "lldb/Utility/DataExtractor.h"
+#include "lldb/Utility/NameMatches.h"
+
+#include "llvm/Support/Host.h"
+
+extern "C" {
+extern char **environ;
+}
+
+using namespace lldb;
+using namespace lldb_private;
+
+size_t Host::GetEnvironment(StringList &env) {
+ char *v;
+ char **var = environ;
+ for (; var != NULL && *var != NULL; ++var) {
+ v = strchr(*var, (int)'-');
+ if (v == NULL)
+ continue;
+ env.AppendString(v);
+ }
+ return env.GetSize();
+}
+
+static bool
+GetOpenBSDProcessArgs(const ProcessInstanceInfoMatch *match_info_ptr,
+ ProcessInstanceInfo &process_info) {
+ if (process_info.ProcessIDIsValid()) {
+ int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_ARGS,
+ (int)process_info.GetProcessID()};
+
+ char arg_data[8192];
+ size_t arg_data_size = sizeof(arg_data);
+ if (::sysctl(mib, 4, arg_data, &arg_data_size, NULL, 0) == 0) {
+ DataExtractor data(arg_data, arg_data_size, endian::InlHostByteOrder(),
+ sizeof(void *));
+ lldb::offset_t offset = 0;
+ const char *cstr;
+
+ cstr = data.GetCStr(&offset);
+ if (cstr) {
+ process_info.GetExecutableFile().SetFile(cstr, false);
+
+ if (!(match_info_ptr == NULL ||
+ NameMatches(
+ process_info.GetExecutableFile().GetFilename().GetCString(),
+ match_info_ptr->GetNameMatchType(),
+ match_info_ptr->GetProcessInfo().GetName())))
+ return false;
+
+ Args &proc_args = process_info.GetArguments();
+ while (1) {
+ const uint8_t *p = data.PeekData(offset, 1);
+ while ((p != NULL) && (*p == '\0') && offset < arg_data_size) {
+ ++offset;
+ p = data.PeekData(offset, 1);
+ }
+ if (p == NULL || offset >= arg_data_size)
+ return true;
+
+ cstr = data.GetCStr(&offset);
+ if (cstr)
+ proc_args.AppendArgument(llvm::StringRef(cstr));
+ else
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+}
+
+static bool GetOpenBSDProcessCPUType(ProcessInstanceInfo &process_info) {
+ if (process_info.ProcessIDIsValid()) {
+ process_info.GetArchitecture() =
+ HostInfo::GetArchitecture(HostInfo::eArchKindDefault);
+ return true;
+ }
+ process_info.GetArchitecture().Clear();
+ return false;
+}
+
+static bool GetOpenBSDProcessUserAndGroup(ProcessInstanceInfo &process_info) {
+ struct kinfo_proc proc_kinfo;
+ size_t proc_kinfo_size;
+
+ if (process_info.ProcessIDIsValid()) {
+ int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID,
+ (int)process_info.GetProcessID()};
+ proc_kinfo_size = sizeof(struct kinfo_proc);
+
+ if (::sysctl(mib, 4, &proc_kinfo, &proc_kinfo_size, NULL, 0) == 0) {
+ if (proc_kinfo_size > 0) {
+ process_info.SetParentProcessID(proc_kinfo.p_ppid);
+ process_info.SetUserID(proc_kinfo.p_ruid);
+ process_info.SetGroupID(proc_kinfo.p_rgid);
+ process_info.SetEffectiveUserID(proc_kinfo.p_uid);
+ process_info.SetEffectiveGroupID(proc_kinfo.p_gid);
+ return true;
+ }
+ }
+ }
+ process_info.SetParentProcessID(LLDB_INVALID_PROCESS_ID);
+ process_info.SetUserID(UINT32_MAX);
+ process_info.SetGroupID(UINT32_MAX);
+ process_info.SetEffectiveUserID(UINT32_MAX);
+ process_info.SetEffectiveGroupID(UINT32_MAX);
+ return false;
+}
+
+uint32_t Host::FindProcesses(const ProcessInstanceInfoMatch &match_info,
+ ProcessInstanceInfoList &process_infos) {
+ std::vector<struct kinfo_proc> kinfos;
+
+ int mib[3] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL};
+
+ size_t pid_data_size = 0;
+ if (::sysctl(mib, 3, NULL, &pid_data_size, NULL, 0) != 0)
+ return 0;
+
+ // Add a few extra in case a few more show up
+ const size_t estimated_pid_count =
+ (pid_data_size / sizeof(struct kinfo_proc)) + 10;
+
+ kinfos.resize(estimated_pid_count);
+ pid_data_size = kinfos.size() * sizeof(struct kinfo_proc);
+
+ if (::sysctl(mib, 3, &kinfos[0], &pid_data_size, NULL, 0) != 0)
+ return 0;
+
+ const size_t actual_pid_count = (pid_data_size / sizeof(struct kinfo_proc));
+
+ bool all_users = match_info.GetMatchAllUsers();
+ const ::pid_t our_pid = getpid();
+ const uid_t our_uid = getuid();
+ for (size_t i = 0; i < actual_pid_count; i++) {
+ const struct kinfo_proc &kinfo = kinfos[i];
+ const bool kinfo_user_matches = (all_users || (kinfo.p_ruid == our_uid) ||
+ // Special case, if lldb is being run as
+ // root we can attach to anything.
+ (our_uid == 0));
+
+ if (kinfo_user_matches == false || // Make sure the user is acceptable
+ kinfo.p_pid == our_pid || // Skip this process
+ kinfo.p_pid == 0 || // Skip kernel (kernel pid is zero)
+ kinfo.p_stat == SZOMB || // Zombies are bad, they like brains...
+ kinfo.p_psflags & PS_TRACED || // Being debugged?
+ kinfo.p_flag & P_WEXIT) // Working on exiting
+ continue;
+
+ ProcessInstanceInfo process_info;
+ process_info.SetProcessID(kinfo.p_pid);
+ process_info.SetParentProcessID(kinfo.p_ppid);
+ process_info.SetUserID(kinfo.p_ruid);
+ process_info.SetGroupID(kinfo.p_rgid);
+ process_info.SetEffectiveUserID(kinfo.p_svuid);
+ process_info.SetEffectiveGroupID(kinfo.p_svgid);
+
+ // Make sure our info matches before we go fetch the name and cpu type
+ if (match_info.Matches(process_info) &&
+ GetOpenBSDProcessArgs(&match_info, process_info)) {
+ GetOpenBSDProcessCPUType(process_info);
+ if (match_info.Matches(process_info))
+ process_infos.Append(process_info);
+ }
+ }
+
+ return process_infos.GetSize();
+}
+
+bool Host::GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &process_info) {
+ process_info.SetProcessID(pid);
+
+ if (GetOpenBSDProcessArgs(NULL, process_info)) {
+ // should use libprocstat instead of going right into sysctl?
+ GetOpenBSDProcessCPUType(process_info);
+ GetOpenBSDProcessUserAndGroup(process_info);
+ return true;
+ }
+
+ process_info.Clear();
+ return false;
+}
+
+Error Host::ShellExpandArguments(ProcessLaunchInfo &launch_info) {
+ return Error("unimplemented");
+}
diff --git a/source/Host/openbsd/HostInfoOpenBSD.cpp b/source/Host/openbsd/HostInfoOpenBSD.cpp
new file mode 100644
index 000000000000..548958899322
--- /dev/null
+++ b/source/Host/openbsd/HostInfoOpenBSD.cpp
@@ -0,0 +1,65 @@
+//===-- HostInfoOpenBSD.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/openbsd/HostInfoOpenBSD.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/sysctl.h>
+#include <sys/types.h>
+#include <sys/utsname.h>
+
+using namespace lldb_private;
+
+bool HostInfoOpenBSD::GetOSVersion(uint32_t &major, uint32_t &minor,
+ uint32_t &update) {
+ struct utsname un;
+
+ ::memset(&un, 0, sizeof(utsname));
+ if (uname(&un) < 0)
+ return false;
+
+ int status = sscanf(un.release, "%u.%u", &major, &minor);
+ return status == 2;
+}
+
+bool HostInfoOpenBSD::GetOSBuildString(std::string &s) {
+ int mib[2] = {CTL_KERN, KERN_OSREV};
+ char osrev_str[12];
+ uint32_t osrev = 0;
+ size_t osrev_len = sizeof(osrev);
+
+ if (::sysctl(mib, 2, &osrev, &osrev_len, NULL, 0) == 0) {
+ ::snprintf(osrev_str, sizeof(osrev_str), "%-8.8u", osrev);
+ s.assign(osrev_str);
+ return true;
+ }
+
+ s.clear();
+ return false;
+}
+
+bool HostInfoOpenBSD::GetOSKernelDescription(std::string &s) {
+ struct utsname un;
+
+ ::memset(&un, 0, sizeof(utsname));
+ s.clear();
+
+ if (uname(&un) < 0)
+ return false;
+
+ s.assign(un.version);
+
+ return true;
+}
+
+FileSpec HostInfoOpenBSD::GetProgramFileSpec() {
+ static FileSpec g_program_filespec;
+ return g_program_filespec;
+}
diff --git a/source/Host/posix/ConnectionFileDescriptorPosix.cpp b/source/Host/posix/ConnectionFileDescriptorPosix.cpp
index 64101fdc4267..a3ac36558e32 100644
--- a/source/Host/posix/ConnectionFileDescriptorPosix.cpp
+++ b/source/Host/posix/ConnectionFileDescriptorPosix.cpp
@@ -19,7 +19,6 @@
#include "lldb/Host/IOObject.h"
#include "lldb/Host/Socket.h"
#include "lldb/Host/SocketAddress.h"
-#include "lldb/Host/StringConvert.h"
#include "lldb/Utility/SelectHelper.h"
// C Includes
@@ -43,13 +42,12 @@
#endif
// Project includes
#include "lldb/Core/Communication.h"
-#include "lldb/Core/Log.h"
-#include "lldb/Core/StreamString.h"
#include "lldb/Core/Timer.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/Socket.h"
#include "lldb/Host/common/TCPSocket.h"
-#include "lldb/Interpreter/Args.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/StreamString.h"
using namespace lldb;
using namespace lldb_private;
@@ -561,10 +559,7 @@ ConnectionFileDescriptor::BytesAvailable(const Timeout<std::micro> &timeout,
// ever get used more generally we will need to lock here as well.
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_CONNECTION));
- if (log)
- log->Printf(
- "%p ConnectionFileDescriptor::BytesAvailable (timeout_usec = %lu)",
- static_cast<void *>(this), long(timeout ? timeout->count() : -1));
+ LLDB_LOG(log, "this = {0}, timeout = {1}", this, timeout);
// Make a copy of the file descriptors to make sure we don't
// have another thread change these values out from under us
@@ -753,14 +748,12 @@ ConnectionStatus ConnectionFileDescriptor::ConnectTCP(llvm::StringRef s,
ConnectionStatus ConnectionFileDescriptor::ConnectUDP(llvm::StringRef s,
Error *error_ptr) {
- Socket *send_socket = nullptr;
- Socket *recv_socket = nullptr;
- Error error = Socket::UdpConnect(s, m_child_processes_inherit, send_socket,
- recv_socket);
+ Socket *socket = nullptr;
+ Error error = Socket::UdpConnect(s, m_child_processes_inherit, socket);
if (error_ptr)
*error_ptr = error;
- m_write_sp.reset(send_socket);
- m_read_sp.reset(recv_socket);
+ m_write_sp.reset(socket);
+ m_read_sp = m_write_sp;
if (error.Fail()) {
return eConnectionStatusError;
}
diff --git a/source/Host/posix/DomainSocket.cpp b/source/Host/posix/DomainSocket.cpp
index cb0a1d057506..538979df2b6b 100644
--- a/source/Host/posix/DomainSocket.cpp
+++ b/source/Host/posix/DomainSocket.cpp
@@ -9,7 +9,7 @@
#include "lldb/Host/posix/DomainSocket.h"
-#include "lldb/Host/FileSystem.h"
+#include "llvm/Support/FileSystem.h"
#include <stddef.h>
#include <sys/socket.h>
@@ -116,5 +116,5 @@ Error DomainSocket::Accept(llvm::StringRef name, bool child_processes_inherit,
size_t DomainSocket::GetNameOffset() const { return 0; }
void DomainSocket::DeleteSocketFile(llvm::StringRef name) {
- FileSystem::Unlink(FileSpec{name, true});
+ llvm::sys::fs::remove(name);
}
diff --git a/source/Host/posix/FileSystem.cpp b/source/Host/posix/FileSystem.cpp
index aaa53ce07723..22f337fcfec5 100644
--- a/source/Host/posix/FileSystem.cpp
+++ b/source/Host/posix/FileSystem.cpp
@@ -25,149 +25,17 @@
#endif
// lldb Includes
-#include "lldb/Core/Error.h"
-#include "lldb/Core/StreamString.h"
#include "lldb/Host/Host.h"
+#include "lldb/Utility/Error.h"
+#include "lldb/Utility/StreamString.h"
+
+#include "llvm/Support/FileSystem.h"
using namespace lldb;
using namespace lldb_private;
const char *FileSystem::DEV_NULL = "/dev/null";
-FileSpec::PathSyntax FileSystem::GetNativePathSyntax() {
- return FileSpec::ePathSyntaxPosix;
-}
-
-Error FileSystem::MakeDirectory(const FileSpec &file_spec,
- uint32_t file_permissions) {
- if (file_spec) {
- Error error;
- if (::mkdir(file_spec.GetCString(), file_permissions) == -1) {
- error.SetErrorToErrno();
- errno = 0;
- switch (error.GetError()) {
- case ENOENT: {
- // Parent directory doesn't exist, so lets make it if we can
- // Make the parent directory and try again
- FileSpec parent_file_spec{file_spec.GetDirectory().GetCString(), false};
- error = MakeDirectory(parent_file_spec, file_permissions);
- if (error.Fail())
- return error;
- // Try and make the directory again now that the parent directory was
- // made successfully
- if (::mkdir(file_spec.GetCString(), file_permissions) == -1) {
- error.SetErrorToErrno();
- }
- return error;
- } break;
- case EEXIST: {
- if (file_spec.IsDirectory())
- return Error(); // It is a directory and it already exists
- } break;
- }
- }
- return error;
- }
- return Error("empty path");
-}
-
-Error FileSystem::DeleteDirectory(const FileSpec &file_spec, bool recurse) {
- Error error;
- if (file_spec) {
- if (recurse) {
- // Save all sub directories in a list so we don't recursively call this
- // function
- // and possibly run out of file descriptors if the directory is too deep.
- std::vector<FileSpec> sub_directories;
-
- FileSpec::ForEachItemInDirectory(
- file_spec.GetCString(),
- [&error, &sub_directories](
- FileSpec::FileType file_type,
- const FileSpec &spec) -> FileSpec::EnumerateDirectoryResult {
- if (file_type == FileSpec::eFileTypeDirectory) {
- // Save all directorires and process them after iterating through
- // this directory
- sub_directories.push_back(spec);
- } else {
- // Update sub_spec to point to the current file and delete it
- error = FileSystem::Unlink(spec);
- }
- // If anything went wrong, stop iterating, else process the next
- // file
- if (error.Fail())
- return FileSpec::eEnumerateDirectoryResultQuit;
- else
- return FileSpec::eEnumerateDirectoryResultNext;
- });
-
- if (error.Success()) {
- // Now delete all sub directories with separate calls that aren't
- // recursively calling into this function _while_ this function is
- // iterating through the current directory.
- for (const auto &sub_directory : sub_directories) {
- error = DeleteDirectory(sub_directory, recurse);
- if (error.Fail())
- break;
- }
- }
- }
-
- if (error.Success()) {
- if (::rmdir(file_spec.GetCString()) != 0)
- error.SetErrorToErrno();
- }
- } else {
- error.SetErrorString("empty path");
- }
- return error;
-}
-
-Error FileSystem::GetFilePermissions(const FileSpec &file_spec,
- uint32_t &file_permissions) {
- Error error;
- struct stat file_stats;
- if (::stat(file_spec.GetCString(), &file_stats) == 0) {
- // The bits in "st_mode" currently match the definitions
- // for the file mode bits in unix.
- file_permissions = file_stats.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
- } else {
- error.SetErrorToErrno();
- }
- return error;
-}
-
-Error FileSystem::SetFilePermissions(const FileSpec &file_spec,
- uint32_t file_permissions) {
- Error error;
- if (::chmod(file_spec.GetCString(), file_permissions) != 0)
- error.SetErrorToErrno();
- return error;
-}
-
-lldb::user_id_t FileSystem::GetFileSize(const FileSpec &file_spec) {
- return file_spec.GetByteSize();
-}
-
-bool FileSystem::GetFileExists(const FileSpec &file_spec) {
- return file_spec.Exists();
-}
-
-Error FileSystem::Hardlink(const FileSpec &src, const FileSpec &dst) {
- Error error;
- if (::link(dst.GetCString(), src.GetCString()) == -1)
- error.SetErrorToErrno();
- return error;
-}
-
-int FileSystem::GetHardlinkCount(const FileSpec &file_spec) {
- struct stat file_stat;
- if (::stat(file_spec.GetCString(), &file_stat) == 0)
- return file_stat.st_nlink;
-
- return -1;
-}
-
Error FileSystem::Symlink(const FileSpec &src, const FileSpec &dst) {
Error error;
if (::symlink(dst.GetCString(), src.GetCString()) == -1)
@@ -175,13 +43,6 @@ Error FileSystem::Symlink(const FileSpec &src, const FileSpec &dst) {
return error;
}
-Error FileSystem::Unlink(const FileSpec &file_spec) {
- Error error;
- if (::unlink(file_spec.GetCString()) == -1)
- error.SetErrorToErrno();
- return error;
-}
-
Error FileSystem::Readlink(const FileSpec &src, FileSpec &dst) {
Error error;
char buf[PATH_MAX];
@@ -213,50 +74,6 @@ Error FileSystem::ResolveSymbolicLink(const FileSpec &src, FileSpec &dst) {
return Error();
}
-#if defined(__NetBSD__)
-static bool IsLocal(const struct statvfs &info) {
- return (info.f_flag & MNT_LOCAL) != 0;
-}
-#else
-static bool IsLocal(const struct statfs &info) {
-#ifdef __linux__
-#define CIFS_MAGIC_NUMBER 0xFF534D42
- switch ((uint32_t)info.f_type) {
- case NFS_SUPER_MAGIC:
- case SMB_SUPER_MAGIC:
- case CIFS_MAGIC_NUMBER:
- return false;
- default:
- return true;
- }
-#else
- return (info.f_flags & MNT_LOCAL) != 0;
-#endif
-}
-#endif
-
-#if defined(__NetBSD__)
-bool FileSystem::IsLocal(const FileSpec &spec) {
- struct statvfs statfs_info;
- std::string path(spec.GetPath());
- if (statvfs(path.c_str(), &statfs_info) == 0)
- return ::IsLocal(statfs_info);
- return false;
-}
-#else
-bool FileSystem::IsLocal(const FileSpec &spec) {
- struct statfs statfs_info;
- std::string path(spec.GetPath());
- if (statfs(path.c_str(), &statfs_info) == 0)
- return ::IsLocal(statfs_info);
- return false;
-}
-#endif
-
FILE *FileSystem::Fopen(const char *path, const char *mode) {
return ::fopen(path, mode);
}
-
-int FileSystem::Stat(const char *path, struct stat *stats) {
- return ::stat(path, stats);
-}
diff --git a/source/Host/posix/HostInfoPosix.cpp b/source/Host/posix/HostInfoPosix.cpp
index 38aac59ecc40..da9e1fb366cc 100644
--- a/source/Host/posix/HostInfoPosix.cpp
+++ b/source/Host/posix/HostInfoPosix.cpp
@@ -11,8 +11,8 @@
#include "Plugins/ScriptInterpreter/Python/lldb-python.h"
#endif
-#include "lldb/Core/Log.h"
#include "lldb/Host/posix/HostInfoPosix.h"
+#include "lldb/Utility/Log.h"
#include "clang/Basic/Version.h"
#include "clang/Config/config.h"
diff --git a/source/Host/posix/HostThreadPosix.cpp b/source/Host/posix/HostThreadPosix.cpp
index ac398998c20f..073b7b0b11e8 100644
--- a/source/Host/posix/HostThreadPosix.cpp
+++ b/source/Host/posix/HostThreadPosix.cpp
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
#include "lldb/Host/posix/HostThreadPosix.h"
-#include "lldb/Core/Error.h"
+#include "lldb/Utility/Error.h"
#include <errno.h>
#include <pthread.h>
diff --git a/source/Host/posix/MainLoopPosix.cpp b/source/Host/posix/MainLoopPosix.cpp
index 08c969e72a26..a73187e730f0 100644
--- a/source/Host/posix/MainLoopPosix.cpp
+++ b/source/Host/posix/MainLoopPosix.cpp
@@ -8,13 +8,13 @@
//===----------------------------------------------------------------------===//
#include "lldb/Host/posix/MainLoopPosix.h"
-#include "lldb/Core/Error.h"
+#include "lldb/Utility/Error.h"
#include <algorithm>
#include <cassert>
#include <cerrno>
#include <csignal>
-#include <vector>
#include <sys/select.h>
+#include <vector>
using namespace lldb;
using namespace lldb_private;
diff --git a/source/Host/posix/PipePosix.cpp b/source/Host/posix/PipePosix.cpp
index 4e0810c1a9b3..3ac5d480de89 100644
--- a/source/Host/posix/PipePosix.cpp
+++ b/source/Host/posix/PipePosix.cpp
@@ -8,7 +8,6 @@
//===----------------------------------------------------------------------===//
#include "lldb/Host/posix/PipePosix.h"
-#include "lldb/Host/FileSystem.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Utility/SelectHelper.h"
#include "llvm/ADT/SmallString.h"
@@ -231,7 +230,7 @@ void PipePosix::Close() {
}
Error PipePosix::Delete(llvm::StringRef name) {
- return FileSystem::Unlink(FileSpec{name.data(), true});
+ return llvm::sys::fs::remove(name);
}
bool PipePosix::CanRead() const {
diff --git a/source/Host/posix/ProcessLauncherPosixFork.cpp b/source/Host/posix/ProcessLauncherPosixFork.cpp
new file mode 100644
index 000000000000..91c32d6e6426
--- /dev/null
+++ b/source/Host/posix/ProcessLauncherPosixFork.cpp
@@ -0,0 +1,231 @@
+//===-- ProcessLauncherLinux.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/posix/ProcessLauncherPosixFork.h"
+#include "lldb/Host/Host.h"
+#include "lldb/Host/HostProcess.h"
+#include "lldb/Host/Pipe.h"
+#include "lldb/Target/ProcessLaunchInfo.h"
+#include "lldb/Utility/FileSpec.h"
+#include "lldb/Utility/Log.h"
+
+#include <limits.h>
+#include <sys/ptrace.h>
+#include <sys/wait.h>
+
+#include <sstream>
+
+#ifdef __ANDROID__
+#include <android/api-level.h>
+#define PT_TRACE_ME PTRACE_TRACEME
+#endif
+
+#if defined(__ANDROID_API__) && __ANDROID_API__ < 21
+#include <linux/personality.h>
+#elif defined(__linux__)
+#include <sys/personality.h>
+#endif
+
+using namespace lldb;
+using namespace lldb_private;
+
+static void FixupEnvironment(Args &env) {
+#ifdef __ANDROID__
+ // If there is no PATH variable specified inside the environment then set the
+ // path to /system/bin. It is required because the default path used by
+ // execve() is wrong on android.
+ static const char *path = "PATH=";
+ for (auto &entry : env.entries()) {
+ if (entry.ref.startswith(path))
+ return;
+ }
+ env.AppendArgument(llvm::StringRef("PATH=/system/bin"));
+#endif
+}
+
+static void LLVM_ATTRIBUTE_NORETURN ExitWithError(int error_fd,
+ const char *operation) {
+ std::ostringstream os;
+ os << operation << " failed: " << strerror(errno);
+ write(error_fd, os.str().data(), os.str().size());
+ close(error_fd);
+ _exit(1);
+}
+
+static void DisableASLRIfRequested(int error_fd, const ProcessLaunchInfo &info) {
+#if defined(__linux__)
+ if (info.GetFlags().Test(lldb::eLaunchFlagDisableASLR)) {
+ const unsigned long personality_get_current = 0xffffffff;
+ int value = personality(personality_get_current);
+ if (value == -1)
+ ExitWithError(error_fd, "personality get");
+
+ value = personality(ADDR_NO_RANDOMIZE | value);
+ if (value == -1)
+ ExitWithError(error_fd, "personality set");
+ }
+#endif
+}
+
+static void DupDescriptor(int error_fd, const FileSpec &file_spec, int fd,
+ int flags) {
+ int target_fd = ::open(file_spec.GetCString(), flags, 0666);
+
+ if (target_fd == -1)
+ ExitWithError(error_fd, "DupDescriptor-open");
+
+ if (target_fd == fd)
+ return;
+
+ if (::dup2(target_fd, fd) == -1)
+ ExitWithError(error_fd, "DupDescriptor-dup2");
+
+ ::close(target_fd);
+ return;
+}
+
+static void LLVM_ATTRIBUTE_NORETURN ChildFunc(int error_fd,
+ const ProcessLaunchInfo &info) {
+ // First, make sure we disable all logging. If we are logging to stdout, our
+ // logs can be mistaken for inferior output.
+ Log::DisableAllLogChannels();
+
+ // Do not inherit setgid powers.
+ if (setgid(getgid()) != 0)
+ ExitWithError(error_fd, "setgid");
+
+ if (info.GetFlags().Test(eLaunchFlagLaunchInSeparateProcessGroup)) {
+ if (setpgid(0, 0) != 0)
+ ExitWithError(error_fd, "setpgid");
+ }
+
+ for (size_t i = 0; i < info.GetNumFileActions(); ++i) {
+ const FileAction &action = *info.GetFileActionAtIndex(i);
+ switch (action.GetAction()) {
+ case FileAction::eFileActionClose:
+ if (close(action.GetFD()) != 0)
+ ExitWithError(error_fd, "close");
+ break;
+ case FileAction::eFileActionDuplicate:
+ if (dup2(action.GetFD(), action.GetActionArgument()) == -1)
+ ExitWithError(error_fd, "dup2");
+ break;
+ case FileAction::eFileActionOpen:
+ DupDescriptor(error_fd, action.GetFileSpec(), action.GetFD(),
+ action.GetActionArgument());
+ break;
+ case FileAction::eFileActionNone:
+ break;
+ }
+ }
+
+ const char **argv = info.GetArguments().GetConstArgumentVector();
+
+ // Change working directory
+ if (info.GetWorkingDirectory() &&
+ 0 != ::chdir(info.GetWorkingDirectory().GetCString()))
+ ExitWithError(error_fd, "chdir");
+
+ DisableASLRIfRequested(error_fd, info);
+ Args env = info.GetEnvironmentEntries();
+ FixupEnvironment(env);
+ const char **envp = env.GetConstArgumentVector();
+
+ // Clear the signal mask to prevent the child from being affected by
+ // any masking done by the parent.
+ sigset_t set;
+ if (sigemptyset(&set) != 0 ||
+ pthread_sigmask(SIG_SETMASK, &set, nullptr) != 0)
+ ExitWithError(error_fd, "pthread_sigmask");
+
+ if (info.GetFlags().Test(eLaunchFlagDebug)) {
+ // HACK:
+ // Close everything besides stdin, stdout, and stderr that has no file
+ // action to avoid leaking. Only do this when debugging, as elsewhere we
+ // actually rely on
+ // passing open descriptors to child processes.
+ for (int fd = 3; fd < sysconf(_SC_OPEN_MAX); ++fd)
+ if (!info.GetFileActionForFD(fd) && fd != error_fd)
+ close(fd);
+
+ // Start tracing this child that is about to exec.
+ if (ptrace(PT_TRACE_ME, 0, nullptr, 0) == -1)
+ ExitWithError(error_fd, "ptrace");
+ }
+
+ // Execute. We should never return...
+ execve(argv[0], const_cast<char *const *>(argv),
+ const_cast<char *const *>(envp));
+
+#if defined(__linux__)
+ if (errno == ETXTBSY) {
+ // On android M and earlier we can get this error because the adb deamon 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 running the test suite. (The file remains open when
+ // someone does
+ // an "adb shell" command in the fork() child before it has had a chance to
+ // exec.) Since
+ // this state should clear up quickly, wait a while and then give it one
+ // more go.
+ usleep(50000);
+ execve(argv[0], const_cast<char *const *>(argv),
+ const_cast<char *const *>(envp));
+ }
+#endif
+
+ // ...unless exec fails. In which case we definitely need to end the child
+ // here.
+ ExitWithError(error_fd, "execve");
+}
+
+HostProcess
+ProcessLauncherPosixFork::LaunchProcess(const ProcessLaunchInfo &launch_info,
+ Error &error) {
+ char exe_path[PATH_MAX];
+ launch_info.GetExecutableFile().GetPath(exe_path, sizeof(exe_path));
+
+ // A pipe used by the child process to report errors.
+ PipePosix pipe;
+ const bool child_processes_inherit = false;
+ error = pipe.CreateNew(child_processes_inherit);
+ if (error.Fail())
+ return HostProcess();
+
+ ::pid_t pid = ::fork();
+ if (pid == -1) {
+ // Fork failed
+ error.SetErrorStringWithFormat("Fork failed with error message: %s",
+ strerror(errno));
+ return HostProcess(LLDB_INVALID_PROCESS_ID);
+ }
+ if (pid == 0) {
+ // child process
+ pipe.CloseReadFileDescriptor();
+ ChildFunc(pipe.ReleaseWriteFileDescriptor(), launch_info);
+ }
+
+ // parent process
+
+ pipe.CloseWriteFileDescriptor();
+ char buf[1000];
+ int r = read(pipe.GetReadFileDescriptor(), buf, sizeof buf);
+
+ if (r == 0)
+ return HostProcess(pid); // No error. We're done.
+
+ error.SetErrorString(buf);
+
+ waitpid(pid, nullptr, 0);
+
+ return HostProcess();
+}
diff --git a/source/Host/windows/ConnectionGenericFileWindows.cpp b/source/Host/windows/ConnectionGenericFileWindows.cpp
index 5d48a1c867ad..8fc038f3f9b6 100644
--- a/source/Host/windows/ConnectionGenericFileWindows.cpp
+++ b/source/Host/windows/ConnectionGenericFileWindows.cpp
@@ -8,8 +8,9 @@
//===----------------------------------------------------------------------===//
#include "lldb/Host/windows/ConnectionGenericFileWindows.h"
-#include "lldb/Core/Error.h"
-#include "lldb/Core/Log.h"
+#include "lldb/Utility/Error.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/Timeout.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
diff --git a/source/Host/windows/FileSystem.cpp b/source/Host/windows/FileSystem.cpp
index f0ba7376876d..092b70b1f4dc 100644
--- a/source/Host/windows/FileSystem.cpp
+++ b/source/Host/windows/FileSystem.cpp
@@ -15,6 +15,7 @@
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/windows/AutoHandle.h"
+#include "lldb/Host/windows/PosixApi.h"
#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/FileSystem.h"
@@ -26,126 +27,6 @@ const char *FileSystem::DEV_NULL = "nul";
const char *FileSystem::PATH_CONVERSION_ERROR =
"Error converting path between UTF-8 and native encoding";
-FileSpec::PathSyntax FileSystem::GetNativePathSyntax() {
- return FileSpec::ePathSyntaxWindows;
-}
-
-Error FileSystem::MakeDirectory(const FileSpec &file_spec,
- uint32_t file_permissions) {
- // On Win32, the mode parameter is ignored, as Windows files and directories
- // support a
- // different permission model than POSIX.
- Error error;
- const auto err_code =
- llvm::sys::fs::create_directories(file_spec.GetPath(), true);
- if (err_code) {
- error.SetErrorString(err_code.message().c_str());
- }
-
- return error;
-}
-
-Error FileSystem::DeleteDirectory(const FileSpec &file_spec, bool recurse) {
- Error error;
- std::wstring path_buffer;
- if (!llvm::ConvertUTF8toWide(file_spec.GetPath(), path_buffer)) {
- error.SetErrorString(PATH_CONVERSION_ERROR);
- return error;
- }
- if (!recurse) {
- BOOL result = ::RemoveDirectoryW(path_buffer.c_str());
- if (!result)
- error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
- } else {
- // SHFileOperation() accepts a list of paths, and so must be
- // double-null-terminated to
- // indicate the end of the list. The first null terminator is there only in
- // the backing
- // store but not the actual vector contents, and so we need to push twice.
- path_buffer.push_back(0);
- path_buffer.push_back(0);
-
- SHFILEOPSTRUCTW shfos = {};
- shfos.wFunc = FO_DELETE;
- shfos.pFrom = (LPCWSTR)path_buffer.data();
- shfos.fFlags = FOF_NO_UI;
-
- int result = ::SHFileOperationW(&shfos);
- // TODO(zturner): Correctly handle the intricacies of SHFileOperation return
- // values.
- if (result != 0)
- error.SetErrorStringWithFormat("SHFileOperation failed");
- }
- return error;
-}
-
-Error FileSystem::GetFilePermissions(const FileSpec &file_spec,
- uint32_t &file_permissions) {
- Error error;
- // Beware that Windows's permission model is different from Unix's, and it's
- // not clear if this API is supposed to check ACLs. To match the caller's
- // expectations as closely as possible, we'll use Microsoft's _stat, which
- // attempts to emulate POSIX stat. This should be good enough for basic
- // checks like FileSpec::Readable.
- struct _stat file_stats;
- if (::_stat(file_spec.GetCString(), &file_stats) == 0) {
- // The owner permission bits in "st_mode" currently match the definitions
- // for the owner file mode bits.
- file_permissions = file_stats.st_mode & (_S_IREAD | _S_IWRITE | _S_IEXEC);
- } else {
- error.SetErrorToErrno();
- }
-
- return error;
-}
-
-Error FileSystem::SetFilePermissions(const FileSpec &file_spec,
- uint32_t file_permissions) {
- Error error;
- error.SetErrorStringWithFormat("%s is not supported on this host",
- LLVM_PRETTY_FUNCTION);
- return error;
-}
-
-lldb::user_id_t FileSystem::GetFileSize(const FileSpec &file_spec) {
- return file_spec.GetByteSize();
-}
-
-bool FileSystem::GetFileExists(const FileSpec &file_spec) {
- return file_spec.Exists();
-}
-
-Error FileSystem::Hardlink(const FileSpec &src, const FileSpec &dst) {
- Error error;
- std::wstring wsrc, wdst;
- if (!llvm::ConvertUTF8toWide(src.GetCString(), wsrc) ||
- !llvm::ConvertUTF8toWide(dst.GetCString(), wdst))
- error.SetErrorString(PATH_CONVERSION_ERROR);
- else if (!::CreateHardLinkW(wsrc.c_str(), wdst.c_str(), nullptr))
- error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
- return error;
-}
-
-int FileSystem::GetHardlinkCount(const FileSpec &file_spec) {
- std::wstring path;
- if (!llvm::ConvertUTF8toWide(file_spec.GetCString(), path))
- return -1;
-
- HANDLE file_handle =
- ::CreateFileW(path.c_str(), FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
- nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
-
- if (file_handle == INVALID_HANDLE_VALUE)
- return -1;
-
- AutoHandle auto_file_handle(file_handle);
- BY_HANDLE_FILE_INFORMATION file_info;
- if (::GetFileInformationByHandle(file_handle, &file_info))
- return file_info.nNumberOfLinks;
-
- return -1;
-}
-
Error FileSystem::Symlink(const FileSpec &src, const FileSpec &dst) {
Error error;
std::wstring wsrc, wdst;
@@ -167,19 +48,6 @@ Error FileSystem::Symlink(const FileSpec &src, const FileSpec &dst) {
return error;
}
-Error FileSystem::Unlink(const FileSpec &file_spec) {
- Error error;
- std::wstring path;
- if (!llvm::ConvertUTF8toWide(file_spec.GetCString(), path)) {
- error.SetErrorString(PATH_CONVERSION_ERROR);
- return error;
- }
- BOOL result = ::DeleteFileW(path.c_str());
- if (!result)
- error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
- return error;
-}
-
Error FileSystem::Readlink(const FileSpec &src, FileSpec &dst) {
Error error;
std::wstring wsrc;
@@ -217,15 +85,6 @@ Error FileSystem::ResolveSymbolicLink(const FileSpec &src, FileSpec &dst) {
return Error("ResolveSymbolicLink() isn't implemented on Windows");
}
-bool FileSystem::IsLocal(const FileSpec &spec) {
- if (spec) {
- // TODO: return true if the file is on a locally mounted file system
- return true;
- }
-
- return false;
-}
-
FILE *FileSystem::Fopen(const char *path, const char *mode) {
std::wstring wpath, wmode;
if (!llvm::ConvertUTF8toWide(path, wpath))
@@ -237,25 +96,3 @@ FILE *FileSystem::Fopen(const char *path, const char *mode) {
return nullptr;
return file;
}
-
-int FileSystem::Stat(const char *path, struct stat *stats) {
- std::wstring wpath;
- if (!llvm::ConvertUTF8toWide(path, wpath)) {
- errno = EINVAL;
- return -EINVAL;
- }
- int stat_result;
-#ifdef _USE_32BIT_TIME_T
- struct _stat32 file_stats;
- stat_result = ::_wstat32(wpath.c_str(), &file_stats);
-#else
- struct _stat64i32 file_stats;
- stat_result = ::_wstat64i32(wpath.c_str(), &file_stats);
-#endif
- if (stat_result == 0) {
- static_assert(sizeof(struct stat) == sizeof(file_stats),
- "stat and _stat32/_stat64i32 must have the same layout");
- *stats = *reinterpret_cast<struct stat *>(&file_stats);
- }
- return stat_result;
-}
diff --git a/source/Host/windows/Host.cpp b/source/Host/windows/Host.cpp
index 3da073605dcb..9a6957b2a1ff 100644
--- a/source/Host/windows/Host.cpp
+++ b/source/Host/windows/Host.cpp
@@ -15,16 +15,16 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Core/Error.h"
-#include "lldb/Core/Log.h"
#include "lldb/Target/Process.h"
+#include "lldb/Utility/Error.h"
+#include "lldb/Utility/Log.h"
-#include "lldb/Core/DataBufferHeap.h"
-#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/StructuredData.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
+#include "lldb/Utility/DataBufferHeap.h"
+#include "lldb/Utility/DataExtractor.h"
#include "llvm/Support/ConvertUTF.h"
@@ -97,14 +97,6 @@ void GetProcessExecutableAndTriple(const AutoHandle &handle,
}
}
-lldb::DataBufferSP Host::GetAuxvData(lldb_private::Process *process) {
- return 0;
-}
-
-lldb::tid_t Host::GetCurrentThreadID() {
- return lldb::tid_t(::GetCurrentThreadId());
-}
-
lldb::thread_t Host::GetCurrentThread() {
return lldb::thread_t(::GetCurrentThread());
}
diff --git a/source/Host/windows/HostInfoWindows.cpp b/source/Host/windows/HostInfoWindows.cpp
index a965ec0ea4e2..53a24ad1893e 100644
--- a/source/Host/windows/HostInfoWindows.cpp
+++ b/source/Host/windows/HostInfoWindows.cpp
@@ -14,10 +14,12 @@
#include <mutex> // std::once
#include "lldb/Host/windows/HostInfoWindows.h"
+#include "lldb/Host/windows/PosixApi.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
+#include "llvm/Support/Threading.h"
#include "llvm/Support/raw_ostream.h"
using namespace lldb_private;
@@ -90,8 +92,8 @@ bool HostInfoWindows::GetHostname(std::string &s) {
}
FileSpec HostInfoWindows::GetProgramFileSpec() {
- static std::once_flag g_once_flag;
- std::call_once(g_once_flag, []() {
+ static llvm::once_flag g_once_flag;
+ llvm::call_once(g_once_flag, []() {
std::vector<wchar_t> buffer(PATH_MAX);
::GetModuleFileNameW(NULL, buffer.data(), buffer.size());
std::string path;
diff --git a/source/Host/windows/HostProcessWindows.cpp b/source/Host/windows/HostProcessWindows.cpp
index 8201d53bd27c..3bbc84a4ca59 100644
--- a/source/Host/windows/HostProcessWindows.cpp
+++ b/source/Host/windows/HostProcessWindows.cpp
@@ -8,10 +8,10 @@
//===----------------------------------------------------------------------===//
#include "lldb/Host/windows/HostProcessWindows.h"
-#include "lldb/Host/FileSpec.h"
#include "lldb/Host/HostThread.h"
#include "lldb/Host/ThreadLauncher.h"
#include "lldb/Host/windows/windows.h"
+#include "lldb/Utility/FileSpec.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/ConvertUTF.h"
diff --git a/source/Host/windows/HostThreadWindows.cpp b/source/Host/windows/HostThreadWindows.cpp
index 41be21bfa304..aa791714c338 100644
--- a/source/Host/windows/HostThreadWindows.cpp
+++ b/source/Host/windows/HostThreadWindows.cpp
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
-#include "lldb/Core/Error.h"
+#include "lldb/Utility/Error.h"
#include "lldb/Host/windows/HostThreadWindows.h"
#include "lldb/Host/windows/windows.h"
diff --git a/source/Host/windows/ThisThread.cpp b/source/Host/windows/ThisThread.cpp
deleted file mode 100644
index 8db12f05b0ba..000000000000
--- a/source/Host/windows/ThisThread.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-//===-- ThisThread.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/Core/Error.h"
-
-#include "lldb/Host/ThisThread.h"
-#include "lldb/Host/windows/windows.h"
-
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/SmallVector.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-#if defined(_MSC_VER) && !defined(__clang__)
-
-namespace {
-static const DWORD MS_VC_EXCEPTION = 0x406D1388;
-
-#pragma pack(push, 8)
-struct THREADNAME_INFO {
- DWORD dwType; // Must be 0x1000.
- LPCSTR szName; // Pointer to thread name
- DWORD dwThreadId; // Thread ID (-1 == current thread)
- DWORD dwFlags; // Reserved. Do not use.
-};
-#pragma pack(pop)
-}
-
-#endif
-
-void ThisThread::SetName(llvm::StringRef name) {
-// Other compilers don't yet support SEH, so we can only set the thread if
-// compiling with MSVC.
-// TODO(zturner): Once clang-cl supports SEH, relax this conditional.
-#if defined(_MSC_VER) && !defined(__clang__)
- THREADNAME_INFO info;
- info.dwType = 0x1000;
- info.szName = name.data();
- info.dwThreadId = ::GetCurrentThreadId();
- info.dwFlags = 0;
-
- __try {
- ::RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR),
- (ULONG_PTR *)&info);
- } __except (EXCEPTION_EXECUTE_HANDLER) {
- }
-#endif
-}
-
-void ThisThread::GetName(llvm::SmallVectorImpl<char> &name) {
- // Getting the thread name is not supported on Windows.
- // TODO(zturner): In SetName(), make a TLS entry that contains the thread's
- // name, and in this function
- // try to extract that TLS entry.
- name.clear();
-}
diff --git a/source/Host/windows/Windows.cpp b/source/Host/windows/Windows.cpp
index 21afc6d85da5..9d0e70e6d126 100644
--- a/source/Host/windows/Windows.cpp
+++ b/source/Host/windows/Windows.cpp
@@ -23,13 +23,6 @@
#include <stdlib.h>
#include <string.h>
-// These prototypes are defined in <direct.h>, but it also defines chdir() and
-// getcwd(), giving multiply defined errors
-extern "C" {
-char *_getcwd(char *buffer, int maxlen);
-int _chdir(const char *path);
-}
-
namespace {
bool utf8ToWide(const char *utf8, wchar_t *buf, size_t bufSize) {
const llvm::UTF8 *sourceStart = reinterpret_cast<const llvm::UTF8 *>(utf8);
@@ -190,31 +183,6 @@ char *basename(char *path) {
return &l1[1];
}
-// use _getcwd() instead of GetCurrentDirectory() because it updates errno
-char *getcwd(char *path, int max) {
- assert(path == NULL || max <= PATH_MAX);
- wchar_t wpath[PATH_MAX];
- if (wchar_t *wresult = _wgetcwd(wpath, PATH_MAX)) {
- // Caller is allowed to pass in NULL for `path`.
- // In that case, we're supposed to allocate a
- // buffer on the caller's behalf.
- if (path == NULL) {
- max = UNI_MAX_UTF8_BYTES_PER_CODE_POINT * wcslen(wresult) + 1;
- path = (char *)malloc(max);
- if (path == NULL) {
- errno = ENOMEM;
- return NULL;
- }
- }
- if (wideToUtf8(wresult, path, max))
- return path;
- }
- return NULL;
-}
-
-// use _chdir() instead of SetCurrentDirectory() because it updates errno
-int chdir(const char *path) { return _chdir(path); }
-
char *dirname(char *path) {
char *l1 = strrchr(path, '\\');
char *l2 = strrchr(path, '/');