Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name RegisterContextPOSIXCore_arm64.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/gnu/usr.bin/clang/liblldbPluginProcess/obj -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/gnu/usr.bin/clang/liblldbPluginProcess/../../../llvm/llvm/include -I /usr/src/gnu/usr.bin/clang/liblldbPluginProcess/../include -I /usr/src/gnu/usr.bin/clang/liblldbPluginProcess/obj -I /usr/src/gnu/usr.bin/clang/liblldbPluginProcess/obj/../include -D NDEBUG -D __STDC_LIMIT_MACROS -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D LLVM_PREFIX="/usr" -I /usr/src/gnu/usr.bin/clang/liblldbPluginProcess/../../../llvm/lldb/include -I /usr/src/gnu/usr.bin/clang/liblldbPluginProcess/../../../llvm/lldb/source -I /usr/src/gnu/usr.bin/clang/liblldbPluginProcess/../../../llvm/clang/include -I /usr/src/gnu/usr.bin/clang/liblldbPluginProcess/obj/../include/lldb/Plugins -internal-isystem /usr/include/c++/v1 -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir=/usr/src/gnu/usr.bin/clang/liblldbPluginProcess/obj -ferror-limit 19 -fvisibility-inlines-hidden -fwrapv -stack-protector 2 -fno-rtti -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c++ /usr/src/gnu/usr.bin/clang/liblldbPluginProcess/../../../llvm/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
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
18using namespace lldb_private;
19
20std::unique_ptr<RegisterContextCorePOSIX_arm64>
21RegisterContextCorePOSIX_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
44RegisterContextCorePOSIX_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
65RegisterContextCorePOSIX_arm64::~RegisterContextCorePOSIX_arm64() = default;
66
67bool RegisterContextCorePOSIX_arm64::ReadGPR() { return true; }
68
69bool RegisterContextCorePOSIX_arm64::ReadFPR() { return false; }
70
71bool RegisterContextCorePOSIX_arm64::WriteGPR() {
72 assert(0)((void)0);
73 return false;
74}
75
76bool RegisterContextCorePOSIX_arm64::WriteFPR() {
77 assert(0)((void)0);
78 return false;
79}
80
81const uint8_t *RegisterContextCorePOSIX_arm64::GetSVEBuffer(uint64_t offset) {
82 return m_sve_data.GetDataStart() + offset;
83}
84
85void 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
111uint32_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
127bool 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
232bool RegisterContextCorePOSIX_arm64::ReadAllRegisterValues(
233 lldb::DataBufferSP &data_sp) {
234 return false;
235}
236
237bool RegisterContextCorePOSIX_arm64::WriteRegister(const RegisterInfo *reg_info,
238 const RegisterValue &value) {
239 return false;
240}
241
242bool RegisterContextCorePOSIX_arm64::WriteAllRegisterValues(
243 const lldb::DataBufferSP &data_sp) {
244 return false;
245}
246
247bool RegisterContextCorePOSIX_arm64::HardwareSingleStep(bool enable) {
248 return false;
249}