1 //===-- RegisterContextPOSIX_arm.cpp --------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
14 #include "lldb/Core/DataBufferHeap.h"
15 #include "lldb/Core/DataExtractor.h"
16 #include "lldb/Core/RegisterValue.h"
17 #include "lldb/Core/Scalar.h"
18 #include "lldb/Target/Target.h"
19 #include "lldb/Target/Thread.h"
20 #include "lldb/Host/Endian.h"
21 #include "llvm/Support/Compiler.h"
23 #include "RegisterContextPOSIX_arm.h"
24 #include "Plugins/Process/elf-core/ProcessElfCore.h"
27 using namespace lldb_private;
29 // arm general purpose registers.
30 const uint32_t g_gpr_regnums_arm[] =
49 LLDB_INVALID_REGNUM // register sets need to end with this flag
52 static_assert(((sizeof g_gpr_regnums_arm / sizeof g_gpr_regnums_arm[0]) - 1) == k_num_gpr_registers_arm, \
53 "g_gpr_regnums_arm has wrong number of register infos");
55 // arm floating point registers.
56 static const uint32_t g_fpu_regnums_arm[] =
139 LLDB_INVALID_REGNUM // register sets need to end with this flag
142 static_assert(((sizeof g_fpu_regnums_arm / sizeof g_fpu_regnums_arm[0]) - 1) == k_num_fpr_registers_arm, \
143 "g_fpu_regnums_arm has wrong number of register infos");
145 // Number of register sets provided by this context.
148 k_num_register_sets = 2
151 // Register sets for arm.
152 static const lldb_private::RegisterSet
153 g_reg_sets_arm[k_num_register_sets] =
155 { "General Purpose Registers", "gpr", k_num_gpr_registers_arm, g_gpr_regnums_arm },
156 { "Floating Point Registers", "fpu", k_num_fpr_registers_arm, g_fpu_regnums_arm }
159 bool RegisterContextPOSIX_arm::IsGPR(unsigned reg)
161 return reg <= m_reg_info.last_gpr; // GPR's come first.
164 bool RegisterContextPOSIX_arm::IsFPR(unsigned reg)
166 return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr);
169 RegisterContextPOSIX_arm::RegisterContextPOSIX_arm(lldb_private::Thread &thread,
170 uint32_t concrete_frame_idx,
171 lldb_private::RegisterInfoInterface *register_info)
172 : lldb_private::RegisterContext(thread, concrete_frame_idx)
174 m_register_info_ap.reset(register_info);
176 switch (register_info->m_target_arch.GetMachine())
178 case llvm::Triple::arm:
179 m_reg_info.num_registers = k_num_registers_arm;
180 m_reg_info.num_gpr_registers = k_num_gpr_registers_arm;
181 m_reg_info.num_fpr_registers = k_num_fpr_registers_arm;
182 m_reg_info.last_gpr = k_last_gpr_arm;
183 m_reg_info.first_fpr = k_first_fpr_arm;
184 m_reg_info.last_fpr = k_last_fpr_arm;
185 m_reg_info.first_fpr_v = fpu_s0_arm;
186 m_reg_info.last_fpr_v = fpu_s31_arm;
187 m_reg_info.gpr_flags = gpr_cpsr_arm;
190 assert(false && "Unhandled target architecture.");
194 ::memset(&m_fpr, 0, sizeof m_fpr);
196 // elf-core yet to support ReadFPR()
197 lldb::ProcessSP base = CalculateProcess();
198 if (base.get()->GetPluginName() == ProcessElfCore::GetPluginNameStatic())
202 RegisterContextPOSIX_arm::~RegisterContextPOSIX_arm()
207 RegisterContextPOSIX_arm::Invalidate()
212 RegisterContextPOSIX_arm::InvalidateAllRegisters()
217 RegisterContextPOSIX_arm::GetRegisterOffset(unsigned reg)
219 assert(reg < m_reg_info.num_registers && "Invalid register number.");
220 return GetRegisterInfo()[reg].byte_offset;
224 RegisterContextPOSIX_arm::GetRegisterSize(unsigned reg)
226 assert(reg < m_reg_info.num_registers && "Invalid register number.");
227 return GetRegisterInfo()[reg].byte_size;
231 RegisterContextPOSIX_arm::GetRegisterCount()
233 size_t num_registers = m_reg_info.num_gpr_registers + m_reg_info.num_fpr_registers;
234 return num_registers;
238 RegisterContextPOSIX_arm::GetGPRSize()
240 return m_register_info_ap->GetGPRSize ();
243 const lldb_private::RegisterInfo *
244 RegisterContextPOSIX_arm::GetRegisterInfo()
246 // Commonly, this method is overridden and g_register_infos is copied and specialized.
247 // So, use GetRegisterInfo() rather than g_register_infos in this scope.
248 return m_register_info_ap->GetRegisterInfo ();
251 const lldb_private::RegisterInfo *
252 RegisterContextPOSIX_arm::GetRegisterInfoAtIndex(size_t reg)
254 if (reg < m_reg_info.num_registers)
255 return &GetRegisterInfo()[reg];
261 RegisterContextPOSIX_arm::GetRegisterSetCount()
264 for (size_t set = 0; set < k_num_register_sets; ++set)
266 if (IsRegisterSetAvailable(set))
273 const lldb_private::RegisterSet *
274 RegisterContextPOSIX_arm::GetRegisterSet(size_t set)
276 if (IsRegisterSetAvailable(set))
278 switch (m_register_info_ap->m_target_arch.GetMachine())
280 case llvm::Triple::arm:
281 return &g_reg_sets_arm[set];
283 assert(false && "Unhandled target architecture.");
291 RegisterContextPOSIX_arm::GetRegisterName(unsigned reg)
293 assert(reg < m_reg_info.num_registers && "Invalid register offset.");
294 return GetRegisterInfo()[reg].name;
298 RegisterContextPOSIX_arm::GetByteOrder()
300 // Get the target process whose privileged thread was used for the register read.
301 lldb::ByteOrder byte_order = lldb::eByteOrderInvalid;
302 lldb_private::Process *process = CalculateProcess().get();
305 byte_order = process->GetByteOrder();
310 RegisterContextPOSIX_arm::IsRegisterSetAvailable(size_t set_index)
312 return set_index < k_num_register_sets;
316 // Used when parsing DWARF and EH frame information and any other
317 // object file sections that contain register numbers in them.
319 RegisterContextPOSIX_arm::ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
322 const uint32_t num_regs = GetRegisterCount();
324 assert (kind < lldb::kNumRegisterKinds);
325 for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx)
327 const lldb_private::RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg_idx);
329 if (reg_info->kinds[kind] == num)
333 return LLDB_INVALID_REGNUM;