442 lines · cpp
1//===-- RegisterContextWindows_arm64.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(__aarch64__) || defined(_M_ARM64)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_arm64.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 GPR_OFFSET_NAME(reg) 027 28#define FPU_OFFSET(idx) 029#define FPU_OFFSET_NAME(reg) 030 31#define EXC_OFFSET_NAME(reg) 032#define DBG_OFFSET_NAME(reg) 033 34#define DEFINE_DBG(reg, i) \35 #reg, NULL, \36 0, DBG_OFFSET_NAME(reg[i]), eEncodingUint, eFormatHex, \37 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \38 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \39 LLDB_INVALID_REGNUM }, \40 NULL, NULL, NULL41 42// Include RegisterInfos_arm64 to declare our g_register_infos_arm64 structure.43#define DECLARE_REGISTER_INFOS_ARM64_STRUCT44#include "Plugins/Process/Utility/RegisterInfos_arm64.h"45#undef DECLARE_REGISTER_INFOS_ARM64_STRUCT46 47static size_t k_num_register_infos = std::size(g_register_infos_arm64_le);48 49// Array of lldb register numbers used to define the set of all General Purpose50// Registers51uint32_t g_gpr_reg_indices[] = {52 gpr_x0, gpr_x1, gpr_x2, gpr_x3, gpr_x4, gpr_x5, gpr_x6, gpr_x7,53 gpr_x8, gpr_x9, gpr_x10, gpr_x11, gpr_x12, gpr_x13, gpr_x14, gpr_x15,54 gpr_x16, gpr_x17, gpr_x18, gpr_x19, gpr_x20, gpr_x21, gpr_x22, gpr_x23,55 gpr_x24, gpr_x25, gpr_x26, gpr_x27, gpr_x28, gpr_fp, gpr_lr, gpr_sp,56 gpr_pc, gpr_cpsr,57 58 gpr_w0, gpr_w1, gpr_w2, gpr_w3, gpr_w4, gpr_w5, gpr_w6, gpr_w7,59 gpr_w8, gpr_w9, gpr_w10, gpr_w11, gpr_w12, gpr_w13, gpr_w14, gpr_w15,60 gpr_w16, gpr_w17, gpr_w18, gpr_w19, gpr_w20, gpr_w21, gpr_w22, gpr_w23,61 gpr_w24, gpr_w25, gpr_w26, gpr_w27, gpr_w28,62};63 64uint32_t g_fpu_reg_indices[] = {65 fpu_v0, fpu_v1, fpu_v2, fpu_v3, fpu_v4, fpu_v5, fpu_v6, fpu_v7,66 fpu_v8, fpu_v9, fpu_v10, fpu_v11, fpu_v12, fpu_v13, fpu_v14, fpu_v15,67 fpu_v16, fpu_v17, fpu_v18, fpu_v19, fpu_v20, fpu_v21, fpu_v22, fpu_v23,68 fpu_v24, fpu_v25, fpu_v26, fpu_v27, fpu_v28, fpu_v29, fpu_v30, fpu_v31,69 70 fpu_s0, fpu_s1, fpu_s2, fpu_s3, fpu_s4, fpu_s5, fpu_s6, fpu_s7,71 fpu_s8, fpu_s9, fpu_s10, fpu_s11, fpu_s12, fpu_s13, fpu_s14, fpu_s15,72 fpu_s16, fpu_s17, fpu_s18, fpu_s19, fpu_s20, fpu_s21, fpu_s22, fpu_s23,73 fpu_s24, fpu_s25, fpu_s26, fpu_s27, fpu_s28, fpu_s29, fpu_s30, fpu_s31,74 75 fpu_d0, fpu_d1, fpu_d2, fpu_d3, fpu_d4, fpu_d5, fpu_d6, fpu_d7,76 fpu_d8, fpu_d9, fpu_d10, fpu_d11, fpu_d12, fpu_d13, fpu_d14, fpu_d15,77 fpu_d16, fpu_d17, fpu_d18, fpu_d19, fpu_d20, fpu_d21, fpu_d22, fpu_d23,78 fpu_d24, fpu_d25, fpu_d26, fpu_d27, fpu_d28, fpu_d29, fpu_d30, fpu_d31,79 80 fpu_fpsr, fpu_fpcr,81};82 83RegisterSet g_register_sets[] = {84 {"General Purpose Registers", "gpr", std::size(g_gpr_reg_indices),85 g_gpr_reg_indices},86 {"Floating Point Registers", "fpu", std::size(g_fpu_reg_indices),87 g_fpu_reg_indices},88};89 90// Constructors and Destructors91RegisterContextWindows_arm64::RegisterContextWindows_arm64(92 Thread &thread, uint32_t concrete_frame_idx)93 : RegisterContextWindows(thread, concrete_frame_idx) {}94 95RegisterContextWindows_arm64::~RegisterContextWindows_arm64() {}96 97size_t RegisterContextWindows_arm64::GetRegisterCount() {98 return std::size(g_register_infos_arm64_le);99}100 101const RegisterInfo *102RegisterContextWindows_arm64::GetRegisterInfoAtIndex(size_t reg) {103 if (reg < k_num_register_infos)104 return &g_register_infos_arm64_le[reg];105 return NULL;106}107 108size_t RegisterContextWindows_arm64::GetRegisterSetCount() {109 return std::size(g_register_sets);110}111 112const RegisterSet *113RegisterContextWindows_arm64::GetRegisterSet(size_t reg_set) {114 return &g_register_sets[reg_set];115}116 117bool RegisterContextWindows_arm64::ReadRegister(const RegisterInfo *reg_info,118 RegisterValue ®_value) {119 if (!CacheAllRegisterValues())120 return false;121 122 if (reg_info == nullptr)123 return false;124 125 const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];126 127 switch (reg) {128 case gpr_x0:129 case gpr_x1:130 case gpr_x2:131 case gpr_x3:132 case gpr_x4:133 case gpr_x5:134 case gpr_x6:135 case gpr_x7:136 case gpr_x8:137 case gpr_x9:138 case gpr_x10:139 case gpr_x11:140 case gpr_x12:141 case gpr_x13:142 case gpr_x14:143 case gpr_x15:144 case gpr_x16:145 case gpr_x17:146 case gpr_x18:147 case gpr_x19:148 case gpr_x20:149 case gpr_x21:150 case gpr_x22:151 case gpr_x23:152 case gpr_x24:153 case gpr_x25:154 case gpr_x26:155 case gpr_x27:156 case gpr_x28:157 reg_value.SetUInt64(m_context.X[reg - gpr_x0]);158 break;159 160 case gpr_fp:161 reg_value.SetUInt64(m_context.Fp);162 break;163 case gpr_sp:164 reg_value.SetUInt64(m_context.Sp);165 break;166 case gpr_lr:167 reg_value.SetUInt64(m_context.Lr);168 break;169 case gpr_pc:170 reg_value.SetUInt64(m_context.Pc);171 break;172 case gpr_cpsr:173 reg_value.SetUInt32(m_context.Cpsr);174 break;175 176 case gpr_w0:177 case gpr_w1:178 case gpr_w2:179 case gpr_w3:180 case gpr_w4:181 case gpr_w5:182 case gpr_w6:183 case gpr_w7:184 case gpr_w8:185 case gpr_w9:186 case gpr_w10:187 case gpr_w11:188 case gpr_w12:189 case gpr_w13:190 case gpr_w14:191 case gpr_w15:192 case gpr_w16:193 case gpr_w17:194 case gpr_w18:195 case gpr_w19:196 case gpr_w20:197 case gpr_w21:198 case gpr_w22:199 case gpr_w23:200 case gpr_w24:201 case gpr_w25:202 case gpr_w26:203 case gpr_w27:204 case gpr_w28:205 reg_value.SetUInt32(206 static_cast<uint32_t>(m_context.X[reg - gpr_w0] & 0xffffffff));207 break;208 209 case fpu_v0:210 case fpu_v1:211 case fpu_v2:212 case fpu_v3:213 case fpu_v4:214 case fpu_v5:215 case fpu_v6:216 case fpu_v7:217 case fpu_v8:218 case fpu_v9:219 case fpu_v10:220 case fpu_v11:221 case fpu_v12:222 case fpu_v13:223 case fpu_v14:224 case fpu_v15:225 case fpu_v16:226 case fpu_v17:227 case fpu_v18:228 case fpu_v19:229 case fpu_v20:230 case fpu_v21:231 case fpu_v22:232 case fpu_v23:233 case fpu_v24:234 case fpu_v25:235 case fpu_v26:236 case fpu_v27:237 case fpu_v28:238 case fpu_v29:239 case fpu_v30:240 case fpu_v31:241 reg_value.SetBytes(m_context.V[reg - fpu_v0].B, reg_info->byte_size,242 endian::InlHostByteOrder());243 break;244 245 case fpu_s0:246 case fpu_s1:247 case fpu_s2:248 case fpu_s3:249 case fpu_s4:250 case fpu_s5:251 case fpu_s6:252 case fpu_s7:253 case fpu_s8:254 case fpu_s9:255 case fpu_s10:256 case fpu_s11:257 case fpu_s12:258 case fpu_s13:259 case fpu_s14:260 case fpu_s15:261 case fpu_s16:262 case fpu_s17:263 case fpu_s18:264 case fpu_s19:265 case fpu_s20:266 case fpu_s21:267 case fpu_s22:268 case fpu_s23:269 case fpu_s24:270 case fpu_s25:271 case fpu_s26:272 case fpu_s27:273 case fpu_s28:274 case fpu_s29:275 case fpu_s30:276 case fpu_s31:277 reg_value.SetFloat(m_context.V[reg - fpu_s0].S[0]);278 break;279 280 case fpu_d0:281 case fpu_d1:282 case fpu_d2:283 case fpu_d3:284 case fpu_d4:285 case fpu_d5:286 case fpu_d6:287 case fpu_d7:288 case fpu_d8:289 case fpu_d9:290 case fpu_d10:291 case fpu_d11:292 case fpu_d12:293 case fpu_d13:294 case fpu_d14:295 case fpu_d15:296 case fpu_d16:297 case fpu_d17:298 case fpu_d18:299 case fpu_d19:300 case fpu_d20:301 case fpu_d21:302 case fpu_d22:303 case fpu_d23:304 case fpu_d24:305 case fpu_d25:306 case fpu_d26:307 case fpu_d27:308 case fpu_d28:309 case fpu_d29:310 case fpu_d30:311 case fpu_d31:312 reg_value.SetDouble(m_context.V[reg - fpu_d0].D[0]);313 break;314 315 case fpu_fpsr:316 reg_value.SetUInt32(m_context.Fpsr);317 break;318 319 case fpu_fpcr:320 reg_value.SetUInt32(m_context.Fpcr);321 break;322 323 default:324 reg_value.SetValueToInvalid();325 return false;326 }327 return true;328}329 330bool RegisterContextWindows_arm64::WriteRegister(331 const RegisterInfo *reg_info, const RegisterValue ®_value) {332 // Since we cannot only write a single register value to the inferior, we333 // need to make sure our cached copy of the register values are fresh.334 // Otherwise when writing one register, we may also overwrite some other335 // register with a stale value.336 if (!CacheAllRegisterValues())337 return false;338 339 const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];340 341 switch (reg) {342 case gpr_x0:343 case gpr_x1:344 case gpr_x2:345 case gpr_x3:346 case gpr_x4:347 case gpr_x5:348 case gpr_x6:349 case gpr_x7:350 case gpr_x8:351 case gpr_x9:352 case gpr_x10:353 case gpr_x11:354 case gpr_x12:355 case gpr_x13:356 case gpr_x14:357 case gpr_x15:358 case gpr_x16:359 case gpr_x17:360 case gpr_x18:361 case gpr_x19:362 case gpr_x20:363 case gpr_x21:364 case gpr_x22:365 case gpr_x23:366 case gpr_x24:367 case gpr_x25:368 case gpr_x26:369 case gpr_x27:370 case gpr_x28:371 m_context.X[reg - gpr_x0] = reg_value.GetAsUInt64();372 break;373 374 case gpr_fp:375 m_context.Fp = reg_value.GetAsUInt64();376 break;377 case gpr_sp:378 m_context.Sp = reg_value.GetAsUInt64();379 break;380 case gpr_lr:381 m_context.Lr = reg_value.GetAsUInt64();382 break;383 case gpr_pc:384 m_context.Pc = reg_value.GetAsUInt64();385 break;386 case gpr_cpsr:387 m_context.Cpsr = reg_value.GetAsUInt32();388 break;389 390 case fpu_v0:391 case fpu_v1:392 case fpu_v2:393 case fpu_v3:394 case fpu_v4:395 case fpu_v5:396 case fpu_v6:397 case fpu_v7:398 case fpu_v8:399 case fpu_v9:400 case fpu_v10:401 case fpu_v11:402 case fpu_v12:403 case fpu_v13:404 case fpu_v14:405 case fpu_v15:406 case fpu_v16:407 case fpu_v17:408 case fpu_v18:409 case fpu_v19:410 case fpu_v20:411 case fpu_v21:412 case fpu_v22:413 case fpu_v23:414 case fpu_v24:415 case fpu_v25:416 case fpu_v26:417 case fpu_v27:418 case fpu_v28:419 case fpu_v29:420 case fpu_v30:421 case fpu_v31:422 memcpy(m_context.V[reg - fpu_v0].B, reg_value.GetBytes(), 16);423 break;424 425 case fpu_fpsr:426 m_context.Fpsr = reg_value.GetAsUInt32();427 break;428 429 case fpu_fpcr:430 m_context.Fpcr = reg_value.GetAsUInt32();431 break;432 433 default:434 return false;435 }436 437 // Physically update the registers in the target process.438 return ApplyAllRegisterValues();439}440 441#endif // defined(__aarch64__) || defined(_M_ARM64)442