[Lldb-commits] [lldb] bd03f6d - [lldb] [Process/FreeBSDRemote] Introduce powerpc support
Michał Górny via lldb-commits
lldb-commits at lists.llvm.org
Tue Feb 9 12:29:19 PST 2021
Author: Michał Górny
Date: 2021-02-09T21:10:45+01:00
New Revision: bd03f6df51d161551a0439d8f51e2640a218048f
URL: https://github.com/llvm/llvm-project/commit/bd03f6df51d161551a0439d8f51e2640a218048f
DIFF: https://github.com/llvm/llvm-project/commit/bd03f6df51d161551a0439d8f51e2640a218048f.diff
LOG: [lldb] [Process/FreeBSDRemote] Introduce powerpc support
Introduce a minimal support for the 32-bit powerpc platform. This
includes support for GPR and FPR registers. I also needed to add
software breakpoint opcode for PPC32/PPC64 (big endian), and to fix
offsets in RegisterInfos_powerpc.h (used only by FreeBSD register
context to be globally unique rather than relative to each struct).
Differential Revision: https://reviews.llvm.org/D95947
Added:
lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_powerpc.cpp
lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_powerpc.h
Modified:
lldb/source/Host/common/NativeProcessProtocol.cpp
lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
lldb/source/Plugins/Process/FreeBSDRemote/CMakeLists.txt
lldb/source/Plugins/Process/Utility/RegisterInfos_powerpc.h
lldb/unittests/Process/Utility/RegisterContextFreeBSDTest.cpp
Removed:
################################################################################
diff --git a/lldb/source/Host/common/NativeProcessProtocol.cpp b/lldb/source/Host/common/NativeProcessProtocol.cpp
index 493e14cb904b..070fda664678 100644
--- a/lldb/source/Host/common/NativeProcessProtocol.cpp
+++ b/lldb/source/Host/common/NativeProcessProtocol.cpp
@@ -522,7 +522,8 @@ NativeProcessProtocol::GetSoftwareBreakpointTrapOpcode(size_t size_hint) {
static const uint8_t g_mips64_opcode[] = {0x00, 0x00, 0x00, 0x0d};
static const uint8_t g_mips64el_opcode[] = {0x0d, 0x00, 0x00, 0x00};
static const uint8_t g_s390x_opcode[] = {0x00, 0x01};
- static const uint8_t g_ppc64le_opcode[] = {0x08, 0x00, 0xe0, 0x7f}; // trap
+ static const uint8_t g_ppc_opcode[] = {0x7f, 0xe0, 0x00, 0x08}; // trap
+ static const uint8_t g_ppcle_opcode[] = {0x08, 0x00, 0xe0, 0x7f}; // trap
switch (GetArchitecture().GetMachine()) {
case llvm::Triple::aarch64:
@@ -544,8 +545,12 @@ NativeProcessProtocol::GetSoftwareBreakpointTrapOpcode(size_t size_hint) {
case llvm::Triple::systemz:
return llvm::makeArrayRef(g_s390x_opcode);
+ case llvm::Triple::ppc:
+ case llvm::Triple::ppc64:
+ return llvm::makeArrayRef(g_ppc_opcode);
+
case llvm::Triple::ppc64le:
- return llvm::makeArrayRef(g_ppc64le_opcode);
+ return llvm::makeArrayRef(g_ppcle_opcode);
default:
return llvm::createStringError(llvm::inconvertibleErrorCode(),
@@ -568,6 +573,8 @@ size_t NativeProcessProtocol::GetSoftwareBreakpointPCOffset() {
case llvm::Triple::mips64el:
case llvm::Triple::mips:
case llvm::Triple::mipsel:
+ case llvm::Triple::ppc:
+ case llvm::Triple::ppc64:
case llvm::Triple::ppc64le:
// On these architectures the PC doesn't get updated for breakpoint hits.
return 0;
diff --git a/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp b/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
index 7994e602703a..e16c573b93f9 100644
--- a/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
+++ b/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
@@ -256,6 +256,7 @@ bool PlatformFreeBSD::CanDebugProcess() {
case llvm::Triple::aarch64:
case llvm::Triple::arm:
case llvm::Triple::mips64:
+ case llvm::Triple::ppc:
case llvm::Triple::x86:
case llvm::Triple::x86_64:
use_legacy_plugin = !!getenv("FREEBSD_LEGACY_PLUGIN");
diff --git a/lldb/source/Plugins/Process/FreeBSDRemote/CMakeLists.txt b/lldb/source/Plugins/Process/FreeBSDRemote/CMakeLists.txt
index 826d7162967a..7480154d9998 100644
--- a/lldb/source/Plugins/Process/FreeBSDRemote/CMakeLists.txt
+++ b/lldb/source/Plugins/Process/FreeBSDRemote/CMakeLists.txt
@@ -4,6 +4,7 @@ add_lldb_library(lldbPluginProcessFreeBSDRemote
NativeRegisterContextFreeBSD_arm.cpp
NativeRegisterContextFreeBSD_arm64.cpp
NativeRegisterContextFreeBSD_mips64.cpp
+ NativeRegisterContextFreeBSD_powerpc.cpp
NativeRegisterContextFreeBSD_x86_64.cpp
NativeThreadFreeBSD.cpp
diff --git a/lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_powerpc.cpp b/lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_powerpc.cpp
new file mode 100644
index 000000000000..f923507b595d
--- /dev/null
+++ b/lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_powerpc.cpp
@@ -0,0 +1,289 @@
+//===-- NativeRegisterContextFreeBSD_powerpc.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(__powerpc__)
+
+#include "NativeRegisterContextFreeBSD_powerpc.h"
+
+#include "lldb/Host/HostInfo.h"
+#include "lldb/Utility/DataBufferHeap.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/Status.h"
+
+#include "Plugins/Process/FreeBSDRemote/NativeProcessFreeBSD.h"
+// for register enum definitions
+#include "Plugins/Process/Utility/RegisterContextPOSIX_powerpc.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;
+
+static const uint32_t g_gpr_regnums[] = {
+ gpr_r0_powerpc, gpr_r1_powerpc, gpr_r2_powerpc, gpr_r3_powerpc,
+ gpr_r4_powerpc, gpr_r5_powerpc, gpr_r6_powerpc, gpr_r7_powerpc,
+ gpr_r8_powerpc, gpr_r9_powerpc, gpr_r10_powerpc, gpr_r11_powerpc,
+ gpr_r12_powerpc, gpr_r13_powerpc, gpr_r14_powerpc, gpr_r15_powerpc,
+ gpr_r16_powerpc, gpr_r17_powerpc, gpr_r18_powerpc, gpr_r19_powerpc,
+ gpr_r20_powerpc, gpr_r21_powerpc, gpr_r22_powerpc, gpr_r23_powerpc,
+ gpr_r24_powerpc, gpr_r25_powerpc, gpr_r26_powerpc, gpr_r27_powerpc,
+ gpr_r28_powerpc, gpr_r29_powerpc, gpr_r30_powerpc, gpr_r31_powerpc,
+ gpr_lr_powerpc, gpr_cr_powerpc, gpr_xer_powerpc, gpr_ctr_powerpc,
+ gpr_pc_powerpc,
+};
+
+static const uint32_t g_fpr_regnums[] = {
+ fpr_f0_powerpc, fpr_f1_powerpc, fpr_f2_powerpc, fpr_f3_powerpc,
+ fpr_f4_powerpc, fpr_f5_powerpc, fpr_f6_powerpc, fpr_f7_powerpc,
+ fpr_f8_powerpc, fpr_f9_powerpc, fpr_f10_powerpc, fpr_f11_powerpc,
+ fpr_f12_powerpc, fpr_f13_powerpc, fpr_f14_powerpc, fpr_f15_powerpc,
+ fpr_f16_powerpc, fpr_f17_powerpc, fpr_f18_powerpc, fpr_f19_powerpc,
+ fpr_f20_powerpc, fpr_f21_powerpc, fpr_f22_powerpc, fpr_f23_powerpc,
+ fpr_f24_powerpc, fpr_f25_powerpc, fpr_f26_powerpc, fpr_f27_powerpc,
+ fpr_f28_powerpc, fpr_f29_powerpc, fpr_f30_powerpc, fpr_f31_powerpc,
+ fpr_fpscr_powerpc,
+};
+
+// Number of register sets provided by this context.
+enum { k_num_register_sets = 2 };
+
+static const RegisterSet g_reg_sets_powerpc[k_num_register_sets] = {
+ {"General Purpose Registers", "gpr", k_num_gpr_registers_powerpc,
+ g_gpr_regnums},
+ {"Floating Point Registers", "fpr", k_num_fpr_registers_powerpc,
+ g_fpr_regnums},
+};
+
+NativeRegisterContextFreeBSD *
+NativeRegisterContextFreeBSD::CreateHostNativeRegisterContextFreeBSD(
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread) {
+ return new NativeRegisterContextFreeBSD_powerpc(target_arch, native_thread);
+}
+
+static RegisterInfoInterface *
+CreateRegisterInfoInterface(const ArchSpec &target_arch) {
+ if (HostInfo::GetArchitecture().GetAddressByteSize() == 4) {
+ return new RegisterContextFreeBSD_powerpc32(target_arch);
+ } else {
+ assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) &&
+ "Register setting path assumes this is a 64-bit host");
+ return new RegisterContextFreeBSD_powerpc64(target_arch);
+ }
+}
+
+NativeRegisterContextFreeBSD_powerpc::NativeRegisterContextFreeBSD_powerpc(
+ const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
+ : NativeRegisterContextRegisterInfo(
+ native_thread, CreateRegisterInfoInterface(target_arch)) {}
+
+RegisterContextFreeBSD_powerpc &
+NativeRegisterContextFreeBSD_powerpc::GetRegisterInfo() const {
+ return static_cast<RegisterContextFreeBSD_powerpc &>(*m_register_info_interface_up);
+}
+
+uint32_t NativeRegisterContextFreeBSD_powerpc::GetRegisterSetCount() const {
+ return k_num_register_sets;
+}
+
+const RegisterSet *
+NativeRegisterContextFreeBSD_powerpc::GetRegisterSet(uint32_t set_index) const {
+ switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
+ case llvm::Triple::ppc:
+ return &g_reg_sets_powerpc[set_index];
+ default:
+ llvm_unreachable("Unhandled target architecture.");
+ }
+}
+
+llvm::Optional<NativeRegisterContextFreeBSD_powerpc::RegSetKind>
+NativeRegisterContextFreeBSD_powerpc::GetSetForNativeRegNum(
+ uint32_t reg_num) const {
+ switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
+ case llvm::Triple::ppc:
+ if (reg_num >= k_first_gpr_powerpc && reg_num <= k_last_gpr_powerpc)
+ return GPRegSet;
+ if (reg_num >= k_first_fpr && reg_num <= k_last_fpr)
+ return FPRegSet;
+ break;
+ default:
+ llvm_unreachable("Unhandled target architecture.");
+ }
+
+ llvm_unreachable("Register does not belong to any register set");
+}
+
+
+uint32_t NativeRegisterContextFreeBSD_powerpc::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_powerpc::ReadRegisterSet(RegSetKind set) {
+ switch (set) {
+ case GPRegSet:
+ return NativeProcessFreeBSD::PtraceWrapper(PT_GETREGS, m_thread.GetID(),
+ m_reg_data.data());
+ case FPRegSet:
+ return NativeProcessFreeBSD::PtraceWrapper(
+ PT_GETFPREGS, m_thread.GetID(), m_reg_data.data() + sizeof(reg));
+ }
+ llvm_unreachable("NativeRegisterContextFreeBSD_powerpc::ReadRegisterSet");
+}
+
+Status NativeRegisterContextFreeBSD_powerpc::WriteRegisterSet(RegSetKind set) {
+ switch (set) {
+ case GPRegSet:
+ return NativeProcessFreeBSD::PtraceWrapper(PT_SETREGS, m_thread.GetID(),
+ m_reg_data.data());
+ case FPRegSet:
+ return NativeProcessFreeBSD::PtraceWrapper(
+ PT_SETFPREGS, m_thread.GetID(), m_reg_data.data() + sizeof(reg));
+ }
+ llvm_unreachable("NativeRegisterContextFreeBSD_powerpc::WriteRegisterSet");
+}
+
+Status
+NativeRegisterContextFreeBSD_powerpc::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>");
+
+ llvm::Optional<RegSetKind> opt_set = GetSetForNativeRegNum(reg);
+ if (!opt_set) {
+ // This is likely an internal register for lldb use only and should not be
+ // directly queried.
+ error.SetErrorStringWithFormat("register \"%s\" is in unrecognized set",
+ reg_info->name);
+ return error;
+ }
+
+ RegSetKind set = opt_set.getValue();
+ 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_powerpc::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>");
+
+ llvm::Optional<RegSetKind> opt_set = GetSetForNativeRegNum(reg);
+ if (!opt_set) {
+ // This is likely an internal register for lldb use only and should not be
+ // directly queried.
+ error.SetErrorStringWithFormat("register \"%s\" is in unrecognized set",
+ reg_info->name);
+ return error;
+ }
+
+ RegSetKind set = opt_set.getValue();
+ 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_powerpc::ReadAllRegisterValues(
+ lldb::DataBufferSP &data_sp) {
+ Status error;
+
+ error = ReadRegisterSet(GPRegSet);
+ if (error.Fail())
+ return error;
+
+ error = ReadRegisterSet(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_powerpc::WriteAllRegisterValues(
+ const lldb::DataBufferSP &data_sp) {
+ Status error;
+
+ if (!data_sp) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextFreeBSD_powerpc::%s invalid data_sp provided",
+ __FUNCTION__);
+ return error;
+ }
+
+ if (data_sp->GetByteSize() != m_reg_data.size()) {
+ error.SetErrorStringWithFormat(
+ "NativeRegisterContextFreeBSD_powerpc::%s data_sp contained mismatched "
+ "data size, expected %zu, actual %" PRIu64,
+ __FUNCTION__, m_reg_data.size(), data_sp->GetByteSize());
+ return error;
+ }
+
+ uint8_t *src = data_sp->GetBytes();
+ if (src == nullptr) {
+ error.SetErrorStringWithFormat("NativeRegisterContextFreeBSD_powerpc::%s "
+ "DataBuffer::GetBytes() returned a null "
+ "pointer",
+ __FUNCTION__);
+ return error;
+ }
+ ::memcpy(m_reg_data.data(), src, m_reg_data.size());
+
+ error = WriteRegisterSet(GPRegSet);
+ if (error.Fail())
+ return error;
+
+ return WriteRegisterSet(FPRegSet);
+}
+
+llvm::Error NativeRegisterContextFreeBSD_powerpc::CopyHardwareWatchpointsFrom(
+ NativeRegisterContextFreeBSD &source) {
+ return llvm::Error::success();
+}
+
+#endif // defined (__powerpc__)
diff --git a/lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_powerpc.h b/lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_powerpc.h
new file mode 100644
index 000000000000..d76fdae1d2e0
--- /dev/null
+++ b/lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_powerpc.h
@@ -0,0 +1,73 @@
+//===-- NativeRegisterContextFreeBSD_powerpc.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(__powerpc__)
+
+#ifndef lldb_NativeRegisterContextFreeBSD_powerpc_h
+#define lldb_NativeRegisterContextFreeBSD_powerpc_h
+
+// clang-format off
+#include <sys/types.h>
+#include <machine/reg.h>
+// clang-format on
+
+#include "Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD.h"
+#include "Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h"
+
+#include <array>
+
+namespace lldb_private {
+namespace process_freebsd {
+
+class NativeProcessFreeBSD;
+
+class NativeRegisterContextFreeBSD_powerpc : public NativeRegisterContextFreeBSD {
+public:
+ NativeRegisterContextFreeBSD_powerpc(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:
+ enum RegSetKind {
+ GPRegSet,
+ FPRegSet,
+ };
+ std::array<uint8_t, sizeof(reg) + sizeof(fpreg)> m_reg_data;
+
+ llvm::Optional<RegSetKind> GetSetForNativeRegNum(uint32_t reg_num) const;
+
+ Status ReadRegisterSet(RegSetKind set);
+ Status WriteRegisterSet(RegSetKind set);
+
+ RegisterContextFreeBSD_powerpc &GetRegisterInfo() const;
+};
+
+} // namespace process_freebsd
+} // namespace lldb_private
+
+#endif // #ifndef lldb_NativeRegisterContextFreeBSD_powerpc_h
+
+#endif // defined (__powerpc__)
diff --git a/lldb/source/Plugins/Process/Utility/RegisterInfos_powerpc.h b/lldb/source/Plugins/Process/Utility/RegisterInfos_powerpc.h
index 51be31f8e028..90863dfdb090 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterInfos_powerpc.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterInfos_powerpc.h
@@ -10,8 +10,8 @@
// Computes the offset of the given GPR in the user data area.
#define GPR_OFFSET(regname) (offsetof(GPR, regname))
-#define FPR_OFFSET(regname) (offsetof(FPR, regname))
-#define VMX_OFFSET(regname) (offsetof(VMX, regname))
+#define FPR_OFFSET(regname) (sizeof(GPR) + offsetof(FPR, regname))
+#define VMX_OFFSET(regname) (sizeof(GPR) + sizeof(FPR) + offsetof(VMX, regname))
#define GPR_SIZE(regname) (sizeof(((GPR *)NULL)->regname))
#ifdef DECLARE_REGISTER_INFOS_POWERPC_STRUCT
diff --git a/lldb/unittests/Process/Utility/RegisterContextFreeBSDTest.cpp b/lldb/unittests/Process/Utility/RegisterContextFreeBSDTest.cpp
index ed0b2275c4ba..548830d19a52 100644
--- a/lldb/unittests/Process/Utility/RegisterContextFreeBSDTest.cpp
+++ b/lldb/unittests/Process/Utility/RegisterContextFreeBSDTest.cpp
@@ -19,7 +19,9 @@
#include "Plugins/Process/Utility/RegisterContextFreeBSD_i386.h"
#include "Plugins/Process/Utility/RegisterContextFreeBSD_mips64.h"
+#include "Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h"
#include "Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.h"
+#include "Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h"
#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm.h"
#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h"
#include "Plugins/Process/Utility/lldb-arm-register-enums.h"
@@ -458,3 +460,95 @@ TEST(RegisterContextFreeBSDTest, mips64) {
}
#endif // defined(__mips64__)
+
+#if defined(__powerpc__)
+
+#define EXPECT_GPR_PPC(lldb_reg, fbsd_reg) \
+ EXPECT_THAT(GetRegParams(reg_ctx, gpr_##lldb_reg##_powerpc), \
+ ::testing::Pair(offsetof(reg, fbsd_reg), \
+ sizeof(reg::fbsd_reg)))
+#define EXPECT_FPU_PPC(lldb_reg, fbsd_reg) \
+ EXPECT_THAT(GetRegParams(reg_ctx, fpr_##lldb_reg##_powerpc), \
+ ::testing::Pair(offsetof(fpreg, fbsd_reg) + base_offset, \
+ sizeof(fpreg::fbsd_reg)))
+
+TEST(RegisterContextFreeBSDTest, powerpc32) {
+ ArchSpec arch{"powerpc-unknown-freebsd"};
+ RegisterContextFreeBSD_powerpc32 reg_ctx{arch};
+
+ EXPECT_GPR_PPC(r0, fixreg[0]);
+ EXPECT_GPR_PPC(r1, fixreg[1]);
+ EXPECT_GPR_PPC(r2, fixreg[2]);
+ EXPECT_GPR_PPC(r3, fixreg[3]);
+ EXPECT_GPR_PPC(r4, fixreg[4]);
+ EXPECT_GPR_PPC(r5, fixreg[5]);
+ EXPECT_GPR_PPC(r6, fixreg[6]);
+ EXPECT_GPR_PPC(r7, fixreg[7]);
+ EXPECT_GPR_PPC(r8, fixreg[8]);
+ EXPECT_GPR_PPC(r9, fixreg[9]);
+ EXPECT_GPR_PPC(r10, fixreg[10]);
+ EXPECT_GPR_PPC(r11, fixreg[11]);
+ EXPECT_GPR_PPC(r12, fixreg[12]);
+ EXPECT_GPR_PPC(r13, fixreg[13]);
+ EXPECT_GPR_PPC(r14, fixreg[14]);
+ EXPECT_GPR_PPC(r15, fixreg[15]);
+ EXPECT_GPR_PPC(r16, fixreg[16]);
+ EXPECT_GPR_PPC(r17, fixreg[17]);
+ EXPECT_GPR_PPC(r18, fixreg[18]);
+ EXPECT_GPR_PPC(r19, fixreg[19]);
+ EXPECT_GPR_PPC(r20, fixreg[20]);
+ EXPECT_GPR_PPC(r21, fixreg[21]);
+ EXPECT_GPR_PPC(r22, fixreg[22]);
+ EXPECT_GPR_PPC(r23, fixreg[23]);
+ EXPECT_GPR_PPC(r24, fixreg[24]);
+ EXPECT_GPR_PPC(r25, fixreg[25]);
+ EXPECT_GPR_PPC(r26, fixreg[26]);
+ EXPECT_GPR_PPC(r27, fixreg[27]);
+ EXPECT_GPR_PPC(r28, fixreg[28]);
+ EXPECT_GPR_PPC(r29, fixreg[29]);
+ EXPECT_GPR_PPC(r30, fixreg[30]);
+ EXPECT_GPR_PPC(r31, fixreg[31]);
+ EXPECT_GPR_PPC(lr, lr);
+ EXPECT_GPR_PPC(cr, cr);
+ EXPECT_GPR_PPC(xer, xer);
+ EXPECT_GPR_PPC(ctr, ctr);
+ EXPECT_GPR_PPC(pc, pc);
+
+ size_t base_offset = reg_ctx.GetRegisterInfo()[fpr_f0_powerpc].byte_offset;
+
+ EXPECT_FPU_PPC(f0, fpreg[0]);
+ EXPECT_FPU_PPC(f1, fpreg[1]);
+ EXPECT_FPU_PPC(f2, fpreg[2]);
+ EXPECT_FPU_PPC(f3, fpreg[3]);
+ EXPECT_FPU_PPC(f4, fpreg[4]);
+ EXPECT_FPU_PPC(f5, fpreg[5]);
+ EXPECT_FPU_PPC(f6, fpreg[6]);
+ EXPECT_FPU_PPC(f7, fpreg[7]);
+ EXPECT_FPU_PPC(f8, fpreg[8]);
+ EXPECT_FPU_PPC(f9, fpreg[9]);
+ EXPECT_FPU_PPC(f10, fpreg[10]);
+ EXPECT_FPU_PPC(f11, fpreg[11]);
+ EXPECT_FPU_PPC(f12, fpreg[12]);
+ EXPECT_FPU_PPC(f13, fpreg[13]);
+ EXPECT_FPU_PPC(f14, fpreg[14]);
+ EXPECT_FPU_PPC(f15, fpreg[15]);
+ EXPECT_FPU_PPC(f16, fpreg[16]);
+ EXPECT_FPU_PPC(f17, fpreg[17]);
+ EXPECT_FPU_PPC(f18, fpreg[18]);
+ EXPECT_FPU_PPC(f19, fpreg[19]);
+ EXPECT_FPU_PPC(f20, fpreg[20]);
+ EXPECT_FPU_PPC(f21, fpreg[21]);
+ EXPECT_FPU_PPC(f22, fpreg[22]);
+ EXPECT_FPU_PPC(f23, fpreg[23]);
+ EXPECT_FPU_PPC(f24, fpreg[24]);
+ EXPECT_FPU_PPC(f25, fpreg[25]);
+ EXPECT_FPU_PPC(f26, fpreg[26]);
+ EXPECT_FPU_PPC(f27, fpreg[27]);
+ EXPECT_FPU_PPC(f28, fpreg[28]);
+ EXPECT_FPU_PPC(f29, fpreg[29]);
+ EXPECT_FPU_PPC(f30, fpreg[30]);
+ EXPECT_FPU_PPC(f31, fpreg[31]);
+ EXPECT_FPU_PPC(fpscr, fpscr);
+}
+
+#endif // defined(__powerpc__)
More information about the lldb-commits
mailing list