mirror of
https://github.com/libretro/Play-.git
synced 2025-01-10 10:31:05 +00:00
FunctionsView now support modules.
git-svn-id: http://svn.purei.org/purei/trunk@428 b36208d7-6611-0410-8bec-b1987f11c4a2
This commit is contained in:
parent
d8b20c1b07
commit
1241465ad5
@ -75,7 +75,7 @@ void CIopBios::Reset(Iop::CSifMan* sifMan)
|
||||
m_cpu.m_State.nCOP0[CCOP_SCU::STATUS] |= CMIPS::STATUS_INT;
|
||||
|
||||
m_intrHandlers.clear();
|
||||
m_loadedModules.clear();
|
||||
m_moduleTags.clear();
|
||||
|
||||
DeleteModules();
|
||||
|
||||
@ -197,14 +197,14 @@ void CIopBios::LoadAndStartModule(CELF& elf, const char* path, const char* args,
|
||||
ExecutableRange moduleRange;
|
||||
uint32 entryPoint = LoadExecutable(elf, moduleRange);
|
||||
|
||||
ModuleListIterator moduleIterator(FindModule(moduleRange.first, moduleRange.second));
|
||||
if(moduleIterator == m_loadedModules.end())
|
||||
ModuleTagIterator moduleIterator(FindModule(moduleRange.first, moduleRange.second));
|
||||
if(moduleIterator == m_moduleTags.end())
|
||||
{
|
||||
LOADEDMODULE module;
|
||||
MODULETAG module;
|
||||
module.name = GetModuleNameFromPath(path);
|
||||
module.begin = moduleRange.first;
|
||||
module.end = moduleRange.second;
|
||||
m_loadedModules.push_back(module);
|
||||
m_moduleTags.push_back(module);
|
||||
}
|
||||
|
||||
uint32 threadId = CreateThread(entryPoint, DEFAULT_PRIORITY);
|
||||
@ -263,7 +263,6 @@ void CIopBios::LoadAndStartModule(CELF& elf, const char* path, const char* args,
|
||||
uint32 version = m_cpu.m_pMemoryMap->GetWord(address + 8);
|
||||
string moduleName = ReadModuleName(address + 0xC);
|
||||
IopModuleMapType::iterator module(m_modules.find(moduleName));
|
||||
if(module == m_modules.end()) continue;
|
||||
|
||||
size_t moduleNameLength = moduleName.length();
|
||||
uint32 entryAddress = address + 0x0C + ((moduleNameLength + 3) & ~0x03);
|
||||
@ -271,7 +270,11 @@ void CIopBios::LoadAndStartModule(CELF& elf, const char* path, const char* args,
|
||||
{
|
||||
uint32 target = m_cpu.m_pMemoryMap->GetWord(entryAddress + 4);
|
||||
uint32 functionId = target & 0xFFFF;
|
||||
string functionName = (module->second)->GetFunctionName(functionId);
|
||||
string functionName = "unknown";
|
||||
if(module != m_modules.end())
|
||||
{
|
||||
functionName = (module->second)->GetFunctionName(functionId);
|
||||
}
|
||||
if(m_cpu.m_Functions.Find(address) == NULL)
|
||||
{
|
||||
m_cpu.m_Functions.InsertTag(entryAddress, (string(moduleName) + "_" + functionName).c_str());
|
||||
@ -885,18 +888,18 @@ string CIopBios::GetModuleNameFromPath(const std::string& path)
|
||||
return path;
|
||||
}
|
||||
|
||||
CIopBios::ModuleListIterator CIopBios::FindModule(uint32 beginAddress, uint32 endAddress)
|
||||
CIopBios::ModuleTagIterator CIopBios::FindModule(uint32 beginAddress, uint32 endAddress)
|
||||
{
|
||||
for(LoadedModuleListType::iterator moduleIterator(m_loadedModules.begin());
|
||||
m_loadedModules.end() != moduleIterator; moduleIterator++)
|
||||
for(ModuleTagListType::iterator moduleIterator(m_moduleTags.begin());
|
||||
m_moduleTags.end() != moduleIterator; moduleIterator++)
|
||||
{
|
||||
LOADEDMODULE& module(*moduleIterator);
|
||||
MODULETAG& module(*moduleIterator);
|
||||
if(beginAddress == module.begin && endAddress == module.end)
|
||||
{
|
||||
return moduleIterator;
|
||||
}
|
||||
}
|
||||
return m_loadedModules.end();
|
||||
return m_moduleTags.end();
|
||||
}
|
||||
|
||||
#ifdef DEBUGGER_INCLUDED
|
||||
@ -920,11 +923,11 @@ void CIopBios::LoadDebugTags(Xml::CNode* root)
|
||||
const char* beginAddress = moduleNode->GetAttribute(TAGS_SECTION_IOP_MODULES_MODULE_BEGINADDRESS);
|
||||
const char* endAddress = moduleNode->GetAttribute(TAGS_SECTION_IOP_MODULES_MODULE_ENDADDRESS);
|
||||
if(!moduleName || !beginAddress || !endAddress) continue;
|
||||
LOADEDMODULE module;
|
||||
MODULETAG module;
|
||||
module.name = moduleName;
|
||||
module.begin = lexical_cast_hex<string>(beginAddress);
|
||||
module.end = lexical_cast_hex<string>(endAddress);
|
||||
m_loadedModules.push_back(module);
|
||||
m_moduleTags.push_back(module);
|
||||
}
|
||||
}
|
||||
|
||||
@ -932,10 +935,10 @@ void CIopBios::SaveDebugTags(Xml::CNode* root)
|
||||
{
|
||||
Xml::CNode* moduleSection = new Xml::CNode(TAGS_SECTION_IOP_MODULES, true);
|
||||
|
||||
for(LoadedModuleListType::const_iterator moduleIterator(m_loadedModules.begin());
|
||||
m_loadedModules.end() != moduleIterator; moduleIterator++)
|
||||
for(ModuleTagListType::const_iterator moduleIterator(m_moduleTags.begin());
|
||||
m_moduleTags.end() != moduleIterator; moduleIterator++)
|
||||
{
|
||||
const LOADEDMODULE& module(*moduleIterator);
|
||||
const MODULETAG& module(*moduleIterator);
|
||||
Xml::CNode* moduleNode = new Xml::CNode(TAGS_SECTION_IOP_MODULES_MODULE, true);
|
||||
moduleNode->InsertAttribute(TAGS_SECTION_IOP_MODULES_MODULE_BEGINADDRESS, lexical_cast_hex<string>(module.begin, 8).c_str());
|
||||
moduleNode->InsertAttribute(TAGS_SECTION_IOP_MODULES_MODULE_ENDADDRESS, lexical_cast_hex<string>(module.end, 8).c_str());
|
||||
@ -948,7 +951,17 @@ void CIopBios::SaveDebugTags(Xml::CNode* root)
|
||||
|
||||
#endif
|
||||
|
||||
//void CIopBios::LoadModuleTags(const LOADEDMODULE& module, CMIPSTags& tags, const char* tagCollectionName)
|
||||
CIopBios::ModuleTagIterator CIopBios::GetModuleTagsBegin()
|
||||
{
|
||||
return m_moduleTags.begin();
|
||||
}
|
||||
|
||||
CIopBios::ModuleTagIterator CIopBios::GetModuleTagsEnd()
|
||||
{
|
||||
return m_moduleTags.end();
|
||||
}
|
||||
|
||||
//void CIopBios::LoadModuleTags(const MODULETAG& module, CMIPSTags& tags, const char* tagCollectionName)
|
||||
//{
|
||||
// CMIPSTags moduleTags;
|
||||
// moduleTags.Unserialize((module.name + "." + string(tagCollectionName)).c_str());
|
||||
@ -962,10 +975,10 @@ void CIopBios::SaveDebugTags(Xml::CNode* root)
|
||||
//
|
||||
//void CIopBios::SaveAllModulesTags(CMIPSTags& tags, const char* tagCollectionName)
|
||||
//{
|
||||
// for(LoadedModuleListType::const_iterator moduleIterator(m_loadedModules.begin());
|
||||
// m_loadedModules.end() != moduleIterator; moduleIterator++)
|
||||
// for(LoadedModuleListType::const_iterator moduleIterator(m_moduleTags.begin());
|
||||
// m_moduleTags.end() != moduleIterator; moduleIterator++)
|
||||
// {
|
||||
// const LOADEDMODULE& module(*moduleIterator);
|
||||
// const MODULETAG& module(*moduleIterator);
|
||||
// CMIPSTags moduleTags;
|
||||
// for(CMIPSTags::TagIterator tag(tags.GetTagsBegin());
|
||||
// tag != tags.GetTagsEnd(); tag++)
|
||||
|
@ -20,6 +20,16 @@
|
||||
class CIopBios : public Iop::CBiosBase
|
||||
{
|
||||
public:
|
||||
struct MODULETAG
|
||||
{
|
||||
std::string name;
|
||||
uint32 begin;
|
||||
uint32 end;
|
||||
};
|
||||
|
||||
typedef std::list<MODULETAG> ModuleTagListType;
|
||||
typedef ModuleTagListType::iterator ModuleTagIterator;
|
||||
|
||||
CIopBios(uint32, uint32, CMIPS&, uint8*, uint32);
|
||||
virtual ~CIopBios();
|
||||
|
||||
@ -40,6 +50,9 @@ public:
|
||||
void SaveDebugTags(Framework::Xml::CNode*);
|
||||
#endif
|
||||
|
||||
ModuleTagIterator GetModuleTagsBegin();
|
||||
ModuleTagIterator GetModuleTagsEnd();
|
||||
|
||||
Iop::CIoman* GetIoman();
|
||||
#ifdef _IOP_EMULATE_MODULES
|
||||
Iop::CDbcMan* GetDbcman();
|
||||
@ -107,13 +120,6 @@ private:
|
||||
uint32 arg;
|
||||
};
|
||||
|
||||
struct LOADEDMODULE
|
||||
{
|
||||
std::string name;
|
||||
uint32 begin;
|
||||
uint32 end;
|
||||
};
|
||||
|
||||
enum THREAD_STATUS
|
||||
{
|
||||
THREAD_STATUS_CREATED = 1,
|
||||
@ -127,8 +133,6 @@ private:
|
||||
typedef std::map<std::string, Iop::CModule*> IopModuleMapType;
|
||||
typedef std::map<uint32, SEMAPHORE> SemaphoreMapType;
|
||||
typedef std::map<uint32, INTRHANDLER> IntrHandlerMapType;
|
||||
typedef std::list<LOADEDMODULE> LoadedModuleListType;
|
||||
typedef LoadedModuleListType::iterator ModuleListIterator;
|
||||
typedef std::pair<uint32, uint32> ExecutableRange;
|
||||
|
||||
THREAD& GetThread(uint32);
|
||||
@ -148,7 +152,7 @@ private:
|
||||
void RelocateElf(CELF&, uint32);
|
||||
std::string ReadModuleName(uint32);
|
||||
std::string GetModuleNameFromPath(const std::string&);
|
||||
ModuleListIterator FindModule(uint32, uint32);
|
||||
ModuleTagIterator FindModule(uint32, uint32);
|
||||
// void LoadModuleTags(const LOADEDMODULE&, CMIPSTags&, const char*);
|
||||
// void SaveAllModulesTags(CMIPSTags&, const char*);
|
||||
#ifdef DEBUGGER_INCLUDED
|
||||
@ -179,7 +183,7 @@ private:
|
||||
SemaphoreMapType m_semaphores;
|
||||
IntrHandlerMapType m_intrHandlers;
|
||||
IopModuleMapType m_modules;
|
||||
LoadedModuleListType m_loadedModules;
|
||||
ModuleTagListType m_moduleTags;
|
||||
Iop::CSifMan* m_sifMan;
|
||||
Iop::CStdio* m_stdio;
|
||||
Iop::CIoman* m_ioman;
|
||||
|
@ -38,6 +38,11 @@ string CCdvdfsv::GetId() const
|
||||
return "cdvdfsv";
|
||||
}
|
||||
|
||||
string CCdvdfsv::GetFunctionName(unsigned int) const
|
||||
{
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
void CCdvdfsv::SetIsoImage(CISO9660* iso)
|
||||
{
|
||||
m_iso = iso;
|
||||
|
@ -16,6 +16,7 @@ namespace Iop
|
||||
virtual ~CCdvdfsv();
|
||||
|
||||
virtual std::string GetId() const;
|
||||
virtual std::string GetFunctionName(unsigned int) const;
|
||||
virtual void Invoke(CMIPS&, unsigned int);
|
||||
// virtual void SaveState(Framework::CStream*);
|
||||
// virtual void LoadState(Framework::CStream*);
|
||||
|
@ -29,6 +29,11 @@ string CFileIo::GetId() const
|
||||
return "fileio";
|
||||
}
|
||||
|
||||
string CFileIo::GetFunctionName(unsigned int) const
|
||||
{
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
//IOP Invoke
|
||||
void CFileIo::Invoke(CMIPS& context, unsigned int functionId)
|
||||
{
|
||||
|
@ -130,6 +130,7 @@ namespace Iop
|
||||
virtual ~CFileIo();
|
||||
|
||||
virtual std::string GetId() const;
|
||||
virtual std::string GetFunctionName(unsigned int) const;
|
||||
virtual void Invoke(CMIPS&, unsigned int);
|
||||
virtual void Invoke(uint32, uint32*, uint32, uint32*, uint32, uint8*);
|
||||
|
||||
|
@ -21,6 +21,11 @@ string CLibSd::GetId() const
|
||||
return "libsd";
|
||||
}
|
||||
|
||||
string CLibSd::GetFunctionName(unsigned int) const
|
||||
{
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
void CLibSd::Invoke(CMIPS& context, unsigned int functionId)
|
||||
{
|
||||
throw runtime_error("Not implemented.");
|
||||
|
@ -13,6 +13,7 @@ namespace Iop
|
||||
virtual ~CLibSd();
|
||||
|
||||
std::string GetId() const;
|
||||
std::string GetFunctionName(unsigned int) const;
|
||||
void Invoke(CMIPS&, unsigned int);
|
||||
void Invoke(uint32, uint32*, uint32, uint32*, uint32, uint8*);
|
||||
|
||||
|
@ -43,6 +43,11 @@ string CMcServ::GetId() const
|
||||
return "mcserv";
|
||||
}
|
||||
|
||||
string CMcServ::GetFunctionName(unsigned int) const
|
||||
{
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
void CMcServ::Invoke(CMIPS& context, unsigned int functionId)
|
||||
{
|
||||
throw runtime_error("Not implemented.");
|
||||
|
@ -16,6 +16,7 @@ namespace Iop
|
||||
CMcServ(CSifMan&);
|
||||
virtual ~CMcServ();
|
||||
std::string GetId() const;
|
||||
std::string GetFunctionName(unsigned int) const;
|
||||
void Invoke(CMIPS&, unsigned int);
|
||||
virtual void Invoke(uint32, uint32*, uint32, uint32*, uint32, uint8*);
|
||||
// virtual void SaveState(Framework::CStream*);
|
||||
|
@ -37,6 +37,11 @@ string CPadMan::GetId() const
|
||||
return "padman";
|
||||
}
|
||||
|
||||
string CPadMan::GetFunctionName(unsigned int) const
|
||||
{
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
void CPadMan::Invoke(CMIPS& context, unsigned int functionId)
|
||||
{
|
||||
throw runtime_error("Not implemented.");
|
||||
|
@ -17,6 +17,7 @@ namespace Iop
|
||||
public:
|
||||
CPadMan(CSifMan&);
|
||||
std::string GetId() const;
|
||||
std::string GetFunctionName(unsigned int) const;
|
||||
void Invoke(CMIPS&, unsigned int);
|
||||
virtual void Invoke(uint32, uint32*, uint32, uint32*, uint32, uint8*);
|
||||
virtual void SaveState(CZipArchiveWriter&);
|
||||
|
@ -20,6 +20,11 @@ string CUnknown::GetId() const
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
string CUnknown::GetFunctionName(unsigned int) const
|
||||
{
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
void CUnknown::Invoke(CMIPS&, unsigned int)
|
||||
{
|
||||
throw runtime_error("Not implemented.");
|
||||
|
@ -15,6 +15,7 @@ namespace Iop
|
||||
virtual ~CUnknown();
|
||||
|
||||
std::string GetId() const;
|
||||
std::string GetFunctionName(unsigned int) const;
|
||||
void Invoke(CMIPS&, unsigned int);
|
||||
virtual void Invoke(uint32, uint32*, uint32, uint32*, uint32, uint8*);
|
||||
virtual void SaveState(CZipArchiveWriter&);
|
||||
|
@ -21,6 +21,11 @@ string CUnknown2::GetId() const
|
||||
return "unknown2";
|
||||
}
|
||||
|
||||
string CUnknown2::GetFunctionName(unsigned int) const
|
||||
{
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
void CUnknown2::Invoke(CMIPS&, unsigned int)
|
||||
{
|
||||
throw runtime_error("Not implemented.");
|
||||
|
@ -15,6 +15,7 @@ namespace Iop
|
||||
virtual ~CUnknown2();
|
||||
|
||||
std::string GetId() const;
|
||||
std::string GetFunctionName(unsigned int) const;
|
||||
void Invoke(CMIPS&, unsigned int);
|
||||
virtual void Invoke(uint32, uint32*, uint32, uint32*, uint32, uint8*);
|
||||
virtual void SaveState(CZipArchiveWriter&);
|
||||
|
Binary file not shown.
@ -56,6 +56,7 @@ private:
|
||||
void Layout1600();
|
||||
void LoadDebugTags();
|
||||
void SaveDebugTags();
|
||||
CFunctionsView::ModuleList GetIopModuleList();
|
||||
|
||||
//View related functions
|
||||
void ActivateView(unsigned int);
|
||||
|
@ -10,16 +10,19 @@
|
||||
|
||||
#define CLSNAME _T("FunctionsView")
|
||||
|
||||
#define DEFAULT_GROUPID (1)
|
||||
#define DEFAULT_GROUPNAME _T("Global")
|
||||
|
||||
using namespace Framework;
|
||||
using namespace std;
|
||||
using namespace std::tr1;
|
||||
|
||||
CFunctionsView::CFunctionsView(HWND hParent, CMIPS* pCtx)
|
||||
CFunctionsView::CFunctionsView(HWND hParent) :
|
||||
m_pCtx(NULL),
|
||||
m_pELF(NULL)
|
||||
{
|
||||
RECT rc;
|
||||
|
||||
m_pCtx = pCtx;
|
||||
m_pELF = NULL;
|
||||
|
||||
if(!DoesWindowClassExist(CLSNAME))
|
||||
{
|
||||
WNDCLASSEX wc;
|
||||
@ -88,8 +91,7 @@ long CFunctionsView::OnNotify(WPARAM wParam, NMHDR* pH)
|
||||
{
|
||||
if(pH->hwndFrom == m_pList->m_hWnd)
|
||||
{
|
||||
NMLISTVIEW* pN;
|
||||
pN = (NMLISTVIEW*)pH;
|
||||
NMLISTVIEW* pN = reinterpret_cast<NMLISTVIEW*>(pH);
|
||||
switch(pN->hdr.code)
|
||||
{
|
||||
case NM_DBLCLK:
|
||||
@ -178,11 +180,21 @@ void CFunctionsView::RefreshLayout()
|
||||
|
||||
void CFunctionsView::RefreshList()
|
||||
{
|
||||
unsigned int nCount;
|
||||
uint32 nAddress;
|
||||
|
||||
m_pList->SetRedraw(false);
|
||||
m_pList->DeleteAllItems();
|
||||
|
||||
if(m_pCtx == NULL) return;
|
||||
bool groupingEnabled = m_moduleListProvider;
|
||||
|
||||
if(groupingEnabled)
|
||||
{
|
||||
InitializeModuleGrouper();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pList->EnableGroupView(false);
|
||||
}
|
||||
|
||||
for(CMIPSTags::TagIterator itTag(m_pCtx->m_Functions.GetTagsBegin());
|
||||
itTag != m_pCtx->m_Functions.GetTagsEnd(); itTag++)
|
||||
{
|
||||
@ -194,16 +206,50 @@ void CFunctionsView::RefreshList()
|
||||
it.pszText = const_cast<LPWSTR>(sTag.c_str());
|
||||
it.lParam = itTag->first;
|
||||
it.mask = LVIF_PARAM | LVIF_TEXT;
|
||||
if(groupingEnabled)
|
||||
{
|
||||
it.iGroupId = GetFunctionGroupId(itTag->first);
|
||||
it.mask |= LVIF_GROUPID;
|
||||
}
|
||||
m_pList->InsertItem(&it);
|
||||
}
|
||||
|
||||
nCount = m_pList->GetItemCount();
|
||||
unsigned int nCount = m_pList->GetItemCount();
|
||||
|
||||
for(unsigned int i = 0; i < nCount; i++)
|
||||
{
|
||||
nAddress = m_pList->GetItemData(i);
|
||||
uint32 nAddress = m_pList->GetItemData(i);
|
||||
m_pList->SetItemText(i, 1, (_T("0x") + lexical_cast_hex<tstring>(nAddress, 8)).c_str());
|
||||
}
|
||||
|
||||
m_pList->SetRedraw(true);
|
||||
}
|
||||
|
||||
void CFunctionsView::InitializeModuleGrouper()
|
||||
{
|
||||
m_pList->RemoveAllGroups();
|
||||
m_pList->EnableGroupView(true);
|
||||
m_pList->InsertGroup(DEFAULT_GROUPNAME, DEFAULT_GROUPID);
|
||||
m_modules = m_moduleListProvider();
|
||||
for(ModuleList::const_iterator moduleIterator(m_modules.begin());
|
||||
m_modules.end() != moduleIterator; moduleIterator++)
|
||||
{
|
||||
const MODULE& module(*moduleIterator);
|
||||
m_pList->InsertGroup(
|
||||
string_cast<tstring>(module.name.c_str()).c_str(),
|
||||
module.begin);
|
||||
}
|
||||
}
|
||||
|
||||
uint32 CFunctionsView::GetFunctionGroupId(uint32 address)
|
||||
{
|
||||
for(ModuleList::const_iterator moduleIterator(m_modules.begin());
|
||||
m_modules.end() != moduleIterator; moduleIterator++)
|
||||
{
|
||||
const MODULE& module(*moduleIterator);
|
||||
if(address >= module.begin && address < module.end) return module.begin;
|
||||
}
|
||||
return DEFAULT_GROUPID;
|
||||
}
|
||||
|
||||
void CFunctionsView::SetELF(CELF* pELF)
|
||||
@ -219,6 +265,21 @@ void CFunctionsView::SetELF(CELF* pELF)
|
||||
}
|
||||
}
|
||||
|
||||
void CFunctionsView::SetContext(CMIPS* context, const ModuleListProvider& moduleListProvider)
|
||||
{
|
||||
if(m_functionTagsChangeConnection.connected())
|
||||
{
|
||||
m_functionTagsChangeConnection.disconnect();
|
||||
}
|
||||
|
||||
m_pCtx = context;
|
||||
m_moduleListProvider = moduleListProvider;
|
||||
|
||||
m_functionTagsChangeConnection = m_pCtx->m_Functions.m_OnTagListChanged.connect(
|
||||
bind(&CFunctionsView::RefreshList, this));
|
||||
RefreshList();
|
||||
}
|
||||
|
||||
void CFunctionsView::OnListDblClick()
|
||||
{
|
||||
int nItem;
|
||||
@ -231,42 +292,32 @@ void CFunctionsView::OnListDblClick()
|
||||
|
||||
void CFunctionsView::OnNewClick()
|
||||
{
|
||||
Win32::CInputBox* pInput;
|
||||
bool bQuit;
|
||||
if(m_pCtx == NULL) return;
|
||||
|
||||
TCHAR sNameX[256];
|
||||
const TCHAR* sValue;
|
||||
uint32 nAddress;
|
||||
|
||||
pInput = new Win32::CInputBox(_T("New Function"), _T("New Function Name:"), _T(""));
|
||||
sValue = pInput->GetValue(m_hWnd);
|
||||
{
|
||||
Win32::CInputBox inputBox(_T("New Function"), _T("New Function Name:"), _T(""));
|
||||
const TCHAR* sValue = inputBox.GetValue(m_hWnd);
|
||||
if(sValue == NULL) return;
|
||||
_tcsncpy(sNameX, sValue, 255);
|
||||
}
|
||||
|
||||
bQuit = (sValue == NULL);
|
||||
if(sValue != NULL)
|
||||
{
|
||||
_tcsncpy(sNameX, sValue, 255);
|
||||
}
|
||||
|
||||
delete pInput;
|
||||
|
||||
if(bQuit) return;
|
||||
|
||||
pInput = new Win32::CInputBox(_T("New Function"), _T("New Function Address:"), _T("00000000"));
|
||||
sValue = pInput->GetValue(m_hWnd);
|
||||
|
||||
bQuit = (sValue == NULL);
|
||||
if(sValue != NULL)
|
||||
{
|
||||
_stscanf(sValue, _T("%x"), &nAddress);
|
||||
if((nAddress & 0x3) != 0x0)
|
||||
{
|
||||
MessageBox(m_hWnd, _T("Invalid address."), NULL, 16);
|
||||
bQuit = true;
|
||||
}
|
||||
}
|
||||
|
||||
delete pInput;
|
||||
|
||||
if(bQuit) return;
|
||||
{
|
||||
Win32::CInputBox inputBox(_T("New Function"), _T("New Function Address:"), _T("00000000"));
|
||||
const TCHAR* sValue = inputBox.GetValue(m_hWnd);
|
||||
if(sValue == NULL) return;
|
||||
if(sValue != NULL)
|
||||
{
|
||||
_stscanf(sValue, _T("%x"), &nAddress);
|
||||
if((nAddress & 0x3) != 0x0)
|
||||
{
|
||||
MessageBox(m_hWnd, _T("Invalid address."), NULL, 16);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_pCtx->m_Functions.InsertTag(nAddress, string_cast<string>(sNameX).c_str());
|
||||
|
||||
@ -276,16 +327,13 @@ void CFunctionsView::OnNewClick()
|
||||
|
||||
void CFunctionsView::OnRenameClick()
|
||||
{
|
||||
int nItem;
|
||||
uint32 nAddress;
|
||||
const char* sName;
|
||||
const TCHAR* sNewNameX;
|
||||
if(m_pCtx == NULL) return;
|
||||
|
||||
nItem = m_pList->GetSelection();
|
||||
int nItem = m_pList->GetSelection();
|
||||
if(nItem == -1) return;
|
||||
|
||||
nAddress = m_pList->GetItemData(nItem);
|
||||
sName = m_pCtx->m_Functions.Find(nAddress);
|
||||
uint32 nAddress = m_pList->GetItemData(nItem);
|
||||
const char* sName = m_pCtx->m_Functions.Find(nAddress);
|
||||
|
||||
if(sName == NULL)
|
||||
{
|
||||
@ -294,7 +342,7 @@ void CFunctionsView::OnRenameClick()
|
||||
}
|
||||
|
||||
Win32::CInputBox RenameInput(_T("Rename Function"), _T("New Function Name:"), string_cast<tstring>(sName).c_str());
|
||||
sNewNameX = RenameInput.GetValue(m_hWnd);
|
||||
const TCHAR* sNewNameX = RenameInput.GetValue(m_hWnd);
|
||||
|
||||
if(sNewNameX == NULL) return;
|
||||
|
||||
@ -306,23 +354,19 @@ void CFunctionsView::OnRenameClick()
|
||||
|
||||
void CFunctionsView::OnImportClick()
|
||||
{
|
||||
unsigned int i, nCount;
|
||||
ELFSYMBOL* pSym;
|
||||
ELFSECTIONHEADER* pSymTab;
|
||||
const char* pStrTab;
|
||||
|
||||
if(m_pCtx == NULL) return;
|
||||
if(m_pELF == NULL) return;
|
||||
|
||||
pSymTab = m_pELF->FindSection(".symtab");
|
||||
ELFSECTIONHEADER* pSymTab = m_pELF->FindSection(".symtab");
|
||||
if(pSymTab == NULL) return;
|
||||
|
||||
pStrTab = (const char*)m_pELF->GetSectionData(pSymTab->nIndex);
|
||||
const char* pStrTab = (const char*)m_pELF->GetSectionData(pSymTab->nIndex);
|
||||
if(pStrTab == NULL) return;
|
||||
|
||||
pSym = (ELFSYMBOL*)m_pELF->FindSectionData(".symtab");
|
||||
nCount = pSymTab->nSize / sizeof(ELFSYMBOL);
|
||||
ELFSYMBOL* pSym = (ELFSYMBOL*)m_pELF->FindSectionData(".symtab");
|
||||
unsigned int nCount = pSymTab->nSize / sizeof(ELFSYMBOL);
|
||||
|
||||
for(i = 0; i < nCount; i++)
|
||||
for(unsigned int i = 0; i < nCount; i++)
|
||||
{
|
||||
if((pSym[i].nInfo & 0x0F) != 0x02) continue;
|
||||
m_pCtx->m_Functions.InsertTag(pSym[i].nValue, (char*)pStrTab + pSym[i].nName);
|
||||
@ -337,17 +381,16 @@ void CFunctionsView::OnImportClick()
|
||||
|
||||
void CFunctionsView::OnDeleteClick()
|
||||
{
|
||||
int nItem;
|
||||
uint32 nAddress;
|
||||
if(m_pCtx == NULL) return;
|
||||
|
||||
nItem = m_pList->GetSelection();
|
||||
int nItem = m_pList->GetSelection();
|
||||
if(nItem == -1) return;
|
||||
if(MessageBox(m_hWnd, _T("Delete this function?"), NULL, MB_ICONQUESTION | MB_YESNO) != IDYES)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
nAddress = m_pList->GetItemData(nItem);
|
||||
uint32 nAddress = m_pList->GetItemData(nItem);
|
||||
m_pCtx->m_Functions.InsertTag(nAddress, NULL);
|
||||
RefreshList();
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define _FUNCTIONSVIEW_H_
|
||||
|
||||
#include <boost/signal.hpp>
|
||||
#include <functional>
|
||||
#include "win32/MDIChild.h"
|
||||
#include "win32/ListView.h"
|
||||
#include "win32/Button.h"
|
||||
@ -9,12 +10,26 @@
|
||||
#include "../MIPS.h"
|
||||
#include "../ELF.h"
|
||||
|
||||
class CFunctionsView : public Framework::Win32::CMDIChild
|
||||
class CFunctionsView : public Framework::Win32::CMDIChild, boost::signals::trackable
|
||||
{
|
||||
public:
|
||||
CFunctionsView(HWND, CMIPS*);
|
||||
~CFunctionsView();
|
||||
struct MODULE
|
||||
{
|
||||
std::string name;
|
||||
uint32 begin;
|
||||
uint32 end;
|
||||
};
|
||||
|
||||
typedef std::list<MODULE> ModuleList;
|
||||
typedef std::tr1::function<ModuleList ()> ModuleListProvider;
|
||||
|
||||
|
||||
CFunctionsView(HWND);
|
||||
virtual ~CFunctionsView();
|
||||
|
||||
void SetContext(CMIPS*, const ModuleListProvider&);
|
||||
void SetELF(CELF*);
|
||||
|
||||
void Refresh();
|
||||
|
||||
boost::signal<void (uint32)> m_OnFunctionDblClick;
|
||||
@ -31,6 +46,8 @@ private:
|
||||
void ResizeListColumns();
|
||||
void RefreshLayout();
|
||||
void RefreshList();
|
||||
void InitializeModuleGrouper();
|
||||
uint32 GetFunctionGroupId(uint32);
|
||||
|
||||
void OnListDblClick();
|
||||
void OnNewClick();
|
||||
@ -45,8 +62,13 @@ private:
|
||||
Framework::Win32::CButton* m_pImport;
|
||||
|
||||
Framework::FlatLayoutPtr m_pLayout;
|
||||
CMIPS* m_pCtx;
|
||||
|
||||
boost::signals::connection m_functionTagsChangeConnection;
|
||||
|
||||
CMIPS* m_pCtx;
|
||||
CELF* m_pELF;
|
||||
ModuleList m_modules;
|
||||
ModuleListProvider m_moduleListProvider;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -136,18 +136,240 @@
|
||||
<vu1_functions />
|
||||
<vu1_comments />
|
||||
<iop>
|
||||
<functions />
|
||||
<functions>
|
||||
<tag address="00004274" value="sysmem_unknown" />
|
||||
<tag address="00004298" value="loadcore_unknown" />
|
||||
<tag address="000042BC" value="intrman_unknown" />
|
||||
<tag address="000042C4" value="intrman_unknown" />
|
||||
<tag address="000042CC" value="intrman_unknown" />
|
||||
<tag address="000042D4" value="intrman_unknown" />
|
||||
<tag address="000042DC" value="intrman_unknown" />
|
||||
<tag address="000042E4" value="intrman_unknown" />
|
||||
<tag address="00004308" value="dmacman_unknown" />
|
||||
<tag address="00004310" value="dmacman_unknown" />
|
||||
<tag address="00004318" value="dmacman_unknown" />
|
||||
<tag address="00004320" value="dmacman_unknown" />
|
||||
<tag address="00004328" value="dmacman_unknown" />
|
||||
<tag address="0000434C" value="thbase_GetThreadId" />
|
||||
<tag address="00004370" value="thsemap_unknown" />
|
||||
<tag address="00004378" value="thsemap_unknown" />
|
||||
<tag address="00004380" value="thsemap_unknown" />
|
||||
<tag address="00004388" value="thsemap_unknown" />
|
||||
<tag address="00004390" value="thsemap_unknown" />
|
||||
<tag address="000043B4" value="sysclib_unknown" />
|
||||
<tag address="000043BC" value="sysclib_unknown" />
|
||||
<tag address="000043C4" value="sysclib_unknown" />
|
||||
<tag address="00018A94" value="intrman_unknown" />
|
||||
<tag address="00018A9C" value="intrman_unknown" />
|
||||
<tag address="00018AA4" value="intrman_unknown" />
|
||||
<tag address="00018AAC" value="intrman_unknown" />
|
||||
<tag address="00018AB4" value="intrman_unknown" />
|
||||
<tag address="00018ABC" value="intrman_unknown" />
|
||||
<tag address="00018AC4" value="intrman_unknown" />
|
||||
<tag address="00018AE8" value="loadcore_unknown" />
|
||||
<tag address="00018AF0" value="loadcore_unknown" />
|
||||
<tag address="00018B14" value="sifman_unknown" />
|
||||
<tag address="00018B1C" value="sifman_unknown" />
|
||||
<tag address="00018B40" value="sysclib_unknown" />
|
||||
<tag address="00018B64" value="thevent_unknown" />
|
||||
<tag address="00018B6C" value="thevent_unknown" />
|
||||
<tag address="00018B74" value="thevent_unknown" />
|
||||
<tag address="00018B7C" value="thevent_unknown" />
|
||||
<tag address="00018B84" value="thevent_unknown" />
|
||||
<tag address="00018B8C" value="thevent_unknown" />
|
||||
<tag address="00018B94" value="thevent_unknown" />
|
||||
<tag address="000269B4" value="sysmem_unknown" />
|
||||
<tag address="000269D8" value="loadcore_unknown" />
|
||||
<tag address="000269FC" value="stdio_unknown" />
|
||||
<tag address="00026A20" value="sysclib_unknown" />
|
||||
<tag address="00026A44" value="thbase_CreateThread" />
|
||||
<tag address="00026A4C" value="thbase_StartThread" />
|
||||
<tag address="00026A70" value="thsemap_unknown" />
|
||||
<tag address="00026A78" value="thsemap_unknown" />
|
||||
<tag address="00026A80" value="thsemap_unknown" />
|
||||
<tag address="00026AA4" value="vblank_unknown" />
|
||||
<tag address="00026AC8" value="sio2man_unknown" />
|
||||
<tag address="00026AD0" value="sio2man_unknown" />
|
||||
<tag address="00026AD8" value="sio2man_unknown" />
|
||||
<tag address="00026AE0" value="sio2man_unknown" />
|
||||
<tag address="00026B04" value="secrman_unknown" />
|
||||
<tag address="00036124" value="sysmem_unknown" />
|
||||
<tag address="00036148" value="intrman_unknown" />
|
||||
<tag address="00036150" value="intrman_unknown" />
|
||||
<tag address="00036174" value="loadcore_unknown" />
|
||||
<tag address="00036198" value="sifcmd_unknown" />
|
||||
<tag address="000361A0" value="sifcmd_unknown" />
|
||||
<tag address="000361A8" value="sifcmd_unknown" />
|
||||
<tag address="000361B0" value="sifcmd_unknown" />
|
||||
<tag address="000361D4" value="sifman_unknown" />
|
||||
<tag address="000361DC" value="sifman_unknown" />
|
||||
<tag address="000361E4" value="sifman_unknown" />
|
||||
<tag address="000361EC" value="sifman_unknown" />
|
||||
<tag address="000361F4" value="sifman_unknown" />
|
||||
<tag address="00036218" value="stdio_unknown" />
|
||||
<tag address="0003623C" value="thbase_CreateThread" />
|
||||
<tag address="00036244" value="thbase_StartThread" />
|
||||
<tag address="0003624C" value="thbase_GetThreadId" />
|
||||
<tag address="00036254" value="thbase_DelayThread" />
|
||||
<tag address="00036278" value="thsemap_unknown" />
|
||||
<tag address="00036280" value="thsemap_unknown" />
|
||||
<tag address="00036288" value="thsemap_unknown" />
|
||||
<tag address="00036290" value="thsemap_unknown" />
|
||||
<tag address="000440B4" value="sysmem_unknown" />
|
||||
<tag address="000440D8" value="intrman_unknown" />
|
||||
<tag address="000440E0" value="intrman_unknown" />
|
||||
<tag address="00044104" value="sysclib_unknown" />
|
||||
<tag address="00044128" value="thbase_CreateThread" />
|
||||
<tag address="00044130" value="thbase_unknown" />
|
||||
<tag address="00044138" value="thbase_StartThread" />
|
||||
<tag address="00044140" value="thbase_unknown" />
|
||||
<tag address="00044148" value="thbase_unknown" />
|
||||
<tag address="0004416C" value="thevent_unknown" />
|
||||
<tag address="00044174" value="thevent_unknown" />
|
||||
<tag address="0004417C" value="thevent_unknown" />
|
||||
<tag address="00044184" value="thevent_unknown" />
|
||||
<tag address="0004418C" value="thevent_unknown" />
|
||||
<tag address="00044194" value="thevent_unknown" />
|
||||
<tag address="000441B8" value="vblank_unknown" />
|
||||
<tag address="000441DC" value="sio2man_unknown" />
|
||||
<tag address="000441E4" value="sio2man_unknown" />
|
||||
<tag address="000441EC" value="sio2man_unknown" />
|
||||
<tag address="00044210" value="sio2d_unknown" />
|
||||
<tag address="00044218" value="sio2d_unknown" />
|
||||
<tag address="00044220" value="sio2d_unknown" />
|
||||
<tag address="00044244" value="dbcman_unknown" />
|
||||
<tag address="0004424C" value="dbcman_unknown" />
|
||||
<tag address="00044254" value="dbcman_unknown" />
|
||||
<tag address="0004425C" value="dbcman_unknown" />
|
||||
<tag address="000580D4" value="sysmem_unknown" />
|
||||
<tag address="000580F8" value="intrman_unknown" />
|
||||
<tag address="00058100" value="intrman_unknown" />
|
||||
<tag address="00058124" value="sifcmd_unknown" />
|
||||
<tag address="00058148" value="sifman_unknown" />
|
||||
<tag address="0005816C" value="sysclib_unknown" />
|
||||
<tag address="00058174" value="sysclib_unknown" />
|
||||
<tag address="0005817C" value="sysclib_unknown" />
|
||||
<tag address="000581A0" value="thbase_CreateThread" />
|
||||
<tag address="000581A8" value="thbase_unknown" />
|
||||
<tag address="000581B0" value="thbase_StartThread" />
|
||||
<tag address="000581B8" value="thbase_unknown" />
|
||||
<tag address="000581C0" value="thbase_unknown" />
|
||||
<tag address="000581C8" value="thbase_DelayThread" />
|
||||
<tag address="000581EC" value="thsemap_unknown" />
|
||||
<tag address="000581F4" value="thsemap_unknown" />
|
||||
<tag address="000581FC" value="thsemap_unknown" />
|
||||
<tag address="00058204" value="thsemap_unknown" />
|
||||
<tag address="00058228" value="vblank_unknown" />
|
||||
<tag address="0005824C" value="sio2man_unknown" />
|
||||
<tag address="00058254" value="sio2man_unknown" />
|
||||
<tag address="0005825C" value="sio2man_unknown" />
|
||||
<tag address="00058264" value="sio2man_unknown" />
|
||||
<tag address="00058288" value="secrman_unknown" />
|
||||
<tag address="00058290" value="secrman_unknown" />
|
||||
<tag address="000582B4" value="cdvdman_unknown" />
|
||||
<tag address="000582D8" value="dbcman_unknown" />
|
||||
<tag address="000582E0" value="dbcman_unknown" />
|
||||
<tag address="000582E8" value="dbcman_unknown" />
|
||||
<tag address="000582F0" value="dbcman_unknown" />
|
||||
<tag address="000582F8" value="dbcman_unknown" />
|
||||
<tag address="00058300" value="dbcman_unknown" />
|
||||
<tag address="00058324" value="sio2d_unknown" />
|
||||
<tag address="0005832C" value="sio2d_unknown" />
|
||||
<tag address="00058334" value="sio2d_unknown" />
|
||||
<tag address="0005833C" value="sio2d_unknown" />
|
||||
<tag address="00058344" value="sio2d_unknown" />
|
||||
<tag address="00058368" value="dmacman_unknown" />
|
||||
<tag address="00058370" value="dmacman_unknown" />
|
||||
<tag address="00074EF4" value="sysmem_unknown" />
|
||||
<tag address="00074EFC" value="sysmem_unknown" />
|
||||
<tag address="00074F04" value="sysmem_unknown" />
|
||||
<tag address="00074F0C" value="sysmem_unknown" />
|
||||
<tag address="00074F30" value="intrman_unknown" />
|
||||
<tag address="00074F54" value="loadcore_unknown" />
|
||||
<tag address="00074F78" value="sifcmd_unknown" />
|
||||
<tag address="00074F80" value="sifcmd_unknown" />
|
||||
<tag address="00074F88" value="sifcmd_unknown" />
|
||||
<tag address="00074F90" value="sifcmd_unknown" />
|
||||
<tag address="00074FB4" value="sysclib_unknown" />
|
||||
<tag address="00074FD8" value="thbase_CreateThread" />
|
||||
<tag address="00074FE0" value="thbase_unknown" />
|
||||
<tag address="00074FE8" value="thbase_StartThread" />
|
||||
<tag address="00074FF0" value="thbase_GetThreadId" />
|
||||
<tag address="00075014" value="thsemap_unknown" />
|
||||
<tag address="0007501C" value="thsemap_unknown" />
|
||||
<tag address="00075024" value="thsemap_unknown" />
|
||||
<tag address="0007502C" value="thsemap_unknown" />
|
||||
<tag address="00075050" value="vblank_unknown" />
|
||||
<tag address="00075074" value="libsd_unknown" />
|
||||
<tag address="0007507C" value="libsd_unknown" />
|
||||
<tag address="00075084" value="libsd_unknown" />
|
||||
<tag address="0007508C" value="libsd_unknown" />
|
||||
<tag address="00075094" value="libsd_unknown" />
|
||||
<tag address="0007509C" value="libsd_unknown" />
|
||||
<tag address="000750A4" value="libsd_unknown" />
|
||||
<tag address="000750AC" value="libsd_unknown" />
|
||||
<tag address="000750B4" value="libsd_unknown" />
|
||||
<tag address="000750BC" value="libsd_unknown" />
|
||||
<tag address="000750C4" value="libsd_unknown" />
|
||||
<tag address="000A0684" value="ioman_unknown" />
|
||||
<tag address="000A068C" value="ioman_unknown" />
|
||||
<tag address="000A0694" value="ioman_unknown" />
|
||||
<tag address="000A069C" value="ioman_unknown" />
|
||||
<tag address="000A06C0" value="loadcore_unknown" />
|
||||
<tag address="000A06E4" value="sifcmd_unknown" />
|
||||
<tag address="000A06EC" value="sifcmd_unknown" />
|
||||
<tag address="000A06F4" value="sifcmd_unknown" />
|
||||
<tag address="000A06FC" value="sifcmd_unknown" />
|
||||
<tag address="000A0720" value="sifman_unknown" />
|
||||
<tag address="000A0728" value="sifman_unknown" />
|
||||
<tag address="000A074C" value="thbase_CreateThread" />
|
||||
<tag address="000A0754" value="thbase_StartThread" />
|
||||
<tag address="000A075C" value="thbase_GetThreadId" />
|
||||
<tag address="000B1124" value="intrman_unknown" />
|
||||
<tag address="000B1148" value="loadcore_unknown" />
|
||||
<tag address="000B116C" value="sifcmd_unknown" />
|
||||
<tag address="000B1174" value="sifcmd_unknown" />
|
||||
<tag address="000B117C" value="sifcmd_unknown" />
|
||||
<tag address="000B1184" value="sifcmd_unknown" />
|
||||
<tag address="000B11A8" value="sifman_unknown" />
|
||||
<tag address="000B11B0" value="sifman_unknown" />
|
||||
<tag address="000B11D4" value="thbase_CreateThread" />
|
||||
<tag address="000B11DC" value="thbase_StartThread" />
|
||||
<tag address="000B11E4" value="thbase_GetThreadId" />
|
||||
<tag address="000B11EC" value="thbase_SleepThread" />
|
||||
<tag address="000B11F4" value="thbase_iWakeupThread" />
|
||||
<tag address="000B11FC" value="thbase_USecToSysClock" />
|
||||
<tag address="000B1220" value="timrman_AllocHardTimer" />
|
||||
<tag address="000B1228" value="timrman_unknown" />
|
||||
<tag address="000B1230" value="timrman_SetTimerCallback" />
|
||||
<tag address="000B1238" value="timrman_unknown" />
|
||||
<tag address="000B1240" value="timrman_unknown" />
|
||||
<tag address="000B1248" value="timrman_unknown" />
|
||||
<tag address="000B126C" value="libsd_unknown" />
|
||||
<tag address="000B1274" value="libsd_unknown" />
|
||||
<tag address="000B127C" value="libsd_unknown" />
|
||||
<tag address="000B1284" value="libsd_unknown" />
|
||||
<tag address="000B128C" value="libsd_unknown" />
|
||||
<tag address="000B1294" value="libsd_unknown" />
|
||||
<tag address="000B129C" value="libsd_unknown" />
|
||||
<tag address="000B12A4" value="libsd_unknown" />
|
||||
<tag address="000B12AC" value="libsd_unknown" />
|
||||
<tag address="000B12B4" value="libsd_unknown" />
|
||||
<tag address="000B12BC" value="libsd_unknown" />
|
||||
<tag address="000B12C4" value="libsd_unknown" />
|
||||
<tag address="000B12CC" value="libsd_unknown" />
|
||||
</functions>
|
||||
<comments />
|
||||
<modules>
|
||||
<module beginAddress="00003800" endAddress="00004470" name="" />
|
||||
<module beginAddress="00014000" endAddress="00019CE0" name="" />
|
||||
<module beginAddress="00025000" endAddress="00027D60" name="" />
|
||||
<module beginAddress="00034000" endAddress="00037550" name="" />
|
||||
<module beginAddress="00042400" endAddress="00044770" name="" />
|
||||
<module beginAddress="00053800" endAddress="0005C900" name="" />
|
||||
<module beginAddress="00070000" endAddress="00096FB0" name="" />
|
||||
<module beginAddress="000A0400" endAddress="000A0930" name="" />
|
||||
<module beginAddress="000AEC00" endAddress="000B1660" name="" />
|
||||
<module beginAddress="00003800" endAddress="00004470" name="sio2man" />
|
||||
<module beginAddress="00014000" endAddress="00019CE0" name="libsd" />
|
||||
<module beginAddress="00025000" endAddress="00027D60" name="sio2d" />
|
||||
<module beginAddress="00034000" endAddress="00037550" name="dbcman" />
|
||||
<module beginAddress="00042400" endAddress="00044770" name="padman" />
|
||||
<module beginAddress="00053800" endAddress="0005C900" name="mc2man" />
|
||||
<module beginAddress="00070000" endAddress="00096FB0" name="sndrv" />
|
||||
<module beginAddress="000A0400" endAddress="000A0930" name="idvd_srv" />
|
||||
<module beginAddress="000AEC00" endAddress="000B1660" name="isnd_srv" />
|
||||
</modules>
|
||||
</iop>
|
||||
</tags>
|
||||
|
Loading…
Reference in New Issue
Block a user