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