Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
hrydgard
GitHub Repository: hrydgard/ppsspp
Path: blob/master/UI/ImDebugger/ImDisasmView.h
3185 views
1
#pragma once
2
3
#include <vector>
4
#include <string>
5
#include <set>
6
#include <algorithm>
7
8
#include "ext/imgui/imgui.h"
9
10
#include "Common/CommonTypes.h"
11
#include "Common/Math/geom2d.h"
12
13
#include "Core/Debugger/DisassemblyManager.h"
14
#include "Core/MIPS/MIPSDebugInterface.h"
15
16
struct ImConfig;
17
struct ImControl;
18
19
// Corresponds to CtrlDisAsmView
20
// TODO: Fold out common code.
21
class ImDisasmView {
22
public:
23
ImDisasmView();
24
~ImDisasmView();
25
26
// Public variables bounds to imgui checkboxes
27
bool followPC_ = true;
28
29
void Draw(ImDrawList *drawList, ImControl &control);
30
31
void PopupMenu(ImControl &control);
32
void NotifyStep();
33
34
void ScrollRelative(int amount);
35
36
void onChar(int c);
37
void onMouseDown(float x, float y, int button);
38
void onMouseUp(float x, float y, int button);
39
void onMouseMove(float x, float y, int button);
40
void scrollAddressIntoView();
41
bool curAddressIsVisible();
42
void ScanVisibleFunctions();
43
void clearFunctions() { g_disassemblyManager.clear(); };
44
45
void getOpcodeText(u32 address, char *dest, int bufsize);
46
u32 yToAddress(float y);
47
48
void setDebugger(MIPSDebugInterface *deb) {
49
if (debugger_ != deb) {
50
debugger_ = deb;
51
curAddress_ = debugger_->GetPC();
52
g_disassemblyManager.setCpu(deb);
53
}
54
}
55
56
MIPSDebugInterface *getDebugger() {
57
return debugger_;
58
}
59
60
void scrollStepping(u32 newPc);
61
u32 getInstructionSizeAt(u32 address); // not const because it might have to analyze.
62
63
void gotoAddr(unsigned int addr) {
64
if (positionLocked_ != 0)
65
return;
66
u32 windowEnd = g_disassemblyManager.getNthNextAddress(windowStart_, visibleRows_);
67
u32 newAddress = g_disassemblyManager.getStartAddress(addr);
68
69
if (newAddress < windowStart_ || newAddress >= windowEnd) {
70
windowStart_ = g_disassemblyManager.getNthPreviousAddress(newAddress, visibleRows_ / 2);
71
}
72
73
setCurAddress(newAddress);
74
ScanVisibleFunctions();
75
}
76
void GotoPC() {
77
gotoAddr(debugger_->GetPC());
78
}
79
void GotoRA() {
80
gotoAddr(debugger_->GetRA());
81
}
82
u32 getSelection() {
83
return curAddress_;
84
}
85
void setShowMode(bool s) {
86
showHex_ = s;
87
}
88
void toggleBreakpoint(bool toggleEnabled = false);
89
void editBreakpoint(ImConfig &cfg);
90
91
void setCurAddress(u32 newAddress, bool extend = false) {
92
newAddress = g_disassemblyManager.getStartAddress(newAddress);
93
const u32 after = g_disassemblyManager.getNthNextAddress(newAddress, 1);
94
curAddress_ = newAddress;
95
selectRangeStart_ = extend ? std::min(selectRangeStart_, newAddress) : newAddress;
96
selectRangeEnd_ = extend ? std::max(selectRangeEnd_, after) : after;
97
updateStatusBarText();
98
}
99
100
void LockPosition() {
101
positionLocked_++;
102
}
103
void UnlockPosition() {
104
positionLocked_--;
105
_assert_(positionLocked_ >= 0);
106
}
107
void Search(std::string_view needle);
108
void SearchNext(bool forward);
109
110
// Check these every frame!
111
const std::string &StatusBarText() const {
112
return statusBarText_;
113
}
114
bool SymbolMapReloaded() {
115
bool retval = mapReloaded_;
116
mapReloaded_ = false;
117
return retval;
118
}
119
120
private:
121
enum class CopyInstructionsMode {
122
OPCODES,
123
DISASM,
124
ADDRESSES,
125
};
126
127
void ProcessKeyboardShortcuts(bool focused);
128
void assembleOpcode(u32 address, const std::string &defaultText);
129
std::string disassembleRange(u32 start, u32 size);
130
void disassembleToFile();
131
void FollowBranch();
132
void calculatePixelPositions();
133
bool getDisasmAddressText(u32 address, char *dest, size_t bufSize, bool abbreviateLabels, bool showData);
134
void updateStatusBarText();
135
void drawBranchLine(ImDrawList *list, Bounds rc, std::map<u32, float> &addressPositions, const BranchLine &line);
136
void CopyInstructions(u32 startAddr, u32 endAddr, CopyInstructionsMode mode);
137
std::set<std::string> getSelectedLineArguments();
138
void drawArguments(ImDrawList *list, Bounds rc, const DisassemblyLineInfo &line, float x, float y, ImColor textColor, const std::set<std::string> &currentArguments);
139
140
u32 curAddress_ = 0;
141
u32 selectRangeStart_ = 0;
142
u32 selectRangeEnd_ = 0;
143
float rowHeight_ = 0.f;
144
float charWidth_ = 0.f;
145
146
bool bpPopup_ = false;
147
bool hasFocus_ = true;
148
bool showHex_ = false;
149
150
MIPSDebugInterface *debugger_ = nullptr;
151
152
u32 windowStart_ = 0;
153
int visibleRows_ = 1;
154
bool displaySymbols_ = true;
155
156
struct {
157
int addressStart;
158
int opcodeStart;
159
int argumentsStart;
160
int arrowsStart;
161
} pixelPositions_{};
162
163
std::vector<u32> jumpStack_;
164
165
std::string searchQuery_;
166
int matchAddress_;
167
bool searching_ = false;
168
bool keyTaken = false;
169
bool mapReloaded_ = false;
170
171
int positionLocked_ = 0;
172
173
std::string statusBarText_;
174
u32 funcBegin_ = 0;
175
char funcNameTemp_[128]{};
176
};
177
178
// Corresponds to the CDisasm dialog
179
class ImDisasmWindow {
180
public:
181
void Draw(MIPSDebugInterface *mipsDebug, ImConfig &cfg, ImControl &control, CoreState coreState);
182
ImDisasmView &View() {
183
return disasmView_;
184
}
185
void NotifyStep() {
186
disasmView_.NotifyStep();
187
}
188
void DirtySymbolMap() {
189
symsDirty_ = true;
190
}
191
const char *Title() const {
192
return "CPU Debugger";
193
}
194
195
private:
196
// We just keep the state directly in the window. Can refactor later.
197
198
enum {
199
INVALID_ADDR = 0xFFFFFFFF,
200
};
201
202
u32 gotoAddr_ = 0x08800000;
203
204
// Symbol cache
205
std::vector<SymbolEntry> symCache_;
206
bool symsDirty_ = true;
207
int selectedSymbol_ = -1;
208
char selectedSymbolName_[128];
209
210
ImDisasmView disasmView_;
211
char searchTerm_[64]{};
212
};
213
214