Line data Source code
1 : //===- DWARFVerifier.h ----------------------------------------------------===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 :
10 : #ifndef LLVM_DEBUGINFO_DWARF_DWARFVERIFIER_H
11 : #define LLVM_DEBUGINFO_DWARF_DWARFVERIFIER_H
12 :
13 : #include "llvm/DebugInfo/DIContext.h"
14 : #include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
15 : #include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"
16 : #include "llvm/DebugInfo/DWARF/DWARFDie.h"
17 : #include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
18 :
19 : #include <cstdint>
20 : #include <map>
21 : #include <set>
22 :
23 : namespace llvm {
24 : class raw_ostream;
25 : struct DWARFAttribute;
26 : class DWARFContext;
27 : class DWARFDie;
28 : class DWARFUnit;
29 : class DWARFCompileUnit;
30 : class DWARFDataExtractor;
31 : class DWARFDebugAbbrev;
32 : class DataExtractor;
33 : struct DWARFSection;
34 :
35 : /// A class that verifies DWARF debug information given a DWARF Context.
36 : class DWARFVerifier {
37 : public:
38 : /// A class that keeps the address range information for a single DIE.
39 0 : struct DieRangeInfo {
40 : DWARFDie Die;
41 :
42 : /// Sorted DWARFAddressRanges.
43 : std::vector<DWARFAddressRange> Ranges;
44 :
45 : /// Sorted DWARFAddressRangeInfo.
46 : std::set<DieRangeInfo> Children;
47 :
48 : DieRangeInfo() = default;
49 526 : DieRangeInfo(DWARFDie Die) : Die(Die) {}
50 :
51 : /// Used for unit testing.
52 : DieRangeInfo(std::vector<DWARFAddressRange> Ranges)
53 : : Ranges(std::move(Ranges)) {}
54 :
55 : typedef std::vector<DWARFAddressRange>::const_iterator
56 : address_range_iterator;
57 : typedef std::set<DieRangeInfo>::const_iterator die_range_info_iterator;
58 :
59 : /// Inserts the address range. If the range overlaps with an existing
60 : /// range, the range is *not* added and an iterator to the overlapping
61 : /// range is returned.
62 : ///
63 : /// This is used for finding overlapping ranges within the same DIE.
64 : address_range_iterator insert(const DWARFAddressRange &R);
65 :
66 : /// Finds an address range in the sorted vector of ranges.
67 344 : address_range_iterator findRange(const DWARFAddressRange &R) const {
68 344 : auto Begin = Ranges.begin();
69 344 : auto End = Ranges.end();
70 344 : auto Iter = std::upper_bound(Begin, End, R);
71 344 : if (Iter != Begin)
72 : --Iter;
73 344 : return Iter;
74 : }
75 :
76 : /// Inserts the address range info. If any of its ranges overlaps with a
77 : /// range in an existing range info, the range info is *not* added and an
78 : /// iterator to the overlapping range info.
79 : ///
80 : /// This is used for finding overlapping children of the same DIE.
81 : die_range_info_iterator insert(const DieRangeInfo &RI);
82 :
83 : /// Return true if ranges in this object contains all ranges within RHS.
84 : bool contains(const DieRangeInfo &RHS) const;
85 :
86 : /// Return true if any range in this object intersects with any range in
87 : /// RHS.
88 : bool intersects(const DieRangeInfo &RHS) const;
89 : };
90 :
91 : private:
92 : raw_ostream &OS;
93 : DWARFContext &DCtx;
94 : DIDumpOptions DumpOpts;
95 : /// A map that tracks all references (converted absolute references) so we
96 : /// can verify each reference points to a valid DIE and not an offset that
97 : /// lies between to valid DIEs.
98 : std::map<uint64_t, std::set<uint32_t>> ReferenceToDIEOffsets;
99 : uint32_t NumDebugLineErrors = 0;
100 :
101 : raw_ostream &error() const;
102 : raw_ostream &warn() const;
103 : raw_ostream ¬e() const;
104 : raw_ostream &dump(const DWARFDie &Die, unsigned indent = 0) const;
105 :
106 : /// Verifies the abbreviations section.
107 : ///
108 : /// This function currently checks that:
109 : /// --No abbreviation declaration has more than one attributes with the same
110 : /// name.
111 : ///
112 : /// \param Abbrev Pointer to the abbreviations section we are verifying
113 : /// Abbrev can be a pointer to either .debug_abbrev or debug_abbrev.dwo.
114 : ///
115 : /// \returns The number of errors that occurred during verification.
116 : unsigned verifyAbbrevSection(const DWARFDebugAbbrev *Abbrev);
117 :
118 : /// Verifies the header of a unit in a .debug_info or .debug_types section.
119 : ///
120 : /// This function currently checks for:
121 : /// - Unit is in 32-bit DWARF format. The function can be modified to
122 : /// support 64-bit format.
123 : /// - The DWARF version is valid
124 : /// - The unit type is valid (if unit is in version >=5)
125 : /// - The unit doesn't extend beyond the containing section
126 : /// - The address size is valid
127 : /// - The offset in the .debug_abbrev section is valid
128 : ///
129 : /// \param DebugInfoData The section data
130 : /// \param Offset A reference to the offset start of the unit. The offset will
131 : /// be updated to point to the next unit in the section
132 : /// \param UnitIndex The index of the unit to be verified
133 : /// \param UnitType A reference to the type of the unit
134 : /// \param isUnitDWARF64 A reference to a flag that shows whether the unit is
135 : /// in 64-bit format.
136 : ///
137 : /// \returns true if the header is verified successfully, false otherwise.
138 : bool verifyUnitHeader(const DWARFDataExtractor DebugInfoData,
139 : uint32_t *Offset, unsigned UnitIndex, uint8_t &UnitType,
140 : bool &isUnitDWARF64);
141 :
142 : /// Verifies the header of a unit in a .debug_info or .debug_types section.
143 : ///
144 : /// This function currently verifies:
145 : /// - The debug info attributes.
146 : /// - The debug info form=s.
147 : /// - The presence of a root DIE.
148 : /// - That the root DIE is a unit DIE.
149 : /// - If a unit type is provided, that the unit DIE matches the unit type.
150 : /// - The DIE ranges.
151 : /// - That call site entries are only nested within subprograms with a
152 : /// DW_AT_call attribute.
153 : ///
154 : /// \param Unit The DWARF Unit to verify.
155 : ///
156 : /// \returns The number of errors that occurred during verification.
157 : unsigned verifyUnitContents(DWARFUnit &Unit);
158 :
159 : /// Verifies the unit headers and contents in a .debug_info or .debug_types
160 : /// section.
161 : ///
162 : /// \param S The DWARF Section to verify.
163 : /// \param SectionKind The object-file section kind that S comes from.
164 : ///
165 : /// \returns The number of errors that occurred during verification.
166 : unsigned verifyUnitSection(const DWARFSection &S,
167 : DWARFSectionKind SectionKind);
168 :
169 : /// Verifies that a call site entry is nested within a subprogram with a
170 : /// DW_AT_call attribute.
171 : ///
172 : /// \returns Number of errors that occurred during verification.
173 : unsigned verifyDebugInfoCallSite(const DWARFDie &Die);
174 :
175 : /// Verify that all Die ranges are valid.
176 : ///
177 : /// This function currently checks for:
178 : /// - cases in which lowPC >= highPC
179 : ///
180 : /// \returns Number of errors that occurred during verification.
181 : unsigned verifyDieRanges(const DWARFDie &Die, DieRangeInfo &ParentRI);
182 :
183 : /// Verifies the attribute's DWARF attribute and its value.
184 : ///
185 : /// This function currently checks for:
186 : /// - DW_AT_ranges values is a valid .debug_ranges offset
187 : /// - DW_AT_stmt_list is a valid .debug_line offset
188 : ///
189 : /// \param Die The DWARF DIE that owns the attribute value
190 : /// \param AttrValue The DWARF attribute value to check
191 : ///
192 : /// \returns NumErrors The number of errors occurred during verification of
193 : /// attributes' values in a unit
194 : unsigned verifyDebugInfoAttribute(const DWARFDie &Die,
195 : DWARFAttribute &AttrValue);
196 :
197 : /// Verifies the attribute's DWARF form.
198 : ///
199 : /// This function currently checks for:
200 : /// - All DW_FORM_ref values that are CU relative have valid CU offsets
201 : /// - All DW_FORM_ref_addr values have valid section offsets
202 : /// - All DW_FORM_strp values have valid .debug_str offsets
203 : ///
204 : /// \param Die The DWARF DIE that owns the attribute value
205 : /// \param AttrValue The DWARF attribute value to check
206 : ///
207 : /// \returns NumErrors The number of errors occurred during verification of
208 : /// attributes' forms in a unit
209 : unsigned verifyDebugInfoForm(const DWARFDie &Die, DWARFAttribute &AttrValue);
210 :
211 : /// Verifies the all valid references that were found when iterating through
212 : /// all of the DIE attributes.
213 : ///
214 : /// This function will verify that all references point to DIEs whose DIE
215 : /// offset matches. This helps to ensure if a DWARF link phase moved things
216 : /// around, that it doesn't create invalid references by failing to relocate
217 : /// CU relative and absolute references.
218 : ///
219 : /// \returns NumErrors The number of errors occurred during verification of
220 : /// references for the .debug_info and .debug_types sections
221 : unsigned verifyDebugInfoReferences();
222 :
223 : /// Verify the DW_AT_stmt_list encoding and value and ensure that no
224 : /// compile units that have the same DW_AT_stmt_list value.
225 : void verifyDebugLineStmtOffsets();
226 :
227 : /// Verify that all of the rows in the line table are valid.
228 : ///
229 : /// This function currently checks for:
230 : /// - addresses within a sequence that decrease in value
231 : /// - invalid file indexes
232 : void verifyDebugLineRows();
233 :
234 : /// Verify that an Apple-style accelerator table is valid.
235 : ///
236 : /// This function currently checks that:
237 : /// - The fixed part of the header fits in the section
238 : /// - The size of the section is as large as what the header describes
239 : /// - There is at least one atom
240 : /// - The form for each atom is valid
241 : /// - The tag for each DIE in the table is valid
242 : /// - The buckets have a valid index, or they are empty
243 : /// - Each hashdata offset is valid
244 : /// - Each DIE is valid
245 : ///
246 : /// \param AccelSection pointer to the section containing the acceleration table
247 : /// \param StrData pointer to the string section
248 : /// \param SectionName the name of the table we're verifying
249 : ///
250 : /// \returns The number of errors occurred during verification
251 : unsigned verifyAppleAccelTable(const DWARFSection *AccelSection,
252 : DataExtractor *StrData,
253 : const char *SectionName);
254 :
255 : unsigned verifyDebugNamesCULists(const DWARFDebugNames &AccelTable);
256 : unsigned verifyNameIndexBuckets(const DWARFDebugNames::NameIndex &NI,
257 : const DataExtractor &StrData);
258 : unsigned verifyNameIndexAbbrevs(const DWARFDebugNames::NameIndex &NI);
259 : unsigned verifyNameIndexAttribute(const DWARFDebugNames::NameIndex &NI,
260 : const DWARFDebugNames::Abbrev &Abbr,
261 : DWARFDebugNames::AttributeEncoding AttrEnc);
262 : unsigned verifyNameIndexEntries(const DWARFDebugNames::NameIndex &NI,
263 : const DWARFDebugNames::NameTableEntry &NTE);
264 : unsigned verifyNameIndexCompleteness(const DWARFDie &Die,
265 : const DWARFDebugNames::NameIndex &NI);
266 :
267 : /// Verify that the DWARF v5 accelerator table is valid.
268 : ///
269 : /// This function currently checks that:
270 : /// - Headers individual Name Indices fit into the section and can be parsed.
271 : /// - Abbreviation tables can be parsed and contain valid index attributes
272 : /// with correct form encodings.
273 : /// - The CU lists reference existing compile units.
274 : /// - The buckets have a valid index, or they are empty.
275 : /// - All names are reachable via the hash table (they have the correct hash,
276 : /// and the hash is in the correct bucket).
277 : /// - Information in the index entries is complete (all required entries are
278 : /// present) and consistent with the debug_info section DIEs.
279 : ///
280 : /// \param AccelSection section containing the acceleration table
281 : /// \param StrData string section
282 : ///
283 : /// \returns The number of errors occurred during verification
284 : unsigned verifyDebugNames(const DWARFSection &AccelSection,
285 : const DataExtractor &StrData);
286 :
287 : public:
288 : DWARFVerifier(raw_ostream &S, DWARFContext &D,
289 : DIDumpOptions DumpOpts = DIDumpOptions::getForSingleDIE())
290 150 : : OS(S), DCtx(D), DumpOpts(std::move(DumpOpts)) {}
291 : /// Verify the information in any of the following sections, if available:
292 : /// .debug_abbrev, debug_abbrev.dwo
293 : ///
294 : /// Any errors are reported to the stream that was this object was
295 : /// constructed with.
296 : ///
297 : /// \returns true if .debug_abbrev and .debug_abbrev.dwo verify successfully,
298 : /// false otherwise.
299 : bool handleDebugAbbrev();
300 :
301 : /// Verify the information in the .debug_info and .debug_types sections.
302 : ///
303 : /// Any errors are reported to the stream that this object was
304 : /// constructed with.
305 : ///
306 : /// \returns true if all sections verify successfully, false otherwise.
307 : bool handleDebugInfo();
308 :
309 : /// Verify the information in the .debug_line section.
310 : ///
311 : /// Any errors are reported to the stream that was this object was
312 : /// constructed with.
313 : ///
314 : /// \returns true if the .debug_line verifies successfully, false otherwise.
315 : bool handleDebugLine();
316 :
317 : /// Verify the information in accelerator tables, if they exist.
318 : ///
319 : /// Any errors are reported to the stream that was this object was
320 : /// constructed with.
321 : ///
322 : /// \returns true if the existing Apple-style accelerator tables verify
323 : /// successfully, false otherwise.
324 : bool handleAccelTables();
325 : };
326 :
327 : static inline bool operator<(const DWARFVerifier::DieRangeInfo &LHS,
328 : const DWARFVerifier::DieRangeInfo &RHS) {
329 2546 : return std::tie(LHS.Ranges, LHS.Die) < std::tie(RHS.Ranges, RHS.Die);
330 : }
331 :
332 : } // end namespace llvm
333 :
334 : #endif // LLVM_DEBUGINFO_DWARF_DWARFCONTEXT_H
|