RegisterContextPOSIXProcessMonitor_powerpc.cpp revision 285101
168313Srnordier//===-- RegisterContextPOSIXProcessMonitor_powerpc.h ------------*- C++ -*-===// 268313Srnordier// 368313Srnordier// The LLVM Compiler Infrastructure 468313Srnordier// 568313Srnordier// This file is distributed under the University of Illinois Open Source 668313Srnordier// License. See LICENSE.TXT for details. 768313Srnordier// 868313Srnordier//===---------------------------------------------------------------------===// 968313Srnordier 1068313Srnordier#include "lldb/Core/DataBufferHeap.h" 1168313Srnordier#include "lldb/Core/RegisterValue.h" 1268313Srnordier#include "lldb/Target/Thread.h" 1368313Srnordier 1468313Srnordier#include "RegisterContextPOSIX_powerpc.h" 1568313Srnordier#include "ProcessPOSIX.h" 1668313Srnordier#include "RegisterContextPOSIXProcessMonitor_powerpc.h" 1768313Srnordier#include "ProcessMonitor.h" 1868313Srnordier 1968313Srnordierusing namespace lldb_private; 2068313Srnordierusing namespace lldb; 2168313Srnordier 2268313Srnordier#define REG_CONTEXT_SIZE (GetGPRSize()) 2368313Srnordier 2468313SrnordierRegisterContextPOSIXProcessMonitor_powerpc::RegisterContextPOSIXProcessMonitor_powerpc(Thread &thread, 2568313Srnordier uint32_t concrete_frame_idx, 2668313Srnordier lldb_private::RegisterInfoInterface *register_info) 2768313Srnordier : RegisterContextPOSIX_powerpc(thread, concrete_frame_idx, register_info) 2868313Srnordier{ 2968313Srnordier} 3068313Srnordier 3168313SrnordierProcessMonitor & 3268313SrnordierRegisterContextPOSIXProcessMonitor_powerpc::GetMonitor() 3368313Srnordier{ 3468313Srnordier ProcessSP base = CalculateProcess(); 3568313Srnordier ProcessPOSIX *process = static_cast<ProcessPOSIX*>(base.get()); 3668313Srnordier return process->GetMonitor(); 3768313Srnordier} 3868313Srnordier 3968313Srnordierbool 4068313SrnordierRegisterContextPOSIXProcessMonitor_powerpc::ReadGPR() 4168313Srnordier{ 4268313Srnordier ProcessMonitor &monitor = GetMonitor(); 4368313Srnordier return monitor.ReadGPR(m_thread.GetID(), &m_gpr_powerpc, GetGPRSize()); 4468313Srnordier} 4568313Srnordier 4668313Srnordierbool 4768313SrnordierRegisterContextPOSIXProcessMonitor_powerpc::ReadFPR() 4868313Srnordier{ 4968313Srnordier ProcessMonitor &monitor = GetMonitor(); 5068313Srnordier return monitor.ReadFPR(m_thread.GetID(), &m_fpr_powerpc, sizeof(m_fpr_powerpc)); 5168313Srnordier} 5268313Srnordier 5368313Srnordierbool 5468313SrnordierRegisterContextPOSIXProcessMonitor_powerpc::ReadVMX() 5568313Srnordier{ 5668313Srnordier // XXX: Need a way to read/write process VMX registers with ptrace. 5768313Srnordier return false; 5868313Srnordier} 5968313Srnordier 6068313Srnordierbool 6168313SrnordierRegisterContextPOSIXProcessMonitor_powerpc::WriteGPR() 6268313Srnordier{ 6368313Srnordier ProcessMonitor &monitor = GetMonitor(); 6468313Srnordier return monitor.WriteGPR(m_thread.GetID(), &m_gpr_powerpc, GetGPRSize()); 6568313Srnordier} 6668313Srnordier 6768313Srnordierbool 6868313SrnordierRegisterContextPOSIXProcessMonitor_powerpc::WriteFPR() 6968313Srnordier{ 7068313Srnordier ProcessMonitor &monitor = GetMonitor(); 7168313Srnordier return monitor.WriteFPR(m_thread.GetID(), &m_fpr_powerpc, sizeof(m_fpr_powerpc)); 7268313Srnordier} 7368313Srnordier 7468313Srnordierbool 7568313SrnordierRegisterContextPOSIXProcessMonitor_powerpc::WriteVMX() 7668313Srnordier{ 7768313Srnordier // XXX: Need a way to read/write process VMX registers with ptrace. 7868313Srnordier return false; 7968313Srnordier} 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