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