void PlatformDarwinKernel::IndexKextsInDirectories (std::vector<lldb_private::FileSpec> kext_dirs) { std::vector<FileSpec> kext_bundles; const uint32_t num_dirs = kext_dirs.size(); for (uint32_t i = 0; i < num_dirs; i++) { const FileSpec &dir = kext_dirs[i]; const bool find_directories = true; const bool find_files = false; const bool find_other = false; FileSpec::EnumerateDirectory (dir.GetPath().c_str(), find_directories, find_files, find_other, GetKextsInDirectory, &kext_bundles); } const uint32_t num_kexts = kext_bundles.size(); for (uint32_t i = 0; i < num_kexts; i++) { const FileSpec &kext = kext_bundles[i]; CFCBundle bundle (kext.GetPath().c_str()); CFStringRef bundle_id (bundle.GetIdentifier()); if (bundle_id && CFGetTypeID (bundle_id) == CFStringGetTypeID ()) { char bundle_id_buf[PATH_MAX]; if (CFStringGetCString (bundle_id, bundle_id_buf, sizeof (bundle_id_buf), kCFStringEncodingUTF8)) { ConstString bundle_conststr(bundle_id_buf); m_name_to_kext_path_map.insert(std::pair<ConstString, FileSpec>(bundle_conststr, kext)); } } } }
static int LocateMacOSXFilesUsingDebugSymbols ( const ModuleSpec &module_spec, FileSpec *out_exec_fspec, // If non-NULL, try and find the executable FileSpec *out_dsym_fspec // If non-NULL try and find the debug symbol file ) { int items_found = 0; if (out_exec_fspec) out_exec_fspec->Clear(); if (out_dsym_fspec) out_dsym_fspec->Clear(); #if !defined (__arm__) // 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(); 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 (out_dsym_fspec) { if (::CFURLGetFileSystemRepresentation (dsym_url.get(), true, (UInt8*)path, sizeof(path)-1)) { out_dsym_fspec->SetFile(path, false); if (out_dsym_fspec->GetFileType () == FileSpec::eFileTypeDirectory) { *out_dsym_fspec = LocateDSYMMachFileInDSYMBundle (*out_dsym_fspec, uuid, arch); if (*out_dsym_fspec) ++items_found; } else { ++items_found; } } } CFCReleaser<CFDictionaryRef> dict(::DBGCopyDSYMPropertyLists (dsym_url.get())); CFDictionaryRef uuid_dict = NULL; if (dict.get()) { char uuid_cstr_buf[64]; const char *uuid_cstr = uuid->GetAsCString (uuid_cstr_buf, sizeof(uuid_cstr_buf)); CFCString uuid_cfstr (uuid_cstr); CFDictionaryRef uuid_dict = static_cast<CFDictionaryRef>(::CFDictionaryGetValue (dict.get(), uuid_cfstr.get())); if (uuid_dict) { CFStringRef actual_src_cfpath = static_cast<CFStringRef>(::CFDictionaryGetValue (uuid_dict, CFSTR("DBGSourcePath"))); if (actual_src_cfpath) { CFStringRef build_src_cfpath = static_cast<CFStringRef>(::CFDictionaryGetValue (uuid_dict, CFSTR("DBGBuildSourcePath"))); if (build_src_cfpath) { char actual_src_path[PATH_MAX]; char build_src_path[PATH_MAX]; ::CFStringGetFileSystemRepresentation (actual_src_cfpath, actual_src_path, sizeof(actual_src_path)); ::CFStringGetFileSystemRepresentation (build_src_cfpath, build_src_path, sizeof(build_src_path)); module_spec.GetSourceMappingList().Append (ConstString(build_src_path), ConstString(actual_src_path), true); } } } } if (out_exec_fspec) { bool success = false; 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))) { ++items_found; out_exec_fspec->SetFile(path, path[0] == '~'); if (out_exec_fspec->Exists()) success = true; } } 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'; FileSpec file_spec (path, true); 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 (FileAtPathContainsArchAndUUID (bundle_exe_file_spec, arch, uuid)) { ++items_found; *out_exec_fspec = bundle_exe_file_spec; } } } } 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 (FileAtPathContainsArchAndUUID (file_spec, arch, uuid)) { ++items_found; *out_exec_fspec = file_spec; } break; } } } } } } } } } #endif // #if !defined (__arm__) return items_found; }
int LocateMacOSXFilesUsingDebugSymbols ( const ModuleSpec &module_spec, FileSpec *out_exec_fspec, // If non-NULL, try and find the executable FileSpec *out_dsym_fspec // If non-NULL try and find the debug symbol file ) { int items_found = 0; if (out_exec_fspec) out_exec_fspec->Clear(); if (out_dsym_fspec) out_dsym_fspec->Clear(); #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 (log) { std::string searching_for; if (out_exec_fspec && out_dsym_fspec) { searching_for = "executable binary and dSYM"; } else if (out_exec_fspec) { searching_for = "executable binary"; } else { searching_for = "dSYM bundle"; } log->Printf ("Calling DebugSymbols framework to locate dSYM bundle for UUID %s, searching for %s", uuid->GetAsString().c_str(), searching_for.c_str()); } CFCReleaser<CFURLRef> dsym_url (::DBGCopyFullDSYMURLForUUID(module_uuid_ref.get(), exec_url.get())); char path[PATH_MAX]; if (dsym_url.get()) { if (out_dsym_fspec) { 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()); } out_dsym_fspec->SetFile(path, path[0] == '~'); if (out_dsym_fspec->GetFileType () == FileSpec::eFileTypeDirectory) { *out_dsym_fspec = Symbols::FindSymbolFileInBundle (*out_dsym_fspec, uuid, arch); if (*out_dsym_fspec) ++items_found; } else { ++items_found; } } } if (out_exec_fspec) { 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; out_exec_fspec->SetFile(path, path[0] == '~'); if (out_exec_fspec->Exists()) success = true; } } 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; *out_exec_fspec = 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; *out_exec_fspec = 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; }