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