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