13f57216cSOmair Javaid //===-- NativeRegisterContextLinux_arm.cpp --------------------*- C++ -*-===// 23f57216cSOmair Javaid // 33f57216cSOmair Javaid // The LLVM Compiler Infrastructure 43f57216cSOmair Javaid // 53f57216cSOmair Javaid // This file is distributed under the University of Illinois Open Source 63f57216cSOmair Javaid // License. See LICENSE.TXT for details. 73f57216cSOmair Javaid // 83f57216cSOmair Javaid //===----------------------------------------------------------------------===// 93f57216cSOmair Javaid 103f57216cSOmair Javaid #include "NativeRegisterContextLinux_arm.h" 113f57216cSOmair Javaid 123f57216cSOmair Javaid #include "lldb/lldb-private-forward.h" 133f57216cSOmair Javaid #include "lldb/Core/DataBufferHeap.h" 143f57216cSOmair Javaid #include "lldb/Core/Error.h" 153f57216cSOmair Javaid #include "lldb/Core/RegisterValue.h" 163f57216cSOmair Javaid #include "lldb/Host/common/NativeProcessProtocol.h" 173f57216cSOmair Javaid #include "lldb/Host/common/NativeThreadProtocol.h" 183f57216cSOmair Javaid #include "Plugins/Process/Linux/NativeProcessLinux.h" 193f57216cSOmair Javaid 203f57216cSOmair Javaid #define REG_CONTEXT_SIZE (GetGPRSize() + sizeof (m_fpr)) 213f57216cSOmair Javaid 223f57216cSOmair Javaid using namespace lldb; 233f57216cSOmair Javaid using namespace lldb_private; 243f57216cSOmair Javaid using namespace lldb_private::process_linux; 253f57216cSOmair Javaid 263f57216cSOmair Javaid // arm general purpose registers. 273f57216cSOmair Javaid static const uint32_t g_gpr_regnums_arm[] = 283f57216cSOmair Javaid { 293f57216cSOmair Javaid gpr_r0_arm, 303f57216cSOmair Javaid gpr_r1_arm, 313f57216cSOmair Javaid gpr_r2_arm, 323f57216cSOmair Javaid gpr_r3_arm, 333f57216cSOmair Javaid gpr_r4_arm, 343f57216cSOmair Javaid gpr_r5_arm, 353f57216cSOmair Javaid gpr_r6_arm, 363f57216cSOmair Javaid gpr_r7_arm, 373f57216cSOmair Javaid gpr_r8_arm, 383f57216cSOmair Javaid gpr_r9_arm, 393f57216cSOmair Javaid gpr_r10_arm, 403f57216cSOmair Javaid gpr_r11_arm, 413f57216cSOmair Javaid gpr_r12_arm, 423f57216cSOmair Javaid gpr_sp_arm, 433f57216cSOmair Javaid gpr_lr_arm, 443f57216cSOmair Javaid gpr_pc_arm, 453f57216cSOmair Javaid gpr_cpsr_arm, 463f57216cSOmair Javaid LLDB_INVALID_REGNUM // register sets need to end with this flag 473f57216cSOmair Javaid }; 483f57216cSOmair Javaid static_assert(((sizeof g_gpr_regnums_arm / sizeof g_gpr_regnums_arm[0]) - 1) == k_num_gpr_registers_arm, \ 493f57216cSOmair Javaid "g_gpr_regnums_arm has wrong number of register infos"); 503f57216cSOmair Javaid 513f57216cSOmair Javaid // arm floating point registers. 523f57216cSOmair Javaid static const uint32_t g_fpu_regnums_arm[] = 533f57216cSOmair Javaid { 543f57216cSOmair Javaid fpu_s0_arm, 553f57216cSOmair Javaid fpu_s1_arm, 563f57216cSOmair Javaid fpu_s2_arm, 573f57216cSOmair Javaid fpu_s3_arm, 583f57216cSOmair Javaid fpu_s4_arm, 593f57216cSOmair Javaid fpu_s5_arm, 603f57216cSOmair Javaid fpu_s6_arm, 613f57216cSOmair Javaid fpu_s7_arm, 623f57216cSOmair Javaid fpu_s8_arm, 633f57216cSOmair Javaid fpu_s9_arm, 643f57216cSOmair Javaid fpu_s10_arm, 653f57216cSOmair Javaid fpu_s11_arm, 663f57216cSOmair Javaid fpu_s12_arm, 673f57216cSOmair Javaid fpu_s13_arm, 683f57216cSOmair Javaid fpu_s14_arm, 693f57216cSOmair Javaid fpu_s15_arm, 703f57216cSOmair Javaid fpu_s16_arm, 713f57216cSOmair Javaid fpu_s17_arm, 723f57216cSOmair Javaid fpu_s18_arm, 733f57216cSOmair Javaid fpu_s19_arm, 743f57216cSOmair Javaid fpu_s20_arm, 753f57216cSOmair Javaid fpu_s21_arm, 763f57216cSOmair Javaid fpu_s22_arm, 773f57216cSOmair Javaid fpu_s23_arm, 783f57216cSOmair Javaid fpu_s24_arm, 793f57216cSOmair Javaid fpu_s25_arm, 803f57216cSOmair Javaid fpu_s26_arm, 813f57216cSOmair Javaid fpu_s27_arm, 823f57216cSOmair Javaid fpu_s28_arm, 833f57216cSOmair Javaid fpu_s29_arm, 843f57216cSOmair Javaid fpu_s30_arm, 853f57216cSOmair Javaid fpu_s31_arm, 863f57216cSOmair Javaid fpu_fpscr_arm, 873f57216cSOmair Javaid LLDB_INVALID_REGNUM // register sets need to end with this flag 883f57216cSOmair Javaid }; 893f57216cSOmair Javaid static_assert(((sizeof g_fpu_regnums_arm / sizeof g_fpu_regnums_arm[0]) - 1) == k_num_fpr_registers_arm, \ 903f57216cSOmair Javaid "g_fpu_regnums_arm has wrong number of register infos"); 913f57216cSOmair Javaid 923f57216cSOmair Javaid namespace { 933f57216cSOmair Javaid // Number of register sets provided by this context. 943f57216cSOmair Javaid enum 953f57216cSOmair Javaid { 963f57216cSOmair Javaid k_num_register_sets = 2 973f57216cSOmair Javaid }; 983f57216cSOmair Javaid } 993f57216cSOmair Javaid 1003f57216cSOmair Javaid // Register sets for arm. 1013f57216cSOmair Javaid static const RegisterSet 1023f57216cSOmair Javaid g_reg_sets_arm[k_num_register_sets] = 1033f57216cSOmair Javaid { 1043f57216cSOmair Javaid { "General Purpose Registers", "gpr", k_num_gpr_registers_arm, g_gpr_regnums_arm }, 1053f57216cSOmair Javaid { "Floating Point Registers", "fpu", k_num_fpr_registers_arm, g_fpu_regnums_arm } 1063f57216cSOmair Javaid }; 1073f57216cSOmair Javaid 1083f57216cSOmair Javaid NativeRegisterContextLinux_arm::NativeRegisterContextLinux_arm ( 1093f57216cSOmair Javaid NativeThreadProtocol &native_thread, 1103f57216cSOmair Javaid uint32_t concrete_frame_idx, 1113f57216cSOmair Javaid RegisterInfoInterface *reg_info_interface_p) : 1123f57216cSOmair Javaid NativeRegisterContextRegisterInfo (native_thread, concrete_frame_idx, reg_info_interface_p) 1133f57216cSOmair Javaid { 1143f57216cSOmair Javaid switch (reg_info_interface_p->m_target_arch.GetMachine()) 1153f57216cSOmair Javaid { 1163f57216cSOmair Javaid case llvm::Triple::arm: 1173f57216cSOmair Javaid m_reg_info.num_registers = k_num_registers_arm; 1183f57216cSOmair Javaid m_reg_info.num_gpr_registers = k_num_gpr_registers_arm; 1193f57216cSOmair Javaid m_reg_info.num_fpr_registers = k_num_fpr_registers_arm; 1203f57216cSOmair Javaid m_reg_info.last_gpr = k_last_gpr_arm; 1213f57216cSOmair Javaid m_reg_info.first_fpr = k_first_fpr_arm; 1223f57216cSOmair Javaid m_reg_info.last_fpr = k_last_fpr_arm; 1233f57216cSOmair Javaid m_reg_info.first_fpr_v = fpu_s0_arm; 1243f57216cSOmair Javaid m_reg_info.last_fpr_v = fpu_s31_arm; 1253f57216cSOmair Javaid m_reg_info.gpr_flags = gpr_cpsr_arm; 1263f57216cSOmair Javaid break; 1273f57216cSOmair Javaid default: 1283f57216cSOmair Javaid assert(false && "Unhandled target architecture."); 1293f57216cSOmair Javaid break; 1303f57216cSOmair Javaid } 1313f57216cSOmair Javaid 1323f57216cSOmair Javaid ::memset(&m_fpr, 0, sizeof (m_fpr)); 1333f57216cSOmair Javaid ::memset(&m_gpr_arm, 0, sizeof (m_gpr_arm)); 1343f57216cSOmair Javaid } 1353f57216cSOmair Javaid 1363f57216cSOmair Javaid uint32_t 1373f57216cSOmair Javaid NativeRegisterContextLinux_arm::GetRegisterSetCount () const 1383f57216cSOmair Javaid { 1393f57216cSOmair Javaid return k_num_register_sets; 1403f57216cSOmair Javaid } 1413f57216cSOmair Javaid 1423f57216cSOmair Javaid const RegisterSet * 1433f57216cSOmair Javaid NativeRegisterContextLinux_arm::GetRegisterSet (uint32_t set_index) const 1443f57216cSOmair Javaid { 1453f57216cSOmair Javaid if (set_index < k_num_register_sets) 1463f57216cSOmair Javaid return &g_reg_sets_arm[set_index]; 1473f57216cSOmair Javaid 1483f57216cSOmair Javaid return nullptr; 1493f57216cSOmair Javaid } 1503f57216cSOmair Javaid 1513f57216cSOmair Javaid Error 1523f57216cSOmair Javaid NativeRegisterContextLinux_arm::ReadRegister (const RegisterInfo *reg_info, RegisterValue ®_value) 1533f57216cSOmair Javaid { 1543f57216cSOmair Javaid Error error; 1553f57216cSOmair Javaid 1563f57216cSOmair Javaid if (!reg_info) 1573f57216cSOmair Javaid { 1583f57216cSOmair Javaid error.SetErrorString ("reg_info NULL"); 1593f57216cSOmair Javaid return error; 1603f57216cSOmair Javaid } 1613f57216cSOmair Javaid 1623f57216cSOmair Javaid const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB]; 1633f57216cSOmair Javaid 1643f57216cSOmair Javaid if (IsFPR(reg)) 1653f57216cSOmair Javaid { 1663f57216cSOmair Javaid if (!ReadFPR()) 1673f57216cSOmair Javaid { 1683f57216cSOmair Javaid error.SetErrorString ("failed to read floating point register"); 1693f57216cSOmair Javaid return error; 1703f57216cSOmair Javaid } 1713f57216cSOmair Javaid } 1723f57216cSOmair Javaid else 1733f57216cSOmair Javaid { 1743f57216cSOmair Javaid uint32_t full_reg = reg; 1753f57216cSOmair Javaid bool is_subreg = reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM); 1763f57216cSOmair Javaid 1773f57216cSOmair Javaid if (is_subreg) 1783f57216cSOmair Javaid { 1793f57216cSOmair Javaid // Read the full aligned 64-bit register. 1803f57216cSOmair Javaid full_reg = reg_info->invalidate_regs[0]; 1813f57216cSOmair Javaid } 1823f57216cSOmair Javaid 1833f57216cSOmair Javaid error = ReadRegisterRaw(full_reg, reg_value); 1843f57216cSOmair Javaid 1853f57216cSOmair Javaid if (error.Success ()) 1863f57216cSOmair Javaid { 1873f57216cSOmair Javaid // If our read was not aligned (for ah,bh,ch,dh), shift our returned value one byte to the right. 1883f57216cSOmair Javaid if (is_subreg && (reg_info->byte_offset & 0x1)) 1893f57216cSOmair Javaid reg_value.SetUInt64(reg_value.GetAsUInt64() >> 8); 1903f57216cSOmair Javaid 1913f57216cSOmair Javaid // If our return byte size was greater than the return value reg size, then 1923f57216cSOmair Javaid // use the type specified by reg_info rather than the uint64_t default 1933f57216cSOmair Javaid if (reg_value.GetByteSize() > reg_info->byte_size) 1943f57216cSOmair Javaid reg_value.SetType(reg_info); 1953f57216cSOmair Javaid } 1963f57216cSOmair Javaid return error; 1973f57216cSOmair Javaid } 1983f57216cSOmair Javaid 1993f57216cSOmair Javaid // Get pointer to m_fpr variable and set the data from it. 2003f57216cSOmair Javaid assert (reg_info->byte_offset < sizeof m_fpr); 2013f57216cSOmair Javaid uint8_t *src = (uint8_t *)&m_fpr + reg_info->byte_offset; 2023f57216cSOmair Javaid switch (reg_info->byte_size) 2033f57216cSOmair Javaid { 2043f57216cSOmair Javaid case 2: 2053f57216cSOmair Javaid reg_value.SetUInt16(*(uint16_t *)src); 2063f57216cSOmair Javaid break; 2073f57216cSOmair Javaid case 4: 2083f57216cSOmair Javaid reg_value.SetUInt32(*(uint32_t *)src); 2093f57216cSOmair Javaid break; 2103f57216cSOmair Javaid case 8: 2113f57216cSOmair Javaid reg_value.SetUInt64(*(uint64_t *)src); 2123f57216cSOmair Javaid break; 2133f57216cSOmair Javaid default: 2143f57216cSOmair Javaid assert(false && "Unhandled data size."); 2153f57216cSOmair Javaid error.SetErrorStringWithFormat ("unhandled byte size: %" PRIu32, reg_info->byte_size); 2163f57216cSOmair Javaid break; 2173f57216cSOmair Javaid } 2183f57216cSOmair Javaid 2193f57216cSOmair Javaid return error; 2203f57216cSOmair Javaid } 2213f57216cSOmair Javaid 2223f57216cSOmair Javaid Error 2233f57216cSOmair Javaid NativeRegisterContextLinux_arm::WriteRegister (const RegisterInfo *reg_info, const RegisterValue ®_value) 2243f57216cSOmair Javaid { 2253f57216cSOmair Javaid if (!reg_info) 2263f57216cSOmair Javaid return Error ("reg_info NULL"); 2273f57216cSOmair Javaid 2283f57216cSOmair Javaid const uint32_t reg_index = reg_info->kinds[lldb::eRegisterKindLLDB]; 2293f57216cSOmair Javaid if (reg_index == LLDB_INVALID_REGNUM) 2303f57216cSOmair Javaid return Error ("no lldb regnum for %s", reg_info && reg_info->name ? reg_info->name : "<unknown register>"); 2313f57216cSOmair Javaid 2323f57216cSOmair Javaid if (IsGPR(reg_index)) 2333f57216cSOmair Javaid return WriteRegisterRaw(reg_index, reg_value); 2343f57216cSOmair Javaid 2353f57216cSOmair Javaid if (IsFPR(reg_index)) 2363f57216cSOmair Javaid { 2373f57216cSOmair Javaid // Get pointer to m_fpr variable and set the data to it. 2383f57216cSOmair Javaid assert (reg_info->byte_offset < sizeof(m_fpr)); 2393f57216cSOmair Javaid uint8_t *dst = (uint8_t *)&m_fpr + reg_info->byte_offset; 2403f57216cSOmair Javaid switch (reg_info->byte_size) 2413f57216cSOmair Javaid { 2423f57216cSOmair Javaid case 2: 2433f57216cSOmair Javaid *(uint16_t *)dst = reg_value.GetAsUInt16(); 2443f57216cSOmair Javaid break; 2453f57216cSOmair Javaid case 4: 2463f57216cSOmair Javaid *(uint32_t *)dst = reg_value.GetAsUInt32(); 2473f57216cSOmair Javaid break; 2483f57216cSOmair Javaid case 8: 2493f57216cSOmair Javaid *(uint64_t *)dst = reg_value.GetAsUInt64(); 2503f57216cSOmair Javaid break; 2513f57216cSOmair Javaid default: 2523f57216cSOmair Javaid assert(false && "Unhandled data size."); 2533f57216cSOmair Javaid return Error ("unhandled register data size %" PRIu32, reg_info->byte_size); 2543f57216cSOmair Javaid } 2553f57216cSOmair Javaid 2563f57216cSOmair Javaid if (!WriteFPR()) 2573f57216cSOmair Javaid { 2583f57216cSOmair Javaid return Error ("NativeRegisterContextLinux_arm::WriteRegister: WriteFPR failed"); 2593f57216cSOmair Javaid } 2603f57216cSOmair Javaid 2613f57216cSOmair Javaid return Error (); 2623f57216cSOmair Javaid } 2633f57216cSOmair Javaid 2643f57216cSOmair Javaid return Error ("failed - register wasn't recognized to be a GPR or an FPR, write strategy unknown"); 2653f57216cSOmair Javaid } 2663f57216cSOmair Javaid 2673f57216cSOmair Javaid Error 2683f57216cSOmair Javaid NativeRegisterContextLinux_arm::ReadAllRegisterValues (lldb::DataBufferSP &data_sp) 2693f57216cSOmair Javaid { 2703f57216cSOmair Javaid Error error; 2713f57216cSOmair Javaid 2723f57216cSOmair Javaid data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0)); 2733f57216cSOmair Javaid if (!data_sp) 274*bef47e49SGreg Clayton return Error ("failed to allocate DataBufferHeap instance of size %" PRIu64, (uint64_t)REG_CONTEXT_SIZE); 2753f57216cSOmair Javaid 2763f57216cSOmair Javaid if (!ReadGPR ()) 2773f57216cSOmair Javaid { 2783f57216cSOmair Javaid error.SetErrorString ("ReadGPR() failed"); 2793f57216cSOmair Javaid return error; 2803f57216cSOmair Javaid } 2813f57216cSOmair Javaid 2823f57216cSOmair Javaid if (!ReadFPR ()) 2833f57216cSOmair Javaid { 2843f57216cSOmair Javaid error.SetErrorString ("ReadFPR() failed"); 2853f57216cSOmair Javaid return error; 2863f57216cSOmair Javaid } 2873f57216cSOmair Javaid 2883f57216cSOmair Javaid uint8_t *dst = data_sp->GetBytes (); 2893f57216cSOmair Javaid if (dst == nullptr) 2903f57216cSOmair Javaid { 291*bef47e49SGreg Clayton error.SetErrorStringWithFormat ("DataBufferHeap instance of size %" PRIu64 " returned a null pointer", (uint64_t)REG_CONTEXT_SIZE); 2923f57216cSOmair Javaid return error; 2933f57216cSOmair Javaid } 2943f57216cSOmair Javaid 2953f57216cSOmair Javaid ::memcpy (dst, &m_gpr_arm, GetGPRSize()); 2963f57216cSOmair Javaid dst += GetGPRSize(); 2973f57216cSOmair Javaid ::memcpy (dst, &m_fpr, sizeof(m_fpr)); 2983f57216cSOmair Javaid 2993f57216cSOmair Javaid return error; 3003f57216cSOmair Javaid } 3013f57216cSOmair Javaid 3023f57216cSOmair Javaid Error 3033f57216cSOmair Javaid NativeRegisterContextLinux_arm::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp) 3043f57216cSOmair Javaid { 3053f57216cSOmair Javaid Error error; 3063f57216cSOmair Javaid 3073f57216cSOmair Javaid if (!data_sp) 3083f57216cSOmair Javaid { 3093f57216cSOmair Javaid error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s invalid data_sp provided", __FUNCTION__); 3103f57216cSOmair Javaid return error; 3113f57216cSOmair Javaid } 3123f57216cSOmair Javaid 3133f57216cSOmair Javaid if (data_sp->GetByteSize () != REG_CONTEXT_SIZE) 3143f57216cSOmair Javaid { 315*bef47e49SGreg Clayton error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s data_sp contained mismatched data size, expected %" PRIu64 ", actual %" PRIu64, __FUNCTION__, (uint64_t)REG_CONTEXT_SIZE, data_sp->GetByteSize ()); 3163f57216cSOmair Javaid return error; 3173f57216cSOmair Javaid } 3183f57216cSOmair Javaid 3193f57216cSOmair Javaid 3203f57216cSOmair Javaid uint8_t *src = data_sp->GetBytes (); 3213f57216cSOmair Javaid if (src == nullptr) 3223f57216cSOmair Javaid { 3233f57216cSOmair Javaid error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s DataBuffer::GetBytes() returned a null pointer", __FUNCTION__); 3243f57216cSOmair Javaid return error; 3253f57216cSOmair Javaid } 3263f57216cSOmair Javaid ::memcpy (&m_gpr_arm, src, GetRegisterInfoInterface ().GetGPRSize ()); 3273f57216cSOmair Javaid 3283f57216cSOmair Javaid if (!WriteGPR ()) 3293f57216cSOmair Javaid { 3303f57216cSOmair Javaid error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s WriteGPR() failed", __FUNCTION__); 3313f57216cSOmair Javaid return error; 3323f57216cSOmair Javaid } 3333f57216cSOmair Javaid 3343f57216cSOmair Javaid src += GetRegisterInfoInterface ().GetGPRSize (); 3353f57216cSOmair Javaid ::memcpy (&m_fpr, src, sizeof(m_fpr)); 3363f57216cSOmair Javaid 3373f57216cSOmair Javaid if (!WriteFPR ()) 3383f57216cSOmair Javaid { 3393f57216cSOmair Javaid error.SetErrorStringWithFormat ("NativeRegisterContextLinux_x86_64::%s WriteFPR() failed", __FUNCTION__); 3403f57216cSOmair Javaid return error; 3413f57216cSOmair Javaid } 3423f57216cSOmair Javaid 3433f57216cSOmair Javaid return error; 3443f57216cSOmair Javaid } 3453f57216cSOmair Javaid 3463f57216cSOmair Javaid Error 3473f57216cSOmair Javaid NativeRegisterContextLinux_arm::WriteRegisterRaw (uint32_t reg_index, const RegisterValue ®_value) 3483f57216cSOmair Javaid { 3493f57216cSOmair Javaid Error error; 3503f57216cSOmair Javaid 3513f57216cSOmair Javaid uint32_t reg_to_write = reg_index; 3523f57216cSOmair Javaid RegisterValue value_to_write = reg_value; 3533f57216cSOmair Javaid 3543f57216cSOmair Javaid // Check if this is a subregister of a full register. 3553f57216cSOmair Javaid const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg_index); 3563f57216cSOmair Javaid if (reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM)) 3573f57216cSOmair Javaid { 3583f57216cSOmair Javaid RegisterValue full_value; 3593f57216cSOmair Javaid uint32_t full_reg = reg_info->invalidate_regs[0]; 3603f57216cSOmair Javaid const RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg); 3613f57216cSOmair Javaid 3623f57216cSOmair Javaid // Read the full register. 3633f57216cSOmair Javaid error = ReadRegister(full_reg_info, full_value); 3643f57216cSOmair Javaid if (error.Fail ()) 3653f57216cSOmair Javaid return error; 3663f57216cSOmair Javaid 3673f57216cSOmair Javaid lldb::ByteOrder byte_order = GetByteOrder(); 3683f57216cSOmair Javaid uint8_t dst[RegisterValue::kMaxRegisterByteSize]; 3693f57216cSOmair Javaid 3703f57216cSOmair Javaid // Get the bytes for the full register. 3713f57216cSOmair Javaid const uint32_t dest_size = full_value.GetAsMemoryData (full_reg_info, 3723f57216cSOmair Javaid dst, 3733f57216cSOmair Javaid sizeof(dst), 3743f57216cSOmair Javaid byte_order, 3753f57216cSOmair Javaid error); 3763f57216cSOmair Javaid if (error.Success() && dest_size) 3773f57216cSOmair Javaid { 3783f57216cSOmair Javaid uint8_t src[RegisterValue::kMaxRegisterByteSize]; 3793f57216cSOmair Javaid 3803f57216cSOmair Javaid // Get the bytes for the source data. 3813f57216cSOmair Javaid const uint32_t src_size = reg_value.GetAsMemoryData (reg_info, src, sizeof(src), byte_order, error); 3823f57216cSOmair Javaid if (error.Success() && src_size && (src_size < dest_size)) 3833f57216cSOmair Javaid { 3843f57216cSOmair Javaid // Copy the src bytes to the destination. 3853f57216cSOmair Javaid memcpy (dst + (reg_info->byte_offset & 0x1), src, src_size); 3863f57216cSOmair Javaid // Set this full register as the value to write. 3873f57216cSOmair Javaid value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order); 3883f57216cSOmair Javaid value_to_write.SetType(full_reg_info); 3893f57216cSOmair Javaid reg_to_write = full_reg; 3903f57216cSOmair Javaid } 3913f57216cSOmair Javaid } 3923f57216cSOmair Javaid } 3933f57216cSOmair Javaid 3943f57216cSOmair Javaid NativeProcessProtocolSP process_sp (m_thread.GetProcess ()); 3953f57216cSOmair Javaid if (!process_sp) 3963f57216cSOmair Javaid { 3973f57216cSOmair Javaid error.SetErrorString ("NativeProcessProtocol is NULL"); 3983f57216cSOmair Javaid return error; 3993f57216cSOmair Javaid } 4003f57216cSOmair Javaid 4013f57216cSOmair Javaid const RegisterInfo *const register_to_write_info_p = GetRegisterInfoAtIndex (reg_to_write); 4023f57216cSOmair Javaid assert (register_to_write_info_p && "register to write does not have valid RegisterInfo"); 4033f57216cSOmair Javaid if (!register_to_write_info_p) 4043f57216cSOmair Javaid { 4053f57216cSOmair Javaid error.SetErrorStringWithFormat ("NativeRegisterContextLinux_arm::%s failed to get RegisterInfo for write register index %" PRIu32, __FUNCTION__, reg_to_write); 4063f57216cSOmair Javaid return error; 4073f57216cSOmair Javaid } 4083f57216cSOmair Javaid 4093f57216cSOmair Javaid NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ()); 4103f57216cSOmair Javaid return process_p->WriteRegisterValue(m_thread.GetID(), 4113f57216cSOmair Javaid register_to_write_info_p->byte_offset, 4123f57216cSOmair Javaid register_to_write_info_p->name, 4133f57216cSOmair Javaid value_to_write); 4143f57216cSOmair Javaid } 4153f57216cSOmair Javaid 4163f57216cSOmair Javaid Error 4173f57216cSOmair Javaid NativeRegisterContextLinux_arm::ReadRegisterRaw (uint32_t reg_index, RegisterValue ®_value) 4183f57216cSOmair Javaid { 4193f57216cSOmair Javaid Error error; 4203f57216cSOmair Javaid const RegisterInfo *const reg_info = GetRegisterInfoAtIndex (reg_index); 4213f57216cSOmair Javaid if (!reg_info) 4223f57216cSOmair Javaid { 4233f57216cSOmair Javaid error.SetErrorStringWithFormat ("register %" PRIu32 " not found", reg_index); 4243f57216cSOmair Javaid return error; 4253f57216cSOmair Javaid } 4263f57216cSOmair Javaid 4273f57216cSOmair Javaid NativeProcessProtocolSP process_sp (m_thread.GetProcess ()); 4283f57216cSOmair Javaid if (!process_sp) 4293f57216cSOmair Javaid { 4303f57216cSOmair Javaid error.SetErrorString ("NativeProcessProtocol is NULL"); 4313f57216cSOmair Javaid return error; 4323f57216cSOmair Javaid } 4333f57216cSOmair Javaid 4343f57216cSOmair Javaid NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ()); 4353f57216cSOmair Javaid return process_p->ReadRegisterValue(m_thread.GetID(), 4363f57216cSOmair Javaid reg_info->byte_offset, 4373f57216cSOmair Javaid reg_info->name, 4383f57216cSOmair Javaid reg_info->byte_size, 4393f57216cSOmair Javaid reg_value); 4403f57216cSOmair Javaid } 4413f57216cSOmair Javaid 4423f57216cSOmair Javaid bool 4433f57216cSOmair Javaid NativeRegisterContextLinux_arm::IsGPR(unsigned reg) const 4443f57216cSOmair Javaid { 4453f57216cSOmair Javaid return reg <= m_reg_info.last_gpr; // GPR's come first. 4463f57216cSOmair Javaid } 4473f57216cSOmair Javaid 4483f57216cSOmair Javaid bool 4493f57216cSOmair Javaid NativeRegisterContextLinux_arm::ReadGPR() 4503f57216cSOmair Javaid { 4513f57216cSOmair Javaid NativeProcessProtocolSP process_sp (m_thread.GetProcess ()); 4523f57216cSOmair Javaid if (!process_sp) 4533f57216cSOmair Javaid return false; 4543f57216cSOmair Javaid NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ()); 4553f57216cSOmair Javaid 4563f57216cSOmair Javaid return process_p->ReadGPR (m_thread.GetID (), &m_gpr_arm, GetRegisterInfoInterface ().GetGPRSize ()).Success(); 4573f57216cSOmair Javaid } 4583f57216cSOmair Javaid 4593f57216cSOmair Javaid bool 4603f57216cSOmair Javaid NativeRegisterContextLinux_arm::WriteGPR() 4613f57216cSOmair Javaid { 4623f57216cSOmair Javaid NativeProcessProtocolSP process_sp (m_thread.GetProcess ()); 4633f57216cSOmair Javaid if (!process_sp) 4643f57216cSOmair Javaid return false; 4653f57216cSOmair Javaid NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ()); 4663f57216cSOmair Javaid 4673f57216cSOmair Javaid return process_p->WriteGPR (m_thread.GetID (), &m_gpr_arm, GetRegisterInfoInterface ().GetGPRSize ()).Success(); 4683f57216cSOmair Javaid } 4693f57216cSOmair Javaid 4703f57216cSOmair Javaid bool 4713f57216cSOmair Javaid NativeRegisterContextLinux_arm::IsFPR(unsigned reg) const 4723f57216cSOmair Javaid { 4733f57216cSOmair Javaid return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr); 4743f57216cSOmair Javaid } 4753f57216cSOmair Javaid 4763f57216cSOmair Javaid bool 4773f57216cSOmair Javaid NativeRegisterContextLinux_arm::ReadFPR () 4783f57216cSOmair Javaid { 4793f57216cSOmair Javaid NativeProcessProtocolSP process_sp (m_thread.GetProcess ()); 4803f57216cSOmair Javaid if (!process_sp) 4813f57216cSOmair Javaid return false; 4823f57216cSOmair Javaid 4833f57216cSOmair Javaid NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ()); 4843f57216cSOmair Javaid return process_p->ReadFPR (m_thread.GetID (), &m_fpr, sizeof (m_fpr)).Success(); 4853f57216cSOmair Javaid } 4863f57216cSOmair Javaid 4873f57216cSOmair Javaid bool 4883f57216cSOmair Javaid NativeRegisterContextLinux_arm::WriteFPR () 4893f57216cSOmair Javaid { 4903f57216cSOmair Javaid NativeProcessProtocolSP process_sp (m_thread.GetProcess ()); 4913f57216cSOmair Javaid if (!process_sp) 4923f57216cSOmair Javaid return false; 4933f57216cSOmair Javaid 4943f57216cSOmair Javaid NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*> (process_sp.get ()); 4953f57216cSOmair Javaid return process_p->WriteFPR (m_thread.GetID (), &m_fpr, sizeof (m_fpr)).Success(); 4963f57216cSOmair Javaid } 4973f57216cSOmair Javaid 4983f57216cSOmair Javaid lldb::ByteOrder 4993f57216cSOmair Javaid NativeRegisterContextLinux_arm::GetByteOrder() const 5003f57216cSOmair Javaid { 5013f57216cSOmair Javaid // Get the target process whose privileged thread was used for the register read. 5023f57216cSOmair Javaid lldb::ByteOrder byte_order = lldb::eByteOrderInvalid; 5033f57216cSOmair Javaid 5043f57216cSOmair Javaid NativeProcessProtocolSP process_sp (m_thread.GetProcess ()); 5053f57216cSOmair Javaid if (!process_sp) 5063f57216cSOmair Javaid return byte_order; 5073f57216cSOmair Javaid 5083f57216cSOmair Javaid if (!process_sp->GetByteOrder (byte_order)) 5093f57216cSOmair Javaid { 5103f57216cSOmair Javaid // FIXME log here 5113f57216cSOmair Javaid } 5123f57216cSOmair Javaid 5133f57216cSOmair Javaid return byte_order; 5143f57216cSOmair Javaid } 5153f57216cSOmair Javaid 5163f57216cSOmair Javaid size_t 5173f57216cSOmair Javaid NativeRegisterContextLinux_arm::GetGPRSize() const 5183f57216cSOmair Javaid { 5193f57216cSOmair Javaid return GetRegisterInfoInterface().GetGPRSize(); 5203f57216cSOmair Javaid } 521