]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFVerifier.h
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / include / llvm / DebugInfo / DWARF / DWARFVerifier.h
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   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     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     address_range_iterator findRange(const DWARFAddressRange &R) const {
68       auto Begin = Ranges.begin();
69       auto End = Ranges.end();
70       auto Iter = std::upper_bound(Begin, End, R);
71       if (Iter != Begin)
72         --Iter;
73       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   // Used to relax some checks that do not currently work portably
101   bool IsObjectFile;
102   bool IsMachOObject;
103
104   raw_ostream &error() const;
105   raw_ostream &warn() const;
106   raw_ostream &note() const;
107   raw_ostream &dump(const DWARFDie &Die, unsigned indent = 0) const;
108
109   /// Verifies the abbreviations section.
110   ///
111   /// This function currently checks that:
112   /// --No abbreviation declaration has more than one attributes with the same
113   /// name.
114   ///
115   /// \param Abbrev Pointer to the abbreviations section we are verifying
116   /// Abbrev can be a pointer to either .debug_abbrev or debug_abbrev.dwo.
117   ///
118   /// \returns The number of errors that occurred during verification.
119   unsigned verifyAbbrevSection(const DWARFDebugAbbrev *Abbrev);
120
121   /// Verifies the header of a unit in a .debug_info or .debug_types section.
122   ///
123   /// This function currently checks for:
124   /// - Unit is in 32-bit DWARF format. The function can be modified to
125   /// support 64-bit format.
126   /// - The DWARF version is valid
127   /// - The unit type is valid (if unit is in version >=5)
128   /// - The unit doesn't extend beyond the containing section
129   /// - The address size is valid
130   /// - The offset in the .debug_abbrev section is valid
131   ///
132   /// \param DebugInfoData The section data
133   /// \param Offset A reference to the offset start of the unit. The offset will
134   /// be updated to point to the next unit in the section
135   /// \param UnitIndex The index of the unit to be verified
136   /// \param UnitType A reference to the type of the unit
137   /// \param isUnitDWARF64 A reference to a flag that shows whether the unit is
138   /// in 64-bit format.
139   ///
140   /// \returns true if the header is verified successfully, false otherwise.
141   bool verifyUnitHeader(const DWARFDataExtractor DebugInfoData,
142                         uint32_t *Offset, unsigned UnitIndex, uint8_t &UnitType,
143                         bool &isUnitDWARF64);
144
145   /// Verifies the header of a unit in a .debug_info or .debug_types section.
146   ///
147   /// This function currently verifies:
148   ///  - The debug info attributes.
149   ///  - The debug info form=s.
150   ///  - The presence of a root DIE.
151   ///  - That the root DIE is a unit DIE.
152   ///  - If a unit type is provided, that the unit DIE matches the unit type.
153   ///  - The DIE ranges.
154   ///  - That call site entries are only nested within subprograms with a
155   ///    DW_AT_call attribute.
156   ///
157   /// \param Unit      The DWARF Unit to verify.
158   ///
159   /// \returns The number of errors that occurred during verification.
160   unsigned verifyUnitContents(DWARFUnit &Unit);
161
162   /// Verifies the unit headers and contents in a .debug_info or .debug_types
163   /// section.
164   ///
165   /// \param S           The DWARF Section to verify.
166   /// \param SectionKind The object-file section kind that S comes from.
167   ///
168   /// \returns The number of errors that occurred during verification.
169   unsigned verifyUnitSection(const DWARFSection &S,
170                              DWARFSectionKind SectionKind);
171
172   /// Verifies that a call site entry is nested within a subprogram with a
173   /// DW_AT_call attribute.
174   ///
175   /// \returns Number of errors that occurred during verification.
176   unsigned verifyDebugInfoCallSite(const DWARFDie &Die);
177
178   /// Verify that all Die ranges are valid.
179   ///
180   /// This function currently checks for:
181   /// - cases in which lowPC >= highPC
182   ///
183   /// \returns Number of errors that occurred during verification.
184   unsigned verifyDieRanges(const DWARFDie &Die, DieRangeInfo &ParentRI);
185
186   /// Verifies the attribute's DWARF attribute and its value.
187   ///
188   /// This function currently checks for:
189   /// - DW_AT_ranges values is a valid .debug_ranges offset
190   /// - DW_AT_stmt_list is a valid .debug_line offset
191   ///
192   /// \param Die          The DWARF DIE that owns the attribute value
193   /// \param AttrValue    The DWARF attribute value to check
194   ///
195   /// \returns NumErrors The number of errors occurred during verification of
196   /// attributes' values in a unit
197   unsigned verifyDebugInfoAttribute(const DWARFDie &Die,
198                                     DWARFAttribute &AttrValue);
199
200   /// Verifies the attribute's DWARF form.
201   ///
202   /// This function currently checks for:
203   /// - All DW_FORM_ref values that are CU relative have valid CU offsets
204   /// - All DW_FORM_ref_addr values have valid section offsets
205   /// - All DW_FORM_strp values have valid .debug_str offsets
206   ///
207   /// \param Die          The DWARF DIE that owns the attribute value
208   /// \param AttrValue    The DWARF attribute value to check
209   ///
210   /// \returns NumErrors The number of errors occurred during verification of
211   /// attributes' forms in a unit
212   unsigned verifyDebugInfoForm(const DWARFDie &Die, DWARFAttribute &AttrValue);
213
214   /// Verifies the all valid references that were found when iterating through
215   /// all of the DIE attributes.
216   ///
217   /// This function will verify that all references point to DIEs whose DIE
218   /// offset matches. This helps to ensure if a DWARF link phase moved things
219   /// around, that it doesn't create invalid references by failing to relocate
220   /// CU relative and absolute references.
221   ///
222   /// \returns NumErrors The number of errors occurred during verification of
223   /// references for the .debug_info and .debug_types sections
224   unsigned verifyDebugInfoReferences();
225
226   /// Verify the DW_AT_stmt_list encoding and value and ensure that no
227   /// compile units that have the same DW_AT_stmt_list value.
228   void verifyDebugLineStmtOffsets();
229
230   /// Verify that all of the rows in the line table are valid.
231   ///
232   /// This function currently checks for:
233   /// - addresses within a sequence that decrease in value
234   /// - invalid file indexes
235   void verifyDebugLineRows();
236
237   /// Verify that an Apple-style accelerator table is valid.
238   ///
239   /// This function currently checks that:
240   /// - The fixed part of the header fits in the section
241   /// - The size of the section is as large as what the header describes
242   /// - There is at least one atom
243   /// - The form for each atom is valid
244   /// - The tag for each DIE in the table is valid
245   /// - The buckets have a valid index, or they are empty
246   /// - Each hashdata offset is valid
247   /// - Each DIE is valid
248   ///
249   /// \param AccelSection pointer to the section containing the acceleration table
250   /// \param StrData pointer to the string section
251   /// \param SectionName the name of the table we're verifying
252   ///
253   /// \returns The number of errors occurred during verification
254   unsigned verifyAppleAccelTable(const DWARFSection *AccelSection,
255                                  DataExtractor *StrData,
256                                  const char *SectionName);
257
258   unsigned verifyDebugNamesCULists(const DWARFDebugNames &AccelTable);
259   unsigned verifyNameIndexBuckets(const DWARFDebugNames::NameIndex &NI,
260                                   const DataExtractor &StrData);
261   unsigned verifyNameIndexAbbrevs(const DWARFDebugNames::NameIndex &NI);
262   unsigned verifyNameIndexAttribute(const DWARFDebugNames::NameIndex &NI,
263                                     const DWARFDebugNames::Abbrev &Abbr,
264                                     DWARFDebugNames::AttributeEncoding AttrEnc);
265   unsigned verifyNameIndexEntries(const DWARFDebugNames::NameIndex &NI,
266                                   const DWARFDebugNames::NameTableEntry &NTE);
267   unsigned verifyNameIndexCompleteness(const DWARFDie &Die,
268                                        const DWARFDebugNames::NameIndex &NI);
269
270   /// Verify that the DWARF v5 accelerator table is valid.
271   ///
272   /// This function currently checks that:
273   /// - Headers individual Name Indices fit into the section and can be parsed.
274   /// - Abbreviation tables can be parsed and contain valid index attributes
275   ///   with correct form encodings.
276   /// - The CU lists reference existing compile units.
277   /// - The buckets have a valid index, or they are empty.
278   /// - All names are reachable via the hash table (they have the correct hash,
279   ///   and the hash is in the correct bucket).
280   /// - Information in the index entries is complete (all required entries are
281   ///   present) and consistent with the debug_info section DIEs.
282   ///
283   /// \param AccelSection section containing the acceleration table
284   /// \param StrData string section
285   ///
286   /// \returns The number of errors occurred during verification
287   unsigned verifyDebugNames(const DWARFSection &AccelSection,
288                             const DataExtractor &StrData);
289
290 public:
291   DWARFVerifier(raw_ostream &S, DWARFContext &D,
292                 DIDumpOptions DumpOpts = DIDumpOptions::getForSingleDIE());
293
294   /// Verify the information in any of the following sections, if available:
295   /// .debug_abbrev, debug_abbrev.dwo
296   ///
297   /// Any errors are reported to the stream that was this object was
298   /// constructed with.
299   ///
300   /// \returns true if .debug_abbrev and .debug_abbrev.dwo verify successfully,
301   /// false otherwise.
302   bool handleDebugAbbrev();
303
304   /// Verify the information in the .debug_info and .debug_types sections.
305   ///
306   /// Any errors are reported to the stream that this object was
307   /// constructed with.
308   ///
309   /// \returns true if all sections verify successfully, false otherwise.
310   bool handleDebugInfo();
311
312   /// Verify the information in the .debug_line section.
313   ///
314   /// Any errors are reported to the stream that was this object was
315   /// constructed with.
316   ///
317   /// \returns true if the .debug_line verifies successfully, false otherwise.
318   bool handleDebugLine();
319
320   /// Verify the information in accelerator tables, if they exist.
321   ///
322   /// Any errors are reported to the stream that was this object was
323   /// constructed with.
324   ///
325   /// \returns true if the existing Apple-style accelerator tables verify
326   /// successfully, false otherwise.
327   bool handleAccelTables();
328 };
329
330 static inline bool operator<(const DWARFVerifier::DieRangeInfo &LHS,
331                              const DWARFVerifier::DieRangeInfo &RHS) {
332   return std::tie(LHS.Ranges, LHS.Die) < std::tie(RHS.Ranges, RHS.Die);
333 }
334
335 } // end namespace llvm
336
337 #endif // LLVM_DEBUGINFO_DWARF_DWARFCONTEXT_H