DWARFVerifier.h 13 KB

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