LLVM  14.0.0git
DWARFVerifier.h
Go to the documentation of this file.
1 //===- DWARFVerifier.h ----------------------------------------------------===//
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_DWARFVERIFIER_H
10 #define LLVM_DEBUGINFO_DWARF_DWARFVERIFIER_H
11 
12 #include "llvm/ADT/Optional.h"
18 #include <cstdint>
19 #include <map>
20 #include <set>
21 
22 namespace llvm {
23 class raw_ostream;
24 struct DWARFAddressRange;
25 struct DWARFAttribute;
26 class DWARFContext;
27 class DWARFDataExtractor;
28 class DWARFDebugAbbrev;
29 class DataExtractor;
30 struct DWARFSection;
31 class DWARFUnit;
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;
48 
49  /// Used for unit testing.
50  DieRangeInfo(std::vector<DWARFAddressRange> Ranges)
51  : Ranges(std::move(Ranges)) {}
52 
53  typedef std::set<DieRangeInfo>::const_iterator die_range_info_iterator;
54 
55  /// Inserts the address range. If the range overlaps with an existing
56  /// range, the range that it overlaps with will be returned and the two
57  /// address ranges will be unioned together in "Ranges".
58  ///
59  /// This is used for finding overlapping ranges in the DW_AT_ranges
60  /// attribute of a DIE. It is also used as a set of address ranges that
61  /// children address ranges must all be contained in.
63 
64  /// Inserts the address range info. If any of its ranges overlaps with a
65  /// range in an existing range info, the range info is *not* added and an
66  /// iterator to the overlapping range info.
67  ///
68  /// This is used for finding overlapping children of the same DIE.
70 
71  /// Return true if ranges in this object contains all ranges within RHS.
72  bool contains(const DieRangeInfo &RHS) const;
73 
74  /// Return true if any range in this object intersects with any range in
75  /// RHS.
76  bool intersects(const DieRangeInfo &RHS) const;
77  };
78 
79 private:
80  raw_ostream &OS;
81  DWARFContext &DCtx;
82  DIDumpOptions DumpOpts;
83  uint32_t NumDebugLineErrors = 0;
84  // Used to relax some checks that do not currently work portably
85  bool IsObjectFile;
86  bool IsMachOObject;
87  using ReferenceMap = std::map<uint64_t, std::set<uint64_t>>;
88 
89  raw_ostream &error() const;
90  raw_ostream &warn() const;
91  raw_ostream &note() const;
92  raw_ostream &dump(const DWARFDie &Die, unsigned indent = 0) const;
93 
94  /// Verifies the abbreviations section.
95  ///
96  /// This function currently checks that:
97  /// --No abbreviation declaration has more than one attributes with the same
98  /// name.
99  ///
100  /// \param Abbrev Pointer to the abbreviations section we are verifying
101  /// Abbrev can be a pointer to either .debug_abbrev or debug_abbrev.dwo.
102  ///
103  /// \returns The number of errors that occurred during verification.
104  unsigned verifyAbbrevSection(const DWARFDebugAbbrev *Abbrev);
105 
106  /// Verifies the header of a unit in a .debug_info or .debug_types section.
107  ///
108  /// This function currently checks for:
109  /// - Unit is in 32-bit DWARF format. The function can be modified to
110  /// support 64-bit format.
111  /// - The DWARF version is valid
112  /// - The unit type is valid (if unit is in version >=5)
113  /// - The unit doesn't extend beyond the containing section
114  /// - The address size is valid
115  /// - The offset in the .debug_abbrev section is valid
116  ///
117  /// \param DebugInfoData The section data
118  /// \param Offset A reference to the offset start of the unit. The offset will
119  /// be updated to point to the next unit in the section
120  /// \param UnitIndex The index of the unit to be verified
121  /// \param UnitType A reference to the type of the unit
122  /// \param isUnitDWARF64 A reference to a flag that shows whether the unit is
123  /// in 64-bit format.
124  ///
125  /// \returns true if the header is verified successfully, false otherwise.
126  bool verifyUnitHeader(const DWARFDataExtractor DebugInfoData,
127  uint64_t *Offset, unsigned UnitIndex, uint8_t &UnitType,
128  bool &isUnitDWARF64);
129  bool verifyName(const DWARFDie &Die);
130 
131  /// Verifies the header of a unit in a .debug_info or .debug_types section.
132  ///
133  /// This function currently verifies:
134  /// - The debug info attributes.
135  /// - The debug info form=s.
136  /// - The presence of a root DIE.
137  /// - That the root DIE is a unit DIE.
138  /// - If a unit type is provided, that the unit DIE matches the unit type.
139  /// - The DIE ranges.
140  /// - That call site entries are only nested within subprograms with a
141  /// DW_AT_call attribute.
142  ///
143  /// \param Unit The DWARF Unit to verify.
144  ///
145  /// \returns The number of errors that occurred during verification.
146  unsigned verifyUnitContents(DWARFUnit &Unit,
147  ReferenceMap &UnitLocalReferences,
148  ReferenceMap &CrossUnitReferences);
149 
150  /// Verifies the unit headers and contents in a .debug_info or .debug_types
151  /// section.
152  ///
153  /// \param S The DWARF Section to verify.
154  /// \param SectionKind The object-file section kind that S comes from.
155  ///
156  /// \returns The number of errors that occurred during verification.
157  unsigned verifyUnitSection(const DWARFSection &S);
158  unsigned verifyUnits(const DWARFUnitVector &Units);
159 
160  /// Verifies that a call site entry is nested within a subprogram with a
161  /// DW_AT_call attribute.
162  ///
163  /// \returns Number of errors that occurred during verification.
164  unsigned verifyDebugInfoCallSite(const DWARFDie &Die);
165 
166  /// Verify that all Die ranges are valid.
167  ///
168  /// This function currently checks for:
169  /// - cases in which lowPC >= highPC
170  ///
171  /// \returns Number of errors that occurred during verification.
172  unsigned verifyDieRanges(const DWARFDie &Die, DieRangeInfo &ParentRI);
173 
174  /// Verifies the attribute's DWARF attribute and its value.
175  ///
176  /// This function currently checks for:
177  /// - DW_AT_ranges values is a valid .debug_ranges offset
178  /// - DW_AT_stmt_list is a valid .debug_line offset
179  ///
180  /// \param Die The DWARF DIE that owns the attribute value
181  /// \param AttrValue The DWARF attribute value to check
182  ///
183  /// \returns NumErrors The number of errors occurred during verification of
184  /// attributes' values in a unit
185  unsigned verifyDebugInfoAttribute(const DWARFDie &Die,
186  DWARFAttribute &AttrValue);
187 
188  /// Verifies the attribute's DWARF form.
189  ///
190  /// This function currently checks for:
191  /// - All DW_FORM_ref values that are CU relative have valid CU offsets
192  /// - All DW_FORM_ref_addr values have valid section offsets
193  /// - All DW_FORM_strp values have valid .debug_str offsets
194  ///
195  /// \param Die The DWARF DIE that owns the attribute value
196  /// \param AttrValue The DWARF attribute value to check
197  ///
198  /// \returns NumErrors The number of errors occurred during verification of
199  /// attributes' forms in a unit
200  unsigned verifyDebugInfoForm(const DWARFDie &Die, DWARFAttribute &AttrValue,
201  ReferenceMap &UnitLocalReferences,
202  ReferenceMap &CrossUnitReferences);
203 
204  /// Verifies the all valid references that were found when iterating through
205  /// all of the DIE attributes.
206  ///
207  /// This function will verify that all references point to DIEs whose DIE
208  /// offset matches. This helps to ensure if a DWARF link phase moved things
209  /// around, that it doesn't create invalid references by failing to relocate
210  /// CU relative and absolute references.
211  ///
212  /// \returns NumErrors The number of errors occurred during verification of
213  /// references for the .debug_info and .debug_types sections
214  unsigned verifyDebugInfoReferences(
215  const ReferenceMap &,
216  llvm::function_ref<DWARFUnit *(uint64_t)> GetUnitForDieOffset);
217 
218  /// Verify the DW_AT_stmt_list encoding and value and ensure that no
219  /// compile units that have the same DW_AT_stmt_list value.
220  void verifyDebugLineStmtOffsets();
221 
222  /// Verify that all of the rows in the line table are valid.
223  ///
224  /// This function currently checks for:
225  /// - addresses within a sequence that decrease in value
226  /// - invalid file indexes
227  void verifyDebugLineRows();
228 
229  /// Verify that an Apple-style accelerator table is valid.
230  ///
231  /// This function currently checks that:
232  /// - The fixed part of the header fits in the section
233  /// - The size of the section is as large as what the header describes
234  /// - There is at least one atom
235  /// - The form for each atom is valid
236  /// - The tag for each DIE in the table is valid
237  /// - The buckets have a valid index, or they are empty
238  /// - Each hashdata offset is valid
239  /// - Each DIE is valid
240  ///
241  /// \param AccelSection pointer to the section containing the acceleration table
242  /// \param StrData pointer to the string section
243  /// \param SectionName the name of the table we're verifying
244  ///
245  /// \returns The number of errors occurred during verification
246  unsigned verifyAppleAccelTable(const DWARFSection *AccelSection,
247  DataExtractor *StrData,
248  const char *SectionName);
249 
250  unsigned verifyDebugNamesCULists(const DWARFDebugNames &AccelTable);
251  unsigned verifyNameIndexBuckets(const DWARFDebugNames::NameIndex &NI,
252  const DataExtractor &StrData);
253  unsigned verifyNameIndexAbbrevs(const DWARFDebugNames::NameIndex &NI);
254  unsigned verifyNameIndexAttribute(const DWARFDebugNames::NameIndex &NI,
255  const DWARFDebugNames::Abbrev &Abbr,
257  unsigned verifyNameIndexEntries(const DWARFDebugNames::NameIndex &NI,
259  unsigned verifyNameIndexCompleteness(const DWARFDie &Die,
260  const DWARFDebugNames::NameIndex &NI);
261 
262  /// Verify that the DWARF v5 accelerator table is valid.
263  ///
264  /// This function currently checks that:
265  /// - Headers individual Name Indices fit into the section and can be parsed.
266  /// - Abbreviation tables can be parsed and contain valid index attributes
267  /// with correct form encodings.
268  /// - The CU lists reference existing compile units.
269  /// - The buckets have a valid index, or they are empty.
270  /// - All names are reachable via the hash table (they have the correct hash,
271  /// and the hash is in the correct bucket).
272  /// - Information in the index entries is complete (all required entries are
273  /// present) and consistent with the debug_info section DIEs.
274  ///
275  /// \param AccelSection section containing the acceleration table
276  /// \param StrData string section
277  ///
278  /// \returns The number of errors occurred during verification
279  unsigned verifyDebugNames(const DWARFSection &AccelSection,
280  const DataExtractor &StrData);
281 
282 public:
285 
286  /// Verify the information in any of the following sections, if available:
287  /// .debug_abbrev, debug_abbrev.dwo
288  ///
289  /// Any errors are reported to the stream that was this object was
290  /// constructed with.
291  ///
292  /// \returns true if .debug_abbrev and .debug_abbrev.dwo verify successfully,
293  /// false otherwise.
294  bool handleDebugAbbrev();
295 
296  /// Verify the information in the .debug_info and .debug_types sections.
297  ///
298  /// Any errors are reported to the stream that this object was
299  /// constructed with.
300  ///
301  /// \returns true if all sections verify successfully, false otherwise.
302  bool handleDebugInfo();
303 
304  /// Verify the information in the .debug_line section.
305  ///
306  /// Any errors are reported to the stream that was this object was
307  /// constructed with.
308  ///
309  /// \returns true if the .debug_line verifies successfully, false otherwise.
310  bool handleDebugLine();
311 
312  /// Verify the information in accelerator tables, if they exist.
313  ///
314  /// Any errors are reported to the stream that was this object was
315  /// constructed with.
316  ///
317  /// \returns true if the existing Apple-style accelerator tables verify
318  /// successfully, false otherwise.
319  bool handleAccelTables();
320 };
321 
322 static inline bool operator<(const DWARFVerifier::DieRangeInfo &LHS,
323  const DWARFVerifier::DieRangeInfo &RHS) {
324  return std::tie(LHS.Ranges, LHS.Die) < std::tie(RHS.Ranges, RHS.Die);
325 }
326 
327 } // end namespace llvm
328 
329 #endif // LLVM_DEBUGINFO_DWARF_DWARFVERIFIER_H
llvm::DWARFSection
Definition: DWARFSection.h:16
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AllocatorList.h:23
llvm::DWARFVerifier
A class that verifies DWARF debug information given a DWARF Context.
Definition: DWARFVerifier.h:34
llvm::DWARFVerifier::DieRangeInfo::Ranges
std::vector< DWARFAddressRange > Ranges
Sorted DWARFAddressRanges.
Definition: DWARFVerifier.h:41
Optional.h
DWARFAcceleratorTable.h
llvm::DWARFVerifier::DWARFVerifier
DWARFVerifier(raw_ostream &S, DWARFContext &D, DIDumpOptions DumpOpts=DIDumpOptions::getForSingleDIE())
Definition: DWARFVerifier.cpp:881
llvm::DWARFContext
DWARFContext This data structure is the top level entity that deals with dwarf debug information pars...
Definition: DWARFContext.h:53
llvm::DWARFDebugNames::NameTableEntry
A single entry in the Name Table (DWARF v5 sect.
Definition: DWARFAcceleratorTable.h:356
llvm::Optional
Definition: APInt.h:33
Offset
uint64_t Offset
Definition: ELFObjHandler.cpp:81
llvm::AccelTable
This class holds an abstract representation of an Accelerator Table, consisting of a sequence of buck...
Definition: AccelTable.h:197
llvm::DWARFDataExtractor
A DataExtractor (typically for an in-memory copy of an object-file section) plus a relocation map for...
Definition: DWARFDataExtractor.h:21
llvm::DWARFVerifier::handleDebugInfo
bool handleDebugInfo()
Verify the information in the .debug_info and .debug_types sections.
Definition: DWARFVerifier.cpp:377
llvm::DWARFDebugNames::Abbrev
Abbreviation describing the encoding of Name Index entries.
Definition: DWARFAcceleratorTable.h:270
llvm::DWARFDebugNames::AttributeEncoding
Index attribute and its encoding.
Definition: DWARFAcceleratorTable.h:256
llvm::DWARFAttribute
Encapsulates a DWARF attribute value and all of the data required to describe the attribute value.
Definition: DWARFAttribute.h:24
llvm::DIDumpOptions::getForSingleDIE
static DIDumpOptions getForSingleDIE()
Return default option set for printing a single DIE without children.
Definition: DIContext.h:195
llvm::DWARFDebugAbbrev
Definition: DWARFDebugAbbrev.h:56
llvm::DWARFDebugNames::NameIndex
Represents a single accelerator table within the DWARF v5 .debug_names section.
Definition: DWARFAcceleratorTable.h:388
DWARFDie.h
llvm::DWARFVerifier::handleDebugLine
bool handleDebugLine()
Verify the information in the .debug_line section.
Definition: DWARFVerifier.cpp:891
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
llvm::DWARFVerifier::handleAccelTables
bool handleAccelTables()
Verify the information in accelerator tables, if they exist.
Definition: DWARFVerifier.cpp:1539
llvm::DWARFVerifier::DieRangeInfo::die_range_info_iterator
std::set< DieRangeInfo >::const_iterator die_range_info_iterator
Definition: DWARFVerifier.h:53
llvm::function_ref
An efficient, type-erasing, non-owning reference to a callable.
Definition: STLExtras.h:168
uint64_t
D
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
llvm::DWARFVerifier::handleDebugAbbrev
bool handleDebugAbbrev()
Verify the information in any of the following sections, if available: .debug_abbrev,...
Definition: DWARFVerifier.cpp:308
llvm::DWARFVerifier::DieRangeInfo::intersects
bool intersects(const DieRangeInfo &RHS) const
Return true if any range in this object intersects with any range in RHS.
Definition: DWARFVerifier.cpp:93
llvm::operator<
bool operator<(int64_t V1, const APSInt &V2)
Definition: APSInt.h:338
DWARFUnit.h
llvm::DWARFVerifier::DieRangeInfo::Die
DWARFDie Die
Definition: DWARFVerifier.h:38
llvm::dwarf::UnitType
UnitType
Constants for unit types in DWARF v5.
Definition: Dwarf.h:460
llvm::DWARFVerifier::DieRangeInfo::DieRangeInfo
DieRangeInfo()=default
llvm::move
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1639
llvm::DWARFVerifier::DieRangeInfo::DieRangeInfo
DieRangeInfo(std::vector< DWARFAddressRange > Ranges)
Used for unit testing.
Definition: DWARFVerifier.h:50
uint32_t
S
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Definition: README.txt:210
llvm::DWARFVerifier::DieRangeInfo::Children
std::set< DieRangeInfo > Children
Sorted DWARFAddressRangeInfo.
Definition: DWARFVerifier.h:44
DIContext.h
std
Definition: BitVector.h:838
llvm::DWARFUnit
Definition: DWARFUnit.h:203
llvm::SectionName
Definition: DWARFSection.h:21
llvm::DWARFVerifier::DieRangeInfo
A class that keeps the address range information for a single DIE.
Definition: DWARFVerifier.h:37
DWARFUnitIndex.h
llvm::DataExtractor
Definition: DataExtractor.h:41
llvm::DWARFVerifier::DieRangeInfo::contains
bool contains(const DieRangeInfo &RHS) const
Return true if ranges in this object contains all ranges within RHS.
Definition: DWARFVerifier.cpp:69
llvm::DWARFDie
Utility class that carries the DWARF compile/type unit and the debug info entry in an object.
Definition: DWARFDie.h:43
llvm::DWARFAddressRange
Definition: DWARFAddressRange.h:22
llvm::DWARFDebugNames
.debug_names section consists of one or more units.
Definition: DWARFAcceleratorTable.h:231
llvm::DWARFVerifier::DieRangeInfo::DieRangeInfo
DieRangeInfo(DWARFDie Die)
Definition: DWARFVerifier.h:47
llvm::DWARFVerifier::DieRangeInfo::insert
Optional< DWARFAddressRange > insert(const DWARFAddressRange &R)
Inserts the address range.
Definition: DWARFVerifier.cpp:32
llvm::DIDumpOptions
Container for dump options that control which debug information will be dumped.
Definition: DIContext.h:180
llvm::DWARFUnitVector
Describe a collection of units.
Definition: DWARFUnit.h:120