Use trace file dump index to accelerate memory reference search
This commit is contained in:
parent
157a7539ba
commit
fc25d8ac8d
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue