bool PathMappingList::FindFile(const FileSpec &orig_spec, FileSpec &new_spec) const { if (!m_pairs.empty()) { char orig_path[PATH_MAX]; const size_t orig_path_len = orig_spec.GetPath(orig_path, sizeof(orig_path)); if (orig_path_len > 0) { const_iterator pos, end = m_pairs.end(); for (pos = m_pairs.begin(); pos != end; ++pos) { const size_t prefix_len = pos->first.GetLength(); if (orig_path_len >= prefix_len) { if (::strncmp(pos->first.GetCString(), orig_path, prefix_len) == 0) { new_spec.SetFile(pos->second.GetCString(), false); new_spec.AppendPathComponent(orig_path + prefix_len); if (new_spec.Exists()) return true; } } } } } new_spec.Clear(); return false; }
static bool LocateDSYMInVincinityOfExecutable(const ModuleSpec &module_spec, FileSpec &dsym_fspec) { Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); const FileSpec *exec_fspec = module_spec.GetFileSpecPtr(); if (exec_fspec) { char path[PATH_MAX]; if (exec_fspec->GetPath(path, sizeof(path))) { // Make sure the module isn't already just a dSYM file... if (strcasestr(path, ".dSYM/Contents/Resources/DWARF") == NULL) { if (log) { if (module_spec.GetUUIDPtr() && module_spec.GetUUIDPtr()->IsValid()) { log->Printf( "Searching for dSYM bundle next to executable %s, UUID %s", path, module_spec.GetUUIDPtr()->GetAsString().c_str()); } else { log->Printf("Searching for dSYM bundle next to executable %s", path); } } ::strncat(path, ".dSYM/Contents/Resources/DWARF/", sizeof(path) - strlen(path) - 1); ::strncat(path, exec_fspec->GetFilename().AsCString(), sizeof(path) - strlen(path) - 1); dsym_fspec.SetFile(path, false); ModuleSpecList module_specs; ModuleSpec matched_module_spec; if (dsym_fspec.Exists() && FileAtPathContainsArchAndUUID(dsym_fspec, module_spec.GetArchitecturePtr(), module_spec.GetUUIDPtr())) { if (log) { log->Printf("dSYM with matching UUID & arch found at %s", path); } return true; } else { FileSpec parent_dirs = exec_fspec; // Remove the binary name from the FileSpec parent_dirs.RemoveLastPathComponent(); // Add a ".dSYM" name to each directory component of the path, // stripping off components. e.g. we may have a binary like // /S/L/F/Foundation.framework/Versions/A/Foundation // and // /S/L/F/Foundation.framework.dSYM // // so we'll need to start with /S/L/F/Foundation.framework/Versions/A, // add the .dSYM part to the "A", and if that doesn't exist, strip off // the "A" and try it again with "Versions", etc., until we find a // dSYM bundle or we've stripped off enough path components that // there's no need to continue. for (int i = 0; i < 4; i++) { // Does this part of the path have a "." character - could it be a // bundle's top level directory? const char *fn = parent_dirs.GetFilename().AsCString(); if (fn == nullptr) break; if (::strchr(fn, '.') != nullptr) { dsym_fspec = parent_dirs; dsym_fspec.RemoveLastPathComponent(); // If the current directory name is "Foundation.framework", see if // "Foundation.framework.dSYM/Contents/Resources/DWARF/Foundation" // exists & has the right uuid. std::string dsym_fn = fn; dsym_fn += ".dSYM"; dsym_fspec.AppendPathComponent(dsym_fn.c_str()); dsym_fspec.AppendPathComponent("Contents"); dsym_fspec.AppendPathComponent("Resources"); dsym_fspec.AppendPathComponent("DWARF"); dsym_fspec.AppendPathComponent( exec_fspec->GetFilename().AsCString()); if (dsym_fspec.Exists() && FileAtPathContainsArchAndUUID( dsym_fspec, module_spec.GetArchitecturePtr(), module_spec.GetUUIDPtr())) { if (log) { log->Printf("dSYM with matching UUID & arch found at %s", dsym_fspec.GetPath().c_str()); } return true; } } parent_dirs.RemoveLastPathComponent(); } } } } } dsym_fspec.Clear(); return false; }