1
0
Fork 0

Use trace file dump index to accelerate memory reference search

This commit is contained in:
torusrxxx 2023-06-11 12:18:54 +08:00
parent 157a7539ba
commit fc25d8ac8d
5 changed files with 112 additions and 29 deletions

View File

@ -62,6 +62,33 @@ std::vector<unsigned char> TraceFileDump::getBytes(duint addr, duint size, unsig
return buffer;
}
// find references to the memory address
std::vector<unsigned long long> TraceFileDump::getReferences(duint startAddr, duint endAddr) const
{
std::vector<unsigned long long> index;
if(endAddr < startAddr)
std::swap(endAddr, startAddr);
// find references to the memory address
auto it = dump.lower_bound({endAddr, maxIndex + 1});
while(it != dump.end() && it->first.addr >= startAddr && it->first.addr <= endAddr)
{
index.push_back(it->first.index);
++it;
}
if(index.empty())
return index;
// rearrange the array and remove duplicates
std::sort(index.begin(), index.end());
std::vector<unsigned long long> result;
result.push_back(index[0]);
for(size_t i = 1; i < index.size(); i++)
{
if(index[i] != result[result.size() - 1])
result.push_back(index[i]);
}
return result;
}
//void TraceFileDump::addMemAccess(duint addr, DumpRecord record)
//{
// Key location = {addr, maxIndex};
@ -99,9 +126,9 @@ void TraceFileDump::findMemAreas()
// find first access to addr
do
{
auto it = dump.lower_bound({addr - 1, maxIndex});
auto it = dump.lower_bound({addr - 1, maxIndex + 1});
// try to find out if addr-1 is in the dump
for(; it != dump.end(); it = dump.lower_bound({addr - 1, maxIndex}))
for(; it != dump.end(); it = dump.lower_bound({addr - 1, maxIndex + 1}))
{
if(it->first.addr != addr - 1)
break;

View File

@ -30,6 +30,7 @@ public:
// Read a byte at "addr" at the moment given in "index"
unsigned char getByte(Key location, bool & success) const;
std::vector<unsigned char> getBytes(duint addr, duint size, unsigned long long index) const;
std::vector<unsigned long long> getReferences(duint startAddr, duint endAddr) const;
// Insert a memory access record
//void addMemAccess(duint addr, DumpRecord record);
void addMemAccess(duint addr, const void* oldData, const void* newData, size_t size);

View File

@ -621,7 +621,7 @@ void TraceFileReader::buildDump(unsigned long long index)
void TraceFileReader::buildDumpTo(unsigned long long index)
{
auto start = dump.getMaxIndex();
for(auto i = start + 1; i <= index; i++)
for(auto i = start + 1; i < index; i++)
{
dump.increaseIndex();
buildDump(i);
@ -644,6 +644,11 @@ void TraceFileReader::debugdump(unsigned long long index)
}
}
std::vector<unsigned long long> TraceFileReader::getReferences(duint startAddr, duint endAddr) const
{
return dump.getReferences(startAddr, endAddr);
}
//TraceFilePage
TraceFilePage::TraceFilePage(TraceFileReader* parent, unsigned long long fileOffset, unsigned long long maxLength)
{

View File

@ -40,8 +40,8 @@ public:
void purgeLastPage();
void buildDump(unsigned long long index);
void buildDumpTo(unsigned long long index);
std::vector<unsigned long long> getReferences(duint startAddr, duint endAddr) const;
void debugdump(unsigned long long index);
signals:
@ -79,6 +79,7 @@ private:
std::map<Range, TraceFilePage, RangeCompare> pages;
TraceFilePage* getPage(unsigned long long index, unsigned long long* base);
TraceFileDump dump;
void buildDump(unsigned long long index);
QBeaEngine* mDisasm;
};

View File

@ -97,7 +97,55 @@ int TraceFileSearchMemReference(TraceFileReader* file, duint address)
GuiReferenceAddColumn(100, QCoreApplication::translate("TraceFileSearch", "Disassembly").toUtf8().constData());
GuiReferenceAddCommand(QCoreApplication::translate("TraceFileSearch", "Follow index in trace").toUtf8().constData(), "gototrace 0x$1");
GuiReferenceSetRowCount(0);
bool useTraceDump = true;
if(useTraceDump)
{
if(file->Length() > 0)
{
file->buildDumpTo(file->Length() - 1);
auto results = file->getReferences(address, address + sizeof(duint) - 1);
for(size_t i = 0; i < results.size(); i++)
{
bool found = false;
unsigned long long index = results[i];
//Memory
duint memAddr[MAX_MEMORY_OPERANDS];
duint memOldContent[MAX_MEMORY_OPERANDS];
duint memNewContent[MAX_MEMORY_OPERANDS];
bool isValid[MAX_MEMORY_OPERANDS];
int memAccessCount = file->MemoryAccessCount(index);
if(memAccessCount > 0)
{
file->MemoryAccessInfo(index, memAddr, memOldContent, memNewContent, isValid);
for(int i = 0; i < memAccessCount; i++)
{
found |= inRange(memAddr[i], address, address + sizeof(duint) - 1);
}
//Constants: TO DO
//Populate reference view
if(found)
{
GuiReferenceSetRowCount(count + 1);
GuiReferenceSetCellContent(count, 0, ToPtrString(file->Registers(index).regcontext.cip).toUtf8().constData());
GuiReferenceSetCellContent(count, 1, file->getIndexText(index).toUtf8().constData());
unsigned char opcode[16];
int opcodeSize = 0;
file->OpCode(index, opcode, &opcodeSize);
zy.Disassemble(file->Registers(index).regcontext.cip, opcode, opcodeSize);
GuiReferenceSetCellContent(count, 2, zy.InstructionText(true).c_str());
//GuiReferenceSetCurrentTaskProgress; GuiReferenceSetProgress
count++;
}
}
}
}
else
count = 0;
return count;
}
else
{
for(unsigned long long index = 0; index < file->Length(); index++)
{
bool found = false;
@ -131,6 +179,7 @@ int TraceFileSearchMemReference(TraceFileReader* file, duint address)
}
}
}
}
return count;
}