Allow to disable/enable breakpoints
Added `ToggleBreakPoint` to both interface BreakPoints/MemChecks. this would allow us to toggle the state of the breakpoint. Also the TMemCheck::is_ranged is not longer serialized to string, since can be deduce by comparing the TMemCheck::start_address and TMemCheck::end_address
This commit is contained in:
parent
7712f0831f
commit
4935e9b560
|
@ -23,6 +23,12 @@ bool BreakPoints::IsAddressBreakPoint(u32 address) const
|
|||
[address](const auto& bp) { return bp.address == address; });
|
||||
}
|
||||
|
||||
bool BreakPoints::IsBreakPointEnable(u32 address) const
|
||||
{
|
||||
return std::any_of(m_breakpoints.begin(), m_breakpoints.end(),
|
||||
[address](const auto& bp) { return bp.is_enabled && bp.address == address; });
|
||||
}
|
||||
|
||||
bool BreakPoints::IsTempBreakPoint(u32 address) const
|
||||
{
|
||||
return std::any_of(m_breakpoints.begin(), m_breakpoints.end(), [address](const auto& bp) {
|
||||
|
@ -51,6 +57,8 @@ BreakPoints::TBreakPointsStr BreakPoints::GetStrings() const
|
|||
if (!bp.is_temporary)
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss.imbue(std::locale::classic());
|
||||
|
||||
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());
|
||||
|
@ -67,6 +75,8 @@ void BreakPoints::AddFromStrings(const TBreakPointsStr& bp_strings)
|
|||
TBreakPoint bp;
|
||||
std::string flags;
|
||||
std::istringstream iss(bp_string);
|
||||
iss.imbue(std::locale::classic());
|
||||
|
||||
iss >> std::hex >> bp.address;
|
||||
iss >> flags;
|
||||
bp.is_enabled = flags.find('n') != flags.npos;
|
||||
|
@ -110,6 +120,18 @@ void BreakPoints::Add(u32 address, bool temp, bool break_on_hit, bool log_on_hit
|
|||
JitInterface::InvalidateICache(address, 4, true);
|
||||
}
|
||||
|
||||
bool BreakPoints::ToggleBreakPoint(u32 address)
|
||||
{
|
||||
auto iter = std::find_if(m_breakpoints.begin(), m_breakpoints.end(),
|
||||
[address](const auto& bp) { return bp.address == address; });
|
||||
|
||||
if (iter == m_breakpoints.end())
|
||||
return false;
|
||||
|
||||
iter->is_enabled = !iter->is_enabled;
|
||||
return true;
|
||||
}
|
||||
|
||||
void BreakPoints::Remove(u32 address)
|
||||
{
|
||||
const auto iter = std::find_if(m_breakpoints.begin(), m_breakpoints.end(),
|
||||
|
@ -155,11 +177,11 @@ MemChecks::TMemChecksStr MemChecks::GetStrings() const
|
|||
for (const TMemCheck& mc : m_mem_checks)
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << std::hex << mc.start_address;
|
||||
ss << " " << (mc.is_ranged ? mc.end_address : mc.start_address) << " "
|
||||
<< (mc.is_ranged ? "n" : "") << (mc.is_break_on_read ? "r" : "")
|
||||
<< (mc.is_break_on_write ? "w" : "") << (mc.log_on_hit ? "l" : "")
|
||||
<< (mc.break_on_hit ? "b" : "");
|
||||
ss.imbue(std::locale::classic());
|
||||
|
||||
ss << std::hex << mc.start_address << " " << mc.end_address << " " << (mc.is_enabled ? "n" : "")
|
||||
<< (mc.is_break_on_read ? "r" : "") << (mc.is_break_on_write ? "w" : "")
|
||||
<< (mc.log_on_hit ? "l" : "") << (mc.break_on_hit ? "b" : "");
|
||||
mc_strings.push_back(ss.str());
|
||||
}
|
||||
|
||||
|
@ -171,18 +193,19 @@ void MemChecks::AddFromStrings(const TMemChecksStr& mc_strings)
|
|||
for (const std::string& mc_string : mc_strings)
|
||||
{
|
||||
TMemCheck mc;
|
||||
std::stringstream ss;
|
||||
ss << std::hex << mc_string;
|
||||
ss >> mc.start_address;
|
||||
mc.is_ranged = mc_string.find('n') != mc_string.npos;
|
||||
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('b') != mc_string.npos;
|
||||
if (mc.is_ranged)
|
||||
ss >> mc.end_address;
|
||||
else
|
||||
mc.end_address = mc.start_address;
|
||||
std::istringstream iss(mc_string);
|
||||
iss.imbue(std::locale::classic());
|
||||
|
||||
std::string flags;
|
||||
iss >> std::hex >> mc.start_address >> mc.end_address >> flags;
|
||||
|
||||
mc.is_ranged = mc.start_address != mc.end_address;
|
||||
mc.is_enabled = flags.find('n') != flags.npos;
|
||||
mc.is_break_on_read = flags.find('r') != flags.npos;
|
||||
mc.is_break_on_write = flags.find('w') != flags.npos;
|
||||
mc.log_on_hit = flags.find('l') != flags.npos;
|
||||
mc.break_on_hit = flags.find('b') != flags.npos;
|
||||
|
||||
Add(mc);
|
||||
}
|
||||
}
|
||||
|
@ -203,6 +226,18 @@ void MemChecks::Add(const TMemCheck& memory_check)
|
|||
});
|
||||
}
|
||||
|
||||
bool MemChecks::ToggleBreakPoint(u32 address)
|
||||
{
|
||||
auto iter = std::find_if(m_mem_checks.begin(), m_mem_checks.end(),
|
||||
[address](const auto& bp) { return bp.start_address == address; });
|
||||
|
||||
if (iter == m_mem_checks.end())
|
||||
return false;
|
||||
|
||||
iter->is_enabled = !iter->is_enabled;
|
||||
return true;
|
||||
}
|
||||
|
||||
void MemChecks::Remove(u32 address)
|
||||
{
|
||||
const auto iter =
|
||||
|
@ -262,6 +297,9 @@ bool MemChecks::OverlapsMemcheck(u32 address, u32 length) const
|
|||
bool TMemCheck::Action(Common::DebugInterface* debug_interface, u32 value, u32 addr, bool write,
|
||||
size_t size, u32 pc)
|
||||
{
|
||||
if (!is_enabled)
|
||||
return false;
|
||||
|
||||
if ((write && is_break_on_write) || (!write && is_break_on_read))
|
||||
{
|
||||
if (log_on_hit)
|
||||
|
|
|
@ -29,6 +29,7 @@ struct TMemCheck
|
|||
u32 start_address = 0;
|
||||
u32 end_address = 0;
|
||||
|
||||
bool is_enabled = true;
|
||||
bool is_ranged = false;
|
||||
|
||||
bool is_break_on_read = false;
|
||||
|
@ -57,6 +58,7 @@ public:
|
|||
|
||||
// is address breakpoint
|
||||
bool IsAddressBreakPoint(u32 address) const;
|
||||
bool IsBreakPointEnable(u32 adresss) const;
|
||||
bool IsTempBreakPoint(u32 address) const;
|
||||
bool IsBreakPointBreakOnHit(u32 address) const;
|
||||
bool IsBreakPointLogOnHit(u32 address) const;
|
||||
|
@ -66,6 +68,9 @@ public:
|
|||
void Add(u32 address, bool temp = false);
|
||||
void Add(const TBreakPoint& bp);
|
||||
|
||||
// Modify Breakpoint
|
||||
bool ToggleBreakPoint(u32 address);
|
||||
|
||||
// Remove Breakpoint
|
||||
void Remove(u32 address);
|
||||
void Clear();
|
||||
|
@ -88,6 +93,8 @@ public:
|
|||
|
||||
void Add(const TMemCheck& memory_check);
|
||||
|
||||
bool ToggleBreakPoint(u32 address);
|
||||
|
||||
// memory breakpoint
|
||||
TMemCheck* GetMemCheck(u32 address, size_t size = 1);
|
||||
bool OverlapsMemcheck(u32 address, u32 length) const;
|
||||
|
|
|
@ -602,8 +602,9 @@ void CheckExternalExceptions()
|
|||
|
||||
void CheckBreakPoints()
|
||||
{
|
||||
if (PowerPC::breakpoints.IsAddressBreakPoint(PC))
|
||||
{
|
||||
if (!PowerPC::breakpoints.IsBreakPointEnable(PC))
|
||||
return;
|
||||
|
||||
if (PowerPC::breakpoints.IsBreakPointBreakOnHit(PC))
|
||||
CPU::Break();
|
||||
if (PowerPC::breakpoints.IsBreakPointLogOnHit(PC))
|
||||
|
@ -616,7 +617,6 @@ void CheckBreakPoints()
|
|||
}
|
||||
if (PowerPC::breakpoints.IsTempBreakPoint(PC))
|
||||
PowerPC::breakpoints.Remove(PC);
|
||||
}
|
||||
}
|
||||
|
||||
void PowerPCState::SetSR(u32 index, u32 value)
|
||||
|
|
Loading…
Reference in New Issue