Author: teemperor Date: Wed Jun 13 08:50:45 2018 New Revision: 334611 URL: http://llvm.org/viewvc/llvm-project?rev=334611&view=rev Log: Add modules support for lldb headers in include/
Summary: This patch adds a modulemap which allows compiling the lldb headers into C++ modules (for example in builds with LLVM_ENABLE_MODULES=On). Even though most of the affected code has been cleaned up to work with the more strict C++ module semantics, there are still some workarounds left in the current modulemap (the most obvious one is the big `lldb` wrapper module). It also moves the Obj-C++ files in lldb to their own subdirectories. This was necessary because we need to filter out the modules flags for this code. Note: With the latest clang and libstdc++ it seems necessary to have a STL C++ module to get a working LLVM_ENABLE_MODULES build for lldb. Otherwise clang will falsely detect ODR violations in the textually included STL code inside the lldb modules. Reviewers: aprantl, bruno Reviewed By: aprantl, bruno Subscribers: mgorny, yamaguchi, v.g.vassilev, lldb-commits Differential Revision: https://reviews.llvm.org/D47929 Added: lldb/trunk/include/lldb/module.modulemap lldb/trunk/source/Host/macosx/objcxx/ lldb/trunk/source/Host/macosx/objcxx/CMakeLists.txt lldb/trunk/source/Host/macosx/objcxx/Host.mm - copied, changed from r334557, lldb/trunk/source/Host/macosx/Host.mm lldb/trunk/source/Host/macosx/objcxx/HostInfoMacOSX.mm - copied, changed from r334557, lldb/trunk/source/Host/macosx/HostInfoMacOSX.mm lldb/trunk/source/Host/macosx/objcxx/HostThreadMacOSX.mm - copied, changed from r334557, lldb/trunk/source/Host/macosx/HostThreadMacOSX.mm lldb/trunk/source/Plugins/Platform/MacOSX/objcxx/ lldb/trunk/source/Plugins/Platform/MacOSX/objcxx/CMakeLists.txt lldb/trunk/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.mm - copied, changed from r334557, lldb/trunk/source/Plugins/Platform/MacOSX/PlatformiOSSimulatorCoreSimulatorSupport.mm Removed: lldb/trunk/source/Host/macosx/Host.mm lldb/trunk/source/Host/macosx/HostInfoMacOSX.mm lldb/trunk/source/Host/macosx/HostThreadMacOSX.mm lldb/trunk/source/Plugins/Platform/MacOSX/PlatformiOSSimulatorCoreSimulatorSupport.mm Modified: lldb/trunk/source/Host/CMakeLists.txt lldb/trunk/source/Host/common/Terminal.cpp lldb/trunk/source/Plugins/Platform/MacOSX/CMakeLists.txt Added: lldb/trunk/include/lldb/module.modulemap URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/module.modulemap?rev=334611&view=auto ============================================================================== --- lldb/trunk/include/lldb/module.modulemap (added) +++ lldb/trunk/include/lldb/module.modulemap Wed Jun 13 08:50:45 2018 @@ -0,0 +1,139 @@ + +module lldb_API { + requires cplusplus + + umbrella "API" + module * { export * } +} + +module lldb_Host { + requires cplusplus + + // Because we have OS-specific headers in Host, we just list + // all OS-independent headers here that will include the correct + // OS-specific header for us. + module ConnectionFileDescriptor { header "Host/ConnectionFileDescriptor.h" export * } + module Debug { header "Host/Debug.h" export * } + module Editline { header "Host/Editline.h" export * } + module FileCache { header "Host/FileCache.h" export * } + module File { header "Host/File.h" export * } + module FileSystem { header "Host/FileSystem.h" export * } + module HostGetOpt { header "Host/HostGetOpt.h" export * } + module Host { header "Host/Host.h" export * } + module HostInfoBase { header "Host/HostInfoBase.h" export * } + module HostInfo { header "Host/HostInfo.h" export * } + module HostNativeProcessBase { header "Host/HostNativeProcessBase.h" export * } + module HostNativeProcess { header "Host/HostNativeProcess.h" export * } + module HostNativeThreadBase { header "Host/HostNativeThreadBase.h" export * } + module HostNativeThreadForward { header "Host/HostNativeThreadForward.h" export * } + module HostNativeThread { header "Host/HostNativeThread.h" export * } + module HostProcess { header "Host/HostProcess.h" export * } + module HostThread { header "Host/HostThread.h" export * } + module LockFileBase { header "Host/LockFileBase.h" export * } + module LockFile { header "Host/LockFile.h" export * } + module MainLoopBase { header "Host/MainLoopBase.h" export * } + module MainLoop { header "Host/MainLoop.h" export * } + module MonitoringProcessLauncher { header "Host/MonitoringProcessLauncher.h" export * } + module OptionParser { header "Host/OptionParser.h" export * } + module PipeBase { header "Host/PipeBase.h" export * } + module Pipe { header "Host/Pipe.h" export * } + module PosixApi { header "Host/PosixApi.h" export * } + module Predicate { header "Host/Predicate.h" export * } + module ProcessLauncher { header "Host/ProcessLauncher.h" export * } + module ProcessRunLock { header "Host/ProcessRunLock.h" export * } + module PseudoTerminal { header "Host/PseudoTerminal.h" export * } + module SocketAddress { header "Host/SocketAddress.h" export * } + module Socket { header "Host/Socket.h" export * } + module StringConvert { header "Host/StringConvert.h" export * } + module Symbols { header "Host/Symbols.h" export * } + module TaskPool { header "Host/TaskPool.h" export * } + module Terminal { header "Host/Terminal.h" export * } + module ThreadLauncher { header "Host/ThreadLauncher.h" export * } + module Time { header "Host/Time.h" export * } + module XML { header "Host/XML.h" export * } + + export * +} + +module lldb_Initialization { + requires cplusplus + + umbrella "Initialization" + module * { export * } +} + + +module lldb_Wrapper { + + module lldb_Breakpoint { + requires cplusplus + + umbrella "Breakpoint" + module * { export * } + } + + module lldb_Core { + requires cplusplus + + umbrella "Core" + module * { export * } + } + + module lldb_DataFormatters { + requires cplusplus + + umbrella "DataFormatters" + module * { export * } + } + + module lldb_Expression { + requires cplusplus + + umbrella "Expression" + module * { export * } + // TODO: This file includes a non-public header. + exclude header "Expression/REPL.h" + } + + module lldb_Interpreter { + requires cplusplus + + umbrella "Interpreter" + module * { export * } + } + + module lldb_Symbol { + requires cplusplus + + umbrella "Symbol" + module * { export * } + } + module lldb_Target { + requires cplusplus + + umbrella "Target" + module * { export * } + } +} + + +module lldb_Utility { + requires cplusplus + + umbrella "Utility" + module * { export * } + + module lldb_defines { header "lldb-defines.h" export * } + module lldb_enumerations { header "lldb-enumerations.h" export * } + module lldb_forward { header "lldb-forward.h" export * } + module lldb_private_enumerations { header "lldb-private-enumerations.h" export * } + module lldb_private_defines { header "lldb-private-defines.h" export * } + module lldb_private_forward { header "lldb-private-forward.h" export * } + module lldb_private { header "lldb-private.h" export * } + module lldb_private_interfaces { header "lldb-private-interfaces.h" export * } + module lldb_private_types { header "lldb-private-types.h" export * } + module lldb_public { header "lldb-public.h" export * } + module lldb_types { header "lldb-types.h" export * } + module lldb_versioning { header "lldb-versioning.h" export * } + +} Modified: lldb/trunk/source/Host/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/CMakeLists.txt?rev=334611&r1=334610&r2=334611&view=diff ============================================================================== --- lldb/trunk/source/Host/CMakeLists.txt (original) +++ lldb/trunk/source/Host/CMakeLists.txt Wed Jun 13 08:50:45 2018 @@ -3,6 +3,18 @@ macro(add_host_subdirectory group) 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" "" 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 @@ -92,10 +104,9 @@ else() if (CMAKE_SYSTEM_NAME MATCHES "Darwin") include_directories(SYSTEM ${LIBXML2_INCLUDE_DIR}) - add_host_subdirectory(macosx - macosx/Host.mm - macosx/HostInfoMacOSX.mm - macosx/HostThreadMacOSX.mm + add_subdirectory(macosx/objcxx) + set(LLDBObjCLibs lldbHostMacOSXObjCXX) + add_host_subdirectory(maqcosx macosx/Symbols.cpp macosx/cfcpp/CFCBundle.cpp macosx/cfcpp/CFCData.cpp @@ -177,7 +188,7 @@ endif() add_lldb_library(lldbHost ${HOST_SOURCES} - + LINK_LIBS lldbCore lldbSymbol @@ -185,7 +196,8 @@ add_lldb_library(lldbHost lldbUtility ${LLDB_PLUGINS} ${EXTRA_LIBS} - + ${LLDBObjCLibs} + LINK_COMPONENTS Object Support Modified: lldb/trunk/source/Host/common/Terminal.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/Terminal.cpp?rev=334611&r1=334610&r2=334611&view=diff ============================================================================== --- lldb/trunk/source/Host/common/Terminal.cpp (original) +++ lldb/trunk/source/Host/common/Terminal.cpp Wed Jun 13 08:50:45 2018 @@ -9,6 +9,7 @@ #include "lldb/Host/Terminal.h" +#include "lldb/Host/Config.h" #include "lldb/Host/PosixApi.h" #include "llvm/ADT/STLExtras.h" Removed: lldb/trunk/source/Host/macosx/Host.mm URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/macosx/Host.mm?rev=334610&view=auto ============================================================================== --- lldb/trunk/source/Host/macosx/Host.mm (original) +++ lldb/trunk/source/Host/macosx/Host.mm (removed) @@ -1,1530 +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/HostInfo.h" -#include "lldb/Host/ThreadLauncher.h" -#include "lldb/Target/ProcessLaunchInfo.h" -#include "lldb/Target/Process.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 (llvm::sys::fs::is_directory(file.GetPath())) { - char path[PATH_MAX]; - if (file.GetPath(path, sizeof(path))) { - CFCBundle bundle(path); - if (bundle.GetPath(path, sizeof(path))) { - bundle_directory.SetFile(path, false); - return true; - } - } - } -#endif - bundle_directory.Clear(); - return false; -} - -bool Host::ResolveExecutableInBundle(FileSpec &file) { -#if defined(__APPLE__) - if (llvm::sys::fs::is_directory(file.GetPath())) { - 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, false); - 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; - if (!HostInfo::GetLLDBPath(ePathTypeSupportExecutableDir, - darwin_debug_file_spec)) { - error.SetErrorString("can't locate the 'darwin-debug' executable"); - return error; - } - - darwin_debug_file_spec.GetFilename().SetCString("darwin-debug"); - - if (!darwin_debug_file_spec.Exists()) { - 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); - if (sysctlbyname("hw.cpu64bit_capable", &is64bit_capable, - &is64bit_capable_len, NULL, 0) == 0) - host_cpu_is_64bit = true; - else - host_cpu_is_64bit = false; - - // 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, false); - - 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, 4, NULL, &pid_data_size, NULL, 0) != 0) - return 0; - - // Add a few extra in case a few more show up - const size_t estimated_pid_count = - (pid_data_size / sizeof(struct kinfo_proc)) + 10; - - kinfos.resize(estimated_pid_count); - pid_data_size = kinfos.size() * sizeof(struct kinfo_proc); - - if (::sysctl(mib, 4, &kinfos[0], &pid_data_size, NULL, 0) != 0) - return 0; - - const size_t actual_pid_count = (pid_data_size / sizeof(struct kinfo_proc)); - - bool all_users = match_info.GetMatchAllUsers(); - const 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 == false || // 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; - - uint32_t major, minor, update; - if (HostInfo::GetOSVersion(major, minor, update)) { - // Kernel panic if we use the POSIX_SPAWN_CLOEXEC_DEFAULT on 10.7 or - // earlier - if (major > 10 || (major == 10 && minor > 7)) { - // Only enable for 10.8 and later OS versions - 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; - FileSpec exe_spec(launch_info.GetExecutableFile()); - - llvm::sys::fs::file_status stats; - status(exe_spec.GetPath(), stats); - if (!exists(stats)) { - exe_spec.ResolvePath(); - status(exe_spec.GetPath(), stats); - } - if (!exists(stats)) { - exe_spec.ResolveExecutableLocation(); - status(exe_spec.GetPath(), stats); - } - if (!exists(stats)) { - error.SetErrorStringWithFormatv("executable doesn't exist: '{0}'", - launch_info.GetExecutableFile()); - 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; - if (!HostInfo::GetLLDBPath(lldb::ePathTypeSupportExecutableDir, - expand_tool_spec)) { - error.SetErrorString( - "could not get support executable directory for lldb-argdumper tool"); - return error; - } - expand_tool_spec.AppendPathComponent("lldb-argdumper"); - if (!expand_tool_spec.Exists()) { - 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 (!cwd.Exists()) { - char *wd = getcwd(nullptr, 0); - if (wd == nullptr) { - error.SetErrorStringWithFormat( - "cwd does not exist; cannot launch with shell argument expansion"); - return error; - } else { - FileSpec working_dir(wd, false); - 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); - } -} Removed: lldb/trunk/source/Host/macosx/HostInfoMacOSX.mm URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/macosx/HostInfoMacOSX.mm?rev=334610&view=auto ============================================================================== --- lldb/trunk/source/Host/macosx/HostInfoMacOSX.mm (original) +++ lldb/trunk/source/Host/macosx/HostInfoMacOSX.mm (removed) @@ -1,319 +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. -// -//===----------------------------------------------------------------------===// - -#if !defined(LLDB_DISABLE_PYTHON) -#include "Plugins/ScriptInterpreter/Python/lldb-python.h" -#endif - -#include "lldb/Host/HostInfo.h" -#include "lldb/Host/macosx/HostInfoMacOSX.h" -#include "lldb/Utility/Args.h" -#include "lldb/Utility/Log.h" -#include "lldb/Utility/SafeMachO.h" - -#include "llvm/ADT/SmallString.h" -#include "llvm/Support/FileSystem.h" -#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; -} - -bool HostInfoMacOSX::GetOSVersion(uint32_t &major, uint32_t &minor, - uint32_t &update) { - static uint32_t g_major = 0; - static uint32_t g_minor = 0; - static uint32_t g_update = 0; - - if (g_major == 0) { - @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]; - if (version_str) - Args::StringToVersion(llvm::StringRef(version_str), g_major, g_minor, - g_update); - } - } - - if (g_major != 0) { - major = g_major; - minor = g_minor; - update = g_update; - return true; - } - return false; -} - -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, false); - else if (err == -1) { - char *large_program_fullpath = (char *)::malloc(len + 1); - - err = _NSGetExecutablePath(large_program_fullpath, &len); - if (err == 0) - g_program_filespec.SetFile(large_program_fullpath, false); - - ::free(large_program_fullpath); - } - } - return g_program_filespec; -} - -bool HostInfoMacOSX::ComputeSupportExeDirectory(FileSpec &file_spec) { - FileSpec lldb_file_spec; - if (!GetLLDBPath(lldb::ePathTypeLLDBShlibDir, 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, true); - if (!llvm::sys::fs::is_directory(support_dir_spec.GetPath())) { - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); - if (log) - log->Printf("HostInfoMacOSX::%s(): failed to find support directory", - __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; - if (!HostInfo::GetLLDBPath(lldb::ePathTypeLLDBShlibDir, 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::ComputePythonDirectory(FileSpec &file_spec) { -#ifndef LLDB_DISABLE_PYTHON - FileSpec lldb_file_spec; - if (!GetLLDBPath(lldb::ePathTypeLLDBShlibDir, 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("/Resources/Python"); - } else { - llvm::SmallString<256> python_version_dir; - llvm::raw_svector_ostream os(python_version_dir); - os << "/python" << PY_MAJOR_VERSION << '.' << PY_MINOR_VERSION - << "/site-packages"; - - // We may get our string truncated. Should we protect this with an assert? - raw_path.append(python_version_dir.c_str()); - } - file_spec.GetDirectory().SetString( - llvm::StringRef(raw_path.c_str(), raw_path.size())); - return true; -#else - return false; -#endif -} - -bool HostInfoMacOSX::ComputeSystemPluginsDirectory(FileSpec &file_spec) { - FileSpec lldb_file_spec; - if (!GetLLDBPath(lldb::ePathTypeLLDBShlibDir, 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", true); - 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); -#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(); - } - } -} Removed: lldb/trunk/source/Host/macosx/HostThreadMacOSX.mm URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/macosx/HostThreadMacOSX.mm?rev=334610&view=auto ============================================================================== --- lldb/trunk/source/Host/macosx/HostThreadMacOSX.mm (original) +++ lldb/trunk/source/Host/macosx/HostThreadMacOSX.mm (removed) @@ -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); -} Added: lldb/trunk/source/Host/macosx/objcxx/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/macosx/objcxx/CMakeLists.txt?rev=334611&view=auto ============================================================================== --- lldb/trunk/source/Host/macosx/objcxx/CMakeLists.txt (added) +++ lldb/trunk/source/Host/macosx/objcxx/CMakeLists.txt Wed Jun 13 08:50:45 2018 @@ -0,0 +1,21 @@ + +remove_module_flags() +include_directories(..) + +add_lldb_library(lldbHostMacOSXObjCXX + Host.mm + HostInfoMacOSX.mm + HostThreadMacOSX.mm + + LINK_LIBS + lldbCore + lldbSymbol + lldbTarget + lldbUtility + ${LLDB_PLUGINS} + ${EXTRA_LIBS} + + LINK_COMPONENTS + Object + Support + ) Copied: lldb/trunk/source/Host/macosx/objcxx/Host.mm (from r334557, lldb/trunk/source/Host/macosx/Host.mm) URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/macosx/objcxx/Host.mm?p2=lldb/trunk/source/Host/macosx/objcxx/Host.mm&p1=lldb/trunk/source/Host/macosx/Host.mm&r1=334557&r2=334611&rev=334611&view=diff ============================================================================== (empty) Copied: lldb/trunk/source/Host/macosx/objcxx/HostInfoMacOSX.mm (from r334557, lldb/trunk/source/Host/macosx/HostInfoMacOSX.mm) URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/macosx/objcxx/HostInfoMacOSX.mm?p2=lldb/trunk/source/Host/macosx/objcxx/HostInfoMacOSX.mm&p1=lldb/trunk/source/Host/macosx/HostInfoMacOSX.mm&r1=334557&r2=334611&rev=334611&view=diff ============================================================================== (empty) Copied: lldb/trunk/source/Host/macosx/objcxx/HostThreadMacOSX.mm (from r334557, lldb/trunk/source/Host/macosx/HostThreadMacOSX.mm) URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/macosx/objcxx/HostThreadMacOSX.mm?p2=lldb/trunk/source/Host/macosx/objcxx/HostThreadMacOSX.mm&p1=lldb/trunk/source/Host/macosx/HostThreadMacOSX.mm&r1=334557&r2=334611&rev=334611&view=diff ============================================================================== (empty) Modified: lldb/trunk/source/Plugins/Platform/MacOSX/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/MacOSX/CMakeLists.txt?rev=334611&r1=334610&r2=334611&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Platform/MacOSX/CMakeLists.txt (original) +++ lldb/trunk/source/Plugins/Platform/MacOSX/CMakeLists.txt Wed Jun 13 08:50:45 2018 @@ -11,13 +11,14 @@ list(APPEND PLUGIN_PLATFORM_MACOSX_SOURC list(APPEND PLUGIN_PLATFORM_MACOSX_DARWIN_ONLY_SOURCES PlatformAppleSimulator.cpp PlatformiOSSimulator.cpp - PlatformiOSSimulatorCoreSimulatorSupport.mm PlatformAppleTVSimulator.cpp PlatformAppleWatchSimulator.cpp ) if(CMAKE_SYSTEM_NAME MATCHES "Darwin") include_directories(${LIBXML2_INCLUDE_DIR}) + add_subdirectory(objcxx) + set(OBJC_LIBS "lldbPluginPlatformMacOSXObjCXX") list(APPEND PLUGIN_PLATFORM_MACOSX_SOURCES ${PLUGIN_PLATFORM_MACOSX_DARWIN_ONLY_SOURCES}) else() @@ -38,6 +39,7 @@ add_lldb_library(lldbPluginPlatformMacOS lldbTarget lldbUtility lldbPluginPlatformPOSIX + ${OBJC_LIBS} LINK_COMPONENTS Support ) Removed: lldb/trunk/source/Plugins/Platform/MacOSX/PlatformiOSSimulatorCoreSimulatorSupport.mm URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/MacOSX/PlatformiOSSimulatorCoreSimulatorSupport.mm?rev=334610&view=auto ============================================================================== --- lldb/trunk/source/Plugins/Platform/MacOSX/PlatformiOSSimulatorCoreSimulatorSupport.mm (original) +++ lldb/trunk/source/Plugins/Platform/MacOSX/PlatformiOSSimulatorCoreSimulatorSupport.mm (removed) @@ -1,634 +0,0 @@ -//===-- PlatformiOSSimulatorCoreSimulatorSupport.cpp ---------------*- C++ -//-*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "PlatformiOSSimulatorCoreSimulatorSupport.h" - -// C Includes -// C++ Includes -// Other libraries and framework includes -#include <CoreFoundation/CoreFoundation.h> -#include <Foundation/Foundation.h> -// Project includes -#include "lldb/Host/PseudoTerminal.h" -#include "lldb/Target/FileAction.h" - -#include "llvm/ADT/StringRef.h" - -using namespace lldb_private; -// CoreSimulator lives as part of Xcode, which means we can't really link -// against it, so we dlopen() -// it at runtime, and error out nicely if that fails -@interface SimServiceContext { -} -+ (id)sharedServiceContextForDeveloperDir:(NSString *)dir - error:(NSError **)error; -@end -// However, the drawback is that the compiler will not know about the selectors -// we're trying to use -// until runtime; to appease clang in this regard, define a fake protocol on -// NSObject that exposes -// the needed interface names for us -@protocol LLDBCoreSimulatorSupport <NSObject> -- (id)defaultDeviceSetWithError:(NSError **)error; -- (NSArray *)devices; -- (id)deviceType; -- (NSString *)name; -- (NSString *)identifier; -- (NSString *)modelIdentifier; -- (NSString *)productFamily; -- (int32_t)productFamilyID; -- (id)runtime; -- (BOOL)available; -- (NSString *)versionString; -- (NSString *)buildVersionString; -- (BOOL)bootWithOptions:(NSDictionary *)options error:(NSError **)error; -- (NSUInteger)state; -- (BOOL)shutdownWithError:(NSError **)error; -- (NSUUID *)UDID; -- (pid_t)spawnWithPath:(NSString *)path - options:(NSDictionary *)options - terminationHandler:(void (^)(int status))terminationHandler - error:(NSError **)error; -@end - -CoreSimulatorSupport::Process::Process(lldb::pid_t p) : m_pid(p), m_error() {} - -CoreSimulatorSupport::Process::Process(Status error) - : m_pid(LLDB_INVALID_PROCESS_ID), m_error(error) {} - -CoreSimulatorSupport::Process::Process(lldb::pid_t p, Status error) - : m_pid(p), m_error(error) {} - -CoreSimulatorSupport::DeviceType::DeviceType() - : m_dev(nil), m_model_identifier() {} - -CoreSimulatorSupport::DeviceType::DeviceType(id d) - : m_dev(d), m_model_identifier() {} - -CoreSimulatorSupport::DeviceType::operator bool() { return m_dev != nil; } - -ConstString CoreSimulatorSupport::DeviceType::GetIdentifier() { - return ConstString([[m_dev identifier] UTF8String]); -} - -ConstString CoreSimulatorSupport::DeviceType::GetProductFamily() { - return ConstString([[m_dev productFamily] UTF8String]); -} - -CoreSimulatorSupport::DeviceType::ProductFamilyID -CoreSimulatorSupport::DeviceType::GetProductFamilyID() { - return ProductFamilyID([m_dev productFamilyID]); -} - -CoreSimulatorSupport::DeviceRuntime::DeviceRuntime() - : m_dev(nil), m_os_version() {} - -CoreSimulatorSupport::DeviceRuntime::DeviceRuntime(id d) - : m_dev(d), m_os_version() {} - -CoreSimulatorSupport::DeviceRuntime::operator bool() { return m_dev != nil; } - -bool CoreSimulatorSupport::DeviceRuntime::IsAvailable() { - return [m_dev available]; -} - -CoreSimulatorSupport::Device::Device() - : m_dev(nil), m_dev_type(), m_dev_runtime() {} - -CoreSimulatorSupport::Device::Device(id d) - : m_dev(d), m_dev_type(), m_dev_runtime() {} - -CoreSimulatorSupport::Device::operator bool() { return m_dev != nil; } - -CoreSimulatorSupport::Device::State CoreSimulatorSupport::Device::GetState() { - return (State)([m_dev state]); -} - -CoreSimulatorSupport::ModelIdentifier::ModelIdentifier(const std::string &mi) - : m_family(), m_versions() { - bool any = false; - bool first_digit = false; - unsigned int val = 0; - - for (char c : mi) { - any = true; - if (::isdigit(c)) { - if (!first_digit) - first_digit = true; - val = 10 * val + (c - '0'); - } else if (c == ',') { - if (first_digit) { - m_versions.push_back(val); - val = 0; - } else - m_family.push_back(c); - } else { - if (first_digit) { - m_family.clear(); - m_versions.clear(); - return; - } else { - m_family.push_back(c); - } - } - } - - if (first_digit) - m_versions.push_back(val); -} - -CoreSimulatorSupport::ModelIdentifier::ModelIdentifier() - : ModelIdentifier("") {} - -CoreSimulatorSupport::OSVersion::OSVersion(const std::string &ver, - const std::string &build) - : m_versions(), m_build(build) { - bool any = false; - unsigned int val = 0; - for (char c : ver) { - if (c == '.') { - m_versions.push_back(val); - val = 0; - } else if (::isdigit(c)) { - val = 10 * val + (c - '0'); - any = true; - } else { - m_versions.clear(); - return; - } - } - if (any) - m_versions.push_back(val); -} - -CoreSimulatorSupport::OSVersion::OSVersion() : OSVersion("", "") {} - -CoreSimulatorSupport::ModelIdentifier -CoreSimulatorSupport::DeviceType::GetModelIdentifier() { - if (!m_model_identifier.hasValue()) { - auto utf8_model_id = [[m_dev modelIdentifier] UTF8String]; - if (utf8_model_id && *utf8_model_id) - m_model_identifier = ModelIdentifier(utf8_model_id); - } - - if (m_model_identifier.hasValue()) - return m_model_identifier.getValue(); - else - return ModelIdentifier(); -} - -CoreSimulatorSupport::OSVersion -CoreSimulatorSupport::DeviceRuntime::GetVersion() { - if (!m_os_version.hasValue()) { - auto utf8_ver_string = [[m_dev versionString] UTF8String]; - auto utf8_build_ver = [[m_dev buildVersionString] UTF8String]; - if (utf8_ver_string && *utf8_ver_string && utf8_build_ver && - *utf8_build_ver) { - m_os_version = OSVersion(utf8_ver_string, utf8_build_ver); - } - } - - if (m_os_version.hasValue()) - return m_os_version.getValue(); - return OSVersion(); -} - -std::string CoreSimulatorSupport::DeviceType::GetName() { - auto utf8_name = [[m_dev name] UTF8String]; - if (utf8_name) - return std::string(utf8_name); - return ""; -} - -std::string CoreSimulatorSupport::Device::GetName() const { - auto utf8_name = [[m_dev name] UTF8String]; - if (utf8_name) - return std::string(utf8_name); - return ""; -} - -std::string CoreSimulatorSupport::Device::GetUDID() const { - auto utf8_udid = [[[m_dev UDID] UUIDString] UTF8String]; - if (utf8_udid) - return std::string(utf8_udid); - else - return std::string(); -} - -CoreSimulatorSupport::DeviceType CoreSimulatorSupport::Device::GetDeviceType() { - if (!m_dev_type.hasValue()) - m_dev_type = DeviceType([m_dev deviceType]); - - return m_dev_type.getValue(); -} - -CoreSimulatorSupport::DeviceRuntime -CoreSimulatorSupport::Device::GetDeviceRuntime() { - if (!m_dev_runtime.hasValue()) - m_dev_runtime = DeviceRuntime([m_dev runtime]); - - return m_dev_runtime.getValue(); -} - -bool CoreSimulatorSupport:: -operator>(const CoreSimulatorSupport::OSVersion &lhs, - const CoreSimulatorSupport::OSVersion &rhs) { - for (size_t i = 0; i < rhs.GetNumVersions(); i++) { - unsigned int l = lhs.GetVersionAtIndex(i); - unsigned int r = rhs.GetVersionAtIndex(i); - if (l > r) - return true; - } - return false; -} - -bool CoreSimulatorSupport:: -operator>(const CoreSimulatorSupport::ModelIdentifier &lhs, - const CoreSimulatorSupport::ModelIdentifier &rhs) { - if (lhs.GetFamily() != rhs.GetFamily()) - return false; - for (size_t i = 0; i < rhs.GetNumVersions(); i++) { - unsigned int l = lhs.GetVersionAtIndex(i); - unsigned int r = rhs.GetVersionAtIndex(i); - if (l > r) - return true; - } - return false; -} - -bool CoreSimulatorSupport:: -operator<(const CoreSimulatorSupport::OSVersion &lhs, - const CoreSimulatorSupport::OSVersion &rhs) { - for (size_t i = 0; i < rhs.GetNumVersions(); i++) { - unsigned int l = lhs.GetVersionAtIndex(i); - unsigned int r = rhs.GetVersionAtIndex(i); - if (l < r) - return true; - } - return false; -} - -bool CoreSimulatorSupport:: -operator<(const CoreSimulatorSupport::ModelIdentifier &lhs, - const CoreSimulatorSupport::ModelIdentifier &rhs) { - if (lhs.GetFamily() != rhs.GetFamily()) - return false; - - for (size_t i = 0; i < rhs.GetNumVersions(); i++) { - unsigned int l = lhs.GetVersionAtIndex(i); - unsigned int r = rhs.GetVersionAtIndex(i); - if (l < r) - return true; - } - return false; -} - -bool CoreSimulatorSupport:: -operator==(const CoreSimulatorSupport::OSVersion &lhs, - const CoreSimulatorSupport::OSVersion &rhs) { - for (size_t i = 0; i < rhs.GetNumVersions(); i++) { - unsigned int l = lhs.GetVersionAtIndex(i); - unsigned int r = rhs.GetVersionAtIndex(i); - if (l != r) - return false; - } - return true; -} - -bool CoreSimulatorSupport:: -operator==(const CoreSimulatorSupport::ModelIdentifier &lhs, - const CoreSimulatorSupport::ModelIdentifier &rhs) { - if (lhs.GetFamily() != rhs.GetFamily()) - return false; - - for (size_t i = 0; i < rhs.GetNumVersions(); i++) { - unsigned int l = lhs.GetVersionAtIndex(i); - unsigned int r = rhs.GetVersionAtIndex(i); - if (l != r) - return false; - } - return true; -} - -bool CoreSimulatorSupport:: -operator!=(const CoreSimulatorSupport::OSVersion &lhs, - const CoreSimulatorSupport::OSVersion &rhs) { - for (size_t i = 0; i < rhs.GetNumVersions(); i++) { - unsigned int l = lhs.GetVersionAtIndex(i); - unsigned int r = rhs.GetVersionAtIndex(i); - if (l != r) - return true; - } - return false; -} - -bool CoreSimulatorSupport:: -operator!=(const CoreSimulatorSupport::ModelIdentifier &lhs, - const CoreSimulatorSupport::ModelIdentifier &rhs) { - if (lhs.GetFamily() != rhs.GetFamily()) - return false; - - for (size_t i = 0; i < rhs.GetNumVersions(); i++) { - unsigned int l = lhs.GetVersionAtIndex(i); - unsigned int r = rhs.GetVersionAtIndex(i); - if (l != r) - return true; - } - return false; -} - -bool CoreSimulatorSupport::Device::Boot(Status &err) { - if (m_dev == nil) { - err.SetErrorString("no valid simulator instance"); - return false; - } - -#define kSimDeviceBootPersist \ - @"persist" /* An NSNumber (boolean) indicating whether or not the session \ - should outlive the calling process (default false) */ - - NSDictionary *options = @{ - kSimDeviceBootPersist : @NO, - }; - -#undef kSimDeviceBootPersist - - NSError *nserror; - if ([m_dev bootWithOptions:options error:&nserror]) { - err.Clear(); - return true; - } else { - err.SetErrorString([[nserror description] UTF8String]); - return false; - } -} - -bool CoreSimulatorSupport::Device::Shutdown(Status &err) { - NSError *nserror; - if ([m_dev shutdownWithError:&nserror]) { - err.Clear(); - return true; - } else { - err.SetErrorString([[nserror description] UTF8String]); - return false; - } -} - -static Status HandleFileAction(ProcessLaunchInfo &launch_info, - NSMutableDictionary *options, NSString *key, - const int fd, File &file) { - Status error; - const FileAction *file_action = launch_info.GetFileActionForFD(fd); - if (file_action) { - switch (file_action->GetAction()) { - case FileAction::eFileActionNone: - break; - - case FileAction::eFileActionClose: - error.SetErrorStringWithFormat("close file action for %i not supported", - fd); - break; - - case FileAction::eFileActionDuplicate: - error.SetErrorStringWithFormat( - "duplication file action for %i not supported", fd); - break; - - case FileAction::eFileActionOpen: { - FileSpec file_spec = file_action->GetFileSpec(); - if (file_spec) { - const int master_fd = launch_info.GetPTY().GetMasterFileDescriptor(); - if (master_fd != PseudoTerminal::invalid_fd) { - // Check in case our file action open wants to open the slave - const char *slave_path = launch_info.GetPTY().GetSlaveName(NULL, 0); - if (slave_path) { - FileSpec slave_spec(slave_path, false); - if (file_spec == slave_spec) { - int slave_fd = launch_info.GetPTY().GetSlaveFileDescriptor(); - if (slave_fd == PseudoTerminal::invalid_fd) - slave_fd = launch_info.GetPTY().OpenSlave(O_RDWR, nullptr, 0); - if (slave_fd == PseudoTerminal::invalid_fd) { - error.SetErrorStringWithFormat("unable to open slave pty '%s'", - slave_path); - return error; // Failure - } - [options setValue:[NSNumber numberWithInteger:slave_fd] - forKey:key]; - return error; // Success - } - } - } - Status posix_error; - int created_fd = - open(file_spec.GetPath().c_str(), file_action->GetActionArgument(), - S_IRUSR | S_IWUSR); - if (created_fd >= 0) { - file.SetDescriptor(created_fd, true); - [options setValue:[NSNumber numberWithInteger:created_fd] forKey:key]; - return error; // Success - } else { - posix_error.SetErrorToErrno(); - error.SetErrorStringWithFormat("unable to open file '%s': %s", - file_spec.GetPath().c_str(), - posix_error.AsCString()); - } - } - } break; - } - } - return error; // Success, no file action, nothing to do -} - -CoreSimulatorSupport::Process -CoreSimulatorSupport::Device::Spawn(ProcessLaunchInfo &launch_info) { -#define kSimDeviceSpawnEnvironment \ - @"environment" /* An NSDictionary (NSStrings -> NSStrings) of environment \ - key/values */ -#define kSimDeviceSpawnStdin @"stdin" /* An NSNumber corresponding to a fd */ -#define kSimDeviceSpawnStdout @"stdout" /* An NSNumber corresponding to a fd \ - */ -#define kSimDeviceSpawnStderr @"stderr" /* An NSNumber corresponding to a fd \ - */ -#define kSimDeviceSpawnArguments \ - @"arguments" /* An NSArray of strings to use as the argv array. If not \ - provided, path will be argv[0] */ -#define kSimDeviceSpawnWaitForDebugger \ - @"wait_for_debugger" /* An NSNumber (bool) */ - - NSMutableDictionary *options = [[NSMutableDictionary alloc] init]; - - if (launch_info.GetFlags().Test(lldb::eLaunchFlagDebug)) - [options setObject:@YES forKey:kSimDeviceSpawnWaitForDebugger]; - - if (launch_info.GetArguments().GetArgumentCount()) { - const Args &args(launch_info.GetArguments()); - NSMutableArray *args_array = [[NSMutableArray alloc] init]; - for (size_t idx = 0; idx < args.GetArgumentCount(); idx++) - [args_array - addObject:[NSString - stringWithUTF8String:args.GetArgumentAtIndex(idx)]]; - - [options setObject:args_array forKey:kSimDeviceSpawnArguments]; - } - - NSMutableDictionary *env_dict = [[NSMutableDictionary alloc] init]; - - for (const auto &KV : launch_info.GetEnvironment()) { - NSString *key_ns = [NSString stringWithUTF8String:KV.first().str().c_str()]; - NSString *value_ns = [NSString stringWithUTF8String:KV.second.c_str()]; - - [env_dict setValue:value_ns forKey:key_ns]; - } - - [options setObject:env_dict forKey:kSimDeviceSpawnEnvironment]; - - Status error; - File stdin_file; - File stdout_file; - File stderr_file; - error = HandleFileAction(launch_info, options, kSimDeviceSpawnStdin, - STDIN_FILENO, stdin_file); - - if (error.Fail()) - return CoreSimulatorSupport::Process(error); - - error = HandleFileAction(launch_info, options, kSimDeviceSpawnStdout, - STDOUT_FILENO, stdout_file); - - if (error.Fail()) - return CoreSimulatorSupport::Process(error); - - error = HandleFileAction(launch_info, options, kSimDeviceSpawnStderr, - STDERR_FILENO, stderr_file); - - if (error.Fail()) - return CoreSimulatorSupport::Process(error); - -#undef kSimDeviceSpawnEnvironment -#undef kSimDeviceSpawnStdin -#undef kSimDeviceSpawnStdout -#undef kSimDeviceSpawnStderr -#undef kSimDeviceSpawnWaitForDebugger -#undef kSimDeviceSpawnArguments - - NSError *nserror; - - pid_t pid = [m_dev - spawnWithPath:[NSString stringWithUTF8String:launch_info - .GetExecutableFile() - .GetPath() - .c_str()] - options:options - terminationHandler:nil - error:&nserror]; - - if (pid < 0) { - const char *nserror_string = [[nserror description] UTF8String]; - error.SetErrorString(nserror_string ? nserror_string : "unable to launch"); - } - - return CoreSimulatorSupport::Process(pid, error); -} - -CoreSimulatorSupport::DeviceSet -CoreSimulatorSupport::DeviceSet::GetAllDevices(const char *developer_dir) { - if (!developer_dir || !developer_dir[0]) - return DeviceSet([NSArray new]); - - Class SimServiceContextClass = NSClassFromString(@"SimServiceContext"); - NSString *dev_dir = @(developer_dir); - NSError *error = nil; - - id serviceContext = - [SimServiceContextClass sharedServiceContextForDeveloperDir:dev_dir - error:&error]; - if (!serviceContext) - return DeviceSet([NSArray new]); - - return DeviceSet([[serviceContext defaultDeviceSetWithError:&error] devices]); -} - -CoreSimulatorSupport::DeviceSet -CoreSimulatorSupport::DeviceSet::GetAvailableDevices( - const char *developer_dir) { - return GetAllDevices(developer_dir).GetDevicesIf([](Device d) -> bool { - return (d && d.GetDeviceType() && d.GetDeviceRuntime() && - d.GetDeviceRuntime().IsAvailable()); - }); -} - -size_t CoreSimulatorSupport::DeviceSet::GetNumDevices() { - return [m_dev count]; -} - -CoreSimulatorSupport::Device -CoreSimulatorSupport::DeviceSet::GetDeviceAtIndex(size_t idx) { - if (idx < GetNumDevices()) - return Device([m_dev objectAtIndex:idx]); - return Device(); -} - -CoreSimulatorSupport::DeviceSet CoreSimulatorSupport::DeviceSet::GetDevicesIf( - std::function<bool(CoreSimulatorSupport::Device)> f) { - NSMutableArray *array = [[NSMutableArray alloc] init]; - for (NSUInteger i = 0; i < GetNumDevices(); i++) { - Device d(GetDeviceAtIndex(i)); - if (f(d)) - [array addObject:(id)d.m_dev]; - } - - return DeviceSet(array); -} - -void CoreSimulatorSupport::DeviceSet::ForEach( - std::function<bool(const Device &)> f) { - const size_t n = GetNumDevices(); - for (NSUInteger i = 0; i < n; ++i) { - if (f(GetDeviceAtIndex(i)) == false) - break; - } -} - -CoreSimulatorSupport::DeviceSet CoreSimulatorSupport::DeviceSet::GetDevices( - CoreSimulatorSupport::DeviceType::ProductFamilyID dev_id) { - NSMutableArray *array = [[NSMutableArray alloc] init]; - const size_t n = GetNumDevices(); - for (NSUInteger i = 0; i < n; ++i) { - Device d(GetDeviceAtIndex(i)); - if (d && d.GetDeviceType() && - d.GetDeviceType().GetProductFamilyID() == dev_id) - [array addObject:(id)d.m_dev]; - } - - return DeviceSet(array); -} - -CoreSimulatorSupport::Device CoreSimulatorSupport::DeviceSet::GetFanciest( - CoreSimulatorSupport::DeviceType::ProductFamilyID dev_id) { - Device dev; - - for (NSUInteger i = 0; i < GetNumDevices(); i++) { - Device d(GetDeviceAtIndex(i)); - if (d && d.GetDeviceType() && - d.GetDeviceType().GetProductFamilyID() == dev_id) { - if (!dev) - dev = d; - else { - if ((d.GetDeviceType().GetModelIdentifier() > - dev.GetDeviceType().GetModelIdentifier()) || - d.GetDeviceRuntime().GetVersion() > - dev.GetDeviceRuntime().GetVersion()) - dev = d; - } - } - } - - return dev; -} Added: lldb/trunk/source/Plugins/Platform/MacOSX/objcxx/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/MacOSX/objcxx/CMakeLists.txt?rev=334611&view=auto ============================================================================== --- lldb/trunk/source/Plugins/Platform/MacOSX/objcxx/CMakeLists.txt (added) +++ lldb/trunk/source/Plugins/Platform/MacOSX/objcxx/CMakeLists.txt Wed Jun 13 08:50:45 2018 @@ -0,0 +1,18 @@ +remove_module_flags() +include_directories(..) + +add_lldb_library(lldbPluginPlatformMacOSXObjCXX + PlatformiOSSimulatorCoreSimulatorSupport.mm + + LINK_LIBS + lldbCore + lldbSymbol + lldbTarget + lldbUtility + ${LLDB_PLUGINS} + ${EXTRA_LIBS} + + LINK_COMPONENTS + Object + Support + ) Copied: lldb/trunk/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.mm (from r334557, lldb/trunk/source/Plugins/Platform/MacOSX/PlatformiOSSimulatorCoreSimulatorSupport.mm) URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.mm?p2=lldb/trunk/source/Plugins/Platform/MacOSX/objcxx/PlatformiOSSimulatorCoreSimulatorSupport.mm&p1=lldb/trunk/source/Plugins/Platform/MacOSX/PlatformiOSSimulatorCoreSimulatorSupport.mm&r1=334557&r2=334611&rev=334611&view=diff ============================================================================== (empty) _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits