LLVM  6.0.0svn
DWARFVerifier.h
Go to the documentation of this file.
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 
16 
17 #include <cstdint>
18 #include <map>
19 #include <set>
20 
21 namespace llvm {
22 class raw_ostream;
23 struct DWARFAttribute;
24 class DWARFContext;
25 class DWARFDie;
26 class DWARFUnit;
27 class DWARFAcceleratorTable;
28 class DWARFDataExtractor;
29 class DWARFDebugAbbrev;
30 class DataExtractor;
31 struct DWARFSection;
32 
33 /// A class that verifies DWARF debug information given a DWARF Context.
35 public:
36  /// A class that keeps the address range information for a single DIE.
37  struct DieRangeInfo {
39 
40  /// Sorted DWARFAddressRanges.
41  std::vector<DWARFAddressRange> Ranges;
42 
43  /// Sorted DWARFAddressRangeInfo.
44  std::set<DieRangeInfo> Children;
45 
46  DieRangeInfo() = default;
47  DieRangeInfo(DWARFDie Die) : Die(Die) {}
48 
49  /// Used for unit testing.
50  DieRangeInfo(std::vector<DWARFAddressRange> Ranges)
51  : Ranges(std::move(Ranges)) {}
52 
53  typedef std::vector<DWARFAddressRange>::const_iterator
55  typedef std::set<DieRangeInfo>::const_iterator die_range_info_iterator;
56 
57  /// Inserts the address range. If the range overlaps with an existing
58  /// range, the range is *not* added and an iterator to the overlapping
59  /// range is returned.
60  ///
61  /// This is used for finding overlapping ranges within the same DIE.
63 
64  /// Finds an address range in the sorted vector of ranges.
66  auto Begin = Ranges.begin();
67  auto End = Ranges.end();
68  auto Iter = std::upper_bound(Begin, End, R);
69  if (Iter != Begin)
70  --Iter;
71  return Iter;
72  }
73 
74  /// Inserts the address range info. If any of its ranges overlaps with a
75  /// range in an existing range info, the range info is *not* added and an
76  /// iterator to the overlapping range info.
77  ///
78  /// This is used for finding overlapping children of the same DIE.
79  die_range_info_iterator insert(const DieRangeInfo &RI);
80 
81  /// Return true if ranges in this object contains all ranges within RHS.
82  bool contains(const DieRangeInfo &RHS) const;
83 
84  /// Return true if any range in this object intersects with any range in
85  /// RHS.
86  bool intersects(const DieRangeInfo &RHS) const;
87  };
88 
89 private:
90  raw_ostream &OS;
91  DWARFContext &DCtx;
92  DIDumpOptions DumpOpts;
93  /// A map that tracks all references (converted absolute references) so we
94  /// can verify each reference points to a valid DIE and not an offset that
95  /// lies between to valid DIEs.
96  std::map<uint64_t, std::set<uint32_t>> ReferenceToDIEOffsets;
97  uint32_t NumDebugLineErrors = 0;
98 
99  raw_ostream &error() const;
100  raw_ostream &warn() const;
101  raw_ostream &note() const;
102 
103  /// Verifies the abbreviations section.
104  ///
105  /// This function currently checks that:
106  /// --No abbreviation declaration has more than one attributes with the same
107  /// name.
108  ///
109  /// \param Abbrev Pointer to the abbreviations section we are verifying
110  /// Abbrev can be a pointer to either .debug_abbrev or debug_abbrev.dwo.
111  ///
112  /// \returns The number of errors that occured during verification.
113  unsigned verifyAbbrevSection(const DWARFDebugAbbrev *Abbrev);
114 
115  /// Verifies the header of a unit in the .debug_info section.
116  ///
117  /// This function currently checks for:
118  /// - Unit is in 32-bit DWARF format. The function can be modified to
119  /// support 64-bit format.
120  /// - The DWARF version is valid
121  /// - The unit type is valid (if unit is in version >=5)
122  /// - The unit doesn't extend beyond .debug_info section
123  /// - The address size is valid
124  /// - The offset in the .debug_abbrev section is valid
125  ///
126  /// \param DebugInfoData The .debug_info section data
127  /// \param Offset A reference to the offset start of the unit. The offset will
128  /// be updated to point to the next unit in .debug_info
129  /// \param UnitIndex The index of the unit to be verified
130  /// \param UnitType A reference to the type of the unit
131  /// \param isUnitDWARF64 A reference to a flag that shows whether the unit is
132  /// in 64-bit format.
133  ///
134  /// \returns true if the header is verified successfully, false otherwise.
135  bool verifyUnitHeader(const DWARFDataExtractor DebugInfoData,
136  uint32_t *Offset, unsigned UnitIndex, uint8_t &UnitType,
137  bool &isUnitDWARF64);
138 
139  /// Verifies the header of a unit in the .debug_info section.
140  ///
141  /// This function currently verifies:
142  /// - The debug info attributes.
143  /// - The debug info form=s.
144  /// - The presence of a root DIE.
145  /// - That the root DIE is a unit DIE.
146  /// - If a unit type is provided, that the unit DIE matches the unit type.
147  /// - The DIE ranges.
148  ///
149  /// \param Unit The DWARF Unit to verifiy.
150  /// \param UnitType An optional unit type which will be used to verify the
151  /// type of the unit DIE.
152  ///
153  /// \returns true if the content is verified successfully, false otherwise.
154  bool verifyUnitContents(DWARFUnit Unit, uint8_t UnitType = 0);
155 
156  /// Verify that all Die ranges are valid.
157  ///
158  /// This function currently checks for:
159  /// - cases in which lowPC >= highPC
160  ///
161  /// \returns Number of errors that occured during verification.
162  unsigned verifyDieRanges(const DWARFDie &Die, DieRangeInfo &ParentRI);
163 
164  /// Verifies the attribute's DWARF attribute and its value.
165  ///
166  /// This function currently checks for:
167  /// - DW_AT_ranges values is a valid .debug_ranges offset
168  /// - DW_AT_stmt_list is a valid .debug_line offset
169  ///
170  /// \param Die The DWARF DIE that owns the attribute value
171  /// \param AttrValue The DWARF attribute value to check
172  ///
173  /// \returns NumErrors The number of errors occured during verification of
174  /// attributes' values in a .debug_info section unit
175  unsigned verifyDebugInfoAttribute(const DWARFDie &Die,
176  DWARFAttribute &AttrValue);
177 
178  /// Verifies the attribute's DWARF form.
179  ///
180  /// This function currently checks for:
181  /// - All DW_FORM_ref values that are CU relative have valid CU offsets
182  /// - All DW_FORM_ref_addr values have valid .debug_info offsets
183  /// - All DW_FORM_strp values have valid .debug_str offsets
184  ///
185  /// \param Die The DWARF DIE that owns the attribute value
186  /// \param AttrValue The DWARF attribute value to check
187  ///
188  /// \returns NumErrors The number of errors occured during verification of
189  /// attributes' forms in a .debug_info section unit
190  unsigned verifyDebugInfoForm(const DWARFDie &Die, DWARFAttribute &AttrValue);
191 
192  /// Verifies the all valid references that were found when iterating through
193  /// all of the DIE attributes.
194  ///
195  /// This function will verify that all references point to DIEs whose DIE
196  /// offset matches. This helps to ensure if a DWARF link phase moved things
197  /// around, that it doesn't create invalid references by failing to relocate
198  /// CU relative and absolute references.
199  ///
200  /// \returns NumErrors The number of errors occured during verification of
201  /// references for the .debug_info section
202  unsigned verifyDebugInfoReferences();
203 
204  /// Verify the the DW_AT_stmt_list encoding and value and ensure that no
205  /// compile units that have the same DW_AT_stmt_list value.
206  void verifyDebugLineStmtOffsets();
207 
208  /// Verify that all of the rows in the line table are valid.
209  ///
210  /// This function currently checks for:
211  /// - addresses within a sequence that decrease in value
212  /// - invalid file indexes
213  void verifyDebugLineRows();
214 
215  /// Verify that an Apple-style accelerator table is valid.
216  ///
217  /// This function currently checks that:
218  /// - The fixed part of the header fits in the section
219  /// - The size of the section is as large as what the header describes
220  /// - There is at least one atom
221  /// - The form for each atom is valid
222  /// - The tag for each DIE in the table is valid
223  /// - The buckets have a valid index, or they are empty
224  /// - Each hashdata offset is valid
225  /// - Each DIE is valid
226  ///
227  /// \param AccelSection pointer to the section containing the acceleration table
228  /// \param StrData pointer to the string section
229  /// \param SectionName the name of the table we're verifying
230  ///
231  /// \returns The number of errors occured during verification
232  unsigned verifyAccelTable(const DWARFSection *AccelSection,
233  DataExtractor *StrData, const char *SectionName);
234 
235 public:
238  : OS(S), DCtx(D), DumpOpts(std::move(DumpOpts)) {}
239  /// Verify the information in any of the following sections, if available:
240  /// .debug_abbrev, debug_abbrev.dwo
241  ///
242  /// Any errors are reported to the stream that was this object was
243  /// constructed with.
244  ///
245  /// \returns true if .debug_abbrev and .debug_abbrev.dwo verify successfully,
246  /// false otherwise.
247  bool handleDebugAbbrev();
248 
249  /// Verify the information in the .debug_info section.
250  ///
251  /// Any errors are reported to the stream that was this object was
252  /// constructed with.
253  ///
254  /// \returns true if the .debug_info verifies successfully, false otherwise.
255  bool handleDebugInfo();
256 
257  /// Verify the information in the .debug_line section.
258  ///
259  /// Any errors are reported to the stream that was this object was
260  /// constructed with.
261  ///
262  /// \returns true if the .debug_line verifies successfully, false otherwise.
263  bool handleDebugLine();
264 
265  /// Verify the information in accelerator tables, if they exist.
266  ///
267  /// Any errors are reported to the stream that was this object was
268  /// constructed with.
269  ///
270  /// \returns true if the existing Apple-style accelerator tables verify
271  /// successfully, false otherwise.
272  bool handleAccelTables();
273 };
274 
275 static inline bool operator<(const DWARFVerifier::DieRangeInfo &LHS,
276  const DWARFVerifier::DieRangeInfo &RHS) {
277  return std::tie(LHS.Ranges, LHS.Die) < std::tie(RHS.Ranges, RHS.Die);
278 }
279 
280 } // end namespace llvm
281 
282 #endif // LLVM_DEBUGINFO_DWARF_DWARFCONTEXT_H
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
bool handleDebugLine()
Verify the information in the .debug_line section.
#define error(X)
bool handleDebugInfo()
Verify the information in the .debug_info section.
Definition: BitVector.h:920
std::set< DieRangeInfo > Children
Sorted DWARFAddressRangeInfo.
Definition: DWARFVerifier.h:44
std::vector< DWARFAddressRange > Ranges
Sorted DWARFAddressRanges.
Definition: DWARFVerifier.h:41
Encapsulates a DWARF attribute value and all of the data required to describe the attribute value...
Container for dump options that control which debug information will be dumped.
Definition: DIContext.h:153
address_range_iterator findRange(const DWARFAddressRange &R) const
Finds an address range in the sorted vector of ranges.
Definition: DWARFVerifier.h:65
Utility class that carries the DWARF compile/type unit and the debug info entry in an object...
Definition: DWARFDie.h:43
bool handleDebugAbbrev()
Verify the information in any of the following sections, if available: .debug_abbrev, debug_abbrev.dwo.
A class that keeps the address range information for a single DIE.
Definition: DWARFVerifier.h:37
bool contains(const DieRangeInfo &RHS) const
Return true if ranges in this object contains all ranges within RHS.
static const unsigned End
DieRangeInfo(std::vector< DWARFAddressRange > Ranges)
Used for unit testing.
Definition: DWARFVerifier.h:50
std::vector< DWARFAddressRange >::const_iterator address_range_iterator
Definition: DWARFVerifier.h:54
UnitType
Constants for unit types in DWARF v5.
Definition: Dwarf.h:321
A DataExtractor (typically for an in-memory copy of an object-file section) plus a relocation map for...
address_range_iterator insert(const DWARFAddressRange &R)
Inserts the address range.
DWARFContext This data structure is the top level entity that deals with dwarf debug information pars...
Definition: DWARFContext.h:59
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
bool intersects(const DieRangeInfo &RHS) const
Return true if any range in this object intersects with any range in RHS.
A class that verifies DWARF debug information given a DWARF Context.
Definition: DWARFVerifier.h:34
DWARFVerifier(raw_ostream &S, DWARFContext &D, DIDumpOptions DumpOpts=DIDumpOptions::getForSingleDIE())
bool handleAccelTables()
Verify the information in accelerator tables, if they exist.
std::set< DieRangeInfo >::const_iterator die_range_info_iterator
Definition: DWARFVerifier.h:55
static DIDumpOptions getForSingleDIE()
Return default option set for printing a single DIE without children.
Definition: DIContext.h:163
bool operator<(int64_t V1, const APSInt &V2)
Definition: APSInt.h:326
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:44