1254721Semaste//===-- RegisterContext.cpp -------------------------------------*- C++ -*-===//
2254721Semaste//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6254721Semaste//
7254721Semaste//===----------------------------------------------------------------------===//
8254721Semaste
9254721Semaste#include "lldb/Target/RegisterContext.h"
10314564Sdim#include "lldb/Core/Module.h"
11314564Sdim#include "lldb/Core/Value.h"
12314564Sdim#include "lldb/Expression/DWARFExpression.h"
13254721Semaste#include "lldb/Target/ExecutionContext.h"
14314564Sdim#include "lldb/Target/Process.h"
15254721Semaste#include "lldb/Target/StackFrame.h"
16314564Sdim#include "lldb/Target/Target.h"
17254721Semaste#include "lldb/Target/Thread.h"
18321369Sdim#include "lldb/Utility/DataExtractor.h"
19321369Sdim#include "lldb/Utility/Endian.h"
20344779Sdim#include "lldb/Utility/RegisterValue.h"
21344779Sdim#include "lldb/Utility/Scalar.h"
22254721Semaste
23254721Semasteusing namespace lldb;
24254721Semasteusing namespace lldb_private;
25254721Semaste
26314564SdimRegisterContext::RegisterContext(Thread &thread, uint32_t concrete_frame_idx)
27314564Sdim    : m_thread(thread), m_concrete_frame_idx(concrete_frame_idx),
28314564Sdim      m_stop_id(thread.GetProcess()->GetStopID()) {}
29254721Semaste
30309124SdimRegisterContext::~RegisterContext() = default;
31254721Semaste
32314564Sdimvoid RegisterContext::InvalidateIfNeeded(bool force) {
33314564Sdim  ProcessSP process_sp(m_thread.GetProcess());
34314564Sdim  bool invalidate = force;
35314564Sdim  uint32_t process_stop_id = UINT32_MAX;
36254721Semaste
37314564Sdim  if (process_sp)
38314564Sdim    process_stop_id = process_sp->GetStopID();
39314564Sdim  else
40314564Sdim    invalidate = true;
41254721Semaste
42314564Sdim  if (!invalidate)
43314564Sdim    invalidate = process_stop_id != GetStopID();
44314564Sdim
45314564Sdim  if (invalidate) {
46314564Sdim    InvalidateAllRegisters();
47314564Sdim    SetStopID(process_stop_id);
48314564Sdim  }
49254721Semaste}
50254721Semaste
51254721Semasteconst RegisterInfo *
52314564SdimRegisterContext::GetRegisterInfoByName(llvm::StringRef reg_name,
53314564Sdim                                       uint32_t start_idx) {
54314564Sdim  if (reg_name.empty())
55314564Sdim    return nullptr;
56254721Semaste
57314564Sdim  const uint32_t num_registers = GetRegisterCount();
58314564Sdim  for (uint32_t reg = start_idx; reg < num_registers; ++reg) {
59314564Sdim    const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
60314564Sdim
61314564Sdim    if (reg_name.equals_lower(reg_info->name) ||
62314564Sdim        reg_name.equals_lower(reg_info->alt_name))
63314564Sdim      return reg_info;
64314564Sdim  }
65314564Sdim  return nullptr;
66254721Semaste}
67254721Semaste
68309124Sdimuint32_t
69314564SdimRegisterContext::UpdateDynamicRegisterSize(const lldb_private::ArchSpec &arch,
70314564Sdim                                           RegisterInfo *reg_info) {
71314564Sdim  ExecutionContext exe_ctx(CalculateThread());
72309124Sdim
73314564Sdim  // In MIPS, the floating point registers size is depends on FR bit of SR
74341825Sdim  // register. if SR.FR  == 1 then all floating point registers are 64 bits.
75314564Sdim  // else they are all 32 bits.
76309124Sdim
77314564Sdim  int expr_result;
78314564Sdim  uint32_t addr_size = arch.GetAddressByteSize();
79314564Sdim  const uint8_t *dwarf_opcode_ptr = reg_info->dynamic_size_dwarf_expr_bytes;
80314564Sdim  const size_t dwarf_opcode_len = reg_info->dynamic_size_dwarf_len;
81314564Sdim
82314564Sdim  DataExtractor dwarf_data(dwarf_opcode_ptr, dwarf_opcode_len,
83314564Sdim                           arch.GetByteOrder(), addr_size);
84314564Sdim  ModuleSP opcode_ctx;
85360784Sdim  DWARFExpression dwarf_expr(opcode_ctx, dwarf_data, nullptr);
86314564Sdim  Value result;
87321369Sdim  Status error;
88327952Sdim  if (dwarf_expr.Evaluate(&exe_ctx, this, opcode_ctx, dwarf_data, nullptr,
89360784Sdim                          eRegisterKindDWARF, nullptr, nullptr, result,
90360784Sdim                          &error)) {
91314564Sdim    expr_result = result.GetScalar().SInt(-1);
92314564Sdim    switch (expr_result) {
93314564Sdim    case 0:
94314564Sdim      return 4;
95314564Sdim    case 1:
96314564Sdim      return 8;
97314564Sdim    default:
98314564Sdim      return reg_info->byte_size;
99309124Sdim    }
100314564Sdim  } else {
101314564Sdim    printf("Error executing DwarfExpression::Evaluate %s\n", error.AsCString());
102314564Sdim    return reg_info->byte_size;
103314564Sdim  }
104309124Sdim}
105309124Sdim
106314564Sdimconst RegisterInfo *RegisterContext::GetRegisterInfo(lldb::RegisterKind kind,
107314564Sdim                                                     uint32_t num) {
108314564Sdim  const uint32_t reg_num = ConvertRegisterKindToRegisterNumber(kind, num);
109314564Sdim  if (reg_num == LLDB_INVALID_REGNUM)
110314564Sdim    return nullptr;
111314564Sdim  return GetRegisterInfoAtIndex(reg_num);
112258054Semaste}
113258054Semaste
114314564Sdimconst char *RegisterContext::GetRegisterName(uint32_t reg) {
115314564Sdim  const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
116314564Sdim  if (reg_info)
117314564Sdim    return reg_info->name;
118314564Sdim  return nullptr;
119254721Semaste}
120254721Semaste
121314564Sdimuint64_t RegisterContext::GetPC(uint64_t fail_value) {
122314564Sdim  uint32_t reg = ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric,
123314564Sdim                                                     LLDB_REGNUM_GENERIC_PC);
124314564Sdim  uint64_t pc = ReadRegisterAsUnsigned(reg, fail_value);
125296417Sdim
126314564Sdim  if (pc != fail_value) {
127314564Sdim    TargetSP target_sp = m_thread.CalculateTarget();
128314564Sdim    if (target_sp) {
129314564Sdim      Target *target = target_sp.get();
130314564Sdim      if (target)
131341825Sdim        pc = target->GetOpcodeLoadAddress(pc, AddressClass::eCode);
132296417Sdim    }
133314564Sdim  }
134296417Sdim
135314564Sdim  return pc;
136254721Semaste}
137254721Semaste
138314564Sdimbool RegisterContext::SetPC(uint64_t pc) {
139314564Sdim  uint32_t reg = ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric,
140314564Sdim                                                     LLDB_REGNUM_GENERIC_PC);
141314564Sdim  bool success = WriteRegisterFromUnsigned(reg, pc);
142314564Sdim  if (success) {
143314564Sdim    StackFrameSP frame_sp(
144314564Sdim        m_thread.GetFrameWithConcreteFrameIndex(m_concrete_frame_idx));
145314564Sdim    if (frame_sp)
146314564Sdim      frame_sp->ChangePC(pc);
147314564Sdim    else
148314564Sdim      m_thread.ClearStackFrames();
149314564Sdim  }
150314564Sdim  return success;
151254721Semaste}
152254721Semaste
153314564Sdimbool RegisterContext::SetPC(Address addr) {
154314564Sdim  TargetSP target_sp = m_thread.CalculateTarget();
155314564Sdim  Target *target = target_sp.get();
156258054Semaste
157314564Sdim  lldb::addr_t callAddr = addr.GetCallableLoadAddress(target);
158314564Sdim  if (callAddr == LLDB_INVALID_ADDRESS)
159314564Sdim    return false;
160258054Semaste
161314564Sdim  return SetPC(callAddr);
162258054Semaste}
163258054Semaste
164314564Sdimuint64_t RegisterContext::GetSP(uint64_t fail_value) {
165314564Sdim  uint32_t reg = ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric,
166314564Sdim                                                     LLDB_REGNUM_GENERIC_SP);
167314564Sdim  return ReadRegisterAsUnsigned(reg, fail_value);
168254721Semaste}
169254721Semaste
170314564Sdimbool RegisterContext::SetSP(uint64_t sp) {
171314564Sdim  uint32_t reg = ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric,
172314564Sdim                                                     LLDB_REGNUM_GENERIC_SP);
173314564Sdim  return WriteRegisterFromUnsigned(reg, sp);
174254721Semaste}
175254721Semaste
176314564Sdimuint64_t RegisterContext::GetFP(uint64_t fail_value) {
177314564Sdim  uint32_t reg = ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric,
178314564Sdim                                                     LLDB_REGNUM_GENERIC_FP);
179314564Sdim  return ReadRegisterAsUnsigned(reg, fail_value);
180254721Semaste}
181254721Semaste
182314564Sdimbool RegisterContext::SetFP(uint64_t fp) {
183314564Sdim  uint32_t reg = ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric,
184314564Sdim                                                     LLDB_REGNUM_GENERIC_FP);
185314564Sdim  return WriteRegisterFromUnsigned(reg, fp);
186254721Semaste}
187254721Semaste
188314564Sdimuint64_t RegisterContext::GetReturnAddress(uint64_t fail_value) {
189314564Sdim  uint32_t reg = ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric,
190314564Sdim                                                     LLDB_REGNUM_GENERIC_RA);
191314564Sdim  return ReadRegisterAsUnsigned(reg, fail_value);
192254721Semaste}
193254721Semaste
194314564Sdimuint64_t RegisterContext::GetFlags(uint64_t fail_value) {
195314564Sdim  uint32_t reg = ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric,
196314564Sdim                                                     LLDB_REGNUM_GENERIC_FLAGS);
197314564Sdim  return ReadRegisterAsUnsigned(reg, fail_value);
198254721Semaste}
199254721Semaste
200314564Sdimuint64_t RegisterContext::ReadRegisterAsUnsigned(uint32_t reg,
201314564Sdim                                                 uint64_t fail_value) {
202314564Sdim  if (reg != LLDB_INVALID_REGNUM)
203314564Sdim    return ReadRegisterAsUnsigned(GetRegisterInfoAtIndex(reg), fail_value);
204314564Sdim  return fail_value;
205254721Semaste}
206254721Semaste
207314564Sdimuint64_t RegisterContext::ReadRegisterAsUnsigned(const RegisterInfo *reg_info,
208314564Sdim                                                 uint64_t fail_value) {
209314564Sdim  if (reg_info) {
210314564Sdim    RegisterValue value;
211314564Sdim    if (ReadRegister(reg_info, value))
212314564Sdim      return value.GetAsUInt64();
213314564Sdim  }
214314564Sdim  return fail_value;
215254721Semaste}
216254721Semaste
217314564Sdimbool RegisterContext::WriteRegisterFromUnsigned(uint32_t reg, uint64_t uval) {
218314564Sdim  if (reg == LLDB_INVALID_REGNUM)
219314564Sdim    return false;
220314564Sdim  return WriteRegisterFromUnsigned(GetRegisterInfoAtIndex(reg), uval);
221254721Semaste}
222254721Semaste
223314564Sdimbool RegisterContext::WriteRegisterFromUnsigned(const RegisterInfo *reg_info,
224314564Sdim                                                uint64_t uval) {
225314564Sdim  if (reg_info) {
226314564Sdim    RegisterValue value;
227314564Sdim    if (value.SetUInt(uval, reg_info->byte_size))
228314564Sdim      return WriteRegister(reg_info, value);
229314564Sdim  }
230314564Sdim  return false;
231254721Semaste}
232254721Semaste
233314564Sdimbool RegisterContext::CopyFromRegisterContext(lldb::RegisterContextSP context) {
234314564Sdim  uint32_t num_register_sets = context->GetRegisterSetCount();
235314564Sdim  // We don't know that two threads have the same register context, so require
236314564Sdim  // the threads to be the same.
237314564Sdim  if (context->GetThreadID() != GetThreadID())
238314564Sdim    return false;
239314564Sdim
240314564Sdim  if (num_register_sets != GetRegisterSetCount())
241314564Sdim    return false;
242314564Sdim
243314564Sdim  RegisterContextSP frame_zero_context = m_thread.GetRegisterContext();
244314564Sdim
245314564Sdim  for (uint32_t set_idx = 0; set_idx < num_register_sets; ++set_idx) {
246314564Sdim    const RegisterSet *const reg_set = GetRegisterSet(set_idx);
247314564Sdim
248314564Sdim    const uint32_t num_registers = reg_set->num_registers;
249314564Sdim    for (uint32_t reg_idx = 0; reg_idx < num_registers; ++reg_idx) {
250314564Sdim      const uint32_t reg = reg_set->registers[reg_idx];
251314564Sdim      const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
252314564Sdim      if (!reg_info || reg_info->value_regs)
253314564Sdim        continue;
254314564Sdim      RegisterValue reg_value;
255314564Sdim
256314564Sdim      // If we can reconstruct the register from the frame we are copying from,
257341825Sdim      // then do so, otherwise use the value from frame 0.
258314564Sdim      if (context->ReadRegister(reg_info, reg_value)) {
259314564Sdim        WriteRegister(reg_info, reg_value);
260314564Sdim      } else if (frame_zero_context->ReadRegister(reg_info, reg_value)) {
261314564Sdim        WriteRegister(reg_info, reg_value);
262314564Sdim      }
263254721Semaste    }
264314564Sdim  }
265314564Sdim  return true;
266254721Semaste}
267254721Semaste
268314564Sdimlldb::tid_t RegisterContext::GetThreadID() const { return m_thread.GetID(); }
269254721Semaste
270314564Sdimuint32_t RegisterContext::NumSupportedHardwareBreakpoints() { return 0; }
271254721Semaste
272314564Sdimuint32_t RegisterContext::SetHardwareBreakpoint(lldb::addr_t addr,
273314564Sdim                                                size_t size) {
274314564Sdim  return LLDB_INVALID_INDEX32;
275254721Semaste}
276254721Semaste
277314564Sdimbool RegisterContext::ClearHardwareBreakpoint(uint32_t hw_idx) { return false; }
278254721Semaste
279314564Sdimuint32_t RegisterContext::NumSupportedHardwareWatchpoints() { return 0; }
280254721Semaste
281314564Sdimuint32_t RegisterContext::SetHardwareWatchpoint(lldb::addr_t addr, size_t size,
282314564Sdim                                                bool read, bool write) {
283314564Sdim  return LLDB_INVALID_INDEX32;
284254721Semaste}
285254721Semaste
286314564Sdimbool RegisterContext::ClearHardwareWatchpoint(uint32_t hw_index) {
287314564Sdim  return false;
288254721Semaste}
289254721Semaste
290314564Sdimbool RegisterContext::HardwareSingleStep(bool enable) { return false; }
291254721Semaste
292321369SdimStatus RegisterContext::ReadRegisterValueFromMemory(
293321369Sdim    const RegisterInfo *reg_info, lldb::addr_t src_addr, uint32_t src_len,
294321369Sdim    RegisterValue &reg_value) {
295321369Sdim  Status error;
296314564Sdim  if (reg_info == nullptr) {
297314564Sdim    error.SetErrorString("invalid register info argument.");
298314564Sdim    return error;
299314564Sdim  }
300254721Semaste
301314564Sdim  // Moving from addr into a register
302314564Sdim  //
303314564Sdim  // Case 1: src_len == dst_len
304314564Sdim  //
305314564Sdim  //   |AABBCCDD| Address contents
306314564Sdim  //   |AABBCCDD| Register contents
307314564Sdim  //
308314564Sdim  // Case 2: src_len > dst_len
309314564Sdim  //
310321369Sdim  //   Status!  (The register should always be big enough to hold the data)
311314564Sdim  //
312314564Sdim  // Case 3: src_len < dst_len
313314564Sdim  //
314314564Sdim  //   |AABB| Address contents
315314564Sdim  //   |AABB0000| Register contents [on little-endian hardware]
316314564Sdim  //   |0000AABB| Register contents [on big-endian hardware]
317314564Sdim  if (src_len > RegisterValue::kMaxRegisterByteSize) {
318314564Sdim    error.SetErrorString("register too small to receive memory data");
319314564Sdim    return error;
320314564Sdim  }
321254721Semaste
322314564Sdim  const uint32_t dst_len = reg_info->byte_size;
323314564Sdim
324314564Sdim  if (src_len > dst_len) {
325314564Sdim    error.SetErrorStringWithFormat(
326314564Sdim        "%u bytes is too big to store in register %s (%u bytes)", src_len,
327314564Sdim        reg_info->name, dst_len);
328314564Sdim    return error;
329314564Sdim  }
330314564Sdim
331314564Sdim  ProcessSP process_sp(m_thread.GetProcess());
332314564Sdim  if (process_sp) {
333314564Sdim    uint8_t src[RegisterValue::kMaxRegisterByteSize];
334314564Sdim
335314564Sdim    // Read the memory
336314564Sdim    const uint32_t bytes_read =
337314564Sdim        process_sp->ReadMemory(src_addr, src, src_len, error);
338314564Sdim
339314564Sdim    // Make sure the memory read succeeded...
340314564Sdim    if (bytes_read != src_len) {
341314564Sdim      if (error.Success()) {
342314564Sdim        // This might happen if we read _some_ bytes but not all
343314564Sdim        error.SetErrorStringWithFormat("read %u of %u bytes", bytes_read,
344314564Sdim                                       src_len);
345314564Sdim      }
346314564Sdim      return error;
347254721Semaste    }
348254721Semaste
349341825Sdim    // We now have a memory buffer that contains the part or all of the
350341825Sdim    // register value. Set the register value using this memory data.
351314564Sdim    // TODO: we might need to add a parameter to this function in case the byte
352314564Sdim    // order of the memory data doesn't match the process. For now we are
353341825Sdim    // assuming they are the same.
354314564Sdim    reg_value.SetFromMemoryData(reg_info, src, src_len,
355314564Sdim                                process_sp->GetByteOrder(), error);
356314564Sdim  } else
357314564Sdim    error.SetErrorString("invalid process");
358314564Sdim
359314564Sdim  return error;
360254721Semaste}
361254721Semaste
362321369SdimStatus RegisterContext::WriteRegisterValueToMemory(
363314564Sdim    const RegisterInfo *reg_info, lldb::addr_t dst_addr, uint32_t dst_len,
364314564Sdim    const RegisterValue &reg_value) {
365314564Sdim  uint8_t dst[RegisterValue::kMaxRegisterByteSize];
366254721Semaste
367321369Sdim  Status error;
368254721Semaste
369314564Sdim  ProcessSP process_sp(m_thread.GetProcess());
370314564Sdim  if (process_sp) {
371254721Semaste
372314564Sdim    // TODO: we might need to add a parameter to this function in case the byte
373314564Sdim    // order of the memory data doesn't match the process. For now we are
374341825Sdim    // assuming they are the same.
375254721Semaste
376314564Sdim    const uint32_t bytes_copied = reg_value.GetAsMemoryData(
377314564Sdim        reg_info, dst, dst_len, process_sp->GetByteOrder(), error);
378254721Semaste
379314564Sdim    if (error.Success()) {
380314564Sdim      if (bytes_copied == 0) {
381314564Sdim        error.SetErrorString("byte copy failed.");
382314564Sdim      } else {
383314564Sdim        const uint32_t bytes_written =
384314564Sdim            process_sp->WriteMemory(dst_addr, dst, bytes_copied, error);
385314564Sdim        if (bytes_written != bytes_copied) {
386314564Sdim          if (error.Success()) {
387314564Sdim            // This might happen if we read _some_ bytes but not all
388314564Sdim            error.SetErrorStringWithFormat("only wrote %u of %u bytes",
389314564Sdim                                           bytes_written, bytes_copied);
390314564Sdim          }
391254721Semaste        }
392314564Sdim      }
393254721Semaste    }
394314564Sdim  } else
395314564Sdim    error.SetErrorString("invalid process");
396254721Semaste
397314564Sdim  return error;
398254721Semaste}
399254721Semaste
400314564Sdimbool RegisterContext::ReadAllRegisterValues(
401314564Sdim    lldb_private::RegisterCheckpoint &reg_checkpoint) {
402314564Sdim  return ReadAllRegisterValues(reg_checkpoint.GetData());
403258884Semaste}
404258884Semaste
405314564Sdimbool RegisterContext::WriteAllRegisterValues(
406314564Sdim    const lldb_private::RegisterCheckpoint &reg_checkpoint) {
407314564Sdim  return WriteAllRegisterValues(reg_checkpoint.GetData());
408258884Semaste}
409258884Semaste
410314564SdimTargetSP RegisterContext::CalculateTarget() {
411314564Sdim  return m_thread.CalculateTarget();
412254721Semaste}
413254721Semaste
414314564SdimProcessSP RegisterContext::CalculateProcess() {
415314564Sdim  return m_thread.CalculateProcess();
416254721Semaste}
417254721Semaste
418314564SdimThreadSP RegisterContext::CalculateThread() {
419314564Sdim  return m_thread.shared_from_this();
420254721Semaste}
421254721Semaste
422314564SdimStackFrameSP RegisterContext::CalculateStackFrame() {
423341825Sdim  // Register contexts might belong to many frames if we have inlined functions
424341825Sdim  // inside a frame since all inlined functions share the same registers, so we
425341825Sdim  // can't definitively say which frame we come from...
426314564Sdim  return StackFrameSP();
427254721Semaste}
428254721Semaste
429314564Sdimvoid RegisterContext::CalculateExecutionContext(ExecutionContext &exe_ctx) {
430314564Sdim  m_thread.CalculateExecutionContext(exe_ctx);
431254721Semaste}
432254721Semaste
433314564Sdimbool RegisterContext::ConvertBetweenRegisterKinds(lldb::RegisterKind source_rk,
434314564Sdim                                                  uint32_t source_regnum,
435314564Sdim                                                  lldb::RegisterKind target_rk,
436314564Sdim                                                  uint32_t &target_regnum) {
437314564Sdim  const uint32_t num_registers = GetRegisterCount();
438314564Sdim  for (uint32_t reg = 0; reg < num_registers; ++reg) {
439314564Sdim    const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
440254721Semaste
441314564Sdim    if (reg_info->kinds[source_rk] == source_regnum) {
442314564Sdim      target_regnum = reg_info->kinds[target_rk];
443314564Sdim      return (target_regnum != LLDB_INVALID_REGNUM);
444254721Semaste    }
445314564Sdim  }
446314564Sdim  return false;
447254721Semaste}
448