summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorRena Kunisaki <hyperhacker@gmail.com>2020-07-06 18:16:32 -0400
committerRena Kunisaki <hyperhacker@gmail.com>2020-07-11 13:38:58 -0400
commita553f2238575420b26e42f8e424f1c90276fe615 (patch)
treee8e0fc21bf920830c2600723c861fba1d7e5d80f /Source/Core
parent87287181dd17156170d601ca5e7c81e66afb6643 (diff)
Add Break On Hit and Log On Hit for instruction breakpoints
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/PowerPC/BreakPoints.cpp27
-rw-r--r--Source/Core/Core/PowerPC/BreakPoints.h5
-rw-r--r--Source/Core/Core/PowerPC/PowerPC.cpp10
-rw-r--r--Source/Core/DolphinQt/Debugger/BreakpointWidget.cpp17
-rw-r--r--Source/Core/DolphinQt/Debugger/BreakpointWidget.h1
-rw-r--r--Source/Core/DolphinQt/Debugger/NewBreakpointDialog.cpp22
-rw-r--r--Source/Core/DolphinQt/Debugger/NewBreakpointDialog.h8
7 files changed, 71 insertions, 19 deletions
diff --git a/Source/Core/Core/PowerPC/BreakPoints.cpp b/Source/Core/Core/PowerPC/BreakPoints.cpp
index fbaeff777e..00227a434b 100644
--- a/Source/Core/Core/PowerPC/BreakPoints.cpp
+++ b/Source/Core/Core/PowerPC/BreakPoints.cpp
@@ -30,6 +30,19 @@ bool BreakPoints::IsTempBreakPoint(u32 address) const
});
}
+bool BreakPoints::IsBreakPointBreakOnHit(u32 address) const
+{
+ return std::any_of(m_breakpoints.begin(), m_breakpoints.end(), [address](const auto& bp) {
+ return bp.address == address && bp.break_on_hit;
+ });
+}
+
+bool BreakPoints::IsBreakPointLogOnHit(u32 address) const
+{
+ return std::any_of(m_breakpoints.begin(), m_breakpoints.end(),
+ [address](const auto& bp) { return bp.address == address && bp.log_on_hit; });
+}
+
BreakPoints::TBreakPointsStr BreakPoints::GetStrings() const
{
TBreakPointsStr bp_strings;
@@ -38,7 +51,8 @@ BreakPoints::TBreakPointsStr BreakPoints::GetStrings() const
if (!bp.is_temporary)
{
std::ostringstream ss;
- ss << std::hex << bp.address << " " << (bp.is_enabled ? "n" : "");
+ ss << std::hex << bp.address << " " << (bp.is_enabled ? "n" : "")
+ << (bp.log_on_hit ? "l" : "") << (bp.break_on_hit ? "b" : "");
bp_strings.push_back(ss.str());
}
}
@@ -55,6 +69,8 @@ void BreakPoints::AddFromStrings(const TBreakPointsStr& bp_strings)
ss << std::hex << bp_string;
ss >> bp.address;
bp.is_enabled = bp_string.find('n') != bp_string.npos;
+ bp.log_on_hit = bp_string.find('l') != bp_string.npos;
+ bp.break_on_hit = bp_string.find('b') != bp_string.npos;
bp.is_temporary = false;
Add(bp);
}
@@ -72,6 +88,11 @@ void BreakPoints::Add(const TBreakPoint& bp)
void BreakPoints::Add(u32 address, bool temp)
{
+ BreakPoints::Add(address, temp, true, false);
+}
+
+void BreakPoints::Add(u32 address, bool temp, bool break_on_hit, bool log_on_hit)
+{
// Only add new addresses
if (IsAddressBreakPoint(address))
return;
@@ -79,6 +100,8 @@ void BreakPoints::Add(u32 address, bool temp)
TBreakPoint bp; // breakpoint settings
bp.is_enabled = true;
bp.is_temporary = temp;
+ bp.break_on_hit = break_on_hit;
+ bp.log_on_hit = log_on_hit;
bp.address = address;
m_breakpoints.push_back(bp);
@@ -154,7 +177,7 @@ void MemChecks::AddFromStrings(const TMemChecksStr& mc_strings)
mc.is_break_on_read = mc_string.find('r') != mc_string.npos;
mc.is_break_on_write = mc_string.find('w') != mc_string.npos;
mc.log_on_hit = mc_string.find('l') != mc_string.npos;
- mc.break_on_hit = mc_string.find('p') != mc_string.npos;
+ mc.break_on_hit = mc_string.find('b') != mc_string.npos;
if (mc.is_ranged)
ss >> mc.end_address;
else
diff --git a/Source/Core/Core/PowerPC/BreakPoints.h b/Source/Core/Core/PowerPC/BreakPoints.h
index c00caeef98..571427f47d 100644
--- a/Source/Core/Core/PowerPC/BreakPoints.h
+++ b/Source/Core/Core/PowerPC/BreakPoints.h
@@ -20,6 +20,8 @@ struct TBreakPoint
u32 address = 0;
bool is_enabled = false;
bool is_temporary = false;
+ bool log_on_hit = false;
+ bool break_on_hit = false;
};
struct TMemCheck
@@ -56,8 +58,11 @@ public:
// is address breakpoint
bool IsAddressBreakPoint(u32 address) const;
bool IsTempBreakPoint(u32 address) const;
+ bool IsBreakPointBreakOnHit(u32 address) const;
+ bool IsBreakPointLogOnHit(u32 address) const;
// Add BreakPoint
+ void Add(u32 address, bool temp, bool break_on_hit, bool log_on_hit);
void Add(u32 address, bool temp = false);
void Add(const TBreakPoint& bp);
diff --git a/Source/Core/Core/PowerPC/PowerPC.cpp b/Source/Core/Core/PowerPC/PowerPC.cpp
index ebac1a07d9..3833774c85 100644
--- a/Source/Core/Core/PowerPC/PowerPC.cpp
+++ b/Source/Core/Core/PowerPC/PowerPC.cpp
@@ -28,6 +28,7 @@
#include "Core/PowerPC/Interpreter/Interpreter.h"
#include "Core/PowerPC/JitInterface.h"
#include "Core/PowerPC/MMU.h"
+#include "Core/PowerPC/PPCSymbolDB.h"
namespace PowerPC
{
@@ -603,7 +604,14 @@ void CheckBreakPoints()
{
if (PowerPC::breakpoints.IsAddressBreakPoint(PC))
{
- CPU::Break();
+ if (PowerPC::breakpoints.IsBreakPointBreakOnHit(PC))
+ CPU::Break();
+ if (PowerPC::breakpoints.IsBreakPointLogOnHit(PC))
+ {
+ NOTICE_LOG(MEMMAP, "BP %08x %s(%08x %08x %08x %08x %08x %08x %08x %08x %08x %08x) LR=%08x",
+ PC, g_symbolDB.GetDescription(PC).c_str(), GPR(3), GPR(4), GPR(5), GPR(6), GPR(7),
+ GPR(8), GPR(9), GPR(10), GPR(11), GPR(12), LR);
+ }
if (PowerPC::breakpoints.IsTempBreakPoint(PC))
PowerPC::breakpoints.Remove(PC);
}
diff --git a/Source/Core/DolphinQt/Debugger/BreakpointWidget.cpp b/Source/Core/DolphinQt/Debugger/BreakpointWidget.cpp
index 2f12877f15..ea686a2dcf 100644
--- a/Source/Core/DolphinQt/Debugger/BreakpointWidget.cpp
+++ b/Source/Core/DolphinQt/Debugger/BreakpointWidget.cpp
@@ -188,7 +188,15 @@ void BreakpointWidget::Update()
m_table->setItem(i, 3,
create_item(QStringLiteral("%1").arg(bp.address, 8, 16, QLatin1Char('0'))));
- m_table->setItem(i, 4, create_item());
+ QString flags;
+
+ if (bp.break_on_hit)
+ flags.append(QLatin1Char{'b'});
+
+ if (bp.log_on_hit)
+ flags.append(QLatin1Char{'l'});
+
+ m_table->setItem(i, 4, create_item(flags));
i++;
}
@@ -308,7 +316,12 @@ void BreakpointWidget::OnSave()
void BreakpointWidget::AddBP(u32 addr)
{
- PowerPC::breakpoints.Add(addr);
+ AddBP(addr, false, true, true);
+}
+
+void BreakpointWidget::AddBP(u32 addr, bool temp, bool break_on_hit, bool log_on_hit)
+{
+ PowerPC::breakpoints.Add(addr, temp, break_on_hit, log_on_hit);
Update();
}
diff --git a/Source/Core/DolphinQt/Debugger/BreakpointWidget.h b/Source/Core/DolphinQt/Debugger/BreakpointWidget.h
index 87ca60679e..570bb02b51 100644
--- a/Source/Core/DolphinQt/Debugger/BreakpointWidget.h
+++ b/Source/Core/DolphinQt/Debugger/BreakpointWidget.h
@@ -22,6 +22,7 @@ public:
~BreakpointWidget();
void AddBP(u32 addr);
+ void AddBP(u32 addr, bool temp, bool break_on_hit, bool log_on_hit);
void AddAddressMBP(u32 addr, bool on_read = true, bool on_write = true, bool do_log = true,
bool do_break = true);
void AddRangedMBP(u32 from, u32 to, bool do_read = true, bool do_write = true, bool do_log = true,
diff --git a/Source/Core/DolphinQt/Debugger/NewBreakpointDialog.cpp b/Source/Core/DolphinQt/Debugger/NewBreakpointDialog.cpp
index 6271be807a..4ad30016cd 100644
--- a/Source/Core/DolphinQt/Debugger/NewBreakpointDialog.cpp
+++ b/Source/Core/DolphinQt/Debugger/NewBreakpointDialog.cpp
@@ -62,12 +62,12 @@ void NewBreakpointDialog::CreateWidgets()
m_memory_on_read_and_write = new QRadioButton(tr("Read or Write"));
m_memory_on_write->setChecked(true);
// i18n: This is a selectable action when adding a breakpoint
- m_memory_do_log = new QRadioButton(tr("Write to Log"));
+ m_do_log = new QRadioButton(tr("Write to Log"));
// i18n: This is a selectable action when adding a breakpoint
- m_memory_do_break = new QRadioButton(tr("Break"));
+ m_do_break = new QRadioButton(tr("Break"));
// i18n: This is a selectable action when adding a breakpoint
- m_memory_do_log_and_break = new QRadioButton(tr("Write to Log and Break"));
- m_memory_do_log_and_break->setChecked(true);
+ m_do_log_and_break = new QRadioButton(tr("Write to Log and Break"));
+ m_do_log_and_break->setChecked(true);
auto* memory_layout = new QGridLayout;
m_memory_box->setLayout(memory_layout);
@@ -89,10 +89,9 @@ void NewBreakpointDialog::CreateWidgets()
QGroupBox* action_box = new QGroupBox(tr("Action"));
auto* action_layout = new QHBoxLayout;
action_box->setLayout(action_layout);
- memory_layout->addWidget(action_box, 3, 0, 1, -1);
- action_layout->addWidget(m_memory_do_log);
- action_layout->addWidget(m_memory_do_break);
- action_layout->addWidget(m_memory_do_log_and_break);
+ action_layout->addWidget(m_do_log);
+ action_layout->addWidget(m_do_break);
+ action_layout->addWidget(m_do_log_and_break);
auto* layout = new QVBoxLayout;
@@ -100,6 +99,7 @@ void NewBreakpointDialog::CreateWidgets()
layout->addWidget(m_instruction_box);
layout->addWidget(m_memory_bp);
layout->addWidget(m_memory_box);
+ layout->addWidget(action_box);
layout->addWidget(m_buttons);
setLayout(layout);
@@ -150,8 +150,8 @@ void NewBreakpointDialog::accept()
bool on_write = m_memory_on_write->isChecked() || m_memory_on_read_and_write->isChecked();
// Actions
- bool do_log = m_memory_do_log->isChecked() || m_memory_do_log_and_break->isChecked();
- bool do_break = m_memory_do_break->isChecked() || m_memory_do_log_and_break->isChecked();
+ bool do_log = m_do_log->isChecked() || m_do_log_and_break->isChecked();
+ bool do_break = m_do_break->isChecked() || m_do_log_and_break->isChecked();
bool good;
@@ -165,7 +165,7 @@ void NewBreakpointDialog::accept()
return;
}
- m_parent->AddBP(address);
+ m_parent->AddBP(address, false, do_break, do_log);
}
else
{
diff --git a/Source/Core/DolphinQt/Debugger/NewBreakpointDialog.h b/Source/Core/DolphinQt/Debugger/NewBreakpointDialog.h
index 681dfa9656..d9d2958c2b 100644
--- a/Source/Core/DolphinQt/Debugger/NewBreakpointDialog.h
+++ b/Source/Core/DolphinQt/Debugger/NewBreakpointDialog.h
@@ -48,9 +48,11 @@ private:
QRadioButton* m_memory_on_read;
QRadioButton* m_memory_on_read_and_write;
QRadioButton* m_memory_on_write;
- QRadioButton* m_memory_do_log;
- QRadioButton* m_memory_do_break;
- QRadioButton* m_memory_do_log_and_break;
+
+ // Action
+ QRadioButton* m_do_log;
+ QRadioButton* m_do_break;
+ QRadioButton* m_do_log_and_break;
QDialogButtonBox* m_buttons;
BreakpointWidget* m_parent;