diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2016-01-13 20:06:56 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2016-01-13 20:06:56 +0000 | 
| commit | 7fed546d1996271dabc7cf71d4d033125c4da4ee (patch) | |
| tree | 2b6dc7dcb4a6380cb331aded15f5a81c0038e194 /source/Plugins/Process/Linux | |
| parent | 9e6d35490a6542f9c97607f93c2ef8ca8e03cbcc (diff) | |
Notes
Diffstat (limited to 'source/Plugins/Process/Linux')
4 files changed, 119 insertions, 11 deletions
| diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp index 31752fed5b42a..79653fc626860 100644 --- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp +++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp @@ -7,7 +7,7 @@  //  //===----------------------------------------------------------------------===// -#if defined(__arm__) +#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)  #include "NativeRegisterContextLinux_arm.h" @@ -16,8 +16,12 @@  #include "lldb/Core/Log.h"  #include "lldb/Core/RegisterValue.h" +#include "Plugins/Process/Linux/Procfs.h"  #include "Plugins/Process/Utility/RegisterContextLinux_arm.h" +#include <elf.h> +#include <sys/socket.h> +  #define REG_CONTEXT_SIZE (GetGPRSize() + sizeof (m_fpr))  #ifndef PTRACE_GETVFPREGS @@ -169,6 +173,8 @@ g_reg_sets_arm[k_num_register_sets] =      { "Floating Point Registers",   "fpu", k_num_fpr_registers_arm, g_fpu_regnums_arm }  }; +#if defined(__arm__) +  NativeRegisterContextLinux*  NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(const ArchSpec& target_arch,                                                                   NativeThreadProtocol &native_thread, @@ -177,6 +183,8 @@ NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(const ArchSpec&      return new NativeRegisterContextLinux_arm(target_arch, native_thread, concrete_frame_idx);  } +#endif // defined(__arm__) +  NativeRegisterContextLinux_arm::NativeRegisterContextLinux_arm (const ArchSpec& target_arch,                                                                  NativeThreadProtocol &native_thread,                                                                  uint32_t concrete_frame_idx) : @@ -919,14 +927,14 @@ NativeRegisterContextLinux_arm::WriteHardwareDebugRegs(int hwbType, int hwb_inde          ctrl_buf = &m_hwp_regs[hwb_index].control;          error = NativeProcessLinux::PtraceWrapper(PTRACE_SETHBPREGS, -                m_thread.GetID(), (PTRACE_TYPE_ARG3) -((hwb_index << 1) + 1), +                m_thread.GetID(), (PTRACE_TYPE_ARG3)(intptr_t) -((hwb_index << 1) + 1),                  addr_buf, sizeof(unsigned int));          if (error.Fail())              return error;          error = NativeProcessLinux::PtraceWrapper(PTRACE_SETHBPREGS, -                m_thread.GetID(), (PTRACE_TYPE_ARG3) -((hwb_index << 1) + 2), +                m_thread.GetID(), (PTRACE_TYPE_ARG3)(intptr_t) -((hwb_index << 1) + 2),                  ctrl_buf, sizeof(unsigned int));      }      else @@ -935,14 +943,14 @@ NativeRegisterContextLinux_arm::WriteHardwareDebugRegs(int hwbType, int hwb_inde          ctrl_buf = &m_hwp_regs[hwb_index].control;          error = NativeProcessLinux::PtraceWrapper(PTRACE_SETHBPREGS, -                m_thread.GetID(), (PTRACE_TYPE_ARG3) ((hwb_index << 1) + 1), +                m_thread.GetID(), (PTRACE_TYPE_ARG3)(intptr_t) ((hwb_index << 1) + 1),                  addr_buf, sizeof(unsigned int));          if (error.Fail())              return error;          error = NativeProcessLinux::PtraceWrapper(PTRACE_SETHBPREGS, -                m_thread.GetID(), (PTRACE_TYPE_ARG3) ((hwb_index << 1) + 2), +                m_thread.GetID(), (PTRACE_TYPE_ARG3)(intptr_t) ((hwb_index << 1) + 2),                  ctrl_buf, sizeof(unsigned int));      } @@ -957,11 +965,33 @@ NativeRegisterContextLinux_arm::CalculateFprOffset(const RegisterInfo* reg_info)  }  Error +NativeRegisterContextLinux_arm::DoReadRegisterValue(uint32_t offset, +                                                    const char* reg_name, +                                                    uint32_t size, +                                                    RegisterValue &value) +{ +    // PTRACE_PEEKUSER don't work in the aarch64 linux kernel used on android devices (always return +    // "Bad address"). To avoid using PTRACE_PEEKUSER we read out the full GPR register set instead. +    // This approach is about 4 times slower but the performance overhead is negligible in +    // comparision to processing time in lldb-server. +    assert(offset % 4 == 0 && "Try to write a register with unaligned offset"); +    if (offset + sizeof(uint32_t) > sizeof(m_gpr_arm)) +        return Error("Register isn't fit into the size of the GPR area"); + +    Error error = DoReadGPR(m_gpr_arm, sizeof(m_gpr_arm)); +    if (error.Fail()) +        return error; + +    value.SetUInt32(m_gpr_arm[offset / sizeof(uint32_t)]); +    return Error(); +} + +Error  NativeRegisterContextLinux_arm::DoWriteRegisterValue(uint32_t offset,                                                       const char* reg_name,                                                       const RegisterValue &value)  { -    // PTRACE_POKEUSER don't work in the aarch64 liux kernel used on android devices (always return +    // PTRACE_POKEUSER don't work in the aarch64 linux kernel used on android devices (always return      // "Bad address"). To avoid using PTRACE_POKEUSER we read out the full GPR register set, modify      // the requested register and write it back. This approach is about 4 times slower but the      // performance overhead is negligible in comparision to processing time in lldb-server. @@ -995,23 +1025,67 @@ NativeRegisterContextLinux_arm::DoWriteRegisterValue(uint32_t offset,  }  Error +NativeRegisterContextLinux_arm::DoReadGPR(void *buf, size_t buf_size) +{ +#ifdef __arm__ +    return NativeRegisterContextLinux::DoReadGPR(buf, buf_size); +#else // __aarch64__ +    struct iovec ioVec; +    ioVec.iov_base = buf; +    ioVec.iov_len = buf_size; + +    return ReadRegisterSet(&ioVec, buf_size, NT_PRSTATUS); +#endif // __arm__ +} + +Error +NativeRegisterContextLinux_arm::DoWriteGPR(void *buf, size_t buf_size) +{ +#ifdef __arm__ +    return NativeRegisterContextLinux::DoWriteGPR(buf, buf_size); +#else // __aarch64__ +    struct iovec ioVec; +    ioVec.iov_base = buf; +    ioVec.iov_len = buf_size; + +    return WriteRegisterSet(&ioVec, buf_size, NT_PRSTATUS); +#endif // __arm__ +} + +Error  NativeRegisterContextLinux_arm::DoReadFPR(void *buf, size_t buf_size)  { +#ifdef __arm__      return NativeProcessLinux::PtraceWrapper(PTRACE_GETVFPREGS,                                               m_thread.GetID(),                                               nullptr,                                               buf,                                               buf_size); +#else // __aarch64__ +    struct iovec ioVec; +    ioVec.iov_base = buf; +    ioVec.iov_len = buf_size; + +    return ReadRegisterSet(&ioVec, buf_size, NT_ARM_VFP); +#endif // __arm__  }  Error  NativeRegisterContextLinux_arm::DoWriteFPR(void *buf, size_t buf_size)  { +#ifdef __arm__      return NativeProcessLinux::PtraceWrapper(PTRACE_SETVFPREGS,                                               m_thread.GetID(),                                               nullptr,                                               buf,                                               buf_size); +#else // __aarch64__ +    struct iovec ioVec; +    ioVec.iov_base = buf; +    ioVec.iov_len = buf_size; + +    return WriteRegisterSet(&ioVec, buf_size, NT_ARM_VFP); +#endif // __arm__  } -#endif // defined(__arm__) +#endif // defined(__arm__) || defined(__arm64__) || defined(__aarch64__) diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h index 611b36ad4db14..349564970428c 100644 --- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h +++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h @@ -7,7 +7,7 @@  //  //===----------------------------------------------------------------------===// -#if defined(__arm__) // arm register context only needed on arm devices +#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)  #ifndef lldb_NativeRegisterContextLinux_arm_h  #define lldb_NativeRegisterContextLinux_arm_h @@ -91,11 +91,23 @@ namespace process_linux {      protected:          Error +        DoReadRegisterValue(uint32_t offset, +                            const char* reg_name, +                            uint32_t size, +                            RegisterValue &value) override; + +        Error          DoWriteRegisterValue(uint32_t offset,                               const char* reg_name,                               const RegisterValue &value) override;          Error +        DoReadGPR(void *buf, size_t buf_size) override; + +        Error +        DoWriteGPR(void *buf, size_t buf_size) override; + +        Error          DoReadFPR(void *buf, size_t buf_size) override;          Error @@ -182,4 +194,4 @@ namespace process_linux {  #endif // #ifndef lldb_NativeRegisterContextLinux_arm_h -#endif // defined(__arm__) +#endif // defined(__arm__) || defined(__arm64__) || defined(__aarch64__) diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp index e4d26fc640f30..22cdbb40d15ca 100644 --- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp +++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp @@ -9,6 +9,7 @@  #if defined (__arm64__) || defined (__aarch64__) +#include "NativeRegisterContextLinux_arm.h"  #include "NativeRegisterContextLinux_arm64.h"  // C Includes @@ -23,6 +24,7 @@  #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"  // System includes - They have to be included after framework includes because they define some @@ -142,7 +144,19 @@ NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(const ArchSpec&                                                                   NativeThreadProtocol &native_thread,                                                                   uint32_t concrete_frame_idx)  { -    return new NativeRegisterContextLinux_arm64(target_arch, native_thread, 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, diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp index 3cfeaf5546bc7..54d6f721c9d8e 100644 --- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp +++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp @@ -1388,7 +1388,15 @@ NativeRegisterContextLinux_mips64::DoReadRegisterValue(uint32_t offset,      {          lldb_private::ArchSpec arch;          if (m_thread.GetProcess()->GetArchitecture(arch)) -            value.SetBytes((void *)(((unsigned char *)®s) + offset + 4 * (arch.GetMachine() == llvm::Triple::mips)), arch.GetFlags() & lldb_private::ArchSpec::eMIPSABI_O32 ? 4 : 8, arch.GetByteOrder()); +        { +            void* target_address = ((uint8_t*)®s) + offset + 4 * (arch.GetMachine() == llvm::Triple::mips); +            uint32_t target_size; +            if ((::strcmp(reg_name, "sr") == 0) || (::strcmp(reg_name, "cause") == 0) || (::strcmp(reg_name, "config5") == 0)) +                target_size = 4; +            else +                target_size = arch.GetFlags() & lldb_private::ArchSpec::eMIPSABI_O32 ? 4 : 8; +            value.SetBytes(target_address, target_size, arch.GetByteOrder()); +        }          else              error.SetErrorString("failed to get architecture");      } | 
