tberghammer created this revision.
tberghammer added reviewers: omjavaid, ovyalov.
tberghammer added a subscriber: lldb-commits.
Herald added subscribers: srhines, danalbert, tberghammer, rengolin, aemerson.
Make the aarch64 lldb-server capable of debugging arm32 applications
After this change an arm32 lldb-server can debug arm32 inferiors both on arm32
and on aarch64 devices and an aarch64 lldb-server can debug both arm32 and
aarch64 inferiors on aarch64 devices.
http://reviews.llvm.org/D15533
Files:
source/Host/common/HostInfoBase.cpp
source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp
source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h
source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
Index: source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
===================================================================
--- source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
+++ 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
@@ -142,7 +143,15 @@
NativeThreadProtocol &native_thread,
uint32_t concrete_frame_idx)
{
- return new NativeRegisterContextLinux_arm64(target_arch, native_thread, concrete_frame_idx);
+ 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:
+ return nullptr;
+ }
}
NativeRegisterContextLinux_arm64::NativeRegisterContextLinux_arm64 (const ArchSpec& target_arch,
Index: source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h
===================================================================
--- source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.h
+++ 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 @@
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 @@
#endif // #ifndef lldb_NativeRegisterContextLinux_arm_h
-#endif // defined(__arm__)
+#endif // defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
Index: source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp
===================================================================
--- source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp
+++ source/Plugins/Process/Linux/NativeRegisterContextLinux_arm.cpp
@@ -7,17 +7,21 @@
//
//===----------------------------------------------------------------------===//
-#if defined(__arm__)
+#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
#include "NativeRegisterContextLinux_arm.h"
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/Error.h"
#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,14 +173,18 @@
{ "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,
uint32_t concrete_frame_idx)
{
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,30 +927,30 @@
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
{
addr_buf = &m_hwp_regs[hwb_index].address;
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,6 +965,28 @@
}
Error
+NativeRegisterContextLinux_arm::DoReadRegisterValue(uint32_t offset,
+ const char* reg_name,
+ uint32_t size,
+ RegisterValue &value)
+{
+ // PTRACE_PEEKUSER don't work in the aarch64 liux 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)
@@ -978,23 +1008,91 @@
}
Error
+NativeRegisterContextLinux_arm::DoReadGPR(void *buf, size_t buf_size)
+{
+#ifdef __arm__
+ return NativeRegisterContextLinux::DoReadGPR(buf, buf_size);
+#else // __aarch64__
+ 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);
+#endif // __arm__
+}
+
+Error
+NativeRegisterContextLinux_arm::DoWriteGPR(void *buf, size_t buf_size)
+{
+#ifdef __arm__
+ return NativeRegisterContextLinux::DoWriteGPR(buf, buf_size);
+#else // __aarch64__
+ 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);
+#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__
+ int regset = NT_ARM_VFP;
+ 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);
+#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__
+ int regset = NT_ARM_VFP;
+ 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);
+#endif // __arm__
}
-#endif // defined(__arm__)
+#endif // defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
Index: source/Host/common/HostInfoBase.cpp
===================================================================
--- source/Host/common/HostInfoBase.cpp
+++ source/Host/common/HostInfoBase.cpp
@@ -409,13 +409,13 @@
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:
_______________________________________________
lldb-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits