This revision was automatically updated to reflect the committed changes.
mgorny marked an inline comment as done.
Closed by commit rG9d029362d1ed: [lldb] [Process/FreeBSDRemote] Introduce arm
(32-bit) support (authored by mgorny).
Herald added a project: LLDB.
Changed prior to commit:
https://reviews.llvm.org/D95696?vs=320203&id=320365#toc
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D95696/new/
https://reviews.llvm.org/D95696
Files:
lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
lldb/source/Plugins/Process/FreeBSDRemote/CMakeLists.txt
lldb/source/Plugins/Process/FreeBSDRemote/NativeProcessFreeBSD.cpp
lldb/source/Plugins/Process/FreeBSDRemote/NativeProcessFreeBSD.h
lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_arm.cpp
lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_arm.h
lldb/unittests/Process/Utility/RegisterContextFreeBSDTest.cpp
Index: lldb/unittests/Process/Utility/RegisterContextFreeBSDTest.cpp
===================================================================
--- lldb/unittests/Process/Utility/RegisterContextFreeBSDTest.cpp
+++ lldb/unittests/Process/Utility/RegisterContextFreeBSDTest.cpp
@@ -9,6 +9,9 @@
// clang-format off
#include <sys/types.h>
#include <machine/reg.h>
+#if defined(__arm__)
+#include <machine/vfp.h>
+#endif
// clang-format on
#include "gmock/gmock.h"
@@ -17,7 +20,9 @@
#include "Plugins/Process/Utility/lldb-x86-register-enums.h"
#include "Plugins/Process/Utility/RegisterContextFreeBSD_i386.h"
#include "Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h"
+#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm.h"
#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h"
+#include "Plugins/Process/Utility/lldb-arm-register-enums.h"
#include "Plugins/Process/Utility/lldb-arm64-register-enums.h"
using namespace lldb;
@@ -234,6 +239,77 @@
#endif // defined(__i386__) || defined(__x86_64__)
+#if defined(__arm__)
+
+#define EXPECT_GPR_ARM(lldb_reg, fbsd_reg) \
+ EXPECT_THAT(GetRegParams(reg_ctx, gpr_##lldb_reg##_arm), \
+ ::testing::Pair(offsetof(reg, fbsd_reg), sizeof(reg::fbsd_reg)))
+#define EXPECT_FPU_ARM(lldb_reg, fbsd_reg) \
+ EXPECT_THAT(GetRegParams(reg_ctx, fpu_##lldb_reg##_arm), \
+ ::testing::Pair(offsetof(vfp_state, fbsd_reg) + base_offset, \
+ sizeof(vfp_state::fbsd_reg)))
+
+TEST(RegisterContextFreeBSDTest, arm) {
+ ArchSpec arch{"arm-unknown-freebsd"};
+ RegisterInfoPOSIX_arm reg_ctx{arch};
+
+ EXPECT_GPR_ARM(r0, r[0]);
+ EXPECT_GPR_ARM(r1, r[1]);
+ EXPECT_GPR_ARM(r2, r[2]);
+ EXPECT_GPR_ARM(r3, r[3]);
+ EXPECT_GPR_ARM(r4, r[4]);
+ EXPECT_GPR_ARM(r5, r[5]);
+ EXPECT_GPR_ARM(r6, r[6]);
+ EXPECT_GPR_ARM(r7, r[7]);
+ EXPECT_GPR_ARM(r8, r[8]);
+ EXPECT_GPR_ARM(r9, r[9]);
+ EXPECT_GPR_ARM(r10, r[10]);
+ EXPECT_GPR_ARM(r11, r[11]);
+ EXPECT_GPR_ARM(r12, r[12]);
+ EXPECT_GPR_ARM(sp, r_sp);
+ EXPECT_GPR_ARM(lr, r_lr);
+ EXPECT_GPR_ARM(pc, r_pc);
+ EXPECT_GPR_ARM(cpsr, r_cpsr);
+
+ size_t base_offset = reg_ctx.GetRegisterInfo()[fpu_d0_arm].byte_offset;
+
+ EXPECT_FPU_ARM(d0, reg[0]);
+ EXPECT_FPU_ARM(d1, reg[1]);
+ EXPECT_FPU_ARM(d2, reg[2]);
+ EXPECT_FPU_ARM(d3, reg[3]);
+ EXPECT_FPU_ARM(d4, reg[4]);
+ EXPECT_FPU_ARM(d5, reg[5]);
+ EXPECT_FPU_ARM(d6, reg[6]);
+ EXPECT_FPU_ARM(d7, reg[7]);
+ EXPECT_FPU_ARM(d8, reg[8]);
+ EXPECT_FPU_ARM(d9, reg[9]);
+ EXPECT_FPU_ARM(d10, reg[10]);
+ EXPECT_FPU_ARM(d11, reg[11]);
+ EXPECT_FPU_ARM(d12, reg[12]);
+ EXPECT_FPU_ARM(d13, reg[13]);
+ EXPECT_FPU_ARM(d14, reg[14]);
+ EXPECT_FPU_ARM(d15, reg[15]);
+ EXPECT_FPU_ARM(d16, reg[16]);
+ EXPECT_FPU_ARM(d17, reg[17]);
+ EXPECT_FPU_ARM(d18, reg[18]);
+ EXPECT_FPU_ARM(d19, reg[19]);
+ EXPECT_FPU_ARM(d20, reg[20]);
+ EXPECT_FPU_ARM(d21, reg[21]);
+ EXPECT_FPU_ARM(d22, reg[22]);
+ EXPECT_FPU_ARM(d23, reg[23]);
+ EXPECT_FPU_ARM(d24, reg[24]);
+ EXPECT_FPU_ARM(d25, reg[25]);
+ EXPECT_FPU_ARM(d26, reg[26]);
+ EXPECT_FPU_ARM(d27, reg[27]);
+ EXPECT_FPU_ARM(d28, reg[28]);
+ EXPECT_FPU_ARM(d29, reg[29]);
+ EXPECT_FPU_ARM(d30, reg[30]);
+ EXPECT_FPU_ARM(d31, reg[31]);
+ EXPECT_FPU_ARM(fpscr, fpscr);
+}
+
+#endif // defined(__arm__)
+
#if defined(__aarch64__)
#define EXPECT_GPR_ARM64(lldb_reg, fbsd_reg) \
Index: lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_arm.h
===================================================================
--- /dev/null
+++ lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_arm.h
@@ -0,0 +1,68 @@
+//===-- NativeRegisterContextFreeBSD_arm.h ----------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(__arm__)
+
+#ifndef lldb_NativeRegisterContextFreeBSD_arm_h
+#define lldb_NativeRegisterContextFreeBSD_arm_h
+
+// clang-format off
+#include <sys/types.h>
+#include <machine/reg.h>
+#include <machine/vfp.h>
+// clang-format on
+
+#include "Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD.h"
+#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm.h"
+
+#include <array>
+
+namespace lldb_private {
+namespace process_freebsd {
+
+class NativeProcessFreeBSD;
+
+class NativeRegisterContextFreeBSD_arm : public NativeRegisterContextFreeBSD {
+public:
+ NativeRegisterContextFreeBSD_arm(const ArchSpec &target_arch,
+ NativeThreadProtocol &native_thread);
+
+ uint32_t GetRegisterSetCount() const override;
+
+ uint32_t GetUserRegisterCount() const override;
+
+ const RegisterSet *GetRegisterSet(uint32_t set_index) const override;
+
+ Status ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue ®_value) override;
+
+ Status WriteRegister(const RegisterInfo *reg_info,
+ const RegisterValue ®_value) override;
+
+ Status ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override;
+
+ Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
+
+ llvm::Error
+ CopyHardwareWatchpointsFrom(NativeRegisterContextFreeBSD &source) override;
+
+private:
+ std::array<uint8_t, sizeof(reg) + sizeof(vfp_state)> m_reg_data;
+
+ Status ReadRegisterSet(uint32_t set);
+ Status WriteRegisterSet(uint32_t set);
+
+ RegisterInfoPOSIX_arm &GetRegisterInfo() const;
+};
+
+} // namespace process_freebsd
+} // namespace lldb_private
+
+#endif // #ifndef lldb_NativeRegisterContextFreeBSD_arm_h
+
+#endif // defined (__arm__)
Index: lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_arm.cpp
===================================================================
--- /dev/null
+++ lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_arm.cpp
@@ -0,0 +1,202 @@
+//===-- NativeRegisterContextFreeBSD_arm.cpp ------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(__arm__)
+
+#include "NativeRegisterContextFreeBSD_arm.h"
+
+#include "lldb/Utility/DataBufferHeap.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/Status.h"
+
+#include "Plugins/Process/FreeBSDRemote/NativeProcessFreeBSD.h"
+#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm.h"
+
+// clang-format off
+#include <sys/param.h>
+#include <sys/ptrace.h>
+#include <sys/types.h>
+// clang-format on
+
+using namespace lldb;
+using namespace lldb_private;
+using namespace lldb_private::process_freebsd;
+
+NativeRegisterContextFreeBSD *
+NativeRegisterContextFreeBSD::CreateHostNativeRegisterContextFreeBSD(
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
+ return new NativeRegisterContextFreeBSD_arm(target_arch, native_thread);
+}
+
+NativeRegisterContextFreeBSD_arm::NativeRegisterContextFreeBSD_arm(
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
+ : NativeRegisterContextRegisterInfo(
+ native_thread, new RegisterInfoPOSIX_arm(target_arch)) {}
+
+RegisterInfoPOSIX_arm &
+NativeRegisterContextFreeBSD_arm::GetRegisterInfo() const {
+ return static_cast<RegisterInfoPOSIX_arm &>(*m_register_info_interface_up);
+}
+
+uint32_t NativeRegisterContextFreeBSD_arm::GetRegisterSetCount() const {
+ return GetRegisterInfo().GetRegisterSetCount();
+}
+
+const RegisterSet *
+NativeRegisterContextFreeBSD_arm::GetRegisterSet(uint32_t set_index) const {
+ return GetRegisterInfo().GetRegisterSet(set_index);
+}
+
+uint32_t NativeRegisterContextFreeBSD_arm::GetUserRegisterCount() const {
+ uint32_t count = 0;
+ for (uint32_t set_index = 0; set_index < GetRegisterSetCount(); ++set_index)
+ count += GetRegisterSet(set_index)->num_registers;
+ return count;
+}
+
+Status NativeRegisterContextFreeBSD_arm::ReadRegisterSet(uint32_t set) {
+ switch (set) {
+ case RegisterInfoPOSIX_arm::GPRegSet:
+ return NativeProcessFreeBSD::PtraceWrapper(PT_GETREGS, m_thread.GetID(),
+ m_reg_data.data());
+ case RegisterInfoPOSIX_arm::FPRegSet:
+ return NativeProcessFreeBSD::PtraceWrapper(
+ PT_GETVFPREGS, m_thread.GetID(),
+ m_reg_data.data() + sizeof(RegisterInfoPOSIX_arm::GPR));
+ }
+ llvm_unreachable("NativeRegisterContextFreeBSD_arm::ReadRegisterSet");
+}
+
+Status NativeRegisterContextFreeBSD_arm::WriteRegisterSet(uint32_t set) {
+ switch (set) {
+ case RegisterInfoPOSIX_arm::GPRegSet:
+ return NativeProcessFreeBSD::PtraceWrapper(PT_SETREGS, m_thread.GetID(),
+ m_reg_data.data());
+ case RegisterInfoPOSIX_arm::FPRegSet:
+ return NativeProcessFreeBSD::PtraceWrapper(
+ PT_SETVFPREGS, m_thread.GetID(),
+ m_reg_data.data() + sizeof(RegisterInfoPOSIX_arm::GPR));
+ }
+ llvm_unreachable("NativeRegisterContextFreeBSD_arm::WriteRegisterSet");
+}
+
+Status
+NativeRegisterContextFreeBSD_arm::ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue ®_value) {
+ Status error;
+
+ if (!reg_info) {
+ error.SetErrorString("reg_info NULL");
+ return error;
+ }
+
+ const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+
+ if (reg == LLDB_INVALID_REGNUM)
+ return Status("no lldb regnum for %s", reg_info && reg_info->name
+ ? reg_info->name
+ : "<unknown register>");
+
+ uint32_t set = GetRegisterInfo().GetRegisterSetFromRegisterIndex(reg);
+ error = ReadRegisterSet(set);
+ if (error.Fail())
+ return error;
+
+ assert(reg_info->byte_offset + reg_info->byte_size <= m_reg_data.size());
+ reg_value.SetBytes(m_reg_data.data() + reg_info->byte_offset,
+ reg_info->byte_size, endian::InlHostByteOrder());
+ return error;
+}
+
+Status NativeRegisterContextFreeBSD_arm::WriteRegister(
+ const RegisterInfo *reg_info, const RegisterValue ®_value) {
+ Status error;
+
+ if (!reg_info)
+ return Status("reg_info NULL");
+
+ const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+
+ if (reg == LLDB_INVALID_REGNUM)
+ return Status("no lldb regnum for %s", reg_info && reg_info->name
+ ? reg_info->name
+ : "<unknown register>");
+
+ uint32_t set = GetRegisterInfo().GetRegisterSetFromRegisterIndex(reg);
+ error = ReadRegisterSet(set);
+ if (error.Fail())
+ return error;
+
+ assert(reg_info->byte_offset + reg_info->byte_size <= m_reg_data.size());
+ ::memcpy(m_reg_data.data() + reg_info->byte_offset, reg_value.GetBytes(),
+ reg_info->byte_size);
+
+ return WriteRegisterSet(set);
+}
+
+Status NativeRegisterContextFreeBSD_arm::ReadAllRegisterValues(
+ lldb::DataBufferSP &data_sp) {
+ Status error;
+
+ error = ReadRegisterSet(RegisterInfoPOSIX_arm::GPRegSet);
+ if (error.Fail())
+ return error;
+
+ error = ReadRegisterSet(RegisterInfoPOSIX_arm::FPRegSet);
+ if (error.Fail())
+ return error;
+
+ data_sp.reset(new DataBufferHeap(m_reg_data.size(), 0));
+ uint8_t *dst = data_sp->GetBytes();
+ ::memcpy(dst, m_reg_data.data(), m_reg_data.size());
+
+ return error;
+}
+
+Status NativeRegisterContextFreeBSD_arm::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ Status error;
+
+ if (!data_sp) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextFreeBSD_arm::%s invalid data_sp provided",
+ __FUNCTION__);
+ return error;
+ }
+
+ if (data_sp->GetByteSize() != m_reg_data.size()) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextFreeBSD_arm::%s data_sp contained mismatched "
+ "data size, expected %" PRIu64 ", actual %" PRIu64,
+ __FUNCTION__, m_reg_data.size(), data_sp->GetByteSize());
+ return error;
+ }
+
+ uint8_t *src = data_sp->GetBytes();
+ if (src == nullptr) {
+ error.SetErrorStringWithFormat("NativeRegisterContextFreeBSD_arm::%s "
+ "DataBuffer::GetBytes() returned a null "
+ "pointer",
+ __FUNCTION__);
+ return error;
+ }
+ ::memcpy(m_reg_data.data(), src, m_reg_data.size());
+
+ error = WriteRegisterSet(RegisterInfoPOSIX_arm::GPRegSet);
+ if (error.Fail())
+ return error;
+
+ return WriteRegisterSet(RegisterInfoPOSIX_arm::FPRegSet);
+}
+
+llvm::Error NativeRegisterContextFreeBSD_arm::CopyHardwareWatchpointsFrom(
+ NativeRegisterContextFreeBSD &source) {
+ return llvm::Error::success();
+}
+
+#endif // defined (__arm__)
Index: lldb/source/Plugins/Process/FreeBSDRemote/NativeProcessFreeBSD.h
===================================================================
--- lldb/source/Plugins/Process/FreeBSDRemote/NativeProcessFreeBSD.h
+++ lldb/source/Plugins/Process/FreeBSDRemote/NativeProcessFreeBSD.h
@@ -84,6 +84,10 @@
static Status PtraceWrapper(int req, lldb::pid_t pid, void *addr = nullptr,
int data = 0, int *result = nullptr);
+protected:
+ llvm::Expected<llvm::ArrayRef<uint8_t>>
+ GetSoftwareBreakpointTrapOpcode(size_t size_hint) override;
+
private:
MainLoop::SignalHandleUP m_sigchld_handle;
ArchSpec m_arch;
Index: lldb/source/Plugins/Process/FreeBSDRemote/NativeProcessFreeBSD.cpp
===================================================================
--- lldb/source/Plugins/Process/FreeBSDRemote/NativeProcessFreeBSD.cpp
+++ lldb/source/Plugins/Process/FreeBSDRemote/NativeProcessFreeBSD.cpp
@@ -354,6 +354,27 @@
return error;
}
+llvm::Expected<llvm::ArrayRef<uint8_t>>
+NativeProcessFreeBSD::GetSoftwareBreakpointTrapOpcode(size_t size_hint) {
+ static const uint8_t g_arm_opcode[] = {0xfe, 0xde, 0xff, 0xe7};
+ static const uint8_t g_thumb_opcode[] = {0x01, 0xde};
+
+ switch (GetArchitecture().GetMachine()) {
+ case llvm::Triple::arm:
+ switch (size_hint) {
+ case 2:
+ return llvm::makeArrayRef(g_thumb_opcode);
+ case 4:
+ return llvm::makeArrayRef(g_arm_opcode);
+ default:
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "Unrecognised trap opcode size hint!");
+ }
+ default:
+ return NativeProcessProtocol::GetSoftwareBreakpointTrapOpcode(size_hint);
+ }
+}
+
Status NativeProcessFreeBSD::Resume(const ResumeActionList &resume_actions) {
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
LLDB_LOG(log, "pid {0}", GetID());
Index: lldb/source/Plugins/Process/FreeBSDRemote/CMakeLists.txt
===================================================================
--- lldb/source/Plugins/Process/FreeBSDRemote/CMakeLists.txt
+++ lldb/source/Plugins/Process/FreeBSDRemote/CMakeLists.txt
@@ -1,6 +1,7 @@
add_lldb_library(lldbPluginProcessFreeBSDRemote
NativeProcessFreeBSD.cpp
NativeRegisterContextFreeBSD.cpp
+ NativeRegisterContextFreeBSD_arm.cpp
NativeRegisterContextFreeBSD_arm64.cpp
NativeRegisterContextFreeBSD_x86_64.cpp
NativeThreadFreeBSD.cpp
Index: lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
===================================================================
--- lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
+++ lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
@@ -254,6 +254,7 @@
switch (host_triple.getArch()) {
case llvm::Triple::aarch64:
+ case llvm::Triple::arm:
case llvm::Triple::x86:
case llvm::Triple::x86_64:
use_legacy_plugin = !!getenv("FREEBSD_LEGACY_PLUGIN");
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits