libdebugger: Initial work for remote support.

- Introduce base classes RemoteDebug{Request,Response} and the first set of
  implementing subclasses for the various types of debug requests. These
  encapsulate the information needed to make a request to the target debugger
  interface, as well as a means to flatten/unflatten to a BMessage. These will
  be used to marshal the relevant information for transmission across the
  eventual transport interface. Not used anywhere yet since there still remain
  some requests and responses to implement, among other things.
This commit is contained in:
Rene Gollent
2016-07-31 17:30:23 -04:00
parent 9c9c24ce08
commit 17954f2e22
3 changed files with 1084 additions and 0 deletions
+4
View File
@@ -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
@@ -0,0 +1,740 @@
/*
* Copyright 2016, Rene Gollent, [email protected].
* Distributed under the terms of the MIT License.
*/
#include "RemoteDebugRequest.h"
#include "Architecture.h"
#include "CpuState.h"
#include <AutoDeleter.h>
#include <Message.h>
#include <stdlib.h>
// #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<uint8> 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<uint8> 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);
}
@@ -0,0 +1,340 @@
/*
* Copyright 2016, Rene Gollent, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef REMOTE_DEBUG_REQUEST_H
#define REMOTE_DEBUG_REQUEST_H
#include "Types.h"
#include <Referenceable.h>
#include <OS.h>
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