LCOV - code coverage report
Current view: top level - include/llvm/DebugInfo/DWARF - DWARFVerifier.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 9 10 90.0 %
Date: 2018-10-20 13:21:21 Functions: 1 1 100.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13