DBG: Start resolving function ends
This commit is contained in:
parent
d379a5a133
commit
b4b4fa0485
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ protected:
|
|||
return (Address >= m_VirtualStart && Address < m_VirtualEnd);
|
||||
}
|
||||
|
||||
BasicBlock* FindBBlockInRange(uint Address);
|
||||
void AcquireReadLock();
|
||||
void ReleaseReadLock();
|
||||
void AcquireExclusiveLock();
|
||||
|
|
|
|||
|
|
@ -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]))
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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);
|
||||
};
|
||||
Loading…
Reference in New Issue