1 //===-- RegisterContextPOSIXCore_ppc64le.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 #include "RegisterContextPOSIXCore_ppc64le.h" 10 11 #include "lldb/Target/Thread.h" 12 #include "lldb/Utility/DataBufferHeap.h" 13 #include "lldb/Utility/RegisterValue.h" 14 15 #include "Plugins/Process/Utility/lldb-ppc64le-register-enums.h" 16 #include "Plugins/Process/elf-core/RegisterUtilities.h" 17 18 #include <memory> 19 20 using namespace lldb_private; 21 22 RegisterContextCorePOSIX_ppc64le::RegisterContextCorePOSIX_ppc64le( 23 Thread &thread, RegisterInfoInterface *register_info, 24 const DataExtractor &gpregset, llvm::ArrayRef<CoreNote> notes) 25 : RegisterContextPOSIX_ppc64le(thread, 0, register_info) { 26 m_gpr_buffer = std::make_shared<DataBufferHeap>(gpregset.GetDataStart(), 27 gpregset.GetByteSize()); 28 m_gpr.SetData(m_gpr_buffer); 29 m_gpr.SetByteOrder(gpregset.GetByteOrder()); 30 31 ArchSpec arch = register_info->GetTargetArchitecture(); 32 DataExtractor fpregset = getRegset(notes, arch.GetTriple(), FPR_Desc); 33 m_fpr_buffer = std::make_shared<DataBufferHeap>(fpregset.GetDataStart(), 34 fpregset.GetByteSize()); 35 m_fpr.SetData(m_fpr_buffer); 36 m_fpr.SetByteOrder(fpregset.GetByteOrder()); 37 38 DataExtractor vmxregset = getRegset(notes, arch.GetTriple(), PPC_VMX_Desc); 39 m_vmx_buffer = std::make_shared<DataBufferHeap>(vmxregset.GetDataStart(), 40 vmxregset.GetByteSize()); 41 m_vmx.SetData(m_vmx_buffer); 42 m_vmx.SetByteOrder(vmxregset.GetByteOrder()); 43 44 DataExtractor vsxregset = getRegset(notes, arch.GetTriple(), PPC_VSX_Desc); 45 m_vsx_buffer = std::make_shared<DataBufferHeap>(vsxregset.GetDataStart(), 46 vsxregset.GetByteSize()); 47 m_vsx.SetData(m_vsx_buffer); 48 m_vsx.SetByteOrder(vsxregset.GetByteOrder()); 49 } 50 51 size_t RegisterContextCorePOSIX_ppc64le::GetFPRSize() const { 52 return k_num_fpr_registers_ppc64le * sizeof(uint64_t); 53 } 54 55 size_t RegisterContextCorePOSIX_ppc64le::GetVMXSize() const { 56 return (k_num_vmx_registers_ppc64le - 1) * sizeof(uint64_t) * 2 + 57 sizeof(uint32_t); 58 } 59 60 size_t RegisterContextCorePOSIX_ppc64le::GetVSXSize() const { 61 return k_num_vsx_registers_ppc64le * sizeof(uint64_t) * 2; 62 } 63 64 bool RegisterContextCorePOSIX_ppc64le::ReadRegister( 65 const RegisterInfo *reg_info, RegisterValue &value) { 66 lldb::offset_t offset = reg_info->byte_offset; 67 68 if (IsFPR(reg_info->kinds[lldb::eRegisterKindLLDB])) { 69 uint64_t v; 70 offset -= GetGPRSize(); 71 offset = m_fpr.CopyData(offset, reg_info->byte_size, &v); 72 73 if (offset == reg_info->byte_size) { 74 value.SetBytes(&v, reg_info->byte_size, m_fpr.GetByteOrder()); 75 return true; 76 } 77 } else if (IsVMX(reg_info->kinds[lldb::eRegisterKindLLDB])) { 78 uint32_t v[4]; 79 offset -= GetGPRSize() + GetFPRSize(); 80 offset = m_vmx.CopyData(offset, reg_info->byte_size, &v); 81 82 if (offset == reg_info->byte_size) { 83 value.SetBytes(v, reg_info->byte_size, m_vmx.GetByteOrder()); 84 return true; 85 } 86 } else if (IsVSX(reg_info->kinds[lldb::eRegisterKindLLDB])) { 87 uint32_t v[4]; 88 lldb::offset_t tmp_offset; 89 offset -= GetGPRSize() + GetFPRSize() + GetVMXSize(); 90 91 if (offset < GetVSXSize() / 2) { 92 tmp_offset = m_vsx.CopyData(offset / 2, reg_info->byte_size / 2, &v); 93 94 if (tmp_offset != reg_info->byte_size / 2) { 95 return false; 96 } 97 98 uint8_t *dst = (uint8_t *)&v + sizeof(uint64_t); 99 tmp_offset = m_fpr.CopyData(offset / 2, reg_info->byte_size / 2, dst); 100 101 if (tmp_offset != reg_info->byte_size / 2) { 102 return false; 103 } 104 105 value.SetBytes(&v, reg_info->byte_size, m_vsx.GetByteOrder()); 106 return true; 107 } else { 108 offset = 109 m_vmx.CopyData(offset - GetVSXSize() / 2, reg_info->byte_size, &v); 110 if (offset == reg_info->byte_size) { 111 value.SetBytes(v, reg_info->byte_size, m_vmx.GetByteOrder()); 112 return true; 113 } 114 } 115 } else { 116 uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size); 117 118 if (offset == reg_info->byte_offset + reg_info->byte_size) { 119 if (reg_info->byte_size < sizeof(v)) 120 value = (uint32_t)v; 121 else 122 value = v; 123 return true; 124 } 125 } 126 127 return false; 128 } 129 130 bool RegisterContextCorePOSIX_ppc64le::WriteRegister( 131 const RegisterInfo *reg_info, const RegisterValue &value) { 132 return false; 133 } 134