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));
|
out->prtt(QString(" gap len = %1h").arg(maxlevel - curlevel,0,16));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static void toStructuredText(LLInst *insn,IStructuredTextTarget *out, int level) {
|
extern void toStructuredText(LLInst *insn,IStructuredTextTarget *out, int level);
|
||||||
out->prtt("LLINST");
|
|
||||||
out->addEOL();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static void toStructuredText(ICODE &stk,IStructuredTextTarget *out, int level) {
|
static void toStructuredText(ICODE &stk,IStructuredTextTarget *out, int level) {
|
||||||
if(level==0) {
|
if(level==0) {
|
||||||
|
|||||||
583
src/disassem.cpp
583
src/disassem.cpp
@ -18,6 +18,7 @@
|
|||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include "src/ui/StructuredTextTarget.h"
|
||||||
|
|
||||||
// Note: for the time being, there is no interactive disassembler
|
// Note: for the time being, there is no interactive disassembler
|
||||||
// for unix
|
// for unix
|
||||||
@ -298,190 +299,190 @@ void Disassembler::dis1Line(LLInst &inst,int loc_ip, int pass)
|
|||||||
|
|
||||||
switch ( inst.getOpcode() )
|
switch ( inst.getOpcode() )
|
||||||
{
|
{
|
||||||
case iADD: case iADC: case iSUB: case iSBB: case iAND: case iOR:
|
case iADD: case iADC: case iSUB: case iSBB: case iAND: case iOR:
|
||||||
case iXOR: case iTEST: case iCMP: case iMOV: case iLEA: case iXCHG:
|
case iXOR: case iTEST: case iCMP: case iMOV: case iLEA: case iXCHG:
|
||||||
strDst(operands_s,inst.getFlag(), inst.m_dst);
|
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);
|
inst.strSrc(operands_s);
|
||||||
break;
|
else
|
||||||
|
operands_s<<", cl";
|
||||||
|
break;
|
||||||
|
|
||||||
case iESC:
|
case iINC: case iDEC: case iNEG: case iNOT: case iPOP:
|
||||||
inst.flops(operands_s);
|
strDst(operands_s,inst.getFlag() | I, inst.m_dst);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case iSAR: case iSHL: case iSHR: case iRCL: case iRCR: case iROL:
|
case iPUSH:
|
||||||
case iROR:
|
if (inst.testFlags(I))
|
||||||
|
{
|
||||||
|
operands_s<<strHex(inst.src().getImm2());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
strDst(operands_s,inst.getFlag() | I, inst.m_dst);
|
strDst(operands_s,inst.getFlag() | I, inst.m_dst);
|
||||||
if(inst.testFlags(I))
|
}
|
||||||
inst.strSrc(operands_s);
|
break;
|
||||||
else
|
|
||||||
operands_s<<", cl";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case iINC: case iDEC: case iNEG: case iNOT: case iPOP:
|
case iDIV: case iIDIV: case iMUL: case iIMUL: case iMOD:
|
||||||
strDst(operands_s,inst.getFlag() | I, inst.m_dst);
|
if (inst.testFlags(I))
|
||||||
break;
|
{
|
||||||
|
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:
|
case iLDS: case iLES: case iBOUND:
|
||||||
if (inst.testFlags(I))
|
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;
|
operands_s<<"L"<<pl[j];
|
||||||
|
}
|
||||||
case iDIV: case iIDIV: case iMUL: case iIMUL: case iMOD:
|
else if (inst.getOpcode() == iJMPF)
|
||||||
if (inst.testFlags(I))
|
{
|
||||||
{
|
operands_s<<"dword ptr";
|
||||||
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";
|
|
||||||
inst.strSrc(operands_s,true);
|
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 */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
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:
|
|
||||||
{
|
{
|
||||||
QString d1=((inst.testFlags(I))? strHex(inst.src().getImm2()): "dx");
|
strDst(operands_s,I, inst.src());
|
||||||
QString d2=((inst.getFlag() & B) ? ", al": ", ax");
|
|
||||||
operands_s<<d1 << d2;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
case iCALL: case iCALLF:
|
||||||
break;
|
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);
|
oper_stream.setFieldWidth(15);
|
||||||
operands_s.flush();
|
operands_s.flush();
|
||||||
@ -690,29 +691,29 @@ void LLInst::flops(QTextStream &out)
|
|||||||
}
|
}
|
||||||
else switch (op & 0x30)
|
else switch (op & 0x30)
|
||||||
{
|
{
|
||||||
case 0x00:
|
case 0x00:
|
||||||
case 0x10:
|
case 0x10:
|
||||||
out << "dword ptr ";
|
out << "dword ptr ";
|
||||||
|
break;
|
||||||
|
case 0x20:
|
||||||
|
out << "qword ptr ";
|
||||||
|
break;
|
||||||
|
case 0x30:
|
||||||
|
switch (op)
|
||||||
|
{
|
||||||
|
case 0x3C: /* FBLD */
|
||||||
|
case 0x3E: /* FBSTP */
|
||||||
|
out << "tbyte ptr ";
|
||||||
break;
|
break;
|
||||||
case 0x20:
|
case 0x3D: /* FILD 64 bit */
|
||||||
|
case 0x3F: /* FISTP 64 bit */
|
||||||
out << "qword ptr ";
|
out << "qword ptr ";
|
||||||
break;
|
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:
|
default:
|
||||||
out << "uint16_t ptr ";
|
out << "uint16_t ptr ";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out.setFieldWidth(0);
|
out.setFieldWidth(0);
|
||||||
formatRM(out, m_dst);
|
formatRM(out, m_dst);
|
||||||
@ -727,46 +728,178 @@ void LLInst::flops(QTextStream &out)
|
|||||||
int destRegIdx=m_dst.regi - rAX;
|
int destRegIdx=m_dst.regi - rAX;
|
||||||
switch (op)
|
switch (op)
|
||||||
{
|
{
|
||||||
case 0x0C:
|
case 0x0C:
|
||||||
out << szFlops0C[destRegIdx];
|
out << szFlops0C[destRegIdx];
|
||||||
break;
|
break;
|
||||||
case 0x0D:
|
case 0x0D:
|
||||||
out << szFlops0D[destRegIdx];
|
out << szFlops0D[destRegIdx];
|
||||||
break;
|
break;
|
||||||
case 0x0E:
|
case 0x0E:
|
||||||
out << szFlops0E[destRegIdx];
|
out << szFlops0E[destRegIdx];
|
||||||
break;
|
break;
|
||||||
case 0x0F:
|
case 0x0F:
|
||||||
out << szFlops0F[destRegIdx];
|
out << szFlops0F[destRegIdx];
|
||||||
break;
|
break;
|
||||||
case 0x15:
|
case 0x15:
|
||||||
out << szFlops15[destRegIdx];
|
out << szFlops15[destRegIdx];
|
||||||
break;
|
break;
|
||||||
case 0x1C:
|
case 0x1C:
|
||||||
out << szFlops1C[destRegIdx];
|
out << szFlops1C[destRegIdx];
|
||||||
break;
|
break;
|
||||||
case 0x33:
|
case 0x33:
|
||||||
out << szFlops33[destRegIdx];
|
out << szFlops33[destRegIdx];
|
||||||
break;
|
break;
|
||||||
case 0x3C:
|
case 0x3C:
|
||||||
out << szFlops3C[destRegIdx];
|
out << szFlops3C[destRegIdx];
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
out << Machine_X86::floatOpName(0x40+op);
|
out << Machine_X86::floatOpName(0x40+op);
|
||||||
if ((op >= 0x20) and (op <= 0x27))
|
if ((op >= 0x20) and (op <= 0x27))
|
||||||
{
|
{
|
||||||
/* This is the ST(i), ST form. */
|
/* This is the ST(i), ST form. */
|
||||||
out << "ST("<<destRegIdx - rAX<<"),ST";
|
out << "ST("<<destRegIdx - rAX<<"),ST";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* ST, ST(i) */
|
/* ST, ST(i) */
|
||||||
out << "ST,ST("<<destRegIdx;
|
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(new Ui::FunctionViewWidget)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
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);
|
//ui->label->setTextFormat(Qt::RichText);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -19,21 +27,33 @@ FunctionViewWidget::~FunctionViewWidget()
|
|||||||
|
|
||||||
void FunctionViewWidget::prtt(const char *s)
|
void FunctionViewWidget::prtt(const char *s)
|
||||||
{
|
{
|
||||||
|
m_doc_cursor->insertText(s);
|
||||||
collected_text+=s;
|
collected_text+=s;
|
||||||
//collected_text+="<br>";
|
//collected_text+="<br>";
|
||||||
}
|
}
|
||||||
void FunctionViewWidget::prtt(const QString &s)
|
void FunctionViewWidget::prtt(const QString &s)
|
||||||
{
|
{
|
||||||
|
m_doc_cursor->insertText(s);
|
||||||
collected_text+=s;
|
collected_text+=s;
|
||||||
//collected_text+="<br>";
|
//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)
|
void FunctionViewWidget::TAGbegin(TAG_TYPE tag_type, void *p)
|
||||||
{
|
{
|
||||||
QColor col= RenderTag_2_Color(tag_type);
|
QColor col= RenderTag_2_Color(tag_type);
|
||||||
|
|
||||||
switch(tag_type)
|
switch(tag_type)
|
||||||
{
|
{
|
||||||
case XT_Function:
|
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;
|
break;
|
||||||
case XT_FuncName:
|
case XT_FuncName:
|
||||||
case XT_Symbol:
|
case XT_Symbol:
|
||||||
@ -42,7 +62,8 @@ void FunctionViewWidget::TAGbegin(TAG_TYPE tag_type, void *p)
|
|||||||
case XT_Number:
|
case XT_Number:
|
||||||
case XT_AsmOffset:
|
case XT_AsmOffset:
|
||||||
case XT_AsmLabel:
|
case XT_AsmLabel:
|
||||||
collected_text+="<font color='"+col.name()+"'>";
|
m_chars_format.setForeground(col);
|
||||||
|
m_doc_cursor->setCharFormat(m_chars_format);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
qDebug()<<"Tag type:"<<tag_type;
|
qDebug()<<"Tag type:"<<tag_type;
|
||||||
@ -56,13 +77,11 @@ void FunctionViewWidget::TAGend(TAG_TYPE tag_type)
|
|||||||
{
|
{
|
||||||
collected_text+="</body>";
|
collected_text+="</body>";
|
||||||
// TODO: What about attributes with spaces?
|
// TODO: What about attributes with spaces?
|
||||||
collected_text.replace(" ", " ");
|
|
||||||
QFile res("result.html");
|
QFile res("result.html");
|
||||||
res.open(QFile::WriteOnly);
|
res.open(QFile::WriteOnly);
|
||||||
res.write(collected_text.toUtf8());
|
res.write(m_current_rendering->toHtml().toUtf8());
|
||||||
res.close();
|
res.close();
|
||||||
collected_text.replace(QChar('\n'),"<br>");
|
ui->textEdit->setDocument(m_current_rendering);
|
||||||
ui->textEdit->setHtml(collected_text);
|
|
||||||
collected_text.clear();
|
collected_text.clear();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -73,7 +92,9 @@ void FunctionViewWidget::TAGend(TAG_TYPE tag_type)
|
|||||||
case XT_Number:
|
case XT_Number:
|
||||||
case XT_AsmOffset:
|
case XT_AsmOffset:
|
||||||
case XT_AsmLabel:
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
qDebug()<<"Tag end:"<<tag_type;
|
qDebug()<<"Tag end:"<<tag_type;
|
||||||
|
|||||||
@ -1,9 +1,12 @@
|
|||||||
#ifndef FUNCTIONVIEWWIDGET_H
|
#ifndef FUNCTIONVIEWWIDGET_H
|
||||||
#define FUNCTIONVIEWWIDGET_H
|
#define FUNCTIONVIEWWIDGET_H
|
||||||
|
|
||||||
#include <QWidget>
|
|
||||||
#include "StructuredTextTarget.h"
|
#include "StructuredTextTarget.h"
|
||||||
#include "RenderTags.h"
|
#include "RenderTags.h"
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QTextDocument>
|
||||||
|
#include <QTextBlockFormat>
|
||||||
//#include "XmlPrt.h"
|
//#include "XmlPrt.h"
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class FunctionViewWidget;
|
class FunctionViewWidget;
|
||||||
@ -11,12 +14,16 @@ class FunctionViewWidget;
|
|||||||
class FunctionViewWidget : public QWidget,public IStructuredTextTarget
|
class FunctionViewWidget : public QWidget,public IStructuredTextTarget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
QTextDocument *m_current_rendering;
|
||||||
|
QTextCursor* m_doc_cursor;
|
||||||
|
QTextBlockFormat m_current_format;
|
||||||
|
QTextCharFormat m_chars_format;
|
||||||
public:
|
public:
|
||||||
explicit FunctionViewWidget(QWidget *parent = 0);
|
explicit FunctionViewWidget(QWidget *parent = 0);
|
||||||
~FunctionViewWidget();
|
~FunctionViewWidget();
|
||||||
void prtt(const char * s);
|
void prtt(const char * s);
|
||||||
void prtt(const QString &s);
|
void prtt(const QString &s);
|
||||||
|
void addEOL() override;
|
||||||
void TAGbegin(enum TAG_TYPE tag_type, void * p);
|
void TAGbegin(enum TAG_TYPE tag_type, void * p);
|
||||||
void TAGend(enum TAG_TYPE tag_type);
|
void TAGend(enum TAG_TYPE tag_type);
|
||||||
private:
|
private:
|
||||||
|
|||||||
@ -16,9 +16,22 @@
|
|||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QTextEdit" name="textEdit">
|
<widget class="QTextEdit" name="textEdit">
|
||||||
<property name="readOnly">
|
<property name="undoRedoEnabled">
|
||||||
<bool>true</bool>
|
<bool>false</bool>
|
||||||
</property>
|
</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>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
|||||||
@ -7,10 +7,7 @@ public:
|
|||||||
virtual void TAGend(TAG_TYPE t)=0;
|
virtual void TAGend(TAG_TYPE t)=0;
|
||||||
virtual void prtt(const QString &v)=0;
|
virtual void prtt(const QString &v)=0;
|
||||||
|
|
||||||
virtual void addEOL() // some targets might want to disable newlines
|
virtual void addEOL() = 0; // some targets might want to disable newlines
|
||||||
{
|
|
||||||
prtt("\n");
|
|
||||||
}
|
|
||||||
void addSpace(int n=1) {
|
void addSpace(int n=1) {
|
||||||
while(n--)
|
while(n--)
|
||||||
prtt(" ");
|
prtt(" ");
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user