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; 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) //void TraceFileDump::addMemAccess(duint addr, DumpRecord record)
//{ //{
// Key location = {addr, maxIndex}; // Key location = {addr, maxIndex};
@ -99,9 +126,9 @@ void TraceFileDump::findMemAreas()
// find first access to addr // find first access to addr
do 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 // 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) if(it->first.addr != addr - 1)
break; break;

View File

@ -30,6 +30,7 @@ public:
// Read a byte at "addr" at the moment given in "index" // Read a byte at "addr" at the moment given in "index"
unsigned char getByte(Key location, bool & success) const; 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 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 // Insert a memory access record
//void addMemAccess(duint addr, DumpRecord record); //void addMemAccess(duint addr, DumpRecord record);
void addMemAccess(duint addr, const void* oldData, const void* newData, size_t size); 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) void TraceFileReader::buildDumpTo(unsigned long long index)
{ {
auto start = dump.getMaxIndex(); auto start = dump.getMaxIndex();
for(auto i = start + 1; i <= index; i++) for(auto i = start + 1; i < index; i++)
{ {
dump.increaseIndex(); dump.increaseIndex();
buildDump(i); 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::TraceFilePage(TraceFileReader* parent, unsigned long long fileOffset, unsigned long long maxLength) TraceFilePage::TraceFilePage(TraceFileReader* parent, unsigned long long fileOffset, unsigned long long maxLength)
{ {

View File

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

View File

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