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 15 enum 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 46 class Architecture; 47 class BMessage; 48 class CpuState; 49 50 51 class RemoteDebugRequest : public BReferenceable { 52 public: 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 GetArchitecture()61 Architecture* GetArchitecture() const 62 { return fArchitecture; } 63 void SetArchitecture(Architecture* architecture); 64 65 protected: 66 virtual status_t LoadSpecificInfoFromMessage( 67 const BMessage& data) = 0; 68 virtual status_t SaveSpecificInfoToMessage( 69 BMessage& _output) const = 0; 70 71 private: 72 Architecture* fArchitecture; 73 }; 74 75 76 class RemoteDebugResponse : public BReferenceable { 77 public: 78 RemoteDebugResponse(); 79 virtual ~RemoteDebugResponse(); 80 81 void SetRequestInfo(RemoteDebugRequest* request, 82 status_t result); 83 Request()84 RemoteDebugRequest* Request() const { return fRequest; } GetArchitecture()85 Architecture* GetArchitecture() const 86 { return fRequest->GetArchitecture(); } 87 88 status_t LoadFromMessage(const BMessage& data); 89 status_t SaveToMessage(BMessage& _output) const; 90 Result()91 status_t Result() const { return fResult; } Succeeded()92 bool Succeeded() const { return fResult == B_OK; } 93 94 protected: 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 106 private: 107 RemoteDebugRequest* fRequest; 108 status_t fResult; 109 }; 110 111 112 // #pragma mark - Requests 113 114 115 class RemoteDebugReadMemoryRequest : public RemoteDebugRequest { 116 public: 117 RemoteDebugReadMemoryRequest(); 118 virtual ~RemoteDebugReadMemoryRequest(); 119 120 void SetTo(target_addr_t address, 121 target_size_t size); 122 Address()123 target_addr_t Address() const { return fAddress; } Size()124 target_size_t Size() const { return fSize; } 125 126 virtual remote_request_type Type() const; 127 128 protected: 129 virtual status_t LoadSpecificInfoFromMessage( 130 const BMessage& data); 131 virtual status_t SaveSpecificInfoToMessage( 132 BMessage& _output) const; 133 134 private: 135 target_addr_t fAddress; 136 target_size_t fSize; 137 }; 138 139 140 class RemoteDebugWriteMemoryRequest : public RemoteDebugRequest { 141 public: 142 RemoteDebugWriteMemoryRequest(); 143 virtual ~RemoteDebugWriteMemoryRequest(); 144 145 status_t SetTo(target_addr_t address, 146 const void* data, target_size_t size); 147 Address()148 target_addr_t Address() const { return fAddress; } Data()149 const void* Data() const { return fData; } Size()150 target_size_t Size() const { return fSize; } 151 152 virtual remote_request_type Type() const; 153 154 protected: 155 virtual status_t LoadSpecificInfoFromMessage( 156 const BMessage& data); 157 virtual status_t SaveSpecificInfoToMessage( 158 BMessage& _output) const; 159 160 private: 161 target_addr_t fAddress; 162 void* fData; 163 target_size_t fSize; 164 }; 165 166 167 class RemoteDebugSetTeamFlagsRequest : public RemoteDebugRequest { 168 public: 169 RemoteDebugSetTeamFlagsRequest(); 170 virtual ~RemoteDebugSetTeamFlagsRequest(); 171 172 void SetTo(int32 flags); 173 Flags()174 int32 Flags() const { return fFlags; } 175 176 virtual remote_request_type Type() const; 177 178 protected: 179 virtual status_t LoadSpecificInfoFromMessage( 180 const BMessage& data); 181 virtual status_t SaveSpecificInfoToMessage( 182 BMessage& _output) const; 183 184 private: 185 int32 fFlags; 186 }; 187 188 189 class RemoteDebugSetThreadFlagsRequest : public RemoteDebugRequest { 190 public: 191 RemoteDebugSetThreadFlagsRequest(); 192 virtual ~RemoteDebugSetThreadFlagsRequest(); 193 194 void SetTo(thread_id thread, int32 flags); 195 Thread()196 thread_id Thread() const { return fThread; } Flags()197 int32 Flags() const { return fFlags; } 198 199 virtual remote_request_type Type() const; 200 201 protected: 202 virtual status_t LoadSpecificInfoFromMessage( 203 const BMessage& data); 204 virtual status_t SaveSpecificInfoToMessage( 205 BMessage& _output) const; 206 207 private: 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. 216 class RemoteDebugThreadActionRequest : public RemoteDebugRequest { 217 public: 218 RemoteDebugThreadActionRequest(); 219 virtual ~RemoteDebugThreadActionRequest(); 220 221 void SetTo(thread_id thread); 222 Thread()223 thread_id Thread() const { return fThread; } 224 225 protected: 226 virtual status_t LoadSpecificInfoFromMessage( 227 const BMessage& data); 228 virtual status_t SaveSpecificInfoToMessage( 229 BMessage& _output) const; 230 231 private: 232 thread_id fThread; 233 }; 234 235 236 class RemoteDebugContinueThreadRequest 237 : public RemoteDebugThreadActionRequest { 238 public: 239 RemoteDebugContinueThreadRequest(); 240 virtual ~RemoteDebugContinueThreadRequest(); 241 242 virtual remote_request_type Type() const; 243 }; 244 245 246 class RemoteDebugStopThreadRequest 247 : public RemoteDebugThreadActionRequest { 248 public: 249 RemoteDebugStopThreadRequest(); 250 virtual ~RemoteDebugStopThreadRequest(); 251 252 virtual remote_request_type Type() const; 253 }; 254 255 256 class RemoteDebugSingleStepThreadRequest 257 : public RemoteDebugThreadActionRequest { 258 public: 259 RemoteDebugSingleStepThreadRequest(); 260 virtual ~RemoteDebugSingleStepThreadRequest(); 261 262 virtual remote_request_type Type() const; 263 }; 264 265 266 class RemoteDebugGetCpuStateRequest 267 : public RemoteDebugThreadActionRequest { 268 public: 269 RemoteDebugGetCpuStateRequest(); 270 virtual ~RemoteDebugGetCpuStateRequest(); 271 272 virtual remote_request_type Type() const; 273 }; 274 275 276 class RemoteDebugSetCpuStateRequest : public RemoteDebugRequest { 277 public: 278 RemoteDebugSetCpuStateRequest(); 279 virtual ~RemoteDebugSetCpuStateRequest(); 280 281 void SetTo(thread_id thread, CpuState* state); 282 Thread()283 thread_id Thread() const { return fThread; } 284 285 virtual remote_request_type Type() const; 286 287 protected: 288 virtual status_t LoadSpecificInfoFromMessage( 289 const BMessage& data); 290 virtual status_t SaveSpecificInfoToMessage( 291 BMessage& _output) const; 292 293 private: 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. 301 class RemoteDebugAddressActionRequest : public RemoteDebugRequest { 302 public: 303 RemoteDebugAddressActionRequest(); 304 virtual ~RemoteDebugAddressActionRequest(); 305 306 void SetTo(target_addr_t address); 307 Address()308 target_addr_t Address() const { return fAddress; } 309 310 protected: 311 virtual status_t LoadSpecificInfoFromMessage( 312 const BMessage& data); 313 virtual status_t SaveSpecificInfoToMessage( 314 BMessage& _output) const; 315 316 private: 317 target_addr_t fAddress; 318 }; 319 320 321 class RemoteDebugInstallBreakpointRequest 322 : public RemoteDebugAddressActionRequest { 323 public: 324 RemoteDebugInstallBreakpointRequest(); 325 virtual ~RemoteDebugInstallBreakpointRequest(); 326 327 virtual remote_request_type Type() const; 328 }; 329 330 331 class RemoteDebugUninstallBreakpointRequest 332 : public RemoteDebugAddressActionRequest { 333 public: 334 RemoteDebugUninstallBreakpointRequest(); 335 virtual ~RemoteDebugUninstallBreakpointRequest(); 336 337 virtual remote_request_type Type() const; 338 }; 339 340 341 class RemoteDebugInstallWatchpointRequest : public RemoteDebugRequest { 342 public: 343 RemoteDebugInstallWatchpointRequest(); 344 virtual ~RemoteDebugInstallWatchpointRequest(); 345 346 void SetTo(target_addr_t address, uint32 type, 347 int32 length); 348 Address()349 target_addr_t Address() const { return fAddress; } WatchType()350 uint32 WatchType() const { return fWatchType; } Length()351 int32 Length() const { return fLength; } 352 353 virtual remote_request_type Type() const; 354 355 protected: 356 virtual status_t LoadSpecificInfoFromMessage( 357 const BMessage& data); 358 virtual status_t SaveSpecificInfoToMessage( 359 BMessage& _output) const; 360 361 private: 362 target_addr_t fAddress; 363 uint32 fWatchType; 364 int32 fLength; 365 }; 366 367 368 class RemoteDebugUninstallWatchpointRequest 369 : public RemoteDebugAddressActionRequest { 370 public: 371 RemoteDebugUninstallWatchpointRequest(); 372 virtual ~RemoteDebugUninstallWatchpointRequest(); 373 374 virtual remote_request_type Type() const; 375 }; 376 377 378 // #pragma mark - Responses 379 380 381 class RemoteDebugReadMemoryResponse : public RemoteDebugResponse { 382 public: 383 RemoteDebugReadMemoryResponse(); 384 virtual ~RemoteDebugReadMemoryResponse(); 385 386 void SetTo(void* data, target_size_t size); 387 Data()388 const void* Data() const { return fData; } Size()389 target_size_t Size() const { return fSize; } 390 391 protected: 392 virtual status_t LoadSpecificInfoFromMessage(const BMessage& data); 393 virtual status_t SaveSpecificInfoToMessage(BMessage& _output) const; 394 395 private: 396 void* fData; 397 target_size_t fSize; 398 }; 399 400 401 class RemoteDebugGetCpuStateResponse : public RemoteDebugResponse { 402 public: 403 RemoteDebugGetCpuStateResponse(); 404 virtual ~RemoteDebugGetCpuStateResponse(); 405 406 void SetTo(CpuState* state); 407 GetCpuState()408 CpuState* GetCpuState() const { return fCpuState; } 409 410 protected: 411 virtual status_t LoadSpecificInfoFromMessage(const BMessage& data); 412 virtual status_t SaveSpecificInfoToMessage(BMessage& _output) const; 413 414 private: 415 CpuState* fCpuState; 416 }; 417 418 419 #endif // REMOTE_DEBUG_REQUEST_H 420