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