diff options
Diffstat (limited to 'source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp')
| -rw-r--r-- | source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp | 1523 |
1 files changed, 702 insertions, 821 deletions
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp index 9489f00c1afe..786778e25a24 100644 --- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp +++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -#if defined (__arm64__) || defined (__aarch64__) +#if defined(__arm64__) || defined(__aarch64__) #include "NativeRegisterContextLinux_arm.h" #include "NativeRegisterContextLinux_arm64.h" @@ -25,9 +25,10 @@ #include "Plugins/Process/Linux/NativeProcessLinux.h" #include "Plugins/Process/Linux/Procfs.h" #include "Plugins/Process/POSIX/ProcessPOSIXLog.h" -#include "Plugins/Process/Utility/RegisterContextLinux_arm64.h" +#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h" -// System includes - They have to be included after framework includes because they define some +// System includes - They have to be included after framework includes because +// they define some // macros which collide with variable names in other modules #include <sys/socket.h> // NT_PRSTATUS and NT_FPREGSET definition @@ -42,1051 +43,931 @@ using namespace lldb_private; using namespace lldb_private::process_linux; // ARM64 general purpose registers. -static const uint32_t g_gpr_regnums_arm64[] = -{ - gpr_x0_arm64, - gpr_x1_arm64, - gpr_x2_arm64, - gpr_x3_arm64, - gpr_x4_arm64, - gpr_x5_arm64, - gpr_x6_arm64, - gpr_x7_arm64, - gpr_x8_arm64, - gpr_x9_arm64, - gpr_x10_arm64, - gpr_x11_arm64, - gpr_x12_arm64, - gpr_x13_arm64, - gpr_x14_arm64, - gpr_x15_arm64, - gpr_x16_arm64, - gpr_x17_arm64, - gpr_x18_arm64, - gpr_x19_arm64, - gpr_x20_arm64, - gpr_x21_arm64, - gpr_x22_arm64, - gpr_x23_arm64, - gpr_x24_arm64, - gpr_x25_arm64, - gpr_x26_arm64, - gpr_x27_arm64, - gpr_x28_arm64, - gpr_fp_arm64, - gpr_lr_arm64, - gpr_sp_arm64, - gpr_pc_arm64, - gpr_cpsr_arm64, +static const uint32_t g_gpr_regnums_arm64[] = { + gpr_x0_arm64, gpr_x1_arm64, gpr_x2_arm64, gpr_x3_arm64, + gpr_x4_arm64, gpr_x5_arm64, gpr_x6_arm64, gpr_x7_arm64, + gpr_x8_arm64, gpr_x9_arm64, gpr_x10_arm64, gpr_x11_arm64, + gpr_x12_arm64, gpr_x13_arm64, gpr_x14_arm64, gpr_x15_arm64, + gpr_x16_arm64, gpr_x17_arm64, gpr_x18_arm64, gpr_x19_arm64, + gpr_x20_arm64, gpr_x21_arm64, gpr_x22_arm64, gpr_x23_arm64, + gpr_x24_arm64, gpr_x25_arm64, gpr_x26_arm64, gpr_x27_arm64, + gpr_x28_arm64, gpr_fp_arm64, gpr_lr_arm64, gpr_sp_arm64, + gpr_pc_arm64, gpr_cpsr_arm64, gpr_w0_arm64, gpr_w1_arm64, + gpr_w2_arm64, gpr_w3_arm64, gpr_w4_arm64, gpr_w5_arm64, + gpr_w6_arm64, gpr_w7_arm64, gpr_w8_arm64, gpr_w9_arm64, + gpr_w10_arm64, gpr_w11_arm64, gpr_w12_arm64, gpr_w13_arm64, + gpr_w14_arm64, gpr_w15_arm64, gpr_w16_arm64, gpr_w17_arm64, + gpr_w18_arm64, gpr_w19_arm64, gpr_w20_arm64, gpr_w21_arm64, + gpr_w22_arm64, gpr_w23_arm64, gpr_w24_arm64, gpr_w25_arm64, + gpr_w26_arm64, gpr_w27_arm64, gpr_w28_arm64, LLDB_INVALID_REGNUM // register sets need to end with this flag }; -static_assert(((sizeof g_gpr_regnums_arm64 / sizeof g_gpr_regnums_arm64[0]) - 1) == k_num_gpr_registers_arm64, \ +static_assert(((sizeof g_gpr_regnums_arm64 / sizeof g_gpr_regnums_arm64[0]) - + 1) == k_num_gpr_registers_arm64, "g_gpr_regnums_arm64 has wrong number of register infos"); // ARM64 floating point registers. -static const uint32_t g_fpu_regnums_arm64[] = -{ - fpu_v0_arm64, - fpu_v1_arm64, - fpu_v2_arm64, - fpu_v3_arm64, - fpu_v4_arm64, - fpu_v5_arm64, - fpu_v6_arm64, - fpu_v7_arm64, - fpu_v8_arm64, - fpu_v9_arm64, - fpu_v10_arm64, - fpu_v11_arm64, - fpu_v12_arm64, - fpu_v13_arm64, - fpu_v14_arm64, - fpu_v15_arm64, - fpu_v16_arm64, - fpu_v17_arm64, - fpu_v18_arm64, - fpu_v19_arm64, - fpu_v20_arm64, - fpu_v21_arm64, - fpu_v22_arm64, - fpu_v23_arm64, - fpu_v24_arm64, - fpu_v25_arm64, - fpu_v26_arm64, - fpu_v27_arm64, - fpu_v28_arm64, - fpu_v29_arm64, - fpu_v30_arm64, - fpu_v31_arm64, - fpu_fpsr_arm64, - fpu_fpcr_arm64, +static const uint32_t g_fpu_regnums_arm64[] = { + fpu_v0_arm64, fpu_v1_arm64, fpu_v2_arm64, fpu_v3_arm64, + fpu_v4_arm64, fpu_v5_arm64, fpu_v6_arm64, fpu_v7_arm64, + fpu_v8_arm64, fpu_v9_arm64, fpu_v10_arm64, fpu_v11_arm64, + fpu_v12_arm64, fpu_v13_arm64, fpu_v14_arm64, fpu_v15_arm64, + fpu_v16_arm64, fpu_v17_arm64, fpu_v18_arm64, fpu_v19_arm64, + fpu_v20_arm64, fpu_v21_arm64, fpu_v22_arm64, fpu_v23_arm64, + fpu_v24_arm64, fpu_v25_arm64, fpu_v26_arm64, fpu_v27_arm64, + fpu_v28_arm64, fpu_v29_arm64, fpu_v30_arm64, fpu_v31_arm64, + fpu_s0_arm64, fpu_s1_arm64, fpu_s2_arm64, fpu_s3_arm64, + fpu_s4_arm64, fpu_s5_arm64, fpu_s6_arm64, fpu_s7_arm64, + fpu_s8_arm64, fpu_s9_arm64, fpu_s10_arm64, fpu_s11_arm64, + fpu_s12_arm64, fpu_s13_arm64, fpu_s14_arm64, fpu_s15_arm64, + fpu_s16_arm64, fpu_s17_arm64, fpu_s18_arm64, fpu_s19_arm64, + fpu_s20_arm64, fpu_s21_arm64, fpu_s22_arm64, fpu_s23_arm64, + fpu_s24_arm64, fpu_s25_arm64, fpu_s26_arm64, fpu_s27_arm64, + fpu_s28_arm64, fpu_s29_arm64, fpu_s30_arm64, fpu_s31_arm64, + + fpu_d0_arm64, fpu_d1_arm64, fpu_d2_arm64, fpu_d3_arm64, + fpu_d4_arm64, fpu_d5_arm64, fpu_d6_arm64, fpu_d7_arm64, + fpu_d8_arm64, fpu_d9_arm64, fpu_d10_arm64, fpu_d11_arm64, + fpu_d12_arm64, fpu_d13_arm64, fpu_d14_arm64, fpu_d15_arm64, + fpu_d16_arm64, fpu_d17_arm64, fpu_d18_arm64, fpu_d19_arm64, + fpu_d20_arm64, fpu_d21_arm64, fpu_d22_arm64, fpu_d23_arm64, + fpu_d24_arm64, fpu_d25_arm64, fpu_d26_arm64, fpu_d27_arm64, + fpu_d28_arm64, fpu_d29_arm64, fpu_d30_arm64, fpu_d31_arm64, + fpu_fpsr_arm64, fpu_fpcr_arm64, LLDB_INVALID_REGNUM // register sets need to end with this flag }; -static_assert(((sizeof g_fpu_regnums_arm64 / sizeof g_fpu_regnums_arm64[0]) - 1) == k_num_fpr_registers_arm64, \ +static_assert(((sizeof g_fpu_regnums_arm64 / sizeof g_fpu_regnums_arm64[0]) - + 1) == k_num_fpr_registers_arm64, "g_fpu_regnums_arm64 has wrong number of register infos"); namespace { - // Number of register sets provided by this context. - enum - { - k_num_register_sets = 2 - }; +// Number of register sets provided by this context. +enum { k_num_register_sets = 2 }; } // Register sets for ARM64. -static const RegisterSet -g_reg_sets_arm64[k_num_register_sets] = -{ - { "General Purpose Registers", "gpr", k_num_gpr_registers_arm64, g_gpr_regnums_arm64 }, - { "Floating Point Registers", "fpu", k_num_fpr_registers_arm64, g_fpu_regnums_arm64 } -}; +static const RegisterSet g_reg_sets_arm64[k_num_register_sets] = { + {"General Purpose Registers", "gpr", k_num_gpr_registers_arm64, + g_gpr_regnums_arm64}, + {"Floating Point Registers", "fpu", k_num_fpr_registers_arm64, + g_fpu_regnums_arm64}}; -NativeRegisterContextLinux* -NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(const ArchSpec& target_arch, - NativeThreadProtocol &native_thread, - uint32_t concrete_frame_idx) -{ - Log *log = ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_REGISTERS); - switch (target_arch.GetMachine()) - { - case llvm::Triple::arm: - return new NativeRegisterContextLinux_arm(target_arch, native_thread, concrete_frame_idx); - case llvm::Triple::aarch64: - return new NativeRegisterContextLinux_arm64(target_arch, native_thread, concrete_frame_idx); - default: - if (log) - log->Printf("NativeRegisterContextLinux::%s() have no register context for architecture: %s\n", __FUNCTION__, - target_arch.GetTriple().getArchName().str().c_str()); - return nullptr; - } +NativeRegisterContextLinux * +NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux( + const ArchSpec &target_arch, NativeThreadProtocol &native_thread, + uint32_t concrete_frame_idx) { + Log *log = ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_REGISTERS); + switch (target_arch.GetMachine()) { + case llvm::Triple::arm: + return new NativeRegisterContextLinux_arm(target_arch, native_thread, + concrete_frame_idx); + case llvm::Triple::aarch64: + return new NativeRegisterContextLinux_arm64(target_arch, native_thread, + concrete_frame_idx); + default: + if (log) + log->Printf("NativeRegisterContextLinux::%s() have no register context " + "for architecture: %s\n", + __FUNCTION__, + target_arch.GetTriple().getArchName().str().c_str()); + return nullptr; + } } -NativeRegisterContextLinux_arm64::NativeRegisterContextLinux_arm64 (const ArchSpec& target_arch, - NativeThreadProtocol &native_thread, - uint32_t concrete_frame_idx) : - NativeRegisterContextLinux (native_thread, concrete_frame_idx, new RegisterContextLinux_arm64(target_arch)) -{ - switch (target_arch.GetMachine()) - { - case llvm::Triple::aarch64: - m_reg_info.num_registers = k_num_registers_arm64; - m_reg_info.num_gpr_registers = k_num_gpr_registers_arm64; - m_reg_info.num_fpr_registers = k_num_fpr_registers_arm64; - m_reg_info.last_gpr = k_last_gpr_arm64; - m_reg_info.first_fpr = k_first_fpr_arm64; - m_reg_info.last_fpr = k_last_fpr_arm64; - m_reg_info.first_fpr_v = fpu_v0_arm64; - m_reg_info.last_fpr_v = fpu_v31_arm64; - m_reg_info.gpr_flags = gpr_cpsr_arm64; - break; - default: - assert(false && "Unhandled target architecture."); - break; - } +NativeRegisterContextLinux_arm64::NativeRegisterContextLinux_arm64( + const ArchSpec &target_arch, NativeThreadProtocol &native_thread, + uint32_t concrete_frame_idx) + : NativeRegisterContextLinux(native_thread, concrete_frame_idx, + new RegisterInfoPOSIX_arm64(target_arch)) { + switch (target_arch.GetMachine()) { + case llvm::Triple::aarch64: + m_reg_info.num_registers = k_num_registers_arm64; + m_reg_info.num_gpr_registers = k_num_gpr_registers_arm64; + m_reg_info.num_fpr_registers = k_num_fpr_registers_arm64; + m_reg_info.last_gpr = k_last_gpr_arm64; + m_reg_info.first_fpr = k_first_fpr_arm64; + m_reg_info.last_fpr = k_last_fpr_arm64; + m_reg_info.first_fpr_v = fpu_v0_arm64; + m_reg_info.last_fpr_v = fpu_v31_arm64; + m_reg_info.gpr_flags = gpr_cpsr_arm64; + break; + default: + assert(false && "Unhandled target architecture."); + break; + } - ::memset(&m_fpr, 0, sizeof (m_fpr)); - ::memset(&m_gpr_arm64, 0, sizeof (m_gpr_arm64)); - ::memset(&m_hwp_regs, 0, sizeof (m_hwp_regs)); + ::memset(&m_fpr, 0, sizeof(m_fpr)); + ::memset(&m_gpr_arm64, 0, sizeof(m_gpr_arm64)); + ::memset(&m_hwp_regs, 0, sizeof(m_hwp_regs)); - // 16 is just a maximum value, query hardware for actual watchpoint count - m_max_hwp_supported = 16; - m_max_hbp_supported = 16; - m_refresh_hwdebug_info = true; + // 16 is just a maximum value, query hardware for actual watchpoint count + m_max_hwp_supported = 16; + m_max_hbp_supported = 16; + m_refresh_hwdebug_info = true; } -uint32_t -NativeRegisterContextLinux_arm64::GetRegisterSetCount () const -{ - return k_num_register_sets; +uint32_t NativeRegisterContextLinux_arm64::GetRegisterSetCount() const { + return k_num_register_sets; } const RegisterSet * -NativeRegisterContextLinux_arm64::GetRegisterSet (uint32_t set_index) const -{ - if (set_index < k_num_register_sets) - return &g_reg_sets_arm64[set_index]; +NativeRegisterContextLinux_arm64::GetRegisterSet(uint32_t set_index) const { + if (set_index < k_num_register_sets) + return &g_reg_sets_arm64[set_index]; - return nullptr; + return nullptr; } -uint32_t -NativeRegisterContextLinux_arm64::GetUserRegisterCount() const -{ - uint32_t count = 0; - for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index) - count += g_reg_sets_arm64[set_index].num_registers; - return count; +uint32_t NativeRegisterContextLinux_arm64::GetUserRegisterCount() const { + uint32_t count = 0; + for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index) + count += g_reg_sets_arm64[set_index].num_registers; + return count; } -Error -NativeRegisterContextLinux_arm64::ReadRegister (const RegisterInfo *reg_info, RegisterValue ®_value) -{ - Error error; +Error NativeRegisterContextLinux_arm64::ReadRegister( + const RegisterInfo *reg_info, RegisterValue ®_value) { + Error error; - if (!reg_info) - { - error.SetErrorString ("reg_info NULL"); - return error; - } + if (!reg_info) { + error.SetErrorString("reg_info NULL"); + return error; + } - const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB]; + const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB]; - if (IsFPR(reg)) - { - error = ReadFPR(); - if (error.Fail()) - return error; - } - else - { - uint32_t full_reg = reg; - bool is_subreg = reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM); + if (IsFPR(reg)) { + error = ReadFPR(); + if (error.Fail()) + return error; + } else { + uint32_t full_reg = reg; + bool is_subreg = reg_info->invalidate_regs && + (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM); - if (is_subreg) - { - // Read the full aligned 64-bit register. - full_reg = reg_info->invalidate_regs[0]; - } + if (is_subreg) { + // Read the full aligned 64-bit register. + full_reg = reg_info->invalidate_regs[0]; + } - error = ReadRegisterRaw(full_reg, reg_value); + error = ReadRegisterRaw(full_reg, reg_value); - if (error.Success ()) - { - // If our read was not aligned (for ah,bh,ch,dh), shift our returned value one byte to the right. - if (is_subreg && (reg_info->byte_offset & 0x1)) - reg_value.SetUInt64(reg_value.GetAsUInt64() >> 8); + if (error.Success()) { + // If our read was not aligned (for ah,bh,ch,dh), shift our returned value + // one byte to the right. + if (is_subreg && (reg_info->byte_offset & 0x1)) + reg_value.SetUInt64(reg_value.GetAsUInt64() >> 8); - // If our return byte size was greater than the return value reg size, then - // use the type specified by reg_info rather than the uint64_t default - if (reg_value.GetByteSize() > reg_info->byte_size) - reg_value.SetType(reg_info); - } - return error; + // If our return byte size was greater than the return value reg size, + // then + // use the type specified by reg_info rather than the uint64_t default + if (reg_value.GetByteSize() > reg_info->byte_size) + reg_value.SetType(reg_info); } - - // Get pointer to m_fpr variable and set the data from it. - uint32_t fpr_offset = CalculateFprOffset(reg_info); - assert (fpr_offset < sizeof m_fpr); - uint8_t *src = (uint8_t *)&m_fpr + fpr_offset; - reg_value.SetFromMemoryData(reg_info, src, reg_info->byte_size, eByteOrderLittle, error); - return error; -} + } -Error -NativeRegisterContextLinux_arm64::WriteRegister (const RegisterInfo *reg_info, const RegisterValue ®_value) -{ - if (!reg_info) - return Error ("reg_info NULL"); + // Get pointer to m_fpr variable and set the data from it. + uint32_t fpr_offset = CalculateFprOffset(reg_info); + assert(fpr_offset < sizeof m_fpr); + uint8_t *src = (uint8_t *)&m_fpr + fpr_offset; + reg_value.SetFromMemoryData(reg_info, src, reg_info->byte_size, + eByteOrderLittle, error); - const uint32_t reg_index = reg_info->kinds[lldb::eRegisterKindLLDB]; - if (reg_index == LLDB_INVALID_REGNUM) - return Error ("no lldb regnum for %s", reg_info && reg_info->name ? reg_info->name : "<unknown register>"); + return error; +} - if (IsGPR(reg_index)) - return WriteRegisterRaw(reg_index, reg_value); +Error NativeRegisterContextLinux_arm64::WriteRegister( + const RegisterInfo *reg_info, const RegisterValue ®_value) { + if (!reg_info) + return Error("reg_info NULL"); - if (IsFPR(reg_index)) - { - // Get pointer to m_fpr variable and set the data to it. - uint32_t fpr_offset = CalculateFprOffset(reg_info); - assert (fpr_offset < sizeof m_fpr); - uint8_t *dst = (uint8_t *)&m_fpr + fpr_offset; - switch (reg_info->byte_size) - { - case 2: - *(uint16_t *)dst = reg_value.GetAsUInt16(); - break; - case 4: - *(uint32_t *)dst = reg_value.GetAsUInt32(); - break; - case 8: - *(uint64_t *)dst = reg_value.GetAsUInt64(); - break; - default: - assert(false && "Unhandled data size."); - return Error ("unhandled register data size %" PRIu32, reg_info->byte_size); - } + const uint32_t reg_index = reg_info->kinds[lldb::eRegisterKindLLDB]; + if (reg_index == LLDB_INVALID_REGNUM) + return Error("no lldb regnum for %s", reg_info && reg_info->name + ? reg_info->name + : "<unknown register>"); - Error error = WriteFPR(); - if (error.Fail()) - return error; + if (IsGPR(reg_index)) + return WriteRegisterRaw(reg_index, reg_value); - return Error (); + if (IsFPR(reg_index)) { + // Get pointer to m_fpr variable and set the data to it. + uint32_t fpr_offset = CalculateFprOffset(reg_info); + assert(fpr_offset < sizeof m_fpr); + uint8_t *dst = (uint8_t *)&m_fpr + fpr_offset; + switch (reg_info->byte_size) { + case 2: + *(uint16_t *)dst = reg_value.GetAsUInt16(); + break; + case 4: + *(uint32_t *)dst = reg_value.GetAsUInt32(); + break; + case 8: + *(uint64_t *)dst = reg_value.GetAsUInt64(); + break; + default: + assert(false && "Unhandled data size."); + return Error("unhandled register data size %" PRIu32, + reg_info->byte_size); } - return Error ("failed - register wasn't recognized to be a GPR or an FPR, write strategy unknown"); -} + Error error = WriteFPR(); + if (error.Fail()) + return error; -Error -NativeRegisterContextLinux_arm64::ReadAllRegisterValues (lldb::DataBufferSP &data_sp) -{ - Error error; + return Error(); + } - data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0)); - if (!data_sp) - return Error ("failed to allocate DataBufferHeap instance of size %" PRIu64, REG_CONTEXT_SIZE); + return Error("failed - register wasn't recognized to be a GPR or an FPR, " + "write strategy unknown"); +} - error = ReadGPR(); - if (error.Fail()) - return error; +Error NativeRegisterContextLinux_arm64::ReadAllRegisterValues( + lldb::DataBufferSP &data_sp) { + Error error; - error = ReadFPR(); - if (error.Fail()) - return error; + data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0)); + if (!data_sp) + return Error("failed to allocate DataBufferHeap instance of size %" PRIu64, + REG_CONTEXT_SIZE); - uint8_t *dst = data_sp->GetBytes (); - if (dst == nullptr) - { - error.SetErrorStringWithFormat ("DataBufferHeap instance of size %" PRIu64 " returned a null pointer", REG_CONTEXT_SIZE); - return error; - } + error = ReadGPR(); + if (error.Fail()) + return error; - ::memcpy (dst, &m_gpr_arm64, GetGPRSize()); - dst += GetGPRSize(); - ::memcpy (dst, &m_fpr, sizeof(m_fpr)); + error = ReadFPR(); + if (error.Fail()) + return error; + uint8_t *dst = data_sp->GetBytes(); + if (dst == nullptr) { + error.SetErrorStringWithFormat("DataBufferHeap instance of size %" PRIu64 + " returned a null pointer", + REG_CONTEXT_SIZE); return error; -} + } -Error -NativeRegisterContextLinux_arm64::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp) -{ - Error error; + ::memcpy(dst, &m_gpr_arm64, GetGPRSize()); + dst += GetGPRSize(); + ::memcpy(dst, &m_fpr, sizeof(m_fpr)); - if (!data_sp) - { - error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s invalid data_sp provided", __FUNCTION__); - return error; - } + return error; +} - if (data_sp->GetByteSize () != REG_CONTEXT_SIZE) - { - error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s data_sp contained mismatched data size, expected %" PRIu64 ", actual %" PRIu64, __FUNCTION__, REG_CONTEXT_SIZE, data_sp->GetByteSize ()); - return error; - } +Error NativeRegisterContextLinux_arm64::WriteAllRegisterValues( + const lldb::DataBufferSP &data_sp) { + Error error; + if (!data_sp) { + error.SetErrorStringWithFormat( + "NativeRegisterContextLinux_x86_64::%s invalid data_sp provided", + __FUNCTION__); + return error; + } - uint8_t *src = data_sp->GetBytes (); - if (src == nullptr) - { - error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s DataBuffer::GetBytes() returned a null pointer", __FUNCTION__); - return error; - } - ::memcpy (&m_gpr_arm64, src, GetRegisterInfoInterface ().GetGPRSize ()); + if (data_sp->GetByteSize() != REG_CONTEXT_SIZE) { + error.SetErrorStringWithFormat( + "NativeRegisterContextLinux_x86_64::%s data_sp contained mismatched " + "data size, expected %" PRIu64 ", actual %" PRIu64, + __FUNCTION__, REG_CONTEXT_SIZE, data_sp->GetByteSize()); + return error; + } - error = WriteGPR(); - if (error.Fail()) - return error; + uint8_t *src = data_sp->GetBytes(); + if (src == nullptr) { + error.SetErrorStringWithFormat("NativeRegisterContextLinux_x86_64::%s " + "DataBuffer::GetBytes() returned a null " + "pointer", + __FUNCTION__); + return error; + } + ::memcpy(&m_gpr_arm64, src, GetRegisterInfoInterface().GetGPRSize()); - src += GetRegisterInfoInterface ().GetGPRSize (); - ::memcpy (&m_fpr, src, sizeof(m_fpr)); + error = WriteGPR(); + if (error.Fail()) + return error; - error = WriteFPR(); - if (error.Fail()) - return error; + src += GetRegisterInfoInterface().GetGPRSize(); + ::memcpy(&m_fpr, src, sizeof(m_fpr)); + error = WriteFPR(); + if (error.Fail()) return error; + + return error; } -bool -NativeRegisterContextLinux_arm64::IsGPR(unsigned reg) const -{ - return reg <= m_reg_info.last_gpr; // GPR's come first. +bool NativeRegisterContextLinux_arm64::IsGPR(unsigned reg) const { + return reg <= m_reg_info.last_gpr; // GPR's come first. } -bool -NativeRegisterContextLinux_arm64::IsFPR(unsigned reg) const -{ - return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr); +bool NativeRegisterContextLinux_arm64::IsFPR(unsigned reg) const { + return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr); } uint32_t -NativeRegisterContextLinux_arm64::SetHardwareBreakpoint (lldb::addr_t addr, size_t size) -{ - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS)); +NativeRegisterContextLinux_arm64::SetHardwareBreakpoint(lldb::addr_t addr, + size_t size) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); - if (log) - log->Printf ("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__); + if (log) + log->Printf("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__); - Error error; + Error error; - // Read hardware breakpoint and watchpoint information. - error = ReadHardwareDebugInfo (); + // Read hardware breakpoint and watchpoint information. + error = ReadHardwareDebugInfo(); - if (error.Fail()) - return LLDB_INVALID_INDEX32; + if (error.Fail()) + return LLDB_INVALID_INDEX32; - uint32_t control_value = 0, bp_index = 0; + uint32_t control_value = 0, bp_index = 0; - // Check if size has a valid hardware breakpoint length. - if (size != 4) - return LLDB_INVALID_INDEX32; // Invalid size for a AArch64 hardware breakpoint + // Check if size has a valid hardware breakpoint length. + if (size != 4) + return LLDB_INVALID_INDEX32; // Invalid size for a AArch64 hardware + // breakpoint - // Check 4-byte alignment for hardware breakpoint target address. - if (addr & 0x03) - return LLDB_INVALID_INDEX32; // Invalid address, should be 4-byte aligned. + // Check 4-byte alignment for hardware breakpoint target address. + if (addr & 0x03) + return LLDB_INVALID_INDEX32; // Invalid address, should be 4-byte aligned. - // Setup control value - control_value = 0; - control_value |= ((1 << size) - 1) << 5; - control_value |= (2 << 1) | 1; + // Setup control value + control_value = 0; + control_value |= ((1 << size) - 1) << 5; + control_value |= (2 << 1) | 1; - // Iterate over stored hardware breakpoints - // Find a free bp_index or update reference count if duplicate. - bp_index = LLDB_INVALID_INDEX32; - for (uint32_t i = 0; i < m_max_hbp_supported; i++) - { - if ((m_hbr_regs[i].control & 1) == 0) - { - bp_index = i; // Mark last free slot - } - else if (m_hbr_regs[i].address == addr && m_hbr_regs[i].control == control_value) - { - bp_index = i; // Mark duplicate index - break; // Stop searching here - } + // Iterate over stored hardware breakpoints + // Find a free bp_index or update reference count if duplicate. + bp_index = LLDB_INVALID_INDEX32; + for (uint32_t i = 0; i < m_max_hbp_supported; i++) { + if ((m_hbr_regs[i].control & 1) == 0) { + bp_index = i; // Mark last free slot + } else if (m_hbr_regs[i].address == addr && + m_hbr_regs[i].control == control_value) { + bp_index = i; // Mark duplicate index + break; // Stop searching here } + } - if (bp_index == LLDB_INVALID_INDEX32) - return LLDB_INVALID_INDEX32; + if (bp_index == LLDB_INVALID_INDEX32) + return LLDB_INVALID_INDEX32; - // Add new or update existing breakpoint - if ((m_hbr_regs[bp_index].control & 1) == 0) - { - m_hbr_regs[bp_index].address = addr; - m_hbr_regs[bp_index].control = control_value; - m_hbr_regs[bp_index].refcount = 1; + // Add new or update existing breakpoint + if ((m_hbr_regs[bp_index].control & 1) == 0) { + m_hbr_regs[bp_index].address = addr; + m_hbr_regs[bp_index].control = control_value; + m_hbr_regs[bp_index].refcount = 1; - // PTRACE call to set corresponding hardware breakpoint register. - error = WriteHardwareDebugRegs(eDREGTypeBREAK); + // PTRACE call to set corresponding hardware breakpoint register. + error = WriteHardwareDebugRegs(eDREGTypeBREAK); - if (error.Fail()) - { - m_hbr_regs[bp_index].address = 0; - m_hbr_regs[bp_index].control &= ~1; - m_hbr_regs[bp_index].refcount = 0; + if (error.Fail()) { + m_hbr_regs[bp_index].address = 0; + m_hbr_regs[bp_index].control &= ~1; + m_hbr_regs[bp_index].refcount = 0; - return LLDB_INVALID_INDEX32; - } + return LLDB_INVALID_INDEX32; } - else - m_hbr_regs[bp_index].refcount++; + } else + m_hbr_regs[bp_index].refcount++; - return bp_index; + return bp_index; } -bool -NativeRegisterContextLinux_arm64::ClearHardwareBreakpoint (uint32_t hw_idx) -{ - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS)); +bool NativeRegisterContextLinux_arm64::ClearHardwareBreakpoint( + uint32_t hw_idx) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); - if (log) - log->Printf ("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__); + if (log) + log->Printf("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__); - Error error; + Error error; - // Read hardware breakpoint and watchpoint information. - error = ReadHardwareDebugInfo (); + // Read hardware breakpoint and watchpoint information. + error = ReadHardwareDebugInfo(); - if (error.Fail()) - return false; - - if (hw_idx >= m_max_hbp_supported) - return false; + if (error.Fail()) + return false; - // Update reference count if multiple references. - if (m_hbr_regs[hw_idx].refcount > 1) - { - m_hbr_regs[hw_idx].refcount--; - return true; - } - else if (m_hbr_regs[hw_idx].refcount == 1) - { - // Create a backup we can revert to in case of failure. - lldb::addr_t tempAddr = m_hbr_regs[hw_idx].address; - uint32_t tempControl = m_hbr_regs[hw_idx].control; - uint32_t tempRefCount = m_hbr_regs[hw_idx].refcount; + if (hw_idx >= m_max_hbp_supported) + return false; - m_hbr_regs[hw_idx].control &= ~1; - m_hbr_regs[hw_idx].address = 0; - m_hbr_regs[hw_idx].refcount = 0; + // Update reference count if multiple references. + if (m_hbr_regs[hw_idx].refcount > 1) { + m_hbr_regs[hw_idx].refcount--; + return true; + } else if (m_hbr_regs[hw_idx].refcount == 1) { + // Create a backup we can revert to in case of failure. + lldb::addr_t tempAddr = m_hbr_regs[hw_idx].address; + uint32_t tempControl = m_hbr_regs[hw_idx].control; + uint32_t tempRefCount = m_hbr_regs[hw_idx].refcount; - // PTRACE call to clear corresponding hardware breakpoint register. - WriteHardwareDebugRegs(eDREGTypeBREAK); + m_hbr_regs[hw_idx].control &= ~1; + m_hbr_regs[hw_idx].address = 0; + m_hbr_regs[hw_idx].refcount = 0; - if (error.Fail()) - { - m_hbr_regs[hw_idx].control = tempControl; - m_hbr_regs[hw_idx].address = tempAddr; - m_hbr_regs[hw_idx].refcount = tempRefCount; + // PTRACE call to clear corresponding hardware breakpoint register. + WriteHardwareDebugRegs(eDREGTypeBREAK); - return false; - } + if (error.Fail()) { + m_hbr_regs[hw_idx].control = tempControl; + m_hbr_regs[hw_idx].address = tempAddr; + m_hbr_regs[hw_idx].refcount = tempRefCount; - return true; + return false; } - return false; + return true; + } + + return false; } -uint32_t -NativeRegisterContextLinux_arm64::NumSupportedHardwareWatchpoints () -{ - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS)); +uint32_t NativeRegisterContextLinux_arm64::NumSupportedHardwareWatchpoints() { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); - if (log) - log->Printf ("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__); + if (log) + log->Printf("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__); - Error error; + Error error; - // Read hardware breakpoint and watchpoint information. - error = ReadHardwareDebugInfo (); + // Read hardware breakpoint and watchpoint information. + error = ReadHardwareDebugInfo(); - if (error.Fail()) - return 0; + if (error.Fail()) + return 0; - return m_max_hwp_supported; + return m_max_hwp_supported; } -uint32_t -NativeRegisterContextLinux_arm64::SetHardwareWatchpoint (lldb::addr_t addr, size_t size, uint32_t watch_flags) -{ - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS)); +uint32_t NativeRegisterContextLinux_arm64::SetHardwareWatchpoint( + lldb::addr_t addr, size_t size, uint32_t watch_flags) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); - if (log) - log->Printf ("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__); - - Error error; + if (log) + log->Printf("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__); - // Read hardware breakpoint and watchpoint information. - error = ReadHardwareDebugInfo (); + Error error; - if (error.Fail()) - return LLDB_INVALID_INDEX32; - - uint32_t control_value = 0, wp_index = 0; - lldb::addr_t real_addr = addr; + // Read hardware breakpoint and watchpoint information. + error = ReadHardwareDebugInfo(); - // Check if we are setting watchpoint other than read/write/access - // Also update watchpoint flag to match AArch64 write-read bit configuration. - switch (watch_flags) - { - case 1: - watch_flags = 2; - break; - case 2: - watch_flags = 1; - break; - case 3: - break; - default: - return LLDB_INVALID_INDEX32; - } + if (error.Fail()) + return LLDB_INVALID_INDEX32; - // Check if size has a valid hardware watchpoint length. - if (size != 1 && size != 2 && size != 4 && size != 8) - return LLDB_INVALID_INDEX32; + uint32_t control_value = 0, wp_index = 0; + lldb::addr_t real_addr = addr; - // Check 8-byte alignment for hardware watchpoint target address. - // Below is a hack to recalculate address and size in order to - // make sure we can watch non 8-byte alligned addresses as well. - if (addr & 0x07) - { - uint8_t watch_mask = (addr & 0x07) + size; + // Check if we are setting watchpoint other than read/write/access + // Also update watchpoint flag to match AArch64 write-read bit configuration. + switch (watch_flags) { + case 1: + watch_flags = 2; + break; + case 2: + watch_flags = 1; + break; + case 3: + break; + default: + return LLDB_INVALID_INDEX32; + } - if (watch_mask > 0x08) - return LLDB_INVALID_INDEX32; - else if (watch_mask <= 0x02) - size = 2; - else if (watch_mask <= 0x04) - size = 4; - else - size = 8; + // Check if size has a valid hardware watchpoint length. + if (size != 1 && size != 2 && size != 4 && size != 8) + return LLDB_INVALID_INDEX32; - addr = addr & (~0x07); - } + // Check 8-byte alignment for hardware watchpoint target address. + // Below is a hack to recalculate address and size in order to + // make sure we can watch non 8-byte alligned addresses as well. + if (addr & 0x07) { + uint8_t watch_mask = (addr & 0x07) + size; - // Setup control value - control_value = watch_flags << 3; - control_value |= ((1 << size) - 1) << 5; - control_value |= (2 << 1) | 1; + if (watch_mask > 0x08) + return LLDB_INVALID_INDEX32; + else if (watch_mask <= 0x02) + size = 2; + else if (watch_mask <= 0x04) + size = 4; + else + size = 8; - // Iterate over stored watchpoints - // Find a free wp_index or update reference count if duplicate. - wp_index = LLDB_INVALID_INDEX32; - for (uint32_t i = 0; i < m_max_hwp_supported; i++) - { - if ((m_hwp_regs[i].control & 1) == 0) - { - wp_index = i; // Mark last free slot - } - else if (m_hwp_regs[i].address == addr && m_hwp_regs[i].control == control_value) - { - wp_index = i; // Mark duplicate index - break; // Stop searching here - } - } + addr = addr & (~0x07); + } - if (wp_index == LLDB_INVALID_INDEX32) - return LLDB_INVALID_INDEX32; + // Setup control value + control_value = watch_flags << 3; + control_value |= ((1 << size) - 1) << 5; + control_value |= (2 << 1) | 1; - // Add new or update existing watchpoint - if ((m_hwp_regs[wp_index].control & 1) == 0) - { - // Update watchpoint in local cache - m_hwp_regs[wp_index].real_addr = real_addr; - m_hwp_regs[wp_index].address = addr; - m_hwp_regs[wp_index].control = control_value; - m_hwp_regs[wp_index].refcount = 1; + // Iterate over stored watchpoints and find a free wp_index + wp_index = LLDB_INVALID_INDEX32; + for (uint32_t i = 0; i < m_max_hwp_supported; i++) { + if ((m_hwp_regs[i].control & 1) == 0) { + wp_index = i; // Mark last free slot + } else if (m_hwp_regs[i].address == addr) { + return LLDB_INVALID_INDEX32; // We do not support duplicate watchpoints. + } + } - // PTRACE call to set corresponding watchpoint register. - error = WriteHardwareDebugRegs(eDREGTypeWATCH); + if (wp_index == LLDB_INVALID_INDEX32) + return LLDB_INVALID_INDEX32; - if (error.Fail()) - { - m_hwp_regs[wp_index].address = 0; - m_hwp_regs[wp_index].control &= ~1; - m_hwp_regs[wp_index].refcount = 0; + // Update watchpoint in local cache + m_hwp_regs[wp_index].real_addr = real_addr; + m_hwp_regs[wp_index].address = addr; + m_hwp_regs[wp_index].control = control_value; - return LLDB_INVALID_INDEX32; - } - } - else - m_hwp_regs[wp_index].refcount++; + // PTRACE call to set corresponding watchpoint register. + error = WriteHardwareDebugRegs(eDREGTypeWATCH); - return wp_index; -} + if (error.Fail()) { + m_hwp_regs[wp_index].address = 0; + m_hwp_regs[wp_index].control &= ~1; -bool -NativeRegisterContextLinux_arm64::ClearHardwareWatchpoint (uint32_t wp_index) -{ - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS)); + return LLDB_INVALID_INDEX32; + } - if (log) - log->Printf ("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__); + return wp_index; +} - Error error; +bool NativeRegisterContextLinux_arm64::ClearHardwareWatchpoint( + uint32_t wp_index) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); - // Read hardware breakpoint and watchpoint information. - error = ReadHardwareDebugInfo (); + if (log) + log->Printf("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__); - if (error.Fail()) - return false; + Error error; - if (wp_index >= m_max_hwp_supported) - return false; + // Read hardware breakpoint and watchpoint information. + error = ReadHardwareDebugInfo(); - // Update reference count if multiple references. - if (m_hwp_regs[wp_index].refcount > 1) - { - m_hwp_regs[wp_index].refcount--; - return true; - } - else if (m_hwp_regs[wp_index].refcount == 1) - { - // Create a backup we can revert to in case of failure. - lldb::addr_t tempAddr = m_hwp_regs[wp_index].address; - uint32_t tempControl = m_hwp_regs[wp_index].control; - uint32_t tempRefCount = m_hwp_regs[wp_index].refcount; + if (error.Fail()) + return false; - // Update watchpoint in local cache - m_hwp_regs[wp_index].control &= ~1; - m_hwp_regs[wp_index].address = 0; - m_hwp_regs[wp_index].refcount = 0; + if (wp_index >= m_max_hwp_supported) + return false; - // Ptrace call to update hardware debug registers - error = WriteHardwareDebugRegs(eDREGTypeWATCH); + // Create a backup we can revert to in case of failure. + lldb::addr_t tempAddr = m_hwp_regs[wp_index].address; + uint32_t tempControl = m_hwp_regs[wp_index].control; - if (error.Fail()) - { - m_hwp_regs[wp_index].control = tempControl; - m_hwp_regs[wp_index].address = tempAddr; - m_hwp_regs[wp_index].refcount = tempRefCount; + // Update watchpoint in local cache + m_hwp_regs[wp_index].control &= ~1; + m_hwp_regs[wp_index].address = 0; - return false; - } + // Ptrace call to update hardware debug registers + error = WriteHardwareDebugRegs(eDREGTypeWATCH); - return true; - } + if (error.Fail()) { + m_hwp_regs[wp_index].control = tempControl; + m_hwp_regs[wp_index].address = tempAddr; return false; + } + + return true; } -Error -NativeRegisterContextLinux_arm64::ClearAllHardwareWatchpoints () -{ - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS)); +Error NativeRegisterContextLinux_arm64::ClearAllHardwareWatchpoints() { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); - if (log) - log->Printf ("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__); + if (log) + log->Printf("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__); - Error error; + Error error; - // Read hardware breakpoint and watchpoint information. - error = ReadHardwareDebugInfo (); + // Read hardware breakpoint and watchpoint information. + error = ReadHardwareDebugInfo(); - if (error.Fail()) - return error; + if (error.Fail()) + return error; - lldb::addr_t tempAddr = 0; - uint32_t tempControl = 0, tempRefCount = 0; + lldb::addr_t tempAddr = 0; + uint32_t tempControl = 0, tempRefCount = 0; - for (uint32_t i = 0; i < m_max_hwp_supported; i++) - { - if (m_hwp_regs[i].control & 0x01) - { - // Create a backup we can revert to in case of failure. - tempAddr = m_hwp_regs[i].address; - tempControl = m_hwp_regs[i].control; - tempRefCount = m_hwp_regs[i].refcount; + for (uint32_t i = 0; i < m_max_hwp_supported; i++) { + if (m_hwp_regs[i].control & 0x01) { + // Create a backup we can revert to in case of failure. + tempAddr = m_hwp_regs[i].address; + tempControl = m_hwp_regs[i].control; - // Clear watchpoints in local cache - m_hwp_regs[i].control &= ~1; - m_hwp_regs[i].address = 0; - m_hwp_regs[i].refcount = 0; + // Clear watchpoints in local cache + m_hwp_regs[i].control &= ~1; + m_hwp_regs[i].address = 0; - // Ptrace call to update hardware debug registers - error = WriteHardwareDebugRegs(eDREGTypeWATCH); + // Ptrace call to update hardware debug registers + error = WriteHardwareDebugRegs(eDREGTypeWATCH); - if (error.Fail()) - { - m_hwp_regs[i].control = tempControl; - m_hwp_regs[i].address = tempAddr; - m_hwp_regs[i].refcount = tempRefCount; + if (error.Fail()) { + m_hwp_regs[i].control = tempControl; + m_hwp_regs[i].address = tempAddr; - return error; - } - } + return error; + } } + } - return Error(); + return Error(); } uint32_t -NativeRegisterContextLinux_arm64::GetWatchpointSize(uint32_t wp_index) -{ - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS)); +NativeRegisterContextLinux_arm64::GetWatchpointSize(uint32_t wp_index) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); - if (log) - log->Printf ("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__); - switch ((m_hwp_regs[wp_index].control >> 5) & 0xff) - { - case 0x01: - return 1; - case 0x03: - return 2; - case 0x0f: - return 4; - case 0xff: - return 8; - default: - return 0; - } + if (log) + log->Printf("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__); + switch ((m_hwp_regs[wp_index].control >> 5) & 0xff) { + case 0x01: + return 1; + case 0x03: + return 2; + case 0x0f: + return 4; + case 0xff: + return 8; + default: + return 0; + } } -bool -NativeRegisterContextLinux_arm64::WatchpointIsEnabled(uint32_t wp_index) -{ - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS)); +bool NativeRegisterContextLinux_arm64::WatchpointIsEnabled(uint32_t wp_index) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); - if (log) - log->Printf ("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__); + if (log) + log->Printf("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__); - if ((m_hwp_regs[wp_index].control & 0x1) == 0x1) - return true; - else - return false; + if ((m_hwp_regs[wp_index].control & 0x1) == 0x1) + return true; + else + return false; } -Error -NativeRegisterContextLinux_arm64::GetWatchpointHitIndex(uint32_t &wp_index, lldb::addr_t trap_addr) -{ - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS)); +Error NativeRegisterContextLinux_arm64::GetWatchpointHitIndex( + uint32_t &wp_index, lldb::addr_t trap_addr) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); - if (log) - log->Printf ("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__); + if (log) + log->Printf("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__); - uint32_t watch_size; - lldb::addr_t watch_addr; + uint32_t watch_size; + lldb::addr_t watch_addr; - for (wp_index = 0; wp_index < m_max_hwp_supported; ++wp_index) - { - watch_size = GetWatchpointSize (wp_index); - watch_addr = m_hwp_regs[wp_index].address; + for (wp_index = 0; wp_index < m_max_hwp_supported; ++wp_index) { + watch_size = GetWatchpointSize(wp_index); + watch_addr = m_hwp_regs[wp_index].address; - if (m_hwp_regs[wp_index].refcount >= 1 && WatchpointIsEnabled(wp_index) - && trap_addr >= watch_addr && trap_addr < watch_addr + watch_size) - { - m_hwp_regs[wp_index].hit_addr = trap_addr; - return Error(); - } + if (WatchpointIsEnabled(wp_index) && trap_addr >= watch_addr && + trap_addr < watch_addr + watch_size) { + m_hwp_regs[wp_index].hit_addr = trap_addr; + return Error(); } + } - wp_index = LLDB_INVALID_INDEX32; - return Error(); + wp_index = LLDB_INVALID_INDEX32; + return Error(); } lldb::addr_t -NativeRegisterContextLinux_arm64::GetWatchpointAddress (uint32_t wp_index) -{ - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS)); +NativeRegisterContextLinux_arm64::GetWatchpointAddress(uint32_t wp_index) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); - if (log) - log->Printf ("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__); + if (log) + log->Printf("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__); - if (wp_index >= m_max_hwp_supported) - return LLDB_INVALID_ADDRESS; + if (wp_index >= m_max_hwp_supported) + return LLDB_INVALID_ADDRESS; - if (WatchpointIsEnabled(wp_index)) - return m_hwp_regs[wp_index].real_addr; - else - return LLDB_INVALID_ADDRESS; + if (WatchpointIsEnabled(wp_index)) + return m_hwp_regs[wp_index].real_addr; + else + return LLDB_INVALID_ADDRESS; } lldb::addr_t -NativeRegisterContextLinux_arm64::GetWatchpointHitAddress (uint32_t wp_index) -{ - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS)); +NativeRegisterContextLinux_arm64::GetWatchpointHitAddress(uint32_t wp_index) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); - if (log) - log->Printf ("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__); + if (log) + log->Printf("NativeRegisterContextLinux_arm64::%s()", __FUNCTION__); - if (wp_index >= m_max_hwp_supported) - return LLDB_INVALID_ADDRESS; + if (wp_index >= m_max_hwp_supported) + return LLDB_INVALID_ADDRESS; - if (WatchpointIsEnabled(wp_index)) - return m_hwp_regs[wp_index].hit_addr; - else - return LLDB_INVALID_ADDRESS; + if (WatchpointIsEnabled(wp_index)) + return m_hwp_regs[wp_index].hit_addr; + else + return LLDB_INVALID_ADDRESS; } -Error -NativeRegisterContextLinux_arm64::ReadHardwareDebugInfo() -{ - if (!m_refresh_hwdebug_info) - { - return Error(); - } - - ::pid_t tid = m_thread.GetID(); +Error NativeRegisterContextLinux_arm64::ReadHardwareDebugInfo() { + if (!m_refresh_hwdebug_info) { + return Error(); + } - int regset = NT_ARM_HW_WATCH; - struct iovec ioVec; - struct user_hwdebug_state dreg_state; - Error error; + ::pid_t tid = m_thread.GetID(); - ioVec.iov_base = &dreg_state; - ioVec.iov_len = sizeof (dreg_state); - error = NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, tid, ®set, &ioVec, ioVec.iov_len); + int regset = NT_ARM_HW_WATCH; + struct iovec ioVec; + struct user_hwdebug_state dreg_state; + Error error; - if (error.Fail()) - return error; + ioVec.iov_base = &dreg_state; + ioVec.iov_len = sizeof(dreg_state); + error = NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, tid, ®set, + &ioVec, ioVec.iov_len); - m_max_hwp_supported = dreg_state.dbg_info & 0xff; + if (error.Fail()) + return error; - regset = NT_ARM_HW_BREAK; - error = NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, tid, ®set, &ioVec, ioVec.iov_len); + m_max_hwp_supported = dreg_state.dbg_info & 0xff; - if (error.Fail()) - return error; - - m_max_hbp_supported = dreg_state.dbg_info & 0xff; - m_refresh_hwdebug_info = false; + regset = NT_ARM_HW_BREAK; + error = NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, tid, ®set, + &ioVec, ioVec.iov_len); + if (error.Fail()) return error; + + m_max_hbp_supported = dreg_state.dbg_info & 0xff; + m_refresh_hwdebug_info = false; + + return error; } -Error -NativeRegisterContextLinux_arm64::WriteHardwareDebugRegs(int hwbType) -{ - struct iovec ioVec; - struct user_hwdebug_state dreg_state; - Error error; +Error NativeRegisterContextLinux_arm64::WriteHardwareDebugRegs(int hwbType) { + struct iovec ioVec; + struct user_hwdebug_state dreg_state; + Error error; - memset (&dreg_state, 0, sizeof (dreg_state)); - ioVec.iov_base = &dreg_state; + memset(&dreg_state, 0, sizeof(dreg_state)); + ioVec.iov_base = &dreg_state; - if (hwbType == eDREGTypeWATCH) - { - hwbType = NT_ARM_HW_WATCH; - ioVec.iov_len = sizeof (dreg_state.dbg_info) + sizeof (dreg_state.pad) - + (sizeof (dreg_state.dbg_regs [0]) * m_max_hwp_supported); + if (hwbType == eDREGTypeWATCH) { + hwbType = NT_ARM_HW_WATCH; + ioVec.iov_len = sizeof(dreg_state.dbg_info) + sizeof(dreg_state.pad) + + (sizeof(dreg_state.dbg_regs[0]) * m_max_hwp_supported); - for (uint32_t i = 0; i < m_max_hwp_supported; i++) - { - dreg_state.dbg_regs[i].addr = m_hwp_regs[i].address; - dreg_state.dbg_regs[i].ctrl = m_hwp_regs[i].control; - } + for (uint32_t i = 0; i < m_max_hwp_supported; i++) { + dreg_state.dbg_regs[i].addr = m_hwp_regs[i].address; + dreg_state.dbg_regs[i].ctrl = m_hwp_regs[i].control; } - else - { - hwbType = NT_ARM_HW_BREAK; - ioVec.iov_len = sizeof (dreg_state.dbg_info) + sizeof (dreg_state.pad) - + (sizeof (dreg_state.dbg_regs [0]) * m_max_hbp_supported); + } else { + hwbType = NT_ARM_HW_BREAK; + ioVec.iov_len = sizeof(dreg_state.dbg_info) + sizeof(dreg_state.pad) + + (sizeof(dreg_state.dbg_regs[0]) * m_max_hbp_supported); - for (uint32_t i = 0; i < m_max_hbp_supported; i++) - { - dreg_state.dbg_regs[i].addr = m_hbr_regs[i].address; - dreg_state.dbg_regs[i].ctrl = m_hbr_regs[i].control; - } + for (uint32_t i = 0; i < m_max_hbp_supported; i++) { + dreg_state.dbg_regs[i].addr = m_hbr_regs[i].address; + dreg_state.dbg_regs[i].ctrl = m_hbr_regs[i].control; } + } - return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_thread.GetID(), &hwbType, &ioVec, ioVec.iov_len); + return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_thread.GetID(), + &hwbType, &ioVec, ioVec.iov_len); } -Error -NativeRegisterContextLinux_arm64::DoReadRegisterValue(uint32_t offset, - const char* reg_name, - uint32_t size, - RegisterValue &value) -{ - Error error; - if (offset > sizeof(struct user_pt_regs)) - { - uintptr_t offset = offset - sizeof(struct user_pt_regs); - if (offset > sizeof(struct user_fpsimd_state)) - { - error.SetErrorString("invalid offset value"); - return error; - } - elf_fpregset_t regs; - int regset = NT_FPREGSET; - struct iovec ioVec; +Error NativeRegisterContextLinux_arm64::DoReadRegisterValue( + uint32_t offset, const char *reg_name, uint32_t size, + RegisterValue &value) { + Error error; + if (offset > sizeof(struct user_pt_regs)) { + uintptr_t offset = offset - sizeof(struct user_pt_regs); + if (offset > sizeof(struct user_fpsimd_state)) { + error.SetErrorString("invalid offset value"); + return error; + } + elf_fpregset_t regs; + int regset = NT_FPREGSET; + struct iovec ioVec; - ioVec.iov_base = ®s; - ioVec.iov_len = sizeof regs; - error = NativeProcessLinux::PtraceWrapper( - PTRACE_GETREGSET, m_thread.GetID(), ®set, &ioVec, sizeof regs); - if (error.Success()) - { - ArchSpec arch; - if (m_thread.GetProcess()->GetArchitecture(arch)) - value.SetBytes((void *)(((unsigned char *)(®s)) + offset), 16, arch.GetByteOrder()); - else - error.SetErrorString("failed to get architecture"); - } + ioVec.iov_base = ®s; + ioVec.iov_len = sizeof regs; + error = NativeProcessLinux::PtraceWrapper( + PTRACE_GETREGSET, m_thread.GetID(), ®set, &ioVec, sizeof regs); + if (error.Success()) { + ArchSpec arch; + if (m_thread.GetProcess()->GetArchitecture(arch)) + value.SetBytes((void *)(((unsigned char *)(®s)) + offset), 16, + arch.GetByteOrder()); + else + error.SetErrorString("failed to get architecture"); } - else - { - elf_gregset_t regs; - int regset = NT_PRSTATUS; - struct iovec ioVec; + } else { + elf_gregset_t regs; + int regset = NT_PRSTATUS; + struct iovec ioVec; - ioVec.iov_base = ®s; - ioVec.iov_len = sizeof regs; - error = NativeProcessLinux::PtraceWrapper( - PTRACE_GETREGSET, m_thread.GetID(), ®set, &ioVec, sizeof regs); - if (error.Success()) - { - ArchSpec arch; - if (m_thread.GetProcess()->GetArchitecture(arch)) - value.SetBytes((void *)(((unsigned char *)(regs)) + offset), 8, arch.GetByteOrder()); - else - error.SetErrorString("failed to get architecture"); - } + ioVec.iov_base = ®s; + ioVec.iov_len = sizeof regs; + error = NativeProcessLinux::PtraceWrapper( + PTRACE_GETREGSET, m_thread.GetID(), ®set, &ioVec, sizeof regs); + if (error.Success()) { + ArchSpec arch; + if (m_thread.GetProcess()->GetArchitecture(arch)) + value.SetBytes((void *)(((unsigned char *)(regs)) + offset), 8, + arch.GetByteOrder()); + else + error.SetErrorString("failed to get architecture"); } - return error; + } + return error; } -Error -NativeRegisterContextLinux_arm64::DoWriteRegisterValue(uint32_t offset, - const char* reg_name, - const RegisterValue &value) -{ - Error error; - ::pid_t tid = m_thread.GetID(); - if (offset > sizeof(struct user_pt_regs)) - { - uintptr_t offset = offset - sizeof(struct user_pt_regs); - if (offset > sizeof(struct user_fpsimd_state)) - { - error.SetErrorString("invalid offset value"); - return error; - } - elf_fpregset_t regs; - int regset = NT_FPREGSET; - struct iovec ioVec; +Error NativeRegisterContextLinux_arm64::DoWriteRegisterValue( + uint32_t offset, const char *reg_name, const RegisterValue &value) { + Error error; + ::pid_t tid = m_thread.GetID(); + if (offset > sizeof(struct user_pt_regs)) { + uintptr_t offset = offset - sizeof(struct user_pt_regs); + if (offset > sizeof(struct user_fpsimd_state)) { + error.SetErrorString("invalid offset value"); + return error; + } + elf_fpregset_t regs; + int regset = NT_FPREGSET; + struct iovec ioVec; - ioVec.iov_base = ®s; - ioVec.iov_len = sizeof regs; - error = NativeProcessLinux::PtraceWrapper( PTRACE_GETREGSET, tid, ®set, &ioVec, sizeof regs); + ioVec.iov_base = ®s; + ioVec.iov_len = sizeof regs; + error = NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, tid, ®set, + &ioVec, sizeof regs); - if (error.Success()) - { - ::memcpy((void *)(((unsigned char *)(®s)) + offset), value.GetBytes(), 16); - error = NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, tid, ®set, &ioVec, sizeof regs); - } + if (error.Success()) { + ::memcpy((void *)(((unsigned char *)(®s)) + offset), value.GetBytes(), + 16); + error = NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, tid, ®set, + &ioVec, sizeof regs); } - else - { - elf_gregset_t regs; - int regset = NT_PRSTATUS; - struct iovec ioVec; + } else { + elf_gregset_t regs; + int regset = NT_PRSTATUS; + struct iovec ioVec; - ioVec.iov_base = ®s; - ioVec.iov_len = sizeof regs; - error = NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, tid, ®set, &ioVec, sizeof regs); - if (error.Success()) - { - ::memcpy((void *)(((unsigned char *)(®s)) + offset), value.GetBytes(), 8); - error = NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, tid, ®set, &ioVec, sizeof regs); - } + ioVec.iov_base = ®s; + ioVec.iov_len = sizeof regs; + error = NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, tid, ®set, + &ioVec, sizeof regs); + if (error.Success()) { + ::memcpy((void *)(((unsigned char *)(®s)) + offset), value.GetBytes(), + 8); + error = NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, tid, ®set, + &ioVec, sizeof regs); } - return error; + } + return error; } -Error -NativeRegisterContextLinux_arm64::DoReadGPR(void *buf, size_t buf_size) -{ - int regset = NT_PRSTATUS; - struct iovec ioVec; - Error error; +Error NativeRegisterContextLinux_arm64::DoReadGPR(void *buf, size_t buf_size) { + int regset = NT_PRSTATUS; + struct iovec ioVec; + Error error; - ioVec.iov_base = buf; - ioVec.iov_len = buf_size; - return NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_thread.GetID(), ®set, &ioVec, buf_size); + ioVec.iov_base = buf; + ioVec.iov_len = buf_size; + return NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_thread.GetID(), + ®set, &ioVec, buf_size); } -Error -NativeRegisterContextLinux_arm64::DoWriteGPR(void *buf, size_t buf_size) -{ - int regset = NT_PRSTATUS; - struct iovec ioVec; - Error error; +Error NativeRegisterContextLinux_arm64::DoWriteGPR(void *buf, size_t buf_size) { + int regset = NT_PRSTATUS; + struct iovec ioVec; + Error error; - ioVec.iov_base = buf; - ioVec.iov_len = buf_size; - return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_thread.GetID(), ®set, &ioVec, buf_size); + ioVec.iov_base = buf; + ioVec.iov_len = buf_size; + return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_thread.GetID(), + ®set, &ioVec, buf_size); } -Error -NativeRegisterContextLinux_arm64::DoReadFPR(void *buf, size_t buf_size) -{ - int regset = NT_FPREGSET; - struct iovec ioVec; - Error error; +Error NativeRegisterContextLinux_arm64::DoReadFPR(void *buf, size_t buf_size) { + int regset = NT_FPREGSET; + struct iovec ioVec; + Error error; - ioVec.iov_base = buf; - ioVec.iov_len = buf_size; - return NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_thread.GetID(), ®set, &ioVec, buf_size); + ioVec.iov_base = buf; + ioVec.iov_len = buf_size; + return NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_thread.GetID(), + ®set, &ioVec, buf_size); } -Error -NativeRegisterContextLinux_arm64::DoWriteFPR(void *buf, size_t buf_size) -{ - int regset = NT_FPREGSET; - struct iovec ioVec; - Error error; +Error NativeRegisterContextLinux_arm64::DoWriteFPR(void *buf, size_t buf_size) { + int regset = NT_FPREGSET; + struct iovec ioVec; + Error error; - ioVec.iov_base = buf; - ioVec.iov_len = buf_size; - return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_thread.GetID(), ®set, &ioVec, buf_size); + ioVec.iov_base = buf; + ioVec.iov_len = buf_size; + return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_thread.GetID(), + ®set, &ioVec, buf_size); } -uint32_t -NativeRegisterContextLinux_arm64::CalculateFprOffset(const RegisterInfo* reg_info) const -{ - return reg_info->byte_offset - GetRegisterInfoAtIndex(m_reg_info.first_fpr)->byte_offset; +uint32_t NativeRegisterContextLinux_arm64::CalculateFprOffset( + const RegisterInfo *reg_info) const { + return reg_info->byte_offset - + GetRegisterInfoAtIndex(m_reg_info.first_fpr)->byte_offset; } #endif // defined (__arm64__) || defined (__aarch64__) |
