1 //===-- LVELFReader.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 LVELFReader class, which is used to describe a 10 // debug information (DWARF) reader. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVELFREADER_H 15 #define LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVELFREADER_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 LVELFReader 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 ELF 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 using LVElementEntry = std::pair<LVElement *, LVElementSet>; 73 using LVElementReference = std::unordered_map<LVOffset, LVElementEntry>; 74 LVElementReference ElementTable; 75 76 Error loadTargetInfo(const object::ObjectFile &Obj); 77 78 void mapRangeAddress(const object::ObjectFile &Obj) override; 79 80 LVElement *createElement(dwarf::Tag Tag); 81 void traverseDieAndChildren(DWARFDie &DIE, LVScope *Parent, 82 DWARFDie &SkeletonDie); 83 // Process the attributes for the given DIE. 84 LVScope *processOneDie(const DWARFDie &InputDIE, LVScope *Parent, 85 DWARFDie &SkeletonDie); 86 void processOneAttribute(const DWARFDie &Die, LVOffset *OffsetPtr, 87 const AttributeSpec &AttrSpec); 88 void createLineAndFileRecords(const DWARFDebugLine::LineTable *Lines); 89 void processLocationGaps(); 90 91 // Add offset to global map. addGlobalOffset(LVOffset Offset)92 void addGlobalOffset(LVOffset Offset) { 93 if (GlobalOffsets.find(Offset) == GlobalOffsets.end()) 94 // Just associate the DIE offset with a null element, as we do not 95 // know if the referenced element has been created. 96 GlobalOffsets.emplace(Offset, nullptr); 97 } 98 99 // Remove offset from global map. removeGlobalOffset(LVOffset Offset)100 void removeGlobalOffset(LVOffset Offset) { 101 LVOffsetElementMap::iterator Iter = GlobalOffsets.find(Offset); 102 if (Iter != GlobalOffsets.end()) 103 GlobalOffsets.erase(Iter); 104 } 105 106 // Get the location information for DW_AT_data_member_location. 107 void processLocationMember(dwarf::Attribute Attr, 108 const DWARFFormValue &FormValue, 109 const DWARFDie &Die, uint64_t OffsetOnEntry); 110 void processLocationList(dwarf::Attribute Attr, 111 const DWARFFormValue &FormValue, const DWARFDie &Die, 112 uint64_t OffsetOnEntry, 113 bool CallSiteLocation = false); 114 void updateReference(dwarf::Attribute Attr, const DWARFFormValue &FormValue); 115 116 // Get an element given the DIE offset. 117 LVElement *getElementForOffset(LVOffset offset, LVElement *Element); 118 119 protected: 120 Error createScopes() override; 121 void sortScopes() override; 122 123 public: 124 LVELFReader() = delete; LVELFReader(StringRef Filename,StringRef FileFormatName,object::ObjectFile & Obj,ScopedPrinter & W)125 LVELFReader(StringRef Filename, StringRef FileFormatName, 126 object::ObjectFile &Obj, ScopedPrinter &W) 127 : LVBinaryReader(Filename, FileFormatName, W, LVBinaryType::ELF), 128 Obj(Obj) {} 129 LVELFReader(const LVELFReader &) = delete; 130 LVELFReader &operator=(const LVELFReader &) = delete; 131 ~LVELFReader() = default; 132 getCUBaseAddress()133 LVAddress getCUBaseAddress() const { return CUBaseAddress; } setCUBaseAddress(LVAddress Address)134 void setCUBaseAddress(LVAddress Address) { CUBaseAddress = Address; } getCUHighAddress()135 LVAddress getCUHighAddress() const { return CUHighAddress; } setCUHighAddress(LVAddress Address)136 void setCUHighAddress(LVAddress Address) { CUHighAddress = Address; } 137 GetSymbolsWithLocations()138 const LVSymbols &GetSymbolsWithLocations() const { 139 return SymbolsWithLocations; 140 } 141 142 std::string getRegisterName(LVSmall Opcode, uint64_t Operands[2]) override; 143 144 void print(raw_ostream &OS) const; 145 146 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) dump()147 void dump() const { print(dbgs()); } 148 #endif 149 }; 150 151 } // end namespace logicalview 152 } // end namespace llvm 153 154 #endif // LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVELFREADER_H 155