CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
hrydgard

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: hrydgard/ppsspp
Path: blob/master/Core/Debugger/Breakpoints.h
Views: 1401
1
// Copyright (c) 2012- PPSSPP Project.
2
3
// This program is free software: you can redistribute it and/or modify
4
// it under the terms of the GNU General Public License as published by
5
// the Free Software Foundation, version 2.0 or later versions.
6
7
// This program is distributed in the hope that it will be useful,
8
// but WITHOUT ANY WARRANTY; without even the implied warranty of
9
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
// GNU General Public License 2.0 for more details.
11
12
// A copy of the GPL 2.0 should have been included with the program.
13
// If not, see http://www.gnu.org/licenses/
14
15
// Official git repository and contact information can be found at
16
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
17
18
#pragma once
19
20
#include <vector>
21
22
#include "Core/Debugger/DebugInterface.h"
23
24
enum BreakAction {
25
BREAK_ACTION_IGNORE = 0x00,
26
BREAK_ACTION_LOG = 0x01,
27
BREAK_ACTION_PAUSE = 0x02,
28
};
29
30
static inline BreakAction &operator |= (BreakAction &lhs, const BreakAction &rhs) {
31
lhs = BreakAction(lhs | rhs);
32
return lhs;
33
}
34
35
static inline BreakAction operator | (const BreakAction &lhs, const BreakAction &rhs) {
36
return BreakAction((u32)lhs | (u32)rhs);
37
}
38
39
struct BreakPointCond {
40
DebugInterface *debug = nullptr;
41
PostfixExpression expression;
42
std::string expressionString;
43
44
u32 Evaluate() {
45
u32 result;
46
if (debug->parseExpression(expression, result) == false)
47
return 0;
48
return result;
49
}
50
};
51
52
struct BreakPoint {
53
u32 addr;
54
bool temporary;
55
56
BreakAction result = BREAK_ACTION_IGNORE;
57
std::string logFormat;
58
59
bool hasCond = false;
60
BreakPointCond cond;
61
62
bool IsEnabled() const {
63
return (result & BREAK_ACTION_PAUSE) != 0;
64
}
65
66
bool operator == (const BreakPoint &other) const {
67
return addr == other.addr;
68
}
69
bool operator < (const BreakPoint &other) const {
70
return addr < other.addr;
71
}
72
};
73
74
enum MemCheckCondition {
75
MEMCHECK_READ = 0x01,
76
MEMCHECK_WRITE = 0x02,
77
MEMCHECK_WRITE_ONCHANGE = 0x04,
78
79
MEMCHECK_READWRITE = 0x03,
80
};
81
82
struct MemCheck {
83
u32 start;
84
u32 end;
85
86
MemCheckCondition cond = MEMCHECK_READ;
87
BreakAction result = BREAK_ACTION_IGNORE;
88
std::string logFormat;
89
90
bool hasCondition = false;
91
BreakPointCond condition;
92
93
u32 numHits = 0;
94
95
u32 lastPC = 0;
96
u32 lastAddr = 0;
97
int lastSize = 0;
98
99
// Called on the stored memcheck (affects numHits, etc.)
100
BreakAction Apply(u32 addr, bool write, int size, u32 pc);
101
// Called on a copy.
102
BreakAction Action(u32 addr, bool write, int size, u32 pc, const char *reason);
103
104
void Log(u32 addr, bool write, int size, u32 pc, const char *reason);
105
106
bool IsEnabled() const {
107
return (result & BREAK_ACTION_PAUSE) != 0;
108
}
109
110
bool operator == (const MemCheck &other) const {
111
return start == other.start && end == other.end;
112
}
113
};
114
115
// BreakPoints cannot overlap, only one is allowed per address.
116
// MemChecks can overlap, as long as their ends are different.
117
// WARNING: MemChecks are not always tracked in HLE currently.
118
class CBreakPoints
119
{
120
public:
121
static const size_t INVALID_BREAKPOINT = -1;
122
static const size_t INVALID_MEMCHECK = -1;
123
124
static bool IsAddressBreakPoint(u32 addr);
125
static bool IsAddressBreakPoint(u32 addr, bool* enabled);
126
static bool IsTempBreakPoint(u32 addr);
127
static bool RangeContainsBreakPoint(u32 addr, u32 size);
128
static void AddBreakPoint(u32 addr, bool temp = false);
129
static void RemoveBreakPoint(u32 addr);
130
static void ChangeBreakPoint(u32 addr, bool enable);
131
static void ChangeBreakPoint(u32 addr, BreakAction result);
132
static void ClearAllBreakPoints();
133
static void ClearTemporaryBreakPoints();
134
135
// Makes a copy of the condition.
136
static void ChangeBreakPointAddCond(u32 addr, const BreakPointCond &cond);
137
static void ChangeBreakPointRemoveCond(u32 addr);
138
static BreakPointCond *GetBreakPointCondition(u32 addr);
139
140
static void ChangeBreakPointLogFormat(u32 addr, const std::string &fmt);
141
142
static BreakAction ExecBreakPoint(u32 addr);
143
144
static void AddMemCheck(u32 start, u32 end, MemCheckCondition cond, BreakAction result);
145
static void RemoveMemCheck(u32 start, u32 end);
146
static void ChangeMemCheck(u32 start, u32 end, MemCheckCondition cond, BreakAction result);
147
static void ClearAllMemChecks();
148
149
static void ChangeMemCheckAddCond(u32 start, u32 end, const BreakPointCond &cond);
150
static void ChangeMemCheckRemoveCond(u32 start, u32 end);
151
static BreakPointCond *GetMemCheckCondition(u32 start, u32 end);
152
153
static void ChangeMemCheckLogFormat(u32 start, u32 end, const std::string &fmt);
154
155
static bool GetMemCheck(u32 start, u32 end, MemCheck *check);
156
static bool GetMemCheckInRange(u32 address, int size, MemCheck *check);
157
static BreakAction ExecMemCheck(u32 address, bool write, int size, u32 pc, const char *reason);
158
static BreakAction ExecOpMemCheck(u32 address, u32 pc);
159
160
static void SetSkipFirst(u32 pc);
161
static u32 CheckSkipFirst();
162
163
// Includes uncached addresses.
164
static std::vector<MemCheck> GetMemCheckRanges(bool write);
165
166
static std::vector<MemCheck> GetMemChecks();
167
static std::vector<BreakPoint> GetBreakpoints();
168
169
static bool HasBreakPoints();
170
static bool HasMemChecks();
171
172
static void Update(u32 addr = 0);
173
174
static bool ValidateLogFormat(DebugInterface *cpu, const std::string &fmt);
175
static bool EvaluateLogFormat(DebugInterface *cpu, const std::string &fmt, std::string &result);
176
177
private:
178
static size_t FindBreakpoint(u32 addr, bool matchTemp = false, bool temp = false);
179
// Finds exactly, not using a range check.
180
static size_t FindMemCheck(u32 start, u32 end);
181
static MemCheck *GetMemCheckLocked(u32 address, int size);
182
static void UpdateCachedMemCheckRanges();
183
184
static std::vector<BreakPoint> breakPoints_;
185
static u32 breakSkipFirstAt_;
186
static u64 breakSkipFirstTicks_;
187
188
static std::vector<MemCheck> memChecks_;
189
static std::vector<MemCheck> memCheckRangesRead_;
190
static std::vector<MemCheck> memCheckRangesWrite_;
191
};
192
193
194
195