Partial refactor of loop.cpp/loop.h
This commit is contained in:
parent
64c76d7826
commit
fad13af628
|
|
@ -161,7 +161,7 @@ extern "C" DLL_EXPORT bool _dbg_addrinfoget(duint addr, SEGMENTREG segment, ADDR
|
|||
}
|
||||
if(addrinfo->flags & flagloop)
|
||||
{
|
||||
if(loopget(addrinfo->loop.depth, addr, &addrinfo->loop.start, &addrinfo->loop.end))
|
||||
if(LoopGet(addrinfo->loop.depth, addr, &addrinfo->loop.start, &addrinfo->loop.end))
|
||||
retval = true;
|
||||
}
|
||||
if(addrinfo->flags & flagcomment)
|
||||
|
|
@ -851,28 +851,28 @@ extern "C" DLL_EXPORT uint _dbg_sendmessage(DBGMSG type, void* param1, void* par
|
|||
case DBG_LOOP_GET:
|
||||
{
|
||||
FUNCTION_LOOP_INFO* info = (FUNCTION_LOOP_INFO*)param1;
|
||||
return (uint)loopget(info->depth, info->addr, &info->start, &info->end);
|
||||
return (uint)LoopGet(info->depth, info->addr, &info->start, &info->end);
|
||||
}
|
||||
break;
|
||||
|
||||
case DBG_LOOP_OVERLAPS:
|
||||
{
|
||||
FUNCTION_LOOP_INFO* info = (FUNCTION_LOOP_INFO*)param1;
|
||||
return (uint)loopoverlaps(info->depth, info->start, info->end, 0);
|
||||
return (uint)LoopOverlaps(info->depth, info->start, info->end, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case DBG_LOOP_ADD:
|
||||
{
|
||||
FUNCTION_LOOP_INFO* info = (FUNCTION_LOOP_INFO*)param1;
|
||||
return (uint)loopadd(info->start, info->end, info->manual);
|
||||
return (uint)LoopAdd(info->start, info->end, info->manual);
|
||||
}
|
||||
break;
|
||||
|
||||
case DBG_LOOP_DEL:
|
||||
{
|
||||
FUNCTION_LOOP_INFO* info = (FUNCTION_LOOP_INFO*)param1;
|
||||
return (uint)loopdel(info->depth, info->addr);
|
||||
return (uint)LoopDelete(info->depth, info->addr);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ void dbsave()
|
|||
LabelCacheSave(root);
|
||||
BookmarkCacheSave(root);
|
||||
FunctionCacheSave(root);
|
||||
loopcachesave(root);
|
||||
LoopCacheSave(root);
|
||||
BpCacheSave(root);
|
||||
WString wdbpath = StringUtils::Utf8ToUtf16(dbpath);
|
||||
if(json_object_size(root))
|
||||
|
|
@ -92,7 +92,7 @@ void dbload()
|
|||
LabelCacheLoad(root);
|
||||
BookmarkCacheLoad(root);
|
||||
FunctionCacheLoad(root);
|
||||
loopcacheload(root);
|
||||
LoopCacheLoad(root);
|
||||
BpCacheLoad(root);
|
||||
json_decref(root); //free root
|
||||
dprintf("%ums\n", GetTickCount() - ticks);
|
||||
|
|
@ -105,7 +105,7 @@ void dbclose()
|
|||
LabelClear();
|
||||
BookmarkClear();
|
||||
FunctionClear();
|
||||
loopclear();
|
||||
LoopClear();
|
||||
BpClear();
|
||||
PatchClear();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1437,14 +1437,14 @@ CMDRESULT cbInstrLoopList(int argc, char* argv[])
|
|||
GuiReferenceAddColumn(0, "Label/Comment");
|
||||
GuiReferenceReloadData();
|
||||
size_t cbsize;
|
||||
loopenum(0, &cbsize);
|
||||
LoopEnum(0, &cbsize);
|
||||
if(!cbsize)
|
||||
{
|
||||
dputs("no loops");
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
Memory<LOOPSINFO*> loops(cbsize, "cbInstrLoopList:loops");
|
||||
loopenum(loops, 0);
|
||||
LoopEnum(loops, 0);
|
||||
int count = (int)(cbsize / sizeof(LOOPSINFO));
|
||||
for(int i = 0; i < count; i++)
|
||||
{
|
||||
|
|
@ -1794,4 +1794,4 @@ CMDRESULT cbInstrLog(int argc, char* argv[])
|
|||
String logString = stringformat(argv[1], formatArgs);
|
||||
dputs(logString.c_str());
|
||||
return STATUS_CONTINUE;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,104 +4,155 @@
|
|||
#include "threading.h"
|
||||
#include "module.h"
|
||||
|
||||
typedef std::map<DepthModuleRange, LOOPSINFO, DepthModuleRangeCompare> LoopsInfo;
|
||||
std::map<DepthModuleRange, LOOPSINFO, DepthModuleRangeCompare> loops;
|
||||
|
||||
static LoopsInfo loops;
|
||||
|
||||
bool loopadd(uint start, uint end, bool manual)
|
||||
bool LoopAdd(uint Start, uint End, bool Manual)
|
||||
{
|
||||
if(!DbgIsDebugging() or end < start or !MemIsValidReadPtr(start))
|
||||
// CHECK: Export function
|
||||
if(!DbgIsDebugging())
|
||||
return false;
|
||||
const uint modbase = ModBaseFromAddr(start);
|
||||
if(modbase != ModBaseFromAddr(end)) //the function boundaries are not in the same mem page
|
||||
|
||||
// Loop must begin before it ends
|
||||
if (Start > End)
|
||||
return false;
|
||||
|
||||
// Memory addresses must be valid
|
||||
if (!MemIsValidReadPtr(Start) || !MemIsValidReadPtr(End))
|
||||
return false;
|
||||
|
||||
// Check if loop boundaries are in the same module range
|
||||
const uint moduleBase = ModBaseFromAddr(Start);
|
||||
|
||||
if(moduleBase != ModBaseFromAddr(End))
|
||||
return false;
|
||||
int finaldepth;
|
||||
if(loopoverlaps(0, start, end, &finaldepth)) //loop cannot overlap another loop
|
||||
|
||||
// Loops cannot overlap other loops
|
||||
int finalDepth = 0;
|
||||
|
||||
if(LoopOverlaps(0, Start, End, &finalDepth))
|
||||
return false;
|
||||
LOOPSINFO loop;
|
||||
ModNameFromAddr(start, loop.mod, true);
|
||||
loop.start = start - modbase;
|
||||
loop.end = end - modbase;
|
||||
loop.depth = finaldepth;
|
||||
if(finaldepth)
|
||||
loopget(finaldepth - 1, start, &loop.parent, 0);
|
||||
|
||||
// Fill out loop information structure
|
||||
LOOPSINFO loopInfo;
|
||||
|
||||
loopInfo.start = Start - moduleBase;
|
||||
loopInfo.end = End - moduleBase;
|
||||
loopInfo.depth = finalDepth;
|
||||
loopInfo.manual = Manual;
|
||||
ModNameFromAddr(Start, loopInfo.mod, true);
|
||||
|
||||
// Link this to a parent loop if one does exist
|
||||
if(finalDepth)
|
||||
LoopGet(finalDepth - 1, Start, &loopInfo.parent, 0);
|
||||
else
|
||||
loop.parent = 0;
|
||||
loop.manual = manual;
|
||||
CriticalSectionLocker locker(LockLoops);
|
||||
loops.insert(std::make_pair(DepthModuleRange(finaldepth, ModuleRange(ModHashFromAddr(modbase), Range(loop.start, loop.end))), loop));
|
||||
loopInfo.parent = 0;
|
||||
|
||||
EXCLUSIVE_ACQUIRE(LockLoops);
|
||||
|
||||
// Insert into list
|
||||
loops.insert(std::make_pair(DepthModuleRange(finalDepth, ModuleRange(ModHashFromAddr(moduleBase), Range(loopInfo.start, loopInfo.end))), loopInfo));
|
||||
return true;
|
||||
}
|
||||
|
||||
//get the start/end of a loop at a certain depth and addr
|
||||
bool loopget(int depth, uint addr, uint* start, uint* end)
|
||||
// Get the start/end of a loop at a certain depth and address
|
||||
bool LoopGet(int Depth, uint Address, uint* Start, uint* End)
|
||||
{
|
||||
// CHECK: Exported function
|
||||
if(!DbgIsDebugging())
|
||||
return false;
|
||||
const uint modbase = ModBaseFromAddr(addr);
|
||||
CriticalSectionLocker locker(LockLoops);
|
||||
LoopsInfo::iterator found = loops.find(DepthModuleRange(depth, ModuleRange(ModHashFromAddr(modbase), Range(addr - modbase, addr - modbase))));
|
||||
if(found == loops.end()) //not found
|
||||
|
||||
// Get the virtual address module
|
||||
const uint moduleBase = ModBaseFromAddr(Address);
|
||||
|
||||
// Virtual address to relative address
|
||||
Address -= moduleBase;
|
||||
|
||||
SHARED_ACQUIRE(LockLoops);
|
||||
|
||||
// Search with this address range
|
||||
auto found = loops.find(DepthModuleRange(Depth, ModuleRange(ModHashFromAddr(moduleBase), Range(Address, Address))));
|
||||
|
||||
if(found == loops.end())
|
||||
return false;
|
||||
if(start)
|
||||
*start = found->second.start + modbase;
|
||||
if(end)
|
||||
*end = found->second.end + modbase;
|
||||
|
||||
// Return the loop start
|
||||
if(Start)
|
||||
*Start = found->second.start + moduleBase;
|
||||
|
||||
// Also the loop end
|
||||
if(End)
|
||||
*End = found->second.end + moduleBase;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//check if a loop overlaps a range, inside is not overlapping
|
||||
bool loopoverlaps(int depth, uint start, uint end, int* finaldepth)
|
||||
bool LoopOverlaps(int Depth, uint Start, uint End, int* FinalDepth)
|
||||
{
|
||||
// CHECK: Export function
|
||||
if(!DbgIsDebugging())
|
||||
return false;
|
||||
|
||||
const uint modbase = ModBaseFromAddr(start);
|
||||
uint curStart = start - modbase;
|
||||
uint curEnd = end - modbase;
|
||||
const uint key = ModHashFromAddr(modbase);
|
||||
// Determine module addresses and lookup keys
|
||||
const uint moduleBase = ModBaseFromAddr(Start);
|
||||
const uint key = ModHashFromAddr(moduleBase);
|
||||
|
||||
CriticalSectionLocker locker(LockLoops);
|
||||
uint curStart = Start - moduleBase;
|
||||
uint curEnd = End - moduleBase;
|
||||
|
||||
//check if the new loop fits in the old loop
|
||||
for(LoopsInfo::iterator i = loops.begin(); i != loops.end(); ++i)
|
||||
SHARED_ACQUIRE(LockLoops);
|
||||
|
||||
// Check if the new loop fits in the old loop
|
||||
for(auto& itr : loops)
|
||||
{
|
||||
if(i->first.second.first != key) //only look in the current module
|
||||
// Only look in the current module
|
||||
if(itr.first.second.first != key)
|
||||
continue;
|
||||
LOOPSINFO* curLoop = &i->second;
|
||||
if(curLoop->start < curStart and curLoop->end > curEnd and curLoop->depth == depth)
|
||||
return loopoverlaps(depth + 1, curStart, curEnd, finaldepth);
|
||||
|
||||
// Loop must be at this recursive depth
|
||||
if (itr.second.depth != Depth)
|
||||
continue;
|
||||
|
||||
if(itr.second.start < curStart && itr.second.end > curEnd)
|
||||
return LoopOverlaps(Depth + 1, curStart, curEnd, FinalDepth);
|
||||
}
|
||||
|
||||
if(finaldepth)
|
||||
*finaldepth = depth;
|
||||
// Did the user request t the loop depth?
|
||||
if(FinalDepth)
|
||||
*FinalDepth = Depth;
|
||||
|
||||
//check for loop overlaps
|
||||
for(LoopsInfo::iterator i = loops.begin(); i != loops.end(); ++i)
|
||||
// Check for loop overlaps
|
||||
for (auto& itr : loops)
|
||||
{
|
||||
if(i->first.second.first != key) //only look in the current module
|
||||
continue;
|
||||
LOOPSINFO* curLoop = &i->second;
|
||||
if(curLoop->start <= curEnd and curLoop->end >= curStart and curLoop->depth == depth)
|
||||
// Only look in the current module
|
||||
if (itr.first.second.first != key)
|
||||
continue;
|
||||
|
||||
// Loop must be at this recursive depth
|
||||
if (itr.second.depth != Depth)
|
||||
continue;
|
||||
|
||||
if(itr.second.start <= curEnd && itr.second.end >= curStart)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//this should delete a loop and all sub-loops that matches a certain addr
|
||||
bool loopdel(int depth, uint addr)
|
||||
// This should delete a loop and all sub-loops that matches a certain addr
|
||||
bool LoopDelete(int Depth, uint Address)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void loopcachesave(JSON root)
|
||||
void LoopCacheSave(JSON Root)
|
||||
{
|
||||
CriticalSectionLocker locker(LockLoops);
|
||||
EXCLUSIVE_ACQUIRE(LockLoops);
|
||||
const JSON jsonloops = json_array();
|
||||
const JSON jsonautoloops = json_array();
|
||||
for(LoopsInfo::iterator i = loops.begin(); i != loops.end(); ++i)
|
||||
for(auto& itr : loops)
|
||||
{
|
||||
const LOOPSINFO curLoop = i->second;
|
||||
const LOOPSINFO curLoop = itr.second;
|
||||
JSON curjsonloop = json_object();
|
||||
json_object_set_new(curjsonloop, "module", json_string(curLoop.mod));
|
||||
json_object_set_new(curjsonloop, "start", json_hex(curLoop.start));
|
||||
|
|
@ -114,18 +165,18 @@ void loopcachesave(JSON root)
|
|||
json_array_append_new(jsonautoloops, curjsonloop);
|
||||
}
|
||||
if(json_array_size(jsonloops))
|
||||
json_object_set(root, "loops", jsonloops);
|
||||
json_object_set(Root, "loops", jsonloops);
|
||||
json_decref(jsonloops);
|
||||
if(json_array_size(jsonautoloops))
|
||||
json_object_set(root, "autoloops", jsonautoloops);
|
||||
json_object_set(Root, "autoloops", jsonautoloops);
|
||||
json_decref(jsonautoloops);
|
||||
}
|
||||
|
||||
void loopcacheload(JSON root)
|
||||
void LoopCacheLoad(JSON Root)
|
||||
{
|
||||
CriticalSectionLocker locker(LockLoops);
|
||||
EXCLUSIVE_ACQUIRE(LockLoops);
|
||||
loops.clear();
|
||||
const JSON jsonloops = json_object_get(root, "loops");
|
||||
const JSON jsonloops = json_object_get(Root, "loops");
|
||||
if(jsonloops)
|
||||
{
|
||||
size_t i;
|
||||
|
|
@ -148,7 +199,7 @@ void loopcacheload(JSON root)
|
|||
loops.insert(std::make_pair(DepthModuleRange(curLoop.depth, ModuleRange(ModHashFromName(curLoop.mod), Range(curLoop.start, curLoop.end))), curLoop));
|
||||
}
|
||||
}
|
||||
JSON jsonautoloops = json_object_get(root, "autoloops");
|
||||
JSON jsonautoloops = json_object_get(Root, "autoloops");
|
||||
if(jsonautoloops)
|
||||
{
|
||||
size_t i;
|
||||
|
|
@ -173,9 +224,9 @@ void loopcacheload(JSON root)
|
|||
}
|
||||
}
|
||||
|
||||
bool loopenum(LOOPSINFO* List, size_t* Size)
|
||||
bool LoopEnum(LOOPSINFO* List, size_t* Size)
|
||||
{
|
||||
// If looplist or size is not requested, fail
|
||||
// If list or size is not requested, fail
|
||||
if(!List && !Size)
|
||||
return false;
|
||||
|
||||
|
|
@ -190,9 +241,9 @@ bool loopenum(LOOPSINFO* List, size_t* Size)
|
|||
return true;
|
||||
}
|
||||
|
||||
for(auto itr = loops.begin(); itr != loops.end(); itr++)
|
||||
for (auto& itr : loops)
|
||||
{
|
||||
*List = itr->second;
|
||||
*List = itr.second;
|
||||
|
||||
// Adjust the offset to a real virtual address
|
||||
uint modbase = ModBaseFromName(List->mod);
|
||||
|
|
@ -205,7 +256,7 @@ bool loopenum(LOOPSINFO* List, size_t* Size)
|
|||
return true;
|
||||
}
|
||||
|
||||
void loopclear()
|
||||
void LoopClear()
|
||||
{
|
||||
EXCLUSIVE_ACQUIRE(LockLoops);
|
||||
loops.clear();
|
||||
|
|
|
|||
|
|
@ -13,13 +13,13 @@ struct LOOPSINFO
|
|||
bool manual;
|
||||
};
|
||||
|
||||
bool loopadd(uint start, uint end, bool manual);
|
||||
bool loopget(int depth, uint addr, uint* start, uint* end);
|
||||
bool loopoverlaps(int depth, uint start, uint end, int* finaldepth);
|
||||
bool loopdel(int depth, uint addr);
|
||||
void loopcachesave(JSON root);
|
||||
void loopcacheload(JSON root);
|
||||
bool loopenum(LOOPSINFO* looplist, size_t* cbsize);
|
||||
void loopclear();
|
||||
bool LoopAdd(uint Start, uint End, bool Manual);
|
||||
bool LoopGet(int Depth, uint Address, uint* Start, uint* End);
|
||||
bool LoopOverlaps(int Depth, uint Start, uint End, int* FinalDepth);
|
||||
bool LoopDelete(int Depth, uint Address);
|
||||
void LoopCacheSave(JSON Root);
|
||||
void LoopCacheLoad(JSON Root);
|
||||
bool LoopEnum(LOOPSINFO* List, size_t* Size);
|
||||
void LoopClear();
|
||||
|
||||
#endif //_LOOP_H
|
||||
Loading…
Reference in New Issue