//===-- LVELFReader.h -------------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file defines the LVELFReader class, which is used to describe a // debug information (DWARF) reader. // //===----------------------------------------------------------------------===// #ifndef LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVELFREADER_H #define LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVELFREADER_H #include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h" #include "llvm/DebugInfo/DWARF/DWARFContext.h" #include "llvm/DebugInfo/LogicalView/Readers/LVBinaryReader.h" #include namespace llvm { namespace logicalview { class LVElement; class LVLine; class LVScopeCompileUnit; class LVSymbol; class LVType; using AttributeSpec = DWARFAbbreviationDeclaration::AttributeSpec; class LVELFReader final : public LVBinaryReader { object::ObjectFile &Obj; // Indicates if ranges data are available; in the case of split DWARF any // reference to ranges is valid only if the skeleton DIE has been loaded. bool RangesDataAvailable = false; LVAddress CUBaseAddress = 0; LVAddress CUHighAddress = 0; // Current elements during the processing of a DIE. LVElement *CurrentElement = nullptr; LVScope *CurrentScope = nullptr; LVSymbol *CurrentSymbol = nullptr; LVType *CurrentType = nullptr; LVOffset CurrentOffset = 0; LVOffset CurrentEndOffset = 0; // In DWARF v4, the files are 1-indexed. // In DWARF v5, the files are 0-indexed. // The ELF reader expects the indexes as 1-indexed. bool IncrementFileIndex = false; // Address ranges collected for current DIE. std::vector CurrentRanges; // Symbols with locations for current compile unit. LVSymbols SymbolsWithLocations; // Global Offsets (Offset, Element). LVOffsetElementMap GlobalOffsets; // Low PC and High PC values for DIE being processed. LVAddress CurrentLowPC = 0; LVAddress CurrentHighPC = 0; bool FoundLowPC = false; bool FoundHighPC = false; // Cross references (Elements). using LVElementSet = std::unordered_set; struct LVElementEntry { LVElement *Element; LVElementSet References; LVElementSet Types; LVElementEntry(LVElement *Element = nullptr) : Element(Element) {} }; using LVElementReference = std::unordered_map; LVElementReference ElementTable; Error loadTargetInfo(const object::ObjectFile &Obj); void mapRangeAddress(const object::ObjectFile &Obj) override; LVElement *createElement(dwarf::Tag Tag); void traverseDieAndChildren(DWARFDie &DIE, LVScope *Parent, DWARFDie &SkeletonDie); // Process the attributes for the given DIE. LVScope *processOneDie(const DWARFDie &InputDIE, LVScope *Parent, DWARFDie &SkeletonDie); void processOneAttribute(const DWARFDie &Die, LVOffset *OffsetPtr, const AttributeSpec &AttrSpec); void createLineAndFileRecords(const DWARFDebugLine::LineTable *Lines); void processLocationGaps(); // Add offset to global map. void addGlobalOffset(LVOffset Offset) { if (GlobalOffsets.find(Offset) == GlobalOffsets.end()) // Just associate the DIE offset with a null element, as we do not // know if the referenced element has been created. GlobalOffsets.emplace(Offset, nullptr); } // Remove offset from global map. void removeGlobalOffset(LVOffset Offset) { LVOffsetElementMap::iterator Iter = GlobalOffsets.find(Offset); if (Iter != GlobalOffsets.end()) GlobalOffsets.erase(Iter); } // Get the location information for DW_AT_data_member_location. void processLocationMember(dwarf::Attribute Attr, const DWARFFormValue &FormValue, const DWARFDie &Die, uint64_t OffsetOnEntry); void processLocationList(dwarf::Attribute Attr, const DWARFFormValue &FormValue, const DWARFDie &Die, uint64_t OffsetOnEntry, bool CallSiteLocation = false); void updateReference(dwarf::Attribute Attr, const DWARFFormValue &FormValue); // Get an element given the DIE offset. LVElement *getElementForOffset(LVOffset offset, LVElement *Element, bool IsType); protected: Error createScopes() override; void sortScopes() override; public: LVELFReader() = delete; LVELFReader(StringRef Filename, StringRef FileFormatName, object::ObjectFile &Obj, ScopedPrinter &W) : LVBinaryReader(Filename, FileFormatName, W, LVBinaryType::ELF), Obj(Obj) {} LVELFReader(const LVELFReader &) = delete; LVELFReader &operator=(const LVELFReader &) = delete; ~LVELFReader() = default; LVAddress getCUBaseAddress() const { return CUBaseAddress; } void setCUBaseAddress(LVAddress Address) { CUBaseAddress = Address; } LVAddress getCUHighAddress() const { return CUHighAddress; } void setCUHighAddress(LVAddress Address) { CUHighAddress = Address; } const LVSymbols &GetSymbolsWithLocations() const { return SymbolsWithLocations; } std::string getRegisterName(LVSmall Opcode, ArrayRef Operands) override; void print(raw_ostream &OS) const; #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) void dump() const { print(dbgs()); } #endif }; } // end namespace logicalview } // end namespace llvm #endif // LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVELFREADER_H