1 //===-- NativeRegisterContextFreeBSD_mips64.cpp ---------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #if defined(__mips64__)
11 #include "NativeRegisterContextFreeBSD_mips64.h"
13 #include "lldb/Utility/DataBufferHeap.h"
14 #include "lldb/Utility/RegisterValue.h"
15 #include "lldb/Utility/Status.h"
17 #include "Plugins/Process/FreeBSD/NativeProcessFreeBSD.h"
18 #include "Plugins/Process/Utility/lldb-mips-freebsd-register-enums.h"
21 #include <sys/param.h>
22 #include <sys/ptrace.h>
23 #include <sys/types.h>
28 using namespace lldb_private
;
29 using namespace lldb_private::process_freebsd
;
31 NativeRegisterContextFreeBSD
*
32 NativeRegisterContextFreeBSD::CreateHostNativeRegisterContextFreeBSD(
33 const ArchSpec
&target_arch
, NativeThreadProtocol
&native_thread
) {
34 return new NativeRegisterContextFreeBSD_mips64(target_arch
, native_thread
);
37 NativeRegisterContextFreeBSD_mips64::NativeRegisterContextFreeBSD_mips64(
38 const ArchSpec
&target_arch
, NativeThreadProtocol
&native_thread
)
39 : NativeRegisterContextRegisterInfo(
40 native_thread
, new RegisterContextFreeBSD_mips64(target_arch
)) {}
42 RegisterContextFreeBSD_mips64
&
43 NativeRegisterContextFreeBSD_mips64::GetRegisterInfo() const {
44 return static_cast<RegisterContextFreeBSD_mips64
&>(
45 *m_register_info_interface_up
);
48 uint32_t NativeRegisterContextFreeBSD_mips64::GetRegisterSetCount() const {
49 return GetRegisterInfo().GetRegisterSetCount();
53 NativeRegisterContextFreeBSD_mips64::GetRegisterSet(uint32_t set_index
) const {
54 return GetRegisterInfo().GetRegisterSet(set_index
);
57 uint32_t NativeRegisterContextFreeBSD_mips64::GetUserRegisterCount() const {
59 for (uint32_t set_index
= 0; set_index
< GetRegisterSetCount(); ++set_index
)
60 count
+= GetRegisterSet(set_index
)->num_registers
;
64 std::optional
<NativeRegisterContextFreeBSD_mips64::RegSetKind
>
65 NativeRegisterContextFreeBSD_mips64::GetSetForNativeRegNum(
66 uint32_t reg_num
) const {
67 switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {
68 case llvm::Triple::mips64
:
69 if (reg_num
>= k_first_gpr_mips64
&& reg_num
<= k_last_gpr_mips64
)
71 if (reg_num
>= k_first_fpr_mips64
&& reg_num
<= k_last_fpr_mips64
)
75 llvm_unreachable("Unhandled target architecture.");
78 llvm_unreachable("Register does not belong to any register set");
81 Status
NativeRegisterContextFreeBSD_mips64::ReadRegisterSet(RegSetKind set
) {
84 return NativeProcessFreeBSD::PtraceWrapper(PT_GETREGS
, m_thread
.GetID(),
87 return NativeProcessFreeBSD::PtraceWrapper(
88 PT_GETFPREGS
, m_thread
.GetID(),
89 m_reg_data
.data() + GetRegisterInfo().GetGPRSize());
91 llvm_unreachable("NativeRegisterContextFreeBSD_mips64::ReadRegisterSet");
94 Status
NativeRegisterContextFreeBSD_mips64::WriteRegisterSet(RegSetKind set
) {
97 return NativeProcessFreeBSD::PtraceWrapper(PT_SETREGS
, m_thread
.GetID(),
100 return NativeProcessFreeBSD::PtraceWrapper(
101 PT_SETFPREGS
, m_thread
.GetID(),
102 m_reg_data
.data() + GetRegisterInfo().GetGPRSize());
104 llvm_unreachable("NativeRegisterContextFreeBSD_mips64::WriteRegisterSet");
108 NativeRegisterContextFreeBSD_mips64::ReadRegister(const RegisterInfo
*reg_info
,
109 RegisterValue
®_value
) {
113 error
.SetErrorString("reg_info NULL");
117 const uint32_t reg
= reg_info
->kinds
[lldb::eRegisterKindLLDB
];
119 if (reg
== LLDB_INVALID_REGNUM
)
120 return Status("no lldb regnum for %s", reg_info
&& reg_info
->name
122 : "<unknown register>");
124 std::optional
<RegSetKind
> opt_set
= GetSetForNativeRegNum(reg
);
126 // This is likely an internal register for lldb use only and should not be
128 error
.SetErrorStringWithFormat("register \"%s\" is in unrecognized set",
133 RegSetKind set
= *opt_set
;
134 error
= ReadRegisterSet(set
);
138 assert(reg_info
->byte_offset
+ reg_info
->byte_size
<= m_reg_data
.size());
139 reg_value
.SetBytes(m_reg_data
.data() + reg_info
->byte_offset
,
140 reg_info
->byte_size
, endian::InlHostByteOrder());
144 Status
NativeRegisterContextFreeBSD_mips64::WriteRegister(
145 const RegisterInfo
*reg_info
, const RegisterValue
®_value
) {
149 return Status("reg_info NULL");
151 const uint32_t reg
= reg_info
->kinds
[lldb::eRegisterKindLLDB
];
153 if (reg
== LLDB_INVALID_REGNUM
)
154 return Status("no lldb regnum for %s", reg_info
&& reg_info
->name
156 : "<unknown register>");
158 std::optional
<RegSetKind
> opt_set
= GetSetForNativeRegNum(reg
);
160 // This is likely an internal register for lldb use only and should not be
162 error
.SetErrorStringWithFormat("register \"%s\" is in unrecognized set",
167 RegSetKind set
= *opt_set
;
168 error
= ReadRegisterSet(set
);
172 assert(reg_info
->byte_offset
+ reg_info
->byte_size
<= m_reg_data
.size());
173 ::memcpy(m_reg_data
.data() + reg_info
->byte_offset
, reg_value
.GetBytes(),
174 reg_info
->byte_size
);
176 return WriteRegisterSet(set
);
179 Status
NativeRegisterContextFreeBSD_mips64::ReadAllRegisterValues(
180 lldb::WritableDataBufferSP
&data_sp
) {
183 error
= ReadRegisterSet(GPRegSet
);
187 error
= ReadRegisterSet(FPRegSet
);
191 data_sp
.reset(new DataBufferHeap(m_reg_data
.size(), 0));
192 uint8_t *dst
= data_sp
->GetBytes();
193 ::memcpy(dst
, m_reg_data
.data(), m_reg_data
.size());
198 Status
NativeRegisterContextFreeBSD_mips64::WriteAllRegisterValues(
199 const lldb::DataBufferSP
&data_sp
) {
203 error
.SetErrorStringWithFormat(
204 "NativeRegisterContextFreeBSD_mips64::%s invalid data_sp provided",
209 if (data_sp
->GetByteSize() != m_reg_data
.size()) {
210 error
.SetErrorStringWithFormat(
211 "NativeRegisterContextFreeBSD_mips64::%s data_sp contained mismatched "
212 "data size, expected %" PRIu64
", actual %" PRIu64
,
213 __FUNCTION__
, m_reg_data
.size(), data_sp
->GetByteSize());
217 const uint8_t *src
= data_sp
->GetBytes();
218 if (src
== nullptr) {
219 error
.SetErrorStringWithFormat("NativeRegisterContextFreeBSD_mips64::%s "
220 "DataBuffer::GetBytes() returned a null "
225 ::memcpy(m_reg_data
.data(), src
, m_reg_data
.size());
227 error
= WriteRegisterSet(GPRegSet
);
231 return WriteRegisterSet(FPRegSet
);
234 llvm::Error
NativeRegisterContextFreeBSD_mips64::CopyHardwareWatchpointsFrom(
235 NativeRegisterContextFreeBSD
&source
) {
236 return llvm::Error::success();
239 #endif // defined (__mips64__)