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 &reg_value) override;
+
+  Status WriteRegister(const RegisterInfo *reg_info,
+                       const RegisterValue &reg_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 &reg_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 &reg_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
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to