xref: /llvm-project/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVDWARFReader.h (revision 9c0c98ed376f8705d0856f29a7ec659120187612)
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