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