info_data mk_hole_info(tactic_state const & s, expr const & hole_args, pos_info const & begin, pos_info end) { return info_data(new hole_info_data(s, hole_args, begin, end)); }
info_data mk_vm_obj_format_info(environment const & env, vm_obj const & thunk) { return info_data(new vm_obj_format_info(env, thunk)); }
info_data mk_identifier_info(name const & full_id) { return info_data(new identifier_info_data(full_id)); }
info_data mk_type_info(expr const & e) { return info_data(new type_info_data(e)); }
void CInfoPortion::load_shared (LPCSTR) { const ITEM_DATA& item_data = *id_to_index::GetById(m_InfoId); CUIXml* pXML = item_data._xml; pXML->SetLocalRoot (pXML->GetRoot()); //loading from XML XML_NODE* pNode = pXML->NavigateToNode(id_to_index::tag_name, item_data.pos_in_file); THROW3 (pNode, "info_portion id=", *item_data.id); //список названий диалогов int dialogs_num = pXML->GetNodesNum(pNode, "dialog"); info_data()->m_DialogNames.clear(); int i = 0; for(; i<dialogs_num; ++i) { shared_str dialog_name = pXML->Read(pNode, "dialog", i,""); info_data()->m_DialogNames.push_back(dialog_name); } //список названий порций информации, которые деактивируются, //после получения этой порции int disable_num = pXML->GetNodesNum(pNode, "disable"); info_data()->m_DisableInfo.clear(); for(i=0; i<disable_num; ++i) { shared_str info_id = pXML->Read(pNode, "disable", i,""); info_data()->m_DisableInfo.push_back(info_id); } //имена скриптовых функций info_data()->m_PhraseScript.Load(pXML, pNode); //индексы статей info_data()->m_Articles.clear(); int articles_num = pXML->GetNodesNum(pNode, "article"); for(i=0; i<articles_num; ++i) { LPCSTR article_str_id = pXML->Read(pNode, "article", i, NULL); THROW(article_str_id); info_data()->m_Articles.push_back(article_str_id); } info_data()->m_ArticlesDisable.clear(); articles_num = pXML->GetNodesNum(pNode, "article_disable"); for(i=0; i<articles_num; ++i) { LPCSTR article_str_id = pXML->Read(pNode, "article_disable", i, NULL); THROW(article_str_id); info_data()->m_ArticlesDisable.push_back(article_str_id); } info_data()->m_GameTasks.clear(); int task_num = pXML->GetNodesNum(pNode, "task"); for(i=0; i<task_num; ++i) { LPCSTR task_str_id = pXML->Read(pNode, "task", i, NULL); THROW(task_str_id); info_data()->m_GameTasks.push_back(task_str_id); } }
bool MachDYLD::ReadDYLIBInfo() { nub_addr_t addr = m_dyld_all_image_infos_addr; if (addr != INVALID_NUB_ADDRESS) { PThreadMutex::Locker locker(m_dyld_info_mutex); //printf("MachDYLD::ReadDYLIBInfo(addr =%8.8p)", addr); bool swap = false; uint32_t i = 0; DYLIBInfo::collection previous_dylibs; previous_dylibs.swap(m_current_dylibs); uint8_t all_dylib_info_data[32]; nub_size_t count = 8 + m_addr_size * 2; nub_size_t bytes_read = DNBProcessMemoryRead(m_pid, addr, count, &all_dylib_info_data[0]); if (bytes_read != count) { m_dylib_info_header.Clear(); return false; } DNBDataRef data(all_dylib_info_data, sizeof(all_dylib_info_data), swap); data.SetPointerSize(m_addr_size); DNBDataRef::offset_t offset = 0; m_dylib_info_header.version = data.Get32(&offset); m_dylib_info_header.dylib_info_count = data.Get32(&offset); m_dylib_info_header.dylib_info_addr = data.GetPointer(&offset); m_dylib_info_header.notification = data.GetPointer(&offset); //printf( "%s: version=%d, count=%d, addr=%8.8p, notify=%8.8p", // __PRETTY_FUNCTION__, // m_dylib_info_header.version, // m_dylib_info_header.dylib_info_count, // m_dylib_info_header.dylib_info_addr, // m_dylib_info_header.notification); switch (m_dylib_info_header.version) { case 1: // 10.4.x and prior { } break; case 2: // 10.5 and later { } break; default: //printf( "Invalid dyld all_dylib_infos version number: %d", m_dylib_info_header.version); return false; break; } // If we made it here, we are assuming that the all dylib info data should // be valid, lets read the info array. if (m_dylib_info_header.dylib_info_count > 0) { if (m_dylib_info_header.dylib_info_addr == 0) { //printf( "dyld is currently updating all_dylib_infos."); } else { m_current_dylibs.resize(m_dylib_info_header.dylib_info_count); count = m_current_dylibs.size() * 3 * m_addr_size; std::vector<uint8_t> info_data(count, 0); bytes_read = DNBProcessMemoryRead(m_pid, m_dylib_info_header.dylib_info_addr, count, &info_data[0]); if (bytes_read == count) { DNBDataRef::offset_t info_data_offset = 0; DNBDataRef info_data_ref(&info_data[0], info_data.size(), swap); info_data_ref.SetPointerSize(m_addr_size); for (i = 0; info_data_ref.ValidOffset(info_data_offset); i++) { assert (i < m_current_dylibs.size()); m_current_dylibs[i].address = info_data_ref.GetPointer(&info_data_offset); nub_addr_t path_addr = info_data_ref.GetPointer(&info_data_offset); m_current_dylibs[i].mod_date = info_data_ref.GetPointer(&info_data_offset); char raw_path[PATH_MAX]; char resolved_path[PATH_MAX]; bytes_read = DNBProcessMemoryRead(m_pid, path_addr, sizeof(raw_path), (char*)&raw_path[0]); if (::realpath(raw_path, resolved_path)) m_current_dylibs[i].path = resolved_path; else m_current_dylibs[i].path = raw_path; } assert(i == m_dylib_info_header.dylib_info_count); UpdateUUIDs(); } else { //printf( "unable to read all data for all_dylib_infos."); m_current_dylibs.clear(); return false; } } } // Read any UUID values that we can get if (m_current_dylibs.empty()) { m_changed_dylibs = previous_dylibs; const size_t num_changed_dylibs = m_changed_dylibs.size(); for (i = 0; i < num_changed_dylibs; i++) { // Indicate the shared library was unloaded by giving it an invalid // address... m_changed_dylibs[i].address = INVALID_NUB_ADDRESS; } } else { m_changed_dylibs.clear(); // Most of the time when we get shared library changes, they just // get appended to the end of the list, so find out the min number // of entries in the current and previous list that match and see // how many are equal. uint32_t curr_dylib_count = m_current_dylibs.size(); uint32_t prev_dylib_count = previous_dylibs.size(); uint32_t common_count = std::min<uint32_t>(prev_dylib_count, curr_dylib_count); MachDYLD::DYLIBInfo::const_iterator curr_pos = m_current_dylibs.begin(); MachDYLD::DYLIBInfo::const_iterator curr_end = m_current_dylibs.end(); MachDYLD::DYLIBInfo::iterator prev_pos = previous_dylibs.begin(); uint32_t idx; for (idx = 0; idx < common_count; idx++) { if (*curr_pos == *prev_pos) { ++curr_pos; ++prev_pos; } else break; } // Remove all the entries that were at the exact same index and that // matched between the previous_dylibs and m_current_dylibs arrays. This will cover // most of the cases as when shared libraries get loaded they get // appended to the end of the list. if (prev_pos != previous_dylibs.begin()) { previous_dylibs.erase(previous_dylibs.begin(), prev_pos); } if (previous_dylibs.empty()) { // We only have new libraries to add, they are the only ones that // have changed. if (curr_pos != curr_end) { m_changed_dylibs.assign(curr_pos, curr_end); } } else { // We still have items in our previous dylib list which means either // one or more shared libraries got unloaded somewhere in the middle // of the list, so we will manually search for each remaining item // in our current list in the previous list for (; curr_pos != curr_end; ++curr_pos) { MachDYLD::DYLIBInfo::iterator pos = std::find(previous_dylibs.begin(), previous_dylibs.end(), *curr_pos); if (pos == previous_dylibs.end()) { // This dylib wasn't here before, add it to our change list m_changed_dylibs.push_back(*curr_pos); } else { // This dylib was in our previous dylib list, it didn't // change, so lets remove it from the previous list so we // don't see it again. previous_dylibs.erase(pos); } } // The only items left if our previous_dylibs array will be shared // libraries that got unloaded (still in previous list, and not // mentioned in the current list). if (!previous_dylibs.empty()) { const size_t num_previous_dylibs = previous_dylibs.size(); for (i = 0; i < num_previous_dylibs; i++) { // Indicate the shared library was unloaded by giving it // an invalid address... previous_dylibs[i].address = INVALID_NUB_ADDRESS; } // Add all remaining previous_dylibs to the changed list with // invalidated addresses so we know they got unloaded. m_changed_dylibs.insert(m_changed_dylibs.end(), previous_dylibs.begin(), previous_dylibs.end()); } } } return true; } return false; }