1 //===-- LVDWARFReader.h -----------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file defines the LVDWARFReader class, which is used to describe a 10 // debug information (DWARF) reader. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVDWARFREADER_H 15 #define LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVDWARFREADER_H 16 17 #include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h" 18 #include "llvm/DebugInfo/DWARF/DWARFContext.h" 19 #include "llvm/DebugInfo/LogicalView/Readers/LVBinaryReader.h" 20 #include <unordered_set> 21 22 namespace llvm { 23 namespace logicalview { 24 25 class LVElement; 26 class LVLine; 27 class LVScopeCompileUnit; 28 class LVSymbol; 29 class LVType; 30 31 using AttributeSpec = DWARFAbbreviationDeclaration::AttributeSpec; 32 33 class LVDWARFReader final : public LVBinaryReader { 34 object::ObjectFile &Obj; 35 36 // Indicates if ranges data are available; in the case of split DWARF any 37 // reference to ranges is valid only if the skeleton DIE has been loaded. 38 bool RangesDataAvailable = false; 39 LVAddress CUBaseAddress = 0; 40 LVAddress CUHighAddress = 0; 41 42 // Current elements during the processing of a DIE. 43 LVElement *CurrentElement = nullptr; 44 LVScope *CurrentScope = nullptr; 45 LVSymbol *CurrentSymbol = nullptr; 46 LVType *CurrentType = nullptr; 47 LVOffset CurrentOffset = 0; 48 LVOffset CurrentEndOffset = 0; 49 50 // In DWARF v4, the files are 1-indexed. 51 // In DWARF v5, the files are 0-indexed. 52 // The DWARF reader expects the indexes as 1-indexed. 53 bool IncrementFileIndex = false; 54 55 // Address ranges collected for current DIE. 56 std::vector<LVAddressRange> CurrentRanges; 57 58 // Symbols with locations for current compile unit. 59 LVSymbols SymbolsWithLocations; 60 61 // Global Offsets (Offset, Element). 62 LVOffsetElementMap GlobalOffsets; 63 64 // Low PC and High PC values for DIE being processed. 65 LVAddress CurrentLowPC = 0; 66 LVAddress CurrentHighPC = 0; 67 bool FoundLowPC = false; 68 bool FoundHighPC = false; 69 70 // Cross references (Elements). 71 using LVElementSet = std::unordered_set<LVElement *>; 72 struct LVElementEntry { 73 LVElement *Element; 74 LVElementSet References; 75 LVElementSet Types; ElementLVElementEntry76 LVElementEntry(LVElement *Element = nullptr) : Element(Element) {} 77 }; 78 using LVElementReference = std::unordered_map<LVOffset, LVElementEntry>; 79 LVElementReference ElementTable; 80 81 Error loadTargetInfo(const object::ObjectFile &Obj); 82 83 void mapRangeAddress(const object::ObjectFile &Obj) override; 84 85 LVElement *createElement(dwarf::Tag Tag); 86 void traverseDieAndChildren(DWARFDie &DIE, LVScope *Parent, 87 DWARFDie &SkeletonDie); 88 // Process the attributes for the given DIE. 89 LVScope *processOneDie(const DWARFDie &InputDIE, LVScope *Parent, 90 DWARFDie &SkeletonDie); 91 void processOneAttribute(const DWARFDie &Die, LVOffset *OffsetPtr, 92 const AttributeSpec &AttrSpec); 93 void createLineAndFileRecords(const DWARFDebugLine::LineTable *Lines); 94 void processLocationGaps(); 95 96 // Add offset to global map. addGlobalOffset(LVOffset Offset)97 void addGlobalOffset(LVOffset Offset) { 98 if (GlobalOffsets.find(Offset) == GlobalOffsets.end()) 99 // Just associate the DIE offset with a null element, as we do not 100 // know if the referenced element has been created. 101 GlobalOffsets.emplace(Offset, nullptr); 102 } 103 104 // Remove offset from global map. removeGlobalOffset(LVOffset Offset)105 void removeGlobalOffset(LVOffset Offset) { 106 LVOffsetElementMap::iterator Iter = GlobalOffsets.find(Offset); 107 if (Iter != GlobalOffsets.end()) 108 GlobalOffsets.erase(Iter); 109 } 110 111 // Get the location information for DW_AT_data_member_location. 112 void processLocationMember(dwarf::Attribute Attr, 113 const DWARFFormValue &FormValue, 114 const DWARFDie &Die, uint64_t OffsetOnEntry); 115 void processLocationList(dwarf::Attribute Attr, 116 const DWARFFormValue &FormValue, const DWARFDie &Die, 117 uint64_t OffsetOnEntry, 118 bool CallSiteLocation = false); 119 void updateReference(dwarf::Attribute Attr, const DWARFFormValue &FormValue); 120 121 // Get an element given the DIE offset. 122 LVElement *getElementForOffset(LVOffset offset, LVElement *Element, 123 bool IsType); 124 125 protected: 126 Error createScopes() override; 127 void sortScopes() override; 128 129 public: 130 LVDWARFReader() = delete; LVDWARFReader(StringRef Filename,StringRef FileFormatName,object::ObjectFile & Obj,ScopedPrinter & W)131 LVDWARFReader(StringRef Filename, StringRef FileFormatName, 132 object::ObjectFile &Obj, ScopedPrinter &W) 133 : LVBinaryReader(Filename, FileFormatName, W, LVBinaryType::ELF), 134 Obj(Obj) {} 135 LVDWARFReader(const LVDWARFReader &) = delete; 136 LVDWARFReader &operator=(const LVDWARFReader &) = delete; 137 ~LVDWARFReader() = default; 138 getCUBaseAddress()139 LVAddress getCUBaseAddress() const { return CUBaseAddress; } setCUBaseAddress(LVAddress Address)140 void setCUBaseAddress(LVAddress Address) { CUBaseAddress = Address; } getCUHighAddress()141 LVAddress getCUHighAddress() const { return CUHighAddress; } setCUHighAddress(LVAddress Address)142 void setCUHighAddress(LVAddress Address) { CUHighAddress = Address; } 143 GetSymbolsWithLocations()144 const LVSymbols &GetSymbolsWithLocations() const { 145 return SymbolsWithLocations; 146 } 147 148 std::string getRegisterName(LVSmall Opcode, 149 ArrayRef<uint64_t> Operands) override; 150 151 void print(raw_ostream &OS) const; 152 153 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) dump()154 void dump() const { print(dbgs()); } 155 #endif 156 }; 157 158 } // end namespace logicalview 159 } // end namespace llvm 160 161 #endif // LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVDWARFREADER_H 162