1//===-- RegisterContextPOSIXProcessMonitor_mips64.h ------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===---------------------------------------------------------------------===// 9 10#include "lldb/Target/Thread.h" 11#include "lldb/Core/RegisterValue.h" 12 13#include "RegisterContextPOSIX_mips64.h" 14#include "ProcessPOSIX.h" 15#include "RegisterContextPOSIXProcessMonitor_mips64.h" 16#include "ProcessMonitor.h" 17 18using namespace lldb_private; 19using namespace lldb; 20 21#define REG_CONTEXT_SIZE (GetGPRSize()) 22 23RegisterContextPOSIXProcessMonitor_mips64::RegisterContextPOSIXProcessMonitor_mips64(Thread &thread, 24 uint32_t concrete_frame_idx, 25 RegisterInfoInterface *register_info) 26 : RegisterContextPOSIX_mips64(thread, concrete_frame_idx, register_info) 27{ 28} 29 30ProcessMonitor & 31RegisterContextPOSIXProcessMonitor_mips64::GetMonitor() 32{ 33 ProcessSP base = CalculateProcess(); 34 ProcessPOSIX *process = static_cast<ProcessPOSIX*>(base.get()); 35 return process->GetMonitor(); 36} 37 38bool 39RegisterContextPOSIXProcessMonitor_mips64::ReadGPR() 40{ 41 ProcessMonitor &monitor = GetMonitor(); 42 return monitor.ReadGPR(m_thread.GetID(), &m_gpr_mips64, GetGPRSize()); 43} 44 45bool 46RegisterContextPOSIXProcessMonitor_mips64::ReadFPR() 47{ 48 // XXX not yet implemented 49 return false; 50} 51 52bool 53RegisterContextPOSIXProcessMonitor_mips64::WriteGPR() 54{ 55 ProcessMonitor &monitor = GetMonitor(); 56 return monitor.WriteGPR(m_thread.GetID(), &m_gpr_mips64, GetGPRSize()); 57} 58 59bool 60RegisterContextPOSIXProcessMonitor_mips64::WriteFPR() 61{ 62 // XXX not yet implemented 63 return false; 64} 65 66bool 67RegisterContextPOSIXProcessMonitor_mips64::ReadRegister(const unsigned reg, 68 RegisterValue &value) 69{ 70 ProcessMonitor &monitor = GetMonitor(); 71 return monitor.ReadRegisterValue(m_thread.GetID(), 72 GetRegisterOffset(reg), 73 GetRegisterName(reg), 74 GetRegisterSize(reg), 75 value); 76} 77 78bool 79RegisterContextPOSIXProcessMonitor_mips64::WriteRegister(const unsigned reg, 80 const RegisterValue &value) 81{ 82 unsigned reg_to_write = reg; 83 RegisterValue value_to_write = value; 84 85 // Check if this is a subregister of a full register. 86 const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg); 87 if (reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM)) 88 { 89 RegisterValue full_value; 90 uint32_t full_reg = reg_info->invalidate_regs[0]; 91 const RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg); 92 93 // Read the full register. 94 if (ReadRegister(full_reg_info, full_value)) 95 { 96 Error error; 97 ByteOrder byte_order = GetByteOrder(); 98 uint8_t dst[RegisterValue::kMaxRegisterByteSize]; 99 100 // Get the bytes for the full register. 101 const uint32_t dest_size = full_value.GetAsMemoryData (full_reg_info, 102 dst, 103 sizeof(dst), 104 byte_order, 105 error); 106 if (error.Success() && dest_size) 107 { 108 uint8_t src[RegisterValue::kMaxRegisterByteSize]; 109 110 // Get the bytes for the source data. 111 const uint32_t src_size = value.GetAsMemoryData (reg_info, src, sizeof(src), byte_order, error); 112 if (error.Success() && src_size && (src_size < dest_size)) 113 { 114 // Copy the src bytes to the destination. 115 memcpy (dst + (reg_info->byte_offset & 0x1), src, src_size); 116 // Set this full register as the value to write. 117 value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order); 118 value_to_write.SetType(full_reg_info); 119 reg_to_write = full_reg; 120 } 121 } 122 } 123 } 124 125 ProcessMonitor &monitor = GetMonitor(); 126 return monitor.WriteRegisterValue(m_thread.GetID(), 127 GetRegisterOffset(reg_to_write), 128 GetRegisterName(reg_to_write), 129 value_to_write); 130} 131 132bool 133RegisterContextPOSIXProcessMonitor_mips64::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value) 134{ 135 if (!reg_info) 136 return false; 137 138 const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; 139 140 if (IsFPR(reg)) 141 { 142 if (!ReadFPR()) 143 return false; 144 } 145 else 146 { 147 uint32_t full_reg = reg; 148 bool is_subreg = reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM); 149 150 if (is_subreg) 151 { 152 // Read the full aligned 64-bit register. 153 full_reg = reg_info->invalidate_regs[0]; 154 } 155 156 bool success = ReadRegister(full_reg, value); 157 158 if (success) 159 { 160 // If our read was not aligned (for ah,bh,ch,dh), shift our returned value one byte to the right. 161 if (is_subreg && (reg_info->byte_offset & 0x1)) 162 value.SetUInt64(value.GetAsUInt64() >> 8); 163 164 // If our return byte size was greater than the return value reg size, then 165 // use the type specified by reg_info rather than the uint64_t default 166 if (value.GetByteSize() > reg_info->byte_size) 167 value.SetType(reg_info); 168 } 169 return success; 170 } 171 172 return false; 173} 174 175bool 176RegisterContextPOSIXProcessMonitor_mips64::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &value) 177{ 178 const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; 179 180 if (IsGPR(reg)) 181 return WriteRegister(reg, value); 182 183 return false; 184} 185 186bool 187RegisterContextPOSIXProcessMonitor_mips64::ReadAllRegisterValues(DataBufferSP &data_sp) 188{ 189 bool success = false; 190 data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0)); 191 if (data_sp && ReadGPR () && ReadFPR ()) 192 { 193 uint8_t *dst = data_sp->GetBytes(); 194 success = dst != 0; 195 196 if (success) 197 { 198 ::memcpy (dst, &m_gpr_mips64, GetGPRSize()); 199 dst += GetGPRSize(); 200 } 201 } 202 return success; 203} 204 205bool 206RegisterContextPOSIXProcessMonitor_mips64::WriteAllRegisterValues(const DataBufferSP &data_sp) 207{ 208 bool success = false; 209 if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) 210 { 211 uint8_t *src = data_sp->GetBytes(); 212 if (src) 213 { 214 ::memcpy (&m_gpr_mips64, src, GetGPRSize()); 215 216 if (WriteGPR()) 217 { 218 src += GetGPRSize(); 219 } 220 } 221 } 222 return success; 223} 224 225uint32_t 226RegisterContextPOSIXProcessMonitor_mips64::SetHardwareWatchpoint(addr_t addr, size_t size, 227 bool read, bool write) 228{ 229 const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints(); 230 uint32_t hw_index; 231 232 for (hw_index = 0; hw_index < num_hw_watchpoints; ++hw_index) 233 { 234 if (IsWatchpointVacant(hw_index)) 235 return SetHardwareWatchpointWithIndex(addr, size, 236 read, write, 237 hw_index); 238 } 239 240 return LLDB_INVALID_INDEX32; 241} 242 243bool 244RegisterContextPOSIXProcessMonitor_mips64::ClearHardwareWatchpoint(uint32_t hw_index) 245{ 246 return false; 247} 248 249bool 250RegisterContextPOSIXProcessMonitor_mips64::HardwareSingleStep(bool enable) 251{ 252 return false; 253} 254 255bool 256RegisterContextPOSIXProcessMonitor_mips64::UpdateAfterBreakpoint() 257{ 258 // PC points one byte past the int3 responsible for the breakpoint. 259 lldb::addr_t pc; 260 261 if ((pc = GetPC()) == LLDB_INVALID_ADDRESS) 262 return false; 263 264 SetPC(pc - 1); 265 return true; 266} 267 268unsigned 269RegisterContextPOSIXProcessMonitor_mips64::GetRegisterIndexFromOffset(unsigned offset) 270{ 271 unsigned reg; 272 for (reg = 0; reg < k_num_registers_mips64; reg++) 273 { 274 if (GetRegisterInfo()[reg].byte_offset == offset) 275 break; 276 } 277 assert(reg < k_num_registers_mips64 && "Invalid register offset."); 278 return reg; 279} 280 281bool 282RegisterContextPOSIXProcessMonitor_mips64::IsWatchpointHit(uint32_t hw_index) 283{ 284 return false; 285} 286 287bool 288RegisterContextPOSIXProcessMonitor_mips64::ClearWatchpointHits() 289{ 290 return false; 291} 292 293addr_t 294RegisterContextPOSIXProcessMonitor_mips64::GetWatchpointAddress(uint32_t hw_index) 295{ 296 return LLDB_INVALID_ADDRESS; 297} 298 299bool 300RegisterContextPOSIXProcessMonitor_mips64::IsWatchpointVacant(uint32_t hw_index) 301{ 302 return false; 303} 304 305bool 306RegisterContextPOSIXProcessMonitor_mips64::SetHardwareWatchpointWithIndex(addr_t addr, size_t size, 307 bool read, bool write, 308 uint32_t hw_index) 309{ 310 return false; 311} 312 313uint32_t 314RegisterContextPOSIXProcessMonitor_mips64::NumSupportedHardwareWatchpoints() 315{ 316 return 0; 317} 318 319