xref: /openbsd-src/gnu/llvm/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVELFReader.h (revision d415bd752c734aee168c4ee86ff32e8cc249eb16)
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