diff --git a/src/kits/debugger/Jamfile b/src/kits/debugger/Jamfile index ea9ee5dec4..6bab1eaddb 100644 --- a/src/kits/debugger/Jamfile +++ b/src/kits/debugger/Jamfile @@ -46,6 +46,7 @@ SEARCH_SOURCE += [ FDirName $(SUBDIR) debug_managers ] ; SEARCH_SOURCE += [ FDirName $(SUBDIR) debugger_interface ] ; SEARCH_SOURCE += [ FDirName $(SUBDIR) debugger_interface core ] ; SEARCH_SOURCE += [ FDirName $(SUBDIR) debugger_interface local ] ; +SEARCH_SOURCE += [ FDirName $(SUBDIR) debugger_interface remote ] ; SEARCH_SOURCE += [ FDirName $(SUBDIR) elf ] ; SEARCH_SOURCE += [ FDirName $(SUBDIR) files ] ; SEARCH_SOURCE += [ FDirName $(SUBDIR) ids ] ; @@ -150,6 +151,9 @@ local sources = # debugger_interface/local LocalDebuggerInterface.cpp + # debugger_interface/remote + RemoteDebugRequest.cpp + # elf CoreFile.cpp ElfFile.cpp diff --git a/src/kits/debugger/debugger_interface/remote/RemoteDebugRequest.cpp b/src/kits/debugger/debugger_interface/remote/RemoteDebugRequest.cpp new file mode 100644 index 0000000000..001339fbf7 --- /dev/null +++ b/src/kits/debugger/debugger_interface/remote/RemoteDebugRequest.cpp @@ -0,0 +1,740 @@ +/* + * Copyright 2016, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ + + +#include "RemoteDebugRequest.h" + +#include "Architecture.h" +#include "CpuState.h" + +#include + +#include + +#include + + +// #pragma mark - RemoteDebugRequest + + +RemoteDebugRequest::RemoteDebugRequest() + : + BReferenceable(), + fArchitecture(NULL) +{ +} + + +RemoteDebugRequest::~RemoteDebugRequest() +{ + if (fArchitecture != NULL) + fArchitecture->ReleaseReference(); +} + + +status_t +RemoteDebugRequest::LoadFromMessage(const BMessage& data) +{ + if (data.FindInt32("type") != Type()) + return B_BAD_VALUE; + + return LoadSpecificInfoFromMessage(data); +} + + +status_t +RemoteDebugRequest::SaveToMessage(BMessage& _output) const +{ + _output.MakeEmpty(); + + status_t error = _output.AddInt32("type", Type()); + if (error != B_OK) + return error; + + return SaveSpecificInfoToMessage(_output); +} + + +void +RemoteDebugRequest::SetArchitecture(Architecture* architecture) +{ + fArchitecture = architecture; + fArchitecture->AcquireReference(); +} + + +// #pragma mark - RemoteDebugResponse + + +RemoteDebugResponse::RemoteDebugResponse() + : + BReferenceable(), + fRequest(NULL), + fResult(B_OK) +{ +} + + +RemoteDebugResponse::~RemoteDebugResponse() +{ + if (fRequest != NULL) + fRequest->ReleaseReference(); +} + + +void +RemoteDebugResponse::SetRequestInfo(RemoteDebugRequest* request, + status_t result) +{ + fRequest = request; + fRequest->AcquireReference(); + fResult = result; +} + + +status_t +RemoteDebugResponse::LoadFromMessage(const BMessage& data) +{ + if (data.FindInt32("type") != Request()->Type()) + return B_BAD_VALUE; + + if (!Succeeded()) + return B_OK; + + return LoadSpecificInfoFromMessage(data); +} + + +status_t +RemoteDebugResponse::SaveToMessage(BMessage& _output) const +{ + _output.MakeEmpty(); + + status_t error = _output.AddInt32("type", Request()->Type()); + if (error != B_OK) + return error; + + error = _output.AddInt32("result", Result()); + if (error != B_OK) + return error; + + if (!Succeeded()) + return B_OK; + + return SaveSpecificInfoToMessage(_output); +} + + +status_t +RemoteDebugResponse::LoadSpecificInfoFromMessage(const BMessage& data) +{ + return B_OK; +} + + +status_t +RemoteDebugResponse::SaveSpecificInfoToMessage(BMessage& _output) const +{ + return B_OK; +} + + +// #pragma mark - RemoteDebugReadMemoryRequest + + +RemoteDebugReadMemoryRequest::RemoteDebugReadMemoryRequest() + : + RemoteDebugRequest(), + fAddress(0), + fSize(0) +{ +} + + +RemoteDebugReadMemoryRequest::~RemoteDebugReadMemoryRequest() +{ +} + + +void +RemoteDebugReadMemoryRequest::SetTo(target_addr_t address, target_size_t size) +{ + fAddress = address; + fSize = size; +} + + +remote_request_type +RemoteDebugReadMemoryRequest::Type() const +{ + return REMOTE_REQUEST_TYPE_READ_MEMORY; +} + + +status_t +RemoteDebugReadMemoryRequest::LoadSpecificInfoFromMessage(const BMessage& data) +{ + if (data.FindUInt64("address", &fAddress) != B_OK) + return B_BAD_VALUE; + + if (data.FindUInt64("size", &fSize) != B_OK) + return B_BAD_VALUE; + + return B_OK; +} + + +status_t +RemoteDebugReadMemoryRequest::SaveSpecificInfoToMessage( + BMessage& _output) const +{ + status_t error = _output.AddUInt64("address", fAddress); + if (error != B_OK) + return error; + + return _output.AddUInt64("size", fSize); +} + + +// #pragma mark - RemoteDebugWriteMemoryRequest + + +RemoteDebugWriteMemoryRequest::RemoteDebugWriteMemoryRequest() + : + RemoteDebugRequest(), + fAddress(0), + fData(NULL), + fSize(0) +{ +} + + +RemoteDebugWriteMemoryRequest::~RemoteDebugWriteMemoryRequest() +{ + if (fData != NULL) + free(fData); +} + + +status_t +RemoteDebugWriteMemoryRequest::SetTo(target_addr_t address, const void* data, + target_size_t size) +{ + if (size == 0 || data == NULL) + return B_BAD_VALUE; + + fAddress = address; + fSize = size; + fData = malloc(fSize); + if (fData == NULL) + return B_NO_MEMORY; + + + memcpy(fData, data, fSize); + return B_OK; +} + + +remote_request_type +RemoteDebugWriteMemoryRequest::Type() const +{ + return REMOTE_REQUEST_TYPE_WRITE_MEMORY; +} + + +status_t +RemoteDebugWriteMemoryRequest::LoadSpecificInfoFromMessage( + const BMessage& data) +{ + if (data.FindUInt64("address", &fAddress) != B_OK) + return B_BAD_VALUE; + + if (data.FindUInt64("size", &fSize) != B_OK) + return B_BAD_VALUE; + + fData = malloc(fSize); + if (fData == NULL) + return B_NO_MEMORY; + + const void* messageData = NULL; + ssize_t numBytes = -1; + status_t error = data.FindData("data", B_RAW_TYPE, &messageData, + &numBytes); + if (error != B_OK) + return error; + + if ((size_t)numBytes != fSize) + return B_MISMATCHED_VALUES; + + memcpy(fData, messageData, numBytes); + + return B_OK; +} + + +status_t +RemoteDebugWriteMemoryRequest::SaveSpecificInfoToMessage( + BMessage& _output) const +{ + status_t error = _output.AddUInt64("address", fAddress); + if (error != B_OK) + return error; + + error = _output.AddUInt64("size", fSize); + if (error != B_OK) + return error; + + return _output.AddData("data", B_RAW_TYPE, fData, (ssize_t)fSize); +} + + +// #pragma mark - RemoteDebugSetTeamFlagsRequest + + +RemoteDebugSetTeamFlagsRequest::RemoteDebugSetTeamFlagsRequest() + : + RemoteDebugRequest(), + fFlags(0) +{ +} + + +RemoteDebugSetTeamFlagsRequest::~RemoteDebugSetTeamFlagsRequest() +{ +} + + +void +RemoteDebugSetTeamFlagsRequest::SetTo(int32 flags) +{ + fFlags = flags; +} + + +remote_request_type +RemoteDebugSetTeamFlagsRequest::Type() const +{ + return REMOTE_REQUEST_TYPE_SET_TEAM_FLAGS; +} + + +status_t +RemoteDebugSetTeamFlagsRequest::LoadSpecificInfoFromMessage( + const BMessage& data) +{ + if (data.FindInt32("flags", &fFlags) != B_OK) + return B_BAD_VALUE; + + return B_OK; +} + + +status_t +RemoteDebugSetTeamFlagsRequest::SaveSpecificInfoToMessage( + BMessage& _output) const +{ + return _output.AddInt32("flags", fFlags); +} + + +// #pragma mark - RemoteDebugSetThreadFlagsRequest + + +RemoteDebugSetThreadFlagsRequest::RemoteDebugSetThreadFlagsRequest() + : + RemoteDebugRequest(), + fThread(-1), + fFlags(0) +{ +} + + +RemoteDebugSetThreadFlagsRequest::~RemoteDebugSetThreadFlagsRequest() +{ +} + + +void +RemoteDebugSetThreadFlagsRequest::SetTo(thread_id thread, int32 flags) +{ + fThread = thread; + fFlags = flags; +} + + +remote_request_type +RemoteDebugSetThreadFlagsRequest::Type() const +{ + return REMOTE_REQUEST_TYPE_SET_THREAD_FLAGS; +} + + +status_t +RemoteDebugSetThreadFlagsRequest::LoadSpecificInfoFromMessage( + const BMessage& data) +{ + if (data.FindInt32("thread", &fThread) != B_OK) + return B_BAD_VALUE; + + if (data.FindInt32("flags", &fFlags) != B_OK) + return B_BAD_VALUE; + + return B_OK; +} + + +status_t +RemoteDebugSetThreadFlagsRequest::SaveSpecificInfoToMessage( + BMessage& _output) const +{ + status_t error = _output.AddInt32("thread", fThread); + if (error != B_OK) + return error; + + return _output.AddInt32("flags", fFlags); +} + + +// #pragma mark - RemoteDebugThreadActionRequest + + +RemoteDebugThreadActionRequest::RemoteDebugThreadActionRequest() + : + RemoteDebugRequest(), + fThread(-1) +{ +} + + +RemoteDebugThreadActionRequest::~RemoteDebugThreadActionRequest() +{ +} + + +void +RemoteDebugThreadActionRequest::SetTo(thread_id thread) +{ + fThread = thread; +} + + +status_t +RemoteDebugThreadActionRequest::LoadSpecificInfoFromMessage( + const BMessage& data) +{ + if (data.FindInt32("thread", &fThread) != B_OK) + return B_BAD_VALUE; + + return B_OK; +} + + +status_t +RemoteDebugThreadActionRequest::SaveSpecificInfoToMessage( + BMessage& _output) const +{ + return _output.AddInt32("thread", fThread); +} + + +// #pragma mark - RemoteDebugContinueThreadRequest + + +RemoteDebugContinueThreadRequest::RemoteDebugContinueThreadRequest() + : + RemoteDebugThreadActionRequest() +{ +} + + +RemoteDebugContinueThreadRequest::~RemoteDebugContinueThreadRequest() +{ +} + +remote_request_type +RemoteDebugContinueThreadRequest::Type() const +{ + return REMOTE_REQUEST_TYPE_CONTINUE_THREAD; +} + + +// #pragma mark - RemoteDebugStopThreadRequest + + +RemoteDebugStopThreadRequest::RemoteDebugStopThreadRequest() + : + RemoteDebugThreadActionRequest() +{ +} + + +RemoteDebugStopThreadRequest::~RemoteDebugStopThreadRequest() +{ +} + +remote_request_type +RemoteDebugStopThreadRequest::Type() const +{ + return REMOTE_REQUEST_TYPE_STOP_THREAD; +} + + +// #pragma mark - RemoteDebugSingleStepThreadRequest + + +RemoteDebugSingleStepThreadRequest::RemoteDebugSingleStepThreadRequest() + : + RemoteDebugThreadActionRequest() +{ +} + + +RemoteDebugSingleStepThreadRequest::~RemoteDebugSingleStepThreadRequest() +{ +} + +remote_request_type +RemoteDebugSingleStepThreadRequest::Type() const +{ + return REMOTE_REQUEST_TYPE_SINGLE_STEP_THREAD; +} + + +// #pragma mark - RemoteDebugGetCpuStateRequest + + +RemoteDebugGetCpuStateRequest::RemoteDebugGetCpuStateRequest() + : + RemoteDebugThreadActionRequest() +{ +} + + +RemoteDebugGetCpuStateRequest::~RemoteDebugGetCpuStateRequest() +{ +} + + +remote_request_type +RemoteDebugGetCpuStateRequest::Type() const +{ + return REMOTE_REQUEST_TYPE_GET_CPU_STATE; +} + + +// #pragma mark - RemoteDebugSetCpuStateRequest + + +RemoteDebugSetCpuStateRequest::RemoteDebugSetCpuStateRequest() + : + RemoteDebugRequest(), + fThread(-1), + fCpuState(NULL) +{ +} + + +RemoteDebugSetCpuStateRequest::~RemoteDebugSetCpuStateRequest() +{ + if (fCpuState != NULL) + fCpuState->ReleaseReference(); +} + + +void +RemoteDebugSetCpuStateRequest::SetTo(thread_id thread, CpuState* state) +{ + fThread = thread; + fCpuState = state; + if (fCpuState != NULL) + fCpuState->AcquireReference(); +} + + +remote_request_type +RemoteDebugSetCpuStateRequest::Type() const +{ + return REMOTE_REQUEST_TYPE_SET_CPU_STATE; +} + + +status_t +RemoteDebugSetCpuStateRequest::LoadSpecificInfoFromMessage( + const BMessage& data) +{ + if (data.FindInt32("thread", &fThread) != B_OK) + return B_BAD_VALUE; + + if (fCpuState != NULL) { + fCpuState->ReleaseReference(); + fCpuState = NULL; + } + + const uint8* buffer = NULL; + ssize_t numBytes = 0; + size_t stateSize = GetArchitecture()->DebugCpuStateSize(); + status_t error = data.FindData("state", B_RAW_TYPE, (const void**)&buffer, + &numBytes); + if (error != B_OK || (size_t)numBytes != stateSize) + return B_BAD_VALUE; + + return GetArchitecture()->CreateCpuState(buffer, stateSize, fCpuState); +} + + +status_t +RemoteDebugSetCpuStateRequest::SaveSpecificInfoToMessage( + BMessage& _output) const +{ + status_t error = _output.AddInt32("thread", fThread); + if (error != B_OK) + return error; + + size_t stateSize = GetArchitecture()->DebugCpuStateSize(); + uint8* buffer = new(std::nothrow) uint8[stateSize]; + if (buffer == NULL) + return B_NO_MEMORY; + + ArrayDeleter deleter(buffer); + error = fCpuState->UpdateDebugState(buffer, stateSize); + if (error != B_OK) + return error; + + return _output.AddData("state", B_RAW_TYPE, buffer, (ssize_t)stateSize); +} + + +// #pragma mark - RemoteDebugReadMemoryResponse + + +RemoteDebugReadMemoryResponse::RemoteDebugReadMemoryResponse() + : + RemoteDebugResponse(), + fData(NULL), + fSize(0) +{ +} + + +RemoteDebugReadMemoryResponse::~RemoteDebugReadMemoryResponse() +{ + if (fData != NULL) + free(fData); +} + + +void +RemoteDebugReadMemoryResponse::SetTo(void* data, target_size_t size) +{ + fData = data; + fSize = size; +} + + +status_t +RemoteDebugReadMemoryResponse::LoadSpecificInfoFromMessage( + const BMessage& data) +{ + status_t error = data.FindUInt64("size", &fSize); + if (error != B_OK) + return error; + + fData = malloc(fSize); + if (fData == NULL) + return B_NO_MEMORY; + + const void* messageData = NULL; + ssize_t numBytes = -1; + error = data.FindData("data", B_RAW_TYPE, &messageData, &numBytes); + if (error != B_OK) + return error; + + if ((size_t)numBytes != fSize) + return B_MISMATCHED_VALUES; + + memcpy(fData, messageData, numBytes); + return B_OK; +} + + +status_t +RemoteDebugReadMemoryResponse::SaveSpecificInfoToMessage( + BMessage& _output) const +{ + if (fData == NULL) + return B_OK; + + status_t error = _output.AddUInt64("size", fSize); + if (error != B_OK) + return error; + + return _output.AddData("data", B_RAW_TYPE, fData, (ssize_t)fSize); +} + + +// #pragma mark - RemoteDebugGetCpuStateResponse + + +RemoteDebugGetCpuStateResponse::RemoteDebugGetCpuStateResponse() + : + RemoteDebugResponse(), + fCpuState(NULL) +{ +} + + +RemoteDebugGetCpuStateResponse::~RemoteDebugGetCpuStateResponse() +{ + if (fCpuState != NULL) + fCpuState->ReleaseReference(); +} + + +void +RemoteDebugGetCpuStateResponse::SetTo(CpuState* state) +{ + fCpuState = state; + if (fCpuState != NULL) + fCpuState->AcquireReference(); +} + + +status_t +RemoteDebugGetCpuStateResponse::LoadSpecificInfoFromMessage( + const BMessage& data) +{ + if (fCpuState != NULL) { + fCpuState->ReleaseReference(); + fCpuState = NULL; + } + + const uint8* buffer = NULL; + ssize_t numBytes = 0; + size_t stateSize = GetArchitecture()->DebugCpuStateSize(); + status_t error = data.FindData("state", B_RAW_TYPE, (const void**)&buffer, + &numBytes); + if (error != B_OK || (size_t)numBytes != stateSize) + return B_BAD_VALUE; + + return GetArchitecture()->CreateCpuState(buffer, stateSize, fCpuState); +} + + +status_t +RemoteDebugGetCpuStateResponse::SaveSpecificInfoToMessage( + BMessage& _output) const +{ + size_t stateSize = GetArchitecture()->DebugCpuStateSize(); + uint8* buffer = new(std::nothrow) uint8[stateSize]; + if (buffer == NULL) + return B_NO_MEMORY; + + ArrayDeleter deleter(buffer); + status_t error = fCpuState->UpdateDebugState(buffer, stateSize); + if (error != B_OK) + return error; + + return _output.AddData("state", B_RAW_TYPE, buffer, (ssize_t)stateSize); +} diff --git a/src/kits/debugger/debugger_interface/remote/RemoteDebugRequest.h b/src/kits/debugger/debugger_interface/remote/RemoteDebugRequest.h new file mode 100644 index 0000000000..4bd24c7696 --- /dev/null +++ b/src/kits/debugger/debugger_interface/remote/RemoteDebugRequest.h @@ -0,0 +1,340 @@ +/* + * Copyright 2016, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ +#ifndef REMOTE_DEBUG_REQUEST_H +#define REMOTE_DEBUG_REQUEST_H + +#include "Types.h" + +#include + +#include + + +enum remote_request_type { + // debug requests + REMOTE_REQUEST_TYPE_READ_MEMORY = 0, + REMOTE_REQUEST_TYPE_WRITE_MEMORY, + REMOTE_REQUEST_TYPE_SET_TEAM_FLAGS, + REMOTE_REQUEST_TYPE_SET_THREAD_FLAGS, + REMOTE_REQUEST_TYPE_CONTINUE_THREAD, + REMOTE_REQUEST_TYPE_STOP_THREAD, + REMOTE_REQUEST_TYPE_SINGLE_STEP_THREAD, + REMOTE_REQUEST_TYPE_GET_CPU_STATE, + REMOTE_REQUEST_TYPE_SET_CPU_STATE, + REMOTE_REQUEST_TYPE_SET_BREAKPOINT, + REMOTE_REQUEST_TYPE_CLEAR_BREAKPOINT, + REMOTE_REQUEST_TYPE_SET_WATCHPOINT, + REMOTE_REQUEST_TYPE_CLEAR_WATCHPOINT, + REMOTE_REQUEST_TYPE_PREPARE_HANDOVER, + REMOTE_REQUEST_TYPE_WRITE_CORE_FILE, + + // team information requests + REMOTE_REQUEST_TYPE_GET_TEAM_INFO, + REMOTE_REQUEST_TYPE_GET_THREAD_INFOS, + REMOTE_REQUEST_TYPE_GET_IMAGE_INFOS, + REMOTE_REQUEST_TYPE_GET_AREA_INFOS, + REMOTE_REQUEST_TYPE_GET_SEM_INFOS, + REMOTE_REQUEST_TYPE_GET_SYMBOL_INFOS, + REMOTE_REQUEST_TYPE_GET_SYMBOL_INFO, + REMOTE_REQUEST_TYPE_GET_THREAD_INFO, + REMOTE_REQUEST_TYPE_GET_MEMORY_PROPERTIES +}; + + +class Architecture; +class BMessage; +class CpuState; + + +class RemoteDebugRequest : public BReferenceable { +public: + RemoteDebugRequest(); + virtual ~RemoteDebugRequest(); + + virtual remote_request_type Type() const = 0; + + status_t LoadFromMessage(const BMessage& data); + status_t SaveToMessage(BMessage& _output) const; + + Architecture* GetArchitecture() const + { return fArchitecture; } + void SetArchitecture(Architecture* architecture); + +protected: + virtual status_t LoadSpecificInfoFromMessage( + const BMessage& data) = 0; + virtual status_t SaveSpecificInfoToMessage( + BMessage& _output) const = 0; + +private: + Architecture* fArchitecture; +}; + + +class RemoteDebugResponse : public BReferenceable { +public: + RemoteDebugResponse(); + virtual ~RemoteDebugResponse(); + + void SetRequestInfo(RemoteDebugRequest* request, + status_t result); + + RemoteDebugRequest* Request() const { return fRequest; } + Architecture* GetArchitecture() const + { return fRequest->GetArchitecture(); } + + status_t LoadFromMessage(const BMessage& data); + status_t SaveToMessage(BMessage& _output) const; + + status_t Result() const { return fResult; } + bool Succeeded() const { return fResult == B_OK; } + +protected: + // for requests that respond with additional + // information beyond a simple success/failure, + // a subclass must be implemented that provides + // versions of the functions below to save/ + // and restore the corresponding additional + // data. Requests that merely return a status + // code can simply instantiate the basic + // response class as is. + virtual status_t LoadSpecificInfoFromMessage(const BMessage& data); + virtual status_t SaveSpecificInfoToMessage(BMessage& _output) const; + +private: + RemoteDebugRequest* fRequest; + status_t fResult; +}; + + +// #pragma mark - Requests + + +class RemoteDebugReadMemoryRequest : public RemoteDebugRequest { +public: + RemoteDebugReadMemoryRequest(); + virtual ~RemoteDebugReadMemoryRequest(); + + void SetTo(target_addr_t address, + target_size_t size); + + target_addr_t Address() const { return fAddress; } + target_size_t Size() const { return fSize; } + + virtual remote_request_type Type() const; + +protected: + virtual status_t LoadSpecificInfoFromMessage( + const BMessage& data); + virtual status_t SaveSpecificInfoToMessage( + BMessage& _output) const; + +private: + target_addr_t fAddress; + target_size_t fSize; +}; + + +class RemoteDebugWriteMemoryRequest : public RemoteDebugRequest { +public: + RemoteDebugWriteMemoryRequest(); + virtual ~RemoteDebugWriteMemoryRequest(); + + status_t SetTo(target_addr_t address, + const void* data, target_size_t size); + + target_addr_t Address() const { return fAddress; } + const void* Data() const { return fData; } + target_size_t Size() const { return fSize; } + + virtual remote_request_type Type() const; + +protected: + virtual status_t LoadSpecificInfoFromMessage( + const BMessage& data); + virtual status_t SaveSpecificInfoToMessage( + BMessage& _output) const; + +private: + target_addr_t fAddress; + void* fData; + target_size_t fSize; +}; + + +class RemoteDebugSetTeamFlagsRequest : public RemoteDebugRequest { +public: + RemoteDebugSetTeamFlagsRequest(); + virtual ~RemoteDebugSetTeamFlagsRequest(); + + void SetTo(int32 flags); + + int32 Flags() const { return fFlags; } + + virtual remote_request_type Type() const; + +protected: + virtual status_t LoadSpecificInfoFromMessage( + const BMessage& data); + virtual status_t SaveSpecificInfoToMessage( + BMessage& _output) const; + +private: + int32 fFlags; +}; + + +class RemoteDebugSetThreadFlagsRequest : public RemoteDebugRequest { +public: + RemoteDebugSetThreadFlagsRequest(); + virtual ~RemoteDebugSetThreadFlagsRequest(); + + void SetTo(thread_id thread, int32 flags); + + thread_id Thread() const { return fThread; } + int32 Flags() const { return fFlags; } + + virtual remote_request_type Type() const; + +protected: + virtual status_t LoadSpecificInfoFromMessage( + const BMessage& data); + virtual status_t SaveSpecificInfoToMessage( + BMessage& _output) const; + +private: + thread_id fThread; + int32 fFlags; +}; + + +// abstract base for the various thread actions, as those all +// take a thread ID as a parameter and have no special response +// requirements, with only the action to be taken differing. +class RemoteDebugThreadActionRequest : public RemoteDebugRequest { +public: + RemoteDebugThreadActionRequest(); + virtual ~RemoteDebugThreadActionRequest(); + + void SetTo(thread_id thread); + + thread_id Thread() const { return fThread; } + +protected: + virtual status_t LoadSpecificInfoFromMessage( + const BMessage& data); + virtual status_t SaveSpecificInfoToMessage( + BMessage& _output) const; + +private: + thread_id fThread; +}; + + +class RemoteDebugContinueThreadRequest + : public RemoteDebugThreadActionRequest { +public: + RemoteDebugContinueThreadRequest(); + virtual ~RemoteDebugContinueThreadRequest(); + + virtual remote_request_type Type() const; +}; + + +class RemoteDebugStopThreadRequest + : public RemoteDebugThreadActionRequest { +public: + RemoteDebugStopThreadRequest(); + virtual ~RemoteDebugStopThreadRequest(); + + virtual remote_request_type Type() const; +}; + + +class RemoteDebugSingleStepThreadRequest + : public RemoteDebugThreadActionRequest { +public: + RemoteDebugSingleStepThreadRequest(); + virtual ~RemoteDebugSingleStepThreadRequest(); + + virtual remote_request_type Type() const; +}; + + +class RemoteDebugGetCpuStateRequest + : public RemoteDebugThreadActionRequest { +public: + RemoteDebugGetCpuStateRequest(); + virtual ~RemoteDebugGetCpuStateRequest(); + + virtual remote_request_type Type() const; +}; + + +class RemoteDebugSetCpuStateRequest : public RemoteDebugRequest { +public: + RemoteDebugSetCpuStateRequest(); + virtual ~RemoteDebugSetCpuStateRequest(); + + void SetTo(thread_id thread, CpuState* state); + + thread_id Thread() const { return fThread; } + + virtual remote_request_type Type() const; + +protected: + virtual status_t LoadSpecificInfoFromMessage( + const BMessage& data); + virtual status_t SaveSpecificInfoToMessage( + BMessage& _output) const; + +private: + thread_id fThread; + CpuState* fCpuState; +}; + + +// #pragma mark - Responses + + +class RemoteDebugReadMemoryResponse : public RemoteDebugResponse { +public: + RemoteDebugReadMemoryResponse(); + virtual ~RemoteDebugReadMemoryResponse(); + + void SetTo(void* data, target_size_t size); + + const void* Data() const { return fData; } + target_size_t Size() const { return fSize; } + +protected: + virtual status_t LoadSpecificInfoFromMessage(const BMessage& data); + virtual status_t SaveSpecificInfoToMessage(BMessage& _output) const; + +private: + void* fData; + target_size_t fSize; +}; + + +class RemoteDebugGetCpuStateResponse : public RemoteDebugResponse { +public: + RemoteDebugGetCpuStateResponse(); + virtual ~RemoteDebugGetCpuStateResponse(); + + void SetTo(CpuState* state); + + CpuState* GetCpuState() const { return fCpuState; } + +protected: + virtual status_t LoadSpecificInfoFromMessage(const BMessage& data); + virtual status_t SaveSpecificInfoToMessage(BMessage& _output) const; + +private: + CpuState* fCpuState; +}; + + +#endif // REMOTE_DEBUG_REQUEST_H