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