"Fossies" - the Fresh Open Source Software Archive

Member "cutter-1.10.3/src/dialogs/XrefsDialog.cpp" (8 May 2020, 7870 Bytes) of package /linux/privat/cutter-1.10.3.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "XrefsDialog.cpp" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 1.10.2_vs_1.10.3.

    1 #include "XrefsDialog.h"
    2 #include "ui_XrefsDialog.h"
    3 
    4 #include "common/TempConfig.h"
    5 #include "common/Helpers.h"
    6 
    7 #include "core/MainWindow.h"
    8 
    9 #include <QJsonArray>
   10 
   11 XrefsDialog::XrefsDialog(MainWindow *main, QWidget *parent) :
   12     QDialog(parent),
   13     addr(0),
   14     toModel(this),
   15     fromModel(this),
   16     ui(new Ui::XrefsDialog)
   17 {
   18     ui->setupUi(this);
   19     setWindowFlags(windowFlags() & (~Qt::WindowContextHelpButtonHint));
   20 
   21     ui->toTreeWidget->setMainWindow(main);
   22     ui->fromTreeWidget->setMainWindow(main);
   23 
   24     ui->toTreeWidget->setModel(&toModel);
   25     ui->fromTreeWidget->setModel(&fromModel);
   26 
   27     // Modify the splitter's location to show more Disassembly instead of empty space. Not possible via Designer
   28     ui->splitter->setSizes(QList<int>() << 300 << 400);
   29 
   30     // Increase asm text edit margin
   31     QTextDocument *asm_docu = ui->previewTextEdit->document();
   32     asm_docu->setDocumentMargin(10);
   33 
   34     setupPreviewColors();
   35     setupPreviewFont();
   36 
   37     // Highlight current line
   38     connect(ui->previewTextEdit, SIGNAL(cursorPositionChanged()), this, SLOT(highlightCurrentLine()));
   39     connect(Config(), SIGNAL(fontsUpdated()), this, SLOT(setupPreviewFont()));
   40     connect(Config(), SIGNAL(colorsUpdated()), this, SLOT(setupPreviewColors()));
   41 
   42     connect(ui->toTreeWidget->selectionModel(), &QItemSelectionModel::selectionChanged,
   43             this, &XrefsDialog::onToTreeWidgetItemSelectionChanged);
   44     connect(ui->fromTreeWidget->selectionModel(), &QItemSelectionModel::selectionChanged,
   45             this, &XrefsDialog::onFromTreeWidgetItemSelectionChanged);
   46 
   47     // Don't create recursive xref dialogs
   48     auto toContextMenu = ui->toTreeWidget->getItemContextMenu();
   49     connect(toContextMenu, &AddressableItemContextMenu::xrefsTriggered, this, &QWidget::close);
   50     auto fromContextMenu = ui->fromTreeWidget->getItemContextMenu();
   51     connect(fromContextMenu, &AddressableItemContextMenu::xrefsTriggered, this, &QWidget::close);
   52 
   53     connect(ui->toTreeWidget, &QAbstractItemView::doubleClicked, this, &QWidget::close);
   54     connect(ui->fromTreeWidget, &QAbstractItemView::doubleClicked, this, &QWidget::close);
   55 }
   56 
   57 XrefsDialog::~XrefsDialog() { }
   58 
   59 QString XrefsDialog::normalizeAddr(const QString &addr) const
   60 {
   61     QString ret = addr;
   62     if (addr.length() < 10) {
   63         ret = ret.mid(3).rightJustified(8, QLatin1Char('0'));
   64         ret.prepend(QLatin1Literal("0x"));
   65     }
   66     return ret;
   67 }
   68 
   69 void XrefsDialog::setupPreviewFont()
   70 {
   71     ui->previewTextEdit->setFont(Config()->getBaseFont());
   72 }
   73 
   74 void XrefsDialog::setupPreviewColors()
   75 {
   76     ui->previewTextEdit->setStyleSheet(QString("QPlainTextEdit { background-color: %1; color: %2; }")
   77                                        .arg(ConfigColor("gui.background").name())
   78                                        .arg(ConfigColor("btext").name()));
   79 }
   80 
   81 void XrefsDialog::highlightCurrentLine()
   82 {
   83     QList<QTextEdit::ExtraSelection> extraSelections;
   84 
   85     if (ui->previewTextEdit->isReadOnly()) {
   86         QTextEdit::ExtraSelection selection = QTextEdit::ExtraSelection();
   87 
   88         selection.format.setBackground(ConfigColor("lineHighlight"));
   89         selection.format.setProperty(QTextFormat::FullWidthSelection, true);
   90         selection.cursor = ui->previewTextEdit->textCursor();
   91         selection.cursor.clearSelection();
   92         extraSelections.append(selection);
   93 
   94         ui->previewTextEdit->setExtraSelections(extraSelections);
   95     }
   96 }
   97 
   98 void XrefsDialog::onFromTreeWidgetItemSelectionChanged()
   99 {
  100     auto index = ui->fromTreeWidget->currentIndex();
  101     if (!ui->fromTreeWidget->selectionModel()->hasSelection() || !index.isValid()) {
  102         return;
  103     }
  104     ui->toTreeWidget->clearSelection();
  105     updatePreview(fromModel.address(index));
  106 }
  107 
  108 void XrefsDialog::onToTreeWidgetItemSelectionChanged()
  109 {
  110     auto index = ui->toTreeWidget->currentIndex();
  111     if (!ui->toTreeWidget->selectionModel()->hasSelection() || !index.isValid()) {
  112         return;
  113     }
  114     ui->fromTreeWidget->clearSelection();
  115     updatePreview(toModel.address(index));
  116 }
  117 
  118 void XrefsDialog::updatePreview(RVA addr)
  119 {
  120     TempConfig tempConfig;
  121     tempConfig.set("scr.html", true);
  122     tempConfig.set("scr.color", COLOR_MODE_16M);
  123     tempConfig.set("asm.lines", false);
  124     tempConfig.set("asm.bytes", false);
  125 
  126     // Use cmd because cmRaw cannot handle the output properly. Why?
  127     QString disas = Core()->cmd("pd--20 @ " + QString::number(addr));
  128     ui->previewTextEdit->document()->setHtml(disas);
  129 
  130     // Does it make any sense?
  131     ui->previewTextEdit->find(normalizeAddr(RAddressString(addr)), QTextDocument::FindBackward);
  132     ui->previewTextEdit->moveCursor(QTextCursor::StartOfLine, QTextCursor::MoveAnchor);
  133 }
  134 
  135 void XrefsDialog::updateLabels(QString name)
  136 {
  137     ui->label_xTo->setText(tr("X-Refs to %1:").arg(name));
  138     ui->label_xFrom->setText(tr("X-Refs from %1:").arg(name));
  139 }
  140 
  141 void XrefsDialog::fillRefsForAddress(RVA addr, QString name, bool whole_function)
  142 {
  143     TempConfig tempConfig;
  144     tempConfig.set("scr.html", false);
  145     tempConfig.set("scr.color", COLOR_MODE_DISABLED);
  146 
  147     setWindowTitle(tr("X-Refs for %1").arg(name));
  148     updateLabels(name);
  149 
  150     toModel.readForOffset(addr, true, whole_function);
  151     fromModel.readForOffset(addr, false, whole_function);
  152 
  153     // Adjust columns to content
  154     qhelpers::adjustColumns(ui->fromTreeWidget, fromModel.columnCount(), 0);
  155     qhelpers::adjustColumns(ui->toTreeWidget, toModel.columnCount(), 0);
  156 
  157     // Automatically select the first line
  158     if (!qhelpers::selectFirstItem(ui->toTreeWidget)) {
  159         qhelpers::selectFirstItem(ui->fromTreeWidget);
  160     }
  161 }
  162 
  163 QString XrefModel::xrefTypeString(const QString &type)
  164 {
  165     if (type == "CODE") {
  166         return QStringLiteral("Code");
  167     } else if (type == "CALL") {
  168         return QStringLiteral("Call");
  169     } else if (type == "DATA") {
  170         return QStringLiteral("Data");
  171     } else if (type == "STRING") {
  172         return QStringLiteral("String");
  173     }
  174     return type;
  175 }
  176 
  177 
  178 XrefModel::XrefModel(QObject *parent)
  179     : AddressableItemModel(parent)
  180 {
  181 }
  182 
  183 void XrefModel::readForOffset(RVA offset, bool to, bool whole_function)
  184 {
  185     beginResetModel();
  186     this->to = to;
  187     xrefs = Core()->getXRefs(offset, to, whole_function);
  188     endResetModel();
  189 }
  190 
  191 int XrefModel::rowCount(const QModelIndex &parent) const
  192 {
  193     Q_UNUSED(parent)
  194     return xrefs.size();
  195 }
  196 
  197 int XrefModel::columnCount(const QModelIndex &parent) const
  198 {
  199     Q_UNUSED(parent)
  200     return Columns::COUNT;
  201 }
  202 
  203 QVariant XrefModel::data(const QModelIndex &index, int role) const
  204 {
  205     if (!index.isValid() || index.row() >= xrefs.count()) {
  206         return QVariant();
  207     }
  208 
  209     const XrefDescription &xref = xrefs.at(index.row());
  210 
  211     switch (role) {
  212     case Qt::DisplayRole:
  213         switch (index.column()) {
  214         case OFFSET:
  215             return to ? xref.from_str : xref.to_str;
  216         case TYPE:
  217             return xrefTypeString(xref.type);
  218         case CODE:
  219             if (to || xref.type != "DATA") {
  220                 return Core()->disassembleSingleInstruction(xref.from);
  221             } else {
  222                 return QString();
  223             }
  224         }
  225         return QVariant();
  226     case FlagDescriptionRole:
  227         return QVariant::fromValue(xref);
  228     default:
  229         return QVariant();
  230     }
  231     return QVariant();
  232 }
  233 
  234 QVariant XrefModel::headerData(int section, Qt::Orientation orientation, int role) const
  235 {
  236     Q_UNUSED(orientation)
  237 
  238     switch (role) {
  239     case Qt::DisplayRole:
  240         switch (section) {
  241         case OFFSET:
  242             return tr("Address");
  243         case TYPE:
  244             return tr("Type");
  245         case CODE:
  246             return tr("Code");
  247         default:
  248             return QVariant();
  249         }
  250     default:
  251         return QVariant();
  252     }
  253 }
  254 
  255 RVA XrefModel::address(const QModelIndex &index) const
  256 {
  257     const auto &xref = xrefs.at(index.row());
  258     return to ? xref.from : xref.to;
  259 }