-
-
Notifications
You must be signed in to change notification settings - Fork 338
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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.
- Loading branch information
Showing
3 changed files
with
181 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |