1 //===-- NativeRegisterContextWindows_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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #if defined(__arm__) || defined(_M_ARM) 10 11 #include "NativeRegisterContextWindows_arm.h" 12 #include "NativeThreadWindows.h" 13 #include "Plugins/Process/Utility/RegisterInfoPOSIX_arm.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_arm[] = { 31 gpr_r0_arm, gpr_r1_arm, gpr_r2_arm, gpr_r3_arm, gpr_r4_arm, 32 gpr_r5_arm, gpr_r6_arm, gpr_r7_arm, gpr_r8_arm, gpr_r9_arm, 33 gpr_r10_arm, gpr_r11_arm, gpr_r12_arm, gpr_sp_arm, gpr_lr_arm, 34 gpr_pc_arm, gpr_cpsr_arm, 35 LLDB_INVALID_REGNUM // Register set must be terminated with this flag 36 }; 37 static_assert(((sizeof g_gpr_regnums_arm / sizeof g_gpr_regnums_arm[0]) - 1) == 38 k_num_gpr_registers_arm, 39 "g_gpr_regnums_arm has wrong number of register infos"); 40 41 static const uint32_t g_fpr_regnums_arm[] = { 42 fpu_s0_arm, fpu_s1_arm, fpu_s2_arm, fpu_s3_arm, fpu_s4_arm, 43 fpu_s5_arm, fpu_s6_arm, fpu_s7_arm, fpu_s8_arm, fpu_s9_arm, 44 fpu_s10_arm, fpu_s11_arm, fpu_s12_arm, fpu_s13_arm, fpu_s14_arm, 45 fpu_s15_arm, fpu_s16_arm, fpu_s17_arm, fpu_s18_arm, fpu_s19_arm, 46 fpu_s20_arm, fpu_s21_arm, fpu_s22_arm, fpu_s23_arm, fpu_s24_arm, 47 fpu_s25_arm, fpu_s26_arm, fpu_s27_arm, fpu_s28_arm, fpu_s29_arm, 48 fpu_s30_arm, fpu_s31_arm, 49 50 fpu_d0_arm, fpu_d1_arm, fpu_d2_arm, fpu_d3_arm, fpu_d4_arm, 51 fpu_d5_arm, fpu_d6_arm, fpu_d7_arm, fpu_d8_arm, fpu_d9_arm, 52 fpu_d10_arm, fpu_d11_arm, fpu_d12_arm, fpu_d13_arm, fpu_d14_arm, 53 fpu_d15_arm, fpu_d16_arm, fpu_d17_arm, fpu_d18_arm, fpu_d19_arm, 54 fpu_d20_arm, fpu_d21_arm, fpu_d22_arm, fpu_d23_arm, fpu_d24_arm, 55 fpu_d25_arm, fpu_d26_arm, fpu_d27_arm, fpu_d28_arm, fpu_d29_arm, 56 fpu_d30_arm, fpu_d31_arm, 57 58 fpu_q0_arm, fpu_q1_arm, fpu_q2_arm, fpu_q3_arm, fpu_q4_arm, 59 fpu_q5_arm, fpu_q6_arm, fpu_q7_arm, fpu_q8_arm, fpu_q9_arm, 60 fpu_q10_arm, fpu_q11_arm, fpu_q12_arm, fpu_q13_arm, fpu_q14_arm, 61 fpu_q15_arm, 62 63 fpu_fpscr_arm, 64 LLDB_INVALID_REGNUM // Register set must be terminated with this flag 65 }; 66 static_assert(((sizeof g_fpr_regnums_arm / sizeof g_fpr_regnums_arm[0]) - 1) == 67 k_num_fpr_registers_arm, 68 "g_fpu_regnums_arm has wrong number of register infos"); 69 70 static const RegisterSet g_reg_sets_arm[] = { 71 {"General Purpose Registers", "gpr", std::size(g_gpr_regnums_arm) - 1, 72 g_gpr_regnums_arm}, 73 {"Floating Point Registers", "fpr", std::size(g_fpr_regnums_arm) - 1, 74 g_fpr_regnums_arm}, 75 }; 76 77 enum { k_num_register_sets = 2 }; 78 79 } // namespace 80 81 static RegisterInfoInterface * 82 CreateRegisterInfoInterface(const ArchSpec &target_arch) { 83 assert((HostInfo::GetArchitecture().GetAddressByteSize() == 4) && 84 "Register setting path assumes this is a 32-bit host"); 85 return new RegisterInfoPOSIX_arm(target_arch); 86 } 87 88 static Status GetThreadContextHelper(lldb::thread_t thread_handle, 89 PCONTEXT context_ptr, 90 const DWORD control_flag) { 91 Log *log = GetLog(WindowsLog::Registers); 92 Status error; 93 94 memset(context_ptr, 0, sizeof(::CONTEXT)); 95 context_ptr->ContextFlags = control_flag; 96 if (!::GetThreadContext(thread_handle, context_ptr)) { 97 error = Status(GetLastError(), eErrorTypeWin32); 98 LLDB_LOG(log, "{0} GetThreadContext failed with error {1}", __FUNCTION__, 99 error); 100 return error; 101 } 102 return Status(); 103 } 104 105 static Status SetThreadContextHelper(lldb::thread_t thread_handle, 106 PCONTEXT context_ptr) { 107 Log *log = GetLog(WindowsLog::Registers); 108 Status error; 109 // It's assumed that the thread has stopped. 110 if (!::SetThreadContext(thread_handle, context_ptr)) { 111 error = Status(GetLastError(), eErrorTypeWin32); 112 LLDB_LOG(log, "{0} SetThreadContext failed with error {1}", __FUNCTION__, 113 error); 114 return error; 115 } 116 return Status(); 117 } 118 119 std::unique_ptr<NativeRegisterContextWindows> 120 NativeRegisterContextWindows::CreateHostNativeRegisterContextWindows( 121 const ArchSpec &target_arch, NativeThreadProtocol &native_thread) { 122 // TODO: Register context for a WoW64 application? 123 124 // Register context for a native 64-bit application. 125 return std::make_unique<NativeRegisterContextWindows_arm>(target_arch, 126 native_thread); 127 } 128 129 NativeRegisterContextWindows_arm::NativeRegisterContextWindows_arm( 130 const ArchSpec &target_arch, NativeThreadProtocol &native_thread) 131 : NativeRegisterContextWindows(native_thread, 132 CreateRegisterInfoInterface(target_arch)) {} 133 134 bool NativeRegisterContextWindows_arm::IsGPR(uint32_t reg_index) const { 135 return (reg_index >= k_first_gpr_arm && reg_index <= k_last_gpr_arm); 136 } 137 138 bool NativeRegisterContextWindows_arm::IsFPR(uint32_t reg_index) const { 139 return (reg_index >= k_first_fpr_arm && reg_index <= k_last_fpr_arm); 140 } 141 142 uint32_t NativeRegisterContextWindows_arm::GetRegisterSetCount() const { 143 return k_num_register_sets; 144 } 145 146 const RegisterSet * 147 NativeRegisterContextWindows_arm::GetRegisterSet(uint32_t set_index) const { 148 if (set_index >= k_num_register_sets) 149 return nullptr; 150 return &g_reg_sets_arm[set_index]; 151 } 152 153 Status NativeRegisterContextWindows_arm::GPRRead(const uint32_t reg, 154 RegisterValue ®_value) { 155 ::CONTEXT tls_context; 156 DWORD context_flag = CONTEXT_CONTROL | CONTEXT_INTEGER; 157 Status error = 158 GetThreadContextHelper(GetThreadHandle(), &tls_context, context_flag); 159 if (error.Fail()) 160 return error; 161 162 switch (reg) { 163 case gpr_r0_arm: 164 reg_value.SetUInt32(tls_context.R0); 165 break; 166 case gpr_r1_arm: 167 reg_value.SetUInt32(tls_context.R1); 168 break; 169 case gpr_r2_arm: 170 reg_value.SetUInt32(tls_context.R2); 171 break; 172 case gpr_r3_arm: 173 reg_value.SetUInt32(tls_context.R3); 174 break; 175 case gpr_r4_arm: 176 reg_value.SetUInt32(tls_context.R4); 177 break; 178 case gpr_r5_arm: 179 reg_value.SetUInt32(tls_context.R5); 180 break; 181 case gpr_r6_arm: 182 reg_value.SetUInt32(tls_context.R6); 183 break; 184 case gpr_r7_arm: 185 reg_value.SetUInt32(tls_context.R7); 186 break; 187 case gpr_r8_arm: 188 reg_value.SetUInt32(tls_context.R8); 189 break; 190 case gpr_r9_arm: 191 reg_value.SetUInt32(tls_context.R9); 192 break; 193 case gpr_r10_arm: 194 reg_value.SetUInt32(tls_context.R10); 195 break; 196 case gpr_r11_arm: 197 reg_value.SetUInt32(tls_context.R11); 198 break; 199 case gpr_r12_arm: 200 reg_value.SetUInt32(tls_context.R12); 201 break; 202 case gpr_sp_arm: 203 reg_value.SetUInt32(tls_context.Sp); 204 break; 205 case gpr_lr_arm: 206 reg_value.SetUInt32(tls_context.Lr); 207 break; 208 case gpr_pc_arm: 209 reg_value.SetUInt32(tls_context.Pc); 210 break; 211 case gpr_cpsr_arm: 212 reg_value.SetUInt32(tls_context.Cpsr); 213 break; 214 } 215 216 return error; 217 } 218 219 Status 220 NativeRegisterContextWindows_arm::GPRWrite(const uint32_t reg, 221 const RegisterValue ®_value) { 222 ::CONTEXT tls_context; 223 DWORD context_flag = CONTEXT_CONTROL | CONTEXT_INTEGER; 224 auto thread_handle = GetThreadHandle(); 225 Status error = 226 GetThreadContextHelper(thread_handle, &tls_context, context_flag); 227 if (error.Fail()) 228 return error; 229 230 switch (reg) { 231 case gpr_r0_arm: 232 tls_context.R0 = reg_value.GetAsUInt32(); 233 break; 234 case gpr_r1_arm: 235 tls_context.R1 = reg_value.GetAsUInt32(); 236 break; 237 case gpr_r2_arm: 238 tls_context.R2 = reg_value.GetAsUInt32(); 239 break; 240 case gpr_r3_arm: 241 tls_context.R3 = reg_value.GetAsUInt32(); 242 break; 243 case gpr_r4_arm: 244 tls_context.R4 = reg_value.GetAsUInt32(); 245 break; 246 case gpr_r5_arm: 247 tls_context.R5 = reg_value.GetAsUInt32(); 248 break; 249 case gpr_r6_arm: 250 tls_context.R6 = reg_value.GetAsUInt32(); 251 break; 252 case gpr_r7_arm: 253 tls_context.R7 = reg_value.GetAsUInt32(); 254 break; 255 case gpr_r8_arm: 256 tls_context.R8 = reg_value.GetAsUInt32(); 257 break; 258 case gpr_r9_arm: 259 tls_context.R9 = reg_value.GetAsUInt32(); 260 break; 261 case gpr_r10_arm: 262 tls_context.R10 = reg_value.GetAsUInt32(); 263 break; 264 case gpr_r11_arm: 265 tls_context.R11 = reg_value.GetAsUInt32(); 266 break; 267 case gpr_r12_arm: 268 tls_context.R12 = reg_value.GetAsUInt32(); 269 break; 270 case gpr_sp_arm: 271 tls_context.Sp = reg_value.GetAsUInt32(); 272 break; 273 case gpr_lr_arm: 274 tls_context.Lr = reg_value.GetAsUInt32(); 275 break; 276 case gpr_pc_arm: 277 tls_context.Pc = reg_value.GetAsUInt32(); 278 break; 279 case gpr_cpsr_arm: 280 tls_context.Cpsr = reg_value.GetAsUInt32(); 281 break; 282 } 283 284 return SetThreadContextHelper(thread_handle, &tls_context); 285 } 286 287 Status NativeRegisterContextWindows_arm::FPRRead(const uint32_t reg, 288 RegisterValue ®_value) { 289 ::CONTEXT tls_context; 290 DWORD context_flag = CONTEXT_CONTROL | CONTEXT_FLOATING_POINT; 291 Status error = 292 GetThreadContextHelper(GetThreadHandle(), &tls_context, context_flag); 293 if (error.Fail()) 294 return error; 295 296 switch (reg) { 297 case fpu_s0_arm: 298 case fpu_s1_arm: 299 case fpu_s2_arm: 300 case fpu_s3_arm: 301 case fpu_s4_arm: 302 case fpu_s5_arm: 303 case fpu_s6_arm: 304 case fpu_s7_arm: 305 case fpu_s8_arm: 306 case fpu_s9_arm: 307 case fpu_s10_arm: 308 case fpu_s11_arm: 309 case fpu_s12_arm: 310 case fpu_s13_arm: 311 case fpu_s14_arm: 312 case fpu_s15_arm: 313 case fpu_s16_arm: 314 case fpu_s17_arm: 315 case fpu_s18_arm: 316 case fpu_s19_arm: 317 case fpu_s20_arm: 318 case fpu_s21_arm: 319 case fpu_s22_arm: 320 case fpu_s23_arm: 321 case fpu_s24_arm: 322 case fpu_s25_arm: 323 case fpu_s26_arm: 324 case fpu_s27_arm: 325 case fpu_s28_arm: 326 case fpu_s29_arm: 327 case fpu_s30_arm: 328 case fpu_s31_arm: 329 reg_value.SetUInt32(tls_context.S[reg - fpu_s0_arm], 330 RegisterValue::eTypeFloat); 331 break; 332 333 case fpu_d0_arm: 334 case fpu_d1_arm: 335 case fpu_d2_arm: 336 case fpu_d3_arm: 337 case fpu_d4_arm: 338 case fpu_d5_arm: 339 case fpu_d6_arm: 340 case fpu_d7_arm: 341 case fpu_d8_arm: 342 case fpu_d9_arm: 343 case fpu_d10_arm: 344 case fpu_d11_arm: 345 case fpu_d12_arm: 346 case fpu_d13_arm: 347 case fpu_d14_arm: 348 case fpu_d15_arm: 349 case fpu_d16_arm: 350 case fpu_d17_arm: 351 case fpu_d18_arm: 352 case fpu_d19_arm: 353 case fpu_d20_arm: 354 case fpu_d21_arm: 355 case fpu_d22_arm: 356 case fpu_d23_arm: 357 case fpu_d24_arm: 358 case fpu_d25_arm: 359 case fpu_d26_arm: 360 case fpu_d27_arm: 361 case fpu_d28_arm: 362 case fpu_d29_arm: 363 case fpu_d30_arm: 364 case fpu_d31_arm: 365 reg_value.SetUInt64(tls_context.D[reg - fpu_d0_arm], 366 RegisterValue::eTypeDouble); 367 break; 368 369 case fpu_q0_arm: 370 case fpu_q1_arm: 371 case fpu_q2_arm: 372 case fpu_q3_arm: 373 case fpu_q4_arm: 374 case fpu_q5_arm: 375 case fpu_q6_arm: 376 case fpu_q7_arm: 377 case fpu_q8_arm: 378 case fpu_q9_arm: 379 case fpu_q10_arm: 380 case fpu_q11_arm: 381 case fpu_q12_arm: 382 case fpu_q13_arm: 383 case fpu_q14_arm: 384 case fpu_q15_arm: 385 reg_value.SetBytes(&tls_context.Q[reg - fpu_q0_arm], 16, 386 endian::InlHostByteOrder()); 387 break; 388 389 case fpu_fpscr_arm: 390 reg_value.SetUInt32(tls_context.Fpscr); 391 break; 392 } 393 394 return error; 395 } 396 397 Status 398 NativeRegisterContextWindows_arm::FPRWrite(const uint32_t reg, 399 const RegisterValue ®_value) { 400 ::CONTEXT tls_context; 401 DWORD context_flag = CONTEXT_CONTROL | CONTEXT_FLOATING_POINT; 402 auto thread_handle = GetThreadHandle(); 403 Status error = 404 GetThreadContextHelper(thread_handle, &tls_context, context_flag); 405 if (error.Fail()) 406 return error; 407 408 switch (reg) { 409 case fpu_s0_arm: 410 case fpu_s1_arm: 411 case fpu_s2_arm: 412 case fpu_s3_arm: 413 case fpu_s4_arm: 414 case fpu_s5_arm: 415 case fpu_s6_arm: 416 case fpu_s7_arm: 417 case fpu_s8_arm: 418 case fpu_s9_arm: 419 case fpu_s10_arm: 420 case fpu_s11_arm: 421 case fpu_s12_arm: 422 case fpu_s13_arm: 423 case fpu_s14_arm: 424 case fpu_s15_arm: 425 case fpu_s16_arm: 426 case fpu_s17_arm: 427 case fpu_s18_arm: 428 case fpu_s19_arm: 429 case fpu_s20_arm: 430 case fpu_s21_arm: 431 case fpu_s22_arm: 432 case fpu_s23_arm: 433 case fpu_s24_arm: 434 case fpu_s25_arm: 435 case fpu_s26_arm: 436 case fpu_s27_arm: 437 case fpu_s28_arm: 438 case fpu_s29_arm: 439 case fpu_s30_arm: 440 case fpu_s31_arm: 441 tls_context.S[reg - fpu_s0_arm] = reg_value.GetAsUInt32(); 442 break; 443 444 case fpu_d0_arm: 445 case fpu_d1_arm: 446 case fpu_d2_arm: 447 case fpu_d3_arm: 448 case fpu_d4_arm: 449 case fpu_d5_arm: 450 case fpu_d6_arm: 451 case fpu_d7_arm: 452 case fpu_d8_arm: 453 case fpu_d9_arm: 454 case fpu_d10_arm: 455 case fpu_d11_arm: 456 case fpu_d12_arm: 457 case fpu_d13_arm: 458 case fpu_d14_arm: 459 case fpu_d15_arm: 460 case fpu_d16_arm: 461 case fpu_d17_arm: 462 case fpu_d18_arm: 463 case fpu_d19_arm: 464 case fpu_d20_arm: 465 case fpu_d21_arm: 466 case fpu_d22_arm: 467 case fpu_d23_arm: 468 case fpu_d24_arm: 469 case fpu_d25_arm: 470 case fpu_d26_arm: 471 case fpu_d27_arm: 472 case fpu_d28_arm: 473 case fpu_d29_arm: 474 case fpu_d30_arm: 475 case fpu_d31_arm: 476 tls_context.D[reg - fpu_d0_arm] = reg_value.GetAsUInt64(); 477 break; 478 479 case fpu_q0_arm: 480 case fpu_q1_arm: 481 case fpu_q2_arm: 482 case fpu_q3_arm: 483 case fpu_q4_arm: 484 case fpu_q5_arm: 485 case fpu_q6_arm: 486 case fpu_q7_arm: 487 case fpu_q8_arm: 488 case fpu_q9_arm: 489 case fpu_q10_arm: 490 case fpu_q11_arm: 491 case fpu_q12_arm: 492 case fpu_q13_arm: 493 case fpu_q14_arm: 494 case fpu_q15_arm: 495 memcpy(&tls_context.Q[reg - fpu_q0_arm], reg_value.GetBytes(), 16); 496 break; 497 498 case fpu_fpscr_arm: 499 tls_context.Fpscr = reg_value.GetAsUInt32(); 500 break; 501 } 502 503 return SetThreadContextHelper(thread_handle, &tls_context); 504 } 505 506 Status 507 NativeRegisterContextWindows_arm::ReadRegister(const RegisterInfo *reg_info, 508 RegisterValue ®_value) { 509 Status error; 510 if (!reg_info) { 511 error = Status::FromErrorString("reg_info NULL"); 512 return error; 513 } 514 515 const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB]; 516 if (reg == LLDB_INVALID_REGNUM) { 517 // This is likely an internal register for lldb use only and should not be 518 // directly queried. 519 error = Status::FromErrorStringWithFormat( 520 "register \"%s\" is an internal-only lldb " 521 "register, cannot read directly", 522 reg_info->name); 523 return error; 524 } 525 526 if (IsGPR(reg)) 527 return GPRRead(reg, reg_value); 528 529 if (IsFPR(reg)) 530 return FPRRead(reg, reg_value); 531 532 return Status::FromErrorString("unimplemented"); 533 } 534 535 Status NativeRegisterContextWindows_arm::WriteRegister( 536 const RegisterInfo *reg_info, const RegisterValue ®_value) { 537 Status error; 538 539 if (!reg_info) { 540 error = Status::FromErrorString("reg_info NULL"); 541 return error; 542 } 543 544 const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB]; 545 if (reg == LLDB_INVALID_REGNUM) { 546 // This is likely an internal register for lldb use only and should not be 547 // directly written. 548 error = Status::FromErrorStringWithFormat( 549 "register \"%s\" is an internal-only lldb " 550 "register, cannot write directly", 551 reg_info->name); 552 return error; 553 } 554 555 if (IsGPR(reg)) 556 return GPRWrite(reg, reg_value); 557 558 if (IsFPR(reg)) 559 return FPRWrite(reg, reg_value); 560 561 return Status::FromErrorString("unimplemented"); 562 } 563 564 Status NativeRegisterContextWindows_arm::ReadAllRegisterValues( 565 lldb::WritableDataBufferSP &data_sp) { 566 const size_t data_size = REG_CONTEXT_SIZE; 567 data_sp = std::make_shared<DataBufferHeap>(data_size, 0); 568 ::CONTEXT tls_context; 569 Status error = 570 GetThreadContextHelper(GetThreadHandle(), &tls_context, CONTEXT_ALL); 571 if (error.Fail()) 572 return error; 573 574 uint8_t *dst = data_sp->GetBytes(); 575 ::memcpy(dst, &tls_context, data_size); 576 return error; 577 } 578 579 Status NativeRegisterContextWindows_arm::WriteAllRegisterValues( 580 const lldb::DataBufferSP &data_sp) { 581 Status error; 582 const size_t data_size = REG_CONTEXT_SIZE; 583 if (!data_sp) { 584 error = Status::FromErrorStringWithFormat( 585 "NativeRegisterContextWindows_arm::%s invalid data_sp provided", 586 __FUNCTION__); 587 return error; 588 } 589 590 if (data_sp->GetByteSize() != data_size) { 591 error = Status::FromErrorStringWithFormatv( 592 "data_sp contained mismatched data size, expected {0}, actual {1}", 593 data_size, data_sp->GetByteSize()); 594 return error; 595 } 596 597 ::CONTEXT tls_context; 598 memcpy(&tls_context, data_sp->GetBytes(), data_size); 599 return SetThreadContextHelper(GetThreadHandle(), &tls_context); 600 } 601 602 Status NativeRegisterContextWindows_arm::IsWatchpointHit(uint32_t wp_index, 603 bool &is_hit) { 604 return Status::FromErrorString("unimplemented"); 605 } 606 607 Status NativeRegisterContextWindows_arm::GetWatchpointHitIndex( 608 uint32_t &wp_index, lldb::addr_t trap_addr) { 609 return Status::FromErrorString("unimplemented"); 610 } 611 612 Status NativeRegisterContextWindows_arm::IsWatchpointVacant(uint32_t wp_index, 613 bool &is_vacant) { 614 return Status::FromErrorString("unimplemented"); 615 } 616 617 Status NativeRegisterContextWindows_arm::SetHardwareWatchpointWithIndex( 618 lldb::addr_t addr, size_t size, uint32_t watch_flags, uint32_t wp_index) { 619 return Status::FromErrorString("unimplemented"); 620 } 621 622 bool NativeRegisterContextWindows_arm::ClearHardwareWatchpoint( 623 uint32_t wp_index) { 624 return false; 625 } 626 627 Status NativeRegisterContextWindows_arm::ClearAllHardwareWatchpoints() { 628 return Status::FromErrorString("unimplemented"); 629 } 630 631 uint32_t NativeRegisterContextWindows_arm::SetHardwareWatchpoint( 632 lldb::addr_t addr, size_t size, uint32_t watch_flags) { 633 return LLDB_INVALID_INDEX32; 634 } 635 636 lldb::addr_t 637 NativeRegisterContextWindows_arm::GetWatchpointAddress(uint32_t wp_index) { 638 return LLDB_INVALID_ADDRESS; 639 } 640 641 uint32_t NativeRegisterContextWindows_arm::NumSupportedHardwareWatchpoints() { 642 // Not implemented 643 return 0; 644 } 645 646 #endif // defined(__arm__) || defined(_M_ARM) 647