LLDB mainline
NativeRegisterContextAIX_ppc64.cpp
Go to the documentation of this file.
1//===------ NativeRegisterContextAIX_ppc64.cpp ----------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#if defined(__powerpc64__)
10
12#include "NativeThreadAIX.h"
15
16using namespace lldb;
17using namespace lldb_private;
18using namespace lldb_private::process_aix;
19
20static const uint32_t g_gpr_regnums_ppc64[] = {
31 LLDB_INVALID_REGNUM // register sets need to end with this flag
32};
33
34static const uint32_t g_fpr_regnums_ppc64[] = {
44 LLDB_INVALID_REGNUM // register sets need to end with this flag
45};
46
47static const uint32_t g_vmx_regnums_ppc64[] = {
57 LLDB_INVALID_REGNUM // register sets need to end with this flag
58};
59
60static const uint32_t g_vsx_regnums_ppc64[] = {
77 LLDB_INVALID_REGNUM // register sets need to end with this flag
78};
79
80// Number of register sets provided by this context.
81static constexpr int k_num_register_sets = 4;
82
83static const RegisterSet g_reg_sets_ppc64[k_num_register_sets] = {
84 {"General Purpose Registers", "gpr", k_num_gpr_registers_ppc64,
85 g_gpr_regnums_ppc64},
86 {"Floating Point Registers", "fpr", k_num_fpr_registers_ppc64,
87 g_fpr_regnums_ppc64},
88 {"AltiVec/VMX Registers", "vmx", k_num_vmx_registers_ppc64,
89 g_vmx_regnums_ppc64},
90 {"VSX Registers", "vsx", k_num_vsx_registers_ppc64, g_vsx_regnums_ppc64},
91};
92
93std::unique_ptr<NativeRegisterContextAIX>
95 const ArchSpec &target_arch, NativeThreadAIX &native_thread) {
96 switch (target_arch.GetMachine()) {
97 case llvm::Triple::ppc:
98 case llvm::Triple::ppc64:
99 return std::make_unique<NativeRegisterContextAIX_ppc64>(target_arch,
100 native_thread);
101 default:
102 llvm_unreachable("have no register context for architecture");
103 }
104}
105
106NativeRegisterContextAIX_ppc64::NativeRegisterContextAIX_ppc64(
107 const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
109 native_thread, new RegisterInfoPOSIX_ppc64(target_arch)),
110 NativeRegisterContextAIX(native_thread) {
111 switch (target_arch.GetMachine()) {
112 case llvm::Triple::ppc:
113 new (&m_gpr_storage.gpr32) GPR_PPC{};
114 m_gpr = &m_gpr_storage.gpr32;
115 break;
116 case llvm::Triple::ppc64:
117 new (&m_gpr_storage.gpr32) GPR_PPC64{};
118 m_gpr = &m_gpr_storage.gpr64;
119 break;
120 default:
121 llvm_unreachable("Unhandled target architecture.");
122 }
123}
124
125uint32_t NativeRegisterContextAIX_ppc64::GetRegisterSetCount() const {
126 return k_num_register_sets;
127}
128
129const RegisterSet *
130NativeRegisterContextAIX_ppc64::GetRegisterSet(uint32_t set_index) const {
131 if (set_index < k_num_register_sets)
132 return &g_reg_sets_ppc64[set_index];
133
134 return nullptr;
135}
136
137uint32_t NativeRegisterContextAIX_ppc64::GetUserRegisterCount() const {
138 uint32_t count = 0;
139 for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index)
140 count += g_reg_sets_ppc64[set_index].num_registers;
141 return count;
142}
143
144Status
145NativeRegisterContextAIX_ppc64::ReadRegister(const RegisterInfo *reg_info,
146 RegisterValue &reg_value) {
148 if (!reg_info)
149 return Status::FromErrorString("reg_info NULL");
150
151 const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
152
153 if (IsGPR(reg)) {
154 error = ReadGPR();
155 if (error.Fail())
156 return error;
157
158 const uint8_t *src = reinterpret_cast<const uint8_t *>(GetGPRBuffer()) +
159 reg_info->byte_offset;
160 reg_value.SetFromMemoryData(*reg_info, src, reg_info->byte_size,
162
163 return error;
164 } else if (IsFPR(reg) || IsVSX(reg) || IsVMX(reg)) {
165 return Status::FromErrorString("unimplemented");
166 }
167
168 return Status::FromErrorString("failed - register wasn't recognized to be a "
169 "GPR, FPR, VSX or VMX, read strategy unknown");
170}
171
172Status
173NativeRegisterContextAIX_ppc64::WriteRegister(const RegisterInfo *reg_info,
174 const RegisterValue &reg_value) {
176 if (!reg_info)
177 return Status::FromErrorString("reg_info NULL");
178
179 const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
180
181 if (IsGPR(reg)) {
182 error = ReadGPR();
183 if (error.Fail())
184 return error;
185
186 uint8_t *dst =
187 reinterpret_cast<uint8_t *>(GetGPRBuffer()) + reg_info->byte_offset;
188 ::memcpy(dst, reg_value.GetBytes(), reg_value.GetByteSize());
189
190 return (WriteGPR());
191 } else if (IsFPR(reg) || IsVMX(reg) || IsVSX(reg)) {
192 return Status::FromErrorString("unimplemented");
193 }
194
195 return Status::FromErrorString("failed - register wasn't recognized to be a "
196 "GPR, FPR, VSX or VMX, read strategy unknown");
197}
198
199Status NativeRegisterContextAIX_ppc64::ReadAllRegisterValues(
201 return Status("unimplemented");
202}
203
204Status NativeRegisterContextAIX_ppc64::WriteAllRegisterValues(
205 const lldb::DataBufferSP &data_sp) {
206 return Status("unimplemented");
207}
208
209bool NativeRegisterContextAIX_ppc64::IsGPR(unsigned reg) const {
210 return reg <= k_last_gpr_ppc64;
211}
212
213bool NativeRegisterContextAIX_ppc64::IsFPR(unsigned reg) const {
214 return (k_first_fpr_ppc64 <= reg && reg <= k_last_fpr_ppc64);
215}
216
217bool NativeRegisterContextAIX_ppc64::IsVMX(unsigned reg) const {
218 return (reg >= k_first_vmx_ppc64) && (reg <= k_last_vmx_ppc64);
219}
220
221bool NativeRegisterContextAIX_ppc64::IsVSX(unsigned reg) const {
222 return (reg >= k_first_vsx_ppc64) && (reg <= k_last_vsx_ppc64);
223}
224
225uint32_t NativeRegisterContextAIX_ppc64::CalculateFprOffset(
226 const RegisterInfo *reg_info) const {
227 return 0;
228}
229
230uint32_t NativeRegisterContextAIX_ppc64::CalculateVmxOffset(
231 const RegisterInfo *reg_info) const {
232 return 0;
233}
234
235uint32_t NativeRegisterContextAIX_ppc64::CalculateVsxOffset(
236 const RegisterInfo *reg_info) const {
237 return 0;
238}
239
240#endif // defined(__powerpc64__)
static llvm::raw_ostream & error(Stream &strm)
uint32_t SetFromMemoryData(const RegisterInfo &reg_info, const void *src, uint32_t src_len, lldb::ByteOrder src_byte_order, Status &error)
const void * GetBytes() const
static Status FromErrorString(const char *str)
Definition Status.h:141
static std::unique_ptr< NativeRegisterContextAIX > CreateHostNativeRegisterContextAIX(const ArchSpec &target_arch, NativeThreadAIX &native_thread)
#define LLDB_INVALID_REGNUM
@ k_num_gpr_registers_ppc64
@ k_num_vmx_registers_ppc64
@ k_num_vsx_registers_ppc64
@ k_num_fpr_registers_ppc64
A class that represents a running process on the host machine.
std::shared_ptr< lldb_private::DataBuffer > DataBufferSP
std::shared_ptr< lldb_private::WritableDataBuffer > WritableDataBufferSP
@ eRegisterKindLLDB
lldb's internal register numbers
Every register is described in detail including its name, alternate name (optional),...
uint32_t byte_offset
The byte offset in the register context data where this register's value is found.
uint32_t byte_size
Size in bytes of the register.
uint32_t kinds[lldb::kNumRegisterKinds]
Holds all of the various register numbers for all register kinds.
Registers are grouped into register sets.