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