1
0
Fork 0

GUI: very basic implementation of CPUInfoBox (resolved issue #64)

This commit is contained in:
Mr. eXoDia 2014-08-05 09:01:50 +02:00
parent 091af5d362
commit cc4d1963ac
4 changed files with 158 additions and 9 deletions

View File

@ -264,10 +264,10 @@ typedef enum
typedef enum
{
size_byte,
size_word,
size_dword,
size_qword
size_byte = 1,
size_word = 2,
size_dword = 4,
size_qword = 8
} MEMORY_SIZE;
//Debugger typedefs

View File

@ -49,22 +49,25 @@ void fillbasicinfo(DISASM* disasm, BASIC_INSTRUCTION_INFO* basicinfo)
basicinfo->branch = false;
}
//find memory displacement
if((disasm->Argument1.ArgType & MEMORY_TYPE) == MEMORY_TYPE || (disasm->Argument2.ArgType & MEMORY_TYPE) == MEMORY_TYPE)
if((disasm->Argument1.ArgType & MEMORY_TYPE) == MEMORY_TYPE)
{
if(disasm->Argument1.Memory.Displacement)
{
basicinfo->type |= TYPE_MEMORY;
basicinfo->memory.value = (ULONG_PTR)disasm->Argument1.Memory.Displacement;
strcpy(basicinfo->memory.mnemonic, disasm->Argument1.ArgMnemonic);
basicinfo->memory.size = argsize2memsize(disasm->Argument1.ArgSize);
}
else if(disasm->Argument2.Memory.Displacement)
basicinfo->memory.size = argsize2memsize(disasm->Argument1.ArgSize);
}
if((disasm->Argument2.ArgType & MEMORY_TYPE) == MEMORY_TYPE)
{
if(disasm->Argument2.Memory.Displacement)
{
basicinfo->type |= TYPE_MEMORY;
basicinfo->memory.value = (ULONG_PTR)disasm->Argument2.Memory.Displacement;
strcpy(basicinfo->memory.mnemonic, disasm->Argument2.ArgMnemonic);
basicinfo->memory.size = argsize2memsize(disasm->Argument2.ArgSize);
}
basicinfo->memory.size = argsize2memsize(disasm->Argument2.ArgSize);
}
//find address value
if(disasm->Instruction.BranchType && disasm->Instruction.AddrValue)

View File

@ -13,8 +13,8 @@ CPUInfoBox::CPUInfoBox(StdTable* parent) : StdTable(parent)
int height = getHeight();
setMaximumHeight(height);
setMinimumHeight(height);
setCopyMenuOnly(true);
connect(Bridge::getBridge(), SIGNAL(dbgStateChanged(DBGSTATE)), this, SLOT(dbgStateChanged(DBGSTATE)));
connect(this, SIGNAL(contextMenuSignal(QPoint)), this, SLOT(contextMenuSlot(QPoint)));
}
int CPUInfoBox::getHeight()
@ -37,11 +37,86 @@ void CPUInfoBox::clear()
setInfoLine(2, "");
}
QString CPUInfoBox::getSymbolicName(int_t addr)
{
char labelText[MAX_LABEL_SIZE] = "";
char moduleText[MAX_MODULE_SIZE] = "";
bool bHasLabel = DbgGetLabelAt(addr, SEG_DEFAULT, labelText);
bool bHasModule = (DbgGetModuleAt(addr, moduleText) && !QString(labelText).startsWith("JMP.&"));
QString addrText;
addrText = QString("%1").arg(addr & (uint_t) - 1, 0, 16, QChar('0')).toUpper();
QString finalText;
if(bHasLabel && bHasModule) //<module.label>
finalText = QString("<%1.%2>").arg(moduleText).arg(labelText);
else if(bHasModule) //module.addr
finalText = QString("%1.%2").arg(moduleText).arg(addrText);
else if(bHasLabel) //<label>
finalText = QString("<%1>").arg(labelText);
else
finalText = addrText;
return finalText;
}
void CPUInfoBox::disasmSelectionChanged(int_t parVA)
{
curAddr = parVA;
if(!DbgIsDebugging() || !DbgMemIsValidReadPtr(parVA))
return;
clear();
DISASM_INSTR instr;
DbgDisasmAt(parVA, &instr);
BASIC_INSTRUCTION_INFO basicinfo;
DbgDisasmFastAt(parVA, &basicinfo);
for(int i = 0, j = 0; i < instr.argcount && j < 2; i++)
{
DISASM_ARG arg = instr.arg[i];
if(arg.type == arg_memory)
{
QString sizeName = "";
int memsize = basicinfo.memory.size;
switch(memsize)
{
case size_byte:
sizeName = "byte ";
break;
case size_word:
sizeName = "word ";
break;
case size_dword:
sizeName = "dword ";
break;
case size_qword:
sizeName = "qword ";
break;
}
if(!DbgMemIsValidReadPtr(arg.value))
setInfoLine(j, sizeName + "[" + QString(arg.mnemonic) + "]=???");
else
{
QString addrText;
if(memsize == sizeof(int_t))
addrText = getSymbolicName(arg.memvalue);
else
addrText = QString("%1").arg(arg.memvalue, memsize * 2, 16, QChar('0')).toUpper();
setInfoLine(j, sizeName + "[" + QString(arg.mnemonic) + "]=" + addrText);
}
j++;
}
else
{
QString mnemonic(arg.mnemonic);
bool ok;
mnemonic.toULongLong(&ok, 16);
if(ok) //skip numbers
continue;
setInfoLine(j, mnemonic + "=" + getSymbolicName(arg.value));
j++;
}
}
//set last line
QString info;
char mod[MAX_MODULE_SIZE] = "";
if(DbgFunctions()->ModNameFromAddr(parVA, mod, true))
@ -67,3 +142,68 @@ void CPUInfoBox::dbgStateChanged(DBGSTATE state)
if(state == stopped)
clear();
}
void CPUInfoBox::followActionSlot()
{
QAction* action = qobject_cast<QAction*>(sender());
if(action && action->objectName().startsWith("DUMP|"))
DbgCmdExec(QString().sprintf("dump \"%s\"", action->objectName().mid(5).toUtf8().constData()).toUtf8().constData());
}
void CPUInfoBox::addFollowMenuItem(QMenu* menu, QString name, int_t value)
{
QAction* newAction = new QAction(name, this);
newAction->setFont(QFont("Courier New", 8));
menu->addAction(newAction);
newAction->setObjectName(QString("DUMP|") + QString("%1").arg(value, sizeof(int_t) * 2, 16, QChar('0')).toUpper());
connect(newAction, SIGNAL(triggered()), this, SLOT(followActionSlot()));
}
void CPUInfoBox::setupFollowMenu(QMenu* menu, int_t wVA)
{
//most basic follow action
addFollowMenuItem(menu, "&Selection", wVA);
//add follow actions
DISASM_INSTR instr;
DbgDisasmAt(wVA, &instr);
for(int i = 0; i < instr.argcount; i++)
{
const DISASM_ARG arg = instr.arg[i];
if(arg.type == arg_memory)
{
if(DbgMemIsValidReadPtr(arg.value))
addFollowMenuItem(menu, "&Address: " + QString(arg.mnemonic).toUpper().trimmed(), arg.value);
if(arg.value != arg.constant)
{
QString constant = QString("%1").arg(arg.constant, 1, 16, QChar('0')).toUpper();
if(DbgMemIsValidReadPtr(arg.constant))
addFollowMenuItem(menu, "&Constant: " + constant, arg.value);
}
if(DbgMemIsValidReadPtr(arg.memvalue))
addFollowMenuItem(menu, "&Value: [" + QString(arg.mnemonic) + "]", arg.value);
}
else
{
if(DbgMemIsValidReadPtr(arg.value))
addFollowMenuItem(menu, QString(arg.mnemonic).toUpper().trimmed(), arg.value);
}
}
}
void CPUInfoBox::contextMenuSlot(QPoint pos)
{
QMenu* wMenu = new QMenu(this); //create context menu
QMenu* wFollowMenu = new QMenu("&Follow in Dump", this);
setupFollowMenu(wFollowMenu, curAddr);
wMenu->addMenu(wFollowMenu);
QMenu wCopyMenu("&Copy", this);
setupCopyMenu(&wCopyMenu);
if(wCopyMenu.actions().length())
{
wMenu->addSeparator();
wMenu->addMenu(&wCopyMenu);
}
wMenu->exec(mapToGlobal(pos)); //execute context menu
}

View File

@ -12,12 +12,18 @@ class CPUInfoBox : public StdTable
public:
explicit CPUInfoBox(StdTable* parent = 0);
int getHeight();
void addFollowMenuItem(QMenu* menu, QString name, int_t value);
void setupFollowMenu(QMenu* menu, int_t wVA);
public slots:
void disasmSelectionChanged(int_t parVA);
void dbgStateChanged(DBGSTATE state);
void contextMenuSlot(QPoint pos);
void followActionSlot();
private:
int_t curAddr;
QString getSymbolicName(int_t addr);
void setInfoLine(int line, QString text);
void clear();
};