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