128db7e65SEugene Zelenko //===- DWARFDebugLoc.cpp --------------------------------------------------===//
282af9438SZachary Turner //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
682af9438SZachary Turner //
782af9438SZachary Turner //===----------------------------------------------------------------------===//
882af9438SZachary Turner
96bda14b3SChandler Carruth #include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
1028db7e65SEugene Zelenko #include "llvm/ADT/StringRef.h"
11264b5d9eSZachary Turner #include "llvm/BinaryFormat/Dwarf.h"
12*290e4823Sserge-sans-paille #include "llvm/DebugInfo/DIContext.h"
13*290e4823Sserge-sans-paille #include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"
14a058736cSReid Kleckner #include "llvm/DebugInfo/DWARF/DWARFExpression.h"
15*290e4823Sserge-sans-paille #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
16*290e4823Sserge-sans-paille #include "llvm/DebugInfo/DWARF/DWARFLocationExpression.h"
17a058736cSReid Kleckner #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
1882af9438SZachary Turner #include "llvm/Support/Format.h"
1982af9438SZachary Turner #include "llvm/Support/raw_ostream.h"
2028db7e65SEugene Zelenko #include <algorithm>
2128db7e65SEugene Zelenko #include <cinttypes>
2228db7e65SEugene Zelenko #include <cstdint>
2382af9438SZachary Turner
2482af9438SZachary Turner using namespace llvm;
25ebe2f560SPavel Labath using object::SectionedAddress;
26ebe2f560SPavel Labath
27*290e4823Sserge-sans-paille namespace llvm {
28*290e4823Sserge-sans-paille class DWARFObject;
29*290e4823Sserge-sans-paille }
30*290e4823Sserge-sans-paille
31ebe2f560SPavel Labath namespace {
32ebe2f560SPavel Labath class DWARFLocationInterpreter {
33ebe2f560SPavel Labath Optional<object::SectionedAddress> Base;
34ebe2f560SPavel Labath std::function<Optional<object::SectionedAddress>(uint32_t)> LookupAddr;
35ebe2f560SPavel Labath
36ebe2f560SPavel Labath public:
DWARFLocationInterpreter(Optional<object::SectionedAddress> Base,std::function<Optional<object::SectionedAddress> (uint32_t)> LookupAddr)37ebe2f560SPavel Labath DWARFLocationInterpreter(
38ebe2f560SPavel Labath Optional<object::SectionedAddress> Base,
39ebe2f560SPavel Labath std::function<Optional<object::SectionedAddress>(uint32_t)> LookupAddr)
40ebe2f560SPavel Labath : Base(Base), LookupAddr(std::move(LookupAddr)) {}
41ebe2f560SPavel Labath
42ebe2f560SPavel Labath Expected<Optional<DWARFLocationExpression>>
43ebe2f560SPavel Labath Interpret(const DWARFLocationEntry &E);
44ebe2f560SPavel Labath };
45ebe2f560SPavel Labath } // namespace
46ebe2f560SPavel Labath
createResolverError(uint32_t Index,unsigned Kind)47ebe2f560SPavel Labath static Error createResolverError(uint32_t Index, unsigned Kind) {
484f60a428SDavid Blaikie return make_error<ResolverError>(Index, (dwarf::LoclistEntries)Kind);
49ebe2f560SPavel Labath }
50ebe2f560SPavel Labath
51ebe2f560SPavel Labath Expected<Optional<DWARFLocationExpression>>
Interpret(const DWARFLocationEntry & E)52ebe2f560SPavel Labath DWARFLocationInterpreter::Interpret(const DWARFLocationEntry &E) {
53ebe2f560SPavel Labath switch (E.Kind) {
54ebe2f560SPavel Labath case dwarf::DW_LLE_end_of_list:
55ebe2f560SPavel Labath return None;
56ebe2f560SPavel Labath case dwarf::DW_LLE_base_addressx: {
57ebe2f560SPavel Labath Base = LookupAddr(E.Value0);
58ebe2f560SPavel Labath if (!Base)
59ebe2f560SPavel Labath return createResolverError(E.Value0, E.Kind);
60ebe2f560SPavel Labath return None;
61ebe2f560SPavel Labath }
62a3af3ac3SPavel Labath case dwarf::DW_LLE_startx_endx: {
63a3af3ac3SPavel Labath Optional<SectionedAddress> LowPC = LookupAddr(E.Value0);
64a3af3ac3SPavel Labath if (!LowPC)
65a3af3ac3SPavel Labath return createResolverError(E.Value0, E.Kind);
66a3af3ac3SPavel Labath Optional<SectionedAddress> HighPC = LookupAddr(E.Value1);
67a3af3ac3SPavel Labath if (!HighPC)
68a3af3ac3SPavel Labath return createResolverError(E.Value1, E.Kind);
69a3af3ac3SPavel Labath return DWARFLocationExpression{
70a3af3ac3SPavel Labath DWARFAddressRange{LowPC->Address, HighPC->Address, LowPC->SectionIndex},
71a3af3ac3SPavel Labath E.Loc};
72a3af3ac3SPavel Labath }
73ebe2f560SPavel Labath case dwarf::DW_LLE_startx_length: {
74ebe2f560SPavel Labath Optional<SectionedAddress> LowPC = LookupAddr(E.Value0);
75ebe2f560SPavel Labath if (!LowPC)
76ebe2f560SPavel Labath return createResolverError(E.Value0, E.Kind);
77ebe2f560SPavel Labath return DWARFLocationExpression{DWARFAddressRange{LowPC->Address,
78ebe2f560SPavel Labath LowPC->Address + E.Value1,
79ebe2f560SPavel Labath LowPC->SectionIndex},
80ebe2f560SPavel Labath E.Loc};
81ebe2f560SPavel Labath }
821fbe8a82SPavel Labath case dwarf::DW_LLE_offset_pair: {
83ebe2f560SPavel Labath if (!Base) {
840541a9d4SPavel Labath return createStringError(inconvertibleErrorCode(),
850541a9d4SPavel Labath "Unable to resolve location list offset pair: "
860541a9d4SPavel Labath "Base address not defined");
87ebe2f560SPavel Labath }
881fbe8a82SPavel Labath DWARFAddressRange Range{Base->Address + E.Value0, Base->Address + E.Value1,
891fbe8a82SPavel Labath Base->SectionIndex};
901fbe8a82SPavel Labath if (Range.SectionIndex == SectionedAddress::UndefSection)
911fbe8a82SPavel Labath Range.SectionIndex = E.SectionIndex;
921fbe8a82SPavel Labath return DWARFLocationExpression{Range, E.Loc};
931fbe8a82SPavel Labath }
94a3af3ac3SPavel Labath case dwarf::DW_LLE_default_location:
95a3af3ac3SPavel Labath return DWARFLocationExpression{None, E.Loc};
96ebe2f560SPavel Labath case dwarf::DW_LLE_base_address:
971fbe8a82SPavel Labath Base = SectionedAddress{E.Value0, E.SectionIndex};
98ebe2f560SPavel Labath return None;
99a3af3ac3SPavel Labath case dwarf::DW_LLE_start_end:
100a3af3ac3SPavel Labath return DWARFLocationExpression{
101a3af3ac3SPavel Labath DWARFAddressRange{E.Value0, E.Value1, E.SectionIndex}, E.Loc};
102ebe2f560SPavel Labath case dwarf::DW_LLE_start_length:
103ebe2f560SPavel Labath return DWARFLocationExpression{
1041fbe8a82SPavel Labath DWARFAddressRange{E.Value0, E.Value0 + E.Value1, E.SectionIndex},
105ebe2f560SPavel Labath E.Loc};
106ebe2f560SPavel Labath default:
107ebe2f560SPavel Labath llvm_unreachable("unreachable locations list kind");
108ebe2f560SPavel Labath }
109ebe2f560SPavel Labath }
11082af9438SZachary Turner
dumpExpression(raw_ostream & OS,DIDumpOptions DumpOpts,ArrayRef<uint8_t> Data,bool IsLittleEndian,unsigned AddressSize,const MCRegisterInfo * MRI,DWARFUnit * U)1110ec5baa1SDavid Blaikie static void dumpExpression(raw_ostream &OS, DIDumpOptions DumpOpts,
1120ec5baa1SDavid Blaikie ArrayRef<uint8_t> Data, bool IsLittleEndian,
1130ec5baa1SDavid Blaikie unsigned AddressSize, const MCRegisterInfo *MRI,
1140ec5baa1SDavid Blaikie DWARFUnit *U) {
115512c03baSFangrui Song DWARFDataExtractor Extractor(Data, IsLittleEndian, AddressSize);
116befbc99aSFangrui Song // Note. We do not pass any format to DWARFExpression, even if the
117befbc99aSFangrui Song // corresponding unit is known. For now, there is only one operation,
118befbc99aSFangrui Song // DW_OP_call_ref, which depends on the format; it is rarely used, and
119befbc99aSFangrui Song // is unexpected in location tables.
1200ec5baa1SDavid Blaikie DWARFExpression(Extractor, AddressSize).print(OS, DumpOpts, MRI, U);
121a058736cSReid Kleckner }
122a058736cSReid Kleckner
dumpLocationList(uint64_t * Offset,raw_ostream & OS,Optional<SectionedAddress> BaseAddr,const MCRegisterInfo * MRI,const DWARFObject & Obj,DWARFUnit * U,DIDumpOptions DumpOpts,unsigned Indent) const123ebe2f560SPavel Labath bool DWARFLocationTable::dumpLocationList(uint64_t *Offset, raw_ostream &OS,
124eafe0cf5SPavel Labath Optional<SectionedAddress> BaseAddr,
125ebe2f560SPavel Labath const MCRegisterInfo *MRI,
1261fbe8a82SPavel Labath const DWARFObject &Obj, DWARFUnit *U,
1271fbe8a82SPavel Labath DIDumpOptions DumpOpts,
128ebe2f560SPavel Labath unsigned Indent) const {
129ebe2f560SPavel Labath DWARFLocationInterpreter Interp(
130eafe0cf5SPavel Labath BaseAddr, [U](uint32_t Index) -> Optional<SectionedAddress> {
131ebe2f560SPavel Labath if (U)
132ebe2f560SPavel Labath return U->getAddrOffsetSectionItem(Index);
133ebe2f560SPavel Labath return None;
134ebe2f560SPavel Labath });
135ebe2f560SPavel Labath OS << format("0x%8.8" PRIx64 ": ", *Offset);
136ebe2f560SPavel Labath Error E = visitLocationList(Offset, [&](const DWARFLocationEntry &E) {
137ebe2f560SPavel Labath Expected<Optional<DWARFLocationExpression>> Loc = Interp.Interpret(E);
138dca2b36bSPavel Labath if (!Loc || DumpOpts.DisplayRawContents)
1391fbe8a82SPavel Labath dumpRawEntry(E, OS, Indent, DumpOpts, Obj);
140ebe2f560SPavel Labath if (Loc && *Loc) {
141ebe2f560SPavel Labath OS << "\n";
142ebe2f560SPavel Labath OS.indent(Indent);
143dca2b36bSPavel Labath if (DumpOpts.DisplayRawContents)
144ebe2f560SPavel Labath OS << " => ";
145dca2b36bSPavel Labath
146dca2b36bSPavel Labath DIDumpOptions RangeDumpOpts(DumpOpts);
147dca2b36bSPavel Labath RangeDumpOpts.DisplayRawContents = false;
148a3af3ac3SPavel Labath if (Loc.get()->Range)
1491fbe8a82SPavel Labath Loc.get()->Range->dump(OS, Data.getAddressSize(), RangeDumpOpts, &Obj);
150a3af3ac3SPavel Labath else
151a3af3ac3SPavel Labath OS << "<default>";
152ebe2f560SPavel Labath }
153ebe2f560SPavel Labath if (!Loc)
154ebe2f560SPavel Labath consumeError(Loc.takeError());
155ebe2f560SPavel Labath
156ebe2f560SPavel Labath if (E.Kind != dwarf::DW_LLE_base_address &&
157ebe2f560SPavel Labath E.Kind != dwarf::DW_LLE_base_addressx &&
158ebe2f560SPavel Labath E.Kind != dwarf::DW_LLE_end_of_list) {
159ebe2f560SPavel Labath OS << ": ";
1600ec5baa1SDavid Blaikie dumpExpression(OS, DumpOpts, E.Loc, Data.isLittleEndian(),
1610ec5baa1SDavid Blaikie Data.getAddressSize(), MRI, U);
162ebe2f560SPavel Labath }
163ebe2f560SPavel Labath return true;
164ebe2f560SPavel Labath });
165ebe2f560SPavel Labath if (E) {
166208a11abSDavid Blaikie DumpOpts.RecoverableErrorHandler(std::move(E));
167ebe2f560SPavel Labath return false;
168ebe2f560SPavel Labath }
169ebe2f560SPavel Labath return true;
170ebe2f560SPavel Labath }
171ebe2f560SPavel Labath
visitAbsoluteLocationList(uint64_t Offset,Optional<SectionedAddress> BaseAddr,std::function<Optional<SectionedAddress> (uint32_t)> LookupAddr,function_ref<bool (Expected<DWARFLocationExpression>)> Callback) const172a03435ecSPavel Labath Error DWARFLocationTable::visitAbsoluteLocationList(
173a03435ecSPavel Labath uint64_t Offset, Optional<SectionedAddress> BaseAddr,
174a03435ecSPavel Labath std::function<Optional<SectionedAddress>(uint32_t)> LookupAddr,
175a03435ecSPavel Labath function_ref<bool(Expected<DWARFLocationExpression>)> Callback) const {
176a03435ecSPavel Labath DWARFLocationInterpreter Interp(BaseAddr, std::move(LookupAddr));
177a03435ecSPavel Labath return visitLocationList(&Offset, [&](const DWARFLocationEntry &E) {
178a03435ecSPavel Labath Expected<Optional<DWARFLocationExpression>> Loc = Interp.Interpret(E);
179a03435ecSPavel Labath if (!Loc)
180a03435ecSPavel Labath return Callback(Loc.takeError());
181a03435ecSPavel Labath if (*Loc)
182a03435ecSPavel Labath return Callback(**Loc);
183a03435ecSPavel Labath return true;
184a03435ecSPavel Labath });
185a03435ecSPavel Labath }
186a03435ecSPavel Labath
dump(raw_ostream & OS,const MCRegisterInfo * MRI,const DWARFObject & Obj,DIDumpOptions DumpOpts,Optional<uint64_t> DumpOffset) const18709080939SPavel Labath void DWARFDebugLoc::dump(raw_ostream &OS, const MCRegisterInfo *MRI,
1881fbe8a82SPavel Labath const DWARFObject &Obj, DIDumpOptions DumpOpts,
18909080939SPavel Labath Optional<uint64_t> DumpOffset) const {
19009080939SPavel Labath auto BaseAddr = None;
19109080939SPavel Labath unsigned Indent = 12;
19209080939SPavel Labath if (DumpOffset) {
1931fbe8a82SPavel Labath dumpLocationList(&*DumpOffset, OS, BaseAddr, MRI, Obj, nullptr, DumpOpts,
19409080939SPavel Labath Indent);
19509080939SPavel Labath } else {
19609080939SPavel Labath uint64_t Offset = 0;
19709080939SPavel Labath StringRef Separator;
19809080939SPavel Labath bool CanContinue = true;
19909080939SPavel Labath while (CanContinue && Data.isValidOffset(Offset)) {
20009080939SPavel Labath OS << Separator;
20109080939SPavel Labath Separator = "\n";
202622c563bSJonas Devlieghere
2031fbe8a82SPavel Labath CanContinue = dumpLocationList(&Offset, OS, BaseAddr, MRI, Obj, nullptr,
20409080939SPavel Labath DumpOpts, Indent);
205f358c3d3SDavid Blaikie OS << '\n';
206a058736cSReid Kleckner }
207a058736cSReid Kleckner }
20809080939SPavel Labath }
209a058736cSReid Kleckner
visitLocationList(uint64_t * Offset,function_ref<bool (const DWARFLocationEntry &)> Callback) const21009080939SPavel Labath Error DWARFDebugLoc::visitLocationList(
21109080939SPavel Labath uint64_t *Offset,
21209080939SPavel Labath function_ref<bool(const DWARFLocationEntry &)> Callback) const {
213bd546e59SPavel Labath DataExtractor::Cursor C(*Offset);
21482af9438SZachary Turner while (true) {
2151fbe8a82SPavel Labath uint64_t SectionIndex;
21609080939SPavel Labath uint64_t Value0 = Data.getRelocatedAddress(C);
2171fbe8a82SPavel Labath uint64_t Value1 = Data.getRelocatedAddress(C, &SectionIndex);
218a058736cSReid Kleckner
21909080939SPavel Labath DWARFLocationEntry E;
2205ca30666SDavid Blaikie
22182af9438SZachary Turner // The end of any given location list is marked by an end of list entry,
22282af9438SZachary Turner // which consists of a 0 for the beginning address offset and a 0 for the
22309080939SPavel Labath // ending address offset. A beginning offset of 0xff...f marks the base
22409080939SPavel Labath // address selection entry.
22509080939SPavel Labath if (Value0 == 0 && Value1 == 0) {
22609080939SPavel Labath E.Kind = dwarf::DW_LLE_end_of_list;
22709080939SPavel Labath } else if (Value0 == (Data.getAddressSize() == 4 ? -1U : -1ULL)) {
22809080939SPavel Labath E.Kind = dwarf::DW_LLE_base_address;
22909080939SPavel Labath E.Value0 = Value1;
2301fbe8a82SPavel Labath E.SectionIndex = SectionIndex;
23109080939SPavel Labath } else {
23209080939SPavel Labath E.Kind = dwarf::DW_LLE_offset_pair;
23309080939SPavel Labath E.Value0 = Value0;
23409080939SPavel Labath E.Value1 = Value1;
2351fbe8a82SPavel Labath E.SectionIndex = SectionIndex;
236bd546e59SPavel Labath unsigned Bytes = Data.getU16(C);
237a058736cSReid Kleckner // A single location description describing the location of the object...
238bd546e59SPavel Labath Data.getU8(C, E.Loc, Bytes);
2395ca30666SDavid Blaikie }
2405ca30666SDavid Blaikie
24109080939SPavel Labath if (!C)
24209080939SPavel Labath return C.takeError();
24309080939SPavel Labath if (!Callback(E) || E.Kind == dwarf::DW_LLE_end_of_list)
24409080939SPavel Labath break;
245a058736cSReid Kleckner }
24609080939SPavel Labath *Offset = C.tell();
24709080939SPavel Labath return Error::success();
248a058736cSReid Kleckner }
249a058736cSReid Kleckner
dumpRawEntry(const DWARFLocationEntry & Entry,raw_ostream & OS,unsigned Indent,DIDumpOptions DumpOpts,const DWARFObject & Obj) const25009080939SPavel Labath void DWARFDebugLoc::dumpRawEntry(const DWARFLocationEntry &Entry,
2511fbe8a82SPavel Labath raw_ostream &OS, unsigned Indent,
2521fbe8a82SPavel Labath DIDumpOptions DumpOpts,
2531fbe8a82SPavel Labath const DWARFObject &Obj) const {
25409080939SPavel Labath uint64_t Value0, Value1;
25509080939SPavel Labath switch (Entry.Kind) {
25609080939SPavel Labath case dwarf::DW_LLE_base_address:
25709080939SPavel Labath Value0 = Data.getAddressSize() == 4 ? -1U : -1ULL;
25809080939SPavel Labath Value1 = Entry.Value0;
25909080939SPavel Labath break;
26009080939SPavel Labath case dwarf::DW_LLE_offset_pair:
26109080939SPavel Labath Value0 = Entry.Value0;
26209080939SPavel Labath Value1 = Entry.Value1;
26309080939SPavel Labath break;
26409080939SPavel Labath case dwarf::DW_LLE_end_of_list:
26509080939SPavel Labath return;
26609080939SPavel Labath default:
26709080939SPavel Labath llvm_unreachable("Not possible in DWARF4!");
26809080939SPavel Labath }
26909080939SPavel Labath OS << '\n';
27009080939SPavel Labath OS.indent(Indent);
27109080939SPavel Labath OS << '(' << format_hex(Value0, 2 + Data.getAddressSize() * 2) << ", "
27209080939SPavel Labath << format_hex(Value1, 2 + Data.getAddressSize() * 2) << ')';
2731fbe8a82SPavel Labath DWARFFormValue::dumpAddressSection(Obj, OS, DumpOpts, Entry.SectionIndex);
27409080939SPavel Labath }
27509080939SPavel Labath
visitLocationList(uint64_t * Offset,function_ref<bool (const DWARFLocationEntry &)> F) const276e1f8c8a1SPavel Labath Error DWARFDebugLoclists::visitLocationList(
277ebe2f560SPavel Labath uint64_t *Offset, function_ref<bool(const DWARFLocationEntry &)> F) const {
27882af9438SZachary Turner
279e1f8c8a1SPavel Labath DataExtractor::Cursor C(*Offset);
280e1f8c8a1SPavel Labath bool Continue = true;
281e1f8c8a1SPavel Labath while (Continue) {
282ebe2f560SPavel Labath DWARFLocationEntry E;
283e1f8c8a1SPavel Labath E.Kind = Data.getU8(C);
284e1f8c8a1SPavel Labath switch (E.Kind) {
285e1f8c8a1SPavel Labath case dwarf::DW_LLE_end_of_list:
286e1f8c8a1SPavel Labath break;
287f358c3d3SDavid Blaikie case dwarf::DW_LLE_base_addressx:
288f358c3d3SDavid Blaikie E.Value0 = Data.getULEB128(C);
289f358c3d3SDavid Blaikie break;
290a3af3ac3SPavel Labath case dwarf::DW_LLE_startx_endx:
291a3af3ac3SPavel Labath E.Value0 = Data.getULEB128(C);
292a3af3ac3SPavel Labath E.Value1 = Data.getULEB128(C);
293a3af3ac3SPavel Labath break;
2944c7dd9cfSGeorge Rimar case dwarf::DW_LLE_startx_length:
295bd546e59SPavel Labath E.Value0 = Data.getULEB128(C);
296581fc63dSGeorge Rimar // Pre-DWARF 5 has different interpretation of the length field. We have
297581fc63dSGeorge Rimar // to support both pre- and standartized styles for the compatibility.
298581fc63dSGeorge Rimar if (Version < 5)
299bd546e59SPavel Labath E.Value1 = Data.getU32(C);
300581fc63dSGeorge Rimar else
301bd546e59SPavel Labath E.Value1 = Data.getULEB128(C);
3024c7dd9cfSGeorge Rimar break;
3034c7dd9cfSGeorge Rimar case dwarf::DW_LLE_offset_pair:
304bd546e59SPavel Labath E.Value0 = Data.getULEB128(C);
305bd546e59SPavel Labath E.Value1 = Data.getULEB128(C);
3061fbe8a82SPavel Labath E.SectionIndex = SectionedAddress::UndefSection;
3074c7dd9cfSGeorge Rimar break;
308a3af3ac3SPavel Labath case dwarf::DW_LLE_default_location:
309a3af3ac3SPavel Labath break;
3104c7dd9cfSGeorge Rimar case dwarf::DW_LLE_base_address:
3111fbe8a82SPavel Labath E.Value0 = Data.getRelocatedAddress(C, &E.SectionIndex);
3124c7dd9cfSGeorge Rimar break;
313a3af3ac3SPavel Labath case dwarf::DW_LLE_start_end:
314a3af3ac3SPavel Labath E.Value0 = Data.getRelocatedAddress(C, &E.SectionIndex);
315a3af3ac3SPavel Labath E.Value1 = Data.getRelocatedAddress(C);
316a3af3ac3SPavel Labath break;
317e1f8c8a1SPavel Labath case dwarf::DW_LLE_start_length:
3181fbe8a82SPavel Labath E.Value0 = Data.getRelocatedAddress(C, &E.SectionIndex);
319e1f8c8a1SPavel Labath E.Value1 = Data.getULEB128(C);
320e1f8c8a1SPavel Labath break;
3214c7dd9cfSGeorge Rimar default:
322bd546e59SPavel Labath cantFail(C.takeError());
323bd546e59SPavel Labath return createStringError(errc::illegal_byte_sequence,
324e1f8c8a1SPavel Labath "LLE of kind %x not supported", (int)E.Kind);
32582af9438SZachary Turner }
32682af9438SZachary Turner
327e1f8c8a1SPavel Labath if (E.Kind != dwarf::DW_LLE_base_address &&
328e1f8c8a1SPavel Labath E.Kind != dwarf::DW_LLE_base_addressx &&
329e1f8c8a1SPavel Labath E.Kind != dwarf::DW_LLE_end_of_list) {
330bd546e59SPavel Labath unsigned Bytes = Version >= 5 ? Data.getULEB128(C) : Data.getU16(C);
33182af9438SZachary Turner // A single location description describing the location of the object...
332bd546e59SPavel Labath Data.getU8(C, E.Loc, Bytes);
3332f9c42c9SDavid Blaikie }
33482af9438SZachary Turner
335e1f8c8a1SPavel Labath if (!C)
336e1f8c8a1SPavel Labath return C.takeError();
337e1f8c8a1SPavel Labath Continue = F(E) && E.Kind != dwarf::DW_LLE_end_of_list;
33882af9438SZachary Turner }
339bd546e59SPavel Labath *Offset = C.tell();
340e1f8c8a1SPavel Labath return Error::success();
341a058736cSReid Kleckner }
342a058736cSReid Kleckner
dumpRawEntry(const DWARFLocationEntry & Entry,raw_ostream & OS,unsigned Indent,DIDumpOptions DumpOpts,const DWARFObject & Obj) const343ebe2f560SPavel Labath void DWARFDebugLoclists::dumpRawEntry(const DWARFLocationEntry &Entry,
3441fbe8a82SPavel Labath raw_ostream &OS, unsigned Indent,
3451fbe8a82SPavel Labath DIDumpOptions DumpOpts,
3461fbe8a82SPavel Labath const DWARFObject &Obj) const {
347e1f8c8a1SPavel Labath size_t MaxEncodingStringLength = 0;
348e1f8c8a1SPavel Labath #define HANDLE_DW_LLE(ID, NAME) \
349e1f8c8a1SPavel Labath MaxEncodingStringLength = std::max(MaxEncodingStringLength, \
350e1f8c8a1SPavel Labath dwarf::LocListEncodingString(ID).size());
351e1f8c8a1SPavel Labath #include "llvm/BinaryFormat/Dwarf.def"
35282af9438SZachary Turner
353e1f8c8a1SPavel Labath OS << "\n";
354e1f8c8a1SPavel Labath OS.indent(Indent);
355ebe2f560SPavel Labath StringRef EncodingString = dwarf::LocListEncodingString(Entry.Kind);
356f358c3d3SDavid Blaikie // Unsupported encodings should have been reported during parsing.
357f358c3d3SDavid Blaikie assert(!EncodingString.empty() && "Unknown loclist entry encoding");
358ebe2f560SPavel Labath OS << format("%-*s(", MaxEncodingStringLength, EncodingString.data());
359ebe2f560SPavel Labath unsigned FieldSize = 2 + 2 * Data.getAddressSize();
360ebe2f560SPavel Labath switch (Entry.Kind) {
361a3af3ac3SPavel Labath case dwarf::DW_LLE_end_of_list:
362a3af3ac3SPavel Labath case dwarf::DW_LLE_default_location:
363a3af3ac3SPavel Labath break;
364a3af3ac3SPavel Labath case dwarf::DW_LLE_startx_endx:
365f358c3d3SDavid Blaikie case dwarf::DW_LLE_startx_length:
366f358c3d3SDavid Blaikie case dwarf::DW_LLE_offset_pair:
367a3af3ac3SPavel Labath case dwarf::DW_LLE_start_end:
368a3af3ac3SPavel Labath case dwarf::DW_LLE_start_length:
369ebe2f560SPavel Labath OS << format_hex(Entry.Value0, FieldSize) << ", "
370ebe2f560SPavel Labath << format_hex(Entry.Value1, FieldSize);
371f358c3d3SDavid Blaikie break;
372f358c3d3SDavid Blaikie case dwarf::DW_LLE_base_addressx:
373f358c3d3SDavid Blaikie case dwarf::DW_LLE_base_address:
374ebe2f560SPavel Labath OS << format_hex(Entry.Value0, FieldSize);
375f358c3d3SDavid Blaikie break;
376f358c3d3SDavid Blaikie }
377f358c3d3SDavid Blaikie OS << ')';
3781fbe8a82SPavel Labath switch (Entry.Kind) {
3791fbe8a82SPavel Labath case dwarf::DW_LLE_base_address:
380a3af3ac3SPavel Labath case dwarf::DW_LLE_start_end:
381a3af3ac3SPavel Labath case dwarf::DW_LLE_start_length:
3821fbe8a82SPavel Labath DWARFFormValue::dumpAddressSection(Obj, OS, DumpOpts, Entry.SectionIndex);
3831fbe8a82SPavel Labath break;
3841fbe8a82SPavel Labath default:
3851fbe8a82SPavel Labath break;
3861fbe8a82SPavel Labath }
387f358c3d3SDavid Blaikie }
3884c7dd9cfSGeorge Rimar
dumpRange(uint64_t StartOffset,uint64_t Size,raw_ostream & OS,const MCRegisterInfo * MRI,const DWARFObject & Obj,DIDumpOptions DumpOpts)389ebe2f560SPavel Labath void DWARFDebugLoclists::dumpRange(uint64_t StartOffset, uint64_t Size,
390eafe0cf5SPavel Labath raw_ostream &OS, const MCRegisterInfo *MRI,
3911fbe8a82SPavel Labath const DWARFObject &Obj,
392e1f8c8a1SPavel Labath DIDumpOptions DumpOpts) {
393e1f8c8a1SPavel Labath if (!Data.isValidOffsetForDataOfSize(StartOffset, Size)) {
394e1f8c8a1SPavel Labath OS << "Invalid dump range\n";
395622c563bSJonas Devlieghere return;
396622c563bSJonas Devlieghere }
397e1f8c8a1SPavel Labath uint64_t Offset = StartOffset;
398e1f8c8a1SPavel Labath StringRef Separator;
399e1f8c8a1SPavel Labath bool CanContinue = true;
400e1f8c8a1SPavel Labath while (CanContinue && Offset < StartOffset + Size) {
401e1f8c8a1SPavel Labath OS << Separator;
402e1f8c8a1SPavel Labath Separator = "\n";
403622c563bSJonas Devlieghere
4041fbe8a82SPavel Labath CanContinue = dumpLocationList(&Offset, OS, /*BaseAddr=*/None, MRI, Obj,
4051fbe8a82SPavel Labath nullptr, DumpOpts, /*Indent=*/12);
406f358c3d3SDavid Blaikie OS << '\n';
40782af9438SZachary Turner }
40882af9438SZachary Turner }
4094f60a428SDavid Blaikie
log(raw_ostream & OS) const4104f60a428SDavid Blaikie void llvm::ResolverError::log(raw_ostream &OS) const {
4114f60a428SDavid Blaikie OS << format("unable to resolve indirect address %u for: %s", Index,
4124f60a428SDavid Blaikie dwarf::LocListEncodingString(Kind).data());
4134f60a428SDavid Blaikie }
4144f60a428SDavid Blaikie
4154f60a428SDavid Blaikie char llvm::ResolverError::ID;
416