Debugger: Add ValueWriter support class.
- Given a value + corresponding location description, this handles ensuring that the data ends up in the appropriate locations in the target team.
This commit is contained in:
@@ -340,6 +340,7 @@ local sources =
|
|||||||
ValueNode.cpp
|
ValueNode.cpp
|
||||||
ValueNodeContainer.cpp
|
ValueNodeContainer.cpp
|
||||||
ValueNodeManager.cpp
|
ValueNodeManager.cpp
|
||||||
|
ValueWriter.cpp
|
||||||
|
|
||||||
# value/type_handlers
|
# value/type_handlers
|
||||||
BListTypeHandler.cpp
|
BListTypeHandler.cpp
|
||||||
|
|||||||
@@ -0,0 +1,135 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009-2012, Ingo Weinhold, [email protected].
|
||||||
|
* Copyright 2013-2015, Rene Gollent, [email protected].
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "ValueWriter.h"
|
||||||
|
|
||||||
|
#include "Architecture.h"
|
||||||
|
#include "BitBuffer.h"
|
||||||
|
#include "CpuState.h"
|
||||||
|
#include "DebuggerInterface.h"
|
||||||
|
#include "Register.h"
|
||||||
|
#include "TeamMemory.h"
|
||||||
|
#include "Tracing.h"
|
||||||
|
#include "ValueLocation.h"
|
||||||
|
|
||||||
|
|
||||||
|
ValueWriter::ValueWriter(Architecture* architecture,
|
||||||
|
DebuggerInterface* interface, CpuState* cpuState, thread_id targetThread)
|
||||||
|
:
|
||||||
|
fArchitecture(architecture),
|
||||||
|
fDebuggerInterface(interface),
|
||||||
|
fCpuState(cpuState),
|
||||||
|
fTargetThread(targetThread)
|
||||||
|
{
|
||||||
|
fArchitecture->AcquireReference();
|
||||||
|
fDebuggerInterface->AcquireReference();
|
||||||
|
if (fCpuState != NULL)
|
||||||
|
fCpuState->AcquireReference();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ValueWriter::~ValueWriter()
|
||||||
|
{
|
||||||
|
fArchitecture->ReleaseReference();
|
||||||
|
fDebuggerInterface->ReleaseReference();
|
||||||
|
if (fCpuState != NULL)
|
||||||
|
fCpuState->ReleaseReference();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ValueWriter::WriteValue(ValueLocation* location, BVariant& value)
|
||||||
|
{
|
||||||
|
if (!location->IsWritable())
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
int32 count = location->CountPieces();
|
||||||
|
if (fCpuState == NULL) {
|
||||||
|
for (int32 i = 0; i < count; i++) {
|
||||||
|
const ValuePieceLocation piece = location->PieceAt(i);
|
||||||
|
if (piece.type == VALUE_PIECE_LOCATION_REGISTER) {
|
||||||
|
TRACE_LOCALS(" -> asked to write value with register piece, "
|
||||||
|
"but no CPU state to write to.\n");
|
||||||
|
return B_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cpuStateWriteNeeded = false;
|
||||||
|
size_t byteOffset = 0;
|
||||||
|
bool bigEndian = fArchitecture->IsBigEndian();
|
||||||
|
const Register* registers = fArchitecture->Registers();
|
||||||
|
for (int32 i = 0; i < count; i++) {
|
||||||
|
ValuePieceLocation piece = location->PieceAt(
|
||||||
|
bigEndian ? i : count - i - 1);
|
||||||
|
uint32 bytesToWrite = piece.size;
|
||||||
|
|
||||||
|
uint8* targetData = (uint8*)value.Bytes() + byteOffset;
|
||||||
|
|
||||||
|
switch (piece.type) {
|
||||||
|
case VALUE_PIECE_LOCATION_MEMORY:
|
||||||
|
{
|
||||||
|
target_addr_t address = piece.address;
|
||||||
|
|
||||||
|
TRACE_LOCALS(" piece %" B_PRId32 ": memory address: %#"
|
||||||
|
B_PRIx64 ", bits: %" B_PRIu32 "\n", i, address,
|
||||||
|
bytesToWrite * 8);
|
||||||
|
|
||||||
|
ssize_t bytesWritten = fDebuggerInterface->WriteMemory(address,
|
||||||
|
targetData, bytesToWrite);
|
||||||
|
|
||||||
|
if (bytesWritten < 0)
|
||||||
|
return bytesWritten;
|
||||||
|
if ((uint32)bytesWritten != bytesToWrite)
|
||||||
|
return B_BAD_ADDRESS;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case VALUE_PIECE_LOCATION_REGISTER:
|
||||||
|
{
|
||||||
|
TRACE_LOCALS(" piece %" B_PRId32 ": register: %" B_PRIu32
|
||||||
|
", bits: %" B_PRIu32 "\n", i, piece.reg, bitSize);
|
||||||
|
|
||||||
|
const Register* target = registers + piece.reg;
|
||||||
|
BVariant pieceValue;
|
||||||
|
switch (bytesToWrite) {
|
||||||
|
case 1:
|
||||||
|
pieceValue.SetTo(*(uint8*)targetData);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
pieceValue.SetTo(*(uint16*)targetData);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
pieceValue.SetTo(*(uint32*)targetData);
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
pieceValue.SetTo(*(uint64*)targetData);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
TRACE_LOCALS("Asked to write unsupported piece size %"
|
||||||
|
B_PRId32 " to register\n", bytesToWrite);
|
||||||
|
return B_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fCpuState->SetRegisterValue(target, pieceValue))
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
cpuStateWriteNeeded = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return B_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
byteOffset += bytesToWrite;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cpuStateWriteNeeded)
|
||||||
|
return fDebuggerInterface->SetCpuState(fTargetThread, fCpuState);
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2015, Rene Gollent, [email protected].
|
||||||
|
* Copyright 2009, Ingo Weinhold, [email protected].
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef VALUE_WRITER_H
|
||||||
|
#define VALUE_WRITER_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <OS.h>
|
||||||
|
#include <String.h>
|
||||||
|
|
||||||
|
#include <Variant.h>
|
||||||
|
|
||||||
|
|
||||||
|
class Architecture;
|
||||||
|
class CpuState;
|
||||||
|
class DebuggerInterface;
|
||||||
|
class ValueLocation;
|
||||||
|
|
||||||
|
|
||||||
|
class ValueWriter {
|
||||||
|
public:
|
||||||
|
ValueWriter(Architecture* architecture,
|
||||||
|
DebuggerInterface* interface,
|
||||||
|
CpuState* cpuState,
|
||||||
|
thread_id targetThread);
|
||||||
|
// cpuState can be NULL
|
||||||
|
~ValueWriter();
|
||||||
|
|
||||||
|
Architecture* GetArchitecture() const
|
||||||
|
{ return fArchitecture; }
|
||||||
|
|
||||||
|
status_t WriteValue(ValueLocation* location,
|
||||||
|
BVariant& value);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Architecture* fArchitecture;
|
||||||
|
DebuggerInterface* fDebuggerInterface;
|
||||||
|
CpuState* fCpuState;
|
||||||
|
thread_id fTargetThread;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // VALUE_WRITER_H
|
||||||
Reference in New Issue
Block a user