1dda28197Spatrick //===-- RegisterContext.cpp -----------------------------------------------===//
2061da546Spatrick //
3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6061da546Spatrick //
7061da546Spatrick //===----------------------------------------------------------------------===//
8061da546Spatrick
9061da546Spatrick #include "lldb/Target/RegisterContext.h"
10061da546Spatrick #include "lldb/Core/Module.h"
11061da546Spatrick #include "lldb/Core/Value.h"
12061da546Spatrick #include "lldb/Expression/DWARFExpression.h"
13061da546Spatrick #include "lldb/Target/ExecutionContext.h"
14061da546Spatrick #include "lldb/Target/Process.h"
15061da546Spatrick #include "lldb/Target/StackFrame.h"
16061da546Spatrick #include "lldb/Target/Target.h"
17061da546Spatrick #include "lldb/Target/Thread.h"
18061da546Spatrick #include "lldb/Utility/DataExtractor.h"
19061da546Spatrick #include "lldb/Utility/Endian.h"
20061da546Spatrick #include "lldb/Utility/RegisterValue.h"
21061da546Spatrick #include "lldb/Utility/Scalar.h"
22061da546Spatrick
23061da546Spatrick using namespace lldb;
24061da546Spatrick using namespace lldb_private;
25061da546Spatrick
RegisterContext(Thread & thread,uint32_t concrete_frame_idx)26061da546Spatrick RegisterContext::RegisterContext(Thread &thread, uint32_t concrete_frame_idx)
27061da546Spatrick : m_thread(thread), m_concrete_frame_idx(concrete_frame_idx),
28061da546Spatrick m_stop_id(thread.GetProcess()->GetStopID()) {}
29061da546Spatrick
30061da546Spatrick RegisterContext::~RegisterContext() = default;
31061da546Spatrick
InvalidateIfNeeded(bool force)32061da546Spatrick void RegisterContext::InvalidateIfNeeded(bool force) {
33061da546Spatrick ProcessSP process_sp(m_thread.GetProcess());
34061da546Spatrick bool invalidate = force;
35061da546Spatrick uint32_t process_stop_id = UINT32_MAX;
36061da546Spatrick
37061da546Spatrick if (process_sp)
38061da546Spatrick process_stop_id = process_sp->GetStopID();
39061da546Spatrick else
40061da546Spatrick invalidate = true;
41061da546Spatrick
42061da546Spatrick if (!invalidate)
43061da546Spatrick invalidate = process_stop_id != GetStopID();
44061da546Spatrick
45061da546Spatrick if (invalidate) {
46061da546Spatrick InvalidateAllRegisters();
47061da546Spatrick SetStopID(process_stop_id);
48061da546Spatrick }
49061da546Spatrick }
50061da546Spatrick
51061da546Spatrick const RegisterInfo *
GetRegisterInfoByName(llvm::StringRef reg_name,uint32_t start_idx)52061da546Spatrick RegisterContext::GetRegisterInfoByName(llvm::StringRef reg_name,
53061da546Spatrick uint32_t start_idx) {
54061da546Spatrick if (reg_name.empty())
55061da546Spatrick return nullptr;
56061da546Spatrick
57*f6aab3d8Srobert // Generic register names take precedence over specific register names.
58*f6aab3d8Srobert // For example, on x86 we want "sp" to refer to the complete RSP/ESP register
59*f6aab3d8Srobert // rather than the 16-bit SP pseudo-register.
60*f6aab3d8Srobert uint32_t generic_reg = Args::StringToGenericRegister(reg_name);
61*f6aab3d8Srobert if (generic_reg != LLDB_INVALID_REGNUM) {
62*f6aab3d8Srobert const RegisterInfo *reg_info =
63*f6aab3d8Srobert GetRegisterInfo(eRegisterKindGeneric, generic_reg);
64*f6aab3d8Srobert if (reg_info)
65*f6aab3d8Srobert return reg_info;
66*f6aab3d8Srobert }
67*f6aab3d8Srobert
68061da546Spatrick const uint32_t num_registers = GetRegisterCount();
69061da546Spatrick for (uint32_t reg = start_idx; reg < num_registers; ++reg) {
70061da546Spatrick const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
71061da546Spatrick
72be691f3bSpatrick if (reg_name.equals_insensitive(reg_info->name) ||
73be691f3bSpatrick reg_name.equals_insensitive(reg_info->alt_name))
74061da546Spatrick return reg_info;
75061da546Spatrick }
76*f6aab3d8Srobert
77061da546Spatrick return nullptr;
78061da546Spatrick }
79061da546Spatrick
GetRegisterInfo(lldb::RegisterKind kind,uint32_t num)80061da546Spatrick const RegisterInfo *RegisterContext::GetRegisterInfo(lldb::RegisterKind kind,
81061da546Spatrick uint32_t num) {
82061da546Spatrick const uint32_t reg_num = ConvertRegisterKindToRegisterNumber(kind, num);
83061da546Spatrick if (reg_num == LLDB_INVALID_REGNUM)
84061da546Spatrick return nullptr;
85061da546Spatrick return GetRegisterInfoAtIndex(reg_num);
86061da546Spatrick }
87061da546Spatrick
GetRegisterName(uint32_t reg)88061da546Spatrick const char *RegisterContext::GetRegisterName(uint32_t reg) {
89061da546Spatrick const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
90061da546Spatrick if (reg_info)
91061da546Spatrick return reg_info->name;
92061da546Spatrick return nullptr;
93061da546Spatrick }
94061da546Spatrick
GetPC(uint64_t fail_value)95061da546Spatrick uint64_t RegisterContext::GetPC(uint64_t fail_value) {
96061da546Spatrick uint32_t reg = ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric,
97061da546Spatrick LLDB_REGNUM_GENERIC_PC);
98061da546Spatrick uint64_t pc = ReadRegisterAsUnsigned(reg, fail_value);
99061da546Spatrick
100061da546Spatrick if (pc != fail_value) {
101061da546Spatrick TargetSP target_sp = m_thread.CalculateTarget();
102061da546Spatrick if (target_sp) {
103061da546Spatrick Target *target = target_sp.get();
104061da546Spatrick if (target)
105061da546Spatrick pc = target->GetOpcodeLoadAddress(pc, AddressClass::eCode);
106061da546Spatrick }
107061da546Spatrick }
108061da546Spatrick
109061da546Spatrick return pc;
110061da546Spatrick }
111061da546Spatrick
SetPC(uint64_t pc)112061da546Spatrick bool RegisterContext::SetPC(uint64_t pc) {
113061da546Spatrick uint32_t reg = ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric,
114061da546Spatrick LLDB_REGNUM_GENERIC_PC);
115061da546Spatrick bool success = WriteRegisterFromUnsigned(reg, pc);
116061da546Spatrick if (success) {
117061da546Spatrick StackFrameSP frame_sp(
118061da546Spatrick m_thread.GetFrameWithConcreteFrameIndex(m_concrete_frame_idx));
119061da546Spatrick if (frame_sp)
120061da546Spatrick frame_sp->ChangePC(pc);
121061da546Spatrick else
122061da546Spatrick m_thread.ClearStackFrames();
123061da546Spatrick }
124061da546Spatrick return success;
125061da546Spatrick }
126061da546Spatrick
GetPCForSymbolication(Address & address)127be691f3bSpatrick bool RegisterContext::GetPCForSymbolication(Address &address) {
128be691f3bSpatrick addr_t pc = GetPC(LLDB_INVALID_ADDRESS);
129be691f3bSpatrick if (pc == LLDB_INVALID_ADDRESS)
130be691f3bSpatrick return false;
131be691f3bSpatrick TargetSP target_sp = m_thread.CalculateTarget();
132be691f3bSpatrick if (!target_sp.get())
133be691f3bSpatrick return false;
134be691f3bSpatrick
135be691f3bSpatrick if (!BehavesLikeZerothFrame() && pc != 0)
136be691f3bSpatrick pc--;
137be691f3bSpatrick address.SetLoadAddress(pc, target_sp.get());
138be691f3bSpatrick return true;
139be691f3bSpatrick }
140be691f3bSpatrick
SetPC(Address addr)141061da546Spatrick bool RegisterContext::SetPC(Address addr) {
142061da546Spatrick TargetSP target_sp = m_thread.CalculateTarget();
143061da546Spatrick Target *target = target_sp.get();
144061da546Spatrick
145061da546Spatrick lldb::addr_t callAddr = addr.GetCallableLoadAddress(target);
146061da546Spatrick if (callAddr == LLDB_INVALID_ADDRESS)
147061da546Spatrick return false;
148061da546Spatrick
149061da546Spatrick return SetPC(callAddr);
150061da546Spatrick }
151061da546Spatrick
GetSP(uint64_t fail_value)152061da546Spatrick uint64_t RegisterContext::GetSP(uint64_t fail_value) {
153061da546Spatrick uint32_t reg = ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric,
154061da546Spatrick LLDB_REGNUM_GENERIC_SP);
155061da546Spatrick return ReadRegisterAsUnsigned(reg, fail_value);
156061da546Spatrick }
157061da546Spatrick
SetSP(uint64_t sp)158061da546Spatrick bool RegisterContext::SetSP(uint64_t sp) {
159061da546Spatrick uint32_t reg = ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric,
160061da546Spatrick LLDB_REGNUM_GENERIC_SP);
161061da546Spatrick return WriteRegisterFromUnsigned(reg, sp);
162061da546Spatrick }
163061da546Spatrick
GetFP(uint64_t fail_value)164061da546Spatrick uint64_t RegisterContext::GetFP(uint64_t fail_value) {
165061da546Spatrick uint32_t reg = ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric,
166061da546Spatrick LLDB_REGNUM_GENERIC_FP);
167061da546Spatrick return ReadRegisterAsUnsigned(reg, fail_value);
168061da546Spatrick }
169061da546Spatrick
SetFP(uint64_t fp)170061da546Spatrick bool RegisterContext::SetFP(uint64_t fp) {
171061da546Spatrick uint32_t reg = ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric,
172061da546Spatrick LLDB_REGNUM_GENERIC_FP);
173061da546Spatrick return WriteRegisterFromUnsigned(reg, fp);
174061da546Spatrick }
175061da546Spatrick
GetReturnAddress(uint64_t fail_value)176061da546Spatrick uint64_t RegisterContext::GetReturnAddress(uint64_t fail_value) {
177061da546Spatrick uint32_t reg = ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric,
178061da546Spatrick LLDB_REGNUM_GENERIC_RA);
179061da546Spatrick return ReadRegisterAsUnsigned(reg, fail_value);
180061da546Spatrick }
181061da546Spatrick
GetFlags(uint64_t fail_value)182061da546Spatrick uint64_t RegisterContext::GetFlags(uint64_t fail_value) {
183061da546Spatrick uint32_t reg = ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric,
184061da546Spatrick LLDB_REGNUM_GENERIC_FLAGS);
185061da546Spatrick return ReadRegisterAsUnsigned(reg, fail_value);
186061da546Spatrick }
187061da546Spatrick
ReadRegisterAsUnsigned(uint32_t reg,uint64_t fail_value)188061da546Spatrick uint64_t RegisterContext::ReadRegisterAsUnsigned(uint32_t reg,
189061da546Spatrick uint64_t fail_value) {
190061da546Spatrick if (reg != LLDB_INVALID_REGNUM)
191061da546Spatrick return ReadRegisterAsUnsigned(GetRegisterInfoAtIndex(reg), fail_value);
192061da546Spatrick return fail_value;
193061da546Spatrick }
194061da546Spatrick
ReadRegisterAsUnsigned(const RegisterInfo * reg_info,uint64_t fail_value)195061da546Spatrick uint64_t RegisterContext::ReadRegisterAsUnsigned(const RegisterInfo *reg_info,
196061da546Spatrick uint64_t fail_value) {
197061da546Spatrick if (reg_info) {
198061da546Spatrick RegisterValue value;
199061da546Spatrick if (ReadRegister(reg_info, value))
200061da546Spatrick return value.GetAsUInt64();
201061da546Spatrick }
202061da546Spatrick return fail_value;
203061da546Spatrick }
204061da546Spatrick
WriteRegisterFromUnsigned(uint32_t reg,uint64_t uval)205061da546Spatrick bool RegisterContext::WriteRegisterFromUnsigned(uint32_t reg, uint64_t uval) {
206061da546Spatrick if (reg == LLDB_INVALID_REGNUM)
207061da546Spatrick return false;
208061da546Spatrick return WriteRegisterFromUnsigned(GetRegisterInfoAtIndex(reg), uval);
209061da546Spatrick }
210061da546Spatrick
WriteRegisterFromUnsigned(const RegisterInfo * reg_info,uint64_t uval)211061da546Spatrick bool RegisterContext::WriteRegisterFromUnsigned(const RegisterInfo *reg_info,
212061da546Spatrick uint64_t uval) {
213061da546Spatrick if (reg_info) {
214061da546Spatrick RegisterValue value;
215061da546Spatrick if (value.SetUInt(uval, reg_info->byte_size))
216061da546Spatrick return WriteRegister(reg_info, value);
217061da546Spatrick }
218061da546Spatrick return false;
219061da546Spatrick }
220061da546Spatrick
CopyFromRegisterContext(lldb::RegisterContextSP context)221061da546Spatrick bool RegisterContext::CopyFromRegisterContext(lldb::RegisterContextSP context) {
222061da546Spatrick uint32_t num_register_sets = context->GetRegisterSetCount();
223061da546Spatrick // We don't know that two threads have the same register context, so require
224061da546Spatrick // the threads to be the same.
225061da546Spatrick if (context->GetThreadID() != GetThreadID())
226061da546Spatrick return false;
227061da546Spatrick
228061da546Spatrick if (num_register_sets != GetRegisterSetCount())
229061da546Spatrick return false;
230061da546Spatrick
231061da546Spatrick RegisterContextSP frame_zero_context = m_thread.GetRegisterContext();
232061da546Spatrick
233061da546Spatrick for (uint32_t set_idx = 0; set_idx < num_register_sets; ++set_idx) {
234061da546Spatrick const RegisterSet *const reg_set = GetRegisterSet(set_idx);
235061da546Spatrick
236061da546Spatrick const uint32_t num_registers = reg_set->num_registers;
237061da546Spatrick for (uint32_t reg_idx = 0; reg_idx < num_registers; ++reg_idx) {
238061da546Spatrick const uint32_t reg = reg_set->registers[reg_idx];
239061da546Spatrick const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
240061da546Spatrick if (!reg_info || reg_info->value_regs)
241061da546Spatrick continue;
242061da546Spatrick RegisterValue reg_value;
243061da546Spatrick
244061da546Spatrick // If we can reconstruct the register from the frame we are copying from,
245061da546Spatrick // then do so, otherwise use the value from frame 0.
246061da546Spatrick if (context->ReadRegister(reg_info, reg_value)) {
247061da546Spatrick WriteRegister(reg_info, reg_value);
248061da546Spatrick } else if (frame_zero_context->ReadRegister(reg_info, reg_value)) {
249061da546Spatrick WriteRegister(reg_info, reg_value);
250061da546Spatrick }
251061da546Spatrick }
252061da546Spatrick }
253061da546Spatrick return true;
254061da546Spatrick }
255061da546Spatrick
GetThreadID() const256061da546Spatrick lldb::tid_t RegisterContext::GetThreadID() const { return m_thread.GetID(); }
257061da546Spatrick
NumSupportedHardwareBreakpoints()258061da546Spatrick uint32_t RegisterContext::NumSupportedHardwareBreakpoints() { return 0; }
259061da546Spatrick
SetHardwareBreakpoint(lldb::addr_t addr,size_t size)260061da546Spatrick uint32_t RegisterContext::SetHardwareBreakpoint(lldb::addr_t addr,
261061da546Spatrick size_t size) {
262061da546Spatrick return LLDB_INVALID_INDEX32;
263061da546Spatrick }
264061da546Spatrick
265dda28197Spatrick // Used when parsing DWARF and EH frame information and any other object file
266dda28197Spatrick // sections that contain register numbers in them.
267dda28197Spatrick uint32_t
ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,uint32_t num)268dda28197Spatrick RegisterContext::ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
269dda28197Spatrick uint32_t num) {
270dda28197Spatrick const uint32_t num_regs = GetRegisterCount();
271dda28197Spatrick
272dda28197Spatrick assert(kind < kNumRegisterKinds);
273dda28197Spatrick for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) {
274dda28197Spatrick const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_idx);
275dda28197Spatrick
276dda28197Spatrick if (reg_info->kinds[kind] == num)
277dda28197Spatrick return reg_idx;
278dda28197Spatrick }
279dda28197Spatrick
280dda28197Spatrick return LLDB_INVALID_REGNUM;
281dda28197Spatrick }
282dda28197Spatrick
ClearHardwareBreakpoint(uint32_t hw_idx)283061da546Spatrick bool RegisterContext::ClearHardwareBreakpoint(uint32_t hw_idx) { return false; }
284061da546Spatrick
NumSupportedHardwareWatchpoints()285061da546Spatrick uint32_t RegisterContext::NumSupportedHardwareWatchpoints() { return 0; }
286061da546Spatrick
SetHardwareWatchpoint(lldb::addr_t addr,size_t size,bool read,bool write)287061da546Spatrick uint32_t RegisterContext::SetHardwareWatchpoint(lldb::addr_t addr, size_t size,
288061da546Spatrick bool read, bool write) {
289061da546Spatrick return LLDB_INVALID_INDEX32;
290061da546Spatrick }
291061da546Spatrick
ClearHardwareWatchpoint(uint32_t hw_index)292061da546Spatrick bool RegisterContext::ClearHardwareWatchpoint(uint32_t hw_index) {
293061da546Spatrick return false;
294061da546Spatrick }
295061da546Spatrick
HardwareSingleStep(bool enable)296061da546Spatrick bool RegisterContext::HardwareSingleStep(bool enable) { return false; }
297061da546Spatrick
ReadRegisterValueFromMemory(const RegisterInfo * reg_info,lldb::addr_t src_addr,uint32_t src_len,RegisterValue & reg_value)298061da546Spatrick Status RegisterContext::ReadRegisterValueFromMemory(
299061da546Spatrick const RegisterInfo *reg_info, lldb::addr_t src_addr, uint32_t src_len,
300061da546Spatrick RegisterValue ®_value) {
301061da546Spatrick Status error;
302061da546Spatrick if (reg_info == nullptr) {
303061da546Spatrick error.SetErrorString("invalid register info argument.");
304061da546Spatrick return error;
305061da546Spatrick }
306061da546Spatrick
307061da546Spatrick // Moving from addr into a register
308061da546Spatrick //
309061da546Spatrick // Case 1: src_len == dst_len
310061da546Spatrick //
311061da546Spatrick // |AABBCCDD| Address contents
312061da546Spatrick // |AABBCCDD| Register contents
313061da546Spatrick //
314061da546Spatrick // Case 2: src_len > dst_len
315061da546Spatrick //
316061da546Spatrick // Status! (The register should always be big enough to hold the data)
317061da546Spatrick //
318061da546Spatrick // Case 3: src_len < dst_len
319061da546Spatrick //
320061da546Spatrick // |AABB| Address contents
321061da546Spatrick // |AABB0000| Register contents [on little-endian hardware]
322061da546Spatrick // |0000AABB| Register contents [on big-endian hardware]
323061da546Spatrick if (src_len > RegisterValue::kMaxRegisterByteSize) {
324061da546Spatrick error.SetErrorString("register too small to receive memory data");
325061da546Spatrick return error;
326061da546Spatrick }
327061da546Spatrick
328061da546Spatrick const uint32_t dst_len = reg_info->byte_size;
329061da546Spatrick
330061da546Spatrick if (src_len > dst_len) {
331061da546Spatrick error.SetErrorStringWithFormat(
332061da546Spatrick "%u bytes is too big to store in register %s (%u bytes)", src_len,
333061da546Spatrick reg_info->name, dst_len);
334061da546Spatrick return error;
335061da546Spatrick }
336061da546Spatrick
337061da546Spatrick ProcessSP process_sp(m_thread.GetProcess());
338061da546Spatrick if (process_sp) {
339061da546Spatrick uint8_t src[RegisterValue::kMaxRegisterByteSize];
340061da546Spatrick
341061da546Spatrick // Read the memory
342061da546Spatrick const uint32_t bytes_read =
343061da546Spatrick process_sp->ReadMemory(src_addr, src, src_len, error);
344061da546Spatrick
345061da546Spatrick // Make sure the memory read succeeded...
346061da546Spatrick if (bytes_read != src_len) {
347061da546Spatrick if (error.Success()) {
348061da546Spatrick // This might happen if we read _some_ bytes but not all
349061da546Spatrick error.SetErrorStringWithFormat("read %u of %u bytes", bytes_read,
350061da546Spatrick src_len);
351061da546Spatrick }
352061da546Spatrick return error;
353061da546Spatrick }
354061da546Spatrick
355061da546Spatrick // We now have a memory buffer that contains the part or all of the
356061da546Spatrick // register value. Set the register value using this memory data.
357061da546Spatrick // TODO: we might need to add a parameter to this function in case the byte
358061da546Spatrick // order of the memory data doesn't match the process. For now we are
359061da546Spatrick // assuming they are the same.
360*f6aab3d8Srobert reg_value.SetFromMemoryData(*reg_info, src, src_len,
361061da546Spatrick process_sp->GetByteOrder(), error);
362061da546Spatrick } else
363061da546Spatrick error.SetErrorString("invalid process");
364061da546Spatrick
365061da546Spatrick return error;
366061da546Spatrick }
367061da546Spatrick
WriteRegisterValueToMemory(const RegisterInfo * reg_info,lldb::addr_t dst_addr,uint32_t dst_len,const RegisterValue & reg_value)368061da546Spatrick Status RegisterContext::WriteRegisterValueToMemory(
369061da546Spatrick const RegisterInfo *reg_info, lldb::addr_t dst_addr, uint32_t dst_len,
370061da546Spatrick const RegisterValue ®_value) {
371061da546Spatrick Status error;
372061da546Spatrick ProcessSP process_sp(m_thread.GetProcess());
373*f6aab3d8Srobert
374*f6aab3d8Srobert if (!process_sp) {
375*f6aab3d8Srobert error.SetErrorString("invalid process");
376*f6aab3d8Srobert return error;
377*f6aab3d8Srobert }
378*f6aab3d8Srobert
379*f6aab3d8Srobert if (reg_info == nullptr) {
380*f6aab3d8Srobert error.SetErrorString("Invalid register info argument.");
381*f6aab3d8Srobert return error;
382*f6aab3d8Srobert }
383061da546Spatrick
384061da546Spatrick // TODO: we might need to add a parameter to this function in case the byte
385061da546Spatrick // order of the memory data doesn't match the process. For now we are
386061da546Spatrick // assuming they are the same.
387*f6aab3d8Srobert uint8_t dst[RegisterValue::kMaxRegisterByteSize];
388061da546Spatrick const uint32_t bytes_copied = reg_value.GetAsMemoryData(
389*f6aab3d8Srobert *reg_info, dst, dst_len, process_sp->GetByteOrder(), error);
390061da546Spatrick
391061da546Spatrick if (error.Success()) {
392061da546Spatrick if (bytes_copied == 0) {
393061da546Spatrick error.SetErrorString("byte copy failed.");
394061da546Spatrick } else {
395061da546Spatrick const uint32_t bytes_written =
396061da546Spatrick process_sp->WriteMemory(dst_addr, dst, bytes_copied, error);
397061da546Spatrick if (bytes_written != bytes_copied) {
398061da546Spatrick if (error.Success()) {
399061da546Spatrick // This might happen if we read _some_ bytes but not all
400061da546Spatrick error.SetErrorStringWithFormat("only wrote %u of %u bytes",
401061da546Spatrick bytes_written, bytes_copied);
402061da546Spatrick }
403061da546Spatrick }
404061da546Spatrick }
405061da546Spatrick }
406061da546Spatrick
407061da546Spatrick return error;
408061da546Spatrick }
409061da546Spatrick
GetByteOrder()410dda28197Spatrick lldb::ByteOrder RegisterContext::GetByteOrder() {
411dda28197Spatrick // Get the target process whose privileged thread was used for the register
412dda28197Spatrick // read.
413dda28197Spatrick lldb::ByteOrder byte_order = lldb::eByteOrderInvalid;
414dda28197Spatrick lldb_private::Process *process = CalculateProcess().get();
415dda28197Spatrick
416dda28197Spatrick if (process)
417dda28197Spatrick byte_order = process->GetByteOrder();
418dda28197Spatrick return byte_order;
419dda28197Spatrick }
420dda28197Spatrick
ReadAllRegisterValues(lldb_private::RegisterCheckpoint & reg_checkpoint)421061da546Spatrick bool RegisterContext::ReadAllRegisterValues(
422061da546Spatrick lldb_private::RegisterCheckpoint ®_checkpoint) {
423061da546Spatrick return ReadAllRegisterValues(reg_checkpoint.GetData());
424061da546Spatrick }
425061da546Spatrick
WriteAllRegisterValues(const lldb_private::RegisterCheckpoint & reg_checkpoint)426061da546Spatrick bool RegisterContext::WriteAllRegisterValues(
427061da546Spatrick const lldb_private::RegisterCheckpoint ®_checkpoint) {
428061da546Spatrick return WriteAllRegisterValues(reg_checkpoint.GetData());
429061da546Spatrick }
430061da546Spatrick
CalculateTarget()431061da546Spatrick TargetSP RegisterContext::CalculateTarget() {
432061da546Spatrick return m_thread.CalculateTarget();
433061da546Spatrick }
434061da546Spatrick
CalculateProcess()435061da546Spatrick ProcessSP RegisterContext::CalculateProcess() {
436061da546Spatrick return m_thread.CalculateProcess();
437061da546Spatrick }
438061da546Spatrick
CalculateThread()439061da546Spatrick ThreadSP RegisterContext::CalculateThread() {
440061da546Spatrick return m_thread.shared_from_this();
441061da546Spatrick }
442061da546Spatrick
CalculateStackFrame()443061da546Spatrick StackFrameSP RegisterContext::CalculateStackFrame() {
444061da546Spatrick // Register contexts might belong to many frames if we have inlined functions
445061da546Spatrick // inside a frame since all inlined functions share the same registers, so we
446061da546Spatrick // can't definitively say which frame we come from...
447061da546Spatrick return StackFrameSP();
448061da546Spatrick }
449061da546Spatrick
CalculateExecutionContext(ExecutionContext & exe_ctx)450061da546Spatrick void RegisterContext::CalculateExecutionContext(ExecutionContext &exe_ctx) {
451061da546Spatrick m_thread.CalculateExecutionContext(exe_ctx);
452061da546Spatrick }
453061da546Spatrick
ConvertBetweenRegisterKinds(lldb::RegisterKind source_rk,uint32_t source_regnum,lldb::RegisterKind target_rk,uint32_t & target_regnum)454061da546Spatrick bool RegisterContext::ConvertBetweenRegisterKinds(lldb::RegisterKind source_rk,
455061da546Spatrick uint32_t source_regnum,
456061da546Spatrick lldb::RegisterKind target_rk,
457061da546Spatrick uint32_t &target_regnum) {
458061da546Spatrick const uint32_t num_registers = GetRegisterCount();
459061da546Spatrick for (uint32_t reg = 0; reg < num_registers; ++reg) {
460061da546Spatrick const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
461061da546Spatrick
462061da546Spatrick if (reg_info->kinds[source_rk] == source_regnum) {
463061da546Spatrick target_regnum = reg_info->kinds[target_rk];
464061da546Spatrick return (target_regnum != LLDB_INVALID_REGNUM);
465061da546Spatrick }
466061da546Spatrick }
467061da546Spatrick return false;
468061da546Spatrick }
469