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