1
0
Fork 0

Refactor comment.cpp/.h

This commit is contained in:
Nukem 2015-03-22 19:03:04 -04:00
parent 05c84c33ee
commit b42bb8a19e
7 changed files with 213 additions and 145 deletions

View File

@ -154,7 +154,7 @@ extern "C" DLL_EXPORT bool _dbg_addrinfoget(duint addr, SEGMENTREG segment, ADDR
if(addrinfo->flags & flagcomment)
{
*addrinfo->comment = 0;
if(commentget(addr, addrinfo->comment))
if(CommentGet(addr, addrinfo->comment))
retval = true;
else
{
@ -300,7 +300,7 @@ extern "C" DLL_EXPORT bool _dbg_addrinfoset(duint addr, ADDRINFO* addrinfo)
}
if(addrinfo->flags & flagcomment) //set comment
{
if(commentset(addr, addrinfo->comment, true))
if(CommentSet(addr, addrinfo->comment, true))
retval = true;
}
if(addrinfo->flags & flagbookmark) //set bookmark
@ -875,13 +875,13 @@ extern "C" DLL_EXPORT uint _dbg_sendmessage(DBGMSG type, void* param1, void* par
case DBG_SET_AUTO_COMMENT_AT:
{
return (uint)commentset((uint)param1, (const char*)param2, false);
return (uint)CommentSet((uint)param1, (const char*)param2, false);
}
break;
case DBG_DELETE_AUTO_COMMENT_RANGE:
{
commentdelrange((uint)param1, (uint)param2);
CommentDelRange((uint)param1, (uint)param2);
}
break;

View File

@ -21,7 +21,7 @@ void dbsave()
dprintf("saving database...");
DWORD ticks = GetTickCount();
JSON root = json_object();
commentcachesave(root);
CommentCacheSave(root);
labelcachesave(root);
BookmarkCacheSave(root);
FunctionCacheSave(root);
@ -82,7 +82,7 @@ void dbload()
dputs("\ninvalid database file (JSON)!");
return;
}
commentcacheload(root);
CommentCacheLoad(root);
labelcacheload(root);
BookmarkCacheLoad(root);
FunctionCacheLoad(root);
@ -95,7 +95,7 @@ void dbload()
void dbclose()
{
dbsave();
commentclear();
CommentClear();
labelclear();
BookmarkClear();
FunctionClear();

View File

@ -183,7 +183,9 @@ bool BookmarkEnum(BOOKMARKSINFO* List, size_t* Size)
if(Size)
{
*Size = bookmarks.size() * sizeof(BOOKMARKSINFO);
return true;
if(!List)
return true;
}
// Copy struct and adjust the relative offset to a virtual address

View File

@ -8,175 +8,244 @@ typedef std::map<uint, COMMENTSINFO> CommentsInfo;
static CommentsInfo comments;
bool commentset(uint addr, const char* text, bool manual)
bool CommentSet(uint Address, const char* Text, bool Manual)
{
if(!DbgIsDebugging() or !memisvalidreadptr(fdProcessInfo->hProcess, addr) or !text or text[0] == '\1' or strlen(text) >= MAX_COMMENT_SIZE - 1)
// CHECK: Exported/Command function
if(!DbgIsDebugging())
return false;
if(!*text) //NOTE: delete when there is no text
// A valid memory address must be supplied
if(!memisvalidreadptr(fdProcessInfo->hProcess, Address))
return false;
// Make sure the string is supplied, within bounds, and not a special delimiter
if(!Text || Text[0] == '\1' || strlen(Text) >= MAX_COMMENT_SIZE - 1)
return false;
// Delete the comment if no text was supplied
if(!*Text)
{
commentdel(addr);
CommentDelete(Address);
return true;
}
// Fill out the structure
COMMENTSINFO comment;
comment.manual = manual;
strcpy_s(comment.text, text);
ModNameFromAddr(addr, comment.mod, true);
comment.addr = addr - ModBaseFromAddr(addr);
const uint key = ModHashFromAddr(addr);
CriticalSectionLocker locker(LockComments);
if(!comments.insert(std::make_pair(key, comment)).second) //key already present
strcpy_s(comment.text, Text);
ModNameFromAddr(Address, comment.mod, true);
comment.manual = Manual;
comment.addr = Address - ModBaseFromAddr(Address);
// Insert into list
const uint key = ModHashFromAddr(Address);
EXCLUSIVE_ACQUIRE(LockComments);
// Only add if the key wasn't present
if(!comments.insert(std::make_pair(key, comment)).second)
comments[key] = comment;
return true;
}
bool commentget(uint addr, char* text)
bool CommentGet(uint Address, char* Text)
{
// CHECK: Exported/Command function
if(!DbgIsDebugging())
return false;
CriticalSectionLocker locker(LockComments);
const CommentsInfo::iterator found = comments.find(ModHashFromAddr(addr));
if(found == comments.end()) //not found
SHARED_ACQUIRE(LockComments);
// Get an existing comment and copy the string buffer
auto found = comments.find(ModHashFromAddr(Address));
// Was it found?
if(found == comments.end())
return false;
strcpy_s(text, MAX_COMMENT_SIZE, found->second.text);
strcpy_s(Text, MAX_COMMENT_SIZE, found->second.text);
return true;
}
bool commentdel(uint addr)
bool CommentDelete(uint Address)
{
// CHECK: Command/Sub function
if(!DbgIsDebugging())
return false;
CriticalSectionLocker locker(LockComments);
return (comments.erase(ModHashFromAddr(addr)) == 1);
EXCLUSIVE_ACQUIRE(LockComments);
return (comments.erase(ModHashFromAddr(Address)) > 0);
}
void commentdelrange(uint start, uint end)
void CommentDelRange(uint Start, uint End)
{
// CHECK: Export function
if(!DbgIsDebugging())
return;
bool bDelAll = (start == 0 && end == ~0); //0x00000000-0xFFFFFFFF
uint modbase = ModBaseFromAddr(start);
if(modbase != ModBaseFromAddr(end))
return;
start -= modbase;
end -= modbase;
CriticalSectionLocker locker(LockComments);
CommentsInfo::iterator i = comments.begin();
while(i != comments.end())
// Are all comments going to be deleted?
if(Start == 0x00000000 && End == 0xFFFFFFFF)
{
if(i->second.manual) //ignore manual
EXCLUSIVE_ACQUIRE(LockComments);
comments.clear();
}
else
{
// Make sure 'Start' and 'End' reference the same module
uint moduleBase = ModBaseFromAddr(Start);
if(moduleBase != ModBaseFromAddr(End))
return;
// Virtual -> relative offset
Start -= moduleBase;
End -= moduleBase;
EXCLUSIVE_ACQUIRE(LockComments);
for(auto itr = comments.begin(); itr != comments.end();)
{
i++;
continue;
// Ignore manually set entries
if(itr->second.manual)
{
itr++;
continue;
}
// [Start, End)
if(itr->second.addr >= Start && itr->second.addr < End)
itr = comments.erase(itr);
else
itr++;
}
if(bDelAll || (i->second.addr >= start && i->second.addr < end))
comments.erase(i++);
else
i++;
}
}
void commentcachesave(JSON root)
void CommentCacheSave(JSON Root)
{
CriticalSectionLocker locker(LockComments);
const JSON jsoncomments = json_array();
const JSON jsonautocomments = json_array();
for(CommentsInfo::iterator i = comments.begin(); i != comments.end(); ++i)
EXCLUSIVE_ACQUIRE(LockComments);
const JSON jsonComments = json_array();
const JSON jsonAutoComments = json_array();
// Build the JSON array
for(auto & itr : comments)
{
const COMMENTSINFO curComment = i->second;
JSON curjsoncomment = json_object();
json_object_set_new(curjsoncomment, "module", json_string(curComment.mod));
json_object_set_new(curjsoncomment, "address", json_hex(curComment.addr));
json_object_set_new(curjsoncomment, "text", json_string(curComment.text));
if(curComment.manual)
json_array_append_new(jsoncomments, curjsoncomment);
JSON currentComment = json_object();
json_object_set_new(currentComment, "module", json_string(itr.second.mod));
json_object_set_new(currentComment, "address", json_hex(itr.second.addr));
json_object_set_new(currentComment, "text", json_string(itr.second.text));
if(itr.second.manual)
json_array_append_new(jsonComments, currentComment);
else
json_array_append_new(jsonautocomments, curjsoncomment);
json_array_append_new(jsonAutoComments, currentComment);
}
if(json_array_size(jsoncomments))
json_object_set(root, "comments", jsoncomments);
json_decref(jsoncomments);
if(json_array_size(jsonautocomments))
json_object_set(root, "autocomments", jsonautocomments);
json_decref(jsonautocomments);
// Save to the JSON root
if(json_array_size(jsonComments))
json_object_set(Root, "comments", jsonComments);
if(json_array_size(jsonAutoComments))
json_object_set(Root, "autocomments", jsonAutoComments);
json_decref(jsonComments);
json_decref(jsonAutoComments);
}
void commentcacheload(JSON root)
void CommentCacheLoad(JSON Root)
{
CriticalSectionLocker locker(LockComments);
EXCLUSIVE_ACQUIRE(LockBookmarks);
// Inline lambda to parse each JSON entry
auto AddBookmarks = [](const JSON Object, bool Manual)
{
size_t i;
JSON value;
json_array_foreach(Object, i, value)
{
COMMENTSINFO commentInfo;
// Module
const char* mod = json_string_value(json_object_get(value, "module"));
if(mod && *mod && strlen(mod) < MAX_MODULE_SIZE)
strcpy_s(commentInfo.mod, mod);
else
commentInfo.mod[0] = '\0';
// Address/Manual
commentInfo.addr = (uint)json_hex_value(json_object_get(value, "address"));
commentInfo.manual = Manual;
// String value
const char* text = json_string_value(json_object_get(value, "text"));
if(text)
strcpy_s(commentInfo.text, text);
else
{
// Skip blank comments
continue;
}
const uint key = ModHashFromName(commentInfo.mod) + commentInfo.addr;
comments.insert(std::make_pair(key, commentInfo));
}
};
// Remove existing entries
comments.clear();
const JSON jsoncomments = json_object_get(root, "comments");
if(jsoncomments)
{
size_t i;
JSON value;
json_array_foreach(jsoncomments, i, value)
{
COMMENTSINFO curComment;
const char* mod = json_string_value(json_object_get(value, "module"));
if(mod && *mod && strlen(mod) < MAX_MODULE_SIZE)
strcpy_s(curComment.mod, mod);
else
*curComment.mod = '\0';
curComment.addr = (uint)json_hex_value(json_object_get(value, "address"));
curComment.manual = true;
const char* text = json_string_value(json_object_get(value, "text"));
if(text)
strcpy_s(curComment.text, text);
else
continue; //skip
const uint key = ModHashFromName(curComment.mod) + curComment.addr;
comments.insert(std::make_pair(key, curComment));
}
}
JSON jsonautocomments = json_object_get(root, "autocomments");
if(jsonautocomments)
{
size_t i;
JSON value;
json_array_foreach(jsonautocomments, i, value)
{
COMMENTSINFO curComment;
const char* mod = json_string_value(json_object_get(value, "module"));
if(mod && *mod && strlen(mod) < MAX_MODULE_SIZE)
strcpy_s(curComment.mod, mod);
else
*curComment.mod = '\0';
curComment.addr = (uint)json_hex_value(json_object_get(value, "address"));
curComment.manual = false;
const char* text = json_string_value(json_object_get(value, "text"));
if(text)
strcpy_s(curComment.text, text);
else
continue; //skip
const uint key = ModHashFromName(curComment.mod) + curComment.addr;
comments.insert(std::make_pair(key, curComment));
}
}
const JSON jsonComments = json_object_get(Root, "comments");
const JSON jsonAutoComments = json_object_get(Root, "autocomments");
// Load user-set comments
if(jsonComments)
AddBookmarks(jsonComments, true);
// Load auto-set comments
if(jsonAutoComments)
AddBookmarks(jsonAutoComments, false);
}
bool commentenum(COMMENTSINFO* commentlist, size_t* cbsize)
bool CommentEnum(COMMENTSINFO* List, size_t* Size)
{
// CHECK: Command function
if(!DbgIsDebugging())
return false;
if(!commentlist && !cbsize)
// At least 1 parameter must be supplied
if(!List && !Size)
return false;
CriticalSectionLocker locker(LockComments);
if(!commentlist && cbsize)
SHARED_ACQUIRE(LockComments);
// Check if the user requested size only
if(Size)
{
*cbsize = comments.size() * sizeof(COMMENTSINFO);
return true;
*Size = comments.size() * sizeof(COMMENTSINFO);
if(!List)
return true;
}
int j = 0;
for(CommentsInfo::iterator i = comments.begin(); i != comments.end(); ++i, j++)
// Populate the returned array
for(auto & itr : comments)
{
commentlist[j] = i->second;
commentlist[j].addr += ModBaseFromName(commentlist[j].mod);
*List = itr.second;
List->addr += ModBaseFromName(List->mod);
List++;
}
return true;
}
void commentclear()
void CommentClear()
{
CriticalSectionLocker locker(LockComments);
CommentsInfo().swap(comments);
EXCLUSIVE_ACQUIRE(LockComments);
comments.clear();
}

View File

@ -1,5 +1,4 @@
#ifndef _COMMENT_H
#define _COMMENT_H
#pragma once
#include "_global.h"
@ -11,13 +10,11 @@ struct COMMENTSINFO
bool manual;
};
bool commentset(uint addr, const char* text, bool manual);
bool commentget(uint addr, char* text);
bool commentdel(uint addr);
void commentdelrange(uint start, uint end);
void commentcachesave(JSON root);
void commentcacheload(JSON root);
bool commentenum(COMMENTSINFO* commentlist, size_t* cbsize);
void commentclear();
#endif //_COMMENT_H
bool CommentSet(uint Address, const char* Text, bool Manual);
bool CommentGet(uint Address, char* Text);
bool CommentDelete(uint Address);
void CommentDelRange(uint Start, uint End);
void CommentCacheSave(JSON Root);
void CommentCacheLoad(JSON Root);
bool CommentEnum(COMMENTSINFO* List, size_t* Size);
void CommentClear();

View File

@ -811,7 +811,7 @@ CMDRESULT cbDebugBenchmark(int argc, char* argv[])
char comment[MAX_COMMENT_SIZE] = "";
for(uint i = addr; i < addr + 100000; i++)
{
commentset(i, "test", false);
CommentSet(i, "test", false);
labelset(i, "test", false);
BookmarkSet(i, false);
FunctionAdd(i, i, false);

View File

@ -294,7 +294,7 @@ CMDRESULT cbInstrCmt(int argc, char* argv[])
uint addr = 0;
if(!valfromstring(argv[1], &addr, false))
return STATUS_ERROR;
if(!commentset(addr, argv[2], true))
if(!CommentSet(addr, argv[2], true))
{
dputs("error setting comment");
return STATUS_ERROR;
@ -312,7 +312,7 @@ CMDRESULT cbInstrCmtdel(int argc, char* argv[])
uint addr = 0;
if(!valfromstring(argv[1], &addr, false))
return STATUS_ERROR;
if(!commentdel(addr))
if(!CommentDelete(addr))
{
dputs("error deleting comment");
return STATUS_ERROR;
@ -1270,14 +1270,14 @@ CMDRESULT cbInstrCommentList(int argc, char* argv[])
GuiReferenceAddColumn(0, "Comment");
GuiReferenceReloadData();
size_t cbsize;
commentenum(0, &cbsize);
CommentEnum(0, &cbsize);
if(!cbsize)
{
dputs("no comments");
return STATUS_CONTINUE;
}
Memory<COMMENTSINFO*> comments(cbsize, "cbInstrCommentList:comments");
commentenum(comments, 0);
CommentEnum(comments, 0);
int count = (int)(cbsize / sizeof(COMMENTSINFO));
for(int i = 0; i < count; i++)
{
@ -1400,7 +1400,7 @@ CMDRESULT cbInstrFunctionList(int argc, char* argv[])
else
{
char comment[MAX_COMMENT_SIZE] = "";
if(commentget(functions[i].start, comment))
if(CommentGet(functions[i].start, comment))
GuiReferenceSetCellContent(i, 3, comment);
}
}
@ -1446,7 +1446,7 @@ CMDRESULT cbInstrLoopList(int argc, char* argv[])
else
{
char comment[MAX_COMMENT_SIZE] = "";
if(commentget(loops[i].start, comment))
if(CommentGet(loops[i].start, comment))
GuiReferenceSetCellContent(i, 3, comment);
}
}