1/*
2 * Copyright 2016, Rene Gollent, rene@gollent.com.
3 * Distributed under the terms of the MIT License.
4 */
5#ifndef REMOTE_DEBUG_REQUEST_H
6#define REMOTE_DEBUG_REQUEST_H
7
8#include <OS.h>
9
10#include <Referenceable.h>
11
12#include "Types.h"
13
14
15enum remote_request_type {
16	// debug requests
17	REMOTE_REQUEST_TYPE_READ_MEMORY = 0,
18	REMOTE_REQUEST_TYPE_WRITE_MEMORY,
19	REMOTE_REQUEST_TYPE_SET_TEAM_FLAGS,
20	REMOTE_REQUEST_TYPE_SET_THREAD_FLAGS,
21	REMOTE_REQUEST_TYPE_CONTINUE_THREAD,
22	REMOTE_REQUEST_TYPE_STOP_THREAD,
23	REMOTE_REQUEST_TYPE_SINGLE_STEP_THREAD,
24	REMOTE_REQUEST_TYPE_GET_CPU_STATE,
25	REMOTE_REQUEST_TYPE_SET_CPU_STATE,
26	REMOTE_REQUEST_TYPE_INSTALL_BREAKPOINT,
27	REMOTE_REQUEST_TYPE_UNINSTALL_BREAKPOINT,
28	REMOTE_REQUEST_TYPE_INSTALL_WATCHPOINT,
29	REMOTE_REQUEST_TYPE_UNINSTALL_WATCHPOINT,
30	REMOTE_REQUEST_TYPE_PREPARE_HANDOVER,
31	REMOTE_REQUEST_TYPE_WRITE_CORE_FILE,
32
33	// team information requests
34	REMOTE_REQUEST_TYPE_GET_TEAM_INFO,
35	REMOTE_REQUEST_TYPE_GET_THREAD_INFOS,
36	REMOTE_REQUEST_TYPE_GET_IMAGE_INFOS,
37	REMOTE_REQUEST_TYPE_GET_AREA_INFOS,
38	REMOTE_REQUEST_TYPE_GET_SEM_INFOS,
39	REMOTE_REQUEST_TYPE_GET_SYMBOL_INFOS,
40	REMOTE_REQUEST_TYPE_GET_SYMBOL_INFO,
41	REMOTE_REQUEST_TYPE_GET_THREAD_INFO,
42	REMOTE_REQUEST_TYPE_GET_MEMORY_PROPERTIES
43};
44
45
46class Architecture;
47class BMessage;
48class CpuState;
49
50
51class RemoteDebugRequest : public BReferenceable {
52public:
53								RemoteDebugRequest();
54	virtual						~RemoteDebugRequest();
55
56	virtual	remote_request_type	Type() const = 0;
57
58			status_t			LoadFromMessage(const BMessage& data);
59			status_t			SaveToMessage(BMessage& _output) const;
60
61			Architecture*		GetArchitecture() const
62									{ return fArchitecture; }
63			void				SetArchitecture(Architecture* architecture);
64
65protected:
66	virtual	status_t			LoadSpecificInfoFromMessage(
67									const BMessage& data) = 0;
68	virtual	status_t			SaveSpecificInfoToMessage(
69									BMessage& _output) const = 0;
70
71private:
72			Architecture*		fArchitecture;
73};
74
75
76class RemoteDebugResponse : public BReferenceable {
77public:
78								RemoteDebugResponse();
79	virtual						~RemoteDebugResponse();
80
81			void				SetRequestInfo(RemoteDebugRequest* request,
82									status_t result);
83
84			RemoteDebugRequest*	Request() const 	{ return fRequest; }
85			Architecture*		GetArchitecture() const
86									{ return fRequest->GetArchitecture(); }
87
88			status_t			LoadFromMessage(const BMessage& data);
89			status_t			SaveToMessage(BMessage& _output) const;
90
91			status_t			Result() const		{ return fResult; }
92			bool				Succeeded() const	{ return fResult == B_OK; }
93
94protected:
95								// for requests that respond with additional
96								// information beyond a simple success/failure,
97								// a subclass must be implemented that provides
98								// versions of the functions below to save/
99								// and restore the corresponding additional
100								// data. Requests that merely return a status
101								// code can simply instantiate the basic
102								// response class as is.
103	virtual	status_t			LoadSpecificInfoFromMessage(const BMessage& data);
104	virtual	status_t			SaveSpecificInfoToMessage(BMessage& _output) const;
105
106private:
107			RemoteDebugRequest*	fRequest;
108			status_t			fResult;
109};
110
111
112// #pragma mark - Requests
113
114
115class RemoteDebugReadMemoryRequest : public RemoteDebugRequest {
116public:
117								RemoteDebugReadMemoryRequest();
118	virtual						~RemoteDebugReadMemoryRequest();
119
120			void				SetTo(target_addr_t address,
121									target_size_t size);
122
123			target_addr_t		Address() const	{ return fAddress; }
124			target_size_t 		Size() const { return fSize; }
125
126	virtual	remote_request_type	Type() const;
127
128protected:
129	virtual	status_t			LoadSpecificInfoFromMessage(
130									const BMessage& data);
131	virtual	status_t			SaveSpecificInfoToMessage(
132									BMessage& _output) const;
133
134private:
135			target_addr_t		fAddress;
136			target_size_t		fSize;
137};
138
139
140class RemoteDebugWriteMemoryRequest : public RemoteDebugRequest {
141public:
142								RemoteDebugWriteMemoryRequest();
143	virtual						~RemoteDebugWriteMemoryRequest();
144
145			status_t			SetTo(target_addr_t address,
146									const void* data, target_size_t size);
147
148			target_addr_t		Address() const	{ return fAddress; }
149			const void*			Data() const	{ return fData; }
150			target_size_t 		Size() const	{ return fSize; }
151
152	virtual	remote_request_type	Type() const;
153
154protected:
155	virtual	status_t			LoadSpecificInfoFromMessage(
156									const BMessage& data);
157	virtual	status_t			SaveSpecificInfoToMessage(
158									BMessage& _output) const;
159
160private:
161			target_addr_t		fAddress;
162			void*				fData;
163			target_size_t		fSize;
164};
165
166
167class RemoteDebugSetTeamFlagsRequest : public RemoteDebugRequest {
168public:
169								RemoteDebugSetTeamFlagsRequest();
170	virtual						~RemoteDebugSetTeamFlagsRequest();
171
172			void				SetTo(int32 flags);
173
174			int32				Flags() const	{ return fFlags; }
175
176	virtual	remote_request_type	Type() const;
177
178protected:
179	virtual	status_t			LoadSpecificInfoFromMessage(
180									const BMessage& data);
181	virtual	status_t			SaveSpecificInfoToMessage(
182									BMessage& _output) const;
183
184private:
185			int32				fFlags;
186};
187
188
189class RemoteDebugSetThreadFlagsRequest : public RemoteDebugRequest {
190public:
191								RemoteDebugSetThreadFlagsRequest();
192	virtual						~RemoteDebugSetThreadFlagsRequest();
193
194			void				SetTo(thread_id thread, int32 flags);
195
196			thread_id			Thread() const	{ return fThread; }
197			int32				Flags() const	{ return fFlags; }
198
199	virtual	remote_request_type	Type() const;
200
201protected:
202	virtual	status_t			LoadSpecificInfoFromMessage(
203									const BMessage& data);
204	virtual	status_t			SaveSpecificInfoToMessage(
205									BMessage& _output) const;
206
207private:
208			thread_id			fThread;
209			int32				fFlags;
210};
211
212
213// abstract base for the various thread actions, as those all
214// take a thread ID as a parameter and have no special response
215// requirements, with only the action to be taken differing.
216class RemoteDebugThreadActionRequest : public RemoteDebugRequest {
217public:
218								RemoteDebugThreadActionRequest();
219	virtual						~RemoteDebugThreadActionRequest();
220
221			void				SetTo(thread_id thread);
222
223			thread_id			Thread() const	{ return fThread; }
224
225protected:
226	virtual	status_t			LoadSpecificInfoFromMessage(
227									const BMessage& data);
228	virtual	status_t			SaveSpecificInfoToMessage(
229									BMessage& _output) const;
230
231private:
232			thread_id			fThread;
233};
234
235
236class RemoteDebugContinueThreadRequest
237	: public RemoteDebugThreadActionRequest {
238public:
239								RemoteDebugContinueThreadRequest();
240	virtual						~RemoteDebugContinueThreadRequest();
241
242	virtual	remote_request_type	Type() const;
243};
244
245
246class RemoteDebugStopThreadRequest
247	: public RemoteDebugThreadActionRequest {
248public:
249								RemoteDebugStopThreadRequest();
250	virtual						~RemoteDebugStopThreadRequest();
251
252	virtual	remote_request_type	Type() const;
253};
254
255
256class RemoteDebugSingleStepThreadRequest
257	: public RemoteDebugThreadActionRequest {
258public:
259								RemoteDebugSingleStepThreadRequest();
260	virtual						~RemoteDebugSingleStepThreadRequest();
261
262	virtual	remote_request_type	Type() const;
263};
264
265
266class RemoteDebugGetCpuStateRequest
267	: public RemoteDebugThreadActionRequest {
268public:
269								RemoteDebugGetCpuStateRequest();
270	virtual						~RemoteDebugGetCpuStateRequest();
271
272	virtual	remote_request_type	Type() const;
273};
274
275
276class RemoteDebugSetCpuStateRequest : public RemoteDebugRequest {
277public:
278								RemoteDebugSetCpuStateRequest();
279	virtual						~RemoteDebugSetCpuStateRequest();
280
281			void				SetTo(thread_id thread, CpuState* state);
282
283			thread_id			Thread() const	{ return fThread; }
284
285	virtual	remote_request_type	Type() const;
286
287protected:
288	virtual	status_t			LoadSpecificInfoFromMessage(
289									const BMessage& data);
290	virtual	status_t			SaveSpecificInfoToMessage(
291									BMessage& _output) const;
292
293private:
294			thread_id			fThread;
295			CpuState*			fCpuState;
296};
297
298
299// abstract base for the various actions that influence how the CPU
300// reacts to a particular memory address, ergo break/watchpoints.
301class RemoteDebugAddressActionRequest : public RemoteDebugRequest {
302public:
303								RemoteDebugAddressActionRequest();
304	virtual						~RemoteDebugAddressActionRequest();
305
306			void				SetTo(target_addr_t address);
307
308			target_addr_t		Address() const	{ return fAddress; }
309
310protected:
311	virtual	status_t			LoadSpecificInfoFromMessage(
312									const BMessage& data);
313	virtual	status_t			SaveSpecificInfoToMessage(
314									BMessage& _output) const;
315
316private:
317			target_addr_t		fAddress;
318};
319
320
321class RemoteDebugInstallBreakpointRequest
322	: public RemoteDebugAddressActionRequest {
323public:
324								RemoteDebugInstallBreakpointRequest();
325	virtual						~RemoteDebugInstallBreakpointRequest();
326
327	virtual	remote_request_type	Type() const;
328};
329
330
331class RemoteDebugUninstallBreakpointRequest
332	: public RemoteDebugAddressActionRequest {
333public:
334								RemoteDebugUninstallBreakpointRequest();
335	virtual						~RemoteDebugUninstallBreakpointRequest();
336
337	virtual	remote_request_type	Type() const;
338};
339
340
341class RemoteDebugInstallWatchpointRequest : public RemoteDebugRequest {
342public:
343								RemoteDebugInstallWatchpointRequest();
344	virtual						~RemoteDebugInstallWatchpointRequest();
345
346			void				SetTo(target_addr_t address, uint32 type,
347									int32 length);
348
349			target_addr_t		Address() const		{ return fAddress; }
350			uint32				WatchType() const	{ return fWatchType; }
351			int32				Length() const		{ return fLength; }
352
353	virtual	remote_request_type	Type() const;
354
355protected:
356	virtual	status_t			LoadSpecificInfoFromMessage(
357									const BMessage& data);
358	virtual	status_t			SaveSpecificInfoToMessage(
359									BMessage& _output) const;
360
361private:
362			target_addr_t		fAddress;
363			uint32				fWatchType;
364			int32				fLength;
365};
366
367
368class RemoteDebugUninstallWatchpointRequest
369	: public RemoteDebugAddressActionRequest {
370public:
371								RemoteDebugUninstallWatchpointRequest();
372	virtual						~RemoteDebugUninstallWatchpointRequest();
373
374	virtual	remote_request_type	Type() const;
375};
376
377
378// #pragma mark - Responses
379
380
381class RemoteDebugReadMemoryResponse : public RemoteDebugResponse {
382public:
383								RemoteDebugReadMemoryResponse();
384	virtual						~RemoteDebugReadMemoryResponse();
385
386			void				SetTo(void* data, target_size_t size);
387
388			const void*			Data() const	{ return fData; }
389			target_size_t		Size() const 	{ return fSize; }
390
391protected:
392	virtual	status_t			LoadSpecificInfoFromMessage(const BMessage& data);
393	virtual	status_t			SaveSpecificInfoToMessage(BMessage& _output) const;
394
395private:
396			void*				fData;
397			target_size_t		fSize;
398};
399
400
401class RemoteDebugGetCpuStateResponse : public RemoteDebugResponse {
402public:
403								RemoteDebugGetCpuStateResponse();
404	virtual						~RemoteDebugGetCpuStateResponse();
405
406			void				SetTo(CpuState* state);
407
408			CpuState*			GetCpuState() const { return fCpuState; }
409
410protected:
411	virtual	status_t			LoadSpecificInfoFromMessage(const BMessage& data);
412	virtual	status_t			SaveSpecificInfoToMessage(BMessage& _output) const;
413
414private:
415			CpuState*			fCpuState;
416};
417
418
419#endif	// REMOTE_DEBUG_REQUEST_H
420