diff options
Diffstat (limited to 'source/Host/macosx')
19 files changed, 0 insertions, 3990 deletions
diff --git a/source/Host/macosx/Symbols.cpp b/source/Host/macosx/Symbols.cpp deleted file mode 100644 index 980bbc34449c..000000000000 --- a/source/Host/macosx/Symbols.cpp +++ /dev/null @@ -1,655 +0,0 @@ -//===-- Symbols.cpp ---------------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "lldb/Host/Symbols.h" - -#include <dirent.h> -#include <pwd.h> - -#include <CoreFoundation/CoreFoundation.h> - -#include "Host/macosx/cfcpp/CFCBundle.h" -#include "Host/macosx/cfcpp/CFCData.h" -#include "Host/macosx/cfcpp/CFCReleaser.h" -#include "Host/macosx/cfcpp/CFCString.h" -#include "lldb/Core/ModuleList.h" -#include "lldb/Core/ModuleSpec.h" -#include "lldb/Host/Host.h" -#include "lldb/Symbol/ObjectFile.h" -#include "lldb/Utility/ArchSpec.h" -#include "lldb/Utility/CleanUp.h" -#include "lldb/Utility/DataBuffer.h" -#include "lldb/Utility/DataExtractor.h" -#include "lldb/Utility/Endian.h" -#include "lldb/Utility/Log.h" -#include "lldb/Utility/StreamString.h" -#include "lldb/Utility/Timer.h" -#include "lldb/Utility/UUID.h" -#include "mach/machine.h" - -#include "llvm/Support/FileSystem.h" - -using namespace lldb; -using namespace lldb_private; - -#if !defined(__arm__) && !defined(__arm64__) && \ - !defined(__aarch64__) // No DebugSymbols on the iOS devices -extern "C" { - -CFURLRef DBGCopyFullDSYMURLForUUID(CFUUIDRef uuid, CFURLRef exec_url); -CFDictionaryRef DBGCopyDSYMPropertyLists(CFURLRef dsym_url); -} -#endif - -int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec, - ModuleSpec &return_module_spec) { - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); - if (!ModuleList::GetGlobalModuleListProperties().GetEnableExternalLookup()) { - if (log) - log->Printf("Spotlight lookup for .dSYM bundles is disabled."); - return 0; - } - - return_module_spec = module_spec; - return_module_spec.GetFileSpec().Clear(); - return_module_spec.GetSymbolFileSpec().Clear(); - - int items_found = 0; - -#if !defined(__arm__) && !defined(__arm64__) && \ - !defined(__aarch64__) // No DebugSymbols on the iOS devices - - const UUID *uuid = module_spec.GetUUIDPtr(); - const ArchSpec *arch = module_spec.GetArchitecturePtr(); - - if (uuid && uuid->IsValid()) { - // Try and locate the dSYM file using DebugSymbols first - llvm::ArrayRef<uint8_t> module_uuid = uuid->GetBytes(); - if (module_uuid.size() == 16) { - CFCReleaser<CFUUIDRef> module_uuid_ref(::CFUUIDCreateWithBytes( - NULL, module_uuid[0], module_uuid[1], module_uuid[2], module_uuid[3], - module_uuid[4], module_uuid[5], module_uuid[6], module_uuid[7], - module_uuid[8], module_uuid[9], module_uuid[10], module_uuid[11], - module_uuid[12], module_uuid[13], module_uuid[14], module_uuid[15])); - - if (module_uuid_ref.get()) { - CFCReleaser<CFURLRef> exec_url; - const FileSpec *exec_fspec = module_spec.GetFileSpecPtr(); - if (exec_fspec) { - char exec_cf_path[PATH_MAX]; - if (exec_fspec->GetPath(exec_cf_path, sizeof(exec_cf_path))) - exec_url.reset(::CFURLCreateFromFileSystemRepresentation( - NULL, (const UInt8 *)exec_cf_path, strlen(exec_cf_path), - FALSE)); - } - - CFCReleaser<CFURLRef> dsym_url( - ::DBGCopyFullDSYMURLForUUID(module_uuid_ref.get(), exec_url.get())); - char path[PATH_MAX]; - - if (dsym_url.get()) { - if (::CFURLGetFileSystemRepresentation( - dsym_url.get(), true, (UInt8 *)path, sizeof(path) - 1)) { - if (log) { - log->Printf("DebugSymbols framework returned dSYM path of %s for " - "UUID %s -- looking for the dSYM", - path, uuid->GetAsString().c_str()); - } - FileSpec dsym_filespec(path); - if (path[0] == '~') - FileSystem::Instance().Resolve(dsym_filespec); - - if (FileSystem::Instance().IsDirectory(dsym_filespec)) { - dsym_filespec = - Symbols::FindSymbolFileInBundle(dsym_filespec, uuid, arch); - ++items_found; - } else { - ++items_found; - } - return_module_spec.GetSymbolFileSpec() = dsym_filespec; - } - - bool success = false; - if (log) { - if (::CFURLGetFileSystemRepresentation( - dsym_url.get(), true, (UInt8 *)path, sizeof(path) - 1)) { - log->Printf("DebugSymbols framework returned dSYM path of %s for " - "UUID %s -- looking for an exec file", - path, uuid->GetAsString().c_str()); - } - } - - CFCReleaser<CFDictionaryRef> dict( - ::DBGCopyDSYMPropertyLists(dsym_url.get())); - CFDictionaryRef uuid_dict = NULL; - if (dict.get()) { - CFCString uuid_cfstr(uuid->GetAsString().c_str()); - uuid_dict = static_cast<CFDictionaryRef>( - ::CFDictionaryGetValue(dict.get(), uuid_cfstr.get())); - } - if (uuid_dict) { - CFStringRef exec_cf_path = - static_cast<CFStringRef>(::CFDictionaryGetValue( - uuid_dict, CFSTR("DBGSymbolRichExecutable"))); - if (exec_cf_path && ::CFStringGetFileSystemRepresentation( - exec_cf_path, path, sizeof(path))) { - if (log) { - log->Printf("plist bundle has exec path of %s for UUID %s", - path, uuid->GetAsString().c_str()); - } - ++items_found; - FileSpec exec_filespec(path); - if (path[0] == '~') - FileSystem::Instance().Resolve(exec_filespec); - if (FileSystem::Instance().Exists(exec_filespec)) { - success = true; - return_module_spec.GetFileSpec() = exec_filespec; - } - } - } - - if (!success) { - // No dictionary, check near the dSYM bundle for an executable that - // matches... - if (::CFURLGetFileSystemRepresentation( - dsym_url.get(), true, (UInt8 *)path, sizeof(path) - 1)) { - char *dsym_extension_pos = ::strstr(path, ".dSYM"); - if (dsym_extension_pos) { - *dsym_extension_pos = '\0'; - if (log) { - log->Printf("Looking for executable binary next to dSYM " - "bundle with name with name %s", - path); - } - FileSpec file_spec(path); - FileSystem::Instance().Resolve(file_spec); - ModuleSpecList module_specs; - ModuleSpec matched_module_spec; - using namespace llvm::sys::fs; - switch (get_file_type(file_spec.GetPath())) { - - case file_type::directory_file: // Bundle directory? - { - CFCBundle bundle(path); - CFCReleaser<CFURLRef> bundle_exe_url( - bundle.CopyExecutableURL()); - if (bundle_exe_url.get()) { - if (::CFURLGetFileSystemRepresentation(bundle_exe_url.get(), - true, (UInt8 *)path, - sizeof(path) - 1)) { - FileSpec bundle_exe_file_spec(path); - FileSystem::Instance().Resolve(bundle_exe_file_spec); - if (ObjectFile::GetModuleSpecifications( - bundle_exe_file_spec, 0, 0, module_specs) && - module_specs.FindMatchingModuleSpec( - module_spec, matched_module_spec)) - - { - ++items_found; - return_module_spec.GetFileSpec() = bundle_exe_file_spec; - if (log) { - log->Printf("Executable binary %s next to dSYM is " - "compatible; using", - path); - } - } - } - } - } break; - - case file_type::fifo_file: // Forget pipes - case file_type::socket_file: // We can't process socket files - case file_type::file_not_found: // File doesn't exist... - case file_type::status_error: - break; - - case file_type::type_unknown: - case file_type::regular_file: - case file_type::symlink_file: - case file_type::block_file: - case file_type::character_file: - if (ObjectFile::GetModuleSpecifications(file_spec, 0, 0, - module_specs) && - module_specs.FindMatchingModuleSpec(module_spec, - matched_module_spec)) - - { - ++items_found; - return_module_spec.GetFileSpec() = file_spec; - if (log) { - log->Printf("Executable binary %s next to dSYM is " - "compatible; using", - path); - } - } - break; - } - } - } - } - } - } - } - } -#endif // #if !defined (__arm__) && !defined (__arm64__) && !defined - // (__aarch64__) - - return items_found; -} - -FileSpec Symbols::FindSymbolFileInBundle(const FileSpec &dsym_bundle_fspec, - const lldb_private::UUID *uuid, - const ArchSpec *arch) { - char path[PATH_MAX]; - if (dsym_bundle_fspec.GetPath(path, sizeof(path)) == 0) - return {}; - - ::strncat(path, "/Contents/Resources/DWARF", sizeof(path) - strlen(path) - 1); - - DIR *dirp = opendir(path); - if (!dirp) - return {}; - - // Make sure we close the directory before exiting this scope. - CleanUp cleanup_dir(closedir, dirp); - - FileSpec dsym_fspec; - dsym_fspec.GetDirectory().SetCString(path); - struct dirent *dp; - while ((dp = readdir(dirp)) != NULL) { - // Only search directories - if (dp->d_type == DT_DIR || dp->d_type == DT_UNKNOWN) { - if (dp->d_namlen == 1 && dp->d_name[0] == '.') - continue; - - if (dp->d_namlen == 2 && dp->d_name[0] == '.' && dp->d_name[1] == '.') - continue; - } - - if (dp->d_type == DT_REG || dp->d_type == DT_UNKNOWN) { - dsym_fspec.GetFilename().SetCString(dp->d_name); - ModuleSpecList module_specs; - if (ObjectFile::GetModuleSpecifications(dsym_fspec, 0, 0, module_specs)) { - ModuleSpec spec; - for (size_t i = 0; i < module_specs.GetSize(); ++i) { - bool got_spec = module_specs.GetModuleSpecAtIndex(i, spec); - UNUSED_IF_ASSERT_DISABLED(got_spec); - assert(got_spec); - if ((uuid == NULL || - (spec.GetUUIDPtr() && spec.GetUUID() == *uuid)) && - (arch == NULL || - (spec.GetArchitecturePtr() && - spec.GetArchitecture().IsCompatibleMatch(*arch)))) { - return dsym_fspec; - } - } - } - } - } - - return {}; -} - -static bool GetModuleSpecInfoFromUUIDDictionary(CFDictionaryRef uuid_dict, - ModuleSpec &module_spec) { - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); - bool success = false; - if (uuid_dict != NULL && CFGetTypeID(uuid_dict) == CFDictionaryGetTypeID()) { - std::string str; - CFStringRef cf_str; - CFDictionaryRef cf_dict; - - cf_str = (CFStringRef)CFDictionaryGetValue( - (CFDictionaryRef)uuid_dict, CFSTR("DBGSymbolRichExecutable")); - if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) { - if (CFCString::FileSystemRepresentation(cf_str, str)) { - module_spec.GetFileSpec().SetFile(str.c_str(), FileSpec::Style::native); - FileSystem::Instance().Resolve(module_spec.GetFileSpec()); - if (log) { - log->Printf( - "From dsymForUUID plist: Symbol rich executable is at '%s'", - str.c_str()); - } - } - } - - cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict, - CFSTR("DBGDSYMPath")); - if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) { - if (CFCString::FileSystemRepresentation(cf_str, str)) { - module_spec.GetSymbolFileSpec().SetFile(str.c_str(), - FileSpec::Style::native); - FileSystem::Instance().Resolve(module_spec.GetFileSpec()); - success = true; - if (log) { - log->Printf("From dsymForUUID plist: dSYM is at '%s'", str.c_str()); - } - } - } - - cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict, - CFSTR("DBGArchitecture")); - if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) { - if (CFCString::FileSystemRepresentation(cf_str, str)) - module_spec.GetArchitecture().SetTriple(str.c_str()); - } - - std::string DBGBuildSourcePath; - std::string DBGSourcePath; - - // If DBGVersion 1 or DBGVersion missing, ignore DBGSourcePathRemapping. - // If DBGVersion 2, strip last two components of path remappings from - // entries to fix an issue with a specific set of - // DBGSourcePathRemapping entries that lldb worked - // with. - // If DBGVersion 3, trust & use the source path remappings as-is. - // - cf_dict = (CFDictionaryRef)CFDictionaryGetValue( - (CFDictionaryRef)uuid_dict, CFSTR("DBGSourcePathRemapping")); - if (cf_dict && CFGetTypeID(cf_dict) == CFDictionaryGetTypeID()) { - // If we see DBGVersion with a value of 2 or higher, this is a new style - // DBGSourcePathRemapping dictionary - bool new_style_source_remapping_dictionary = false; - bool do_truncate_remapping_names = false; - std::string original_DBGSourcePath_value = DBGSourcePath; - cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict, - CFSTR("DBGVersion")); - if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) { - std::string version; - CFCString::FileSystemRepresentation(cf_str, version); - if (!version.empty() && isdigit(version[0])) { - int version_number = atoi(version.c_str()); - if (version_number > 1) { - new_style_source_remapping_dictionary = true; - } - if (version_number == 2) { - do_truncate_remapping_names = true; - } - } - } - - CFIndex kv_pair_count = CFDictionaryGetCount((CFDictionaryRef)uuid_dict); - if (kv_pair_count > 0) { - CFStringRef *keys = - (CFStringRef *)malloc(kv_pair_count * sizeof(CFStringRef)); - CFStringRef *values = - (CFStringRef *)malloc(kv_pair_count * sizeof(CFStringRef)); - if (keys != nullptr && values != nullptr) { - CFDictionaryGetKeysAndValues((CFDictionaryRef)uuid_dict, - (const void **)keys, - (const void **)values); - } - for (CFIndex i = 0; i < kv_pair_count; i++) { - DBGBuildSourcePath.clear(); - DBGSourcePath.clear(); - if (keys[i] && CFGetTypeID(keys[i]) == CFStringGetTypeID()) { - CFCString::FileSystemRepresentation(keys[i], DBGBuildSourcePath); - } - if (values[i] && CFGetTypeID(values[i]) == CFStringGetTypeID()) { - CFCString::FileSystemRepresentation(values[i], DBGSourcePath); - } - if (!DBGBuildSourcePath.empty() && !DBGSourcePath.empty()) { - // In the "old style" DBGSourcePathRemapping dictionary, the - // DBGSourcePath values (the "values" half of key-value path pairs) - // were wrong. Ignore them and use the universal DBGSourcePath - // string from earlier. - if (new_style_source_remapping_dictionary && - !original_DBGSourcePath_value.empty()) { - DBGSourcePath = original_DBGSourcePath_value; - } - if (DBGSourcePath[0] == '~') { - FileSpec resolved_source_path(DBGSourcePath.c_str()); - FileSystem::Instance().Resolve(resolved_source_path); - DBGSourcePath = resolved_source_path.GetPath(); - } - // With version 2 of DBGSourcePathRemapping, we can chop off the - // last two filename parts from the source remapping and get a more - // general source remapping that still works. Add this as another - // option in addition to the full source path remap. - module_spec.GetSourceMappingList().Append( - ConstString(DBGBuildSourcePath.c_str()), - ConstString(DBGSourcePath.c_str()), true); - if (do_truncate_remapping_names) { - FileSpec build_path(DBGBuildSourcePath.c_str()); - FileSpec source_path(DBGSourcePath.c_str()); - build_path.RemoveLastPathComponent(); - build_path.RemoveLastPathComponent(); - source_path.RemoveLastPathComponent(); - source_path.RemoveLastPathComponent(); - module_spec.GetSourceMappingList().Append( - ConstString(build_path.GetPath().c_str()), - ConstString(source_path.GetPath().c_str()), true); - } - } - } - if (keys) - free(keys); - if (values) - free(values); - } - } - - - // If we have a DBGBuildSourcePath + DBGSourcePath pair, append them to the - // source remappings list. - - cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict, - CFSTR("DBGBuildSourcePath")); - if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) { - CFCString::FileSystemRepresentation(cf_str, DBGBuildSourcePath); - } - - cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict, - CFSTR("DBGSourcePath")); - if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) { - CFCString::FileSystemRepresentation(cf_str, DBGSourcePath); - } - - if (!DBGBuildSourcePath.empty() && !DBGSourcePath.empty()) { - if (DBGSourcePath[0] == '~') { - FileSpec resolved_source_path(DBGSourcePath.c_str()); - FileSystem::Instance().Resolve(resolved_source_path); - DBGSourcePath = resolved_source_path.GetPath(); - } - module_spec.GetSourceMappingList().Append( - ConstString(DBGBuildSourcePath.c_str()), - ConstString(DBGSourcePath.c_str()), true); - } - } - return success; -} - -bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec, - bool force_lookup) { - bool success = false; - const UUID *uuid_ptr = module_spec.GetUUIDPtr(); - const FileSpec *file_spec_ptr = module_spec.GetFileSpecPtr(); - - // It's expensive to check for the DBGShellCommands defaults setting, only do - // it once per lldb run and cache the result. - static bool g_have_checked_for_dbgshell_command = false; - static const char *g_dbgshell_command = NULL; - if (!g_have_checked_for_dbgshell_command) { - g_have_checked_for_dbgshell_command = true; - CFTypeRef defaults_setting = CFPreferencesCopyAppValue( - CFSTR("DBGShellCommands"), CFSTR("com.apple.DebugSymbols")); - if (defaults_setting && - CFGetTypeID(defaults_setting) == CFStringGetTypeID()) { - char cstr_buf[PATH_MAX]; - if (CFStringGetCString((CFStringRef)defaults_setting, cstr_buf, - sizeof(cstr_buf), kCFStringEncodingUTF8)) { - g_dbgshell_command = - strdup(cstr_buf); // this malloc'ed memory will never be freed - } - } - if (defaults_setting) { - CFRelease(defaults_setting); - } - } - - // When g_dbgshell_command is NULL, the user has not enabled the use of an - // external program to find the symbols, don't run it for them. - if (!force_lookup && g_dbgshell_command == NULL) { - return false; - } - - if (uuid_ptr || - (file_spec_ptr && FileSystem::Instance().Exists(*file_spec_ptr))) { - static bool g_located_dsym_for_uuid_exe = false; - static bool g_dsym_for_uuid_exe_exists = false; - static char g_dsym_for_uuid_exe_path[PATH_MAX]; - if (!g_located_dsym_for_uuid_exe) { - g_located_dsym_for_uuid_exe = true; - const char *dsym_for_uuid_exe_path_cstr = - getenv("LLDB_APPLE_DSYMFORUUID_EXECUTABLE"); - FileSpec dsym_for_uuid_exe_spec; - if (dsym_for_uuid_exe_path_cstr) { - dsym_for_uuid_exe_spec.SetFile(dsym_for_uuid_exe_path_cstr, - FileSpec::Style::native); - FileSystem::Instance().Resolve(dsym_for_uuid_exe_spec); - g_dsym_for_uuid_exe_exists = - FileSystem::Instance().Exists(dsym_for_uuid_exe_spec); - } - - if (!g_dsym_for_uuid_exe_exists) { - dsym_for_uuid_exe_spec.SetFile("/usr/local/bin/dsymForUUID", - FileSpec::Style::native); - g_dsym_for_uuid_exe_exists = - FileSystem::Instance().Exists(dsym_for_uuid_exe_spec); - if (!g_dsym_for_uuid_exe_exists) { - long bufsize; - if ((bufsize = sysconf(_SC_GETPW_R_SIZE_MAX)) != -1) { - char buffer[bufsize]; - struct passwd pwd; - struct passwd *tilde_rc = NULL; - // we are a library so we need to use the reentrant version of - // getpwnam() - if (getpwnam_r("rc", &pwd, buffer, bufsize, &tilde_rc) == 0 && - tilde_rc && tilde_rc->pw_dir) { - std::string dsymforuuid_path(tilde_rc->pw_dir); - dsymforuuid_path += "/bin/dsymForUUID"; - dsym_for_uuid_exe_spec.SetFile(dsymforuuid_path.c_str(), - FileSpec::Style::native); - g_dsym_for_uuid_exe_exists = - FileSystem::Instance().Exists(dsym_for_uuid_exe_spec); - } - } - } - } - if (!g_dsym_for_uuid_exe_exists && g_dbgshell_command != NULL) { - dsym_for_uuid_exe_spec.SetFile(g_dbgshell_command, - FileSpec::Style::native); - FileSystem::Instance().Resolve(dsym_for_uuid_exe_spec); - g_dsym_for_uuid_exe_exists = - FileSystem::Instance().Exists(dsym_for_uuid_exe_spec); - } - - if (g_dsym_for_uuid_exe_exists) - dsym_for_uuid_exe_spec.GetPath(g_dsym_for_uuid_exe_path, - sizeof(g_dsym_for_uuid_exe_path)); - } - if (g_dsym_for_uuid_exe_exists) { - std::string uuid_str; - char file_path[PATH_MAX]; - file_path[0] = '\0'; - - if (uuid_ptr) - uuid_str = uuid_ptr->GetAsString(); - - if (file_spec_ptr) - file_spec_ptr->GetPath(file_path, sizeof(file_path)); - - StreamString command; - if (!uuid_str.empty()) - command.Printf("%s --ignoreNegativeCache --copyExecutable %s", - g_dsym_for_uuid_exe_path, uuid_str.c_str()); - else if (file_path[0] != '\0') - command.Printf("%s --ignoreNegativeCache --copyExecutable %s", - g_dsym_for_uuid_exe_path, file_path); - - if (!command.GetString().empty()) { - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); - int exit_status = -1; - int signo = -1; - std::string command_output; - if (log) { - if (!uuid_str.empty()) - log->Printf("Calling %s with UUID %s to find dSYM", - g_dsym_for_uuid_exe_path, uuid_str.c_str()); - else if (file_path[0] != '\0') - log->Printf("Calling %s with file %s to find dSYM", - g_dsym_for_uuid_exe_path, file_path); - } - Status error = Host::RunShellCommand( - command.GetData(), - NULL, // current working directory - &exit_status, // Exit status - &signo, // Signal int * - &command_output, // Command output - std::chrono::seconds( - 30), // Large timeout to allow for long dsym download times - false); // Don't run in a shell (we don't need shell expansion) - if (error.Success() && exit_status == 0 && !command_output.empty()) { - CFCData data(CFDataCreateWithBytesNoCopy( - NULL, (const UInt8 *)command_output.data(), command_output.size(), - kCFAllocatorNull)); - - CFCReleaser<CFDictionaryRef> plist( - (CFDictionaryRef)::CFPropertyListCreateFromXMLData( - NULL, data.get(), kCFPropertyListImmutable, NULL)); - - if (plist.get() && - CFGetTypeID(plist.get()) == CFDictionaryGetTypeID()) { - if (!uuid_str.empty()) { - CFCString uuid_cfstr(uuid_str.c_str()); - CFDictionaryRef uuid_dict = (CFDictionaryRef)CFDictionaryGetValue( - plist.get(), uuid_cfstr.get()); - success = - GetModuleSpecInfoFromUUIDDictionary(uuid_dict, module_spec); - } else { - const CFIndex num_values = ::CFDictionaryGetCount(plist.get()); - if (num_values > 0) { - std::vector<CFStringRef> keys(num_values, NULL); - std::vector<CFDictionaryRef> values(num_values, NULL); - ::CFDictionaryGetKeysAndValues(plist.get(), NULL, - (const void **)&values[0]); - if (num_values == 1) { - return GetModuleSpecInfoFromUUIDDictionary(values[0], - module_spec); - } else { - for (CFIndex i = 0; i < num_values; ++i) { - ModuleSpec curr_module_spec; - if (GetModuleSpecInfoFromUUIDDictionary(values[i], - curr_module_spec)) { - if (module_spec.GetArchitecture().IsCompatibleMatch( - curr_module_spec.GetArchitecture())) { - module_spec = curr_module_spec; - return true; - } - } - } - } - } - } - } - } else { - if (log) { - if (!uuid_str.empty()) - log->Printf("Called %s on %s, no matches", - g_dsym_for_uuid_exe_path, uuid_str.c_str()); - else if (file_path[0] != '\0') - log->Printf("Called %s on %s, no matches", - g_dsym_for_uuid_exe_path, file_path); - } - } - } - } - } - return success; -} diff --git a/source/Host/macosx/cfcpp/CFCBundle.cpp b/source/Host/macosx/cfcpp/CFCBundle.cpp deleted file mode 100644 index 08f16701c36f..000000000000 --- a/source/Host/macosx/cfcpp/CFCBundle.cpp +++ /dev/null @@ -1,83 +0,0 @@ -//===-- CFCBundle.cpp -------------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "CFCBundle.h" -#include "CFCString.h" - -//---------------------------------------------------------------------- -// CFCBundle constructor -//---------------------------------------------------------------------- -CFCBundle::CFCBundle(const char *path) : CFCReleaser<CFBundleRef>() { - if (path && path[0]) - SetPath(path); -} - -CFCBundle::CFCBundle(CFURLRef url) - : CFCReleaser<CFBundleRef>(url ? CFBundleCreate(NULL, url) : NULL) {} - -//---------------------------------------------------------------------- -// Destructor -//---------------------------------------------------------------------- -CFCBundle::~CFCBundle() {} - -//---------------------------------------------------------------------- -// Set the path for a bundle by supplying a -//---------------------------------------------------------------------- -bool CFCBundle::SetPath(const char *path) { - CFAllocatorRef alloc = kCFAllocatorDefault; - // Release our old bundle and URL - reset(); - - // Make a CFStringRef from the supplied path - CFCString cf_path; - cf_path.SetFileSystemRepresentation(path); - if (cf_path.get()) { - // Make our Bundle URL - CFCReleaser<CFURLRef> bundle_url(::CFURLCreateWithFileSystemPath( - alloc, cf_path.get(), kCFURLPOSIXPathStyle, true)); - if (bundle_url.get()) - reset(::CFBundleCreate(alloc, bundle_url.get())); - } - return get() != NULL; -} - -bool CFCBundle::GetPath(char *dst, size_t dst_len) { - CFBundleRef bundle = get(); - if (bundle) { - CFCReleaser<CFURLRef> bundle_url(CFBundleCopyBundleURL(bundle)); - if (bundle_url.get()) { - Boolean resolveAgainstBase = 0; - return ::CFURLGetFileSystemRepresentation(bundle_url.get(), - resolveAgainstBase, - (UInt8 *)dst, dst_len) != 0; - } - } - return false; -} - -CFStringRef CFCBundle::GetIdentifier() const { - CFBundleRef bundle = get(); - if (bundle != NULL) - return ::CFBundleGetIdentifier(bundle); - return NULL; -} - -CFTypeRef CFCBundle::GetValueForInfoDictionaryKey(CFStringRef key) const { - CFBundleRef bundle = get(); - if (bundle != NULL) - return ::CFBundleGetValueForInfoDictionaryKey(bundle, key); - return NULL; -} - -CFURLRef CFCBundle::CopyExecutableURL() const { - CFBundleRef bundle = get(); - if (bundle != NULL) - return CFBundleCopyExecutableURL(bundle); - return NULL; -} diff --git a/source/Host/macosx/cfcpp/CFCBundle.h b/source/Host/macosx/cfcpp/CFCBundle.h deleted file mode 100644 index 9506b93f6536..000000000000 --- a/source/Host/macosx/cfcpp/CFCBundle.h +++ /dev/null @@ -1,42 +0,0 @@ -//===-- CFCBundle.h ---------------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef CoreFoundationCPP_CFBundle_h_ -#define CoreFoundationCPP_CFBundle_h_ - -#include "CFCReleaser.h" - -class CFCBundle : public CFCReleaser<CFBundleRef> { -public: - //------------------------------------------------------------------ - // Constructors and Destructors - //------------------------------------------------------------------ - CFCBundle(const char *path = NULL); - CFCBundle(CFURLRef url); - - virtual ~CFCBundle(); - - CFURLRef CopyExecutableURL() const; - - CFStringRef GetIdentifier() const; - - CFTypeRef GetValueForInfoDictionaryKey(CFStringRef key) const; - - bool GetPath(char *dst, size_t dst_len); - - bool SetPath(const char *path); - -private: - // Disallow copy and assignment constructors - CFCBundle(const CFCBundle &); - - const CFCBundle &operator=(const CFCBundle &); -}; - -#endif // #ifndef CoreFoundationCPP_CFBundle_h_ diff --git a/source/Host/macosx/cfcpp/CFCData.cpp b/source/Host/macosx/cfcpp/CFCData.cpp deleted file mode 100644 index 95cadede8ff6..000000000000 --- a/source/Host/macosx/cfcpp/CFCData.cpp +++ /dev/null @@ -1,66 +0,0 @@ -//===-- CFCData.cpp ---------------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "CFCData.h" - -//---------------------------------------------------------------------- -// CFCData constructor -//---------------------------------------------------------------------- -CFCData::CFCData(CFDataRef data) : CFCReleaser<CFDataRef>(data) {} - -//---------------------------------------------------------------------- -// CFCData copy constructor -//---------------------------------------------------------------------- -CFCData::CFCData(const CFCData &rhs) : CFCReleaser<CFDataRef>(rhs) {} - -//---------------------------------------------------------------------- -// CFCData copy constructor -//---------------------------------------------------------------------- -CFCData &CFCData::operator=(const CFCData &rhs) - -{ - if (this != &rhs) - *this = rhs; - return *this; -} - -//---------------------------------------------------------------------- -// Destructor -//---------------------------------------------------------------------- -CFCData::~CFCData() {} - -CFIndex CFCData::GetLength() const { - CFDataRef data = get(); - if (data) - return CFDataGetLength(data); - return 0; -} - -const uint8_t *CFCData::GetBytePtr() const { - CFDataRef data = get(); - if (data) - return CFDataGetBytePtr(data); - return NULL; -} - -CFDataRef CFCData::Serialize(CFPropertyListRef plist, - CFPropertyListFormat format) { - CFAllocatorRef alloc = kCFAllocatorDefault; - reset(); - CFCReleaser<CFWriteStreamRef> stream( - ::CFWriteStreamCreateWithAllocatedBuffers(alloc, alloc)); - ::CFWriteStreamOpen(stream.get()); - CFIndex len = - ::CFPropertyListWriteToStream(plist, stream.get(), format, NULL); - if (len > 0) - reset((CFDataRef)::CFWriteStreamCopyProperty(stream.get(), - kCFStreamPropertyDataWritten)); - ::CFWriteStreamClose(stream.get()); - return get(); -} diff --git a/source/Host/macosx/cfcpp/CFCData.h b/source/Host/macosx/cfcpp/CFCData.h deleted file mode 100644 index e89d7bec7832..000000000000 --- a/source/Host/macosx/cfcpp/CFCData.h +++ /dev/null @@ -1,35 +0,0 @@ -//===-- CFCData.h -----------------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef CoreFoundationCPP_CFData_h_ -#define CoreFoundationCPP_CFData_h_ - -#include "CFCReleaser.h" - -class CFCData : public CFCReleaser<CFDataRef> { -public: - //------------------------------------------------------------------ - // Constructors and Destructors - //------------------------------------------------------------------ - CFCData(CFDataRef data = NULL); - CFCData(const CFCData &rhs); - CFCData &operator=(const CFCData &rhs); - virtual ~CFCData(); - - CFDataRef Serialize(CFPropertyListRef plist, CFPropertyListFormat format); - const uint8_t *GetBytePtr() const; - CFIndex GetLength() const; - -protected: - //------------------------------------------------------------------ - // Classes that inherit from CFCData can see and modify these - //------------------------------------------------------------------ -}; - -#endif // #ifndef CoreFoundationCPP_CFData_h_ diff --git a/source/Host/macosx/cfcpp/CFCMutableArray.cpp b/source/Host/macosx/cfcpp/CFCMutableArray.cpp deleted file mode 100644 index f426e9c13a59..000000000000 --- a/source/Host/macosx/cfcpp/CFCMutableArray.cpp +++ /dev/null @@ -1,140 +0,0 @@ -//===-- CFCMutableArray.cpp -------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "CFCMutableArray.h" -#include "CFCString.h" - -//---------------------------------------------------------------------- -// CFCString constructor -//---------------------------------------------------------------------- -CFCMutableArray::CFCMutableArray(CFMutableArrayRef s) - : CFCReleaser<CFMutableArrayRef>(s) {} - -//---------------------------------------------------------------------- -// CFCMutableArray copy constructor -//---------------------------------------------------------------------- -CFCMutableArray::CFCMutableArray(const CFCMutableArray &rhs) - : CFCReleaser<CFMutableArrayRef>(rhs) // NOTE: this won't make a copy of the - // array, just add a new reference to - // it -{} - -//---------------------------------------------------------------------- -// CFCMutableArray copy constructor -//---------------------------------------------------------------------- -CFCMutableArray &CFCMutableArray::operator=(const CFCMutableArray &rhs) { - if (this != &rhs) - *this = rhs; // NOTE: this operator won't make a copy of the array, just add - // a new reference to it - return *this; -} - -//---------------------------------------------------------------------- -// Destructor -//---------------------------------------------------------------------- -CFCMutableArray::~CFCMutableArray() {} - -CFIndex CFCMutableArray::GetCount() const { - CFMutableArrayRef array = get(); - if (array) - return ::CFArrayGetCount(array); - return 0; -} - -CFIndex CFCMutableArray::GetCountOfValue(CFRange range, - const void *value) const { - CFMutableArrayRef array = get(); - if (array) - return ::CFArrayGetCountOfValue(array, range, value); - return 0; -} - -CFIndex CFCMutableArray::GetCountOfValue(const void *value) const { - CFMutableArrayRef array = get(); - if (array) - return ::CFArrayGetCountOfValue(array, CFRangeMake(0, GetCount()), value); - return 0; -} - -const void *CFCMutableArray::GetValueAtIndex(CFIndex idx) const { - CFMutableArrayRef array = get(); - if (array) { - const CFIndex num_array_items = ::CFArrayGetCount(array); - if (0 <= idx && idx < num_array_items) { - return ::CFArrayGetValueAtIndex(array, idx); - } - } - return NULL; -} - -bool CFCMutableArray::SetValueAtIndex(CFIndex idx, const void *value) { - CFMutableArrayRef array = get(); - if (array != NULL) { - const CFIndex num_array_items = ::CFArrayGetCount(array); - if (0 <= idx && idx < num_array_items) { - ::CFArraySetValueAtIndex(array, idx, value); - return true; - } - } - return false; -} - -bool CFCMutableArray::AppendValue(const void *value, bool can_create) { - CFMutableArrayRef array = get(); - if (array == NULL) { - if (!can_create) - return false; - array = - ::CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); - reset(array); - } - if (array != NULL) { - ::CFArrayAppendValue(array, value); - return true; - } - return false; -} - -bool CFCMutableArray::AppendCStringAsCFString(const char *s, - CFStringEncoding encoding, - bool can_create) { - CFMutableArrayRef array = get(); - if (array == NULL) { - if (!can_create) - return false; - array = - ::CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); - reset(array); - } - if (array != NULL) { - CFCString cf_str(s, encoding); - ::CFArrayAppendValue(array, cf_str.get()); - return true; - } - return false; -} - -bool CFCMutableArray::AppendFileSystemRepresentationAsCFString( - const char *s, bool can_create) { - CFMutableArrayRef array = get(); - if (array == NULL) { - if (!can_create) - return false; - array = - ::CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); - reset(array); - } - if (array != NULL) { - CFCString cf_path; - cf_path.SetFileSystemRepresentation(s); - ::CFArrayAppendValue(array, cf_path.get()); - return true; - } - return false; -} diff --git a/source/Host/macosx/cfcpp/CFCMutableArray.h b/source/Host/macosx/cfcpp/CFCMutableArray.h deleted file mode 100644 index 23d1f932bfc7..000000000000 --- a/source/Host/macosx/cfcpp/CFCMutableArray.h +++ /dev/null @@ -1,46 +0,0 @@ -//===-- CFCMutableArray.h ---------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef CoreFoundationCPP_CFMutableArray_h_ -#define CoreFoundationCPP_CFMutableArray_h_ - -#include "CFCReleaser.h" - -class CFCMutableArray : public CFCReleaser<CFMutableArrayRef> { -public: - //------------------------------------------------------------------ - // Constructors and Destructors - //------------------------------------------------------------------ - CFCMutableArray(CFMutableArrayRef array = NULL); - CFCMutableArray(const CFCMutableArray &rhs); // This will copy the array - // contents into a new array - CFCMutableArray &operator=(const CFCMutableArray &rhs); // This will re-use - // the same array and - // just bump the ref - // count - virtual ~CFCMutableArray(); - - CFIndex GetCount() const; - CFIndex GetCountOfValue(const void *value) const; - CFIndex GetCountOfValue(CFRange range, const void *value) const; - const void *GetValueAtIndex(CFIndex idx) const; - bool SetValueAtIndex(CFIndex idx, const void *value); - bool AppendValue(const void *value, - bool can_create = true); // Appends value and optionally - // creates a CFCMutableArray if this - // class doesn't contain one - bool - AppendCStringAsCFString(const char *cstr, - CFStringEncoding encoding = kCFStringEncodingUTF8, - bool can_create = true); - bool AppendFileSystemRepresentationAsCFString(const char *s, - bool can_create = true); -}; - -#endif // #ifndef CoreFoundationCPP_CFMutableArray_h_ diff --git a/source/Host/macosx/cfcpp/CFCMutableDictionary.cpp b/source/Host/macosx/cfcpp/CFCMutableDictionary.cpp deleted file mode 100644 index 0c52aa3ed051..000000000000 --- a/source/Host/macosx/cfcpp/CFCMutableDictionary.cpp +++ /dev/null @@ -1,465 +0,0 @@ -//===-- CFCMutableDictionary.cpp --------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "CFCMutableDictionary.h" -#include "CFCString.h" -//---------------------------------------------------------------------- -// CFCString constructor -//---------------------------------------------------------------------- -CFCMutableDictionary::CFCMutableDictionary(CFMutableDictionaryRef s) - : CFCReleaser<CFMutableDictionaryRef>(s) {} - -//---------------------------------------------------------------------- -// CFCMutableDictionary copy constructor -//---------------------------------------------------------------------- -CFCMutableDictionary::CFCMutableDictionary(const CFCMutableDictionary &rhs) - : CFCReleaser<CFMutableDictionaryRef>(rhs) {} - -//---------------------------------------------------------------------- -// CFCMutableDictionary copy constructor -//---------------------------------------------------------------------- -const CFCMutableDictionary &CFCMutableDictionary:: -operator=(const CFCMutableDictionary &rhs) { - if (this != &rhs) - *this = rhs; - return *this; -} - -//---------------------------------------------------------------------- -// Destructor -//---------------------------------------------------------------------- -CFCMutableDictionary::~CFCMutableDictionary() {} - -CFIndex CFCMutableDictionary::GetCount() const { - CFMutableDictionaryRef dict = get(); - if (dict) - return ::CFDictionaryGetCount(dict); - return 0; -} - -CFIndex CFCMutableDictionary::GetCountOfKey(const void *key) const - -{ - CFMutableDictionaryRef dict = get(); - if (dict) - return ::CFDictionaryGetCountOfKey(dict, key); - return 0; -} - -CFIndex CFCMutableDictionary::GetCountOfValue(const void *value) const - -{ - CFMutableDictionaryRef dict = get(); - if (dict) - return ::CFDictionaryGetCountOfValue(dict, value); - return 0; -} - -void CFCMutableDictionary::GetKeysAndValues(const void **keys, - const void **values) const { - CFMutableDictionaryRef dict = get(); - if (dict) - ::CFDictionaryGetKeysAndValues(dict, keys, values); -} - -const void *CFCMutableDictionary::GetValue(const void *key) const - -{ - CFMutableDictionaryRef dict = get(); - if (dict) - return ::CFDictionaryGetValue(dict, key); - return NULL; -} - -Boolean -CFCMutableDictionary::GetValueIfPresent(const void *key, - const void **value_handle) const { - CFMutableDictionaryRef dict = get(); - if (dict) - return ::CFDictionaryGetValueIfPresent(dict, key, value_handle); - return false; -} - -CFMutableDictionaryRef CFCMutableDictionary::Dictionary(bool can_create) { - CFMutableDictionaryRef dict = get(); - if (can_create && dict == NULL) { - dict = ::CFDictionaryCreateMutable(kCFAllocatorDefault, 0, - &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); - reset(dict); - } - return dict; -} - -bool CFCMutableDictionary::AddValue(CFStringRef key, const void *value, - bool can_create) { - CFMutableDictionaryRef dict = Dictionary(can_create); - if (dict != NULL) { - // Let the dictionary own the CFNumber - ::CFDictionaryAddValue(dict, key, value); - return true; - } - return false; -} - -bool CFCMutableDictionary::SetValue(CFStringRef key, const void *value, - bool can_create) { - CFMutableDictionaryRef dict = Dictionary(can_create); - if (dict != NULL) { - // Let the dictionary own the CFNumber - ::CFDictionarySetValue(dict, key, value); - return true; - } - return false; -} - -bool CFCMutableDictionary::AddValueSInt8(CFStringRef key, int8_t value, - bool can_create) { - CFMutableDictionaryRef dict = Dictionary(can_create); - if (dict != NULL) { - CFCReleaser<CFNumberRef> cf_number( - ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt8Type, &value)); - if (cf_number.get()) { - // Let the dictionary own the CFNumber - ::CFDictionaryAddValue(dict, key, cf_number.get()); - return true; - } - } - return false; -} - -bool CFCMutableDictionary::SetValueSInt8(CFStringRef key, int8_t value, - bool can_create) { - CFMutableDictionaryRef dict = Dictionary(can_create); - if (dict != NULL) { - CFCReleaser<CFNumberRef> cf_number( - ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt8Type, &value)); - if (cf_number.get()) { - // Let the dictionary own the CFNumber - ::CFDictionarySetValue(dict, key, cf_number.get()); - return true; - } - } - return false; -} - -bool CFCMutableDictionary::AddValueSInt16(CFStringRef key, int16_t value, - bool can_create) { - CFMutableDictionaryRef dict = Dictionary(can_create); - if (dict != NULL) { - CFCReleaser<CFNumberRef> cf_number( - ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt16Type, &value)); - if (cf_number.get()) { - // Let the dictionary own the CFNumber - ::CFDictionaryAddValue(dict, key, cf_number.get()); - return true; - } - } - return false; -} - -bool CFCMutableDictionary::SetValueSInt16(CFStringRef key, int16_t value, - bool can_create) { - CFMutableDictionaryRef dict = Dictionary(can_create); - if (dict != NULL) { - CFCReleaser<CFNumberRef> cf_number( - ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt16Type, &value)); - if (cf_number.get()) { - // Let the dictionary own the CFNumber - ::CFDictionarySetValue(dict, key, cf_number.get()); - return true; - } - } - return false; -} - -bool CFCMutableDictionary::AddValueSInt32(CFStringRef key, int32_t value, - bool can_create) { - CFMutableDictionaryRef dict = Dictionary(can_create); - if (dict != NULL) { - CFCReleaser<CFNumberRef> cf_number( - ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value)); - if (cf_number.get()) { - // Let the dictionary own the CFNumber - ::CFDictionaryAddValue(dict, key, cf_number.get()); - return true; - } - } - return false; -} - -bool CFCMutableDictionary::SetValueSInt32(CFStringRef key, int32_t value, - bool can_create) { - CFMutableDictionaryRef dict = Dictionary(can_create); - if (dict != NULL) { - CFCReleaser<CFNumberRef> cf_number( - ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value)); - if (cf_number.get()) { - // Let the dictionary own the CFNumber - ::CFDictionarySetValue(dict, key, cf_number.get()); - return true; - } - } - return false; -} - -bool CFCMutableDictionary::AddValueSInt64(CFStringRef key, int64_t value, - bool can_create) { - CFMutableDictionaryRef dict = Dictionary(can_create); - if (dict != NULL) { - CFCReleaser<CFNumberRef> cf_number( - ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &value)); - if (cf_number.get()) { - // Let the dictionary own the CFNumber - ::CFDictionaryAddValue(dict, key, cf_number.get()); - return true; - } - } - return false; -} - -bool CFCMutableDictionary::SetValueSInt64(CFStringRef key, int64_t value, - bool can_create) { - CFMutableDictionaryRef dict = Dictionary(can_create); - if (dict != NULL) { - CFCReleaser<CFNumberRef> cf_number( - ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &value)); - if (cf_number.get()) { - // Let the dictionary own the CFNumber - ::CFDictionarySetValue(dict, key, cf_number.get()); - return true; - } - } - return false; -} - -bool CFCMutableDictionary::AddValueUInt8(CFStringRef key, uint8_t value, - bool can_create) { - CFMutableDictionaryRef dict = Dictionary(can_create); - if (dict != NULL) { - // Have to promote to the next size type so things don't appear negative of - // the MSBit is set... - int16_t sval = value; - CFCReleaser<CFNumberRef> cf_number( - ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt16Type, &sval)); - if (cf_number.get()) { - // Let the dictionary own the CFNumber - ::CFDictionaryAddValue(dict, key, cf_number.get()); - return true; - } - } - return false; -} - -bool CFCMutableDictionary::SetValueUInt8(CFStringRef key, uint8_t value, - bool can_create) { - CFMutableDictionaryRef dict = Dictionary(can_create); - if (dict != NULL) { - // Have to promote to the next size type so things don't appear negative of - // the MSBit is set... - int16_t sval = value; - CFCReleaser<CFNumberRef> cf_number( - ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt16Type, &sval)); - if (cf_number.get()) { - // Let the dictionary own the CFNumber - ::CFDictionarySetValue(dict, key, cf_number.get()); - return true; - } - } - return false; -} - -bool CFCMutableDictionary::AddValueUInt16(CFStringRef key, uint16_t value, - bool can_create) { - CFMutableDictionaryRef dict = Dictionary(can_create); - if (dict != NULL) { - // Have to promote to the next size type so things don't appear negative of - // the MSBit is set... - int32_t sval = value; - CFCReleaser<CFNumberRef> cf_number( - ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &sval)); - if (cf_number.get()) { - // Let the dictionary own the CFNumber - ::CFDictionaryAddValue(dict, key, cf_number.get()); - return true; - } - } - return false; -} - -bool CFCMutableDictionary::SetValueUInt16(CFStringRef key, uint16_t value, - bool can_create) { - CFMutableDictionaryRef dict = Dictionary(can_create); - if (dict != NULL) { - // Have to promote to the next size type so things don't appear negative of - // the MSBit is set... - int32_t sval = value; - CFCReleaser<CFNumberRef> cf_number( - ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &sval)); - if (cf_number.get()) { - // Let the dictionary own the CFNumber - ::CFDictionarySetValue(dict, key, cf_number.get()); - return true; - } - } - return false; -} - -bool CFCMutableDictionary::AddValueUInt32(CFStringRef key, uint32_t value, - bool can_create) { - CFMutableDictionaryRef dict = Dictionary(can_create); - if (dict != NULL) { - // Have to promote to the next size type so things don't appear negative of - // the MSBit is set... - int64_t sval = value; - CFCReleaser<CFNumberRef> cf_number( - ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &sval)); - if (cf_number.get()) { - // Let the dictionary own the CFNumber - ::CFDictionaryAddValue(dict, key, cf_number.get()); - return true; - } - } - return false; -} - -bool CFCMutableDictionary::SetValueUInt32(CFStringRef key, uint32_t value, - bool can_create) { - CFMutableDictionaryRef dict = Dictionary(can_create); - if (dict != NULL) { - // Have to promote to the next size type so things don't appear negative of - // the MSBit is set... - int64_t sval = value; - CFCReleaser<CFNumberRef> cf_number( - ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &sval)); - if (cf_number.get()) { - // Let the dictionary own the CFNumber - ::CFDictionarySetValue(dict, key, cf_number.get()); - return true; - } - } - return false; -} - -bool CFCMutableDictionary::AddValueUInt64(CFStringRef key, uint64_t value, - bool can_create) { - CFMutableDictionaryRef dict = Dictionary(can_create); - if (dict != NULL) { - // The number may appear negative if the MSBit is set in "value". Due to a - // limitation of CFNumber, there isn't a way to have it show up otherwise - // as of this writing. - CFCReleaser<CFNumberRef> cf_number( - ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &value)); - if (cf_number.get()) { - // Let the dictionary own the CFNumber - ::CFDictionaryAddValue(dict, key, cf_number.get()); - return true; - } - } - return false; -} - -bool CFCMutableDictionary::SetValueUInt64(CFStringRef key, uint64_t value, - bool can_create) { - CFMutableDictionaryRef dict = Dictionary(can_create); - if (dict != NULL) { - // The number may appear negative if the MSBit is set in "value". Due to a - // limitation of CFNumber, there isn't a way to have it show up otherwise - // as of this writing. - CFCReleaser<CFNumberRef> cf_number( - ::CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &value)); - if (cf_number.get()) { - // Let the dictionary own the CFNumber - ::CFDictionarySetValue(dict, key, cf_number.get()); - return true; - } - } - return false; -} - -bool CFCMutableDictionary::AddValueDouble(CFStringRef key, double value, - bool can_create) { - CFMutableDictionaryRef dict = Dictionary(can_create); - if (dict != NULL) { - // The number may appear negative if the MSBit is set in "value". Due to a - // limitation of CFNumber, there isn't a way to have it show up otherwise - // as of this writing. - CFCReleaser<CFNumberRef> cf_number( - ::CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &value)); - if (cf_number.get()) { - // Let the dictionary own the CFNumber - ::CFDictionaryAddValue(dict, key, cf_number.get()); - return true; - } - } - return false; -} - -bool CFCMutableDictionary::SetValueDouble(CFStringRef key, double value, - bool can_create) { - CFMutableDictionaryRef dict = Dictionary(can_create); - if (dict != NULL) { - // The number may appear negative if the MSBit is set in "value". Due to a - // limitation of CFNumber, there isn't a way to have it show up otherwise - // as of this writing. - CFCReleaser<CFNumberRef> cf_number( - ::CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &value)); - if (cf_number.get()) { - // Let the dictionary own the CFNumber - ::CFDictionarySetValue(dict, key, cf_number.get()); - return true; - } - } - return false; -} - -bool CFCMutableDictionary::AddValueCString(CFStringRef key, const char *cstr, - bool can_create) { - CFMutableDictionaryRef dict = Dictionary(can_create); - if (dict != NULL) { - CFCString cf_str(cstr, kCFStringEncodingUTF8); - if (cf_str.get()) { - // Let the dictionary own the CFNumber - ::CFDictionaryAddValue(dict, key, cf_str.get()); - return true; - } - } - return false; -} - -bool CFCMutableDictionary::SetValueCString(CFStringRef key, const char *cstr, - bool can_create) { - CFMutableDictionaryRef dict = Dictionary(can_create); - if (dict != NULL) { - CFCString cf_str(cstr, kCFStringEncodingUTF8); - if (cf_str.get()) { - // Let the dictionary own the CFNumber - ::CFDictionarySetValue(dict, key, cf_str.get()); - return true; - } - } - return false; -} - -void CFCMutableDictionary::RemoveAllValues() { - CFMutableDictionaryRef dict = get(); - if (dict) - ::CFDictionaryRemoveAllValues(dict); -} - -void CFCMutableDictionary::RemoveValue(const void *value) { - CFMutableDictionaryRef dict = get(); - if (dict) - ::CFDictionaryRemoveValue(dict, value); -} -void CFCMutableDictionary::ReplaceValue(const void *key, const void *value) { - CFMutableDictionaryRef dict = get(); - if (dict) - ::CFDictionaryReplaceValue(dict, key, value); -} diff --git a/source/Host/macosx/cfcpp/CFCMutableDictionary.h b/source/Host/macosx/cfcpp/CFCMutableDictionary.h deleted file mode 100644 index b30a2e616cd5..000000000000 --- a/source/Host/macosx/cfcpp/CFCMutableDictionary.h +++ /dev/null @@ -1,75 +0,0 @@ -//===-- CFCMutableDictionary.h ----------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef CoreFoundationCPP_CFMutableDictionary_h_ -#define CoreFoundationCPP_CFMutableDictionary_h_ - -#include "CFCReleaser.h" - -class CFCMutableDictionary : public CFCReleaser<CFMutableDictionaryRef> { -public: - //------------------------------------------------------------------ - // Constructors and Destructors - //------------------------------------------------------------------ - CFCMutableDictionary(CFMutableDictionaryRef s = NULL); - CFCMutableDictionary(const CFCMutableDictionary &rhs); - virtual ~CFCMutableDictionary(); - - //------------------------------------------------------------------ - // Operators - //------------------------------------------------------------------ - const CFCMutableDictionary &operator=(const CFCMutableDictionary &rhs); - - CFIndex GetCount() const; - CFIndex GetCountOfKey(const void *value) const; - CFIndex GetCountOfValue(const void *value) const; - void GetKeysAndValues(const void **keys, const void **values) const; - const void *GetValue(const void *key) const; - Boolean GetValueIfPresent(const void *key, const void **value_handle) const; - bool AddValue(CFStringRef key, const void *value, bool can_create = false); - bool SetValue(CFStringRef key, const void *value, bool can_create = false); - bool AddValueSInt8(CFStringRef key, int8_t value, bool can_create = false); - bool SetValueSInt8(CFStringRef key, int8_t value, bool can_create = false); - bool AddValueSInt16(CFStringRef key, int16_t value, bool can_create = false); - bool SetValueSInt16(CFStringRef key, int16_t value, bool can_create = false); - bool AddValueSInt32(CFStringRef key, int32_t value, bool can_create = false); - bool SetValueSInt32(CFStringRef key, int32_t value, bool can_create = false); - bool AddValueSInt64(CFStringRef key, int64_t value, bool can_create = false); - bool SetValueSInt64(CFStringRef key, int64_t value, bool can_create = false); - bool AddValueUInt8(CFStringRef key, uint8_t value, bool can_create = false); - bool SetValueUInt8(CFStringRef key, uint8_t value, bool can_create = false); - bool AddValueUInt16(CFStringRef key, uint16_t value, bool can_create = false); - bool SetValueUInt16(CFStringRef key, uint16_t value, bool can_create = false); - bool AddValueUInt32(CFStringRef key, uint32_t value, bool can_create = false); - bool SetValueUInt32(CFStringRef key, uint32_t value, bool can_create = false); - bool AddValueUInt64(CFStringRef key, uint64_t value, bool can_create = false); - bool SetValueUInt64(CFStringRef key, uint64_t value, bool can_create = false); - bool AddValueDouble(CFStringRef key, double value, bool can_create = false); - bool SetValueDouble(CFStringRef key, double value, bool can_create = false); - bool AddValueCString(CFStringRef key, const char *cstr, - bool can_create = false); - bool SetValueCString(CFStringRef key, const char *cstr, - bool can_create = false); - void RemoveValue(const void *value); - void ReplaceValue(const void *key, const void *value); - void RemoveAllValues(); - CFMutableDictionaryRef Dictionary(bool can_create); - -protected: - //------------------------------------------------------------------ - // Classes that inherit from CFCMutableDictionary can see and modify these - //------------------------------------------------------------------ - -private: - //------------------------------------------------------------------ - // For CFCMutableDictionary only - //------------------------------------------------------------------ -}; - -#endif // CoreFoundationCPP_CFMutableDictionary_h_ diff --git a/source/Host/macosx/cfcpp/CFCMutableSet.cpp b/source/Host/macosx/cfcpp/CFCMutableSet.cpp deleted file mode 100644 index b8bf81e1b52e..000000000000 --- a/source/Host/macosx/cfcpp/CFCMutableSet.cpp +++ /dev/null @@ -1,85 +0,0 @@ -//===-- CFCMutableSet.cpp ---------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "CFCMutableSet.h" - - -//---------------------------------------------------------------------- -// CFCString constructor -//---------------------------------------------------------------------- -CFCMutableSet::CFCMutableSet(CFMutableSetRef s) - : CFCReleaser<CFMutableSetRef>(s) {} - -//---------------------------------------------------------------------- -// CFCMutableSet copy constructor -//---------------------------------------------------------------------- -CFCMutableSet::CFCMutableSet(const CFCMutableSet &rhs) - : CFCReleaser<CFMutableSetRef>(rhs) {} - -//---------------------------------------------------------------------- -// CFCMutableSet copy constructor -//---------------------------------------------------------------------- -const CFCMutableSet &CFCMutableSet::operator=(const CFCMutableSet &rhs) { - if (this != &rhs) - *this = rhs; - return *this; -} - -//---------------------------------------------------------------------- -// Destructor -//---------------------------------------------------------------------- -CFCMutableSet::~CFCMutableSet() {} - -CFIndex CFCMutableSet::GetCount() const { - CFMutableSetRef set = get(); - if (set) - return ::CFSetGetCount(set); - return 0; -} - -CFIndex CFCMutableSet::GetCountOfValue(const void *value) const { - CFMutableSetRef set = get(); - if (set) - return ::CFSetGetCountOfValue(set, value); - return 0; -} - -const void *CFCMutableSet::GetValue(const void *value) const { - CFMutableSetRef set = get(); - if (set) - return ::CFSetGetValue(set, value); - return NULL; -} - -const void *CFCMutableSet::AddValue(const void *value, bool can_create) { - CFMutableSetRef set = get(); - if (set == NULL) { - if (!can_create) - return NULL; - set = ::CFSetCreateMutable(kCFAllocatorDefault, 0, &kCFTypeSetCallBacks); - reset(set); - } - if (set != NULL) { - ::CFSetAddValue(set, value); - return value; - } - return NULL; -} - -void CFCMutableSet::RemoveValue(const void *value) { - CFMutableSetRef set = get(); - if (set) - ::CFSetRemoveValue(set, value); -} - -void CFCMutableSet::RemoveAllValues() { - CFMutableSetRef set = get(); - if (set) - ::CFSetRemoveAllValues(set); -} diff --git a/source/Host/macosx/cfcpp/CFCMutableSet.h b/source/Host/macosx/cfcpp/CFCMutableSet.h deleted file mode 100644 index 1459b7e46328..000000000000 --- a/source/Host/macosx/cfcpp/CFCMutableSet.h +++ /dev/null @@ -1,47 +0,0 @@ -//===-- CFCMutableSet.h -----------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef CoreFoundationCPP_CFMutableSet_h_ -#define CoreFoundationCPP_CFMutableSet_h_ - -#include "CFCReleaser.h" - -class CFCMutableSet : public CFCReleaser<CFMutableSetRef> { -public: - //------------------------------------------------------------------ - // Constructors and Destructors - //------------------------------------------------------------------ - CFCMutableSet(CFMutableSetRef s = NULL); - CFCMutableSet(const CFCMutableSet &rhs); - virtual ~CFCMutableSet(); - - //------------------------------------------------------------------ - // Operators - //------------------------------------------------------------------ - const CFCMutableSet &operator=(const CFCMutableSet &rhs); - - CFIndex GetCount() const; - CFIndex GetCountOfValue(const void *value) const; - const void *GetValue(const void *value) const; - const void *AddValue(const void *value, bool can_create); - void RemoveValue(const void *value); - void RemoveAllValues(); - -protected: - //------------------------------------------------------------------ - // Classes that inherit from CFCMutableSet can see and modify these - //------------------------------------------------------------------ - -private: - //------------------------------------------------------------------ - // For CFCMutableSet only - //------------------------------------------------------------------ -}; - -#endif // CoreFoundationCPP_CFMutableSet_h_ diff --git a/source/Host/macosx/cfcpp/CFCReleaser.h b/source/Host/macosx/cfcpp/CFCReleaser.h deleted file mode 100644 index c596d1e1e7ed..000000000000 --- a/source/Host/macosx/cfcpp/CFCReleaser.h +++ /dev/null @@ -1,128 +0,0 @@ -//===-- CFCReleaser.h -------------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef CoreFoundationCPP_CFReleaser_h_ -#define CoreFoundationCPP_CFReleaser_h_ - -#include <CoreFoundation/CoreFoundation.h> - -#ifdef __cplusplus - -#include <assert.h> - -//---------------------------------------------------------------------- -// Templatized CF helper class that can own any CF pointer and will -// call CFRelease() on any valid pointer it owns unless that pointer is -// explicitly released using the release() member function. This class -// is designed to mimic the std::auto_ptr<T> class and has all of the -// same functions. The one thing to watch out for is the -// CFCReleaser<T>::release() function won't actually CFRelease any owned -// pointer, it is designed to relinquish ownership of the pointer just -// like std:auto_ptr<T>::release() does. -//---------------------------------------------------------------------- -template <class T> class CFCReleaser { -public: - //---------------------------------------------------------- - // Constructor that takes a pointer to a CF object that is - // to be released when this object goes out of scope - //---------------------------------------------------------- - CFCReleaser(T ptr = NULL) : _ptr(ptr) {} - - //---------------------------------------------------------- - // Copy constructor - // - // Note that copying a CFCReleaser will not transfer - // ownership of the contained pointer, but it will bump its - // reference count. This is where this class differs from - // std::auto_ptr. - //---------------------------------------------------------- - CFCReleaser(const CFCReleaser &rhs) : _ptr(rhs.get()) { - if (get()) - ::CFRetain(get()); - } - - //---------------------------------------------------------- - // The destructor will release the pointer that it contains - // if it has a valid pointer. - //---------------------------------------------------------- - virtual ~CFCReleaser() { reset(); } - - //---------------------------------------------------------- - // Assignment operator. - // - // Note that assigning one CFCReleaser to another will - // not transfer ownership of the contained pointer, but it - // will bump its reference count. This is where this class - // differs from std::auto_ptr. - //---------------------------------------------------------- - CFCReleaser &operator=(const CFCReleaser<T> &rhs) { - if (this != &rhs) { - // Replace our owned pointer with the new one - reset(rhs.get()); - // Retain the current pointer that we own - if (get()) - ::CFRetain(get()); - } - return *this; - } - - //---------------------------------------------------------- - // Get the address of the contained type in case it needs - // to be passed to a function that will fill in a pointer - // value. The function currently will assert if _ptr is not - // NULL because the only time this method should be used is - // if another function will modify the contents, and we - // could leak a pointer if this is not NULL. If the - // assertion fires, check the offending code, or call - // reset() prior to using the "ptr_address()" member to make - // sure any owned objects has CFRelease called on it. - // I had to add the "enforce_null" bool here because some - // API's require the pointer address even though they don't change it. - //---------------------------------------------------------- - T *ptr_address(bool enforce_null = true) { - if (enforce_null) - assert(_ptr == NULL); - return &_ptr; - } - - //---------------------------------------------------------- - // Access the pointer itself - //---------------------------------------------------------- - T get() { return _ptr; } - - const T get() const { return _ptr; } - - //---------------------------------------------------------- - // Set a new value for the pointer and CFRelease our old - // value if we had a valid one. - //---------------------------------------------------------- - void reset(T ptr = NULL) { - if ((_ptr != NULL) && (ptr != _ptr)) - ::CFRelease(_ptr); - _ptr = ptr; - } - - //---------------------------------------------------------- - // Release ownership without calling CFRelease. This class - // is designed to mimic std::auto_ptr<T>, so the release - // method releases ownership of the contained pointer - // and does NOT call CFRelease. - //---------------------------------------------------------- - T release() { - T tmp = _ptr; - _ptr = NULL; - return tmp; - } - -private: - T _ptr; -}; - -#endif // #ifdef __cplusplus -#endif // #ifndef CoreFoundationCPP_CFReleaser_h_ diff --git a/source/Host/macosx/cfcpp/CFCString.cpp b/source/Host/macosx/cfcpp/CFCString.cpp deleted file mode 100644 index 6191f873c98a..000000000000 --- a/source/Host/macosx/cfcpp/CFCString.cpp +++ /dev/null @@ -1,160 +0,0 @@ -//===-- CFCString.cpp -------------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "CFCString.h" -#include <glob.h> -#include <string> - -//---------------------------------------------------------------------- -// CFCString constructor -//---------------------------------------------------------------------- -CFCString::CFCString(CFStringRef s) : CFCReleaser<CFStringRef>(s) {} - -//---------------------------------------------------------------------- -// CFCString copy constructor -//---------------------------------------------------------------------- -CFCString::CFCString(const CFCString &rhs) : CFCReleaser<CFStringRef>(rhs) {} - -//---------------------------------------------------------------------- -// CFCString copy constructor -//---------------------------------------------------------------------- -CFCString &CFCString::operator=(const CFCString &rhs) { - if (this != &rhs) - *this = rhs; - return *this; -} - -CFCString::CFCString(const char *cstr, CFStringEncoding cstr_encoding) - : CFCReleaser<CFStringRef>() { - if (cstr && cstr[0]) { - reset( - ::CFStringCreateWithCString(kCFAllocatorDefault, cstr, cstr_encoding)); - } -} - -//---------------------------------------------------------------------- -// Destructor -//---------------------------------------------------------------------- -CFCString::~CFCString() {} - -const char *CFCString::GetFileSystemRepresentation(std::string &s) { - return CFCString::FileSystemRepresentation(get(), s); -} - -CFStringRef CFCString::SetFileSystemRepresentation(const char *path) { - CFStringRef new_value = NULL; - if (path && path[0]) - new_value = - ::CFStringCreateWithFileSystemRepresentation(kCFAllocatorDefault, path); - reset(new_value); - return get(); -} - -CFStringRef -CFCString::SetFileSystemRepresentationFromCFType(CFTypeRef cf_type) { - CFStringRef new_value = NULL; - if (cf_type != NULL) { - CFTypeID cf_type_id = ::CFGetTypeID(cf_type); - - if (cf_type_id == ::CFStringGetTypeID()) { - // Retain since we are using the existing object - new_value = (CFStringRef)::CFRetain(cf_type); - } else if (cf_type_id == ::CFURLGetTypeID()) { - new_value = - ::CFURLCopyFileSystemPath((CFURLRef)cf_type, kCFURLPOSIXPathStyle); - } - } - reset(new_value); - return get(); -} - -CFStringRef -CFCString::SetFileSystemRepresentationAndExpandTilde(const char *path) { - std::string expanded_path; - if (CFCString::ExpandTildeInPath(path, expanded_path)) - SetFileSystemRepresentation(expanded_path.c_str()); - else - reset(); - return get(); -} - -const char *CFCString::UTF8(std::string &str) { - return CFCString::UTF8(get(), str); -} - -// Static function that puts a copy of the UTF8 contents of CF_STR into STR and -// returns the C string pointer that is contained in STR when successful, else -// NULL is returned. This allows the std::string parameter to own the extracted -// string, -// and also allows that string to be returned as a C string pointer that can be -// used. - -const char *CFCString::UTF8(CFStringRef cf_str, std::string &str) { - if (cf_str) { - const CFStringEncoding encoding = kCFStringEncodingUTF8; - CFIndex max_utf8_str_len = CFStringGetLength(cf_str); - max_utf8_str_len = - CFStringGetMaximumSizeForEncoding(max_utf8_str_len, encoding); - if (max_utf8_str_len > 0) { - str.resize(max_utf8_str_len); - if (!str.empty()) { - if (CFStringGetCString(cf_str, &str[0], str.size(), encoding)) { - str.resize(strlen(str.c_str())); - return str.c_str(); - } - } - } - } - return NULL; -} - -const char *CFCString::ExpandTildeInPath(const char *path, - std::string &expanded_path) { - glob_t globbuf; - if (::glob(path, GLOB_TILDE, NULL, &globbuf) == 0) { - expanded_path = globbuf.gl_pathv[0]; - ::globfree(&globbuf); - } else - expanded_path.clear(); - - return expanded_path.c_str(); -} - -// Static function that puts a copy of the file system representation of CF_STR -// into STR and returns the C string pointer that is contained in STR when -// successful, else NULL is returned. This allows the std::string parameter to -// own the extracted string, and also allows that string to be returned as a C -// string pointer that can be used. - -const char *CFCString::FileSystemRepresentation(CFStringRef cf_str, - std::string &str) { - if (cf_str) { - CFIndex max_length = - ::CFStringGetMaximumSizeOfFileSystemRepresentation(cf_str); - if (max_length > 0) { - str.resize(max_length); - if (!str.empty()) { - if (::CFStringGetFileSystemRepresentation(cf_str, &str[0], - str.size())) { - str.erase(::strlen(str.c_str())); - return str.c_str(); - } - } - } - } - str.erase(); - return NULL; -} - -CFIndex CFCString::GetLength() const { - CFStringRef str = get(); - if (str) - return CFStringGetLength(str); - return 0; -} diff --git a/source/Host/macosx/cfcpp/CFCString.h b/source/Host/macosx/cfcpp/CFCString.h deleted file mode 100644 index a7bb029408fb..000000000000 --- a/source/Host/macosx/cfcpp/CFCString.h +++ /dev/null @@ -1,41 +0,0 @@ -//===-- CFCString.h ---------------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef CoreFoundationCPP_CFString_h_ -#define CoreFoundationCPP_CFString_h_ - -#include <iosfwd> - -#include "CFCReleaser.h" - -class CFCString : public CFCReleaser<CFStringRef> { -public: - //------------------------------------------------------------------ - // Constructors and Destructors - //------------------------------------------------------------------ - CFCString(CFStringRef cf_str = NULL); - CFCString(const char *s, CFStringEncoding encoding = kCFStringEncodingUTF8); - CFCString(const CFCString &rhs); - CFCString &operator=(const CFCString &rhs); - virtual ~CFCString(); - - const char *GetFileSystemRepresentation(std::string &str); - CFStringRef SetFileSystemRepresentation(const char *path); - CFStringRef SetFileSystemRepresentationFromCFType(CFTypeRef cf_type); - CFStringRef SetFileSystemRepresentationAndExpandTilde(const char *path); - const char *UTF8(std::string &str); - CFIndex GetLength() const; - static const char *UTF8(CFStringRef cf_str, std::string &str); - static const char *FileSystemRepresentation(CFStringRef cf_str, - std::string &str); - static const char *ExpandTildeInPath(const char *path, - std::string &expanded_path); -}; - -#endif // #ifndef CoreFoundationCPP_CFString_h_ diff --git a/source/Host/macosx/cfcpp/CoreFoundationCPP.h b/source/Host/macosx/cfcpp/CoreFoundationCPP.h deleted file mode 100644 index 88d0f5a23f80..000000000000 --- a/source/Host/macosx/cfcpp/CoreFoundationCPP.h +++ /dev/null @@ -1,30 +0,0 @@ -//===-- CoreFoundationCPP.h -------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -//---------------------------------------------------------------------- -// -// CoreFoundationCPP.h -// CoreFoundationCPP -// -// Created by Greg Clayton on 4/23/09. -// -// -//---------------------------------------------------------------------- - -#ifndef CoreFoundationCPP_CoreFoundationCPP_H_ -#define CoreFoundationCPP_CoreFoundationCPP_H_ - -#include <CoreFoundationCPP/CFCBundle.h> -#include <CoreFoundationCPP/CFCData.h> -#include <CoreFoundationCPP/CFCMutableArray.h> -#include <CoreFoundationCPP/CFCMutableDictionary.h> -#include <CoreFoundationCPP/CFCMutableSet.h> -#include <CoreFoundationCPP/CFCReleaser.h> -#include <CoreFoundationCPP/CFCString.h> - -#endif // CoreFoundationCPP_CoreFoundationCPP_H_ diff --git a/source/Host/macosx/objcxx/CMakeLists.txt b/source/Host/macosx/objcxx/CMakeLists.txt deleted file mode 100644 index 77e3091dc4fe..000000000000 --- a/source/Host/macosx/objcxx/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ - -remove_module_flags() -include_directories(..) - -add_lldb_library(lldbHostMacOSXObjCXX - Host.mm - HostInfoMacOSX.mm - HostThreadMacOSX.mm - - LINK_LIBS - lldbCore - lldbSymbol - lldbTarget - lldbUtility - ${EXTRA_LIBS} - - LINK_COMPONENTS - Object - Support - ) diff --git a/source/Host/macosx/objcxx/Host.mm b/source/Host/macosx/objcxx/Host.mm deleted file mode 100644 index 3cf44c4cb65f..000000000000 --- a/source/Host/macosx/objcxx/Host.mm +++ /dev/null @@ -1,1522 +0,0 @@ -//===-- Host.mm -------------------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "lldb/Host/Host.h" - -#include <AvailabilityMacros.h> - -#if !defined(MAC_OS_X_VERSION_10_7) || \ - MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 -#define NO_XPC_SERVICES 1 -#endif - -#if !defined(NO_XPC_SERVICES) -#define __XPC_PRIVATE_H__ -#include <xpc/xpc.h> - -#define LaunchUsingXPCRightName "com.apple.lldb.RootDebuggingXPCService" - -// These XPC messaging keys are used for communication between Host.mm and the -// XPC service. -#define LauncherXPCServiceAuthKey "auth-key" -#define LauncherXPCServiceArgPrefxKey "arg" -#define LauncherXPCServiceEnvPrefxKey "env" -#define LauncherXPCServiceCPUTypeKey "cpuType" -#define LauncherXPCServicePosixspawnFlagsKey "posixspawnFlags" -#define LauncherXPCServiceStdInPathKeyKey "stdInPath" -#define LauncherXPCServiceStdOutPathKeyKey "stdOutPath" -#define LauncherXPCServiceStdErrPathKeyKey "stdErrPath" -#define LauncherXPCServiceChildPIDKey "childPID" -#define LauncherXPCServiceErrorTypeKey "errorType" -#define LauncherXPCServiceCodeTypeKey "errorCode" - -#endif - -#include "llvm/Support/Host.h" - -#include <asl.h> -#include <crt_externs.h> -#include <grp.h> -#include <libproc.h> -#include <pwd.h> -#include <spawn.h> -#include <stdio.h> -#include <stdlib.h> -#include <sys/proc.h> -#include <sys/stat.h> -#include <sys/sysctl.h> -#include <sys/types.h> -#include <unistd.h> - -#include "lldb/Host/ConnectionFileDescriptor.h" -#include "lldb/Host/FileSystem.h" -#include "lldb/Host/HostInfo.h" -#include "lldb/Host/ThreadLauncher.h" -#include "lldb/Target/Process.h" -#include "lldb/Target/ProcessLaunchInfo.h" -#include "lldb/Utility/ArchSpec.h" -#include "lldb/Utility/CleanUp.h" -#include "lldb/Utility/DataBufferHeap.h" -#include "lldb/Utility/DataExtractor.h" -#include "lldb/Utility/Endian.h" -#include "lldb/Utility/FileSpec.h" -#include "lldb/Utility/Log.h" -#include "lldb/Utility/NameMatches.h" -#include "lldb/Utility/StreamString.h" -#include "lldb/Utility/StructuredData.h" -#include "lldb/lldb-defines.h" - -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/Errno.h" - -#include "../cfcpp/CFCBundle.h" -#include "../cfcpp/CFCMutableArray.h" -#include "../cfcpp/CFCMutableDictionary.h" -#include "../cfcpp/CFCReleaser.h" -#include "../cfcpp/CFCString.h" - -#include <objc/objc-auto.h> - -#include <CoreFoundation/CoreFoundation.h> -#include <Foundation/Foundation.h> - -#ifndef _POSIX_SPAWN_DISABLE_ASLR -#define _POSIX_SPAWN_DISABLE_ASLR 0x0100 -#endif - -extern "C" { -int __pthread_chdir(const char *path); -int __pthread_fchdir(int fildes); -} - -using namespace lldb; -using namespace lldb_private; - -bool Host::GetBundleDirectory(const FileSpec &file, - FileSpec &bundle_directory) { -#if defined(__APPLE__) - if (FileSystem::Instance().IsDirectory(file)) { - char path[PATH_MAX]; - if (file.GetPath(path, sizeof(path))) { - CFCBundle bundle(path); - if (bundle.GetPath(path, sizeof(path))) { - bundle_directory.SetFile(path, FileSpec::Style::native); - return true; - } - } - } -#endif - bundle_directory.Clear(); - return false; -} - -bool Host::ResolveExecutableInBundle(FileSpec &file) { -#if defined(__APPLE__) - if (FileSystem::Instance().IsDirectory(file)) { - char path[PATH_MAX]; - if (file.GetPath(path, sizeof(path))) { - CFCBundle bundle(path); - CFCReleaser<CFURLRef> url(bundle.CopyExecutableURL()); - if (url.get()) { - if (::CFURLGetFileSystemRepresentation(url.get(), YES, (UInt8 *)path, - sizeof(path))) { - file.SetFile(path, FileSpec::Style::native); - return true; - } - } - } - } -#endif - return false; -} - -static void *AcceptPIDFromInferior(void *arg) { - const char *connect_url = (const char *)arg; - ConnectionFileDescriptor file_conn; - Status error; - if (file_conn.Connect(connect_url, &error) == eConnectionStatusSuccess) { - char pid_str[256]; - ::memset(pid_str, 0, sizeof(pid_str)); - ConnectionStatus status; - const size_t pid_str_len = file_conn.Read( - pid_str, sizeof(pid_str), std::chrono::seconds(0), status, NULL); - if (pid_str_len > 0) { - int pid = atoi(pid_str); - return (void *)(intptr_t)pid; - } - } - return NULL; -} - -static bool WaitForProcessToSIGSTOP(const lldb::pid_t pid, - const int timeout_in_seconds) { - const int time_delta_usecs = 100000; - const int num_retries = timeout_in_seconds / time_delta_usecs; - for (int i = 0; i < num_retries; i++) { - struct proc_bsdinfo bsd_info; - int error = ::proc_pidinfo(pid, PROC_PIDTBSDINFO, (uint64_t)0, &bsd_info, - PROC_PIDTBSDINFO_SIZE); - - switch (error) { - case EINVAL: - case ENOTSUP: - case ESRCH: - case EPERM: - return false; - - default: - break; - - case 0: - if (bsd_info.pbi_status == SSTOP) - return true; - } - ::usleep(time_delta_usecs); - } - return false; -} -#if !defined(__arm__) && !defined(__arm64__) && !defined(__aarch64__) - -const char *applscript_in_new_tty = "tell application \"Terminal\"\n" - " activate\n" - " do script \"/bin/bash -c '%s';exit\"\n" - "end tell\n"; - -const char *applscript_in_existing_tty = "\ -set the_shell_script to \"/bin/bash -c '%s';exit\"\n\ -tell application \"Terminal\"\n\ - repeat with the_window in (get windows)\n\ - repeat with the_tab in tabs of the_window\n\ - set the_tty to tty in the_tab\n\ - if the_tty contains \"%s\" then\n\ - if the_tab is not busy then\n\ - set selected of the_tab to true\n\ - set frontmost of the_window to true\n\ - do script the_shell_script in the_tab\n\ - return\n\ - end if\n\ - end if\n\ - end repeat\n\ - end repeat\n\ - do script the_shell_script\n\ -end tell\n"; - -static Status -LaunchInNewTerminalWithAppleScript(const char *exe_path, - ProcessLaunchInfo &launch_info) { - Status error; - char unix_socket_name[PATH_MAX] = "/tmp/XXXXXX"; - if (::mktemp(unix_socket_name) == NULL) { - error.SetErrorString("failed to make temporary path for a unix socket"); - return error; - } - - StreamString command; - FileSpec darwin_debug_file_spec = HostInfo::GetSupportExeDir(); - if (!darwin_debug_file_spec) { - error.SetErrorString("can't locate the 'darwin-debug' executable"); - return error; - } - - darwin_debug_file_spec.GetFilename().SetCString("darwin-debug"); - - if (!FileSystem::Instance().Exists(darwin_debug_file_spec)) { - error.SetErrorStringWithFormat( - "the 'darwin-debug' executable doesn't exists at '%s'", - darwin_debug_file_spec.GetPath().c_str()); - return error; - } - - char launcher_path[PATH_MAX]; - darwin_debug_file_spec.GetPath(launcher_path, sizeof(launcher_path)); - - const ArchSpec &arch_spec = launch_info.GetArchitecture(); - // Only set the architecture if it is valid and if it isn't Haswell (x86_64h). - if (arch_spec.IsValid() && - arch_spec.GetCore() != ArchSpec::eCore_x86_64_x86_64h) - command.Printf("arch -arch %s ", arch_spec.GetArchitectureName()); - - command.Printf("'%s' --unix-socket=%s", launcher_path, unix_socket_name); - - if (arch_spec.IsValid()) - command.Printf(" --arch=%s", arch_spec.GetArchitectureName()); - - FileSpec working_dir{launch_info.GetWorkingDirectory()}; - if (working_dir) - command.Printf(" --working-dir '%s'", working_dir.GetCString()); - else { - char cwd[PATH_MAX]; - if (getcwd(cwd, PATH_MAX)) - command.Printf(" --working-dir '%s'", cwd); - } - - if (launch_info.GetFlags().Test(eLaunchFlagDisableASLR)) - command.PutCString(" --disable-aslr"); - - // We are launching on this host in a terminal. So compare the environment on - // the host to what is supplied in the launch_info. Any items that aren't in - // the host environment need to be sent to darwin-debug. If we send all - // environment entries, we might blow the max command line length, so we only - // send user modified entries. - Environment host_env = Host::GetEnvironment(); - - for (const auto &KV : launch_info.GetEnvironment()) { - auto host_entry = host_env.find(KV.first()); - if (host_entry == host_env.end() || host_entry->second != KV.second) - command.Format(" --env='{0}'", Environment::compose(KV)); - } - - command.PutCString(" -- "); - - const char **argv = launch_info.GetArguments().GetConstArgumentVector(); - if (argv) { - for (size_t i = 0; argv[i] != NULL; ++i) { - if (i == 0) - command.Printf(" '%s'", exe_path); - else - command.Printf(" '%s'", argv[i]); - } - } else { - command.Printf(" '%s'", exe_path); - } - command.PutCString(" ; echo Process exited with status $?"); - if (launch_info.GetFlags().Test(lldb::eLaunchFlagCloseTTYOnExit)) - command.PutCString(" ; exit"); - - StreamString applescript_source; - - applescript_source.Printf(applscript_in_new_tty, - command.GetString().str().c_str()); - NSAppleScript *applescript = [[NSAppleScript alloc] - initWithSource:[NSString stringWithCString:applescript_source.GetString() - .str() - .c_str() - encoding:NSUTF8StringEncoding]]; - - lldb::pid_t pid = LLDB_INVALID_PROCESS_ID; - - Status lldb_error; - // Sleep and wait a bit for debugserver to start to listen... - ConnectionFileDescriptor file_conn; - char connect_url[128]; - ::snprintf(connect_url, sizeof(connect_url), "unix-accept://%s", - unix_socket_name); - - // Spawn a new thread to accept incoming connection on the connect_url - // so we can grab the pid from the inferior. We have to do this because we - // are sending an AppleScript that will launch a process in Terminal.app, - // in a shell and the shell will fork/exec a couple of times before we get - // to the process that we wanted to launch. So when our process actually - // gets launched, we will handshake with it and get the process ID for it. - HostThread accept_thread = ThreadLauncher::LaunchThread( - unix_socket_name, AcceptPIDFromInferior, connect_url, &lldb_error); - - [applescript executeAndReturnError:nil]; - - thread_result_t accept_thread_result = NULL; - lldb_error = accept_thread.Join(&accept_thread_result); - if (lldb_error.Success() && accept_thread_result) { - pid = (intptr_t)accept_thread_result; - - // Wait for process to be stopped at the entry point by watching - // for the process status to be set to SSTOP which indicates it it - // SIGSTOP'ed at the entry point - WaitForProcessToSIGSTOP(pid, 5); - } - - llvm::sys::fs::remove(unix_socket_name); - [applescript release]; - if (pid != LLDB_INVALID_PROCESS_ID) - launch_info.SetProcessID(pid); - return error; -} - -#endif // #if !defined(__arm__) && !defined(__arm64__) && !defined(__aarch64__) - -bool Host::OpenFileInExternalEditor(const FileSpec &file_spec, - uint32_t line_no) { -#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__) - return false; -#else - // We attach this to an 'odoc' event to specify a particular selection - typedef struct { - int16_t reserved0; // must be zero - int16_t fLineNumber; - int32_t fSelStart; - int32_t fSelEnd; - uint32_t reserved1; // must be zero - uint32_t reserved2; // must be zero - } BabelAESelInfo; - - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_HOST)); - char file_path[PATH_MAX]; - file_spec.GetPath(file_path, PATH_MAX); - CFCString file_cfstr(file_path, kCFStringEncodingUTF8); - CFCReleaser<CFURLRef> file_URL(::CFURLCreateWithFileSystemPath( - NULL, file_cfstr.get(), kCFURLPOSIXPathStyle, false)); - - if (log) - log->Printf( - "Sending source file: \"%s\" and line: %d to external editor.\n", - file_path, line_no); - - long error; - BabelAESelInfo file_and_line_info = { - 0, // reserved0 - (int16_t)(line_no - 1), // fLineNumber (zero based line number) - 1, // fSelStart - 1024, // fSelEnd - 0, // reserved1 - 0 // reserved2 - }; - - AEKeyDesc file_and_line_desc; - - error = ::AECreateDesc(typeUTF8Text, &file_and_line_info, - sizeof(file_and_line_info), - &(file_and_line_desc.descContent)); - - if (error != noErr) { - if (log) - log->Printf("Error creating AEDesc: %ld.\n", error); - return false; - } - - file_and_line_desc.descKey = keyAEPosition; - - static std::string g_app_name; - static FSRef g_app_fsref; - - LSApplicationParameters app_params; - ::memset(&app_params, 0, sizeof(app_params)); - app_params.flags = - kLSLaunchDefaults | kLSLaunchDontAddToRecents | kLSLaunchDontSwitch; - - char *external_editor = ::getenv("LLDB_EXTERNAL_EDITOR"); - - if (external_editor) { - if (log) - log->Printf("Looking for external editor \"%s\".\n", external_editor); - - if (g_app_name.empty() || - strcmp(g_app_name.c_str(), external_editor) != 0) { - CFCString editor_name(external_editor, kCFStringEncodingUTF8); - error = ::LSFindApplicationForInfo(kLSUnknownCreator, NULL, - editor_name.get(), &g_app_fsref, NULL); - - // If we found the app, then store away the name so we don't have to - // re-look it up. - if (error != noErr) { - if (log) - log->Printf( - "Could not find External Editor application, error: %ld.\n", - error); - return false; - } - } - app_params.application = &g_app_fsref; - } - - ProcessSerialNumber psn; - CFCReleaser<CFArrayRef> file_array( - CFArrayCreate(NULL, (const void **)file_URL.ptr_address(false), 1, NULL)); - error = ::LSOpenURLsWithRole(file_array.get(), kLSRolesAll, - &file_and_line_desc, &app_params, &psn, 1); - - AEDisposeDesc(&(file_and_line_desc.descContent)); - - if (error != noErr) { - if (log) - log->Printf("LSOpenURLsWithRole failed, error: %ld.\n", error); - - return false; - } - - return true; -#endif // #if !defined(__arm__) && !defined(__arm64__) && !defined(__aarch64__) -} - -Environment Host::GetEnvironment() { return Environment(*_NSGetEnviron()); } - -static bool GetMacOSXProcessCPUType(ProcessInstanceInfo &process_info) { - if (process_info.ProcessIDIsValid()) { - // Make a new mib to stay thread safe - int mib[CTL_MAXNAME] = { - 0, - }; - size_t mib_len = CTL_MAXNAME; - if (::sysctlnametomib("sysctl.proc_cputype", mib, &mib_len)) - return false; - - mib[mib_len] = process_info.GetProcessID(); - mib_len++; - - cpu_type_t cpu, sub = 0; - size_t len = sizeof(cpu); - if (::sysctl(mib, mib_len, &cpu, &len, 0, 0) == 0) { - switch (cpu) { - case CPU_TYPE_I386: - sub = CPU_SUBTYPE_I386_ALL; - break; - case CPU_TYPE_X86_64: - sub = CPU_SUBTYPE_X86_64_ALL; - break; - -#if defined(CPU_TYPE_ARM64) && defined(CPU_SUBTYPE_ARM64_ALL) - case CPU_TYPE_ARM64: - sub = CPU_SUBTYPE_ARM64_ALL; - break; -#endif - - case CPU_TYPE_ARM: { - // Note that we fetched the cpu type from the PROCESS but we can't get a - // cpusubtype of the - // process -- we can only get the host's cpu subtype. - uint32_t cpusubtype = 0; - len = sizeof(cpusubtype); - if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) == 0) - sub = cpusubtype; - - bool host_cpu_is_64bit; - uint32_t is64bit_capable; - size_t is64bit_capable_len = sizeof(is64bit_capable); - host_cpu_is_64bit = - sysctlbyname("hw.cpu64bit_capable", &is64bit_capable, - &is64bit_capable_len, NULL, 0) == 0; - - // if the host is an armv8 device, its cpusubtype will be in - // CPU_SUBTYPE_ARM64 numbering - // and we need to rewrite it to a reasonable CPU_SUBTYPE_ARM value - // instead. - - if (host_cpu_is_64bit) { - sub = CPU_SUBTYPE_ARM_V7; - } - } break; - - default: - break; - } - process_info.GetArchitecture().SetArchitecture(eArchTypeMachO, cpu, sub); - return true; - } - } - process_info.GetArchitecture().Clear(); - return false; -} - -static bool GetMacOSXProcessArgs(const ProcessInstanceInfoMatch *match_info_ptr, - ProcessInstanceInfo &process_info) { - if (process_info.ProcessIDIsValid()) { - int proc_args_mib[3] = {CTL_KERN, KERN_PROCARGS2, - (int)process_info.GetProcessID()}; - - size_t arg_data_size = 0; - if (::sysctl(proc_args_mib, 3, nullptr, &arg_data_size, NULL, 0) || - arg_data_size == 0) - arg_data_size = 8192; - - // Add a few bytes to the calculated length, I know we need to add at least - // one byte - // to this number otherwise we get junk back, so add 128 just in case... - DataBufferHeap arg_data(arg_data_size + 128, 0); - arg_data_size = arg_data.GetByteSize(); - if (::sysctl(proc_args_mib, 3, arg_data.GetBytes(), &arg_data_size, NULL, - 0) == 0) { - DataExtractor data(arg_data.GetBytes(), arg_data_size, - endian::InlHostByteOrder(), sizeof(void *)); - lldb::offset_t offset = 0; - uint32_t argc = data.GetU32(&offset); - llvm::Triple &triple = process_info.GetArchitecture().GetTriple(); - const llvm::Triple::ArchType triple_arch = triple.getArch(); - const bool check_for_ios_simulator = - (triple_arch == llvm::Triple::x86 || - triple_arch == llvm::Triple::x86_64); - const char *cstr = data.GetCStr(&offset); - if (cstr) { - process_info.GetExecutableFile().SetFile(cstr, FileSpec::Style::native); - - if (match_info_ptr == NULL || - NameMatches( - process_info.GetExecutableFile().GetFilename().GetCString(), - match_info_ptr->GetNameMatchType(), - match_info_ptr->GetProcessInfo().GetName())) { - // Skip NULLs - while (1) { - const uint8_t *p = data.PeekData(offset, 1); - if ((p == NULL) || (*p != '\0')) - break; - ++offset; - } - // Now extract all arguments - Args &proc_args = process_info.GetArguments(); - for (int i = 0; i < static_cast<int>(argc); ++i) { - cstr = data.GetCStr(&offset); - if (cstr) - proc_args.AppendArgument(llvm::StringRef(cstr)); - } - - Environment &proc_env = process_info.GetEnvironment(); - while ((cstr = data.GetCStr(&offset))) { - if (cstr[0] == '\0') - break; - - if (check_for_ios_simulator) { - if (strncmp(cstr, "SIMULATOR_UDID=", strlen("SIMULATOR_UDID=")) == - 0) - process_info.GetArchitecture().GetTriple().setOS( - llvm::Triple::IOS); - else - process_info.GetArchitecture().GetTriple().setOS( - llvm::Triple::MacOSX); - } - - proc_env.insert(cstr); - } - return true; - } - } - } - } - return false; -} - -static bool GetMacOSXProcessUserAndGroup(ProcessInstanceInfo &process_info) { - if (process_info.ProcessIDIsValid()) { - int mib[4]; - mib[0] = CTL_KERN; - mib[1] = KERN_PROC; - mib[2] = KERN_PROC_PID; - mib[3] = process_info.GetProcessID(); - struct kinfo_proc proc_kinfo; - size_t proc_kinfo_size = sizeof(struct kinfo_proc); - - if (::sysctl(mib, 4, &proc_kinfo, &proc_kinfo_size, NULL, 0) == 0) { - if (proc_kinfo_size > 0) { - process_info.SetParentProcessID(proc_kinfo.kp_eproc.e_ppid); - process_info.SetUserID(proc_kinfo.kp_eproc.e_pcred.p_ruid); - process_info.SetGroupID(proc_kinfo.kp_eproc.e_pcred.p_rgid); - process_info.SetEffectiveUserID(proc_kinfo.kp_eproc.e_ucred.cr_uid); - if (proc_kinfo.kp_eproc.e_ucred.cr_ngroups > 0) - process_info.SetEffectiveGroupID( - proc_kinfo.kp_eproc.e_ucred.cr_groups[0]); - else - process_info.SetEffectiveGroupID(UINT32_MAX); - return true; - } - } - } - process_info.SetParentProcessID(LLDB_INVALID_PROCESS_ID); - process_info.SetUserID(UINT32_MAX); - process_info.SetGroupID(UINT32_MAX); - process_info.SetEffectiveUserID(UINT32_MAX); - process_info.SetEffectiveGroupID(UINT32_MAX); - return false; -} - -uint32_t Host::FindProcesses(const ProcessInstanceInfoMatch &match_info, - ProcessInstanceInfoList &process_infos) { - std::vector<struct kinfo_proc> kinfos; - - int mib[3] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL}; - - size_t pid_data_size = 0; - if (::sysctl(mib, 3, nullptr, &pid_data_size, nullptr, 0) != 0) - return 0; - - // Add a few extra in case a few more show up - const size_t estimated_pid_count = - (pid_data_size / sizeof(struct kinfo_proc)) + 10; - - kinfos.resize(estimated_pid_count); - pid_data_size = kinfos.size() * sizeof(struct kinfo_proc); - - if (::sysctl(mib, 3, &kinfos[0], &pid_data_size, nullptr, 0) != 0) - return 0; - - const size_t actual_pid_count = (pid_data_size / sizeof(struct kinfo_proc)); - - bool all_users = match_info.GetMatchAllUsers(); - const lldb::pid_t our_pid = getpid(); - const uid_t our_uid = getuid(); - for (size_t i = 0; i < actual_pid_count; i++) { - const struct kinfo_proc &kinfo = kinfos[i]; - - bool kinfo_user_matches = false; - if (all_users) - kinfo_user_matches = true; - else - kinfo_user_matches = kinfo.kp_eproc.e_pcred.p_ruid == our_uid; - - // Special case, if lldb is being run as root we can attach to anything. - if (our_uid == 0) - kinfo_user_matches = true; - - if (!kinfo_user_matches || // Make sure the user is acceptable - static_cast<lldb::pid_t>(kinfo.kp_proc.p_pid) == - our_pid || // Skip this process - kinfo.kp_proc.p_pid == 0 || // Skip kernel (kernel pid is zero) - kinfo.kp_proc.p_stat == SZOMB || // Zombies are bad, they like brains... - kinfo.kp_proc.p_flag & P_TRACED || // Being debugged? - kinfo.kp_proc.p_flag & P_WEXIT || // Working on exiting? - kinfo.kp_proc.p_flag & P_TRANSLATED) // Skip translated ppc (Rosetta) - continue; - - ProcessInstanceInfo process_info; - process_info.SetProcessID(kinfo.kp_proc.p_pid); - process_info.SetParentProcessID(kinfo.kp_eproc.e_ppid); - process_info.SetUserID(kinfo.kp_eproc.e_pcred.p_ruid); - process_info.SetGroupID(kinfo.kp_eproc.e_pcred.p_rgid); - process_info.SetEffectiveUserID(kinfo.kp_eproc.e_ucred.cr_uid); - if (kinfo.kp_eproc.e_ucred.cr_ngroups > 0) - process_info.SetEffectiveGroupID(kinfo.kp_eproc.e_ucred.cr_groups[0]); - else - process_info.SetEffectiveGroupID(UINT32_MAX); - - // Make sure our info matches before we go fetch the name and cpu type - if (match_info.Matches(process_info)) { - // Get CPU type first so we can know to look for iOS simulator is we have - // x86 or x86_64 - if (GetMacOSXProcessCPUType(process_info)) { - if (GetMacOSXProcessArgs(&match_info, process_info)) { - if (match_info.Matches(process_info)) - process_infos.Append(process_info); - } - } - } - } - return process_infos.GetSize(); -} - -bool Host::GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &process_info) { - process_info.SetProcessID(pid); - bool success = false; - - // Get CPU type first so we can know to look for iOS simulator is we have x86 - // or x86_64 - if (GetMacOSXProcessCPUType(process_info)) - success = true; - - if (GetMacOSXProcessArgs(NULL, process_info)) - success = true; - - if (GetMacOSXProcessUserAndGroup(process_info)) - success = true; - - if (success) - return true; - - process_info.Clear(); - return false; -} - -#if !NO_XPC_SERVICES -static void PackageXPCArguments(xpc_object_t message, const char *prefix, - const Args &args) { - size_t count = args.GetArgumentCount(); - char buf[50]; // long enough for 'argXXX' - memset(buf, 0, 50); - sprintf(buf, "%sCount", prefix); - xpc_dictionary_set_int64(message, buf, count); - for (size_t i = 0; i < count; i++) { - memset(buf, 0, 50); - sprintf(buf, "%s%zi", prefix, i); - xpc_dictionary_set_string(message, buf, args.GetArgumentAtIndex(i)); - } -} - -static void PackageXPCEnvironment(xpc_object_t message, llvm::StringRef prefix, - const Environment &env) { - xpc_dictionary_set_int64(message, (prefix + "Count").str().c_str(), - env.size()); - size_t i = 0; - for (const auto &KV : env) { - xpc_dictionary_set_string(message, (prefix + llvm::Twine(i)).str().c_str(), - Environment::compose(KV).c_str()); - } -} - -/* - A valid authorizationRef means that - - there is the LaunchUsingXPCRightName rights in the /etc/authorization - - we have successfully copied the rights to be send over the XPC wire - Once obtained, it will be valid for as long as the process lives. - */ -static AuthorizationRef authorizationRef = NULL; -static Status getXPCAuthorization(ProcessLaunchInfo &launch_info) { - Status error; - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST | - LIBLLDB_LOG_PROCESS)); - - if ((launch_info.GetUserID() == 0) && !authorizationRef) { - OSStatus createStatus = - AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, - kAuthorizationFlagDefaults, &authorizationRef); - if (createStatus != errAuthorizationSuccess) { - error.SetError(1, eErrorTypeGeneric); - error.SetErrorString("Can't create authorizationRef."); - LLDB_LOG(log, "error: {0}", error); - return error; - } - - OSStatus rightsStatus = - AuthorizationRightGet(LaunchUsingXPCRightName, NULL); - if (rightsStatus != errAuthorizationSuccess) { - // No rights in the security database, Create it with the right prompt. - CFStringRef prompt = - CFSTR("Xcode is trying to take control of a root process."); - CFStringRef keys[] = {CFSTR("en")}; - CFTypeRef values[] = {prompt}; - CFDictionaryRef promptDict = CFDictionaryCreate( - kCFAllocatorDefault, (const void **)keys, (const void **)values, 1, - &kCFCopyStringDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); - - CFStringRef keys1[] = {CFSTR("class"), CFSTR("group"), CFSTR("comment"), - CFSTR("default-prompt"), CFSTR("shared")}; - CFTypeRef values1[] = {CFSTR("user"), CFSTR("admin"), - CFSTR(LaunchUsingXPCRightName), promptDict, - kCFBooleanFalse}; - CFDictionaryRef dict = CFDictionaryCreate( - kCFAllocatorDefault, (const void **)keys1, (const void **)values1, 5, - &kCFCopyStringDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); - rightsStatus = AuthorizationRightSet( - authorizationRef, LaunchUsingXPCRightName, dict, NULL, NULL, NULL); - CFRelease(promptDict); - CFRelease(dict); - } - - OSStatus copyRightStatus = errAuthorizationDenied; - if (rightsStatus == errAuthorizationSuccess) { - AuthorizationItem item1 = {LaunchUsingXPCRightName, 0, NULL, 0}; - AuthorizationItem items[] = {item1}; - AuthorizationRights requestedRights = {1, items}; - AuthorizationFlags authorizationFlags = - kAuthorizationFlagInteractionAllowed | kAuthorizationFlagExtendRights; - copyRightStatus = AuthorizationCopyRights( - authorizationRef, &requestedRights, kAuthorizationEmptyEnvironment, - authorizationFlags, NULL); - } - - if (copyRightStatus != errAuthorizationSuccess) { - // Eventually when the commandline supports running as root and the user - // is not - // logged in in the current audit session, we will need the trick in gdb - // where - // we ask the user to type in the root passwd in the terminal. - error.SetError(2, eErrorTypeGeneric); - error.SetErrorStringWithFormat( - "Launching as root needs root authorization."); - LLDB_LOG(log, "error: {0}", error); - - if (authorizationRef) { - AuthorizationFree(authorizationRef, kAuthorizationFlagDefaults); - authorizationRef = NULL; - } - } - } - - return error; -} -#endif - -static short GetPosixspawnFlags(const ProcessLaunchInfo &launch_info) { - short flags = POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETSIGMASK; - - if (launch_info.GetFlags().Test(eLaunchFlagExec)) - flags |= POSIX_SPAWN_SETEXEC; // Darwin specific posix_spawn flag - - if (launch_info.GetFlags().Test(eLaunchFlagDebug)) - flags |= POSIX_SPAWN_START_SUSPENDED; // Darwin specific posix_spawn flag - - if (launch_info.GetFlags().Test(eLaunchFlagDisableASLR)) - flags |= _POSIX_SPAWN_DISABLE_ASLR; // Darwin specific posix_spawn flag - - if (launch_info.GetLaunchInSeparateProcessGroup()) - flags |= POSIX_SPAWN_SETPGROUP; - -#ifdef POSIX_SPAWN_CLOEXEC_DEFAULT -#if defined(__x86_64__) || defined(__i386__) - static LazyBool g_use_close_on_exec_flag = eLazyBoolCalculate; - if (g_use_close_on_exec_flag == eLazyBoolCalculate) { - g_use_close_on_exec_flag = eLazyBoolNo; - - llvm::VersionTuple version = HostInfo::GetOSVersion(); - if (version > llvm::VersionTuple(10, 7)) { - // Kernel panic if we use the POSIX_SPAWN_CLOEXEC_DEFAULT on 10.7 or - // earlier - g_use_close_on_exec_flag = eLazyBoolYes; - } - } -#else - static LazyBool g_use_close_on_exec_flag = eLazyBoolYes; -#endif // defined(__x86_64__) || defined(__i386__) - // Close all files exception those with file actions if this is supported. - if (g_use_close_on_exec_flag == eLazyBoolYes) - flags |= POSIX_SPAWN_CLOEXEC_DEFAULT; -#endif // ifdef POSIX_SPAWN_CLOEXEC_DEFAULT - return flags; -} - -static Status LaunchProcessXPC(const char *exe_path, - ProcessLaunchInfo &launch_info, - lldb::pid_t &pid) { -#if !NO_XPC_SERVICES - Status error = getXPCAuthorization(launch_info); - if (error.Fail()) - return error; - - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST | - LIBLLDB_LOG_PROCESS)); - - uid_t requested_uid = launch_info.GetUserID(); - const char *xpc_service = nil; - bool send_auth = false; - AuthorizationExternalForm extForm; - if (requested_uid == 0) { - if (AuthorizationMakeExternalForm(authorizationRef, &extForm) == - errAuthorizationSuccess) { - send_auth = true; - } else { - error.SetError(3, eErrorTypeGeneric); - error.SetErrorStringWithFormat("Launching root via XPC needs to " - "externalize authorization reference."); - LLDB_LOG(log, "error: {0}", error); - return error; - } - xpc_service = LaunchUsingXPCRightName; - } else { - error.SetError(4, eErrorTypeGeneric); - error.SetErrorStringWithFormat( - "Launching via XPC is only currently available for root."); - LLDB_LOG(log, "error: {0}", error); - return error; - } - - xpc_connection_t conn = xpc_connection_create(xpc_service, NULL); - - xpc_connection_set_event_handler(conn, ^(xpc_object_t event) { - xpc_type_t type = xpc_get_type(event); - - if (type == XPC_TYPE_ERROR) { - if (event == XPC_ERROR_CONNECTION_INTERRUPTED) { - // The service has either canceled itself, crashed, or been terminated. - // The XPC connection is still valid and sending a message to it will - // re-launch the service. - // If the service is state-full, this is the time to initialize the new - // service. - return; - } else if (event == XPC_ERROR_CONNECTION_INVALID) { - // The service is invalid. Either the service name supplied to - // xpc_connection_create() is incorrect - // or we (this process) have canceled the service; we can do any cleanup - // of application state at this point. - // printf("Service disconnected"); - return; - } else { - // printf("Unexpected error from service: %s", - // xpc_dictionary_get_string(event, XPC_ERROR_KEY_DESCRIPTION)); - } - - } else { - // printf("Received unexpected event in handler"); - } - }); - - xpc_connection_set_finalizer_f(conn, xpc_finalizer_t(xpc_release)); - xpc_connection_resume(conn); - xpc_object_t message = xpc_dictionary_create(nil, nil, 0); - - if (send_auth) { - xpc_dictionary_set_data(message, LauncherXPCServiceAuthKey, extForm.bytes, - sizeof(AuthorizationExternalForm)); - } - - PackageXPCArguments(message, LauncherXPCServiceArgPrefxKey, - launch_info.GetArguments()); - PackageXPCEnvironment(message, LauncherXPCServiceEnvPrefxKey, - launch_info.GetEnvironment()); - - // Posix spawn stuff. - xpc_dictionary_set_int64(message, LauncherXPCServiceCPUTypeKey, - launch_info.GetArchitecture().GetMachOCPUType()); - xpc_dictionary_set_int64(message, LauncherXPCServicePosixspawnFlagsKey, - GetPosixspawnFlags(launch_info)); - const FileAction *file_action = launch_info.GetFileActionForFD(STDIN_FILENO); - if (file_action && !file_action->GetPath().empty()) { - xpc_dictionary_set_string(message, LauncherXPCServiceStdInPathKeyKey, - file_action->GetPath().str().c_str()); - } - file_action = launch_info.GetFileActionForFD(STDOUT_FILENO); - if (file_action && !file_action->GetPath().empty()) { - xpc_dictionary_set_string(message, LauncherXPCServiceStdOutPathKeyKey, - file_action->GetPath().str().c_str()); - } - file_action = launch_info.GetFileActionForFD(STDERR_FILENO); - if (file_action && !file_action->GetPath().empty()) { - xpc_dictionary_set_string(message, LauncherXPCServiceStdErrPathKeyKey, - file_action->GetPath().str().c_str()); - } - - xpc_object_t reply = - xpc_connection_send_message_with_reply_sync(conn, message); - xpc_type_t returnType = xpc_get_type(reply); - if (returnType == XPC_TYPE_DICTIONARY) { - pid = xpc_dictionary_get_int64(reply, LauncherXPCServiceChildPIDKey); - if (pid == 0) { - int errorType = - xpc_dictionary_get_int64(reply, LauncherXPCServiceErrorTypeKey); - int errorCode = - xpc_dictionary_get_int64(reply, LauncherXPCServiceCodeTypeKey); - - error.SetError(errorCode, eErrorTypeGeneric); - error.SetErrorStringWithFormat( - "Problems with launching via XPC. Error type : %i, code : %i", - errorType, errorCode); - LLDB_LOG(log, "error: {0}", error); - - if (authorizationRef) { - AuthorizationFree(authorizationRef, kAuthorizationFlagDefaults); - authorizationRef = NULL; - } - } - } else if (returnType == XPC_TYPE_ERROR) { - error.SetError(5, eErrorTypeGeneric); - error.SetErrorStringWithFormat( - "Problems with launching via XPC. XPC error : %s", - xpc_dictionary_get_string(reply, XPC_ERROR_KEY_DESCRIPTION)); - LLDB_LOG(log, "error: {0}", error); - } - - return error; -#else - Status error; - return error; -#endif -} - -static bool AddPosixSpawnFileAction(void *_file_actions, const FileAction *info, - Log *log, Status &error) { - if (info == NULL) - return false; - - posix_spawn_file_actions_t *file_actions = - reinterpret_cast<posix_spawn_file_actions_t *>(_file_actions); - - switch (info->GetAction()) { - case FileAction::eFileActionNone: - error.Clear(); - break; - - case FileAction::eFileActionClose: - if (info->GetFD() == -1) - error.SetErrorString( - "invalid fd for posix_spawn_file_actions_addclose(...)"); - else { - error.SetError( - ::posix_spawn_file_actions_addclose(file_actions, info->GetFD()), - eErrorTypePOSIX); - if (error.Fail()) - LLDB_LOG(log, - "error: {0}, posix_spawn_file_actions_addclose " - "(action={1}, fd={2})", - error, file_actions, info->GetFD()); - } - break; - - case FileAction::eFileActionDuplicate: - if (info->GetFD() == -1) - error.SetErrorString( - "invalid fd for posix_spawn_file_actions_adddup2(...)"); - else if (info->GetActionArgument() == -1) - error.SetErrorString( - "invalid duplicate fd for posix_spawn_file_actions_adddup2(...)"); - else { - error.SetError( - ::posix_spawn_file_actions_adddup2(file_actions, info->GetFD(), - info->GetActionArgument()), - eErrorTypePOSIX); - if (error.Fail()) - LLDB_LOG(log, - "error: {0}, posix_spawn_file_actions_adddup2 " - "(action={1}, fd={2}, dup_fd={3})", - error, file_actions, info->GetFD(), info->GetActionArgument()); - } - break; - - case FileAction::eFileActionOpen: - if (info->GetFD() == -1) - error.SetErrorString( - "invalid fd in posix_spawn_file_actions_addopen(...)"); - else { - int oflag = info->GetActionArgument(); - - mode_t mode = 0; - - if (oflag & O_CREAT) - mode = 0640; - - error.SetError(::posix_spawn_file_actions_addopen( - file_actions, info->GetFD(), - info->GetPath().str().c_str(), oflag, mode), - eErrorTypePOSIX); - if (error.Fail()) - LLDB_LOG(log, - "error: {0}, posix_spawn_file_actions_addopen (action={1}, " - "fd={2}, path='{3}', oflag={4}, mode={5})", - error, file_actions, info->GetFD(), info->GetPath(), oflag, - mode); - } - break; - } - return error.Success(); -} - -static Status LaunchProcessPosixSpawn(const char *exe_path, - const ProcessLaunchInfo &launch_info, - lldb::pid_t &pid) { - Status error; - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST | - LIBLLDB_LOG_PROCESS)); - - posix_spawnattr_t attr; - error.SetError(::posix_spawnattr_init(&attr), eErrorTypePOSIX); - - if (error.Fail()) { - LLDB_LOG(log, "error: {0}, ::posix_spawnattr_init ( &attr )", error); - return error; - } - - // Make sure we clean up the posix spawn attributes before exiting this scope. - CleanUp cleanup_attr(posix_spawnattr_destroy, &attr); - - sigset_t no_signals; - sigset_t all_signals; - sigemptyset(&no_signals); - sigfillset(&all_signals); - ::posix_spawnattr_setsigmask(&attr, &no_signals); - ::posix_spawnattr_setsigdefault(&attr, &all_signals); - - short flags = GetPosixspawnFlags(launch_info); - - error.SetError(::posix_spawnattr_setflags(&attr, flags), eErrorTypePOSIX); - if (error.Fail()) { - LLDB_LOG(log, - "error: {0}, ::posix_spawnattr_setflags ( &attr, flags={1:x} )", - error, flags); - return error; - } - -// posix_spawnattr_setbinpref_np appears to be an Apple extension per: -// http://www.unix.com/man-page/OSX/3/posix_spawnattr_setbinpref_np/ -#if !defined(__arm__) - - // Don't set the binpref if a shell was provided. After all, that's only - // going to affect what version of the shell - // is launched, not what fork of the binary is launched. We insert "arch - // --arch <ARCH> as part of the shell invocation - // to do that job on OSX. - - if (launch_info.GetShell() == nullptr) { - // We don't need to do this for ARM, and we really shouldn't now that we - // have multiple CPU subtypes and no posix_spawnattr call that allows us - // to set which CPU subtype to launch... - const ArchSpec &arch_spec = launch_info.GetArchitecture(); - cpu_type_t cpu = arch_spec.GetMachOCPUType(); - cpu_type_t sub = arch_spec.GetMachOCPUSubType(); - if (cpu != 0 && cpu != static_cast<cpu_type_t>(UINT32_MAX) && - cpu != static_cast<cpu_type_t>(LLDB_INVALID_CPUTYPE) && - !(cpu == 0x01000007 && sub == 8)) // If haswell is specified, don't try - // to set the CPU type or we will fail - { - size_t ocount = 0; - error.SetError(::posix_spawnattr_setbinpref_np(&attr, 1, &cpu, &ocount), - eErrorTypePOSIX); - if (error.Fail()) - LLDB_LOG(log, - "error: {0}, ::posix_spawnattr_setbinpref_np ( &attr, 1, " - "cpu_type = {1:x}, count => {2} )", - error, cpu, ocount); - - if (error.Fail() || ocount != 1) - return error; - } - } -#endif // !defined(__arm__) - - const char *tmp_argv[2]; - char *const *argv = const_cast<char *const *>( - launch_info.GetArguments().GetConstArgumentVector()); - Environment::Envp envp = launch_info.GetEnvironment().getEnvp(); - if (argv == NULL) { - // posix_spawn gets very unhappy if it doesn't have at least the program - // name in argv[0]. One of the side affects I have noticed is the - // environment - // variables don't make it into the child process if "argv == NULL"!!! - tmp_argv[0] = exe_path; - tmp_argv[1] = NULL; - argv = const_cast<char *const *>(tmp_argv); - } - - FileSpec working_dir{launch_info.GetWorkingDirectory()}; - if (working_dir) { - // Set the working directory on this thread only - if (__pthread_chdir(working_dir.GetCString()) < 0) { - if (errno == ENOENT) { - error.SetErrorStringWithFormat("No such file or directory: %s", - working_dir.GetCString()); - } else if (errno == ENOTDIR) { - error.SetErrorStringWithFormat("Path doesn't name a directory: %s", - working_dir.GetCString()); - } else { - error.SetErrorStringWithFormat("An unknown error occurred when " - "changing directory for process " - "execution."); - } - return error; - } - } - - ::pid_t result_pid = LLDB_INVALID_PROCESS_ID; - const size_t num_file_actions = launch_info.GetNumFileActions(); - if (num_file_actions > 0) { - posix_spawn_file_actions_t file_actions; - error.SetError(::posix_spawn_file_actions_init(&file_actions), - eErrorTypePOSIX); - if (error.Fail()) { - LLDB_LOG(log, - "error: {0}, ::posix_spawn_file_actions_init ( &file_actions )", - error); - return error; - } - - // Make sure we clean up the posix file actions before exiting this scope. - CleanUp cleanup_fileact(posix_spawn_file_actions_destroy, &file_actions); - - for (size_t i = 0; i < num_file_actions; ++i) { - const FileAction *launch_file_action = - launch_info.GetFileActionAtIndex(i); - if (launch_file_action) { - if (!AddPosixSpawnFileAction(&file_actions, launch_file_action, log, - error)) - return error; - } - } - - error.SetError( - ::posix_spawnp(&result_pid, exe_path, &file_actions, &attr, argv, envp), - eErrorTypePOSIX); - - if (error.Fail()) { - LLDB_LOG(log, - "error: {0}, ::posix_spawnp(pid => {1}, path = '{2}', " - "file_actions = {3}, " - "attr = {4}, argv = {5}, envp = {6} )", - error, result_pid, exe_path, &file_actions, &attr, argv, - envp.get()); - if (log) { - for (int ii = 0; argv[ii]; ++ii) - LLDB_LOG(log, "argv[{0}] = '{1}'", ii, argv[ii]); - } - } - - } else { - error.SetError( - ::posix_spawnp(&result_pid, exe_path, NULL, &attr, argv, envp), - eErrorTypePOSIX); - - if (error.Fail()) { - LLDB_LOG(log, - "error: {0}, ::posix_spawnp ( pid => {1}, path = '{2}', " - "file_actions = NULL, attr = {3}, argv = {4}, envp = {5} )", - error, result_pid, exe_path, &attr, argv, envp.get()); - if (log) { - for (int ii = 0; argv[ii]; ++ii) - LLDB_LOG(log, "argv[{0}] = '{1}'", ii, argv[ii]); - } - } - } - pid = result_pid; - - if (working_dir) { - // No more thread specific current working directory - __pthread_fchdir(-1); - } - - return error; -} - -static bool ShouldLaunchUsingXPC(ProcessLaunchInfo &launch_info) { - bool result = false; - -#if !NO_XPC_SERVICES - bool launchingAsRoot = launch_info.GetUserID() == 0; - bool currentUserIsRoot = HostInfo::GetEffectiveUserID() == 0; - - if (launchingAsRoot && !currentUserIsRoot) { - // If current user is already root, we don't need XPC's help. - result = true; - } -#endif - - return result; -} - -Status Host::LaunchProcess(ProcessLaunchInfo &launch_info) { - Status error; - - FileSystem &fs = FileSystem::Instance(); - FileSpec exe_spec(launch_info.GetExecutableFile()); - - if (!fs.Exists(exe_spec)) - FileSystem::Instance().Resolve(exe_spec); - - if (!fs.Exists(exe_spec)) - FileSystem::Instance().ResolveExecutableLocation(exe_spec); - - if (!fs.Exists(exe_spec)) { - error.SetErrorStringWithFormatv("executable doesn't exist: '{0}'", - exe_spec); - return error; - } - - if (launch_info.GetFlags().Test(eLaunchFlagLaunchInTTY)) { -#if !defined(__arm__) && !defined(__arm64__) && !defined(__aarch64__) - return LaunchInNewTerminalWithAppleScript(exe_spec.GetPath().c_str(), - launch_info); -#else - error.SetErrorString("launching a process in a new terminal is not " - "supported on iOS devices"); - return error; -#endif - } - - lldb::pid_t pid = LLDB_INVALID_PROCESS_ID; - - if (ShouldLaunchUsingXPC(launch_info)) { - error = LaunchProcessXPC(exe_spec.GetPath().c_str(), launch_info, pid); - } else { - error = - LaunchProcessPosixSpawn(exe_spec.GetPath().c_str(), launch_info, pid); - } - - if (pid != LLDB_INVALID_PROCESS_ID) { - // If all went well, then set the process ID into the launch info - launch_info.SetProcessID(pid); - - // Make sure we reap any processes we spawn or we will have zombies. - bool monitoring = launch_info.MonitorProcess(); - UNUSED_IF_ASSERT_DISABLED(monitoring); - assert(monitoring); - } else { - // Invalid process ID, something didn't go well - if (error.Success()) - error.SetErrorString("process launch failed for unknown reasons"); - } - return error; -} - -Status Host::ShellExpandArguments(ProcessLaunchInfo &launch_info) { - Status error; - if (launch_info.GetFlags().Test(eLaunchFlagShellExpandArguments)) { - FileSpec expand_tool_spec = HostInfo::GetSupportExeDir(); - if (!expand_tool_spec) { - error.SetErrorString( - "could not get support executable directory for lldb-argdumper tool"); - return error; - } - expand_tool_spec.AppendPathComponent("lldb-argdumper"); - if (!FileSystem::Instance().Exists(expand_tool_spec)) { - error.SetErrorStringWithFormat( - "could not find the lldb-argdumper tool: %s", - expand_tool_spec.GetPath().c_str()); - return error; - } - - StreamString expand_tool_spec_stream; - expand_tool_spec_stream.Printf("\"%s\"", - expand_tool_spec.GetPath().c_str()); - - Args expand_command(expand_tool_spec_stream.GetData()); - expand_command.AppendArguments(launch_info.GetArguments()); - - int status; - std::string output; - FileSpec cwd(launch_info.GetWorkingDirectory()); - if (!FileSystem::Instance().Exists(cwd)) { - char *wd = getcwd(nullptr, 0); - if (wd == nullptr) { - error.SetErrorStringWithFormat( - "cwd does not exist; cannot launch with shell argument expansion"); - return error; - } else { - FileSpec working_dir(wd); - free(wd); - launch_info.SetWorkingDirectory(working_dir); - } - } - RunShellCommand(expand_command, cwd, &status, nullptr, &output, - std::chrono::seconds(10)); - - if (status != 0) { - error.SetErrorStringWithFormat("lldb-argdumper exited with error %d", - status); - return error; - } - - auto data_sp = StructuredData::ParseJSON(output); - if (!data_sp) { - error.SetErrorString("invalid JSON"); - return error; - } - - auto dict_sp = data_sp->GetAsDictionary(); - if (!data_sp) { - error.SetErrorString("invalid JSON"); - return error; - } - - auto args_sp = dict_sp->GetObjectForDotSeparatedPath("arguments"); - if (!args_sp) { - error.SetErrorString("invalid JSON"); - return error; - } - - auto args_array_sp = args_sp->GetAsArray(); - if (!args_array_sp) { - error.SetErrorString("invalid JSON"); - return error; - } - - launch_info.GetArguments().Clear(); - - for (size_t i = 0; i < args_array_sp->GetSize(); i++) { - auto item_sp = args_array_sp->GetItemAtIndex(i); - if (!item_sp) - continue; - auto str_sp = item_sp->GetAsString(); - if (!str_sp) - continue; - - launch_info.GetArguments().AppendArgument(str_sp->GetValue()); - } - } - - return error; -} - -HostThread Host::StartMonitoringChildProcess( - const Host::MonitorChildProcessCallback &callback, lldb::pid_t pid, - bool monitor_signals) { - unsigned long mask = DISPATCH_PROC_EXIT; - if (monitor_signals) - mask |= DISPATCH_PROC_SIGNAL; - - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_HOST | - LIBLLDB_LOG_PROCESS)); - - dispatch_source_t source = ::dispatch_source_create( - DISPATCH_SOURCE_TYPE_PROC, pid, mask, - ::dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)); - - if (log) - log->Printf("Host::StartMonitoringChildProcess " - "(callback, pid=%i, monitor_signals=%i) " - "source = %p\n", - static_cast<int>(pid), monitor_signals, - reinterpret_cast<void *>(source)); - - if (source) { - Host::MonitorChildProcessCallback callback_copy = callback; - ::dispatch_source_set_cancel_handler(source, ^{ - dispatch_release(source); - }); - ::dispatch_source_set_event_handler(source, ^{ - - int status = 0; - int wait_pid = 0; - bool cancel = false; - bool exited = false; - wait_pid = llvm::sys::RetryAfterSignal(-1, ::waitpid, pid, &status, 0); - if (wait_pid >= 0) { - int signal = 0; - int exit_status = 0; - const char *status_cstr = NULL; - if (WIFSTOPPED(status)) { - signal = WSTOPSIG(status); - status_cstr = "STOPPED"; - } else if (WIFEXITED(status)) { - exit_status = WEXITSTATUS(status); - status_cstr = "EXITED"; - exited = true; - } else if (WIFSIGNALED(status)) { - signal = WTERMSIG(status); - status_cstr = "SIGNALED"; - exited = true; - exit_status = -1; - } else { - status_cstr = "???"; - } - - if (log) - log->Printf("::waitpid (pid = %llu, &status, 0) => pid = %i, status " - "= 0x%8.8x (%s), signal = %i, exit_status = %i", - pid, wait_pid, status, status_cstr, signal, exit_status); - - if (callback_copy) - cancel = callback_copy(pid, exited, signal, exit_status); - - if (exited || cancel) { - ::dispatch_source_cancel(source); - } - } - }); - - ::dispatch_resume(source); - } - return HostThread(); -} - -//---------------------------------------------------------------------- -// Log to both stderr and to ASL Logging when running on MacOSX. -//---------------------------------------------------------------------- -void Host::SystemLog(SystemLogType type, const char *format, va_list args) { - if (format && format[0]) { - static aslmsg g_aslmsg = NULL; - if (g_aslmsg == NULL) { - g_aslmsg = ::asl_new(ASL_TYPE_MSG); - char asl_key_sender[PATH_MAX]; - snprintf(asl_key_sender, sizeof(asl_key_sender), - "com.apple.LLDB.framework"); - ::asl_set(g_aslmsg, ASL_KEY_SENDER, asl_key_sender); - } - - // Copy the va_list so we can log this message twice - va_list copy_args; - va_copy(copy_args, args); - // Log to stderr - ::vfprintf(stderr, format, copy_args); - va_end(copy_args); - - int asl_level; - switch (type) { - case eSystemLogError: - asl_level = ASL_LEVEL_ERR; - break; - - case eSystemLogWarning: - asl_level = ASL_LEVEL_WARNING; - break; - } - - // Log to ASL - ::asl_vlog(NULL, g_aslmsg, asl_level, format, args); - } -} diff --git a/source/Host/macosx/objcxx/HostInfoMacOSX.mm b/source/Host/macosx/objcxx/HostInfoMacOSX.mm deleted file mode 100644 index 165e87e8bed4..000000000000 --- a/source/Host/macosx/objcxx/HostInfoMacOSX.mm +++ /dev/null @@ -1,280 +0,0 @@ -//===-- HostInfoMacOSX.mm ---------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "lldb/Host/macosx/HostInfoMacOSX.h" -#include "lldb/Host/FileSystem.h" -#include "lldb/Host/HostInfo.h" -#include "lldb/Utility/Args.h" -#include "lldb/Utility/Log.h" - -#include "llvm/ADT/SmallString.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/Path.h" -#include "llvm/Support/raw_ostream.h" - -// C++ Includes -#include <string> - -// C inclues -#include <stdlib.h> -#include <sys/sysctl.h> -#include <sys/syslimits.h> -#include <sys/types.h> - -// Objective-C/C++ includes -#include <CoreFoundation/CoreFoundation.h> -#include <Foundation/Foundation.h> -#include <mach-o/dyld.h> -#include <objc/objc-auto.h> - -// These are needed when compiling on systems -// that do not yet have these definitions -#include <AvailabilityMacros.h> -#ifndef CPU_SUBTYPE_X86_64_H -#define CPU_SUBTYPE_X86_64_H ((cpu_subtype_t)8) -#endif -#ifndef CPU_TYPE_ARM64 -#define CPU_TYPE_ARM64 (CPU_TYPE_ARM | CPU_ARCH_ABI64) -#endif - -#include <TargetConditionals.h> // for TARGET_OS_TV, TARGET_OS_WATCH - -using namespace lldb_private; - -bool HostInfoMacOSX::GetOSBuildString(std::string &s) { - int mib[2] = {CTL_KERN, KERN_OSVERSION}; - char cstr[PATH_MAX]; - size_t cstr_len = sizeof(cstr); - if (::sysctl(mib, 2, cstr, &cstr_len, NULL, 0) == 0) { - s.assign(cstr, cstr_len); - return true; - } - - s.clear(); - return false; -} - -bool HostInfoMacOSX::GetOSKernelDescription(std::string &s) { - int mib[2] = {CTL_KERN, KERN_VERSION}; - char cstr[PATH_MAX]; - size_t cstr_len = sizeof(cstr); - if (::sysctl(mib, 2, cstr, &cstr_len, NULL, 0) == 0) { - s.assign(cstr, cstr_len); - return true; - } - s.clear(); - return false; -} - -llvm::VersionTuple HostInfoMacOSX::GetOSVersion() { - static llvm::VersionTuple g_version; - - if (g_version.empty()) { - @autoreleasepool { - NSDictionary *version_info = [NSDictionary - dictionaryWithContentsOfFile: - @"/System/Library/CoreServices/SystemVersion.plist"]; - NSString *version_value = [version_info objectForKey:@"ProductVersion"]; - const char *version_str = [version_value UTF8String]; - g_version.tryParse(version_str); - } - } - - return g_version; -} - -FileSpec HostInfoMacOSX::GetProgramFileSpec() { - static FileSpec g_program_filespec; - if (!g_program_filespec) { - char program_fullpath[PATH_MAX]; - // If DST is NULL, then return the number of bytes needed. - uint32_t len = sizeof(program_fullpath); - int err = _NSGetExecutablePath(program_fullpath, &len); - if (err == 0) - g_program_filespec.SetFile(program_fullpath, FileSpec::Style::native); - else if (err == -1) { - char *large_program_fullpath = (char *)::malloc(len + 1); - - err = _NSGetExecutablePath(large_program_fullpath, &len); - if (err == 0) - g_program_filespec.SetFile(large_program_fullpath, - FileSpec::Style::native); - - ::free(large_program_fullpath); - } - } - return g_program_filespec; -} - -bool HostInfoMacOSX::ComputeSupportExeDirectory(FileSpec &file_spec) { - FileSpec lldb_file_spec = GetShlibDir(); - if (!lldb_file_spec) - return false; - - std::string raw_path = lldb_file_spec.GetPath(); - - size_t framework_pos = raw_path.find("LLDB.framework"); - if (framework_pos != std::string::npos) { - framework_pos += strlen("LLDB.framework"); -#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__) - // Shallow bundle - raw_path.resize(framework_pos); -#else - // Normal bundle - raw_path.resize(framework_pos); - raw_path.append("/Resources"); -#endif - } else { - // Find the bin path relative to the lib path where the cmake-based - // OS X .dylib lives. This is not going to work if the bin and lib - // dir are not both in the same dir. - // - // It is not going to work to do it by the executable path either, - // as in the case of a python script, the executable is python, not - // the lldb driver. - raw_path.append("/../bin"); - FileSpec support_dir_spec(raw_path); - FileSystem::Instance().Resolve(support_dir_spec); - if (!FileSystem::Instance().IsDirectory(support_dir_spec)) { - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); - if (log) - log->Printf("HostInfoMacOSX::%s(): failed to find support directory", - __FUNCTION__); - return false; - } - - // Get normalization from support_dir_spec. Note the FileSpec resolve - // does not remove '..' in the path. - char *const dir_realpath = - realpath(support_dir_spec.GetPath().c_str(), NULL); - if (dir_realpath) { - raw_path = dir_realpath; - free(dir_realpath); - } else { - raw_path = support_dir_spec.GetPath(); - } - } - - file_spec.GetDirectory().SetString( - llvm::StringRef(raw_path.c_str(), raw_path.size())); - return (bool)file_spec.GetDirectory(); -} - -bool HostInfoMacOSX::ComputeHeaderDirectory(FileSpec &file_spec) { - FileSpec lldb_file_spec = GetShlibDir(); - if (!lldb_file_spec) - return false; - - std::string raw_path = lldb_file_spec.GetPath(); - - size_t framework_pos = raw_path.find("LLDB.framework"); - if (framework_pos != std::string::npos) { - framework_pos += strlen("LLDB.framework"); - raw_path.resize(framework_pos); - raw_path.append("/Headers"); - } - file_spec.GetDirectory().SetString( - llvm::StringRef(raw_path.c_str(), raw_path.size())); - return true; -} - -bool HostInfoMacOSX::ComputeSystemPluginsDirectory(FileSpec &file_spec) { - FileSpec lldb_file_spec = GetShlibDir(); - if (!lldb_file_spec) - return false; - - std::string raw_path = lldb_file_spec.GetPath(); - - size_t framework_pos = raw_path.find("LLDB.framework"); - if (framework_pos == std::string::npos) - return false; - - framework_pos += strlen("LLDB.framework"); - raw_path.resize(framework_pos); - raw_path.append("/Resources/PlugIns"); - file_spec.GetDirectory().SetString( - llvm::StringRef(raw_path.c_str(), raw_path.size())); - return true; -} - -bool HostInfoMacOSX::ComputeUserPluginsDirectory(FileSpec &file_spec) { - FileSpec temp_file("~/Library/Application Support/LLDB/PlugIns"); - FileSystem::Instance().Resolve(temp_file); - file_spec.GetDirectory().SetCString(temp_file.GetPath().c_str()); - return true; -} - -void HostInfoMacOSX::ComputeHostArchitectureSupport(ArchSpec &arch_32, - ArchSpec &arch_64) { - // All apple systems support 32 bit execution. - uint32_t cputype, cpusubtype; - uint32_t is_64_bit_capable = false; - size_t len = sizeof(cputype); - ArchSpec host_arch; - // These will tell us about the kernel architecture, which even on a 64 - // bit machine can be 32 bit... - if (::sysctlbyname("hw.cputype", &cputype, &len, NULL, 0) == 0) { - len = sizeof(cpusubtype); - if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) != 0) - cpusubtype = CPU_TYPE_ANY; - - len = sizeof(is_64_bit_capable); - ::sysctlbyname("hw.cpu64bit_capable", &is_64_bit_capable, &len, NULL, 0); - - if (is_64_bit_capable) { - if (cputype & CPU_ARCH_ABI64) { - // We have a 64 bit kernel on a 64 bit system - arch_64.SetArchitecture(eArchTypeMachO, cputype, cpusubtype); - } else { - // We have a 64 bit kernel that is returning a 32 bit cputype, the - // cpusubtype will be correct as if it were for a 64 bit architecture - arch_64.SetArchitecture(eArchTypeMachO, cputype | CPU_ARCH_ABI64, - cpusubtype); - } - - // Now we need modify the cpusubtype for the 32 bit slices. - uint32_t cpusubtype32 = cpusubtype; -#if defined(__i386__) || defined(__x86_64__) - if (cpusubtype == CPU_SUBTYPE_486 || cpusubtype == CPU_SUBTYPE_X86_64_H) - cpusubtype32 = CPU_SUBTYPE_I386_ALL; -#elif defined(__arm__) || defined(__arm64__) || defined(__aarch64__) - if (cputype == CPU_TYPE_ARM || cputype == CPU_TYPE_ARM64) - cpusubtype32 = CPU_SUBTYPE_ARM_V7S; -#endif - arch_32.SetArchitecture(eArchTypeMachO, cputype & ~(CPU_ARCH_MASK), - cpusubtype32); - - if (cputype == CPU_TYPE_ARM || cputype == CPU_TYPE_ARM64) { -// When running on a watch or tv, report the host os correctly -#if defined(TARGET_OS_TV) && TARGET_OS_TV == 1 - arch_32.GetTriple().setOS(llvm::Triple::TvOS); - arch_64.GetTriple().setOS(llvm::Triple::TvOS); -#elif defined(TARGET_OS_BRIDGE) && TARGET_OS_BRIDGE == 1 - arch_32.GetTriple().setOS(llvm::Triple::BridgeOS); - arch_64.GetTriple().setOS(llvm::Triple::BridgeOS); -#else - arch_32.GetTriple().setOS(llvm::Triple::IOS); - arch_64.GetTriple().setOS(llvm::Triple::IOS); -#endif - } else { - arch_32.GetTriple().setOS(llvm::Triple::MacOSX); - arch_64.GetTriple().setOS(llvm::Triple::MacOSX); - } - } else { - // We have a 32 bit kernel on a 32 bit system - arch_32.SetArchitecture(eArchTypeMachO, cputype, cpusubtype); -#if defined(TARGET_OS_WATCH) && TARGET_OS_WATCH == 1 - arch_32.GetTriple().setOS(llvm::Triple::WatchOS); -#else - arch_32.GetTriple().setOS(llvm::Triple::IOS); -#endif - arch_64.Clear(); - } - } -} diff --git a/source/Host/macosx/objcxx/HostThreadMacOSX.mm b/source/Host/macosx/objcxx/HostThreadMacOSX.mm deleted file mode 100644 index c5051cdf30d7..000000000000 --- a/source/Host/macosx/objcxx/HostThreadMacOSX.mm +++ /dev/null @@ -1,70 +0,0 @@ -//===-- HostThreadMacOSX.cpp ------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "lldb/Host/macosx/HostThreadMacOSX.h" -#include "lldb/Host/Host.h" - -#include <CoreFoundation/CoreFoundation.h> -#include <Foundation/Foundation.h> - -#include <pthread.h> - -using namespace lldb_private; - -namespace { - -pthread_once_t g_thread_create_once = PTHREAD_ONCE_INIT; -pthread_key_t g_thread_create_key = 0; - -class MacOSXDarwinThread { -public: - MacOSXDarwinThread() : m_pool(nil) { - m_pool = [[NSAutoreleasePool alloc] init]; - } - - ~MacOSXDarwinThread() { - if (m_pool) { - [m_pool drain]; - m_pool = nil; - } - } - - static void PThreadDestructor(void *v) { - if (v) - delete static_cast<MacOSXDarwinThread *>(v); - ::pthread_setspecific(g_thread_create_key, NULL); - } - -protected: - NSAutoreleasePool *m_pool; - -private: - DISALLOW_COPY_AND_ASSIGN(MacOSXDarwinThread); -}; - -void InitThreadCreated() { - ::pthread_key_create(&g_thread_create_key, - MacOSXDarwinThread::PThreadDestructor); -} -} // namespace - -HostThreadMacOSX::HostThreadMacOSX() : HostThreadPosix() {} - -HostThreadMacOSX::HostThreadMacOSX(lldb::thread_t thread) - : HostThreadPosix(thread) {} - -lldb::thread_result_t -HostThreadMacOSX::ThreadCreateTrampoline(lldb::thread_arg_t arg) { - ::pthread_once(&g_thread_create_once, InitThreadCreated); - if (g_thread_create_key) { - ::pthread_setspecific(g_thread_create_key, new MacOSXDarwinThread()); - } - - return HostThreadPosix::ThreadCreateTrampoline(arg); -} |