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) {
|
||||||
|
|||||||
133
src/disassem.cpp
133
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
|
||||||
@ -768,5 +769,137 @@ void LLInst::flops(QTextStream &out)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/****************************************************************************
|
||||||
|
* 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="undoRedoEnabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="lineWrapMode">
|
||||||
|
<enum>QTextEdit::NoWrap</enum>
|
||||||
|
</property>
|
||||||
<property name="readOnly">
|
<property name="readOnly">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</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