summaryrefslogtreecommitdiff
path: root/source/Host
diff options
context:
space:
mode:
Diffstat (limited to 'source/Host')
-rw-r--r--source/Host/CMakeLists.txt179
-rw-r--r--source/Host/android/HostInfoAndroid.cpp95
-rw-r--r--source/Host/android/LibcGlue.cpp29
-rw-r--r--source/Host/linux/AbstractSocket.cpp22
-rw-r--r--source/Host/linux/Host.cpp297
-rw-r--r--source/Host/linux/HostInfoLinux.cpp228
-rw-r--r--source/Host/linux/LibcGlue.cpp31
-rw-r--r--source/Host/linux/ProcessLauncherLinux.cpp0
-rw-r--r--source/Host/linux/Support.cpp44
-rw-r--r--source/Host/macosx/Symbols.cpp655
-rw-r--r--source/Host/macosx/cfcpp/CFCBundle.cpp83
-rw-r--r--source/Host/macosx/cfcpp/CFCBundle.h42
-rw-r--r--source/Host/macosx/cfcpp/CFCData.cpp66
-rw-r--r--source/Host/macosx/cfcpp/CFCData.h35
-rw-r--r--source/Host/macosx/cfcpp/CFCMutableArray.cpp140
-rw-r--r--source/Host/macosx/cfcpp/CFCMutableArray.h46
-rw-r--r--source/Host/macosx/cfcpp/CFCMutableDictionary.cpp465
-rw-r--r--source/Host/macosx/cfcpp/CFCMutableDictionary.h75
-rw-r--r--source/Host/macosx/cfcpp/CFCMutableSet.cpp85
-rw-r--r--source/Host/macosx/cfcpp/CFCMutableSet.h47
-rw-r--r--source/Host/macosx/cfcpp/CFCReleaser.h128
-rw-r--r--source/Host/macosx/cfcpp/CFCString.cpp160
-rw-r--r--source/Host/macosx/cfcpp/CFCString.h41
-rw-r--r--source/Host/macosx/cfcpp/CoreFoundationCPP.h30
-rw-r--r--source/Host/macosx/objcxx/CMakeLists.txt20
-rw-r--r--source/Host/macosx/objcxx/Host.mm1522
-rw-r--r--source/Host/macosx/objcxx/HostInfoMacOSX.mm280
-rw-r--r--source/Host/macosx/objcxx/HostThreadMacOSX.mm70
-rw-r--r--source/Host/windows/ConnectionGenericFileWindows.cpp323
-rw-r--r--source/Host/windows/EditLineWin.cpp350
-rw-r--r--source/Host/windows/FileSystem.cpp107
-rw-r--r--source/Host/windows/Host.cpp275
-rw-r--r--source/Host/windows/HostInfoWindows.cpp120
-rw-r--r--source/Host/windows/HostProcessWindows.cpp120
-rw-r--r--source/Host/windows/HostThreadWindows.cpp75
-rw-r--r--source/Host/windows/LockFileWindows.cpp79
-rw-r--r--source/Host/windows/PipeWindows.cpp339
-rw-r--r--source/Host/windows/ProcessLauncherWindows.cpp159
-rw-r--r--source/Host/windows/ProcessRunLock.cpp82
-rw-r--r--source/Host/windows/Windows.cpp231
40 files changed, 0 insertions, 7175 deletions
diff --git a/source/Host/CMakeLists.txt b/source/Host/CMakeLists.txt
deleted file mode 100644
index 333f109a9a26..000000000000
--- a/source/Host/CMakeLists.txt
+++ /dev/null
@@ -1,179 +0,0 @@
-macro(add_host_subdirectory group)
- list(APPEND HOST_SOURCES ${ARGN})
- source_group(${group} FILES ${ARGN})
-endmacro()
-
-# Removes all module flags from the current CMAKE_CXX_FLAGS. Used for
-# the Objective-C++ code in lldb which we don't want to build with modules.
-# Reasons for this are that modules with Objective-C++ would require that
-# all LLVM/Clang modules are Objective-C++ compatible (which they are likely
-# not) and we would have rebuild a second set of modules just for the few
-# Objective-C++ files in lldb (which slows down the build process).
-macro(remove_module_flags)
- string(REGEX REPLACE "-fmodules-cache-path=[^ ]+" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
- string(REGEX REPLACE "-fmodules-local-submodule-visibility" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
- string(REGEX REPLACE "-fmodules" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
- string(REGEX REPLACE "-gmodules" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
- string(REGEX REPLACE "-fcxx-modules" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
-endmacro()
-
-add_host_subdirectory(common
- common/File.cpp
- common/FileCache.cpp
- common/FileSystem.cpp
- common/GetOptInc.cpp
- common/Host.cpp
- common/HostInfoBase.cpp
- common/HostNativeThreadBase.cpp
- common/HostProcess.cpp
- common/HostThread.cpp
- common/LockFileBase.cpp
- common/MainLoop.cpp
- common/MonitoringProcessLauncher.cpp
- common/NativeWatchpointList.cpp
- common/NativeProcessProtocol.cpp
- common/NativeRegisterContext.cpp
- common/NativeThreadProtocol.cpp
- common/OptionParser.cpp
- common/PipeBase.cpp
- common/ProcessRunLock.cpp
- common/PseudoTerminal.cpp
- common/Socket.cpp
- common/SocketAddress.cpp
- common/StringConvert.cpp
- common/Symbols.cpp
- common/TaskPool.cpp
- common/TCPSocket.cpp
- common/Terminal.cpp
- common/ThreadLauncher.cpp
- common/XML.cpp
- common/UDPSocket.cpp
- )
-
-if (NOT LLDB_DISABLE_LIBEDIT)
- add_host_subdirectory(common
- common/Editline.cpp
- )
-endif()
-
-add_host_subdirectory(posix
- posix/ConnectionFileDescriptorPosix.cpp
- )
-
-if (CMAKE_SYSTEM_NAME MATCHES "Windows")
- add_host_subdirectory(windows
- windows/ConnectionGenericFileWindows.cpp
- windows/EditLineWin.cpp
- windows/FileSystem.cpp
- windows/Host.cpp
- windows/HostInfoWindows.cpp
- windows/HostProcessWindows.cpp
- windows/HostThreadWindows.cpp
- windows/LockFileWindows.cpp
- windows/PipeWindows.cpp
- windows/ProcessLauncherWindows.cpp
- windows/ProcessRunLock.cpp
- windows/Windows.cpp
- )
-else()
- add_host_subdirectory(posix
- posix/DomainSocket.cpp
- posix/FileSystem.cpp
- posix/HostInfoPosix.cpp
- posix/HostProcessPosix.cpp
- posix/HostThreadPosix.cpp
- posix/LockFilePosix.cpp
- posix/PipePosix.cpp
- posix/ProcessLauncherPosixFork.cpp
- )
-
- if (CMAKE_SYSTEM_NAME MATCHES "Darwin")
- include_directories(SYSTEM ${LIBXML2_INCLUDE_DIR})
- add_subdirectory(macosx/objcxx)
- set(LLDBObjCLibs lldbHostMacOSXObjCXX)
- add_host_subdirectory(macosx
- macosx/Symbols.cpp
- macosx/cfcpp/CFCBundle.cpp
- macosx/cfcpp/CFCData.cpp
- macosx/cfcpp/CFCMutableArray.cpp
- macosx/cfcpp/CFCMutableDictionary.cpp
- macosx/cfcpp/CFCMutableSet.cpp
- macosx/cfcpp/CFCString.cpp
- )
- if(IOS)
- set_property(SOURCE macosx/Host.mm APPEND PROPERTY
- COMPILE_DEFINITIONS "NO_XPC_SERVICES=1")
- endif()
-
-
- elseif (CMAKE_SYSTEM_NAME MATCHES "Linux|Android")
- add_host_subdirectory(linux
- linux/AbstractSocket.cpp
- linux/Host.cpp
- linux/HostInfoLinux.cpp
- linux/LibcGlue.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
- )
-
- elseif (CMAKE_SYSTEM_NAME MATCHES "NetBSD")
- add_host_subdirectory(netbsd
- netbsd/Host.cpp
- netbsd/HostInfoNetBSD.cpp
- )
-
- elseif (CMAKE_SYSTEM_NAME MATCHES "OpenBSD")
- add_host_subdirectory(openbsd
- openbsd/Host.cpp
- openbsd/HostInfoOpenBSD.cpp
- )
- endif()
-endif()
-
-set(EXTRA_LIBS)
-if (CMAKE_SYSTEM_NAME MATCHES "NetBSD")
- list(APPEND EXTRA_LIBS kvm)
-endif ()
-if (APPLE)
- list(APPEND EXTRA_LIBS xml2)
-else ()
- if (LIBXML2_FOUND)
- list(APPEND EXTRA_LIBS ${LIBXML2_LIBRARIES})
- endif()
-endif ()
-if (HAVE_LIBDL)
- list(APPEND EXTRA_LIBS ${CMAKE_DL_LIBS})
-endif()
-if (NOT LLDB_DISABLE_LIBEDIT)
- list(APPEND EXTRA_LIBS ${libedit_LIBRARIES})
-endif()
-
-add_lldb_library(lldbHost
- ${HOST_SOURCES}
-
- LINK_LIBS
- lldbCore
- lldbSymbol
- lldbTarget
- lldbUtility
- ${EXTRA_LIBS}
- ${LLDBObjCLibs}
-
- LINK_COMPONENTS
- Object
- Support
- )
-
-if (NOT LLDB_DISABLE_LIBEDIT)
- target_include_directories(lldbHost PUBLIC ${libedit_INCLUDE_DIRS})
-endif()
diff --git a/source/Host/android/HostInfoAndroid.cpp b/source/Host/android/HostInfoAndroid.cpp
deleted file mode 100644
index 3dea01f8240d..000000000000
--- a/source/Host/android/HostInfoAndroid.cpp
+++ /dev/null
@@ -1,95 +0,0 @@
-//===-- HostInfoAndroid.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/android/HostInfoAndroid.h"
-#include "lldb/Host/FileSystem.h"
-#include "lldb/Host/linux/HostInfoLinux.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
-
-using namespace lldb_private;
-using namespace llvm;
-
-void HostInfoAndroid::ComputeHostArchitectureSupport(ArchSpec &arch_32,
- ArchSpec &arch_64) {
- HostInfoLinux::ComputeHostArchitectureSupport(arch_32, arch_64);
-
- if (arch_32.IsValid()) {
- arch_32.GetTriple().setEnvironment(llvm::Triple::Android);
- }
- if (arch_64.IsValid()) {
- arch_64.GetTriple().setEnvironment(llvm::Triple::Android);
- }
-}
-
-FileSpec HostInfoAndroid::GetDefaultShell() {
- return FileSpec("/system/bin/sh");
-}
-
-FileSpec HostInfoAndroid::ResolveLibraryPath(const std::string &module_path,
- const ArchSpec &arch) {
- static const char *const ld_library_path_separator = ":";
- static const char *const default_lib32_path[] = {"/vendor/lib", "/system/lib",
- nullptr};
- static const char *const default_lib64_path[] = {"/vendor/lib64",
- "/system/lib64", nullptr};
-
- if (module_path.empty() || module_path[0] == '/') {
- FileSpec file_spec(module_path.c_str());
- FileSystem::Instance().Resolve(file_spec);
- return file_spec;
- }
-
- SmallVector<StringRef, 4> ld_paths;
-
- if (const char *ld_library_path = ::getenv("LD_LIBRARY_PATH"))
- StringRef(ld_library_path)
- .split(ld_paths, StringRef(ld_library_path_separator), -1, false);
-
- const char *const *default_lib_path = nullptr;
- switch (arch.GetAddressByteSize()) {
- case 4:
- default_lib_path = default_lib32_path;
- break;
- case 8:
- default_lib_path = default_lib64_path;
- break;
- default:
- assert(false && "Unknown address byte size");
- return FileSpec();
- }
-
- for (const char *const *it = default_lib_path; *it; ++it)
- ld_paths.push_back(StringRef(*it));
-
- for (const StringRef &path : ld_paths) {
- FileSpec file_candidate(path.str().c_str());
- FileSystem::Instance().Resolve(file_candidate);
- file_candidate.AppendPathComponent(module_path.c_str());
-
- if (FileSystem::Instance().Exists(file_candidate))
- return file_candidate;
- }
-
- return FileSpec();
-}
-
-bool HostInfoAndroid::ComputeTempFileBaseDirectory(FileSpec &file_spec) {
- bool success = HostInfoLinux::ComputeTempFileBaseDirectory(file_spec);
-
- // On Android, there is no path which is guaranteed to be writable. If the
- // user has not provided a path via an environment variable, the generic
- // algorithm will deduce /tmp, which is plain wrong. In that case we have an
- // invalid directory, we substitute the path with /data/local/tmp, which is
- // correct at least in some cases (i.e., when running as shell user).
- if (!success || !FileSystem::Instance().Exists(file_spec))
- file_spec = FileSpec("/data/local/tmp");
-
- return FileSystem::Instance().Exists(file_spec);
-}
diff --git a/source/Host/android/LibcGlue.cpp b/source/Host/android/LibcGlue.cpp
deleted file mode 100644
index 13437f9704e3..000000000000
--- a/source/Host/android/LibcGlue.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-//===-- LibcGlue.cpp --------------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// This files adds functions missing from libc on earlier versions of Android
-
-#include <android/api-level.h>
-
-#include <sys/syscall.h>
-
-#if __ANDROID_API__ < 21
-
-#include <fcntl.h>
-#include <signal.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include "lldb/Host/Time.h"
-
-time_t timegm(struct tm *t) { return (time_t)timegm64(t); }
-
-int posix_openpt(int flags) { return open("/dev/ptmx", flags); }
-
-#endif
diff --git a/source/Host/linux/AbstractSocket.cpp b/source/Host/linux/AbstractSocket.cpp
deleted file mode 100644
index 2d6f6adaf1ef..000000000000
--- a/source/Host/linux/AbstractSocket.cpp
+++ /dev/null
@@ -1,22 +0,0 @@
-//===-- AbstractSocket.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/AbstractSocket.h"
-
-#include "llvm/ADT/StringRef.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-AbstractSocket::AbstractSocket(bool child_processes_inherit)
- : DomainSocket(ProtocolUnixAbstract, child_processes_inherit) {}
-
-size_t AbstractSocket::GetNameOffset() const { return 1; }
-
-void AbstractSocket::DeleteSocketFile(llvm::StringRef name) {}
diff --git a/source/Host/linux/Host.cpp b/source/Host/linux/Host.cpp
deleted file mode 100644
index bd596f8cbfe0..000000000000
--- a/source/Host/linux/Host.cpp
+++ /dev/null
@@ -1,297 +0,0 @@
-//===-- source/Host/linux/Host.cpp ------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/utsname.h>
-#include <unistd.h>
-
-#include "llvm/Object/ELF.h"
-#include "llvm/Support/ScopedPrinter.h"
-
-#include "lldb/Target/Process.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/Status.h"
-
-#include "lldb/Host/FileSystem.h"
-#include "lldb/Host/Host.h"
-#include "lldb/Host/HostInfo.h"
-#include "lldb/Host/linux/Support.h"
-#include "lldb/Utility/DataExtractor.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-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;
-}
-
-static bool IsDirNumeric(const char *dname) {
- for (; *dname; dname++) {
- if (!isdigit(*dname))
- return false;
- }
- return true;
-}
-
-static ArchSpec GetELFProcessCPUType(llvm::StringRef exe_path) {
- Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
-
- auto buffer_sp = FileSystem::Instance().CreateDataBuffer(exe_path, 0x20, 0);
- if (!buffer_sp)
- return ArchSpec();
-
- uint8_t exe_class =
- llvm::object::getElfArchType(
- {buffer_sp->GetChars(), size_t(buffer_sp->GetByteSize())})
- .first;
-
- switch (exe_class) {
- case llvm::ELF::ELFCLASS32:
- return HostInfo::GetArchitecture(HostInfo::eArchKind32);
- case llvm::ELF::ELFCLASS64:
- return HostInfo::GetArchitecture(HostInfo::eArchKind64);
- default:
- LLDB_LOG(log, "Unknown elf class ({0}) in file {1}", exe_class, exe_path);
- return ArchSpec();
- }
-}
-
-static bool GetProcessAndStatInfo(::pid_t pid,
- ProcessInstanceInfo &process_info,
- ProcessState &State, ::pid_t &tracerpid) {
- tracerpid = 0;
- process_info.Clear();
-
- 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');
-
- 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,
- Status(errno, eErrorTypePOSIX));
- return false;
- }
- ExePath.resize(len);
-
- // If the binary has been deleted, the link name has " (deleted)" appended.
- // Remove if there.
- llvm::StringRef PathRef = ExePath;
- PathRef.consume_back(" (deleted)");
-
- process_info.SetArchitecture(GetELFProcessCPUType(PathRef));
-
- // Get the process environment.
- auto BufferOrError = getProcFile(pid, "environ");
- if (!BufferOrError)
- return false;
- std::unique_ptr<llvm::MemoryBuffer> Environ = std::move(*BufferOrError);
-
- // 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, FileSpec::Style::native);
-
- llvm::StringRef Rest = Environ->getBuffer();
- while (!Rest.empty()) {
- llvm::StringRef Var;
- std::tie(Var, Rest) = Rest.split('\0');
- process_info.GetEnvironment().insert(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;
-}
-
-uint32_t Host::FindProcesses(const ProcessInstanceInfoMatch &match_info,
- ProcessInstanceInfoList &process_infos) {
- static const char procdir[] = "/proc/";
-
- DIR *dirproc = opendir(procdir);
- if (dirproc) {
- struct dirent *direntry = NULL;
- const uid_t our_uid = getuid();
- const lldb::pid_t our_pid = getpid();
- bool all_users = match_info.GetMatchAllUsers();
-
- while ((direntry = readdir(dirproc)) != NULL) {
- if (direntry->d_type != DT_DIR || !IsDirNumeric(direntry->d_name))
- continue;
-
- lldb::pid_t pid = atoi(direntry->d_name);
-
- // Skip this process.
- if (pid == our_pid)
- continue;
-
- ::pid_t tracerpid;
- ProcessState State;
- ProcessInstanceInfo process_info;
-
- if (!GetProcessAndStatInfo(pid, process_info, State, tracerpid))
- continue;
-
- // Skip if process is being debugged.
- if (tracerpid != 0)
- continue;
-
- if (State == ProcessState::Zombie)
- continue;
-
- // Check for user match if we're not matching all users and not running
- // as root.
- if (!all_users && (our_uid != 0) && (process_info.GetUserID() != our_uid))
- continue;
-
- if (match_info.Matches(process_info)) {
- process_infos.Append(process_info);
- }
- }
-
- closedir(dirproc);
- }
-
- return process_infos.GetSize();
-}
-
-bool Host::FindProcessThreads(const lldb::pid_t pid, TidMap &tids_to_attach) {
- bool tids_changed = false;
- static const char procdir[] = "/proc/";
- static const char taskdir[] = "/task/";
- std::string process_task_dir = procdir + llvm::to_string(pid) + taskdir;
- DIR *dirproc = opendir(process_task_dir.c_str());
-
- if (dirproc) {
- struct dirent *direntry = NULL;
- while ((direntry = readdir(dirproc)) != NULL) {
- if (direntry->d_type != DT_DIR || !IsDirNumeric(direntry->d_name))
- continue;
-
- lldb::tid_t tid = atoi(direntry->d_name);
- TidMap::iterator it = tids_to_attach.find(tid);
- if (it == tids_to_attach.end()) {
- tids_to_attach.insert(TidPair(tid, false));
- tids_changed = true;
- }
- }
- closedir(dirproc);
- }
-
- return tids_changed;
-}
-
-bool Host::GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &process_info) {
- ::pid_t tracerpid;
- ProcessState State;
- return GetProcessAndStatInfo(pid, process_info, State, tracerpid);
-}
-
-Environment Host::GetEnvironment() { return Environment(environ); }
-
-Status Host::ShellExpandArguments(ProcessLaunchInfo &launch_info) {
- return Status("unimplemented");
-}
diff --git a/source/Host/linux/HostInfoLinux.cpp b/source/Host/linux/HostInfoLinux.cpp
deleted file mode 100644
index f5a6b2c97a0d..000000000000
--- a/source/Host/linux/HostInfoLinux.cpp
+++ /dev/null
@@ -1,228 +0,0 @@
-//===-- HostInfoLinux.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/HostInfoLinux.h"
-#include "lldb/Host/Config.h"
-#include "lldb/Host/FileSystem.h"
-#include "lldb/Utility/Log.h"
-
-#include "llvm/Support/Threading.h"
-
-#include <limits.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/utsname.h>
-#include <unistd.h>
-
-#include <algorithm>
-#include <mutex>
-
-using namespace lldb_private;
-
-namespace {
-struct HostInfoLinuxFields {
- std::string m_distribution_id;
- llvm::VersionTuple m_os_version;
-};
-
-HostInfoLinuxFields *g_fields = nullptr;
-}
-
-void HostInfoLinux::Initialize() {
- HostInfoPosix::Initialize();
-
- g_fields = new HostInfoLinuxFields();
-}
-
-llvm::VersionTuple HostInfoLinux::GetOSVersion() {
- static llvm::once_flag g_once_flag;
- llvm::call_once(g_once_flag, []() {
- struct utsname un;
- if (uname(&un) != 0)
- return;
-
- llvm::StringRef release = un.release;
- // The kernel release string can include a lot of stuff (e.g.
- // 4.9.0-6-amd64). We're only interested in the numbered prefix.
- release = release.substr(0, release.find_first_not_of("0123456789."));
- g_fields->m_os_version.tryParse(release);
- });
-
- return g_fields->m_os_version;
-}
-
-bool HostInfoLinux::GetOSBuildString(std::string &s) {
- struct utsname un;
- ::memset(&un, 0, sizeof(utsname));
- s.clear();
-
- if (uname(&un) < 0)
- return false;
-
- s.assign(un.release);
- return true;
-}
-
-bool HostInfoLinux::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;
-}
-
-llvm::StringRef HostInfoLinux::GetDistributionId() {
- // Try to run 'lbs_release -i', and use that response for the distribution
- // id.
- static llvm::once_flag g_once_flag;
- llvm::call_once(g_once_flag, []() {
-
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST));
- if (log)
- log->Printf("attempting to determine Linux distribution...");
-
- // check if the lsb_release command exists at one of the following paths
- const char *const exe_paths[] = {"/bin/lsb_release",
- "/usr/bin/lsb_release"};
-
- for (size_t exe_index = 0;
- exe_index < sizeof(exe_paths) / sizeof(exe_paths[0]); ++exe_index) {
- const char *const get_distribution_info_exe = exe_paths[exe_index];
- if (access(get_distribution_info_exe, F_OK)) {
- // this exe doesn't exist, move on to next exe
- if (log)
- log->Printf("executable doesn't exist: %s",
- get_distribution_info_exe);
- continue;
- }
-
- // execute the distribution-retrieval command, read output
- std::string get_distribution_id_command(get_distribution_info_exe);
- get_distribution_id_command += " -i";
-
- FILE *file = popen(get_distribution_id_command.c_str(), "r");
- if (!file) {
- if (log)
- log->Printf("failed to run command: \"%s\", cannot retrieve "
- "platform information",
- get_distribution_id_command.c_str());
- break;
- }
-
- // retrieve the distribution id string.
- char distribution_id[256] = {'\0'};
- if (fgets(distribution_id, sizeof(distribution_id) - 1, file) != NULL) {
- if (log)
- log->Printf("distribution id command returned \"%s\"",
- distribution_id);
-
- const char *const distributor_id_key = "Distributor ID:\t";
- if (strstr(distribution_id, distributor_id_key)) {
- // strip newlines
- std::string id_string(distribution_id + strlen(distributor_id_key));
- id_string.erase(std::remove(id_string.begin(), id_string.end(), '\n'),
- id_string.end());
-
- // lower case it and convert whitespace to underscores
- std::transform(
- id_string.begin(), id_string.end(), id_string.begin(),
- [](char ch) { return tolower(isspace(ch) ? '_' : ch); });
-
- g_fields->m_distribution_id = id_string;
- if (log)
- log->Printf("distribution id set to \"%s\"",
- g_fields->m_distribution_id.c_str());
- } else {
- if (log)
- log->Printf("failed to find \"%s\" field in \"%s\"",
- distributor_id_key, distribution_id);
- }
- } else {
- if (log)
- log->Printf("failed to retrieve distribution id, \"%s\" returned no"
- " lines",
- get_distribution_id_command.c_str());
- }
-
- // clean up the file
- pclose(file);
- }
- });
-
- return g_fields->m_distribution_id;
-}
-
-FileSpec HostInfoLinux::GetProgramFileSpec() {
- static FileSpec g_program_filespec;
-
- if (!g_program_filespec) {
- char exe_path[PATH_MAX];
- ssize_t len = readlink("/proc/self/exe", exe_path, sizeof(exe_path) - 1);
- if (len > 0) {
- exe_path[len] = 0;
- g_program_filespec.SetFile(exe_path, FileSpec::Style::native);
- }
- }
-
- return g_program_filespec;
-}
-
-bool HostInfoLinux::ComputeSupportExeDirectory(FileSpec &file_spec) {
- if (HostInfoPosix::ComputeSupportExeDirectory(file_spec) &&
- file_spec.IsAbsolute() && FileSystem::Instance().Exists(file_spec))
- return true;
- file_spec.GetDirectory() = GetProgramFileSpec().GetDirectory();
- return !file_spec.GetDirectory().IsEmpty();
-}
-
-bool HostInfoLinux::ComputeSystemPluginsDirectory(FileSpec &file_spec) {
- FileSpec temp_file("/usr/lib" LLDB_LIBDIR_SUFFIX "/lldb/plugins");
- FileSystem::Instance().Resolve(temp_file);
- file_spec.GetDirectory().SetCString(temp_file.GetPath().c_str());
- return true;
-}
-
-bool HostInfoLinux::ComputeUserPluginsDirectory(FileSpec &file_spec) {
- // XDG Base Directory Specification
- // http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html If
- // XDG_DATA_HOME exists, use that, otherwise use ~/.local/share/lldb.
- const char *xdg_data_home = getenv("XDG_DATA_HOME");
- if (xdg_data_home && xdg_data_home[0]) {
- std::string user_plugin_dir(xdg_data_home);
- user_plugin_dir += "/lldb";
- file_spec.GetDirectory().SetCString(user_plugin_dir.c_str());
- } else
- file_spec.GetDirectory().SetCString("~/.local/share/lldb");
- return true;
-}
-
-void HostInfoLinux::ComputeHostArchitectureSupport(ArchSpec &arch_32,
- ArchSpec &arch_64) {
- HostInfoPosix::ComputeHostArchitectureSupport(arch_32, arch_64);
-
- const char *distribution_id = GetDistributionId().data();
-
- // On Linux, "unknown" in the vendor slot isn't what we want for the default
- // triple. It's probably an artifact of config.guess.
- if (arch_32.IsValid()) {
- arch_32.SetDistributionId(distribution_id);
- if (arch_32.GetTriple().getVendor() == llvm::Triple::UnknownVendor)
- arch_32.GetTriple().setVendorName(llvm::StringRef());
- }
- if (arch_64.IsValid()) {
- arch_64.SetDistributionId(distribution_id);
- if (arch_64.GetTriple().getVendor() == llvm::Triple::UnknownVendor)
- arch_64.GetTriple().setVendorName(llvm::StringRef());
- }
-}
diff --git a/source/Host/linux/LibcGlue.cpp b/source/Host/linux/LibcGlue.cpp
deleted file mode 100644
index 93d2a41d2eb1..000000000000
--- a/source/Host/linux/LibcGlue.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-//===-- LibcGlue.cpp --------------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// This file adds functions missing from libc on older versions of linux
-
-#include <cerrno>
-#include <lldb/Host/linux/Uio.h>
-#include <sys/syscall.h>
-#include <unistd.h>
-
-#if !HAVE_PROCESS_VM_READV
-// If the syscall wrapper is not available, provide one.
-ssize_t process_vm_readv(::pid_t pid, const struct iovec *local_iov,
- unsigned long liovcnt, const struct iovec *remote_iov,
- unsigned long riovcnt, unsigned long flags) {
-#if HAVE_NR_PROCESS_VM_READV
- // If we have the syscall number, we can issue the syscall ourselves.
- return syscall(__NR_process_vm_readv, pid, local_iov, liovcnt, remote_iov,
- riovcnt, flags);
-#else // If not, let's pretend the syscall is not present.
- errno = ENOSYS;
- return -1;
-#endif
-}
-#endif
diff --git a/source/Host/linux/ProcessLauncherLinux.cpp b/source/Host/linux/ProcessLauncherLinux.cpp
deleted file mode 100644
index e69de29bb2d1..000000000000
--- a/source/Host/linux/ProcessLauncherLinux.cpp
+++ /dev/null
diff --git a/source/Host/linux/Support.cpp b/source/Host/linux/Support.cpp
deleted file mode 100644
index 31808401ea61..000000000000
--- a/source/Host/linux/Support.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-//===-- 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;
-}
-
-llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
-lldb_private::getProcFile(const llvm::Twine &file) {
- Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- std::string File = ("/proc/" + 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/macosx/Symbols.cpp b/source/Host/macosx/Symbols.cpp
deleted file mode 100644
index 980bbc34449c..000000000000
--- a/source/Host/macosx/Symbols.cpp
+++ /dev/null
@@ -1,655 +0,0 @@
-//===-- Symbols.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/Symbols.h"
-
-#include <dirent.h>
-#include <pwd.h>
-
-#include <CoreFoundation/CoreFoundation.h>
-
-#include "Host/macosx/cfcpp/CFCBundle.h"
-#include "Host/macosx/cfcpp/CFCData.h"
-#include "Host/macosx/cfcpp/CFCReleaser.h"
-#include "Host/macosx/cfcpp/CFCString.h"
-#include "lldb/Core/ModuleList.h"
-#include "lldb/Core/ModuleSpec.h"
-#include "lldb/Host/Host.h"
-#include "lldb/Symbol/ObjectFile.h"
-#include "lldb/Utility/ArchSpec.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/Timer.h"
-#include "lldb/Utility/UUID.h"
-#include "mach/machine.h"
-
-#include "llvm/Support/FileSystem.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-#if !defined(__arm__) && !defined(__arm64__) && \
- !defined(__aarch64__) // No DebugSymbols on the iOS devices
-extern "C" {
-
-CFURLRef DBGCopyFullDSYMURLForUUID(CFUUIDRef uuid, CFURLRef exec_url);
-CFDictionaryRef DBGCopyDSYMPropertyLists(CFURLRef dsym_url);
-}
-#endif
-
-int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec,
- ModuleSpec &return_module_spec) {
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- if (!ModuleList::GetGlobalModuleListProperties().GetEnableExternalLookup()) {
- if (log)
- log->Printf("Spotlight lookup for .dSYM bundles is disabled.");
- return 0;
- }
-
- return_module_spec = module_spec;
- return_module_spec.GetFileSpec().Clear();
- return_module_spec.GetSymbolFileSpec().Clear();
-
- int items_found = 0;
-
-#if !defined(__arm__) && !defined(__arm64__) && \
- !defined(__aarch64__) // No DebugSymbols on the iOS devices
-
- const UUID *uuid = module_spec.GetUUIDPtr();
- const ArchSpec *arch = module_spec.GetArchitecturePtr();
-
- if (uuid && uuid->IsValid()) {
- // Try and locate the dSYM file using DebugSymbols first
- llvm::ArrayRef<uint8_t> module_uuid = uuid->GetBytes();
- if (module_uuid.size() == 16) {
- CFCReleaser<CFUUIDRef> module_uuid_ref(::CFUUIDCreateWithBytes(
- NULL, module_uuid[0], module_uuid[1], module_uuid[2], module_uuid[3],
- module_uuid[4], module_uuid[5], module_uuid[6], module_uuid[7],
- module_uuid[8], module_uuid[9], module_uuid[10], module_uuid[11],
- module_uuid[12], module_uuid[13], module_uuid[14], module_uuid[15]));
-
- if (module_uuid_ref.get()) {
- CFCReleaser<CFURLRef> exec_url;
- const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
- if (exec_fspec) {
- char exec_cf_path[PATH_MAX];
- if (exec_fspec->GetPath(exec_cf_path, sizeof(exec_cf_path)))
- exec_url.reset(::CFURLCreateFromFileSystemRepresentation(
- NULL, (const UInt8 *)exec_cf_path, strlen(exec_cf_path),
- FALSE));
- }
-
- CFCReleaser<CFURLRef> dsym_url(
- ::DBGCopyFullDSYMURLForUUID(module_uuid_ref.get(), exec_url.get()));
- char path[PATH_MAX];
-
- if (dsym_url.get()) {
- if (::CFURLGetFileSystemRepresentation(
- dsym_url.get(), true, (UInt8 *)path, sizeof(path) - 1)) {
- if (log) {
- log->Printf("DebugSymbols framework returned dSYM path of %s for "
- "UUID %s -- looking for the dSYM",
- path, uuid->GetAsString().c_str());
- }
- FileSpec dsym_filespec(path);
- if (path[0] == '~')
- FileSystem::Instance().Resolve(dsym_filespec);
-
- if (FileSystem::Instance().IsDirectory(dsym_filespec)) {
- dsym_filespec =
- Symbols::FindSymbolFileInBundle(dsym_filespec, uuid, arch);
- ++items_found;
- } else {
- ++items_found;
- }
- return_module_spec.GetSymbolFileSpec() = dsym_filespec;
- }
-
- bool success = false;
- if (log) {
- if (::CFURLGetFileSystemRepresentation(
- dsym_url.get(), true, (UInt8 *)path, sizeof(path) - 1)) {
- log->Printf("DebugSymbols framework returned dSYM path of %s for "
- "UUID %s -- looking for an exec file",
- path, uuid->GetAsString().c_str());
- }
- }
-
- CFCReleaser<CFDictionaryRef> dict(
- ::DBGCopyDSYMPropertyLists(dsym_url.get()));
- CFDictionaryRef uuid_dict = NULL;
- if (dict.get()) {
- CFCString uuid_cfstr(uuid->GetAsString().c_str());
- uuid_dict = static_cast<CFDictionaryRef>(
- ::CFDictionaryGetValue(dict.get(), uuid_cfstr.get()));
- }
- if (uuid_dict) {
- CFStringRef exec_cf_path =
- static_cast<CFStringRef>(::CFDictionaryGetValue(
- uuid_dict, CFSTR("DBGSymbolRichExecutable")));
- if (exec_cf_path && ::CFStringGetFileSystemRepresentation(
- exec_cf_path, path, sizeof(path))) {
- if (log) {
- log->Printf("plist bundle has exec path of %s for UUID %s",
- path, uuid->GetAsString().c_str());
- }
- ++items_found;
- FileSpec exec_filespec(path);
- if (path[0] == '~')
- FileSystem::Instance().Resolve(exec_filespec);
- if (FileSystem::Instance().Exists(exec_filespec)) {
- success = true;
- return_module_spec.GetFileSpec() = exec_filespec;
- }
- }
- }
-
- if (!success) {
- // No dictionary, check near the dSYM bundle for an executable that
- // matches...
- if (::CFURLGetFileSystemRepresentation(
- dsym_url.get(), true, (UInt8 *)path, sizeof(path) - 1)) {
- char *dsym_extension_pos = ::strstr(path, ".dSYM");
- if (dsym_extension_pos) {
- *dsym_extension_pos = '\0';
- if (log) {
- log->Printf("Looking for executable binary next to dSYM "
- "bundle with name with name %s",
- path);
- }
- FileSpec file_spec(path);
- FileSystem::Instance().Resolve(file_spec);
- ModuleSpecList module_specs;
- ModuleSpec matched_module_spec;
- 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(
- bundle.CopyExecutableURL());
- if (bundle_exe_url.get()) {
- if (::CFURLGetFileSystemRepresentation(bundle_exe_url.get(),
- true, (UInt8 *)path,
- sizeof(path) - 1)) {
- FileSpec bundle_exe_file_spec(path);
- FileSystem::Instance().Resolve(bundle_exe_file_spec);
- if (ObjectFile::GetModuleSpecifications(
- bundle_exe_file_spec, 0, 0, module_specs) &&
- module_specs.FindMatchingModuleSpec(
- module_spec, matched_module_spec))
-
- {
- ++items_found;
- return_module_spec.GetFileSpec() = bundle_exe_file_spec;
- if (log) {
- log->Printf("Executable binary %s next to dSYM is "
- "compatible; using",
- path);
- }
- }
- }
- }
- } break;
-
- 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 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,
- matched_module_spec))
-
- {
- ++items_found;
- return_module_spec.GetFileSpec() = file_spec;
- if (log) {
- log->Printf("Executable binary %s next to dSYM is "
- "compatible; using",
- path);
- }
- }
- break;
- }
- }
- }
- }
- }
- }
- }
- }
-#endif // #if !defined (__arm__) && !defined (__arm64__) && !defined
- // (__aarch64__)
-
- return items_found;
-}
-
-FileSpec Symbols::FindSymbolFileInBundle(const FileSpec &dsym_bundle_fspec,
- const lldb_private::UUID *uuid,
- const ArchSpec *arch) {
- char path[PATH_MAX];
- if (dsym_bundle_fspec.GetPath(path, sizeof(path)) == 0)
- return {};
-
- ::strncat(path, "/Contents/Resources/DWARF", sizeof(path) - strlen(path) - 1);
-
- DIR *dirp = opendir(path);
- if (!dirp)
- return {};
-
- // Make sure we close the directory before exiting this scope.
- CleanUp cleanup_dir(closedir, dirp);
-
- FileSpec dsym_fspec;
- dsym_fspec.GetDirectory().SetCString(path);
- struct dirent *dp;
- while ((dp = readdir(dirp)) != NULL) {
- // Only search directories
- if (dp->d_type == DT_DIR || dp->d_type == DT_UNKNOWN) {
- if (dp->d_namlen == 1 && dp->d_name[0] == '.')
- continue;
-
- if (dp->d_namlen == 2 && dp->d_name[0] == '.' && dp->d_name[1] == '.')
- continue;
- }
-
- if (dp->d_type == DT_REG || dp->d_type == DT_UNKNOWN) {
- dsym_fspec.GetFilename().SetCString(dp->d_name);
- ModuleSpecList module_specs;
- if (ObjectFile::GetModuleSpecifications(dsym_fspec, 0, 0, module_specs)) {
- ModuleSpec spec;
- for (size_t i = 0; i < module_specs.GetSize(); ++i) {
- 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)))) {
- return dsym_fspec;
- }
- }
- }
- }
- }
-
- return {};
-}
-
-static bool GetModuleSpecInfoFromUUIDDictionary(CFDictionaryRef uuid_dict,
- ModuleSpec &module_spec) {
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- bool success = false;
- if (uuid_dict != NULL && CFGetTypeID(uuid_dict) == CFDictionaryGetTypeID()) {
- std::string str;
- CFStringRef cf_str;
- CFDictionaryRef cf_dict;
-
- cf_str = (CFStringRef)CFDictionaryGetValue(
- (CFDictionaryRef)uuid_dict, CFSTR("DBGSymbolRichExecutable"));
- if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
- if (CFCString::FileSystemRepresentation(cf_str, str)) {
- module_spec.GetFileSpec().SetFile(str.c_str(), FileSpec::Style::native);
- FileSystem::Instance().Resolve(module_spec.GetFileSpec());
- if (log) {
- log->Printf(
- "From dsymForUUID plist: Symbol rich executable is at '%s'",
- str.c_str());
- }
- }
- }
-
- cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict,
- CFSTR("DBGDSYMPath"));
- if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
- if (CFCString::FileSystemRepresentation(cf_str, str)) {
- module_spec.GetSymbolFileSpec().SetFile(str.c_str(),
- FileSpec::Style::native);
- FileSystem::Instance().Resolve(module_spec.GetFileSpec());
- success = true;
- if (log) {
- log->Printf("From dsymForUUID plist: dSYM is at '%s'", str.c_str());
- }
- }
- }
-
- cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict,
- CFSTR("DBGArchitecture"));
- if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
- if (CFCString::FileSystemRepresentation(cf_str, str))
- module_spec.GetArchitecture().SetTriple(str.c_str());
- }
-
- std::string DBGBuildSourcePath;
- std::string DBGSourcePath;
-
- // If DBGVersion 1 or DBGVersion missing, ignore DBGSourcePathRemapping.
- // If DBGVersion 2, strip last two components of path remappings from
- // entries to fix an issue with a specific set of
- // DBGSourcePathRemapping entries that lldb worked
- // with.
- // If DBGVersion 3, trust & use the source path remappings as-is.
- //
- cf_dict = (CFDictionaryRef)CFDictionaryGetValue(
- (CFDictionaryRef)uuid_dict, CFSTR("DBGSourcePathRemapping"));
- if (cf_dict && CFGetTypeID(cf_dict) == CFDictionaryGetTypeID()) {
- // If we see DBGVersion with a value of 2 or higher, this is a new style
- // DBGSourcePathRemapping dictionary
- bool new_style_source_remapping_dictionary = false;
- bool do_truncate_remapping_names = false;
- std::string original_DBGSourcePath_value = DBGSourcePath;
- cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict,
- CFSTR("DBGVersion"));
- if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
- std::string version;
- CFCString::FileSystemRepresentation(cf_str, version);
- if (!version.empty() && isdigit(version[0])) {
- int version_number = atoi(version.c_str());
- if (version_number > 1) {
- new_style_source_remapping_dictionary = true;
- }
- if (version_number == 2) {
- do_truncate_remapping_names = true;
- }
- }
- }
-
- CFIndex kv_pair_count = CFDictionaryGetCount((CFDictionaryRef)uuid_dict);
- if (kv_pair_count > 0) {
- CFStringRef *keys =
- (CFStringRef *)malloc(kv_pair_count * sizeof(CFStringRef));
- CFStringRef *values =
- (CFStringRef *)malloc(kv_pair_count * sizeof(CFStringRef));
- if (keys != nullptr && values != nullptr) {
- CFDictionaryGetKeysAndValues((CFDictionaryRef)uuid_dict,
- (const void **)keys,
- (const void **)values);
- }
- for (CFIndex i = 0; i < kv_pair_count; i++) {
- DBGBuildSourcePath.clear();
- DBGSourcePath.clear();
- if (keys[i] && CFGetTypeID(keys[i]) == CFStringGetTypeID()) {
- CFCString::FileSystemRepresentation(keys[i], DBGBuildSourcePath);
- }
- if (values[i] && CFGetTypeID(values[i]) == CFStringGetTypeID()) {
- CFCString::FileSystemRepresentation(values[i], DBGSourcePath);
- }
- if (!DBGBuildSourcePath.empty() && !DBGSourcePath.empty()) {
- // In the "old style" DBGSourcePathRemapping dictionary, the
- // DBGSourcePath values (the "values" half of key-value path pairs)
- // were wrong. Ignore them and use the universal DBGSourcePath
- // string from earlier.
- if (new_style_source_remapping_dictionary &&
- !original_DBGSourcePath_value.empty()) {
- DBGSourcePath = original_DBGSourcePath_value;
- }
- if (DBGSourcePath[0] == '~') {
- FileSpec resolved_source_path(DBGSourcePath.c_str());
- FileSystem::Instance().Resolve(resolved_source_path);
- DBGSourcePath = resolved_source_path.GetPath();
- }
- // With version 2 of DBGSourcePathRemapping, we can chop off the
- // last two filename parts from the source remapping and get a more
- // general source remapping that still works. Add this as another
- // option in addition to the full source path remap.
- module_spec.GetSourceMappingList().Append(
- ConstString(DBGBuildSourcePath.c_str()),
- ConstString(DBGSourcePath.c_str()), true);
- if (do_truncate_remapping_names) {
- FileSpec build_path(DBGBuildSourcePath.c_str());
- FileSpec source_path(DBGSourcePath.c_str());
- build_path.RemoveLastPathComponent();
- build_path.RemoveLastPathComponent();
- source_path.RemoveLastPathComponent();
- source_path.RemoveLastPathComponent();
- module_spec.GetSourceMappingList().Append(
- ConstString(build_path.GetPath().c_str()),
- ConstString(source_path.GetPath().c_str()), true);
- }
- }
- }
- if (keys)
- free(keys);
- if (values)
- free(values);
- }
- }
-
-
- // If we have a DBGBuildSourcePath + DBGSourcePath pair, append them to the
- // source remappings list.
-
- cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict,
- CFSTR("DBGBuildSourcePath"));
- if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
- CFCString::FileSystemRepresentation(cf_str, DBGBuildSourcePath);
- }
-
- cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict,
- CFSTR("DBGSourcePath"));
- if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
- CFCString::FileSystemRepresentation(cf_str, DBGSourcePath);
- }
-
- if (!DBGBuildSourcePath.empty() && !DBGSourcePath.empty()) {
- if (DBGSourcePath[0] == '~') {
- FileSpec resolved_source_path(DBGSourcePath.c_str());
- FileSystem::Instance().Resolve(resolved_source_path);
- DBGSourcePath = resolved_source_path.GetPath();
- }
- module_spec.GetSourceMappingList().Append(
- ConstString(DBGBuildSourcePath.c_str()),
- ConstString(DBGSourcePath.c_str()), true);
- }
- }
- return success;
-}
-
-bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec,
- bool force_lookup) {
- bool success = false;
- const UUID *uuid_ptr = module_spec.GetUUIDPtr();
- const FileSpec *file_spec_ptr = module_spec.GetFileSpecPtr();
-
- // It's expensive to check for the DBGShellCommands defaults setting, only do
- // it once per lldb run and cache the result.
- static bool g_have_checked_for_dbgshell_command = false;
- static const char *g_dbgshell_command = NULL;
- if (!g_have_checked_for_dbgshell_command) {
- g_have_checked_for_dbgshell_command = true;
- CFTypeRef defaults_setting = CFPreferencesCopyAppValue(
- CFSTR("DBGShellCommands"), CFSTR("com.apple.DebugSymbols"));
- if (defaults_setting &&
- CFGetTypeID(defaults_setting) == CFStringGetTypeID()) {
- char cstr_buf[PATH_MAX];
- if (CFStringGetCString((CFStringRef)defaults_setting, cstr_buf,
- sizeof(cstr_buf), kCFStringEncodingUTF8)) {
- g_dbgshell_command =
- strdup(cstr_buf); // this malloc'ed memory will never be freed
- }
- }
- if (defaults_setting) {
- CFRelease(defaults_setting);
- }
- }
-
- // When g_dbgshell_command is NULL, the user has not enabled the use of an
- // external program to find the symbols, don't run it for them.
- if (!force_lookup && g_dbgshell_command == NULL) {
- return false;
- }
-
- if (uuid_ptr ||
- (file_spec_ptr && FileSystem::Instance().Exists(*file_spec_ptr))) {
- static bool g_located_dsym_for_uuid_exe = false;
- static bool g_dsym_for_uuid_exe_exists = false;
- static char g_dsym_for_uuid_exe_path[PATH_MAX];
- if (!g_located_dsym_for_uuid_exe) {
- g_located_dsym_for_uuid_exe = true;
- const char *dsym_for_uuid_exe_path_cstr =
- getenv("LLDB_APPLE_DSYMFORUUID_EXECUTABLE");
- FileSpec dsym_for_uuid_exe_spec;
- if (dsym_for_uuid_exe_path_cstr) {
- dsym_for_uuid_exe_spec.SetFile(dsym_for_uuid_exe_path_cstr,
- FileSpec::Style::native);
- FileSystem::Instance().Resolve(dsym_for_uuid_exe_spec);
- g_dsym_for_uuid_exe_exists =
- FileSystem::Instance().Exists(dsym_for_uuid_exe_spec);
- }
-
- if (!g_dsym_for_uuid_exe_exists) {
- dsym_for_uuid_exe_spec.SetFile("/usr/local/bin/dsymForUUID",
- FileSpec::Style::native);
- g_dsym_for_uuid_exe_exists =
- FileSystem::Instance().Exists(dsym_for_uuid_exe_spec);
- if (!g_dsym_for_uuid_exe_exists) {
- long bufsize;
- if ((bufsize = sysconf(_SC_GETPW_R_SIZE_MAX)) != -1) {
- char buffer[bufsize];
- struct passwd pwd;
- struct passwd *tilde_rc = NULL;
- // we are a library so we need to use the reentrant version of
- // getpwnam()
- if (getpwnam_r("rc", &pwd, buffer, bufsize, &tilde_rc) == 0 &&
- tilde_rc && tilde_rc->pw_dir) {
- std::string dsymforuuid_path(tilde_rc->pw_dir);
- dsymforuuid_path += "/bin/dsymForUUID";
- dsym_for_uuid_exe_spec.SetFile(dsymforuuid_path.c_str(),
- FileSpec::Style::native);
- g_dsym_for_uuid_exe_exists =
- FileSystem::Instance().Exists(dsym_for_uuid_exe_spec);
- }
- }
- }
- }
- if (!g_dsym_for_uuid_exe_exists && g_dbgshell_command != NULL) {
- dsym_for_uuid_exe_spec.SetFile(g_dbgshell_command,
- FileSpec::Style::native);
- FileSystem::Instance().Resolve(dsym_for_uuid_exe_spec);
- g_dsym_for_uuid_exe_exists =
- FileSystem::Instance().Exists(dsym_for_uuid_exe_spec);
- }
-
- if (g_dsym_for_uuid_exe_exists)
- dsym_for_uuid_exe_spec.GetPath(g_dsym_for_uuid_exe_path,
- sizeof(g_dsym_for_uuid_exe_path));
- }
- if (g_dsym_for_uuid_exe_exists) {
- std::string uuid_str;
- char file_path[PATH_MAX];
- file_path[0] = '\0';
-
- if (uuid_ptr)
- uuid_str = uuid_ptr->GetAsString();
-
- if (file_spec_ptr)
- file_spec_ptr->GetPath(file_path, sizeof(file_path));
-
- StreamString command;
- if (!uuid_str.empty())
- command.Printf("%s --ignoreNegativeCache --copyExecutable %s",
- g_dsym_for_uuid_exe_path, uuid_str.c_str());
- else if (file_path[0] != '\0')
- command.Printf("%s --ignoreNegativeCache --copyExecutable %s",
- g_dsym_for_uuid_exe_path, file_path);
-
- if (!command.GetString().empty()) {
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- int exit_status = -1;
- int signo = -1;
- std::string command_output;
- if (log) {
- if (!uuid_str.empty())
- log->Printf("Calling %s with UUID %s to find dSYM",
- g_dsym_for_uuid_exe_path, uuid_str.c_str());
- else if (file_path[0] != '\0')
- log->Printf("Calling %s with file %s to find dSYM",
- g_dsym_for_uuid_exe_path, file_path);
- }
- Status error = Host::RunShellCommand(
- command.GetData(),
- NULL, // current working directory
- &exit_status, // Exit status
- &signo, // Signal int *
- &command_output, // Command output
- std::chrono::seconds(
- 30), // Large timeout to allow for long dsym download times
- false); // Don't run in a shell (we don't need shell expansion)
- if (error.Success() && exit_status == 0 && !command_output.empty()) {
- CFCData data(CFDataCreateWithBytesNoCopy(
- NULL, (const UInt8 *)command_output.data(), command_output.size(),
- kCFAllocatorNull));
-
- CFCReleaser<CFDictionaryRef> plist(
- (CFDictionaryRef)::CFPropertyListCreateFromXMLData(
- NULL, data.get(), kCFPropertyListImmutable, NULL));
-
- if (plist.get() &&
- CFGetTypeID(plist.get()) == CFDictionaryGetTypeID()) {
- if (!uuid_str.empty()) {
- CFCString uuid_cfstr(uuid_str.c_str());
- CFDictionaryRef uuid_dict = (CFDictionaryRef)CFDictionaryGetValue(
- plist.get(), uuid_cfstr.get());
- success =
- GetModuleSpecInfoFromUUIDDictionary(uuid_dict, module_spec);
- } else {
- const CFIndex num_values = ::CFDictionaryGetCount(plist.get());
- if (num_values > 0) {
- std::vector<CFStringRef> keys(num_values, NULL);
- std::vector<CFDictionaryRef> values(num_values, NULL);
- ::CFDictionaryGetKeysAndValues(plist.get(), NULL,
- (const void **)&values[0]);
- if (num_values == 1) {
- return GetModuleSpecInfoFromUUIDDictionary(values[0],
- module_spec);
- } else {
- for (CFIndex i = 0; i < num_values; ++i) {
- ModuleSpec curr_module_spec;
- if (GetModuleSpecInfoFromUUIDDictionary(values[i],
- curr_module_spec)) {
- if (module_spec.GetArchitecture().IsCompatibleMatch(
- curr_module_spec.GetArchitecture())) {
- module_spec = curr_module_spec;
- return true;
- }
- }
- }
- }
- }
- }
- }
- } else {
- if (log) {
- if (!uuid_str.empty())
- log->Printf("Called %s on %s, no matches",
- g_dsym_for_uuid_exe_path, uuid_str.c_str());
- else if (file_path[0] != '\0')
- log->Printf("Called %s on %s, no matches",
- g_dsym_for_uuid_exe_path, file_path);
- }
- }
- }
- }
- }
- return success;
-}
diff --git a/source/Host/macosx/cfcpp/CFCBundle.cpp b/source/Host/macosx/cfcpp/CFCBundle.cpp
deleted file mode 100644
index 08f16701c36f..000000000000
--- a/source/Host/macosx/cfcpp/CFCBundle.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-//===-- CFCBundle.cpp -------------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CFCBundle.h"
-#include "CFCString.h"
-
-//----------------------------------------------------------------------
-// CFCBundle constructor
-//----------------------------------------------------------------------
-CFCBundle::CFCBundle(const char *path) : CFCReleaser<CFBundleRef>() {
- if (path && path[0])
- SetPath(path);
-}
-
-CFCBundle::CFCBundle(CFURLRef url)
- : CFCReleaser<CFBundleRef>(url ? CFBundleCreate(NULL, url) : NULL) {}
-
-//----------------------------------------------------------------------
-// Destructor
-//----------------------------------------------------------------------
-CFCBundle::~CFCBundle() {}
-
-//----------------------------------------------------------------------
-// Set the path for a bundle by supplying a
-//----------------------------------------------------------------------
-bool CFCBundle::SetPath(const char *path) {
- CFAllocatorRef alloc = kCFAllocatorDefault;
- // Release our old bundle and URL
- reset();
-
- // Make a CFStringRef from the supplied path
- CFCString cf_path;
- cf_path.SetFileSystemRepresentation(path);
- if (cf_path.get()) {
- // Make our Bundle URL
- CFCReleaser<CFURLRef> bundle_url(::CFURLCreateWithFileSystemPath(
- alloc, cf_path.get(), kCFURLPOSIXPathStyle, true));
- if (bundle_url.get())
- reset(::CFBundleCreate(alloc, bundle_url.get()));
- }
- return get() != NULL;
-}
-
-bool CFCBundle::GetPath(char *dst, size_t dst_len) {
- CFBundleRef bundle = get();
- if (bundle) {
- CFCReleaser<CFURLRef> bundle_url(CFBundleCopyBundleURL(bundle));
- if (bundle_url.get()) {
- Boolean resolveAgainstBase = 0;
- return ::CFURLGetFileSystemRepresentation(bundle_url.get(),
- resolveAgainstBase,
- (UInt8 *)dst, dst_len) != 0;
- }
- }
- return false;
-}
-
-CFStringRef CFCBundle::GetIdentifier() const {
- CFBundleRef bundle = get();
- if (bundle != NULL)
- return ::CFBundleGetIdentifier(bundle);
- return NULL;
-}
-
-CFTypeRef CFCBundle::GetValueForInfoDictionaryKey(CFStringRef key) const {
- CFBundleRef bundle = get();
- if (bundle != NULL)
- return ::CFBundleGetValueForInfoDictionaryKey(bundle, key);
- return NULL;
-}
-
-CFURLRef CFCBundle::CopyExecutableURL() const {
- CFBundleRef bundle = get();
- if (bundle != NULL)
- return CFBundleCopyExecutableURL(bundle);
- return NULL;
-}
diff --git a/source/Host/macosx/cfcpp/CFCBundle.h b/source/Host/macosx/cfcpp/CFCBundle.h
deleted file mode 100644
index 9506b93f6536..000000000000
--- a/source/Host/macosx/cfcpp/CFCBundle.h
+++ /dev/null
@@ -1,42 +0,0 @@
-//===-- CFCBundle.h ---------------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef CoreFoundationCPP_CFBundle_h_
-#define CoreFoundationCPP_CFBundle_h_
-
-#include "CFCReleaser.h"
-
-class CFCBundle : public CFCReleaser<CFBundleRef> {
-public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- CFCBundle(const char *path = NULL);
- CFCBundle(CFURLRef url);
-
- virtual ~CFCBundle();
-
- CFURLRef CopyExecutableURL() const;
-
- CFStringRef GetIdentifier() const;
-
- CFTypeRef GetValueForInfoDictionaryKey(CFStringRef key) const;
-
- bool GetPath(char *dst, size_t dst_len);
-
- bool SetPath(const char *path);
-
-private:
- // Disallow copy and assignment constructors
- CFCBundle(const CFCBundle &);
-
- const CFCBundle &operator=(const CFCBundle &);
-};
-
-#endif // #ifndef CoreFoundationCPP_CFBundle_h_
diff --git a/source/Host/macosx/cfcpp/CFCData.cpp b/source/Host/macosx/cfcpp/CFCData.cpp
deleted file mode 100644
index 95cadede8ff6..000000000000
--- a/source/Host/macosx/cfcpp/CFCData.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-//===-- CFCData.cpp ---------------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CFCData.h"
-
-//----------------------------------------------------------------------
-// CFCData constructor
-//----------------------------------------------------------------------
-CFCData::CFCData(CFDataRef data) : CFCReleaser<CFDataRef>(data) {}
-
-//----------------------------------------------------------------------
-// CFCData copy constructor
-//----------------------------------------------------------------------
-CFCData::CFCData(const CFCData &rhs) : CFCReleaser<CFDataRef>(rhs) {}
-
-//----------------------------------------------------------------------
-// CFCData copy constructor
-//----------------------------------------------------------------------
-CFCData &CFCData::operator=(const CFCData &rhs)
-
-{
- if (this != &rhs)
- *this = rhs;
- return *this;
-}
-
-//----------------------------------------------------------------------
-// Destructor
-//----------------------------------------------------------------------
-CFCData::~CFCData() {}
-
-CFIndex CFCData::GetLength() const {
- CFDataRef data = get();
- if (data)
- return CFDataGetLength(data);
- return 0;
-}
-
-const uint8_t *CFCData::GetBytePtr() const {
- CFDataRef data = get();
- if (data)
- return CFDataGetBytePtr(data);
- return NULL;
-}
-
-CFDataRef CFCData::Serialize(CFPropertyListRef plist,
- CFPropertyListFormat format) {
- CFAllocatorRef alloc = kCFAllocatorDefault;
- reset();
- CFCReleaser<CFWriteStreamRef> stream(
- ::CFWriteStreamCreateWithAllocatedBuffers(alloc, alloc));
- ::CFWriteStreamOpen(stream.get());
- CFIndex len =
- ::CFPropertyListWriteToStream(plist, stream.get(), format, NULL);
- if (len > 0)
- reset((CFDataRef)::CFWriteStreamCopyProperty(stream.get(),
- kCFStreamPropertyDataWritten));
- ::CFWriteStreamClose(stream.get());
- return get();
-}
diff --git a/source/Host/macosx/cfcpp/CFCData.h b/source/Host/macosx/cfcpp/CFCData.h
deleted file mode 100644
index e89d7bec7832..000000000000
--- a/source/Host/macosx/cfcpp/CFCData.h
+++ /dev/null
@@ -1,35 +0,0 @@
-//===-- CFCData.h -----------------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef CoreFoundationCPP_CFData_h_
-#define CoreFoundationCPP_CFData_h_
-
-#include "CFCReleaser.h"
-
-class CFCData : public CFCReleaser<CFDataRef> {
-public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- CFCData(CFDataRef data = NULL);
- CFCData(const CFCData &rhs);
- CFCData &operator=(const CFCData &rhs);
- virtual ~CFCData();
-
- CFDataRef Serialize(CFPropertyListRef plist, CFPropertyListFormat format);
- const uint8_t *GetBytePtr() const;
- CFIndex GetLength() const;
-
-protected:
- //------------------------------------------------------------------
- // Classes that inherit from CFCData can see and modify these
- //------------------------------------------------------------------
-};
-
-#endif // #ifndef CoreFoundationCPP_CFData_h_
diff --git a/source/Host/macosx/cfcpp/CFCMutableArray.cpp b/source/Host/macosx/cfcpp/CFCMutableArray.cpp
deleted file mode 100644
index f426e9c13a59..000000000000
--- a/source/Host/macosx/cfcpp/CFCMutableArray.cpp
+++ /dev/null
@@ -1,140 +0,0 @@
-//===-- CFCMutableArray.cpp -------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CFCMutableArray.h"
-#include "CFCString.h"
-
-//----------------------------------------------------------------------
-// CFCString constructor
-//----------------------------------------------------------------------
-CFCMutableArray::CFCMutableArray(CFMutableArrayRef s)
- : CFCReleaser<CFMutableArrayRef>(s) {}
-
-//----------------------------------------------------------------------
-// CFCMutableArray copy constructor
-//----------------------------------------------------------------------
-CFCMutableArray::CFCMutableArray(const CFCMutableArray &rhs)
- : CFCReleaser<CFMutableArrayRef>(rhs) // NOTE: this won't make a copy of the
- // array, just add a new reference to
- // it
-{}
-
-//----------------------------------------------------------------------
-// CFCMutableArray copy constructor
-//----------------------------------------------------------------------
-CFCMutableArray &CFCMutableArray::operator=(const CFCMutableArray &rhs) {
- if (this != &rhs)
- *this = rhs; // NOTE: this operator won't make a copy of the array, just add
- // a new reference to it
- return *this;
-}
-
-//----------------------------------------------------------------------
-// Destructor
-//----------------------------------------------------------------------
-CFCMutableArray::~CFCMutableArray() {}
-
-CFIndex CFCMutableArray::GetCount() const {
- CFMutableArrayRef array = get();
- if (array)
- return ::CFArrayGetCount(array);
- return 0;
-}
-
-CFIndex CFCMutableArray::GetCountOfValue(CFRange range,
- const void *value) const {
- CFMutableArrayRef array = get();
- if (array)
- return ::CFArrayGetCountOfValue(array, range, value);
- return 0;
-}
-
-CFIndex CFCMutableArray::GetCountOfValue(const void *value) const {
- CFMutableArrayRef array = get();
- if (array)
- return ::CFArrayGetCountOfValue(array, CFRangeMake(0, GetCount()), value);
- return 0;
-}
-
-const void *CFCMutableArray::GetValueAtIndex(CFIndex idx) const {
- CFMutableArrayRef array = get();
- if (array) {
- const CFIndex num_array_items = ::CFArrayGetCount(array);
- if (0 <= idx && idx < num_array_items) {
- return ::CFArrayGetValueAtIndex(array, idx);
- }
- }
- return NULL;
-}
-
-bool CFCMutableArray::SetValueAtIndex(CFIndex idx, const void *value) {
- CFMutableArrayRef array = get();
- if (array != NULL) {
- const CFIndex num_array_items = ::CFArrayGetCount(array);
- if (0 <= idx && idx < num_array_items) {
- ::CFArraySetValueAtIndex(array, idx, value);
- return true;
- }
- }
- return false;
-}
-
-bool CFCMutableArray::AppendValue(const void *value, bool can_create) {
- CFMutableArrayRef array = get();
- if (array == NULL) {
- if (!can_create)
- return false;
- array =
- ::CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
- reset(array);
- }
- if (array != NULL) {
- ::CFArrayAppendValue(array, value);
- return true;
- }
- return false;
-}
-
-bool CFCMutableArray::AppendCStringAsCFString(const char *s,
- CFStringEncoding encoding,
- bool can_create) {
- CFMutableArrayRef array = get();
- if (array == NULL) {
- if (!can_create)
- return false;
- array =
- ::CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
- reset(array);
- }
- if (array != NULL) {
- CFCString cf_str(s, encoding);
- ::CFArrayAppendValue(array, cf_str.get());
- return true;
- }
- return false;
-}
-
-bool CFCMutableArray::AppendFileSystemRepresentationAsCFString(
- const char *s, bool can_create) {
- CFMutableArrayRef array = get();
- if (array == NULL) {
- if (!can_create)
- return false;
- array =
- ::CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
- reset(array);
- }
- if (array != NULL) {
- CFCString cf_path;
- cf_path.SetFileSystemRepresentation(s);
- ::CFArrayAppendValue(array, cf_path.get());
- return true;
- }
- return false;
-}
diff --git a/source/Host/macosx/cfcpp/CFCMutableArray.h b/source/Host/macosx/cfcpp/CFCMutableArray.h
deleted file mode 100644
index 23d1f932bfc7..000000000000
--- a/source/Host/macosx/cfcpp/CFCMutableArray.h
+++ /dev/null
@@ -1,46 +0,0 @@
-//===-- CFCMutableArray.h ---------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef CoreFoundationCPP_CFMutableArray_h_
-#define CoreFoundationCPP_CFMutableArray_h_
-
-#include "CFCReleaser.h"
-
-class CFCMutableArray : public CFCReleaser<CFMutableArrayRef> {
-public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- CFCMutableArray(CFMutableArrayRef array = NULL);
- CFCMutableArray(const CFCMutableArray &rhs); // This will copy the array
- // contents into a new array
- CFCMutableArray &operator=(const CFCMutableArray &rhs); // This will re-use
- // the same array and
- // just bump the ref
- // count
- virtual ~CFCMutableArray();
-
- CFIndex GetCount() const;
- CFIndex GetCountOfValue(const void *value) const;
- CFIndex GetCountOfValue(CFRange range, const void *value) const;
- const void *GetValueAtIndex(CFIndex idx) const;
- bool SetValueAtIndex(CFIndex idx, const void *value);
- bool AppendValue(const void *value,
- bool can_create = true); // Appends value and optionally
- // creates a CFCMutableArray if this
- // class doesn't contain one
- bool
- AppendCStringAsCFString(const char *cstr,
- CFStringEncoding encoding = kCFStringEncodingUTF8,
- bool can_create = true);
- bool AppendFileSystemRepresentationAsCFString(const char *s,
- bool can_create = true);
-};
-
-#endif // #ifndef CoreFoundationCPP_CFMutableArray_h_
diff --git a/source/Host/macosx/cfcpp/CFCMutableDictionary.cpp b/source/Host/macosx/cfcpp/CFCMutableDictionary.cpp
deleted file mode 100644
index 0c52aa3ed051..000000000000
--- a/source/Host/macosx/cfcpp/CFCMutableDictionary.cpp
+++ /dev/null
@@ -1,465 +0,0 @@
-//===-- CFCMutableDictionary.cpp --------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CFCMutableDictionary.h"
-#include "CFCString.h"
-//----------------------------------------------------------------------
-// CFCString constructor
-//----------------------------------------------------------------------
-CFCMutableDictionary::CFCMutableDictionary(CFMutableDictionaryRef s)
- : CFCReleaser<CFMutableDictionaryRef>(s) {}
-
-//----------------------------------------------------------------------
-// CFCMutableDictionary copy constructor
-//----------------------------------------------------------------------
-CFCMutableDictionary::CFCMutableDictionary(const CFCMutableDictionary &rhs)
- : CFCReleaser<CFMutableDictionaryRef>(rhs) {}
-
-//----------------------------------------------------------------------
-// CFCMutableDictionary copy constructor
-//----------------------------------------------------------------------
-const CFCMutableDictionary &CFCMutableDictionary::
-operator=(const CFCMutableDictionary &rhs) {
- if (this != &rhs)
- *this = rhs;
- return *this;
-}
-
-//----------------------------------------------------------------------
-// Destructor
-//----------------------------------------------------------------------
-CFCMutableDictionary::~CFCMutableDictionary() {}
-
-CFIndex CFCMutableDictionary::GetCount() const {
- CFMutableDictionaryRef dict = get();
- if (dict)
- return ::CFDictionaryGetCount(dict);
- return 0;
-}
-
-CFIndex CFCMutableDictionary::GetCountOfKey(const void *key) const
-
-{
- CFMutableDictionaryRef dict = get();
- if (dict)
- return ::CFDictionaryGetCountOfKey(dict, key);
- return 0;
-}
-
-CFIndex CFCMutableDictionary::GetCountOfValue(const void *value) const
-
-{
- CFMutableDictionaryRef dict = get();
- if (dict)
- return ::CFDictionaryGetCountOfValue(dict, value);
- return 0;
-}
-
-void CFCMutableDictionary::GetKeysAndValues(const void **keys,
- const void **values) const {
- CFMutableDictionaryRef dict = get();
- if (dict)
- ::CFDictionaryGetKeysAndValues(dict, keys, values);
-}
-
-const void *CFCMutableDictionary::GetValue(const void *key) const
-
-{
- CFMutableDictionaryRef dict = get();
- if (dict)
- return ::CFDictionaryGetValue(dict, key);
- return NULL;
-}
-
-Boolean
-CFCMutableDictionary::GetValueIfPresent(const void *key,
- const void **value_handle) const {
- CFMutableDictionaryRef dict = get();
- if (dict)
- return ::CFDictionaryGetValueIfPresent(dict, key, value_handle);
- return false;
-}
-
-CFMutableDictionaryRef CFCMutableDictionary::Dictionary(bool can_create) {
- CFMutableDictionaryRef dict = get();
- if (can_create && dict == NULL) {
- dict = ::CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks);
- reset(dict);
- }
- return dict;
-}
-
-bool CFCMutableDictionary::AddValue(CFStringRef key, const void *value,
- bool can_create) {
- CFMutableDictionaryRef dict = Dictionary(can_create);
- if (dict != NULL) {
- // Let the dictionary own the CFNumber
- ::CFDictionaryAddValue(dict, key, value);
- return true;
- }
- return false;
-}
-
-bool CFCMutableDictionary::SetValue(CFStringRef key, const void *value,
- bool can_create) {
- CFMutableDictionaryRef dict = Dictionary(can_create);
- if (dict != NULL) {
- // Let the dictionary own the CFNumber
- ::CFDictionarySetValue(dict, key, value);
- return true;
- }
- return false;
-}
-
-bool CFCMutableDictionary::AddValueSInt8(CFStringRef key, int8_t value,
- bool can_create) {
- CFMutableDictionaryRef dict = Dictionary(can_create);
- if (dict != NULL) {
- CFCReleaser<CFNumberRef> cf_number(
- ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt8Type, &value));
- if (cf_number.get()) {
- // Let the dictionary own the CFNumber
- ::CFDictionaryAddValue(dict, key, cf_number.get());
- return true;
- }
- }
- return false;
-}
-
-bool CFCMutableDictionary::SetValueSInt8(CFStringRef key, int8_t value,
- bool can_create) {
- CFMutableDictionaryRef dict = Dictionary(can_create);
- if (dict != NULL) {
- CFCReleaser<CFNumberRef> cf_number(
- ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt8Type, &value));
- if (cf_number.get()) {
- // Let the dictionary own the CFNumber
- ::CFDictionarySetValue(dict, key, cf_number.get());
- return true;
- }
- }
- return false;
-}
-
-bool CFCMutableDictionary::AddValueSInt16(CFStringRef key, int16_t value,
- bool can_create) {
- CFMutableDictionaryRef dict = Dictionary(can_create);
- if (dict != NULL) {
- CFCReleaser<CFNumberRef> cf_number(
- ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt16Type, &value));
- if (cf_number.get()) {
- // Let the dictionary own the CFNumber
- ::CFDictionaryAddValue(dict, key, cf_number.get());
- return true;
- }
- }
- return false;
-}
-
-bool CFCMutableDictionary::SetValueSInt16(CFStringRef key, int16_t value,
- bool can_create) {
- CFMutableDictionaryRef dict = Dictionary(can_create);
- if (dict != NULL) {
- CFCReleaser<CFNumberRef> cf_number(
- ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt16Type, &value));
- if (cf_number.get()) {
- // Let the dictionary own the CFNumber
- ::CFDictionarySetValue(dict, key, cf_number.get());
- return true;
- }
- }
- return false;
-}
-
-bool CFCMutableDictionary::AddValueSInt32(CFStringRef key, int32_t value,
- bool can_create) {
- CFMutableDictionaryRef dict = Dictionary(can_create);
- if (dict != NULL) {
- CFCReleaser<CFNumberRef> cf_number(
- ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value));
- if (cf_number.get()) {
- // Let the dictionary own the CFNumber
- ::CFDictionaryAddValue(dict, key, cf_number.get());
- return true;
- }
- }
- return false;
-}
-
-bool CFCMutableDictionary::SetValueSInt32(CFStringRef key, int32_t value,
- bool can_create) {
- CFMutableDictionaryRef dict = Dictionary(can_create);
- if (dict != NULL) {
- CFCReleaser<CFNumberRef> cf_number(
- ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value));
- if (cf_number.get()) {
- // Let the dictionary own the CFNumber
- ::CFDictionarySetValue(dict, key, cf_number.get());
- return true;
- }
- }
- return false;
-}
-
-bool CFCMutableDictionary::AddValueSInt64(CFStringRef key, int64_t value,
- bool can_create) {
- CFMutableDictionaryRef dict = Dictionary(can_create);
- if (dict != NULL) {
- CFCReleaser<CFNumberRef> cf_number(
- ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &value));
- if (cf_number.get()) {
- // Let the dictionary own the CFNumber
- ::CFDictionaryAddValue(dict, key, cf_number.get());
- return true;
- }
- }
- return false;
-}
-
-bool CFCMutableDictionary::SetValueSInt64(CFStringRef key, int64_t value,
- bool can_create) {
- CFMutableDictionaryRef dict = Dictionary(can_create);
- if (dict != NULL) {
- CFCReleaser<CFNumberRef> cf_number(
- ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &value));
- if (cf_number.get()) {
- // Let the dictionary own the CFNumber
- ::CFDictionarySetValue(dict, key, cf_number.get());
- return true;
- }
- }
- return false;
-}
-
-bool CFCMutableDictionary::AddValueUInt8(CFStringRef key, uint8_t value,
- bool can_create) {
- CFMutableDictionaryRef dict = Dictionary(can_create);
- if (dict != NULL) {
- // Have to promote to the next size type so things don't appear negative of
- // the MSBit is set...
- int16_t sval = value;
- CFCReleaser<CFNumberRef> cf_number(
- ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt16Type, &sval));
- if (cf_number.get()) {
- // Let the dictionary own the CFNumber
- ::CFDictionaryAddValue(dict, key, cf_number.get());
- return true;
- }
- }
- return false;
-}
-
-bool CFCMutableDictionary::SetValueUInt8(CFStringRef key, uint8_t value,
- bool can_create) {
- CFMutableDictionaryRef dict = Dictionary(can_create);
- if (dict != NULL) {
- // Have to promote to the next size type so things don't appear negative of
- // the MSBit is set...
- int16_t sval = value;
- CFCReleaser<CFNumberRef> cf_number(
- ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt16Type, &sval));
- if (cf_number.get()) {
- // Let the dictionary own the CFNumber
- ::CFDictionarySetValue(dict, key, cf_number.get());
- return true;
- }
- }
- return false;
-}
-
-bool CFCMutableDictionary::AddValueUInt16(CFStringRef key, uint16_t value,
- bool can_create) {
- CFMutableDictionaryRef dict = Dictionary(can_create);
- if (dict != NULL) {
- // Have to promote to the next size type so things don't appear negative of
- // the MSBit is set...
- int32_t sval = value;
- CFCReleaser<CFNumberRef> cf_number(
- ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &sval));
- if (cf_number.get()) {
- // Let the dictionary own the CFNumber
- ::CFDictionaryAddValue(dict, key, cf_number.get());
- return true;
- }
- }
- return false;
-}
-
-bool CFCMutableDictionary::SetValueUInt16(CFStringRef key, uint16_t value,
- bool can_create) {
- CFMutableDictionaryRef dict = Dictionary(can_create);
- if (dict != NULL) {
- // Have to promote to the next size type so things don't appear negative of
- // the MSBit is set...
- int32_t sval = value;
- CFCReleaser<CFNumberRef> cf_number(
- ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &sval));
- if (cf_number.get()) {
- // Let the dictionary own the CFNumber
- ::CFDictionarySetValue(dict, key, cf_number.get());
- return true;
- }
- }
- return false;
-}
-
-bool CFCMutableDictionary::AddValueUInt32(CFStringRef key, uint32_t value,
- bool can_create) {
- CFMutableDictionaryRef dict = Dictionary(can_create);
- if (dict != NULL) {
- // Have to promote to the next size type so things don't appear negative of
- // the MSBit is set...
- int64_t sval = value;
- CFCReleaser<CFNumberRef> cf_number(
- ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &sval));
- if (cf_number.get()) {
- // Let the dictionary own the CFNumber
- ::CFDictionaryAddValue(dict, key, cf_number.get());
- return true;
- }
- }
- return false;
-}
-
-bool CFCMutableDictionary::SetValueUInt32(CFStringRef key, uint32_t value,
- bool can_create) {
- CFMutableDictionaryRef dict = Dictionary(can_create);
- if (dict != NULL) {
- // Have to promote to the next size type so things don't appear negative of
- // the MSBit is set...
- int64_t sval = value;
- CFCReleaser<CFNumberRef> cf_number(
- ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &sval));
- if (cf_number.get()) {
- // Let the dictionary own the CFNumber
- ::CFDictionarySetValue(dict, key, cf_number.get());
- return true;
- }
- }
- return false;
-}
-
-bool CFCMutableDictionary::AddValueUInt64(CFStringRef key, uint64_t value,
- bool can_create) {
- CFMutableDictionaryRef dict = Dictionary(can_create);
- if (dict != NULL) {
- // The number may appear negative if the MSBit is set in "value". Due to a
- // limitation of CFNumber, there isn't a way to have it show up otherwise
- // as of this writing.
- CFCReleaser<CFNumberRef> cf_number(
- ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &value));
- if (cf_number.get()) {
- // Let the dictionary own the CFNumber
- ::CFDictionaryAddValue(dict, key, cf_number.get());
- return true;
- }
- }
- return false;
-}
-
-bool CFCMutableDictionary::SetValueUInt64(CFStringRef key, uint64_t value,
- bool can_create) {
- CFMutableDictionaryRef dict = Dictionary(can_create);
- if (dict != NULL) {
- // The number may appear negative if the MSBit is set in "value". Due to a
- // limitation of CFNumber, there isn't a way to have it show up otherwise
- // as of this writing.
- CFCReleaser<CFNumberRef> cf_number(
- ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &value));
- if (cf_number.get()) {
- // Let the dictionary own the CFNumber
- ::CFDictionarySetValue(dict, key, cf_number.get());
- return true;
- }
- }
- return false;
-}
-
-bool CFCMutableDictionary::AddValueDouble(CFStringRef key, double value,
- bool can_create) {
- CFMutableDictionaryRef dict = Dictionary(can_create);
- if (dict != NULL) {
- // The number may appear negative if the MSBit is set in "value". Due to a
- // limitation of CFNumber, there isn't a way to have it show up otherwise
- // as of this writing.
- CFCReleaser<CFNumberRef> cf_number(
- ::CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &value));
- if (cf_number.get()) {
- // Let the dictionary own the CFNumber
- ::CFDictionaryAddValue(dict, key, cf_number.get());
- return true;
- }
- }
- return false;
-}
-
-bool CFCMutableDictionary::SetValueDouble(CFStringRef key, double value,
- bool can_create) {
- CFMutableDictionaryRef dict = Dictionary(can_create);
- if (dict != NULL) {
- // The number may appear negative if the MSBit is set in "value". Due to a
- // limitation of CFNumber, there isn't a way to have it show up otherwise
- // as of this writing.
- CFCReleaser<CFNumberRef> cf_number(
- ::CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &value));
- if (cf_number.get()) {
- // Let the dictionary own the CFNumber
- ::CFDictionarySetValue(dict, key, cf_number.get());
- return true;
- }
- }
- return false;
-}
-
-bool CFCMutableDictionary::AddValueCString(CFStringRef key, const char *cstr,
- bool can_create) {
- CFMutableDictionaryRef dict = Dictionary(can_create);
- if (dict != NULL) {
- CFCString cf_str(cstr, kCFStringEncodingUTF8);
- if (cf_str.get()) {
- // Let the dictionary own the CFNumber
- ::CFDictionaryAddValue(dict, key, cf_str.get());
- return true;
- }
- }
- return false;
-}
-
-bool CFCMutableDictionary::SetValueCString(CFStringRef key, const char *cstr,
- bool can_create) {
- CFMutableDictionaryRef dict = Dictionary(can_create);
- if (dict != NULL) {
- CFCString cf_str(cstr, kCFStringEncodingUTF8);
- if (cf_str.get()) {
- // Let the dictionary own the CFNumber
- ::CFDictionarySetValue(dict, key, cf_str.get());
- return true;
- }
- }
- return false;
-}
-
-void CFCMutableDictionary::RemoveAllValues() {
- CFMutableDictionaryRef dict = get();
- if (dict)
- ::CFDictionaryRemoveAllValues(dict);
-}
-
-void CFCMutableDictionary::RemoveValue(const void *value) {
- CFMutableDictionaryRef dict = get();
- if (dict)
- ::CFDictionaryRemoveValue(dict, value);
-}
-void CFCMutableDictionary::ReplaceValue(const void *key, const void *value) {
- CFMutableDictionaryRef dict = get();
- if (dict)
- ::CFDictionaryReplaceValue(dict, key, value);
-}
diff --git a/source/Host/macosx/cfcpp/CFCMutableDictionary.h b/source/Host/macosx/cfcpp/CFCMutableDictionary.h
deleted file mode 100644
index b30a2e616cd5..000000000000
--- a/source/Host/macosx/cfcpp/CFCMutableDictionary.h
+++ /dev/null
@@ -1,75 +0,0 @@
-//===-- CFCMutableDictionary.h ----------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef CoreFoundationCPP_CFMutableDictionary_h_
-#define CoreFoundationCPP_CFMutableDictionary_h_
-
-#include "CFCReleaser.h"
-
-class CFCMutableDictionary : public CFCReleaser<CFMutableDictionaryRef> {
-public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- CFCMutableDictionary(CFMutableDictionaryRef s = NULL);
- CFCMutableDictionary(const CFCMutableDictionary &rhs);
- virtual ~CFCMutableDictionary();
-
- //------------------------------------------------------------------
- // Operators
- //------------------------------------------------------------------
- const CFCMutableDictionary &operator=(const CFCMutableDictionary &rhs);
-
- CFIndex GetCount() const;
- CFIndex GetCountOfKey(const void *value) const;
- CFIndex GetCountOfValue(const void *value) const;
- void GetKeysAndValues(const void **keys, const void **values) const;
- const void *GetValue(const void *key) const;
- Boolean GetValueIfPresent(const void *key, const void **value_handle) const;
- bool AddValue(CFStringRef key, const void *value, bool can_create = false);
- bool SetValue(CFStringRef key, const void *value, bool can_create = false);
- bool AddValueSInt8(CFStringRef key, int8_t value, bool can_create = false);
- bool SetValueSInt8(CFStringRef key, int8_t value, bool can_create = false);
- bool AddValueSInt16(CFStringRef key, int16_t value, bool can_create = false);
- bool SetValueSInt16(CFStringRef key, int16_t value, bool can_create = false);
- bool AddValueSInt32(CFStringRef key, int32_t value, bool can_create = false);
- bool SetValueSInt32(CFStringRef key, int32_t value, bool can_create = false);
- bool AddValueSInt64(CFStringRef key, int64_t value, bool can_create = false);
- bool SetValueSInt64(CFStringRef key, int64_t value, bool can_create = false);
- bool AddValueUInt8(CFStringRef key, uint8_t value, bool can_create = false);
- bool SetValueUInt8(CFStringRef key, uint8_t value, bool can_create = false);
- bool AddValueUInt16(CFStringRef key, uint16_t value, bool can_create = false);
- bool SetValueUInt16(CFStringRef key, uint16_t value, bool can_create = false);
- bool AddValueUInt32(CFStringRef key, uint32_t value, bool can_create = false);
- bool SetValueUInt32(CFStringRef key, uint32_t value, bool can_create = false);
- bool AddValueUInt64(CFStringRef key, uint64_t value, bool can_create = false);
- bool SetValueUInt64(CFStringRef key, uint64_t value, bool can_create = false);
- bool AddValueDouble(CFStringRef key, double value, bool can_create = false);
- bool SetValueDouble(CFStringRef key, double value, bool can_create = false);
- bool AddValueCString(CFStringRef key, const char *cstr,
- bool can_create = false);
- bool SetValueCString(CFStringRef key, const char *cstr,
- bool can_create = false);
- void RemoveValue(const void *value);
- void ReplaceValue(const void *key, const void *value);
- void RemoveAllValues();
- CFMutableDictionaryRef Dictionary(bool can_create);
-
-protected:
- //------------------------------------------------------------------
- // Classes that inherit from CFCMutableDictionary can see and modify these
- //------------------------------------------------------------------
-
-private:
- //------------------------------------------------------------------
- // For CFCMutableDictionary only
- //------------------------------------------------------------------
-};
-
-#endif // CoreFoundationCPP_CFMutableDictionary_h_
diff --git a/source/Host/macosx/cfcpp/CFCMutableSet.cpp b/source/Host/macosx/cfcpp/CFCMutableSet.cpp
deleted file mode 100644
index b8bf81e1b52e..000000000000
--- a/source/Host/macosx/cfcpp/CFCMutableSet.cpp
+++ /dev/null
@@ -1,85 +0,0 @@
-//===-- CFCMutableSet.cpp ---------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CFCMutableSet.h"
-
-
-//----------------------------------------------------------------------
-// CFCString constructor
-//----------------------------------------------------------------------
-CFCMutableSet::CFCMutableSet(CFMutableSetRef s)
- : CFCReleaser<CFMutableSetRef>(s) {}
-
-//----------------------------------------------------------------------
-// CFCMutableSet copy constructor
-//----------------------------------------------------------------------
-CFCMutableSet::CFCMutableSet(const CFCMutableSet &rhs)
- : CFCReleaser<CFMutableSetRef>(rhs) {}
-
-//----------------------------------------------------------------------
-// CFCMutableSet copy constructor
-//----------------------------------------------------------------------
-const CFCMutableSet &CFCMutableSet::operator=(const CFCMutableSet &rhs) {
- if (this != &rhs)
- *this = rhs;
- return *this;
-}
-
-//----------------------------------------------------------------------
-// Destructor
-//----------------------------------------------------------------------
-CFCMutableSet::~CFCMutableSet() {}
-
-CFIndex CFCMutableSet::GetCount() const {
- CFMutableSetRef set = get();
- if (set)
- return ::CFSetGetCount(set);
- return 0;
-}
-
-CFIndex CFCMutableSet::GetCountOfValue(const void *value) const {
- CFMutableSetRef set = get();
- if (set)
- return ::CFSetGetCountOfValue(set, value);
- return 0;
-}
-
-const void *CFCMutableSet::GetValue(const void *value) const {
- CFMutableSetRef set = get();
- if (set)
- return ::CFSetGetValue(set, value);
- return NULL;
-}
-
-const void *CFCMutableSet::AddValue(const void *value, bool can_create) {
- CFMutableSetRef set = get();
- if (set == NULL) {
- if (!can_create)
- return NULL;
- set = ::CFSetCreateMutable(kCFAllocatorDefault, 0, &kCFTypeSetCallBacks);
- reset(set);
- }
- if (set != NULL) {
- ::CFSetAddValue(set, value);
- return value;
- }
- return NULL;
-}
-
-void CFCMutableSet::RemoveValue(const void *value) {
- CFMutableSetRef set = get();
- if (set)
- ::CFSetRemoveValue(set, value);
-}
-
-void CFCMutableSet::RemoveAllValues() {
- CFMutableSetRef set = get();
- if (set)
- ::CFSetRemoveAllValues(set);
-}
diff --git a/source/Host/macosx/cfcpp/CFCMutableSet.h b/source/Host/macosx/cfcpp/CFCMutableSet.h
deleted file mode 100644
index 1459b7e46328..000000000000
--- a/source/Host/macosx/cfcpp/CFCMutableSet.h
+++ /dev/null
@@ -1,47 +0,0 @@
-//===-- CFCMutableSet.h -----------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef CoreFoundationCPP_CFMutableSet_h_
-#define CoreFoundationCPP_CFMutableSet_h_
-
-#include "CFCReleaser.h"
-
-class CFCMutableSet : public CFCReleaser<CFMutableSetRef> {
-public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- CFCMutableSet(CFMutableSetRef s = NULL);
- CFCMutableSet(const CFCMutableSet &rhs);
- virtual ~CFCMutableSet();
-
- //------------------------------------------------------------------
- // Operators
- //------------------------------------------------------------------
- const CFCMutableSet &operator=(const CFCMutableSet &rhs);
-
- CFIndex GetCount() const;
- CFIndex GetCountOfValue(const void *value) const;
- const void *GetValue(const void *value) const;
- const void *AddValue(const void *value, bool can_create);
- void RemoveValue(const void *value);
- void RemoveAllValues();
-
-protected:
- //------------------------------------------------------------------
- // Classes that inherit from CFCMutableSet can see and modify these
- //------------------------------------------------------------------
-
-private:
- //------------------------------------------------------------------
- // For CFCMutableSet only
- //------------------------------------------------------------------
-};
-
-#endif // CoreFoundationCPP_CFMutableSet_h_
diff --git a/source/Host/macosx/cfcpp/CFCReleaser.h b/source/Host/macosx/cfcpp/CFCReleaser.h
deleted file mode 100644
index c596d1e1e7ed..000000000000
--- a/source/Host/macosx/cfcpp/CFCReleaser.h
+++ /dev/null
@@ -1,128 +0,0 @@
-//===-- CFCReleaser.h -------------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef CoreFoundationCPP_CFReleaser_h_
-#define CoreFoundationCPP_CFReleaser_h_
-
-#include <CoreFoundation/CoreFoundation.h>
-
-#ifdef __cplusplus
-
-#include <assert.h>
-
-//----------------------------------------------------------------------
-// Templatized CF helper class that can own any CF pointer and will
-// call CFRelease() on any valid pointer it owns unless that pointer is
-// explicitly released using the release() member function. This class
-// is designed to mimic the std::auto_ptr<T> class and has all of the
-// same functions. The one thing to watch out for is the
-// CFCReleaser<T>::release() function won't actually CFRelease any owned
-// pointer, it is designed to relinquish ownership of the pointer just
-// like std:auto_ptr<T>::release() does.
-//----------------------------------------------------------------------
-template <class T> class CFCReleaser {
-public:
- //----------------------------------------------------------
- // Constructor that takes a pointer to a CF object that is
- // to be released when this object goes out of scope
- //----------------------------------------------------------
- CFCReleaser(T ptr = NULL) : _ptr(ptr) {}
-
- //----------------------------------------------------------
- // Copy constructor
- //
- // Note that copying a CFCReleaser will not transfer
- // ownership of the contained pointer, but it will bump its
- // reference count. This is where this class differs from
- // std::auto_ptr.
- //----------------------------------------------------------
- CFCReleaser(const CFCReleaser &rhs) : _ptr(rhs.get()) {
- if (get())
- ::CFRetain(get());
- }
-
- //----------------------------------------------------------
- // The destructor will release the pointer that it contains
- // if it has a valid pointer.
- //----------------------------------------------------------
- virtual ~CFCReleaser() { reset(); }
-
- //----------------------------------------------------------
- // Assignment operator.
- //
- // Note that assigning one CFCReleaser to another will
- // not transfer ownership of the contained pointer, but it
- // will bump its reference count. This is where this class
- // differs from std::auto_ptr.
- //----------------------------------------------------------
- CFCReleaser &operator=(const CFCReleaser<T> &rhs) {
- if (this != &rhs) {
- // Replace our owned pointer with the new one
- reset(rhs.get());
- // Retain the current pointer that we own
- if (get())
- ::CFRetain(get());
- }
- return *this;
- }
-
- //----------------------------------------------------------
- // Get the address of the contained type in case it needs
- // to be passed to a function that will fill in a pointer
- // value. The function currently will assert if _ptr is not
- // NULL because the only time this method should be used is
- // if another function will modify the contents, and we
- // could leak a pointer if this is not NULL. If the
- // assertion fires, check the offending code, or call
- // reset() prior to using the "ptr_address()" member to make
- // sure any owned objects has CFRelease called on it.
- // I had to add the "enforce_null" bool here because some
- // API's require the pointer address even though they don't change it.
- //----------------------------------------------------------
- T *ptr_address(bool enforce_null = true) {
- if (enforce_null)
- assert(_ptr == NULL);
- return &_ptr;
- }
-
- //----------------------------------------------------------
- // Access the pointer itself
- //----------------------------------------------------------
- T get() { return _ptr; }
-
- const T get() const { return _ptr; }
-
- //----------------------------------------------------------
- // Set a new value for the pointer and CFRelease our old
- // value if we had a valid one.
- //----------------------------------------------------------
- void reset(T ptr = NULL) {
- if ((_ptr != NULL) && (ptr != _ptr))
- ::CFRelease(_ptr);
- _ptr = ptr;
- }
-
- //----------------------------------------------------------
- // Release ownership without calling CFRelease. This class
- // is designed to mimic std::auto_ptr<T>, so the release
- // method releases ownership of the contained pointer
- // and does NOT call CFRelease.
- //----------------------------------------------------------
- T release() {
- T tmp = _ptr;
- _ptr = NULL;
- return tmp;
- }
-
-private:
- T _ptr;
-};
-
-#endif // #ifdef __cplusplus
-#endif // #ifndef CoreFoundationCPP_CFReleaser_h_
diff --git a/source/Host/macosx/cfcpp/CFCString.cpp b/source/Host/macosx/cfcpp/CFCString.cpp
deleted file mode 100644
index 6191f873c98a..000000000000
--- a/source/Host/macosx/cfcpp/CFCString.cpp
+++ /dev/null
@@ -1,160 +0,0 @@
-//===-- CFCString.cpp -------------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CFCString.h"
-#include <glob.h>
-#include <string>
-
-//----------------------------------------------------------------------
-// CFCString constructor
-//----------------------------------------------------------------------
-CFCString::CFCString(CFStringRef s) : CFCReleaser<CFStringRef>(s) {}
-
-//----------------------------------------------------------------------
-// CFCString copy constructor
-//----------------------------------------------------------------------
-CFCString::CFCString(const CFCString &rhs) : CFCReleaser<CFStringRef>(rhs) {}
-
-//----------------------------------------------------------------------
-// CFCString copy constructor
-//----------------------------------------------------------------------
-CFCString &CFCString::operator=(const CFCString &rhs) {
- if (this != &rhs)
- *this = rhs;
- return *this;
-}
-
-CFCString::CFCString(const char *cstr, CFStringEncoding cstr_encoding)
- : CFCReleaser<CFStringRef>() {
- if (cstr && cstr[0]) {
- reset(
- ::CFStringCreateWithCString(kCFAllocatorDefault, cstr, cstr_encoding));
- }
-}
-
-//----------------------------------------------------------------------
-// Destructor
-//----------------------------------------------------------------------
-CFCString::~CFCString() {}
-
-const char *CFCString::GetFileSystemRepresentation(std::string &s) {
- return CFCString::FileSystemRepresentation(get(), s);
-}
-
-CFStringRef CFCString::SetFileSystemRepresentation(const char *path) {
- CFStringRef new_value = NULL;
- if (path && path[0])
- new_value =
- ::CFStringCreateWithFileSystemRepresentation(kCFAllocatorDefault, path);
- reset(new_value);
- return get();
-}
-
-CFStringRef
-CFCString::SetFileSystemRepresentationFromCFType(CFTypeRef cf_type) {
- CFStringRef new_value = NULL;
- if (cf_type != NULL) {
- CFTypeID cf_type_id = ::CFGetTypeID(cf_type);
-
- if (cf_type_id == ::CFStringGetTypeID()) {
- // Retain since we are using the existing object
- new_value = (CFStringRef)::CFRetain(cf_type);
- } else if (cf_type_id == ::CFURLGetTypeID()) {
- new_value =
- ::CFURLCopyFileSystemPath((CFURLRef)cf_type, kCFURLPOSIXPathStyle);
- }
- }
- reset(new_value);
- return get();
-}
-
-CFStringRef
-CFCString::SetFileSystemRepresentationAndExpandTilde(const char *path) {
- std::string expanded_path;
- if (CFCString::ExpandTildeInPath(path, expanded_path))
- SetFileSystemRepresentation(expanded_path.c_str());
- else
- reset();
- return get();
-}
-
-const char *CFCString::UTF8(std::string &str) {
- return CFCString::UTF8(get(), str);
-}
-
-// Static function that puts a copy of the UTF8 contents of CF_STR into STR and
-// returns the C string pointer that is contained in STR when successful, else
-// NULL is returned. This allows the std::string parameter to own the extracted
-// string,
-// and also allows that string to be returned as a C string pointer that can be
-// used.
-
-const char *CFCString::UTF8(CFStringRef cf_str, std::string &str) {
- if (cf_str) {
- const CFStringEncoding encoding = kCFStringEncodingUTF8;
- CFIndex max_utf8_str_len = CFStringGetLength(cf_str);
- max_utf8_str_len =
- CFStringGetMaximumSizeForEncoding(max_utf8_str_len, encoding);
- if (max_utf8_str_len > 0) {
- str.resize(max_utf8_str_len);
- if (!str.empty()) {
- if (CFStringGetCString(cf_str, &str[0], str.size(), encoding)) {
- str.resize(strlen(str.c_str()));
- return str.c_str();
- }
- }
- }
- }
- return NULL;
-}
-
-const char *CFCString::ExpandTildeInPath(const char *path,
- std::string &expanded_path) {
- glob_t globbuf;
- if (::glob(path, GLOB_TILDE, NULL, &globbuf) == 0) {
- expanded_path = globbuf.gl_pathv[0];
- ::globfree(&globbuf);
- } else
- expanded_path.clear();
-
- return expanded_path.c_str();
-}
-
-// Static function that puts a copy of the file system representation of CF_STR
-// into STR and returns the C string pointer that is contained in STR when
-// successful, else NULL is returned. This allows the std::string parameter to
-// own the extracted string, and also allows that string to be returned as a C
-// string pointer that can be used.
-
-const char *CFCString::FileSystemRepresentation(CFStringRef cf_str,
- std::string &str) {
- if (cf_str) {
- CFIndex max_length =
- ::CFStringGetMaximumSizeOfFileSystemRepresentation(cf_str);
- if (max_length > 0) {
- str.resize(max_length);
- if (!str.empty()) {
- if (::CFStringGetFileSystemRepresentation(cf_str, &str[0],
- str.size())) {
- str.erase(::strlen(str.c_str()));
- return str.c_str();
- }
- }
- }
- }
- str.erase();
- return NULL;
-}
-
-CFIndex CFCString::GetLength() const {
- CFStringRef str = get();
- if (str)
- return CFStringGetLength(str);
- return 0;
-}
diff --git a/source/Host/macosx/cfcpp/CFCString.h b/source/Host/macosx/cfcpp/CFCString.h
deleted file mode 100644
index a7bb029408fb..000000000000
--- a/source/Host/macosx/cfcpp/CFCString.h
+++ /dev/null
@@ -1,41 +0,0 @@
-//===-- CFCString.h ---------------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef CoreFoundationCPP_CFString_h_
-#define CoreFoundationCPP_CFString_h_
-
-#include <iosfwd>
-
-#include "CFCReleaser.h"
-
-class CFCString : public CFCReleaser<CFStringRef> {
-public:
- //------------------------------------------------------------------
- // Constructors and Destructors
- //------------------------------------------------------------------
- CFCString(CFStringRef cf_str = NULL);
- CFCString(const char *s, CFStringEncoding encoding = kCFStringEncodingUTF8);
- CFCString(const CFCString &rhs);
- CFCString &operator=(const CFCString &rhs);
- virtual ~CFCString();
-
- const char *GetFileSystemRepresentation(std::string &str);
- CFStringRef SetFileSystemRepresentation(const char *path);
- CFStringRef SetFileSystemRepresentationFromCFType(CFTypeRef cf_type);
- CFStringRef SetFileSystemRepresentationAndExpandTilde(const char *path);
- const char *UTF8(std::string &str);
- CFIndex GetLength() const;
- static const char *UTF8(CFStringRef cf_str, std::string &str);
- static const char *FileSystemRepresentation(CFStringRef cf_str,
- std::string &str);
- static const char *ExpandTildeInPath(const char *path,
- std::string &expanded_path);
-};
-
-#endif // #ifndef CoreFoundationCPP_CFString_h_
diff --git a/source/Host/macosx/cfcpp/CoreFoundationCPP.h b/source/Host/macosx/cfcpp/CoreFoundationCPP.h
deleted file mode 100644
index 88d0f5a23f80..000000000000
--- a/source/Host/macosx/cfcpp/CoreFoundationCPP.h
+++ /dev/null
@@ -1,30 +0,0 @@
-//===-- CoreFoundationCPP.h -------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//----------------------------------------------------------------------
-//
-// CoreFoundationCPP.h
-// CoreFoundationCPP
-//
-// Created by Greg Clayton on 4/23/09.
-//
-//
-//----------------------------------------------------------------------
-
-#ifndef CoreFoundationCPP_CoreFoundationCPP_H_
-#define CoreFoundationCPP_CoreFoundationCPP_H_
-
-#include <CoreFoundationCPP/CFCBundle.h>
-#include <CoreFoundationCPP/CFCData.h>
-#include <CoreFoundationCPP/CFCMutableArray.h>
-#include <CoreFoundationCPP/CFCMutableDictionary.h>
-#include <CoreFoundationCPP/CFCMutableSet.h>
-#include <CoreFoundationCPP/CFCReleaser.h>
-#include <CoreFoundationCPP/CFCString.h>
-
-#endif // CoreFoundationCPP_CoreFoundationCPP_H_
diff --git a/source/Host/macosx/objcxx/CMakeLists.txt b/source/Host/macosx/objcxx/CMakeLists.txt
deleted file mode 100644
index 77e3091dc4fe..000000000000
--- a/source/Host/macosx/objcxx/CMakeLists.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-
-remove_module_flags()
-include_directories(..)
-
-add_lldb_library(lldbHostMacOSXObjCXX
- Host.mm
- HostInfoMacOSX.mm
- HostThreadMacOSX.mm
-
- LINK_LIBS
- lldbCore
- lldbSymbol
- lldbTarget
- lldbUtility
- ${EXTRA_LIBS}
-
- LINK_COMPONENTS
- Object
- Support
- )
diff --git a/source/Host/macosx/objcxx/Host.mm b/source/Host/macosx/objcxx/Host.mm
deleted file mode 100644
index 3cf44c4cb65f..000000000000
--- a/source/Host/macosx/objcxx/Host.mm
+++ /dev/null
@@ -1,1522 +0,0 @@
-//===-- Host.mm -------------------------------------------------*- 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/Host.h"
-
-#include <AvailabilityMacros.h>
-
-#if !defined(MAC_OS_X_VERSION_10_7) || \
- MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7
-#define NO_XPC_SERVICES 1
-#endif
-
-#if !defined(NO_XPC_SERVICES)
-#define __XPC_PRIVATE_H__
-#include <xpc/xpc.h>
-
-#define LaunchUsingXPCRightName "com.apple.lldb.RootDebuggingXPCService"
-
-// These XPC messaging keys are used for communication between Host.mm and the
-// XPC service.
-#define LauncherXPCServiceAuthKey "auth-key"
-#define LauncherXPCServiceArgPrefxKey "arg"
-#define LauncherXPCServiceEnvPrefxKey "env"
-#define LauncherXPCServiceCPUTypeKey "cpuType"
-#define LauncherXPCServicePosixspawnFlagsKey "posixspawnFlags"
-#define LauncherXPCServiceStdInPathKeyKey "stdInPath"
-#define LauncherXPCServiceStdOutPathKeyKey "stdOutPath"
-#define LauncherXPCServiceStdErrPathKeyKey "stdErrPath"
-#define LauncherXPCServiceChildPIDKey "childPID"
-#define LauncherXPCServiceErrorTypeKey "errorType"
-#define LauncherXPCServiceCodeTypeKey "errorCode"
-
-#endif
-
-#include "llvm/Support/Host.h"
-
-#include <asl.h>
-#include <crt_externs.h>
-#include <grp.h>
-#include <libproc.h>
-#include <pwd.h>
-#include <spawn.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/proc.h>
-#include <sys/stat.h>
-#include <sys/sysctl.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include "lldb/Host/ConnectionFileDescriptor.h"
-#include "lldb/Host/FileSystem.h"
-#include "lldb/Host/HostInfo.h"
-#include "lldb/Host/ThreadLauncher.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/ProcessLaunchInfo.h"
-#include "lldb/Utility/ArchSpec.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 "lldb/Utility/StructuredData.h"
-#include "lldb/lldb-defines.h"
-
-#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/Errno.h"
-
-#include "../cfcpp/CFCBundle.h"
-#include "../cfcpp/CFCMutableArray.h"
-#include "../cfcpp/CFCMutableDictionary.h"
-#include "../cfcpp/CFCReleaser.h"
-#include "../cfcpp/CFCString.h"
-
-#include <objc/objc-auto.h>
-
-#include <CoreFoundation/CoreFoundation.h>
-#include <Foundation/Foundation.h>
-
-#ifndef _POSIX_SPAWN_DISABLE_ASLR
-#define _POSIX_SPAWN_DISABLE_ASLR 0x0100
-#endif
-
-extern "C" {
-int __pthread_chdir(const char *path);
-int __pthread_fchdir(int fildes);
-}
-
-using namespace lldb;
-using namespace lldb_private;
-
-bool Host::GetBundleDirectory(const FileSpec &file,
- FileSpec &bundle_directory) {
-#if defined(__APPLE__)
- if (FileSystem::Instance().IsDirectory(file)) {
- char path[PATH_MAX];
- if (file.GetPath(path, sizeof(path))) {
- CFCBundle bundle(path);
- if (bundle.GetPath(path, sizeof(path))) {
- bundle_directory.SetFile(path, FileSpec::Style::native);
- return true;
- }
- }
- }
-#endif
- bundle_directory.Clear();
- return false;
-}
-
-bool Host::ResolveExecutableInBundle(FileSpec &file) {
-#if defined(__APPLE__)
- if (FileSystem::Instance().IsDirectory(file)) {
- char path[PATH_MAX];
- if (file.GetPath(path, sizeof(path))) {
- CFCBundle bundle(path);
- CFCReleaser<CFURLRef> url(bundle.CopyExecutableURL());
- if (url.get()) {
- if (::CFURLGetFileSystemRepresentation(url.get(), YES, (UInt8 *)path,
- sizeof(path))) {
- file.SetFile(path, FileSpec::Style::native);
- return true;
- }
- }
- }
- }
-#endif
- return false;
-}
-
-static void *AcceptPIDFromInferior(void *arg) {
- const char *connect_url = (const char *)arg;
- ConnectionFileDescriptor file_conn;
- Status error;
- if (file_conn.Connect(connect_url, &error) == eConnectionStatusSuccess) {
- char pid_str[256];
- ::memset(pid_str, 0, sizeof(pid_str));
- ConnectionStatus status;
- const size_t pid_str_len = file_conn.Read(
- pid_str, sizeof(pid_str), std::chrono::seconds(0), status, NULL);
- if (pid_str_len > 0) {
- int pid = atoi(pid_str);
- return (void *)(intptr_t)pid;
- }
- }
- return NULL;
-}
-
-static bool WaitForProcessToSIGSTOP(const lldb::pid_t pid,
- const int timeout_in_seconds) {
- const int time_delta_usecs = 100000;
- const int num_retries = timeout_in_seconds / time_delta_usecs;
- for (int i = 0; i < num_retries; i++) {
- struct proc_bsdinfo bsd_info;
- int error = ::proc_pidinfo(pid, PROC_PIDTBSDINFO, (uint64_t)0, &bsd_info,
- PROC_PIDTBSDINFO_SIZE);
-
- switch (error) {
- case EINVAL:
- case ENOTSUP:
- case ESRCH:
- case EPERM:
- return false;
-
- default:
- break;
-
- case 0:
- if (bsd_info.pbi_status == SSTOP)
- return true;
- }
- ::usleep(time_delta_usecs);
- }
- return false;
-}
-#if !defined(__arm__) && !defined(__arm64__) && !defined(__aarch64__)
-
-const char *applscript_in_new_tty = "tell application \"Terminal\"\n"
- " activate\n"
- " do script \"/bin/bash -c '%s';exit\"\n"
- "end tell\n";
-
-const char *applscript_in_existing_tty = "\
-set the_shell_script to \"/bin/bash -c '%s';exit\"\n\
-tell application \"Terminal\"\n\
- repeat with the_window in (get windows)\n\
- repeat with the_tab in tabs of the_window\n\
- set the_tty to tty in the_tab\n\
- if the_tty contains \"%s\" then\n\
- if the_tab is not busy then\n\
- set selected of the_tab to true\n\
- set frontmost of the_window to true\n\
- do script the_shell_script in the_tab\n\
- return\n\
- end if\n\
- end if\n\
- end repeat\n\
- end repeat\n\
- do script the_shell_script\n\
-end tell\n";
-
-static Status
-LaunchInNewTerminalWithAppleScript(const char *exe_path,
- ProcessLaunchInfo &launch_info) {
- Status error;
- char unix_socket_name[PATH_MAX] = "/tmp/XXXXXX";
- if (::mktemp(unix_socket_name) == NULL) {
- error.SetErrorString("failed to make temporary path for a unix socket");
- return error;
- }
-
- StreamString command;
- FileSpec darwin_debug_file_spec = HostInfo::GetSupportExeDir();
- if (!darwin_debug_file_spec) {
- error.SetErrorString("can't locate the 'darwin-debug' executable");
- return error;
- }
-
- darwin_debug_file_spec.GetFilename().SetCString("darwin-debug");
-
- if (!FileSystem::Instance().Exists(darwin_debug_file_spec)) {
- error.SetErrorStringWithFormat(
- "the 'darwin-debug' executable doesn't exists at '%s'",
- darwin_debug_file_spec.GetPath().c_str());
- return error;
- }
-
- char launcher_path[PATH_MAX];
- darwin_debug_file_spec.GetPath(launcher_path, sizeof(launcher_path));
-
- const ArchSpec &arch_spec = launch_info.GetArchitecture();
- // Only set the architecture if it is valid and if it isn't Haswell (x86_64h).
- if (arch_spec.IsValid() &&
- arch_spec.GetCore() != ArchSpec::eCore_x86_64_x86_64h)
- command.Printf("arch -arch %s ", arch_spec.GetArchitectureName());
-
- command.Printf("'%s' --unix-socket=%s", launcher_path, unix_socket_name);
-
- if (arch_spec.IsValid())
- command.Printf(" --arch=%s", arch_spec.GetArchitectureName());
-
- FileSpec working_dir{launch_info.GetWorkingDirectory()};
- if (working_dir)
- command.Printf(" --working-dir '%s'", working_dir.GetCString());
- else {
- char cwd[PATH_MAX];
- if (getcwd(cwd, PATH_MAX))
- command.Printf(" --working-dir '%s'", cwd);
- }
-
- if (launch_info.GetFlags().Test(eLaunchFlagDisableASLR))
- command.PutCString(" --disable-aslr");
-
- // We are launching on this host in a terminal. So compare the environment on
- // the host to what is supplied in the launch_info. Any items that aren't in
- // the host environment need to be sent to darwin-debug. If we send all
- // environment entries, we might blow the max command line length, so we only
- // send user modified entries.
- Environment host_env = Host::GetEnvironment();
-
- for (const auto &KV : launch_info.GetEnvironment()) {
- auto host_entry = host_env.find(KV.first());
- if (host_entry == host_env.end() || host_entry->second != KV.second)
- command.Format(" --env='{0}'", Environment::compose(KV));
- }
-
- command.PutCString(" -- ");
-
- const char **argv = launch_info.GetArguments().GetConstArgumentVector();
- if (argv) {
- for (size_t i = 0; argv[i] != NULL; ++i) {
- if (i == 0)
- command.Printf(" '%s'", exe_path);
- else
- command.Printf(" '%s'", argv[i]);
- }
- } else {
- command.Printf(" '%s'", exe_path);
- }
- command.PutCString(" ; echo Process exited with status $?");
- if (launch_info.GetFlags().Test(lldb::eLaunchFlagCloseTTYOnExit))
- command.PutCString(" ; exit");
-
- StreamString applescript_source;
-
- applescript_source.Printf(applscript_in_new_tty,
- command.GetString().str().c_str());
- NSAppleScript *applescript = [[NSAppleScript alloc]
- initWithSource:[NSString stringWithCString:applescript_source.GetString()
- .str()
- .c_str()
- encoding:NSUTF8StringEncoding]];
-
- lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
-
- Status lldb_error;
- // Sleep and wait a bit for debugserver to start to listen...
- ConnectionFileDescriptor file_conn;
- char connect_url[128];
- ::snprintf(connect_url, sizeof(connect_url), "unix-accept://%s",
- unix_socket_name);
-
- // Spawn a new thread to accept incoming connection on the connect_url
- // so we can grab the pid from the inferior. We have to do this because we
- // are sending an AppleScript that will launch a process in Terminal.app,
- // in a shell and the shell will fork/exec a couple of times before we get
- // to the process that we wanted to launch. So when our process actually
- // gets launched, we will handshake with it and get the process ID for it.
- HostThread accept_thread = ThreadLauncher::LaunchThread(
- unix_socket_name, AcceptPIDFromInferior, connect_url, &lldb_error);
-
- [applescript executeAndReturnError:nil];
-
- thread_result_t accept_thread_result = NULL;
- lldb_error = accept_thread.Join(&accept_thread_result);
- if (lldb_error.Success() && accept_thread_result) {
- pid = (intptr_t)accept_thread_result;
-
- // Wait for process to be stopped at the entry point by watching
- // for the process status to be set to SSTOP which indicates it it
- // SIGSTOP'ed at the entry point
- WaitForProcessToSIGSTOP(pid, 5);
- }
-
- llvm::sys::fs::remove(unix_socket_name);
- [applescript release];
- if (pid != LLDB_INVALID_PROCESS_ID)
- launch_info.SetProcessID(pid);
- return error;
-}
-
-#endif // #if !defined(__arm__) && !defined(__arm64__) && !defined(__aarch64__)
-
-bool Host::OpenFileInExternalEditor(const FileSpec &file_spec,
- uint32_t line_no) {
-#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
- return false;
-#else
- // We attach this to an 'odoc' event to specify a particular selection
- typedef struct {
- int16_t reserved0; // must be zero
- int16_t fLineNumber;
- int32_t fSelStart;
- int32_t fSelEnd;
- uint32_t reserved1; // must be zero
- uint32_t reserved2; // must be zero
- } BabelAESelInfo;
-
- Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_HOST));
- char file_path[PATH_MAX];
- file_spec.GetPath(file_path, PATH_MAX);
- CFCString file_cfstr(file_path, kCFStringEncodingUTF8);
- CFCReleaser<CFURLRef> file_URL(::CFURLCreateWithFileSystemPath(
- NULL, file_cfstr.get(), kCFURLPOSIXPathStyle, false));
-
- if (log)
- log->Printf(
- "Sending source file: \"%s\" and line: %d to external editor.\n",
- file_path, line_no);
-
- long error;
- BabelAESelInfo file_and_line_info = {
- 0, // reserved0
- (int16_t)(line_no - 1), // fLineNumber (zero based line number)
- 1, // fSelStart
- 1024, // fSelEnd
- 0, // reserved1
- 0 // reserved2
- };
-
- AEKeyDesc file_and_line_desc;
-
- error = ::AECreateDesc(typeUTF8Text, &file_and_line_info,
- sizeof(file_and_line_info),
- &(file_and_line_desc.descContent));
-
- if (error != noErr) {
- if (log)
- log->Printf("Error creating AEDesc: %ld.\n", error);
- return false;
- }
-
- file_and_line_desc.descKey = keyAEPosition;
-
- static std::string g_app_name;
- static FSRef g_app_fsref;
-
- LSApplicationParameters app_params;
- ::memset(&app_params, 0, sizeof(app_params));
- app_params.flags =
- kLSLaunchDefaults | kLSLaunchDontAddToRecents | kLSLaunchDontSwitch;
-
- char *external_editor = ::getenv("LLDB_EXTERNAL_EDITOR");
-
- if (external_editor) {
- if (log)
- log->Printf("Looking for external editor \"%s\".\n", external_editor);
-
- if (g_app_name.empty() ||
- strcmp(g_app_name.c_str(), external_editor) != 0) {
- CFCString editor_name(external_editor, kCFStringEncodingUTF8);
- error = ::LSFindApplicationForInfo(kLSUnknownCreator, NULL,
- editor_name.get(), &g_app_fsref, NULL);
-
- // If we found the app, then store away the name so we don't have to
- // re-look it up.
- if (error != noErr) {
- if (log)
- log->Printf(
- "Could not find External Editor application, error: %ld.\n",
- error);
- return false;
- }
- }
- app_params.application = &g_app_fsref;
- }
-
- ProcessSerialNumber psn;
- CFCReleaser<CFArrayRef> file_array(
- CFArrayCreate(NULL, (const void **)file_URL.ptr_address(false), 1, NULL));
- error = ::LSOpenURLsWithRole(file_array.get(), kLSRolesAll,
- &file_and_line_desc, &app_params, &psn, 1);
-
- AEDisposeDesc(&(file_and_line_desc.descContent));
-
- if (error != noErr) {
- if (log)
- log->Printf("LSOpenURLsWithRole failed, error: %ld.\n", error);
-
- return false;
- }
-
- return true;
-#endif // #if !defined(__arm__) && !defined(__arm64__) && !defined(__aarch64__)
-}
-
-Environment Host::GetEnvironment() { return Environment(*_NSGetEnviron()); }
-
-static bool GetMacOSXProcessCPUType(ProcessInstanceInfo &process_info) {
- if (process_info.ProcessIDIsValid()) {
- // Make a new mib to stay thread safe
- int mib[CTL_MAXNAME] = {
- 0,
- };
- size_t mib_len = CTL_MAXNAME;
- if (::sysctlnametomib("sysctl.proc_cputype", mib, &mib_len))
- return false;
-
- mib[mib_len] = process_info.GetProcessID();
- mib_len++;
-
- cpu_type_t cpu, sub = 0;
- size_t len = sizeof(cpu);
- if (::sysctl(mib, mib_len, &cpu, &len, 0, 0) == 0) {
- switch (cpu) {
- case CPU_TYPE_I386:
- sub = CPU_SUBTYPE_I386_ALL;
- break;
- case CPU_TYPE_X86_64:
- sub = CPU_SUBTYPE_X86_64_ALL;
- break;
-
-#if defined(CPU_TYPE_ARM64) && defined(CPU_SUBTYPE_ARM64_ALL)
- case CPU_TYPE_ARM64:
- sub = CPU_SUBTYPE_ARM64_ALL;
- break;
-#endif
-
- case CPU_TYPE_ARM: {
- // Note that we fetched the cpu type from the PROCESS but we can't get a
- // cpusubtype of the
- // process -- we can only get the host's cpu subtype.
- uint32_t cpusubtype = 0;
- len = sizeof(cpusubtype);
- if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) == 0)
- sub = cpusubtype;
-
- bool host_cpu_is_64bit;
- uint32_t is64bit_capable;
- size_t is64bit_capable_len = sizeof(is64bit_capable);
- host_cpu_is_64bit =
- sysctlbyname("hw.cpu64bit_capable", &is64bit_capable,
- &is64bit_capable_len, NULL, 0) == 0;
-
- // if the host is an armv8 device, its cpusubtype will be in
- // CPU_SUBTYPE_ARM64 numbering
- // and we need to rewrite it to a reasonable CPU_SUBTYPE_ARM value
- // instead.
-
- if (host_cpu_is_64bit) {
- sub = CPU_SUBTYPE_ARM_V7;
- }
- } break;
-
- default:
- break;
- }
- process_info.GetArchitecture().SetArchitecture(eArchTypeMachO, cpu, sub);
- return true;
- }
- }
- process_info.GetArchitecture().Clear();
- return false;
-}
-
-static bool GetMacOSXProcessArgs(const ProcessInstanceInfoMatch *match_info_ptr,
- ProcessInstanceInfo &process_info) {
- if (process_info.ProcessIDIsValid()) {
- int proc_args_mib[3] = {CTL_KERN, KERN_PROCARGS2,
- (int)process_info.GetProcessID()};
-
- size_t arg_data_size = 0;
- if (::sysctl(proc_args_mib, 3, nullptr, &arg_data_size, NULL, 0) ||
- arg_data_size == 0)
- arg_data_size = 8192;
-
- // Add a few bytes to the calculated length, I know we need to add at least
- // one byte
- // to this number otherwise we get junk back, so add 128 just in case...
- DataBufferHeap arg_data(arg_data_size + 128, 0);
- arg_data_size = arg_data.GetByteSize();
- if (::sysctl(proc_args_mib, 3, arg_data.GetBytes(), &arg_data_size, NULL,
- 0) == 0) {
- DataExtractor data(arg_data.GetBytes(), arg_data_size,
- endian::InlHostByteOrder(), sizeof(void *));
- lldb::offset_t offset = 0;
- uint32_t argc = data.GetU32(&offset);
- llvm::Triple &triple = process_info.GetArchitecture().GetTriple();
- const llvm::Triple::ArchType triple_arch = triple.getArch();
- const bool check_for_ios_simulator =
- (triple_arch == llvm::Triple::x86 ||
- triple_arch == llvm::Triple::x86_64);
- const char *cstr = data.GetCStr(&offset);
- if (cstr) {
- process_info.GetExecutableFile().SetFile(cstr, FileSpec::Style::native);
-
- if (match_info_ptr == NULL ||
- NameMatches(
- process_info.GetExecutableFile().GetFilename().GetCString(),
- match_info_ptr->GetNameMatchType(),
- match_info_ptr->GetProcessInfo().GetName())) {
- // Skip NULLs
- while (1) {
- const uint8_t *p = data.PeekData(offset, 1);
- if ((p == NULL) || (*p != '\0'))
- break;
- ++offset;
- }
- // Now extract all arguments
- Args &proc_args = process_info.GetArguments();
- for (int i = 0; i < static_cast<int>(argc); ++i) {
- cstr = data.GetCStr(&offset);
- if (cstr)
- proc_args.AppendArgument(llvm::StringRef(cstr));
- }
-
- Environment &proc_env = process_info.GetEnvironment();
- while ((cstr = data.GetCStr(&offset))) {
- if (cstr[0] == '\0')
- break;
-
- if (check_for_ios_simulator) {
- if (strncmp(cstr, "SIMULATOR_UDID=", strlen("SIMULATOR_UDID=")) ==
- 0)
- process_info.GetArchitecture().GetTriple().setOS(
- llvm::Triple::IOS);
- else
- process_info.GetArchitecture().GetTriple().setOS(
- llvm::Triple::MacOSX);
- }
-
- proc_env.insert(cstr);
- }
- return true;
- }
- }
- }
- }
- return false;
-}
-
-static bool GetMacOSXProcessUserAndGroup(ProcessInstanceInfo &process_info) {
- if (process_info.ProcessIDIsValid()) {
- int mib[4];
- mib[0] = CTL_KERN;
- mib[1] = KERN_PROC;
- mib[2] = KERN_PROC_PID;
- mib[3] = process_info.GetProcessID();
- struct kinfo_proc proc_kinfo;
- size_t 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.kp_eproc.e_ppid);
- process_info.SetUserID(proc_kinfo.kp_eproc.e_pcred.p_ruid);
- process_info.SetGroupID(proc_kinfo.kp_eproc.e_pcred.p_rgid);
- process_info.SetEffectiveUserID(proc_kinfo.kp_eproc.e_ucred.cr_uid);
- if (proc_kinfo.kp_eproc.e_ucred.cr_ngroups > 0)
- process_info.SetEffectiveGroupID(
- proc_kinfo.kp_eproc.e_ucred.cr_groups[0]);
- else
- process_info.SetEffectiveGroupID(UINT32_MAX);
- 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, nullptr, &pid_data_size, nullptr, 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, nullptr, 0) != 0)
- return 0;
-
- const size_t actual_pid_count = (pid_data_size / sizeof(struct kinfo_proc));
-
- bool all_users = match_info.GetMatchAllUsers();
- const lldb::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];
-
- bool kinfo_user_matches = false;
- if (all_users)
- kinfo_user_matches = true;
- else
- kinfo_user_matches = kinfo.kp_eproc.e_pcred.p_ruid == our_uid;
-
- // Special case, if lldb is being run as root we can attach to anything.
- if (our_uid == 0)
- kinfo_user_matches = true;
-
- if (!kinfo_user_matches || // Make sure the user is acceptable
- static_cast<lldb::pid_t>(kinfo.kp_proc.p_pid) ==
- our_pid || // Skip this process
- kinfo.kp_proc.p_pid == 0 || // Skip kernel (kernel pid is zero)
- kinfo.kp_proc.p_stat == SZOMB || // Zombies are bad, they like brains...
- kinfo.kp_proc.p_flag & P_TRACED || // Being debugged?
- kinfo.kp_proc.p_flag & P_WEXIT || // Working on exiting?
- kinfo.kp_proc.p_flag & P_TRANSLATED) // Skip translated ppc (Rosetta)
- continue;
-
- ProcessInstanceInfo process_info;
- process_info.SetProcessID(kinfo.kp_proc.p_pid);
- process_info.SetParentProcessID(kinfo.kp_eproc.e_ppid);
- process_info.SetUserID(kinfo.kp_eproc.e_pcred.p_ruid);
- process_info.SetGroupID(kinfo.kp_eproc.e_pcred.p_rgid);
- process_info.SetEffectiveUserID(kinfo.kp_eproc.e_ucred.cr_uid);
- if (kinfo.kp_eproc.e_ucred.cr_ngroups > 0)
- process_info.SetEffectiveGroupID(kinfo.kp_eproc.e_ucred.cr_groups[0]);
- else
- process_info.SetEffectiveGroupID(UINT32_MAX);
-
- // Make sure our info matches before we go fetch the name and cpu type
- if (match_info.Matches(process_info)) {
- // Get CPU type first so we can know to look for iOS simulator is we have
- // x86 or x86_64
- if (GetMacOSXProcessCPUType(process_info)) {
- if (GetMacOSXProcessArgs(&match_info, 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);
- bool success = false;
-
- // Get CPU type first so we can know to look for iOS simulator is we have x86
- // or x86_64
- if (GetMacOSXProcessCPUType(process_info))
- success = true;
-
- if (GetMacOSXProcessArgs(NULL, process_info))
- success = true;
-
- if (GetMacOSXProcessUserAndGroup(process_info))
- success = true;
-
- if (success)
- return true;
-
- process_info.Clear();
- return false;
-}
-
-#if !NO_XPC_SERVICES
-static void PackageXPCArguments(xpc_object_t message, const char *prefix,
- const Args &args) {
- size_t count = args.GetArgumentCount();
- char buf[50]; // long enough for 'argXXX'
- memset(buf, 0, 50);
- sprintf(buf, "%sCount", prefix);
- xpc_dictionary_set_int64(message, buf, count);
- for (size_t i = 0; i < count; i++) {
- memset(buf, 0, 50);
- sprintf(buf, "%s%zi", prefix, i);
- xpc_dictionary_set_string(message, buf, args.GetArgumentAtIndex(i));
- }
-}
-
-static void PackageXPCEnvironment(xpc_object_t message, llvm::StringRef prefix,
- const Environment &env) {
- xpc_dictionary_set_int64(message, (prefix + "Count").str().c_str(),
- env.size());
- size_t i = 0;
- for (const auto &KV : env) {
- xpc_dictionary_set_string(message, (prefix + llvm::Twine(i)).str().c_str(),
- Environment::compose(KV).c_str());
- }
-}
-
-/*
- A valid authorizationRef means that
- - there is the LaunchUsingXPCRightName rights in the /etc/authorization
- - we have successfully copied the rights to be send over the XPC wire
- Once obtained, it will be valid for as long as the process lives.
- */
-static AuthorizationRef authorizationRef = NULL;
-static Status getXPCAuthorization(ProcessLaunchInfo &launch_info) {
- Status error;
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST |
- LIBLLDB_LOG_PROCESS));
-
- if ((launch_info.GetUserID() == 0) && !authorizationRef) {
- OSStatus createStatus =
- AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment,
- kAuthorizationFlagDefaults, &authorizationRef);
- if (createStatus != errAuthorizationSuccess) {
- error.SetError(1, eErrorTypeGeneric);
- error.SetErrorString("Can't create authorizationRef.");
- LLDB_LOG(log, "error: {0}", error);
- return error;
- }
-
- OSStatus rightsStatus =
- AuthorizationRightGet(LaunchUsingXPCRightName, NULL);
- if (rightsStatus != errAuthorizationSuccess) {
- // No rights in the security database, Create it with the right prompt.
- CFStringRef prompt =
- CFSTR("Xcode is trying to take control of a root process.");
- CFStringRef keys[] = {CFSTR("en")};
- CFTypeRef values[] = {prompt};
- CFDictionaryRef promptDict = CFDictionaryCreate(
- kCFAllocatorDefault, (const void **)keys, (const void **)values, 1,
- &kCFCopyStringDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks);
-
- CFStringRef keys1[] = {CFSTR("class"), CFSTR("group"), CFSTR("comment"),
- CFSTR("default-prompt"), CFSTR("shared")};
- CFTypeRef values1[] = {CFSTR("user"), CFSTR("admin"),
- CFSTR(LaunchUsingXPCRightName), promptDict,
- kCFBooleanFalse};
- CFDictionaryRef dict = CFDictionaryCreate(
- kCFAllocatorDefault, (const void **)keys1, (const void **)values1, 5,
- &kCFCopyStringDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks);
- rightsStatus = AuthorizationRightSet(
- authorizationRef, LaunchUsingXPCRightName, dict, NULL, NULL, NULL);
- CFRelease(promptDict);
- CFRelease(dict);
- }
-
- OSStatus copyRightStatus = errAuthorizationDenied;
- if (rightsStatus == errAuthorizationSuccess) {
- AuthorizationItem item1 = {LaunchUsingXPCRightName, 0, NULL, 0};
- AuthorizationItem items[] = {item1};
- AuthorizationRights requestedRights = {1, items};
- AuthorizationFlags authorizationFlags =
- kAuthorizationFlagInteractionAllowed | kAuthorizationFlagExtendRights;
- copyRightStatus = AuthorizationCopyRights(
- authorizationRef, &requestedRights, kAuthorizationEmptyEnvironment,
- authorizationFlags, NULL);
- }
-
- if (copyRightStatus != errAuthorizationSuccess) {
- // Eventually when the commandline supports running as root and the user
- // is not
- // logged in in the current audit session, we will need the trick in gdb
- // where
- // we ask the user to type in the root passwd in the terminal.
- error.SetError(2, eErrorTypeGeneric);
- error.SetErrorStringWithFormat(
- "Launching as root needs root authorization.");
- LLDB_LOG(log, "error: {0}", error);
-
- if (authorizationRef) {
- AuthorizationFree(authorizationRef, kAuthorizationFlagDefaults);
- authorizationRef = NULL;
- }
- }
- }
-
- return error;
-}
-#endif
-
-static short GetPosixspawnFlags(const ProcessLaunchInfo &launch_info) {
- short flags = POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETSIGMASK;
-
- if (launch_info.GetFlags().Test(eLaunchFlagExec))
- flags |= POSIX_SPAWN_SETEXEC; // Darwin specific posix_spawn flag
-
- if (launch_info.GetFlags().Test(eLaunchFlagDebug))
- flags |= POSIX_SPAWN_START_SUSPENDED; // Darwin specific posix_spawn flag
-
- if (launch_info.GetFlags().Test(eLaunchFlagDisableASLR))
- flags |= _POSIX_SPAWN_DISABLE_ASLR; // Darwin specific posix_spawn flag
-
- if (launch_info.GetLaunchInSeparateProcessGroup())
- flags |= POSIX_SPAWN_SETPGROUP;
-
-#ifdef POSIX_SPAWN_CLOEXEC_DEFAULT
-#if defined(__x86_64__) || defined(__i386__)
- static LazyBool g_use_close_on_exec_flag = eLazyBoolCalculate;
- if (g_use_close_on_exec_flag == eLazyBoolCalculate) {
- g_use_close_on_exec_flag = eLazyBoolNo;
-
- llvm::VersionTuple version = HostInfo::GetOSVersion();
- if (version > llvm::VersionTuple(10, 7)) {
- // Kernel panic if we use the POSIX_SPAWN_CLOEXEC_DEFAULT on 10.7 or
- // earlier
- g_use_close_on_exec_flag = eLazyBoolYes;
- }
- }
-#else
- static LazyBool g_use_close_on_exec_flag = eLazyBoolYes;
-#endif // defined(__x86_64__) || defined(__i386__)
- // Close all files exception those with file actions if this is supported.
- if (g_use_close_on_exec_flag == eLazyBoolYes)
- flags |= POSIX_SPAWN_CLOEXEC_DEFAULT;
-#endif // ifdef POSIX_SPAWN_CLOEXEC_DEFAULT
- return flags;
-}
-
-static Status LaunchProcessXPC(const char *exe_path,
- ProcessLaunchInfo &launch_info,
- lldb::pid_t &pid) {
-#if !NO_XPC_SERVICES
- Status error = getXPCAuthorization(launch_info);
- if (error.Fail())
- return error;
-
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST |
- LIBLLDB_LOG_PROCESS));
-
- uid_t requested_uid = launch_info.GetUserID();
- const char *xpc_service = nil;
- bool send_auth = false;
- AuthorizationExternalForm extForm;
- if (requested_uid == 0) {
- if (AuthorizationMakeExternalForm(authorizationRef, &extForm) ==
- errAuthorizationSuccess) {
- send_auth = true;
- } else {
- error.SetError(3, eErrorTypeGeneric);
- error.SetErrorStringWithFormat("Launching root via XPC needs to "
- "externalize authorization reference.");
- LLDB_LOG(log, "error: {0}", error);
- return error;
- }
- xpc_service = LaunchUsingXPCRightName;
- } else {
- error.SetError(4, eErrorTypeGeneric);
- error.SetErrorStringWithFormat(
- "Launching via XPC is only currently available for root.");
- LLDB_LOG(log, "error: {0}", error);
- return error;
- }
-
- xpc_connection_t conn = xpc_connection_create(xpc_service, NULL);
-
- xpc_connection_set_event_handler(conn, ^(xpc_object_t event) {
- xpc_type_t type = xpc_get_type(event);
-
- if (type == XPC_TYPE_ERROR) {
- if (event == XPC_ERROR_CONNECTION_INTERRUPTED) {
- // The service has either canceled itself, crashed, or been terminated.
- // The XPC connection is still valid and sending a message to it will
- // re-launch the service.
- // If the service is state-full, this is the time to initialize the new
- // service.
- return;
- } else if (event == XPC_ERROR_CONNECTION_INVALID) {
- // The service is invalid. Either the service name supplied to
- // xpc_connection_create() is incorrect
- // or we (this process) have canceled the service; we can do any cleanup
- // of application state at this point.
- // printf("Service disconnected");
- return;
- } else {
- // printf("Unexpected error from service: %s",
- // xpc_dictionary_get_string(event, XPC_ERROR_KEY_DESCRIPTION));
- }
-
- } else {
- // printf("Received unexpected event in handler");
- }
- });
-
- xpc_connection_set_finalizer_f(conn, xpc_finalizer_t(xpc_release));
- xpc_connection_resume(conn);
- xpc_object_t message = xpc_dictionary_create(nil, nil, 0);
-
- if (send_auth) {
- xpc_dictionary_set_data(message, LauncherXPCServiceAuthKey, extForm.bytes,
- sizeof(AuthorizationExternalForm));
- }
-
- PackageXPCArguments(message, LauncherXPCServiceArgPrefxKey,
- launch_info.GetArguments());
- PackageXPCEnvironment(message, LauncherXPCServiceEnvPrefxKey,
- launch_info.GetEnvironment());
-
- // Posix spawn stuff.
- xpc_dictionary_set_int64(message, LauncherXPCServiceCPUTypeKey,
- launch_info.GetArchitecture().GetMachOCPUType());
- xpc_dictionary_set_int64(message, LauncherXPCServicePosixspawnFlagsKey,
- GetPosixspawnFlags(launch_info));
- const FileAction *file_action = launch_info.GetFileActionForFD(STDIN_FILENO);
- if (file_action && !file_action->GetPath().empty()) {
- xpc_dictionary_set_string(message, LauncherXPCServiceStdInPathKeyKey,
- file_action->GetPath().str().c_str());
- }
- file_action = launch_info.GetFileActionForFD(STDOUT_FILENO);
- if (file_action && !file_action->GetPath().empty()) {
- xpc_dictionary_set_string(message, LauncherXPCServiceStdOutPathKeyKey,
- file_action->GetPath().str().c_str());
- }
- file_action = launch_info.GetFileActionForFD(STDERR_FILENO);
- if (file_action && !file_action->GetPath().empty()) {
- xpc_dictionary_set_string(message, LauncherXPCServiceStdErrPathKeyKey,
- file_action->GetPath().str().c_str());
- }
-
- xpc_object_t reply =
- xpc_connection_send_message_with_reply_sync(conn, message);
- xpc_type_t returnType = xpc_get_type(reply);
- if (returnType == XPC_TYPE_DICTIONARY) {
- pid = xpc_dictionary_get_int64(reply, LauncherXPCServiceChildPIDKey);
- if (pid == 0) {
- int errorType =
- xpc_dictionary_get_int64(reply, LauncherXPCServiceErrorTypeKey);
- int errorCode =
- xpc_dictionary_get_int64(reply, LauncherXPCServiceCodeTypeKey);
-
- error.SetError(errorCode, eErrorTypeGeneric);
- error.SetErrorStringWithFormat(
- "Problems with launching via XPC. Error type : %i, code : %i",
- errorType, errorCode);
- LLDB_LOG(log, "error: {0}", error);
-
- if (authorizationRef) {
- AuthorizationFree(authorizationRef, kAuthorizationFlagDefaults);
- authorizationRef = NULL;
- }
- }
- } else if (returnType == XPC_TYPE_ERROR) {
- error.SetError(5, eErrorTypeGeneric);
- error.SetErrorStringWithFormat(
- "Problems with launching via XPC. XPC error : %s",
- xpc_dictionary_get_string(reply, XPC_ERROR_KEY_DESCRIPTION));
- LLDB_LOG(log, "error: {0}", error);
- }
-
- return error;
-#else
- Status error;
- return error;
-#endif
-}
-
-static bool AddPosixSpawnFileAction(void *_file_actions, const FileAction *info,
- Log *log, Status &error) {
- if (info == NULL)
- return false;
-
- posix_spawn_file_actions_t *file_actions =
- reinterpret_cast<posix_spawn_file_actions_t *>(_file_actions);
-
- switch (info->GetAction()) {
- case FileAction::eFileActionNone:
- error.Clear();
- break;
-
- case FileAction::eFileActionClose:
- if (info->GetFD() == -1)
- error.SetErrorString(
- "invalid fd for posix_spawn_file_actions_addclose(...)");
- else {
- error.SetError(
- ::posix_spawn_file_actions_addclose(file_actions, info->GetFD()),
- eErrorTypePOSIX);
- if (error.Fail())
- LLDB_LOG(log,
- "error: {0}, posix_spawn_file_actions_addclose "
- "(action={1}, fd={2})",
- error, file_actions, info->GetFD());
- }
- break;
-
- case FileAction::eFileActionDuplicate:
- if (info->GetFD() == -1)
- error.SetErrorString(
- "invalid fd for posix_spawn_file_actions_adddup2(...)");
- else if (info->GetActionArgument() == -1)
- error.SetErrorString(
- "invalid duplicate fd for posix_spawn_file_actions_adddup2(...)");
- else {
- error.SetError(
- ::posix_spawn_file_actions_adddup2(file_actions, info->GetFD(),
- info->GetActionArgument()),
- eErrorTypePOSIX);
- 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;
-
- case FileAction::eFileActionOpen:
- if (info->GetFD() == -1)
- error.SetErrorString(
- "invalid fd in posix_spawn_file_actions_addopen(...)");
- else {
- int oflag = info->GetActionArgument();
-
- mode_t mode = 0;
-
- if (oflag & O_CREAT)
- mode = 0640;
-
- error.SetError(::posix_spawn_file_actions_addopen(
- file_actions, info->GetFD(),
- info->GetPath().str().c_str(), oflag, mode),
- eErrorTypePOSIX);
- 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;
- }
- return error.Success();
-}
-
-static Status LaunchProcessPosixSpawn(const char *exe_path,
- const ProcessLaunchInfo &launch_info,
- lldb::pid_t &pid) {
- Status error;
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST |
- LIBLLDB_LOG_PROCESS));
-
- posix_spawnattr_t attr;
- error.SetError(::posix_spawnattr_init(&attr), eErrorTypePOSIX);
-
- if (error.Fail()) {
- LLDB_LOG(log, "error: {0}, ::posix_spawnattr_init ( &attr )", error);
- return error;
- }
-
- // Make sure we clean up the posix spawn attributes before exiting this scope.
- CleanUp cleanup_attr(posix_spawnattr_destroy, &attr);
-
- sigset_t no_signals;
- sigset_t all_signals;
- sigemptyset(&no_signals);
- sigfillset(&all_signals);
- ::posix_spawnattr_setsigmask(&attr, &no_signals);
- ::posix_spawnattr_setsigdefault(&attr, &all_signals);
-
- short flags = GetPosixspawnFlags(launch_info);
-
- error.SetError(::posix_spawnattr_setflags(&attr, flags), eErrorTypePOSIX);
- 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/
-#if !defined(__arm__)
-
- // Don't set the binpref if a shell was provided. After all, that's only
- // going to affect what version of the shell
- // is launched, not what fork of the binary is launched. We insert "arch
- // --arch <ARCH> as part of the shell invocation
- // to do that job on OSX.
-
- if (launch_info.GetShell() == nullptr) {
- // We don't need to do this for ARM, and we really shouldn't now that we
- // have multiple CPU subtypes and no posix_spawnattr call that allows us
- // to set which CPU subtype to launch...
- const ArchSpec &arch_spec = launch_info.GetArchitecture();
- cpu_type_t cpu = arch_spec.GetMachOCPUType();
- cpu_type_t sub = arch_spec.GetMachOCPUSubType();
- if (cpu != 0 && cpu != static_cast<cpu_type_t>(UINT32_MAX) &&
- cpu != static_cast<cpu_type_t>(LLDB_INVALID_CPUTYPE) &&
- !(cpu == 0x01000007 && sub == 8)) // If haswell is specified, don't try
- // to set the CPU type or we will fail
- {
- size_t ocount = 0;
- error.SetError(::posix_spawnattr_setbinpref_np(&attr, 1, &cpu, &ocount),
- eErrorTypePOSIX);
- 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;
- }
- }
-#endif // !defined(__arm__)
-
- const char *tmp_argv[2];
- char *const *argv = const_cast<char *const *>(
- launch_info.GetArguments().GetConstArgumentVector());
- Environment::Envp envp = launch_info.GetEnvironment().getEnvp();
- if (argv == NULL) {
- // posix_spawn gets very unhappy if it doesn't have at least the program
- // name in argv[0]. One of the side affects I have noticed is the
- // environment
- // variables don't make it into the child process if "argv == NULL"!!!
- tmp_argv[0] = exe_path;
- tmp_argv[1] = NULL;
- argv = const_cast<char *const *>(tmp_argv);
- }
-
- FileSpec working_dir{launch_info.GetWorkingDirectory()};
- if (working_dir) {
- // Set the working directory on this thread only
- if (__pthread_chdir(working_dir.GetCString()) < 0) {
- if (errno == ENOENT) {
- error.SetErrorStringWithFormat("No such file or directory: %s",
- working_dir.GetCString());
- } else if (errno == ENOTDIR) {
- error.SetErrorStringWithFormat("Path doesn't name a directory: %s",
- working_dir.GetCString());
- } else {
- error.SetErrorStringWithFormat("An unknown error occurred when "
- "changing directory for process "
- "execution.");
- }
- return error;
- }
- }
-
- ::pid_t result_pid = LLDB_INVALID_PROCESS_ID;
- const size_t num_file_actions = launch_info.GetNumFileActions();
- if (num_file_actions > 0) {
- posix_spawn_file_actions_t file_actions;
- error.SetError(::posix_spawn_file_actions_init(&file_actions),
- eErrorTypePOSIX);
- if (error.Fail()) {
- LLDB_LOG(log,
- "error: {0}, ::posix_spawn_file_actions_init ( &file_actions )",
- error);
- return error;
- }
-
- // Make sure we clean up the posix file actions before exiting this scope.
- CleanUp cleanup_fileact(posix_spawn_file_actions_destroy, &file_actions);
-
- for (size_t i = 0; i < num_file_actions; ++i) {
- const FileAction *launch_file_action =
- launch_info.GetFileActionAtIndex(i);
- if (launch_file_action) {
- if (!AddPosixSpawnFileAction(&file_actions, launch_file_action, log,
- error))
- return error;
- }
- }
-
- error.SetError(
- ::posix_spawnp(&result_pid, exe_path, &file_actions, &attr, argv, envp),
- eErrorTypePOSIX);
-
- 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.get());
- if (log) {
- for (int ii = 0; argv[ii]; ++ii)
- LLDB_LOG(log, "argv[{0}] = '{1}'", ii, argv[ii]);
- }
- }
-
- } else {
- error.SetError(
- ::posix_spawnp(&result_pid, exe_path, NULL, &attr, argv, envp),
- eErrorTypePOSIX);
-
- 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.get());
- if (log) {
- for (int ii = 0; argv[ii]; ++ii)
- LLDB_LOG(log, "argv[{0}] = '{1}'", ii, argv[ii]);
- }
- }
- }
- pid = result_pid;
-
- if (working_dir) {
- // No more thread specific current working directory
- __pthread_fchdir(-1);
- }
-
- return error;
-}
-
-static bool ShouldLaunchUsingXPC(ProcessLaunchInfo &launch_info) {
- bool result = false;
-
-#if !NO_XPC_SERVICES
- bool launchingAsRoot = launch_info.GetUserID() == 0;
- bool currentUserIsRoot = HostInfo::GetEffectiveUserID() == 0;
-
- if (launchingAsRoot && !currentUserIsRoot) {
- // If current user is already root, we don't need XPC's help.
- result = true;
- }
-#endif
-
- return result;
-}
-
-Status Host::LaunchProcess(ProcessLaunchInfo &launch_info) {
- Status error;
-
- FileSystem &fs = FileSystem::Instance();
- FileSpec exe_spec(launch_info.GetExecutableFile());
-
- if (!fs.Exists(exe_spec))
- FileSystem::Instance().Resolve(exe_spec);
-
- if (!fs.Exists(exe_spec))
- FileSystem::Instance().ResolveExecutableLocation(exe_spec);
-
- if (!fs.Exists(exe_spec)) {
- error.SetErrorStringWithFormatv("executable doesn't exist: '{0}'",
- exe_spec);
- return error;
- }
-
- if (launch_info.GetFlags().Test(eLaunchFlagLaunchInTTY)) {
-#if !defined(__arm__) && !defined(__arm64__) && !defined(__aarch64__)
- return LaunchInNewTerminalWithAppleScript(exe_spec.GetPath().c_str(),
- launch_info);
-#else
- error.SetErrorString("launching a process in a new terminal is not "
- "supported on iOS devices");
- return error;
-#endif
- }
-
- lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
-
- if (ShouldLaunchUsingXPC(launch_info)) {
- error = LaunchProcessXPC(exe_spec.GetPath().c_str(), launch_info, pid);
- } else {
- error =
- LaunchProcessPosixSpawn(exe_spec.GetPath().c_str(), launch_info, pid);
- }
-
- if (pid != LLDB_INVALID_PROCESS_ID) {
- // If all went well, then set the process ID into the launch info
- launch_info.SetProcessID(pid);
-
- // Make sure we reap any processes we spawn or we will have zombies.
- bool monitoring = launch_info.MonitorProcess();
- UNUSED_IF_ASSERT_DISABLED(monitoring);
- assert(monitoring);
- } else {
- // Invalid process ID, something didn't go well
- if (error.Success())
- error.SetErrorString("process launch failed for unknown reasons");
- }
- return error;
-}
-
-Status Host::ShellExpandArguments(ProcessLaunchInfo &launch_info) {
- Status error;
- if (launch_info.GetFlags().Test(eLaunchFlagShellExpandArguments)) {
- FileSpec expand_tool_spec = HostInfo::GetSupportExeDir();
- if (!expand_tool_spec) {
- error.SetErrorString(
- "could not get support executable directory for lldb-argdumper tool");
- return error;
- }
- expand_tool_spec.AppendPathComponent("lldb-argdumper");
- if (!FileSystem::Instance().Exists(expand_tool_spec)) {
- error.SetErrorStringWithFormat(
- "could not find the lldb-argdumper tool: %s",
- expand_tool_spec.GetPath().c_str());
- return error;
- }
-
- StreamString expand_tool_spec_stream;
- expand_tool_spec_stream.Printf("\"%s\"",
- expand_tool_spec.GetPath().c_str());
-
- Args expand_command(expand_tool_spec_stream.GetData());
- expand_command.AppendArguments(launch_info.GetArguments());
-
- int status;
- std::string output;
- FileSpec cwd(launch_info.GetWorkingDirectory());
- if (!FileSystem::Instance().Exists(cwd)) {
- char *wd = getcwd(nullptr, 0);
- if (wd == nullptr) {
- error.SetErrorStringWithFormat(
- "cwd does not exist; cannot launch with shell argument expansion");
- return error;
- } else {
- FileSpec working_dir(wd);
- free(wd);
- launch_info.SetWorkingDirectory(working_dir);
- }
- }
- RunShellCommand(expand_command, cwd, &status, nullptr, &output,
- std::chrono::seconds(10));
-
- if (status != 0) {
- error.SetErrorStringWithFormat("lldb-argdumper exited with error %d",
- status);
- return error;
- }
-
- auto data_sp = StructuredData::ParseJSON(output);
- if (!data_sp) {
- error.SetErrorString("invalid JSON");
- return error;
- }
-
- auto dict_sp = data_sp->GetAsDictionary();
- if (!data_sp) {
- error.SetErrorString("invalid JSON");
- return error;
- }
-
- auto args_sp = dict_sp->GetObjectForDotSeparatedPath("arguments");
- if (!args_sp) {
- error.SetErrorString("invalid JSON");
- return error;
- }
-
- auto args_array_sp = args_sp->GetAsArray();
- if (!args_array_sp) {
- error.SetErrorString("invalid JSON");
- return error;
- }
-
- launch_info.GetArguments().Clear();
-
- for (size_t i = 0; i < args_array_sp->GetSize(); i++) {
- auto item_sp = args_array_sp->GetItemAtIndex(i);
- if (!item_sp)
- continue;
- auto str_sp = item_sp->GetAsString();
- if (!str_sp)
- continue;
-
- launch_info.GetArguments().AppendArgument(str_sp->GetValue());
- }
- }
-
- return error;
-}
-
-HostThread Host::StartMonitoringChildProcess(
- const Host::MonitorChildProcessCallback &callback, lldb::pid_t pid,
- bool monitor_signals) {
- unsigned long mask = DISPATCH_PROC_EXIT;
- if (monitor_signals)
- mask |= DISPATCH_PROC_SIGNAL;
-
- Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_HOST |
- LIBLLDB_LOG_PROCESS));
-
- dispatch_source_t source = ::dispatch_source_create(
- DISPATCH_SOURCE_TYPE_PROC, pid, mask,
- ::dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));
-
- if (log)
- log->Printf("Host::StartMonitoringChildProcess "
- "(callback, pid=%i, monitor_signals=%i) "
- "source = %p\n",
- static_cast<int>(pid), monitor_signals,
- reinterpret_cast<void *>(source));
-
- if (source) {
- Host::MonitorChildProcessCallback callback_copy = callback;
- ::dispatch_source_set_cancel_handler(source, ^{
- dispatch_release(source);
- });
- ::dispatch_source_set_event_handler(source, ^{
-
- int status = 0;
- int wait_pid = 0;
- bool cancel = false;
- bool exited = false;
- wait_pid = llvm::sys::RetryAfterSignal(-1, ::waitpid, pid, &status, 0);
- if (wait_pid >= 0) {
- int signal = 0;
- int exit_status = 0;
- const char *status_cstr = NULL;
- if (WIFSTOPPED(status)) {
- signal = WSTOPSIG(status);
- status_cstr = "STOPPED";
- } else if (WIFEXITED(status)) {
- exit_status = WEXITSTATUS(status);
- status_cstr = "EXITED";
- exited = true;
- } else if (WIFSIGNALED(status)) {
- signal = WTERMSIG(status);
- status_cstr = "SIGNALED";
- exited = true;
- exit_status = -1;
- } else {
- status_cstr = "???";
- }
-
- if (log)
- log->Printf("::waitpid (pid = %llu, &status, 0) => pid = %i, status "
- "= 0x%8.8x (%s), signal = %i, exit_status = %i",
- pid, wait_pid, status, status_cstr, signal, exit_status);
-
- if (callback_copy)
- cancel = callback_copy(pid, exited, signal, exit_status);
-
- if (exited || cancel) {
- ::dispatch_source_cancel(source);
- }
- }
- });
-
- ::dispatch_resume(source);
- }
- return HostThread();
-}
-
-//----------------------------------------------------------------------
-// Log to both stderr and to ASL Logging when running on MacOSX.
-//----------------------------------------------------------------------
-void Host::SystemLog(SystemLogType type, const char *format, va_list args) {
- if (format && format[0]) {
- static aslmsg g_aslmsg = NULL;
- if (g_aslmsg == NULL) {
- g_aslmsg = ::asl_new(ASL_TYPE_MSG);
- char asl_key_sender[PATH_MAX];
- snprintf(asl_key_sender, sizeof(asl_key_sender),
- "com.apple.LLDB.framework");
- ::asl_set(g_aslmsg, ASL_KEY_SENDER, asl_key_sender);
- }
-
- // Copy the va_list so we can log this message twice
- va_list copy_args;
- va_copy(copy_args, args);
- // Log to stderr
- ::vfprintf(stderr, format, copy_args);
- va_end(copy_args);
-
- int asl_level;
- switch (type) {
- case eSystemLogError:
- asl_level = ASL_LEVEL_ERR;
- break;
-
- case eSystemLogWarning:
- asl_level = ASL_LEVEL_WARNING;
- break;
- }
-
- // Log to ASL
- ::asl_vlog(NULL, g_aslmsg, asl_level, format, args);
- }
-}
diff --git a/source/Host/macosx/objcxx/HostInfoMacOSX.mm b/source/Host/macosx/objcxx/HostInfoMacOSX.mm
deleted file mode 100644
index 165e87e8bed4..000000000000
--- a/source/Host/macosx/objcxx/HostInfoMacOSX.mm
+++ /dev/null
@@ -1,280 +0,0 @@
-//===-- HostInfoMacOSX.mm ---------------------------------------*- 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/macosx/HostInfoMacOSX.h"
-#include "lldb/Host/FileSystem.h"
-#include "lldb/Host/HostInfo.h"
-#include "lldb/Utility/Args.h"
-#include "lldb/Utility/Log.h"
-
-#include "llvm/ADT/SmallString.h"
-#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/Path.h"
-#include "llvm/Support/raw_ostream.h"
-
-// C++ Includes
-#include <string>
-
-// C inclues
-#include <stdlib.h>
-#include <sys/sysctl.h>
-#include <sys/syslimits.h>
-#include <sys/types.h>
-
-// Objective-C/C++ includes
-#include <CoreFoundation/CoreFoundation.h>
-#include <Foundation/Foundation.h>
-#include <mach-o/dyld.h>
-#include <objc/objc-auto.h>
-
-// These are needed when compiling on systems
-// that do not yet have these definitions
-#include <AvailabilityMacros.h>
-#ifndef CPU_SUBTYPE_X86_64_H
-#define CPU_SUBTYPE_X86_64_H ((cpu_subtype_t)8)
-#endif
-#ifndef CPU_TYPE_ARM64
-#define CPU_TYPE_ARM64 (CPU_TYPE_ARM | CPU_ARCH_ABI64)
-#endif
-
-#include <TargetConditionals.h> // for TARGET_OS_TV, TARGET_OS_WATCH
-
-using namespace lldb_private;
-
-bool HostInfoMacOSX::GetOSBuildString(std::string &s) {
- int mib[2] = {CTL_KERN, KERN_OSVERSION};
- char cstr[PATH_MAX];
- size_t cstr_len = sizeof(cstr);
- if (::sysctl(mib, 2, cstr, &cstr_len, NULL, 0) == 0) {
- s.assign(cstr, cstr_len);
- return true;
- }
-
- s.clear();
- return false;
-}
-
-bool HostInfoMacOSX::GetOSKernelDescription(std::string &s) {
- int mib[2] = {CTL_KERN, KERN_VERSION};
- char cstr[PATH_MAX];
- size_t cstr_len = sizeof(cstr);
- if (::sysctl(mib, 2, cstr, &cstr_len, NULL, 0) == 0) {
- s.assign(cstr, cstr_len);
- return true;
- }
- s.clear();
- return false;
-}
-
-llvm::VersionTuple HostInfoMacOSX::GetOSVersion() {
- static llvm::VersionTuple g_version;
-
- if (g_version.empty()) {
- @autoreleasepool {
- NSDictionary *version_info = [NSDictionary
- dictionaryWithContentsOfFile:
- @"/System/Library/CoreServices/SystemVersion.plist"];
- NSString *version_value = [version_info objectForKey:@"ProductVersion"];
- const char *version_str = [version_value UTF8String];
- g_version.tryParse(version_str);
- }
- }
-
- return g_version;
-}
-
-FileSpec HostInfoMacOSX::GetProgramFileSpec() {
- static FileSpec g_program_filespec;
- if (!g_program_filespec) {
- char program_fullpath[PATH_MAX];
- // If DST is NULL, then return the number of bytes needed.
- uint32_t len = sizeof(program_fullpath);
- int err = _NSGetExecutablePath(program_fullpath, &len);
- if (err == 0)
- g_program_filespec.SetFile(program_fullpath, FileSpec::Style::native);
- else if (err == -1) {
- char *large_program_fullpath = (char *)::malloc(len + 1);
-
- err = _NSGetExecutablePath(large_program_fullpath, &len);
- if (err == 0)
- g_program_filespec.SetFile(large_program_fullpath,
- FileSpec::Style::native);
-
- ::free(large_program_fullpath);
- }
- }
- return g_program_filespec;
-}
-
-bool HostInfoMacOSX::ComputeSupportExeDirectory(FileSpec &file_spec) {
- FileSpec lldb_file_spec = GetShlibDir();
- if (!lldb_file_spec)
- return false;
-
- std::string raw_path = lldb_file_spec.GetPath();
-
- size_t framework_pos = raw_path.find("LLDB.framework");
- if (framework_pos != std::string::npos) {
- framework_pos += strlen("LLDB.framework");
-#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
- // Shallow bundle
- raw_path.resize(framework_pos);
-#else
- // Normal bundle
- raw_path.resize(framework_pos);
- raw_path.append("/Resources");
-#endif
- } else {
- // Find the bin path relative to the lib path where the cmake-based
- // OS X .dylib lives. This is not going to work if the bin and lib
- // dir are not both in the same dir.
- //
- // It is not going to work to do it by the executable path either,
- // as in the case of a python script, the executable is python, not
- // the lldb driver.
- raw_path.append("/../bin");
- FileSpec support_dir_spec(raw_path);
- FileSystem::Instance().Resolve(support_dir_spec);
- if (!FileSystem::Instance().IsDirectory(support_dir_spec)) {
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- if (log)
- log->Printf("HostInfoMacOSX::%s(): failed to find support directory",
- __FUNCTION__);
- return false;
- }
-
- // Get normalization from support_dir_spec. Note the FileSpec resolve
- // does not remove '..' in the path.
- char *const dir_realpath =
- realpath(support_dir_spec.GetPath().c_str(), NULL);
- if (dir_realpath) {
- raw_path = dir_realpath;
- free(dir_realpath);
- } else {
- raw_path = support_dir_spec.GetPath();
- }
- }
-
- file_spec.GetDirectory().SetString(
- llvm::StringRef(raw_path.c_str(), raw_path.size()));
- return (bool)file_spec.GetDirectory();
-}
-
-bool HostInfoMacOSX::ComputeHeaderDirectory(FileSpec &file_spec) {
- FileSpec lldb_file_spec = GetShlibDir();
- if (!lldb_file_spec)
- return false;
-
- std::string raw_path = lldb_file_spec.GetPath();
-
- size_t framework_pos = raw_path.find("LLDB.framework");
- if (framework_pos != std::string::npos) {
- framework_pos += strlen("LLDB.framework");
- raw_path.resize(framework_pos);
- raw_path.append("/Headers");
- }
- file_spec.GetDirectory().SetString(
- llvm::StringRef(raw_path.c_str(), raw_path.size()));
- return true;
-}
-
-bool HostInfoMacOSX::ComputeSystemPluginsDirectory(FileSpec &file_spec) {
- FileSpec lldb_file_spec = GetShlibDir();
- if (!lldb_file_spec)
- return false;
-
- std::string raw_path = lldb_file_spec.GetPath();
-
- size_t framework_pos = raw_path.find("LLDB.framework");
- if (framework_pos == std::string::npos)
- return false;
-
- framework_pos += strlen("LLDB.framework");
- raw_path.resize(framework_pos);
- raw_path.append("/Resources/PlugIns");
- file_spec.GetDirectory().SetString(
- llvm::StringRef(raw_path.c_str(), raw_path.size()));
- return true;
-}
-
-bool HostInfoMacOSX::ComputeUserPluginsDirectory(FileSpec &file_spec) {
- FileSpec temp_file("~/Library/Application Support/LLDB/PlugIns");
- FileSystem::Instance().Resolve(temp_file);
- file_spec.GetDirectory().SetCString(temp_file.GetPath().c_str());
- return true;
-}
-
-void HostInfoMacOSX::ComputeHostArchitectureSupport(ArchSpec &arch_32,
- ArchSpec &arch_64) {
- // All apple systems support 32 bit execution.
- uint32_t cputype, cpusubtype;
- uint32_t is_64_bit_capable = false;
- size_t len = sizeof(cputype);
- ArchSpec host_arch;
- // These will tell us about the kernel architecture, which even on a 64
- // bit machine can be 32 bit...
- if (::sysctlbyname("hw.cputype", &cputype, &len, NULL, 0) == 0) {
- len = sizeof(cpusubtype);
- if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) != 0)
- cpusubtype = CPU_TYPE_ANY;
-
- len = sizeof(is_64_bit_capable);
- ::sysctlbyname("hw.cpu64bit_capable", &is_64_bit_capable, &len, NULL, 0);
-
- if (is_64_bit_capable) {
- if (cputype & CPU_ARCH_ABI64) {
- // We have a 64 bit kernel on a 64 bit system
- arch_64.SetArchitecture(eArchTypeMachO, cputype, cpusubtype);
- } else {
- // We have a 64 bit kernel that is returning a 32 bit cputype, the
- // cpusubtype will be correct as if it were for a 64 bit architecture
- arch_64.SetArchitecture(eArchTypeMachO, cputype | CPU_ARCH_ABI64,
- cpusubtype);
- }
-
- // Now we need modify the cpusubtype for the 32 bit slices.
- uint32_t cpusubtype32 = cpusubtype;
-#if defined(__i386__) || defined(__x86_64__)
- if (cpusubtype == CPU_SUBTYPE_486 || cpusubtype == CPU_SUBTYPE_X86_64_H)
- cpusubtype32 = CPU_SUBTYPE_I386_ALL;
-#elif defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
- if (cputype == CPU_TYPE_ARM || cputype == CPU_TYPE_ARM64)
- cpusubtype32 = CPU_SUBTYPE_ARM_V7S;
-#endif
- arch_32.SetArchitecture(eArchTypeMachO, cputype & ~(CPU_ARCH_MASK),
- cpusubtype32);
-
- if (cputype == CPU_TYPE_ARM || cputype == CPU_TYPE_ARM64) {
-// When running on a watch or tv, report the host os correctly
-#if defined(TARGET_OS_TV) && TARGET_OS_TV == 1
- arch_32.GetTriple().setOS(llvm::Triple::TvOS);
- arch_64.GetTriple().setOS(llvm::Triple::TvOS);
-#elif defined(TARGET_OS_BRIDGE) && TARGET_OS_BRIDGE == 1
- arch_32.GetTriple().setOS(llvm::Triple::BridgeOS);
- arch_64.GetTriple().setOS(llvm::Triple::BridgeOS);
-#else
- arch_32.GetTriple().setOS(llvm::Triple::IOS);
- arch_64.GetTriple().setOS(llvm::Triple::IOS);
-#endif
- } else {
- arch_32.GetTriple().setOS(llvm::Triple::MacOSX);
- arch_64.GetTriple().setOS(llvm::Triple::MacOSX);
- }
- } else {
- // We have a 32 bit kernel on a 32 bit system
- arch_32.SetArchitecture(eArchTypeMachO, cputype, cpusubtype);
-#if defined(TARGET_OS_WATCH) && TARGET_OS_WATCH == 1
- arch_32.GetTriple().setOS(llvm::Triple::WatchOS);
-#else
- arch_32.GetTriple().setOS(llvm::Triple::IOS);
-#endif
- arch_64.Clear();
- }
- }
-}
diff --git a/source/Host/macosx/objcxx/HostThreadMacOSX.mm b/source/Host/macosx/objcxx/HostThreadMacOSX.mm
deleted file mode 100644
index c5051cdf30d7..000000000000
--- a/source/Host/macosx/objcxx/HostThreadMacOSX.mm
+++ /dev/null
@@ -1,70 +0,0 @@
-//===-- HostThreadMacOSX.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/macosx/HostThreadMacOSX.h"
-#include "lldb/Host/Host.h"
-
-#include <CoreFoundation/CoreFoundation.h>
-#include <Foundation/Foundation.h>
-
-#include <pthread.h>
-
-using namespace lldb_private;
-
-namespace {
-
-pthread_once_t g_thread_create_once = PTHREAD_ONCE_INIT;
-pthread_key_t g_thread_create_key = 0;
-
-class MacOSXDarwinThread {
-public:
- MacOSXDarwinThread() : m_pool(nil) {
- m_pool = [[NSAutoreleasePool alloc] init];
- }
-
- ~MacOSXDarwinThread() {
- if (m_pool) {
- [m_pool drain];
- m_pool = nil;
- }
- }
-
- static void PThreadDestructor(void *v) {
- if (v)
- delete static_cast<MacOSXDarwinThread *>(v);
- ::pthread_setspecific(g_thread_create_key, NULL);
- }
-
-protected:
- NSAutoreleasePool *m_pool;
-
-private:
- DISALLOW_COPY_AND_ASSIGN(MacOSXDarwinThread);
-};
-
-void InitThreadCreated() {
- ::pthread_key_create(&g_thread_create_key,
- MacOSXDarwinThread::PThreadDestructor);
-}
-} // namespace
-
-HostThreadMacOSX::HostThreadMacOSX() : HostThreadPosix() {}
-
-HostThreadMacOSX::HostThreadMacOSX(lldb::thread_t thread)
- : HostThreadPosix(thread) {}
-
-lldb::thread_result_t
-HostThreadMacOSX::ThreadCreateTrampoline(lldb::thread_arg_t arg) {
- ::pthread_once(&g_thread_create_once, InitThreadCreated);
- if (g_thread_create_key) {
- ::pthread_setspecific(g_thread_create_key, new MacOSXDarwinThread());
- }
-
- return HostThreadPosix::ThreadCreateTrampoline(arg);
-}
diff --git a/source/Host/windows/ConnectionGenericFileWindows.cpp b/source/Host/windows/ConnectionGenericFileWindows.cpp
deleted file mode 100644
index e59e190dcb2d..000000000000
--- a/source/Host/windows/ConnectionGenericFileWindows.cpp
+++ /dev/null
@@ -1,323 +0,0 @@
-//===-- ConnectionGenericFileWindows.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/windows/ConnectionGenericFileWindows.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/Status.h"
-#include "lldb/Utility/Timeout.h"
-
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/ConvertUTF.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-namespace {
-// This is a simple helper class to package up the information needed to return
-// from a Read/Write operation function. Since there is a lot of code to be
-// run before exit regardless of whether the operation succeeded or failed,
-// combined with many possible return paths, this is the cleanest way to
-// represent it.
-class ReturnInfo {
-public:
- void Set(size_t bytes, ConnectionStatus status, DWORD error_code) {
- m_error.SetError(error_code, eErrorTypeWin32);
- m_bytes = bytes;
- m_status = status;
- }
-
- void Set(size_t bytes, ConnectionStatus status, llvm::StringRef error_msg) {
- m_error.SetErrorString(error_msg.data());
- m_bytes = bytes;
- m_status = status;
- }
-
- size_t GetBytes() const { return m_bytes; }
- ConnectionStatus GetStatus() const { return m_status; }
- const Status &GetError() const { return m_error; }
-
-private:
- Status m_error;
- size_t m_bytes;
- ConnectionStatus m_status;
-};
-}
-
-ConnectionGenericFile::ConnectionGenericFile()
- : m_file(INVALID_HANDLE_VALUE), m_owns_file(false) {
- ::ZeroMemory(&m_overlapped, sizeof(m_overlapped));
- ::ZeroMemory(&m_file_position, sizeof(m_file_position));
- InitializeEventHandles();
-}
-
-ConnectionGenericFile::ConnectionGenericFile(lldb::file_t file, bool owns_file)
- : m_file(file), m_owns_file(owns_file) {
- ::ZeroMemory(&m_overlapped, sizeof(m_overlapped));
- ::ZeroMemory(&m_file_position, sizeof(m_file_position));
- InitializeEventHandles();
-}
-
-ConnectionGenericFile::~ConnectionGenericFile() {
- if (m_owns_file && IsConnected())
- ::CloseHandle(m_file);
-
- ::CloseHandle(m_event_handles[kBytesAvailableEvent]);
- ::CloseHandle(m_event_handles[kInterruptEvent]);
-}
-
-void ConnectionGenericFile::InitializeEventHandles() {
- m_event_handles[kInterruptEvent] = CreateEvent(NULL, FALSE, FALSE, NULL);
-
- // Note, we should use a manual reset event for the hEvent argument of the
- // OVERLAPPED. This is because both WaitForMultipleObjects and
- // GetOverlappedResult (if you set the bWait argument to TRUE) will wait for
- // the event to be signalled. If we use an auto-reset event,
- // WaitForMultipleObjects will reset the event, return successfully, and then
- // GetOverlappedResult will block since the event is no longer signalled.
- m_event_handles[kBytesAvailableEvent] =
- ::CreateEvent(NULL, TRUE, FALSE, NULL);
-}
-
-bool ConnectionGenericFile::IsConnected() const {
- return m_file && (m_file != INVALID_HANDLE_VALUE);
-}
-
-lldb::ConnectionStatus ConnectionGenericFile::Connect(llvm::StringRef path,
- Status *error_ptr) {
- Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION));
- if (log)
- log->Printf("%p ConnectionGenericFile::Connect (url = '%s')",
- static_cast<void *>(this), path.str().c_str());
-
- if (!path.consume_front("file://")) {
- if (error_ptr)
- error_ptr->SetErrorStringWithFormat("unsupported connection URL: '%s'",
- path.str().c_str());
- return eConnectionStatusError;
- }
-
- if (IsConnected()) {
- ConnectionStatus status = Disconnect(error_ptr);
- if (status != eConnectionStatusSuccess)
- return status;
- }
-
- // Open the file for overlapped access. If it does not exist, create it. We
- // open it overlapped so that we can issue asynchronous reads and then use
- // WaitForMultipleObjects to allow the read to be interrupted by an event
- // object.
- std::wstring wpath;
- if (!llvm::ConvertUTF8toWide(path, wpath)) {
- if (error_ptr)
- error_ptr->SetError(1, eErrorTypeGeneric);
- return eConnectionStatusError;
- }
- m_file = ::CreateFileW(wpath.c_str(), GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ, NULL, OPEN_ALWAYS,
- FILE_FLAG_OVERLAPPED, NULL);
- if (m_file == INVALID_HANDLE_VALUE) {
- if (error_ptr)
- error_ptr->SetError(::GetLastError(), eErrorTypeWin32);
- return eConnectionStatusError;
- }
-
- m_owns_file = true;
- m_uri.assign(path);
- return eConnectionStatusSuccess;
-}
-
-lldb::ConnectionStatus ConnectionGenericFile::Disconnect(Status *error_ptr) {
- Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION));
- if (log)
- log->Printf("%p ConnectionGenericFile::Disconnect ()",
- static_cast<void *>(this));
-
- if (!IsConnected())
- return eConnectionStatusSuccess;
-
- // Reset the handle so that after we unblock any pending reads, subsequent
- // calls to Read() will see a disconnected state.
- HANDLE old_file = m_file;
- m_file = INVALID_HANDLE_VALUE;
-
- // Set the disconnect event so that any blocking reads unblock, then cancel
- // any pending IO operations.
- ::CancelIoEx(old_file, &m_overlapped);
-
- // Close the file handle if we owned it, but don't close the event handles.
- // We could always reconnect with the same Connection instance.
- if (m_owns_file)
- ::CloseHandle(old_file);
-
- ::ZeroMemory(&m_file_position, sizeof(m_file_position));
- m_owns_file = false;
- m_uri.clear();
- return eConnectionStatusSuccess;
-}
-
-size_t ConnectionGenericFile::Read(void *dst, size_t dst_len,
- const Timeout<std::micro> &timeout,
- lldb::ConnectionStatus &status,
- Status *error_ptr) {
- ReturnInfo return_info;
- BOOL result = 0;
- DWORD bytes_read = 0;
-
- if (error_ptr)
- error_ptr->Clear();
-
- if (!IsConnected()) {
- return_info.Set(0, eConnectionStatusNoConnection, ERROR_INVALID_HANDLE);
- goto finish;
- }
-
- m_overlapped.hEvent = m_event_handles[kBytesAvailableEvent];
-
- result = ::ReadFile(m_file, dst, dst_len, NULL, &m_overlapped);
- if (result || ::GetLastError() == ERROR_IO_PENDING) {
- if (!result) {
- // The expected return path. The operation is pending. Wait for the
- // operation to complete or be interrupted.
- DWORD milliseconds =
- timeout
- ? std::chrono::duration_cast<std::chrono::milliseconds>(*timeout)
- .count()
- : INFINITE;
- DWORD wait_result =
- ::WaitForMultipleObjects(llvm::array_lengthof(m_event_handles),
- m_event_handles, FALSE, milliseconds);
- // All of the events are manual reset events, so make sure we reset them
- // to non-signalled.
- switch (wait_result) {
- case WAIT_OBJECT_0 + kBytesAvailableEvent:
- break;
- case WAIT_OBJECT_0 + kInterruptEvent:
- return_info.Set(0, eConnectionStatusInterrupted, 0);
- goto finish;
- case WAIT_TIMEOUT:
- return_info.Set(0, eConnectionStatusTimedOut, 0);
- goto finish;
- case WAIT_FAILED:
- return_info.Set(0, eConnectionStatusError, ::GetLastError());
- goto finish;
- }
- }
- // The data is ready. Figure out how much was read and return;
- if (!::GetOverlappedResult(m_file, &m_overlapped, &bytes_read, FALSE)) {
- DWORD result_error = ::GetLastError();
- // ERROR_OPERATION_ABORTED occurs when someone calls Disconnect() during
- // a blocking read. This triggers a call to CancelIoEx, which causes the
- // operation to complete and the result to be ERROR_OPERATION_ABORTED.
- if (result_error == ERROR_HANDLE_EOF ||
- result_error == ERROR_OPERATION_ABORTED ||
- result_error == ERROR_BROKEN_PIPE)
- return_info.Set(bytes_read, eConnectionStatusEndOfFile, 0);
- else
- return_info.Set(bytes_read, eConnectionStatusError, result_error);
- } else if (bytes_read == 0)
- return_info.Set(bytes_read, eConnectionStatusEndOfFile, 0);
- else
- return_info.Set(bytes_read, eConnectionStatusSuccess, 0);
-
- goto finish;
- } else if (::GetLastError() == ERROR_BROKEN_PIPE) {
- // The write end of a pipe was closed. This is equivalent to EOF.
- return_info.Set(0, eConnectionStatusEndOfFile, 0);
- } else {
- // An unknown error occurred. Fail out.
- return_info.Set(0, eConnectionStatusError, ::GetLastError());
- }
- goto finish;
-
-finish:
- status = return_info.GetStatus();
- if (error_ptr)
- *error_ptr = return_info.GetError();
-
- // kBytesAvailableEvent is a manual reset event. Make sure it gets reset
- // here so that any subsequent operations don't immediately see bytes
- // available.
- ResetEvent(m_event_handles[kBytesAvailableEvent]);
-
- IncrementFilePointer(return_info.GetBytes());
- Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION));
- if (log) {
- log->Printf("%p ConnectionGenericFile::Read() handle = %p, dst = %p, "
- "dst_len = %zu) => %zu, error = %s",
- this, m_file, dst, dst_len, return_info.GetBytes(),
- return_info.GetError().AsCString());
- }
-
- return return_info.GetBytes();
-}
-
-size_t ConnectionGenericFile::Write(const void *src, size_t src_len,
- lldb::ConnectionStatus &status,
- Status *error_ptr) {
- ReturnInfo return_info;
- DWORD bytes_written = 0;
- BOOL result = 0;
-
- if (error_ptr)
- error_ptr->Clear();
-
- if (!IsConnected()) {
- return_info.Set(0, eConnectionStatusNoConnection, ERROR_INVALID_HANDLE);
- goto finish;
- }
-
- m_overlapped.hEvent = NULL;
-
- // Writes are not interruptible like reads are, so just block until it's
- // done.
- result = ::WriteFile(m_file, src, src_len, NULL, &m_overlapped);
- if (!result && ::GetLastError() != ERROR_IO_PENDING) {
- return_info.Set(0, eConnectionStatusError, ::GetLastError());
- goto finish;
- }
-
- if (!::GetOverlappedResult(m_file, &m_overlapped, &bytes_written, TRUE)) {
- return_info.Set(bytes_written, eConnectionStatusError, ::GetLastError());
- goto finish;
- }
-
- return_info.Set(bytes_written, eConnectionStatusSuccess, 0);
- goto finish;
-
-finish:
- status = return_info.GetStatus();
- if (error_ptr)
- *error_ptr = return_info.GetError();
-
- IncrementFilePointer(return_info.GetBytes());
- Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION));
- if (log) {
- log->Printf("%p ConnectionGenericFile::Write() handle = %p, src = %p, "
- "src_len = %zu) => %zu, error = %s",
- this, m_file, src, src_len, return_info.GetBytes(),
- return_info.GetError().AsCString());
- }
- return return_info.GetBytes();
-}
-
-std::string ConnectionGenericFile::GetURI() { return m_uri; }
-
-bool ConnectionGenericFile::InterruptRead() {
- return ::SetEvent(m_event_handles[kInterruptEvent]);
-}
-
-void ConnectionGenericFile::IncrementFilePointer(DWORD amount) {
- LARGE_INTEGER old_pos;
- old_pos.HighPart = m_overlapped.OffsetHigh;
- old_pos.LowPart = m_overlapped.Offset;
- old_pos.QuadPart += amount;
- m_overlapped.Offset = old_pos.LowPart;
- m_overlapped.OffsetHigh = old_pos.HighPart;
-}
diff --git a/source/Host/windows/EditLineWin.cpp b/source/Host/windows/EditLineWin.cpp
deleted file mode 100644
index 3bccc4e1a2c9..000000000000
--- a/source/Host/windows/EditLineWin.cpp
+++ /dev/null
@@ -1,350 +0,0 @@
-//===-- EditLineWin.cpp -----------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// this file is only relevant for Visual C++
-#if defined(_WIN32)
-
-#include "lldb/Host/windows/windows.h"
-
-#include "lldb/Host/windows/editlinewin.h"
-#include "llvm/Support/ErrorHandling.h"
-#include <assert.h>
-#include <vector>
-
-// edit line EL_ADDFN function pointer type
-typedef unsigned char (*el_addfn_func)(EditLine *e, int ch);
-typedef const char *(*el_prompt_func)(EditLine *);
-
-// edit line wrapper binding container
-struct el_binding {
- //
- const char *name;
- const char *help;
- // function pointer to callback routine
- el_addfn_func func;
- // ascii key this function is bound to
- const char *key;
-};
-
-// stored key bindings
-static std::vector<el_binding *> _bindings;
-
-// TODO: this should in fact be related to the exact edit line context we create
-static void *clientData = NULL;
-
-// store the current prompt string
-// default to what we expect to receive anyway
-static const char *_prompt = "(lldb) ";
-
-#if !defined(_WIP_INPUT_METHOD)
-
-static char *el_get_s(char *buffer, int chars) { return gets_s(buffer, chars); }
-#else
-
-static void con_output(char _in) {
- HANDLE hout = GetStdHandle(STD_OUTPUT_HANDLE);
- DWORD written = 0;
- // get the cursor position
- CONSOLE_SCREEN_BUFFER_INFO info;
- GetConsoleScreenBufferInfo(hout, &info);
- // output this char
- WriteConsoleOutputCharacterA(hout, &_in, 1, info.dwCursorPosition, &written);
- // advance cursor position
- info.dwCursorPosition.X++;
- SetConsoleCursorPosition(hout, info.dwCursorPosition);
-}
-
-static void con_backspace(void) {
- HANDLE hout = GetStdHandle(STD_OUTPUT_HANDLE);
- DWORD written = 0;
- // get cursor position
- CONSOLE_SCREEN_BUFFER_INFO info;
- GetConsoleScreenBufferInfo(hout, &info);
- // nudge cursor backwards
- info.dwCursorPosition.X--;
- SetConsoleCursorPosition(hout, info.dwCursorPosition);
- // blank out the last character
- WriteConsoleOutputCharacterA(hout, " ", 1, info.dwCursorPosition, &written);
-}
-
-static void con_return(void) {
- HANDLE hout = GetStdHandle(STD_OUTPUT_HANDLE);
- DWORD written = 0;
- // get cursor position
- CONSOLE_SCREEN_BUFFER_INFO info;
- GetConsoleScreenBufferInfo(hout, &info);
- // move onto the new line
- info.dwCursorPosition.X = 0;
- info.dwCursorPosition.Y++;
- SetConsoleCursorPosition(hout, info.dwCursorPosition);
-}
-
-static bool runBind(char _key) {
- for (int i = 0; i < _bindings.size(); i++) {
- el_binding *bind = _bindings[i];
- if (bind->key[0] == _key) {
- bind->func((EditLine *)-1, _key);
- return true;
- }
- }
- return false;
-}
-
-// replacement get_s which is EL_BIND aware
-static char *el_get_s(char *buffer, int chars) {
- //
- char *head = buffer;
- //
- for (;; Sleep(10)) {
- //
- INPUT_RECORD _record;
- //
- DWORD _read = 0;
- if (ReadConsoleInputA(GetStdHandle(STD_INPUT_HANDLE), &_record, 1,
- &_read) == FALSE)
- break;
- // if we didn't read a key
- if (_read == 0)
- continue;
- // only interested in key events
- if (_record.EventType != KEY_EVENT)
- continue;
- // is the key down
- if (!_record.Event.KeyEvent.bKeyDown)
- continue;
- // read the ascii key character
- char _key = _record.Event.KeyEvent.uChar.AsciiChar;
- // non ascii conformant key press
- if (_key == 0) {
- // check the scan code
- // if VK_UP scroll back through history
- // if VK_DOWN scroll forward through history
- continue;
- }
- // try to execute any bind this key may have
- if (runBind(_key))
- continue;
- // if we read a return key
- if (_key == '\n' || _key == '\r') {
- con_return();
- break;
- }
- // key is backspace
- if (_key == 0x8) {
- // avoid deleting past beginning
- if (head > buffer) {
- con_backspace();
- head--;
- }
- continue;
- }
-
- // add this key to the input buffer
- if ((head - buffer) < (chars - 1)) {
- con_output(_key);
- *(head++) = _key;
- }
- }
- // insert end of line character
- *head = '\0';
-
- return buffer;
-}
-#endif
-
-// edit line initialize
-EditLine *el_init(const char *, FILE *, FILE *, FILE *) {
- //
- SetConsoleTitleA("lldb");
- // return dummy handle
- return (EditLine *)-1;
-}
-
-const char *el_gets(EditLine *el, int *length) {
- // print the prompt if we have one
- if (_prompt != NULL)
- printf("%s", _prompt);
- // create a buffer for the user input
- char *buffer = new char[MAX_PATH];
- // try to get user input string
- if (el_get_s(buffer, MAX_PATH)) {
- // get the string length in 'length'
- while (buffer[*length] != '\0')
- (*length)++;
- // return the input buffer
- // remember that this memory has the be free'd somewhere
- return buffer;
- } else {
- // on error
- delete[] buffer;
- return NULL;
- }
-}
-
-int el_set(EditLine *el, int code, ...) {
- va_list vl;
- va_start(vl, code);
- //
- switch (code) {
- // edit line set prompt message
- case (EL_PROMPT): {
- // EL_PROMPT, char *(*f)( EditLine *)
- // define a prompt printing function as 'f', which is to return a
- // string that
- // contains the prompt.
-
- // get the function pointer from the arg list
- void *func_vp = (void *)va_arg(vl, el_prompt_func);
- // cast to suitable prototype
- el_prompt_func func_fp = (el_prompt_func)func_vp;
- // call to get the prompt as a string
- _prompt = func_fp(el);
- } break;
-
- case (EL_PROMPT_ESC): {
- // EL_PROMPT, char *(*f)( EditLine *)
- // define a prompt printing function as 'f', which is to return a
- // string that
- // contains the prompt.
-
- // get the function pointer from the arg list
- void *func_vp = (void *)va_arg(vl, el_prompt_func);
- va_arg(vl, int);
- // call to get the prompt as a string
- el_prompt_func func_fp = (el_prompt_func)func_vp;
- _prompt = func_fp(el);
- } break;
-
- case (EL_EDITOR): {
- // EL_EDITOR, const char *mode
- // set editing mode to "emacs" or "vi"
- } break;
- case (EL_HIST): {
- // EL_HIST, History *(*fun)(History *, int op, ... ), const char *ptr
- // defines which history function to use, which is usually history().
- // Ptr should be the
- // value returned by history_init().
- } break;
- case (EL_ADDFN): {
- // EL_ADDFN, const char *name, const char *help, unsigned char
- // (*func)(EditLine *e, int ch)
- // add a user defined function, func), referred to as 'name' which is
- // invoked when a key which is bound to 'name' is
- // entered. 'help' is a description of 'name'. at invocation time, 'ch'
- // is the key which caused the invocation. the
- // return value of 'func()' should be one of:
- // CC_NORM add a normal character
- // CC_NEWLINE end of line was entered
- // CC_EOF EOF was entered
- // CC_ARGHACK expecting further command input as arguments, do
- // nothing visually.
- // CC_REFRESH refresh display.
- // CC_REFRESH_BEEP refresh display and beep.
- // CC_CURSOR cursor moved so update and perform CC_REFRESH
- // CC_REDISPLAY redisplay entire input line. this is useful
- // if a key binding outputs extra information.
- // CC_ERROR an error occurred. beep and flush tty.
- // CC_FATAL fatal error, reset tty to known state.
-
- el_binding *binding = new el_binding;
- binding->name = va_arg(vl, const char *);
- binding->help = va_arg(vl, const char *);
- binding->func = va_arg(vl, el_addfn_func);
- binding->key = 0;
- // add this to the bindings list
- _bindings.push_back(binding);
- } break;
- case (EL_BIND): {
- // EL_BIND, const char *, ..., NULL
- // perform the BIND built-in command. Refer to editrc(5) for more
- // information.
-
- const char *name = va_arg(vl, const char *);
-
- for (auto bind : _bindings) {
- if (strcmp(bind->name, name) == 0) {
- bind->key = va_arg(vl, const char *);
- break;
- }
- }
-
- } break;
- case (EL_CLIENTDATA): {
- clientData = va_arg(vl, void *);
- } break;
- }
- return 0;
-}
-
-void el_end(EditLine *el) {
- // assert( !"Not implemented!" );
-}
-
-void el_reset(EditLine *) { llvm_unreachable("Not implemented!"); }
-
-int el_getc(EditLine *, char *) {
- llvm_unreachable("Not implemented!");
-}
-
-void el_push(EditLine *, const char *) {}
-
-void el_beep(EditLine *) { Beep(1000, 500); }
-
-int el_parse(EditLine *, int, const char **) {
- llvm_unreachable("Not implemented!");
-}
-
-int el_get(EditLine *el, int code, ...) {
- va_list vl;
- va_start(vl, code);
-
- switch (code) {
- case (EL_CLIENTDATA): {
- void **dout = va_arg(vl, void **);
- *dout = clientData;
- } break;
- default:
- llvm_unreachable("Not implemented!");
- }
- return 0;
-}
-
-int el_source(EditLine *el, const char *file) {
- // init edit line by reading the contents of 'file' nothing to do here on
- // windows...
- return 0;
-}
-
-void el_resize(EditLine *) { llvm_unreachable("Not implemented!"); }
-
-const LineInfo *el_line(EditLine *el) { return 0; }
-
-int el_insertstr(EditLine *, const char *) {
- // assert( !"Not implemented!" );
- return 0;
-}
-
-void el_deletestr(EditLine *, int) { llvm_unreachable("Not implemented!"); }
-
-History *history_init(void) {
- // return dummy handle
- return (History *)-1;
-}
-
-void history_end(History *) {
- // assert( !"Not implemented!" );
-}
-
-int history(History *, HistEvent *, int op, ...) {
- // perform operation 'op' on the history list with optional arguments as
- // needed by the operation.
- return 0;
-}
-
-#endif
diff --git a/source/Host/windows/FileSystem.cpp b/source/Host/windows/FileSystem.cpp
deleted file mode 100644
index 3217cdc8480a..000000000000
--- a/source/Host/windows/FileSystem.cpp
+++ /dev/null
@@ -1,107 +0,0 @@
-//===-- FileSystem.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/windows/windows.h"
-
-#include <shellapi.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#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"
-
-using namespace lldb_private;
-
-const char *FileSystem::DEV_NULL = "nul";
-
-const char *FileSystem::PATH_CONVERSION_ERROR =
- "Error converting path between UTF-8 and native encoding";
-
-Status FileSystem::Symlink(const FileSpec &src, const FileSpec &dst) {
- Status error;
- std::wstring wsrc, wdst;
- if (!llvm::ConvertUTF8toWide(src.GetCString(), wsrc) ||
- !llvm::ConvertUTF8toWide(dst.GetCString(), wdst))
- error.SetErrorString(PATH_CONVERSION_ERROR);
- if (error.Fail())
- return error;
- DWORD attrib = ::GetFileAttributesW(wdst.c_str());
- if (attrib == INVALID_FILE_ATTRIBUTES) {
- error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
- return error;
- }
- bool is_directory = !!(attrib & FILE_ATTRIBUTE_DIRECTORY);
- DWORD flag = is_directory ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0;
- BOOL result = ::CreateSymbolicLinkW(wsrc.c_str(), wdst.c_str(), flag);
- if (!result)
- error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
- return error;
-}
-
-Status FileSystem::Readlink(const FileSpec &src, FileSpec &dst) {
- Status error;
- std::wstring wsrc;
- if (!llvm::ConvertUTF8toWide(src.GetCString(), wsrc)) {
- error.SetErrorString(PATH_CONVERSION_ERROR);
- return error;
- }
-
- HANDLE h = ::CreateFileW(wsrc.c_str(), GENERIC_READ,
- FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
- OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT, NULL);
- if (h == INVALID_HANDLE_VALUE) {
- error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
- return error;
- }
-
- std::vector<wchar_t> buf(PATH_MAX + 1);
- // Subtract 1 from the path length since this function does not add a null
- // terminator.
- DWORD result = ::GetFinalPathNameByHandleW(
- h, buf.data(), buf.size() - 1, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
- std::string path;
- if (result == 0)
- error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
- else if (!llvm::convertWideToUTF8(buf.data(), path))
- error.SetErrorString(PATH_CONVERSION_ERROR);
- else
- dst.SetFile(path, FileSpec::Style::native);
-
- ::CloseHandle(h);
- return error;
-}
-
-Status FileSystem::ResolveSymbolicLink(const FileSpec &src, FileSpec &dst) {
- return Status("ResolveSymbolicLink() isn't implemented on Windows");
-}
-
-FILE *FileSystem::Fopen(const char *path, const char *mode) {
- std::wstring wpath, wmode;
- if (!llvm::ConvertUTF8toWide(path, wpath))
- return nullptr;
- if (!llvm::ConvertUTF8toWide(mode, wmode))
- return nullptr;
- FILE *file;
- if (_wfopen_s(&file, wpath.c_str(), wmode.c_str()) != 0)
- return nullptr;
- return file;
-}
-
-int FileSystem::Open(const char *path, int flags, int mode) {
- std::wstring wpath;
- if (!llvm::ConvertUTF8toWide(path, wpath))
- return -1;
- int result;
- ::_wsopen_s(&result, wpath.c_str(), flags, _SH_DENYNO, mode);
- return result;
-}
diff --git a/source/Host/windows/Host.cpp b/source/Host/windows/Host.cpp
deleted file mode 100644
index 3ac16a42286a..000000000000
--- a/source/Host/windows/Host.cpp
+++ /dev/null
@@ -1,275 +0,0 @@
-//===-- source/Host/windows/Host.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/windows/AutoHandle.h"
-#include "lldb/Host/windows/windows.h"
-#include <stdio.h>
-
-#include "lldb/Host/FileSystem.h"
-#include "lldb/Host/Host.h"
-#include "lldb/Host/HostInfo.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Utility/DataBufferHeap.h"
-#include "lldb/Utility/DataExtractor.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/Status.h"
-#include "lldb/Utility/StructuredData.h"
-
-#include "llvm/Support/ConvertUTF.h"
-
-// Windows includes
-#include <tlhelp32.h>
-
-using namespace lldb;
-using namespace lldb_private;
-
-namespace {
-bool GetTripleForProcess(const FileSpec &executable, llvm::Triple &triple) {
- // Open the PE File as a binary file, and parse just enough information to
- // determine the machine type.
- File imageBinary;
- FileSystem::Instance().Open(imageBinary, executable, File::eOpenOptionRead,
- lldb::eFilePermissionsUserRead);
- imageBinary.SeekFromStart(0x3c);
- int32_t peOffset = 0;
- uint32_t peHead = 0;
- uint16_t machineType = 0;
- size_t readSize = sizeof(peOffset);
- imageBinary.Read(&peOffset, readSize);
- imageBinary.SeekFromStart(peOffset);
- imageBinary.Read(&peHead, readSize);
- if (peHead != 0x00004550) // "PE\0\0", little-endian
- return false; // Status: Can't find PE header
- readSize = 2;
- imageBinary.Read(&machineType, readSize);
- triple.setVendor(llvm::Triple::PC);
- triple.setOS(llvm::Triple::Win32);
- triple.setArch(llvm::Triple::UnknownArch);
- if (machineType == 0x8664)
- triple.setArch(llvm::Triple::x86_64);
- else if (machineType == 0x14c)
- triple.setArch(llvm::Triple::x86);
-
- return true;
-}
-
-bool GetExecutableForProcess(const AutoHandle &handle, std::string &path) {
- // Get the process image path. MAX_PATH isn't long enough, paths can
- // actually be up to 32KB.
- std::vector<wchar_t> buffer(PATH_MAX);
- DWORD dwSize = buffer.size();
- if (!::QueryFullProcessImageNameW(handle.get(), 0, &buffer[0], &dwSize))
- return false;
- return llvm::convertWideToUTF8(buffer.data(), path);
-}
-
-void GetProcessExecutableAndTriple(const AutoHandle &handle,
- ProcessInstanceInfo &process) {
- // We may not have permissions to read the path from the process. So start
- // off by setting the executable file to whatever Toolhelp32 gives us, and
- // then try to enhance this with more detailed information, but fail
- // gracefully.
- std::string executable;
- llvm::Triple triple;
- triple.setVendor(llvm::Triple::PC);
- triple.setOS(llvm::Triple::Win32);
- triple.setArch(llvm::Triple::UnknownArch);
- if (GetExecutableForProcess(handle, executable)) {
- FileSpec executableFile(executable.c_str());
- process.SetExecutableFile(executableFile, true);
- GetTripleForProcess(executableFile, triple);
- }
- process.SetArchitecture(ArchSpec(triple));
-
- // TODO(zturner): Add the ability to get the process user name.
-}
-}
-
-lldb::thread_t Host::GetCurrentThread() {
- return lldb::thread_t(::GetCurrentThread());
-}
-
-void Host::Kill(lldb::pid_t pid, int signo) {
- TerminateProcess((HANDLE)pid, 1);
-}
-
-const char *Host::GetSignalAsCString(int signo) { return NULL; }
-
-FileSpec Host::GetModuleFileSpecForHostAddress(const void *host_addr) {
- FileSpec module_filespec;
-
- HMODULE hmodule = NULL;
- if (!::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
- (LPCTSTR)host_addr, &hmodule))
- return module_filespec;
-
- std::vector<wchar_t> buffer(PATH_MAX);
- DWORD chars_copied = 0;
- do {
- chars_copied = ::GetModuleFileNameW(hmodule, &buffer[0], buffer.size());
- if (chars_copied == buffer.size() &&
- ::GetLastError() == ERROR_INSUFFICIENT_BUFFER)
- buffer.resize(buffer.size() * 2);
- } while (chars_copied >= buffer.size());
- std::string path;
- if (!llvm::convertWideToUTF8(buffer.data(), path))
- return module_filespec;
- module_filespec.SetFile(path, FileSpec::Style::native);
- return module_filespec;
-}
-
-uint32_t Host::FindProcesses(const ProcessInstanceInfoMatch &match_info,
- ProcessInstanceInfoList &process_infos) {
- process_infos.Clear();
-
- AutoHandle snapshot(CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0));
- if (!snapshot.IsValid())
- return 0;
-
- PROCESSENTRY32W pe = {};
- pe.dwSize = sizeof(PROCESSENTRY32W);
- if (Process32FirstW(snapshot.get(), &pe)) {
- do {
- AutoHandle handle(::OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE,
- pe.th32ProcessID),
- nullptr);
-
- ProcessInstanceInfo process;
- std::string exeFile;
- llvm::convertWideToUTF8(pe.szExeFile, exeFile);
- process.SetExecutableFile(FileSpec(exeFile), true);
- process.SetProcessID(pe.th32ProcessID);
- process.SetParentProcessID(pe.th32ParentProcessID);
- GetProcessExecutableAndTriple(handle, process);
-
- if (match_info.MatchAllProcesses() || match_info.Matches(process))
- process_infos.Append(process);
- } while (Process32NextW(snapshot.get(), &pe));
- }
- return process_infos.GetSize();
-}
-
-bool Host::GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &process_info) {
- process_info.Clear();
-
- AutoHandle handle(
- ::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid),
- nullptr);
- if (!handle.IsValid())
- return false;
-
- process_info.SetProcessID(pid);
- GetProcessExecutableAndTriple(handle, process_info);
-
- // Need to read the PEB to get parent process and command line arguments.
- return true;
-}
-
-HostThread Host::StartMonitoringChildProcess(
- const Host::MonitorChildProcessCallback &callback, lldb::pid_t pid,
- bool monitor_signals) {
- return HostThread();
-}
-
-Status Host::ShellExpandArguments(ProcessLaunchInfo &launch_info) {
- Status error;
- if (launch_info.GetFlags().Test(eLaunchFlagShellExpandArguments)) {
- FileSpec expand_tool_spec = HostInfo::GetSupportExeDir();
- if (!expand_tool_spec) {
- error.SetErrorString("could not find support executable directory for "
- "the lldb-argdumper tool");
- return error;
- }
- expand_tool_spec.AppendPathComponent("lldb-argdumper.exe");
- if (!FileSystem::Instance().Exists(expand_tool_spec)) {
- error.SetErrorString("could not find the lldb-argdumper tool");
- return error;
- }
-
- std::string quoted_cmd_string;
- launch_info.GetArguments().GetQuotedCommandString(quoted_cmd_string);
- std::replace(quoted_cmd_string.begin(), quoted_cmd_string.end(), '\\', '/');
- StreamString expand_command;
-
- expand_command.Printf("\"%s\" %s", expand_tool_spec.GetPath().c_str(),
- quoted_cmd_string.c_str());
-
- int status;
- std::string output;
- std::string command = expand_command.GetString();
- RunShellCommand(command.c_str(), launch_info.GetWorkingDirectory(), &status,
- nullptr, &output, std::chrono::seconds(10));
-
- if (status != 0) {
- error.SetErrorStringWithFormat("lldb-argdumper exited with error %d",
- status);
- return error;
- }
-
- auto data_sp = StructuredData::ParseJSON(output);
- if (!data_sp) {
- error.SetErrorString("invalid JSON");
- return error;
- }
-
- auto dict_sp = data_sp->GetAsDictionary();
- if (!data_sp) {
- error.SetErrorString("invalid JSON");
- return error;
- }
-
- auto args_sp = dict_sp->GetObjectForDotSeparatedPath("arguments");
- if (!args_sp) {
- error.SetErrorString("invalid JSON");
- return error;
- }
-
- auto args_array_sp = args_sp->GetAsArray();
- if (!args_array_sp) {
- error.SetErrorString("invalid JSON");
- return error;
- }
-
- launch_info.GetArguments().Clear();
-
- for (size_t i = 0; i < args_array_sp->GetSize(); i++) {
- auto item_sp = args_array_sp->GetItemAtIndex(i);
- if (!item_sp)
- continue;
- auto str_sp = item_sp->GetAsString();
- if (!str_sp)
- continue;
-
- launch_info.GetArguments().AppendArgument(str_sp->GetValue());
- }
- }
-
- return error;
-}
-
-Environment Host::GetEnvironment() {
- Environment env;
- // The environment block on Windows is a contiguous buffer of NULL terminated
- // strings, where the end of the environment block is indicated by two
- // consecutive NULLs.
- LPWCH environment_block = ::GetEnvironmentStringsW();
- while (*environment_block != L'\0') {
- std::string current_var;
- auto current_var_size = wcslen(environment_block) + 1;
- if (!llvm::convertWideToUTF8(environment_block, current_var)) {
- environment_block += current_var_size;
- continue;
- }
- if (current_var[0] != '=')
- env.insert(current_var);
-
- environment_block += current_var_size;
- }
- return env;
-}
diff --git a/source/Host/windows/HostInfoWindows.cpp b/source/Host/windows/HostInfoWindows.cpp
deleted file mode 100644
index 81392d9a85b3..000000000000
--- a/source/Host/windows/HostInfoWindows.cpp
+++ /dev/null
@@ -1,120 +0,0 @@
-//===-- HostInfoWindows.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/windows/windows.h"
-
-#include <objbase.h>
-
-#include <mutex>
-
-#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;
-
-FileSpec HostInfoWindows::m_program_filespec;
-
-void HostInfoWindows::Initialize() {
- ::CoInitializeEx(nullptr, COINIT_MULTITHREADED);
- HostInfoBase::Initialize();
-}
-
-void HostInfoWindows::Terminate() {
- HostInfoBase::Terminate();
- ::CoUninitialize();
-}
-
-size_t HostInfoWindows::GetPageSize() {
- SYSTEM_INFO systemInfo;
- GetNativeSystemInfo(&systemInfo);
- return systemInfo.dwPageSize;
-}
-
-llvm::VersionTuple HostInfoWindows::GetOSVersion() {
- OSVERSIONINFOEX info;
-
- ZeroMemory(&info, sizeof(OSVERSIONINFOEX));
- info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
-#pragma warning(push)
-#pragma warning(disable : 4996)
- // Starting with Microsoft SDK for Windows 8.1, this function is deprecated
- // in favor of the new Windows Version Helper APIs. Since we don't specify a
- // minimum SDK version, it's easier to simply disable the warning rather than
- // try to support both APIs.
- if (GetVersionEx((LPOSVERSIONINFO)&info) == 0)
- return llvm::VersionTuple();
-#pragma warning(pop)
-
- return llvm::VersionTuple(info.dwMajorVersion, info.dwMinorVersion,
- info.wServicePackMajor);
-}
-
-bool HostInfoWindows::GetOSBuildString(std::string &s) {
- s.clear();
- llvm::VersionTuple version = GetOSVersion();
- if (version.empty())
- return false;
-
- llvm::raw_string_ostream stream(s);
- stream << "Windows NT " << version.getAsString();
- return true;
-}
-
-bool HostInfoWindows::GetOSKernelDescription(std::string &s) {
- return GetOSBuildString(s);
-}
-
-bool HostInfoWindows::GetHostname(std::string &s) {
- wchar_t buffer[MAX_COMPUTERNAME_LENGTH + 1];
- DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
- if (!::GetComputerNameW(buffer, &dwSize))
- return false;
-
- return llvm::convertWideToUTF8(buffer, s);
-}
-
-FileSpec HostInfoWindows::GetProgramFileSpec() {
- 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;
- llvm::convertWideToUTF8(buffer.data(), path);
- m_program_filespec.SetFile(path, FileSpec::Style::native);
- });
- return m_program_filespec;
-}
-
-FileSpec HostInfoWindows::GetDefaultShell() {
- // Try to retrieve ComSpec from the environment. On the rare occasion
- // that it fails, try a well-known path for ComSpec instead.
-
- std::string shell;
- if (GetEnvironmentVar("ComSpec", shell))
- return FileSpec(shell);
-
- return FileSpec("C:\\Windows\\system32\\cmd.exe");
-}
-
-bool HostInfoWindows::GetEnvironmentVar(const std::string &var_name,
- std::string &var) {
- std::wstring wvar_name;
- if (!llvm::ConvertUTF8toWide(var_name, wvar_name))
- return false;
-
- if (const wchar_t *wvar = _wgetenv(wvar_name.c_str()))
- return llvm::convertWideToUTF8(wvar, var);
- return false;
-}
diff --git a/source/Host/windows/HostProcessWindows.cpp b/source/Host/windows/HostProcessWindows.cpp
deleted file mode 100644
index 701167ff6fea..000000000000
--- a/source/Host/windows/HostProcessWindows.cpp
+++ /dev/null
@@ -1,120 +0,0 @@
-//===-- HostProcessWindows.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/windows/HostProcessWindows.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"
-
-#include <psapi.h>
-
-using namespace lldb_private;
-
-namespace {
-struct MonitorInfo {
- Host::MonitorChildProcessCallback callback;
- HANDLE process_handle;
-};
-}
-
-HostProcessWindows::HostProcessWindows()
- : HostNativeProcessBase(), m_owns_handle(true) {}
-
-HostProcessWindows::HostProcessWindows(lldb::process_t process)
- : HostNativeProcessBase(process), m_owns_handle(true) {}
-
-HostProcessWindows::~HostProcessWindows() { Close(); }
-
-void HostProcessWindows::SetOwnsHandle(bool owns) { m_owns_handle = owns; }
-
-Status HostProcessWindows::Terminate() {
- Status error;
- if (m_process == nullptr)
- error.SetError(ERROR_INVALID_HANDLE, lldb::eErrorTypeWin32);
-
- if (!::TerminateProcess(m_process, 0))
- error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
-
- return error;
-}
-
-Status HostProcessWindows::GetMainModule(FileSpec &file_spec) const {
- Status error;
- if (m_process == nullptr)
- error.SetError(ERROR_INVALID_HANDLE, lldb::eErrorTypeWin32);
-
- std::vector<wchar_t> wpath(PATH_MAX);
- if (::GetProcessImageFileNameW(m_process, wpath.data(), wpath.size())) {
- std::string path;
- if (llvm::convertWideToUTF8(wpath.data(), path))
- file_spec.SetFile(path, FileSpec::Style::native);
- else
- error.SetErrorString("Error converting path to UTF-8");
- } else
- error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
-
- return error;
-}
-
-lldb::pid_t HostProcessWindows::GetProcessId() const {
- return (m_process == LLDB_INVALID_PROCESS) ? -1 : ::GetProcessId(m_process);
-}
-
-bool HostProcessWindows::IsRunning() const {
- if (m_process == nullptr)
- return false;
-
- DWORD code = 0;
- if (!::GetExitCodeProcess(m_process, &code))
- return false;
-
- return (code == STILL_ACTIVE);
-}
-
-HostThread HostProcessWindows::StartMonitoring(
- const Host::MonitorChildProcessCallback &callback, bool monitor_signals) {
- HostThread monitor_thread;
- MonitorInfo *info = new MonitorInfo;
- info->callback = callback;
-
- // Since the life of this HostProcessWindows instance and the life of the
- // process may be different, duplicate the handle so that the monitor thread
- // can have ownership over its own copy of the handle.
- HostThread result;
- if (::DuplicateHandle(GetCurrentProcess(), m_process, GetCurrentProcess(),
- &info->process_handle, 0, FALSE, DUPLICATE_SAME_ACCESS))
- result = ThreadLauncher::LaunchThread("ChildProcessMonitor",
- HostProcessWindows::MonitorThread,
- info, nullptr);
- return result;
-}
-
-lldb::thread_result_t HostProcessWindows::MonitorThread(void *thread_arg) {
- DWORD exit_code;
-
- MonitorInfo *info = static_cast<MonitorInfo *>(thread_arg);
- if (info) {
- ::WaitForSingleObject(info->process_handle, INFINITE);
- ::GetExitCodeProcess(info->process_handle, &exit_code);
- info->callback(::GetProcessId(info->process_handle), true, 0, exit_code);
- ::CloseHandle(info->process_handle);
- delete (info);
- }
- return 0;
-}
-
-void HostProcessWindows::Close() {
- if (m_owns_handle && m_process != LLDB_INVALID_PROCESS)
- ::CloseHandle(m_process);
- m_process = nullptr;
-}
diff --git a/source/Host/windows/HostThreadWindows.cpp b/source/Host/windows/HostThreadWindows.cpp
deleted file mode 100644
index b516230e7fa4..000000000000
--- a/source/Host/windows/HostThreadWindows.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-//===-- HostThreadWindows.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/Utility/Status.h"
-
-#include "lldb/Host/windows/HostThreadWindows.h"
-#include "lldb/Host/windows/windows.h"
-
-#include "llvm/ADT/STLExtras.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-namespace {
-void __stdcall ExitThreadProxy(ULONG_PTR dwExitCode) {
- ::ExitThread(dwExitCode);
-}
-}
-
-HostThreadWindows::HostThreadWindows()
- : HostNativeThreadBase(), m_owns_handle(true) {}
-
-HostThreadWindows::HostThreadWindows(lldb::thread_t thread)
- : HostNativeThreadBase(thread), m_owns_handle(true) {}
-
-HostThreadWindows::~HostThreadWindows() { Reset(); }
-
-void HostThreadWindows::SetOwnsHandle(bool owns) { m_owns_handle = owns; }
-
-Status HostThreadWindows::Join(lldb::thread_result_t *result) {
- Status error;
- if (IsJoinable()) {
- DWORD wait_result = ::WaitForSingleObject(m_thread, INFINITE);
- if (WAIT_OBJECT_0 == wait_result && result) {
- DWORD exit_code = 0;
- if (!::GetExitCodeThread(m_thread, &exit_code))
- *result = 0;
- *result = exit_code;
- } else if (WAIT_OBJECT_0 != wait_result)
- error.SetError(::GetLastError(), eErrorTypeWin32);
- } else
- error.SetError(ERROR_INVALID_HANDLE, eErrorTypeWin32);
-
- Reset();
- return error;
-}
-
-Status HostThreadWindows::Cancel() {
- Status error;
-
- DWORD result = ::QueueUserAPC(::ExitThreadProxy, m_thread, 0);
- error.SetError(result, eErrorTypeWin32);
- return error;
-}
-
-lldb::tid_t HostThreadWindows::GetThreadId() const {
- return ::GetThreadId(m_thread);
-}
-
-void HostThreadWindows::Reset() {
- if (m_owns_handle && m_thread != LLDB_INVALID_HOST_THREAD)
- ::CloseHandle(m_thread);
-
- HostNativeThreadBase::Reset();
-}
-
-bool HostThreadWindows::EqualsThread(lldb::thread_t thread) const {
- return GetThreadId() == ::GetThreadId(thread);
-}
diff --git a/source/Host/windows/LockFileWindows.cpp b/source/Host/windows/LockFileWindows.cpp
deleted file mode 100644
index 2178fd1f5f6c..000000000000
--- a/source/Host/windows/LockFileWindows.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-//===-- LockFileWindows.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/windows/LockFileWindows.h"
-
-#include <io.h>
-
-using namespace lldb;
-using namespace lldb_private;
-
-namespace {
-
-Status fileLock(HANDLE file_handle, DWORD flags, const uint64_t start,
- const uint64_t len) {
- if (start != 0)
- return Status("Non-zero start lock regions are not supported");
-
- OVERLAPPED overlapped = {};
-
- if (!::LockFileEx(file_handle, flags, 0, len, 0, &overlapped) &&
- ::GetLastError() != ERROR_IO_PENDING)
- return Status(::GetLastError(), eErrorTypeWin32);
-
- DWORD bytes;
- if (!::GetOverlappedResult(file_handle, &overlapped, &bytes, TRUE))
- return Status(::GetLastError(), eErrorTypeWin32);
-
- return Status();
-}
-
-} // namespace
-
-LockFileWindows::LockFileWindows(int fd)
- : LockFileBase(fd), m_file(reinterpret_cast<HANDLE>(_get_osfhandle(fd))) {}
-
-LockFileWindows::~LockFileWindows() { Unlock(); }
-
-bool LockFileWindows::IsValidFile() const {
- return LockFileBase::IsValidFile() && m_file != INVALID_HANDLE_VALUE;
-}
-
-Status LockFileWindows::DoWriteLock(const uint64_t start, const uint64_t len) {
- return fileLock(m_file, LOCKFILE_EXCLUSIVE_LOCK, start, len);
-}
-
-Status LockFileWindows::DoTryWriteLock(const uint64_t start,
- const uint64_t len) {
- return fileLock(m_file, LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY,
- start, len);
-}
-
-Status LockFileWindows::DoReadLock(const uint64_t start, const uint64_t len) {
- return fileLock(m_file, 0, start, len);
-}
-
-Status LockFileWindows::DoTryReadLock(const uint64_t start,
- const uint64_t len) {
- return fileLock(m_file, LOCKFILE_FAIL_IMMEDIATELY, start, len);
-}
-
-Status LockFileWindows::DoUnlock() {
- OVERLAPPED overlapped = {};
-
- if (!::UnlockFileEx(m_file, 0, m_len, 0, &overlapped) &&
- ::GetLastError() != ERROR_IO_PENDING)
- return Status(::GetLastError(), eErrorTypeWin32);
-
- DWORD bytes;
- if (!::GetOverlappedResult(m_file, &overlapped, &bytes, TRUE))
- return Status(::GetLastError(), eErrorTypeWin32);
-
- return Status();
-}
diff --git a/source/Host/windows/PipeWindows.cpp b/source/Host/windows/PipeWindows.cpp
deleted file mode 100644
index 57221a72899c..000000000000
--- a/source/Host/windows/PipeWindows.cpp
+++ /dev/null
@@ -1,339 +0,0 @@
-//===-- PipeWindows.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/windows/PipeWindows.h"
-
-#include "llvm/ADT/SmallString.h"
-#include "llvm/Support/Process.h"
-#include "llvm/Support/raw_ostream.h"
-
-#include <fcntl.h>
-#include <io.h>
-#include <rpc.h>
-
-#include <atomic>
-#include <string>
-
-using namespace lldb;
-using namespace lldb_private;
-
-namespace {
-std::atomic<uint32_t> g_pipe_serial(0);
-constexpr llvm::StringLiteral g_pipe_name_prefix = "\\\\.\\Pipe\\";
-} // namespace
-
-PipeWindows::PipeWindows()
- : m_read(INVALID_HANDLE_VALUE), m_write(INVALID_HANDLE_VALUE),
- m_read_fd(PipeWindows::kInvalidDescriptor),
- m_write_fd(PipeWindows::kInvalidDescriptor) {
- ZeroMemory(&m_read_overlapped, sizeof(m_read_overlapped));
- ZeroMemory(&m_write_overlapped, sizeof(m_write_overlapped));
-}
-
-PipeWindows::PipeWindows(pipe_t read, pipe_t write)
- : m_read((HANDLE)read), m_write((HANDLE)write),
- m_read_fd(PipeWindows::kInvalidDescriptor),
- m_write_fd(PipeWindows::kInvalidDescriptor) {
- assert(read != LLDB_INVALID_PIPE || write != LLDB_INVALID_PIPE);
-
- // Don't risk in passing file descriptors and getting handles from them by
- // _get_osfhandle since the retrieved handles are highly likely unrecognized
- // in the current process and usually crashes the program. Pass handles
- // instead since the handle can be inherited.
-
- if (read != LLDB_INVALID_PIPE) {
- m_read_fd = _open_osfhandle((intptr_t)read, _O_RDONLY);
- // Make sure the fd and native handle are consistent.
- if (m_read_fd < 0)
- m_read = INVALID_HANDLE_VALUE;
- }
-
- if (write != LLDB_INVALID_PIPE) {
- m_write_fd = _open_osfhandle((intptr_t)write, _O_WRONLY);
- if (m_write_fd < 0)
- m_write = INVALID_HANDLE_VALUE;
- }
-
- ZeroMemory(&m_read_overlapped, sizeof(m_read_overlapped));
- ZeroMemory(&m_write_overlapped, sizeof(m_write_overlapped));
-}
-
-PipeWindows::~PipeWindows() { Close(); }
-
-Status PipeWindows::CreateNew(bool child_process_inherit) {
- // Create an anonymous pipe with the specified inheritance.
- SECURITY_ATTRIBUTES sa{sizeof(SECURITY_ATTRIBUTES), 0,
- child_process_inherit ? TRUE : FALSE};
- BOOL result = ::CreatePipe(&m_read, &m_write, &sa, 1024);
- if (result == FALSE)
- return Status(::GetLastError(), eErrorTypeWin32);
-
- m_read_fd = _open_osfhandle((intptr_t)m_read, _O_RDONLY);
- ZeroMemory(&m_read_overlapped, sizeof(m_read_overlapped));
- m_read_overlapped.hEvent = ::CreateEventA(nullptr, TRUE, FALSE, nullptr);
-
- m_write_fd = _open_osfhandle((intptr_t)m_write, _O_WRONLY);
- ZeroMemory(&m_write_overlapped, sizeof(m_write_overlapped));
-
- return Status();
-}
-
-Status PipeWindows::CreateNewNamed(bool child_process_inherit) {
- // Even for anonymous pipes, we open a named pipe. This is because you
- // cannot get overlapped i/o on Windows without using a named pipe. So we
- // synthesize a unique name.
- uint32_t serial = g_pipe_serial.fetch_add(1);
- std::string pipe_name;
- llvm::raw_string_ostream pipe_name_stream(pipe_name);
- pipe_name_stream << "lldb.pipe." << ::GetCurrentProcessId() << "." << serial;
- pipe_name_stream.flush();
-
- return CreateNew(pipe_name.c_str(), child_process_inherit);
-}
-
-Status PipeWindows::CreateNew(llvm::StringRef name,
- bool child_process_inherit) {
- if (name.empty())
- return Status(ERROR_INVALID_PARAMETER, eErrorTypeWin32);
-
- if (CanRead() || CanWrite())
- return Status(ERROR_ALREADY_EXISTS, eErrorTypeWin32);
-
- std::string pipe_path = g_pipe_name_prefix;
- pipe_path.append(name);
-
- // Always open for overlapped i/o. We implement blocking manually in Read
- // and Write.
- DWORD read_mode = FILE_FLAG_OVERLAPPED;
- m_read = ::CreateNamedPipeA(
- pipe_path.c_str(), PIPE_ACCESS_INBOUND | read_mode,
- PIPE_TYPE_BYTE | PIPE_WAIT, 1, 1024, 1024, 120 * 1000, NULL);
- if (INVALID_HANDLE_VALUE == m_read)
- return Status(::GetLastError(), eErrorTypeWin32);
- m_read_fd = _open_osfhandle((intptr_t)m_read, _O_RDONLY);
- ZeroMemory(&m_read_overlapped, sizeof(m_read_overlapped));
- m_read_overlapped.hEvent = ::CreateEvent(nullptr, TRUE, FALSE, nullptr);
-
- // Open the write end of the pipe. Note that closing either the read or
- // write end of the pipe could directly close the pipe itself.
- Status result = OpenNamedPipe(name, child_process_inherit, false);
- if (!result.Success()) {
- CloseReadFileDescriptor();
- return result;
- }
-
- return result;
-}
-
-Status PipeWindows::CreateWithUniqueName(llvm::StringRef prefix,
- bool child_process_inherit,
- llvm::SmallVectorImpl<char> &name) {
- llvm::SmallString<128> pipe_name;
- Status error;
- ::UUID unique_id;
- RPC_CSTR unique_string;
- RPC_STATUS status = ::UuidCreate(&unique_id);
- if (status == RPC_S_OK || status == RPC_S_UUID_LOCAL_ONLY)
- status = ::UuidToStringA(&unique_id, &unique_string);
- if (status == RPC_S_OK) {
- pipe_name = prefix;
- pipe_name += "-";
- pipe_name += reinterpret_cast<char *>(unique_string);
- ::RpcStringFreeA(&unique_string);
- error = CreateNew(pipe_name, child_process_inherit);
- } else {
- error.SetError(status, eErrorTypeWin32);
- }
- if (error.Success())
- name = pipe_name;
- return error;
-}
-
-Status PipeWindows::OpenAsReader(llvm::StringRef name,
- bool child_process_inherit) {
- if (CanRead())
- return Status(ERROR_ALREADY_EXISTS, eErrorTypeWin32);
-
- return OpenNamedPipe(name, child_process_inherit, true);
-}
-
-Status
-PipeWindows::OpenAsWriterWithTimeout(llvm::StringRef name,
- bool child_process_inherit,
- const std::chrono::microseconds &timeout) {
- if (CanWrite())
- return Status(ERROR_ALREADY_EXISTS, eErrorTypeWin32);
-
- return OpenNamedPipe(name, child_process_inherit, false);
-}
-
-Status PipeWindows::OpenNamedPipe(llvm::StringRef name,
- bool child_process_inherit, bool is_read) {
- if (name.empty())
- return Status(ERROR_INVALID_PARAMETER, eErrorTypeWin32);
-
- assert(is_read ? !CanRead() : !CanWrite());
-
- SECURITY_ATTRIBUTES attributes = {};
- attributes.bInheritHandle = child_process_inherit;
-
- std::string pipe_path = g_pipe_name_prefix;
- pipe_path.append(name);
-
- if (is_read) {
- m_read = ::CreateFileA(pipe_path.c_str(), GENERIC_READ, 0, &attributes,
- OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
- if (INVALID_HANDLE_VALUE == m_read)
- return Status(::GetLastError(), eErrorTypeWin32);
-
- m_read_fd = _open_osfhandle((intptr_t)m_read, _O_RDONLY);
-
- ZeroMemory(&m_read_overlapped, sizeof(m_read_overlapped));
- m_read_overlapped.hEvent = ::CreateEvent(nullptr, TRUE, FALSE, nullptr);
- } else {
- m_write = ::CreateFileA(pipe_path.c_str(), GENERIC_WRITE, 0, &attributes,
- OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
- if (INVALID_HANDLE_VALUE == m_write)
- return Status(::GetLastError(), eErrorTypeWin32);
-
- m_write_fd = _open_osfhandle((intptr_t)m_write, _O_WRONLY);
-
- ZeroMemory(&m_write_overlapped, sizeof(m_write_overlapped));
- }
-
- return Status();
-}
-
-int PipeWindows::GetReadFileDescriptor() const { return m_read_fd; }
-
-int PipeWindows::GetWriteFileDescriptor() const { return m_write_fd; }
-
-int PipeWindows::ReleaseReadFileDescriptor() {
- if (!CanRead())
- return PipeWindows::kInvalidDescriptor;
- int result = m_read_fd;
- m_read_fd = PipeWindows::kInvalidDescriptor;
- if (m_read_overlapped.hEvent)
- ::CloseHandle(m_read_overlapped.hEvent);
- m_read = INVALID_HANDLE_VALUE;
- ZeroMemory(&m_read_overlapped, sizeof(m_read_overlapped));
- return result;
-}
-
-int PipeWindows::ReleaseWriteFileDescriptor() {
- if (!CanWrite())
- return PipeWindows::kInvalidDescriptor;
- int result = m_write_fd;
- m_write_fd = PipeWindows::kInvalidDescriptor;
- m_write = INVALID_HANDLE_VALUE;
- ZeroMemory(&m_write_overlapped, sizeof(m_write_overlapped));
- return result;
-}
-
-void PipeWindows::CloseReadFileDescriptor() {
- if (!CanRead())
- return;
-
- if (m_read_overlapped.hEvent)
- ::CloseHandle(m_read_overlapped.hEvent);
-
- _close(m_read_fd);
- m_read = INVALID_HANDLE_VALUE;
- m_read_fd = PipeWindows::kInvalidDescriptor;
- ZeroMemory(&m_read_overlapped, sizeof(m_read_overlapped));
-}
-
-void PipeWindows::CloseWriteFileDescriptor() {
- if (!CanWrite())
- return;
-
- _close(m_write_fd);
- m_write = INVALID_HANDLE_VALUE;
- m_write_fd = PipeWindows::kInvalidDescriptor;
- ZeroMemory(&m_write_overlapped, sizeof(m_write_overlapped));
-}
-
-void PipeWindows::Close() {
- CloseReadFileDescriptor();
- CloseWriteFileDescriptor();
-}
-
-Status PipeWindows::Delete(llvm::StringRef name) { return Status(); }
-
-bool PipeWindows::CanRead() const { return (m_read != INVALID_HANDLE_VALUE); }
-
-bool PipeWindows::CanWrite() const { return (m_write != INVALID_HANDLE_VALUE); }
-
-HANDLE
-PipeWindows::GetReadNativeHandle() { return m_read; }
-
-HANDLE
-PipeWindows::GetWriteNativeHandle() { return m_write; }
-
-Status PipeWindows::ReadWithTimeout(void *buf, size_t size,
- const std::chrono::microseconds &duration,
- size_t &bytes_read) {
- if (!CanRead())
- return Status(ERROR_INVALID_HANDLE, eErrorTypeWin32);
-
- bytes_read = 0;
- DWORD sys_bytes_read = size;
- BOOL result = ::ReadFile(m_read, buf, sys_bytes_read, &sys_bytes_read,
- &m_read_overlapped);
- if (!result && GetLastError() != ERROR_IO_PENDING)
- return Status(::GetLastError(), eErrorTypeWin32);
-
- DWORD timeout = (duration == std::chrono::microseconds::zero())
- ? INFINITE
- : duration.count() * 1000;
- DWORD wait_result = ::WaitForSingleObject(m_read_overlapped.hEvent, timeout);
- if (wait_result != WAIT_OBJECT_0) {
- // The operation probably failed. However, if it timed out, we need to
- // cancel the I/O. Between the time we returned from WaitForSingleObject
- // and the time we call CancelIoEx, the operation may complete. If that
- // hapens, CancelIoEx will fail and return ERROR_NOT_FOUND. If that
- // happens, the original operation should be considered to have been
- // successful.
- bool failed = true;
- DWORD failure_error = ::GetLastError();
- if (wait_result == WAIT_TIMEOUT) {
- BOOL cancel_result = CancelIoEx(m_read, &m_read_overlapped);
- if (!cancel_result && GetLastError() == ERROR_NOT_FOUND)
- failed = false;
- }
- if (failed)
- return Status(failure_error, eErrorTypeWin32);
- }
-
- // Now we call GetOverlappedResult setting bWait to false, since we've
- // already waited as long as we're willing to.
- if (!GetOverlappedResult(m_read, &m_read_overlapped, &sys_bytes_read, FALSE))
- return Status(::GetLastError(), eErrorTypeWin32);
-
- bytes_read = sys_bytes_read;
- return Status();
-}
-
-Status PipeWindows::Write(const void *buf, size_t num_bytes,
- size_t &bytes_written) {
- if (!CanWrite())
- return Status(ERROR_INVALID_HANDLE, eErrorTypeWin32);
-
- DWORD sys_bytes_written = 0;
- BOOL write_result = ::WriteFile(m_write, buf, num_bytes, &sys_bytes_written,
- &m_write_overlapped);
- if (!write_result && GetLastError() != ERROR_IO_PENDING)
- return Status(::GetLastError(), eErrorTypeWin32);
-
- BOOL result = GetOverlappedResult(m_write, &m_write_overlapped,
- &sys_bytes_written, TRUE);
- if (!result)
- return Status(::GetLastError(), eErrorTypeWin32);
- return Status();
-}
diff --git a/source/Host/windows/ProcessLauncherWindows.cpp b/source/Host/windows/ProcessLauncherWindows.cpp
deleted file mode 100644
index a186c7177fdf..000000000000
--- a/source/Host/windows/ProcessLauncherWindows.cpp
+++ /dev/null
@@ -1,159 +0,0 @@
-//===-- ProcessLauncherWindows.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/windows/ProcessLauncherWindows.h"
-#include "lldb/Host/HostProcess.h"
-#include "lldb/Target/ProcessLaunchInfo.h"
-
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/Support/ConvertUTF.h"
-
-#include <string>
-#include <vector>
-
-using namespace lldb;
-using namespace lldb_private;
-
-namespace {
-void CreateEnvironmentBuffer(const Environment &env,
- std::vector<char> &buffer) {
- if (env.size() == 0)
- return;
-
- // Environment buffer is a null terminated list of null terminated strings
- for (const auto &KV : env) {
- std::wstring warg;
- if (llvm::ConvertUTF8toWide(Environment::compose(KV), warg)) {
- buffer.insert(buffer.end(), (char *)warg.c_str(),
- (char *)(warg.c_str() + warg.size() + 1));
- }
- }
- // One null wchar_t (to end the block) is two null bytes
- buffer.push_back(0);
- buffer.push_back(0);
-}
-}
-
-HostProcess
-ProcessLauncherWindows::LaunchProcess(const ProcessLaunchInfo &launch_info,
- Status &error) {
- error.Clear();
-
- std::string executable;
- std::string commandLine;
- std::vector<char> environment;
- STARTUPINFO startupinfo = {};
- PROCESS_INFORMATION pi = {};
-
- HANDLE stdin_handle = GetStdioHandle(launch_info, STDIN_FILENO);
- HANDLE stdout_handle = GetStdioHandle(launch_info, STDOUT_FILENO);
- HANDLE stderr_handle = GetStdioHandle(launch_info, STDERR_FILENO);
-
- startupinfo.cb = sizeof(startupinfo);
- startupinfo.dwFlags |= STARTF_USESTDHANDLES;
- startupinfo.hStdError =
- stderr_handle ? stderr_handle : ::GetStdHandle(STD_ERROR_HANDLE);
- startupinfo.hStdInput =
- stdin_handle ? stdin_handle : ::GetStdHandle(STD_INPUT_HANDLE);
- startupinfo.hStdOutput =
- stdout_handle ? stdout_handle : ::GetStdHandle(STD_OUTPUT_HANDLE);
-
- const char *hide_console_var =
- getenv("LLDB_LAUNCH_INFERIORS_WITHOUT_CONSOLE");
- if (hide_console_var &&
- llvm::StringRef(hide_console_var).equals_lower("true")) {
- startupinfo.dwFlags |= STARTF_USESHOWWINDOW;
- startupinfo.wShowWindow = SW_HIDE;
- }
-
- DWORD flags = CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT;
- if (launch_info.GetFlags().Test(eLaunchFlagDebug))
- flags |= DEBUG_ONLY_THIS_PROCESS;
-
- if (launch_info.GetFlags().Test(eLaunchFlagDisableSTDIO))
- flags &= ~CREATE_NEW_CONSOLE;
-
- LPVOID env_block = nullptr;
- ::CreateEnvironmentBuffer(launch_info.GetEnvironment(), environment);
- if (!environment.empty())
- env_block = environment.data();
-
- executable = launch_info.GetExecutableFile().GetPath();
- launch_info.GetArguments().GetQuotedCommandString(commandLine);
-
- std::wstring wexecutable, wcommandLine, wworkingDirectory;
- llvm::ConvertUTF8toWide(executable, wexecutable);
- llvm::ConvertUTF8toWide(commandLine, wcommandLine);
- llvm::ConvertUTF8toWide(launch_info.GetWorkingDirectory().GetCString(),
- wworkingDirectory);
-
- wcommandLine.resize(PATH_MAX); // Needs to be over-allocated because
- // CreateProcessW can modify it
- BOOL result = ::CreateProcessW(
- wexecutable.c_str(), &wcommandLine[0], NULL, NULL, TRUE, flags, env_block,
- wworkingDirectory.size() == 0 ? NULL : wworkingDirectory.c_str(),
- &startupinfo, &pi);
-
- if (!result) {
- // Call GetLastError before we make any other system calls.
- error.SetError(::GetLastError(), eErrorTypeWin32);
- }
-
- if (result) {
- // Do not call CloseHandle on pi.hProcess, since we want to pass that back
- // through the HostProcess.
- ::CloseHandle(pi.hThread);
- }
-
- if (stdin_handle)
- ::CloseHandle(stdin_handle);
- if (stdout_handle)
- ::CloseHandle(stdout_handle);
- if (stderr_handle)
- ::CloseHandle(stderr_handle);
-
- if (!result)
- return HostProcess();
-
- return HostProcess(pi.hProcess);
-}
-
-HANDLE
-ProcessLauncherWindows::GetStdioHandle(const ProcessLaunchInfo &launch_info,
- int fd) {
- const FileAction *action = launch_info.GetFileActionForFD(fd);
- if (action == nullptr)
- return NULL;
- SECURITY_ATTRIBUTES secattr = {};
- secattr.nLength = sizeof(SECURITY_ATTRIBUTES);
- secattr.bInheritHandle = TRUE;
-
- llvm::StringRef path = action->GetPath();
- DWORD access = 0;
- DWORD share = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
- DWORD create = 0;
- DWORD flags = 0;
- if (fd == STDIN_FILENO) {
- access = GENERIC_READ;
- create = OPEN_EXISTING;
- flags = FILE_ATTRIBUTE_READONLY;
- }
- if (fd == STDOUT_FILENO || fd == STDERR_FILENO) {
- access = GENERIC_WRITE;
- create = CREATE_ALWAYS;
- if (fd == STDERR_FILENO)
- flags = FILE_FLAG_WRITE_THROUGH;
- }
-
- std::wstring wpath;
- llvm::ConvertUTF8toWide(path, wpath);
- HANDLE result = ::CreateFileW(wpath.c_str(), access, share, &secattr, create,
- flags, NULL);
- return (result == INVALID_HANDLE_VALUE) ? NULL : result;
-}
diff --git a/source/Host/windows/ProcessRunLock.cpp b/source/Host/windows/ProcessRunLock.cpp
deleted file mode 100644
index 64276917fc81..000000000000
--- a/source/Host/windows/ProcessRunLock.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-//===-- ProcessRunLock.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/ProcessRunLock.h"
-#include "lldb/Host/windows/windows.h"
-
-static PSRWLOCK GetLock(lldb::rwlock_t lock) {
- return static_cast<PSRWLOCK>(lock);
-}
-
-static bool ReadLock(lldb::rwlock_t rwlock) {
- ::AcquireSRWLockShared(GetLock(rwlock));
- return true;
-}
-
-static bool ReadUnlock(lldb::rwlock_t rwlock) {
- ::ReleaseSRWLockShared(GetLock(rwlock));
- return true;
-}
-
-static bool WriteLock(lldb::rwlock_t rwlock) {
- ::AcquireSRWLockExclusive(GetLock(rwlock));
- return true;
-}
-
-static bool WriteTryLock(lldb::rwlock_t rwlock) {
- return !!::TryAcquireSRWLockExclusive(GetLock(rwlock));
-}
-
-static bool WriteUnlock(lldb::rwlock_t rwlock) {
- ::ReleaseSRWLockExclusive(GetLock(rwlock));
- return true;
-}
-
-using namespace lldb_private;
-
-ProcessRunLock::ProcessRunLock() : m_running(false) {
- m_rwlock = new SRWLOCK;
- InitializeSRWLock(GetLock(m_rwlock));
-}
-
-ProcessRunLock::~ProcessRunLock() { delete static_cast<SRWLOCK *>(m_rwlock); }
-
-bool ProcessRunLock::ReadTryLock() {
- ::ReadLock(m_rwlock);
- if (m_running == false)
- return true;
- ::ReadUnlock(m_rwlock);
- return false;
-}
-
-bool ProcessRunLock::ReadUnlock() { return ::ReadUnlock(m_rwlock); }
-
-bool ProcessRunLock::SetRunning() {
- WriteLock(m_rwlock);
- m_running = true;
- WriteUnlock(m_rwlock);
- return true;
-}
-
-bool ProcessRunLock::TrySetRunning() {
- if (WriteTryLock(m_rwlock)) {
- bool was_running = m_running;
- m_running = true;
- WriteUnlock(m_rwlock);
- return !was_running;
- }
- return false;
-}
-
-bool ProcessRunLock::SetStopped() {
- WriteLock(m_rwlock);
- m_running = false;
- WriteUnlock(m_rwlock);
- return true;
-}
diff --git a/source/Host/windows/Windows.cpp b/source/Host/windows/Windows.cpp
deleted file mode 100644
index 9d0e70e6d126..000000000000
--- a/source/Host/windows/Windows.cpp
+++ /dev/null
@@ -1,231 +0,0 @@
-//===-- Windows.cpp ---------------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// This file provides Windows support functions
-
-#include "lldb/Host/PosixApi.h"
-#include "lldb/Host/windows/windows.h"
-
-#include "llvm/Support/ConvertUTF.h"
-
-#include <assert.h>
-#include <cerrno>
-#include <ctype.h>
-#include <io.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-namespace {
-bool utf8ToWide(const char *utf8, wchar_t *buf, size_t bufSize) {
- const llvm::UTF8 *sourceStart = reinterpret_cast<const llvm::UTF8 *>(utf8);
- size_t sourceLen = strlen(utf8) + 1 /* convert null too */;
- llvm::UTF16 *target = reinterpret_cast<llvm::UTF16 *>(buf);
- llvm::ConversionFlags flags = llvm::strictConversion;
- return llvm::ConvertUTF8toUTF16(&sourceStart, sourceStart + sourceLen, &target,
- target + bufSize, flags) == llvm::conversionOK;
-}
-
-bool wideToUtf8(const wchar_t *wide, char *buf, size_t bufSize) {
- const llvm::UTF16 *sourceStart = reinterpret_cast<const llvm::UTF16 *>(wide);
- size_t sourceLen = wcslen(wide) + 1 /* convert null too */;
- llvm::UTF8 *target = reinterpret_cast<llvm::UTF8 *>(buf);
- llvm::ConversionFlags flags = llvm::strictConversion;
- return llvm::ConvertUTF16toUTF8(&sourceStart, sourceStart + sourceLen, &target,
- target + bufSize, flags) == llvm::conversionOK;
-}
-}
-
-int vasprintf(char **ret, const char *fmt, va_list ap) {
- char *buf;
- int len;
- size_t buflen;
- va_list ap2;
-
-#if defined(_MSC_VER) || defined(__MINGW64)
- ap2 = ap;
- len = _vscprintf(fmt, ap2);
-#else
- va_copy(ap2, ap);
- len = vsnprintf(NULL, 0, fmt, ap2);
-#endif
-
- if (len >= 0 &&
- (buf = (char *)malloc((buflen = (size_t)(len + 1)))) != NULL) {
- len = vsnprintf(buf, buflen, fmt, ap);
- *ret = buf;
- } else {
- *ret = NULL;
- len = -1;
- }
-
- va_end(ap2);
- return len;
-}
-
-char *strcasestr(const char *s, const char *find) {
- char c, sc;
- size_t len;
-
- if ((c = *find++) != 0) {
- c = tolower((unsigned char)c);
- len = strlen(find);
- do {
- do {
- if ((sc = *s++) == 0)
- return 0;
- } while ((char)tolower((unsigned char)sc) != c);
- } while (strncasecmp(s, find, len) != 0);
- s--;
- }
- return ((char *)s);
-}
-
-char *realpath(const char *name, char *resolved) {
- char *retname = NULL;
-
- /* SUSv3 says we must set `errno = EINVAL', and return NULL,
- * if `name' is passed as a NULL pointer.
- */
- if (name == NULL) {
- errno = EINVAL;
- return NULL;
- }
-
- /* Otherwise, `name' must refer to a readable filesystem object,
- * if we are going to resolve its absolute path name.
- */
- wchar_t wideNameBuffer[PATH_MAX];
- wchar_t *wideName = wideNameBuffer;
- if (!utf8ToWide(name, wideName, PATH_MAX)) {
- errno = EINVAL;
- return NULL;
- }
-
- if (_waccess(wideName, 4) != 0)
- return NULL;
-
- /* If `name' didn't point to an existing entity,
- * then we don't get to here; we simply fall past this block,
- * returning NULL, with `errno' appropriately set by `access'.
- *
- * When we _do_ get to here, then we can use `_fullpath' to
- * resolve the full path for `name' into `resolved', but first,
- * check that we have a suitable buffer, in which to return it.
- */
-
- if ((retname = resolved) == NULL) {
- /* Caller didn't give us a buffer, so we'll exercise the
- * option granted by SUSv3, and allocate one.
- *
- * `_fullpath' would do this for us, but it uses `malloc', and
- * Microsoft's implementation doesn't set `errno' on failure.
- * If we don't do this explicitly ourselves, then we will not
- * know if `_fullpath' fails on `malloc' failure, or for some
- * other reason, and we want to set `errno = ENOMEM' for the
- * `malloc' failure case.
- */
-
- retname = (char *)malloc(PATH_MAX);
- if (retname == NULL) {
- errno = ENOMEM;
- return NULL;
- }
- }
-
- /* Otherwise, when we do have a valid buffer,
- * `_fullpath' should only fail if the path name is too long.
- */
-
- wchar_t wideFullPathBuffer[PATH_MAX];
- wchar_t *wideFullPath;
- if ((wideFullPath = _wfullpath(wideFullPathBuffer, wideName, PATH_MAX)) ==
- NULL) {
- errno = ENAMETOOLONG;
- return NULL;
- }
-
- // Do a LongPath<->ShortPath roundtrip so that case is resolved by OS
- // FIXME: Check for failure
- size_t initialLength = wcslen(wideFullPath);
- GetShortPathNameW(wideFullPath, wideNameBuffer, PATH_MAX);
- GetLongPathNameW(wideNameBuffer, wideFullPathBuffer, initialLength + 1);
-
- // Convert back to UTF-8
- if (!wideToUtf8(wideFullPathBuffer, retname, PATH_MAX)) {
- errno = EINVAL;
- return NULL;
- }
-
- // Force drive to be upper case
- if (retname[1] == ':')
- retname[0] = toupper(retname[0]);
-
- return retname;
-}
-
-#ifdef _MSC_VER
-
-char *basename(char *path) {
- char *l1 = strrchr(path, '\\');
- char *l2 = strrchr(path, '/');
- if (l2 > l1)
- l1 = l2;
- if (!l1)
- return path; // no base name
- return &l1[1];
-}
-
-char *dirname(char *path) {
- char *l1 = strrchr(path, '\\');
- char *l2 = strrchr(path, '/');
- if (l2 > l1)
- l1 = l2;
- if (!l1)
- return NULL; // no dir name
- *l1 = 0;
- return path;
-}
-
-int strcasecmp(const char *s1, const char *s2) { return stricmp(s1, s2); }
-
-int strncasecmp(const char *s1, const char *s2, size_t n) {
- return strnicmp(s1, s2, n);
-}
-
-int usleep(uint32_t useconds) {
- Sleep(useconds / 1000);
- return 0;
-}
-
-#if _MSC_VER < 1900
-namespace lldb_private {
-int vsnprintf(char *buffer, size_t count, const char *format, va_list argptr) {
- int old_errno = errno;
- int r = ::vsnprintf(buffer, count, format, argptr);
- int new_errno = errno;
- buffer[count - 1] = '\0';
- if (r == -1 || r == count) {
- FILE *nul = fopen("nul", "w");
- int bytes_written = ::vfprintf(nul, format, argptr);
- fclose(nul);
- if (bytes_written < count)
- errno = new_errno;
- else {
- errno = old_errno;
- r = bytes_written;
- }
- }
- return r;
-}
-} // namespace lldb_private
-#endif
-
-#endif // _MSC_VER