From 56d9f7178d875bf032025aa80b529b6fd2096be7 Mon Sep 17 00:00:00 2001 From: Pedro de Medeiros Date: Tue, 5 Jul 2022 00:15:07 -0300 Subject: [PATCH] support labels in BreakpointViewer --- src/BreakpointViewer.cpp | 83 +++++++++++++++++++++++++++++----------- src/BreakpointViewer.h | 10 ++++- src/BreakpointViewer.ui | 5 +++ src/DebuggerForm.cpp | 2 +- 4 files changed, 75 insertions(+), 25 deletions(-) diff --git a/src/BreakpointViewer.cpp b/src/BreakpointViewer.cpp index 5b74abd8..648be812 100644 --- a/src/BreakpointViewer.cpp +++ b/src/BreakpointViewer.cpp @@ -1,6 +1,7 @@ #include "BreakpointViewer.h" #include "Convert.h" #include "CommClient.h" +#include "DebugSession.h" #include "OpenMSXConnection.h" #include "ScopedAssign.h" #include "ranges.h" @@ -17,17 +18,18 @@ enum TableColumns { ENABLED = 0, WP_TYPE = 1, LOCATION = 2, - BP_ADDRESS = 2, WP_REGION = 2, T_CONDITION = 3, SLOT = 4, SEGMENT = 5, - ID = 6 + ID = 6, + BP_ADDRESS = 7, }; -BreakpointViewer::BreakpointViewer(QWidget* parent) - : QTabWidget(parent), - ui(new Ui::BreakpointViewer) +BreakpointViewer::BreakpointViewer(DebugSession& session, QWidget* parent) + : QTabWidget(parent), + ui(new Ui::BreakpointViewer), + debugSession(session) { setupUi(this); @@ -39,9 +41,10 @@ BreakpointViewer::BreakpointViewer(QWidget* parent) connect(btnRemoveCn, &QPushButton::clicked, this, &BreakpointViewer::on_btnRemoveCn_clicked); bpTableWidget->horizontalHeader()->setHighlightSections(false); - bpTableWidget->sortByColumn(BP_ADDRESS, Qt::AscendingOrder); + bpTableWidget->sortByColumn(LOCATION, Qt::AscendingOrder); bpTableWidget->setColumnHidden(WP_TYPE, true); bpTableWidget->setColumnHidden(ID, true); + bpTableWidget->setColumnHidden(BP_ADDRESS, true); bpTableWidget->resizeColumnsToContents(); bpTableWidget->setSortingEnabled(true); connect(bpTableWidget, &QTableWidget::itemPressed, this, &BreakpointViewer::on_itemPressed); @@ -254,7 +257,7 @@ void BreakpointViewer::setBreakpointChecked(BreakpointRef::Type type, int row, Q table->setSortingEnabled(oldValue); } -void BreakpointViewer::setTextField(BreakpointRef::Type type, int row, int column, const QString& value) +void BreakpointViewer::setTextField(BreakpointRef::Type type, int row, int column, const QString& value, const QString& tooltip) { auto sa = ScopedAssign(userMode, false); @@ -264,6 +267,7 @@ void BreakpointViewer::setTextField(BreakpointRef::Type type, int row, int colum table->setSortingEnabled(false); item->setText(value); + item->setToolTip(tooltip); table->setSortingEnabled(oldValue); } @@ -309,13 +313,24 @@ std::optional BreakpointViewer::parseSegmentField(std::optional in return {}; } +std::optional BreakpointViewer::parseSymbolOrValue(const QString& field) const +{ + if (Symbol* s = debugSession.symbolTable().getAddressSymbol(field)) { + return AddressRange{uint16_t(s->value())}; + } + if (auto address = stringToValue(field)) { + return AddressRange{*address}; + } + return {}; +} + static const char* ComboTypeNames[] = { "read_mem", "write_mem", "read_io", "write_io" }; std::optional BreakpointViewer::parseLocationField( std::optional index, BreakpointRef::Type type, const QString& field, const QString& comboTxt) { if (type == BreakpointRef::BREAKPOINT) { - auto value = stringToValue(field); + auto value = parseSymbolOrValue(field); return value ? AddressRange{*value} : (index ? breakpoints->getBreakpoint(*index).range : std::optional()); } @@ -367,27 +382,34 @@ void BreakpointViewer::changeTableItem(BreakpointRef::Type type, QTableWidgetIte case LOCATION: { auto* model = table->model(); auto* combo = (QComboBox*) table->indexWidget(model->index(row, WP_TYPE)); - int adrLen; + int adrLen; if (type == BreakpointRef::CONDITION) { return; } else if (type == BreakpointRef::WATCHPOINT) { auto wType = static_cast(combo->currentIndex() + 1); adrLen = (wType == Breakpoint::WATCHPOINT_IOREAD || wType == Breakpoint::WATCHPOINT_IOWRITE) - ? 2 : 4; + ? 2 : 4; } else { adrLen = 4; } if (auto range = parseLocationField(index, type, item->text(), combo ? combo->currentText() : "")) { auto [begin, end] = *range; - setTextField(type, row, LOCATION, QString("%1%2%3") - .arg(hexValue(begin, adrLen)) - .arg(end ? ":" : "") - .arg(end ? hexValue(*end, adrLen) : "")); + QString address = QString("%1%2%3") + .arg(hexValue(begin, adrLen)) + .arg(end ? ":" : "") + .arg(end ? hexValue(*end, adrLen) : ""); + setTextField(type, row, BP_ADDRESS, address); + + // Use a symbolic address in the location field if available + QString location = ((type == BreakpointRef::BREAKPOINT) && debugSession.symbolTable().getAddressSymbol(item->text())) + ? item->text() : address; + setTextField(type, row, LOCATION, location, location != address ? address : ""); } else { enabled = false; setTextField(type, row, LOCATION, ""); + setTextField(type, row, BP_ADDRESS, ""); setBreakpointChecked(type, row, Qt::Unchecked); } if (!enabled) return; @@ -706,7 +728,7 @@ int BreakpointViewer::createTableRow(BreakpointRef::Type type, int row) createComboBox(row); } - // address + // location auto* item2 = new QTableWidgetItem(); item2->setTextAlignment(Qt::AlignCenter); table->setItem(row, LOCATION, item2); @@ -742,6 +764,14 @@ int BreakpointViewer::createTableRow(BreakpointRef::Type type, int row) item6->setText(""); table->setItem(row, ID, item6); + // bp_address + if (type == BreakpointRef::BREAKPOINT) { + auto* item7 = new QTableWidgetItem(); + item7->setFlags(Qt::NoItemFlags); + item7->setText(""); + table->setItem(row, BP_ADDRESS, item7); + } + return row; } @@ -762,15 +792,24 @@ void BreakpointViewer::fillTableRow(int index, BreakpointRef::Type type, int row combo->setCurrentIndex(static_cast(bp.type) - 1); } - // location - int locLen = (bp.type == Breakpoint::WATCHPOINT_IOREAD - || bp.type == Breakpoint::WATCHPOINT_IOWRITE) ? 2 : 4; - QString location = QString("%1%2%3").arg(hexValue(bp.range->start, locLen)) - .arg(bp.range->end ? ":" : "") - .arg(bp.range->end ? hexValue(*bp.range->end, locLen) : ""); - // location auto* item2 = table->item(row, LOCATION); + QString location; + + if (bp.type == Breakpoint::BREAKPOINT) { + if (Symbol* s = debugSession.symbolTable().getAddressSymbol(item2->text())) { + if (s->value() == bp.range->start) { + location = s->text(); + } + } + } + if (location.isEmpty()) { + int locLen = (bp.type == Breakpoint::WATCHPOINT_IOREAD + || bp.type == Breakpoint::WATCHPOINT_IOWRITE) ? 2 : 4; + location = QString("%1%2%3").arg(hexValue(bp.range->start, locLen)) + .arg(bp.range->end ? ":" : "") + .arg(bp.range->end ? hexValue(*bp.range->end, locLen) : ""); + } item2->setText(location); auto* item3 = table->item(row, T_CONDITION); diff --git a/src/BreakpointViewer.h b/src/BreakpointViewer.h index ef81693c..29581d00 100644 --- a/src/BreakpointViewer.h +++ b/src/BreakpointViewer.h @@ -10,6 +10,7 @@ class QPaintEvent; class Breakpoints; +class DebugSession; struct BreakpointRef { enum Type { BREAKPOINT, WATCHPOINT, CONDITION, ALL } type; @@ -24,7 +25,7 @@ class BreakpointViewer : public QTabWidget, private Ui::BreakpointViewer { Q_OBJECT public: - BreakpointViewer(QWidget* parent = nullptr); + BreakpointViewer(DebugSession& session, QWidget* parent = nullptr); void setBreakpoints(Breakpoints* bps); void on_btnAddBp_clicked(); @@ -42,7 +43,10 @@ class BreakpointViewer : public QTabWidget, private Ui::BreakpointViewer void contentsUpdated(bool merge); private: - void setTextField(BreakpointRef::Type type, int row, int column, const QString& value); + void setTextField(BreakpointRef::Type type, int row, int column, const QString& value, const QString& tooltip = {}); + + std::optional parseSymbolOrValue(const QString& field) const; + std::optional parseLocationField(std::optional index, BreakpointRef::Type type, const QString& field, @@ -86,6 +90,8 @@ class BreakpointViewer : public QTabWidget, private Ui::BreakpointViewer private: Ui::BreakpointViewer* ui; + DebugSession& debugSession; + QTableWidget* tables[BreakpointRef::ALL]; std::map maps[BreakpointRef::ALL]; diff --git a/src/BreakpointViewer.ui b/src/BreakpointViewer.ui index 635c4da0..08e2e1c9 100644 --- a/src/BreakpointViewer.ui +++ b/src/BreakpointViewer.ui @@ -115,6 +115,11 @@ # + + + real_addr + + diff --git a/src/DebuggerForm.cpp b/src/DebuggerForm.cpp index 48d15de4..9e4406f4 100644 --- a/src/DebuggerForm.cpp +++ b/src/DebuggerForm.cpp @@ -566,7 +566,7 @@ void DebuggerForm::createForm() connect(dw, &DockableWidget::visibilityChanged, this, &DebuggerForm::dockWidgetVisibilityChanged); // create breakpoints viewer - bpView = new BreakpointViewer(this); + bpView = new BreakpointViewer(session, this); dw = new DockableWidget(dockMan); dw->setWidget(bpView); dw->setTitle(tr("Debug list"));