2 * Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Copyright 2013-2015, Rene Gollent, rene@gollent.com.
4 * Distributed under the terms of the MIT License.
8 #include "ValueWriter.h"
10 #include "Architecture.h"
11 #include "BitBuffer.h"
13 #include "DebuggerInterface.h"
15 #include "TeamMemory.h"
17 #include "ValueLocation.h"
20 ValueWriter::ValueWriter(Architecture
* architecture
,
21 DebuggerInterface
* interface
, CpuState
* cpuState
, thread_id targetThread
)
23 fArchitecture(architecture
),
24 fDebuggerInterface(interface
),
26 fTargetThread(targetThread
)
28 fArchitecture
->AcquireReference();
29 fDebuggerInterface
->AcquireReference();
30 if (fCpuState
!= NULL
)
31 fCpuState
->AcquireReference();
35 ValueWriter::~ValueWriter()
37 fArchitecture
->ReleaseReference();
38 fDebuggerInterface
->ReleaseReference();
39 if (fCpuState
!= NULL
)
40 fCpuState
->ReleaseReference();
45 ValueWriter::WriteValue(ValueLocation
* location
, BVariant
& value
)
47 if (!location
->IsWritable())
50 int32 count
= location
->CountPieces();
51 if (fCpuState
== NULL
) {
52 for (int32 i
= 0; i
< count
; i
++) {
53 const ValuePieceLocation piece
= location
->PieceAt(i
);
54 if (piece
.type
== VALUE_PIECE_LOCATION_REGISTER
) {
55 TRACE_LOCALS(" -> asked to write value with register piece, "
56 "but no CPU state to write to.\n");
62 bool cpuStateWriteNeeded
= false;
63 size_t byteOffset
= 0;
64 bool bigEndian
= fArchitecture
->IsBigEndian();
65 const Register
* registers
= fArchitecture
->Registers();
66 for (int32 i
= 0; i
< count
; i
++) {
67 ValuePieceLocation piece
= location
->PieceAt(
68 bigEndian
? i
: count
- i
- 1);
69 uint32 bytesToWrite
= piece
.size
;
71 uint8
* targetData
= (uint8
*)value
.Bytes() + byteOffset
;
74 case VALUE_PIECE_LOCATION_MEMORY
:
76 target_addr_t address
= piece
.address
;
78 TRACE_LOCALS(" piece %" B_PRId32
": memory address: %#"
79 B_PRIx64
", bits: %" B_PRIu32
"\n", i
, address
,
82 ssize_t bytesWritten
= fDebuggerInterface
->WriteMemory(address
,
83 targetData
, bytesToWrite
);
87 if ((uint32
)bytesWritten
!= bytesToWrite
)
92 case VALUE_PIECE_LOCATION_REGISTER
:
94 TRACE_LOCALS(" piece %" B_PRId32
": register: %" B_PRIu32
95 ", bits: %" B_PRIu64
"\n", i
, piece
.reg
, piece
.bitSize
);
97 const Register
* target
= registers
+ piece
.reg
;
99 switch (bytesToWrite
) {
101 pieceValue
.SetTo(*(uint8
*)targetData
);
104 pieceValue
.SetTo(*(uint16
*)targetData
);
107 pieceValue
.SetTo(*(uint32
*)targetData
);
110 pieceValue
.SetTo(*(uint64
*)targetData
);
113 TRACE_LOCALS("Asked to write unsupported piece size %"
114 B_PRId32
" to register\n", bytesToWrite
);
115 return B_UNSUPPORTED
;
118 if (!fCpuState
->SetRegisterValue(target
, pieceValue
))
121 cpuStateWriteNeeded
= true;
125 return B_UNSUPPORTED
;
128 byteOffset
+= bytesToWrite
;
131 if (cpuStateWriteNeeded
)
132 return fDebuggerInterface
->SetCpuState(fTargetThread
, fCpuState
);