xref: /openbsd-src/gnu/llvm/lldb/source/Target/RegisterContext.cpp (revision f6aab3d83b51b91c24247ad2c2573574de475a82)
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 &reg_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 &reg_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 &reg_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 &reg_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