LLDB  mainline
RegisterContextPOSIX_arm64.cpp
Go to the documentation of this file.
1 //===-- RegisterContextPOSIX_arm64.cpp --------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include <cstring>
10 #include <errno.h>
11 #include <stdint.h>
12 
13 #include "lldb/Target/Process.h"
14 #include "lldb/Target/Target.h"
15 #include "lldb/Target/Thread.h"
18 #include "lldb/Utility/Endian.h"
20 #include "lldb/Utility/Scalar.h"
21 #include "llvm/Support/Compiler.h"
22 
24 
25 using namespace lldb;
26 using namespace lldb_private;
27 
28 // ARM64 general purpose registers.
46  LLDB_INVALID_REGNUM // register sets need to end with this flag
47 };
48 static_assert(((sizeof g_gpr_regnums_arm64 / sizeof g_gpr_regnums_arm64[0]) -
50  "g_gpr_regnums_arm64 has wrong number of register infos");
51 
52 // ARM64 floating point registers.
53 static const uint32_t g_fpu_regnums_arm64[] = {
70 
80  LLDB_INVALID_REGNUM // register sets need to end with this flag
81 };
82 static_assert(((sizeof g_fpu_regnums_arm64 / sizeof g_fpu_regnums_arm64[0]) -
84  "g_fpu_regnums_arm64 has wrong number of register infos");
85 
86 // Number of register sets provided by this context.
87 enum { k_num_register_sets = 2 };
88 
89 // Register sets for ARM64.
90 static const lldb_private::RegisterSet g_reg_sets_arm64[k_num_register_sets] = {
91  {"General Purpose Registers", "gpr", k_num_gpr_registers_arm64,
92  g_gpr_regnums_arm64},
93  {"Floating Point Registers", "fpu", k_num_fpr_registers_arm64,
94  g_fpu_regnums_arm64}};
95 
97  return reg <= m_reg_info.last_gpr; // GPR's come first.
98 }
99 
101  return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr);
102 }
103 
105  lldb_private::Thread &thread, uint32_t concrete_frame_idx,
107  : lldb_private::RegisterContext(thread, concrete_frame_idx) {
108  m_register_info_up.reset(register_info);
109 
110  switch (register_info->m_target_arch.GetMachine()) {
111  case llvm::Triple::aarch64:
121  break;
122  default:
123  assert(false && "Unhandled target architecture.");
124  break;
125  }
126 
127  ::memset(&m_fpr, 0, sizeof m_fpr);
128 }
129 
131 
133 
135 
137  assert(reg < m_reg_info.num_registers && "Invalid register number.");
138  return GetRegisterInfo()[reg].byte_offset;
139 }
140 
142  assert(reg < m_reg_info.num_registers && "Invalid register number.");
143  return GetRegisterInfo()[reg].byte_size;
144 }
145 
147  size_t num_registers =
149  return num_registers;
150 }
151 
153  return m_register_info_up->GetGPRSize();
154 }
155 
156 const lldb_private::RegisterInfo *
158  // Commonly, this method is overridden and g_register_infos is copied and
159  // specialized. So, use GetRegisterInfo() rather than g_register_infos in
160  // this scope.
161  return m_register_info_up->GetRegisterInfo();
162 }
163 
164 const lldb_private::RegisterInfo *
166  if (reg < m_reg_info.num_registers)
167  return &GetRegisterInfo()[reg];
168  else
169  return NULL;
170 }
171 
173  size_t sets = 0;
174  for (size_t set = 0; set < k_num_register_sets; ++set) {
175  if (IsRegisterSetAvailable(set))
176  ++sets;
177  }
178 
179  return sets;
180 }
181 
182 const lldb_private::RegisterSet *
184  if (IsRegisterSetAvailable(set)) {
185  switch (m_register_info_up->m_target_arch.GetMachine()) {
186  case llvm::Triple::aarch64:
187  return &g_reg_sets_arm64[set];
188  default:
189  assert(false && "Unhandled target architecture.");
190  return NULL;
191  }
192  }
193  return NULL;
194 }
195 
197  assert(reg < m_reg_info.num_registers && "Invalid register offset.");
198  return GetRegisterInfo()[reg].name;
199 }
200 
202  // Get the target process whose privileged thread was used for the register
203  // read.
205  lldb_private::Process *process = CalculateProcess().get();
206 
207  if (process)
208  byte_order = process->GetByteOrder();
209  return byte_order;
210 }
211 
213  return set_index < k_num_register_sets;
214 }
215 
216 // Used when parsing DWARF and EH frame information and any other object file
217 // sections that contain register numbers in them.
219  lldb::RegisterKind kind, uint32_t num) {
220  const uint32_t num_regs = GetRegisterCount();
221 
222  assert(kind < lldb::kNumRegisterKinds);
223  for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) {
224  const lldb_private::RegisterInfo *reg_info =
225  GetRegisterInfoAtIndex(reg_idx);
226 
227  if (reg_info->kinds[kind] == num)
228  return reg_idx;
229  }
230 
231  return LLDB_INVALID_REGNUM;
232 }
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) override
Convert from a given register numbering scheme to the lldb register numbering scheme.
RegisterInfo interface to patch RegisterInfo structure for archs.
lldb::ByteOrder GetByteOrder() const
Definition: Process.cpp:3366
std::unique_ptr< lldb_private::RegisterInfoInterface > m_register_info_up
static const lldb_private::RegisterSet g_reg_sets_arm64[k_num_register_sets]
const char * GetRegisterName(unsigned reg)
virtual bool IsRegisterSetAvailable(size_t set_index)
static const uint32_t g_fpu_regnums_arm64[]
struct RegisterContextPOSIX_arm64::FPU m_fpr
const lldb_private::RegisterSet * GetRegisterSet(size_t set) override
A plug-in interface definition class for debugging a process.
Definition: Process.h:353
RegisterContextPOSIX_arm64(lldb_private::Thread &thread, uint32_t concrete_frame_idx, lldb_private::RegisterInfoInterface *register_info)
virtual unsigned GetRegisterOffset(unsigned reg)
Definition: SBAddress.h:15
virtual unsigned GetRegisterSize(unsigned reg)
virtual const lldb_private::RegisterInfo * GetRegisterInfo()
lldb::ProcessSP CalculateProcess() override
const lldb_private::RegisterInfo * GetRegisterInfoAtIndex(size_t reg) override
const uint32_t g_gpr_regnums_arm64[]
llvm::Triple::ArchType GetMachine() const
Returns a machine family for the current architecture.
Definition: ArchSpec.cpp:726
#define LLDB_INVALID_REGNUM
Definition: lldb-defines.h:90