433 lines · cpp
1//===-- RegisterContextWindows_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#if defined(__arm__) || defined(_M_ARM)10 11#include "lldb/Host/windows/HostThreadWindows.h"12#include "lldb/Host/windows/windows.h"13#include "lldb/Utility/RegisterValue.h"14#include "lldb/Utility/Status.h"15#include "lldb/lldb-private-types.h"16 17#include "RegisterContextWindows_arm.h"18#include "TargetThreadWindows.h"19 20#include "llvm/ADT/STLExtras.h"21 22using namespace lldb;23using namespace lldb_private;24 25#define GPR_OFFSET(idx) 026#define FPU_OFFSET(idx) 027#define FPSCR_OFFSET 028#define EXC_OFFSET(reg) 029#define DBG_OFFSET_NAME(reg) 030 31#define DEFINE_DBG(reg, i) \32 #reg, NULL, \33 0, DBG_OFFSET_NAME(reg[i]), eEncodingUint, eFormatHex, \34 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \35 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \36 LLDB_INVALID_REGNUM }, \37 NULL, NULL, NULL38 39// Include RegisterInfos_arm to declare our g_register_infos_arm structure.40#define DECLARE_REGISTER_INFOS_ARM_STRUCT41#include "Plugins/Process/Utility/RegisterInfos_arm.h"42#undef DECLARE_REGISTER_INFOS_ARM_STRUCT43 44static size_t k_num_register_infos = std::size(g_register_infos_arm);45 46// Array of lldb register numbers used to define the set of all General Purpose47// Registers48uint32_t g_gpr_reg_indices[] = {49 gpr_r0, gpr_r1, gpr_r2, gpr_r3, gpr_r4, gpr_r5, gpr_r6, gpr_r7, gpr_r8,50 gpr_r9, gpr_r10, gpr_r11, gpr_r12, gpr_sp, gpr_lr, gpr_pc, gpr_cpsr,51};52 53uint32_t g_fpu_reg_indices[] = {54 fpu_s0, fpu_s1, fpu_s2, fpu_s3, fpu_s4, fpu_s5, fpu_s6, fpu_s7,55 fpu_s8, fpu_s9, fpu_s10, fpu_s11, fpu_s12, fpu_s13, fpu_s14, fpu_s15,56 fpu_s16, fpu_s17, fpu_s18, fpu_s19, fpu_s20, fpu_s21, fpu_s22, fpu_s23,57 fpu_s24, fpu_s25, fpu_s26, fpu_s27, fpu_s28, fpu_s29, fpu_s30, fpu_s31,58 59 fpu_d0, fpu_d1, fpu_d2, fpu_d3, fpu_d4, fpu_d5, fpu_d6, fpu_d7,60 fpu_d8, fpu_d9, fpu_d10, fpu_d11, fpu_d12, fpu_d13, fpu_d14, fpu_d15,61 fpu_d16, fpu_d17, fpu_d18, fpu_d19, fpu_d20, fpu_d21, fpu_d22, fpu_d23,62 fpu_d24, fpu_d25, fpu_d26, fpu_d27, fpu_d28, fpu_d29, fpu_d30, fpu_d31,63 64 fpu_q0, fpu_q1, fpu_q2, fpu_q3, fpu_q4, fpu_q5, fpu_q6, fpu_q7,65 fpu_q8, fpu_q9, fpu_q10, fpu_q11, fpu_q12, fpu_q13, fpu_q14, fpu_q15,66 67 fpu_fpscr,68};69 70RegisterSet g_register_sets[] = {71 {"General Purpose Registers", "gpr", std::size(g_gpr_reg_indices),72 g_gpr_reg_indices},73 {"Floating Point Registers", "fpu", std::size(g_fpu_reg_indices),74 g_fpu_reg_indices},75};76 77// Constructors and Destructors78RegisterContextWindows_arm::RegisterContextWindows_arm(79 Thread &thread, uint32_t concrete_frame_idx)80 : RegisterContextWindows(thread, concrete_frame_idx) {}81 82RegisterContextWindows_arm::~RegisterContextWindows_arm() {}83 84size_t RegisterContextWindows_arm::GetRegisterCount() {85 return std::size(g_register_infos_arm);86}87 88const RegisterInfo *89RegisterContextWindows_arm::GetRegisterInfoAtIndex(size_t reg) {90 if (reg < k_num_register_infos)91 return &g_register_infos_arm[reg];92 return NULL;93}94 95size_t RegisterContextWindows_arm::GetRegisterSetCount() {96 return std::size(g_register_sets);97}98 99const RegisterSet *RegisterContextWindows_arm::GetRegisterSet(size_t reg_set) {100 return &g_register_sets[reg_set];101}102 103bool RegisterContextWindows_arm::ReadRegister(const RegisterInfo *reg_info,104 RegisterValue ®_value) {105 if (!CacheAllRegisterValues())106 return false;107 108 if (reg_info == nullptr)109 return false;110 111 const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];112 113 switch (reg) {114 case gpr_r0:115 reg_value.SetUInt32(m_context.R0);116 break;117 case gpr_r1:118 reg_value.SetUInt32(m_context.R1);119 break;120 case gpr_r2:121 reg_value.SetUInt32(m_context.R2);122 break;123 case gpr_r3:124 reg_value.SetUInt32(m_context.R3);125 break;126 case gpr_r4:127 reg_value.SetUInt32(m_context.R4);128 break;129 case gpr_r5:130 reg_value.SetUInt32(m_context.R5);131 break;132 case gpr_r6:133 reg_value.SetUInt32(m_context.R6);134 break;135 case gpr_r7:136 reg_value.SetUInt32(m_context.R7);137 break;138 case gpr_r8:139 reg_value.SetUInt32(m_context.R8);140 break;141 case gpr_r9:142 reg_value.SetUInt32(m_context.R9);143 break;144 case gpr_r10:145 reg_value.SetUInt32(m_context.R10);146 break;147 case gpr_r11:148 reg_value.SetUInt32(m_context.R11);149 break;150 case gpr_r12:151 reg_value.SetUInt32(m_context.R12);152 break;153 case gpr_sp:154 reg_value.SetUInt32(m_context.Sp);155 break;156 case gpr_lr:157 reg_value.SetUInt32(m_context.Lr);158 break;159 case gpr_pc:160 reg_value.SetUInt32(m_context.Pc);161 break;162 case gpr_cpsr:163 reg_value.SetUInt32(m_context.Cpsr);164 break;165 166 case fpu_s0:167 case fpu_s1:168 case fpu_s2:169 case fpu_s3:170 case fpu_s4:171 case fpu_s5:172 case fpu_s6:173 case fpu_s7:174 case fpu_s8:175 case fpu_s9:176 case fpu_s10:177 case fpu_s11:178 case fpu_s12:179 case fpu_s13:180 case fpu_s14:181 case fpu_s15:182 case fpu_s16:183 case fpu_s17:184 case fpu_s18:185 case fpu_s19:186 case fpu_s20:187 case fpu_s21:188 case fpu_s22:189 case fpu_s23:190 case fpu_s24:191 case fpu_s25:192 case fpu_s26:193 case fpu_s27:194 case fpu_s28:195 case fpu_s29:196 case fpu_s30:197 case fpu_s31:198 reg_value.SetUInt32(m_context.S[reg - fpu_s0], RegisterValue::eTypeFloat);199 break;200 201 case fpu_d0:202 case fpu_d1:203 case fpu_d2:204 case fpu_d3:205 case fpu_d4:206 case fpu_d5:207 case fpu_d6:208 case fpu_d7:209 case fpu_d8:210 case fpu_d9:211 case fpu_d10:212 case fpu_d11:213 case fpu_d12:214 case fpu_d13:215 case fpu_d14:216 case fpu_d15:217 case fpu_d16:218 case fpu_d17:219 case fpu_d18:220 case fpu_d19:221 case fpu_d20:222 case fpu_d21:223 case fpu_d22:224 case fpu_d23:225 case fpu_d24:226 case fpu_d25:227 case fpu_d26:228 case fpu_d27:229 case fpu_d28:230 case fpu_d29:231 case fpu_d30:232 case fpu_d31:233 reg_value.SetUInt64(m_context.D[reg - fpu_d0], RegisterValue::eTypeDouble);234 break;235 236 case fpu_q0:237 case fpu_q1:238 case fpu_q2:239 case fpu_q3:240 case fpu_q4:241 case fpu_q5:242 case fpu_q6:243 case fpu_q7:244 case fpu_q8:245 case fpu_q9:246 case fpu_q10:247 case fpu_q11:248 case fpu_q12:249 case fpu_q13:250 case fpu_q14:251 case fpu_q15:252 reg_value.SetBytes(&m_context.Q[reg - fpu_q0], reg_info->byte_size,253 endian::InlHostByteOrder());254 break;255 256 case fpu_fpscr:257 reg_value.SetUInt32(m_context.Fpscr);258 break;259 260 default:261 reg_value.SetValueToInvalid();262 return false;263 }264 return true;265}266 267bool RegisterContextWindows_arm::WriteRegister(const RegisterInfo *reg_info,268 const RegisterValue ®_value) {269 // Since we cannot only write a single register value to the inferior, we270 // need to make sure our cached copy of the register values are fresh.271 // Otherwise when writing EAX, for example, we may also overwrite some other272 // register with a stale value.273 if (!CacheAllRegisterValues())274 return false;275 276 const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];277 278 switch (reg) {279 case gpr_r0:280 m_context.R0 = reg_value.GetAsUInt32();281 break;282 case gpr_r1:283 m_context.R1 = reg_value.GetAsUInt32();284 break;285 case gpr_r2:286 m_context.R2 = reg_value.GetAsUInt32();287 break;288 case gpr_r3:289 m_context.R3 = reg_value.GetAsUInt32();290 break;291 case gpr_r4:292 m_context.R4 = reg_value.GetAsUInt32();293 break;294 case gpr_r5:295 m_context.R5 = reg_value.GetAsUInt32();296 break;297 case gpr_r6:298 m_context.R6 = reg_value.GetAsUInt32();299 break;300 case gpr_r7:301 m_context.R7 = reg_value.GetAsUInt32();302 break;303 case gpr_r8:304 m_context.R8 = reg_value.GetAsUInt32();305 break;306 case gpr_r9:307 m_context.R9 = reg_value.GetAsUInt32();308 break;309 case gpr_r10:310 m_context.R10 = reg_value.GetAsUInt32();311 break;312 case gpr_r11:313 m_context.R11 = reg_value.GetAsUInt32();314 break;315 case gpr_r12:316 m_context.R12 = reg_value.GetAsUInt32();317 break;318 case gpr_sp:319 m_context.Sp = reg_value.GetAsUInt32();320 break;321 case gpr_lr:322 m_context.Lr = reg_value.GetAsUInt32();323 break;324 case gpr_pc:325 m_context.Pc = reg_value.GetAsUInt32();326 break;327 case gpr_cpsr:328 m_context.Cpsr = reg_value.GetAsUInt32();329 break;330 331 case fpu_s0:332 case fpu_s1:333 case fpu_s2:334 case fpu_s3:335 case fpu_s4:336 case fpu_s5:337 case fpu_s6:338 case fpu_s7:339 case fpu_s8:340 case fpu_s9:341 case fpu_s10:342 case fpu_s11:343 case fpu_s12:344 case fpu_s13:345 case fpu_s14:346 case fpu_s15:347 case fpu_s16:348 case fpu_s17:349 case fpu_s18:350 case fpu_s19:351 case fpu_s20:352 case fpu_s21:353 case fpu_s22:354 case fpu_s23:355 case fpu_s24:356 case fpu_s25:357 case fpu_s26:358 case fpu_s27:359 case fpu_s28:360 case fpu_s29:361 case fpu_s30:362 case fpu_s31:363 m_context.S[reg - fpu_s0] = reg_value.GetAsUInt32();364 break;365 366 case fpu_d0:367 case fpu_d1:368 case fpu_d2:369 case fpu_d3:370 case fpu_d4:371 case fpu_d5:372 case fpu_d6:373 case fpu_d7:374 case fpu_d8:375 case fpu_d9:376 case fpu_d10:377 case fpu_d11:378 case fpu_d12:379 case fpu_d13:380 case fpu_d14:381 case fpu_d15:382 case fpu_d16:383 case fpu_d17:384 case fpu_d18:385 case fpu_d19:386 case fpu_d20:387 case fpu_d21:388 case fpu_d22:389 case fpu_d23:390 case fpu_d24:391 case fpu_d25:392 case fpu_d26:393 case fpu_d27:394 case fpu_d28:395 case fpu_d29:396 case fpu_d30:397 case fpu_d31:398 m_context.D[reg - fpu_d0] = reg_value.GetAsUInt64();399 break;400 401 case fpu_q0:402 case fpu_q1:403 case fpu_q2:404 case fpu_q3:405 case fpu_q4:406 case fpu_q5:407 case fpu_q6:408 case fpu_q7:409 case fpu_q8:410 case fpu_q9:411 case fpu_q10:412 case fpu_q11:413 case fpu_q12:414 case fpu_q13:415 case fpu_q14:416 case fpu_q15:417 memcpy(&m_context.Q[reg - fpu_q0], reg_value.GetBytes(), 16);418 break;419 420 case fpu_fpscr:421 m_context.Fpscr = reg_value.GetAsUInt32();422 break;423 424 default:425 return false;426 }427 428 // Physically update the registers in the target process.429 return ApplyAllRegisterValues();430}431 432#endif // defined(__arm__) || defined(_M_ARM)433