size_t ModuleList::FindModules ( const FileSpec *file_spec_ptr, const ArchSpec *arch_ptr, const lldb_private::UUID *uuid_ptr, const ConstString *object_name, ModuleList& matching_module_list ) const { size_t existing_matches = matching_module_list.GetSize(); ModuleMatches matcher (file_spec_ptr, arch_ptr, uuid_ptr, object_name, false); Mutex::Locker locker(m_modules_mutex); collection::const_iterator end = m_modules.end(); collection::const_iterator pos; for (pos = std::find_if (m_modules.begin(), end, matcher); pos != end; pos = std::find_if (++pos, end, matcher)) { ModuleSP module_sp(*pos); matching_module_list.Append(module_sp); } return matching_module_list.GetSize() - existing_matches; }
//---------------------------------------------------------------------- // Assume that dyld is in memory at ADDR and try to parse it's load // commands //---------------------------------------------------------------------- bool DynamicLoaderMacOSXDYLD::ReadDYLDInfoFromMemoryAndSetNotificationCallback(lldb::addr_t addr) { std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex()); DataExtractor data; // Load command data if (ReadMachHeader (addr, &m_dyld.header, &data)) { if (m_dyld.header.filetype == llvm::MachO::MH_DYLINKER) { m_dyld.address = addr; ModuleSP dyld_module_sp; if (ParseLoadCommands (data, m_dyld, &m_dyld.file_spec)) { if (m_dyld.file_spec) { UpdateDYLDImageInfoFromNewImageInfo (m_dyld); } } dyld_module_sp = GetDYLDModule(); Target &target = m_process->GetTarget(); if (m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS && dyld_module_sp.get()) { static ConstString g_dyld_all_image_infos ("dyld_all_image_infos"); const Symbol *symbol = dyld_module_sp->FindFirstSymbolWithNameAndType (g_dyld_all_image_infos, eSymbolTypeData); if (symbol) m_dyld_all_image_infos_addr = symbol->GetLoadAddress(&target); } // Update all image infos InitializeFromAllImageInfos (); // If we didn't have an executable before, but now we do, then the // dyld module shared pointer might be unique and we may need to add // it again (since Target::SetExecutableModule() will clear the // images). So append the dyld module back to the list if it is /// unique! if (dyld_module_sp) { target.GetImages().AppendIfNeeded (dyld_module_sp); // At this point we should have read in dyld's module, and so we should set breakpoints in it: ModuleList modules; modules.Append(dyld_module_sp); target.ModulesDidLoad(modules); SetDYLDModule (dyld_module_sp); } return true; } } return false; }
size_t ModuleList::FindModules (const ModuleSpec &module_spec, ModuleList& matching_module_list) const { size_t existing_matches = matching_module_list.GetSize(); Mutex::Locker locker(m_modules_mutex); collection::const_iterator pos, end = m_modules.end(); for (pos = m_modules.begin(); pos != end; ++pos) { ModuleSP module_sp(*pos); if (module_sp->MatchesModuleSpec (module_spec)) matching_module_list.Append(module_sp); } return matching_module_list.GetSize() - existing_matches; }
void JITLoaderMono::ProcessEntry (uint32_t type, const addr_t addr, int64_t size) { ModuleSP module_sp; Target &target = m_process->GetTarget(); ModuleList &module_list = target.GetImages(); Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_JIT_LOADER)); switch (type) { case ENTRY_CODE_REGION: // // This entry defines a code region in the JIT. // We represent it using an lldb module. // The entry starts with a magic string so ReadModuleFromMemory () // will create an ObjectFileMono object for it. // char jit_name[64]; snprintf(jit_name, 64, "Mono"); module_sp = m_process->ReadModuleFromMemory( FileSpec(jit_name, false), addr, size); if (module_sp && module_sp->GetObjectFile()) { bool changed; ObjectFileMono *ofile = (ObjectFileMono*)module_sp->GetObjectFile (); module_sp->GetObjectFile()->GetSymtab(); module_list.AppendIfNeeded(module_sp); module_sp->SetLoadAddress(target, 0, true, changed); ModuleList mlist; mlist.Append(module_sp); target.ModulesDidLoad(mlist); m_regions [ofile->GetId ()] = ofile; } else { if (log) log->Printf("JITLoaderMono::%s failed to load module for " "JIT entry at 0x%" PRIx64, __FUNCTION__, addr); } break; case ENTRY_UNLOAD_CODE_REGION: { uint8_t *buf = new uint8_t [size]; Error error; UnloadCodeRegionEntry *entry = (UnloadCodeRegionEntry*)buf; m_process->ReadMemory (addr, buf, size, error); assert (!error.Fail ()); auto iter = m_regions.find (entry->id); assert (iter != m_regions.end ()); ObjectFileMono *ofile = (ObjectFileMono*)iter->second; ModuleList mlist; mlist.Append(ofile->GetModule ()); target.ModulesDidUnload(mlist, true); break; } case ENTRY_METHOD: { uint8_t *buf = new uint8_t [size]; Error error; m_process->ReadMemory (addr, buf, size, error); assert (!error.Fail ()); int region_id = ObjectFileMono::GetMethodEntryRegion(buf, size); auto iter = m_regions.find (region_id); assert (iter != m_regions.end ()); ObjectFileMono *ofile = (ObjectFileMono*)iter->second; ofile->AddMethod (buf, size); // This is needed so breakpoints can be resolved ModuleList mlist; mlist.Append (ofile->GetModule ()); target.ModulesDidLoad (mlist); break; } case ENTRY_TRAMPOLINE: { uint8_t *buf = new uint8_t [size]; Error error; m_process->ReadMemory (addr, buf, size, error); assert (!error.Fail ()); int region_id = ObjectFileMono::GetTrampolineEntryRegion(buf, size); auto iter = m_regions.find (region_id); assert (iter != m_regions.end ()); ObjectFileMono *ofile = (ObjectFileMono*)iter->second; ofile->AddTrampoline (buf, size); break; } default: if (log) log->Printf("JITLoaderMono::%s unknown entry type %d", __FUNCTION__, type); break; } }