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 LVOffset CurrentEndOffset = 0; 43 44 // In DWARF v4, the files are 1-indexed. 45 // In DWARF v5, the files are 0-indexed. 46 // The DWARF reader expects the indexes as 1-indexed. 47 bool IncrementFileIndex = false; 48 49 // Symbols with locations for current compile unit. 50 LVSymbols SymbolsWithLocations; 51 52 // Global Offsets (Offset, Element). 53 LVOffsetElementMap GlobalOffsets; 54 55 // Low PC and High PC values for DIE being processed. 56 LVAddress CurrentLowPC = 0; 57 LVAddress CurrentHighPC = 0; 58 bool FoundLowPC = false; 59 bool FoundHighPC = false; 60 61 // The value is updated for each Compile Unit that is processed. 62 std::optional<LVAddress> TombstoneAddress; 63 64 // Cross references (Elements). 65 using LVElementSet = std::unordered_set<LVElement *>; 66 struct LVElementEntry { 67 LVElement *Element; 68 LVElementSet References; 69 LVElementSet Types; ElementLVElementEntry70 LVElementEntry(LVElement *Element = nullptr) : Element(Element) {} 71 }; 72 using LVElementReference = std::unordered_map<LVOffset, LVElementEntry>; 73 LVElementReference ElementTable; 74 75 Error loadTargetInfo(const object::ObjectFile &Obj); 76 77 void mapRangeAddress(const object::ObjectFile &Obj) override; 78 79 void traverseDieAndChildren(DWARFDie &DIE, LVScope *Parent, 80 DWARFDie &SkeletonDie); 81 // Process the attributes for the given DIE. 82 LVScope *processOneDie(const DWARFDie &InputDIE, LVScope *Parent, 83 DWARFDie &SkeletonDie); 84 void processOneAttribute(const DWARFDie &Die, LVOffset *OffsetPtr, 85 const AttributeSpec &AttrSpec); 86 void createLineAndFileRecords(const DWARFDebugLine::LineTable *Lines); 87 void processLocationGaps(); 88 89 // Add offset to global map. addGlobalOffset(LVOffset Offset)90 void addGlobalOffset(LVOffset Offset) { 91 if (GlobalOffsets.find(Offset) == GlobalOffsets.end()) 92 // Just associate the DIE offset with a null element, as we do not 93 // know if the referenced element has been created. 94 GlobalOffsets.emplace(Offset, nullptr); 95 } 96 97 // Remove offset from global map. removeGlobalOffset(LVOffset Offset)98 void removeGlobalOffset(LVOffset Offset) { GlobalOffsets.erase(Offset); } 99 100 // Get the location information for DW_AT_data_member_location. 101 void processLocationMember(dwarf::Attribute Attr, 102 const DWARFFormValue &FormValue, 103 const DWARFDie &Die, uint64_t OffsetOnEntry); 104 void processLocationList(dwarf::Attribute Attr, 105 const DWARFFormValue &FormValue, const DWARFDie &Die, 106 uint64_t OffsetOnEntry, 107 bool CallSiteLocation = false); 108 void updateReference(dwarf::Attribute Attr, const DWARFFormValue &FormValue); 109 110 // Get an element given the DIE offset. 111 LVElement *getElementForOffset(LVOffset offset, LVElement *Element, 112 bool IsType); 113 114 protected: 115 Error createScopes() override; 116 void sortScopes() override; 117 118 public: 119 LVDWARFReader() = delete; LVDWARFReader(StringRef Filename,StringRef FileFormatName,object::ObjectFile & Obj,ScopedPrinter & W)120 LVDWARFReader(StringRef Filename, StringRef FileFormatName, 121 object::ObjectFile &Obj, ScopedPrinter &W) 122 : LVBinaryReader(Filename, FileFormatName, W, LVBinaryType::ELF), 123 Obj(Obj) {} 124 LVDWARFReader(const LVDWARFReader &) = delete; 125 LVDWARFReader &operator=(const LVDWARFReader &) = delete; 126 ~LVDWARFReader() = default; 127 getCUBaseAddress()128 LVAddress getCUBaseAddress() const { return CUBaseAddress; } setCUBaseAddress(LVAddress Address)129 void setCUBaseAddress(LVAddress Address) { CUBaseAddress = Address; } getCUHighAddress()130 LVAddress getCUHighAddress() const { return CUHighAddress; } setCUHighAddress(LVAddress Address)131 void setCUHighAddress(LVAddress Address) { CUHighAddress = Address; } 132 setTombstoneAddress(LVAddress Address)133 void setTombstoneAddress(LVAddress Address) { TombstoneAddress = Address; } getTombstoneAddress()134 LVAddress getTombstoneAddress() const { 135 assert(TombstoneAddress && "Unset tombstone value"); 136 return TombstoneAddress.value(); 137 } 138 GetSymbolsWithLocations()139 const LVSymbols &GetSymbolsWithLocations() const { 140 return SymbolsWithLocations; 141 } 142 143 std::string getRegisterName(LVSmall Opcode, 144 ArrayRef<uint64_t> Operands) override; 145 146 void print(raw_ostream &OS) const; 147 148 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) dump()149 void dump() const { print(dbgs()); } 150 #endif 151 }; 152 153 } // end namespace logicalview 154 } // end namespace llvm 155 156 #endif // LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVDWARFREADER_H 157