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