1 //===-- NativeRegisterContextLinux_arm.cpp --------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #if defined(__arm__) 11 12 #include "NativeRegisterContextLinux_arm.h" 13 14 #include "lldb/Core/DataBufferHeap.h" 15 #include "lldb/Core/Error.h" 16 #include "lldb/Core/Log.h" 17 #include "lldb/Core/RegisterValue.h" 18 19 #include "Plugins/Process/Utility/RegisterContextLinux_arm.h" 20 21 #define REG_CONTEXT_SIZE (GetGPRSize() + sizeof (m_fpr)) 22 23 #ifndef PTRACE_GETVFPREGS 24 #define PTRACE_GETVFPREGS 27 25 #define PTRACE_SETVFPREGS 28 26 #endif 27 #ifndef PTRACE_GETHBPREGS 28 #define PTRACE_GETHBPREGS 29 29 #define PTRACE_SETHBPREGS 30 30 #endif 31 #if !defined(PTRACE_TYPE_ARG3) 32 #define PTRACE_TYPE_ARG3 void * 33 #endif 34 #if !defined(PTRACE_TYPE_ARG4) 35 #define PTRACE_TYPE_ARG4 void * 36 #endif 37 38 using namespace lldb; 39 using namespace lldb_private; 40 using namespace lldb_private::process_linux; 41 42 // arm general purpose registers. 43 static const uint32_t g_gpr_regnums_arm[] = 44 { 45 gpr_r0_arm, 46 gpr_r1_arm, 47 gpr_r2_arm, 48 gpr_r3_arm, 49 gpr_r4_arm, 50 gpr_r5_arm, 51 gpr_r6_arm, 52 gpr_r7_arm, 53 gpr_r8_arm, 54 gpr_r9_arm, 55 gpr_r10_arm, 56 gpr_r11_arm, 57 gpr_r12_arm, 58 gpr_sp_arm, 59 gpr_lr_arm, 60 gpr_pc_arm, 61 gpr_cpsr_arm, 62 LLDB_INVALID_REGNUM // register sets need to end with this flag 63 }; 64 static_assert(((sizeof g_gpr_regnums_arm / sizeof g_gpr_regnums_arm[0]) - 1) == k_num_gpr_registers_arm, \ 65 "g_gpr_regnums_arm has wrong number of register infos"); 66 67 // arm floating point registers. 68 static const uint32_t g_fpu_regnums_arm[] = 69 { 70 fpu_s0_arm, 71 fpu_s1_arm, 72 fpu_s2_arm, 73 fpu_s3_arm, 74 fpu_s4_arm, 75 fpu_s5_arm, 76 fpu_s6_arm, 77 fpu_s7_arm, 78 fpu_s8_arm, 79 fpu_s9_arm, 80 fpu_s10_arm, 81 fpu_s11_arm, 82 fpu_s12_arm, 83 fpu_s13_arm, 84 fpu_s14_arm, 85 fpu_s15_arm, 86 fpu_s16_arm, 87 fpu_s17_arm, 88 fpu_s18_arm, 89 fpu_s19_arm, 90 fpu_s20_arm, 91 fpu_s21_arm, 92 fpu_s22_arm, 93 fpu_s23_arm, 94 fpu_s24_arm, 95 fpu_s25_arm, 96 fpu_s26_arm, 97 fpu_s27_arm, 98 fpu_s28_arm, 99 fpu_s29_arm, 100 fpu_s30_arm, 101 fpu_s31_arm, 102 fpu_fpscr_arm, 103 LLDB_INVALID_REGNUM // register sets need to end with this flag 104 }; 105 static_assert(((sizeof g_fpu_regnums_arm / sizeof g_fpu_regnums_arm[0]) - 1) == k_num_fpr_registers_arm, \ 106 "g_fpu_regnums_arm has wrong number of register infos"); 107 108 namespace { 109 // Number of register sets provided by this context. 110 enum 111 { 112 k_num_register_sets = 2 113 }; 114 } 115 116 // Register sets for arm. 117 static const RegisterSet 118 g_reg_sets_arm[k_num_register_sets] = 119 { 120 { "General Purpose Registers", "gpr", k_num_gpr_registers_arm, g_gpr_regnums_arm }, 121 { "Floating Point Registers", "fpu", k_num_fpr_registers_arm, g_fpu_regnums_arm } 122 }; 123 124 NativeRegisterContextLinux* 125 NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(const ArchSpec& target_arch, 126 NativeThreadProtocol &native_thread, 127 uint32_t concrete_frame_idx) 128 { 129 return new NativeRegisterContextLinux_arm(target_arch, native_thread, concrete_frame_idx); 130 } 131 132 NativeRegisterContextLinux_arm::NativeRegisterContextLinux_arm (const ArchSpec& target_arch, 133 NativeThreadProtocol &native_thread, 134 uint32_t concrete_frame_idx) : 135 NativeRegisterContextLinux (native_thread, concrete_frame_idx, new RegisterContextLinux_arm(target_arch)) 136 { 137 switch (target_arch.GetMachine()) 138 { 139 case llvm::Triple::arm: 140 m_reg_info.num_registers = k_num_registers_arm; 141 m_reg_info.num_gpr_registers = k_num_gpr_registers_arm; 142 m_reg_info.num_fpr_registers = k_num_fpr_registers_arm; 143 m_reg_info.last_gpr = k_last_gpr_arm; 144 m_reg_info.first_fpr = k_first_fpr_arm; 145 m_reg_info.last_fpr = k_last_fpr_arm; 146 m_reg_info.first_fpr_v = fpu_s0_arm; 147 m_reg_info.last_fpr_v = fpu_s31_arm; 148 m_reg_info.gpr_flags = gpr_cpsr_arm; 149 break; 150 default: 151 assert(false && "Unhandled target architecture."); 152 break; 153 } 154 155 ::memset(&m_fpr, 0, sizeof (m_fpr)); 156 ::memset(&m_gpr_arm, 0, sizeof (m_gpr_arm)); 157 ::memset(&m_hwp_regs, 0, sizeof (m_hwp_regs)); 158 159 // 16 is just a maximum value, query hardware for actual watchpoint count 160 m_max_hwp_supported = 16; 161 m_max_hbp_supported = 16; 162 m_refresh_hwdebug_info = true; 163 } 164 165 uint32_t 166 NativeRegisterContextLinux_arm::GetRegisterSetCount () const 167 { 168 return k_num_register_sets; 169 } 170 171 uint32_t 172 NativeRegisterContextLinux_arm::GetUserRegisterCount() const 173 { 174 uint32_t count = 0; 175 for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index) 176 count += g_reg_sets_arm[set_index].num_registers; 177 return count; 178 } 179 180 const RegisterSet * 181 NativeRegisterContextLinux_arm::GetRegisterSet (uint32_t set_index) const 182 { 183 if (set_index < k_num_register_sets) 184 return &g_reg_sets_arm[set_index]; 185 186 return nullptr; 187 } 188 189 Error 190 NativeRegisterContextLinux_arm::ReadRegister (const RegisterInfo *reg_info, RegisterValue ®_value) 191 { 192 Error error; 193 194 if (!reg_info) 195 { 196 error.SetErrorString ("reg_info NULL"); 197 return error; 198 } 199 200 const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB]; 201 202 if (IsFPR(reg)) 203 { 204 error = ReadFPR(); 205 if (error.Fail()) 206 return error; 207 } 208 else 209 { 210 uint32_t full_reg = reg; 211 bool is_subreg = reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM); 212 213 if (is_subreg) 214 { 215 // Read the full aligned 64-bit register. 216 full_reg = reg_info->invalidate_regs[0]; 217 } 218 219 error = ReadRegisterRaw(full_reg, reg_value); 220 221 if (error.Success ()) 222 { 223 // If our read was not aligned (for ah,bh,ch,dh), shift our returned value one byte to the right. 224 if (is_subreg && (reg_info->byte_offset & 0x1)) 225 reg_value.SetUInt64(reg_value.GetAsUInt64() >> 8); 226 227 // If our return byte size was greater than the return value reg size, then 228 // use the type specified by reg_info rather than the uint64_t default 229 if (reg_value.GetByteSize() > reg_info->byte_size) 230 reg_value.SetType(reg_info); 231 } 232 return error; 233 } 234 235 // Get pointer to m_fpr variable and set the data from it. 236 uint32_t fpr_offset = CalculateFprOffset(reg_info); 237 assert (fpr_offset < sizeof m_fpr); 238 uint8_t *src = (uint8_t *)&m_fpr + fpr_offset; 239 switch (reg_info->byte_size) 240 { 241 case 2: 242 reg_value.SetUInt16(*(uint16_t *)src); 243 break; 244 case 4: 245 reg_value.SetUInt32(*(uint32_t *)src); 246 break; 247 case 8: 248 reg_value.SetUInt64(*(uint64_t *)src); 249 break; 250 default: 251 assert(false && "Unhandled data size."); 252 error.SetErrorStringWithFormat ("unhandled byte size: %" PRIu32, reg_info->byte_size); 253 break; 254 } 255 256 return error; 257 } 258 259 Error 260 NativeRegisterContextLinux_arm::WriteRegister (const RegisterInfo *reg_info, const RegisterValue ®_value) 261 { 262 if (!reg_info) 263 return Error ("reg_info NULL"); 264 265 const uint32_t reg_index = reg_info->kinds[lldb::eRegisterKindLLDB]; 266 if (reg_index == LLDB_INVALID_REGNUM) 267 return Error ("no lldb regnum for %s", reg_info && reg_info->name ? reg_info->name : "<unknown register>"); 268 269 if (IsGPR(reg_index)) 270 return WriteRegisterRaw(reg_index, reg_value); 271 272 if (IsFPR(reg_index)) 273 { 274 // Get pointer to m_fpr variable and set the data to it. 275 uint32_t fpr_offset = CalculateFprOffset(reg_info); 276 assert (fpr_offset < sizeof m_fpr); 277 uint8_t *dst = (uint8_t *)&m_fpr + fpr_offset; 278 switch (reg_info->byte_size) 279 { 280 case 2: 281 *(uint16_t *)dst = reg_value.GetAsUInt16(); 282 break; 283 case 4: 284 *(uint32_t *)dst = reg_value.GetAsUInt32(); 285 break; 286 case 8: 287 *(uint64_t *)dst = reg_value.GetAsUInt64(); 288 break; 289 default: 290 assert(false && "Unhandled data size."); 291 return Error ("unhandled register data size %" PRIu32, reg_info->byte_size); 292 } 293 294 Error error = WriteFPR(); 295 if (error.Fail()) 296 return error; 297 298 return Error (); 299 } 300 301 return Error ("failed - register wasn't recognized to be a GPR or an FPR, write strategy unknown"); 302 } 303 304 Error 305 NativeRegisterContextLinux_arm::ReadAllRegisterValues (lldb::DataBufferSP &data_sp) 306 { 307 Error error; 308 309 data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0)); 310 if (!data_sp) 311 return Error ("failed to allocate DataBufferHeap instance of size %" PRIu64, (uint64_t)REG_CONTEXT_SIZE); 312 313 error = ReadGPR(); 314 if (error.Fail()) 315 return error; 316 317 error = ReadFPR(); 318 if (error.Fail()) 319 return error; 320 321 uint8_t *dst = data_sp->GetBytes (); 322 if (dst == nullptr) 323 { 324 error.SetErrorStringWithFormat ("DataBufferHeap instance of size %" PRIu64 " returned a null pointer", (uint64_t)REG_CONTEXT_SIZE); 325 return error; 326 } 327 328 ::memcpy (dst, &m_gpr_arm, GetGPRSize()); 329 dst += GetGPRSize(); 330 ::memcpy (dst, &m_fpr, sizeof(m_fpr)); 331 332 return error; 333 } 334 335 Error 336 NativeRegisterContextLinux_arm::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp) 337 { 338 Error error; 339 340 if (!data_sp) 341 { 342 error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s invalid data_sp provided", __FUNCTION__); 343 return error; 344 } 345 346 if (data_sp->GetByteSize () != REG_CONTEXT_SIZE) 347 { 348 error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s data_sp contained mismatched data size, expected %" PRIu64 ", actual %" PRIu64, __FUNCTION__, (uint64_t)REG_CONTEXT_SIZE, data_sp->GetByteSize ()); 349 return error; 350 } 351 352 353 uint8_t *src = data_sp->GetBytes (); 354 if (src == nullptr) 355 { 356 error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s DataBuffer::GetBytes() returned a null pointer", __FUNCTION__); 357 return error; 358 } 359 ::memcpy (&m_gpr_arm, src, GetRegisterInfoInterface ().GetGPRSize ()); 360 361 error = WriteGPR(); 362 if (error.Fail()) 363 return error; 364 365 src += GetRegisterInfoInterface ().GetGPRSize (); 366 ::memcpy (&m_fpr, src, sizeof(m_fpr)); 367 368 error = WriteFPR(); 369 if (error.Fail()) 370 return error; 371 372 return error; 373 } 374 375 bool 376 NativeRegisterContextLinux_arm::IsGPR(unsigned reg) const 377 { 378 return reg <= m_reg_info.last_gpr; // GPR's come first. 379 } 380 381 bool 382 NativeRegisterContextLinux_arm::IsFPR(unsigned reg) const 383 { 384 return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr); 385 } 386 387 uint32_t 388 NativeRegisterContextLinux_arm::SetHardwareBreakpoint (lldb::addr_t addr, size_t size) 389 { 390 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS)); 391 392 if (log) 393 log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__); 394 395 Error error; 396 397 // Read hardware breakpoint and watchpoint information. 398 error = ReadHardwareDebugInfo (); 399 400 if (error.Fail()) 401 return LLDB_INVALID_INDEX32; 402 403 uint32_t control_value = 0, bp_index = 0; 404 405 // Check if size has a valid hardware breakpoint length. 406 // Thumb instructions are 2-bytes but we have no way here to determine 407 // if target address is a thumb or arm instruction. 408 // TODO: Add support for setting thumb mode hardware breakpoints 409 if (size != 4 && size != 2) 410 return LLDB_INVALID_INDEX32; 411 412 // Setup control value 413 // Make the byte_mask into a valid Byte Address Select mask 414 control_value = 0xfu << 5; 415 416 // Enable this breakpoint and make it stop in privileged or user mode; 417 control_value |= 7; 418 419 // Make sure bits 1:0 are clear in our address 420 // This should be different once we support thumb here. 421 addr &= ~((lldb::addr_t)3); 422 423 // Iterate over stored hardware breakpoints 424 // Find a free bp_index or update reference count if duplicate. 425 bp_index = LLDB_INVALID_INDEX32; 426 427 for (uint32_t i = 0; i < m_max_hbp_supported; i++) 428 { 429 if ((m_hbr_regs[i].control & 1) == 0) 430 { 431 bp_index = i; // Mark last free slot 432 } 433 else if (m_hbr_regs[i].address == addr && m_hbr_regs[i].control == control_value) 434 { 435 bp_index = i; // Mark duplicate index 436 break; // Stop searching here 437 } 438 } 439 440 if (bp_index == LLDB_INVALID_INDEX32) 441 return LLDB_INVALID_INDEX32; 442 443 // Add new or update existing breakpoint 444 if ((m_hbr_regs[bp_index].control & 1) == 0) 445 { 446 m_hbr_regs[bp_index].address = addr; 447 m_hbr_regs[bp_index].control = control_value; 448 m_hbr_regs[bp_index].refcount = 1; 449 450 // PTRACE call to set corresponding hardware breakpoint register. 451 error = WriteHardwareDebugRegs(eDREGTypeBREAK, bp_index); 452 453 if (error.Fail()) 454 { 455 m_hbr_regs[bp_index].address = 0; 456 m_hbr_regs[bp_index].control &= ~1; 457 m_hbr_regs[bp_index].refcount = 0; 458 459 return LLDB_INVALID_INDEX32; 460 } 461 } 462 else 463 m_hbr_regs[bp_index].refcount++; 464 465 return bp_index; 466 } 467 468 bool 469 NativeRegisterContextLinux_arm::ClearHardwareBreakpoint (uint32_t hw_idx) 470 { 471 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS)); 472 473 if (log) 474 log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__); 475 476 Error error; 477 478 // Read hardware breakpoint and watchpoint information. 479 error = ReadHardwareDebugInfo (); 480 481 if (error.Fail()) 482 return false; 483 484 if (hw_idx >= m_max_hbp_supported) 485 return false; 486 487 // Update reference count if multiple references. 488 if (m_hbr_regs[hw_idx].refcount > 1) 489 { 490 m_hbr_regs[hw_idx].refcount--; 491 return true; 492 } 493 else if (m_hbr_regs[hw_idx].refcount == 1) 494 { 495 // Create a backup we can revert to in case of failure. 496 lldb::addr_t tempAddr = m_hbr_regs[hw_idx].address; 497 uint32_t tempControl = m_hbr_regs[hw_idx].control; 498 uint32_t tempRefCount = m_hbr_regs[hw_idx].refcount; 499 500 m_hbr_regs[hw_idx].control &= ~1; 501 m_hbr_regs[hw_idx].address = 0; 502 m_hbr_regs[hw_idx].refcount = 0; 503 504 // PTRACE call to clear corresponding hardware breakpoint register. 505 WriteHardwareDebugRegs(eDREGTypeBREAK, hw_idx); 506 507 if (error.Fail()) 508 { 509 m_hbr_regs[hw_idx].control = tempControl; 510 m_hbr_regs[hw_idx].address = tempAddr; 511 m_hbr_regs[hw_idx].refcount = tempRefCount; 512 513 return false; 514 } 515 516 return true; 517 } 518 519 return false; 520 } 521 522 uint32_t 523 NativeRegisterContextLinux_arm::NumSupportedHardwareWatchpoints () 524 { 525 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS)); 526 527 if (log) 528 log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__); 529 530 Error error; 531 532 // Read hardware breakpoint and watchpoint information. 533 error = ReadHardwareDebugInfo (); 534 535 if (error.Fail()) 536 return LLDB_INVALID_INDEX32; 537 538 return m_max_hwp_supported; 539 } 540 541 uint32_t 542 NativeRegisterContextLinux_arm::SetHardwareWatchpoint (lldb::addr_t addr, size_t size, uint32_t watch_flags) 543 { 544 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS)); 545 546 if (log) 547 log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__); 548 549 Error error; 550 551 // Read hardware breakpoint and watchpoint information. 552 error = ReadHardwareDebugInfo (); 553 554 if (error.Fail()) 555 return LLDB_INVALID_INDEX32; 556 557 uint32_t control_value = 0, wp_index = 0, addr_word_offset = 0, byte_mask = 0; 558 559 // Check if we are setting watchpoint other than read/write/access 560 // Also update watchpoint flag to match Arm write-read bit configuration. 561 switch (watch_flags) 562 { 563 case 1: 564 watch_flags = 2; 565 break; 566 case 2: 567 watch_flags = 1; 568 break; 569 case 3: 570 break; 571 default: 572 return LLDB_INVALID_INDEX32; 573 } 574 575 // Can't watch zero bytes 576 // Can't watch more than 4 bytes per WVR/WCR pair 577 578 if (size == 0 || size > 4) 579 return LLDB_INVALID_INDEX32; 580 581 // We can only watch up to four bytes that follow a 4 byte aligned address 582 // per watchpoint register pair, so make sure we can properly encode this. 583 addr_word_offset = addr % 4; 584 byte_mask = ((1u << size) - 1u) << addr_word_offset; 585 586 // Check if we need multiple watchpoint register 587 if (byte_mask > 0xfu) 588 return LLDB_INVALID_INDEX32; 589 590 // Setup control value 591 // Make the byte_mask into a valid Byte Address Select mask 592 control_value = byte_mask << 5; 593 594 //Turn on appropriate watchpoint flags read or write 595 control_value |= (watch_flags << 3); 596 597 // Enable this watchpoint and make it stop in privileged or user mode; 598 control_value |= 7; 599 600 // Make sure bits 1:0 are clear in our address 601 addr &= ~((lldb::addr_t)3); 602 603 // Iterate over stored watchpoints 604 // Find a free wp_index or update reference count if duplicate. 605 wp_index = LLDB_INVALID_INDEX32; 606 for (uint32_t i = 0; i < m_max_hwp_supported; i++) 607 { 608 if ((m_hwp_regs[i].control & 1) == 0) 609 { 610 wp_index = i; // Mark last free slot 611 } 612 else if (m_hwp_regs[i].address == addr && m_hwp_regs[i].control == control_value) 613 { 614 wp_index = i; // Mark duplicate index 615 break; // Stop searching here 616 } 617 } 618 619 if (wp_index == LLDB_INVALID_INDEX32) 620 return LLDB_INVALID_INDEX32; 621 622 // Add new or update existing watchpoint 623 if ((m_hwp_regs[wp_index].control & 1) == 0) 624 { 625 // Update watchpoint in local cache 626 m_hwp_regs[wp_index].address = addr; 627 m_hwp_regs[wp_index].control = control_value; 628 m_hwp_regs[wp_index].refcount = 1; 629 630 // PTRACE call to set corresponding watchpoint register. 631 error = WriteHardwareDebugRegs(eDREGTypeWATCH, wp_index); 632 633 if (error.Fail()) 634 { 635 m_hwp_regs[wp_index].address = 0; 636 m_hwp_regs[wp_index].control &= ~1; 637 m_hwp_regs[wp_index].refcount = 0; 638 639 return LLDB_INVALID_INDEX32; 640 } 641 } 642 else 643 m_hwp_regs[wp_index].refcount++; 644 645 return wp_index; 646 } 647 648 bool 649 NativeRegisterContextLinux_arm::ClearHardwareWatchpoint (uint32_t wp_index) 650 { 651 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS)); 652 653 if (log) 654 log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__); 655 656 Error error; 657 658 // Read hardware breakpoint and watchpoint information. 659 error = ReadHardwareDebugInfo (); 660 661 if (error.Fail()) 662 return false; 663 664 if (wp_index >= m_max_hwp_supported) 665 return false; 666 667 // Update reference count if multiple references. 668 if (m_hwp_regs[wp_index].refcount > 1) 669 { 670 m_hwp_regs[wp_index].refcount--; 671 return true; 672 } 673 else if (m_hwp_regs[wp_index].refcount == 1) 674 { 675 // Create a backup we can revert to in case of failure. 676 lldb::addr_t tempAddr = m_hwp_regs[wp_index].address; 677 uint32_t tempControl = m_hwp_regs[wp_index].control; 678 uint32_t tempRefCount = m_hwp_regs[wp_index].refcount; 679 680 // Update watchpoint in local cache 681 m_hwp_regs[wp_index].control &= ~1; 682 m_hwp_regs[wp_index].address = 0; 683 m_hwp_regs[wp_index].refcount = 0; 684 685 // Ptrace call to update hardware debug registers 686 error = WriteHardwareDebugRegs(eDREGTypeWATCH, wp_index); 687 688 if (error.Fail()) 689 { 690 m_hwp_regs[wp_index].control = tempControl; 691 m_hwp_regs[wp_index].address = tempAddr; 692 m_hwp_regs[wp_index].refcount = tempRefCount; 693 694 return false; 695 } 696 697 return true; 698 } 699 700 return false; 701 } 702 703 Error 704 NativeRegisterContextLinux_arm::ClearAllHardwareWatchpoints () 705 { 706 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS)); 707 708 if (log) 709 log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__); 710 711 Error error; 712 713 // Read hardware breakpoint and watchpoint information. 714 error = ReadHardwareDebugInfo (); 715 716 if (error.Fail()) 717 return error; 718 719 lldb::addr_t tempAddr = 0; 720 uint32_t tempControl = 0, tempRefCount = 0; 721 722 for (uint32_t i = 0; i < m_max_hwp_supported; i++) 723 { 724 if (m_hwp_regs[i].control & 0x01) 725 { 726 // Create a backup we can revert to in case of failure. 727 tempAddr = m_hwp_regs[i].address; 728 tempControl = m_hwp_regs[i].control; 729 tempRefCount = m_hwp_regs[i].refcount; 730 731 // Clear watchpoints in local cache 732 m_hwp_regs[i].control &= ~1; 733 m_hwp_regs[i].address = 0; 734 m_hwp_regs[i].refcount = 0; 735 736 // Ptrace call to update hardware debug registers 737 error = WriteHardwareDebugRegs(eDREGTypeWATCH, i); 738 739 if (error.Fail()) 740 { 741 m_hwp_regs[i].control = tempControl; 742 m_hwp_regs[i].address = tempAddr; 743 m_hwp_regs[i].refcount = tempRefCount; 744 745 return error; 746 } 747 } 748 } 749 750 return Error(); 751 } 752 753 uint32_t 754 NativeRegisterContextLinux_arm::GetWatchpointSize(uint32_t wp_index) 755 { 756 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS)); 757 758 if (log) 759 log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__); 760 761 switch ((m_hwp_regs[wp_index].control >> 5) & 0x0f) 762 { 763 case 0x01: 764 return 1; 765 case 0x03: 766 return 2; 767 case 0x07: 768 return 3; 769 case 0x0f: 770 return 4; 771 default: 772 return 0; 773 } 774 } 775 bool 776 NativeRegisterContextLinux_arm::WatchpointIsEnabled(uint32_t wp_index) 777 { 778 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS)); 779 780 if (log) 781 log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__); 782 783 if ((m_hwp_regs[wp_index].control & 0x1) == 0x1) 784 return true; 785 else 786 return false; 787 } 788 789 Error 790 NativeRegisterContextLinux_arm::GetWatchpointHitIndex(uint32_t &wp_index, lldb::addr_t trap_addr) 791 { 792 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS)); 793 794 if (log) 795 log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__); 796 797 uint32_t watch_size; 798 lldb::addr_t watch_addr; 799 800 for (wp_index = 0; wp_index < m_max_hwp_supported; ++wp_index) 801 { 802 watch_size = GetWatchpointSize (wp_index); 803 watch_addr = m_hwp_regs[wp_index].address; 804 805 if (m_hwp_regs[wp_index].refcount >= 1 && WatchpointIsEnabled(wp_index) 806 && trap_addr >= watch_addr && trap_addr < watch_addr + watch_size) 807 { 808 return Error(); 809 } 810 } 811 812 wp_index = LLDB_INVALID_INDEX32; 813 return Error(); 814 } 815 816 lldb::addr_t 817 NativeRegisterContextLinux_arm::GetWatchpointAddress (uint32_t wp_index) 818 { 819 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS)); 820 821 if (log) 822 log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__); 823 824 if (wp_index >= m_max_hwp_supported) 825 return LLDB_INVALID_ADDRESS; 826 827 if (WatchpointIsEnabled(wp_index)) 828 return m_hwp_regs[wp_index].address; 829 else 830 return LLDB_INVALID_ADDRESS; 831 } 832 833 Error 834 NativeRegisterContextLinux_arm::ReadHardwareDebugInfo() 835 { 836 Error error; 837 838 if (!m_refresh_hwdebug_info) 839 { 840 return Error(); 841 } 842 843 unsigned int cap_val; 844 845 error = NativeProcessLinux::PtraceWrapper(PTRACE_GETHBPREGS, m_thread.GetID(), nullptr, &cap_val, sizeof(unsigned int)); 846 847 if (error.Fail()) 848 return error; 849 850 m_max_hwp_supported = (cap_val >> 8) & 0xff; 851 m_max_hbp_supported = cap_val & 0xff; 852 m_refresh_hwdebug_info = false; 853 854 return error; 855 } 856 857 Error 858 NativeRegisterContextLinux_arm::WriteHardwareDebugRegs(int hwbType, int hwb_index) 859 { 860 Error error; 861 862 lldb::addr_t *addr_buf; 863 uint32_t *ctrl_buf; 864 865 if (hwbType == eDREGTypeWATCH) 866 { 867 addr_buf = &m_hwp_regs[hwb_index].address; 868 ctrl_buf = &m_hwp_regs[hwb_index].control; 869 870 error = NativeProcessLinux::PtraceWrapper(PTRACE_SETHBPREGS, 871 m_thread.GetID(), (PTRACE_TYPE_ARG3) -((hwb_index << 1) + 1), 872 addr_buf, sizeof(unsigned int)); 873 874 if (error.Fail()) 875 return error; 876 877 error = NativeProcessLinux::PtraceWrapper(PTRACE_SETHBPREGS, 878 m_thread.GetID(), (PTRACE_TYPE_ARG3) -((hwb_index << 1) + 2), 879 ctrl_buf, sizeof(unsigned int)); 880 } 881 else 882 { 883 addr_buf = &m_hwp_regs[hwb_index].address; 884 ctrl_buf = &m_hwp_regs[hwb_index].control; 885 886 error = NativeProcessLinux::PtraceWrapper(PTRACE_SETHBPREGS, 887 m_thread.GetID(), (PTRACE_TYPE_ARG3) ((hwb_index << 1) + 1), 888 addr_buf, sizeof(unsigned int)); 889 890 if (error.Fail()) 891 return error; 892 893 error = NativeProcessLinux::PtraceWrapper(PTRACE_SETHBPREGS, 894 m_thread.GetID(), (PTRACE_TYPE_ARG3) ((hwb_index << 1) + 2), 895 ctrl_buf, sizeof(unsigned int)); 896 897 } 898 899 return error; 900 } 901 902 uint32_t 903 NativeRegisterContextLinux_arm::CalculateFprOffset(const RegisterInfo* reg_info) const 904 { 905 return reg_info->byte_offset - GetRegisterInfoAtIndex(m_reg_info.first_fpr)->byte_offset; 906 } 907 908 Error 909 NativeRegisterContextLinux_arm::DoWriteRegisterValue(uint32_t offset, 910 const char* reg_name, 911 const RegisterValue &value) 912 { 913 // PTRACE_POKEUSER don't work in the aarch64 liux kernel used on android devices (always return 914 // "Bad address"). To avoid using PTRACE_POKEUSER we read out the full GPR register set, modify 915 // the requested register and write it back. This approach is about 4 times slower but the 916 // performance overhead is negligible in comparision to processing time in lldb-server. 917 assert(offset % 4 == 0 && "Try to write a register with unaligned offset"); 918 if (offset + sizeof(uint32_t) > sizeof(m_gpr_arm)) 919 return Error("Register isn't fit into the size of the GPR area"); 920 921 Error error = DoReadGPR(m_gpr_arm, sizeof(m_gpr_arm)); 922 if (error.Fail()) 923 return error; 924 925 m_gpr_arm[offset / sizeof(uint32_t)] = value.GetAsUInt32(); 926 return DoWriteGPR(m_gpr_arm, sizeof(m_gpr_arm)); 927 } 928 929 Error 930 NativeRegisterContextLinux_arm::DoReadFPR(void *buf, size_t buf_size) 931 { 932 return NativeProcessLinux::PtraceWrapper(PTRACE_GETVFPREGS, 933 m_thread.GetID(), 934 nullptr, 935 buf, 936 buf_size); 937 } 938 939 Error 940 NativeRegisterContextLinux_arm::DoWriteFPR(void *buf, size_t buf_size) 941 { 942 return NativeProcessLinux::PtraceWrapper(PTRACE_SETVFPREGS, 943 m_thread.GetID(), 944 nullptr, 945 buf, 946 buf_size); 947 } 948 949 #endif // defined(__arm__) 950