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_DEBUGINFO_DWARF_DWARFCONTEXT_H
     11 #define LLVM_DEBUGINFO_DWARF_DWARFCONTEXT_H
     12 
     13 #include "llvm/ADT/DenseMap.h"
     14 #include "llvm/ADT/MapVector.h"
     15 #include "llvm/ADT/SmallString.h"
     16 #include "llvm/ADT/SmallVector.h"
     17 #include "llvm/ADT/StringMap.h"
     18 #include "llvm/ADT/StringRef.h"
     19 #include "llvm/ADT/iterator_range.h"
     20 #include "llvm/DebugInfo/DIContext.h"
     21 #include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
     22 #include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
     23 #include "llvm/DebugInfo/DWARF/DWARFDebugAranges.h"
     24 #include "llvm/DebugInfo/DWARF/DWARFDebugFrame.h"
     25 #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
     26 #include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
     27 #include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h"
     28 #include "llvm/DebugInfo/DWARF/DWARFGdbIndex.h"
     29 #include "llvm/DebugInfo/DWARF/DWARFSection.h"
     30 #include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
     31 #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
     32 #include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
     33 #include "llvm/Object/ObjectFile.h"
     34 #include "llvm/Support/Host.h"
     35 #include <cstdint>
     36 #include <deque>
     37 #include <map>
     38 #include <memory>
     39 #include <utility>
     40 
     41 namespace llvm {
     42 
     43 class MemoryBuffer;
     44 class raw_ostream;
     45 
     46 /// Reads a value from data extractor and applies a relocation to the result if
     47 /// one exists for the given offset.
     48 uint64_t getRelocatedValue(const DataExtractor &Data, uint32_t Size,
     49                            uint32_t *Off, const RelocAddrMap *Relocs,
     50                            uint64_t *SecNdx = nullptr);
     51 
     52 /// DWARFContext
     53 /// This data structure is the top level entity that deals with dwarf debug
     54 /// information parsing. The actual data is supplied through pure virtual
     55 /// methods that a concrete implementation provides.
     56 class DWARFContext : public DIContext {
     57   DWARFUnitSection<DWARFCompileUnit> CUs;
     58   std::deque<DWARFUnitSection<DWARFTypeUnit>> TUs;
     59   std::unique_ptr<DWARFUnitIndex> CUIndex;
     60   std::unique_ptr<DWARFGdbIndex> GdbIndex;
     61   std::unique_ptr<DWARFUnitIndex> TUIndex;
     62   std::unique_ptr<DWARFDebugAbbrev> Abbrev;
     63   std::unique_ptr<DWARFDebugLoc> Loc;
     64   std::unique_ptr<DWARFDebugAranges> Aranges;
     65   std::unique_ptr<DWARFDebugLine> Line;
     66   std::unique_ptr<DWARFDebugFrame> DebugFrame;
     67   std::unique_ptr<DWARFDebugFrame> EHFrame;
     68   std::unique_ptr<DWARFDebugMacro> Macro;
     69 
     70   DWARFUnitSection<DWARFCompileUnit> DWOCUs;
     71   std::deque<DWARFUnitSection<DWARFTypeUnit>> DWOTUs;
     72   std::unique_ptr<DWARFDebugAbbrev> AbbrevDWO;
     73   std::unique_ptr<DWARFDebugLocDWO> LocDWO;
     74 
     75   /// The maximum DWARF version of all units.
     76   unsigned MaxVersion;
     77 
     78   struct DWOFile {
     79     object::OwningBinary<object::ObjectFile> File;
     80     std::unique_ptr<DWARFContext> Context;
     81   };
     82   StringMap<std::weak_ptr<DWOFile>> DWOFiles;
     83   std::weak_ptr<DWOFile> DWP;
     84   bool CheckedForDWP = false;
     85 
     86   /// Read compile units from the debug_info section (if necessary)
     87   /// and store them in CUs.
     88   void parseCompileUnits();
     89 
     90   /// Read type units from the debug_types sections (if necessary)
     91   /// and store them in TUs.
     92   void parseTypeUnits();
     93 
     94   /// Read compile units from the debug_info.dwo section (if necessary)
     95   /// and store them in DWOCUs.
     96   void parseDWOCompileUnits();
     97 
     98   /// Read type units from the debug_types.dwo section (if necessary)
     99   /// and store them in DWOTUs.
    100   void parseDWOTypeUnits();
    101 
    102 public:
    103   DWARFContext() : DIContext(CK_DWARF), MaxVersion(0) {}
    104   DWARFContext(DWARFContext &) = delete;
    105   DWARFContext &operator=(DWARFContext &) = delete;
    106 
    107   static bool classof(const DIContext *DICtx) {
    108     return DICtx->getKind() == CK_DWARF;
    109   }
    110 
    111   void dump(raw_ostream &OS, DIDumpOptions DumpOpts) override;
    112 
    113   bool verify(raw_ostream &OS, DIDumpType DumpType = DIDT_All) override;
    114 
    115   typedef DWARFUnitSection<DWARFCompileUnit>::iterator_range cu_iterator_range;
    116   typedef DWARFUnitSection<DWARFTypeUnit>::iterator_range tu_iterator_range;
    117   typedef iterator_range<decltype(TUs)::iterator> tu_section_iterator_range;
    118 
    119   /// Get compile units in this context.
    120   cu_iterator_range compile_units() {
    121     parseCompileUnits();
    122     return cu_iterator_range(CUs.begin(), CUs.end());
    123   }
    124 
    125   /// Get type units in this context.
    126   tu_section_iterator_range type_unit_sections() {
    127     parseTypeUnits();
    128     return tu_section_iterator_range(TUs.begin(), TUs.end());
    129   }
    130 
    131   /// Get compile units in the DWO context.
    132   cu_iterator_range dwo_compile_units() {
    133     parseDWOCompileUnits();
    134     return cu_iterator_range(DWOCUs.begin(), DWOCUs.end());
    135   }
    136 
    137   /// Get type units in the DWO context.
    138   tu_section_iterator_range dwo_type_unit_sections() {
    139     parseDWOTypeUnits();
    140     return tu_section_iterator_range(DWOTUs.begin(), DWOTUs.end());
    141   }
    142 
    143   /// Get the number of compile units in this context.
    144   unsigned getNumCompileUnits() {
    145     parseCompileUnits();
    146     return CUs.size();
    147   }
    148 
    149   /// Get the number of compile units in this context.
    150   unsigned getNumTypeUnits() {
    151     parseTypeUnits();
    152     return TUs.size();
    153   }
    154 
    155   /// Get the number of compile units in the DWO context.
    156   unsigned getNumDWOCompileUnits() {
    157     parseDWOCompileUnits();
    158     return DWOCUs.size();
    159   }
    160 
    161   /// Get the number of compile units in the DWO context.
    162   unsigned getNumDWOTypeUnits() {
    163     parseDWOTypeUnits();
    164     return DWOTUs.size();
    165   }
    166 
    167   /// Get the compile unit at the specified index for this compile unit.
    168   DWARFCompileUnit *getCompileUnitAtIndex(unsigned index) {
    169     parseCompileUnits();
    170     return CUs[index].get();
    171   }
    172 
    173   /// Get the compile unit at the specified index for the DWO compile units.
    174   DWARFCompileUnit *getDWOCompileUnitAtIndex(unsigned index) {
    175     parseDWOCompileUnits();
    176     return DWOCUs[index].get();
    177   }
    178 
    179   DWARFCompileUnit *getDWOCompileUnitForHash(uint64_t Hash);
    180 
    181   /// Get a DIE given an exact offset.
    182   DWARFDie getDIEForOffset(uint32_t Offset);
    183 
    184   unsigned getMaxVersion() const { return MaxVersion; }
    185 
    186   void setMaxVersionIfGreater(unsigned Version) {
    187     if (Version > MaxVersion)
    188       MaxVersion = Version;
    189   }
    190 
    191   const DWARFUnitIndex &getCUIndex();
    192   DWARFGdbIndex &getGdbIndex();
    193   const DWARFUnitIndex &getTUIndex();
    194 
    195   /// Get a pointer to the parsed DebugAbbrev object.
    196   const DWARFDebugAbbrev *getDebugAbbrev();
    197 
    198   /// Get a pointer to the parsed DebugLoc object.
    199   const DWARFDebugLoc *getDebugLoc();
    200 
    201   /// Get a pointer to the parsed dwo abbreviations object.
    202   const DWARFDebugAbbrev *getDebugAbbrevDWO();
    203 
    204   /// Get a pointer to the parsed DebugLoc object.
    205   const DWARFDebugLocDWO *getDebugLocDWO();
    206 
    207   /// Get a pointer to the parsed DebugAranges object.
    208   const DWARFDebugAranges *getDebugAranges();
    209 
    210   /// Get a pointer to the parsed frame information object.
    211   const DWARFDebugFrame *getDebugFrame();
    212 
    213   /// Get a pointer to the parsed eh frame information object.
    214   const DWARFDebugFrame *getEHFrame();
    215 
    216   /// Get a pointer to the parsed DebugMacro object.
    217   const DWARFDebugMacro *getDebugMacro();
    218 
    219   /// Get a pointer to a parsed line table corresponding to a compile unit.
    220   const DWARFDebugLine::LineTable *getLineTableForUnit(DWARFUnit *cu);
    221 
    222   DILineInfo getLineInfoForAddress(uint64_t Address,
    223       DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
    224   DILineInfoTable getLineInfoForAddressRange(uint64_t Address, uint64_t Size,
    225       DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
    226   DIInliningInfo getInliningInfoForAddress(uint64_t Address,
    227       DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
    228 
    229   virtual StringRef getFileName() const = 0;
    230   virtual bool isLittleEndian() const = 0;
    231   virtual uint8_t getAddressSize() const = 0;
    232   virtual const DWARFSection &getInfoSection() = 0;
    233   typedef MapVector<object::SectionRef, DWARFSection,
    234                     std::map<object::SectionRef, unsigned>> TypeSectionMap;
    235   virtual const TypeSectionMap &getTypesSections() = 0;
    236   virtual StringRef getAbbrevSection() = 0;
    237   virtual const DWARFSection &getLocSection() = 0;
    238   virtual StringRef getARangeSection() = 0;
    239   virtual StringRef getDebugFrameSection() = 0;
    240   virtual StringRef getEHFrameSection() = 0;
    241   virtual const DWARFSection &getLineSection() = 0;
    242   virtual StringRef getStringSection() = 0;
    243   virtual const DWARFSection& getRangeSection() = 0;
    244   virtual StringRef getMacinfoSection() = 0;
    245   virtual StringRef getPubNamesSection() = 0;
    246   virtual StringRef getPubTypesSection() = 0;
    247   virtual StringRef getGnuPubNamesSection() = 0;
    248   virtual StringRef getGnuPubTypesSection() = 0;
    249 
    250   /// DWARF v5
    251   /// @{
    252   virtual const DWARFSection &getStringOffsetSection() = 0;
    253   /// @}
    254 
    255   // Sections for DWARF5 split dwarf proposal.
    256   virtual const DWARFSection &getInfoDWOSection() = 0;
    257   virtual const TypeSectionMap &getTypesDWOSections() = 0;
    258   virtual StringRef getAbbrevDWOSection() = 0;
    259   virtual const DWARFSection &getLineDWOSection() = 0;
    260   virtual const DWARFSection &getLocDWOSection() = 0;
    261   virtual StringRef getStringDWOSection() = 0;
    262   virtual const DWARFSection &getStringOffsetDWOSection() = 0;
    263   virtual const DWARFSection &getRangeDWOSection() = 0;
    264   virtual const DWARFSection &getAddrSection() = 0;
    265   virtual const DWARFSection& getAppleNamesSection() = 0;
    266   virtual const DWARFSection& getAppleTypesSection() = 0;
    267   virtual const DWARFSection& getAppleNamespacesSection() = 0;
    268   virtual const DWARFSection& getAppleObjCSection() = 0;
    269   virtual StringRef getCUIndexSection() = 0;
    270   virtual StringRef getGdbIndexSection() = 0;
    271   virtual StringRef getTUIndexSection() = 0;
    272 
    273   static bool isSupportedVersion(unsigned version) {
    274     return version == 2 || version == 3 || version == 4 || version == 5;
    275   }
    276 
    277   std::shared_ptr<DWARFContext> getDWOContext(StringRef AbsolutePath);
    278 
    279 private:
    280   /// Return the compile unit that includes an offset (relative to .debug_info).
    281   DWARFCompileUnit *getCompileUnitForOffset(uint32_t Offset);
    282 
    283   /// Return the compile unit which contains instruction with provided
    284   /// address.
    285   DWARFCompileUnit *getCompileUnitForAddress(uint64_t Address);
    286 };
    287 
    288 /// DWARFContextInMemory is the simplest possible implementation of a
    289 /// DWARFContext. It assumes all content is available in memory and stores
    290 /// pointers to it.
    291 class DWARFContextInMemory : public DWARFContext {
    292   virtual void anchor();
    293 
    294   StringRef FileName;
    295   bool IsLittleEndian;
    296   uint8_t AddressSize;
    297   DWARFSection InfoSection;
    298   TypeSectionMap TypesSections;
    299   StringRef AbbrevSection;
    300   DWARFSection LocSection;
    301   StringRef ARangeSection;
    302   StringRef DebugFrameSection;
    303   StringRef EHFrameSection;
    304   DWARFSection LineSection;
    305   StringRef StringSection;
    306   DWARFSection RangeSection;
    307   StringRef MacinfoSection;
    308   StringRef PubNamesSection;
    309   StringRef PubTypesSection;
    310   StringRef GnuPubNamesSection;
    311   StringRef GnuPubTypesSection;
    312 
    313   /// DWARF v5
    314   /// @{
    315   DWARFSection StringOffsetSection;
    316   /// @}
    317 
    318   // Sections for DWARF5 split dwarf proposal.
    319   DWARFSection InfoDWOSection;
    320   TypeSectionMap TypesDWOSections;
    321   StringRef AbbrevDWOSection;
    322   DWARFSection LineDWOSection;
    323   DWARFSection LocDWOSection;
    324   StringRef StringDWOSection;
    325   DWARFSection StringOffsetDWOSection;
    326   DWARFSection RangeDWOSection;
    327   DWARFSection AddrSection;
    328   DWARFSection AppleNamesSection;
    329   DWARFSection AppleTypesSection;
    330   DWARFSection AppleNamespacesSection;
    331   DWARFSection AppleObjCSection;
    332   StringRef CUIndexSection;
    333   StringRef GdbIndexSection;
    334   StringRef TUIndexSection;
    335 
    336   SmallVector<SmallString<32>, 4> UncompressedSections;
    337 
    338   StringRef *MapSectionToMember(StringRef Name);
    339 
    340   /// If Sec is compressed section, decompresses and updates its contents
    341   /// provided by Data. Otherwise leaves it unchanged.
    342   Error maybeDecompress(const object::SectionRef &Sec, StringRef Name,
    343                         StringRef &Data);
    344 
    345 public:
    346   DWARFContextInMemory(const object::ObjectFile &Obj,
    347     const LoadedObjectInfo *L = nullptr);
    348 
    349   DWARFContextInMemory(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
    350                        uint8_t AddrSize,
    351                        bool isLittleEndian = sys::IsLittleEndianHost);
    352 
    353   StringRef getFileName() const override { return FileName; }
    354   bool isLittleEndian() const override { return IsLittleEndian; }
    355   uint8_t getAddressSize() const override { return AddressSize; }
    356   const DWARFSection &getInfoSection() override { return InfoSection; }
    357   const TypeSectionMap &getTypesSections() override { return TypesSections; }
    358   StringRef getAbbrevSection() override { return AbbrevSection; }
    359   const DWARFSection &getLocSection() override { return LocSection; }
    360   StringRef getARangeSection() override { return ARangeSection; }
    361   StringRef getDebugFrameSection() override { return DebugFrameSection; }
    362   StringRef getEHFrameSection() override { return EHFrameSection; }
    363   const DWARFSection &getLineSection() override { return LineSection; }
    364   StringRef getStringSection() override { return StringSection; }
    365   const DWARFSection &getRangeSection() override { return RangeSection; }
    366   StringRef getMacinfoSection() override { return MacinfoSection; }
    367   StringRef getPubNamesSection() override { return PubNamesSection; }
    368   StringRef getPubTypesSection() override { return PubTypesSection; }
    369   StringRef getGnuPubNamesSection() override { return GnuPubNamesSection; }
    370   StringRef getGnuPubTypesSection() override { return GnuPubTypesSection; }
    371   const DWARFSection& getAppleNamesSection() override { return AppleNamesSection; }
    372   const DWARFSection& getAppleTypesSection() override { return AppleTypesSection; }
    373   const DWARFSection& getAppleNamespacesSection() override { return AppleNamespacesSection; }
    374   const DWARFSection& getAppleObjCSection() override { return AppleObjCSection; }
    375 
    376   // DWARF v5
    377   const DWARFSection &getStringOffsetSection() override {
    378     return StringOffsetSection;
    379   }
    380 
    381   // Sections for DWARF5 split dwarf proposal.
    382   const DWARFSection &getInfoDWOSection() override { return InfoDWOSection; }
    383 
    384   const TypeSectionMap &getTypesDWOSections() override {
    385     return TypesDWOSections;
    386   }
    387 
    388   StringRef getAbbrevDWOSection() override { return AbbrevDWOSection; }
    389   const DWARFSection &getLineDWOSection() override { return LineDWOSection; }
    390   const DWARFSection &getLocDWOSection() override { return LocDWOSection; }
    391   StringRef getStringDWOSection() override { return StringDWOSection; }
    392 
    393   const DWARFSection &getStringOffsetDWOSection() override {
    394     return StringOffsetDWOSection;
    395   }
    396 
    397   const DWARFSection &getRangeDWOSection() override { return RangeDWOSection; }
    398 
    399   const DWARFSection &getAddrSection() override { return AddrSection; }
    400 
    401   StringRef getCUIndexSection() override { return CUIndexSection; }
    402   StringRef getGdbIndexSection() override { return GdbIndexSection; }
    403   StringRef getTUIndexSection() override { return TUIndexSection; }
    404 };
    405 
    406 } // end namespace llvm
    407 
    408 #endif // LLVM_DEBUGINFO_DWARF_DWARFCONTEXT_H
    409