]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.cpp
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm-project / lldb / source / Plugins / Process / elf-core / RegisterContextPOSIXCore_ppc64le.cpp
1 //===-- RegisterContextPOSIXCore_ppc64le.cpp --------------------*- C++ -*-===//
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 }