Use QTextDocument instead of html to build text display
Continued work on rendering disassembly level text.
This commit is contained in:
parent
6ade935e37
commit
4cc3b41e64
@ -98,11 +98,7 @@ static void toStructuredText(STKFRAME &stk,IStructuredTextTarget *out, int level
|
||||
out->prtt(QString(" gap len = %1h").arg(maxlevel - curlevel,0,16));
|
||||
}
|
||||
}
|
||||
static void toStructuredText(LLInst *insn,IStructuredTextTarget *out, int level) {
|
||||
out->prtt("LLINST");
|
||||
out->addEOL();
|
||||
|
||||
}
|
||||
extern void toStructuredText(LLInst *insn,IStructuredTextTarget *out, int level);
|
||||
|
||||
static void toStructuredText(ICODE &stk,IStructuredTextTarget *out, int level) {
|
||||
if(level==0) {
|
||||
|
||||
583
src/disassem.cpp
583
src/disassem.cpp
@ -18,6 +18,7 @@
|
||||
#include <iomanip>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "src/ui/StructuredTextTarget.h"
|
||||
|
||||
// Note: for the time being, there is no interactive disassembler
|
||||
// for unix
|
||||
@ -298,190 +299,190 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
|
||||
|
||||
switch ( inst.getOpcode() )
|
||||
{
|
||||
case iADD: case iADC: case iSUB: case iSBB: case iAND: case iOR:
|
||||
case iXOR: case iTEST: case iCMP: case iMOV: case iLEA: case iXCHG:
|
||||
strDst(operands_s,inst.getFlag(), inst.m_dst);
|
||||
case iADD: case iADC: case iSUB: case iSBB: case iAND: case iOR:
|
||||
case iXOR: case iTEST: case iCMP: case iMOV: case iLEA: case iXCHG:
|
||||
strDst(operands_s,inst.getFlag(), inst.m_dst);
|
||||
inst.strSrc(operands_s);
|
||||
break;
|
||||
|
||||
case iESC:
|
||||
inst.flops(operands_s);
|
||||
break;
|
||||
|
||||
case iSAR: case iSHL: case iSHR: case iRCL: case iRCR: case iROL:
|
||||
case iROR:
|
||||
strDst(operands_s,inst.getFlag() | I, inst.m_dst);
|
||||
if(inst.testFlags(I))
|
||||
inst.strSrc(operands_s);
|
||||
break;
|
||||
else
|
||||
operands_s<<", cl";
|
||||
break;
|
||||
|
||||
case iESC:
|
||||
inst.flops(operands_s);
|
||||
break;
|
||||
case iINC: case iDEC: case iNEG: case iNOT: case iPOP:
|
||||
strDst(operands_s,inst.getFlag() | I, inst.m_dst);
|
||||
break;
|
||||
|
||||
case iSAR: case iSHL: case iSHR: case iRCL: case iRCR: case iROL:
|
||||
case iROR:
|
||||
case iPUSH:
|
||||
if (inst.testFlags(I))
|
||||
{
|
||||
operands_s<<strHex(inst.src().getImm2());
|
||||
}
|
||||
else
|
||||
{
|
||||
strDst(operands_s,inst.getFlag() | I, inst.m_dst);
|
||||
if(inst.testFlags(I))
|
||||
inst.strSrc(operands_s);
|
||||
else
|
||||
operands_s<<", cl";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case iINC: case iDEC: case iNEG: case iNOT: case iPOP:
|
||||
strDst(operands_s,inst.getFlag() | I, inst.m_dst);
|
||||
break;
|
||||
case iDIV: case iIDIV: case iMUL: case iIMUL: case iMOD:
|
||||
if (inst.testFlags(I))
|
||||
{
|
||||
strDst(operands_s,inst.getFlag(), inst.m_dst) <<", ";
|
||||
formatRM(operands_s, inst.src());
|
||||
inst.strSrc(operands_s);
|
||||
}
|
||||
else
|
||||
strDst(operands_s,inst.getFlag() | I, inst.src());
|
||||
break;
|
||||
|
||||
case iPUSH:
|
||||
if (inst.testFlags(I))
|
||||
case iLDS: case iLES: case iBOUND:
|
||||
strDst(operands_s,inst.getFlag(), inst.m_dst)<<", dword ptr";
|
||||
inst.strSrc(operands_s,true);
|
||||
break;
|
||||
|
||||
case iJB: case iJBE: case iJAE: case iJA:
|
||||
case iJL: case iJLE: case iJGE: case iJG:
|
||||
case iJE: case iJNE: case iJS: case iJNS:
|
||||
case iJO: case iJNO: case iJP: case iJNP:
|
||||
case iJCXZ:case iLOOP: case iLOOPE:case iLOOPNE:
|
||||
case iJMP: case iJMPF:
|
||||
|
||||
/* Check if there is a symbol here */
|
||||
{
|
||||
ICODE *lab=pc.GetIcode(inst.src().getImm2());
|
||||
selectTable(Label);
|
||||
if ((inst.src().getImm2() < (uint32_t)numIcode) and /* Ensure in range */
|
||||
readVal(operands_s, lab->ll()->label, nullptr))
|
||||
{
|
||||
break; /* Symbolic label. Done */
|
||||
}
|
||||
}
|
||||
|
||||
if (inst.testFlags(NO_LABEL))
|
||||
{
|
||||
//strcpy(p + WID_PTR, strHex(pIcode->ll()->immed.op));
|
||||
operands_s<<strHex(inst.src().getImm2());
|
||||
}
|
||||
else if (inst.testFlags(I) )
|
||||
{
|
||||
j = inst.src().getImm2();
|
||||
if (pl.count(j)==0) /* Forward jump */
|
||||
{
|
||||
operands_s<<strHex(inst.src().getImm2());
|
||||
pl[j] = ++g_lab;
|
||||
}
|
||||
else
|
||||
if (inst.getOpcode() == iJMPF)
|
||||
{
|
||||
strDst(operands_s,inst.getFlag() | I, inst.m_dst);
|
||||
operands_s<<" far ptr ";
|
||||
}
|
||||
break;
|
||||
|
||||
case iDIV: case iIDIV: case iMUL: case iIMUL: case iMOD:
|
||||
if (inst.testFlags(I))
|
||||
{
|
||||
strDst(operands_s,inst.getFlag(), inst.m_dst) <<", ";
|
||||
formatRM(operands_s, inst.src());
|
||||
inst.strSrc(operands_s);
|
||||
}
|
||||
else
|
||||
strDst(operands_s,inst.getFlag() | I, inst.src());
|
||||
break;
|
||||
|
||||
case iLDS: case iLES: case iBOUND:
|
||||
strDst(operands_s,inst.getFlag(), inst.m_dst)<<", dword ptr";
|
||||
operands_s<<"L"<<pl[j];
|
||||
}
|
||||
else if (inst.getOpcode() == iJMPF)
|
||||
{
|
||||
operands_s<<"dword ptr";
|
||||
inst.strSrc(operands_s,true);
|
||||
break;
|
||||
|
||||
case iJB: case iJBE: case iJAE: case iJA:
|
||||
case iJL: case iJLE: case iJGE: case iJG:
|
||||
case iJE: case iJNE: case iJS: case iJNS:
|
||||
case iJO: case iJNO: case iJP: case iJNP:
|
||||
case iJCXZ:case iLOOP: case iLOOPE:case iLOOPNE:
|
||||
case iJMP: case iJMPF:
|
||||
|
||||
/* Check if there is a symbol here */
|
||||
{
|
||||
ICODE *lab=pc.GetIcode(inst.src().getImm2());
|
||||
selectTable(Label);
|
||||
if ((inst.src().getImm2() < (uint32_t)numIcode) and /* Ensure in range */
|
||||
readVal(operands_s, lab->ll()->label, nullptr))
|
||||
{
|
||||
break; /* Symbolic label. Done */
|
||||
}
|
||||
}
|
||||
|
||||
if (inst.testFlags(NO_LABEL))
|
||||
{
|
||||
//strcpy(p + WID_PTR, strHex(pIcode->ll()->immed.op));
|
||||
operands_s<<strHex(inst.src().getImm2());
|
||||
}
|
||||
else if (inst.testFlags(I) )
|
||||
{
|
||||
j = inst.src().getImm2();
|
||||
if (pl.count(j)==0) /* Forward jump */
|
||||
{
|
||||
pl[j] = ++g_lab;
|
||||
}
|
||||
if (inst.getOpcode() == iJMPF)
|
||||
{
|
||||
operands_s<<" far ptr ";
|
||||
}
|
||||
operands_s<<"L"<<pl[j];
|
||||
}
|
||||
else if (inst.getOpcode() == iJMPF)
|
||||
{
|
||||
operands_s<<"dword ptr";
|
||||
inst.strSrc(operands_s,true);
|
||||
}
|
||||
else
|
||||
{
|
||||
strDst(operands_s,I, inst.src());
|
||||
}
|
||||
break;
|
||||
|
||||
case iCALL: case iCALLF:
|
||||
if (inst.testFlags(I))
|
||||
{
|
||||
QString oper = QString("%1 ptr %2")
|
||||
.arg((inst.getOpcode() == iCALL) ? "near" : "far")
|
||||
.arg((inst.src().proc.proc)->name);
|
||||
operands_s<< qPrintable(oper);
|
||||
}
|
||||
else if (inst.getOpcode() == iCALLF)
|
||||
{
|
||||
operands_s<<"dword ptr ";
|
||||
inst.strSrc(operands_s,true);
|
||||
}
|
||||
else
|
||||
strDst(operands_s,I, inst.src());
|
||||
break;
|
||||
|
||||
case iENTER:
|
||||
operands_s<<strHex(inst.m_dst.off) << ", " << strHex(inst.src().getImm2());
|
||||
break;
|
||||
|
||||
case iRET: case iRETF: case iINT:
|
||||
if (inst.testFlags(I))
|
||||
{
|
||||
operands_s<<strHex(inst.src().getImm2());
|
||||
}
|
||||
break;
|
||||
|
||||
case iCMPS: case iREPNE_CMPS: case iREPE_CMPS:
|
||||
case iSCAS: case iREPNE_SCAS: case iREPE_SCAS:
|
||||
case iSTOS: case iREP_STOS:
|
||||
case iLODS: case iREP_LODS:
|
||||
case iMOVS: case iREP_MOVS:
|
||||
case iINS: case iREP_INS:
|
||||
case iOUTS: case iREP_OUTS:
|
||||
if (inst.src().segOver)
|
||||
{
|
||||
bool is_dx_src=(inst.getOpcode() == iOUTS or inst.getOpcode() == iREP_OUTS);
|
||||
if(is_dx_src)
|
||||
operands_s<<"dx, "<<szPtr[inst.getFlag() & B];
|
||||
else
|
||||
operands_s<<szPtr[inst.getFlag() & B];
|
||||
if (inst.getOpcode() == iLODS or
|
||||
inst.getOpcode() == iREP_LODS or
|
||||
inst.getOpcode() == iOUTS or
|
||||
inst.getOpcode() == iREP_OUTS)
|
||||
{
|
||||
operands_s<<Machine_X86::regName(inst.src().segOver); // szWreg[src.segOver-rAX]
|
||||
}
|
||||
else
|
||||
{
|
||||
operands_s<<"es:[di], "<<Machine_X86::regName(inst.src().segOver);
|
||||
}
|
||||
operands_s<<":[si]";
|
||||
}
|
||||
else
|
||||
{
|
||||
if(inst.getFlag() & B)
|
||||
opcode_with_mods+='B';
|
||||
else
|
||||
opcode_with_mods+='W';
|
||||
}
|
||||
break;
|
||||
|
||||
case iXLAT:
|
||||
if (inst.src().segOver)
|
||||
{
|
||||
operands_s<<" "<<szPtr[1];
|
||||
operands_s<<Machine_X86::regName(inst.src().segOver)<<":[bx]";
|
||||
}
|
||||
break;
|
||||
|
||||
case iIN:
|
||||
(inst.getFlag() & B)? operands_s<<"al, " : operands_s<< "ax, ";
|
||||
(inst.testFlags(I))? operands_s << strHex(inst.src().getImm2()) : operands_s<< "dx";
|
||||
break;
|
||||
|
||||
case iOUT:
|
||||
else
|
||||
{
|
||||
QString d1=((inst.testFlags(I))? strHex(inst.src().getImm2()): "dx");
|
||||
QString d2=((inst.getFlag() & B) ? ", al": ", ax");
|
||||
operands_s<<d1 << d2;
|
||||
strDst(operands_s,I, inst.src());
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
case iCALL: case iCALLF:
|
||||
if (inst.testFlags(I))
|
||||
{
|
||||
QString oper = QString("%1 ptr %2")
|
||||
.arg((inst.getOpcode() == iCALL) ? "near" : "far")
|
||||
.arg((inst.src().proc.proc)->name);
|
||||
operands_s<< qPrintable(oper);
|
||||
}
|
||||
else if (inst.getOpcode() == iCALLF)
|
||||
{
|
||||
operands_s<<"dword ptr ";
|
||||
inst.strSrc(operands_s,true);
|
||||
}
|
||||
else
|
||||
strDst(operands_s,I, inst.src());
|
||||
break;
|
||||
|
||||
case iENTER:
|
||||
operands_s<<strHex(inst.m_dst.off) << ", " << strHex(inst.src().getImm2());
|
||||
break;
|
||||
|
||||
case iRET: case iRETF: case iINT:
|
||||
if (inst.testFlags(I))
|
||||
{
|
||||
operands_s<<strHex(inst.src().getImm2());
|
||||
}
|
||||
break;
|
||||
|
||||
case iCMPS: case iREPNE_CMPS: case iREPE_CMPS:
|
||||
case iSCAS: case iREPNE_SCAS: case iREPE_SCAS:
|
||||
case iSTOS: case iREP_STOS:
|
||||
case iLODS: case iREP_LODS:
|
||||
case iMOVS: case iREP_MOVS:
|
||||
case iINS: case iREP_INS:
|
||||
case iOUTS: case iREP_OUTS:
|
||||
if (inst.src().segOver)
|
||||
{
|
||||
bool is_dx_src=(inst.getOpcode() == iOUTS or inst.getOpcode() == iREP_OUTS);
|
||||
if(is_dx_src)
|
||||
operands_s<<"dx, "<<szPtr[inst.getFlag() & B];
|
||||
else
|
||||
operands_s<<szPtr[inst.getFlag() & B];
|
||||
if (inst.getOpcode() == iLODS or
|
||||
inst.getOpcode() == iREP_LODS or
|
||||
inst.getOpcode() == iOUTS or
|
||||
inst.getOpcode() == iREP_OUTS)
|
||||
{
|
||||
operands_s<<Machine_X86::regName(inst.src().segOver); // szWreg[src.segOver-rAX]
|
||||
}
|
||||
else
|
||||
{
|
||||
operands_s<<"es:[di], "<<Machine_X86::regName(inst.src().segOver);
|
||||
}
|
||||
operands_s<<":[si]";
|
||||
}
|
||||
else
|
||||
{
|
||||
if(inst.getFlag() & B)
|
||||
opcode_with_mods+='B';
|
||||
else
|
||||
opcode_with_mods+='W';
|
||||
}
|
||||
break;
|
||||
|
||||
case iXLAT:
|
||||
if (inst.src().segOver)
|
||||
{
|
||||
operands_s<<" "<<szPtr[1];
|
||||
operands_s<<Machine_X86::regName(inst.src().segOver)<<":[bx]";
|
||||
}
|
||||
break;
|
||||
|
||||
case iIN:
|
||||
(inst.getFlag() & B)? operands_s<<"al, " : operands_s<< "ax, ";
|
||||
(inst.testFlags(I))? operands_s << strHex(inst.src().getImm2()) : operands_s<< "dx";
|
||||
break;
|
||||
|
||||
case iOUT:
|
||||
{
|
||||
QString d1=((inst.testFlags(I))? strHex(inst.src().getImm2()): "dx");
|
||||
QString d2=((inst.getFlag() & B) ? ", al": ", ax");
|
||||
operands_s<<d1 << d2;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
oper_stream.setFieldWidth(15);
|
||||
operands_s.flush();
|
||||
@ -690,29 +691,29 @@ void LLInst::flops(QTextStream &out)
|
||||
}
|
||||
else switch (op & 0x30)
|
||||
{
|
||||
case 0x00:
|
||||
case 0x10:
|
||||
out << "dword ptr ";
|
||||
case 0x00:
|
||||
case 0x10:
|
||||
out << "dword ptr ";
|
||||
break;
|
||||
case 0x20:
|
||||
out << "qword ptr ";
|
||||
break;
|
||||
case 0x30:
|
||||
switch (op)
|
||||
{
|
||||
case 0x3C: /* FBLD */
|
||||
case 0x3E: /* FBSTP */
|
||||
out << "tbyte ptr ";
|
||||
break;
|
||||
case 0x20:
|
||||
case 0x3D: /* FILD 64 bit */
|
||||
case 0x3F: /* FISTP 64 bit */
|
||||
out << "qword ptr ";
|
||||
break;
|
||||
case 0x30:
|
||||
switch (op)
|
||||
{
|
||||
case 0x3C: /* FBLD */
|
||||
case 0x3E: /* FBSTP */
|
||||
out << "tbyte ptr ";
|
||||
break;
|
||||
case 0x3D: /* FILD 64 bit */
|
||||
case 0x3F: /* FISTP 64 bit */
|
||||
out << "qword ptr ";
|
||||
break;
|
||||
|
||||
default:
|
||||
out << "uint16_t ptr ";
|
||||
break;
|
||||
}
|
||||
default:
|
||||
out << "uint16_t ptr ";
|
||||
break;
|
||||
}
|
||||
}
|
||||
out.setFieldWidth(0);
|
||||
formatRM(out, m_dst);
|
||||
@ -727,46 +728,178 @@ void LLInst::flops(QTextStream &out)
|
||||
int destRegIdx=m_dst.regi - rAX;
|
||||
switch (op)
|
||||
{
|
||||
case 0x0C:
|
||||
out << szFlops0C[destRegIdx];
|
||||
break;
|
||||
case 0x0D:
|
||||
out << szFlops0D[destRegIdx];
|
||||
break;
|
||||
case 0x0E:
|
||||
out << szFlops0E[destRegIdx];
|
||||
break;
|
||||
case 0x0F:
|
||||
out << szFlops0F[destRegIdx];
|
||||
break;
|
||||
case 0x15:
|
||||
out << szFlops15[destRegIdx];
|
||||
break;
|
||||
case 0x1C:
|
||||
out << szFlops1C[destRegIdx];
|
||||
break;
|
||||
case 0x33:
|
||||
out << szFlops33[destRegIdx];
|
||||
break;
|
||||
case 0x3C:
|
||||
out << szFlops3C[destRegIdx];
|
||||
break;
|
||||
default:
|
||||
out << Machine_X86::floatOpName(0x40+op);
|
||||
if ((op >= 0x20) and (op <= 0x27))
|
||||
{
|
||||
/* This is the ST(i), ST form. */
|
||||
out << "ST("<<destRegIdx - rAX<<"),ST";
|
||||
}
|
||||
else
|
||||
{
|
||||
/* ST, ST(i) */
|
||||
out << "ST,ST("<<destRegIdx;
|
||||
}
|
||||
case 0x0C:
|
||||
out << szFlops0C[destRegIdx];
|
||||
break;
|
||||
case 0x0D:
|
||||
out << szFlops0D[destRegIdx];
|
||||
break;
|
||||
case 0x0E:
|
||||
out << szFlops0E[destRegIdx];
|
||||
break;
|
||||
case 0x0F:
|
||||
out << szFlops0F[destRegIdx];
|
||||
break;
|
||||
case 0x15:
|
||||
out << szFlops15[destRegIdx];
|
||||
break;
|
||||
case 0x1C:
|
||||
out << szFlops1C[destRegIdx];
|
||||
break;
|
||||
case 0x33:
|
||||
out << szFlops33[destRegIdx];
|
||||
break;
|
||||
case 0x3C:
|
||||
out << szFlops3C[destRegIdx];
|
||||
break;
|
||||
default:
|
||||
out << Machine_X86::floatOpName(0x40+op);
|
||||
if ((op >= 0x20) and (op <= 0x27))
|
||||
{
|
||||
/* This is the ST(i), ST form. */
|
||||
out << "ST("<<destRegIdx - rAX<<"),ST";
|
||||
}
|
||||
else
|
||||
{
|
||||
/* ST, ST(i) */
|
||||
out << "ST,ST("<<destRegIdx;
|
||||
}
|
||||
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/****************************************************************************
|
||||
* formatRM
|
||||
***************************************************************************/
|
||||
static void formatRM(IStructuredTextTarget *out,const LLOperand &pm)
|
||||
{
|
||||
if (pm.segOver)
|
||||
{
|
||||
out->prtt(Machine_X86::regName(pm.segOver)+':');
|
||||
}
|
||||
|
||||
if (pm.regi == rUNDEF)
|
||||
{
|
||||
out->prtt(QString("[")+strHex((uint32_t)pm.off)+"]");
|
||||
}
|
||||
else if (pm.isReg())
|
||||
{
|
||||
out->prtt(Machine_X86::regName(pm.regi));
|
||||
}
|
||||
|
||||
else if (pm.off)
|
||||
{
|
||||
if (pm.off < 0)
|
||||
{
|
||||
out->prtt("["+Machine_X86::regName(pm.regi)+"-"+strHex((uint32_t)(- pm.off))+"]");
|
||||
}
|
||||
else
|
||||
{
|
||||
out->prtt("["+Machine_X86::regName(pm.regi)+"+"+strHex((uint32_t)(pm.off))+"]");
|
||||
}
|
||||
}
|
||||
else
|
||||
out->prtt("["+Machine_X86::regName(pm.regi)+"]");
|
||||
}
|
||||
static void strDst(IStructuredTextTarget *out,uint32_t flg, const LLOperand &pm)
|
||||
{
|
||||
/* Immediates to memory require size descriptor */
|
||||
//os << setw(WID_PTR);
|
||||
if ((flg & I) and not pm.isReg()) {
|
||||
out->addTaggedString(XT_Keyword,szPtr[flg&B]);
|
||||
}
|
||||
formatRM(out,pm);
|
||||
}
|
||||
static void strSrc(IStructuredTextTarget *out,LLInst *insn,bool skip_comma=false)
|
||||
{
|
||||
if(false==skip_comma)
|
||||
out->prtt(", ");
|
||||
if (insn->testFlags(I))
|
||||
out->addTaggedString(XT_Number,strHex(insn->src().getImm2()));
|
||||
else if (insn->testFlags(IM_SRC)) /* level 2 */
|
||||
out->addTaggedString(XT_Symbol,"dx:ax");
|
||||
else
|
||||
formatRM(out,insn->src());
|
||||
}
|
||||
|
||||
void toStructuredText(LLInst *insn,IStructuredTextTarget *out, int level) {
|
||||
|
||||
const LLInst &inst(*insn);
|
||||
QString opcode = Machine_X86::opcodeName(insn->getOpcode());
|
||||
out->addSpace(4);
|
||||
out->addTaggedString(XT_Number,strHex(insn->label));
|
||||
out->addSpace(4);
|
||||
out->addTaggedString(XT_Keyword,Machine_X86::opcodeName(insn->getOpcode()),insn);
|
||||
out->addSpace(2);
|
||||
|
||||
switch(insn->getOpcode()) {
|
||||
case iADD: case iADC: case iSUB: case iSBB: case iAND: case iOR:
|
||||
case iXOR: case iTEST: case iCMP: case iMOV: case iLEA: case iXCHG:
|
||||
strDst(out,insn->getFlag(), insn->m_dst);
|
||||
strSrc(out,insn);
|
||||
break;
|
||||
case iSAR: case iSHL: case iSHR: case iRCL: case iRCR: case iROL:
|
||||
case iROR:
|
||||
strDst(out,insn->getFlag() | I, insn->m_dst);
|
||||
if(insn->testFlags(I))
|
||||
strSrc(out,insn);
|
||||
else {
|
||||
out->prtt(", ");
|
||||
out->addTaggedString(XT_Symbol,"cl");
|
||||
}
|
||||
break;
|
||||
|
||||
case iINC: case iDEC: case iNEG: case iNOT: case iPOP:
|
||||
strDst(out,insn->getFlag() | I, insn->m_dst);
|
||||
break;
|
||||
case iPUSH:
|
||||
if (inst.testFlags(I))
|
||||
{
|
||||
out->addTaggedString(XT_Number,strHex(inst.src().getImm2()));
|
||||
}
|
||||
else
|
||||
{
|
||||
strDst(out,insn->getFlag() | I, insn->m_dst);
|
||||
}
|
||||
break;
|
||||
|
||||
case iDIV: case iIDIV: case iMUL: case iIMUL: case iMOD:
|
||||
if (inst.testFlags(I))
|
||||
{
|
||||
strDst(out,insn->getFlag(), insn->m_dst);
|
||||
out->prtt(", ");
|
||||
formatRM(out, inst.src());
|
||||
strSrc(out,insn);
|
||||
}
|
||||
else
|
||||
strDst(out,insn->getFlag() | I, insn->m_dst);
|
||||
break;
|
||||
case iLDS: case iLES: case iBOUND:
|
||||
strDst(out,inst.getFlag(), inst.m_dst);
|
||||
out->prtt(", ");
|
||||
out->addTaggedString(XT_Keyword,"dword ptr");
|
||||
strSrc(out,insn,true);
|
||||
break;
|
||||
case iJB: case iJBE: case iJAE: case iJA:
|
||||
case iJL: case iJLE: case iJGE: case iJG:
|
||||
case iJE: case iJNE: case iJS: case iJNS:
|
||||
case iJO: case iJNO: case iJP: case iJNP:
|
||||
case iJCXZ:case iLOOP: case iLOOPE:case iLOOPNE:
|
||||
case iJMP: case iJMPF:
|
||||
|
||||
/* Check if there is a symbol here */
|
||||
{
|
||||
// ICODE *lab=pc.GetIcode(inst.src().getImm2());
|
||||
// selectTable(Label);
|
||||
// if ((inst.src().getImm2() < (uint32_t)numIcode) and /* Ensure in range */
|
||||
// readVal(operands_s, lab->ll()->label, nullptr))
|
||||
// {
|
||||
// break; /* Symbolic label. Done */
|
||||
// }
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
out->addEOL();
|
||||
}
|
||||
|
||||
@ -9,6 +9,14 @@ FunctionViewWidget::FunctionViewWidget(QWidget *parent) :
|
||||
ui(new Ui::FunctionViewWidget)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
m_current_rendering = new QTextDocument(ui->textEdit);
|
||||
m_doc_cursor = new QTextCursor(m_current_rendering);
|
||||
ui->textEdit->setTextBackgroundColor(Qt::black);
|
||||
m_current_format = m_doc_cursor->blockFormat();
|
||||
m_current_format.setNonBreakableLines(true); // each block is single line
|
||||
m_current_format.setBackground(Qt::black);
|
||||
m_chars_format.setBackground(Qt::black);
|
||||
m_chars_format.setForeground(Qt::white);
|
||||
//ui->label->setTextFormat(Qt::RichText);
|
||||
}
|
||||
|
||||
@ -19,21 +27,33 @@ FunctionViewWidget::~FunctionViewWidget()
|
||||
|
||||
void FunctionViewWidget::prtt(const char *s)
|
||||
{
|
||||
m_doc_cursor->insertText(s);
|
||||
collected_text+=s;
|
||||
//collected_text+="<br>";
|
||||
}
|
||||
void FunctionViewWidget::prtt(const QString &s)
|
||||
{
|
||||
m_doc_cursor->insertText(s);
|
||||
collected_text+=s;
|
||||
//collected_text+="<br>";
|
||||
}
|
||||
|
||||
void FunctionViewWidget::addEOL()
|
||||
{
|
||||
m_doc_cursor->insertBlock(m_current_format);
|
||||
m_doc_cursor->setBlockFormat(m_current_format);
|
||||
}
|
||||
void FunctionViewWidget::TAGbegin(TAG_TYPE tag_type, void *p)
|
||||
{
|
||||
QColor col= RenderTag_2_Color(tag_type);
|
||||
|
||||
switch(tag_type)
|
||||
{
|
||||
case XT_Function:
|
||||
collected_text+="<body style='color: #FFFFFF; background-color: #000000'>";
|
||||
m_current_rendering->clear();
|
||||
m_chars_format.setForeground(Qt::white);
|
||||
m_doc_cursor->setBlockFormat(m_current_format);
|
||||
m_doc_cursor->setCharFormat(m_chars_format);
|
||||
break;
|
||||
case XT_FuncName:
|
||||
case XT_Symbol:
|
||||
@ -42,7 +62,8 @@ void FunctionViewWidget::TAGbegin(TAG_TYPE tag_type, void *p)
|
||||
case XT_Number:
|
||||
case XT_AsmOffset:
|
||||
case XT_AsmLabel:
|
||||
collected_text+="<font color='"+col.name()+"'>";
|
||||
m_chars_format.setForeground(col);
|
||||
m_doc_cursor->setCharFormat(m_chars_format);
|
||||
break;
|
||||
default:
|
||||
qDebug()<<"Tag type:"<<tag_type;
|
||||
@ -56,13 +77,11 @@ void FunctionViewWidget::TAGend(TAG_TYPE tag_type)
|
||||
{
|
||||
collected_text+="</body>";
|
||||
// TODO: What about attributes with spaces?
|
||||
collected_text.replace(" ", " ");
|
||||
QFile res("result.html");
|
||||
res.open(QFile::WriteOnly);
|
||||
res.write(collected_text.toUtf8());
|
||||
res.write(m_current_rendering->toHtml().toUtf8());
|
||||
res.close();
|
||||
collected_text.replace(QChar('\n'),"<br>");
|
||||
ui->textEdit->setHtml(collected_text);
|
||||
ui->textEdit->setDocument(m_current_rendering);
|
||||
collected_text.clear();
|
||||
break;
|
||||
}
|
||||
@ -73,7 +92,9 @@ void FunctionViewWidget::TAGend(TAG_TYPE tag_type)
|
||||
case XT_Number:
|
||||
case XT_AsmOffset:
|
||||
case XT_AsmLabel:
|
||||
collected_text+="</font>";
|
||||
m_chars_format.setForeground(Qt::white);
|
||||
m_doc_cursor->setCharFormat(m_chars_format);
|
||||
m_doc_cursor->setBlockFormat(m_current_format);
|
||||
break;
|
||||
default:
|
||||
qDebug()<<"Tag end:"<<tag_type;
|
||||
|
||||
@ -1,9 +1,12 @@
|
||||
#ifndef FUNCTIONVIEWWIDGET_H
|
||||
#define FUNCTIONVIEWWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
#include "StructuredTextTarget.h"
|
||||
#include "RenderTags.h"
|
||||
|
||||
#include <QWidget>
|
||||
#include <QTextDocument>
|
||||
#include <QTextBlockFormat>
|
||||
//#include "XmlPrt.h"
|
||||
namespace Ui {
|
||||
class FunctionViewWidget;
|
||||
@ -11,12 +14,16 @@ class FunctionViewWidget;
|
||||
class FunctionViewWidget : public QWidget,public IStructuredTextTarget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
QTextDocument *m_current_rendering;
|
||||
QTextCursor* m_doc_cursor;
|
||||
QTextBlockFormat m_current_format;
|
||||
QTextCharFormat m_chars_format;
|
||||
public:
|
||||
explicit FunctionViewWidget(QWidget *parent = 0);
|
||||
~FunctionViewWidget();
|
||||
void prtt(const char * s);
|
||||
void prtt(const QString &s);
|
||||
void addEOL() override;
|
||||
void TAGbegin(enum TAG_TYPE tag_type, void * p);
|
||||
void TAGend(enum TAG_TYPE tag_type);
|
||||
private:
|
||||
|
||||
@ -16,9 +16,22 @@
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QTextEdit" name="textEdit">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="undoRedoEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="lineWrapMode">
|
||||
<enum>QTextEdit::NoWrap</enum>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="html">
|
||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'Corbel'; font-size:10pt; font-weight:400; font-style:normal;" bgcolor="#000000">
|
||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
||||
@ -7,10 +7,7 @@ public:
|
||||
virtual void TAGend(TAG_TYPE t)=0;
|
||||
virtual void prtt(const QString &v)=0;
|
||||
|
||||
virtual void addEOL() // some targets might want to disable newlines
|
||||
{
|
||||
prtt("\n");
|
||||
}
|
||||
virtual void addEOL() = 0; // some targets might want to disable newlines
|
||||
void addSpace(int n=1) {
|
||||
while(n--)
|
||||
prtt(" ");
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user