From 4cc3b41e64996801581a62dfbde86ae7c9ead481 Mon Sep 17 00:00:00 2001 From: nemerle Date: Thu, 5 May 2016 16:06:06 +0200 Subject: [PATCH] Use QTextDocument instead of html to build text display Continued work on rendering disassembly level text. --- src/Procedure.cpp | 6 +- src/disassem.cpp | 583 +++++++++++++++++++++------------- src/ui/FunctionViewWidget.cpp | 35 +- src/ui/FunctionViewWidget.h | 11 +- src/ui/FunctionViewWidget.ui | 19 +- src/ui/StructuredTextTarget.h | 5 +- 6 files changed, 413 insertions(+), 246 deletions(-) diff --git a/src/Procedure.cpp b/src/Procedure.cpp index 03967d0..3e6fce2 100644 --- a/src/Procedure.cpp +++ b/src/Procedure.cpp @@ -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) { diff --git a/src/disassem.cpp b/src/disassem.cpp index e5aa49e..87326d2 100644 --- a/src/disassem.cpp +++ b/src/disassem.cpp @@ -18,6 +18,7 @@ #include #include #include +#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<ll()->label, nullptr)) + { + break; /* Symbolic label. Done */ + } + } + + if (inst.testFlags(NO_LABEL)) + { + //strcpy(p + WID_PTR, strHex(pIcode->ll()->immed.op)); + operands_s<ll()->label, nullptr)) - { - break; /* Symbolic label. Done */ - } } - - if (inst.testFlags(NO_LABEL)) - { - //strcpy(p + WID_PTR, strHex(pIcode->ll()->immed.op)); - operands_s<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<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<= 0x20) and (op <= 0x27)) - { - /* This is the ST(i), ST form. */ - out << "ST("<= 0x20) and (op <= 0x27)) + { + /* This is the ST(i), ST form. */ + out << "ST("<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(); +} diff --git a/src/ui/FunctionViewWidget.cpp b/src/ui/FunctionViewWidget.cpp index 5b3d027..5bb65ef 100644 --- a/src/ui/FunctionViewWidget.cpp +++ b/src/ui/FunctionViewWidget.cpp @@ -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+="
"; } void FunctionViewWidget::prtt(const QString &s) { + m_doc_cursor->insertText(s); collected_text+=s; //collected_text+="
"; } + +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+=""; + 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+=""; + m_chars_format.setForeground(col); + m_doc_cursor->setCharFormat(m_chars_format); break; default: qDebug()<<"Tag type:"<toHtml().toUtf8()); res.close(); - collected_text.replace(QChar('\n'),"
"); - 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+="
"; + 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:"< #include "StructuredTextTarget.h" #include "RenderTags.h" + +#include +#include +#include //#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: diff --git a/src/ui/FunctionViewWidget.ui b/src/ui/FunctionViewWidget.ui index 8b44818..ae685ea 100644 --- a/src/ui/FunctionViewWidget.ui +++ b/src/ui/FunctionViewWidget.ui @@ -16,9 +16,22 @@ - - true - + + false + + + QTextEdit::NoWrap + + + true + + + <!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> + diff --git a/src/ui/StructuredTextTarget.h b/src/ui/StructuredTextTarget.h index 93a4108..c80243b 100644 --- a/src/ui/StructuredTextTarget.h +++ b/src/ui/StructuredTextTarget.h @@ -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(" ");