From d5916fd14c82eb05f836633c57a0b67190df95c6 Mon Sep 17 00:00:00 2001 From: Sepalani Date: Wed, 1 Sep 2021 11:58:56 +0400 Subject: MemoryWidget: Add negative offset search support --- Source/Core/DolphinQt/Debugger/MemoryWidget.cpp | 83 ++++++++++++++++--------- 1 file changed, 54 insertions(+), 29 deletions(-) (limited to 'Source/Core/DolphinQt/Debugger/MemoryWidget.cpp') diff --git a/Source/Core/DolphinQt/Debugger/MemoryWidget.cpp b/Source/Core/DolphinQt/Debugger/MemoryWidget.cpp index 04320c8e0d..4739cf5474 100644 --- a/Source/Core/DolphinQt/Debugger/MemoryWidget.cpp +++ b/Source/Core/DolphinQt/Debugger/MemoryWidget.cpp @@ -3,6 +3,7 @@ #include "DolphinQt/Debugger/MemoryWidget.h" +#include #include #include @@ -449,26 +450,21 @@ void MemoryWidget::SetAddress(u32 address) void MemoryWidget::OnSearchAddress() { - bool good_addr, good_offset; - // Returns 0 if conversion fails - const u32 addr = m_search_address->text().toUInt(&good_addr, 16); - const u32 offset = m_search_offset->text().toUInt(&good_offset, 16); + const auto target_addr = GetTargetAddress(); + + if (target_addr.is_good_address && target_addr.is_good_offset) + m_memory_view->SetAddress(target_addr.address); QFont addr_font, offset_font; QPalette addr_palette, offset_palette; - if (good_addr || m_search_address->text().isEmpty()) - { - if (good_addr) - m_memory_view->SetAddress(addr + offset); - } - else + if (!target_addr.is_good_address) { addr_font.setBold(true); addr_palette.setColor(QPalette::Text, Qt::red); } - if (!good_offset && !m_search_offset->text().isEmpty()) + if (!target_addr.is_good_offset) { offset_font.setBold(true); offset_palette.setColor(QPalette::Text, Qt::red); @@ -500,18 +496,15 @@ void MemoryWidget::OnSetValue() if (!Core::IsRunning()) return; - bool good_address, good_offset; - // Returns 0 if conversion fails - u32 addr = m_search_address->text().toUInt(&good_address, 16); - addr += m_search_offset->text().toUInt(&good_offset, 16); + auto target_addr = GetTargetAddress(); - if (!good_address) + if (!target_addr.is_good_address) { ModalMessageBox::critical(this, tr("Error"), tr("Bad address provided.")); return; } - if (!good_offset) + if (!target_addr.is_good_offset) { ModalMessageBox::critical(this, tr("Error"), tr("Bad offset provided.")); return; @@ -533,7 +526,7 @@ void MemoryWidget::OnSetValue() const QByteArray bytes = GetValueData(); for (const char c : bytes) - accessors->WriteU8(addr++, static_cast(c)); + accessors->WriteU8(target_addr.address++, static_cast(c)); Update(); } @@ -612,34 +605,66 @@ QByteArray MemoryWidget::GetValueData() const return QByteArray::fromHex(value); } +MemoryWidget::TargetAddress MemoryWidget::GetTargetAddress() const +{ + TargetAddress target; + + // Returns 0 if conversion fails + const u32 addr = m_search_address->text().toUInt(&target.is_good_address, 16); + target.is_good_address |= m_search_address->text().isEmpty(); + const s32 offset = m_search_offset->text().toInt(&target.is_good_offset, 16); + const u32 neg_offset = offset != std::numeric_limits::min() ? + -offset : + u32(std::numeric_limits::max()) + 1; + target.is_good_offset |= m_search_offset->text().isEmpty(); + target.is_good_offset &= offset >= 0 || neg_offset <= addr; + target.is_good_offset &= offset <= 0 || (std::numeric_limits::max() - u32(offset)) >= addr; + + if (!target.is_good_address || !target.is_good_offset) + return target; + + if (offset < 0) + target.address = addr - neg_offset; + else + target.address = addr + u32(offset); + return target; +} + void MemoryWidget::FindValue(bool next) { - if (!IsValueValid()) + auto target_addr = GetTargetAddress(); + + if (!target_addr.is_good_address) { - m_result_label->setText(tr("Bad value provided.")); + m_result_label->setText(tr("Bad address provided.")); return; } - const QByteArray search_for = GetValueData(); - - if (search_for.isEmpty()) + if (!target_addr.is_good_offset) { - m_result_label->setText(tr("No Value Given")); + m_result_label->setText(tr("Bad offset provided.")); return; } - u32 addr = 0; if (!m_search_address->text().isEmpty()) { // skip the quoted address so we don't potentially refind the last result - addr = m_search_address->text().toUInt(nullptr, 16) + - m_search_offset->text().toUInt(nullptr, 16) + (next ? 1 : -1); + target_addr.address += next ? 1 : -1; + } + + const QByteArray search_for = GetValueData(); + + if (search_for.isEmpty()) + { + m_result_label->setText(tr("No value provided.")); + return; } AddressSpace::Accessors* accessors = AddressSpace::GetAccessors(m_memory_view->GetAddressSpace()); - const auto found_addr = accessors->Search(addr, reinterpret_cast(search_for.data()), - static_cast(search_for.size()), next); + const auto found_addr = + accessors->Search(target_addr.address, reinterpret_cast(search_for.data()), + static_cast(search_for.size()), next); if (found_addr.has_value()) { -- cgit v1.2.3