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_DWARF_DWARFCONTEXT_H 11 #define LLVM_DEBUGINFO_DWARF_DWARFCONTEXT_H 12 13 #include "llvm/ADT/DenseMap.h" 14 #include "llvm/ADT/MapVector.h" 15 #include "llvm/ADT/SmallString.h" 16 #include "llvm/ADT/SmallVector.h" 17 #include "llvm/ADT/StringMap.h" 18 #include "llvm/ADT/StringRef.h" 19 #include "llvm/ADT/iterator_range.h" 20 #include "llvm/DebugInfo/DIContext.h" 21 #include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h" 22 #include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h" 23 #include "llvm/DebugInfo/DWARF/DWARFDebugAranges.h" 24 #include "llvm/DebugInfo/DWARF/DWARFDebugFrame.h" 25 #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h" 26 #include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h" 27 #include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h" 28 #include "llvm/DebugInfo/DWARF/DWARFGdbIndex.h" 29 #include "llvm/DebugInfo/DWARF/DWARFSection.h" 30 #include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h" 31 #include "llvm/DebugInfo/DWARF/DWARFUnit.h" 32 #include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h" 33 #include "llvm/Object/ObjectFile.h" 34 #include "llvm/Support/Host.h" 35 #include <cstdint> 36 #include <deque> 37 #include <map> 38 #include <memory> 39 #include <utility> 40 41 namespace llvm { 42 43 class MemoryBuffer; 44 class raw_ostream; 45 46 /// Reads a value from data extractor and applies a relocation to the result if 47 /// one exists for the given offset. 48 uint64_t getRelocatedValue(const DataExtractor &Data, uint32_t Size, 49 uint32_t *Off, const RelocAddrMap *Relocs, 50 uint64_t *SecNdx = nullptr); 51 52 /// DWARFContext 53 /// This data structure is the top level entity that deals with dwarf debug 54 /// information parsing. The actual data is supplied through pure virtual 55 /// methods that a concrete implementation provides. 56 class DWARFContext : public DIContext { 57 DWARFUnitSection<DWARFCompileUnit> CUs; 58 std::deque<DWARFUnitSection<DWARFTypeUnit>> TUs; 59 std::unique_ptr<DWARFUnitIndex> CUIndex; 60 std::unique_ptr<DWARFGdbIndex> GdbIndex; 61 std::unique_ptr<DWARFUnitIndex> TUIndex; 62 std::unique_ptr<DWARFDebugAbbrev> Abbrev; 63 std::unique_ptr<DWARFDebugLoc> Loc; 64 std::unique_ptr<DWARFDebugAranges> Aranges; 65 std::unique_ptr<DWARFDebugLine> Line; 66 std::unique_ptr<DWARFDebugFrame> DebugFrame; 67 std::unique_ptr<DWARFDebugFrame> EHFrame; 68 std::unique_ptr<DWARFDebugMacro> Macro; 69 70 DWARFUnitSection<DWARFCompileUnit> DWOCUs; 71 std::deque<DWARFUnitSection<DWARFTypeUnit>> DWOTUs; 72 std::unique_ptr<DWARFDebugAbbrev> AbbrevDWO; 73 std::unique_ptr<DWARFDebugLocDWO> LocDWO; 74 75 /// The maximum DWARF version of all units. 76 unsigned MaxVersion; 77 78 struct DWOFile { 79 object::OwningBinary<object::ObjectFile> File; 80 std::unique_ptr<DWARFContext> Context; 81 }; 82 StringMap<std::weak_ptr<DWOFile>> DWOFiles; 83 std::weak_ptr<DWOFile> DWP; 84 bool CheckedForDWP = false; 85 86 /// Read compile units from the debug_info section (if necessary) 87 /// and store them in CUs. 88 void parseCompileUnits(); 89 90 /// Read type units from the debug_types sections (if necessary) 91 /// and store them in TUs. 92 void parseTypeUnits(); 93 94 /// Read compile units from the debug_info.dwo section (if necessary) 95 /// and store them in DWOCUs. 96 void parseDWOCompileUnits(); 97 98 /// Read type units from the debug_types.dwo section (if necessary) 99 /// and store them in DWOTUs. 100 void parseDWOTypeUnits(); 101 102 public: 103 DWARFContext() : DIContext(CK_DWARF), MaxVersion(0) {} 104 DWARFContext(DWARFContext &) = delete; 105 DWARFContext &operator=(DWARFContext &) = delete; 106 107 static bool classof(const DIContext *DICtx) { 108 return DICtx->getKind() == CK_DWARF; 109 } 110 111 void dump(raw_ostream &OS, DIDumpOptions DumpOpts) override; 112 113 bool verify(raw_ostream &OS, DIDumpType DumpType = DIDT_All) override; 114 115 typedef DWARFUnitSection<DWARFCompileUnit>::iterator_range cu_iterator_range; 116 typedef DWARFUnitSection<DWARFTypeUnit>::iterator_range tu_iterator_range; 117 typedef iterator_range<decltype(TUs)::iterator> tu_section_iterator_range; 118 119 /// Get compile units in this context. 120 cu_iterator_range compile_units() { 121 parseCompileUnits(); 122 return cu_iterator_range(CUs.begin(), CUs.end()); 123 } 124 125 /// Get type units in this context. 126 tu_section_iterator_range type_unit_sections() { 127 parseTypeUnits(); 128 return tu_section_iterator_range(TUs.begin(), TUs.end()); 129 } 130 131 /// Get compile units in the DWO context. 132 cu_iterator_range dwo_compile_units() { 133 parseDWOCompileUnits(); 134 return cu_iterator_range(DWOCUs.begin(), DWOCUs.end()); 135 } 136 137 /// Get type units in the DWO context. 138 tu_section_iterator_range dwo_type_unit_sections() { 139 parseDWOTypeUnits(); 140 return tu_section_iterator_range(DWOTUs.begin(), DWOTUs.end()); 141 } 142 143 /// Get the number of compile units in this context. 144 unsigned getNumCompileUnits() { 145 parseCompileUnits(); 146 return CUs.size(); 147 } 148 149 /// Get the number of compile units in this context. 150 unsigned getNumTypeUnits() { 151 parseTypeUnits(); 152 return TUs.size(); 153 } 154 155 /// Get the number of compile units in the DWO context. 156 unsigned getNumDWOCompileUnits() { 157 parseDWOCompileUnits(); 158 return DWOCUs.size(); 159 } 160 161 /// Get the number of compile units in the DWO context. 162 unsigned getNumDWOTypeUnits() { 163 parseDWOTypeUnits(); 164 return DWOTUs.size(); 165 } 166 167 /// Get the compile unit at the specified index for this compile unit. 168 DWARFCompileUnit *getCompileUnitAtIndex(unsigned index) { 169 parseCompileUnits(); 170 return CUs[index].get(); 171 } 172 173 /// Get the compile unit at the specified index for the DWO compile units. 174 DWARFCompileUnit *getDWOCompileUnitAtIndex(unsigned index) { 175 parseDWOCompileUnits(); 176 return DWOCUs[index].get(); 177 } 178 179 DWARFCompileUnit *getDWOCompileUnitForHash(uint64_t Hash); 180 181 /// Get a DIE given an exact offset. 182 DWARFDie getDIEForOffset(uint32_t Offset); 183 184 unsigned getMaxVersion() const { return MaxVersion; } 185 186 void setMaxVersionIfGreater(unsigned Version) { 187 if (Version > MaxVersion) 188 MaxVersion = Version; 189 } 190 191 const DWARFUnitIndex &getCUIndex(); 192 DWARFGdbIndex &getGdbIndex(); 193 const DWARFUnitIndex &getTUIndex(); 194 195 /// Get a pointer to the parsed DebugAbbrev object. 196 const DWARFDebugAbbrev *getDebugAbbrev(); 197 198 /// Get a pointer to the parsed DebugLoc object. 199 const DWARFDebugLoc *getDebugLoc(); 200 201 /// Get a pointer to the parsed dwo abbreviations object. 202 const DWARFDebugAbbrev *getDebugAbbrevDWO(); 203 204 /// Get a pointer to the parsed DebugLoc object. 205 const DWARFDebugLocDWO *getDebugLocDWO(); 206 207 /// Get a pointer to the parsed DebugAranges object. 208 const DWARFDebugAranges *getDebugAranges(); 209 210 /// Get a pointer to the parsed frame information object. 211 const DWARFDebugFrame *getDebugFrame(); 212 213 /// Get a pointer to the parsed eh frame information object. 214 const DWARFDebugFrame *getEHFrame(); 215 216 /// Get a pointer to the parsed DebugMacro object. 217 const DWARFDebugMacro *getDebugMacro(); 218 219 /// Get a pointer to a parsed line table corresponding to a compile unit. 220 const DWARFDebugLine::LineTable *getLineTableForUnit(DWARFUnit *cu); 221 222 DILineInfo getLineInfoForAddress(uint64_t Address, 223 DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override; 224 DILineInfoTable getLineInfoForAddressRange(uint64_t Address, uint64_t Size, 225 DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override; 226 DIInliningInfo getInliningInfoForAddress(uint64_t Address, 227 DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override; 228 229 virtual StringRef getFileName() const = 0; 230 virtual bool isLittleEndian() const = 0; 231 virtual uint8_t getAddressSize() const = 0; 232 virtual const DWARFSection &getInfoSection() = 0; 233 typedef MapVector<object::SectionRef, DWARFSection, 234 std::map<object::SectionRef, unsigned>> TypeSectionMap; 235 virtual const TypeSectionMap &getTypesSections() = 0; 236 virtual StringRef getAbbrevSection() = 0; 237 virtual const DWARFSection &getLocSection() = 0; 238 virtual StringRef getARangeSection() = 0; 239 virtual StringRef getDebugFrameSection() = 0; 240 virtual StringRef getEHFrameSection() = 0; 241 virtual const DWARFSection &getLineSection() = 0; 242 virtual StringRef getStringSection() = 0; 243 virtual const DWARFSection& getRangeSection() = 0; 244 virtual StringRef getMacinfoSection() = 0; 245 virtual StringRef getPubNamesSection() = 0; 246 virtual StringRef getPubTypesSection() = 0; 247 virtual StringRef getGnuPubNamesSection() = 0; 248 virtual StringRef getGnuPubTypesSection() = 0; 249 250 /// DWARF v5 251 /// @{ 252 virtual const DWARFSection &getStringOffsetSection() = 0; 253 /// @} 254 255 // Sections for DWARF5 split dwarf proposal. 256 virtual const DWARFSection &getInfoDWOSection() = 0; 257 virtual const TypeSectionMap &getTypesDWOSections() = 0; 258 virtual StringRef getAbbrevDWOSection() = 0; 259 virtual const DWARFSection &getLineDWOSection() = 0; 260 virtual const DWARFSection &getLocDWOSection() = 0; 261 virtual StringRef getStringDWOSection() = 0; 262 virtual const DWARFSection &getStringOffsetDWOSection() = 0; 263 virtual const DWARFSection &getRangeDWOSection() = 0; 264 virtual const DWARFSection &getAddrSection() = 0; 265 virtual const DWARFSection& getAppleNamesSection() = 0; 266 virtual const DWARFSection& getAppleTypesSection() = 0; 267 virtual const DWARFSection& getAppleNamespacesSection() = 0; 268 virtual const DWARFSection& getAppleObjCSection() = 0; 269 virtual StringRef getCUIndexSection() = 0; 270 virtual StringRef getGdbIndexSection() = 0; 271 virtual StringRef getTUIndexSection() = 0; 272 273 static bool isSupportedVersion(unsigned version) { 274 return version == 2 || version == 3 || version == 4 || version == 5; 275 } 276 277 std::shared_ptr<DWARFContext> getDWOContext(StringRef AbsolutePath); 278 279 private: 280 /// Return the compile unit that includes an offset (relative to .debug_info). 281 DWARFCompileUnit *getCompileUnitForOffset(uint32_t Offset); 282 283 /// Return the compile unit which contains instruction with provided 284 /// address. 285 DWARFCompileUnit *getCompileUnitForAddress(uint64_t Address); 286 }; 287 288 /// DWARFContextInMemory is the simplest possible implementation of a 289 /// DWARFContext. It assumes all content is available in memory and stores 290 /// pointers to it. 291 class DWARFContextInMemory : public DWARFContext { 292 virtual void anchor(); 293 294 StringRef FileName; 295 bool IsLittleEndian; 296 uint8_t AddressSize; 297 DWARFSection InfoSection; 298 TypeSectionMap TypesSections; 299 StringRef AbbrevSection; 300 DWARFSection LocSection; 301 StringRef ARangeSection; 302 StringRef DebugFrameSection; 303 StringRef EHFrameSection; 304 DWARFSection LineSection; 305 StringRef StringSection; 306 DWARFSection RangeSection; 307 StringRef MacinfoSection; 308 StringRef PubNamesSection; 309 StringRef PubTypesSection; 310 StringRef GnuPubNamesSection; 311 StringRef GnuPubTypesSection; 312 313 /// DWARF v5 314 /// @{ 315 DWARFSection StringOffsetSection; 316 /// @} 317 318 // Sections for DWARF5 split dwarf proposal. 319 DWARFSection InfoDWOSection; 320 TypeSectionMap TypesDWOSections; 321 StringRef AbbrevDWOSection; 322 DWARFSection LineDWOSection; 323 DWARFSection LocDWOSection; 324 StringRef StringDWOSection; 325 DWARFSection StringOffsetDWOSection; 326 DWARFSection RangeDWOSection; 327 DWARFSection AddrSection; 328 DWARFSection AppleNamesSection; 329 DWARFSection AppleTypesSection; 330 DWARFSection AppleNamespacesSection; 331 DWARFSection AppleObjCSection; 332 StringRef CUIndexSection; 333 StringRef GdbIndexSection; 334 StringRef TUIndexSection; 335 336 SmallVector<SmallString<32>, 4> UncompressedSections; 337 338 StringRef *MapSectionToMember(StringRef Name); 339 340 /// If Sec is compressed section, decompresses and updates its contents 341 /// provided by Data. Otherwise leaves it unchanged. 342 Error maybeDecompress(const object::SectionRef &Sec, StringRef Name, 343 StringRef &Data); 344 345 public: 346 DWARFContextInMemory(const object::ObjectFile &Obj, 347 const LoadedObjectInfo *L = nullptr); 348 349 DWARFContextInMemory(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections, 350 uint8_t AddrSize, 351 bool isLittleEndian = sys::IsLittleEndianHost); 352 353 StringRef getFileName() const override { return FileName; } 354 bool isLittleEndian() const override { return IsLittleEndian; } 355 uint8_t getAddressSize() const override { return AddressSize; } 356 const DWARFSection &getInfoSection() override { return InfoSection; } 357 const TypeSectionMap &getTypesSections() override { return TypesSections; } 358 StringRef getAbbrevSection() override { return AbbrevSection; } 359 const DWARFSection &getLocSection() override { return LocSection; } 360 StringRef getARangeSection() override { return ARangeSection; } 361 StringRef getDebugFrameSection() override { return DebugFrameSection; } 362 StringRef getEHFrameSection() override { return EHFrameSection; } 363 const DWARFSection &getLineSection() override { return LineSection; } 364 StringRef getStringSection() override { return StringSection; } 365 const DWARFSection &getRangeSection() override { return RangeSection; } 366 StringRef getMacinfoSection() override { return MacinfoSection; } 367 StringRef getPubNamesSection() override { return PubNamesSection; } 368 StringRef getPubTypesSection() override { return PubTypesSection; } 369 StringRef getGnuPubNamesSection() override { return GnuPubNamesSection; } 370 StringRef getGnuPubTypesSection() override { return GnuPubTypesSection; } 371 const DWARFSection& getAppleNamesSection() override { return AppleNamesSection; } 372 const DWARFSection& getAppleTypesSection() override { return AppleTypesSection; } 373 const DWARFSection& getAppleNamespacesSection() override { return AppleNamespacesSection; } 374 const DWARFSection& getAppleObjCSection() override { return AppleObjCSection; } 375 376 // DWARF v5 377 const DWARFSection &getStringOffsetSection() override { 378 return StringOffsetSection; 379 } 380 381 // Sections for DWARF5 split dwarf proposal. 382 const DWARFSection &getInfoDWOSection() override { return InfoDWOSection; } 383 384 const TypeSectionMap &getTypesDWOSections() override { 385 return TypesDWOSections; 386 } 387 388 StringRef getAbbrevDWOSection() override { return AbbrevDWOSection; } 389 const DWARFSection &getLineDWOSection() override { return LineDWOSection; } 390 const DWARFSection &getLocDWOSection() override { return LocDWOSection; } 391 StringRef getStringDWOSection() override { return StringDWOSection; } 392 393 const DWARFSection &getStringOffsetDWOSection() override { 394 return StringOffsetDWOSection; 395 } 396 397 const DWARFSection &getRangeDWOSection() override { return RangeDWOSection; } 398 399 const DWARFSection &getAddrSection() override { return AddrSection; } 400 401 StringRef getCUIndexSection() override { return CUIndexSection; } 402 StringRef getGdbIndexSection() override { return GdbIndexSection; } 403 StringRef getTUIndexSection() override { return TUIndexSection; } 404 }; 405 406 } // end namespace llvm 407 408 #endif // LLVM_DEBUGINFO_DWARF_DWARFCONTEXT_H 409