File: | src/gnu/usr.bin/clang/liblldbPluginProcess/../../../llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp |
Warning: | line 162, column 9 Value stored to 'sve_reg_num' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===-- RegisterContextPOSIXCore_arm64.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_arm64.h" |
10 | #include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h" |
11 | |
12 | #include "Plugins/Process/elf-core/RegisterUtilities.h" |
13 | #include "lldb/Target/Thread.h" |
14 | #include "lldb/Utility/RegisterValue.h" |
15 | |
16 | #include <memory> |
17 | |
18 | using namespace lldb_private; |
19 | |
20 | std::unique_ptr<RegisterContextCorePOSIX_arm64> |
21 | RegisterContextCorePOSIX_arm64::Create(Thread &thread, const ArchSpec &arch, |
22 | const DataExtractor &gpregset, |
23 | llvm::ArrayRef<CoreNote> notes) { |
24 | Flags opt_regsets = RegisterInfoPOSIX_arm64::eRegsetMaskDefault; |
25 | |
26 | DataExtractor sve_data = getRegset(notes, arch.GetTriple(), AARCH64_SVE_Desc); |
27 | if (sve_data.GetByteSize() > sizeof(sve::user_sve_header)) |
28 | opt_regsets.Set(RegisterInfoPOSIX_arm64::eRegsetMaskSVE); |
29 | |
30 | // Pointer Authentication register set data is based on struct |
31 | // user_pac_mask declared in ptrace.h. See reference implementation |
32 | // in Linux kernel source at arch/arm64/include/uapi/asm/ptrace.h. |
33 | DataExtractor pac_data = getRegset(notes, arch.GetTriple(), AARCH64_PAC_Desc); |
34 | if (pac_data.GetByteSize() >= sizeof(uint64_t) * 2) |
35 | opt_regsets.Set(RegisterInfoPOSIX_arm64::eRegsetMaskPAuth); |
36 | |
37 | auto register_info_up = |
38 | std::make_unique<RegisterInfoPOSIX_arm64>(arch, opt_regsets); |
39 | return std::unique_ptr<RegisterContextCorePOSIX_arm64>( |
40 | new RegisterContextCorePOSIX_arm64(thread, std::move(register_info_up), |
41 | gpregset, notes)); |
42 | } |
43 | |
44 | RegisterContextCorePOSIX_arm64::RegisterContextCorePOSIX_arm64( |
45 | Thread &thread, std::unique_ptr<RegisterInfoPOSIX_arm64> register_info, |
46 | const DataExtractor &gpregset, llvm::ArrayRef<CoreNote> notes) |
47 | : RegisterContextPOSIX_arm64(thread, std::move(register_info)) { |
48 | m_gpr_data.SetData(std::make_shared<DataBufferHeap>(gpregset.GetDataStart(), |
49 | gpregset.GetByteSize())); |
50 | m_gpr_data.SetByteOrder(gpregset.GetByteOrder()); |
51 | |
52 | const llvm::Triple &target_triple = |
53 | m_register_info_up->GetTargetArchitecture().GetTriple(); |
54 | m_fpr_data = getRegset(notes, target_triple, FPR_Desc); |
55 | |
56 | if (m_register_info_up->IsSVEEnabled()) |
57 | m_sve_data = getRegset(notes, target_triple, AARCH64_SVE_Desc); |
58 | |
59 | if (m_register_info_up->IsPAuthEnabled()) |
60 | m_pac_data = getRegset(notes, target_triple, AARCH64_PAC_Desc); |
61 | |
62 | ConfigureRegisterContext(); |
63 | } |
64 | |
65 | RegisterContextCorePOSIX_arm64::~RegisterContextCorePOSIX_arm64() = default; |
66 | |
67 | bool RegisterContextCorePOSIX_arm64::ReadGPR() { return true; } |
68 | |
69 | bool RegisterContextCorePOSIX_arm64::ReadFPR() { return false; } |
70 | |
71 | bool RegisterContextCorePOSIX_arm64::WriteGPR() { |
72 | assert(0)((void)0); |
73 | return false; |
74 | } |
75 | |
76 | bool RegisterContextCorePOSIX_arm64::WriteFPR() { |
77 | assert(0)((void)0); |
78 | return false; |
79 | } |
80 | |
81 | const uint8_t *RegisterContextCorePOSIX_arm64::GetSVEBuffer(uint64_t offset) { |
82 | return m_sve_data.GetDataStart() + offset; |
83 | } |
84 | |
85 | void RegisterContextCorePOSIX_arm64::ConfigureRegisterContext() { |
86 | if (m_sve_data.GetByteSize() > sizeof(sve::user_sve_header)) { |
87 | uint64_t sve_header_field_offset = 8; |
88 | m_sve_vector_length = m_sve_data.GetU16(&sve_header_field_offset); |
89 | sve_header_field_offset = 12; |
90 | uint16_t sve_header_flags_field = |
91 | m_sve_data.GetU16(&sve_header_field_offset); |
92 | if ((sve_header_flags_field & sve::ptrace_regs_mask) == |
93 | sve::ptrace_regs_fpsimd) |
94 | m_sve_state = SVEState::FPSIMD; |
95 | else if ((sve_header_flags_field & sve::ptrace_regs_mask) == |
96 | sve::ptrace_regs_sve) |
97 | m_sve_state = SVEState::Full; |
98 | |
99 | if (!sve::vl_valid(m_sve_vector_length)) { |
100 | m_sve_state = SVEState::Disabled; |
101 | m_sve_vector_length = 0; |
102 | } |
103 | } else |
104 | m_sve_state = SVEState::Disabled; |
105 | |
106 | if (m_sve_state != SVEState::Disabled) |
107 | m_register_info_up->ConfigureVectorLength( |
108 | sve::vq_from_vl(m_sve_vector_length)); |
109 | } |
110 | |
111 | uint32_t RegisterContextCorePOSIX_arm64::CalculateSVEOffset( |
112 | const RegisterInfo *reg_info) { |
113 | // Start of Z0 data is after GPRs plus 8 bytes of vg register |
114 | uint32_t sve_reg_offset = LLDB_INVALID_INDEX320xffffffffU; |
115 | if (m_sve_state == SVEState::FPSIMD) { |
116 | const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB]; |
117 | sve_reg_offset = sve::ptrace_fpsimd_offset + (reg - GetRegNumSVEZ0()) * 16; |
118 | } else if (m_sve_state == SVEState::Full) { |
119 | uint32_t sve_z0_offset = GetGPRSize() + 16; |
120 | sve_reg_offset = |
121 | sve::SigRegsOffset() + reg_info->byte_offset - sve_z0_offset; |
122 | } |
123 | |
124 | return sve_reg_offset; |
125 | } |
126 | |
127 | bool RegisterContextCorePOSIX_arm64::ReadRegister(const RegisterInfo *reg_info, |
128 | RegisterValue &value) { |
129 | Status error; |
130 | lldb::offset_t offset; |
131 | |
132 | offset = reg_info->byte_offset; |
133 | if (offset + reg_info->byte_size <= GetGPRSize()) { |
134 | uint64_t v = m_gpr_data.GetMaxU64(&offset, reg_info->byte_size); |
135 | if (offset == reg_info->byte_offset + reg_info->byte_size) { |
136 | value = v; |
137 | return true; |
138 | } |
139 | } |
140 | |
141 | const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB]; |
142 | if (reg == LLDB_INVALID_REGNUM0xffffffffU) |
143 | return false; |
144 | |
145 | if (IsFPR(reg)) { |
146 | if (m_sve_state == SVEState::Disabled) { |
147 | // SVE is disabled take legacy route for FPU register access |
148 | offset -= GetGPRSize(); |
149 | if (offset < m_fpr_data.GetByteSize()) { |
150 | value.SetFromMemoryData(reg_info, m_fpr_data.GetDataStart() + offset, |
151 | reg_info->byte_size, lldb::eByteOrderLittle, |
152 | error); |
153 | return error.Success(); |
154 | } |
155 | } else { |
156 | // FPSR and FPCR will be located right after Z registers in |
157 | // SVEState::FPSIMD while in SVEState::Full they will be located at the |
158 | // end of register data after an alignment correction based on currently |
159 | // selected vector length. |
160 | uint32_t sve_reg_num = LLDB_INVALID_REGNUM0xffffffffU; |
161 | if (reg == GetRegNumFPSR()) { |
162 | sve_reg_num = reg; |
Value stored to 'sve_reg_num' is never read | |
163 | if (m_sve_state == SVEState::Full) |
164 | offset = sve::PTraceFPSROffset(sve::vq_from_vl(m_sve_vector_length)); |
165 | else if (m_sve_state == SVEState::FPSIMD) |
166 | offset = sve::ptrace_fpsimd_offset + (32 * 16); |
167 | } else if (reg == GetRegNumFPCR()) { |
168 | sve_reg_num = reg; |
169 | if (m_sve_state == SVEState::Full) |
170 | offset = sve::PTraceFPCROffset(sve::vq_from_vl(m_sve_vector_length)); |
171 | else if (m_sve_state == SVEState::FPSIMD) |
172 | offset = sve::ptrace_fpsimd_offset + (32 * 16) + 4; |
173 | } else { |
174 | // Extract SVE Z register value register number for this reg_info |
175 | if (reg_info->value_regs && |
176 | reg_info->value_regs[0] != LLDB_INVALID_REGNUM0xffffffffU) |
177 | sve_reg_num = reg_info->value_regs[0]; |
178 | offset = CalculateSVEOffset(GetRegisterInfoAtIndex(sve_reg_num)); |
179 | } |
180 | |
181 | assert(sve_reg_num != LLDB_INVALID_REGNUM)((void)0); |
182 | assert(offset < m_sve_data.GetByteSize())((void)0); |
183 | value.SetFromMemoryData(reg_info, GetSVEBuffer(offset), |
184 | reg_info->byte_size, lldb::eByteOrderLittle, |
185 | error); |
186 | } |
187 | } else if (IsSVE(reg)) { |
188 | if (IsSVEVG(reg)) { |
189 | value = GetSVERegVG(); |
190 | return true; |
191 | } |
192 | |
193 | switch (m_sve_state) { |
194 | case SVEState::FPSIMD: { |
195 | // In FPSIMD state SVE payload mirrors legacy fpsimd struct and so just |
196 | // copy 16 bytes of v register to the start of z register. All other |
197 | // SVE register will be set to zero. |
198 | uint64_t byte_size = 1; |
199 | uint8_t zeros = 0; |
200 | const uint8_t *src = &zeros; |
201 | if (IsSVEZ(reg)) { |
202 | byte_size = 16; |
203 | offset = CalculateSVEOffset(reg_info); |
204 | assert(offset < m_sve_data.GetByteSize())((void)0); |
205 | src = GetSVEBuffer(offset); |
206 | } |
207 | value.SetFromMemoryData(reg_info, src, byte_size, lldb::eByteOrderLittle, |
208 | error); |
209 | } break; |
210 | case SVEState::Full: |
211 | offset = CalculateSVEOffset(reg_info); |
212 | assert(offset < m_sve_data.GetByteSize())((void)0); |
213 | value.SetFromMemoryData(reg_info, GetSVEBuffer(offset), |
214 | reg_info->byte_size, lldb::eByteOrderLittle, |
215 | error); |
216 | break; |
217 | case SVEState::Disabled: |
218 | default: |
219 | return false; |
220 | } |
221 | } else if (IsPAuth(reg)) { |
222 | offset = reg_info->byte_offset - m_register_info_up->GetPAuthOffset(); |
223 | assert(offset < m_pac_data.GetByteSize())((void)0); |
224 | value.SetFromMemoryData(reg_info, m_pac_data.GetDataStart() + offset, |
225 | reg_info->byte_size, lldb::eByteOrderLittle, error); |
226 | } else |
227 | return false; |
228 | |
229 | return error.Success(); |
230 | } |
231 | |
232 | bool RegisterContextCorePOSIX_arm64::ReadAllRegisterValues( |
233 | lldb::DataBufferSP &data_sp) { |
234 | return false; |
235 | } |
236 | |
237 | bool RegisterContextCorePOSIX_arm64::WriteRegister(const RegisterInfo *reg_info, |
238 | const RegisterValue &value) { |
239 | return false; |
240 | } |
241 | |
242 | bool RegisterContextCorePOSIX_arm64::WriteAllRegisterValues( |
243 | const lldb::DataBufferSP &data_sp) { |
244 | return false; |
245 | } |
246 | |
247 | bool RegisterContextCorePOSIX_arm64::HardwareSingleStep(bool enable) { |
248 | return false; |
249 | } |