Bug Summary

File:llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
Warning:line 265, 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-10/lib/clang/10.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/build-llvm/lib/DebugInfo/DWARF -I /build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/DebugInfo/DWARF -I /build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/build-llvm/include -I /build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/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-10/lib/clang/10.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-10~++20200112100611+7fa5290d5bd/build-llvm/lib/DebugInfo/DWARF -fdebug-prefix-map=/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd=. -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-01-13-084841-49055-1 -x c++ /build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/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-10~++20200112100611+7fa5290d5bd/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp"
, 105)
;
106 }
107}
108
109// When directly dumping the .debug_loc without a compile unit, we have to guess
110// at the DWARF version. This only affects DW_OP_call_ref, which is a rare
111// expression that LLVM doesn't produce. Guessing the wrong version means we
112// won't be able to pretty print expressions in DWARF2 binaries produced by
113// non-LLVM tools.
114static void dumpExpression(raw_ostream &OS, ArrayRef<uint8_t> Data,
115 bool IsLittleEndian, unsigned AddressSize,
116 const MCRegisterInfo *MRI, DWARFUnit *U) {
117 DWARFDataExtractor Extractor(toStringRef(Data), IsLittleEndian, AddressSize);
118 DWARFExpression(Extractor, dwarf::DWARF_VERSION, AddressSize).print(OS, 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, E.Loc, Data.isLittleEndian(), Data.getAddressSize(),
159 MRI, U);
160 }
161 return true;
162 });
163 if (E) {
164 OS << "\n";
165 OS.indent(Indent);
166 OS << "error: " << toString(std::move(E));
167 return false;
168 }
169 return true;
170}
171
172Error DWARFLocationTable::visitAbsoluteLocationList(
173 uint64_t Offset, Optional<SectionedAddress> BaseAddr,
174 std::function<Optional<SectionedAddress>(uint32_t)> LookupAddr,
175 function_ref<bool(Expected<DWARFLocationExpression>)> Callback) const {
176 DWARFLocationInterpreter Interp(BaseAddr, std::move(LookupAddr));
177 return visitLocationList(&Offset, [&](const DWARFLocationEntry &E) {
178 Expected<Optional<DWARFLocationExpression>> Loc = Interp.Interpret(E);
179 if (!Loc)
180 return Callback(Loc.takeError());
181 if (*Loc)
182 return Callback(**Loc);
183 return true;
184 });
185}
186
187void DWARFDebugLoc::dump(raw_ostream &OS, const MCRegisterInfo *MRI,
188 const DWARFObject &Obj, DIDumpOptions DumpOpts,
189 Optional<uint64_t> DumpOffset) const {
190 auto BaseAddr = None;
191 unsigned Indent = 12;
192 if (DumpOffset) {
193 dumpLocationList(&*DumpOffset, OS, BaseAddr, MRI, Obj, nullptr, DumpOpts,
194 Indent);
195 } else {
196 uint64_t Offset = 0;
197 StringRef Separator;
198 bool CanContinue = true;
199 while (CanContinue && Data.isValidOffset(Offset)) {
200 OS << Separator;
201 Separator = "\n";
202
203 CanContinue = dumpLocationList(&Offset, OS, BaseAddr, MRI, Obj, nullptr,
204 DumpOpts, Indent);
205 OS << '\n';
206 }
207 }
208}
209
210Error DWARFDebugLoc::visitLocationList(
211 uint64_t *Offset,
212 function_ref<bool(const DWARFLocationEntry &)> Callback) const {
213 DataExtractor::Cursor C(*Offset);
214 while (true) {
215 uint64_t SectionIndex;
216 uint64_t Value0 = Data.getRelocatedAddress(C);
217 uint64_t Value1 = Data.getRelocatedAddress(C, &SectionIndex);
218
219 DWARFLocationEntry E;
220
221 // The end of any given location list is marked by an end of list entry,
222 // which consists of a 0 for the beginning address offset and a 0 for the
223 // ending address offset. A beginning offset of 0xff...f marks the base
224 // address selection entry.
225 if (Value0 == 0 && Value1 == 0) {
226 E.Kind = dwarf::DW_LLE_end_of_list;
227 } else if (Value0 == (Data.getAddressSize() == 4 ? -1U : -1ULL)) {
228 E.Kind = dwarf::DW_LLE_base_address;
229 E.Value0 = Value1;
230 E.SectionIndex = SectionIndex;
231 } else {
232 E.Kind = dwarf::DW_LLE_offset_pair;
233 E.Value0 = Value0;
234 E.Value1 = Value1;
235 E.SectionIndex = SectionIndex;
236 unsigned Bytes = Data.getU16(C);
237 // A single location description describing the location of the object...
238 Data.getU8(C, E.Loc, Bytes);
239 }
240
241 if (!C)
242 return C.takeError();
243 if (!Callback(E) || E.Kind == dwarf::DW_LLE_end_of_list)
244 break;
245 }
246 *Offset = C.tell();
247 return Error::success();
248}
249
250void DWARFDebugLoc::dumpRawEntry(const DWARFLocationEntry &Entry,
251 raw_ostream &OS, unsigned Indent,
252 DIDumpOptions DumpOpts,
253 const DWARFObject &Obj) const {
254 uint64_t Value0, Value1;
255 switch (Entry.Kind) {
256 case dwarf::DW_LLE_base_address:
257 Value0 = Data.getAddressSize() == 4 ? -1U : -1ULL;
258 Value1 = Entry.Value0;
259 break;
260 case dwarf::DW_LLE_offset_pair:
261 Value0 = Entry.Value0;
262 Value1 = Entry.Value1;
263 break;
264 case dwarf::DW_LLE_end_of_list:
265 Value0 = Value1 = 0;
Although the value stored to 'Value1' is used in the enclosing expression, the value is never actually read from 'Value1'
266 return;
267 default:
268 llvm_unreachable("Not possible in DWARF4!")::llvm::llvm_unreachable_internal("Not possible in DWARF4!", "/build/llvm-toolchain-snapshot-10~++20200112100611+7fa5290d5bd/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp"
, 268)
;
269 }
270 OS << '\n';
271 OS.indent(Indent);
272 OS << '(' << format_hex(Value0, 2 + Data.getAddressSize() * 2) << ", "
273 << format_hex(Value1, 2 + Data.getAddressSize() * 2) << ')';
274 DWARFFormValue::dumpAddressSection(Obj, OS, DumpOpts, Entry.SectionIndex);
275}
276
277Error DWARFDebugLoclists::visitLocationList(
278 uint64_t *Offset, function_ref<bool(const DWARFLocationEntry &)> F) const {
279
280 DataExtractor::Cursor C(*Offset);
281 bool Continue = true;
282 while (Continue) {
283 DWARFLocationEntry E;
284 E.Kind = Data.getU8(C);
285 switch (E.Kind) {
286 case dwarf::DW_LLE_end_of_list:
287 break;
288 case dwarf::DW_LLE_base_addressx:
289 E.Value0 = Data.getULEB128(C);
290 break;
291 case dwarf::DW_LLE_startx_endx:
292 E.Value0 = Data.getULEB128(C);
293 E.Value1 = Data.getULEB128(C);
294 break;
295 case dwarf::DW_LLE_startx_length:
296 E.Value0 = Data.getULEB128(C);
297 // Pre-DWARF 5 has different interpretation of the length field. We have
298 // to support both pre- and standartized styles for the compatibility.
299 if (Version < 5)
300 E.Value1 = Data.getU32(C);
301 else
302 E.Value1 = Data.getULEB128(C);
303 break;
304 case dwarf::DW_LLE_offset_pair:
305 E.Value0 = Data.getULEB128(C);
306 E.Value1 = Data.getULEB128(C);
307 E.SectionIndex = SectionedAddress::UndefSection;
308 break;
309 case dwarf::DW_LLE_default_location:
310 break;
311 case dwarf::DW_LLE_base_address:
312 E.Value0 = Data.getRelocatedAddress(C, &E.SectionIndex);
313 break;
314 case dwarf::DW_LLE_start_end:
315 E.Value0 = Data.getRelocatedAddress(C, &E.SectionIndex);
316 E.Value1 = Data.getRelocatedAddress(C);
317 break;
318 case dwarf::DW_LLE_start_length:
319 E.Value0 = Data.getRelocatedAddress(C, &E.SectionIndex);
320 E.Value1 = Data.getULEB128(C);
321 break;
322 default:
323 cantFail(C.takeError());
324 return createStringError(errc::illegal_byte_sequence,
325 "LLE of kind %x not supported", (int)E.Kind);
326 }
327
328 if (E.Kind != dwarf::DW_LLE_base_address &&
329 E.Kind != dwarf::DW_LLE_base_addressx &&
330 E.Kind != dwarf::DW_LLE_end_of_list) {
331 unsigned Bytes = Version >= 5 ? Data.getULEB128(C) : Data.getU16(C);
332 // A single location description describing the location of the object...
333 Data.getU8(C, E.Loc, Bytes);
334 }
335
336 if (!C)
337 return C.takeError();
338 Continue = F(E) && E.Kind != dwarf::DW_LLE_end_of_list;
339 }
340 *Offset = C.tell();
341 return Error::success();
342}
343
344void DWARFDebugLoclists::dumpRawEntry(const DWARFLocationEntry &Entry,
345 raw_ostream &OS, unsigned Indent,
346 DIDumpOptions DumpOpts,
347 const DWARFObject &Obj) const {
348 size_t MaxEncodingStringLength = 0;
349#define HANDLE_DW_LLE(ID, NAME) \
350 MaxEncodingStringLength = std::max(MaxEncodingStringLength, \
351 dwarf::LocListEncodingString(ID).size());
352#include "llvm/BinaryFormat/Dwarf.def"
353
354 OS << "\n";
355 OS.indent(Indent);
356 StringRef EncodingString = dwarf::LocListEncodingString(Entry.Kind);
357 // Unsupported encodings should have been reported during parsing.
358 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-10~++20200112100611+7fa5290d5bd/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp"
, 358, __PRETTY_FUNCTION__))
;
359 OS << format("%-*s(", MaxEncodingStringLength, EncodingString.data());
360 unsigned FieldSize = 2 + 2 * Data.getAddressSize();
361 switch (Entry.Kind) {
362 case dwarf::DW_LLE_end_of_list:
363 case dwarf::DW_LLE_default_location:
364 break;
365 case dwarf::DW_LLE_startx_endx:
366 case dwarf::DW_LLE_startx_length:
367 case dwarf::DW_LLE_offset_pair:
368 case dwarf::DW_LLE_start_end:
369 case dwarf::DW_LLE_start_length:
370 OS << format_hex(Entry.Value0, FieldSize) << ", "
371 << format_hex(Entry.Value1, FieldSize);
372 break;
373 case dwarf::DW_LLE_base_addressx:
374 case dwarf::DW_LLE_base_address:
375 OS << format_hex(Entry.Value0, FieldSize);
376 break;
377 }
378 OS << ')';
379 switch (Entry.Kind) {
380 case dwarf::DW_LLE_base_address:
381 case dwarf::DW_LLE_start_end:
382 case dwarf::DW_LLE_start_length:
383 DWARFFormValue::dumpAddressSection(Obj, OS, DumpOpts, Entry.SectionIndex);
384 break;
385 default:
386 break;
387 }
388}
389
390void DWARFDebugLoclists::dumpRange(uint64_t StartOffset, uint64_t Size,
391 raw_ostream &OS, const MCRegisterInfo *MRI,
392 const DWARFObject &Obj,
393 DIDumpOptions DumpOpts) {
394 if (!Data.isValidOffsetForDataOfSize(StartOffset, Size)) {
395 OS << "Invalid dump range\n";
396 return;
397 }
398 uint64_t Offset = StartOffset;
399 StringRef Separator;
400 bool CanContinue = true;
401 while (CanContinue && Offset < StartOffset + Size) {
402 OS << Separator;
403 Separator = "\n";
404
405 CanContinue = dumpLocationList(&Offset, OS, /*BaseAddr=*/None, MRI, Obj,
406 nullptr, DumpOpts, /*Indent=*/12);
407 OS << '\n';
408 }
409}