aboutsummaryrefslogtreecommitdiff
path: root/source/Host/macosx/Symbols.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-01-02 19:26:05 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-01-02 19:26:05 +0000
commit14f1b3e8826ce43b978db93a62d1166055db5394 (patch)
tree0a00ad8d3498783fe0193f3b656bca17c4c8697d /source/Host/macosx/Symbols.cpp
parent4ee8c119c71a06dcad1e0fecc8c675e480e59337 (diff)
downloadsrc-14f1b3e8826ce43b978db93a62d1166055db5394.tar.gz
src-14f1b3e8826ce43b978db93a62d1166055db5394.zip
Vendor import of lldb trunk r290819:vendor/lldb/lldb-trunk-r290819
Notes
Notes: svn path=/vendor/lldb/dist/; revision=311128 svn path=/vendor/lldb/lldb-trunk-r290819/; revision=311129; tag=vendor/lldb/lldb-trunk-r290819
Diffstat (limited to 'source/Host/macosx/Symbols.cpp')
-rw-r--r--source/Host/macosx/Symbols.cpp987
1 files changed, 512 insertions, 475 deletions
diff --git a/source/Host/macosx/Symbols.cpp b/source/Host/macosx/Symbols.cpp
index f6a18febe6da..c428377eb7d2 100644
--- a/source/Host/macosx/Symbols.cpp
+++ b/source/Host/macosx/Symbols.cpp
@@ -10,15 +10,19 @@
#include "lldb/Host/Symbols.h"
// C Includes
+#include "lldb/Utility/SafeMachO.h"
#include <dirent.h>
#include <pwd.h>
-#include "lldb/Utility/SafeMachO.h"
// C++ Includes
// Other libraries and framework includes
#include <CoreFoundation/CoreFoundation.h>
// Project includes
+#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/ArchSpec.h"
#include "lldb/Core/DataBuffer.h"
#include "lldb/Core/DataExtractor.h"
@@ -32,528 +36,561 @@
#include "lldb/Host/Host.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Utility/CleanUp.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 "mach/machine.h"
using namespace lldb;
using namespace lldb_private;
using namespace llvm::MachO;
-#if !defined (__arm__) && !defined (__arm64__) && !defined (__aarch64__) // No DebugSymbols on the iOS devices
+#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);
-
+CFURLRef DBGCopyFullDSYMURLForUUID(CFUUIDRef uuid, CFURLRef exec_url);
+CFDictionaryRef DBGCopyDSYMPropertyLists(CFURLRef dsym_url);
}
#endif
-int
-LocateMacOSXFilesUsingDebugSymbols
-(
- const ModuleSpec &module_spec,
- ModuleSpec &return_module_spec
-)
-{
- 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
- const UInt8 *module_uuid = (const UInt8 *)uuid->GetBytes();
- if (module_uuid != NULL)
- {
- 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();
- Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
- 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];
+int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec,
+ ModuleSpec &return_module_spec) {
+ 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
+ const UInt8 *module_uuid = (const UInt8 *)uuid->GetBytes();
+ if (module_uuid != NULL) {
+ 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();
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
+ 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));
+ }
- if (dsym_url.get())
+ 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, path[0] == '~');
+
+ if (dsym_filespec.GetFileType() == FileSpec::eFileTypeDirectory) {
+ 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, path[0] == '~');
+ if (exec_filespec.Exists()) {
+ 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, true);
+ ModuleSpecList module_specs;
+ ModuleSpec matched_module_spec;
+ switch (file_spec.GetFileType()) {
+ case FileSpec::eFileTypeDirectory: // Bundle directory?
{
- 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, path[0] == '~');
-
- if (dsym_filespec.GetFileType () == FileSpec::eFileTypeDirectory)
- {
- 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());
+ 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, true);
+ 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);
}
-
+ }
}
-
- 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, path[0] == '~');
- if (exec_filespec.Exists())
- {
- 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, true);
- ModuleSpecList module_specs;
- ModuleSpec matched_module_spec;
- switch (file_spec.GetFileType())
- {
- case FileSpec::eFileTypeDirectory: // 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, true);
- 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 FileSpec::eFileTypePipe: // Forget pipes
- case FileSpec::eFileTypeSocket: // We can't process socket files
- case FileSpec::eFileTypeInvalid: // File doesn't exist...
- break;
-
- case FileSpec::eFileTypeUnknown:
- case FileSpec::eFileTypeRegular:
- case FileSpec::eFileTypeSymbolicLink:
- case FileSpec::eFileTypeOther:
- 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;
- }
- }
- }
+ }
+ } break;
+
+ case FileSpec::eFileTypePipe: // Forget pipes
+ case FileSpec::eFileTypeSocket: // We can't process socket files
+ case FileSpec::eFileTypeInvalid: // File doesn't exist...
+ break;
+
+ case FileSpec::eFileTypeUnknown:
+ case FileSpec::eFileTypeRegular:
+ case FileSpec::eFileTypeSymbolicLink:
+ case FileSpec::eFileTypeOther:
+ 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__)
+ }
+#endif // #if !defined (__arm__) && !defined (__arm64__) && !defined
+ // (__aarch64__)
- return items_found;
+ return items_found;
}
-FileSpec
-Symbols::FindSymbolFileInBundle (const FileSpec& dsym_bundle_fspec,
- const lldb_private::UUID *uuid,
- const ArchSpec *arch)
-{
- char path[PATH_MAX];
-
- FileSpec dsym_fspec;
-
- if (dsym_bundle_fspec.GetPath(path, sizeof(path)))
- {
- ::strncat (path, "/Contents/Resources/DWARF", sizeof(path) - strlen(path) - 1);
-
- lldb_utility::CleanUp <DIR *, int> dirp (opendir(path), NULL, closedir);
- if (dirp.is_valid())
- {
- dsym_fspec.GetDirectory().SetCString(path);
- struct dirent* dp;
- while ((dp = readdir(dirp.get())) != 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;
- }
+FileSpec Symbols::FindSymbolFileInBundle(const FileSpec &dsym_bundle_fspec,
+ const lldb_private::UUID *uuid,
+ const ArchSpec *arch) {
+ char path[PATH_MAX];
+
+ FileSpec dsym_fspec;
+
+ if (dsym_bundle_fspec.GetPath(path, sizeof(path))) {
+ ::strncat(path, "/Contents/Resources/DWARF",
+ sizeof(path) - strlen(path) - 1);
+
+ lldb_utility::CleanUp<DIR *, int> dirp(opendir(path), NULL, closedir);
+ if (dirp.is_valid()) {
+ dsym_fspec.GetDirectory().SetCString(path);
+ struct dirent *dp;
+ while ((dp = readdir(dirp.get())) != 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)
- {
- assert(module_specs.GetModuleSpecAtIndex(i, spec));
- if ((uuid == NULL || (spec.GetUUIDPtr() && spec.GetUUID() == *uuid)) &&
- (arch == NULL || (spec.GetArchitecturePtr() && spec.GetArchitecture().IsCompatibleMatch(*arch))))
- {
- return dsym_fspec;
- }
- }
- }
- }
+ 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) {
+ assert(module_specs.GetModuleSpecAtIndex(i, spec));
+ if ((uuid == NULL ||
+ (spec.GetUUIDPtr() && spec.GetUUID() == *uuid)) &&
+ (arch == NULL ||
+ (spec.GetArchitecturePtr() &&
+ spec.GetArchitecture().IsCompatibleMatch(*arch)))) {
+ return dsym_fspec;
+ }
}
+ }
}
+ }
}
- dsym_fspec.Clear();
- return dsym_fspec;
+ }
+ dsym_fspec.Clear();
+ return dsym_fspec;
}
-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;
-
- 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(), true);
- 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(), true);
- success = true;
- if (log)
- {
- log->Printf ("From dsymForUUID plist: dSYM is at '%s'", str.c_str());
- }
- }
+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(), true);
+ if (log) {
+ log->Printf(
+ "From dsymForUUID plist: Symbol rich executable 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());
+ }
+ }
+
+ 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(), true);
+ success = true;
+ if (log) {
+ log->Printf("From dsymForUUID plist: dSYM is at '%s'", str.c_str());
}
+ }
+ }
- std::string DBGBuildSourcePath;
- std::string DBGSourcePath;
+ 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());
+ }
- cf_str = (CFStringRef)CFDictionaryGetValue ((CFDictionaryRef) uuid_dict, CFSTR("DBGBuildSourcePath"));
- if (cf_str && CFGetTypeID (cf_str) == CFStringGetTypeID ())
- {
- CFCString::FileSystemRepresentation(cf_str, DBGBuildSourcePath);
- }
+ std::string DBGBuildSourcePath;
+ std::string DBGSourcePath;
- 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())
- {
- module_spec.GetSourceMappingList().Append (ConstString(DBGBuildSourcePath.c_str()), ConstString(DBGSourcePath.c_str()), true);
- }
+ cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict,
+ CFSTR("DBGBuildSourcePath"));
+ if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
+ CFCString::FileSystemRepresentation(cf_str, DBGBuildSourcePath);
}
- return success;
-}
+ cf_str = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)uuid_dict,
+ CFSTR("DBGSourcePath"));
+ if (cf_str && CFGetTypeID(cf_str) == CFStringGetTypeID()) {
+ CFCString::FileSystemRepresentation(cf_str, DBGSourcePath);
+ }
-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 == false)
- {
- 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 (!DBGBuildSourcePath.empty() && !DBGSourcePath.empty()) {
+ if (DBGSourcePath[0] == '~') {
+ FileSpec resolved_source_path(DBGSourcePath.c_str(), true);
+ DBGSourcePath = resolved_source_path.GetPath();
+ }
+ module_spec.GetSourceMappingList().Append(
+ ConstString(DBGBuildSourcePath.c_str()),
+ ConstString(DBGSourcePath.c_str()), true);
+ }
+
+ 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;
+ 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 (defaults_setting)
- {
- CFRelease (defaults_setting);
+ }
+
+ 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 == true &&
+ !original_DBGSourcePath_value.empty()) {
+ DBGSourcePath = original_DBGSourcePath_value;
+ }
+ if (DBGSourcePath[0] == '~') {
+ FileSpec resolved_source_path(DBGSourcePath.c_str(), true);
+ DBGSourcePath = resolved_source_path.GetPath();
+ }
+ module_spec.GetSourceMappingList().Append(
+ ConstString(DBGBuildSourcePath.c_str()),
+ ConstString(DBGSourcePath.c_str()), true);
+ }
+ }
+ if (keys)
+ free(keys);
+ if (values)
+ free(values);
+ }
}
+ }
+ return success;
+}
- // 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 == false && g_dbgshell_command == NULL)
- {
- return false;
+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 == false) {
+ 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 (uuid_ptr || (file_spec_ptr && file_spec_ptr->Exists()))
- {
- 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, true);
- g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists();
+ 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 == false && g_dbgshell_command == NULL) {
+ return false;
+ }
+
+ if (uuid_ptr || (file_spec_ptr && file_spec_ptr->Exists())) {
+ 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, true);
+ g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists();
+ }
+
+ if (!g_dsym_for_uuid_exe_exists) {
+ dsym_for_uuid_exe_spec.SetFile("/usr/local/bin/dsymForUUID", false);
+ g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists();
+ 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(), false);
+ g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists();
}
-
- if (!g_dsym_for_uuid_exe_exists)
- {
- dsym_for_uuid_exe_spec.SetFile("/usr/local/bin/dsymForUUID", false);
- g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists();
- 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(), false);
- g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists();
- }
+ }
+ }
+ }
+ if (!g_dsym_for_uuid_exe_exists && g_dbgshell_command != NULL) {
+ dsym_for_uuid_exe_spec.SetFile(g_dbgshell_command, true);
+ g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists();
+ }
+
+ 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);
+ }
+ Error error = Host::RunShellCommand(
+ command.GetData(),
+ NULL, // current working directory
+ &exit_status, // Exit status
+ &signo, // Signal int *
+ &command_output, // Command output
+ 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;
+ }
}
+ }
}
+ }
}
- if (!g_dsym_for_uuid_exe_exists && g_dbgshell_command != NULL)
- {
- dsym_for_uuid_exe_spec.SetFile(g_dbgshell_command, true);
- g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists();
- }
-
- 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;
+ }
+ } else {
+ if (log) {
if (!uuid_str.empty())
- command.Printf("%s --ignoreNegativeCache --copyExecutable %s", g_dsym_for_uuid_exe_path, uuid_str.c_str());
+ log->Printf("Called %s on %s, no matches",
+ 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);
- }
- Error error = Host::RunShellCommand (command.GetData(),
- NULL, // current working directory
- &exit_status, // Exit status
- &signo, // Signal int *
- &command_output, // Command output
- 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);
- }
- }
- }
+ log->Printf("Called %s on %s, no matches",
+ g_dsym_for_uuid_exe_path, file_path);
+ }
}
+ }
}
- return success;
+ }
+ return success;
}
-