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 0; 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 lldb::addr_t real_addr = addr; 618 619 // Check if we are setting watchpoint other than read/write/access 620 // Also update watchpoint flag to match Arm write-read bit configuration. 621 switch (watch_flags) 622 { 623 case 1: 624 watch_flags = 2; 625 break; 626 case 2: 627 watch_flags = 1; 628 break; 629 case 3: 630 break; 631 default: 632 return LLDB_INVALID_INDEX32; 633 } 634 635 // Can't watch zero bytes 636 // Can't watch more than 4 bytes per WVR/WCR pair 637 638 if (size == 0 || size > 4) 639 return LLDB_INVALID_INDEX32; 640 641 // Check 4-byte alignment for hardware watchpoint target address. 642 // Below is a hack to recalculate address and size in order to 643 // make sure we can watch non 4-byte alligned addresses as well. 644 if (addr & 0x03) 645 { 646 uint8_t watch_mask = (addr & 0x03) + size; 647 648 if (watch_mask > 0x04) 649 return LLDB_INVALID_INDEX32; 650 else if (watch_mask <= 0x02) 651 size = 2; 652 else if (watch_mask <= 0x04) 653 size = 4; 654 655 addr = addr & (~0x03); 656 } 657 658 // We can only watch up to four bytes that follow a 4 byte aligned address 659 // per watchpoint register pair, so make sure we can properly encode this. 660 addr_word_offset = addr % 4; 661 byte_mask = ((1u << size) - 1u) << addr_word_offset; 662 663 // Check if we need multiple watchpoint register 664 if (byte_mask > 0xfu) 665 return LLDB_INVALID_INDEX32; 666 667 // Setup control value 668 // Make the byte_mask into a valid Byte Address Select mask 669 control_value = byte_mask << 5; 670 671 //Turn on appropriate watchpoint flags read or write 672 control_value |= (watch_flags << 3); 673 674 // Enable this watchpoint and make it stop in privileged or user mode; 675 control_value |= 7; 676 677 // Make sure bits 1:0 are clear in our address 678 addr &= ~((lldb::addr_t)3); 679 680 // Iterate over stored watchpoints 681 // Find a free wp_index or update reference count if duplicate. 682 wp_index = LLDB_INVALID_INDEX32; 683 for (uint32_t i = 0; i < m_max_hwp_supported; i++) 684 { 685 if ((m_hwp_regs[i].control & 1) == 0) 686 { 687 wp_index = i; // Mark last free slot 688 } 689 else if (m_hwp_regs[i].address == addr && m_hwp_regs[i].control == control_value) 690 { 691 wp_index = i; // Mark duplicate index 692 break; // Stop searching here 693 } 694 } 695 696 if (wp_index == LLDB_INVALID_INDEX32) 697 return LLDB_INVALID_INDEX32; 698 699 // Add new or update existing watchpoint 700 if ((m_hwp_regs[wp_index].control & 1) == 0) 701 { 702 // Update watchpoint in local cache 703 m_hwp_regs[wp_index].real_addr = real_addr; 704 m_hwp_regs[wp_index].address = addr; 705 m_hwp_regs[wp_index].control = control_value; 706 m_hwp_regs[wp_index].refcount = 1; 707 708 // PTRACE call to set corresponding watchpoint register. 709 error = WriteHardwareDebugRegs(eDREGTypeWATCH, wp_index); 710 711 if (error.Fail()) 712 { 713 m_hwp_regs[wp_index].address = 0; 714 m_hwp_regs[wp_index].control &= ~1; 715 m_hwp_regs[wp_index].refcount = 0; 716 717 return LLDB_INVALID_INDEX32; 718 } 719 } 720 else 721 m_hwp_regs[wp_index].refcount++; 722 723 return wp_index; 724 } 725 726 bool 727 NativeRegisterContextLinux_arm::ClearHardwareWatchpoint (uint32_t wp_index) 728 { 729 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS)); 730 731 if (log) 732 log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__); 733 734 Error error; 735 736 // Read hardware breakpoint and watchpoint information. 737 error = ReadHardwareDebugInfo (); 738 739 if (error.Fail()) 740 return false; 741 742 if (wp_index >= m_max_hwp_supported) 743 return false; 744 745 // Update reference count if multiple references. 746 if (m_hwp_regs[wp_index].refcount > 1) 747 { 748 m_hwp_regs[wp_index].refcount--; 749 return true; 750 } 751 else if (m_hwp_regs[wp_index].refcount == 1) 752 { 753 // Create a backup we can revert to in case of failure. 754 lldb::addr_t tempAddr = m_hwp_regs[wp_index].address; 755 uint32_t tempControl = m_hwp_regs[wp_index].control; 756 uint32_t tempRefCount = m_hwp_regs[wp_index].refcount; 757 758 // Update watchpoint in local cache 759 m_hwp_regs[wp_index].control &= ~1; 760 m_hwp_regs[wp_index].address = 0; 761 m_hwp_regs[wp_index].refcount = 0; 762 763 // Ptrace call to update hardware debug registers 764 error = WriteHardwareDebugRegs(eDREGTypeWATCH, wp_index); 765 766 if (error.Fail()) 767 { 768 m_hwp_regs[wp_index].control = tempControl; 769 m_hwp_regs[wp_index].address = tempAddr; 770 m_hwp_regs[wp_index].refcount = tempRefCount; 771 772 return false; 773 } 774 775 return true; 776 } 777 778 return false; 779 } 780 781 Error 782 NativeRegisterContextLinux_arm::ClearAllHardwareWatchpoints () 783 { 784 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS)); 785 786 if (log) 787 log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__); 788 789 Error error; 790 791 // Read hardware breakpoint and watchpoint information. 792 error = ReadHardwareDebugInfo (); 793 794 if (error.Fail()) 795 return error; 796 797 lldb::addr_t tempAddr = 0; 798 uint32_t tempControl = 0, tempRefCount = 0; 799 800 for (uint32_t i = 0; i < m_max_hwp_supported; i++) 801 { 802 if (m_hwp_regs[i].control & 0x01) 803 { 804 // Create a backup we can revert to in case of failure. 805 tempAddr = m_hwp_regs[i].address; 806 tempControl = m_hwp_regs[i].control; 807 tempRefCount = m_hwp_regs[i].refcount; 808 809 // Clear watchpoints in local cache 810 m_hwp_regs[i].control &= ~1; 811 m_hwp_regs[i].address = 0; 812 m_hwp_regs[i].refcount = 0; 813 814 // Ptrace call to update hardware debug registers 815 error = WriteHardwareDebugRegs(eDREGTypeWATCH, i); 816 817 if (error.Fail()) 818 { 819 m_hwp_regs[i].control = tempControl; 820 m_hwp_regs[i].address = tempAddr; 821 m_hwp_regs[i].refcount = tempRefCount; 822 823 return error; 824 } 825 } 826 } 827 828 return Error(); 829 } 830 831 uint32_t 832 NativeRegisterContextLinux_arm::GetWatchpointSize(uint32_t wp_index) 833 { 834 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS)); 835 836 if (log) 837 log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__); 838 839 switch ((m_hwp_regs[wp_index].control >> 5) & 0x0f) 840 { 841 case 0x01: 842 return 1; 843 case 0x03: 844 return 2; 845 case 0x07: 846 return 3; 847 case 0x0f: 848 return 4; 849 default: 850 return 0; 851 } 852 } 853 bool 854 NativeRegisterContextLinux_arm::WatchpointIsEnabled(uint32_t wp_index) 855 { 856 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS)); 857 858 if (log) 859 log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__); 860 861 if ((m_hwp_regs[wp_index].control & 0x1) == 0x1) 862 return true; 863 else 864 return false; 865 } 866 867 Error 868 NativeRegisterContextLinux_arm::GetWatchpointHitIndex(uint32_t &wp_index, lldb::addr_t trap_addr) 869 { 870 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS)); 871 872 if (log) 873 log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__); 874 875 uint32_t watch_size; 876 lldb::addr_t watch_addr; 877 878 for (wp_index = 0; wp_index < m_max_hwp_supported; ++wp_index) 879 { 880 watch_size = GetWatchpointSize (wp_index); 881 watch_addr = m_hwp_regs[wp_index].address; 882 883 if (m_hwp_regs[wp_index].refcount >= 1 && WatchpointIsEnabled(wp_index) 884 && trap_addr >= watch_addr && trap_addr < watch_addr + watch_size) 885 { 886 m_hwp_regs[wp_index].hit_addr = trap_addr; 887 return Error(); 888 } 889 } 890 891 wp_index = LLDB_INVALID_INDEX32; 892 return Error(); 893 } 894 895 lldb::addr_t 896 NativeRegisterContextLinux_arm::GetWatchpointAddress (uint32_t wp_index) 897 { 898 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS)); 899 900 if (log) 901 log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__); 902 903 if (wp_index >= m_max_hwp_supported) 904 return LLDB_INVALID_ADDRESS; 905 906 if (WatchpointIsEnabled(wp_index)) 907 return m_hwp_regs[wp_index].real_addr; 908 else 909 return LLDB_INVALID_ADDRESS; 910 } 911 912 lldb::addr_t 913 NativeRegisterContextLinux_arm::GetWatchpointHitAddress (uint32_t wp_index) 914 { 915 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS)); 916 917 if (log) 918 log->Printf ("NativeRegisterContextLinux_arm::%s()", __FUNCTION__); 919 920 if (wp_index >= m_max_hwp_supported) 921 return LLDB_INVALID_ADDRESS; 922 923 if (WatchpointIsEnabled(wp_index)) 924 return m_hwp_regs[wp_index].hit_addr; 925 else 926 return LLDB_INVALID_ADDRESS; 927 } 928 929 Error 930 NativeRegisterContextLinux_arm::ReadHardwareDebugInfo() 931 { 932 Error error; 933 934 if (!m_refresh_hwdebug_info) 935 { 936 return Error(); 937 } 938 939 unsigned int cap_val; 940 941 error = NativeProcessLinux::PtraceWrapper(PTRACE_GETHBPREGS, m_thread.GetID(), nullptr, &cap_val, sizeof(unsigned int)); 942 943 if (error.Fail()) 944 return error; 945 946 m_max_hwp_supported = (cap_val >> 8) & 0xff; 947 m_max_hbp_supported = cap_val & 0xff; 948 m_refresh_hwdebug_info = false; 949 950 return error; 951 } 952 953 Error 954 NativeRegisterContextLinux_arm::WriteHardwareDebugRegs(int hwbType, int hwb_index) 955 { 956 Error error; 957 958 lldb::addr_t *addr_buf; 959 uint32_t *ctrl_buf; 960 961 if (hwbType == eDREGTypeWATCH) 962 { 963 addr_buf = &m_hwp_regs[hwb_index].address; 964 ctrl_buf = &m_hwp_regs[hwb_index].control; 965 966 error = NativeProcessLinux::PtraceWrapper(PTRACE_SETHBPREGS, 967 m_thread.GetID(), (PTRACE_TYPE_ARG3)(intptr_t) -((hwb_index << 1) + 1), 968 addr_buf, sizeof(unsigned int)); 969 970 if (error.Fail()) 971 return error; 972 973 error = NativeProcessLinux::PtraceWrapper(PTRACE_SETHBPREGS, 974 m_thread.GetID(), (PTRACE_TYPE_ARG3)(intptr_t) -((hwb_index << 1) + 2), 975 ctrl_buf, sizeof(unsigned int)); 976 } 977 else 978 { 979 addr_buf = &m_hwp_regs[hwb_index].address; 980 ctrl_buf = &m_hwp_regs[hwb_index].control; 981 982 error = NativeProcessLinux::PtraceWrapper(PTRACE_SETHBPREGS, 983 m_thread.GetID(), (PTRACE_TYPE_ARG3)(intptr_t) ((hwb_index << 1) + 1), 984 addr_buf, sizeof(unsigned int)); 985 986 if (error.Fail()) 987 return error; 988 989 error = NativeProcessLinux::PtraceWrapper(PTRACE_SETHBPREGS, 990 m_thread.GetID(), (PTRACE_TYPE_ARG3)(intptr_t) ((hwb_index << 1) + 2), 991 ctrl_buf, sizeof(unsigned int)); 992 993 } 994 995 return error; 996 } 997 998 uint32_t 999 NativeRegisterContextLinux_arm::CalculateFprOffset(const RegisterInfo* reg_info) const 1000 { 1001 return reg_info->byte_offset - GetRegisterInfoAtIndex(m_reg_info.first_fpr)->byte_offset; 1002 } 1003 1004 Error 1005 NativeRegisterContextLinux_arm::DoReadRegisterValue(uint32_t offset, 1006 const char* reg_name, 1007 uint32_t size, 1008 RegisterValue &value) 1009 { 1010 // PTRACE_PEEKUSER don't work in the aarch64 linux kernel used on android devices (always return 1011 // "Bad address"). To avoid using PTRACE_PEEKUSER we read out the full GPR register set instead. 1012 // This approach is about 4 times slower but the performance overhead is negligible in 1013 // comparision to processing time in lldb-server. 1014 assert(offset % 4 == 0 && "Try to write a register with unaligned offset"); 1015 if (offset + sizeof(uint32_t) > sizeof(m_gpr_arm)) 1016 return Error("Register isn't fit into the size of the GPR area"); 1017 1018 Error error = DoReadGPR(m_gpr_arm, sizeof(m_gpr_arm)); 1019 if (error.Fail()) 1020 return error; 1021 1022 value.SetUInt32(m_gpr_arm[offset / sizeof(uint32_t)]); 1023 return Error(); 1024 } 1025 1026 Error 1027 NativeRegisterContextLinux_arm::DoWriteRegisterValue(uint32_t offset, 1028 const char* reg_name, 1029 const RegisterValue &value) 1030 { 1031 // PTRACE_POKEUSER don't work in the aarch64 linux kernel used on android devices (always return 1032 // "Bad address"). To avoid using PTRACE_POKEUSER we read out the full GPR register set, modify 1033 // the requested register and write it back. This approach is about 4 times slower but the 1034 // performance overhead is negligible in comparision to processing time in lldb-server. 1035 assert(offset % 4 == 0 && "Try to write a register with unaligned offset"); 1036 if (offset + sizeof(uint32_t) > sizeof(m_gpr_arm)) 1037 return Error("Register isn't fit into the size of the GPR area"); 1038 1039 Error error = DoReadGPR(m_gpr_arm, sizeof(m_gpr_arm)); 1040 if (error.Fail()) 1041 return error; 1042 1043 uint32_t reg_value = value.GetAsUInt32(); 1044 // As precaution for an undefined behavior encountered while setting PC we 1045 // will clear thumb bit of new PC if we are already in thumb mode; that is 1046 // CPSR thumb mode bit is set. 1047 if (offset / sizeof(uint32_t) == gpr_pc_arm) 1048 { 1049 // Check if we are already in thumb mode and 1050 // thumb bit of current PC is read out to be zero and 1051 // thumb bit of next PC is read out to be one. 1052 if ((m_gpr_arm[gpr_cpsr_arm] & 0x20) && 1053 !(m_gpr_arm[gpr_pc_arm] & 0x01) && 1054 (value.GetAsUInt32() & 0x01)) 1055 { 1056 reg_value &= (~1ull); 1057 } 1058 } 1059 1060 m_gpr_arm[offset / sizeof(uint32_t)] = reg_value; 1061 return DoWriteGPR(m_gpr_arm, sizeof(m_gpr_arm)); 1062 } 1063 1064 Error 1065 NativeRegisterContextLinux_arm::DoReadGPR(void *buf, size_t buf_size) 1066 { 1067 #ifdef __arm__ 1068 return NativeRegisterContextLinux::DoReadGPR(buf, buf_size); 1069 #else // __aarch64__ 1070 struct iovec ioVec; 1071 ioVec.iov_base = buf; 1072 ioVec.iov_len = buf_size; 1073 1074 return ReadRegisterSet(&ioVec, buf_size, NT_PRSTATUS); 1075 #endif // __arm__ 1076 } 1077 1078 Error 1079 NativeRegisterContextLinux_arm::DoWriteGPR(void *buf, size_t buf_size) 1080 { 1081 #ifdef __arm__ 1082 return NativeRegisterContextLinux::DoWriteGPR(buf, buf_size); 1083 #else // __aarch64__ 1084 struct iovec ioVec; 1085 ioVec.iov_base = buf; 1086 ioVec.iov_len = buf_size; 1087 1088 return WriteRegisterSet(&ioVec, buf_size, NT_PRSTATUS); 1089 #endif // __arm__ 1090 } 1091 1092 Error 1093 NativeRegisterContextLinux_arm::DoReadFPR(void *buf, size_t buf_size) 1094 { 1095 #ifdef __arm__ 1096 return NativeProcessLinux::PtraceWrapper(PTRACE_GETVFPREGS, 1097 m_thread.GetID(), 1098 nullptr, 1099 buf, 1100 buf_size); 1101 #else // __aarch64__ 1102 struct iovec ioVec; 1103 ioVec.iov_base = buf; 1104 ioVec.iov_len = buf_size; 1105 1106 return ReadRegisterSet(&ioVec, buf_size, NT_ARM_VFP); 1107 #endif // __arm__ 1108 } 1109 1110 Error 1111 NativeRegisterContextLinux_arm::DoWriteFPR(void *buf, size_t buf_size) 1112 { 1113 #ifdef __arm__ 1114 return NativeProcessLinux::PtraceWrapper(PTRACE_SETVFPREGS, 1115 m_thread.GetID(), 1116 nullptr, 1117 buf, 1118 buf_size); 1119 #else // __aarch64__ 1120 struct iovec ioVec; 1121 ioVec.iov_base = buf; 1122 ioVec.iov_len = buf_size; 1123 1124 return WriteRegisterSet(&ioVec, buf_size, NT_ARM_VFP); 1125 #endif // __arm__ 1126 } 1127 1128 #endif // defined(__arm__) || defined(__arm64__) || defined(__aarch64__) 1129