xref: /freebsd/contrib/llvm-project/llvm/include/llvm/DebugInfo/LogicalView/Readers/LVDWARFReader.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===-- LVDWARFReader.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 LVDWARFReader class, which is used to describe a
10 // debug information (DWARF) reader.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVDWARFREADER_H
15 #define LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVDWARFREADER_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 LVDWARFReader 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   LVOffset CurrentEndOffset = 0;
43 
44   // In DWARF v4, the files are 1-indexed.
45   // In DWARF v5, the files are 0-indexed.
46   // The DWARF reader expects the indexes as 1-indexed.
47   bool IncrementFileIndex = false;
48 
49   // Symbols with locations for current compile unit.
50   LVSymbols SymbolsWithLocations;
51 
52   // Global Offsets (Offset, Element).
53   LVOffsetElementMap GlobalOffsets;
54 
55   // Low PC and High PC values for DIE being processed.
56   LVAddress CurrentLowPC = 0;
57   LVAddress CurrentHighPC = 0;
58   bool FoundLowPC = false;
59   bool FoundHighPC = false;
60 
61   // The value is updated for each Compile Unit that is processed.
62   std::optional<LVAddress> TombstoneAddress;
63 
64   // Cross references (Elements).
65   using LVElementSet = std::unordered_set<LVElement *>;
66   struct LVElementEntry {
67     LVElement *Element;
68     LVElementSet References;
69     LVElementSet Types;
ElementLVElementEntry70     LVElementEntry(LVElement *Element = nullptr) : Element(Element) {}
71   };
72   using LVElementReference = std::unordered_map<LVOffset, LVElementEntry>;
73   LVElementReference ElementTable;
74 
75   Error loadTargetInfo(const object::ObjectFile &Obj);
76 
77   void mapRangeAddress(const object::ObjectFile &Obj) override;
78 
79   void traverseDieAndChildren(DWARFDie &DIE, LVScope *Parent,
80                               DWARFDie &SkeletonDie);
81   // Process the attributes for the given DIE.
82   LVScope *processOneDie(const DWARFDie &InputDIE, LVScope *Parent,
83                          DWARFDie &SkeletonDie);
84   void processOneAttribute(const DWARFDie &Die, LVOffset *OffsetPtr,
85                            const AttributeSpec &AttrSpec);
86   void createLineAndFileRecords(const DWARFDebugLine::LineTable *Lines);
87   void processLocationGaps();
88 
89   // Add offset to global map.
addGlobalOffset(LVOffset Offset)90   void addGlobalOffset(LVOffset Offset) {
91     if (GlobalOffsets.find(Offset) == GlobalOffsets.end())
92       // Just associate the DIE offset with a null element, as we do not
93       // know if the referenced element has been created.
94       GlobalOffsets.emplace(Offset, nullptr);
95   }
96 
97   // Remove offset from global map.
removeGlobalOffset(LVOffset Offset)98   void removeGlobalOffset(LVOffset Offset) { GlobalOffsets.erase(Offset); }
99 
100   // Get the location information for DW_AT_data_member_location.
101   void processLocationMember(dwarf::Attribute Attr,
102                              const DWARFFormValue &FormValue,
103                              const DWARFDie &Die, uint64_t OffsetOnEntry);
104   void processLocationList(dwarf::Attribute Attr,
105                            const DWARFFormValue &FormValue, const DWARFDie &Die,
106                            uint64_t OffsetOnEntry,
107                            bool CallSiteLocation = false);
108   void updateReference(dwarf::Attribute Attr, const DWARFFormValue &FormValue);
109 
110   // Get an element given the DIE offset.
111   LVElement *getElementForOffset(LVOffset offset, LVElement *Element,
112                                  bool IsType);
113 
114 protected:
115   Error createScopes() override;
116   void sortScopes() override;
117 
118 public:
119   LVDWARFReader() = delete;
LVDWARFReader(StringRef Filename,StringRef FileFormatName,object::ObjectFile & Obj,ScopedPrinter & W)120   LVDWARFReader(StringRef Filename, StringRef FileFormatName,
121                 object::ObjectFile &Obj, ScopedPrinter &W)
122       : LVBinaryReader(Filename, FileFormatName, W, LVBinaryType::ELF),
123         Obj(Obj) {}
124   LVDWARFReader(const LVDWARFReader &) = delete;
125   LVDWARFReader &operator=(const LVDWARFReader &) = delete;
126   ~LVDWARFReader() = default;
127 
getCUBaseAddress()128   LVAddress getCUBaseAddress() const { return CUBaseAddress; }
setCUBaseAddress(LVAddress Address)129   void setCUBaseAddress(LVAddress Address) { CUBaseAddress = Address; }
getCUHighAddress()130   LVAddress getCUHighAddress() const { return CUHighAddress; }
setCUHighAddress(LVAddress Address)131   void setCUHighAddress(LVAddress Address) { CUHighAddress = Address; }
132 
setTombstoneAddress(LVAddress Address)133   void setTombstoneAddress(LVAddress Address) { TombstoneAddress = Address; }
getTombstoneAddress()134   LVAddress getTombstoneAddress() const {
135     assert(TombstoneAddress && "Unset tombstone value");
136     return TombstoneAddress.value();
137   }
138 
GetSymbolsWithLocations()139   const LVSymbols &GetSymbolsWithLocations() const {
140     return SymbolsWithLocations;
141   }
142 
143   std::string getRegisterName(LVSmall Opcode,
144                               ArrayRef<uint64_t> Operands) override;
145 
146   void print(raw_ostream &OS) const;
147 
148 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump()149   void dump() const { print(dbgs()); }
150 #endif
151 };
152 
153 } // end namespace logicalview
154 } // end namespace llvm
155 
156 #endif // LLVM_DEBUGINFO_LOGICALVIEW_READERS_LVDWARFREADER_H
157