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 #include <vector> 26 27 namespace llvm { 28 29 // In place of applying the relocations to the data we've read from disk we use 30 // a separate mapping table to the side and checking that at locations in the 31 // dwarf where we expect relocated values. This adds a bit of complexity to the 32 // dwarf parsing/extraction at the benefit of not allocating memory for the 33 // entire size of the debug info sections. 34 typedef DenseMap<uint64_t, std::pair<uint8_t, int64_t> > RelocAddrMap; 35 36 /// DWARFContext 37 /// This data structure is the top level entity that deals with dwarf debug 38 /// information parsing. The actual data is supplied through pure virtual 39 /// methods that a concrete implementation provides. 40 class DWARFContext : public DIContext { 41 42 DWARFUnitSection<DWARFCompileUnit> CUs; 43 std::vector<DWARFUnitSection<DWARFTypeUnit>> TUs; 44 std::unique_ptr<DWARFUnitIndex> CUIndex; 45 std::unique_ptr<DWARFUnitIndex> TUIndex; 46 std::unique_ptr<DWARFDebugAbbrev> Abbrev; 47 std::unique_ptr<DWARFDebugLoc> Loc; 48 std::unique_ptr<DWARFDebugAranges> Aranges; 49 std::unique_ptr<DWARFDebugLine> Line; 50 std::unique_ptr<DWARFDebugFrame> DebugFrame; 51 std::unique_ptr<DWARFDebugMacro> Macro; 52 53 DWARFUnitSection<DWARFCompileUnit> DWOCUs; 54 std::vector<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) override; 85 86 typedef DWARFUnitSection<DWARFCompileUnit>::iterator_range cu_iterator_range; 87 typedef DWARFUnitSection<DWARFTypeUnit>::iterator_range tu_iterator_range; 88 typedef iterator_range<std::vector<DWARFUnitSection<DWARFTypeUnit>>::iterator> tu_section_iterator_range; 89 90 /// Get compile units in this context. 91 cu_iterator_range compile_units() { 92 parseCompileUnits(); 93 return cu_iterator_range(CUs.begin(), CUs.end()); 94 } 95 96 /// Get type units in this context. 97 tu_section_iterator_range type_unit_sections() { 98 parseTypeUnits(); 99 return tu_section_iterator_range(TUs.begin(), TUs.end()); 100 } 101 102 /// Get compile units in the DWO context. 103 cu_iterator_range dwo_compile_units() { 104 parseDWOCompileUnits(); 105 return cu_iterator_range(DWOCUs.begin(), DWOCUs.end()); 106 } 107 108 /// Get type units in the DWO context. 109 tu_section_iterator_range dwo_type_unit_sections() { 110 parseDWOTypeUnits(); 111 return tu_section_iterator_range(DWOTUs.begin(), DWOTUs.end()); 112 } 113 114 /// Get the number of compile units in this context. 115 unsigned getNumCompileUnits() { 116 parseCompileUnits(); 117 return CUs.size(); 118 } 119 120 /// Get the number of compile units in this context. 121 unsigned getNumTypeUnits() { 122 parseTypeUnits(); 123 return TUs.size(); 124 } 125 126 /// Get the number of compile units in the DWO context. 127 unsigned getNumDWOCompileUnits() { 128 parseDWOCompileUnits(); 129 return DWOCUs.size(); 130 } 131 132 /// Get the number of compile units in the DWO context. 133 unsigned getNumDWOTypeUnits() { 134 parseDWOTypeUnits(); 135 return DWOTUs.size(); 136 } 137 138 /// Get the compile unit at the specified index for this compile unit. 139 DWARFCompileUnit *getCompileUnitAtIndex(unsigned index) { 140 parseCompileUnits(); 141 return CUs[index].get(); 142 } 143 144 /// Get the compile unit at the specified index for the DWO compile units. 145 DWARFCompileUnit *getDWOCompileUnitAtIndex(unsigned index) { 146 parseDWOCompileUnits(); 147 return DWOCUs[index].get(); 148 } 149 150 const DWARFUnitIndex &getCUIndex(); 151 const DWARFUnitIndex &getTUIndex(); 152 153 /// Get a pointer to the parsed DebugAbbrev object. 154 const DWARFDebugAbbrev *getDebugAbbrev(); 155 156 /// Get a pointer to the parsed DebugLoc object. 157 const DWARFDebugLoc *getDebugLoc(); 158 159 /// Get a pointer to the parsed dwo abbreviations object. 160 const DWARFDebugAbbrev *getDebugAbbrevDWO(); 161 162 /// Get a pointer to the parsed DebugLoc object. 163 const DWARFDebugLocDWO *getDebugLocDWO(); 164 165 /// Get a pointer to the parsed DebugAranges object. 166 const DWARFDebugAranges *getDebugAranges(); 167 168 /// Get a pointer to the parsed frame information object. 169 const DWARFDebugFrame *getDebugFrame(); 170 171 /// Get a pointer to the parsed DebugMacro object. 172 const DWARFDebugMacro *getDebugMacro(); 173 174 /// Get a pointer to a parsed line table corresponding to a compile unit. 175 const DWARFDebugLine::LineTable *getLineTableForUnit(DWARFUnit *cu); 176 177 DILineInfo getLineInfoForAddress(uint64_t Address, 178 DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override; 179 DILineInfoTable getLineInfoForAddressRange(uint64_t Address, uint64_t Size, 180 DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override; 181 DIInliningInfo getInliningInfoForAddress(uint64_t Address, 182 DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override; 183 184 virtual bool isLittleEndian() const = 0; 185 virtual uint8_t getAddressSize() const = 0; 186 virtual const DWARFSection &getInfoSection() = 0; 187 typedef MapVector<object::SectionRef, DWARFSection, 188 std::map<object::SectionRef, unsigned>> TypeSectionMap; 189 virtual const TypeSectionMap &getTypesSections() = 0; 190 virtual StringRef getAbbrevSection() = 0; 191 virtual const DWARFSection &getLocSection() = 0; 192 virtual StringRef getARangeSection() = 0; 193 virtual StringRef getDebugFrameSection() = 0; 194 virtual const DWARFSection &getLineSection() = 0; 195 virtual StringRef getStringSection() = 0; 196 virtual StringRef getRangeSection() = 0; 197 virtual StringRef getMacinfoSection() = 0; 198 virtual StringRef getPubNamesSection() = 0; 199 virtual StringRef getPubTypesSection() = 0; 200 virtual StringRef getGnuPubNamesSection() = 0; 201 virtual StringRef getGnuPubTypesSection() = 0; 202 203 // Sections for DWARF5 split dwarf proposal. 204 virtual const DWARFSection &getInfoDWOSection() = 0; 205 virtual const TypeSectionMap &getTypesDWOSections() = 0; 206 virtual StringRef getAbbrevDWOSection() = 0; 207 virtual const DWARFSection &getLineDWOSection() = 0; 208 virtual const DWARFSection &getLocDWOSection() = 0; 209 virtual StringRef getStringDWOSection() = 0; 210 virtual StringRef getStringOffsetDWOSection() = 0; 211 virtual StringRef getRangeDWOSection() = 0; 212 virtual StringRef getAddrSection() = 0; 213 virtual const DWARFSection& getAppleNamesSection() = 0; 214 virtual const DWARFSection& getAppleTypesSection() = 0; 215 virtual const DWARFSection& getAppleNamespacesSection() = 0; 216 virtual const DWARFSection& getAppleObjCSection() = 0; 217 virtual StringRef getCUIndexSection() = 0; 218 virtual StringRef getTUIndexSection() = 0; 219 220 static bool isSupportedVersion(unsigned version) { 221 return version == 2 || version == 3 || version == 4; 222 } 223 private: 224 /// Return the compile unit that includes an offset (relative to .debug_info). 225 DWARFCompileUnit *getCompileUnitForOffset(uint32_t Offset); 226 227 /// Return the compile unit which contains instruction with provided 228 /// address. 229 DWARFCompileUnit *getCompileUnitForAddress(uint64_t Address); 230 }; 231 232 /// DWARFContextInMemory is the simplest possible implementation of a 233 /// DWARFContext. It assumes all content is available in memory and stores 234 /// pointers to it. 235 class DWARFContextInMemory : public DWARFContext { 236 virtual void anchor(); 237 bool IsLittleEndian; 238 uint8_t AddressSize; 239 DWARFSection InfoSection; 240 TypeSectionMap TypesSections; 241 StringRef AbbrevSection; 242 DWARFSection LocSection; 243 StringRef ARangeSection; 244 StringRef DebugFrameSection; 245 DWARFSection LineSection; 246 StringRef StringSection; 247 StringRef RangeSection; 248 StringRef MacinfoSection; 249 StringRef PubNamesSection; 250 StringRef PubTypesSection; 251 StringRef GnuPubNamesSection; 252 StringRef GnuPubTypesSection; 253 254 // Sections for DWARF5 split dwarf proposal. 255 DWARFSection InfoDWOSection; 256 TypeSectionMap TypesDWOSections; 257 StringRef AbbrevDWOSection; 258 DWARFSection LineDWOSection; 259 DWARFSection LocDWOSection; 260 StringRef StringDWOSection; 261 StringRef StringOffsetDWOSection; 262 StringRef RangeDWOSection; 263 StringRef AddrSection; 264 DWARFSection AppleNamesSection; 265 DWARFSection AppleTypesSection; 266 DWARFSection AppleNamespacesSection; 267 DWARFSection AppleObjCSection; 268 StringRef CUIndexSection; 269 StringRef TUIndexSection; 270 271 SmallVector<SmallString<32>, 4> UncompressedSections; 272 273 public: 274 DWARFContextInMemory(const object::ObjectFile &Obj, 275 const LoadedObjectInfo *L = nullptr); 276 bool isLittleEndian() const override { return IsLittleEndian; } 277 uint8_t getAddressSize() const override { return AddressSize; } 278 const DWARFSection &getInfoSection() override { return InfoSection; } 279 const TypeSectionMap &getTypesSections() override { return TypesSections; } 280 StringRef getAbbrevSection() override { return AbbrevSection; } 281 const DWARFSection &getLocSection() override { return LocSection; } 282 StringRef getARangeSection() override { return ARangeSection; } 283 StringRef getDebugFrameSection() override { return DebugFrameSection; } 284 const DWARFSection &getLineSection() override { return LineSection; } 285 StringRef getStringSection() override { return StringSection; } 286 StringRef getRangeSection() override { return RangeSection; } 287 StringRef getMacinfoSection() override { return MacinfoSection; } 288 StringRef getPubNamesSection() override { return PubNamesSection; } 289 StringRef getPubTypesSection() override { return PubTypesSection; } 290 StringRef getGnuPubNamesSection() override { return GnuPubNamesSection; } 291 StringRef getGnuPubTypesSection() override { return GnuPubTypesSection; } 292 const DWARFSection& getAppleNamesSection() override { return AppleNamesSection; } 293 const DWARFSection& getAppleTypesSection() override { return AppleTypesSection; } 294 const DWARFSection& getAppleNamespacesSection() override { return AppleNamespacesSection; } 295 const DWARFSection& getAppleObjCSection() override { return AppleObjCSection; } 296 297 // Sections for DWARF5 split dwarf proposal. 298 const DWARFSection &getInfoDWOSection() override { return InfoDWOSection; } 299 const TypeSectionMap &getTypesDWOSections() override { 300 return TypesDWOSections; 301 } 302 StringRef getAbbrevDWOSection() override { return AbbrevDWOSection; } 303 const DWARFSection &getLineDWOSection() override { return LineDWOSection; } 304 const DWARFSection &getLocDWOSection() override { return LocDWOSection; } 305 StringRef getStringDWOSection() override { return StringDWOSection; } 306 StringRef getStringOffsetDWOSection() override { 307 return StringOffsetDWOSection; 308 } 309 StringRef getRangeDWOSection() override { return RangeDWOSection; } 310 StringRef getAddrSection() override { 311 return AddrSection; 312 } 313 StringRef getCUIndexSection() override { return CUIndexSection; } 314 StringRef getTUIndexSection() override { return TUIndexSection; } 315 }; 316 317 } 318 319 #endif 320