summaryrefslogtreecommitdiff
path: root/source/Host/macosx/Symbols.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Host/macosx/Symbols.cpp')
-rw-r--r--source/Host/macosx/Symbols.cpp655
1 files changed, 0 insertions, 655 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;
-}