LLDB  mainline
RegisterContextPOSIX_arm.cpp
Go to the documentation of this file.
1 //===-- RegisterContextPOSIX_arm.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 // arm general purpose registers.
34  LLDB_INVALID_REGNUM // register sets need to end with this flag
35 
36 };
37 static_assert(((sizeof g_gpr_regnums_arm / sizeof g_gpr_regnums_arm[0]) - 1) ==
39  "g_gpr_regnums_arm has wrong number of register infos");
40 
41 // arm floating point registers.
42 static const uint32_t g_fpu_regnums_arm[] = {
60  LLDB_INVALID_REGNUM // register sets need to end with this flag
61 
62 };
63 static_assert(((sizeof g_fpu_regnums_arm / sizeof g_fpu_regnums_arm[0]) - 1) ==
65  "g_fpu_regnums_arm has wrong number of register infos");
66 
67 // Number of register sets provided by this context.
68 enum { k_num_register_sets = 2 };
69 
70 // Register sets for arm.
71 static const lldb_private::RegisterSet g_reg_sets_arm[k_num_register_sets] = {
72  {"General Purpose Registers", "gpr", k_num_gpr_registers_arm,
73  g_gpr_regnums_arm},
74  {"Floating Point Registers", "fpu", k_num_fpr_registers_arm,
75  g_fpu_regnums_arm}};
76 
77 bool RegisterContextPOSIX_arm::IsGPR(unsigned reg) {
78  return reg <= m_reg_info.last_gpr; // GPR's come first.
79 }
80 
81 bool RegisterContextPOSIX_arm::IsFPR(unsigned reg) {
82  return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr);
83 }
84 
86  lldb_private::Thread &thread, uint32_t concrete_frame_idx,
88  : lldb_private::RegisterContext(thread, concrete_frame_idx) {
89  m_register_info_up.reset(register_info);
90 
91  switch (register_info->m_target_arch.GetMachine()) {
92  case llvm::Triple::arm:
102  break;
103  default:
104  assert(false && "Unhandled target architecture.");
105  break;
106  }
107 
108  ::memset(&m_fpr, 0, sizeof m_fpr);
109 }
110 
112 
114 
116 
118  assert(reg < m_reg_info.num_registers && "Invalid register number.");
119  return GetRegisterInfo()[reg].byte_offset;
120 }
121 
123  assert(reg < m_reg_info.num_registers && "Invalid register number.");
124  return GetRegisterInfo()[reg].byte_size;
125 }
126 
128  size_t num_registers =
130  return num_registers;
131 }
132 
134  return m_register_info_up->GetGPRSize();
135 }
136 
137 const lldb_private::RegisterInfo *RegisterContextPOSIX_arm::GetRegisterInfo() {
138  // Commonly, this method is overridden and g_register_infos is copied and
139  // specialized. So, use GetRegisterInfo() rather than g_register_infos in
140  // this scope.
141  return m_register_info_up->GetRegisterInfo();
142 }
143 
144 const lldb_private::RegisterInfo *
146  if (reg < m_reg_info.num_registers)
147  return &GetRegisterInfo()[reg];
148  else
149  return NULL;
150 }
151 
153  size_t sets = 0;
154  for (size_t set = 0; set < k_num_register_sets; ++set) {
155  if (IsRegisterSetAvailable(set))
156  ++sets;
157  }
158 
159  return sets;
160 }
161 
162 const lldb_private::RegisterSet *
164  if (IsRegisterSetAvailable(set)) {
165  switch (m_register_info_up->m_target_arch.GetMachine()) {
166  case llvm::Triple::arm:
167  return &g_reg_sets_arm[set];
168  default:
169  assert(false && "Unhandled target architecture.");
170  return NULL;
171  }
172  }
173  return NULL;
174 }
175 
176 const char *RegisterContextPOSIX_arm::GetRegisterName(unsigned reg) {
177  assert(reg < m_reg_info.num_registers && "Invalid register offset.");
178  return GetRegisterInfo()[reg].name;
179 }
180 
182  // Get the target process whose privileged thread was used for the register
183  // read.
185  lldb_private::Process *process = CalculateProcess().get();
186 
187  if (process)
188  byte_order = process->GetByteOrder();
189  return byte_order;
190 }
191 
193  return set_index < k_num_register_sets;
194 }
195 
196 // Used when parsing DWARF and EH frame information and any other object file
197 // sections that contain register numbers in them.
199  lldb::RegisterKind kind, uint32_t num) {
200  const uint32_t num_regs = GetRegisterCount();
201 
202  assert(kind < lldb::kNumRegisterKinds);
203  for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx) {
204  const lldb_private::RegisterInfo *reg_info =
205  GetRegisterInfoAtIndex(reg_idx);
206 
207  if (reg_info->kinds[kind] == num)
208  return reg_idx;
209  }
210 
211  return LLDB_INVALID_REGNUM;
212 }
virtual const lldb_private::RegisterInfo * GetRegisterInfo()
RegisterContextPOSIX_arm(lldb_private::Thread &thread, uint32_t concrete_frame_idx, lldb_private::RegisterInfoInterface *register_info)
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
RegisterInfo interface to patch RegisterInfo structure for archs.
const lldb_private::RegisterSet * GetRegisterSet(size_t set) override
virtual unsigned GetRegisterOffset(unsigned reg)
lldb::ByteOrder GetByteOrder() const
Definition: Process.cpp:3366
const uint32_t g_gpr_regnums_arm[]
const char * GetRegisterName(unsigned reg)
uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num) override
Convert from a given register numbering scheme to the lldb register numbering scheme.
virtual bool IsRegisterSetAvailable(size_t set_index)
static const lldb_private::RegisterSet g_reg_sets_arm[k_num_register_sets]
const lldb_private::RegisterInfo * GetRegisterInfoAtIndex(size_t reg) override
A plug-in interface definition class for debugging a process.
Definition: Process.h:353
struct RegisterContextPOSIX_arm::FPU m_fpr
static const uint32_t g_fpu_regnums_arm[]
virtual unsigned GetRegisterSize(unsigned reg)
std::unique_ptr< lldb_private::RegisterInfoInterface > m_register_info_up
Definition: SBAddress.h:15
lldb::ProcessSP CalculateProcess() override
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