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/Error.h" 38#include "llvm/Support/Host.h" 39#include <cstdint> 40#include <deque> 41#include <map> 42#include <memory> 43 44namespace llvm { 45 46class DataExtractor; 47class MCRegisterInfo; 48class MemoryBuffer; 49class 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. 54enum 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. 59class DWARFContext : public DIContext { 60 DWARFUnitSection<DWARFCompileUnit> CUs; 61 std::deque<DWARFUnitSection<DWARFTypeUnit>> TUs; 62 std::unique_ptr<DWARFUnitIndex> CUIndex; 63 std::unique_ptr<DWARFGdbIndex> GdbIndex; 64 std::unique_ptr<DWARFUnitIndex> TUIndex; 65 std::unique_ptr<DWARFDebugAbbrev> Abbrev; 66 std::unique_ptr<DWARFDebugLoc> Loc; 67 std::unique_ptr<DWARFDebugAranges> Aranges; 68 std::unique_ptr<DWARFDebugLine> Line; 69 std::unique_ptr<DWARFDebugFrame> DebugFrame; 70 std::unique_ptr<DWARFDebugFrame> EHFrame; 71 std::unique_ptr<DWARFDebugMacro> Macro; 72 std::unique_ptr<DWARFAcceleratorTable> AppleNames; 73 std::unique_ptr<DWARFAcceleratorTable> AppleTypes; 74 std::unique_ptr<DWARFAcceleratorTable> AppleNamespaces; 75 std::unique_ptr<DWARFAcceleratorTable> AppleObjC; 76 77 DWARFUnitSection<DWARFCompileUnit> DWOCUs; 78 std::deque<DWARFUnitSection<DWARFTypeUnit>> DWOTUs; 79 std::unique_ptr<DWARFDebugAbbrev> AbbrevDWO; 80 std::unique_ptr<DWARFDebugLocDWO> LocDWO; 81 82 /// The maximum DWARF version of all units. 83 unsigned MaxVersion = 0; 84 85 struct DWOFile { 86 object::OwningBinary<object::ObjectFile> File; 87 std::unique_ptr<DWARFContext> Context; 88 }; 89 StringMap<std::weak_ptr<DWOFile>> DWOFiles; 90 std::weak_ptr<DWOFile> DWP; 91 bool CheckedForDWP = false; 92 std::string DWPName; 93 94 std::unique_ptr<MCRegisterInfo> RegInfo; 95 96 /// Read compile units from the debug_info section (if necessary) 97 /// and store them in CUs. 98 void parseCompileUnits(); 99 100 /// Read type units from the debug_types sections (if necessary) 101 /// and store them in TUs. 102 void parseTypeUnits(); 103 104 /// Read compile units from the debug_info.dwo section (if necessary) 105 /// and store them in DWOCUs. 106 void parseDWOCompileUnits(); 107 108 /// Read type units from the debug_types.dwo section (if necessary) 109 /// and store them in DWOTUs. 110 void parseDWOTypeUnits(); 111 112protected: 113 std::unique_ptr<const DWARFObject> DObj; 114 115public: 116 DWARFContext(std::unique_ptr<const DWARFObject> DObj, 117 std::string DWPName = ""); 118 ~DWARFContext(); 119 120 DWARFContext(DWARFContext &) = delete; 121 DWARFContext &operator=(DWARFContext &) = delete; 122 123 const DWARFObject &getDWARFObj() const { return *DObj; } 124 125 static bool classof(const DIContext *DICtx) { 126 return DICtx->getKind() == CK_DWARF; 127 } 128 129 /// Dump a textual representation to \p OS. If any \p DumpOffsets are present, 130 /// dump only the record at the specified offset. 131 void dump(raw_ostream &OS, DIDumpOptions DumpOpts, 132 std::array<Optional<uint64_t>, DIDT_ID_Count> DumpOffsets); 133 134 void dump(raw_ostream &OS, DIDumpOptions DumpOpts) override { 135 std::array<Optional<uint64_t>, DIDT_ID_Count> DumpOffsets; 136 dump(OS, DumpOpts, DumpOffsets); 137 } 138 139 bool verify(raw_ostream &OS, DIDumpOptions DumpOpts = {}) override; 140 141 using cu_iterator_range = DWARFUnitSection<DWARFCompileUnit>::iterator_range; 142 using tu_iterator_range = DWARFUnitSection<DWARFTypeUnit>::iterator_range; 143 using tu_section_iterator_range = iterator_range<decltype(TUs)::iterator>; 144 145 /// Get compile units in this context. 146 cu_iterator_range compile_units() { 147 parseCompileUnits(); 148 return cu_iterator_range(CUs.begin(), CUs.end()); 149 } 150 151 /// Get type units in this context. 152 tu_section_iterator_range type_unit_sections() { 153 parseTypeUnits(); 154 return tu_section_iterator_range(TUs.begin(), TUs.end()); 155 } 156 157 /// Get compile units in the DWO context. 158 cu_iterator_range dwo_compile_units() { 159 parseDWOCompileUnits(); 160 return cu_iterator_range(DWOCUs.begin(), DWOCUs.end()); 161 } 162 163 /// Get type units in the DWO context. 164 tu_section_iterator_range dwo_type_unit_sections() { 165 parseDWOTypeUnits(); 166 return tu_section_iterator_range(DWOTUs.begin(), DWOTUs.end()); 167 } 168 169 /// Get the number of compile units in this context. 170 unsigned getNumCompileUnits() { 171 parseCompileUnits(); 172 return CUs.size(); 173 } 174 175 /// Get the number of compile units in this context. 176 unsigned getNumTypeUnits() { 177 parseTypeUnits(); 178 return TUs.size(); 179 } 180 181 /// Get the number of compile units in the DWO context. 182 unsigned getNumDWOCompileUnits() { 183 parseDWOCompileUnits(); 184 return DWOCUs.size(); 185 } 186 187 /// Get the number of compile units in the DWO context. 188 unsigned getNumDWOTypeUnits() { 189 parseDWOTypeUnits(); 190 return DWOTUs.size(); 191 } 192 193 /// Get the compile unit at the specified index for this compile unit. 194 DWARFCompileUnit *getCompileUnitAtIndex(unsigned index) { 195 parseCompileUnits(); 196 return CUs[index].get(); 197 } 198 199 /// Get the compile unit at the specified index for the DWO compile units. 200 DWARFCompileUnit *getDWOCompileUnitAtIndex(unsigned index) { 201 parseDWOCompileUnits(); 202 return DWOCUs[index].get(); 203 } 204 205 DWARFCompileUnit *getDWOCompileUnitForHash(uint64_t Hash); 206 207 /// Get a DIE given an exact offset. 208 DWARFDie getDIEForOffset(uint32_t Offset); 209 210 unsigned getMaxVersion() const { return MaxVersion; } 211 212 void setMaxVersionIfGreater(unsigned Version) { 213 if (Version > MaxVersion) 214 MaxVersion = Version; 215 } 216 217 const DWARFUnitIndex &getCUIndex(); 218 DWARFGdbIndex &getGdbIndex(); 219 const DWARFUnitIndex &getTUIndex(); 220 221 /// Get a pointer to the parsed DebugAbbrev object. 222 const DWARFDebugAbbrev *getDebugAbbrev(); 223 224 /// Get a pointer to the parsed DebugLoc object. 225 const DWARFDebugLoc *getDebugLoc(); 226 227 /// Get a pointer to the parsed dwo abbreviations object. 228 const DWARFDebugAbbrev *getDebugAbbrevDWO(); 229 230 /// Get a pointer to the parsed DebugLoc object. 231 const DWARFDebugLocDWO *getDebugLocDWO(); 232 233 /// Get a pointer to the parsed DebugAranges object. 234 const DWARFDebugAranges *getDebugAranges(); 235 236 /// Get a pointer to the parsed frame information object. 237 const DWARFDebugFrame *getDebugFrame(); 238 239 /// Get a pointer to the parsed eh frame information object. 240 const DWARFDebugFrame *getEHFrame(); 241 242 /// Get a pointer to the parsed DebugMacro object. 243 const DWARFDebugMacro *getDebugMacro(); 244 245 /// Get a reference to the parsed accelerator table object. 246 const DWARFAcceleratorTable &getAppleNames(); 247 248 /// Get a reference to the parsed accelerator table object. 249 const DWARFAcceleratorTable &getAppleTypes(); 250 251 /// Get a reference to the parsed accelerator table object. 252 const DWARFAcceleratorTable &getAppleNamespaces(); 253 254 /// Get a reference to the parsed accelerator table object. 255 const DWARFAcceleratorTable &getAppleObjC(); 256 257 /// Get a pointer to a parsed line table corresponding to a compile unit. 258 const DWARFDebugLine::LineTable *getLineTableForUnit(DWARFUnit *cu); 259 260 DILineInfo getLineInfoForAddress(uint64_t Address, 261 DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override; 262 DILineInfoTable getLineInfoForAddressRange(uint64_t Address, uint64_t Size, 263 DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override; 264 DIInliningInfo getInliningInfoForAddress(uint64_t Address, 265 DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override; 266 267 bool isLittleEndian() const { return DObj->isLittleEndian(); } 268 static bool isSupportedVersion(unsigned version) { 269 return version == 2 || version == 3 || version == 4 || version == 5; 270 } 271 272 std::shared_ptr<DWARFContext> getDWOContext(StringRef AbsolutePath); 273 274 const MCRegisterInfo *getRegisterInfo() const { return RegInfo.get(); } 275 276 /// Function used to handle default error reporting policy. Prints a error 277 /// message and returns Continue, so DWARF context ignores the error. 278 static ErrorPolicy defaultErrorHandler(Error E); 279 static std::unique_ptr<DWARFContext> 280 create(const object::ObjectFile &Obj, const LoadedObjectInfo *L = nullptr, 281 function_ref<ErrorPolicy(Error)> HandleError = defaultErrorHandler, 282 std::string DWPName = ""); 283 284 static std::unique_ptr<DWARFContext> 285 create(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections, 286 uint8_t AddrSize, bool isLittleEndian = sys::IsLittleEndianHost); 287 288 /// Loads register info for the architecture of the provided object file. 289 /// Improves readability of dumped DWARF expressions. Requires the caller to 290 /// have initialized the relevant target descriptions. 291 Error loadRegisterInfo(const object::ObjectFile &Obj); 292 293private: 294 /// Return the compile unit that includes an offset (relative to .debug_info). 295 DWARFCompileUnit *getCompileUnitForOffset(uint32_t Offset); 296 297 /// Return the compile unit which contains instruction with provided 298 /// address. 299 DWARFCompileUnit *getCompileUnitForAddress(uint64_t Address); 300}; 301 302} // end namespace llvm 303 304#endif // LLVM_DEBUGINFO_DWARF_DWARFCONTEXT_H 305