diff options
Diffstat (limited to 'source/Host')
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 |