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