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