void DynamicLoaderMacOSXDYLD::UpdateImageInfosHeaderAndLoadCommands( ImageInfo::collection &image_infos, uint32_t infos_count, bool update_executable) { uint32_t exe_idx = UINT32_MAX; // Read any UUID values that we can get for (uint32_t i = 0; i < infos_count; i++) { if (!image_infos[i].UUIDValid()) { DataExtractor data; // Load command data if (!ReadMachHeader(image_infos[i].address, &image_infos[i].header, &data)) continue; ParseLoadCommands(data, image_infos[i], NULL); if (image_infos[i].header.filetype == llvm::MachO::MH_EXECUTE) exe_idx = i; } } Target &target = m_process->GetTarget(); if (exe_idx < image_infos.size()) { const bool can_create = true; ModuleSP exe_module_sp( FindTargetModuleForImageInfo(image_infos[exe_idx], can_create, NULL)); if (exe_module_sp) { UpdateImageLoadAddress(exe_module_sp.get(), image_infos[exe_idx]); if (exe_module_sp.get() != target.GetExecutableModulePointer()) { // Don't load dependent images since we are in dyld where we will know // and find out about all images that are loaded. Also when setting the // executable module, it will clear the targets module list, and if we // have an in memory dyld module, it will get removed from the list // so we will need to add it back after setting the executable module, // so we first try and see if we already have a weak pointer to the // dyld module, make it into a shared pointer, then add the executable, // then re-add it back to make sure it is always in the list. ModuleSP dyld_module_sp(GetDYLDModule()); const bool get_dependent_images = false; m_process->GetTarget().SetExecutableModule(exe_module_sp, get_dependent_images); if (dyld_module_sp) { if (target.GetImages().AppendIfNeeded(dyld_module_sp)) { std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex()); // Also add it to the section list. UpdateImageLoadAddress(dyld_module_sp.get(), m_dyld); } } } } } }
bool DynamicLoaderMacOSXDYLD::ReadImageInfos (lldb::addr_t image_infos_addr, uint32_t image_infos_count, ImageInfo::collection &image_infos) { std::lock_guard<std::recursive_mutex> baseclass_guard(GetMutex()); const ByteOrder endian = GetByteOrderFromMagic (m_dyld.header.magic); const uint32_t addr_size = m_dyld.GetAddressByteSize(); image_infos.resize(image_infos_count); const size_t count = image_infos.size() * 3 * addr_size; DataBufferHeap info_data(count, 0); Error error; const size_t bytes_read = m_process->ReadMemory (image_infos_addr, info_data.GetBytes(), info_data.GetByteSize(), error); if (bytes_read == count) { lldb::offset_t info_data_offset = 0; DataExtractor info_data_ref(info_data.GetBytes(), info_data.GetByteSize(), endian, addr_size); for (size_t i = 0; i < image_infos.size() && info_data_ref.ValidOffset(info_data_offset); i++) { image_infos[i].address = info_data_ref.GetPointer(&info_data_offset); lldb::addr_t path_addr = info_data_ref.GetPointer(&info_data_offset); image_infos[i].mod_date = info_data_ref.GetPointer(&info_data_offset); char raw_path[PATH_MAX]; m_process->ReadCStringFromMemory (path_addr, raw_path, sizeof(raw_path), error); // don't resolve the path if (error.Success()) { const bool resolve_path = false; image_infos[i].file_spec.SetFile(raw_path, resolve_path); } } return true; } else { return false; } }