10b57cec5SDimitry Andric //===- DWARFDebugLoc.cpp --------------------------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
100b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
110b57cec5SDimitry Andric #include "llvm/BinaryFormat/Dwarf.h"
1281ad6265SDimitry Andric #include "llvm/DebugInfo/DIContext.h"
1381ad6265SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"
140b57cec5SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFExpression.h"
1581ad6265SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
1681ad6265SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFLocationExpression.h"
170b57cec5SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
180b57cec5SDimitry Andric #include "llvm/Support/Format.h"
190b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
200b57cec5SDimitry Andric #include <algorithm>
210b57cec5SDimitry Andric #include <cinttypes>
220b57cec5SDimitry Andric #include <cstdint>
230b57cec5SDimitry Andric 
240b57cec5SDimitry Andric using namespace llvm;
25480093f4SDimitry Andric using object::SectionedAddress;
26480093f4SDimitry Andric 
2781ad6265SDimitry Andric namespace llvm {
2881ad6265SDimitry Andric class DWARFObject;
2981ad6265SDimitry Andric }
3081ad6265SDimitry Andric 
31480093f4SDimitry Andric namespace {
32480093f4SDimitry Andric class DWARFLocationInterpreter {
33bdd1243dSDimitry Andric   std::optional<object::SectionedAddress> Base;
34bdd1243dSDimitry Andric   std::function<std::optional<object::SectionedAddress>(uint32_t)> LookupAddr;
35480093f4SDimitry Andric 
36480093f4SDimitry Andric public:
DWARFLocationInterpreter(std::optional<object::SectionedAddress> Base,std::function<std::optional<object::SectionedAddress> (uint32_t)> LookupAddr)37480093f4SDimitry Andric   DWARFLocationInterpreter(
38bdd1243dSDimitry Andric       std::optional<object::SectionedAddress> Base,
39bdd1243dSDimitry Andric       std::function<std::optional<object::SectionedAddress>(uint32_t)>
40bdd1243dSDimitry Andric           LookupAddr)
41480093f4SDimitry Andric       : Base(Base), LookupAddr(std::move(LookupAddr)) {}
42480093f4SDimitry Andric 
43bdd1243dSDimitry Andric   Expected<std::optional<DWARFLocationExpression>>
44480093f4SDimitry Andric   Interpret(const DWARFLocationEntry &E);
45480093f4SDimitry Andric };
46480093f4SDimitry Andric } // namespace
47480093f4SDimitry Andric 
createResolverError(uint32_t Index,unsigned Kind)48480093f4SDimitry Andric static Error createResolverError(uint32_t Index, unsigned Kind) {
490eae32dcSDimitry Andric   return make_error<ResolverError>(Index, (dwarf::LoclistEntries)Kind);
50480093f4SDimitry Andric }
51480093f4SDimitry Andric 
52bdd1243dSDimitry Andric Expected<std::optional<DWARFLocationExpression>>
Interpret(const DWARFLocationEntry & E)53480093f4SDimitry Andric DWARFLocationInterpreter::Interpret(const DWARFLocationEntry &E) {
54480093f4SDimitry Andric   switch (E.Kind) {
55480093f4SDimitry Andric   case dwarf::DW_LLE_end_of_list:
56bdd1243dSDimitry Andric     return std::nullopt;
57480093f4SDimitry Andric   case dwarf::DW_LLE_base_addressx: {
58480093f4SDimitry Andric     Base = LookupAddr(E.Value0);
59480093f4SDimitry Andric     if (!Base)
60480093f4SDimitry Andric       return createResolverError(E.Value0, E.Kind);
61bdd1243dSDimitry Andric     return std::nullopt;
62480093f4SDimitry Andric   }
63480093f4SDimitry Andric   case dwarf::DW_LLE_startx_endx: {
64bdd1243dSDimitry Andric     std::optional<SectionedAddress> LowPC = LookupAddr(E.Value0);
65480093f4SDimitry Andric     if (!LowPC)
66480093f4SDimitry Andric       return createResolverError(E.Value0, E.Kind);
67bdd1243dSDimitry Andric     std::optional<SectionedAddress> HighPC = LookupAddr(E.Value1);
68480093f4SDimitry Andric     if (!HighPC)
69480093f4SDimitry Andric       return createResolverError(E.Value1, E.Kind);
70480093f4SDimitry Andric     return DWARFLocationExpression{
71480093f4SDimitry Andric         DWARFAddressRange{LowPC->Address, HighPC->Address, LowPC->SectionIndex},
72480093f4SDimitry Andric         E.Loc};
73480093f4SDimitry Andric   }
74480093f4SDimitry Andric   case dwarf::DW_LLE_startx_length: {
75bdd1243dSDimitry Andric     std::optional<SectionedAddress> LowPC = LookupAddr(E.Value0);
76480093f4SDimitry Andric     if (!LowPC)
77480093f4SDimitry Andric       return createResolverError(E.Value0, E.Kind);
78480093f4SDimitry Andric     return DWARFLocationExpression{DWARFAddressRange{LowPC->Address,
79480093f4SDimitry Andric                                                      LowPC->Address + E.Value1,
80480093f4SDimitry Andric                                                      LowPC->SectionIndex},
81480093f4SDimitry Andric                                    E.Loc};
82480093f4SDimitry Andric   }
83480093f4SDimitry Andric   case dwarf::DW_LLE_offset_pair: {
84480093f4SDimitry Andric     if (!Base) {
85480093f4SDimitry Andric       return createStringError(inconvertibleErrorCode(),
86480093f4SDimitry Andric                                "Unable to resolve location list offset pair: "
87480093f4SDimitry Andric                                "Base address not defined");
88480093f4SDimitry Andric     }
89480093f4SDimitry Andric     DWARFAddressRange Range{Base->Address + E.Value0, Base->Address + E.Value1,
90480093f4SDimitry Andric                             Base->SectionIndex};
91480093f4SDimitry Andric     if (Range.SectionIndex == SectionedAddress::UndefSection)
92480093f4SDimitry Andric       Range.SectionIndex = E.SectionIndex;
93480093f4SDimitry Andric     return DWARFLocationExpression{Range, E.Loc};
94480093f4SDimitry Andric   }
95480093f4SDimitry Andric   case dwarf::DW_LLE_default_location:
96bdd1243dSDimitry Andric     return DWARFLocationExpression{std::nullopt, E.Loc};
97480093f4SDimitry Andric   case dwarf::DW_LLE_base_address:
98480093f4SDimitry Andric     Base = SectionedAddress{E.Value0, E.SectionIndex};
99bdd1243dSDimitry Andric     return std::nullopt;
100480093f4SDimitry Andric   case dwarf::DW_LLE_start_end:
101480093f4SDimitry Andric     return DWARFLocationExpression{
102480093f4SDimitry Andric         DWARFAddressRange{E.Value0, E.Value1, E.SectionIndex}, E.Loc};
103480093f4SDimitry Andric   case dwarf::DW_LLE_start_length:
104480093f4SDimitry Andric     return DWARFLocationExpression{
105480093f4SDimitry Andric         DWARFAddressRange{E.Value0, E.Value0 + E.Value1, E.SectionIndex},
106480093f4SDimitry Andric         E.Loc};
107480093f4SDimitry Andric   default:
108480093f4SDimitry Andric     llvm_unreachable("unreachable locations list kind");
109480093f4SDimitry Andric   }
110480093f4SDimitry Andric }
1110b57cec5SDimitry Andric 
dumpExpression(raw_ostream & OS,DIDumpOptions DumpOpts,ArrayRef<uint8_t> Data,bool IsLittleEndian,unsigned AddressSize,DWARFUnit * U)112e8d8bef9SDimitry Andric static void dumpExpression(raw_ostream &OS, DIDumpOptions DumpOpts,
113e8d8bef9SDimitry Andric                            ArrayRef<uint8_t> Data, bool IsLittleEndian,
114bdd1243dSDimitry Andric                            unsigned AddressSize, DWARFUnit *U) {
1155ffd83dbSDimitry Andric   DWARFDataExtractor Extractor(Data, IsLittleEndian, AddressSize);
1165ffd83dbSDimitry Andric   // Note. We do not pass any format to DWARFExpression, even if the
1175ffd83dbSDimitry Andric   // corresponding unit is known. For now, there is only one operation,
1185ffd83dbSDimitry Andric   // DW_OP_call_ref, which depends on the format; it is rarely used, and
1195ffd83dbSDimitry Andric   // is unexpected in location tables.
120bdd1243dSDimitry Andric   DWARFExpression(Extractor, AddressSize).print(OS, DumpOpts, U);
1210b57cec5SDimitry Andric }
1220b57cec5SDimitry Andric 
dumpLocationList(uint64_t * Offset,raw_ostream & OS,std::optional<SectionedAddress> BaseAddr,const DWARFObject & Obj,DWARFUnit * U,DIDumpOptions DumpOpts,unsigned Indent) const123bdd1243dSDimitry Andric bool DWARFLocationTable::dumpLocationList(
124bdd1243dSDimitry Andric     uint64_t *Offset, raw_ostream &OS, std::optional<SectionedAddress> BaseAddr,
125bdd1243dSDimitry Andric     const DWARFObject &Obj, DWARFUnit *U, DIDumpOptions DumpOpts,
1260b57cec5SDimitry Andric     unsigned Indent) const {
127480093f4SDimitry Andric   DWARFLocationInterpreter Interp(
128bdd1243dSDimitry Andric       BaseAddr, [U](uint32_t Index) -> std::optional<SectionedAddress> {
129480093f4SDimitry Andric         if (U)
130480093f4SDimitry Andric           return U->getAddrOffsetSectionItem(Index);
131bdd1243dSDimitry Andric         return std::nullopt;
132480093f4SDimitry Andric       });
133480093f4SDimitry Andric   OS << format("0x%8.8" PRIx64 ": ", *Offset);
134480093f4SDimitry Andric   Error E = visitLocationList(Offset, [&](const DWARFLocationEntry &E) {
135bdd1243dSDimitry Andric     Expected<std::optional<DWARFLocationExpression>> Loc = Interp.Interpret(E);
136480093f4SDimitry Andric     if (!Loc || DumpOpts.DisplayRawContents)
137480093f4SDimitry Andric       dumpRawEntry(E, OS, Indent, DumpOpts, Obj);
138480093f4SDimitry Andric     if (Loc && *Loc) {
1398bcb0991SDimitry Andric       OS << "\n";
140480093f4SDimitry Andric       OS.indent(Indent);
141480093f4SDimitry Andric       if (DumpOpts.DisplayRawContents)
142480093f4SDimitry Andric         OS << "          => ";
1430b57cec5SDimitry Andric 
144480093f4SDimitry Andric       DIDumpOptions RangeDumpOpts(DumpOpts);
145480093f4SDimitry Andric       RangeDumpOpts.DisplayRawContents = false;
146480093f4SDimitry Andric       if (Loc.get()->Range)
147480093f4SDimitry Andric         Loc.get()->Range->dump(OS, Data.getAddressSize(), RangeDumpOpts, &Obj);
148480093f4SDimitry Andric       else
149480093f4SDimitry Andric         OS << "<default>";
150480093f4SDimitry Andric     }
151480093f4SDimitry Andric     if (!Loc)
152480093f4SDimitry Andric       consumeError(Loc.takeError());
153480093f4SDimitry Andric 
154480093f4SDimitry Andric     if (E.Kind != dwarf::DW_LLE_base_address &&
155480093f4SDimitry Andric         E.Kind != dwarf::DW_LLE_base_addressx &&
156480093f4SDimitry Andric         E.Kind != dwarf::DW_LLE_end_of_list) {
157480093f4SDimitry Andric       OS << ": ";
158e8d8bef9SDimitry Andric       dumpExpression(OS, DumpOpts, E.Loc, Data.isLittleEndian(),
159bdd1243dSDimitry Andric                      Data.getAddressSize(), U);
160480093f4SDimitry Andric     }
161480093f4SDimitry Andric     return true;
162480093f4SDimitry Andric   });
163480093f4SDimitry Andric   if (E) {
1645ffd83dbSDimitry Andric     DumpOpts.RecoverableErrorHandler(std::move(E));
165480093f4SDimitry Andric     return false;
166480093f4SDimitry Andric   }
167480093f4SDimitry Andric   return true;
1680b57cec5SDimitry Andric }
1690b57cec5SDimitry Andric 
visitAbsoluteLocationList(uint64_t Offset,std::optional<SectionedAddress> BaseAddr,std::function<std::optional<SectionedAddress> (uint32_t)> LookupAddr,function_ref<bool (Expected<DWARFLocationExpression>)> Callback) const170480093f4SDimitry Andric Error DWARFLocationTable::visitAbsoluteLocationList(
171bdd1243dSDimitry Andric     uint64_t Offset, std::optional<SectionedAddress> BaseAddr,
172bdd1243dSDimitry Andric     std::function<std::optional<SectionedAddress>(uint32_t)> LookupAddr,
173480093f4SDimitry Andric     function_ref<bool(Expected<DWARFLocationExpression>)> Callback) const {
174480093f4SDimitry Andric   DWARFLocationInterpreter Interp(BaseAddr, std::move(LookupAddr));
175480093f4SDimitry Andric   return visitLocationList(&Offset, [&](const DWARFLocationEntry &E) {
176bdd1243dSDimitry Andric     Expected<std::optional<DWARFLocationExpression>> Loc = Interp.Interpret(E);
177480093f4SDimitry Andric     if (!Loc)
178480093f4SDimitry Andric       return Callback(Loc.takeError());
179480093f4SDimitry Andric     if (*Loc)
180480093f4SDimitry Andric       return Callback(**Loc);
181480093f4SDimitry Andric     return true;
182480093f4SDimitry Andric   });
183480093f4SDimitry Andric }
184480093f4SDimitry Andric 
dump(raw_ostream & OS,const DWARFObject & Obj,DIDumpOptions DumpOpts,std::optional<uint64_t> DumpOffset) const185bdd1243dSDimitry Andric void DWARFDebugLoc::dump(raw_ostream &OS, const DWARFObject &Obj,
186bdd1243dSDimitry Andric                          DIDumpOptions DumpOpts,
187bdd1243dSDimitry Andric                          std::optional<uint64_t> DumpOffset) const {
188bdd1243dSDimitry Andric   auto BaseAddr = std::nullopt;
189480093f4SDimitry Andric   unsigned Indent = 12;
190480093f4SDimitry Andric   if (DumpOffset) {
191bdd1243dSDimitry Andric     dumpLocationList(&*DumpOffset, OS, BaseAddr, Obj, nullptr, DumpOpts,
192480093f4SDimitry Andric                      Indent);
193480093f4SDimitry Andric   } else {
194480093f4SDimitry Andric     uint64_t Offset = 0;
195480093f4SDimitry Andric     StringRef Separator;
196480093f4SDimitry Andric     bool CanContinue = true;
197480093f4SDimitry Andric     while (CanContinue && Data.isValidOffset(Offset)) {
198480093f4SDimitry Andric       OS << Separator;
199480093f4SDimitry Andric       Separator = "\n";
200480093f4SDimitry Andric 
201bdd1243dSDimitry Andric       CanContinue = dumpLocationList(&Offset, OS, BaseAddr, Obj, nullptr,
202480093f4SDimitry Andric                                      DumpOpts, Indent);
2038bcb0991SDimitry Andric       OS << '\n';
2040b57cec5SDimitry Andric     }
2050b57cec5SDimitry Andric   }
206480093f4SDimitry Andric }
2070b57cec5SDimitry Andric 
visitLocationList(uint64_t * Offset,function_ref<bool (const DWARFLocationEntry &)> Callback) const208480093f4SDimitry Andric Error DWARFDebugLoc::visitLocationList(
209480093f4SDimitry Andric     uint64_t *Offset,
210480093f4SDimitry Andric     function_ref<bool(const DWARFLocationEntry &)> Callback) const {
2118bcb0991SDimitry Andric   DataExtractor::Cursor C(*Offset);
2120b57cec5SDimitry Andric   while (true) {
213480093f4SDimitry Andric     uint64_t SectionIndex;
214480093f4SDimitry Andric     uint64_t Value0 = Data.getRelocatedAddress(C);
215480093f4SDimitry Andric     uint64_t Value1 = Data.getRelocatedAddress(C, &SectionIndex);
2160b57cec5SDimitry Andric 
217480093f4SDimitry Andric     DWARFLocationEntry E;
2180b57cec5SDimitry Andric 
2190b57cec5SDimitry Andric     // The end of any given location list is marked by an end of list entry,
2200b57cec5SDimitry Andric     // which consists of a 0 for the beginning address offset and a 0 for the
221480093f4SDimitry Andric     // ending address offset. A beginning offset of 0xff...f marks the base
222480093f4SDimitry Andric     // address selection entry.
223480093f4SDimitry Andric     if (Value0 == 0 && Value1 == 0) {
224480093f4SDimitry Andric       E.Kind = dwarf::DW_LLE_end_of_list;
225480093f4SDimitry Andric     } else if (Value0 == (Data.getAddressSize() == 4 ? -1U : -1ULL)) {
226480093f4SDimitry Andric       E.Kind = dwarf::DW_LLE_base_address;
227480093f4SDimitry Andric       E.Value0 = Value1;
228480093f4SDimitry Andric       E.SectionIndex = SectionIndex;
229480093f4SDimitry Andric     } else {
230480093f4SDimitry Andric       E.Kind = dwarf::DW_LLE_offset_pair;
231480093f4SDimitry Andric       E.Value0 = Value0;
232480093f4SDimitry Andric       E.Value1 = Value1;
233480093f4SDimitry Andric       E.SectionIndex = SectionIndex;
2348bcb0991SDimitry Andric       unsigned Bytes = Data.getU16(C);
2350b57cec5SDimitry Andric       // A single location description describing the location of the object...
2368bcb0991SDimitry Andric       Data.getU8(C, E.Loc, Bytes);
2378bcb0991SDimitry Andric     }
2388bcb0991SDimitry Andric 
239480093f4SDimitry Andric     if (!C)
240480093f4SDimitry Andric       return C.takeError();
241480093f4SDimitry Andric     if (!Callback(E) || E.Kind == dwarf::DW_LLE_end_of_list)
2420b57cec5SDimitry Andric       break;
2430b57cec5SDimitry Andric   }
244480093f4SDimitry Andric   *Offset = C.tell();
245480093f4SDimitry Andric   return Error::success();
2460b57cec5SDimitry Andric }
2470b57cec5SDimitry Andric 
dumpRawEntry(const DWARFLocationEntry & Entry,raw_ostream & OS,unsigned Indent,DIDumpOptions DumpOpts,const DWARFObject & Obj) const248480093f4SDimitry Andric void DWARFDebugLoc::dumpRawEntry(const DWARFLocationEntry &Entry,
249480093f4SDimitry Andric                                  raw_ostream &OS, unsigned Indent,
250480093f4SDimitry Andric                                  DIDumpOptions DumpOpts,
251480093f4SDimitry Andric                                  const DWARFObject &Obj) const {
252480093f4SDimitry Andric   uint64_t Value0, Value1;
253480093f4SDimitry Andric   switch (Entry.Kind) {
254480093f4SDimitry Andric   case dwarf::DW_LLE_base_address:
255480093f4SDimitry Andric     Value0 = Data.getAddressSize() == 4 ? -1U : -1ULL;
256480093f4SDimitry Andric     Value1 = Entry.Value0;
257480093f4SDimitry Andric     break;
258480093f4SDimitry Andric   case dwarf::DW_LLE_offset_pair:
259480093f4SDimitry Andric     Value0 = Entry.Value0;
260480093f4SDimitry Andric     Value1 = Entry.Value1;
261480093f4SDimitry Andric     break;
262480093f4SDimitry Andric   case dwarf::DW_LLE_end_of_list:
263480093f4SDimitry Andric     return;
264480093f4SDimitry Andric   default:
265480093f4SDimitry Andric     llvm_unreachable("Not possible in DWARF4!");
266480093f4SDimitry Andric   }
267480093f4SDimitry Andric   OS << '\n';
268480093f4SDimitry Andric   OS.indent(Indent);
269480093f4SDimitry Andric   OS << '(' << format_hex(Value0, 2 + Data.getAddressSize() * 2) << ", "
270480093f4SDimitry Andric      << format_hex(Value1, 2 + Data.getAddressSize() * 2) << ')';
271480093f4SDimitry Andric   DWARFFormValue::dumpAddressSection(Obj, OS, DumpOpts, Entry.SectionIndex);
272480093f4SDimitry Andric }
273480093f4SDimitry Andric 
visitLocationList(uint64_t * Offset,function_ref<bool (const DWARFLocationEntry &)> F) const274480093f4SDimitry Andric Error DWARFDebugLoclists::visitLocationList(
275480093f4SDimitry Andric     uint64_t *Offset, function_ref<bool(const DWARFLocationEntry &)> F) const {
276480093f4SDimitry Andric 
2778bcb0991SDimitry Andric   DataExtractor::Cursor C(*Offset);
278480093f4SDimitry Andric   bool Continue = true;
279480093f4SDimitry Andric   while (Continue) {
280480093f4SDimitry Andric     DWARFLocationEntry E;
281480093f4SDimitry Andric     E.Kind = Data.getU8(C);
282480093f4SDimitry Andric     switch (E.Kind) {
283480093f4SDimitry Andric     case dwarf::DW_LLE_end_of_list:
284480093f4SDimitry Andric       break;
2858bcb0991SDimitry Andric     case dwarf::DW_LLE_base_addressx:
2868bcb0991SDimitry Andric       E.Value0 = Data.getULEB128(C);
2878bcb0991SDimitry Andric       break;
288480093f4SDimitry Andric     case dwarf::DW_LLE_startx_endx:
289480093f4SDimitry Andric       E.Value0 = Data.getULEB128(C);
290480093f4SDimitry Andric       E.Value1 = Data.getULEB128(C);
291480093f4SDimitry Andric       break;
2920b57cec5SDimitry Andric     case dwarf::DW_LLE_startx_length:
2938bcb0991SDimitry Andric       E.Value0 = Data.getULEB128(C);
2940b57cec5SDimitry Andric       // Pre-DWARF 5 has different interpretation of the length field. We have
2950b57cec5SDimitry Andric       // to support both pre- and standartized styles for the compatibility.
2960b57cec5SDimitry Andric       if (Version < 5)
2978bcb0991SDimitry Andric         E.Value1 = Data.getU32(C);
2980b57cec5SDimitry Andric       else
2998bcb0991SDimitry Andric         E.Value1 = Data.getULEB128(C);
3000b57cec5SDimitry Andric       break;
3010b57cec5SDimitry Andric     case dwarf::DW_LLE_offset_pair:
3028bcb0991SDimitry Andric       E.Value0 = Data.getULEB128(C);
3038bcb0991SDimitry Andric       E.Value1 = Data.getULEB128(C);
304480093f4SDimitry Andric       E.SectionIndex = SectionedAddress::UndefSection;
305480093f4SDimitry Andric       break;
306480093f4SDimitry Andric     case dwarf::DW_LLE_default_location:
3070b57cec5SDimitry Andric       break;
3080b57cec5SDimitry Andric     case dwarf::DW_LLE_base_address:
309480093f4SDimitry Andric       E.Value0 = Data.getRelocatedAddress(C, &E.SectionIndex);
310480093f4SDimitry Andric       break;
311480093f4SDimitry Andric     case dwarf::DW_LLE_start_end:
312480093f4SDimitry Andric       E.Value0 = Data.getRelocatedAddress(C, &E.SectionIndex);
313480093f4SDimitry Andric       E.Value1 = Data.getRelocatedAddress(C);
314480093f4SDimitry Andric       break;
315480093f4SDimitry Andric     case dwarf::DW_LLE_start_length:
316480093f4SDimitry Andric       E.Value0 = Data.getRelocatedAddress(C, &E.SectionIndex);
317480093f4SDimitry Andric       E.Value1 = Data.getULEB128(C);
3180b57cec5SDimitry Andric       break;
3190b57cec5SDimitry Andric     default:
3208bcb0991SDimitry Andric       cantFail(C.takeError());
3218bcb0991SDimitry Andric       return createStringError(errc::illegal_byte_sequence,
322480093f4SDimitry Andric                                "LLE of kind %x not supported", (int)E.Kind);
3230b57cec5SDimitry Andric     }
3240b57cec5SDimitry Andric 
325480093f4SDimitry Andric     if (E.Kind != dwarf::DW_LLE_base_address &&
326480093f4SDimitry Andric         E.Kind != dwarf::DW_LLE_base_addressx &&
327480093f4SDimitry Andric         E.Kind != dwarf::DW_LLE_end_of_list) {
3288bcb0991SDimitry Andric       unsigned Bytes = Version >= 5 ? Data.getULEB128(C) : Data.getU16(C);
3290b57cec5SDimitry Andric       // A single location description describing the location of the object...
3308bcb0991SDimitry Andric       Data.getU8(C, E.Loc, Bytes);
3310b57cec5SDimitry Andric     }
3320b57cec5SDimitry Andric 
333480093f4SDimitry Andric     if (!C)
334480093f4SDimitry Andric       return C.takeError();
335480093f4SDimitry Andric     Continue = F(E) && E.Kind != dwarf::DW_LLE_end_of_list;
3360b57cec5SDimitry Andric   }
3378bcb0991SDimitry Andric   *Offset = C.tell();
338480093f4SDimitry Andric   return Error::success();
3390b57cec5SDimitry Andric }
3400b57cec5SDimitry Andric 
dumpRawEntry(const DWARFLocationEntry & Entry,raw_ostream & OS,unsigned Indent,DIDumpOptions DumpOpts,const DWARFObject & Obj) const341480093f4SDimitry Andric void DWARFDebugLoclists::dumpRawEntry(const DWARFLocationEntry &Entry,
342480093f4SDimitry Andric                                       raw_ostream &OS, unsigned Indent,
343480093f4SDimitry Andric                                       DIDumpOptions DumpOpts,
344480093f4SDimitry Andric                                       const DWARFObject &Obj) const {
345480093f4SDimitry Andric   size_t MaxEncodingStringLength = 0;
346480093f4SDimitry Andric #define HANDLE_DW_LLE(ID, NAME)                                                \
347480093f4SDimitry Andric   MaxEncodingStringLength = std::max(MaxEncodingStringLength,                  \
348480093f4SDimitry Andric                                      dwarf::LocListEncodingString(ID).size());
349480093f4SDimitry Andric #include "llvm/BinaryFormat/Dwarf.def"
3500b57cec5SDimitry Andric 
3518bcb0991SDimitry Andric   OS << "\n";
3520b57cec5SDimitry Andric   OS.indent(Indent);
353480093f4SDimitry Andric   StringRef EncodingString = dwarf::LocListEncodingString(Entry.Kind);
3548bcb0991SDimitry Andric   // Unsupported encodings should have been reported during parsing.
3558bcb0991SDimitry Andric   assert(!EncodingString.empty() && "Unknown loclist entry encoding");
356480093f4SDimitry Andric   OS << format("%-*s(", MaxEncodingStringLength, EncodingString.data());
357480093f4SDimitry Andric   unsigned FieldSize = 2 + 2 * Data.getAddressSize();
358480093f4SDimitry Andric   switch (Entry.Kind) {
359480093f4SDimitry Andric   case dwarf::DW_LLE_end_of_list:
360480093f4SDimitry Andric   case dwarf::DW_LLE_default_location:
361480093f4SDimitry Andric     break;
362480093f4SDimitry Andric   case dwarf::DW_LLE_startx_endx:
3638bcb0991SDimitry Andric   case dwarf::DW_LLE_startx_length:
3648bcb0991SDimitry Andric   case dwarf::DW_LLE_offset_pair:
365480093f4SDimitry Andric   case dwarf::DW_LLE_start_end:
366480093f4SDimitry Andric   case dwarf::DW_LLE_start_length:
367480093f4SDimitry Andric     OS << format_hex(Entry.Value0, FieldSize) << ", "
368480093f4SDimitry Andric        << format_hex(Entry.Value1, FieldSize);
3698bcb0991SDimitry Andric     break;
3708bcb0991SDimitry Andric   case dwarf::DW_LLE_base_addressx:
3718bcb0991SDimitry Andric   case dwarf::DW_LLE_base_address:
372480093f4SDimitry Andric     OS << format_hex(Entry.Value0, FieldSize);
3738bcb0991SDimitry Andric     break;
3748bcb0991SDimitry Andric   }
3758bcb0991SDimitry Andric   OS << ')';
376480093f4SDimitry Andric   switch (Entry.Kind) {
3770b57cec5SDimitry Andric   case dwarf::DW_LLE_base_address:
378480093f4SDimitry Andric   case dwarf::DW_LLE_start_end:
379480093f4SDimitry Andric   case dwarf::DW_LLE_start_length:
380480093f4SDimitry Andric     DWARFFormValue::dumpAddressSection(Obj, OS, DumpOpts, Entry.SectionIndex);
3810b57cec5SDimitry Andric     break;
3820b57cec5SDimitry Andric   default:
383480093f4SDimitry Andric     break;
384480093f4SDimitry Andric   }
3850b57cec5SDimitry Andric }
3860b57cec5SDimitry Andric 
dumpRange(uint64_t StartOffset,uint64_t Size,raw_ostream & OS,const DWARFObject & Obj,DIDumpOptions DumpOpts)387480093f4SDimitry Andric void DWARFDebugLoclists::dumpRange(uint64_t StartOffset, uint64_t Size,
388bdd1243dSDimitry Andric                                    raw_ostream &OS, const DWARFObject &Obj,
389480093f4SDimitry Andric                                    DIDumpOptions DumpOpts) {
390480093f4SDimitry Andric   if (!Data.isValidOffsetForDataOfSize(StartOffset, Size))  {
391480093f4SDimitry Andric     OS << "Invalid dump range\n";
3920b57cec5SDimitry Andric     return;
3930b57cec5SDimitry Andric   }
394480093f4SDimitry Andric   uint64_t Offset = StartOffset;
395480093f4SDimitry Andric   StringRef Separator;
396480093f4SDimitry Andric   bool CanContinue = true;
397480093f4SDimitry Andric   while (CanContinue && Offset < StartOffset + Size) {
398480093f4SDimitry Andric     OS << Separator;
399480093f4SDimitry Andric     Separator = "\n";
4000b57cec5SDimitry Andric 
401bdd1243dSDimitry Andric     CanContinue = dumpLocationList(&Offset, OS, /*BaseAddr=*/std::nullopt, Obj,
402480093f4SDimitry Andric                                    nullptr, DumpOpts, /*Indent=*/12);
4038bcb0991SDimitry Andric     OS << '\n';
4040b57cec5SDimitry Andric   }
4050b57cec5SDimitry Andric }
4060eae32dcSDimitry Andric 
log(raw_ostream & OS) const4070eae32dcSDimitry Andric void llvm::ResolverError::log(raw_ostream &OS) const {
4080eae32dcSDimitry Andric   OS << format("unable to resolve indirect address %u for: %s", Index,
4090eae32dcSDimitry Andric                dwarf::LocListEncodingString(Kind).data());
4100eae32dcSDimitry Andric }
4110eae32dcSDimitry Andric 
4120eae32dcSDimitry Andric char llvm::ResolverError::ID;
413