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