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: DWARFContext()78 DWARFContext() : DIContext(CK_DWARF) {} 79 classof(const DIContext * DICtx)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. compile_units()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. type_unit_sections()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. dwo_compile_units()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. dwo_type_unit_sections()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. getNumCompileUnits()116 unsigned getNumCompileUnits() { 117 parseCompileUnits(); 118 return CUs.size(); 119 } 120 121 /// Get the number of compile units in this context. getNumTypeUnits()122 unsigned getNumTypeUnits() { 123 parseTypeUnits(); 124 return TUs.size(); 125 } 126 127 /// Get the number of compile units in the DWO context. getNumDWOCompileUnits()128 unsigned getNumDWOCompileUnits() { 129 parseDWOCompileUnits(); 130 return DWOCUs.size(); 131 } 132 133 /// Get the number of compile units in the DWO context. getNumDWOTypeUnits()134 unsigned getNumDWOTypeUnits() { 135 parseDWOTypeUnits(); 136 return DWOTUs.size(); 137 } 138 139 /// Get the compile unit at the specified index for this compile unit. getCompileUnitAtIndex(unsigned index)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. getDWOCompileUnitAtIndex(unsigned index)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 isSupportedVersion(unsigned version)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); isLittleEndian()282 bool isLittleEndian() const override { return IsLittleEndian; } getAddressSize()283 uint8_t getAddressSize() const override { return AddressSize; } getInfoSection()284 const DWARFSection &getInfoSection() override { return InfoSection; } getTypesSections()285 const TypeSectionMap &getTypesSections() override { return TypesSections; } getAbbrevSection()286 StringRef getAbbrevSection() override { return AbbrevSection; } getLocSection()287 const DWARFSection &getLocSection() override { return LocSection; } getARangeSection()288 StringRef getARangeSection() override { return ARangeSection; } getDebugFrameSection()289 StringRef getDebugFrameSection() override { return DebugFrameSection; } getEHFrameSection()290 StringRef getEHFrameSection() override { return EHFrameSection; } getLineSection()291 const DWARFSection &getLineSection() override { return LineSection; } getStringSection()292 StringRef getStringSection() override { return StringSection; } getRangeSection()293 StringRef getRangeSection() override { return RangeSection; } getMacinfoSection()294 StringRef getMacinfoSection() override { return MacinfoSection; } getPubNamesSection()295 StringRef getPubNamesSection() override { return PubNamesSection; } getPubTypesSection()296 StringRef getPubTypesSection() override { return PubTypesSection; } getGnuPubNamesSection()297 StringRef getGnuPubNamesSection() override { return GnuPubNamesSection; } getGnuPubTypesSection()298 StringRef getGnuPubTypesSection() override { return GnuPubTypesSection; } getAppleNamesSection()299 const DWARFSection& getAppleNamesSection() override { return AppleNamesSection; } getAppleTypesSection()300 const DWARFSection& getAppleTypesSection() override { return AppleTypesSection; } getAppleNamespacesSection()301 const DWARFSection& getAppleNamespacesSection() override { return AppleNamespacesSection; } getAppleObjCSection()302 const DWARFSection& getAppleObjCSection() override { return AppleObjCSection; } 303 304 // Sections for DWARF5 split dwarf proposal. getInfoDWOSection()305 const DWARFSection &getInfoDWOSection() override { return InfoDWOSection; } getTypesDWOSections()306 const TypeSectionMap &getTypesDWOSections() override { 307 return TypesDWOSections; 308 } getAbbrevDWOSection()309 StringRef getAbbrevDWOSection() override { return AbbrevDWOSection; } getLineDWOSection()310 const DWARFSection &getLineDWOSection() override { return LineDWOSection; } getLocDWOSection()311 const DWARFSection &getLocDWOSection() override { return LocDWOSection; } getStringDWOSection()312 StringRef getStringDWOSection() override { return StringDWOSection; } getStringOffsetDWOSection()313 StringRef getStringOffsetDWOSection() override { 314 return StringOffsetDWOSection; 315 } getRangeDWOSection()316 StringRef getRangeDWOSection() override { return RangeDWOSection; } getAddrSection()317 StringRef getAddrSection() override { 318 return AddrSection; 319 } getCUIndexSection()320 StringRef getCUIndexSection() override { return CUIndexSection; } getTUIndexSection()321 StringRef getTUIndexSection() override { return TUIndexSection; } 322 }; 323 324 } 325 326 #endif 327