750 lines · cpp
1//===-- NativeRegisterContextWindows_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 "NativeRegisterContextWindows_arm64.h"12#include "NativeThreadWindows.h"13#include "ProcessWindowsLog.h"14#include "lldb/Host/HostInfo.h"15#include "lldb/Host/HostThread.h"16#include "lldb/Host/windows/HostThreadWindows.h"17#include "lldb/Host/windows/windows.h"18 19#include "lldb/Utility/Log.h"20#include "lldb/Utility/RegisterValue.h"21#include "llvm/ADT/STLExtras.h"22 23using namespace lldb;24using namespace lldb_private;25 26#define REG_CONTEXT_SIZE sizeof(::CONTEXT)27 28namespace {29static const uint32_t g_gpr_regnums_arm64[] = {30 gpr_x0_arm64, gpr_x1_arm64, gpr_x2_arm64, gpr_x3_arm64,31 gpr_x4_arm64, gpr_x5_arm64, gpr_x6_arm64, gpr_x7_arm64,32 gpr_x8_arm64, gpr_x9_arm64, gpr_x10_arm64, gpr_x11_arm64,33 gpr_x12_arm64, gpr_x13_arm64, gpr_x14_arm64, gpr_x15_arm64,34 gpr_x16_arm64, gpr_x17_arm64, gpr_x18_arm64, gpr_x19_arm64,35 gpr_x20_arm64, gpr_x21_arm64, gpr_x22_arm64, gpr_x23_arm64,36 gpr_x24_arm64, gpr_x25_arm64, gpr_x26_arm64, gpr_x27_arm64,37 gpr_x28_arm64, gpr_fp_arm64, gpr_lr_arm64, gpr_sp_arm64,38 gpr_pc_arm64, gpr_cpsr_arm64, gpr_w0_arm64, gpr_w1_arm64,39 gpr_w2_arm64, gpr_w3_arm64, gpr_w4_arm64, gpr_w5_arm64,40 gpr_w6_arm64, gpr_w7_arm64, gpr_w8_arm64, gpr_w9_arm64,41 gpr_w10_arm64, gpr_w11_arm64, gpr_w12_arm64, gpr_w13_arm64,42 gpr_w14_arm64, gpr_w15_arm64, gpr_w16_arm64, gpr_w17_arm64,43 gpr_w18_arm64, gpr_w19_arm64, gpr_w20_arm64, gpr_w21_arm64,44 gpr_w22_arm64, gpr_w23_arm64, gpr_w24_arm64, gpr_w25_arm64,45 gpr_w26_arm64, gpr_w27_arm64, gpr_w28_arm64,46 LLDB_INVALID_REGNUM // Register set must be terminated with this flag47};48static_assert(((sizeof g_gpr_regnums_arm64 / sizeof g_gpr_regnums_arm64[0]) -49 1) == k_num_gpr_registers_arm64,50 "g_gpr_regnums_arm64 has wrong number of register infos");51 52static const uint32_t g_fpr_regnums_arm64[] = {53 fpu_v0_arm64, fpu_v1_arm64, fpu_v2_arm64, fpu_v3_arm64,54 fpu_v4_arm64, fpu_v5_arm64, fpu_v6_arm64, fpu_v7_arm64,55 fpu_v8_arm64, fpu_v9_arm64, fpu_v10_arm64, fpu_v11_arm64,56 fpu_v12_arm64, fpu_v13_arm64, fpu_v14_arm64, fpu_v15_arm64,57 fpu_v16_arm64, fpu_v17_arm64, fpu_v18_arm64, fpu_v19_arm64,58 fpu_v20_arm64, fpu_v21_arm64, fpu_v22_arm64, fpu_v23_arm64,59 fpu_v24_arm64, fpu_v25_arm64, fpu_v26_arm64, fpu_v27_arm64,60 fpu_v28_arm64, fpu_v29_arm64, fpu_v30_arm64, fpu_v31_arm64,61 fpu_s0_arm64, fpu_s1_arm64, fpu_s2_arm64, fpu_s3_arm64,62 fpu_s4_arm64, fpu_s5_arm64, fpu_s6_arm64, fpu_s7_arm64,63 fpu_s8_arm64, fpu_s9_arm64, fpu_s10_arm64, fpu_s11_arm64,64 fpu_s12_arm64, fpu_s13_arm64, fpu_s14_arm64, fpu_s15_arm64,65 fpu_s16_arm64, fpu_s17_arm64, fpu_s18_arm64, fpu_s19_arm64,66 fpu_s20_arm64, fpu_s21_arm64, fpu_s22_arm64, fpu_s23_arm64,67 fpu_s24_arm64, fpu_s25_arm64, fpu_s26_arm64, fpu_s27_arm64,68 fpu_s28_arm64, fpu_s29_arm64, fpu_s30_arm64, fpu_s31_arm64,69 70 fpu_d0_arm64, fpu_d1_arm64, fpu_d2_arm64, fpu_d3_arm64,71 fpu_d4_arm64, fpu_d5_arm64, fpu_d6_arm64, fpu_d7_arm64,72 fpu_d8_arm64, fpu_d9_arm64, fpu_d10_arm64, fpu_d11_arm64,73 fpu_d12_arm64, fpu_d13_arm64, fpu_d14_arm64, fpu_d15_arm64,74 fpu_d16_arm64, fpu_d17_arm64, fpu_d18_arm64, fpu_d19_arm64,75 fpu_d20_arm64, fpu_d21_arm64, fpu_d22_arm64, fpu_d23_arm64,76 fpu_d24_arm64, fpu_d25_arm64, fpu_d26_arm64, fpu_d27_arm64,77 fpu_d28_arm64, fpu_d29_arm64, fpu_d30_arm64, fpu_d31_arm64,78 fpu_fpsr_arm64, fpu_fpcr_arm64,79 LLDB_INVALID_REGNUM // Register set must be terminated with this flag80};81static_assert(((sizeof g_fpr_regnums_arm64 / sizeof g_fpr_regnums_arm64[0]) -82 1) == k_num_fpr_registers_arm64,83 "g_fpu_regnums_arm64 has wrong number of register infos");84 85static const RegisterSet g_reg_sets_arm64[] = {86 {"General Purpose Registers", "gpr", std::size(g_gpr_regnums_arm64) - 1,87 g_gpr_regnums_arm64},88 {"Floating Point Registers", "fpr", std::size(g_fpr_regnums_arm64) - 1,89 g_fpr_regnums_arm64},90};91 92enum { k_num_register_sets = 2 };93 94} // namespace95 96static RegisterInfoInterface *97CreateRegisterInfoInterface(const ArchSpec &target_arch) {98 assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) &&99 "Register setting path assumes this is a 64-bit host");100 return new RegisterInfoPOSIX_arm64(101 target_arch, RegisterInfoPOSIX_arm64::eRegsetMaskDefault);102}103 104static Status GetThreadContextHelper(lldb::thread_t thread_handle,105 PCONTEXT context_ptr,106 const DWORD control_flag) {107 Log *log = GetLog(WindowsLog::Registers);108 Status error;109 110 memset(context_ptr, 0, sizeof(::CONTEXT));111 context_ptr->ContextFlags = control_flag;112 if (!::GetThreadContext(thread_handle, context_ptr)) {113 error = Status(GetLastError(), eErrorTypeWin32);114 LLDB_LOG(log, "{0} GetThreadContext failed with error {1}", __FUNCTION__,115 error);116 return error;117 }118 return Status();119}120 121static Status SetThreadContextHelper(lldb::thread_t thread_handle,122 PCONTEXT context_ptr) {123 Log *log = GetLog(WindowsLog::Registers);124 Status error;125 // It's assumed that the thread has stopped.126 if (!::SetThreadContext(thread_handle, context_ptr)) {127 error = Status(GetLastError(), eErrorTypeWin32);128 LLDB_LOG(log, "{0} SetThreadContext failed with error {1}", __FUNCTION__,129 error);130 return error;131 }132 return Status();133}134 135std::unique_ptr<NativeRegisterContextWindows>136NativeRegisterContextWindows::CreateHostNativeRegisterContextWindows(137 const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {138 // Register context for a native 64-bit application.139 return std::make_unique<NativeRegisterContextWindows_arm64>(target_arch,140 native_thread);141}142 143NativeRegisterContextWindows_arm64::NativeRegisterContextWindows_arm64(144 const ArchSpec &target_arch, NativeThreadProtocol &native_thread)145 : NativeRegisterContextRegisterInfo(146 native_thread, CreateRegisterInfoInterface(target_arch)) {147 // Currently, there is no API to query the maximum supported hardware148 // breakpoints and watchpoints on Windows. The values set below are based149 // on tests conducted on Windows 11 with Snapdragon Elite X hardware.150 m_max_hwp_supported = 1;151}152 153bool NativeRegisterContextWindows_arm64::IsGPR(uint32_t reg_index) const {154 return (reg_index >= k_first_gpr_arm64 && reg_index <= k_last_gpr_arm64);155}156 157bool NativeRegisterContextWindows_arm64::IsFPR(uint32_t reg_index) const {158 return (reg_index >= k_first_fpr_arm64 && reg_index <= k_last_fpr_arm64);159}160 161uint32_t NativeRegisterContextWindows_arm64::GetRegisterSetCount() const {162 return k_num_register_sets;163}164 165const RegisterSet *166NativeRegisterContextWindows_arm64::GetRegisterSet(uint32_t set_index) const {167 if (set_index >= k_num_register_sets)168 return nullptr;169 return &g_reg_sets_arm64[set_index];170}171 172Status NativeRegisterContextWindows_arm64::GPRRead(const uint32_t reg,173 RegisterValue ®_value) {174 ::CONTEXT tls_context;175 DWORD context_flag = CONTEXT_CONTROL | CONTEXT_INTEGER;176 Status error =177 GetThreadContextHelper(GetThreadHandle(), &tls_context, context_flag);178 if (error.Fail())179 return error;180 181 switch (reg) {182 case gpr_x0_arm64:183 case gpr_x1_arm64:184 case gpr_x2_arm64:185 case gpr_x3_arm64:186 case gpr_x4_arm64:187 case gpr_x5_arm64:188 case gpr_x6_arm64:189 case gpr_x7_arm64:190 case gpr_x8_arm64:191 case gpr_x9_arm64:192 case gpr_x10_arm64:193 case gpr_x11_arm64:194 case gpr_x12_arm64:195 case gpr_x13_arm64:196 case gpr_x14_arm64:197 case gpr_x15_arm64:198 case gpr_x16_arm64:199 case gpr_x17_arm64:200 case gpr_x18_arm64:201 case gpr_x19_arm64:202 case gpr_x20_arm64:203 case gpr_x21_arm64:204 case gpr_x22_arm64:205 case gpr_x23_arm64:206 case gpr_x24_arm64:207 case gpr_x25_arm64:208 case gpr_x26_arm64:209 case gpr_x27_arm64:210 case gpr_x28_arm64:211 reg_value.SetUInt64(tls_context.X[reg - gpr_x0_arm64]);212 break;213 214 case gpr_fp_arm64:215 reg_value.SetUInt64(tls_context.Fp);216 break;217 case gpr_sp_arm64:218 reg_value.SetUInt64(tls_context.Sp);219 break;220 case gpr_lr_arm64:221 reg_value.SetUInt64(tls_context.Lr);222 break;223 case gpr_pc_arm64:224 reg_value.SetUInt64(tls_context.Pc);225 break;226 case gpr_cpsr_arm64:227 reg_value.SetUInt32(tls_context.Cpsr);228 break;229 230 case gpr_w0_arm64:231 case gpr_w1_arm64:232 case gpr_w2_arm64:233 case gpr_w3_arm64:234 case gpr_w4_arm64:235 case gpr_w5_arm64:236 case gpr_w6_arm64:237 case gpr_w7_arm64:238 case gpr_w8_arm64:239 case gpr_w9_arm64:240 case gpr_w10_arm64:241 case gpr_w11_arm64:242 case gpr_w12_arm64:243 case gpr_w13_arm64:244 case gpr_w14_arm64:245 case gpr_w15_arm64:246 case gpr_w16_arm64:247 case gpr_w17_arm64:248 case gpr_w18_arm64:249 case gpr_w19_arm64:250 case gpr_w20_arm64:251 case gpr_w21_arm64:252 case gpr_w22_arm64:253 case gpr_w23_arm64:254 case gpr_w24_arm64:255 case gpr_w25_arm64:256 case gpr_w26_arm64:257 case gpr_w27_arm64:258 case gpr_w28_arm64:259 reg_value.SetUInt32(260 static_cast<uint32_t>(tls_context.X[reg - gpr_w0_arm64] & 0xffffffff));261 break;262 }263 264 return error;265}266 267Status268NativeRegisterContextWindows_arm64::GPRWrite(const uint32_t reg,269 const RegisterValue ®_value) {270 ::CONTEXT tls_context;271 DWORD context_flag = CONTEXT_CONTROL | CONTEXT_INTEGER;272 auto thread_handle = GetThreadHandle();273 Status error =274 GetThreadContextHelper(thread_handle, &tls_context, context_flag);275 if (error.Fail())276 return error;277 278 switch (reg) {279 case gpr_x0_arm64:280 case gpr_x1_arm64:281 case gpr_x2_arm64:282 case gpr_x3_arm64:283 case gpr_x4_arm64:284 case gpr_x5_arm64:285 case gpr_x6_arm64:286 case gpr_x7_arm64:287 case gpr_x8_arm64:288 case gpr_x9_arm64:289 case gpr_x10_arm64:290 case gpr_x11_arm64:291 case gpr_x12_arm64:292 case gpr_x13_arm64:293 case gpr_x14_arm64:294 case gpr_x15_arm64:295 case gpr_x16_arm64:296 case gpr_x17_arm64:297 case gpr_x18_arm64:298 case gpr_x19_arm64:299 case gpr_x20_arm64:300 case gpr_x21_arm64:301 case gpr_x22_arm64:302 case gpr_x23_arm64:303 case gpr_x24_arm64:304 case gpr_x25_arm64:305 case gpr_x26_arm64:306 case gpr_x27_arm64:307 case gpr_x28_arm64:308 tls_context.X[reg - gpr_x0_arm64] = reg_value.GetAsUInt64();309 break;310 311 case gpr_fp_arm64:312 tls_context.Fp = reg_value.GetAsUInt64();313 break;314 case gpr_sp_arm64:315 tls_context.Sp = reg_value.GetAsUInt64();316 break;317 case gpr_lr_arm64:318 tls_context.Lr = reg_value.GetAsUInt64();319 break;320 case gpr_pc_arm64:321 tls_context.Pc = reg_value.GetAsUInt64();322 break;323 case gpr_cpsr_arm64:324 tls_context.Cpsr = reg_value.GetAsUInt32();325 break;326 327 case gpr_w0_arm64:328 case gpr_w1_arm64:329 case gpr_w2_arm64:330 case gpr_w3_arm64:331 case gpr_w4_arm64:332 case gpr_w5_arm64:333 case gpr_w6_arm64:334 case gpr_w7_arm64:335 case gpr_w8_arm64:336 case gpr_w9_arm64:337 case gpr_w10_arm64:338 case gpr_w11_arm64:339 case gpr_w12_arm64:340 case gpr_w13_arm64:341 case gpr_w14_arm64:342 case gpr_w15_arm64:343 case gpr_w16_arm64:344 case gpr_w17_arm64:345 case gpr_w18_arm64:346 case gpr_w19_arm64:347 case gpr_w20_arm64:348 case gpr_w21_arm64:349 case gpr_w22_arm64:350 case gpr_w23_arm64:351 case gpr_w24_arm64:352 case gpr_w25_arm64:353 case gpr_w26_arm64:354 case gpr_w27_arm64:355 case gpr_w28_arm64:356 tls_context.X[reg - gpr_w0_arm64] = reg_value.GetAsUInt32();357 break;358 }359 360 return SetThreadContextHelper(thread_handle, &tls_context);361}362 363Status NativeRegisterContextWindows_arm64::FPRRead(const uint32_t reg,364 RegisterValue ®_value) {365 ::CONTEXT tls_context;366 DWORD context_flag = CONTEXT_CONTROL | CONTEXT_FLOATING_POINT;367 Status error =368 GetThreadContextHelper(GetThreadHandle(), &tls_context, context_flag);369 if (error.Fail())370 return error;371 372 switch (reg) {373 case fpu_v0_arm64:374 case fpu_v1_arm64:375 case fpu_v2_arm64:376 case fpu_v3_arm64:377 case fpu_v4_arm64:378 case fpu_v5_arm64:379 case fpu_v6_arm64:380 case fpu_v7_arm64:381 case fpu_v8_arm64:382 case fpu_v9_arm64:383 case fpu_v10_arm64:384 case fpu_v11_arm64:385 case fpu_v12_arm64:386 case fpu_v13_arm64:387 case fpu_v14_arm64:388 case fpu_v15_arm64:389 case fpu_v16_arm64:390 case fpu_v17_arm64:391 case fpu_v18_arm64:392 case fpu_v19_arm64:393 case fpu_v20_arm64:394 case fpu_v21_arm64:395 case fpu_v22_arm64:396 case fpu_v23_arm64:397 case fpu_v24_arm64:398 case fpu_v25_arm64:399 case fpu_v26_arm64:400 case fpu_v27_arm64:401 case fpu_v28_arm64:402 case fpu_v29_arm64:403 case fpu_v30_arm64:404 case fpu_v31_arm64:405 reg_value.SetBytes(tls_context.V[reg - fpu_v0_arm64].B, 16,406 endian::InlHostByteOrder());407 break;408 409 case fpu_s0_arm64:410 case fpu_s1_arm64:411 case fpu_s2_arm64:412 case fpu_s3_arm64:413 case fpu_s4_arm64:414 case fpu_s5_arm64:415 case fpu_s6_arm64:416 case fpu_s7_arm64:417 case fpu_s8_arm64:418 case fpu_s9_arm64:419 case fpu_s10_arm64:420 case fpu_s11_arm64:421 case fpu_s12_arm64:422 case fpu_s13_arm64:423 case fpu_s14_arm64:424 case fpu_s15_arm64:425 case fpu_s16_arm64:426 case fpu_s17_arm64:427 case fpu_s18_arm64:428 case fpu_s19_arm64:429 case fpu_s20_arm64:430 case fpu_s21_arm64:431 case fpu_s22_arm64:432 case fpu_s23_arm64:433 case fpu_s24_arm64:434 case fpu_s25_arm64:435 case fpu_s26_arm64:436 case fpu_s27_arm64:437 case fpu_s28_arm64:438 case fpu_s29_arm64:439 case fpu_s30_arm64:440 case fpu_s31_arm64:441 reg_value.SetFloat(tls_context.V[reg - fpu_s0_arm64].S[0]);442 break;443 444 case fpu_d0_arm64:445 case fpu_d1_arm64:446 case fpu_d2_arm64:447 case fpu_d3_arm64:448 case fpu_d4_arm64:449 case fpu_d5_arm64:450 case fpu_d6_arm64:451 case fpu_d7_arm64:452 case fpu_d8_arm64:453 case fpu_d9_arm64:454 case fpu_d10_arm64:455 case fpu_d11_arm64:456 case fpu_d12_arm64:457 case fpu_d13_arm64:458 case fpu_d14_arm64:459 case fpu_d15_arm64:460 case fpu_d16_arm64:461 case fpu_d17_arm64:462 case fpu_d18_arm64:463 case fpu_d19_arm64:464 case fpu_d20_arm64:465 case fpu_d21_arm64:466 case fpu_d22_arm64:467 case fpu_d23_arm64:468 case fpu_d24_arm64:469 case fpu_d25_arm64:470 case fpu_d26_arm64:471 case fpu_d27_arm64:472 case fpu_d28_arm64:473 case fpu_d29_arm64:474 case fpu_d30_arm64:475 case fpu_d31_arm64:476 reg_value.SetDouble(tls_context.V[reg - fpu_d0_arm64].D[0]);477 break;478 479 case fpu_fpsr_arm64:480 reg_value.SetUInt32(tls_context.Fpsr);481 break;482 483 case fpu_fpcr_arm64:484 reg_value.SetUInt32(tls_context.Fpcr);485 break;486 }487 488 return error;489}490 491Status492NativeRegisterContextWindows_arm64::FPRWrite(const uint32_t reg,493 const RegisterValue ®_value) {494 ::CONTEXT tls_context;495 DWORD context_flag = CONTEXT_CONTROL | CONTEXT_FLOATING_POINT;496 auto thread_handle = GetThreadHandle();497 Status error =498 GetThreadContextHelper(thread_handle, &tls_context, context_flag);499 if (error.Fail())500 return error;501 502 switch (reg) {503 case fpu_v0_arm64:504 case fpu_v1_arm64:505 case fpu_v2_arm64:506 case fpu_v3_arm64:507 case fpu_v4_arm64:508 case fpu_v5_arm64:509 case fpu_v6_arm64:510 case fpu_v7_arm64:511 case fpu_v8_arm64:512 case fpu_v9_arm64:513 case fpu_v10_arm64:514 case fpu_v11_arm64:515 case fpu_v12_arm64:516 case fpu_v13_arm64:517 case fpu_v14_arm64:518 case fpu_v15_arm64:519 case fpu_v16_arm64:520 case fpu_v17_arm64:521 case fpu_v18_arm64:522 case fpu_v19_arm64:523 case fpu_v20_arm64:524 case fpu_v21_arm64:525 case fpu_v22_arm64:526 case fpu_v23_arm64:527 case fpu_v24_arm64:528 case fpu_v25_arm64:529 case fpu_v26_arm64:530 case fpu_v27_arm64:531 case fpu_v28_arm64:532 case fpu_v29_arm64:533 case fpu_v30_arm64:534 case fpu_v31_arm64:535 memcpy(tls_context.V[reg - fpu_v0_arm64].B, reg_value.GetBytes(), 16);536 break;537 538 case fpu_s0_arm64:539 case fpu_s1_arm64:540 case fpu_s2_arm64:541 case fpu_s3_arm64:542 case fpu_s4_arm64:543 case fpu_s5_arm64:544 case fpu_s6_arm64:545 case fpu_s7_arm64:546 case fpu_s8_arm64:547 case fpu_s9_arm64:548 case fpu_s10_arm64:549 case fpu_s11_arm64:550 case fpu_s12_arm64:551 case fpu_s13_arm64:552 case fpu_s14_arm64:553 case fpu_s15_arm64:554 case fpu_s16_arm64:555 case fpu_s17_arm64:556 case fpu_s18_arm64:557 case fpu_s19_arm64:558 case fpu_s20_arm64:559 case fpu_s21_arm64:560 case fpu_s22_arm64:561 case fpu_s23_arm64:562 case fpu_s24_arm64:563 case fpu_s25_arm64:564 case fpu_s26_arm64:565 case fpu_s27_arm64:566 case fpu_s28_arm64:567 case fpu_s29_arm64:568 case fpu_s30_arm64:569 case fpu_s31_arm64:570 tls_context.V[reg - fpu_s0_arm64].S[0] = reg_value.GetAsFloat();571 break;572 573 case fpu_d0_arm64:574 case fpu_d1_arm64:575 case fpu_d2_arm64:576 case fpu_d3_arm64:577 case fpu_d4_arm64:578 case fpu_d5_arm64:579 case fpu_d6_arm64:580 case fpu_d7_arm64:581 case fpu_d8_arm64:582 case fpu_d9_arm64:583 case fpu_d10_arm64:584 case fpu_d11_arm64:585 case fpu_d12_arm64:586 case fpu_d13_arm64:587 case fpu_d14_arm64:588 case fpu_d15_arm64:589 case fpu_d16_arm64:590 case fpu_d17_arm64:591 case fpu_d18_arm64:592 case fpu_d19_arm64:593 case fpu_d20_arm64:594 case fpu_d21_arm64:595 case fpu_d22_arm64:596 case fpu_d23_arm64:597 case fpu_d24_arm64:598 case fpu_d25_arm64:599 case fpu_d26_arm64:600 case fpu_d27_arm64:601 case fpu_d28_arm64:602 case fpu_d29_arm64:603 case fpu_d30_arm64:604 case fpu_d31_arm64:605 tls_context.V[reg - fpu_d0_arm64].D[0] = reg_value.GetAsDouble();606 break;607 608 case fpu_fpsr_arm64:609 tls_context.Fpsr = reg_value.GetAsUInt32();610 break;611 612 case fpu_fpcr_arm64:613 tls_context.Fpcr = reg_value.GetAsUInt32();614 break;615 }616 617 return SetThreadContextHelper(thread_handle, &tls_context);618}619 620Status621NativeRegisterContextWindows_arm64::ReadRegister(const RegisterInfo *reg_info,622 RegisterValue ®_value) {623 Status error;624 if (!reg_info) {625 error = Status::FromErrorString("reg_info NULL");626 return error;627 }628 629 const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];630 if (reg == LLDB_INVALID_REGNUM) {631 // This is likely an internal register for lldb use only and should not be632 // directly queried.633 error = Status::FromErrorStringWithFormat(634 "register \"%s\" is an internal-only lldb "635 "register, cannot read directly",636 reg_info->name);637 return error;638 }639 640 if (IsGPR(reg))641 return GPRRead(reg, reg_value);642 643 if (IsFPR(reg))644 return FPRRead(reg, reg_value);645 646 return Status::FromErrorString("unimplemented");647}648 649Status NativeRegisterContextWindows_arm64::WriteRegister(650 const RegisterInfo *reg_info, const RegisterValue ®_value) {651 Status error;652 653 if (!reg_info) {654 error = Status::FromErrorString("reg_info NULL");655 return error;656 }657 658 const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];659 if (reg == LLDB_INVALID_REGNUM) {660 // This is likely an internal register for lldb use only and should not be661 // directly written.662 error = Status::FromErrorStringWithFormat(663 "register \"%s\" is an internal-only lldb "664 "register, cannot write directly",665 reg_info->name);666 return error;667 }668 669 if (IsGPR(reg))670 return GPRWrite(reg, reg_value);671 672 if (IsFPR(reg))673 return FPRWrite(reg, reg_value);674 675 return Status::FromErrorString("unimplemented");676}677 678Status NativeRegisterContextWindows_arm64::ReadAllRegisterValues(679 lldb::WritableDataBufferSP &data_sp) {680 const size_t data_size = REG_CONTEXT_SIZE;681 data_sp = std::make_shared<DataBufferHeap>(data_size, 0);682 ::CONTEXT tls_context;683 Status error =684 GetThreadContextHelper(GetThreadHandle(), &tls_context, CONTEXT_ALL);685 if (error.Fail())686 return error;687 688 uint8_t *dst = data_sp->GetBytes();689 ::memcpy(dst, &tls_context, data_size);690 return error;691}692 693Status NativeRegisterContextWindows_arm64::WriteAllRegisterValues(694 const lldb::DataBufferSP &data_sp) {695 Status error;696 const size_t data_size = REG_CONTEXT_SIZE;697 if (!data_sp) {698 error = Status::FromErrorStringWithFormat(699 "NativeRegisterContextWindows_arm64::%s invalid data_sp provided",700 __FUNCTION__);701 return error;702 }703 704 if (data_sp->GetByteSize() != data_size) {705 error = Status::FromErrorStringWithFormatv(706 "data_sp contained mismatched data size, expected {0}, actual {1}",707 data_size, data_sp->GetByteSize());708 return error;709 }710 711 ::CONTEXT tls_context;712 memcpy(&tls_context, data_sp->GetBytes(), data_size);713 return SetThreadContextHelper(GetThreadHandle(), &tls_context);714}715 716llvm::Error NativeRegisterContextWindows_arm64::ReadHardwareDebugInfo() {717 ::CONTEXT tls_context;718 Status error = GetThreadContextHelper(GetThreadHandle(), &tls_context,719 CONTEXT_DEBUG_REGISTERS);720 if (error.Fail())721 return error.ToError();722 723 for (uint32_t i = 0; i < m_max_hwp_supported; i++) {724 m_hwp_regs[i].address = tls_context.Wvr[i];725 m_hwp_regs[i].control = tls_context.Wcr[i];726 }727 728 return llvm::Error::success();729}730 731llvm::Error732NativeRegisterContextWindows_arm64::WriteHardwareDebugRegs(DREGType hwbType) {733 ::CONTEXT tls_context;734 Status error = GetThreadContextHelper(GetThreadHandle(), &tls_context,735 CONTEXT_DEBUG_REGISTERS);736 if (error.Fail())737 return error.ToError();738 739 if (hwbType == eDREGTypeWATCH) {740 for (uint32_t i = 0; i < m_max_hwp_supported; i++) {741 tls_context.Wvr[i] = m_hwp_regs[i].address;742 tls_context.Wcr[i] = m_hwp_regs[i].control;743 }744 }745 746 return SetThreadContextHelper(GetThreadHandle(), &tls_context).ToError();747}748 749#endif // defined(__aarch64__) || defined(_M_ARM64)750