Path: blob/main/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeRegisterContextFreeBSD_mips64.cpp
96379 views
//===-- NativeRegisterContextFreeBSD_mips64.cpp ---------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#if defined(__mips64__)910#include "NativeRegisterContextFreeBSD_mips64.h"1112#include "lldb/Utility/DataBufferHeap.h"13#include "lldb/Utility/RegisterValue.h"14#include "lldb/Utility/Status.h"1516#include "Plugins/Process/FreeBSD/NativeProcessFreeBSD.h"17#include "Plugins/Process/Utility/lldb-mips-freebsd-register-enums.h"1819// clang-format off20#include <sys/param.h>21#include <sys/ptrace.h>22#include <sys/types.h>23// clang-format on24#include <optional>2526using namespace lldb;27using namespace lldb_private;28using namespace lldb_private::process_freebsd;2930NativeRegisterContextFreeBSD *31NativeRegisterContextFreeBSD::CreateHostNativeRegisterContextFreeBSD(32const ArchSpec &target_arch, NativeThreadFreeBSD &native_thread) {33return new NativeRegisterContextFreeBSD_mips64(target_arch, native_thread);34}3536NativeRegisterContextFreeBSD_mips64::NativeRegisterContextFreeBSD_mips64(37const ArchSpec &target_arch, NativeThreadFreeBSD &native_thread)38: NativeRegisterContextRegisterInfo(39native_thread, new RegisterContextFreeBSD_mips64(target_arch)) {}4041RegisterContextFreeBSD_mips64 &42NativeRegisterContextFreeBSD_mips64::GetRegisterInfo() const {43return static_cast<RegisterContextFreeBSD_mips64 &>(44*m_register_info_interface_up);45}4647uint32_t NativeRegisterContextFreeBSD_mips64::GetRegisterSetCount() const {48return GetRegisterInfo().GetRegisterSetCount();49}5051const RegisterSet *52NativeRegisterContextFreeBSD_mips64::GetRegisterSet(uint32_t set_index) const {53return GetRegisterInfo().GetRegisterSet(set_index);54}5556uint32_t NativeRegisterContextFreeBSD_mips64::GetUserRegisterCount() const {57uint32_t count = 0;58for (uint32_t set_index = 0; set_index < GetRegisterSetCount(); ++set_index)59count += GetRegisterSet(set_index)->num_registers;60return count;61}6263std::optional<NativeRegisterContextFreeBSD_mips64::RegSetKind>64NativeRegisterContextFreeBSD_mips64::GetSetForNativeRegNum(65uint32_t reg_num) const {66switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) {67case llvm::Triple::mips64:68if (reg_num >= k_first_gpr_mips64 && reg_num <= k_last_gpr_mips64)69return GPRegSet;70if (reg_num >= k_first_fpr_mips64 && reg_num <= k_last_fpr_mips64)71return FPRegSet;72break;73default:74llvm_unreachable("Unhandled target architecture.");75}7677llvm_unreachable("Register does not belong to any register set");78}7980Status NativeRegisterContextFreeBSD_mips64::ReadRegisterSet(RegSetKind set) {81switch (set) {82case GPRegSet:83return NativeProcessFreeBSD::PtraceWrapper(PT_GETREGS, m_thread.GetID(),84m_reg_data.data());85case FPRegSet:86return NativeProcessFreeBSD::PtraceWrapper(87PT_GETFPREGS, m_thread.GetID(),88m_reg_data.data() + GetRegisterInfo().GetGPRSize());89}90llvm_unreachable("NativeRegisterContextFreeBSD_mips64::ReadRegisterSet");91}9293Status NativeRegisterContextFreeBSD_mips64::WriteRegisterSet(RegSetKind set) {94switch (set) {95case GPRegSet:96return NativeProcessFreeBSD::PtraceWrapper(PT_SETREGS, m_thread.GetID(),97m_reg_data.data());98case FPRegSet:99return NativeProcessFreeBSD::PtraceWrapper(100PT_SETFPREGS, m_thread.GetID(),101m_reg_data.data() + GetRegisterInfo().GetGPRSize());102}103llvm_unreachable("NativeRegisterContextFreeBSD_mips64::WriteRegisterSet");104}105106Status107NativeRegisterContextFreeBSD_mips64::ReadRegister(const RegisterInfo *reg_info,108RegisterValue ®_value) {109Status error;110111if (!reg_info) {112error.SetErrorString("reg_info NULL");113return error;114}115116const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];117118if (reg == LLDB_INVALID_REGNUM)119return Status("no lldb regnum for %s", reg_info && reg_info->name120? reg_info->name121: "<unknown register>");122123std::optional<RegSetKind> opt_set = GetSetForNativeRegNum(reg);124if (!opt_set) {125// This is likely an internal register for lldb use only and should not be126// directly queried.127error.SetErrorStringWithFormat("register \"%s\" is in unrecognized set",128reg_info->name);129return error;130}131132RegSetKind set = *opt_set;133error = ReadRegisterSet(set);134if (error.Fail())135return error;136137assert(reg_info->byte_offset + reg_info->byte_size <= m_reg_data.size());138reg_value.SetBytes(m_reg_data.data() + reg_info->byte_offset,139reg_info->byte_size, endian::InlHostByteOrder());140return error;141}142143Status NativeRegisterContextFreeBSD_mips64::WriteRegister(144const RegisterInfo *reg_info, const RegisterValue ®_value) {145Status error;146147if (!reg_info)148return Status("reg_info NULL");149150const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];151152if (reg == LLDB_INVALID_REGNUM)153return Status("no lldb regnum for %s", reg_info && reg_info->name154? reg_info->name155: "<unknown register>");156157std::optional<RegSetKind> opt_set = GetSetForNativeRegNum(reg);158if (!opt_set) {159// This is likely an internal register for lldb use only and should not be160// directly queried.161error.SetErrorStringWithFormat("register \"%s\" is in unrecognized set",162reg_info->name);163return error;164}165166RegSetKind set = *opt_set;167error = ReadRegisterSet(set);168if (error.Fail())169return error;170171assert(reg_info->byte_offset + reg_info->byte_size <= m_reg_data.size());172::memcpy(m_reg_data.data() + reg_info->byte_offset, reg_value.GetBytes(),173reg_info->byte_size);174175return WriteRegisterSet(set);176}177178Status NativeRegisterContextFreeBSD_mips64::ReadAllRegisterValues(179lldb::WritableDataBufferSP &data_sp) {180Status error;181182error = ReadRegisterSet(GPRegSet);183if (error.Fail())184return error;185186error = ReadRegisterSet(FPRegSet);187if (error.Fail())188return error;189190data_sp.reset(new DataBufferHeap(m_reg_data.size(), 0));191uint8_t *dst = data_sp->GetBytes();192::memcpy(dst, m_reg_data.data(), m_reg_data.size());193194return error;195}196197Status NativeRegisterContextFreeBSD_mips64::WriteAllRegisterValues(198const lldb::DataBufferSP &data_sp) {199Status error;200201if (!data_sp) {202error.SetErrorStringWithFormat(203"NativeRegisterContextFreeBSD_mips64::%s invalid data_sp provided",204__FUNCTION__);205return error;206}207208if (data_sp->GetByteSize() != m_reg_data.size()) {209error.SetErrorStringWithFormat(210"NativeRegisterContextFreeBSD_mips64::%s data_sp contained mismatched "211"data size, expected %" PRIu64 ", actual %" PRIu64,212__FUNCTION__, m_reg_data.size(), data_sp->GetByteSize());213return error;214}215216const uint8_t *src = data_sp->GetBytes();217if (src == nullptr) {218error.SetErrorStringWithFormat("NativeRegisterContextFreeBSD_mips64::%s "219"DataBuffer::GetBytes() returned a null "220"pointer",221__FUNCTION__);222return error;223}224::memcpy(m_reg_data.data(), src, m_reg_data.size());225226error = WriteRegisterSet(GPRegSet);227if (error.Fail())228return error;229230return WriteRegisterSet(FPRegSet);231}232233llvm::Error NativeRegisterContextFreeBSD_mips64::CopyHardwareWatchpointsFrom(234NativeRegisterContextFreeBSD &source) {235return llvm::Error::success();236}237238#endif // defined (__mips64__)239240241