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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -97,37 +97,86 @@ 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;
|
||||
|
||||
for(unsigned long long index = 0; index < file->Length(); index++)
|
||||
if(useTraceDump)
|
||||
{
|
||||
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)
|
||||
if(file->Length() > 0)
|
||||
{
|
||||
file->MemoryAccessInfo(index, memAddr, memOldContent, memNewContent, isValid);
|
||||
for(int i = 0; i < memAccessCount; i++)
|
||||
file->buildDumpTo(file->Length() - 1);
|
||||
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
|
||||
if(found)
|
||||
}
|
||||
else
|
||||
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);
|
||||
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++;
|
||||
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++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue