194 lines · cpp
1//===-- RegisterInfoPOSIX_arm.cpp -----------------------------------------===//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-exception6//7//===---------------------------------------------------------------------===//8 9#include <cassert>10#include <cstddef>11#include <vector>12 13#include "lldb/lldb-defines.h"14#include "llvm/Support/Compiler.h"15 16#include "RegisterInfoPOSIX_arm.h"17 18using namespace lldb;19using namespace lldb_private;20 21// Based on RegisterContextDarwin_arm.cpp22#define GPR_OFFSET(idx) ((idx)*4)23#define FPU_OFFSET(idx) ((idx)*4 + sizeof(RegisterInfoPOSIX_arm::GPR))24#define FPSCR_OFFSET \25 (LLVM_EXTENSION offsetof(RegisterInfoPOSIX_arm::FPU, fpscr) + \26 sizeof(RegisterInfoPOSIX_arm::GPR))27#define EXC_OFFSET(idx) \28 ((idx)*4 + sizeof(RegisterInfoPOSIX_arm::GPR) + \29 sizeof(RegisterInfoPOSIX_arm::FPU))30#define DBG_OFFSET(reg) \31 ((LLVM_EXTENSION offsetof(RegisterInfoPOSIX_arm::DBG, reg) + \32 sizeof(RegisterInfoPOSIX_arm::GPR) + sizeof(RegisterInfoPOSIX_arm::FPU) + \33 sizeof(RegisterInfoPOSIX_arm::EXC)))34 35#define DEFINE_DBG(reg, i) \36 #reg, NULL, sizeof(((RegisterInfoPOSIX_arm::DBG *) NULL)->reg[i]), \37 DBG_OFFSET(reg[i]), eEncodingUint, eFormatHex, \38 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \39 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \40 dbg_##reg##i }, \41 NULL, NULL, NULL,42#define REG_CONTEXT_SIZE \43 (sizeof(RegisterInfoPOSIX_arm::GPR) + sizeof(RegisterInfoPOSIX_arm::FPU) + \44 sizeof(RegisterInfoPOSIX_arm::EXC))45 46// Include RegisterInfos_arm to declare our g_register_infos_arm structure.47#define DECLARE_REGISTER_INFOS_ARM_STRUCT48#include "RegisterInfos_arm.h"49#undef DECLARE_REGISTER_INFOS_ARM_STRUCT50 51static const lldb_private::RegisterInfo *52GetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch) {53 switch (target_arch.GetMachine()) {54 case llvm::Triple::arm:55 return g_register_infos_arm;56 default:57 assert(false && "Unhandled target architecture.");58 return nullptr;59 }60}61 62static uint32_t63GetRegisterInfoCount(const lldb_private::ArchSpec &target_arch) {64 switch (target_arch.GetMachine()) {65 case llvm::Triple::arm:66 return static_cast<uint32_t>(sizeof(g_register_infos_arm) /67 sizeof(g_register_infos_arm[0]));68 default:69 assert(false && "Unhandled target architecture.");70 return 0;71 }72}73 74// Number of register sets provided by this context.75enum {76 k_num_gpr_registers = gpr_cpsr - gpr_r0 + 1,77 k_num_fpr_registers = fpu_q15 - fpu_s0 + 1,78 k_num_register_sets = 279};80 81// arm general purpose registers.82static const uint32_t g_gpr_regnums_arm[] = {83 gpr_r0, gpr_r1,84 gpr_r2, gpr_r3,85 gpr_r4, gpr_r5,86 gpr_r6, gpr_r7,87 gpr_r8, gpr_r9,88 gpr_r10, gpr_r11,89 gpr_r12, gpr_sp,90 gpr_lr, gpr_pc,91 gpr_cpsr, LLDB_INVALID_REGNUM // register sets need to end with this flag92};93static_assert(((sizeof g_gpr_regnums_arm / sizeof g_gpr_regnums_arm[0]) - 1) ==94 k_num_gpr_registers,95 "g_gpr_regnums_arm has wrong number of register infos");96 97// arm floating point registers.98static const uint32_t g_fpu_regnums_arm[] = {99 fpu_s0, fpu_s1,100 fpu_s2, fpu_s3,101 fpu_s4, fpu_s5,102 fpu_s6, fpu_s7,103 fpu_s8, fpu_s9,104 fpu_s10, fpu_s11,105 fpu_s12, fpu_s13,106 fpu_s14, fpu_s15,107 fpu_s16, fpu_s17,108 fpu_s18, fpu_s19,109 fpu_s20, fpu_s21,110 fpu_s22, fpu_s23,111 fpu_s24, fpu_s25,112 fpu_s26, fpu_s27,113 fpu_s28, fpu_s29,114 fpu_s30, fpu_s31,115 fpu_fpscr, fpu_d0,116 fpu_d1, fpu_d2,117 fpu_d3, fpu_d4,118 fpu_d5, fpu_d6,119 fpu_d7, fpu_d8,120 fpu_d9, fpu_d10,121 fpu_d11, fpu_d12,122 fpu_d13, fpu_d14,123 fpu_d15, fpu_d16,124 fpu_d17, fpu_d18,125 fpu_d19, fpu_d20,126 fpu_d21, fpu_d22,127 fpu_d23, fpu_d24,128 fpu_d25, fpu_d26,129 fpu_d27, fpu_d28,130 fpu_d29, fpu_d30,131 fpu_d31, fpu_q0,132 fpu_q1, fpu_q2,133 fpu_q3, fpu_q4,134 fpu_q5, fpu_q6,135 fpu_q7, fpu_q8,136 fpu_q9, fpu_q10,137 fpu_q11, fpu_q12,138 fpu_q13, fpu_q14,139 fpu_q15, LLDB_INVALID_REGNUM // register sets need to end with this flag140};141static_assert(((sizeof g_fpu_regnums_arm / sizeof g_fpu_regnums_arm[0]) - 1) ==142 k_num_fpr_registers,143 "g_fpu_regnums_arm has wrong number of register infos");144 145// Register sets for arm.146static const RegisterSet g_reg_sets_arm[k_num_register_sets] = {147 {"General Purpose Registers", "gpr", k_num_gpr_registers,148 g_gpr_regnums_arm},149 {"Floating Point Registers", "fpu", k_num_fpr_registers,150 g_fpu_regnums_arm}};151 152RegisterInfoPOSIX_arm::RegisterInfoPOSIX_arm(153 const lldb_private::ArchSpec &target_arch)154 : lldb_private::RegisterInfoAndSetInterface(target_arch),155 m_register_info_p(GetRegisterInfoPtr(target_arch)),156 m_register_info_count(GetRegisterInfoCount(target_arch)) {}157 158size_t RegisterInfoPOSIX_arm::GetGPRSize() const {159 return sizeof(struct RegisterInfoPOSIX_arm::GPR);160}161 162size_t RegisterInfoPOSIX_arm::GetFPRSize() const {163 return sizeof(struct RegisterInfoPOSIX_arm::FPU);164}165 166const lldb_private::RegisterInfo *167RegisterInfoPOSIX_arm::GetRegisterInfo() const {168 return m_register_info_p;169}170 171size_t RegisterInfoPOSIX_arm::GetRegisterSetCount() const {172 return k_num_register_sets;173}174 175size_t RegisterInfoPOSIX_arm::GetRegisterSetFromRegisterIndex(176 uint32_t reg_index) const {177 if (reg_index <= gpr_cpsr)178 return GPRegSet;179 if (reg_index <= fpu_q15)180 return FPRegSet;181 return LLDB_INVALID_REGNUM;182}183 184const lldb_private::RegisterSet *185RegisterInfoPOSIX_arm::GetRegisterSet(size_t set_index) const {186 if (set_index < GetRegisterSetCount())187 return &g_reg_sets_arm[set_index];188 return nullptr;189}190 191uint32_t RegisterInfoPOSIX_arm::GetRegisterCount() const {192 return m_register_info_count;193}194