Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
hrydgard
GitHub Repository: hrydgard/ppsspp
Path: blob/master/UI/ImDebugger/ImStructViewer.h
3185 views
1
#pragma once
2
3
#include "ext/imgui/imgui.h"
4
5
#include "Common/GhidraClient.h"
6
#include "Core/MIPS/MIPSDebugInterface.h"
7
8
struct ImConfig;
9
struct ImControl;
10
11
// Struct viewer visualizes objects data in game memory using types and symbols fetched from a Ghidra project.
12
// It also allows to set memory breakpoints and edit field values which is helpful when reverse engineering unknown
13
// types.
14
//
15
// To use this you will need to install an unofficial Ghidra extension "ghidra-rest-api" by Kotcrab.
16
// (available at https://github.com/kotcrab/ghidra-rest-api). After installing the extension and starting the API
17
// server in Ghidra you can open the Struct viewer window and press the "Connect" button to start using it.
18
//
19
// See the original pull request https://github.com/hrydgard/ppsspp/pull/19629 for a screenshot and how to test this
20
// without the need to set up Ghidra.
21
class ImStructViewer {
22
struct Watch {
23
int id = 0;
24
std::string expression;
25
u32 address = 0;
26
std::string typePathName;
27
std::string name;
28
};
29
30
struct WatchForm {
31
char name[256] = {};
32
std::string typeDisplayName;
33
std::string typePathName;
34
char expression[256] = {};
35
bool dynamic = false;
36
std::string error;
37
ImGuiTextFilter typeFilter;
38
39
void Clear();
40
41
void SetFrom(const std::unordered_map<std::string, GhidraType> &types, const Watch &watch);
42
};
43
44
public:
45
void Draw(ImConfig &cfg, ImControl &control, MIPSDebugInterface *mipsDebug);
46
47
private:
48
ImControl *control_ = nullptr;
49
MIPSDebugInterface *mipsDebug_ = nullptr;
50
51
ImGuiTextFilter globalFilter_;
52
ImGuiTextFilter watchFilter_;
53
54
GhidraClient ghidraClient_;
55
char ghidraHost_[128] = "localhost";
56
int ghidraPort_ = 18489;
57
bool fetchedAtLeastOnce_ = false; // True if fetched from Ghidra successfully at least once
58
59
std::vector<Watch> watches_;
60
int nextWatchId_ = 0; // ID value to use when creating new watch entry
61
int removeWatchId_ = -1; // Watch entry id to be removed on next draw
62
int editWatchId_ = -1; // Watch entry id currently being edited
63
Watch addWatch_; // Temporary variable to store watch entry added from the Globals tab
64
WatchForm watchForm_; // State for the new and edit watch form UI
65
66
void DrawConnectionSetup();
67
68
void DrawStructViewer();
69
70
void DrawGlobals();
71
72
void DrawWatch();
73
74
void DrawWatchForm();
75
76
void ClearWatchForm();
77
78
void DrawType(
79
u32 base,
80
u32 offset,
81
const std::string &typePathName,
82
const char *typeDisplayNameOverride,
83
const char *name,
84
int watchId,
85
ImGuiTreeNodeFlags extraTreeNodeFlags = 0);
86
87
void DrawIndexedMembers(
88
u32 base,
89
u32 offset,
90
const std::string &typePathName,
91
const char *name,
92
u32 elementCount,
93
int elementLength,
94
bool openFirst);
95
96
void DrawContextMenu(
97
u32 base,
98
u32 offset,
99
int length,
100
const std::string &typePathName,
101
const char *name,
102
int watchId,
103
const u64 *value);
104
};
105
106