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/MapVector.h" 14 #include "llvm/ADT/SmallString.h" 15 #include "llvm/ADT/SmallVector.h" 16 #include "llvm/ADT/StringMap.h" 17 #include "llvm/ADT/StringRef.h" 18 #include "llvm/ADT/iterator_range.h" 19 #include "llvm/DebugInfo/DIContext.h" 20 #include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.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/DWARFDie.h" 29 #include "llvm/DebugInfo/DWARF/DWARFGdbIndex.h" 30 #include "llvm/DebugInfo/DWARF/DWARFObject.h" 31 #include "llvm/DebugInfo/DWARF/DWARFSection.h" 32 #include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h" 33 #include "llvm/DebugInfo/DWARF/DWARFUnit.h" 34 #include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h" 35 #include "llvm/Object/Binary.h" 36 #include "llvm/Object/ObjectFile.h" 37 #include "llvm/Support/DataExtractor.h" 38 #include "llvm/Support/Error.h" 39 #include "llvm/Support/Host.h" 40 #include <cstdint> 41 #include <deque> 42 #include <map> 43 #include <memory> 44 45 namespace llvm { 46 47 class MCRegisterInfo; 48 class MemoryBuffer; 49 class raw_ostream; 50 51 /// Used as a return value for a error callback passed to DWARF context. 52 /// Callback should return Halt if client application wants to stop 53 /// object parsing, or should return Continue otherwise. 54 enum class ErrorPolicy { Halt, Continue }; 55 56 /// DWARFContext 57 /// This data structure is the top level entity that deals with dwarf debug 58 /// information parsing. The actual data is supplied through DWARFObj. 59 class DWARFContext : public DIContext { 60 DWARFUnitVector NormalUnits; 61 std::unique_ptr<DWARFUnitIndex> CUIndex; 62 std::unique_ptr<DWARFGdbIndex> GdbIndex; 63 std::unique_ptr<DWARFUnitIndex> TUIndex; 64 std::unique_ptr<DWARFDebugAbbrev> Abbrev; 65 std::unique_ptr<DWARFDebugLoc> Loc; 66 std::unique_ptr<DWARFDebugAranges> Aranges; 67 std::unique_ptr<DWARFDebugLine> Line; 68 std::unique_ptr<DWARFDebugFrame> DebugFrame; 69 std::unique_ptr<DWARFDebugFrame> EHFrame; 70 std::unique_ptr<DWARFDebugMacro> Macro; 71 std::unique_ptr<DWARFDebugNames> Names; 72 std::unique_ptr<AppleAcceleratorTable> AppleNames; 73 std::unique_ptr<AppleAcceleratorTable> AppleTypes; 74 std::unique_ptr<AppleAcceleratorTable> AppleNamespaces; 75 std::unique_ptr<AppleAcceleratorTable> AppleObjC; 76 77 DWARFUnitVector DWOUnits; 78 std::unique_ptr<DWARFDebugAbbrev> AbbrevDWO; 79 std::unique_ptr<DWARFDebugLoclists> LocDWO; 80 81 /// The maximum DWARF version of all units. 82 unsigned MaxVersion = 0; 83 84 struct DWOFile { 85 object::OwningBinary<object::ObjectFile> File; 86 std::unique_ptr<DWARFContext> Context; 87 }; 88 StringMap<std::weak_ptr<DWOFile>> DWOFiles; 89 std::weak_ptr<DWOFile> DWP; 90 bool CheckedForDWP = false; 91 std::string DWPName; 92 93 std::unique_ptr<MCRegisterInfo> RegInfo; 94 95 /// Read compile units from the debug_info section (if necessary) 96 /// and type units from the debug_types sections (if necessary) 97 /// and store them in NormalUnits. 98 void parseNormalUnits(); 99 100 /// Read compile units from the debug_info.dwo section (if necessary) 101 /// and type units from the debug_types.dwo section (if necessary) 102 /// and store them in DWOUnits. 103 /// If \p Lazy is true, set up to parse but don't actually parse them. 104 enum { EagerParse = false, LazyParse = true }; 105 void parseDWOUnits(bool Lazy = false); 106 107 std::unique_ptr<const DWARFObject> DObj; 108 109 public: 110 DWARFContext(std::unique_ptr<const DWARFObject> DObj, 111 std::string DWPName = ""); 112 ~DWARFContext(); 113 114 DWARFContext(DWARFContext &) = delete; 115 DWARFContext &operator=(DWARFContext &) = delete; 116 getDWARFObj()117 const DWARFObject &getDWARFObj() const { return *DObj; } 118 classof(const DIContext * DICtx)119 static bool classof(const DIContext *DICtx) { 120 return DICtx->getKind() == CK_DWARF; 121 } 122 123 /// Dump a textual representation to \p OS. If any \p DumpOffsets are present, 124 /// dump only the record at the specified offset. 125 void dump(raw_ostream &OS, DIDumpOptions DumpOpts, 126 std::array<Optional<uint64_t>, DIDT_ID_Count> DumpOffsets); 127 dump(raw_ostream & OS,DIDumpOptions DumpOpts)128 void dump(raw_ostream &OS, DIDumpOptions DumpOpts) override { 129 std::array<Optional<uint64_t>, DIDT_ID_Count> DumpOffsets; 130 dump(OS, DumpOpts, DumpOffsets); 131 } 132 133 bool verify(raw_ostream &OS, DIDumpOptions DumpOpts = {}) override; 134 135 using unit_iterator_range = DWARFUnitVector::iterator_range; 136 137 /// Get units from .debug_info in this context. info_section_units()138 unit_iterator_range info_section_units() { 139 parseNormalUnits(); 140 return unit_iterator_range(NormalUnits.begin(), 141 NormalUnits.begin() + 142 NormalUnits.getNumInfoUnits()); 143 } 144 145 /// Get units from .debug_types in this context. types_section_units()146 unit_iterator_range types_section_units() { 147 parseNormalUnits(); 148 return unit_iterator_range( 149 NormalUnits.begin() + NormalUnits.getNumInfoUnits(), NormalUnits.end()); 150 } 151 152 /// Get compile units in this context. compile_units()153 unit_iterator_range compile_units() { return info_section_units(); } 154 155 /// Get type units in this context. type_units()156 unit_iterator_range type_units() { return types_section_units(); } 157 158 /// Get all normal compile/type units in this context. normal_units()159 unit_iterator_range normal_units() { 160 parseNormalUnits(); 161 return unit_iterator_range(NormalUnits.begin(), NormalUnits.end()); 162 } 163 164 /// Get units from .debug_info..dwo in the DWO context. dwo_info_section_units()165 unit_iterator_range dwo_info_section_units() { 166 parseDWOUnits(); 167 return unit_iterator_range(DWOUnits.begin(), 168 DWOUnits.begin() + DWOUnits.getNumInfoUnits()); 169 } 170 171 /// Get units from .debug_types.dwo in the DWO context. dwo_types_section_units()172 unit_iterator_range dwo_types_section_units() { 173 parseDWOUnits(); 174 return unit_iterator_range(DWOUnits.begin() + DWOUnits.getNumInfoUnits(), 175 DWOUnits.end()); 176 } 177 178 /// Get compile units in the DWO context. dwo_compile_units()179 unit_iterator_range dwo_compile_units() { return dwo_info_section_units(); } 180 181 /// Get type units in the DWO context. dwo_type_units()182 unit_iterator_range dwo_type_units() { return dwo_types_section_units(); } 183 184 /// Get all units in the DWO context. dwo_units()185 unit_iterator_range dwo_units() { 186 parseDWOUnits(); 187 return unit_iterator_range(DWOUnits.begin(), DWOUnits.end()); 188 } 189 190 /// Get the number of compile units in this context. getNumCompileUnits()191 unsigned getNumCompileUnits() { 192 parseNormalUnits(); 193 return NormalUnits.getNumInfoUnits(); 194 } 195 196 /// Get the number of type units in this context. getNumTypeUnits()197 unsigned getNumTypeUnits() { 198 parseNormalUnits(); 199 return NormalUnits.getNumTypesUnits(); 200 } 201 202 /// Get the number of compile units in the DWO context. getNumDWOCompileUnits()203 unsigned getNumDWOCompileUnits() { 204 parseDWOUnits(); 205 return DWOUnits.getNumInfoUnits(); 206 } 207 208 /// Get the number of type units in the DWO context. getNumDWOTypeUnits()209 unsigned getNumDWOTypeUnits() { 210 parseDWOUnits(); 211 return DWOUnits.getNumTypesUnits(); 212 } 213 214 /// Get the unit at the specified index. getUnitAtIndex(unsigned index)215 DWARFUnit *getUnitAtIndex(unsigned index) { 216 parseNormalUnits(); 217 return NormalUnits[index].get(); 218 } 219 220 /// Get the unit at the specified index for the DWO units. getDWOUnitAtIndex(unsigned index)221 DWARFUnit *getDWOUnitAtIndex(unsigned index) { 222 parseDWOUnits(); 223 return DWOUnits[index].get(); 224 } 225 226 DWARFCompileUnit *getDWOCompileUnitForHash(uint64_t Hash); 227 228 /// Return the compile unit that includes an offset (relative to .debug_info). 229 DWARFCompileUnit *getCompileUnitForOffset(uint32_t Offset); 230 231 /// Get a DIE given an exact offset. 232 DWARFDie getDIEForOffset(uint32_t Offset); 233 getMaxVersion()234 unsigned getMaxVersion() { 235 // Ensure info units have been parsed to discover MaxVersion 236 info_section_units(); 237 return MaxVersion; 238 } 239 getMaxDWOVersion()240 unsigned getMaxDWOVersion() { 241 // Ensure DWO info units have been parsed to discover MaxVersion 242 dwo_info_section_units(); 243 return MaxVersion; 244 } 245 setMaxVersionIfGreater(unsigned Version)246 void setMaxVersionIfGreater(unsigned Version) { 247 if (Version > MaxVersion) 248 MaxVersion = Version; 249 } 250 251 const DWARFUnitIndex &getCUIndex(); 252 DWARFGdbIndex &getGdbIndex(); 253 const DWARFUnitIndex &getTUIndex(); 254 255 /// Get a pointer to the parsed DebugAbbrev object. 256 const DWARFDebugAbbrev *getDebugAbbrev(); 257 258 /// Get a pointer to the parsed DebugLoc object. 259 const DWARFDebugLoc *getDebugLoc(); 260 261 /// Get a pointer to the parsed dwo abbreviations object. 262 const DWARFDebugAbbrev *getDebugAbbrevDWO(); 263 264 /// Get a pointer to the parsed DebugLoc object. 265 const DWARFDebugLoclists *getDebugLocDWO(); 266 267 /// Get a pointer to the parsed DebugAranges object. 268 const DWARFDebugAranges *getDebugAranges(); 269 270 /// Get a pointer to the parsed frame information object. 271 const DWARFDebugFrame *getDebugFrame(); 272 273 /// Get a pointer to the parsed eh frame information object. 274 const DWARFDebugFrame *getEHFrame(); 275 276 /// Get a pointer to the parsed DebugMacro object. 277 const DWARFDebugMacro *getDebugMacro(); 278 279 /// Get a reference to the parsed accelerator table object. 280 const DWARFDebugNames &getDebugNames(); 281 282 /// Get a reference to the parsed accelerator table object. 283 const AppleAcceleratorTable &getAppleNames(); 284 285 /// Get a reference to the parsed accelerator table object. 286 const AppleAcceleratorTable &getAppleTypes(); 287 288 /// Get a reference to the parsed accelerator table object. 289 const AppleAcceleratorTable &getAppleNamespaces(); 290 291 /// Get a reference to the parsed accelerator table object. 292 const AppleAcceleratorTable &getAppleObjC(); 293 294 /// Get a pointer to a parsed line table corresponding to a compile unit. 295 /// Report any parsing issues as warnings on stderr. 296 const DWARFDebugLine::LineTable *getLineTableForUnit(DWARFUnit *U); 297 298 /// Get a pointer to a parsed line table corresponding to a compile unit. 299 /// Report any recoverable parsing problems using the callback. 300 Expected<const DWARFDebugLine::LineTable *> 301 getLineTableForUnit(DWARFUnit *U, 302 std::function<void(Error)> RecoverableErrorCallback); 303 getStringExtractor()304 DataExtractor getStringExtractor() const { 305 return DataExtractor(DObj->getStringSection(), false, 0); 306 } getLineStringExtractor()307 DataExtractor getLineStringExtractor() const { 308 return DataExtractor(DObj->getLineStringSection(), false, 0); 309 } 310 311 /// Wraps the returned DIEs for a given address. 312 struct DIEsForAddress { 313 DWARFCompileUnit *CompileUnit = nullptr; 314 DWARFDie FunctionDIE; 315 DWARFDie BlockDIE; 316 explicit operator bool() const { return CompileUnit != nullptr; } 317 }; 318 319 /// Get the compilation unit, the function DIE and lexical block DIE for the 320 /// given address where applicable. 321 DIEsForAddress getDIEsForAddress(uint64_t Address); 322 323 DILineInfo getLineInfoForAddress(uint64_t Address, 324 DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override; 325 DILineInfoTable getLineInfoForAddressRange(uint64_t Address, uint64_t Size, 326 DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override; 327 DIInliningInfo getInliningInfoForAddress(uint64_t Address, 328 DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override; 329 isLittleEndian()330 bool isLittleEndian() const { return DObj->isLittleEndian(); } isSupportedVersion(unsigned version)331 static bool isSupportedVersion(unsigned version) { 332 return version == 2 || version == 3 || version == 4 || version == 5; 333 } 334 335 std::shared_ptr<DWARFContext> getDWOContext(StringRef AbsolutePath); 336 getRegisterInfo()337 const MCRegisterInfo *getRegisterInfo() const { return RegInfo.get(); } 338 339 /// Function used to handle default error reporting policy. Prints a error 340 /// message and returns Continue, so DWARF context ignores the error. 341 static ErrorPolicy defaultErrorHandler(Error E); 342 static std::unique_ptr<DWARFContext> 343 create(const object::ObjectFile &Obj, const LoadedObjectInfo *L = nullptr, 344 function_ref<ErrorPolicy(Error)> HandleError = defaultErrorHandler, 345 std::string DWPName = ""); 346 347 static std::unique_ptr<DWARFContext> 348 create(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections, 349 uint8_t AddrSize, bool isLittleEndian = sys::IsLittleEndianHost); 350 351 /// Loads register info for the architecture of the provided object file. 352 /// Improves readability of dumped DWARF expressions. Requires the caller to 353 /// have initialized the relevant target descriptions. 354 Error loadRegisterInfo(const object::ObjectFile &Obj); 355 356 /// Get address size from CUs. 357 /// TODO: refactor compile_units() to make this const. 358 uint8_t getCUAddrSize(); 359 360 /// Dump Error as warning message to stderr. 361 static void dumpWarning(Error Warning); 362 getArch()363 Triple::ArchType getArch() const { 364 return getDWARFObj().getFile()->getArch(); 365 } 366 367 private: 368 /// Return the compile unit which contains instruction with provided 369 /// address. 370 DWARFCompileUnit *getCompileUnitForAddress(uint64_t Address); 371 }; 372 373 } // end namespace llvm 374 375 #endif // LLVM_DEBUGINFO_DWARF_DWARFCONTEXT_H 376