Bug Summary

File:llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
Warning:line 263, column 14
Although the value stored to 'Value1' is used in the enclosing expression, the value is never actually read from 'Value1'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name DWARFDebugLoc.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 -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-12/lib/clang/12.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-12~++20210107111113+c9154e8fa377/build-llvm/lib/DebugInfo/DWARF -I /build/llvm-toolchain-snapshot-12~++20210107111113+c9154e8fa377/llvm/lib/DebugInfo/DWARF -I /build/llvm-toolchain-snapshot-12~++20210107111113+c9154e8fa377/build-llvm/include -I /build/llvm-toolchain-snapshot-12~++20210107111113+c9154e8fa377/llvm/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-12/lib/clang/12.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-12~++20210107111113+c9154e8fa377/build-llvm/lib/DebugInfo/DWARF -fdebug-prefix-map=/build/llvm-toolchain-snapshot-12~++20210107111113+c9154e8fa377=. -ferror-limit 19 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -o /tmp/scan-build-2021-01-08-143434-21064-1 -x c++ /build/llvm-toolchain-snapshot-12~++20210107111113+c9154e8fa377/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
1//===- DWARFDebugLoc.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 "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
10#include "llvm/ADT/StringRef.h"
11#include "llvm/BinaryFormat/Dwarf.h"
12#include "llvm/DebugInfo/DWARF/DWARFContext.h"
13#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
14#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
15#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
16#include "llvm/Support/Compiler.h"
17#include "llvm/Support/Format.h"
18#include "llvm/Support/WithColor.h"
19#include "llvm/Support/raw_ostream.h"
20#include <algorithm>
21#include <cinttypes>
22#include <cstdint>
23
24using namespace llvm;
25using object::SectionedAddress;
26
27namespace {
28class DWARFLocationInterpreter {
29 Optional<object::SectionedAddress> Base;
30 std::function<Optional<object::SectionedAddress>(uint32_t)> LookupAddr;
31
32public:
33 DWARFLocationInterpreter(
34 Optional<object::SectionedAddress> Base,
35 std::function<Optional<object::SectionedAddress>(uint32_t)> LookupAddr)
36 : Base(Base), LookupAddr(std::move(LookupAddr)) {}
37
38 Expected<Optional<DWARFLocationExpression>>
39 Interpret(const DWARFLocationEntry &E);
40};
41} // namespace
42
43static Error createResolverError(uint32_t Index, unsigned Kind) {
44 return createStringError(errc::invalid_argument,
45 "Unable to resolve indirect address %u for: %s",
46 Index, dwarf::LocListEncodingString(Kind).data());
47}
48
49Expected<Optional<DWARFLocationExpression>>
50DWARFLocationInterpreter::Interpret(const DWARFLocationEntry &E) {
51 switch (E.Kind) {
52 case dwarf::DW_LLE_end_of_list:
53 return None;
54 case dwarf::DW_LLE_base_addressx: {
55 Base = LookupAddr(E.Value0);
56 if (!Base)
57 return createResolverError(E.Value0, E.Kind);
58 return None;
59 }
60 case dwarf::DW_LLE_startx_endx: {
61 Optional<SectionedAddress> LowPC = LookupAddr(E.Value0);
62 if (!LowPC)
63 return createResolverError(E.Value0, E.Kind);
64 Optional<SectionedAddress> HighPC = LookupAddr(E.Value1);
65 if (!HighPC)
66 return createResolverError(E.Value1, E.Kind);
67 return DWARFLocationExpression{
68 DWARFAddressRange{LowPC->Address, HighPC->Address, LowPC->SectionIndex},
69 E.Loc};
70 }
71 case dwarf::DW_LLE_startx_length: {
72 Optional<SectionedAddress> LowPC = LookupAddr(E.Value0);
73 if (!LowPC)
74 return createResolverError(E.Value0, E.Kind);
75 return DWARFLocationExpression{DWARFAddressRange{LowPC->Address,
76 LowPC->Address + E.Value1,
77 LowPC->SectionIndex},
78 E.Loc};
79 }
80 case dwarf::DW_LLE_offset_pair: {
81 if (!Base) {
82 return createStringError(inconvertibleErrorCode(),
83 "Unable to resolve location list offset pair: "
84 "Base address not defined");
85 }
86 DWARFAddressRange Range{Base->Address + E.Value0, Base->Address + E.Value1,
87 Base->SectionIndex};
88 if (Range.SectionIndex == SectionedAddress::UndefSection)
89 Range.SectionIndex = E.SectionIndex;
90 return DWARFLocationExpression{Range, E.Loc};
91 }
92 case dwarf::DW_LLE_default_location:
93 return DWARFLocationExpression{None, E.Loc};
94 case dwarf::DW_LLE_base_address:
95 Base = SectionedAddress{E.Value0, E.SectionIndex};
96 return None;
97 case dwarf::DW_LLE_start_end:
98 return DWARFLocationExpression{
99 DWARFAddressRange{E.Value0, E.Value1, E.SectionIndex}, E.Loc};
100 case dwarf::DW_LLE_start_length:
101 return DWARFLocationExpression{
102 DWARFAddressRange{E.Value0, E.Value0 + E.Value1, E.SectionIndex},
103 E.Loc};
104 default:
105 llvm_unreachable("unreachable locations list kind")::llvm::llvm_unreachable_internal("unreachable locations list kind"
, "/build/llvm-toolchain-snapshot-12~++20210107111113+c9154e8fa377/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp"
, 105)
;
106 }
107}
108
109static void dumpExpression(raw_ostream &OS, DIDumpOptions DumpOpts,
110 ArrayRef<uint8_t> Data, bool IsLittleEndian,
111 unsigned AddressSize, const MCRegisterInfo *MRI,
112 DWARFUnit *U) {
113 DWARFDataExtractor Extractor(Data, IsLittleEndian, AddressSize);
114 // Note. We do not pass any format to DWARFExpression, even if the
115 // corresponding unit is known. For now, there is only one operation,
116 // DW_OP_call_ref, which depends on the format; it is rarely used, and
117 // is unexpected in location tables.
118 DWARFExpression(Extractor, AddressSize).print(OS, DumpOpts, MRI, U);
119}
120
121bool DWARFLocationTable::dumpLocationList(uint64_t *Offset, raw_ostream &OS,
122 Optional<SectionedAddress> BaseAddr,
123 const MCRegisterInfo *MRI,
124 const DWARFObject &Obj, DWARFUnit *U,
125 DIDumpOptions DumpOpts,
126 unsigned Indent) const {
127 DWARFLocationInterpreter Interp(
128 BaseAddr, [U](uint32_t Index) -> Optional<SectionedAddress> {
129 if (U)
130 return U->getAddrOffsetSectionItem(Index);
131 return None;
132 });
133 OS << format("0x%8.8" PRIx64"l" "x" ": ", *Offset);
134 Error E = visitLocationList(Offset, [&](const DWARFLocationEntry &E) {
135 Expected<Optional<DWARFLocationExpression>> Loc = Interp.Interpret(E);
136 if (!Loc || DumpOpts.DisplayRawContents)
137 dumpRawEntry(E, OS, Indent, DumpOpts, Obj);
138 if (Loc && *Loc) {
139 OS << "\n";
140 OS.indent(Indent);
141 if (DumpOpts.DisplayRawContents)
142 OS << " => ";
143
144 DIDumpOptions RangeDumpOpts(DumpOpts);
145 RangeDumpOpts.DisplayRawContents = false;
146 if (Loc.get()->Range)
147 Loc.get()->Range->dump(OS, Data.getAddressSize(), RangeDumpOpts, &Obj);
148 else
149 OS << "<default>";
150 }
151 if (!Loc)
152 consumeError(Loc.takeError());
153
154 if (E.Kind != dwarf::DW_LLE_base_address &&
155 E.Kind != dwarf::DW_LLE_base_addressx &&
156 E.Kind != dwarf::DW_LLE_end_of_list) {
157 OS << ": ";
158 dumpExpression(OS, DumpOpts, E.Loc, Data.isLittleEndian(),
159 Data.getAddressSize(), MRI, U);
160 }
161 return true;
162 });
163 if (E) {
164 DumpOpts.RecoverableErrorHandler(std::move(E));
165 return false;
166 }
167 return true;
168}
169
170Error DWARFLocationTable::visitAbsoluteLocationList(
171 uint64_t Offset, Optional<SectionedAddress> BaseAddr,
172 std::function<Optional<SectionedAddress>(uint32_t)> LookupAddr,
173 function_ref<bool(Expected<DWARFLocationExpression>)> Callback) const {
174 DWARFLocationInterpreter Interp(BaseAddr, std::move(LookupAddr));
175 return visitLocationList(&Offset, [&](const DWARFLocationEntry &E) {
176 Expected<Optional<DWARFLocationExpression>> Loc = Interp.Interpret(E);
177 if (!Loc)
178 return Callback(Loc.takeError());
179 if (*Loc)
180 return Callback(**Loc);
181 return true;
182 });
183}
184
185void DWARFDebugLoc::dump(raw_ostream &OS, const MCRegisterInfo *MRI,
186 const DWARFObject &Obj, DIDumpOptions DumpOpts,
187 Optional<uint64_t> DumpOffset) const {
188 auto BaseAddr = None;
189 unsigned Indent = 12;
190 if (DumpOffset) {
191 dumpLocationList(&*DumpOffset, OS, BaseAddr, MRI, Obj, nullptr, DumpOpts,
192 Indent);
193 } else {
194 uint64_t Offset = 0;
195 StringRef Separator;
196 bool CanContinue = true;
197 while (CanContinue && Data.isValidOffset(Offset)) {
198 OS << Separator;
199 Separator = "\n";
200
201 CanContinue = dumpLocationList(&Offset, OS, BaseAddr, MRI, Obj, nullptr,
202 DumpOpts, Indent);
203 OS << '\n';
204 }
205 }
206}
207
208Error DWARFDebugLoc::visitLocationList(
209 uint64_t *Offset,
210 function_ref<bool(const DWARFLocationEntry &)> Callback) const {
211 DataExtractor::Cursor C(*Offset);
212 while (true) {
213 uint64_t SectionIndex;
214 uint64_t Value0 = Data.getRelocatedAddress(C);
215 uint64_t Value1 = Data.getRelocatedAddress(C, &SectionIndex);
216
217 DWARFLocationEntry E;
218
219 // The end of any given location list is marked by an end of list entry,
220 // which consists of a 0 for the beginning address offset and a 0 for the
221 // ending address offset. A beginning offset of 0xff...f marks the base
222 // address selection entry.
223 if (Value0 == 0 && Value1 == 0) {
224 E.Kind = dwarf::DW_LLE_end_of_list;
225 } else if (Value0 == (Data.getAddressSize() == 4 ? -1U : -1ULL)) {
226 E.Kind = dwarf::DW_LLE_base_address;
227 E.Value0 = Value1;
228 E.SectionIndex = SectionIndex;
229 } else {
230 E.Kind = dwarf::DW_LLE_offset_pair;
231 E.Value0 = Value0;
232 E.Value1 = Value1;
233 E.SectionIndex = SectionIndex;
234 unsigned Bytes = Data.getU16(C);
235 // A single location description describing the location of the object...
236 Data.getU8(C, E.Loc, Bytes);
237 }
238
239 if (!C)
240 return C.takeError();
241 if (!Callback(E) || E.Kind == dwarf::DW_LLE_end_of_list)
242 break;
243 }
244 *Offset = C.tell();
245 return Error::success();
246}
247
248void DWARFDebugLoc::dumpRawEntry(const DWARFLocationEntry &Entry,
249 raw_ostream &OS, unsigned Indent,
250 DIDumpOptions DumpOpts,
251 const DWARFObject &Obj) const {
252 uint64_t Value0, Value1;
253 switch (Entry.Kind) {
254 case dwarf::DW_LLE_base_address:
255 Value0 = Data.getAddressSize() == 4 ? -1U : -1ULL;
256 Value1 = Entry.Value0;
257 break;
258 case dwarf::DW_LLE_offset_pair:
259 Value0 = Entry.Value0;
260 Value1 = Entry.Value1;
261 break;
262 case dwarf::DW_LLE_end_of_list:
263 Value0 = Value1 = 0;
Although the value stored to 'Value1' is used in the enclosing expression, the value is never actually read from 'Value1'
264 return;
265 default:
266 llvm_unreachable("Not possible in DWARF4!")::llvm::llvm_unreachable_internal("Not possible in DWARF4!", "/build/llvm-toolchain-snapshot-12~++20210107111113+c9154e8fa377/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp"
, 266)
;
267 }
268 OS << '\n';
269 OS.indent(Indent);
270 OS << '(' << format_hex(Value0, 2 + Data.getAddressSize() * 2) << ", "
271 << format_hex(Value1, 2 + Data.getAddressSize() * 2) << ')';
272 DWARFFormValue::dumpAddressSection(Obj, OS, DumpOpts, Entry.SectionIndex);
273}
274
275Error DWARFDebugLoclists::visitLocationList(
276 uint64_t *Offset, function_ref<bool(const DWARFLocationEntry &)> F) const {
277
278 DataExtractor::Cursor C(*Offset);
279 bool Continue = true;
280 while (Continue) {
281 DWARFLocationEntry E;
282 E.Kind = Data.getU8(C);
283 switch (E.Kind) {
284 case dwarf::DW_LLE_end_of_list:
285 break;
286 case dwarf::DW_LLE_base_addressx:
287 E.Value0 = Data.getULEB128(C);
288 break;
289 case dwarf::DW_LLE_startx_endx:
290 E.Value0 = Data.getULEB128(C);
291 E.Value1 = Data.getULEB128(C);
292 break;
293 case dwarf::DW_LLE_startx_length:
294 E.Value0 = Data.getULEB128(C);
295 // Pre-DWARF 5 has different interpretation of the length field. We have
296 // to support both pre- and standartized styles for the compatibility.
297 if (Version < 5)
298 E.Value1 = Data.getU32(C);
299 else
300 E.Value1 = Data.getULEB128(C);
301 break;
302 case dwarf::DW_LLE_offset_pair:
303 E.Value0 = Data.getULEB128(C);
304 E.Value1 = Data.getULEB128(C);
305 E.SectionIndex = SectionedAddress::UndefSection;
306 break;
307 case dwarf::DW_LLE_default_location:
308 break;
309 case dwarf::DW_LLE_base_address:
310 E.Value0 = Data.getRelocatedAddress(C, &E.SectionIndex);
311 break;
312 case dwarf::DW_LLE_start_end:
313 E.Value0 = Data.getRelocatedAddress(C, &E.SectionIndex);
314 E.Value1 = Data.getRelocatedAddress(C);
315 break;
316 case dwarf::DW_LLE_start_length:
317 E.Value0 = Data.getRelocatedAddress(C, &E.SectionIndex);
318 E.Value1 = Data.getULEB128(C);
319 break;
320 default:
321 cantFail(C.takeError());
322 return createStringError(errc::illegal_byte_sequence,
323 "LLE of kind %x not supported", (int)E.Kind);
324 }
325
326 if (E.Kind != dwarf::DW_LLE_base_address &&
327 E.Kind != dwarf::DW_LLE_base_addressx &&
328 E.Kind != dwarf::DW_LLE_end_of_list) {
329 unsigned Bytes = Version >= 5 ? Data.getULEB128(C) : Data.getU16(C);
330 // A single location description describing the location of the object...
331 Data.getU8(C, E.Loc, Bytes);
332 }
333
334 if (!C)
335 return C.takeError();
336 Continue = F(E) && E.Kind != dwarf::DW_LLE_end_of_list;
337 }
338 *Offset = C.tell();
339 return Error::success();
340}
341
342void DWARFDebugLoclists::dumpRawEntry(const DWARFLocationEntry &Entry,
343 raw_ostream &OS, unsigned Indent,
344 DIDumpOptions DumpOpts,
345 const DWARFObject &Obj) const {
346 size_t MaxEncodingStringLength = 0;
347#define HANDLE_DW_LLE(ID, NAME) \
348 MaxEncodingStringLength = std::max(MaxEncodingStringLength, \
349 dwarf::LocListEncodingString(ID).size());
350#include "llvm/BinaryFormat/Dwarf.def"
351
352 OS << "\n";
353 OS.indent(Indent);
354 StringRef EncodingString = dwarf::LocListEncodingString(Entry.Kind);
355 // Unsupported encodings should have been reported during parsing.
356 assert(!EncodingString.empty() && "Unknown loclist entry encoding")((!EncodingString.empty() && "Unknown loclist entry encoding"
) ? static_cast<void> (0) : __assert_fail ("!EncodingString.empty() && \"Unknown loclist entry encoding\""
, "/build/llvm-toolchain-snapshot-12~++20210107111113+c9154e8fa377/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp"
, 356, __PRETTY_FUNCTION__))
;
357 OS << format("%-*s(", MaxEncodingStringLength, EncodingString.data());
358 unsigned FieldSize = 2 + 2 * Data.getAddressSize();
359 switch (Entry.Kind) {
360 case dwarf::DW_LLE_end_of_list:
361 case dwarf::DW_LLE_default_location:
362 break;
363 case dwarf::DW_LLE_startx_endx:
364 case dwarf::DW_LLE_startx_length:
365 case dwarf::DW_LLE_offset_pair:
366 case dwarf::DW_LLE_start_end:
367 case dwarf::DW_LLE_start_length:
368 OS << format_hex(Entry.Value0, FieldSize) << ", "
369 << format_hex(Entry.Value1, FieldSize);
370 break;
371 case dwarf::DW_LLE_base_addressx:
372 case dwarf::DW_LLE_base_address:
373 OS << format_hex(Entry.Value0, FieldSize);
374 break;
375 }
376 OS << ')';
377 switch (Entry.Kind) {
378 case dwarf::DW_LLE_base_address:
379 case dwarf::DW_LLE_start_end:
380 case dwarf::DW_LLE_start_length:
381 DWARFFormValue::dumpAddressSection(Obj, OS, DumpOpts, Entry.SectionIndex);
382 break;
383 default:
384 break;
385 }
386}
387
388void DWARFDebugLoclists::dumpRange(uint64_t StartOffset, uint64_t Size,
389 raw_ostream &OS, const MCRegisterInfo *MRI,
390 const DWARFObject &Obj,
391 DIDumpOptions DumpOpts) {
392 if (!Data.isValidOffsetForDataOfSize(StartOffset, Size)) {
393 OS << "Invalid dump range\n";
394 return;
395 }
396 uint64_t Offset = StartOffset;
397 StringRef Separator;
398 bool CanContinue = true;
399 while (CanContinue && Offset < StartOffset + Size) {
400 OS << Separator;
401 Separator = "\n";
402
403 CanContinue = dumpLocationList(&Offset, OS, /*BaseAddr=*/None, MRI, Obj,
404 nullptr, DumpOpts, /*Indent=*/12);
405 OS << '\n';
406 }
407}