Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 14 | pmbaty | 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. |
||
| 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. |
||
| 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; |
||
| 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 | |||
| 133 | LVAddress getCUBaseAddress() const { return CUBaseAddress; } |
||
| 134 | void setCUBaseAddress(LVAddress Address) { CUBaseAddress = Address; } |
||
| 135 | LVAddress getCUHighAddress() const { return CUHighAddress; } |
||
| 136 | void setCUHighAddress(LVAddress Address) { CUHighAddress = Address; } |
||
| 137 | |||
| 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) |
||
| 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 |