Home | History | Annotate | Download | only in DWARF
      1 //===-- DWARFContext.h ------------------------------------------*- C++ -*-===//
      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_LIB_DEBUGINFO_DWARFCONTEXT_H
     11 #define LLVM_LIB_DEBUGINFO_DWARFCONTEXT_H
     12 
     13 #include "llvm/ADT/MapVector.h"
     14 #include "llvm/ADT/SmallVector.h"
     15 #include "llvm/DebugInfo/DIContext.h"
     16 #include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
     17 #include "llvm/DebugInfo/DWARF/DWARFDebugAranges.h"
     18 #include "llvm/DebugInfo/DWARF/DWARFDebugFrame.h"
     19 #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
     20 #include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
     21 #include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h"
     22 #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
     23 #include "llvm/DebugInfo/DWARF/DWARFSection.h"
     24 #include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
     25 #include <vector>
     26 
     27 namespace llvm {
     28 
     29 // In place of applying the relocations to the data we've read from disk we use
     30 // a separate mapping table to the side and checking that at locations in the
     31 // dwarf where we expect relocated values. This adds a bit of complexity to the
     32 // dwarf parsing/extraction at the benefit of not allocating memory for the
     33 // entire size of the debug info sections.
     34 typedef DenseMap<uint64_t, std::pair<uint8_t, int64_t> > RelocAddrMap;
     35 
     36 /// DWARFContext
     37 /// This data structure is the top level entity that deals with dwarf debug
     38 /// information parsing. The actual data is supplied through pure virtual
     39 /// methods that a concrete implementation provides.
     40 class DWARFContext : public DIContext {
     41 
     42   DWARFUnitSection<DWARFCompileUnit> CUs;
     43   std::vector<DWARFUnitSection<DWARFTypeUnit>> TUs;
     44   std::unique_ptr<DWARFUnitIndex> CUIndex;
     45   std::unique_ptr<DWARFUnitIndex> TUIndex;
     46   std::unique_ptr<DWARFDebugAbbrev> Abbrev;
     47   std::unique_ptr<DWARFDebugLoc> Loc;
     48   std::unique_ptr<DWARFDebugAranges> Aranges;
     49   std::unique_ptr<DWARFDebugLine> Line;
     50   std::unique_ptr<DWARFDebugFrame> DebugFrame;
     51   std::unique_ptr<DWARFDebugMacro> Macro;
     52 
     53   DWARFUnitSection<DWARFCompileUnit> DWOCUs;
     54   std::vector<DWARFUnitSection<DWARFTypeUnit>> DWOTUs;
     55   std::unique_ptr<DWARFDebugAbbrev> AbbrevDWO;
     56   std::unique_ptr<DWARFDebugLocDWO> LocDWO;
     57 
     58   DWARFContext(DWARFContext &) = delete;
     59   DWARFContext &operator=(DWARFContext &) = delete;
     60 
     61   /// Read compile units from the debug_info section (if necessary)
     62   /// and store them in CUs.
     63   void parseCompileUnits();
     64 
     65   /// Read type units from the debug_types sections (if necessary)
     66   /// and store them in TUs.
     67   void parseTypeUnits();
     68 
     69   /// Read compile units from the debug_info.dwo section (if necessary)
     70   /// and store them in DWOCUs.
     71   void parseDWOCompileUnits();
     72 
     73   /// Read type units from the debug_types.dwo section (if necessary)
     74   /// and store them in DWOTUs.
     75   void parseDWOTypeUnits();
     76 
     77 public:
     78   DWARFContext() : DIContext(CK_DWARF) {}
     79 
     80   static bool classof(const DIContext *DICtx) {
     81     return DICtx->getKind() == CK_DWARF;
     82   }
     83 
     84   void dump(raw_ostream &OS, DIDumpType DumpType = DIDT_All) override;
     85 
     86   typedef DWARFUnitSection<DWARFCompileUnit>::iterator_range cu_iterator_range;
     87   typedef DWARFUnitSection<DWARFTypeUnit>::iterator_range tu_iterator_range;
     88   typedef iterator_range<std::vector<DWARFUnitSection<DWARFTypeUnit>>::iterator> tu_section_iterator_range;
     89 
     90   /// Get compile units in this context.
     91   cu_iterator_range compile_units() {
     92     parseCompileUnits();
     93     return cu_iterator_range(CUs.begin(), CUs.end());
     94   }
     95 
     96   /// Get type units in this context.
     97   tu_section_iterator_range type_unit_sections() {
     98     parseTypeUnits();
     99     return tu_section_iterator_range(TUs.begin(), TUs.end());
    100   }
    101 
    102   /// Get compile units in the DWO context.
    103   cu_iterator_range dwo_compile_units() {
    104     parseDWOCompileUnits();
    105     return cu_iterator_range(DWOCUs.begin(), DWOCUs.end());
    106   }
    107 
    108   /// Get type units in the DWO context.
    109   tu_section_iterator_range dwo_type_unit_sections() {
    110     parseDWOTypeUnits();
    111     return tu_section_iterator_range(DWOTUs.begin(), DWOTUs.end());
    112   }
    113 
    114   /// Get the number of compile units in this context.
    115   unsigned getNumCompileUnits() {
    116     parseCompileUnits();
    117     return CUs.size();
    118   }
    119 
    120   /// Get the number of compile units in this context.
    121   unsigned getNumTypeUnits() {
    122     parseTypeUnits();
    123     return TUs.size();
    124   }
    125 
    126   /// Get the number of compile units in the DWO context.
    127   unsigned getNumDWOCompileUnits() {
    128     parseDWOCompileUnits();
    129     return DWOCUs.size();
    130   }
    131 
    132   /// Get the number of compile units in the DWO context.
    133   unsigned getNumDWOTypeUnits() {
    134     parseDWOTypeUnits();
    135     return DWOTUs.size();
    136   }
    137 
    138   /// Get the compile unit at the specified index for this compile unit.
    139   DWARFCompileUnit *getCompileUnitAtIndex(unsigned index) {
    140     parseCompileUnits();
    141     return CUs[index].get();
    142   }
    143 
    144   /// Get the compile unit at the specified index for the DWO compile units.
    145   DWARFCompileUnit *getDWOCompileUnitAtIndex(unsigned index) {
    146     parseDWOCompileUnits();
    147     return DWOCUs[index].get();
    148   }
    149 
    150   const DWARFUnitIndex &getCUIndex();
    151   const DWARFUnitIndex &getTUIndex();
    152 
    153   /// Get a pointer to the parsed DebugAbbrev object.
    154   const DWARFDebugAbbrev *getDebugAbbrev();
    155 
    156   /// Get a pointer to the parsed DebugLoc object.
    157   const DWARFDebugLoc *getDebugLoc();
    158 
    159   /// Get a pointer to the parsed dwo abbreviations object.
    160   const DWARFDebugAbbrev *getDebugAbbrevDWO();
    161 
    162   /// Get a pointer to the parsed DebugLoc object.
    163   const DWARFDebugLocDWO *getDebugLocDWO();
    164 
    165   /// Get a pointer to the parsed DebugAranges object.
    166   const DWARFDebugAranges *getDebugAranges();
    167 
    168   /// Get a pointer to the parsed frame information object.
    169   const DWARFDebugFrame *getDebugFrame();
    170 
    171   /// Get a pointer to the parsed DebugMacro object.
    172   const DWARFDebugMacro *getDebugMacro();
    173 
    174   /// Get a pointer to a parsed line table corresponding to a compile unit.
    175   const DWARFDebugLine::LineTable *getLineTableForUnit(DWARFUnit *cu);
    176 
    177   DILineInfo getLineInfoForAddress(uint64_t Address,
    178       DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
    179   DILineInfoTable getLineInfoForAddressRange(uint64_t Address, uint64_t Size,
    180       DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
    181   DIInliningInfo getInliningInfoForAddress(uint64_t Address,
    182       DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
    183 
    184   virtual bool isLittleEndian() const = 0;
    185   virtual uint8_t getAddressSize() const = 0;
    186   virtual const DWARFSection &getInfoSection() = 0;
    187   typedef MapVector<object::SectionRef, DWARFSection,
    188                     std::map<object::SectionRef, unsigned>> TypeSectionMap;
    189   virtual const TypeSectionMap &getTypesSections() = 0;
    190   virtual StringRef getAbbrevSection() = 0;
    191   virtual const DWARFSection &getLocSection() = 0;
    192   virtual StringRef getARangeSection() = 0;
    193   virtual StringRef getDebugFrameSection() = 0;
    194   virtual const DWARFSection &getLineSection() = 0;
    195   virtual StringRef getStringSection() = 0;
    196   virtual StringRef getRangeSection() = 0;
    197   virtual StringRef getMacinfoSection() = 0;
    198   virtual StringRef getPubNamesSection() = 0;
    199   virtual StringRef getPubTypesSection() = 0;
    200   virtual StringRef getGnuPubNamesSection() = 0;
    201   virtual StringRef getGnuPubTypesSection() = 0;
    202 
    203   // Sections for DWARF5 split dwarf proposal.
    204   virtual const DWARFSection &getInfoDWOSection() = 0;
    205   virtual const TypeSectionMap &getTypesDWOSections() = 0;
    206   virtual StringRef getAbbrevDWOSection() = 0;
    207   virtual const DWARFSection &getLineDWOSection() = 0;
    208   virtual const DWARFSection &getLocDWOSection() = 0;
    209   virtual StringRef getStringDWOSection() = 0;
    210   virtual StringRef getStringOffsetDWOSection() = 0;
    211   virtual StringRef getRangeDWOSection() = 0;
    212   virtual StringRef getAddrSection() = 0;
    213   virtual const DWARFSection& getAppleNamesSection() = 0;
    214   virtual const DWARFSection& getAppleTypesSection() = 0;
    215   virtual const DWARFSection& getAppleNamespacesSection() = 0;
    216   virtual const DWARFSection& getAppleObjCSection() = 0;
    217   virtual StringRef getCUIndexSection() = 0;
    218   virtual StringRef getTUIndexSection() = 0;
    219 
    220   static bool isSupportedVersion(unsigned version) {
    221     return version == 2 || version == 3 || version == 4;
    222   }
    223 private:
    224   /// Return the compile unit that includes an offset (relative to .debug_info).
    225   DWARFCompileUnit *getCompileUnitForOffset(uint32_t Offset);
    226 
    227   /// Return the compile unit which contains instruction with provided
    228   /// address.
    229   DWARFCompileUnit *getCompileUnitForAddress(uint64_t Address);
    230 };
    231 
    232 /// DWARFContextInMemory is the simplest possible implementation of a
    233 /// DWARFContext. It assumes all content is available in memory and stores
    234 /// pointers to it.
    235 class DWARFContextInMemory : public DWARFContext {
    236   virtual void anchor();
    237   bool IsLittleEndian;
    238   uint8_t AddressSize;
    239   DWARFSection InfoSection;
    240   TypeSectionMap TypesSections;
    241   StringRef AbbrevSection;
    242   DWARFSection LocSection;
    243   StringRef ARangeSection;
    244   StringRef DebugFrameSection;
    245   DWARFSection LineSection;
    246   StringRef StringSection;
    247   StringRef RangeSection;
    248   StringRef MacinfoSection;
    249   StringRef PubNamesSection;
    250   StringRef PubTypesSection;
    251   StringRef GnuPubNamesSection;
    252   StringRef GnuPubTypesSection;
    253 
    254   // Sections for DWARF5 split dwarf proposal.
    255   DWARFSection InfoDWOSection;
    256   TypeSectionMap TypesDWOSections;
    257   StringRef AbbrevDWOSection;
    258   DWARFSection LineDWOSection;
    259   DWARFSection LocDWOSection;
    260   StringRef StringDWOSection;
    261   StringRef StringOffsetDWOSection;
    262   StringRef RangeDWOSection;
    263   StringRef AddrSection;
    264   DWARFSection AppleNamesSection;
    265   DWARFSection AppleTypesSection;
    266   DWARFSection AppleNamespacesSection;
    267   DWARFSection AppleObjCSection;
    268   StringRef CUIndexSection;
    269   StringRef TUIndexSection;
    270 
    271   SmallVector<SmallString<32>, 4> UncompressedSections;
    272 
    273 public:
    274   DWARFContextInMemory(const object::ObjectFile &Obj,
    275     const LoadedObjectInfo *L = nullptr);
    276   bool isLittleEndian() const override { return IsLittleEndian; }
    277   uint8_t getAddressSize() const override { return AddressSize; }
    278   const DWARFSection &getInfoSection() override { return InfoSection; }
    279   const TypeSectionMap &getTypesSections() override { return TypesSections; }
    280   StringRef getAbbrevSection() override { return AbbrevSection; }
    281   const DWARFSection &getLocSection() override { return LocSection; }
    282   StringRef getARangeSection() override { return ARangeSection; }
    283   StringRef getDebugFrameSection() override { return DebugFrameSection; }
    284   const DWARFSection &getLineSection() override { return LineSection; }
    285   StringRef getStringSection() override { return StringSection; }
    286   StringRef getRangeSection() override { return RangeSection; }
    287   StringRef getMacinfoSection() override { return MacinfoSection; }
    288   StringRef getPubNamesSection() override { return PubNamesSection; }
    289   StringRef getPubTypesSection() override { return PubTypesSection; }
    290   StringRef getGnuPubNamesSection() override { return GnuPubNamesSection; }
    291   StringRef getGnuPubTypesSection() override { return GnuPubTypesSection; }
    292   const DWARFSection& getAppleNamesSection() override { return AppleNamesSection; }
    293   const DWARFSection& getAppleTypesSection() override { return AppleTypesSection; }
    294   const DWARFSection& getAppleNamespacesSection() override { return AppleNamespacesSection; }
    295   const DWARFSection& getAppleObjCSection() override { return AppleObjCSection; }
    296 
    297   // Sections for DWARF5 split dwarf proposal.
    298   const DWARFSection &getInfoDWOSection() override { return InfoDWOSection; }
    299   const TypeSectionMap &getTypesDWOSections() override {
    300     return TypesDWOSections;
    301   }
    302   StringRef getAbbrevDWOSection() override { return AbbrevDWOSection; }
    303   const DWARFSection &getLineDWOSection() override { return LineDWOSection; }
    304   const DWARFSection &getLocDWOSection() override { return LocDWOSection; }
    305   StringRef getStringDWOSection() override { return StringDWOSection; }
    306   StringRef getStringOffsetDWOSection() override {
    307     return StringOffsetDWOSection;
    308   }
    309   StringRef getRangeDWOSection() override { return RangeDWOSection; }
    310   StringRef getAddrSection() override {
    311     return AddrSection;
    312   }
    313   StringRef getCUIndexSection() override { return CUIndexSection; }
    314   StringRef getTUIndexSection() override { return TUIndexSection; }
    315 };
    316 
    317 }
    318 
    319 #endif
    320