87 lines
2.6 KiB
C++
87 lines
2.6 KiB
C++
#include "stdafx.h"
|
|
#include "BreakpointManager.h"
|
|
#include "DebugTypes.h"
|
|
#include "Debugger.h"
|
|
#include "Breakpoint.h"
|
|
#include "ExpressionEvaluator.h"
|
|
|
|
BreakpointManager::BreakpointManager(Debugger *debugger)
|
|
{
|
|
_debugger = debugger;
|
|
}
|
|
|
|
void BreakpointManager::SetBreakpoints(Breakpoint breakpoints[], uint32_t count)
|
|
{
|
|
for(int j = 0; j < BreakpointManager::CategoryCount; j++) {
|
|
for(int i = 0; i < BreakpointManager::BreakpointTypeCount; i++) {
|
|
_breakpoints[j][i].clear();
|
|
_rpnList[j][i].clear();
|
|
_hasBreakpoint[j][i] = false;
|
|
}
|
|
}
|
|
|
|
_bpExpEval.reset(new ExpressionEvaluator(_debugger));
|
|
for(uint32_t j = 0; j < count; j++) {
|
|
Breakpoint &bp = breakpoints[j];
|
|
for(int i = 0; i < BreakpointManager::BreakpointTypeCount; i++) {
|
|
BreakpointType bpType = (BreakpointType)i;
|
|
bool isEnabled = bp.IsEnabled(); //TODO && _console->GetSettings()->CheckFlag(EmulationFlags::DebuggerWindowEnabled);
|
|
if((bp.IsMarked() || isEnabled) && bp.HasBreakpointType(bpType)) {
|
|
BreakpointCategory category = bp.GetBreakpointCategory();
|
|
_breakpoints[(int)category][i].push_back(bp);
|
|
|
|
if(bp.HasCondition()) {
|
|
bool success = true;
|
|
ExpressionData data = _bpExpEval->GetRpnList(bp.GetCondition(), success);
|
|
_rpnList[(int)category][i].push_back(success ? data : ExpressionData());
|
|
} else {
|
|
_rpnList[(int)category][i].push_back(ExpressionData());
|
|
}
|
|
|
|
_hasBreakpoint[(int)category][i] = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
BreakpointType BreakpointManager::GetBreakpointType(MemoryOperationType type)
|
|
{
|
|
switch(type) {
|
|
default:
|
|
case MemoryOperationType::ExecOperand:
|
|
case MemoryOperationType::ExecOpCode:
|
|
return BreakpointType::Execute;
|
|
|
|
case MemoryOperationType::DmaRead:
|
|
case MemoryOperationType::Read:
|
|
return BreakpointType::Read;
|
|
|
|
case MemoryOperationType::DmaWrite:
|
|
case MemoryOperationType::Write:
|
|
return BreakpointType::Write;
|
|
}
|
|
}
|
|
|
|
bool BreakpointManager::CheckBreakpoint(MemoryOperationInfo operationInfo, AddressInfo &address)
|
|
{
|
|
BreakpointCategory category = Breakpoint::GetBreakpointCategory(address.Type);
|
|
BreakpointType type = GetBreakpointType(operationInfo.Type);
|
|
|
|
if(!_hasBreakpoint[(int)category][(int)type]) {
|
|
return false;
|
|
}
|
|
|
|
DebugState state;
|
|
_debugger->GetState(state);
|
|
EvalResultType resultType;
|
|
vector<Breakpoint> &breakpoints = _breakpoints[(int)category][(int)type];
|
|
for(size_t i = 0; i < breakpoints.size(); i++) {
|
|
if(breakpoints[i].Matches(operationInfo.Address, address)) {
|
|
if(!breakpoints[i].HasCondition() || _bpExpEval->Evaluate(_rpnList[(int)category][(int)type][i], state, resultType, operationInfo)) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|