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