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 |