LLVM API Documentation
00001 //===-- DWARFUnit.h ---------------------------------------------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 00010 #ifndef LLVM_LIB_DEBUGINFO_DWARFUNIT_H 00011 #define LLVM_LIB_DEBUGINFO_DWARFUNIT_H 00012 00013 #include "DWARFDebugAbbrev.h" 00014 #include "DWARFDebugInfoEntry.h" 00015 #include "DWARFDebugRangeList.h" 00016 #include "DWARFRelocMap.h" 00017 #include <vector> 00018 00019 namespace llvm { 00020 00021 namespace object { 00022 class ObjectFile; 00023 } 00024 00025 class DWARFContext; 00026 class DWARFDebugAbbrev; 00027 class StringRef; 00028 class raw_ostream; 00029 class DWARFUnit; 00030 00031 /// Base class for all DWARFUnitSection classes. This provides the 00032 /// functionality common to all unit types. 00033 class DWARFUnitSectionBase { 00034 public: 00035 /// Returns the Unit that contains the given section offset in the 00036 /// same section this Unit originated from. 00037 virtual DWARFUnit *getUnitForOffset(uint32_t Offset) const = 0; 00038 00039 protected: 00040 ~DWARFUnitSectionBase() {} 00041 }; 00042 00043 /// Concrete instance of DWARFUnitSection, specialized for one Unit type. 00044 template<typename UnitType> 00045 class DWARFUnitSection final : public SmallVector<std::unique_ptr<UnitType>, 1>, 00046 public DWARFUnitSectionBase { 00047 00048 struct UnitOffsetComparator { 00049 bool operator()(const std::unique_ptr<UnitType> &LHS, 00050 const std::unique_ptr<UnitType> &RHS) const { 00051 return LHS->getOffset() < RHS->getOffset(); 00052 } 00053 bool operator()(const std::unique_ptr<UnitType> &LHS, 00054 uint32_t RHS) const { 00055 return LHS->getOffset() < RHS; 00056 } 00057 bool operator()(uint32_t LHS, 00058 const std::unique_ptr<UnitType> &RHS) const { 00059 return LHS < RHS->getOffset(); 00060 } 00061 }; 00062 00063 public: 00064 typedef llvm::SmallVectorImpl<std::unique_ptr<UnitType>> UnitVector; 00065 typedef typename UnitVector::iterator iterator; 00066 typedef llvm::iterator_range<typename UnitVector::iterator> iterator_range; 00067 00068 UnitType *getUnitForOffset(uint32_t Offset) const { 00069 auto *CU = std::lower_bound(this->begin(), this->end(), Offset, 00070 UnitOffsetComparator()); 00071 if (CU != this->end()) 00072 return CU->get(); 00073 return nullptr; 00074 } 00075 }; 00076 00077 class DWARFUnit { 00078 DWARFContext &Context; 00079 00080 const DWARFDebugAbbrev *Abbrev; 00081 StringRef InfoSection; 00082 StringRef RangeSection; 00083 uint32_t RangeSectionBase; 00084 StringRef StringSection; 00085 StringRef StringOffsetSection; 00086 StringRef AddrOffsetSection; 00087 uint32_t AddrOffsetSectionBase; 00088 const RelocAddrMap *RelocMap; 00089 bool isLittleEndian; 00090 const DWARFUnitSectionBase &UnitSection; 00091 00092 uint32_t Offset; 00093 uint32_t Length; 00094 uint16_t Version; 00095 const DWARFAbbreviationDeclarationSet *Abbrevs; 00096 uint8_t AddrSize; 00097 uint64_t BaseAddr; 00098 // The compile unit debug information entry items. 00099 std::vector<DWARFDebugInfoEntryMinimal> DieArray; 00100 00101 class DWOHolder { 00102 object::OwningBinary<object::ObjectFile> DWOFile; 00103 std::unique_ptr<DWARFContext> DWOContext; 00104 DWARFUnit *DWOU; 00105 public: 00106 DWOHolder(StringRef DWOPath); 00107 DWARFUnit *getUnit() const { return DWOU; } 00108 }; 00109 std::unique_ptr<DWOHolder> DWO; 00110 00111 protected: 00112 virtual bool extractImpl(DataExtractor debug_info, uint32_t *offset_ptr); 00113 /// Size in bytes of the unit header. 00114 virtual uint32_t getHeaderSize() const { return 11; } 00115 00116 public: 00117 DWARFUnit(DWARFContext& Context, const DWARFDebugAbbrev *DA, StringRef IS, 00118 StringRef RS, StringRef SS, StringRef SOS, StringRef AOS, 00119 const RelocAddrMap *M, bool LE, const DWARFUnitSectionBase &UnitSection); 00120 00121 virtual ~DWARFUnit(); 00122 00123 DWARFContext& getContext() const { return Context; } 00124 00125 StringRef getStringSection() const { return StringSection; } 00126 StringRef getStringOffsetSection() const { return StringOffsetSection; } 00127 void setAddrOffsetSection(StringRef AOS, uint32_t Base) { 00128 AddrOffsetSection = AOS; 00129 AddrOffsetSectionBase = Base; 00130 } 00131 void setRangesSection(StringRef RS, uint32_t Base) { 00132 RangeSection = RS; 00133 RangeSectionBase = Base; 00134 } 00135 00136 bool getAddrOffsetSectionItem(uint32_t Index, uint64_t &Result) const; 00137 // FIXME: Result should be uint64_t in DWARF64. 00138 bool getStringOffsetSectionItem(uint32_t Index, uint32_t &Result) const; 00139 00140 DataExtractor getDebugInfoExtractor() const { 00141 return DataExtractor(InfoSection, isLittleEndian, AddrSize); 00142 } 00143 DataExtractor getStringExtractor() const { 00144 return DataExtractor(StringSection, false, 0); 00145 } 00146 00147 const RelocAddrMap *getRelocMap() const { return RelocMap; } 00148 00149 bool extract(DataExtractor debug_info, uint32_t* offset_ptr); 00150 00151 /// extractRangeList - extracts the range list referenced by this compile 00152 /// unit from .debug_ranges section. Returns true on success. 00153 /// Requires that compile unit is already extracted. 00154 bool extractRangeList(uint32_t RangeListOffset, 00155 DWARFDebugRangeList &RangeList) const; 00156 void clear(); 00157 uint32_t getOffset() const { return Offset; } 00158 uint32_t getNextUnitOffset() const { return Offset + Length + 4; } 00159 uint32_t getLength() const { return Length; } 00160 uint16_t getVersion() const { return Version; } 00161 const DWARFAbbreviationDeclarationSet *getAbbreviations() const { 00162 return Abbrevs; 00163 } 00164 uint8_t getAddressByteSize() const { return AddrSize; } 00165 uint64_t getBaseAddress() const { return BaseAddr; } 00166 00167 void setBaseAddress(uint64_t base_addr) { 00168 BaseAddr = base_addr; 00169 } 00170 00171 const DWARFDebugInfoEntryMinimal * 00172 getCompileUnitDIE(bool extract_cu_die_only = true) { 00173 extractDIEsIfNeeded(extract_cu_die_only); 00174 return DieArray.empty() ? nullptr : &DieArray[0]; 00175 } 00176 00177 const char *getCompilationDir(); 00178 uint64_t getDWOId(); 00179 00180 void collectAddressRanges(DWARFAddressRangesVector &CURanges); 00181 00182 /// getInlinedChainForAddress - fetches inlined chain for a given address. 00183 /// Returns empty chain if there is no subprogram containing address. The 00184 /// chain is valid as long as parsed compile unit DIEs are not cleared. 00185 DWARFDebugInfoEntryInlinedChain getInlinedChainForAddress(uint64_t Address); 00186 00187 /// getUnitSection - Return the DWARFUnitSection containing this unit. 00188 const DWARFUnitSectionBase &getUnitSection() const { return UnitSection; } 00189 00190 private: 00191 /// Size in bytes of the .debug_info data associated with this compile unit. 00192 size_t getDebugInfoSize() const { return Length + 4 - getHeaderSize(); } 00193 00194 /// extractDIEsIfNeeded - Parses a compile unit and indexes its DIEs if it 00195 /// hasn't already been done. Returns the number of DIEs parsed at this call. 00196 size_t extractDIEsIfNeeded(bool CUDieOnly); 00197 /// extractDIEsToVector - Appends all parsed DIEs to a vector. 00198 void extractDIEsToVector(bool AppendCUDie, bool AppendNonCUDIEs, 00199 std::vector<DWARFDebugInfoEntryMinimal> &DIEs) const; 00200 /// setDIERelations - We read in all of the DIE entries into our flat list 00201 /// of DIE entries and now we need to go back through all of them and set the 00202 /// parent, sibling and child pointers for quick DIE navigation. 00203 void setDIERelations(); 00204 /// clearDIEs - Clear parsed DIEs to keep memory usage low. 00205 void clearDIEs(bool KeepCUDie); 00206 00207 /// parseDWO - Parses .dwo file for current compile unit. Returns true if 00208 /// it was actually constructed. 00209 bool parseDWO(); 00210 00211 /// getSubprogramForAddress - Returns subprogram DIE with address range 00212 /// encompassing the provided address. The pointer is alive as long as parsed 00213 /// compile unit DIEs are not cleared. 00214 const DWARFDebugInfoEntryMinimal *getSubprogramForAddress(uint64_t Address); 00215 }; 00216 00217 } 00218 00219 #endif