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/RegisterValue.h" 16 #include "lldb/Utility/Error.h" 17 #include "lldb/Utility/Log.h" 18 19 #include "Plugins/Process/Linux/Procfs.h" 20 #include "Plugins/Process/POSIX/ProcessPOSIXLog.h" 21 #include "Plugins/Process/Utility/RegisterInfoPOSIX_arm.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 NativeRegisterContextLinux * 99 NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux( 100 const ArchSpec &target_arch, NativeThreadProtocol &native_thread, 101 uint32_t concrete_frame_idx) { 102 return new NativeRegisterContextLinux_arm(target_arch, native_thread, 103 concrete_frame_idx); 104 } 105 106 #endif // defined(__arm__) 107 108 NativeRegisterContextLinux_arm::NativeRegisterContextLinux_arm( 109 const ArchSpec &target_arch, NativeThreadProtocol &native_thread, 110 uint32_t concrete_frame_idx) 111 : NativeRegisterContextLinux(native_thread, concrete_frame_idx, 112 new RegisterInfoPOSIX_arm(target_arch)) { 113 switch (target_arch.GetMachine()) { 114 case llvm::Triple::arm: 115 m_reg_info.num_registers = k_num_registers_arm; 116 m_reg_info.num_gpr_registers = k_num_gpr_registers_arm; 117 m_reg_info.num_fpr_registers = k_num_fpr_registers_arm; 118 m_reg_info.last_gpr = k_last_gpr_arm; 119 m_reg_info.first_fpr = k_first_fpr_arm; 120 m_reg_info.last_fpr = k_last_fpr_arm; 121 m_reg_info.first_fpr_v = fpu_s0_arm; 122 m_reg_info.last_fpr_v = fpu_s31_arm; 123 m_reg_info.gpr_flags = gpr_cpsr_arm; 124 break; 125 default: 126 assert(false && "Unhandled target architecture."); 127 break; 128 } 129 130 ::memset(&m_fpr, 0, sizeof(m_fpr)); 131 ::memset(&m_gpr_arm, 0, sizeof(m_gpr_arm)); 132 ::memset(&m_hwp_regs, 0, sizeof(m_hwp_regs)); 133 ::memset(&m_hbr_regs, 0, sizeof(m_hbr_regs)); 134 135 // 16 is just a maximum value, query hardware for actual watchpoint count 136 m_max_hwp_supported = 16; 137 m_max_hbp_supported = 16; 138 m_refresh_hwdebug_info = true; 139 } 140 141 uint32_t NativeRegisterContextLinux_arm::GetRegisterSetCount() const { 142 return k_num_register_sets; 143 } 144 145 uint32_t NativeRegisterContextLinux_arm::GetUserRegisterCount() const { 146 uint32_t count = 0; 147 for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index) 148 count += g_reg_sets_arm[set_index].num_registers; 149 return count; 150 } 151 152 const RegisterSet * 153 NativeRegisterContextLinux_arm::GetRegisterSet(uint32_t set_index) const { 154 if (set_index < k_num_register_sets) 155 return &g_reg_sets_arm[set_index]; 156 157 return nullptr; 158 } 159 160 Error NativeRegisterContextLinux_arm::ReadRegister(const RegisterInfo *reg_info, 161 RegisterValue ®_value) { 162 Error error; 163 164 if (!reg_info) { 165 error.SetErrorString("reg_info NULL"); 166 return error; 167 } 168 169 const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB]; 170 171 if (IsFPR(reg)) { 172 error = ReadFPR(); 173 if (error.Fail()) 174 return error; 175 } else { 176 uint32_t full_reg = reg; 177 bool is_subreg = reg_info->invalidate_regs && 178 (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM); 179 180 if (is_subreg) { 181 // Read the full aligned 64-bit register. 182 full_reg = reg_info->invalidate_regs[0]; 183 } 184 185 error = ReadRegisterRaw(full_reg, reg_value); 186 187 if (error.Success()) { 188 // If our read was not aligned (for ah,bh,ch,dh), shift our returned value 189 // one byte to the right. 190 if (is_subreg && (reg_info->byte_offset & 0x1)) 191 reg_value.SetUInt64(reg_value.GetAsUInt64() >> 8); 192 193 // If our return byte size was greater than the return value reg size, 194 // then 195 // use the type specified by reg_info rather than the uint64_t default 196 if (reg_value.GetByteSize() > reg_info->byte_size) 197 reg_value.SetType(reg_info); 198 } 199 return error; 200 } 201 202 // Get pointer to m_fpr variable and set the data from it. 203 uint32_t fpr_offset = CalculateFprOffset(reg_info); 204 assert(fpr_offset < sizeof m_fpr); 205 uint8_t *src = (uint8_t *)&m_fpr + fpr_offset; 206 switch (reg_info->byte_size) { 207 case 2: 208 reg_value.SetUInt16(*(uint16_t *)src); 209 break; 210 case 4: 211 reg_value.SetUInt32(*(uint32_t *)src); 212 break; 213 case 8: 214 reg_value.SetUInt64(*(uint64_t *)src); 215 break; 216 case 16: 217 reg_value.SetBytes(src, 16, GetByteOrder()); 218 break; 219 default: 220 assert(false && "Unhandled data size."); 221 error.SetErrorStringWithFormat("unhandled byte size: %" PRIu32, 222 reg_info->byte_size); 223 break; 224 } 225 226 return error; 227 } 228 229 Error NativeRegisterContextLinux_arm::WriteRegister( 230 const RegisterInfo *reg_info, const RegisterValue ®_value) { 231 if (!reg_info) 232 return Error("reg_info NULL"); 233 234 const uint32_t reg_index = reg_info->kinds[lldb::eRegisterKindLLDB]; 235 if (reg_index == LLDB_INVALID_REGNUM) 236 return Error("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 Error("unhandled register data size %" PRIu32, 261 reg_info->byte_size); 262 } 263 264 Error error = WriteFPR(); 265 if (error.Fail()) 266 return error; 267 268 return Error(); 269 } 270 271 return Error("failed - register wasn't recognized to be a GPR or an FPR, " 272 "write strategy unknown"); 273 } 274 275 Error NativeRegisterContextLinux_arm::ReadAllRegisterValues( 276 lldb::DataBufferSP &data_sp) { 277 Error error; 278 279 data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0)); 280 if (!data_sp) 281 return Error("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 Error NativeRegisterContextLinux_arm::WriteAllRegisterValues( 308 const lldb::DataBufferSP &data_sp) { 309 Error 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 Error 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 Error 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 Error 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 Error 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 Error(); 484 } 485 } 486 487 bp_index = LLDB_INVALID_INDEX32; 488 return Error(); 489 } 490 491 Error NativeRegisterContextLinux_arm::ClearAllHardwareBreakpoints() { 492 Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_BREAKPOINTS)); 493 494 if (log) 495 log->Printf("NativeRegisterContextLinux_arm::%s()", __FUNCTION__); 496 497 Error 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 Error(); 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 Error 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 Error 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 562 // Also 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. 583 // Below is a hack to recalculate address and size in order to 584 // make sure we can watch 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 Error 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 Error NativeRegisterContextLinux_arm::ClearAllHardwareWatchpoints() { 687 // Read hardware breakpoint and watchpoint information. 688 Error 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 Error(); 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 Error NativeRegisterContextLinux_arm::GetWatchpointHitIndex( 749 uint32_t &wp_index, lldb::addr_t trap_addr) { 750 Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS)); 751 LLDB_LOG(log, "wp_index: {0}, trap_addr: {1:x}", wp_index, trap_addr); 752 753 uint32_t watch_size; 754 lldb::addr_t watch_addr; 755 756 for (wp_index = 0; wp_index < m_max_hwp_supported; ++wp_index) { 757 watch_size = GetWatchpointSize(wp_index); 758 watch_addr = m_hwp_regs[wp_index].address; 759 760 if (WatchpointIsEnabled(wp_index) && trap_addr >= watch_addr && 761 trap_addr < watch_addr + watch_size) { 762 m_hwp_regs[wp_index].hit_addr = trap_addr; 763 return Error(); 764 } 765 } 766 767 wp_index = LLDB_INVALID_INDEX32; 768 return Error(); 769 } 770 771 lldb::addr_t 772 NativeRegisterContextLinux_arm::GetWatchpointAddress(uint32_t wp_index) { 773 Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS)); 774 LLDB_LOG(log, "wp_index: {0}", wp_index); 775 776 if (wp_index >= m_max_hwp_supported) 777 return LLDB_INVALID_ADDRESS; 778 779 if (WatchpointIsEnabled(wp_index)) 780 return m_hwp_regs[wp_index].real_addr; 781 else 782 return LLDB_INVALID_ADDRESS; 783 } 784 785 lldb::addr_t 786 NativeRegisterContextLinux_arm::GetWatchpointHitAddress(uint32_t wp_index) { 787 Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_WATCHPOINTS)); 788 LLDB_LOG(log, "wp_index: {0}", wp_index); 789 790 if (wp_index >= m_max_hwp_supported) 791 return LLDB_INVALID_ADDRESS; 792 793 if (WatchpointIsEnabled(wp_index)) 794 return m_hwp_regs[wp_index].hit_addr; 795 else 796 return LLDB_INVALID_ADDRESS; 797 } 798 799 Error NativeRegisterContextLinux_arm::ReadHardwareDebugInfo() { 800 Error error; 801 802 if (!m_refresh_hwdebug_info) { 803 return Error(); 804 } 805 806 unsigned int cap_val; 807 808 error = NativeProcessLinux::PtraceWrapper(PTRACE_GETHBPREGS, m_thread.GetID(), 809 nullptr, &cap_val, 810 sizeof(unsigned int)); 811 812 if (error.Fail()) 813 return error; 814 815 m_max_hwp_supported = (cap_val >> 8) & 0xff; 816 m_max_hbp_supported = cap_val & 0xff; 817 m_refresh_hwdebug_info = false; 818 819 return error; 820 } 821 822 Error NativeRegisterContextLinux_arm::WriteHardwareDebugRegs(int hwbType, 823 int hwb_index) { 824 Error error; 825 826 lldb::addr_t *addr_buf; 827 uint32_t *ctrl_buf; 828 829 if (hwbType == eDREGTypeWATCH) { 830 addr_buf = &m_hwp_regs[hwb_index].address; 831 ctrl_buf = &m_hwp_regs[hwb_index].control; 832 833 error = NativeProcessLinux::PtraceWrapper( 834 PTRACE_SETHBPREGS, m_thread.GetID(), 835 (PTRACE_TYPE_ARG3)(intptr_t) - ((hwb_index << 1) + 1), addr_buf, 836 sizeof(unsigned int)); 837 838 if (error.Fail()) 839 return error; 840 841 error = NativeProcessLinux::PtraceWrapper( 842 PTRACE_SETHBPREGS, m_thread.GetID(), 843 (PTRACE_TYPE_ARG3)(intptr_t) - ((hwb_index << 1) + 2), ctrl_buf, 844 sizeof(unsigned int)); 845 } else { 846 addr_buf = &m_hbr_regs[hwb_index].address; 847 ctrl_buf = &m_hbr_regs[hwb_index].control; 848 849 error = NativeProcessLinux::PtraceWrapper( 850 PTRACE_SETHBPREGS, m_thread.GetID(), 851 (PTRACE_TYPE_ARG3)(intptr_t)((hwb_index << 1) + 1), addr_buf, 852 sizeof(unsigned int)); 853 854 if (error.Fail()) 855 return error; 856 857 error = NativeProcessLinux::PtraceWrapper( 858 PTRACE_SETHBPREGS, m_thread.GetID(), 859 (PTRACE_TYPE_ARG3)(intptr_t)((hwb_index << 1) + 2), ctrl_buf, 860 sizeof(unsigned int)); 861 } 862 863 return error; 864 } 865 866 uint32_t NativeRegisterContextLinux_arm::CalculateFprOffset( 867 const RegisterInfo *reg_info) const { 868 return reg_info->byte_offset - 869 GetRegisterInfoAtIndex(m_reg_info.first_fpr)->byte_offset; 870 } 871 872 Error NativeRegisterContextLinux_arm::DoReadRegisterValue( 873 uint32_t offset, const char *reg_name, uint32_t size, 874 RegisterValue &value) { 875 // PTRACE_PEEKUSER don't work in the aarch64 linux kernel used on android 876 // devices (always return 877 // "Bad address"). To avoid using PTRACE_PEEKUSER we read out the full GPR 878 // register set instead. 879 // This approach is about 4 times slower but the performance overhead is 880 // negligible in 881 // comparision to processing time in lldb-server. 882 assert(offset % 4 == 0 && "Try to write a register with unaligned offset"); 883 if (offset + sizeof(uint32_t) > sizeof(m_gpr_arm)) 884 return Error("Register isn't fit into the size of the GPR area"); 885 886 Error error = DoReadGPR(m_gpr_arm, sizeof(m_gpr_arm)); 887 if (error.Fail()) 888 return error; 889 890 value.SetUInt32(m_gpr_arm[offset / sizeof(uint32_t)]); 891 return Error(); 892 } 893 894 Error NativeRegisterContextLinux_arm::DoWriteRegisterValue( 895 uint32_t offset, const char *reg_name, const RegisterValue &value) { 896 // PTRACE_POKEUSER don't work in the aarch64 linux kernel used on android 897 // devices (always return 898 // "Bad address"). To avoid using PTRACE_POKEUSER we read out the full GPR 899 // register set, modify 900 // the requested register and write it back. This approach is about 4 times 901 // slower but the 902 // performance overhead is negligible in comparision to processing time in 903 // lldb-server. 904 assert(offset % 4 == 0 && "Try to write a register with unaligned offset"); 905 if (offset + sizeof(uint32_t) > sizeof(m_gpr_arm)) 906 return Error("Register isn't fit into the size of the GPR area"); 907 908 Error error = DoReadGPR(m_gpr_arm, sizeof(m_gpr_arm)); 909 if (error.Fail()) 910 return error; 911 912 uint32_t reg_value = value.GetAsUInt32(); 913 // As precaution for an undefined behavior encountered while setting PC we 914 // will clear thumb bit of new PC if we are already in thumb mode; that is 915 // CPSR thumb mode bit is set. 916 if (offset / sizeof(uint32_t) == gpr_pc_arm) { 917 // Check if we are already in thumb mode and 918 // thumb bit of current PC is read out to be zero and 919 // thumb bit of next PC is read out to be one. 920 if ((m_gpr_arm[gpr_cpsr_arm] & 0x20) && !(m_gpr_arm[gpr_pc_arm] & 0x01) && 921 (value.GetAsUInt32() & 0x01)) { 922 reg_value &= (~1ull); 923 } 924 } 925 926 m_gpr_arm[offset / sizeof(uint32_t)] = reg_value; 927 return DoWriteGPR(m_gpr_arm, sizeof(m_gpr_arm)); 928 } 929 930 Error NativeRegisterContextLinux_arm::DoReadGPR(void *buf, size_t buf_size) { 931 #ifdef __arm__ 932 return NativeRegisterContextLinux::DoReadGPR(buf, buf_size); 933 #else // __aarch64__ 934 struct iovec ioVec; 935 ioVec.iov_base = buf; 936 ioVec.iov_len = buf_size; 937 938 return ReadRegisterSet(&ioVec, buf_size, NT_PRSTATUS); 939 #endif // __arm__ 940 } 941 942 Error NativeRegisterContextLinux_arm::DoWriteGPR(void *buf, size_t buf_size) { 943 #ifdef __arm__ 944 return NativeRegisterContextLinux::DoWriteGPR(buf, buf_size); 945 #else // __aarch64__ 946 struct iovec ioVec; 947 ioVec.iov_base = buf; 948 ioVec.iov_len = buf_size; 949 950 return WriteRegisterSet(&ioVec, buf_size, NT_PRSTATUS); 951 #endif // __arm__ 952 } 953 954 Error NativeRegisterContextLinux_arm::DoReadFPR(void *buf, size_t buf_size) { 955 #ifdef __arm__ 956 return NativeProcessLinux::PtraceWrapper(PTRACE_GETVFPREGS, m_thread.GetID(), 957 nullptr, buf, buf_size); 958 #else // __aarch64__ 959 struct iovec ioVec; 960 ioVec.iov_base = buf; 961 ioVec.iov_len = buf_size; 962 963 return ReadRegisterSet(&ioVec, buf_size, NT_ARM_VFP); 964 #endif // __arm__ 965 } 966 967 Error NativeRegisterContextLinux_arm::DoWriteFPR(void *buf, size_t buf_size) { 968 #ifdef __arm__ 969 return NativeProcessLinux::PtraceWrapper(PTRACE_SETVFPREGS, m_thread.GetID(), 970 nullptr, buf, buf_size); 971 #else // __aarch64__ 972 struct iovec ioVec; 973 ioVec.iov_base = buf; 974 ioVec.iov_len = buf_size; 975 976 return WriteRegisterSet(&ioVec, buf_size, NT_ARM_VFP); 977 #endif // __arm__ 978 } 979 980 #endif // defined(__arm__) || defined(__arm64__) || defined(__aarch64__) 981