Bug Summary

File:llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
Warning:line 260, 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 -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 -mthread-model posix -mframe-pointer=none -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining -debugger-tuning=gdb -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-11/lib/clang/11.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/build-llvm/lib/DebugInfo/DWARF -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/DebugInfo/DWARF -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/build-llvm/include -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/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-11/lib/clang/11.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-11~++20200309111110+2c36c23f347/build-llvm/lib/DebugInfo/DWARF -fdebug-prefix-map=/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347=. -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -o /tmp/scan-build-2020-03-09-184146-41876-1 -x c++ /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/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-11~++20200309111110+2c36c23f347/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp"
, 105)
;
106 }
107}
108
109static void dumpExpression(raw_ostream &OS, ArrayRef<uint8_t> Data,
110 bool IsLittleEndian, unsigned AddressSize,
111 const MCRegisterInfo *MRI, DWARFUnit *U) {
112 DWARFDataExtractor Extractor(Data, IsLittleEndian, AddressSize);
113 DWARFExpression(Extractor, AddressSize).print(OS, MRI, U);
114}
115
116bool DWARFLocationTable::dumpLocationList(uint64_t *Offset, raw_ostream &OS,
117 Optional<SectionedAddress> BaseAddr,
118 const MCRegisterInfo *MRI,
119 const DWARFObject &Obj, DWARFUnit *U,
120 DIDumpOptions DumpOpts,
121 unsigned Indent) const {
122 DWARFLocationInterpreter Interp(
123 BaseAddr, [U](uint32_t Index) -> Optional<SectionedAddress> {
124 if (U)
125 return U->getAddrOffsetSectionItem(Index);
126 return None;
127 });
128 OS << format("0x%8.8" PRIx64"l" "x" ": ", *Offset);
129 Error E = visitLocationList(Offset, [&](const DWARFLocationEntry &E) {
130 Expected<Optional<DWARFLocationExpression>> Loc = Interp.Interpret(E);
131 if (!Loc || DumpOpts.DisplayRawContents)
132 dumpRawEntry(E, OS, Indent, DumpOpts, Obj);
133 if (Loc && *Loc) {
134 OS << "\n";
135 OS.indent(Indent);
136 if (DumpOpts.DisplayRawContents)
137 OS << " => ";
138
139 DIDumpOptions RangeDumpOpts(DumpOpts);
140 RangeDumpOpts.DisplayRawContents = false;
141 if (Loc.get()->Range)
142 Loc.get()->Range->dump(OS, Data.getAddressSize(), RangeDumpOpts, &Obj);
143 else
144 OS << "<default>";
145 }
146 if (!Loc)
147 consumeError(Loc.takeError());
148
149 if (E.Kind != dwarf::DW_LLE_base_address &&
150 E.Kind != dwarf::DW_LLE_base_addressx &&
151 E.Kind != dwarf::DW_LLE_end_of_list) {
152 OS << ": ";
153 dumpExpression(OS, E.Loc, Data.isLittleEndian(), Data.getAddressSize(),
154 MRI, U);
155 }
156 return true;
157 });
158 if (E) {
159 OS << "\n";
160 OS.indent(Indent);
161 OS << "error: " << toString(std::move(E));
162 return false;
163 }
164 return true;
165}
166
167Error DWARFLocationTable::visitAbsoluteLocationList(
168 uint64_t Offset, Optional<SectionedAddress> BaseAddr,
169 std::function<Optional<SectionedAddress>(uint32_t)> LookupAddr,
170 function_ref<bool(Expected<DWARFLocationExpression>)> Callback) const {
171 DWARFLocationInterpreter Interp(BaseAddr, std::move(LookupAddr));
172 return visitLocationList(&Offset, [&](const DWARFLocationEntry &E) {
173 Expected<Optional<DWARFLocationExpression>> Loc = Interp.Interpret(E);
174 if (!Loc)
175 return Callback(Loc.takeError());
176 if (*Loc)
177 return Callback(**Loc);
178 return true;
179 });
180}
181
182void DWARFDebugLoc::dump(raw_ostream &OS, const MCRegisterInfo *MRI,
183 const DWARFObject &Obj, DIDumpOptions DumpOpts,
184 Optional<uint64_t> DumpOffset) const {
185 auto BaseAddr = None;
186 unsigned Indent = 12;
187 if (DumpOffset) {
188 dumpLocationList(&*DumpOffset, OS, BaseAddr, MRI, Obj, nullptr, DumpOpts,
189 Indent);
190 } else {
191 uint64_t Offset = 0;
192 StringRef Separator;
193 bool CanContinue = true;
194 while (CanContinue && Data.isValidOffset(Offset)) {
195 OS << Separator;
196 Separator = "\n";
197
198 CanContinue = dumpLocationList(&Offset, OS, BaseAddr, MRI, Obj, nullptr,
199 DumpOpts, Indent);
200 OS << '\n';
201 }
202 }
203}
204
205Error DWARFDebugLoc::visitLocationList(
206 uint64_t *Offset,
207 function_ref<bool(const DWARFLocationEntry &)> Callback) const {
208 DataExtractor::Cursor C(*Offset);
209 while (true) {
210 uint64_t SectionIndex;
211 uint64_t Value0 = Data.getRelocatedAddress(C);
212 uint64_t Value1 = Data.getRelocatedAddress(C, &SectionIndex);
213
214 DWARFLocationEntry E;
215
216 // The end of any given location list is marked by an end of list entry,
217 // which consists of a 0 for the beginning address offset and a 0 for the
218 // ending address offset. A beginning offset of 0xff...f marks the base
219 // address selection entry.
220 if (Value0 == 0 && Value1 == 0) {
221 E.Kind = dwarf::DW_LLE_end_of_list;
222 } else if (Value0 == (Data.getAddressSize() == 4 ? -1U : -1ULL)) {
223 E.Kind = dwarf::DW_LLE_base_address;
224 E.Value0 = Value1;
225 E.SectionIndex = SectionIndex;
226 } else {
227 E.Kind = dwarf::DW_LLE_offset_pair;
228 E.Value0 = Value0;
229 E.Value1 = Value1;
230 E.SectionIndex = SectionIndex;
231 unsigned Bytes = Data.getU16(C);
232 // A single location description describing the location of the object...
233 Data.getU8(C, E.Loc, Bytes);
234 }
235
236 if (!C)
237 return C.takeError();
238 if (!Callback(E) || E.Kind == dwarf::DW_LLE_end_of_list)
239 break;
240 }
241 *Offset = C.tell();
242 return Error::success();
243}
244
245void DWARFDebugLoc::dumpRawEntry(const DWARFLocationEntry &Entry,
246 raw_ostream &OS, unsigned Indent,
247 DIDumpOptions DumpOpts,
248 const DWARFObject &Obj) const {
249 uint64_t Value0, Value1;
250 switch (Entry.Kind) {
251 case dwarf::DW_LLE_base_address:
252 Value0 = Data.getAddressSize() == 4 ? -1U : -1ULL;
253 Value1 = Entry.Value0;
254 break;
255 case dwarf::DW_LLE_offset_pair:
256 Value0 = Entry.Value0;
257 Value1 = Entry.Value1;
258 break;
259 case dwarf::DW_LLE_end_of_list:
260 Value0 = Value1 = 0;
Although the value stored to 'Value1' is used in the enclosing expression, the value is never actually read from 'Value1'
261 return;
262 default:
263 llvm_unreachable("Not possible in DWARF4!")::llvm::llvm_unreachable_internal("Not possible in DWARF4!", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp"
, 263)
;
264 }
265 OS << '\n';
266 OS.indent(Indent);
267 OS << '(' << format_hex(Value0, 2 + Data.getAddressSize() * 2) << ", "
268 << format_hex(Value1, 2 + Data.getAddressSize() * 2) << ')';
269 DWARFFormValue::dumpAddressSection(Obj, OS, DumpOpts, Entry.SectionIndex);
270}
271
272Error DWARFDebugLoclists::visitLocationList(
273 uint64_t *Offset, function_ref<bool(const DWARFLocationEntry &)> F) const {
274
275 DataExtractor::Cursor C(*Offset);
276 bool Continue = true;
277 while (Continue) {
278 DWARFLocationEntry E;
279 E.Kind = Data.getU8(C);
280 switch (E.Kind) {
281 case dwarf::DW_LLE_end_of_list:
282 break;
283 case dwarf::DW_LLE_base_addressx:
284 E.Value0 = Data.getULEB128(C);
285 break;
286 case dwarf::DW_LLE_startx_endx:
287 E.Value0 = Data.getULEB128(C);
288 E.Value1 = Data.getULEB128(C);
289 break;
290 case dwarf::DW_LLE_startx_length:
291 E.Value0 = Data.getULEB128(C);
292 // Pre-DWARF 5 has different interpretation of the length field. We have
293 // to support both pre- and standartized styles for the compatibility.
294 if (Version < 5)
295 E.Value1 = Data.getU32(C);
296 else
297 E.Value1 = Data.getULEB128(C);
298 break;
299 case dwarf::DW_LLE_offset_pair:
300 E.Value0 = Data.getULEB128(C);
301 E.Value1 = Data.getULEB128(C);
302 E.SectionIndex = SectionedAddress::UndefSection;
303 break;
304 case dwarf::DW_LLE_default_location:
305 break;
306 case dwarf::DW_LLE_base_address:
307 E.Value0 = Data.getRelocatedAddress(C, &E.SectionIndex);
308 break;
309 case dwarf::DW_LLE_start_end:
310 E.Value0 = Data.getRelocatedAddress(C, &E.SectionIndex);
311 E.Value1 = Data.getRelocatedAddress(C);
312 break;
313 case dwarf::DW_LLE_start_length:
314 E.Value0 = Data.getRelocatedAddress(C, &E.SectionIndex);
315 E.Value1 = Data.getULEB128(C);
316 break;
317 default:
318 cantFail(C.takeError());
319 return createStringError(errc::illegal_byte_sequence,
320 "LLE of kind %x not supported", (int)E.Kind);
321 }
322
323 if (E.Kind != dwarf::DW_LLE_base_address &&
324 E.Kind != dwarf::DW_LLE_base_addressx &&
325 E.Kind != dwarf::DW_LLE_end_of_list) {
326 unsigned Bytes = Version >= 5 ? Data.getULEB128(C) : Data.getU16(C);
327 // A single location description describing the location of the object...
328 Data.getU8(C, E.Loc, Bytes);
329 }
330
331 if (!C)
332 return C.takeError();
333 Continue = F(E) && E.Kind != dwarf::DW_LLE_end_of_list;
334 }
335 *Offset = C.tell();
336 return Error::success();
337}
338
339void DWARFDebugLoclists::dumpRawEntry(const DWARFLocationEntry &Entry,
340 raw_ostream &OS, unsigned Indent,
341 DIDumpOptions DumpOpts,
342 const DWARFObject &Obj) const {
343 size_t MaxEncodingStringLength = 0;
344#define HANDLE_DW_LLE(ID, NAME) \
345 MaxEncodingStringLength = std::max(MaxEncodingStringLength, \
346 dwarf::LocListEncodingString(ID).size());
347#include "llvm/BinaryFormat/Dwarf.def"
348
349 OS << "\n";
350 OS.indent(Indent);
351 StringRef EncodingString = dwarf::LocListEncodingString(Entry.Kind);
352 // Unsupported encodings should have been reported during parsing.
353 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-11~++20200309111110+2c36c23f347/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp"
, 353, __PRETTY_FUNCTION__))
;
354 OS << format("%-*s(", MaxEncodingStringLength, EncodingString.data());
355 unsigned FieldSize = 2 + 2 * Data.getAddressSize();
356 switch (Entry.Kind) {
357 case dwarf::DW_LLE_end_of_list:
358 case dwarf::DW_LLE_default_location:
359 break;
360 case dwarf::DW_LLE_startx_endx:
361 case dwarf::DW_LLE_startx_length:
362 case dwarf::DW_LLE_offset_pair:
363 case dwarf::DW_LLE_start_end:
364 case dwarf::DW_LLE_start_length:
365 OS << format_hex(Entry.Value0, FieldSize) << ", "
366 << format_hex(Entry.Value1, FieldSize);
367 break;
368 case dwarf::DW_LLE_base_addressx:
369 case dwarf::DW_LLE_base_address:
370 OS << format_hex(Entry.Value0, FieldSize);
371 break;
372 }
373 OS << ')';
374 switch (Entry.Kind) {
375 case dwarf::DW_LLE_base_address:
376 case dwarf::DW_LLE_start_end:
377 case dwarf::DW_LLE_start_length:
378 DWARFFormValue::dumpAddressSection(Obj, OS, DumpOpts, Entry.SectionIndex);
379 break;
380 default:
381 break;
382 }
383}
384
385void DWARFDebugLoclists::dumpRange(uint64_t StartOffset, uint64_t Size,
386 raw_ostream &OS, const MCRegisterInfo *MRI,
387 const DWARFObject &Obj,
388 DIDumpOptions DumpOpts) {
389 if (!Data.isValidOffsetForDataOfSize(StartOffset, Size)) {
390 OS << "Invalid dump range\n";
391 return;
392 }
393 uint64_t Offset = StartOffset;
394 StringRef Separator;
395 bool CanContinue = true;
396 while (CanContinue && Offset < StartOffset + Size) {
397 OS << Separator;
398 Separator = "\n";
399
400 CanContinue = dumpLocationList(&Offset, OS, /*BaseAddr=*/None, MRI, Obj,
401 nullptr, DumpOpts, /*Indent=*/12);
402 OS << '\n';
403 }
404}