1
0
Fork 0

DBG: Start resolving function ends

This commit is contained in:
Nukem 2015-07-09 02:57:49 -04:00
parent d379a5a133
commit b4b4fa0485
5 changed files with 98 additions and 44 deletions

View File

@ -33,6 +33,43 @@ AnalysisPass::~AnalysisPass()
BridgeFree(m_Data);
}
BasicBlock* AnalysisPass::FindBBlockInRange(uint Address)
{
// NOTE: __MUST__ BE A SORTED VECTOR
//
// Use a binary search
uint indexLo = 0;
uint indexHi = m_MainBlocks.size();
// Get a pointer to pure data
const auto blocks = m_MainBlocks.data();
while(indexHi > indexLo)
{
uint indexMid = (indexLo + indexHi) / 2;
auto entry = &blocks[indexMid];
if(Address < entry->VirtualStart)
{
// Continue search in lower half
indexHi = indexMid;
}
else if(Address >= entry->VirtualEnd)
{
// Continue search in upper half
indexLo = indexMid + 1;
}
else
{
// Address is within limits, return entry
return entry;
}
}
// Not found
return nullptr;
}
void AnalysisPass::AcquireReadLock()
{
AcquireSRWLockShared(&m_InternalLock);
@ -64,7 +101,7 @@ uint AnalysisPass::IdealThreadCount()
if(maximumThreads > 1)
maximumThreads -= 1;
m_InternalMaxThreads = (BYTE)min(maximumThreads, 255);
SetIdealThreadCount(maximumThreads);
}
return m_InternalMaxThreads;

View File

@ -32,6 +32,7 @@ protected:
return (Address >= m_VirtualStart && Address < m_VirtualEnd);
}
BasicBlock* FindBBlockInRange(uint Address);
void AcquireReadLock();
void ReleaseReadLock();
void AcquireExclusiveLock();

View File

@ -5,6 +5,7 @@
#include "console.h"
#include "debugger.h"
#include "module.h"
#include "function.h"
FunctionPass::FunctionPass(uint VirtualStart, uint VirtualEnd, BBlockArray & MainBlocks)
: AnalysisPass(VirtualStart, VirtualEnd, MainBlocks)
@ -88,6 +89,23 @@ bool FunctionPass::Analyse()
AnalysisWorker(threadWorkStart, threadWorkStop, &threadFunctions[i]);
});
std::vector<FunctionDef> funcs;
// Merge thread vectors into single local
for(uint i = 0; i < IdealThreadCount(); i++)
std::move(threadFunctions[i].begin(), threadFunctions[i].end(), std::back_inserter(funcs));
// Sort and remove duplicates
std::sort(funcs.begin(), funcs.end());
funcs.erase(std::unique(funcs.begin(), funcs.end()), funcs.end());
FunctionClear();
for(auto & func : funcs)
{
FunctionAdd(func.VirtualStart, func.VirtualEnd - 1, true);
}
GuiUpdateAllViews();
delete[] threadFunctions;
return true;
}
@ -177,6 +195,44 @@ void FunctionPass::FindFunctionWorkerPrepass(uint Start, uint End, std::vector<F
void FunctionPass::FindFunctionWorker(std::vector<FunctionDef>* Blocks)
{
// Helper to link final blocks to function
auto ResolveKnownFunctionEnd = [this](FunctionDef * Function)
{
auto startBlock = FindBBlockInRange(Function->VirtualStart);
auto endBlock = FindBBlockInRange(Function->VirtualEnd);
if(!startBlock || !endBlock)
return false;
// Debug
//assert(startBlock->VirtualStart == Function->VirtualStart);
//assert(endBlock->VirtualEnd == Function->VirtualEnd);
// Calculate indexes from pointer arithmetic
Function->BBlockStart = ((uint)startBlock - (uint)m_MainBlocks.data()) / sizeof(BasicBlock);
Function->BBlockEnd = ((uint)endBlock - (uint)m_MainBlocks.data()) / sizeof(BasicBlock);
// Set the flag for blocks that have been scanned
for(uint i = Function->BBlockStart; i < Function->BBlockEnd; i++)
m_MainBlocks[i].SetFlag(BASIC_BLOCK_FLAG_FUNCTION);
return true;
};
// Enumerate all function entries for this thread
for(auto & block : *Blocks)
{
// Sometimes the ending address is already supplied, so
// check first
if(block.VirtualEnd != 0)
{
if(ResolveKnownFunctionEnd(&block))
continue;
}
// else
// ...
}
}
void FunctionPass::EnumerateFunctionRuntimeEntries64(std::function<bool (PRUNTIME_FUNCTION)> Callback)
@ -184,12 +240,11 @@ void FunctionPass::EnumerateFunctionRuntimeEntries64(std::function<bool (PRUNTIM
if(!m_FunctionInfo)
return;
// Get the table pointer
PRUNTIME_FUNCTION functionTable = (PRUNTIME_FUNCTION)m_FunctionInfo;
// Enumerate each entry
// Get the table pointer and size
auto functionTable = (PRUNTIME_FUNCTION)m_FunctionInfo;
ULONG totalCount = (m_FunctionInfoSize / sizeof(RUNTIME_FUNCTION));
// Enumerate each entry
for(ULONG i = 0; i < totalCount; i++)
{
if(!Callback(&functionTable[i]))

View File

@ -321,42 +321,4 @@ BasicBlock* LinearPass::CreateBlockWorker(std::vector<BasicBlock>* Blocks, uint
Blocks->push_back(block);
return &Blocks->back();
}
BasicBlock* LinearPass::FindBBlockInRange(uint Address)
{
// NOTE: This function assumes that the main block
// vector is sorted
//
// Use a binary search
uint indexLo = 0;
uint indexHi = m_MainBlocks.size();
// Get a pointer to pure data
const auto blocks = m_MainBlocks.data();
while(indexHi > indexLo)
{
uint indexMid = (indexLo + indexHi) / 2;
auto entry = &blocks[indexMid];
if(Address < entry->VirtualStart)
{
// Continue search in lower half
indexHi = indexMid;
}
else if(Address >= entry->VirtualEnd)
{
// Continue search in upper half
indexLo = indexMid + 1;
}
else
{
// Address is within limits, return entry
return entry;
}
}
// Not found
return nullptr;
}

View File

@ -18,5 +18,4 @@ private:
void AnalysisWorker(uint Start, uint End, BBlockArray* Blocks);
void AnalysisOverlapWorker(uint Start, uint End, BBlockArray* Insertions);
BasicBlock* CreateBlockWorker(BBlockArray* Blocks, uint Start, uint End, bool Call, bool Jmp, bool Ret, bool Intr);
BasicBlock* FindBBlockInRange(uint Address);
};