Skip to content

Commit

Permalink
Debugger: Add ValueWriter support class.
Browse files Browse the repository at this point in the history
- Given a value + corresponding location description, this handles
  ensuring that the data ends up in the appropriate locations in the
  target team.
  • Loading branch information
anevilyak committed Jul 18, 2015
1 parent 5b026a2 commit 568f200
Show file tree
Hide file tree
Showing 3 changed files with 181 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/apps/debugger/Jamfile
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,7 @@ local sources =
ValueNode.cpp
ValueNodeContainer.cpp
ValueNodeManager.cpp
ValueWriter.cpp

# value/type_handlers
BListTypeHandler.cpp
Expand Down
135 changes: 135 additions & 0 deletions src/apps/debugger/value/ValueWriter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
/*
* Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de.
* Copyright 2013-2015, Rene Gollent, rene@gollent.com.
* 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;
}
45 changes: 45 additions & 0 deletions src/apps/debugger/value/ValueWriter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright 2015, Rene Gollent, rene@gollent.com.
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* 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

0 comments on commit 568f200

Please sign in to comment.