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 #include <set>
22 #include <map>
23 #include <string>
24 #include <mutex>
25 
26 #include "Common/CommonTypes.h"
27 #include "Common/File/Path.h"
28 
29 enum SymbolType {
30 	ST_NONE     = 0,
31 	ST_FUNCTION = 1,
32 	ST_DATA     = 2,
33 	ST_ALL      = 3,
34 };
35 
36 struct SymbolInfo {
37 	SymbolType type;
38 	u32 address;
39 	u32 size;
40 	u32 moduleAddress;
41 };
42 
43 struct SymbolEntry {
44 	std::string name;
45 	u32 address;
46 	u32 size;
47 };
48 
49 struct LoadedModuleInfo {
50 	std::string name;
51 	u32 address;
52 	u32 size;
53 	bool active;
54 };
55 
56 enum DataType {
57 	DATATYPE_NONE, DATATYPE_BYTE, DATATYPE_HALFWORD, DATATYPE_WORD, DATATYPE_ASCII
58 };
59 
60 struct LabelDefinition;
61 
62 #ifdef _WIN32
63 struct HWND__;
64 typedef struct HWND__ *HWND;
65 #endif
66 
67 class SymbolMap {
68 public:
SymbolMap()69 	SymbolMap() {}
70 	void Clear();
71 	void SortSymbols();
72 
73 	bool LoadSymbolMap(const Path &filename);
74 	void SaveSymbolMap(const Path &filename) const;
75 	bool LoadNocashSym(const Path &filename);
76 	void SaveNocashSym(const Path &filename) const;
77 
78 	SymbolType GetSymbolType(u32 address);
79 	bool GetSymbolInfo(SymbolInfo *info, u32 address, SymbolType symmask = ST_FUNCTION);
80 	u32 GetNextSymbolAddress(u32 address, SymbolType symmask);
81 	std::string GetDescription(unsigned int address);
82 	std::vector<SymbolEntry> GetAllSymbols(SymbolType symmask);
83 
84 #ifdef _WIN32
85 	void FillSymbolListBox(HWND listbox, SymbolType symType);
86 #endif
87 	void GetLabels(std::vector<LabelDefinition> &dest);
88 
89 	void AddModule(const char *name, u32 address, u32 size);
90 	void UnloadModule(u32 address, u32 size);
91 	u32 GetModuleRelativeAddr(u32 address, int moduleIndex = -1) const;
92 	u32 GetModuleAbsoluteAddr(u32 relative, int moduleIndex) const;
93 	int GetModuleIndex(u32 address) const;
94 	bool IsModuleActive(int moduleIndex);
95 	std::vector<LoadedModuleInfo> getAllModules() const;
96 
97 	void AddFunction(const char* name, u32 address, u32 size, int moduleIndex = -1);
98 	u32 GetFunctionStart(u32 address);
99 	int GetFunctionNum(u32 address);
100 	u32 GetFunctionSize(u32 startAddress);
101 	u32 GetFunctionModuleAddress(u32 startAddress);
102 	bool SetFunctionSize(u32 startAddress, u32 newSize);
103 	bool RemoveFunction(u32 startAddress, bool removeName);
104 	// Search for the first address their may be a function after address.
105 	// Only valid for currently loaded modules.  Not guaranteed there will be a function.
106 	u32 FindPossibleFunctionAtAfter(u32 address);
107 
108 	void AddLabel(const char* name, u32 address, int moduleIndex = -1);
109 	std::string GetLabelString(u32 address);
110 	void SetLabelName(const char* name, u32 address);
111 	bool GetLabelValue(const char* name, u32& dest);
112 
113 	void AddData(u32 address, u32 size, DataType type, int moduleIndex = -1);
114 	u32 GetDataStart(u32 address);
115 	u32 GetDataSize(u32 startAddress);
116 	u32 GetDataModuleAddress(u32 startAddress);
117 	DataType GetDataType(u32 startAddress);
118 
119 	static const u32 INVALID_ADDRESS = (u32)-1;
120 
121 	void UpdateActiveSymbols();
122 
123 private:
124 	void AssignFunctionIndices();
125 	const char *GetLabelName(u32 address);
126 	const char *GetLabelNameRel(u32 relAddress, int moduleIndex) const;
127 
128 	struct FunctionEntry {
129 		u32 start;
130 		u32 size;
131 		int index;
132 		int module;
133 	};
134 
135 	struct LabelEntry {
136 		u32 addr;
137 		int module;
138 		char name[128];
139 	};
140 
141 	struct DataEntry {
142 		DataType type;
143 		u32 start;
144 		u32 size;
145 		int module;
146 	};
147 
148 	struct ModuleEntry {
149 		// Note: this index is +1, 0 matches any for backwards-compat.
150 		int index;
151 		u32 start;
152 		u32 size;
153 		char name[128];
154 	};
155 
156 	// These are flattened, read-only copies of the actual data in active modules only.
157 	std::map<u32, const FunctionEntry> activeFunctions;
158 	std::map<u32, const LabelEntry> activeLabels;
159 	std::map<u32, const DataEntry> activeData;
160 	bool activeNeedUpdate_ = false;
161 
162 	// This is indexed by the end address of the module.
163 	std::map<u32, const ModuleEntry> activeModuleEnds;
164 
165 	typedef std::pair<int, u32> SymbolKey;
166 
167 	// These are indexed by the module id and relative address in the module.
168 	std::map<SymbolKey, FunctionEntry> functions;
169 	std::map<SymbolKey, LabelEntry> labels;
170 	std::map<SymbolKey, DataEntry> data;
171 	std::vector<ModuleEntry> modules;
172 
173 	mutable std::recursive_mutex lock_;
174 	bool sawUnknownModule = false;
175 };
176 
177 extern SymbolMap *g_symbolMap;
178 
179