Refactor AbstractTableView for cross-platform
This commit is contained in:
parent
663bfbbb06
commit
7733012330
|
@ -176,7 +176,10 @@ extern "C"
|
||||||
#define MAX_SECTION_SIZE 10
|
#define MAX_SECTION_SIZE 10
|
||||||
#define MAX_COMMAND_LINE_SIZE 256
|
#define MAX_COMMAND_LINE_SIZE 256
|
||||||
#define MAX_MNEMONIC_SIZE 64
|
#define MAX_MNEMONIC_SIZE 64
|
||||||
|
|
||||||
|
#ifndef PAGE_SIZE
|
||||||
#define PAGE_SIZE 0x1000
|
#define PAGE_SIZE 0x1000
|
||||||
|
#endif // PAGE_SIZE
|
||||||
|
|
||||||
//Debugger enums
|
//Debugger enums
|
||||||
typedef enum
|
typedef enum
|
||||||
|
|
|
@ -19,11 +19,11 @@ public:
|
||||||
virtual void unlock() = 0;
|
virtual void unlock() = 0;
|
||||||
virtual AbstractStdTable* list() const = 0;
|
virtual AbstractStdTable* list() const = 0;
|
||||||
virtual AbstractStdTable* searchList() const = 0;
|
virtual AbstractStdTable* searchList() const = 0;
|
||||||
virtual void filter(const QString & filter, FilterType type, int startColumn) = 0;
|
virtual void filter(const QString & filter, FilterType type, duint startColumn) = 0;
|
||||||
|
|
||||||
bool rowMatchesFilter(const QString & filter, FilterType type, int row, int startColumn) const
|
bool rowMatchesFilter(const QString & filter, FilterType type, duint row, duint startColumn) const
|
||||||
{
|
{
|
||||||
int count = list()->getColumnCount();
|
auto count = list()->getColumnCount();
|
||||||
if(startColumn + 1 > count)
|
if(startColumn + 1 > count)
|
||||||
return false;
|
return false;
|
||||||
auto cs = Qt::CaseInsensitive;
|
auto cs = Qt::CaseInsensitive;
|
||||||
|
@ -32,21 +32,21 @@ public:
|
||||||
case FilterStartsWithTextCaseSensitive:
|
case FilterStartsWithTextCaseSensitive:
|
||||||
cs = Qt::CaseSensitive;
|
cs = Qt::CaseSensitive;
|
||||||
case FilterStartsWithTextCaseInsensitive:
|
case FilterStartsWithTextCaseInsensitive:
|
||||||
for(int i = startColumn; i < count; i++)
|
for(duint i = startColumn; i < count; i++)
|
||||||
if(list()->getCellContent(row, i).startsWith(filter, cs))
|
if(list()->getCellContent(row, i).startsWith(filter, cs))
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
case FilterContainsTextCaseSensitive:
|
case FilterContainsTextCaseSensitive:
|
||||||
cs = Qt::CaseSensitive;
|
cs = Qt::CaseSensitive;
|
||||||
case FilterContainsTextCaseInsensitive:
|
case FilterContainsTextCaseInsensitive:
|
||||||
for(int i = startColumn; i < count; i++)
|
for(duint i = startColumn; i < count; i++)
|
||||||
if(list()->getCellContent(row, i).contains(filter, cs))
|
if(list()->getCellContent(row, i).contains(filter, cs))
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
case FilterRegexCaseSensitive:
|
case FilterRegexCaseSensitive:
|
||||||
cs = Qt::CaseSensitive;
|
cs = Qt::CaseSensitive;
|
||||||
case FilterRegexCaseInsensitive:
|
case FilterRegexCaseInsensitive:
|
||||||
for(int i = startColumn; i < count; i++)
|
for(duint i = startColumn; i < count; i++)
|
||||||
if(list()->getCellContent(row, i).contains(QRegExp(filter, cs)))
|
if(list()->getCellContent(row, i).contains(QRegExp(filter, cs)))
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -811,10 +811,10 @@ QString AbstractStdTable::copyTable(const std::vector<int> & colWidths)
|
||||||
finalText += getColTitle(i);
|
finalText += getColTitle(i);
|
||||||
}
|
}
|
||||||
finalText += "\r\n";
|
finalText += "\r\n";
|
||||||
for(int i = 0; i < rowCount; i++)
|
for(duint i = 0; i < rowCount; i++)
|
||||||
{
|
{
|
||||||
QString finalRowText = "";
|
QString finalRowText = "";
|
||||||
for(int j = 0; j < colCount; j++)
|
for(duint j = 0; j < colCount; j++)
|
||||||
{
|
{
|
||||||
if(j)
|
if(j)
|
||||||
finalRowText += " ";
|
finalRowText += " ";
|
||||||
|
@ -857,7 +857,7 @@ void AbstractStdTable::copyTableResizeSlot()
|
||||||
for(duint i = 0; i < colCount; i++)
|
for(duint i = 0; i < colCount; i++)
|
||||||
{
|
{
|
||||||
auto max = getCellContent(0, i).length();
|
auto max = getCellContent(0, i).length();
|
||||||
for(int j = 1; j < rowCount; j++)
|
for(duint j = 1; j < rowCount; j++)
|
||||||
max = std::max(getCellContent(j, i).length(), max);
|
max = std::max(getCellContent(j, i).length(), max);
|
||||||
colWidths.push_back(max);
|
colWidths.push_back(max);
|
||||||
}
|
}
|
||||||
|
@ -894,7 +894,7 @@ void AbstractStdTable::exportTableSlot()
|
||||||
{
|
{
|
||||||
std::vector<QString> headers;
|
std::vector<QString> headers;
|
||||||
headers.reserve(getColumnCount());
|
headers.reserve(getColumnCount());
|
||||||
for(int i = 0; i < getColumnCount(); i++)
|
for(duint i = 0; i < getColumnCount(); i++)
|
||||||
headers.push_back(getColTitle(i));
|
headers.push_back(getColTitle(i));
|
||||||
ExportCSV(getRowCount(), getColumnCount(), headers, [this](duint row, duint column)
|
ExportCSV(getRowCount(), getColumnCount(), headers, [this](duint row, duint column)
|
||||||
{
|
{
|
||||||
|
@ -975,7 +975,7 @@ void AbstractStdTable::setupCopyColumnMenu(MenuBuilder* copyMenu)
|
||||||
{
|
{
|
||||||
copyMenu->addBuilder(new MenuBuilder(this, [this](QMenu * menu)
|
copyMenu->addBuilder(new MenuBuilder(this, [this](QMenu * menu)
|
||||||
{
|
{
|
||||||
for(int i = 0; i < getColumnCount(); i++)
|
for(duint i = 0; i < getColumnCount(); i++)
|
||||||
{
|
{
|
||||||
if(!getCellContent(getInitialSelection(), i).length()) //skip empty cells
|
if(!getCellContent(getInitialSelection(), i).length()) //skip empty cells
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -132,7 +132,7 @@ void AbstractTableView::updateShortcutsSlot()
|
||||||
void AbstractTableView::loadColumnFromConfig(const QString & viewName)
|
void AbstractTableView::loadColumnFromConfig(const QString & viewName)
|
||||||
{
|
{
|
||||||
duint columnCount = getColumnCount();
|
duint columnCount = getColumnCount();
|
||||||
for(int i = 0; i < columnCount; i++)
|
for(duint i = 0; i < columnCount; i++)
|
||||||
{
|
{
|
||||||
duint width = ConfigUint("Gui", QString("%1ColumnWidth%2").arg(viewName).arg(i).toUtf8().constData());
|
duint width = ConfigUint("Gui", QString("%1ColumnWidth%2").arg(viewName).arg(i).toUtf8().constData());
|
||||||
duint hidden = ConfigUint("Gui", QString("%1ColumnHidden%2").arg(viewName).arg(i).toUtf8().constData());
|
duint hidden = ConfigUint("Gui", QString("%1ColumnHidden%2").arg(viewName).arg(i).toUtf8().constData());
|
||||||
|
@ -224,7 +224,7 @@ void AbstractTableView::paintEvent(QPaintEvent* event)
|
||||||
QPen separatorPen(mSeparatorColor, 2);
|
QPen separatorPen(mSeparatorColor, 2);
|
||||||
QBrush backgroundBrush(mHeaderBackgroundColor);
|
QBrush backgroundBrush(mHeaderBackgroundColor);
|
||||||
|
|
||||||
for(int j = 0; j < getColumnCount(); j++)
|
for(duint j = 0; j < getColumnCount(); j++)
|
||||||
{
|
{
|
||||||
int i = mColumnOrder[j];
|
int i = mColumnOrder[j];
|
||||||
if(getColumnHidden(i))
|
if(getColumnHidden(i))
|
||||||
|
@ -267,7 +267,7 @@ void AbstractTableView::paintEvent(QPaintEvent* event)
|
||||||
int y = getHeaderHeight();
|
int y = getHeaderHeight();
|
||||||
|
|
||||||
// Iterate over all columns and cells
|
// Iterate over all columns and cells
|
||||||
for(int k = 0; k < getColumnCount(); k++)
|
for(duint k = 0; k < getColumnCount(); k++)
|
||||||
{
|
{
|
||||||
int j = mColumnOrder[k];
|
int j = mColumnOrder[k];
|
||||||
if(getColumnHidden(j))
|
if(getColumnHidden(j))
|
||||||
|
@ -322,8 +322,8 @@ void AbstractTableView::mouseMoveEvent(QMouseEvent* event)
|
||||||
{
|
{
|
||||||
if(getColumnCount() <= 1)
|
if(getColumnCount() <= 1)
|
||||||
return;
|
return;
|
||||||
int colIndex = getColumnIndexFromX(event->x());
|
auto colIndex = getColumnIndexFromX(event->x());
|
||||||
int displayIndex = getColumnDisplayIndexFromX(event->x());
|
auto displayIndex = getColumnDisplayIndexFromX(event->x());
|
||||||
int startPos = getColumnPosition(displayIndex); // Position X of the start of column
|
int startPos = getColumnPosition(displayIndex); // Position X of the start of column
|
||||||
int endPos = startPos + getColumnWidth(colIndex); // Position X of the end of column
|
int endPos = startPos + getColumnWidth(colIndex); // Position X of the end of column
|
||||||
bool onHandle = ((colIndex != 0) && (event->x() >= startPos) && (event->x() <= (startPos + 2))) || ((event->x() <= endPos) && (event->x() >= (endPos - 2)));
|
bool onHandle = ((colIndex != 0) && (event->x() >= startPos) && (event->x() <= (startPos + 2))) || ((event->x() <= endPos) && (event->x() >= (endPos - 2)));
|
||||||
|
@ -384,7 +384,7 @@ void AbstractTableView::mouseMoveEvent(QMouseEvent* event)
|
||||||
|
|
||||||
case AbstractTableView::HeaderButtonPressed:
|
case AbstractTableView::HeaderButtonPressed:
|
||||||
{
|
{
|
||||||
int colIndex = getColumnIndexFromX(event->x());
|
auto colIndex = getColumnIndexFromX(event->x());
|
||||||
|
|
||||||
if(colIndex == mHeader.activeButtonIndex)
|
if(colIndex == mHeader.activeButtonIndex)
|
||||||
{
|
{
|
||||||
|
@ -447,7 +447,7 @@ void AbstractTableView::mousePressEvent(QMouseEvent* event)
|
||||||
{
|
{
|
||||||
mReorderStartX = event->x();
|
mReorderStartX = event->x();
|
||||||
|
|
||||||
int colIndex = getColumnIndexFromX(event->x());
|
auto colIndex = getColumnIndexFromX(event->x());
|
||||||
if(mColumnList[colIndex].header.isClickable)
|
if(mColumnList[colIndex].header.isClickable)
|
||||||
{
|
{
|
||||||
//qDebug() << "Button " << colIndex << "has been pressed.";
|
//qDebug() << "Button " << colIndex << "has been pressed.";
|
||||||
|
@ -515,7 +515,7 @@ void AbstractTableView::mouseReleaseEvent(QMouseEvent* event)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Release all buttons
|
// Release all buttons
|
||||||
for(int i = 0; i < getColumnCount(); i++)
|
for(duint i = 0; i < getColumnCount(); i++)
|
||||||
{
|
{
|
||||||
mColumnList[i].header.isPressed = false;
|
mColumnList[i].header.isPressed = false;
|
||||||
}
|
}
|
||||||
|
@ -904,7 +904,7 @@ void AbstractTableView::updateScrollBarRange(duint range)
|
||||||
{
|
{
|
||||||
// Count leading zeros
|
// Count leading zeros
|
||||||
int leadingZeroCount = 0;
|
int leadingZeroCount = 0;
|
||||||
for(duint mask = 0x8000000000000000; mask != 0; mask >>= 1)
|
for(uint64_t mask = 0x8000000000000000; mask != 0; mask >>= 1)
|
||||||
{
|
{
|
||||||
if((maxTableOffset & mask) != 0)
|
if((maxTableOffset & mask) != 0)
|
||||||
{
|
{
|
||||||
|
@ -954,28 +954,23 @@ dsint AbstractTableView::getIndexOffsetFromY(int y) const
|
||||||
duint AbstractTableView::getColumnIndexFromX(int x) const
|
duint AbstractTableView::getColumnIndexFromX(int x) const
|
||||||
{
|
{
|
||||||
int scrollX = -horizontalScrollBar()->value();
|
int scrollX = -horizontalScrollBar()->value();
|
||||||
duint colIndex = 0;
|
|
||||||
|
|
||||||
while(colIndex < getColumnCount())
|
for(duint colIndex = 0; colIndex < getColumnCount(); colIndex++)
|
||||||
{
|
{
|
||||||
auto col = mColumnOrder[colIndex];
|
auto col = mColumnOrder[colIndex];
|
||||||
if(getColumnHidden(col))
|
if(getColumnHidden(col))
|
||||||
{
|
{
|
||||||
colIndex++;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
scrollX += getColumnWidth(col);
|
|
||||||
|
|
||||||
|
scrollX += getColumnWidth(col);
|
||||||
if(x <= scrollX)
|
if(x <= scrollX)
|
||||||
{
|
{
|
||||||
return mColumnOrder[colIndex];
|
return mColumnOrder[colIndex];
|
||||||
}
|
}
|
||||||
else if(colIndex < getColumnCount())
|
|
||||||
{
|
|
||||||
colIndex++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return getColumnCount() > 0 ? mColumnOrder[getColumnCount() - 1] : -1;
|
|
||||||
|
return getColumnCount() > 0 ? mColumnOrder[getColumnCount() - 1] : - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -985,31 +980,27 @@ duint AbstractTableView::getColumnIndexFromX(int x) const
|
||||||
*
|
*
|
||||||
* @return Displayed index.
|
* @return Displayed index.
|
||||||
*/
|
*/
|
||||||
int AbstractTableView::getColumnDisplayIndexFromX(int x)
|
duint AbstractTableView::getColumnDisplayIndexFromX(int x)
|
||||||
{
|
{
|
||||||
int scrollX = -horizontalScrollBar()->value();
|
int scrollX = -horizontalScrollBar()->value();
|
||||||
int colIndex = 0;
|
|
||||||
|
|
||||||
while(colIndex < getColumnCount())
|
for(duint colIndex = 0; colIndex < getColumnCount(); colIndex++)
|
||||||
{
|
{
|
||||||
auto col = mColumnOrder[colIndex];
|
auto col = mColumnOrder[colIndex];
|
||||||
if(getColumnHidden(col))
|
if(getColumnHidden(col))
|
||||||
{
|
{
|
||||||
colIndex++;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
scrollX += getColumnWidth(col);
|
|
||||||
|
|
||||||
|
scrollX += getColumnWidth(col);
|
||||||
if(x <= scrollX)
|
if(x <= scrollX)
|
||||||
{
|
{
|
||||||
return colIndex;
|
return colIndex;
|
||||||
}
|
}
|
||||||
else if(colIndex < getColumnCount())
|
|
||||||
{
|
|
||||||
colIndex++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return getColumnCount() - 1;
|
|
||||||
|
// TODO: what if there are no columns?
|
||||||
|
return getColumnCount() > 0 ? getColumnCount() - 1 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractTableView::updateLastColumnWidth()
|
void AbstractTableView::updateLastColumnWidth()
|
||||||
|
@ -1020,7 +1011,7 @@ void AbstractTableView::updateLastColumnWidth()
|
||||||
int totalWidth = 0;
|
int totalWidth = 0;
|
||||||
int lastWidth = totalWidth;
|
int lastWidth = totalWidth;
|
||||||
int last = 0;
|
int last = 0;
|
||||||
for(int i = 0; i < getColumnCount(); i++)
|
for(duint i = 0; i < getColumnCount(); i++)
|
||||||
{
|
{
|
||||||
if(getColumnHidden(mColumnOrder[i]))
|
if(getColumnHidden(mColumnOrder[i]))
|
||||||
continue;
|
continue;
|
||||||
|
@ -1041,7 +1032,7 @@ void AbstractTableView::updateLastColumnWidth()
|
||||||
MethodInvoker::invokeMethod([this]()
|
MethodInvoker::invokeMethod([this]()
|
||||||
{
|
{
|
||||||
int totalWidth = 0;
|
int totalWidth = 0;
|
||||||
for(int i = 0; i < getColumnCount(); i++)
|
for(duint i = 0; i < getColumnCount(); i++)
|
||||||
if(!getColumnHidden(i))
|
if(!getColumnHidden(i))
|
||||||
totalWidth += getColumnWidth(i);
|
totalWidth += getColumnWidth(i);
|
||||||
|
|
||||||
|
@ -1065,7 +1056,7 @@ int AbstractTableView::getColumnPosition(duint index) const
|
||||||
|
|
||||||
if((index >= 0) && (index < getColumnCount()))
|
if((index >= 0) && (index < getColumnCount()))
|
||||||
{
|
{
|
||||||
for(int i = 0; i < index; i++)
|
for(duint i = 0; i < index; i++)
|
||||||
if(!getColumnHidden(mColumnOrder[i]))
|
if(!getColumnHidden(mColumnOrder[i]))
|
||||||
posX += getColumnWidth(mColumnOrder[i]);
|
posX += getColumnWidth(mColumnOrder[i]);
|
||||||
return posX;
|
return posX;
|
||||||
|
@ -1150,7 +1141,7 @@ void AbstractTableView::deleteAllColumns()
|
||||||
|
|
||||||
void AbstractTableView::setColTitle(duint col, const QString & title)
|
void AbstractTableView::setColTitle(duint col, const QString & title)
|
||||||
{
|
{
|
||||||
if(mColumnList.size() > 0 && col >= 0 && col < mColumnList.size())
|
if(mColumnList.size() > 0 && col < mColumnList.size())
|
||||||
{
|
{
|
||||||
Column column = mColumnList.takeAt(col);
|
Column column = mColumnList.takeAt(col);
|
||||||
column.title = title;
|
column.title = title;
|
||||||
|
@ -1160,7 +1151,7 @@ void AbstractTableView::setColTitle(duint col, const QString & title)
|
||||||
|
|
||||||
QString AbstractTableView::getColTitle(duint col) const
|
QString AbstractTableView::getColTitle(duint col) const
|
||||||
{
|
{
|
||||||
if(mColumnList.size() > 0 && col >= 0 && col < mColumnList.size())
|
if(mColumnList.size() > 0 && col < mColumnList.size())
|
||||||
return mColumnList[col].title;
|
return mColumnList[col].title;
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,10 +8,10 @@
|
||||||
#include "MemoryPage.h"
|
#include "MemoryPage.h"
|
||||||
#include "DisassemblyPopup.h"
|
#include "DisassemblyPopup.h"
|
||||||
|
|
||||||
Disassembly::Disassembly(QWidget* parent, bool isMain, Architecture* architecture)
|
Disassembly::Disassembly(Architecture* architecture, bool isMain, QWidget* parent)
|
||||||
: AbstractTableView(parent),
|
: AbstractTableView(parent),
|
||||||
mIsMain(isMain),
|
mArchitecture(architecture),
|
||||||
mArchitecture(architecture)
|
mIsMain(isMain)
|
||||||
{
|
{
|
||||||
mMemPage = new MemoryPage(0, 0);
|
mMemPage = new MemoryPage(0, 0);
|
||||||
|
|
||||||
|
@ -73,6 +73,11 @@ Disassembly::~Disassembly()
|
||||||
BridgeFree(mXrefInfo.references);
|
BridgeFree(mXrefInfo.references);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Architecture* Disassembly::getArchitecture() const
|
||||||
|
{
|
||||||
|
return mArchitecture;
|
||||||
|
}
|
||||||
|
|
||||||
void Disassembly::updateColors()
|
void Disassembly::updateColors()
|
||||||
{
|
{
|
||||||
AbstractTableView::updateColors();
|
AbstractTableView::updateColors();
|
||||||
|
@ -663,7 +668,7 @@ void Disassembly::mouseMoveEvent(QMouseEvent* event)
|
||||||
|
|
||||||
if((transY(y) >= 0) && (transY(y) <= this->getTableHeight()))
|
if((transY(y) >= 0) && (transY(y) <= this->getTableHeight()))
|
||||||
{
|
{
|
||||||
int i = getIndexOffsetFromY(transY(y));
|
auto i = getIndexOffsetFromY(transY(y));
|
||||||
|
|
||||||
if(mMemPage->getSize() > 0)
|
if(mMemPage->getSize() > 0)
|
||||||
{
|
{
|
||||||
|
@ -713,7 +718,7 @@ duint Disassembly::getAddressForPosition(int mousex, int mousey)
|
||||||
return 0; //Don't show this in highlight mode
|
return 0; //Don't show this in highlight mode
|
||||||
if(getColumnIndexFromX(mousex) != 2)
|
if(getColumnIndexFromX(mousex) != 2)
|
||||||
return 0; //Disassembly popup for other column is undefined
|
return 0; //Disassembly popup for other column is undefined
|
||||||
int rowOffset = getIndexOffsetFromY(transY(mousey));
|
auto rowOffset = getIndexOffsetFromY(transY(mousey));
|
||||||
if(rowOffset < mInstBuffer.size())
|
if(rowOffset < mInstBuffer.size())
|
||||||
{
|
{
|
||||||
ZydisTokenizer::SingleToken token;
|
ZydisTokenizer::SingleToken token;
|
||||||
|
@ -752,7 +757,7 @@ void Disassembly::mousePressEvent(QMouseEvent* event)
|
||||||
{
|
{
|
||||||
if(getColumnIndexFromX(event->x()) == 2) //click in instruction column
|
if(getColumnIndexFromX(event->x()) == 2) //click in instruction column
|
||||||
{
|
{
|
||||||
int rowOffset = getIndexOffsetFromY(transY(event->y()));
|
auto rowOffset = getIndexOffsetFromY(transY(event->y()));
|
||||||
if(rowOffset < mInstBuffer.size())
|
if(rowOffset < mInstBuffer.size())
|
||||||
{
|
{
|
||||||
ZydisTokenizer::SingleToken token;
|
ZydisTokenizer::SingleToken token;
|
||||||
|
@ -790,7 +795,7 @@ void Disassembly::mousePressEvent(QMouseEvent* event)
|
||||||
{
|
{
|
||||||
if(event->y() > getHeaderHeight())
|
if(event->y() > getHeaderHeight())
|
||||||
{
|
{
|
||||||
dsint index = getIndexOffsetFromY(transY(event->y()));
|
auto index = getIndexOffsetFromY(transY(event->y()));
|
||||||
|
|
||||||
if(mInstBuffer.size() > index && index >= 0)
|
if(mInstBuffer.size() > index && index >= 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -13,8 +13,9 @@ class Disassembly : public AbstractTableView
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
Disassembly(QWidget* parent, bool isMain, Architecture* architecture);
|
Disassembly(Architecture* architecture, bool isMain, QWidget* parent = nullptr);
|
||||||
~Disassembly() override;
|
~Disassembly() override;
|
||||||
|
Architecture* getArchitecture() const;
|
||||||
|
|
||||||
// Configuration
|
// Configuration
|
||||||
void updateColors() override;
|
void updateColors() override;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -4,7 +4,6 @@
|
||||||
#include "RichTextPainter.h"
|
#include "RichTextPainter.h"
|
||||||
#include "MemoryPage.h"
|
#include "MemoryPage.h"
|
||||||
#include "VaHistory.h"
|
#include "VaHistory.h"
|
||||||
#include <QTextCodec>
|
|
||||||
|
|
||||||
class HexDump : public AbstractTableView
|
class HexDump : public AbstractTableView
|
||||||
{
|
{
|
||||||
|
@ -74,12 +73,12 @@ public:
|
||||||
bool isData = true;
|
bool isData = true;
|
||||||
int itemCount = 16;
|
int itemCount = 16;
|
||||||
int separator = 0;
|
int separator = 0;
|
||||||
QTextCodec* textCodec = nullptr; //name of the text codec (leave empty if you want to keep your sanity)
|
QByteArray textEncoding; // name of the text codec (leave empty if you want to keep your sanity)
|
||||||
DataDescriptor data;
|
DataDescriptor data;
|
||||||
std::function<void()> columnSwitch;
|
std::function<void()> columnSwitch;
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit HexDump(QWidget* parent = 0);
|
HexDump(Architecture* architecture, QWidget* parent = nullptr);
|
||||||
~HexDump() override;
|
~HexDump() override;
|
||||||
|
|
||||||
// Configuration
|
// Configuration
|
||||||
|
@ -87,41 +86,40 @@ public:
|
||||||
void updateFonts() override;
|
void updateFonts() override;
|
||||||
void updateShortcuts() override;
|
void updateShortcuts() override;
|
||||||
|
|
||||||
//QString getStringToPrint(int rowBase, int rowOffset, int col);
|
|
||||||
void mouseMoveEvent(QMouseEvent* event) override;
|
void mouseMoveEvent(QMouseEvent* event) override;
|
||||||
void mousePressEvent(QMouseEvent* event) override;
|
void mousePressEvent(QMouseEvent* event) override;
|
||||||
void mouseReleaseEvent(QMouseEvent* event) override;
|
void mouseReleaseEvent(QMouseEvent* event) override;
|
||||||
void wheelEvent(QWheelEvent* event) override;
|
void wheelEvent(QWheelEvent* event) override;
|
||||||
void keyPressEvent(QKeyEvent* event) override;
|
void keyPressEvent(QKeyEvent* event) override;
|
||||||
|
|
||||||
QString paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h) override;
|
QString paintContent(QPainter* painter, duint row, duint column, int x, int y, int w, int h) override;
|
||||||
void paintGraphicDump(QPainter* painter, int x, int y, int addr);
|
void paintGraphicDump(QPainter* painter, int x, int y, int addr);
|
||||||
void printSelected(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h);
|
void printSelected(QPainter* painter, duint row, duint column, int x, int y, int w, int h);
|
||||||
|
|
||||||
// Selection Management
|
// Selection Management
|
||||||
void expandSelectionUpTo(dsint rva);
|
void expandSelectionUpTo(duint rva);
|
||||||
void setSingleSelection(dsint rva);
|
void setSingleSelection(duint rva);
|
||||||
dsint getInitialSelection() const;
|
duint getInitialSelection() const;
|
||||||
dsint getSelectionStart() const;
|
duint getSelectionStart() const;
|
||||||
dsint getSelectionEnd() const;
|
duint getSelectionEnd() const;
|
||||||
bool isSelected(dsint rva) const;
|
bool isSelected(duint rva) const;
|
||||||
|
|
||||||
virtual void getColumnRichText(int col, dsint rva, RichTextPainter::List & richText);
|
virtual void getColumnRichText(duint column, duint rva, RichTextPainter::List & richText);
|
||||||
|
|
||||||
static size_t getSizeOf(DataSize size);
|
static size_t getSizeOf(DataSize size);
|
||||||
|
|
||||||
void toString(DataDescriptor desc, duint rva, byte_t* data, RichTextPainter::CustomRichText_t & richText);
|
void toString(DataDescriptor desc, duint rva, uint8_t* data, RichTextPainter::CustomRichText_t & richText);
|
||||||
|
|
||||||
void byteToString(duint rva, byte_t byte, ByteViewMode mode, RichTextPainter::CustomRichText_t & richText);
|
void byteToString(duint rva, uint8_t byte, ByteViewMode mode, RichTextPainter::CustomRichText_t & richText);
|
||||||
void wordToString(duint rva, uint16 word, WordViewMode mode, RichTextPainter::CustomRichText_t & richText);
|
void wordToString(duint rva, uint16_t word, WordViewMode mode, RichTextPainter::CustomRichText_t & richText);
|
||||||
static void dwordToString(duint rva, uint32 dword, DwordViewMode mode, RichTextPainter::CustomRichText_t & richText);
|
static void dwordToString(duint rva, uint32_t dword, DwordViewMode mode, RichTextPainter::CustomRichText_t & richText);
|
||||||
static void qwordToString(duint rva, uint64 qword, QwordViewMode mode, RichTextPainter::CustomRichText_t & richText);
|
static void qwordToString(duint rva, uint64_t qword, QwordViewMode mode, RichTextPainter::CustomRichText_t & richText);
|
||||||
static void twordToString(duint rva, void* tword, TwordViewMode mode, RichTextPainter::CustomRichText_t & richText);
|
static void twordToString(duint rva, void* tword, TwordViewMode mode, RichTextPainter::CustomRichText_t & richText);
|
||||||
|
|
||||||
int getItemIndexFromX(int x) const;
|
int getItemIndexFromX(int x) const;
|
||||||
dsint getItemStartingAddress(int x, int y);
|
duint getItemStartingAddress(int x, int y);
|
||||||
|
|
||||||
int getBytePerRowCount() const;
|
size_t getBytePerRowCount() const;
|
||||||
int getItemPixelWidth(ColumnDescriptor desc) const;
|
int getItemPixelWidth(ColumnDescriptor desc) const;
|
||||||
|
|
||||||
//descriptor management
|
//descriptor management
|
||||||
|
@ -129,8 +127,8 @@ public:
|
||||||
void appendResetDescriptor(int width, QString title, bool clickable, ColumnDescriptor descriptor);
|
void appendResetDescriptor(int width, QString title, bool clickable, ColumnDescriptor descriptor);
|
||||||
void clearDescriptors();
|
void clearDescriptors();
|
||||||
|
|
||||||
void printDumpAt(dsint parVA, bool select, bool repaint = true, bool updateTableOffset = true);
|
void printDumpAt(duint parVA, bool select, bool repaint = true, bool updateTableOffset = true);
|
||||||
duint rvaToVa(dsint rva) const;
|
duint rvaToVa(duint rva) const;
|
||||||
|
|
||||||
duint getTableOffsetRva() const;
|
duint getTableOffsetRva() const;
|
||||||
QString makeAddrText(duint va) const;
|
QString makeAddrText(duint va) const;
|
||||||
|
@ -144,7 +142,7 @@ signals:
|
||||||
void selectionUpdated();
|
void selectionUpdated();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void printDumpAt(dsint parVA);
|
void printDumpAt(duint parVA);
|
||||||
void debugStateChanged(DBGSTATE state);
|
void debugStateChanged(DBGSTATE state);
|
||||||
void updateDumpSlot();
|
void updateDumpSlot();
|
||||||
void copySelectionSlot();
|
void copySelectionSlot();
|
||||||
|
@ -162,9 +160,9 @@ private:
|
||||||
|
|
||||||
struct SelectionData
|
struct SelectionData
|
||||||
{
|
{
|
||||||
dsint firstSelectedIndex;
|
duint firstSelectedIndex = 0;
|
||||||
dsint fromIndex;
|
duint fromIndex = 0;
|
||||||
dsint toIndex;
|
duint toIndex = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
SelectionData mSelection;
|
SelectionData mSelection;
|
||||||
|
@ -209,13 +207,14 @@ private:
|
||||||
std::vector<uint8_t> mUpdateCacheTemp;
|
std::vector<uint8_t> mUpdateCacheTemp;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
MemoryPage* mMemPage;
|
Architecture* mArchitecture = nullptr;
|
||||||
int mByteOffset;
|
MemoryPage* mMemPage = nullptr;
|
||||||
|
dsint mByteOffset = 0;
|
||||||
QList<ColumnDescriptor> mDescriptor;
|
QList<ColumnDescriptor> mDescriptor;
|
||||||
int mForceColumn;
|
int mForceColumn;
|
||||||
bool mRvaDisplayEnabled;
|
bool mRvaDisplayEnabled;
|
||||||
duint mRvaDisplayBase;
|
duint mRvaDisplayBase;
|
||||||
dsint mRvaDisplayPageBase;
|
duint mRvaDisplayPageBase;
|
||||||
QString mSyncAddrExpression;
|
QString mSyncAddrExpression;
|
||||||
QAction* mCopyAddress;
|
QAction* mCopyAddress;
|
||||||
QAction* mCopyRva;
|
QAction* mCopyRva;
|
||||||
|
|
|
@ -278,7 +278,7 @@ void LabeledSplitter::loadFromConfig(const QString & configName)
|
||||||
size_t sizeofState = strlen(state);
|
size_t sizeofState = strlen(state);
|
||||||
if(sizeofState > 0)
|
if(sizeofState > 0)
|
||||||
this->restoreState(QByteArray::fromBase64(QByteArray(state, int(sizeofState))));
|
this->restoreState(QByteArray::fromBase64(QByteArray(state, int(sizeofState))));
|
||||||
connect(Bridge::getBridge(), SIGNAL(shutdown()), this, SLOT(shutdownSlot()));
|
connect(Bridge::getBridge(), SIGNAL(close()), this, SLOT(shutdownSlot()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -102,8 +102,8 @@ void ReferenceView::connectBridge()
|
||||||
connect(Bridge::getBridge(), SIGNAL(referenceSetProgress(int)), this, SLOT(referenceSetProgressSlot(int)));
|
connect(Bridge::getBridge(), SIGNAL(referenceSetProgress(int)), this, SLOT(referenceSetProgressSlot(int)));
|
||||||
connect(Bridge::getBridge(), SIGNAL(referenceSetCurrentTaskProgress(int, QString)), this, SLOT(referenceSetCurrentTaskProgressSlot(int, QString)));
|
connect(Bridge::getBridge(), SIGNAL(referenceSetCurrentTaskProgress(int, QString)), this, SLOT(referenceSetCurrentTaskProgressSlot(int, QString)));
|
||||||
connect(Bridge::getBridge(), SIGNAL(referenceAddCommand(QString, QString)), this, SLOT(addCommand(QString, QString)));
|
connect(Bridge::getBridge(), SIGNAL(referenceAddCommand(QString, QString)), this, SLOT(addCommand(QString, QString)));
|
||||||
connect(stdSearchList(), SIGNAL(selectionChangedSignal(int)), this, SLOT(searchSelectionChanged(int)));
|
connect(stdSearchList(), SIGNAL(selectionChanged(duint)), this, SLOT(searchSelectionChanged(int)));
|
||||||
connect(stdList(), SIGNAL(selectionChangedSignal(int)), this, SLOT(searchSelectionChanged(int)));
|
connect(stdList(), SIGNAL(selectionChanged(duint)), this, SLOT(searchSelectionChanged(int)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReferenceView::disconnectBridge()
|
void ReferenceView::disconnectBridge()
|
||||||
|
@ -113,8 +113,8 @@ void ReferenceView::disconnectBridge()
|
||||||
disconnect(Bridge::getBridge(), SIGNAL(referenceSetProgress(int)), this, SLOT(referenceSetProgressSlot(int)));
|
disconnect(Bridge::getBridge(), SIGNAL(referenceSetProgress(int)), this, SLOT(referenceSetProgressSlot(int)));
|
||||||
disconnect(Bridge::getBridge(), SIGNAL(referenceSetCurrentTaskProgress(int, QString)), this, SLOT(referenceSetCurrentTaskProgressSlot(int, QString)));
|
disconnect(Bridge::getBridge(), SIGNAL(referenceSetCurrentTaskProgress(int, QString)), this, SLOT(referenceSetCurrentTaskProgressSlot(int, QString)));
|
||||||
disconnect(Bridge::getBridge(), SIGNAL(referenceAddCommand(QString, QString)), this, SLOT(addCommand(QString, QString)));
|
disconnect(Bridge::getBridge(), SIGNAL(referenceAddCommand(QString, QString)), this, SLOT(addCommand(QString, QString)));
|
||||||
disconnect(stdSearchList(), SIGNAL(selectionChangedSignal(int)), this, SLOT(searchSelectionChanged(int)));
|
disconnect(stdSearchList(), SIGNAL(selectionChanged(int)), this, SLOT(searchSelectionChanged(int)));
|
||||||
disconnect(stdList(), SIGNAL(selectionChangedSignal(int)), this, SLOT(searchSelectionChanged(int)));
|
disconnect(stdList(), SIGNAL(selectionChanged(int)), this, SLOT(searchSelectionChanged(int)));
|
||||||
}
|
}
|
||||||
|
|
||||||
int ReferenceView::progress() const
|
int ReferenceView::progress() const
|
||||||
|
@ -284,7 +284,7 @@ void ReferenceView::followGenericAddress()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReferenceView::setBreakpointAt(int row, BPSetAction action)
|
void ReferenceView::setBreakpointAt(duint row, BPSetAction action)
|
||||||
{
|
{
|
||||||
if(!DbgIsDebugging())
|
if(!DbgIsDebugging())
|
||||||
return;
|
return;
|
||||||
|
@ -334,14 +334,14 @@ void ReferenceView::toggleBreakpoint()
|
||||||
void ReferenceView::setBreakpointOnAllCommands()
|
void ReferenceView::setBreakpointOnAllCommands()
|
||||||
{
|
{
|
||||||
GuiDisableUpdateScope s;
|
GuiDisableUpdateScope s;
|
||||||
for(int i = 0; i < mCurList->getRowCount(); i++)
|
for(duint i = 0; i < mCurList->getRowCount(); i++)
|
||||||
setBreakpointAt(i, Enable);
|
setBreakpointAt(i, Enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReferenceView::removeBreakpointOnAllCommands()
|
void ReferenceView::removeBreakpointOnAllCommands()
|
||||||
{
|
{
|
||||||
GuiDisableUpdateScope s;
|
GuiDisableUpdateScope s;
|
||||||
for(int i = 0; i < mCurList->getRowCount(); i++)
|
for(duint i = 0; i < mCurList->getRowCount(); i++)
|
||||||
setBreakpointAt(i, Remove);
|
setBreakpointAt(i, Remove);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -355,7 +355,7 @@ void ReferenceView::setBreakpointOnAllApiCalls()
|
||||||
QString apiText = mCurList->getCellContent(mCurList->getInitialSelection(), 1);
|
QString apiText = mCurList->getCellContent(mCurList->getInitialSelection(), 1);
|
||||||
|
|
||||||
GuiDisableUpdateScope s;
|
GuiDisableUpdateScope s;
|
||||||
for(int i = 0; i < mCurList->getRowCount(); i++)
|
for(duint i = 0; i < mCurList->getRowCount(); i++)
|
||||||
if(mCurList->getCellContent(i, 1) == apiText)
|
if(mCurList->getCellContent(i, 1) == apiText)
|
||||||
setBreakpointAt(i, Enable);
|
setBreakpointAt(i, Enable);
|
||||||
}
|
}
|
||||||
|
@ -371,7 +371,7 @@ void ReferenceView::removeBreakpointOnAllApiCalls()
|
||||||
QString apiText = mCurList->getCellContent(mCurList->getInitialSelection(), 1);
|
QString apiText = mCurList->getCellContent(mCurList->getInitialSelection(), 1);
|
||||||
|
|
||||||
GuiDisableUpdateScope s;
|
GuiDisableUpdateScope s;
|
||||||
for(int i = 0; i < mCurList->getRowCount(); i++)
|
for(duint i = 0; i < mCurList->getRowCount(); i++)
|
||||||
if(mCurList->getCellContent(i, 1) == apiText)
|
if(mCurList->getCellContent(i, 1) == apiText)
|
||||||
setBreakpointAt(i, Remove);
|
setBreakpointAt(i, Remove);
|
||||||
}
|
}
|
||||||
|
@ -423,7 +423,7 @@ void ReferenceView::referenceExecCommand()
|
||||||
for(int selected : mCurList->getSelection()) //to do: enable multi-selection
|
for(int selected : mCurList->getSelection()) //to do: enable multi-selection
|
||||||
{
|
{
|
||||||
QString specializedCommand = command;
|
QString specializedCommand = command;
|
||||||
for(int i = 0; i < mCurList->getColumnCount(); i++)
|
for(duint i = 0; i < mCurList->getColumnCount(); i++)
|
||||||
{
|
{
|
||||||
QString token = "$" + QString::number(i);
|
QString token = "$" + QString::number(i);
|
||||||
if(specializedCommand.contains(token))
|
if(specializedCommand.contains(token))
|
||||||
|
|
|
@ -75,7 +75,7 @@ private:
|
||||||
Remove
|
Remove
|
||||||
};
|
};
|
||||||
|
|
||||||
void setBreakpointAt(int row, BPSetAction action);
|
void setBreakpointAt(duint row, BPSetAction action);
|
||||||
dsint apiAddressFromString(const QString & s);
|
dsint apiAddressFromString(const QString & s);
|
||||||
|
|
||||||
void mouseReleaseEvent(QMouseEvent* event);
|
void mouseReleaseEvent(QMouseEvent* event);
|
||||||
|
|
|
@ -93,7 +93,6 @@ SearchListView::SearchListView(QWidget* parent, AbstractSearchList* abstractSear
|
||||||
|
|
||||||
// Set global variables
|
// Set global variables
|
||||||
mCurList = abstractSearchList->list();
|
mCurList = abstractSearchList->list();
|
||||||
mSearchStartCol = 0;
|
|
||||||
|
|
||||||
// Install input event filter
|
// Install input event filter
|
||||||
mSearchBox->installEventFilter(this);
|
mSearchBox->installEventFilter(this);
|
||||||
|
@ -205,9 +204,9 @@ void SearchListView::filterEntries()
|
||||||
bool hasSetSingleSelection = false;
|
bool hasSetSingleSelection = false;
|
||||||
if(!mLastFirstColValue.isEmpty())
|
if(!mLastFirstColValue.isEmpty())
|
||||||
{
|
{
|
||||||
int rows = mCurList->getRowCount();
|
auto rows = mCurList->getRowCount();
|
||||||
mCurList->setTableOffset(0);
|
mCurList->setTableOffset(0);
|
||||||
for(int i = 0; i < rows; i++)
|
for(duint i = 0; i < rows; i++)
|
||||||
{
|
{
|
||||||
if(mCurList->getCellContent(i, 0) == mLastFirstColValue)
|
if(mCurList->getCellContent(i, 0) == mLastFirstColValue)
|
||||||
{
|
{
|
||||||
|
|
|
@ -14,8 +14,8 @@ class SearchListView : public QWidget, public ActionHelper<SearchListView>
|
||||||
public:
|
public:
|
||||||
explicit SearchListView(QWidget* parent, AbstractSearchList* abstractSearchList, bool enableRegex, bool enableLock);
|
explicit SearchListView(QWidget* parent, AbstractSearchList* abstractSearchList, bool enableRegex, bool enableLock);
|
||||||
|
|
||||||
AbstractStdTable* mCurList;
|
AbstractStdTable* mCurList = nullptr;
|
||||||
int mSearchStartCol;
|
duint mSearchStartCol = 0;
|
||||||
|
|
||||||
bool findTextInList(AbstractStdTable* list, QString text, int row, int startcol, bool startswith);
|
bool findTextInList(AbstractStdTable* list, QString text, int row, int startcol, bool startswith);
|
||||||
void refreshSearchList();
|
void refreshSearchList();
|
||||||
|
|
|
@ -24,20 +24,13 @@ int StdIconTable::getIconColumn() const
|
||||||
return mIconColumn;
|
return mIconColumn;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StdIconTable::setRowCount(dsint count)
|
void StdIconTable::setRowCount(duint count)
|
||||||
{
|
{
|
||||||
int wRowToAddOrRemove = count - int(mIcon.size());
|
mIcon.resize(count);
|
||||||
for(int i = 0; i < qAbs(wRowToAddOrRemove); i++)
|
|
||||||
{
|
|
||||||
if(wRowToAddOrRemove > 0)
|
|
||||||
mIcon.push_back(QIcon());
|
|
||||||
else
|
|
||||||
mIcon.pop_back();
|
|
||||||
}
|
|
||||||
StdTable::setRowCount(count);
|
StdTable::setRowCount(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StdIconTable::sortRows(int column, bool ascending)
|
void StdIconTable::sortRows(duint column, bool ascending)
|
||||||
{
|
{
|
||||||
auto sortFn = mColumnSortFunctions.at(column);
|
auto sortFn = mColumnSortFunctions.at(column);
|
||||||
std::vector<size_t> index;
|
std::vector<size_t> index;
|
||||||
|
@ -61,24 +54,24 @@ void StdIconTable::sortRows(int column, bool ascending)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString StdIconTable::paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h)
|
QString StdIconTable::paintContent(QPainter* painter, duint row, duint col, int x, int y, int w, int h)
|
||||||
{
|
{
|
||||||
if(col == mIconColumn)
|
if(col == mIconColumn)
|
||||||
{
|
{
|
||||||
// Draw the selection first, so that transparent icons are drawn properly
|
// Draw the selection first, so that transparent icons are drawn properly
|
||||||
if(isSelected(rowBase, rowOffset))
|
if(isSelected(row))
|
||||||
painter->fillRect(QRect(x, y, w, h), QBrush(mSelectionColor));
|
painter->fillRect(QRect(x, y, w, h), QBrush(mSelectionColor));
|
||||||
|
|
||||||
mIcon.at(rowBase + rowOffset).paint(painter, x, y, h, h);
|
mIcon.at(row).paint(painter, x, y, h, h);
|
||||||
QString wStr = StdTable::paintContent(painter, rowBase, rowOffset, col, x + h, y, w - h, h);
|
QString str = StdTable::paintContent(painter, row, col, x + h, y, w - h, h);
|
||||||
|
|
||||||
if(wStr.length())
|
if(str.length())
|
||||||
{
|
{
|
||||||
painter->setPen(getCellColor(rowBase + rowOffset, col));
|
painter->setPen(getCellColor(row, col));
|
||||||
painter->drawText(QRect(x + 4 + h, y, w - 4 - h, h), Qt::AlignVCenter | Qt::AlignLeft, wStr);
|
painter->drawText(QRect(x + 4 + h, y, w - 4 - h, h), Qt::AlignVCenter | Qt::AlignLeft, str);
|
||||||
}
|
}
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return StdTable::paintContent(painter, rowBase, rowOffset, col, x, y, w, h);
|
return StdTable::paintContent(painter, row, col, x, y, w, h);
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,7 +79,7 @@ void StdSearchListView::reloadData()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void StdSearchListView::setSearchStartCol(int col)
|
void StdSearchListView::setSearchStartCol(duint col)
|
||||||
{
|
{
|
||||||
if(col < stdList()->getColumnCount())
|
if(col < stdList()->getColumnCount())
|
||||||
mSearchStartCol = col;
|
mSearchStartCol = col;
|
||||||
|
|
|
@ -23,7 +23,7 @@ public slots:
|
||||||
virtual void setRowCount(dsint count);
|
virtual void setRowCount(dsint count);
|
||||||
void setCellContent(int r, int c, QString s);
|
void setCellContent(int r, int c, QString s);
|
||||||
void reloadData();
|
void reloadData();
|
||||||
void setSearchStartCol(int col);
|
void setSearchStartCol(duint col);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
StdTableSearchList* mSearchListData;
|
StdTableSearchList* mSearchListData;
|
||||||
|
|
|
@ -52,30 +52,36 @@ void StdTable::deleteAllColumns()
|
||||||
mColumnSortFunctions.clear();
|
mColumnSortFunctions.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void StdTable::setRowCount(dsint count)
|
void StdTable::setRowCount(duint count)
|
||||||
{
|
{
|
||||||
int wRowToAddOrRemove = count - int(mData.size());
|
auto oldSize = mData.size();
|
||||||
for(int i = 0; i < qAbs(wRowToAddOrRemove); i++)
|
mData.resize(count);
|
||||||
|
if(oldSize < count)
|
||||||
{
|
{
|
||||||
if(wRowToAddOrRemove > 0)
|
for(duint i = oldSize; i < count; i++)
|
||||||
{
|
{
|
||||||
mData.push_back(std::vector<CellData>());
|
mData[i].resize(getColumnCount());
|
||||||
for(int j = 0; j < getColumnCount(); j++)
|
|
||||||
mData[mData.size() - 1].push_back(CellData());
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
mData.pop_back();
|
|
||||||
}
|
}
|
||||||
AbstractTableView::setRowCount(count);
|
AbstractTableView::setRowCount(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StdTable::setCellContent(int r, int c, QString s)
|
void StdTable::setCellContent(duint r, duint c, QString s)
|
||||||
{
|
{
|
||||||
if(isValidIndex(r, c))
|
if(isValidIndex(r, c))
|
||||||
mData[r][c].text = std::move(s);
|
mData[r][c].text = std::move(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString StdTable::getCellContent(int r, int c)
|
void StdTable::setCellContent(duint r, duint c, QString s, duint userdata)
|
||||||
|
{
|
||||||
|
if(isValidIndex(r, c))
|
||||||
|
{
|
||||||
|
mData[r][c].text = std::move(s);
|
||||||
|
mData[r][c].userdata = userdata;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString StdTable::getCellContent(duint r, duint c)
|
||||||
{
|
{
|
||||||
if(isValidIndex(r, c))
|
if(isValidIndex(r, c))
|
||||||
return mData[r][c].text;
|
return mData[r][c].text;
|
||||||
|
@ -83,25 +89,25 @@ QString StdTable::getCellContent(int r, int c)
|
||||||
return QString("");
|
return QString("");
|
||||||
}
|
}
|
||||||
|
|
||||||
void StdTable::setCellUserdata(int r, int c, duint userdata)
|
void StdTable::setCellUserdata(duint r, duint c, duint userdata)
|
||||||
{
|
{
|
||||||
if(isValidIndex(r, c))
|
if(isValidIndex(r, c))
|
||||||
mData[r][c].userdata = userdata;
|
mData[r][c].userdata = userdata;
|
||||||
}
|
}
|
||||||
|
|
||||||
duint StdTable::getCellUserdata(int r, int c)
|
duint StdTable::getCellUserdata(duint r, duint c)
|
||||||
{
|
{
|
||||||
return isValidIndex(r, c) ? mData[r][c].userdata : 0;
|
return isValidIndex(r, c) ? mData[r][c].userdata : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StdTable::isValidIndex(int r, int c)
|
bool StdTable::isValidIndex(duint r, duint c)
|
||||||
{
|
{
|
||||||
if(r < 0 || c < 0 || r >= int(mData.size()))
|
if(r < 0 || c < 0 || r >= int(mData.size()))
|
||||||
return false;
|
return false;
|
||||||
return c < int(mData.at(r).size());
|
return c < int(mData.at(r).size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void StdTable::sortRows(int column, bool ascending)
|
void StdTable::sortRows(duint column, bool ascending)
|
||||||
{
|
{
|
||||||
auto sortFn = mColumnSortFunctions.at(column);
|
auto sortFn = mColumnSortFunctions.at(column);
|
||||||
std::stable_sort(mData.begin(), mData.end(), [column, ascending, &sortFn](const std::vector<CellData> & a, const std::vector<CellData> & b)
|
std::stable_sort(mData.begin(), mData.end(), [column, ascending, &sortFn](const std::vector<CellData> & a, const std::vector<CellData> & b)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include "StdTableSearchList.h"
|
#include "StdTableSearchList.h"
|
||||||
#include "StdIconTable.h"
|
#include "StdIconTable.h"
|
||||||
|
|
||||||
void StdTableSearchList::filter(const QString & filter, FilterType type, int startColumn)
|
void StdTableSearchList::filter(const QString & filter, FilterType type, duint startColumn)
|
||||||
{
|
{
|
||||||
StdIconTable* mSearchIconList = qobject_cast<StdIconTable*>(mSearchList);
|
StdIconTable* mSearchIconList = qobject_cast<StdIconTable*>(mSearchList);
|
||||||
StdIconTable* mIconList = qobject_cast<StdIconTable*>(mList);
|
StdIconTable* mIconList = qobject_cast<StdIconTable*>(mList);
|
||||||
|
|
|
@ -17,7 +17,7 @@ public:
|
||||||
AbstractStdTable* list() const override { return mList; }
|
AbstractStdTable* list() const override { return mList; }
|
||||||
AbstractStdTable* searchList() const override { return mSearchList; }
|
AbstractStdTable* searchList() const override { return mSearchList; }
|
||||||
|
|
||||||
void filter(const QString & filter, FilterType type, int startColumn) override;
|
void filter(const QString & filter, FilterType type, duint startColumn) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
StdTable* mList;
|
StdTable* mList;
|
||||||
|
|
|
@ -85,7 +85,7 @@ void Bridge::initBridge()
|
||||||
mBridge = new Bridge();
|
mBridge = new Bridge();
|
||||||
}
|
}
|
||||||
|
|
||||||
Architecture* Bridge::getArch()
|
Architecture* Bridge::getArchitecture()
|
||||||
{
|
{
|
||||||
return &mArch;
|
return &mArch;
|
||||||
}
|
}
|
||||||
|
@ -335,7 +335,7 @@ void* Bridge::processMessage(GUIMSG type, void* param1, void* param2)
|
||||||
|
|
||||||
case GUI_REF_SETSEARCHSTARTCOL:
|
case GUI_REF_SETSEARCHSTARTCOL:
|
||||||
if(referenceManager->currentReferenceView())
|
if(referenceManager->currentReferenceView())
|
||||||
referenceManager->currentReferenceView()->setSearchStartCol((int)param1);
|
referenceManager->currentReferenceView()->setSearchStartCol((duint)param1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GUI_REF_INITIALIZE:
|
case GUI_REF_INITIALIZE:
|
||||||
|
@ -379,7 +379,7 @@ void* Bridge::processMessage(GUIMSG type, void* param1, void* param2)
|
||||||
byte_t buffer[16];
|
byte_t buffer[16];
|
||||||
if(!DbgMemRead(parVA, buffer, 16))
|
if(!DbgMemRead(parVA, buffer, 16))
|
||||||
return 0;
|
return 0;
|
||||||
QZydis disasm(int(ConfigUint("Disassembler", "MaxModuleSize")), Bridge::getArch());
|
QZydis disasm(int(ConfigUint("Disassembler", "MaxModuleSize")), Bridge::getArchitecture());
|
||||||
Instruction_t instr = disasm.DisassembleAt(buffer, 16, 0, parVA);
|
Instruction_t instr = disasm.DisassembleAt(buffer, 16, 0, parVA);
|
||||||
QString finalInstruction;
|
QString finalInstruction;
|
||||||
for(const auto & curToken : instr.tokens.tokens)
|
for(const auto & curToken : instr.tokens.tokens)
|
||||||
|
|
|
@ -43,6 +43,8 @@ class QZydis
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QZydis(int maxModuleSize, Architecture* architecture);
|
QZydis(int maxModuleSize, Architecture* architecture);
|
||||||
|
QZydis(const QZydis &) = delete;
|
||||||
|
QZydis(QZydis &&) = delete;
|
||||||
~QZydis();
|
~QZydis();
|
||||||
ulong DisassembleBack(const uint8_t* data, duint base, duint size, duint ip, int n);
|
ulong DisassembleBack(const uint8_t* data, duint base, duint size, duint ip, int n);
|
||||||
ulong DisassembleNext(const uint8_t* data, duint base, duint size, duint ip, int n);
|
ulong DisassembleNext(const uint8_t* data, duint base, duint size, duint ip, int n);
|
||||||
|
|
|
@ -112,7 +112,7 @@ retryFindWindow:
|
||||||
refresh();
|
refresh();
|
||||||
QString pidText = QString().sprintf(ConfigBool("Gui", "PidTidInHex") ? "%.8X" : "%u", pid);
|
QString pidText = QString().sprintf(ConfigBool("Gui", "PidTidInHex") ? "%.8X" : "%u", pid);
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for(int i = 0; i < mSearchListView->mCurList->getRowCount(); i++)
|
for(duint i = 0; i < mSearchListView->mCurList->getRowCount(); i++)
|
||||||
{
|
{
|
||||||
if(mSearchListView->mCurList->getCellContent(i, ColPid) == pidText)
|
if(mSearchListView->mCurList->getCellContent(i, ColPid) == pidText)
|
||||||
{
|
{
|
||||||
|
|
|
@ -22,7 +22,7 @@ BreakpointsView::BreakpointsView(QWidget* parent)
|
||||||
addColumnAt(0, tr("Summary"), true);
|
addColumnAt(0, tr("Summary"), true);
|
||||||
loadColumnFromConfig("BreakpointsView");
|
loadColumnFromConfig("BreakpointsView");
|
||||||
|
|
||||||
mDisasm = new QZydis(ConfigUint("Disassembler", "MaxModuleSize"), Bridge::getArch());
|
mDisasm = new QZydis(ConfigUint("Disassembler", "MaxModuleSize"), Bridge::getArchitecture());
|
||||||
mDisasm->UpdateConfig();
|
mDisasm->UpdateConfig();
|
||||||
enableMultiSelection(true);
|
enableMultiSelection(true);
|
||||||
|
|
||||||
|
|
|
@ -3,13 +3,10 @@
|
||||||
#include "Configuration.h"
|
#include "Configuration.h"
|
||||||
#include "Bridge.h"
|
#include "Bridge.h"
|
||||||
|
|
||||||
CPUArgumentWidget::CPUArgumentWidget(QWidget* parent) :
|
CPUArgumentWidget::CPUArgumentWidget(Architecture* architecture, QWidget* parent) :
|
||||||
QWidget(parent),
|
QWidget(parent),
|
||||||
ui(new Ui::CPUArgumentWidget),
|
ui(new Ui::CPUArgumentWidget),
|
||||||
mTable(nullptr),
|
mArchitecture(architecture)
|
||||||
mCurrentCallingConvention(-1),
|
|
||||||
mStackOffset(0),
|
|
||||||
mAllowUpdate(true)
|
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
mTable = ui->table;
|
mTable = ui->table;
|
||||||
|
@ -32,7 +29,7 @@ CPUArgumentWidget::CPUArgumentWidget(QWidget* parent) :
|
||||||
connect(mFollowAddrStack, SIGNAL(triggered()), this, SLOT(followStackSlot()));
|
connect(mFollowAddrStack, SIGNAL(triggered()), this, SLOT(followStackSlot()));
|
||||||
|
|
||||||
connect(Bridge::getBridge(), SIGNAL(repaintTableView()), this, SLOT(refreshData()));
|
connect(Bridge::getBridge(), SIGNAL(repaintTableView()), this, SLOT(refreshData()));
|
||||||
connect(Bridge::getBridge(), SIGNAL(disassembleAt(dsint, dsint)), this, SLOT(disassembleAtSlot(dsint, dsint)));
|
connect(Bridge::getBridge(), SIGNAL(disassembleAt(duint, duint)), this, SLOT(disassembleAtSlot(duint, duint)));
|
||||||
}
|
}
|
||||||
|
|
||||||
CPUArgumentWidget::~CPUArgumentWidget()
|
CPUArgumentWidget::~CPUArgumentWidget()
|
||||||
|
@ -46,7 +43,7 @@ void CPUArgumentWidget::updateStackOffset(bool iscall)
|
||||||
mStackOffset = cur.getStackOffset() + (iscall ? 0 : cur.getCallOffset());
|
mStackOffset = cur.getStackOffset() + (iscall ? 0 : cur.getCallOffset());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPUArgumentWidget::disassembleAtSlot(dsint addr, dsint cip)
|
void CPUArgumentWidget::disassembleAtSlot(duint addr, duint cip)
|
||||||
{
|
{
|
||||||
Q_UNUSED(addr);
|
Q_UNUSED(addr);
|
||||||
if(mCurrentCallingConvention == -1) //no calling conventions
|
if(mCurrentCallingConvention == -1) //no calling conventions
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "StdTable.h"
|
#include "StdTable.h"
|
||||||
#include "StringUtil.h"
|
#include "StringUtil.h"
|
||||||
|
#include "Architecture.h"
|
||||||
|
|
||||||
namespace Ui
|
namespace Ui
|
||||||
{
|
{
|
||||||
|
@ -15,7 +16,7 @@ class CPUArgumentWidget : public QWidget
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit CPUArgumentWidget(QWidget* parent = 0);
|
explicit CPUArgumentWidget(Architecture* architecture, QWidget* parent = nullptr);
|
||||||
~CPUArgumentWidget();
|
~CPUArgumentWidget();
|
||||||
|
|
||||||
static QString defaultArgFormat(const QString & format, const QString & expression)
|
static QString defaultArgFormat(const QString & format, const QString & expression)
|
||||||
|
@ -40,7 +41,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void disassembleAtSlot(dsint addr, dsint cip);
|
void disassembleAtSlot(duint addr, duint cip);
|
||||||
void refreshData();
|
void refreshData();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
@ -133,11 +134,12 @@ private:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Ui::CPUArgumentWidget* ui;
|
Architecture* mArchitecture = nullptr;
|
||||||
StdTable* mTable;
|
Ui::CPUArgumentWidget* ui = nullptr;
|
||||||
int mCurrentCallingConvention;
|
StdTable* mTable = nullptr;
|
||||||
duint mStackOffset;
|
int mCurrentCallingConvention = -1;
|
||||||
bool mAllowUpdate;
|
duint mStackOffset = 0;
|
||||||
|
bool mAllowUpdate = true;
|
||||||
std::vector<CallingConvention> mCallingConventions;
|
std::vector<CallingConvention> mCallingConventions;
|
||||||
std::vector<duint> mArgumentValues;
|
std::vector<duint> mArgumentValues;
|
||||||
QAction* mFollowDisasm;
|
QAction* mFollowDisasm;
|
||||||
|
|
|
@ -26,7 +26,8 @@
|
||||||
#include "BrowseDialog.h"
|
#include "BrowseDialog.h"
|
||||||
#include "Tracer/TraceBrowser.h"
|
#include "Tracer/TraceBrowser.h"
|
||||||
|
|
||||||
CPUDisassembly::CPUDisassembly(QWidget* parent, bool isMain) : Disassembly(parent, isMain)
|
CPUDisassembly::CPUDisassembly(Architecture* architecture, bool isMain, QWidget* parent)
|
||||||
|
: Disassembly(architecture, isMain, parent)
|
||||||
{
|
{
|
||||||
setWindowTitle("Disassembly");
|
setWindowTitle("Disassembly");
|
||||||
|
|
||||||
|
@ -34,7 +35,7 @@ CPUDisassembly::CPUDisassembly(QWidget* parent, bool isMain) : Disassembly(paren
|
||||||
setupRightClickContextMenu();
|
setupRightClickContextMenu();
|
||||||
|
|
||||||
// Connect bridge<->disasm calls
|
// Connect bridge<->disasm calls
|
||||||
connect(Bridge::getBridge(), SIGNAL(disassembleAt(dsint, dsint)), this, SLOT(disassembleAtSlot(dsint, dsint)));
|
connect(Bridge::getBridge(), SIGNAL(disassembleAt(duint, duint)), this, SLOT(disassembleAtSlot(duint, duint)));
|
||||||
if(mIsMain)
|
if(mIsMain)
|
||||||
{
|
{
|
||||||
connect(Bridge::getBridge(), SIGNAL(selectionDisasmGet(SELECTIONDATA*)), this, SLOT(selectionGetSlot(SELECTIONDATA*)));
|
connect(Bridge::getBridge(), SIGNAL(selectionDisasmGet(SELECTIONDATA*)), this, SLOT(selectionGetSlot(SELECTIONDATA*)));
|
||||||
|
@ -133,7 +134,7 @@ void CPUDisassembly::mouseDoubleClickEvent(QMouseEvent* event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPUDisassembly::addFollowReferenceMenuItem(QString name, dsint value, QMenu* menu, bool isReferences, bool isFollowInCPU)
|
void CPUDisassembly::addFollowReferenceMenuItem(QString name, duint value, QMenu* menu, bool isReferences, bool isFollowInCPU)
|
||||||
{
|
{
|
||||||
foreach(QAction* action, menu->actions()) //check for duplicate action
|
foreach(QAction* action, menu->actions()) //check for duplicate action
|
||||||
if(action->text() == name)
|
if(action->text() == name)
|
||||||
|
@ -149,7 +150,7 @@ void CPUDisassembly::addFollowReferenceMenuItem(QString name, dsint value, QMenu
|
||||||
connect(newAction, SIGNAL(triggered()), this, SLOT(followActionSlot()));
|
connect(newAction, SIGNAL(triggered()), this, SLOT(followActionSlot()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPUDisassembly::setupFollowReferenceMenu(dsint wVA, QMenu* menu, bool isReferences, bool isFollowInCPU)
|
void CPUDisassembly::setupFollowReferenceMenu(duint va, QMenu* menu, bool isReferences, bool isFollowInCPU)
|
||||||
{
|
{
|
||||||
//remove previous actions
|
//remove previous actions
|
||||||
QList<QAction*> list = menu->actions();
|
QList<QAction*> list = menu->actions();
|
||||||
|
@ -162,12 +163,12 @@ void CPUDisassembly::setupFollowReferenceMenu(dsint wVA, QMenu* menu, bool isRef
|
||||||
if(isReferences)
|
if(isReferences)
|
||||||
menu->addAction(mReferenceSelectedAddressAction);
|
menu->addAction(mReferenceSelectedAddressAction);
|
||||||
else
|
else
|
||||||
addFollowReferenceMenuItem(tr("&Selected Address"), wVA, menu, isReferences, isFollowInCPU);
|
addFollowReferenceMenuItem(tr("&Selected Address"), va, menu, isReferences, isFollowInCPU);
|
||||||
}
|
}
|
||||||
|
|
||||||
//add follow actions
|
//add follow actions
|
||||||
DISASM_INSTR instr;
|
DISASM_INSTR instr;
|
||||||
DbgDisasmAt(wVA, &instr);
|
DbgDisasmAt(va, &instr);
|
||||||
|
|
||||||
if(!isReferences) //follow in dump
|
if(!isReferences) //follow in dump
|
||||||
{
|
{
|
||||||
|
@ -735,19 +736,19 @@ void CPUDisassembly::setLabelSlot()
|
||||||
{
|
{
|
||||||
if(!DbgIsDebugging())
|
if(!DbgIsDebugging())
|
||||||
return;
|
return;
|
||||||
duint wVA = rvaToVa(getInitialSelection());
|
duint va = rvaToVa(getInitialSelection());
|
||||||
LineEditDialog mLineEdit(this);
|
LineEditDialog mLineEdit(this);
|
||||||
mLineEdit.setTextMaxLength(MAX_LABEL_SIZE - 2);
|
mLineEdit.setTextMaxLength(MAX_LABEL_SIZE - 2);
|
||||||
QString addr_text = ToPtrString(wVA);
|
QString addr_text = ToPtrString(va);
|
||||||
char label_text[MAX_COMMENT_SIZE] = "";
|
char label_text[MAX_COMMENT_SIZE] = "";
|
||||||
if(DbgGetLabelAt((duint)wVA, SEG_DEFAULT, label_text))
|
if(DbgGetLabelAt((duint)va, SEG_DEFAULT, label_text))
|
||||||
mLineEdit.setText(QString(label_text));
|
mLineEdit.setText(QString(label_text));
|
||||||
mLineEdit.setWindowTitle(tr("Add label at ") + addr_text);
|
mLineEdit.setWindowTitle(tr("Add label at ") + addr_text);
|
||||||
restart:
|
restart:
|
||||||
if(mLineEdit.exec() != QDialog::Accepted)
|
if(mLineEdit.exec() != QDialog::Accepted)
|
||||||
return;
|
return;
|
||||||
QByteArray utf8data = mLineEdit.editText.toUtf8();
|
QByteArray utf8data = mLineEdit.editText.toUtf8();
|
||||||
if(!utf8data.isEmpty() && DbgIsValidExpression(utf8data.constData()) && DbgValFromString(utf8data.constData()) != wVA)
|
if(!utf8data.isEmpty() && DbgIsValidExpression(utf8data.constData()) && DbgValFromString(utf8data.constData()) != va)
|
||||||
{
|
{
|
||||||
QMessageBox msg(QMessageBox::Warning, tr("The label may be in use"),
|
QMessageBox msg(QMessageBox::Warning, tr("The label may be in use"),
|
||||||
tr("The label \"%1\" may be an existing label or a valid expression. Using such label might have undesired effects. Do you still want to continue?").arg(mLineEdit.editText),
|
tr("The label \"%1\" may be an existing label or a valid expression. Using such label might have undesired effects. Do you still want to continue?").arg(mLineEdit.editText),
|
||||||
|
@ -758,7 +759,7 @@ restart:
|
||||||
if(msg.exec() == QMessageBox::No)
|
if(msg.exec() == QMessageBox::No)
|
||||||
goto restart;
|
goto restart;
|
||||||
}
|
}
|
||||||
if(!DbgSetLabelAt(wVA, utf8data.constData()))
|
if(!DbgSetLabelAt(va, utf8data.constData()))
|
||||||
SimpleErrorBox(this, tr("Error!"), tr("DbgSetLabelAt failed!"));
|
SimpleErrorBox(this, tr("Error!"), tr("DbgSetLabelAt failed!"));
|
||||||
|
|
||||||
GuiUpdateAllViews();
|
GuiUpdateAllViews();
|
||||||
|
@ -914,7 +915,7 @@ void CPUDisassembly::assembleSlot()
|
||||||
|
|
||||||
assembly_error = false;
|
assembly_error = false;
|
||||||
|
|
||||||
assembleDialog.setSelectedInstrVa(wVA);
|
assembleDialog.setSelectedInstrVa(va);
|
||||||
if(ConfigBool("Disassembler", "Uppercase"))
|
if(ConfigBool("Disassembler", "Uppercase"))
|
||||||
actual_inst = actual_inst.toUpper().replace(QRegularExpression("0X([0-9A-F]+)"), "0x\\1");
|
actual_inst = actual_inst.toUpper().replace(QRegularExpression("0X([0-9A-F]+)"), "0x\\1");
|
||||||
assembleDialog.setTextEditValue(actual_inst);
|
assembleDialog.setTextEditValue(actual_inst);
|
||||||
|
@ -937,7 +938,7 @@ void CPUDisassembly::assembleSlot()
|
||||||
if(expression == QString("???") || expression.toLower() == instr.instStr.toLower() || expression == QString(""))
|
if(expression == QString("???") || expression.toLower() == instr.instStr.toLower() || expression == QString(""))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if(!DbgFunctions()->AssembleAtEx(wVA, expression.toUtf8().constData(), error, assembleDialog.bFillWithNopsChecked))
|
if(!DbgFunctions()->AssembleAtEx(va, expression.toUtf8().constData(), error, assembleDialog.bFillWithNopsChecked))
|
||||||
{
|
{
|
||||||
QMessageBox msg(QMessageBox::Critical, tr("Error!"), tr("Failed to assemble instruction \" %1 \" (%2)").arg(expression).arg(error));
|
QMessageBox msg(QMessageBox::Critical, tr("Error!"), tr("Failed to assemble instruction \" %1 \" (%2)").arg(expression).arg(error));
|
||||||
msg.setWindowIcon(DIcon("compile-error"));
|
msg.setWindowIcon(DIcon("compile-error"));
|
||||||
|
@ -951,20 +952,20 @@ void CPUDisassembly::assembleSlot()
|
||||||
while(assembly_error);
|
while(assembly_error);
|
||||||
|
|
||||||
//select next instruction after assembling
|
//select next instruction after assembling
|
||||||
setSingleSelection(wRVA);
|
setSingleSelection(rva);
|
||||||
|
|
||||||
dsint botRVA = getTableOffset();
|
auto botRVA = getTableOffset();
|
||||||
dsint topRVA = getInstructionRVA(getTableOffset(), getNbrOfLineToPrint() - 1);
|
auto topRVA = getInstructionRVA(getTableOffset(), getNbrOfLineToPrint() - 1);
|
||||||
|
|
||||||
dsint wInstrSize = getInstructionRVA(wRVA, 1) - wRVA - 1;
|
// TODO: this seems dumb
|
||||||
|
auto instrSize = getInstructionRVA(rva, 1) - rva - 1;
|
||||||
expandSelectionUpTo(wRVA + wInstrSize);
|
expandSelectionUpTo(rva + instrSize);
|
||||||
selectNext(false);
|
selectNext(false);
|
||||||
|
|
||||||
if(getSelectionStart() < botRVA)
|
if(getSelectionStart() < botRVA)
|
||||||
setTableOffset(getSelectionStart());
|
setTableOffset(getSelectionStart());
|
||||||
else if(getSelectionEnd() >= topRVA)
|
else if(getSelectionEnd() >= topRVA)
|
||||||
setTableOffset(getInstructionRVA(getSelectionEnd(), -getNbrOfLineToPrint() + 2));
|
setTableOffset(getInstructionRVA(getSelectionEnd(), -(dsint)getNbrOfLineToPrint() + 2));
|
||||||
|
|
||||||
//refresh view
|
//refresh view
|
||||||
GuiUpdateAllViews();
|
GuiUpdateAllViews();
|
||||||
|
@ -1533,7 +1534,8 @@ void CPUDisassembly::pushSelectionInto(bool copyBytes, QTextStream & stream, QTe
|
||||||
if(i)
|
if(i)
|
||||||
stream << "\r\n";
|
stream << "\r\n";
|
||||||
duint cur_addr = rvaToVa(inst.rva);
|
duint cur_addr = rvaToVa(inst.rva);
|
||||||
QString address = getAddrText(cur_addr, 0, addressLen > sizeof(duint) * 2 + 1);
|
QString label;
|
||||||
|
QString address = getAddrText(cur_addr, label, addressLen > sizeof(duint) * 2 + 1);
|
||||||
QString bytes;
|
QString bytes;
|
||||||
QString bytesHtml;
|
QString bytesHtml;
|
||||||
if(copyBytes)
|
if(copyBytes)
|
||||||
|
|
|
@ -13,7 +13,7 @@ class CPUDisassembly : public Disassembly
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CPUDisassembly(QWidget* parent, bool isMain);
|
CPUDisassembly(Architecture* architecture, bool isMain, QWidget* parent = nullptr);
|
||||||
|
|
||||||
// Mouse management
|
// Mouse management
|
||||||
void contextMenuEvent(QContextMenuEvent* event);
|
void contextMenuEvent(QContextMenuEvent* event);
|
||||||
|
@ -22,8 +22,8 @@ public:
|
||||||
|
|
||||||
// Context menu management
|
// Context menu management
|
||||||
void setupRightClickContextMenu();
|
void setupRightClickContextMenu();
|
||||||
void addFollowReferenceMenuItem(QString name, dsint value, QMenu* menu, bool isReferences, bool isFollowInCPU);
|
void addFollowReferenceMenuItem(QString name, duint value, QMenu* menu, bool isReferences, bool isFollowInCPU);
|
||||||
void setupFollowReferenceMenu(dsint wVA, QMenu* menu, bool isReferences, bool isFollowInCPU);
|
void setupFollowReferenceMenu(duint va, QMenu* menu, bool isReferences, bool isFollowInCPU);
|
||||||
void copySelectionSlot(bool copyBytes);
|
void copySelectionSlot(bool copyBytes);
|
||||||
void copySelectionToFileSlot(bool copyBytes);
|
void copySelectionToFileSlot(bool copyBytes);
|
||||||
void setSideBar(CPUSideBar* sideBar);
|
void setSideBar(CPUSideBar* sideBar);
|
||||||
|
|
|
@ -15,11 +15,11 @@
|
||||||
#include "MiscUtil.h"
|
#include "MiscUtil.h"
|
||||||
#include "BackgroundFlickerThread.h"
|
#include "BackgroundFlickerThread.h"
|
||||||
|
|
||||||
CPUDump::CPUDump(CPUDisassembly* disas, CPUMultiDump* multiDump, QWidget* parent) : HexDump(parent)
|
CPUDump::CPUDump(CPUMultiDump* multiDump, CPUDisassembly* disassembly, QWidget* parent)
|
||||||
|
: HexDump(multiDump->getArchitecture(), parent),
|
||||||
|
mMultiDump(multiDump),
|
||||||
|
mDisassembly(disassembly)
|
||||||
{
|
{
|
||||||
mDisas = disas;
|
|
||||||
mMultiDump = multiDump;
|
|
||||||
|
|
||||||
duint setting;
|
duint setting;
|
||||||
if(BridgeSettingGetUint("Gui", "AsciiSeparator", &setting))
|
if(BridgeSettingGetUint("Gui", "AsciiSeparator", &setting))
|
||||||
mAsciiSeparator = setting & 0xF;
|
mAsciiSeparator = setting & 0xF;
|
||||||
|
@ -27,7 +27,7 @@ CPUDump::CPUDump(CPUDisassembly* disas, CPUMultiDump* multiDump, QWidget* parent
|
||||||
setView((ViewEnum_t)ConfigUint("HexDump", "DefaultView"));
|
setView((ViewEnum_t)ConfigUint("HexDump", "DefaultView"));
|
||||||
|
|
||||||
connect(this, SIGNAL(selectionUpdated()), this, SLOT(selectionUpdatedSlot()));
|
connect(this, SIGNAL(selectionUpdated()), this, SLOT(selectionUpdatedSlot()));
|
||||||
connect(this, SIGNAL(headerButtonReleased(int)), this, SLOT(headerButtonReleasedSlot(int)));
|
connect(this, SIGNAL(headerButtonReleased(duint)), this, SLOT(headerButtonReleasedSlot(duint)));
|
||||||
|
|
||||||
mPluginMenu = multiDump->mDumpPluginMenu;
|
mPluginMenu = multiDump->mDumpPluginMenu;
|
||||||
|
|
||||||
|
@ -263,7 +263,7 @@ void CPUDump::getAttention()
|
||||||
thread->start();
|
thread->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPUDump::getColumnRichText(int col, dsint rva, RichTextPainter::List & richText)
|
void CPUDump::getColumnRichText(duint col, duint rva, RichTextPainter::List & richText)
|
||||||
{
|
{
|
||||||
if(col && !mDescriptor.at(col - 1).isData && mDescriptor.at(col - 1).itemCount) //print comments
|
if(col && !mDescriptor.at(col - 1).isData && mDescriptor.at(col - 1).itemCount) //print comments
|
||||||
{
|
{
|
||||||
|
@ -308,16 +308,17 @@ void CPUDump::getColumnRichText(int col, dsint rva, RichTextPainter::List & rich
|
||||||
HexDump::getColumnRichText(col, rva, richText);
|
HexDump::getColumnRichText(col, rva, richText);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CPUDump::paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h)
|
QString CPUDump::paintContent(QPainter* painter, duint row, duint col, int x, int y, int w, int h)
|
||||||
{
|
{
|
||||||
// Reset byte offset when base address is reached
|
// Reset byte offset when base address is reached
|
||||||
if(rowBase == 0 && mByteOffset != 0)
|
// TODO: wtf?
|
||||||
|
if(getTableOffset() == 0 && mByteOffset != 0)
|
||||||
printDumpAt(mMemPage->getBase(), false, false);
|
printDumpAt(mMemPage->getBase(), false, false);
|
||||||
|
|
||||||
if(!col) //address
|
if(!col) //address
|
||||||
{
|
{
|
||||||
char label[MAX_LABEL_SIZE] = "";
|
char label[MAX_LABEL_SIZE] = "";
|
||||||
dsint cur_addr = rvaToVa((rowBase + rowOffset) * getBytePerRowCount() - mByteOffset);
|
dsint cur_addr = rvaToVa(row * getBytePerRowCount() - mByteOffset);
|
||||||
QColor background;
|
QColor background;
|
||||||
if(DbgGetLabelAt(cur_addr, SEG_DEFAULT, label)) //label
|
if(DbgGetLabelAt(cur_addr, SEG_DEFAULT, label)) //label
|
||||||
{
|
{
|
||||||
|
@ -334,7 +335,7 @@ QString CPUDump::paintContent(QPainter* painter, dsint rowBase, int rowOffset, i
|
||||||
painter->drawText(QRect(x + 4, y, w - 4, h), Qt::AlignVCenter | Qt::AlignLeft, makeAddrText(cur_addr));
|
painter->drawText(QRect(x + 4, y, w - 4, h), Qt::AlignVCenter | Qt::AlignLeft, makeAddrText(cur_addr));
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
return HexDump::paintContent(painter, rowBase, rowOffset, col, x, y, w, h);
|
return HexDump::paintContent(painter, row, col, x, y, w, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPUDump::contextMenuEvent(QContextMenuEvent* event)
|
void CPUDump::contextMenuEvent(QContextMenuEvent* event)
|
||||||
|
@ -1327,7 +1328,7 @@ void CPUDump::findReferencesSlot()
|
||||||
{
|
{
|
||||||
QString addrStart = ToPtrString(rvaToVa(getSelectionStart()));
|
QString addrStart = ToPtrString(rvaToVa(getSelectionStart()));
|
||||||
QString addrEnd = ToPtrString(rvaToVa(getSelectionEnd()));
|
QString addrEnd = ToPtrString(rvaToVa(getSelectionEnd()));
|
||||||
QString addrDisasm = ToPtrString(mDisas->rvaToVa(mDisas->getSelectionStart()));
|
QString addrDisasm = ToPtrString(mDisassembly->rvaToVa(mDisassembly->getSelectionStart()));
|
||||||
DbgCmdExec(QString("findrefrange " + addrStart + ", " + addrEnd + ", " + addrDisasm));
|
DbgCmdExec(QString("findrefrange " + addrStart + ", " + addrEnd + ", " + addrDisasm));
|
||||||
emit displayReferencesWidget();
|
emit displayReferencesWidget();
|
||||||
}
|
}
|
||||||
|
@ -1611,7 +1612,7 @@ void CPUDump::setView(ViewEnum_t view)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPUDump::headerButtonReleasedSlot(int colIndex)
|
void CPUDump::headerButtonReleasedSlot(duint colIndex)
|
||||||
{
|
{
|
||||||
auto callback = mDescriptor[colIndex].columnSwitch;
|
auto callback = mDescriptor[colIndex].columnSwitch;
|
||||||
if(callback)
|
if(callback)
|
||||||
|
|
|
@ -12,9 +12,9 @@ class CPUDump : public HexDump
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit CPUDump(CPUDisassembly* disas, CPUMultiDump* multiDump, QWidget* parent = 0);
|
explicit CPUDump(CPUMultiDump* multiDump, CPUDisassembly* disasassembly, QWidget* parent = nullptr);
|
||||||
void getColumnRichText(int col, dsint rva, RichTextPainter::List & richText) override;
|
void getColumnRichText(duint col, duint rva, RichTextPainter::List & richText) override;
|
||||||
QString paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h);
|
QString paintContent(QPainter* painter, duint row, duint col, int x, int y, int w, int h) override;
|
||||||
void setupContextMenu();
|
void setupContextMenu();
|
||||||
void getAttention();
|
void getAttention();
|
||||||
void contextMenuEvent(QContextMenuEvent* event) override;
|
void contextMenuEvent(QContextMenuEvent* event) override;
|
||||||
|
@ -82,7 +82,7 @@ public slots:
|
||||||
void syncWithExpressionSlot();
|
void syncWithExpressionSlot();
|
||||||
void allocMemorySlot();
|
void allocMemorySlot();
|
||||||
|
|
||||||
void headerButtonReleasedSlot(int colIndex);
|
void headerButtonReleasedSlot(duint colIndex);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MenuBuilder* mMenuBuilder;
|
MenuBuilder* mMenuBuilder;
|
||||||
|
@ -94,8 +94,8 @@ private:
|
||||||
|
|
||||||
GotoDialog* mGoto = nullptr;
|
GotoDialog* mGoto = nullptr;
|
||||||
GotoDialog* mGotoOffset = nullptr;
|
GotoDialog* mGotoOffset = nullptr;
|
||||||
CPUDisassembly* mDisas;
|
CPUDisassembly* mDisassembly = nullptr;
|
||||||
CPUMultiDump* mMultiDump;
|
CPUMultiDump* mMultiDump = nullptr;
|
||||||
int mAsciiSeparator = 0;
|
int mAsciiSeparator = 0;
|
||||||
|
|
||||||
enum ViewEnum_t
|
enum ViewEnum_t
|
||||||
|
|
|
@ -5,7 +5,9 @@
|
||||||
#include "Bridge.h"
|
#include "Bridge.h"
|
||||||
#include "QZydis.h"
|
#include "QZydis.h"
|
||||||
|
|
||||||
CPUInfoBox::CPUInfoBox(QWidget* parent) : StdTable(parent)
|
CPUInfoBox::CPUInfoBox(Architecture* architecture, QWidget* parent)
|
||||||
|
: StdTable(parent),
|
||||||
|
mArchitecture(architecture)
|
||||||
{
|
{
|
||||||
setWindowTitle("InfoBox");
|
setWindowTitle("InfoBox");
|
||||||
enableMultiSelection(false);
|
enableMultiSelection(false);
|
||||||
|
@ -32,7 +34,7 @@ CPUInfoBox::CPUInfoBox(QWidget* parent) : StdTable(parent)
|
||||||
setSingleSelection(-1);
|
setSingleSelection(-1);
|
||||||
|
|
||||||
int maxModuleSize = (int)ConfigUint("Disassembler", "MaxModuleSize");
|
int maxModuleSize = (int)ConfigUint("Disassembler", "MaxModuleSize");
|
||||||
mDisasm = new QZydis(maxModuleSize, Bridge::getArch());
|
mDisasm = new QZydis(maxModuleSize, architecture);
|
||||||
|
|
||||||
setupContextMenu();
|
setupContextMenu();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "StdTable.h"
|
#include "StdTable.h"
|
||||||
|
#include "Architecture.h"
|
||||||
|
|
||||||
class WordEditDialog;
|
class WordEditDialog;
|
||||||
class XrefBrowseDialog;
|
class XrefBrowseDialog;
|
||||||
|
@ -10,7 +11,7 @@ class CPUInfoBox : public StdTable
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit CPUInfoBox(QWidget* parent = 0);
|
CPUInfoBox(Architecture* architecture, QWidget* parent = nullptr);
|
||||||
~CPUInfoBox();
|
~CPUInfoBox();
|
||||||
int getHeight();
|
int getHeight();
|
||||||
void addFollowMenuItem(QMenu* menu, QString name, duint value);
|
void addFollowMenuItem(QMenu* menu, QString name, duint value);
|
||||||
|
@ -37,6 +38,7 @@ public slots:
|
||||||
void addInfoLine(const QString & infoLine);
|
void addInfoLine(const QString & infoLine);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Architecture* mArchitecture = nullptr;
|
||||||
duint mCurAddr = 0;
|
duint mCurAddr = 0;
|
||||||
duint mCurRva = 0;
|
duint mCurRva = 0;
|
||||||
duint mCurOffset = 0;
|
duint mCurOffset = 0;
|
||||||
|
|
|
@ -9,8 +9,9 @@
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QTabBar>
|
#include <QTabBar>
|
||||||
|
|
||||||
CPUMultiDump::CPUMultiDump(CPUDisassembly* disas, int nbCpuDumpTabs, QWidget* parent)
|
CPUMultiDump::CPUMultiDump(CPUDisassembly* disassembly, int nbCpuDumpTabs, QWidget* parent)
|
||||||
: MHTabWidget(parent, true)
|
: MHTabWidget(parent, true),
|
||||||
|
mMainDisassembly(disassembly)
|
||||||
{
|
{
|
||||||
setWindowTitle("CPUMultiDump");
|
setWindowTitle("CPUMultiDump");
|
||||||
mMaxCPUDumpTabs = nbCpuDumpTabs;
|
mMaxCPUDumpTabs = nbCpuDumpTabs;
|
||||||
|
@ -22,7 +23,7 @@ CPUMultiDump::CPUMultiDump(CPUDisassembly* disas, int nbCpuDumpTabs, QWidget* pa
|
||||||
|
|
||||||
for(uint i = 0; i < mMaxCPUDumpTabs; i++)
|
for(uint i = 0; i < mMaxCPUDumpTabs; i++)
|
||||||
{
|
{
|
||||||
CPUDump* cpuDump = new CPUDump(disas, this);
|
CPUDump* cpuDump = new CPUDump(this, mMainDisassembly);
|
||||||
//cpuDump->loadColumnFromConfig(QString("CPUDump%1").arg(i + 1)); //TODO: needs a workaround because the columns change
|
//cpuDump->loadColumnFromConfig(QString("CPUDump%1").arg(i + 1)); //TODO: needs a workaround because the columns change
|
||||||
connect(cpuDump, SIGNAL(displayReferencesWidget()), this, SLOT(displayReferencesWidgetSlot()));
|
connect(cpuDump, SIGNAL(displayReferencesWidget()), this, SLOT(displayReferencesWidgetSlot()));
|
||||||
connect(cpuDump, SIGNAL(showDisassemblyTab(duint, duint, duint)), this, SLOT(showDisassemblyTabSlot(duint, duint, duint)));
|
connect(cpuDump, SIGNAL(showDisassemblyTab(duint, duint, duint)), this, SLOT(showDisassemblyTabSlot(duint, duint, duint)));
|
||||||
|
@ -50,7 +51,7 @@ CPUMultiDump::CPUMultiDump(CPUDisassembly* disas, int nbCpuDumpTabs, QWidget* pa
|
||||||
connect(this, SIGNAL(currentChanged(int)), this, SLOT(updateCurrentTabSlot(int)));
|
connect(this, SIGNAL(currentChanged(int)), this, SLOT(updateCurrentTabSlot(int)));
|
||||||
connect(tabBar(), SIGNAL(OnDoubleClickTabIndex(int)), this, SLOT(openChangeTabTitleDialogSlot(int)));
|
connect(tabBar(), SIGNAL(OnDoubleClickTabIndex(int)), this, SLOT(openChangeTabTitleDialogSlot(int)));
|
||||||
|
|
||||||
connect(Bridge::getBridge(), SIGNAL(dumpAt(dsint)), this, SLOT(printDumpAtSlot(dsint)));
|
connect(Bridge::getBridge(), SIGNAL(dumpAt(duint)), this, SLOT(printDumpAtSlot(duint)));
|
||||||
connect(Bridge::getBridge(), SIGNAL(dumpAtN(duint, int)), this, SLOT(printDumpAtNSlot(duint, int)));
|
connect(Bridge::getBridge(), SIGNAL(dumpAtN(duint, int)), this, SLOT(printDumpAtNSlot(duint, int)));
|
||||||
connect(Bridge::getBridge(), SIGNAL(selectionDumpGet(SELECTIONDATA*)), this, SLOT(selectionGetSlot(SELECTIONDATA*)));
|
connect(Bridge::getBridge(), SIGNAL(selectionDumpGet(SELECTIONDATA*)), this, SLOT(selectionGetSlot(SELECTIONDATA*)));
|
||||||
connect(Bridge::getBridge(), SIGNAL(selectionDumpSet(const SELECTIONDATA*)), this, SLOT(selectionSetSlot(const SELECTIONDATA*)));
|
connect(Bridge::getBridge(), SIGNAL(selectionDumpSet(const SELECTIONDATA*)), this, SLOT(selectionSetSlot(const SELECTIONDATA*)));
|
||||||
|
@ -61,6 +62,11 @@ CPUMultiDump::CPUMultiDump(CPUDisassembly* disas, int nbCpuDumpTabs, QWidget* pa
|
||||||
connect(mCurrentCPUDump, SIGNAL(selectionUpdated()), mCurrentCPUDump, SLOT(selectionUpdatedSlot()));
|
connect(mCurrentCPUDump, SIGNAL(selectionUpdated()), mCurrentCPUDump, SLOT(selectionUpdatedSlot()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Architecture* CPUMultiDump::getArchitecture() const
|
||||||
|
{
|
||||||
|
return mMainDisassembly->getArchitecture();
|
||||||
|
}
|
||||||
|
|
||||||
CPUDump* CPUMultiDump::getCurrentCPUDump()
|
CPUDump* CPUMultiDump::getCurrentCPUDump()
|
||||||
{
|
{
|
||||||
return mCurrentCPUDump;
|
return mCurrentCPUDump;
|
||||||
|
@ -152,7 +158,7 @@ void CPUMultiDump::updateCurrentTabSlot(int tabIndex)
|
||||||
mCurrentCPUDump = t;
|
mCurrentCPUDump = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPUMultiDump::printDumpAtSlot(dsint parVa)
|
void CPUMultiDump::printDumpAtSlot(duint va)
|
||||||
{
|
{
|
||||||
if(mInitAllDumpTabs)
|
if(mInitAllDumpTabs)
|
||||||
{
|
{
|
||||||
|
@ -165,8 +171,8 @@ void CPUMultiDump::printDumpAtSlot(dsint parVa)
|
||||||
if(cpuDump)
|
if(cpuDump)
|
||||||
{
|
{
|
||||||
cpuDump->mHistory.historyClear();
|
cpuDump->mHistory.historyClear();
|
||||||
cpuDump->mHistory.addVaToHistory(parVa);
|
cpuDump->mHistory.addVaToHistory(va);
|
||||||
cpuDump->printDumpAt(parVa);
|
cpuDump->printDumpAt(va);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,12 +181,12 @@ void CPUMultiDump::printDumpAtSlot(dsint parVa)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SwitchToDumpWindow();
|
SwitchToDumpWindow();
|
||||||
mCurrentCPUDump->printDumpAt(parVa);
|
mCurrentCPUDump->printDumpAt(va);
|
||||||
mCurrentCPUDump->mHistory.addVaToHistory(parVa);
|
mCurrentCPUDump->mHistory.addVaToHistory(va);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPUMultiDump::printDumpAtNSlot(duint parVa, int index)
|
void CPUMultiDump::printDumpAtNSlot(duint va, int index)
|
||||||
{
|
{
|
||||||
int tabindex = GetDumpWindowIndex(index);
|
int tabindex = GetDumpWindowIndex(index);
|
||||||
if(tabindex == 2147483647)
|
if(tabindex == 2147483647)
|
||||||
|
@ -189,8 +195,8 @@ void CPUMultiDump::printDumpAtNSlot(duint parVa, int index)
|
||||||
if(!current)
|
if(!current)
|
||||||
return;
|
return;
|
||||||
setCurrentIndex(tabindex);
|
setCurrentIndex(tabindex);
|
||||||
current->printDumpAt(parVa);
|
current->printDumpAt(va);
|
||||||
current->mHistory.addVaToHistory(parVa);
|
current->mHistory.addVaToHistory(va);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPUMultiDump::selectionGetSlot(SELECTIONDATA* selectionData)
|
void CPUMultiDump::selectionGetSlot(SELECTIONDATA* selectionData)
|
||||||
|
@ -238,23 +244,23 @@ void CPUMultiDump::focusCurrentDumpSlot()
|
||||||
void CPUMultiDump::showDisassemblyTabSlot(duint selectionStart, duint selectionEnd, duint firstAddress)
|
void CPUMultiDump::showDisassemblyTabSlot(duint selectionStart, duint selectionEnd, duint firstAddress)
|
||||||
{
|
{
|
||||||
Q_UNUSED(firstAddress); // TODO: implement setTableOffset(firstAddress)
|
Q_UNUSED(firstAddress); // TODO: implement setTableOffset(firstAddress)
|
||||||
if(!mDisassembly)
|
if(!mExtraDisassembly)
|
||||||
{
|
{
|
||||||
mDisassembly = new CPUDisassembly(this, false);
|
mExtraDisassembly = new CPUDisassembly(mMainDisassembly->getArchitecture(), false, this);
|
||||||
this->addTabEx(mDisassembly, DIcon(ArchValue("processor32", "processor64")), tr("Disassembly"), "DumpDisassembly");
|
this->addTabEx(mExtraDisassembly, DIcon(ArchValue("processor32", "processor64")), tr("Disassembly"), "DumpDisassembly");
|
||||||
}
|
}
|
||||||
// Set CIP
|
// Set CIP
|
||||||
auto clearHistory = mDisassembly->getBase() == 0;
|
auto clearHistory = mExtraDisassembly->getBase() == 0;
|
||||||
mDisassembly->disassembleAtSlot(selectionStart, Bridge::getBridge()->mLastCip);
|
mExtraDisassembly->disassembleAtSlot(selectionStart, Bridge::getBridge()->mLastCip);
|
||||||
if(clearHistory)
|
if(clearHistory)
|
||||||
mDisassembly->historyClear();
|
mExtraDisassembly->historyClear();
|
||||||
// Make the address visisble in memory
|
// Make the address visisble in memory
|
||||||
mDisassembly->disassembleAt(selectionStart, true, -1);
|
mExtraDisassembly->disassembleAt(selectionStart, true, -1);
|
||||||
// Set selection to match the dump
|
// Set selection to match the dump
|
||||||
mDisassembly->setSingleSelection(selectionStart - mDisassembly->getBase());
|
mExtraDisassembly->setSingleSelection(selectionStart - mExtraDisassembly->getBase());
|
||||||
mDisassembly->expandSelectionUpTo(selectionEnd - mDisassembly->getBase());
|
mExtraDisassembly->expandSelectionUpTo(selectionEnd - mExtraDisassembly->getBase());
|
||||||
// Show the tab
|
// Show the tab
|
||||||
setCurrentWidget(mDisassembly);
|
setCurrentWidget(mExtraDisassembly);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPUMultiDump::getDumpAttention()
|
void CPUMultiDump::getDumpAttention()
|
||||||
|
|
|
@ -14,11 +14,12 @@ class CPUMultiDump : public MHTabWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit CPUMultiDump(CPUDisassembly* disas, int nbCpuDumpTabs = 1, QWidget* parent = 0);
|
explicit CPUMultiDump(CPUDisassembly* disassembly, int nbCpuDumpTabs = 1, QWidget* parent = nullptr);
|
||||||
|
Architecture* getArchitecture() const;
|
||||||
CPUDump* getCurrentCPUDump();
|
CPUDump* getCurrentCPUDump();
|
||||||
void getTabNames(QList<QString> & names);
|
void getTabNames(QList<QString> & names);
|
||||||
int getMaxCPUTabs();
|
int getMaxCPUTabs();
|
||||||
QMenu* mDumpPluginMenu;
|
QMenu* mDumpPluginMenu; // TODO: no
|
||||||
void saveWindowSettings();
|
void saveWindowSettings();
|
||||||
void loadWindowSettings();
|
void loadWindowSettings();
|
||||||
|
|
||||||
|
@ -27,8 +28,8 @@ signals:
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void updateCurrentTabSlot(int tabIndex);
|
void updateCurrentTabSlot(int tabIndex);
|
||||||
void printDumpAtSlot(dsint parVa);
|
void printDumpAtSlot(duint va);
|
||||||
void printDumpAtNSlot(duint parVa, int index);
|
void printDumpAtNSlot(duint va, int index);
|
||||||
void selectionGetSlot(SELECTIONDATA* selectionData);
|
void selectionGetSlot(SELECTIONDATA* selectionData);
|
||||||
void selectionSetSlot(const SELECTIONDATA* selectionData);
|
void selectionSetSlot(const SELECTIONDATA* selectionData);
|
||||||
void dbgStateChangedSlot(DBGSTATE dbgState);
|
void dbgStateChangedSlot(DBGSTATE dbgState);
|
||||||
|
@ -46,7 +47,8 @@ private:
|
||||||
WatchView* mWatch;
|
WatchView* mWatch;
|
||||||
LocalVarsView* mLocalVars;
|
LocalVarsView* mLocalVars;
|
||||||
StructWidget* mStructWidget;
|
StructWidget* mStructWidget;
|
||||||
CPUDisassembly* mDisassembly = nullptr;
|
CPUDisassembly* mMainDisassembly = nullptr;
|
||||||
|
CPUDisassembly* mExtraDisassembly = nullptr;
|
||||||
|
|
||||||
int GetDumpWindowIndex(int dump);
|
int GetDumpWindowIndex(int dump);
|
||||||
int GetWatchWindowIndex();
|
int GetWatchWindowIndex();
|
||||||
|
|
|
@ -37,7 +37,7 @@ CPURegistersView::CPURegistersView(CPUWidget* parent) : RegistersView(parent), m
|
||||||
connect(Bridge::getBridge(), SIGNAL(updateRegisters()), this, SLOT(updateRegistersSlot()));
|
connect(Bridge::getBridge(), SIGNAL(updateRegisters()), this, SLOT(updateRegistersSlot()));
|
||||||
connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(displayCustomContextMenuSlot(QPoint)));
|
connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(displayCustomContextMenuSlot(QPoint)));
|
||||||
connect(Bridge::getBridge(), SIGNAL(dbgStateChanged(DBGSTATE)), this, SLOT(debugStateChangedSlot(DBGSTATE)));
|
connect(Bridge::getBridge(), SIGNAL(dbgStateChanged(DBGSTATE)), this, SLOT(debugStateChangedSlot(DBGSTATE)));
|
||||||
connect(parent->getDisasmWidget(), SIGNAL(selectionChanged(dsint)), this, SLOT(disasmSelectionChangedSlot(dsint)));
|
connect(parent->getDisasmWidget(), SIGNAL(selectionChanged(duint)), this, SLOT(disasmSelectionChangedSlot(duint)));
|
||||||
// context menu actions
|
// context menu actions
|
||||||
connect(wCM_Incrementx87Stack, SIGNAL(triggered()), this, SLOT(onIncrementx87StackAction()));
|
connect(wCM_Incrementx87Stack, SIGNAL(triggered()), this, SLOT(onIncrementx87StackAction()));
|
||||||
connect(wCM_Decrementx87Stack, SIGNAL(triggered()), this, SLOT(onDecrementx87StackAction()));
|
connect(wCM_Decrementx87Stack, SIGNAL(triggered()), this, SLOT(onDecrementx87StackAction()));
|
||||||
|
|
|
@ -215,7 +215,7 @@ void CPUSideBar::paintEvent(QPaintEvent* event)
|
||||||
std::vector<JumpLine> jumpLines;
|
std::vector<JumpLine> jumpLines;
|
||||||
std::vector<LabelArrow> labelArrows;
|
std::vector<LabelArrow> labelArrows;
|
||||||
|
|
||||||
for(int line = 0; line < mViewableRows; line++)
|
for(duint line = 0; line < mViewableRows; line++)
|
||||||
{
|
{
|
||||||
if(line >= mInstrBuffer->size()) //at the end of the page it will crash otherwise
|
if(line >= mInstrBuffer->size()) //at the end of the page it will crash otherwise
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -9,7 +9,8 @@
|
||||||
#include "CPUMultiDump.h"
|
#include "CPUMultiDump.h"
|
||||||
#include "GotoDialog.h"
|
#include "GotoDialog.h"
|
||||||
|
|
||||||
CPUStack::CPUStack(CPUMultiDump* multiDump, QWidget* parent) : HexDump(parent)
|
CPUStack::CPUStack(CPUMultiDump* multiDump, QWidget* parent)
|
||||||
|
: HexDump(multiDump->getArchitecture(), parent)
|
||||||
{
|
{
|
||||||
setWindowTitle("Stack");
|
setWindowTitle("Stack");
|
||||||
setShowHeader(false);
|
setShowHeader(false);
|
||||||
|
@ -309,7 +310,7 @@ void CPUStack::updateFreezeStackAction()
|
||||||
mFreezeStack->setChecked(bStackFrozen);
|
mFreezeStack->setChecked(bStackFrozen);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPUStack::getColumnRichText(int col, dsint rva, RichTextPainter::List & richText)
|
void CPUStack::getColumnRichText(duint col, duint rva, RichTextPainter::List & richText)
|
||||||
{
|
{
|
||||||
// Compute VA
|
// Compute VA
|
||||||
duint va = rvaToVa(rva);
|
duint va = rvaToVa(rva);
|
||||||
|
@ -365,24 +366,24 @@ void CPUStack::getColumnRichText(int col, dsint rva, RichTextPainter::List & ric
|
||||||
HexDump::getColumnRichText(col, rva, richText);
|
HexDump::getColumnRichText(col, rva, richText);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CPUStack::paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h)
|
QString CPUStack::paintContent(QPainter* painter, duint row, duint col, int x, int y, int w, int h)
|
||||||
{
|
{
|
||||||
// Compute RVA
|
// Compute RVA
|
||||||
int wBytePerRowCount = getBytePerRowCount();
|
auto bytePerRowCount = getBytePerRowCount();
|
||||||
dsint wRva = (rowBase + rowOffset) * wBytePerRowCount - mByteOffset;
|
dsint rva = row * bytePerRowCount - mByteOffset;
|
||||||
duint wVa = rvaToVa(wRva);
|
duint va = rvaToVa(rva);
|
||||||
|
|
||||||
bool wIsSelected = isSelected(wRva);
|
bool rowSelected = isSelected(rva);
|
||||||
if(wIsSelected) //highlight if selected
|
if(rowSelected) //highlight if selected
|
||||||
painter->fillRect(QRect(x, y, w, h), QBrush(mSelectionColor));
|
painter->fillRect(QRect(x, y, w, h), QBrush(mSelectionColor));
|
||||||
|
|
||||||
if(col == 0) // paint stack address
|
if(col == 0) // paint stack address
|
||||||
{
|
{
|
||||||
QColor background;
|
QColor background;
|
||||||
char labelText[MAX_LABEL_SIZE] = "";
|
char labelText[MAX_LABEL_SIZE] = "";
|
||||||
if(DbgGetLabelAt(wVa, SEG_DEFAULT, labelText)) //label
|
if(DbgGetLabelAt(va, SEG_DEFAULT, labelText)) //label
|
||||||
{
|
{
|
||||||
if(wVa == mCsp) //CSP
|
if(va == mCsp) //CSP
|
||||||
{
|
{
|
||||||
background = ConfigColor("StackCspBackgroundColor");
|
background = ConfigColor("StackCspBackgroundColor");
|
||||||
painter->setPen(QPen(ConfigColor("StackCspColor")));
|
painter->setPen(QPen(ConfigColor("StackCspColor")));
|
||||||
|
@ -395,12 +396,12 @@ QString CPUStack::paintContent(QPainter* painter, dsint rowBase, int rowOffset,
|
||||||
}
|
}
|
||||||
else //no label
|
else //no label
|
||||||
{
|
{
|
||||||
if(wVa == mCsp) //CSP
|
if(va == mCsp) //CSP
|
||||||
{
|
{
|
||||||
background = ConfigColor("StackCspBackgroundColor");
|
background = ConfigColor("StackCspBackgroundColor");
|
||||||
painter->setPen(QPen(ConfigColor("StackCspColor")));
|
painter->setPen(QPen(ConfigColor("StackCspColor")));
|
||||||
}
|
}
|
||||||
else if(wIsSelected) //selected normal address
|
else if(rowSelected) //selected normal address
|
||||||
{
|
{
|
||||||
background = ConfigColor("StackSelectedAddressBackgroundColor");
|
background = ConfigColor("StackSelectedAddressBackgroundColor");
|
||||||
painter->setPen(QPen(ConfigColor("StackSelectedAddressColor"))); //black address (DisassemblySelectedAddressColor)
|
painter->setPen(QPen(ConfigColor("StackSelectedAddressColor"))); //black address (DisassemblySelectedAddressColor)
|
||||||
|
@ -413,7 +414,7 @@ QString CPUStack::paintContent(QPainter* painter, dsint rowBase, int rowOffset,
|
||||||
}
|
}
|
||||||
if(background.alpha())
|
if(background.alpha())
|
||||||
painter->fillRect(QRect(x, y, w, h), QBrush(background)); //fill background when defined
|
painter->fillRect(QRect(x, y, w, h), QBrush(background)); //fill background when defined
|
||||||
painter->drawText(QRect(x + 4, y, w - 4, h), Qt::AlignVCenter | Qt::AlignLeft, makeAddrText(wVa));
|
painter->drawText(QRect(x + 4, y, w - 4, h), Qt::AlignVCenter | Qt::AlignLeft, makeAddrText(va));
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
else if(col == 1) // paint stack data
|
else if(col == 1) // paint stack data
|
||||||
|
@ -422,14 +423,14 @@ QString CPUStack::paintContent(QPainter* painter, dsint rowBase, int rowOffset,
|
||||||
{
|
{
|
||||||
int stackFrameBitfield = 0; // 0:none, 1:top of stack frame, 2:bottom of stack frame, 4:middle of stack frame
|
int stackFrameBitfield = 0; // 0:none, 1:top of stack frame, 2:bottom of stack frame, 4:middle of stack frame
|
||||||
int party = 0;
|
int party = 0;
|
||||||
if(wVa >= mCallstack[0].addr)
|
if(va >= mCallstack[0].addr)
|
||||||
{
|
{
|
||||||
for(size_t i = 0; i < mCallstack.size() - 1; i++)
|
for(size_t i = 0; i < mCallstack.size() - 1; i++)
|
||||||
{
|
{
|
||||||
if(wVa >= mCallstack[i].addr && wVa < mCallstack[i + 1].addr)
|
if(va >= mCallstack[i].addr && va < mCallstack[i + 1].addr)
|
||||||
{
|
{
|
||||||
stackFrameBitfield |= (mCallstack[i].addr == wVa) ? 1 : 0;
|
stackFrameBitfield |= (mCallstack[i].addr == va) ? 1 : 0;
|
||||||
stackFrameBitfield |= (mCallstack[i + 1].addr == wVa + sizeof(duint)) ? 2 : 0;
|
stackFrameBitfield |= (mCallstack[i + 1].addr == va + sizeof(duint)) ? 2 : 0;
|
||||||
if(stackFrameBitfield == 0)
|
if(stackFrameBitfield == 0)
|
||||||
stackFrameBitfield = 4;
|
stackFrameBitfield = 4;
|
||||||
party = mCallstack[i].party;
|
party = mCallstack[i].party;
|
||||||
|
@ -438,14 +439,14 @@ QString CPUStack::paintContent(QPainter* painter, dsint rowBase, int rowOffset,
|
||||||
}
|
}
|
||||||
// draw stack frame
|
// draw stack frame
|
||||||
if(stackFrameBitfield == 0)
|
if(stackFrameBitfield == 0)
|
||||||
return HexDump::paintContent(painter, rowBase, rowOffset, 1, x, y, w, h);
|
return HexDump::paintContent(painter, row, 1, x, y, w, h);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int height = getRowHeight();
|
int height = getRowHeight();
|
||||||
int halfHeight = height / 2;
|
int halfHeight = height / 2;
|
||||||
int width = 5;
|
int width = 5;
|
||||||
int offset = 2;
|
int offset = 2;
|
||||||
auto result = HexDump::paintContent(painter, rowBase, rowOffset, 1, x + (width - 2), y, w - (width - 2), h);
|
auto result = HexDump::paintContent(painter, row, 1, x + (width - 2), y, w - (width - 2), h);
|
||||||
if(party == mod_user)
|
if(party == mod_user)
|
||||||
painter->setPen(QPen(mUserStackFrameColor, 2));
|
painter->setPen(QPen(mUserStackFrameColor, 2));
|
||||||
else
|
else
|
||||||
|
@ -468,13 +469,13 @@ QString CPUStack::paintContent(QPainter* painter, dsint rowBase, int rowOffset,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return HexDump::paintContent(painter, rowBase, rowOffset, 1, x, y, w, h);
|
return HexDump::paintContent(painter, row, 1, x, y, w, h);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return HexDump::paintContent(painter, rowBase, rowOffset, 1, x, y, w, h);
|
return HexDump::paintContent(painter, row, 1, x, y, w, h);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return HexDump::paintContent(painter, rowBase, rowOffset, col, x, y, w, h);
|
return HexDump::paintContent(painter, row, col, x, y, w, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPUStack::contextMenuEvent(QContextMenuEvent* event)
|
void CPUStack::contextMenuEvent(QContextMenuEvent* event)
|
||||||
|
@ -602,7 +603,7 @@ void CPUStack::updateSlot()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPUStack::disasmSelectionChanged(dsint parVA)
|
void CPUStack::disasmSelectionChanged(duint parVA)
|
||||||
{
|
{
|
||||||
// When the selected instruction is changed, select the argument that is in the stack.
|
// When the selected instruction is changed, select the argument that is in the stack.
|
||||||
DISASM_INSTR instr;
|
DISASM_INSTR instr;
|
||||||
|
|
|
@ -11,16 +11,16 @@ class CPUStack : public HexDump
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit CPUStack(CPUMultiDump* multiDump, QWidget* parent = 0);
|
explicit CPUStack(CPUMultiDump* multiDump, QWidget* parent = nullptr);
|
||||||
|
|
||||||
// Configuration
|
// Configuration
|
||||||
virtual void updateColors();
|
void updateColors() override;
|
||||||
virtual void updateFonts();
|
void updateFonts() override;
|
||||||
|
|
||||||
void getColumnRichText(int col, dsint rva, RichTextPainter::List & richText) override;
|
void getColumnRichText(duint col, duint rva, RichTextPainter::List & richText) override;
|
||||||
QString paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h) override;
|
QString paintContent(QPainter* painter, duint row, duint col, int x, int y, int w, int h) override;
|
||||||
void contextMenuEvent(QContextMenuEvent* event);
|
void contextMenuEvent(QContextMenuEvent* event) override;
|
||||||
void mouseDoubleClickEvent(QMouseEvent* event);
|
void mouseDoubleClickEvent(QMouseEvent* event) override;
|
||||||
void wheelEvent(QWheelEvent* event) override;
|
void wheelEvent(QWheelEvent* event) override;
|
||||||
void setupContextMenu();
|
void setupContextMenu();
|
||||||
void updateFreezeStackAction();
|
void updateFreezeStackAction();
|
||||||
|
@ -52,7 +52,7 @@ public slots:
|
||||||
void realignSlot();
|
void realignSlot();
|
||||||
void freezeStackSlot();
|
void freezeStackSlot();
|
||||||
void dbgStateChangedSlot(DBGSTATE state);
|
void dbgStateChangedSlot(DBGSTATE state);
|
||||||
void disasmSelectionChanged(dsint parVA);
|
void disasmSelectionChanged(duint parVA);
|
||||||
void updateSlot();
|
void updateSlot();
|
||||||
void copyPtrColumnSlot();
|
void copyPtrColumnSlot();
|
||||||
void copyCommentsColumnSlot();
|
void copyCommentsColumnSlot();
|
||||||
|
@ -82,5 +82,5 @@ private:
|
||||||
CommonActions* mCommonActions;
|
CommonActions* mCommonActions;
|
||||||
|
|
||||||
std::vector<CPUCallStack> mCallstack;
|
std::vector<CPUCallStack> mCallstack;
|
||||||
static int CPUStack::getCurrentFrame(const std::vector<CPUStack::CPUCallStack> & mCallstack, duint wVA);
|
static int CPUStack::getCurrentFrame(const std::vector<CPUStack::CPUCallStack> & mCallstack, duint va);
|
||||||
};
|
};
|
||||||
|
|
|
@ -14,22 +14,25 @@
|
||||||
#include "Configuration.h"
|
#include "Configuration.h"
|
||||||
#include "TabWidget.h"
|
#include "TabWidget.h"
|
||||||
|
|
||||||
CPUWidget::CPUWidget(QWidget* parent) : QWidget(parent), ui(new Ui::CPUWidget)
|
CPUWidget::CPUWidget(Architecture* architecture, QWidget* parent)
|
||||||
|
: QWidget(parent),
|
||||||
|
ui(new Ui::CPUWidget),
|
||||||
|
mArchitecture(architecture)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
setDefaultDisposition();
|
setDefaultDisposition();
|
||||||
|
|
||||||
setStyleSheet("AbstractTableView:focus, CPURegistersView:focus, CPUSideBar:focus { border: 1px solid #000000; }");
|
setStyleSheet("AbstractTableView:focus, CPURegistersView:focus, CPUSideBar:focus { border: 1px solid #000000; }");
|
||||||
|
|
||||||
mDisas = new CPUDisassembly(this, true);
|
mDisassembly = new CPUDisassembly(architecture, true, this);
|
||||||
mSideBar = new CPUSideBar(mDisas);
|
mSideBar = new CPUSideBar(mDisassembly);
|
||||||
mDisas->setSideBar(mSideBar);
|
mDisassembly->setSideBar(mSideBar);
|
||||||
mArgumentWidget = new CPUArgumentWidget(this);
|
mArgumentWidget = new CPUArgumentWidget(architecture, this);
|
||||||
mGraph = new DisassemblerGraphView(this);
|
mGraph = new DisassemblerGraphView(architecture, this);
|
||||||
|
|
||||||
connect(mDisas, SIGNAL(tableOffsetChanged(dsint)), mSideBar, SLOT(changeTopmostAddress(dsint)));
|
connect(mDisassembly, SIGNAL(tableOffsetChanged(duint)), mSideBar, SLOT(changeTopmostAddress(duint)));
|
||||||
connect(mDisas, SIGNAL(viewableRowsChanged(int)), mSideBar, SLOT(setViewableRows(int)));
|
connect(mDisassembly, SIGNAL(viewableRowsChanged(duint)), mSideBar, SLOT(setViewableRows(duint)));
|
||||||
connect(mDisas, SIGNAL(selectionChanged(dsint)), mSideBar, SLOT(setSelection(dsint)));
|
connect(mDisassembly, SIGNAL(selectionChanged(duint)), mSideBar, SLOT(setSelection(duint)));
|
||||||
connect(mGraph, SIGNAL(detachGraph()), this, SLOT(detachGraph()));
|
connect(mGraph, SIGNAL(detachGraph()), this, SLOT(detachGraph()));
|
||||||
connect(Bridge::getBridge(), SIGNAL(dbgStateChanged(DBGSTATE)), mSideBar, SLOT(debugStateChangedSlot(DBGSTATE)));
|
connect(Bridge::getBridge(), SIGNAL(dbgStateChanged(DBGSTATE)), mSideBar, SLOT(debugStateChangedSlot(DBGSTATE)));
|
||||||
connect(Bridge::getBridge(), SIGNAL(updateSideBar()), mSideBar, SLOT(reload()));
|
connect(Bridge::getBridge(), SIGNAL(updateSideBar()), mSideBar, SLOT(reload()));
|
||||||
|
@ -37,12 +40,12 @@ CPUWidget::CPUWidget(QWidget* parent) : QWidget(parent), ui(new Ui::CPUWidget)
|
||||||
connect(Bridge::getBridge(), SIGNAL(focusDisasm()), this, SLOT(setDisasmFocus()));
|
connect(Bridge::getBridge(), SIGNAL(focusDisasm()), this, SLOT(setDisasmFocus()));
|
||||||
connect(Bridge::getBridge(), SIGNAL(focusGraph()), this, SLOT(setGraphFocus()));
|
connect(Bridge::getBridge(), SIGNAL(focusGraph()), this, SLOT(setGraphFocus()));
|
||||||
|
|
||||||
mDisas->setCodeFoldingManager(mSideBar->getCodeFoldingManager());
|
mDisassembly->setCodeFoldingManager(mSideBar->getCodeFoldingManager());
|
||||||
|
|
||||||
ui->mTopLeftUpperHSplitter->setCollapsible(0, true); //allow collapsing of the side bar
|
ui->mTopLeftUpperHSplitter->setCollapsible(0, true); //allow collapsing of the side bar
|
||||||
|
|
||||||
ui->mTopLeftUpperLeftFrameLayout->addWidget(mSideBar);
|
ui->mTopLeftUpperLeftFrameLayout->addWidget(mSideBar);
|
||||||
ui->mTopLeftUpperRightFrameLayout->addWidget(mDisas);
|
ui->mTopLeftUpperRightFrameLayout->addWidget(mDisassembly);
|
||||||
ui->mTopLeftUpperRightFrameLayout->addWidget(mGraph);
|
ui->mTopLeftUpperRightFrameLayout->addWidget(mGraph);
|
||||||
mGraph->hide();
|
mGraph->hide();
|
||||||
disasMode = 0;
|
disasMode = 0;
|
||||||
|
@ -51,14 +54,14 @@ CPUWidget::CPUWidget(QWidget* parent) : QWidget(parent), ui(new Ui::CPUWidget)
|
||||||
ui->mTopLeftVSplitter->setCollapsible(1, true); //allow collapsing of the InfoBox
|
ui->mTopLeftVSplitter->setCollapsible(1, true); //allow collapsing of the InfoBox
|
||||||
connect(ui->mTopLeftVSplitter, SIGNAL(splitterMoved(int, int)), this, SLOT(splitterMoved(int, int)));
|
connect(ui->mTopLeftVSplitter, SIGNAL(splitterMoved(int, int)), this, SLOT(splitterMoved(int, int)));
|
||||||
|
|
||||||
mInfo = new CPUInfoBox();
|
mInfo = new CPUInfoBox(architecture);
|
||||||
ui->mTopLeftLowerFrameLayout->addWidget(mInfo);
|
ui->mTopLeftLowerFrameLayout->addWidget(mInfo);
|
||||||
int height = mInfo->getHeight();
|
int height = mInfo->getHeight();
|
||||||
ui->mTopLeftLowerFrame->setMinimumHeight(height + 2);
|
ui->mTopLeftLowerFrame->setMinimumHeight(height + 2);
|
||||||
|
|
||||||
connect(mDisas, SIGNAL(selectionChanged(dsint)), mInfo, SLOT(disasmSelectionChanged(dsint)));
|
connect(mDisassembly, SIGNAL(selectionChanged(duint)), mInfo, SLOT(disasmSelectionChanged(duint)));
|
||||||
|
|
||||||
mDump = new CPUMultiDump(mDisas, 5, this); //dump widget
|
mDump = new CPUMultiDump(mDisassembly, 5, this); //dump widget
|
||||||
ui->mBotLeftFrameLayout->addWidget(mDump);
|
ui->mBotLeftFrameLayout->addWidget(mDump);
|
||||||
|
|
||||||
mGeneralRegs = new CPURegistersView(this);
|
mGeneralRegs = new CPURegistersView(this);
|
||||||
|
@ -85,9 +88,9 @@ CPUWidget::CPUWidget(QWidget* parent) : QWidget(parent), ui(new Ui::CPUWidget)
|
||||||
|
|
||||||
mStack = new CPUStack(mDump, 0); //stack widget
|
mStack = new CPUStack(mDump, 0); //stack widget
|
||||||
ui->mBotRightFrameLayout->addWidget(mStack);
|
ui->mBotRightFrameLayout->addWidget(mStack);
|
||||||
connect(mDisas, SIGNAL(selectionChanged(dsint)), mStack, SLOT(disasmSelectionChanged(dsint)));
|
connect(mDisassembly, SIGNAL(selectionChanged(duint)), mStack, SLOT(disasmSelectionChanged(duint)));
|
||||||
|
|
||||||
mDisas->setAccessibleName(tr("Disassembly"));
|
mDisassembly->setAccessibleName(tr("Disassembly"));
|
||||||
mStack->setAccessibleName(tr("Stack"));
|
mStack->setAccessibleName(tr("Stack"));
|
||||||
upperScrollArea->setAccessibleName(tr("Registers"));
|
upperScrollArea->setAccessibleName(tr("Registers"));
|
||||||
mDump->setAccessibleName(tr("Dump"));
|
mDump->setAccessibleName(tr("Dump"));
|
||||||
|
@ -96,7 +99,7 @@ CPUWidget::CPUWidget(QWidget* parent) : QWidget(parent), ui(new Ui::CPUWidget)
|
||||||
mInfo->setAccessibleName(tr("InfoBox"));
|
mInfo->setAccessibleName(tr("InfoBox"));
|
||||||
|
|
||||||
// load column config
|
// load column config
|
||||||
mDisas->loadColumnFromConfig("CPUDisassembly");
|
mDisassembly->loadColumnFromConfig("CPUDisassembly");
|
||||||
mStack->loadColumnFromConfig("CPUStack");
|
mStack->loadColumnFromConfig("CPUStack");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,6 +149,11 @@ CPUWidget::~CPUWidget()
|
||||||
delete ui;
|
delete ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Architecture* CPUWidget::getArchitecture() const
|
||||||
|
{
|
||||||
|
return mArchitecture;
|
||||||
|
}
|
||||||
|
|
||||||
void CPUWidget::setDefaultDisposition()
|
void CPUWidget::setDefaultDisposition()
|
||||||
{
|
{
|
||||||
// This is magic, don't touch it...
|
// This is magic, don't touch it...
|
||||||
|
@ -180,18 +188,18 @@ void CPUWidget::setDisasmFocus()
|
||||||
if(disasMode == 1)
|
if(disasMode == 1)
|
||||||
{
|
{
|
||||||
mGraph->hide();
|
mGraph->hide();
|
||||||
mDisas->show();
|
mDisassembly->show();
|
||||||
mSideBar->show();
|
mSideBar->show();
|
||||||
ui->mTopLeftUpperHSplitter->restoreState(mDisasmSidebarSplitterStatus);
|
ui->mTopLeftUpperHSplitter->restoreState(mDisasmSidebarSplitterStatus);
|
||||||
disasMode = 0;
|
disasMode = 0;
|
||||||
connect(mDisas, SIGNAL(selectionChanged(dsint)), mInfo, SLOT(disasmSelectionChanged(dsint)));
|
connect(mDisassembly, SIGNAL(selectionChanged(duint)), mInfo, SLOT(disasmSelectionChanged(duint)));
|
||||||
disconnect(mGraph, SIGNAL(selectionChanged(dsint)), mInfo, SLOT(disasmSelectionChanged(dsint)));
|
disconnect(mGraph, SIGNAL(selectionChanged(duint)), mInfo, SLOT(disasmSelectionChanged(duint)));
|
||||||
}
|
}
|
||||||
else if(disasMode == 2)
|
else if(disasMode == 2)
|
||||||
{
|
{
|
||||||
activateWindow();
|
activateWindow();
|
||||||
}
|
}
|
||||||
mDisas->setFocus();
|
mDisassembly->setFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPUWidget::setGraphFocus()
|
void CPUWidget::setGraphFocus()
|
||||||
|
@ -199,14 +207,14 @@ void CPUWidget::setGraphFocus()
|
||||||
if(disasMode == 0)
|
if(disasMode == 0)
|
||||||
{
|
{
|
||||||
mDisasmSidebarSplitterStatus = ui->mTopLeftUpperHSplitter->saveState();
|
mDisasmSidebarSplitterStatus = ui->mTopLeftUpperHSplitter->saveState();
|
||||||
mDisas->hide();
|
mDisassembly->hide();
|
||||||
mSideBar->hide();
|
mSideBar->hide();
|
||||||
mGraph->show();
|
mGraph->show();
|
||||||
// Hide the sidebar area
|
// Hide the sidebar area
|
||||||
ui->mTopLeftUpperHSplitter->setSizes(QList<int>({0, 100}));
|
ui->mTopLeftUpperHSplitter->setSizes(QList<int>({0, 100}));
|
||||||
disasMode = 1;
|
disasMode = 1;
|
||||||
disconnect(mDisas, SIGNAL(selectionChanged(dsint)), mInfo, SLOT(disasmSelectionChanged(dsint)));
|
disconnect(mDisassembly, SIGNAL(selectionChanged(duint)), mInfo, SLOT(disasmSelectionChanged(duint)));
|
||||||
connect(mGraph, SIGNAL(selectionChanged(dsint)), mInfo, SLOT(disasmSelectionChanged(dsint)));
|
connect(mGraph, SIGNAL(selectionChanged(duint)), mInfo, SLOT(disasmSelectionChanged(duint)));
|
||||||
}
|
}
|
||||||
else if(disasMode == 2)
|
else if(disasMode == 2)
|
||||||
{
|
{
|
||||||
|
@ -250,12 +258,12 @@ void CPUWidget::detachGraph()
|
||||||
|
|
||||||
disasMode = 2;
|
disasMode = 2;
|
||||||
|
|
||||||
mDisas->show();
|
mDisassembly->show();
|
||||||
mSideBar->show();
|
mSideBar->show();
|
||||||
// restore the sidebar splitter so that the sidebar is visible
|
// restore the sidebar splitter so that the sidebar is visible
|
||||||
ui->mTopLeftUpperHSplitter->restoreState(mDisasmSidebarSplitterStatus);
|
ui->mTopLeftUpperHSplitter->restoreState(mDisasmSidebarSplitterStatus);
|
||||||
connect(mDisas, SIGNAL(selectionChanged(dsint)), mInfo, SLOT(disasmSelectionChanged(dsint)));
|
connect(mDisassembly, SIGNAL(selectionChanged(duint)), mInfo, SLOT(disasmSelectionChanged(duint)));
|
||||||
connect(mGraph, SIGNAL(selectionChanged(dsint)), mInfo, SLOT(disasmSelectionChanged(dsint)));
|
connect(mGraph, SIGNAL(selectionChanged(duint)), mInfo, SLOT(disasmSelectionChanged(duint)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -266,7 +274,7 @@ void CPUWidget::attachGraph(QWidget* widget)
|
||||||
ui->mTopLeftUpperRightFrameLayout->addWidget(mGraph);
|
ui->mTopLeftUpperRightFrameLayout->addWidget(mGraph);
|
||||||
mGraph->hide();
|
mGraph->hide();
|
||||||
mGraphWindow->close();
|
mGraphWindow->close();
|
||||||
disconnect(mGraph, SIGNAL(selectionChanged(dsint)), mInfo, SLOT(disasmSelectionChanged(dsint)));
|
disconnect(mGraph, SIGNAL(selectionChanged(duint)), mInfo, SLOT(disasmSelectionChanged(duint)));
|
||||||
delete mGraphWindow;
|
delete mGraphWindow;
|
||||||
mGraphWindow = nullptr;
|
mGraphWindow = nullptr;
|
||||||
disasMode = 0;
|
disasMode = 0;
|
||||||
|
@ -276,9 +284,9 @@ void CPUWidget::attachGraph(QWidget* widget)
|
||||||
duint CPUWidget::getSelectionVa()
|
duint CPUWidget::getSelectionVa()
|
||||||
{
|
{
|
||||||
if(disasMode < 2)
|
if(disasMode < 2)
|
||||||
return disasMode == 0 ? mDisas->getSelectedVa() : mGraph->get_cursor_pos();
|
return disasMode == 0 ? mDisassembly->getSelectedVa() : mGraph->get_cursor_pos();
|
||||||
else
|
else
|
||||||
return !mGraph->hasFocus() ? mDisas->getSelectedVa() : mGraph->get_cursor_pos();
|
return !mGraph->hasFocus() ? mDisassembly->getSelectedVa() : mGraph->get_cursor_pos();
|
||||||
}
|
}
|
||||||
|
|
||||||
CPUSideBar* CPUWidget::getSidebarWidget()
|
CPUSideBar* CPUWidget::getSidebarWidget()
|
||||||
|
@ -288,7 +296,7 @@ CPUSideBar* CPUWidget::getSidebarWidget()
|
||||||
|
|
||||||
CPUDisassembly* CPUWidget::getDisasmWidget()
|
CPUDisassembly* CPUWidget::getDisasmWidget()
|
||||||
{
|
{
|
||||||
return mDisas;
|
return mDisassembly;
|
||||||
}
|
}
|
||||||
|
|
||||||
DisassemblerGraphView* CPUWidget::getGraphWidget()
|
DisassemblerGraphView* CPUWidget::getGraphWidget()
|
||||||
|
|
|
@ -24,8 +24,9 @@ class CPUWidget : public QWidget
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit CPUWidget(QWidget* parent = 0);
|
explicit CPUWidget(Architecture* architecture, QWidget* parent = nullptr);
|
||||||
~CPUWidget();
|
~CPUWidget();
|
||||||
|
Architecture* getArchitecture() const;
|
||||||
|
|
||||||
// Misc
|
// Misc
|
||||||
void setDefaultDisposition();
|
void setDefaultDisposition();
|
||||||
|
@ -49,7 +50,7 @@ public slots:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
CPUSideBar* mSideBar;
|
CPUSideBar* mSideBar;
|
||||||
CPUDisassembly* mDisas;
|
CPUDisassembly* mDisassembly;
|
||||||
DisassemblerGraphView* mGraph;
|
DisassemblerGraphView* mGraph;
|
||||||
MHDetachedWindow* mGraphWindow;
|
MHDetachedWindow* mGraphWindow;
|
||||||
CPUMultiDump* mDump;
|
CPUMultiDump* mDump;
|
||||||
|
@ -61,6 +62,7 @@ protected:
|
||||||
int disasMode;
|
int disasMode;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Architecture* mArchitecture = nullptr;
|
||||||
Ui::CPUWidget* ui;
|
Ui::CPUWidget* ui;
|
||||||
QByteArray mDisasmSidebarSplitterStatus;
|
QByteArray mDisasmSidebarSplitterStatus;
|
||||||
|
|
||||||
|
|
|
@ -73,16 +73,16 @@ void CallStackView::setupContextMenu()
|
||||||
mMenuBuilder->loadFromConfig();
|
mMenuBuilder->loadFromConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CallStackView::paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h)
|
QString CallStackView::paintContent(QPainter* painter, duint row, duint col, int x, int y, int w, int h)
|
||||||
{
|
{
|
||||||
if(isSelected(rowBase, rowOffset))
|
if(isSelected(row))
|
||||||
painter->fillRect(QRect(x, y, w, h), QBrush(mSelectionColor));
|
painter->fillRect(QRect(x, y, w, h), QBrush(mSelectionColor));
|
||||||
|
|
||||||
bool isSpaceRow = !getCellContent(rowBase + rowOffset, ColThread).isEmpty();
|
bool isSpaceRow = !getCellContent(row, ColThread).isEmpty();
|
||||||
|
|
||||||
if(col == ColThread && !(rowBase + rowOffset))
|
if(col == ColThread && row == 0)
|
||||||
{
|
{
|
||||||
QString ret = getCellContent(rowBase + rowOffset, col);
|
QString ret = getCellContent(row, col);
|
||||||
if(!ret.isEmpty())
|
if(!ret.isEmpty())
|
||||||
{
|
{
|
||||||
painter->fillRect(QRect(x, y, w, h), QBrush(ConfigColor("ThreadCurrentBackgroundColor")));
|
painter->fillRect(QRect(x, y, w, h), QBrush(ConfigColor("ThreadCurrentBackgroundColor")));
|
||||||
|
@ -98,8 +98,8 @@ QString CallStackView::paintContent(QPainter* painter, dsint rowBase, int rowOff
|
||||||
}
|
}
|
||||||
else if(col == ColFrom || col == ColTo || col == ColAddress)
|
else if(col == ColFrom || col == ColTo || col == ColAddress)
|
||||||
{
|
{
|
||||||
QString ret = getCellContent(rowBase + rowOffset, col);
|
QString ret = getCellContent(row, col);
|
||||||
BPXTYPE bpxtype = DbgGetBpxTypeAt(getCellUserdata(rowBase + rowOffset, col));
|
BPXTYPE bpxtype = DbgGetBpxTypeAt(getCellUserdata(row, col));
|
||||||
if(bpxtype & bp_normal)
|
if(bpxtype & bp_normal)
|
||||||
{
|
{
|
||||||
painter->fillRect(QRect(x, y, w, h), QBrush(ConfigColor("DisassemblyBreakpointBackgroundColor")));
|
painter->fillRect(QRect(x, y, w, h), QBrush(ConfigColor("DisassemblyBreakpointBackgroundColor")));
|
||||||
|
@ -115,7 +115,7 @@ QString CallStackView::paintContent(QPainter* painter, dsint rowBase, int rowOff
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return StdIconTable::paintContent(painter, rowBase, rowOffset, col, x, y, w, h);
|
return StdIconTable::paintContent(painter, row, col, x, y, w, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CallStackView::updateCallStack()
|
void CallStackView::updateCallStack()
|
||||||
|
|
|
@ -10,7 +10,7 @@ ColumnReorderDialog::ColumnReorderDialog(AbstractTableView* parent) :
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint | Qt::MSWindowsFixedSizeDialogHint);
|
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint | Qt::MSWindowsFixedSizeDialogHint);
|
||||||
for(int j = 0; j < parent->getColumnCount(); j++)
|
for(duint j = 0; j < parent->getColumnCount(); j++)
|
||||||
{
|
{
|
||||||
int i = parent->mColumnOrder[j];
|
int i = parent->mColumnOrder[j];
|
||||||
if(parent->getColumnHidden(i))
|
if(parent->getColumnHidden(i))
|
||||||
|
|
|
@ -17,18 +17,12 @@
|
||||||
#include "MiscUtil.h"
|
#include "MiscUtil.h"
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
|
|
||||||
DisassemblerGraphView::DisassemblerGraphView(QWidget* parent)
|
DisassemblerGraphView::DisassemblerGraphView(Architecture* architecture, QWidget* parent)
|
||||||
: QAbstractScrollArea(parent),
|
: QAbstractScrollArea(parent),
|
||||||
mFontMetrics(nullptr),
|
mArchitecture(architecture),
|
||||||
currentGraph(duint(0)),
|
currentGraph(0),
|
||||||
disasm(ConfigUint("Disassembler", "MaxModuleSize"), Bridge::getArch()),
|
disasm(ConfigUint("Disassembler", "MaxModuleSize"), architecture),
|
||||||
mCip(0),
|
layoutType(LayoutType::Medium)
|
||||||
mGoto(nullptr),
|
|
||||||
syncOrigin(false),
|
|
||||||
forceCenter(false),
|
|
||||||
layoutType(LayoutType::Medium),
|
|
||||||
mHistoryLock(false),
|
|
||||||
mXrefDlg(nullptr)
|
|
||||||
{
|
{
|
||||||
this->status = "Loading...";
|
this->status = "Loading...";
|
||||||
|
|
||||||
|
|
|
@ -206,7 +206,7 @@ public:
|
||||||
bool inBlock = false;
|
bool inBlock = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
DisassemblerGraphView(QWidget* parent = nullptr);
|
DisassemblerGraphView(Architecture* architecture, QWidget* parent = nullptr);
|
||||||
~DisassemblerGraphView();
|
~DisassemblerGraphView();
|
||||||
void resetGraph();
|
void resetGraph();
|
||||||
void initFont();
|
void initFont();
|
||||||
|
@ -294,6 +294,7 @@ public slots:
|
||||||
void enableHighlightingModeSlot();
|
void enableHighlightingModeSlot();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Architecture* mArchitecture = nullptr;
|
||||||
bool graphZoomMode;
|
bool graphZoomMode;
|
||||||
qreal zoomLevel;
|
qreal zoomLevel;
|
||||||
qreal zoomLevelOld;
|
qreal zoomLevelOld;
|
||||||
|
@ -329,23 +330,23 @@ private:
|
||||||
std::unordered_map<duint, DisassemblerBlock> blocks;
|
std::unordered_map<duint, DisassemblerBlock> blocks;
|
||||||
std::vector<int> col_edge_x;
|
std::vector<int> col_edge_x;
|
||||||
std::vector<int> row_edge_y;
|
std::vector<int> row_edge_y;
|
||||||
CachedFontMetrics* mFontMetrics;
|
CachedFontMetrics* mFontMetrics = nullptr;
|
||||||
MenuBuilder* mMenuBuilder;
|
MenuBuilder* mMenuBuilder = nullptr;
|
||||||
CommonActions* mCommonActions;
|
CommonActions* mCommonActions = nullptr;
|
||||||
QMenu* mPluginMenu;
|
QMenu* mPluginMenu = nullptr;
|
||||||
bool drawOverview;
|
bool drawOverview;
|
||||||
bool onlySummary;
|
bool onlySummary;
|
||||||
bool syncOrigin;
|
bool syncOrigin = false;
|
||||||
int overviewXOfs;
|
int overviewXOfs;
|
||||||
int overviewYOfs;
|
int overviewYOfs;
|
||||||
qreal overviewScale;
|
qreal overviewScale;
|
||||||
duint mCip;
|
duint mCip = 0;
|
||||||
bool forceCenter;
|
bool forceCenter = false;
|
||||||
bool saveGraph;
|
bool saveGraph;
|
||||||
bool mHistoryLock; //Don't add a history while going to previous/next
|
bool mHistoryLock = false; //Don't add a history while going to previous/next
|
||||||
LayoutType layoutType;
|
LayoutType layoutType;
|
||||||
|
|
||||||
MenuBuilder* mHighlightMenuBuilder;
|
MenuBuilder* mHighlightMenuBuilder = nullptr;
|
||||||
ZydisTokenizer::SingleToken mHighlightToken;
|
ZydisTokenizer::SingleToken mHighlightToken;
|
||||||
bool mHighlightingModeEnabled;
|
bool mHighlightingModeEnabled;
|
||||||
bool mPermanentHighlightingMode;
|
bool mPermanentHighlightingMode;
|
||||||
|
@ -387,8 +388,8 @@ private:
|
||||||
BridgeCFGraph currentGraph;
|
BridgeCFGraph currentGraph;
|
||||||
std::unordered_map<duint, duint> currentBlockMap;
|
std::unordered_map<duint, duint> currentBlockMap;
|
||||||
QZydis disasm;
|
QZydis disasm;
|
||||||
GotoDialog* mGoto;
|
GotoDialog* mGoto = nullptr;
|
||||||
XrefBrowseDialog* mXrefDlg;
|
XrefBrowseDialog* mXrefDlg = nullptr;
|
||||||
|
|
||||||
void addReferenceAction(QMenu* menu, duint addr, const QString & description);
|
void addReferenceAction(QMenu* menu, duint addr, const QString & description);
|
||||||
bool getHighlightedTokenValueText(QString & text);
|
bool getHighlightedTokenValueText(QString & text);
|
||||||
|
|
|
@ -284,7 +284,7 @@ void HandlesView::enableAllPrivilegesSlot()
|
||||||
{
|
{
|
||||||
if(!DbgIsDebugging())
|
if(!DbgIsDebugging())
|
||||||
return;
|
return;
|
||||||
for(int i = 0; i < mPrivilegesTable->getRowCount(); i++)
|
for(duint i = 0; i < mPrivilegesTable->getRowCount(); i++)
|
||||||
if(mPrivilegesTable->getCellContent(i, 1) != tr("Unknown"))
|
if(mPrivilegesTable->getCellContent(i, 1) != tr("Unknown"))
|
||||||
DbgCmdExecDirect(QString("EnablePrivilege \"%1\"").arg(mPrivilegesTable->getCellContent(i, 0)));
|
DbgCmdExecDirect(QString("EnablePrivilege \"%1\"").arg(mPrivilegesTable->getCellContent(i, 0)));
|
||||||
enumPrivileges();
|
enumPrivileges();
|
||||||
|
@ -294,7 +294,7 @@ void HandlesView::disableAllPrivilegesSlot()
|
||||||
{
|
{
|
||||||
if(!DbgIsDebugging())
|
if(!DbgIsDebugging())
|
||||||
return;
|
return;
|
||||||
for(int i = 0; i < mPrivilegesTable->getRowCount(); i++)
|
for(duint i = 0; i < mPrivilegesTable->getRowCount(); i++)
|
||||||
if(mPrivilegesTable->getCellContent(i, 1) != tr("Unknown"))
|
if(mPrivilegesTable->getCellContent(i, 1) != tr("Unknown"))
|
||||||
DbgCmdExecDirect(QString("DisablePrivilege \"%1\"").arg(mPrivilegesTable->getCellContent(i, 0)));
|
DbgCmdExecDirect(QString("DisablePrivilege \"%1\"").arg(mPrivilegesTable->getCellContent(i, 0)));
|
||||||
enumPrivileges();
|
enumPrivileges();
|
||||||
|
|
|
@ -195,7 +195,7 @@ MainWindow::MainWindow(QWidget* parent)
|
||||||
mScriptView->hide();
|
mScriptView->hide();
|
||||||
|
|
||||||
// CPU view
|
// CPU view
|
||||||
mCpuWidget = new CPUWidget();
|
mCpuWidget = new CPUWidget(Bridge::getArchitecture());
|
||||||
mCpuWidget->setWindowTitle(tr("CPU"));
|
mCpuWidget->setWindowTitle(tr("CPU"));
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
mCpuWidget->setWindowIcon(DIcon("processor64"));
|
mCpuWidget->setWindowIcon(DIcon("processor64"));
|
||||||
|
@ -836,7 +836,7 @@ void MainWindow::closeEvent(QCloseEvent* event)
|
||||||
bExecuteThread = false;
|
bExecuteThread = false;
|
||||||
Sleep(100);
|
Sleep(100);
|
||||||
mCloseThread->start();
|
mCloseThread->start();
|
||||||
emit Bridge::getBridge()->shutdown();
|
emit Bridge::getBridge()->close();
|
||||||
}
|
}
|
||||||
if(bCanClose)
|
if(bCanClose)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1088,7 +1088,7 @@ RegistersView::RegistersView(QWidget* parent) : QScrollArea(parent), mVScrollOff
|
||||||
connect(Config(), SIGNAL(fontsUpdated()), this, SLOT(fontsUpdatedSlot()));
|
connect(Config(), SIGNAL(fontsUpdated()), this, SLOT(fontsUpdatedSlot()));
|
||||||
// self communication for repainting (maybe some other widgets needs this information, too)
|
// self communication for repainting (maybe some other widgets needs this information, too)
|
||||||
connect(this, SIGNAL(refresh()), this, SLOT(reload()));
|
connect(this, SIGNAL(refresh()), this, SLOT(reload()));
|
||||||
connect(Bridge::getBridge(), SIGNAL(shutdown()), this, SLOT(shutdownSlot()));
|
connect(Bridge::getBridge(), SIGNAL(close()), this, SLOT(shutdownSlot()));
|
||||||
|
|
||||||
InitMappings();
|
InitMappings();
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ SourceView::~SourceView()
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString SourceView::getCellContent(int r, int c)
|
QString SourceView::getCellContent(duint r, duint c)
|
||||||
{
|
{
|
||||||
if(!isValidIndex(r, c))
|
if(!isValidIndex(r, c))
|
||||||
return QString();
|
return QString();
|
||||||
|
@ -59,7 +59,7 @@ QString SourceView::getCellContent(int r, int c)
|
||||||
return "INVALID";
|
return "INVALID";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SourceView::isValidIndex(int r, int c)
|
bool SourceView::isValidIndex(duint r, duint c)
|
||||||
{
|
{
|
||||||
if(!mFileLines)
|
if(!mFileLines)
|
||||||
return false;
|
return false;
|
||||||
|
@ -68,7 +68,7 @@ bool SourceView::isValidIndex(int r, int c)
|
||||||
return r >= 0 && size_t(r) < mFileLines->size();
|
return r >= 0 && size_t(r) < mFileLines->size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SourceView::sortRows(int column, bool ascending)
|
void SourceView::sortRows(duint column, bool ascending)
|
||||||
{
|
{
|
||||||
Q_UNUSED(column);
|
Q_UNUSED(column);
|
||||||
Q_UNUSED(ascending);
|
Q_UNUSED(ascending);
|
||||||
|
@ -83,7 +83,7 @@ void SourceView::prepareData()
|
||||||
mPrepareTableOffset = getTableOffset();
|
mPrepareTableOffset = getTableOffset();
|
||||||
mLines.clear();
|
mLines.clear();
|
||||||
mLines.resize(lines);
|
mLines.resize(lines);
|
||||||
for(auto i = 0; i < lines; i++)
|
for(duint i = 0; i < lines; i++)
|
||||||
parseLine(mPrepareTableOffset + i, mLines[i]);
|
parseLine(mPrepareTableOffset + i, mLines[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,9 +13,9 @@ public:
|
||||||
SourceView(QString path, duint addr, QWidget* parent = nullptr);
|
SourceView(QString path, duint addr, QWidget* parent = nullptr);
|
||||||
~SourceView();
|
~SourceView();
|
||||||
|
|
||||||
QString getCellContent(int r, int c) override;
|
QString getCellContent(duint r, duint c) override;
|
||||||
bool isValidIndex(int r, int c) override;
|
bool isValidIndex(duint r, duint c) override;
|
||||||
void sortRows(int column, bool ascending) override;
|
void sortRows(duint column, bool ascending) override;
|
||||||
void prepareData() override;
|
void prepareData() override;
|
||||||
|
|
||||||
QString getSourcePath();
|
QString getSourcePath();
|
||||||
|
|
|
@ -366,10 +366,10 @@ void ThreadView::updateThreadList()
|
||||||
reloadData();
|
reloadData();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ThreadView::paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h)
|
QString ThreadView::paintContent(QPainter* painter, duint row, duint col, int x, int y, int w, int h)
|
||||||
{
|
{
|
||||||
QString ret = StdTable::paintContent(painter, rowBase, rowOffset, col, x, y, w, h);
|
QString ret = StdTable::paintContent(painter, row, col, x, y, w, h);
|
||||||
duint threadId = getCellUserdata(rowBase + rowOffset, 1);
|
duint threadId = getCellUserdata(row, 1);
|
||||||
if(threadId == mCurrentThreadId && !col)
|
if(threadId == mCurrentThreadId && !col)
|
||||||
{
|
{
|
||||||
painter->fillRect(QRect(x, y, w, h), QBrush(ConfigColor("ThreadCurrentBackgroundColor")));
|
painter->fillRect(QRect(x, y, w, h), QBrush(ConfigColor("ThreadCurrentBackgroundColor")));
|
||||||
|
|
|
@ -181,10 +181,9 @@ QString WatchView::getSelectedId()
|
||||||
return QChar('.') + getCellContent(getInitialSelection(), ColId);
|
return QChar('.') + getCellContent(getInitialSelection(), ColId);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString WatchView::paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h)
|
QString WatchView::paintContent(QPainter* painter, duint row, duint col, int x, int y, int w, int h)
|
||||||
{
|
{
|
||||||
QString ret = StdTable::paintContent(painter, rowBase, rowOffset, col, x, y, w, h);
|
QString ret = StdTable::paintContent(painter, row, col, x, y, w, h);
|
||||||
const dsint row = rowBase + rowOffset;
|
|
||||||
if(row != getInitialSelection() && DbgFunctions()->WatchIsWatchdogTriggered(getCellContent(row, ColId).toUInt()))
|
if(row != getInitialSelection() && DbgFunctions()->WatchIsWatchdogTriggered(getCellContent(row, ColId).toUInt()))
|
||||||
{
|
{
|
||||||
painter->fillRect(QRect(x, y, w, h), mWatchTriggeredBackgroundColor);
|
painter->fillRect(QRect(x, y, w, h), mWatchTriggeredBackgroundColor);
|
||||||
|
|
|
@ -10,7 +10,7 @@ class WatchView : public StdTable
|
||||||
public:
|
public:
|
||||||
WatchView(CPUMultiDump* parent);
|
WatchView(CPUMultiDump* parent);
|
||||||
|
|
||||||
QString paintContent(QPainter* painter, dsint rowBase, int rowOffset, int col, int x, int y, int w, int h) override;
|
QString paintContent(QPainter* painter, duint row, duint col, int x, int y, int w, int h) override;
|
||||||
void updateColors() override;
|
void updateColors() override;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
|
@ -56,7 +56,7 @@ ZehSymbolTable::ZehSymbolTable(QWidget* parent)
|
||||||
Initialize();
|
Initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ZehSymbolTable::getCellContent(int r, int c)
|
QString ZehSymbolTable::getCellContent(duint r, duint c)
|
||||||
{
|
{
|
||||||
QMutexLocker lock(&mMutex);
|
QMutexLocker lock(&mMutex);
|
||||||
if(!isValidIndex(r, c))
|
if(!isValidIndex(r, c))
|
||||||
|
@ -66,13 +66,13 @@ QString ZehSymbolTable::getCellContent(int r, int c)
|
||||||
return symbolInfoString(info.get(), c);
|
return symbolInfoString(info.get(), c);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ZehSymbolTable::isValidIndex(int r, int c)
|
bool ZehSymbolTable::isValidIndex(duint r, duint c)
|
||||||
{
|
{
|
||||||
QMutexLocker lock(&mMutex);
|
QMutexLocker lock(&mMutex);
|
||||||
return r >= 0 && r < (int)mData.size() && c >= 0 && c <= ColUndecorated;
|
return r >= 0 && r < (int)mData.size() && c >= 0 && c <= ColUndecorated;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZehSymbolTable::sortRows(int column, bool ascending)
|
void ZehSymbolTable::sortRows(duint column, bool ascending)
|
||||||
{
|
{
|
||||||
QMutexLocker lock(&mMutex);
|
QMutexLocker lock(&mMutex);
|
||||||
std::stable_sort(mData.begin(), mData.end(), [this, column, ascending](const SYMBOLPTR & a, const SYMBOLPTR & b)
|
std::stable_sort(mData.begin(), mData.end(), [this, column, ascending](const SYMBOLPTR & a, const SYMBOLPTR & b)
|
||||||
|
@ -119,7 +119,7 @@ void ZehSymbolTable::sortRows(int column, bool ascending)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ZehSymbolTable::symbolInfoString(const SYMBOLINFO* info, int c)
|
QString ZehSymbolTable::symbolInfoString(const SYMBOLINFO* info, duint c)
|
||||||
{
|
{
|
||||||
switch(c)
|
switch(c)
|
||||||
{
|
{
|
||||||
|
|
|
@ -9,9 +9,9 @@ class ZehSymbolTable : public AbstractStdTable
|
||||||
public:
|
public:
|
||||||
ZehSymbolTable(QWidget* parent = nullptr);
|
ZehSymbolTable(QWidget* parent = nullptr);
|
||||||
|
|
||||||
QString getCellContent(int r, int c) override;
|
QString getCellContent(duint r, duint c) override;
|
||||||
bool isValidIndex(int r, int c) override;
|
bool isValidIndex(duint r, duint c) override;
|
||||||
void sortRows(int column, bool ascending) override;
|
void sortRows(duint column, bool ascending) override;
|
||||||
|
|
||||||
friend class SymbolView;
|
friend class SymbolView;
|
||||||
friend class SearchListViewSymbols;
|
friend class SearchListViewSymbols;
|
||||||
|
@ -36,5 +36,5 @@ private:
|
||||||
ColUndecorated
|
ColUndecorated
|
||||||
};
|
};
|
||||||
|
|
||||||
QString symbolInfoString(const SYMBOLINFO* info, int c);
|
QString symbolInfoString(const SYMBOLINFO* info, duint c);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1102,7 +1102,7 @@ void TraceBrowser::mouseDoubleClickEvent(QMouseEvent* event)
|
||||||
|
|
||||||
void TraceBrowser::mouseMoveEvent(QMouseEvent* event)
|
void TraceBrowser::mouseMoveEvent(QMouseEvent* event)
|
||||||
{
|
{
|
||||||
duint index = getIndexOffsetFromY(transY(event->y())) + getTableOffset();
|
auto index = getIndexOffsetFromY(transY(event->y())) + getTableOffset();
|
||||||
if((event->buttons() & Qt::LeftButton) != 0 && getGuiState() == AbstractTableView::NoState && mTraceFile != nullptr && mTraceFile->Progress() == 100)
|
if((event->buttons() & Qt::LeftButton) != 0 && getGuiState() == AbstractTableView::NoState && mTraceFile != nullptr && mTraceFile->Progress() == 100)
|
||||||
{
|
{
|
||||||
if(index < getRowCount())
|
if(index < getRowCount())
|
||||||
|
@ -1751,7 +1751,7 @@ void TraceBrowser::exportSlot()
|
||||||
return;
|
return;
|
||||||
std::vector<QString> headers;
|
std::vector<QString> headers;
|
||||||
headers.reserve(getColumnCount());
|
headers.reserve(getColumnCount());
|
||||||
for(int i = 0; i < getColumnCount(); i++)
|
for(duint i = 0; i < getColumnCount(); i++)
|
||||||
headers.push_back(getColTitle(i));
|
headers.push_back(getColTitle(i));
|
||||||
ExportCSV(getRowCount(), getColumnCount(), headers, [this](dsint row, dsint col)
|
ExportCSV(getRowCount(), getColumnCount(), headers, [this](dsint row, dsint col)
|
||||||
{
|
{
|
||||||
|
|
|
@ -18,7 +18,8 @@ TraceFileReader::TraceFileReader(QObject* parent) : QObject(parent)
|
||||||
EXEPath.clear();
|
EXEPath.clear();
|
||||||
|
|
||||||
int maxModuleSize = (int)ConfigUint("Disassembler", "MaxModuleSize");
|
int maxModuleSize = (int)ConfigUint("Disassembler", "MaxModuleSize");
|
||||||
mDisasm = new QZydis(maxModuleSize, Bridge::getArch());
|
// TODO: refactor this to come from the parent TraceWidget
|
||||||
|
mDisasm = new QZydis(maxModuleSize, Bridge::getArchitecture());
|
||||||
connect(Config(), SIGNAL(tokenizerConfigUpdated()), this, SLOT(tokenizerUpdatedSlot()));
|
connect(Config(), SIGNAL(tokenizerConfigUpdated()), this, SLOT(tokenizerUpdatedSlot()));
|
||||||
connect(Config(), SIGNAL(colorsUpdated()), this, SLOT(tokenizerUpdatedSlot()));
|
connect(Config(), SIGNAL(colorsUpdated()), this, SLOT(tokenizerUpdatedSlot()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,13 +22,27 @@ public:
|
||||||
if(unicode >= 0xD800)
|
if(unicode >= 0xD800)
|
||||||
{
|
{
|
||||||
if(unicode >= 0xE000)
|
if(unicode >= 0xE000)
|
||||||
|
{
|
||||||
unicode -= 0xE000 - 0xD800;
|
unicode -= 0xE000 - 0xD800;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
// is lonely surrogate
|
// is lonely surrogate
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)
|
||||||
|
return mFontMetrics.horizontalAdvance(ch);
|
||||||
|
#else
|
||||||
return mFontMetrics.width(ch);
|
return mFontMetrics.width(ch);
|
||||||
|
#endif // QT_VERSION
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(!mWidths[unicode])
|
if(!mWidths[unicode])
|
||||||
|
{
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)
|
||||||
|
return mWidths[unicode] = mFontMetrics.horizontalAdvance(ch);
|
||||||
|
#else
|
||||||
return mWidths[unicode] = mFontMetrics.width(ch);
|
return mWidths[unicode] = mFontMetrics.width(ch);
|
||||||
|
#endif // QT_VERSION
|
||||||
|
}
|
||||||
return mWidths[unicode];
|
return mWidths[unicode];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,11 +53,21 @@ public:
|
||||||
for(const QChar & ch : text)
|
for(const QChar & ch : text)
|
||||||
{
|
{
|
||||||
if(ch.isHighSurrogate())
|
if(ch.isHighSurrogate())
|
||||||
|
{
|
||||||
temp = ch;
|
temp = ch;
|
||||||
|
}
|
||||||
else if(ch.isLowSurrogate())
|
else if(ch.isLowSurrogate())
|
||||||
|
{
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)
|
||||||
|
result += mFontMetrics.horizontalAdvance(QString(temp) + ch);
|
||||||
|
#else
|
||||||
result += mFontMetrics.width(QString(temp) + ch);
|
result += mFontMetrics.width(QString(temp) + ch);
|
||||||
|
#endif // QT_VERSION
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
result += width(ch);
|
result += width(ch);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ Configuration::Configuration() : QObject(), noMoreMsgbox(false)
|
||||||
defaultColors.insert("AbstractTableViewBackgroundColor", QColor("#FFF8F0"));
|
defaultColors.insert("AbstractTableViewBackgroundColor", QColor("#FFF8F0"));
|
||||||
defaultColors.insert("AbstractTableViewTextColor", QColor("#000000"));
|
defaultColors.insert("AbstractTableViewTextColor", QColor("#000000"));
|
||||||
defaultColors.insert("AbstractTableViewHeaderTextColor", QColor("#000000"));
|
defaultColors.insert("AbstractTableViewHeaderTextColor", QColor("#000000"));
|
||||||
|
defaultColors.insert("AbstractTableViewHeaderBackgroundColor", QColor("#C0C0C0"));
|
||||||
defaultColors.insert("AbstractTableViewSelectionColor", QColor("#C0C0C0"));
|
defaultColors.insert("AbstractTableViewSelectionColor", QColor("#C0C0C0"));
|
||||||
|
|
||||||
defaultColors.insert("DisassemblyCipColor", QColor("#FFFFFF"));
|
defaultColors.insert("DisassemblyCipColor", QColor("#FFFFFF"));
|
||||||
|
|
|
@ -5,6 +5,12 @@
|
||||||
//TODO: fix performance (possibly use QTextLayout?)
|
//TODO: fix performance (possibly use QTextLayout?)
|
||||||
void RichTextPainter::paintRichText(QPainter* painter, int x, int y, int w, int h, int xinc, const List & richText, CachedFontMetrics* fontMetrics)
|
void RichTextPainter::paintRichText(QPainter* painter, int x, int y, int w, int h, int xinc, const List & richText, CachedFontMetrics* fontMetrics)
|
||||||
{
|
{
|
||||||
|
#ifdef Q_OS_DARWIN
|
||||||
|
w -= 2;
|
||||||
|
#else
|
||||||
|
w -= 1;
|
||||||
|
#endif // Q_OS_DARWIN
|
||||||
|
|
||||||
QPen pen;
|
QPen pen;
|
||||||
QPen highlightPen;
|
QPen highlightPen;
|
||||||
QBrush brush(Qt::cyan);
|
QBrush brush(Qt::cyan);
|
||||||
|
@ -41,7 +47,7 @@ void RichTextPainter::paintRichText(QPainter* painter, int x, int y, int w, int
|
||||||
painter->setPen(pen);
|
painter->setPen(pen);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
painter->drawText(QRect(x + xinc, y, w - xinc, h), Qt::TextBypassShaping, curRichText.text);
|
painter->drawText(QRect(x + xinc, y, w - xinc, h), 0, curRichText.text);
|
||||||
if(curRichText.underline && curRichText.underlineColor.alpha())
|
if(curRichText.underline && curRichText.underlineColor.alpha())
|
||||||
{
|
{
|
||||||
highlightPen.setColor(curRichText.underlineColor);
|
highlightPen.setColor(curRichText.underlineColor);
|
||||||
|
|
Loading…
Reference in New Issue