9#if defined(__aarch64__)
24#include <sys/ptrace.h>
36static std::mutex g_register_type_detector_mutex;
42 std::lock_guard<std::mutex> lock(g_register_type_detector_mutex);
51 return new NativeRegisterContextFreeBSD_arm64(target_arch, native_thread);
54NativeRegisterContextFreeBSD_arm64::NativeRegisterContextFreeBSD_arm64(
60 GetRegisterInfoInterface().GetRegisterInfo(),
61 GetRegisterInfoInterface().GetRegisterCount());
65NativeRegisterContextFreeBSD_arm64::GetRegisterInfo()
const {
69uint32_t NativeRegisterContextFreeBSD_arm64::GetRegisterSetCount()
const {
74NativeRegisterContextFreeBSD_arm64::GetRegisterSet(uint32_t set_index)
const {
75 return GetRegisterInfo().GetRegisterSet(set_index);
78uint32_t NativeRegisterContextFreeBSD_arm64::GetUserRegisterCount()
const {
80 for (uint32_t set_index = 0; set_index < GetRegisterSetCount(); ++set_index)
85Status NativeRegisterContextFreeBSD_arm64::ReadRegisterSet(uint32_t set) {
92 PT_GETFPREGS, m_thread.GetID(),
95 llvm_unreachable(
"NativeRegisterContextFreeBSD_arm64::ReadRegisterSet");
98Status NativeRegisterContextFreeBSD_arm64::WriteRegisterSet(uint32_t set) {
105 PT_SETFPREGS, m_thread.GetID(),
108 llvm_unreachable(
"NativeRegisterContextFreeBSD_arm64::WriteRegisterSet");
112NativeRegisterContextFreeBSD_arm64::ReadRegister(
const RegisterInfo *reg_info,
123 "no lldb regnum for %s",
124 reg_info && reg_info->
name ? reg_info->
name :
"<unknown register>");
126 uint32_t set = GetRegisterInfo().GetRegisterSetFromRegisterIndex(reg);
127 error = ReadRegisterSet(set);
137Status NativeRegisterContextFreeBSD_arm64::WriteRegister(
148 "no lldb regnum for %s",
149 reg_info && reg_info->
name ? reg_info->
name :
"<unknown register>");
151 uint32_t set = GetRegisterInfo().GetRegisterSetFromRegisterIndex(reg);
152 error = ReadRegisterSet(set);
160 return WriteRegisterSet(set);
163Status NativeRegisterContextFreeBSD_arm64::ReadAllRegisterValues(
176 uint8_t *dst = data_sp->GetBytes();
177 ::memcpy(dst, m_reg_data.data(), m_reg_data.size());
182Status NativeRegisterContextFreeBSD_arm64::WriteAllRegisterValues(
188 "NativeRegisterContextFreeBSD_arm64::%s invalid data_sp provided",
193 if (data_sp->GetByteSize() != m_reg_data.size()) {
195 "NativeRegisterContextFreeBSD_arm64::%s data_sp contained mismatched "
196 "data size, expected %" PRIu64
", actual %" PRIu64,
197 __FUNCTION__, m_reg_data.size(), data_sp->GetByteSize());
201 const uint8_t *src = data_sp->GetBytes();
202 if (src ==
nullptr) {
204 "NativeRegisterContextFreeBSD_arm64::%s "
205 "DataBuffer::GetBytes() returned a null "
210 ::memcpy(m_reg_data.data(), src, m_reg_data.size());
219llvm::Error NativeRegisterContextFreeBSD_arm64::CopyHardwareWatchpointsFrom(
221 auto &r_source =
static_cast<NativeRegisterContextFreeBSD_arm64 &
>(source);
222 llvm::Error
error = r_source.ReadHardwareDebugInfo();
226 m_dbreg = r_source.m_dbreg;
227 m_hbp_regs = r_source.m_hbp_regs;
228 m_hwp_regs = r_source.m_hwp_regs;
229 m_max_hbp_supported = r_source.m_max_hbp_supported;
230 m_max_hwp_supported = r_source.m_max_hwp_supported;
237llvm::Error NativeRegisterContextFreeBSD_arm64::ReadHardwareDebugInfo() {
242 return llvm::Error::success();
245 m_thread.GetID(), &m_dbreg);
247 return res.ToError();
249 LLDB_LOG(log,
"m_dbreg read: debug_ver={0}, nbkpts={1}, nwtpts={2}",
250 m_dbreg.db_debug_ver, m_dbreg.db_nbkpts, m_dbreg.db_nwtpts);
251 m_max_hbp_supported = m_dbreg.db_nbkpts;
252 m_max_hwp_supported = m_dbreg.db_nwtpts;
253 assert(m_max_hbp_supported <= m_hbp_regs.size());
254 assert(m_max_hwp_supported <= m_hwp_regs.size());
257 return llvm::Error::success();
261NativeRegisterContextFreeBSD_arm64::WriteHardwareDebugRegs(DREGType) {
262 assert(m_read_dbreg &&
"dbregs must be read before writing them back");
265 for (uint32_t i = 0; i < m_max_hbp_supported; i++) {
266 m_dbreg.db_breakregs[i].dbr_addr = m_hbp_regs[i].address;
267 m_dbreg.db_breakregs[i].dbr_ctrl = m_hbp_regs[i].control;
269 for (uint32_t i = 0; i < m_max_hwp_supported; i++) {
270 m_dbreg.db_watchregs[i].dbw_addr = m_hwp_regs[i].address;
271 m_dbreg.db_watchregs[i].dbw_ctrl = m_hwp_regs[i].control;
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
@ AUXV_FREEBSD_AT_HWCAP
FreeBSD specific AT_HWCAP value.
@ AUXV_AT_HWCAP2
Extension of AT_HWCAP.
size_t GetRegisterSetCount() const override
This class manages the storage and detection of register type information.
bool HasDetected() const
Returns true if field detection has been run at least once.
void UpdateRegisterInfo(const RegisterInfo *reg_info, uint32_t num_regs)
Add the type information of any registers named in this class, to the relevant RegisterInfo instances...
void DetectTypes(uint64_t hwcap, uint64_t hwcap2, uint64_t hwcap3)
For the registers listed in this class, detect which fields are present and build types for those.
A subclass of DataBuffer that stores a data buffer on the heap.
std::optional< uint64_t > GetAuxValue(enum AuxVector::EntryType type)
void SetBytes(const void *bytes, size_t length, lldb::ByteOrder byte_order)
const void * GetBytes() const
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
static Status FromErrorString(const char *str)
Manages communication with the inferior (debugee) process.
static Status PtraceWrapper(int req, lldb::pid_t pid, void *addr=nullptr, int data=0, int *result=nullptr)
static NativeRegisterContextFreeBSD * CreateHostNativeRegisterContextFreeBSD(const ArchSpec &target_arch, NativeThreadFreeBSD &native_thread)
NativeProcessFreeBSD & GetProcess()
#define LLDB_INVALID_REGNUM
lldb::ByteOrder InlHostByteOrder()
Status WriteHardwareDebugRegs(int hwbType, ::pid_t tid, uint32_t max_supported, const std::array< NativeRegisterContextDBReg::DREG, 16 > ®s)
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
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.
const char * name
Name of this register, can't be NULL.
Registers are grouped into register sets.
size_t num_registers
The number of registers in REGISTERS array below.