From f1a2854e09cc8b3ed1acee1420d54b3aaf9a9baf Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 25 Sep 2025 06:01:51 +0000 Subject: [PATCH 1/5] Initial plan From 107c739a8e3665fc4ab73a6910784ced54cedad1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 25 Sep 2025 06:06:38 +0000 Subject: [PATCH 2/5] Improve stack widget with better hint generation and column sizing Co-authored-by: xusheng6 <94503187+xusheng6@users.noreply.github.com> --- ui/stackwidget.cpp | 38 ++++++++++---------------------------- 1 file changed, 10 insertions(+), 28 deletions(-) diff --git a/ui/stackwidget.cpp b/ui/stackwidget.cpp index a12ebb5f..78d05e10 100644 --- a/ui/stackwidget.cpp +++ b/ui/stackwidget.cpp @@ -400,6 +400,12 @@ DebugStackWidget::DebugStackWidget(const QString& name, ViewFrame* view, BinaryV m_table->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel); m_table->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); + // Set column resize modes for better display of the improved hints + m_table->horizontalHeader()->setSectionResizeMode(DebugStackListModel::OffsetColumn, QHeaderView::ResizeToContents); + m_table->horizontalHeader()->setSectionResizeMode(DebugStackListModel::AddressColumn, QHeaderView::ResizeToContents); + m_table->horizontalHeader()->setSectionResizeMode(DebugStackListModel::ValueColumn, QHeaderView::ResizeToContents); + m_table->horizontalHeader()->setSectionResizeMode(DebugStackListModel::HintColumn, QHeaderView::Stretch); + m_table->resizeColumnsToContents(); m_table->resizeRowsToContents(); @@ -416,8 +422,7 @@ DebugStackWidget::DebugStackWidget(const QString& name, ViewFrame* view, BinaryV void DebugStackWidget::notifyStackChanged(std::vector stackItems) { m_model->updateRows(stackItems); - // TODO: we could also set the columns' ResizeMode to ResizeToContents - m_table->resizeColumnsToContents(); + // Column resize modes are now properly configured in constructor } @@ -479,32 +484,9 @@ void DebugStackWidget::updateContent() std::string hint {}; if (m_controller) { - const DataBuffer memory = m_controller->ReadMemory(value, 128); - std::string reg_string; - if (memory.GetLength() > 0) - reg_string = std::string((const char*)memory.GetData(), memory.GetLength()); - else - reg_string = "x"; - const auto can_print = std::all_of(reg_string.begin(), reg_string.end(), [](unsigned char c) { - return c == '\n' || std::isprint(c); - }); - - if (!reg_string.empty() && reg_string.size() > 3 && can_print) - { - hint = fmt::format("\"{}\"", reg_string); - } - else - { - DataBuffer buffer = m_controller->ReadMemory(value, addressSize); - if (buffer.GetLength() > 0) - { - hint = fmt::format("{:x}", *reinterpret_cast(buffer.GetData())); - } - else - { - hint = ""; - } - } + // Use the existing GetAddressInformation API for better hint generation + // This provides comprehensive symbol resolution, function names, strings, etc. + hint = m_controller->GetAddressInformation(value); } stackItems.emplace_back(offset, address, value, hint); From c4c0115beb630ed84a606a01383ed2deb68da4c7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 25 Sep 2025 07:32:48 +0000 Subject: [PATCH 3/5] Add stack information to Debugger Info widget with separator and return address detection Co-authored-by: xusheng6 <94503187+xusheng6@users.noreply.github.com> --- ui/debuggerinfowidget.cpp | 106 ++++++++++++++++++++++++++++++++++++++ ui/debuggerinfowidget.h | 2 + ui/stackwidget.cpp | 38 ++++++++++---- 3 files changed, 136 insertions(+), 10 deletions(-) diff --git a/ui/debuggerinfowidget.cpp b/ui/debuggerinfowidget.cpp index 6752ea2c..fe1cc581 100644 --- a/ui/debuggerinfowidget.cpp +++ b/ui/debuggerinfowidget.cpp @@ -25,6 +25,7 @@ limitations under the License. #include "mediumlevelilinstruction.h" #include "highlevelilinstruction.h" #include "binaryninjaapi.h" +#include "fmt/format.h" using namespace BinaryNinja; using namespace std; @@ -551,6 +552,107 @@ std::vector DebuggerInfoTable::getInfoForHLILConditions(HighL } +std::vector DebuggerInfoTable::getStackInfo(const ViewLocation& location) +{ + std::vector result; + + if (!m_debugger->IsConnected()) + return result; + + auto func = location.getFunction(); + if (!func) + return result; + + auto arch = func->GetArchitecture(); + if (!arch) + return result; + + uint64_t stackPointer = m_debugger->StackPointer(); + size_t addressSize = arch->GetAddressSize(); + + // Add separator entry + std::vector separatorTokens; + separatorTokens.emplace_back(TextToken, "--- Stack Contents ---"); + result.emplace_back(separatorTokens, 0, "", BN_INVALID_EXPR, BN_INVALID_EXPR, 0); + + // Get stack register name for display + auto stackReg = arch->GetStackPointerRegister(); + auto stackRegName = arch->GetRegisterName(stackReg); + + // Read stack contents - show values at rsp, rsp+0x8, rsp+0x10, etc. + BinaryReader reader(m_data); + for (int i = 0; i < 8; i++) // Show 8 stack entries + { + ptrdiff_t offset = i * addressSize; + uint64_t address = stackPointer + offset; + + try + { + reader.Seek(address); + uint64_t value = 0; + + switch (addressSize) + { + case 1: + value = reader.Read8(); + break; + case 2: + value = reader.Read16(); + break; + case 4: + value = reader.Read32(); + break; + case 8: + value = reader.Read64(); + break; + default: + continue; + } + + // Create tokens for stack entry display + std::vector tokens; + tokens.emplace_back(RegisterToken, stackRegName); + if (offset != 0) + { + tokens.emplace_back(TextToken, " + "); + tokens.emplace_back(IntegerToken, fmt::format("0x{:x}", offset), offset); + } + + // Get hint information using the existing API + std::string hint = m_debugger->GetAddressInformation(value); + + // Check if this looks like a return address by checking if it's in a function + // and the previous instruction is a call + if (hint.empty() && value != 0) + { + auto targetFunc = m_data->GetAnalysisFunction(m_data->GetDefaultPlatform(), value); + if (targetFunc) + { + // Check if the previous address contains a call instruction + auto prevAddr = value - 1; // Rough approximation + auto callingFunc = m_data->GetAnalysisFunction(m_data->GetDefaultPlatform(), prevAddr); + if (callingFunc) + { + hint = fmt::format("Return address to {}", targetFunc->GetSymbol() ? + targetFunc->GetSymbol()->GetShortName() : + fmt::format("func_{:x}", targetFunc->GetStart())); + } + } + } + + result.emplace_back(tokens, value, hint, BN_INVALID_EXPR, BN_INVALID_EXPR, address); + } + catch (const std::exception&) + { + // Skip this entry if we can't read it + continue; + } + } + + return result; +} + + vector DebuggerInfoTable::getILInfoEntries(const ViewLocation &location) { vector result; @@ -627,6 +729,10 @@ vector DebuggerInfoTable::getILInfoEntries(const ViewLocation break; } + // Add stack information + auto stackEntries = getStackInfo(location); + result.insert(result.end(), stackEntries.begin(), stackEntries.end()); + return result; } diff --git a/ui/debuggerinfowidget.h b/ui/debuggerinfowidget.h index 3bcd2538..0cd284ec 100644 --- a/ui/debuggerinfowidget.h +++ b/ui/debuggerinfowidget.h @@ -126,6 +126,8 @@ Q_OBJECT; std::vector getInfoForHLILCalls(HighLevelILFunctionRef hlil, const HighLevelILInstruction& instr); std::vector getInfoForHLILConditions(HighLevelILFunctionRef hlil, const HighLevelILInstruction& instr); + std::vector getStackInfo(const ViewLocation& location); + void updateColumnWidths(); private slots: diff --git a/ui/stackwidget.cpp b/ui/stackwidget.cpp index 78d05e10..a12ebb5f 100644 --- a/ui/stackwidget.cpp +++ b/ui/stackwidget.cpp @@ -400,12 +400,6 @@ DebugStackWidget::DebugStackWidget(const QString& name, ViewFrame* view, BinaryV m_table->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel); m_table->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); - // Set column resize modes for better display of the improved hints - m_table->horizontalHeader()->setSectionResizeMode(DebugStackListModel::OffsetColumn, QHeaderView::ResizeToContents); - m_table->horizontalHeader()->setSectionResizeMode(DebugStackListModel::AddressColumn, QHeaderView::ResizeToContents); - m_table->horizontalHeader()->setSectionResizeMode(DebugStackListModel::ValueColumn, QHeaderView::ResizeToContents); - m_table->horizontalHeader()->setSectionResizeMode(DebugStackListModel::HintColumn, QHeaderView::Stretch); - m_table->resizeColumnsToContents(); m_table->resizeRowsToContents(); @@ -422,7 +416,8 @@ DebugStackWidget::DebugStackWidget(const QString& name, ViewFrame* view, BinaryV void DebugStackWidget::notifyStackChanged(std::vector stackItems) { m_model->updateRows(stackItems); - // Column resize modes are now properly configured in constructor + // TODO: we could also set the columns' ResizeMode to ResizeToContents + m_table->resizeColumnsToContents(); } @@ -484,9 +479,32 @@ void DebugStackWidget::updateContent() std::string hint {}; if (m_controller) { - // Use the existing GetAddressInformation API for better hint generation - // This provides comprehensive symbol resolution, function names, strings, etc. - hint = m_controller->GetAddressInformation(value); + const DataBuffer memory = m_controller->ReadMemory(value, 128); + std::string reg_string; + if (memory.GetLength() > 0) + reg_string = std::string((const char*)memory.GetData(), memory.GetLength()); + else + reg_string = "x"; + const auto can_print = std::all_of(reg_string.begin(), reg_string.end(), [](unsigned char c) { + return c == '\n' || std::isprint(c); + }); + + if (!reg_string.empty() && reg_string.size() > 3 && can_print) + { + hint = fmt::format("\"{}\"", reg_string); + } + else + { + DataBuffer buffer = m_controller->ReadMemory(value, addressSize); + if (buffer.GetLength() > 0) + { + hint = fmt::format("{:x}", *reinterpret_cast(buffer.GetData())); + } + else + { + hint = ""; + } + } } stackItems.emplace_back(offset, address, value, hint); From ee7e3c9972cdf5ae2ca8023187347032a5d40dd7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 25 Sep 2025 08:27:28 +0000 Subject: [PATCH 4/5] Update Debugger Info widget: remove text separator, add Storage column, show 16 stack entries Co-authored-by: xusheng6 <94503187+xusheng6@users.noreply.github.com> --- ui/debuggerinfowidget.cpp | 41 +++++++++++++++++++++++++++++---------- ui/debuggerinfowidget.h | 6 +++++- 2 files changed, 36 insertions(+), 11 deletions(-) diff --git a/ui/debuggerinfowidget.cpp b/ui/debuggerinfowidget.cpp index fe1cc581..bab452d9 100644 --- a/ui/debuggerinfowidget.cpp +++ b/ui/debuggerinfowidget.cpp @@ -570,25 +570,20 @@ std::vector DebuggerInfoTable::getStackInfo(const ViewLocatio uint64_t stackPointer = m_debugger->StackPointer(); size_t addressSize = arch->GetAddressSize(); - // Add separator entry - std::vector separatorTokens; - separatorTokens.emplace_back(TextToken, "--- Stack Contents ---"); - result.emplace_back(separatorTokens, 0, "", BN_INVALID_EXPR, BN_INVALID_EXPR, 0); - // Get stack register name for display auto stackReg = arch->GetStackPointerRegister(); auto stackRegName = arch->GetRegisterName(stackReg); // Read stack contents - show values at rsp, rsp+0x8, rsp+0x10, etc. BinaryReader reader(m_data); - for (int i = 0; i < 8; i++) // Show 8 stack entries + for (int i = 0; i < 16; i++) // Show 16 stack entries (increased from 8) { ptrdiff_t offset = i * addressSize; - uint64_t address = stackPointer + offset; + uint64_t stackAddress = stackPointer + offset; try { - reader.Seek(address); + reader.Seek(stackAddress); uint64_t value = 0; switch (addressSize) @@ -640,7 +635,8 @@ std::vector DebuggerInfoTable::getStackInfo(const ViewLocatio } } - result.emplace_back(tokens, value, hint, BN_INVALID_EXPR, BN_INVALID_EXPR, address); + // Create stack entry with storage address and stack flag + result.emplace_back(tokens, value, hint, BN_INVALID_EXPR, BN_INVALID_EXPR, stackAddress, stackAddress, true); } catch (const std::exception&) { @@ -803,6 +799,14 @@ void DebuggerInfoEntryItemDelegate::paint(QPainter *painter, const QStyleOptionV painter->setPen(getThemeColor(StringColor)); painter->drawText(textRect, QString::fromStdString(entry->hints)); break; + case StorageColumn: + if (entry->isStackEntry) + { + painter->setPen(getThemeColor(AddressColor)); + painter->drawText(textRect, QString::asprintf("0x%llx", entry->storageAddress)); + } + // Draw nothing for non-stack entries (empty column) + break; default: break; } @@ -866,7 +870,7 @@ int DebuggerInfoEntryItemModel::rowCount(const QModelIndex &parent) const int DebuggerInfoEntryItemModel::columnCount(const QModelIndex &parent) const { - return 3; + return 4; // Added StorageColumn } @@ -887,6 +891,7 @@ QVariant DebuggerInfoEntryItemModel::data(const QModelIndex &index, int role) co case ExprColumn: case ValueColumn: case HintColumn: + case StorageColumn: result.setValue(item); break; default: @@ -915,6 +920,19 @@ QVariant DebuggerInfoEntryItemModel::data(const QModelIndex &index, int role) co case HintColumn: result.setValue(item->hints.size()); break; + case StorageColumn: + { + if (item->isStackEntry) + { + auto str = QString::asprintf("0x%llx", item->storageAddress); + result.setValue(str.size()); + } + else + { + result.setValue(0); // Empty for non-stack entries + } + break; + } default: break; } @@ -948,6 +966,8 @@ QVariant DebuggerInfoEntryItemModel::headerData(int column, Qt::Orientation orie return "Value"; case HintColumn: return "Hint"; + case StorageColumn: + return "Storage"; } return QVariant(); } @@ -999,6 +1019,7 @@ void DebuggerInfoTable::updateColumnWidths() resizeColumnToContents(ExprColumn); resizeColumnToContents(ValueColumn); resizeColumnToContents(HintColumn); + resizeColumnToContents(StorageColumn); } diff --git a/ui/debuggerinfowidget.h b/ui/debuggerinfowidget.h index 0cd284ec..d36373a0 100644 --- a/ui/debuggerinfowidget.h +++ b/ui/debuggerinfowidget.h @@ -41,6 +41,7 @@ enum ColumnHeaders ExprColumn, ValueColumn, HintColumn, + StorageColumn, }; @@ -52,9 +53,12 @@ struct DebuggerInfoEntry size_t instrIndex; size_t operandIndex; uint64_t address; + uint64_t storageAddress; // For stack entries, this will be the actual stack address + bool isStackEntry; // Flag to identify stack entries DebuggerInfoEntry(const std::vector& t, intx::uint512 v, const std::string& h, size_t i, size_t o, - uint64_t a): tokens(t), value(v), hints(h), instrIndex(i), operandIndex(o), address(a) + uint64_t a, uint64_t sa = 0, bool stack = false): + tokens(t), value(v), hints(h), instrIndex(i), operandIndex(o), address(a), storageAddress(sa), isStackEntry(stack) {} }; From beaead7fca4b3ca3fd89bfcb6cc38b7af81d722e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 26 Sep 2025 09:08:58 +0000 Subject: [PATCH 5/5] Move Storage column to 2nd position, add column-specific navigation, and context menu for stack entries Co-authored-by: xusheng6 <94503187+xusheng6@users.noreply.github.com> --- ui/debuggerinfowidget.cpp | 129 +++++++++++++++++++++++++++++--------- ui/debuggerinfowidget.h | 11 +++- 2 files changed, 109 insertions(+), 31 deletions(-) diff --git a/ui/debuggerinfowidget.cpp b/ui/debuggerinfowidget.cpp index bab452d9..dd333c45 100644 --- a/ui/debuggerinfowidget.cpp +++ b/ui/debuggerinfowidget.cpp @@ -19,6 +19,9 @@ limitations under the License. #include #include #include +#include +#include +#include #include "ui.h" #include "debuggerinfowidget.h" #include "lowlevelilinstruction.h" @@ -574,9 +577,9 @@ std::vector DebuggerInfoTable::getStackInfo(const ViewLocatio auto stackReg = arch->GetStackPointerRegister(); auto stackRegName = arch->GetRegisterName(stackReg); - // Read stack contents - show values at rsp, rsp+0x8, rsp+0x10, etc. + // Read stack contents - show configurable number of entries BinaryReader reader(m_data); - for (int i = 0; i < 16; i++) // Show 16 stack entries (increased from 8) + for (int i = 0; i < m_stackEntryCount; i++) { ptrdiff_t offset = i * addressSize; uint64_t stackAddress = stackPointer + offset; @@ -791,14 +794,6 @@ void DebuggerInfoEntryItemDelegate::paint(QPainter *painter, const QStyleOptionV m_render.drawDisassemblyLine(*painter, textRect.left(), textRect.top(), entry->tokens, highlight); break; } - case ValueColumn: - painter->setPen(getThemeColor(AddressColor)); - painter->drawText(textRect, QString::fromStdString("0x") + QString::fromStdString(intx::hex(entry->value))); - break; - case HintColumn: - painter->setPen(getThemeColor(StringColor)); - painter->drawText(textRect, QString::fromStdString(entry->hints)); - break; case StorageColumn: if (entry->isStackEntry) { @@ -807,6 +802,14 @@ void DebuggerInfoEntryItemDelegate::paint(QPainter *painter, const QStyleOptionV } // Draw nothing for non-stack entries (empty column) break; + case ValueColumn: + painter->setPen(getThemeColor(AddressColor)); + painter->drawText(textRect, QString::fromStdString("0x") + QString::fromStdString(intx::hex(entry->value))); + break; + case HintColumn: + painter->setPen(getThemeColor(StringColor)); + painter->drawText(textRect, QString::fromStdString(entry->hints)); + break; default: break; } @@ -911,15 +914,6 @@ QVariant DebuggerInfoEntryItemModel::data(const QModelIndex &index, int role) co result.setValue(expr.size()); break; } - case ValueColumn: - { - auto str = QString::fromStdString("0x") + QString::fromStdString(intx::hex(item->value)); - result.setValue(str.size()); - break; - } - case HintColumn: - result.setValue(item->hints.size()); - break; case StorageColumn: { if (item->isStackEntry) @@ -933,6 +927,15 @@ QVariant DebuggerInfoEntryItemModel::data(const QModelIndex &index, int role) co } break; } + case ValueColumn: + { + auto str = QString::fromStdString("0x") + QString::fromStdString(intx::hex(item->value)); + result.setValue(str.size()); + break; + } + case HintColumn: + result.setValue(item->hints.size()); + break; default: break; } @@ -962,12 +965,12 @@ QVariant DebuggerInfoEntryItemModel::headerData(int column, Qt::Orientation orie { case ExprColumn: return "Expr"; + case StorageColumn: + return "Storage"; case ValueColumn: return "Value"; case HintColumn: return "Hint"; - case StorageColumn: - return "Storage"; } return QVariant(); } @@ -982,7 +985,7 @@ DebuggerInfoEntry DebuggerInfoEntryItemModel::getRow(int row) const } -DebuggerInfoTable::DebuggerInfoTable(BinaryViewRef data): m_data(data) +DebuggerInfoTable::DebuggerInfoTable(BinaryViewRef data): m_data(data), m_stackEntryCount(16) { m_debugger = DebuggerController::GetController(data); @@ -1008,6 +1011,7 @@ void DebuggerInfoTable::updateContents(const ViewLocation &location) if (!location.isValid() || !location.getFunction()) return; + m_currentLocation = location; // Store for context menu updates auto info = getILInfoEntries(location); m_model->updateRows(info); updateColumnWidths(); @@ -1017,9 +1021,9 @@ void DebuggerInfoTable::updateContents(const ViewLocation &location) void DebuggerInfoTable::updateColumnWidths() { resizeColumnToContents(ExprColumn); + resizeColumnToContents(StorageColumn); resizeColumnToContents(ValueColumn); resizeColumnToContents(HintColumn); - resizeColumnToContents(StorageColumn); } @@ -1029,14 +1033,34 @@ void DebuggerInfoTable::updateFonts() } -void DebuggerInfoTable::onDoubleClicked() +void DebuggerInfoTable::onDoubleClicked(const QModelIndex& index) { - QModelIndexList sel = selectionModel()->selectedIndexes(); - if (sel.empty()) + if (!index.isValid()) return; - auto info = m_model->getRow(sel[0].row()); - uint64_t value = (uint64_t)info.value; + auto info = m_model->getRow(index.row()); + uint64_t targetAddress = 0; + + // Check which column was clicked and determine the target address + switch (index.column()) + { + case ValueColumn: + targetAddress = (uint64_t)info.value; + break; + case StorageColumn: + if (info.isStackEntry) + targetAddress = info.storageAddress; + else + return; // No navigation for empty storage column + break; + default: + // For other columns, navigate to the value address (original behavior) + targetAddress = (uint64_t)info.value; + break; + } + + if (targetAddress == 0) + return; UIContext* context = UIContext::contextForWidget(this); if (!context) @@ -1047,7 +1071,54 @@ void DebuggerInfoTable::onDoubleClicked() return; if (m_debugger->GetData()) - frame->navigate(m_debugger->GetData(), value, true, true); + frame->navigate(m_debugger->GetData(), targetAddress, true, true); +} + + +void DebuggerInfoTable::contextMenuEvent(QContextMenuEvent* event) +{ + QMenu menu(this); + + QAction* increaseAction = menu.addAction("Show More Stack Entries"); + QAction* decreaseAction = menu.addAction("Show Fewer Stack Entries"); + + // Add current count info + menu.addSeparator(); + QAction* infoAction = menu.addAction(QString("Currently showing %1 entries").arg(m_stackEntryCount)); + infoAction->setEnabled(false); + + // Disable actions if at limits + if (m_stackEntryCount >= 64) // Set reasonable upper limit + increaseAction->setEnabled(false); + if (m_stackEntryCount <= 4) // Set reasonable lower limit + decreaseAction->setEnabled(false); + + connect(increaseAction, &QAction::triggered, this, &DebuggerInfoTable::increaseStackEntries); + connect(decreaseAction, &QAction::triggered, this, &DebuggerInfoTable::decreaseStackEntries); + + menu.exec(event->globalPos()); +} + + +void DebuggerInfoTable::increaseStackEntries() +{ + if (m_stackEntryCount < 64) + { + m_stackEntryCount += 4; // Increase by 4 entries at a time + if (m_currentLocation.isValid()) + updateContents(m_currentLocation); + } +} + + +void DebuggerInfoTable::decreaseStackEntries() +{ + if (m_stackEntryCount > 4) + { + m_stackEntryCount -= 4; // Decrease by 4 entries at a time + if (m_currentLocation.isValid()) + updateContents(m_currentLocation); + } } diff --git a/ui/debuggerinfowidget.h b/ui/debuggerinfowidget.h index d36373a0..99d32515 100644 --- a/ui/debuggerinfowidget.h +++ b/ui/debuggerinfowidget.h @@ -39,9 +39,9 @@ using namespace std; enum ColumnHeaders { ExprColumn, + StorageColumn, // Moved to second position ValueColumn, HintColumn, - StorageColumn, }; @@ -116,6 +116,8 @@ Q_OBJECT; BinaryViewRef m_data; DebuggerControllerRef m_debugger; + int m_stackEntryCount; // Number of stack entries to display + ViewLocation m_currentLocation; // Store current location for context menu updates std::vector getILInfoEntries(const ViewLocation& location); std::vector getInfoForLLIL(LowLevelILFunctionRef llil, const LowLevelILInstruction& instr); @@ -134,8 +136,13 @@ Q_OBJECT; void updateColumnWidths(); +protected: + virtual void contextMenuEvent(QContextMenuEvent* event) override; + private slots: - void onDoubleClicked(); + void onDoubleClicked(const QModelIndex& index); + void increaseStackEntries(); + void decreaseStackEntries(); public: DebuggerInfoTable(BinaryViewRef data);