1 //===-- NativeRegisterContextFreeBSD_arm.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 //===----------------------------------------------------------------------===//
11 #include "NativeRegisterContextFreeBSD_arm.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/RegisterInfoPOSIX_arm.h"
21 #include <sys/param.h>
22 #include <sys/ptrace.h>
23 #include <sys/types.h>
27 using namespace lldb_private
;
28 using namespace lldb_private::process_freebsd
;
30 NativeRegisterContextFreeBSD
*
31 NativeRegisterContextFreeBSD::CreateHostNativeRegisterContextFreeBSD(
32 const ArchSpec
&target_arch
, NativeThreadProtocol
&native_thread
) {
33 return new NativeRegisterContextFreeBSD_arm(target_arch
, native_thread
);
36 NativeRegisterContextFreeBSD_arm::NativeRegisterContextFreeBSD_arm(
37 const ArchSpec
&target_arch
, NativeThreadProtocol
&native_thread
)
38 : NativeRegisterContextRegisterInfo(
39 native_thread
, new RegisterInfoPOSIX_arm(target_arch
)) {}
41 RegisterInfoPOSIX_arm
&
42 NativeRegisterContextFreeBSD_arm::GetRegisterInfo() const {
43 return static_cast<RegisterInfoPOSIX_arm
&>(*m_register_info_interface_up
);
46 uint32_t NativeRegisterContextFreeBSD_arm::GetRegisterSetCount() const {
47 return GetRegisterInfo().GetRegisterSetCount();
51 NativeRegisterContextFreeBSD_arm::GetRegisterSet(uint32_t set_index
) const {
52 return GetRegisterInfo().GetRegisterSet(set_index
);
55 uint32_t NativeRegisterContextFreeBSD_arm::GetUserRegisterCount() const {
57 for (uint32_t set_index
= 0; set_index
< GetRegisterSetCount(); ++set_index
)
58 count
+= GetRegisterSet(set_index
)->num_registers
;
62 Status
NativeRegisterContextFreeBSD_arm::ReadRegisterSet(uint32_t set
) {
64 case RegisterInfoPOSIX_arm::GPRegSet
:
65 return NativeProcessFreeBSD::PtraceWrapper(PT_GETREGS
, m_thread
.GetID(),
67 case RegisterInfoPOSIX_arm::FPRegSet
:
68 return NativeProcessFreeBSD::PtraceWrapper(
69 PT_GETVFPREGS
, m_thread
.GetID(),
70 m_reg_data
.data() + sizeof(RegisterInfoPOSIX_arm::GPR
));
72 llvm_unreachable("NativeRegisterContextFreeBSD_arm::ReadRegisterSet");
75 Status
NativeRegisterContextFreeBSD_arm::WriteRegisterSet(uint32_t set
) {
77 case RegisterInfoPOSIX_arm::GPRegSet
:
78 return NativeProcessFreeBSD::PtraceWrapper(PT_SETREGS
, m_thread
.GetID(),
80 case RegisterInfoPOSIX_arm::FPRegSet
:
81 return NativeProcessFreeBSD::PtraceWrapper(
82 PT_SETVFPREGS
, m_thread
.GetID(),
83 m_reg_data
.data() + sizeof(RegisterInfoPOSIX_arm::GPR
));
85 llvm_unreachable("NativeRegisterContextFreeBSD_arm::WriteRegisterSet");
89 NativeRegisterContextFreeBSD_arm::ReadRegister(const RegisterInfo
*reg_info
,
90 RegisterValue
®_value
) {
94 error
.SetErrorString("reg_info NULL");
98 const uint32_t reg
= reg_info
->kinds
[lldb::eRegisterKindLLDB
];
100 if (reg
== LLDB_INVALID_REGNUM
)
101 return Status("no lldb regnum for %s", reg_info
&& reg_info
->name
103 : "<unknown register>");
105 uint32_t set
= GetRegisterInfo().GetRegisterSetFromRegisterIndex(reg
);
106 error
= ReadRegisterSet(set
);
110 assert(reg_info
->byte_offset
+ reg_info
->byte_size
<= m_reg_data
.size());
111 reg_value
.SetBytes(m_reg_data
.data() + reg_info
->byte_offset
,
112 reg_info
->byte_size
, endian::InlHostByteOrder());
116 Status
NativeRegisterContextFreeBSD_arm::WriteRegister(
117 const RegisterInfo
*reg_info
, const RegisterValue
®_value
) {
121 return Status("reg_info NULL");
123 const uint32_t reg
= reg_info
->kinds
[lldb::eRegisterKindLLDB
];
125 if (reg
== LLDB_INVALID_REGNUM
)
126 return Status("no lldb regnum for %s", reg_info
&& reg_info
->name
128 : "<unknown register>");
130 uint32_t set
= GetRegisterInfo().GetRegisterSetFromRegisterIndex(reg
);
131 error
= ReadRegisterSet(set
);
135 assert(reg_info
->byte_offset
+ reg_info
->byte_size
<= m_reg_data
.size());
136 ::memcpy(m_reg_data
.data() + reg_info
->byte_offset
, reg_value
.GetBytes(),
137 reg_info
->byte_size
);
139 return WriteRegisterSet(set
);
142 Status
NativeRegisterContextFreeBSD_arm::ReadAllRegisterValues(
143 lldb::WritableDataBufferSP
&data_sp
) {
146 error
= ReadRegisterSet(RegisterInfoPOSIX_arm::GPRegSet
);
150 error
= ReadRegisterSet(RegisterInfoPOSIX_arm::FPRegSet
);
154 data_sp
.reset(new DataBufferHeap(m_reg_data
.size(), 0));
155 uint8_t *dst
= data_sp
->GetBytes();
156 ::memcpy(dst
, m_reg_data
.data(), m_reg_data
.size());
161 Status
NativeRegisterContextFreeBSD_arm::WriteAllRegisterValues(
162 const lldb::DataBufferSP
&data_sp
) {
166 error
.SetErrorStringWithFormat(
167 "NativeRegisterContextFreeBSD_arm::%s invalid data_sp provided",
172 if (data_sp
->GetByteSize() != m_reg_data
.size()) {
173 error
.SetErrorStringWithFormat(
174 "NativeRegisterContextFreeBSD_arm::%s data_sp contained mismatched "
175 "data size, expected %" PRIu64
", actual %" PRIu64
,
176 __FUNCTION__
, m_reg_data
.size(), data_sp
->GetByteSize());
180 const uint8_t *src
= data_sp
->GetBytes();
181 if (src
== nullptr) {
182 error
.SetErrorStringWithFormat("NativeRegisterContextFreeBSD_arm::%s "
183 "DataBuffer::GetBytes() returned a null "
188 ::memcpy(m_reg_data
.data(), src
, m_reg_data
.size());
190 error
= WriteRegisterSet(RegisterInfoPOSIX_arm::GPRegSet
);
194 return WriteRegisterSet(RegisterInfoPOSIX_arm::FPRegSet
);
197 llvm::Error
NativeRegisterContextFreeBSD_arm::CopyHardwareWatchpointsFrom(
198 NativeRegisterContextFreeBSD
&source
) {
199 return llvm::Error::success();
202 #endif // defined (__arm__)