1 //===-- NativeRegisterContextFreeBSD_mips64.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(__mips64__) 10 11 #include "NativeRegisterContextFreeBSD_mips64.h" 12 13 #include "lldb/Utility/DataBufferHeap.h" 14 #include "lldb/Utility/RegisterValue.h" 15 #include "lldb/Utility/Status.h" 16 17 #include "Plugins/Process/FreeBSD/NativeProcessFreeBSD.h" 18 19 // clang-format off 20 #include <sys/param.h> 21 #include <sys/ptrace.h> 22 #include <sys/types.h> 23 // clang-format on 24 25 using namespace lldb; 26 using namespace lldb_private; 27 using namespace lldb_private::process_freebsd; 28 29 NativeRegisterContextFreeBSD * 30 NativeRegisterContextFreeBSD::CreateHostNativeRegisterContextFreeBSD( 31 const ArchSpec &target_arch, NativeThreadProtocol &native_thread) { 32 return new NativeRegisterContextFreeBSD_mips64(target_arch, native_thread); 33 } 34 35 NativeRegisterContextFreeBSD_mips64::NativeRegisterContextFreeBSD_mips64( 36 const ArchSpec &target_arch, NativeThreadProtocol &native_thread) 37 : NativeRegisterContextRegisterInfo( 38 native_thread, new RegisterContextFreeBSD_mips64(target_arch)) {} 39 40 RegisterContextFreeBSD_mips64 & 41 NativeRegisterContextFreeBSD_mips64::GetRegisterInfo() const { 42 return static_cast<RegisterContextFreeBSD_mips64 &>( 43 *m_register_info_interface_up); 44 } 45 46 uint32_t NativeRegisterContextFreeBSD_mips64::GetRegisterSetCount() const { 47 return GetRegisterInfo().GetRegisterSetCount(); 48 } 49 50 const RegisterSet * 51 NativeRegisterContextFreeBSD_mips64::GetRegisterSet(uint32_t set_index) const { 52 return GetRegisterInfo().GetRegisterSet(set_index); 53 } 54 55 uint32_t NativeRegisterContextFreeBSD_mips64::GetUserRegisterCount() const { 56 uint32_t count = 0; 57 for (uint32_t set_index = 0; set_index < GetRegisterSetCount(); ++set_index) 58 count += GetRegisterSet(set_index)->num_registers; 59 return count; 60 } 61 62 Status NativeRegisterContextFreeBSD_mips64::ReadRegisterSet(RegSetKind set) { 63 switch (set) { 64 case GPRegSet: 65 return NativeProcessFreeBSD::PtraceWrapper(PT_GETREGS, m_thread.GetID(), 66 m_reg_data.data()); 67 } 68 llvm_unreachable("NativeRegisterContextFreeBSD_mips64::ReadRegisterSet"); 69 } 70 71 Status NativeRegisterContextFreeBSD_mips64::WriteRegisterSet(RegSetKind set) { 72 switch (set) { 73 case GPRegSet: 74 return NativeProcessFreeBSD::PtraceWrapper(PT_SETREGS, m_thread.GetID(), 75 m_reg_data.data()); 76 } 77 llvm_unreachable("NativeRegisterContextFreeBSD_mips64::WriteRegisterSet"); 78 } 79 80 Status 81 NativeRegisterContextFreeBSD_mips64::ReadRegister(const RegisterInfo *reg_info, 82 RegisterValue ®_value) { 83 Status error; 84 85 if (!reg_info) { 86 error.SetErrorString("reg_info NULL"); 87 return error; 88 } 89 90 const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB]; 91 92 if (reg == LLDB_INVALID_REGNUM) 93 return Status("no lldb regnum for %s", reg_info && reg_info->name 94 ? reg_info->name 95 : "<unknown register>"); 96 97 RegSetKind set = GPRegSet; 98 error = ReadRegisterSet(set); 99 if (error.Fail()) 100 return error; 101 102 assert(reg_info->byte_offset + reg_info->byte_size <= m_reg_data.size()); 103 reg_value.SetBytes(m_reg_data.data() + reg_info->byte_offset, 104 reg_info->byte_size, endian::InlHostByteOrder()); 105 return error; 106 } 107 108 Status NativeRegisterContextFreeBSD_mips64::WriteRegister( 109 const RegisterInfo *reg_info, const RegisterValue ®_value) { 110 Status error; 111 112 if (!reg_info) 113 return Status("reg_info NULL"); 114 115 const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB]; 116 117 if (reg == LLDB_INVALID_REGNUM) 118 return Status("no lldb regnum for %s", reg_info && reg_info->name 119 ? reg_info->name 120 : "<unknown register>"); 121 122 RegSetKind set = GPRegSet; 123 error = ReadRegisterSet(set); 124 if (error.Fail()) 125 return error; 126 127 assert(reg_info->byte_offset + reg_info->byte_size <= m_reg_data.size()); 128 ::memcpy(m_reg_data.data() + reg_info->byte_offset, reg_value.GetBytes(), 129 reg_info->byte_size); 130 131 return WriteRegisterSet(set); 132 } 133 134 Status NativeRegisterContextFreeBSD_mips64::ReadAllRegisterValues( 135 lldb::DataBufferSP &data_sp) { 136 Status error; 137 138 error = ReadRegisterSet(GPRegSet); 139 if (error.Fail()) 140 return error; 141 142 data_sp.reset(new DataBufferHeap(m_reg_data.size(), 0)); 143 uint8_t *dst = data_sp->GetBytes(); 144 ::memcpy(dst, m_reg_data.data(), m_reg_data.size()); 145 146 return error; 147 } 148 149 Status NativeRegisterContextFreeBSD_mips64::WriteAllRegisterValues( 150 const lldb::DataBufferSP &data_sp) { 151 Status error; 152 153 if (!data_sp) { 154 error.SetErrorStringWithFormat( 155 "NativeRegisterContextFreeBSD_mips64::%s invalid data_sp provided", 156 __FUNCTION__); 157 return error; 158 } 159 160 if (data_sp->GetByteSize() != m_reg_data.size()) { 161 error.SetErrorStringWithFormat( 162 "NativeRegisterContextFreeBSD_mips64::%s data_sp contained mismatched " 163 "data size, expected %" PRIu64 ", actual %" PRIu64, 164 __FUNCTION__, m_reg_data.size(), data_sp->GetByteSize()); 165 return error; 166 } 167 168 uint8_t *src = data_sp->GetBytes(); 169 if (src == nullptr) { 170 error.SetErrorStringWithFormat("NativeRegisterContextFreeBSD_mips64::%s " 171 "DataBuffer::GetBytes() returned a null " 172 "pointer", 173 __FUNCTION__); 174 return error; 175 } 176 ::memcpy(m_reg_data.data(), src, m_reg_data.size()); 177 178 return WriteRegisterSet(GPRegSet); 179 } 180 181 llvm::Error NativeRegisterContextFreeBSD_mips64::CopyHardwareWatchpointsFrom( 182 NativeRegisterContextFreeBSD &source) { 183 return llvm::Error::success(); 184 } 185 186 #endif // defined (__mips64__) 187