xref: /freebsd/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===- DWARFDebugLoc.h ------------------------------------------*- C++ -*-===//
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 #ifndef LLVM_DEBUGINFO_DWARF_DWARFDEBUGLOC_H
10 #define LLVM_DEBUGINFO_DWARF_DWARFDEBUGLOC_H
11 
12 #include "llvm/ADT/SmallVector.h"
13 #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
14 #include "llvm/Support/Compiler.h"
15 #include "llvm/Support/Errc.h"
16 #include <cstdint>
17 
18 namespace llvm {
19 class DWARFUnit;
20 class MCRegisterInfo;
21 class raw_ostream;
22 class DWARFObject;
23 struct DIDumpOptions;
24 struct DWARFLocationExpression;
25 namespace object {
26 struct SectionedAddress;
27 }
28 
29 /// A single location within a location list. Entries are stored in the DWARF5
30 /// form even if they originally come from a DWARF<=4 location list.
31 struct DWARFLocationEntry {
32   /// The entry kind (DW_LLE_***).
33   uint8_t Kind;
34 
35   /// The first value of the location entry (if applicable).
36   uint64_t Value0;
37 
38   /// The second value of the location entry (if applicable).
39   uint64_t Value1;
40 
41   /// The index of the section this entry is relative to (if applicable).
42   uint64_t SectionIndex;
43 
44   /// The location expression itself (if applicable).
45   SmallVector<uint8_t, 4> Loc;
46 };
47 
48 /// An abstract base class for various kinds of location tables (.debug_loc,
49 /// .debug_loclists, and their dwo variants).
50 class DWARFLocationTable {
51 public:
DWARFLocationTable(DWARFDataExtractor Data)52   DWARFLocationTable(DWARFDataExtractor Data) : Data(std::move(Data)) {}
53   virtual ~DWARFLocationTable() = default;
54 
55   /// Call the user-provided callback for each entry (including the end-of-list
56   /// entry) in the location list starting at \p Offset. The callback can return
57   /// false to terminate the iteration early. Returns an error if it was unable
58   /// to parse the entire location list correctly. Upon successful termination
59   /// \p Offset will be updated point past the end of the list.
60   virtual Error visitLocationList(
61       uint64_t *Offset,
62       function_ref<bool(const DWARFLocationEntry &)> Callback) const = 0;
63 
64   /// Dump the location list at the given \p Offset. The function returns true
65   /// iff it has successfully reched the end of the list. This means that one
66   /// can attempt to parse another list after the current one (\p Offset will be
67   /// updated to point past the end of the current list).
68   LLVM_ABI bool
69   dumpLocationList(uint64_t *Offset, raw_ostream &OS,
70                    std::optional<object::SectionedAddress> BaseAddr,
71                    const DWARFObject &Obj, DWARFUnit *U, DIDumpOptions DumpOpts,
72                    unsigned Indent) const;
73 
74   LLVM_ABI Error visitAbsoluteLocationList(
75       uint64_t Offset, std::optional<object::SectionedAddress> BaseAddr,
76       std::function<std::optional<object::SectionedAddress>(uint32_t)>
77           LookupAddr,
78       function_ref<bool(Expected<DWARFLocationExpression>)> Callback) const;
79 
getData()80   const DWARFDataExtractor &getData() { return Data; }
81 
82 protected:
83   DWARFDataExtractor Data;
84 
85   virtual void dumpRawEntry(const DWARFLocationEntry &Entry, raw_ostream &OS,
86                             unsigned Indent, DIDumpOptions DumpOpts,
87                             const DWARFObject &Obj) const = 0;
88 };
89 
90 class LLVM_ABI DWARFDebugLoc final : public DWARFLocationTable {
91 public:
92   /// A list of locations that contain one variable.
93   struct LocationList {
94     /// The beginning offset where this location list is stored in the debug_loc
95     /// section.
96     uint64_t Offset;
97     /// All the locations in which the variable is stored.
98     SmallVector<DWARFLocationEntry, 2> Entries;
99   };
100 
101 private:
102   using LocationLists = SmallVector<LocationList, 4>;
103 
104   /// A list of all the variables in the debug_loc section, each one describing
105   /// the locations in which the variable is stored.
106   LocationLists Locations;
107 
108 public:
DWARFDebugLoc(DWARFDataExtractor Data)109   DWARFDebugLoc(DWARFDataExtractor Data)
110       : DWARFLocationTable(std::move(Data)) {}
111 
112   /// Print the location lists found within the debug_loc section.
113   void dump(raw_ostream &OS, const DWARFObject &Obj, DIDumpOptions DumpOpts,
114             std::optional<uint64_t> Offset) const;
115 
116   Error visitLocationList(
117       uint64_t *Offset,
118       function_ref<bool(const DWARFLocationEntry &)> Callback) const override;
119 
120 protected:
121   void dumpRawEntry(const DWARFLocationEntry &Entry, raw_ostream &OS,
122                     unsigned Indent, DIDumpOptions DumpOpts,
123                     const DWARFObject &Obj) const override;
124 };
125 
126 class LLVM_ABI DWARFDebugLoclists final : public DWARFLocationTable {
127 public:
DWARFDebugLoclists(DWARFDataExtractor Data,uint16_t Version)128   DWARFDebugLoclists(DWARFDataExtractor Data, uint16_t Version)
129       : DWARFLocationTable(std::move(Data)), Version(Version) {}
130 
131   Error visitLocationList(
132       uint64_t *Offset,
133       function_ref<bool(const DWARFLocationEntry &)> Callback) const override;
134 
135   /// Dump all location lists within the given range.
136   void dumpRange(uint64_t StartOffset, uint64_t Size, raw_ostream &OS,
137                  const DWARFObject &Obj, DIDumpOptions DumpOpts);
138 
139 protected:
140   void dumpRawEntry(const DWARFLocationEntry &Entry, raw_ostream &OS,
141                     unsigned Indent, DIDumpOptions DumpOpts,
142                     const DWARFObject &Obj) const override;
143 
144 private:
145   uint16_t Version;
146 };
147 
148 class LLVM_ABI ResolverError : public ErrorInfo<ResolverError> {
149 public:
150   static char ID;
151 
ResolverError(uint32_t Index,dwarf::LoclistEntries Kind)152   ResolverError(uint32_t Index, dwarf::LoclistEntries Kind) : Index(Index), Kind(Kind) {}
153 
154   void log(raw_ostream &OS) const override;
convertToErrorCode()155   std::error_code convertToErrorCode() const override {
156     return llvm::errc::invalid_argument;
157   }
158 
159 private:
160   uint32_t Index;
161   dwarf::LoclistEntries Kind;
162 };
163 
164 } // end namespace llvm
165 
166 #endif // LLVM_DEBUGINFO_DWARF_DWARFDEBUGLOC_H
167