[Lldb-commits] [lldb] r257322 - Make the aarch64 lldb-server capable of debugging arm32 applications

Tamas Berghammer via lldb-commits lldb-commits at lists.llvm.org
Mon Jan 11 02:39:17 PST 2016


Author: tberghammer
Date: Mon Jan 11 04:39:09 2016
New Revision: 257322

URL: http://llvm.org/viewvc/llvm-project?rev=257322&view=rev
Log:
Make the aarch64 lldb-server capable of debugging arm32 applications

Differential revision: http://reviews.llvm.org/D15533

Modified:
    lldb/trunk/source/Host/common/HostInfoBase.cpp
    lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp
    lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h
    lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp

Modified: lldb/trunk/source/Host/common/HostInfoBase.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/HostInfoBase.cpp?rev=257322&r1=257321&r2=257322&view=diff
==============================================================================
--- lldb/trunk/source/Host/common/HostInfoBase.cpp (original)
+++ lldb/trunk/source/Host/common/HostInfoBase.cpp Mon Jan 11 04:39:09 2016
@@ -409,13 +409,13 @@ HostInfoBase::ComputeHostArchitectureSup
             arch_32.SetTriple(triple);
             break;
 
+        case llvm::Triple::aarch64:
         case llvm::Triple::ppc64:
         case llvm::Triple::x86_64:
             arch_64.SetTriple(triple);
             arch_32.SetTriple(triple.get32BitArchVariant());
             break;
 
-        case llvm::Triple::aarch64:
         case llvm::Triple::mips64:
         case llvm::Triple::mips64el:
         case llvm::Triple::sparcv9:

Modified: lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp?rev=257322&r1=257321&r2=257322&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp Mon Jan 11 04:39:09 2016
@@ -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::CreateHostNa
     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::WriteHar
         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::WriteHar
         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::Calculat
 }
 
 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::DoWriteR
 }
 
 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__)

Modified: lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h?rev=257322&r1=257321&r2=257322&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h (original)
+++ lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h Mon Jan 11 04:39:09 2016
@@ -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__)

Modified: lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp?rev=257322&r1=257321&r2=257322&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp Mon Jan 11 04:39:09 2016
@@ -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::CreateHostNa
                                                                  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,




More information about the lldb-commits mailing list