1 //===-- LVLocation.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 LVOperation and LVLocation classes, which are used
10 // to describe variable locations.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVLOCATION_H
15 #define LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVLOCATION_H
16 
17 #include "llvm/DebugInfo/LogicalView/Core/LVObject.h"
18 
19 namespace llvm {
20 namespace logicalview {
21 
22 using LVLineRange = std::pair<LVLine *, LVLine *>;
23 
24 // The DW_AT_data_member_location attribute is a simple member offset.
25 const LVSmall LVLocationMemberOffset = 0;
26 
27 class LVOperation final {
28   // To describe an operation:
29   // OpCode
30   // Operands[0]: First operand.
31   // Operands[1]: Second operand.
32   //   OP_bregx, OP_bit_piece, OP_[GNU_]const_type,
33   //   OP_[GNU_]deref_type, OP_[GNU_]entry_value, OP_implicit_value,
34   //   OP_[GNU_]implicit_pointer, OP_[GNU_]regval_type, OP_xderef_type.
35   LVSmall Opcode = 0;
36   uint64_t Operands[2];
37 
38 public:
39   LVOperation() = delete;
40   LVOperation(LVSmall Opcode, LVUnsigned Operand1, LVUnsigned Operand2)
41       : Opcode(Opcode) {
42     Operands[0] = Operand1;
43     Operands[1] = Operand2;
44   }
45   LVOperation(const LVOperation &) = delete;
46   LVOperation &operator=(const LVOperation &) = delete;
47   ~LVOperation() = default;
48 
49   LVSmall getOpcode() const { return Opcode; }
50   uint64_t getOperand1() const { return Operands[0]; }
51   uint64_t getOperand2() const { return Operands[1]; }
52   std::string getOperandsDWARFInfo();
53   std::string getOperandsCodeViewInfo();
54 
55   void print(raw_ostream &OS, bool Full = true) const;
56 
57 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
58   void dump() { print(dbgs()); }
59 #endif
60 };
61 
62 class LVLocation : public LVObject {
63   enum class Property {
64     IsAddressRange,
65     IsBaseClassOffset,
66     IsBaseClassStep,
67     IsClassOffset,
68     IsFixedAddress,
69     IsLocationSimple,
70     IsGapEntry,
71     IsOperation,
72     IsOperationList,
73     IsRegister,
74     IsStackOffset,
75     IsDiscardedRange,
76     IsInvalidRange,
77     IsInvalidLower,
78     IsInvalidUpper,
79     IsCallSite,
80     LastEntry
81   };
82   // Typed bitvector with properties for this location.
83   LVProperties<Property> Properties;
84 
85   // True if the location it is associated with a debug range.
86   bool hasAssociatedRange() const {
87     return !getIsClassOffset() && !getIsDiscardedRange();
88   }
89 
90 protected:
91   // Line numbers associated with locations ranges.
92   LVLine *LowerLine = nullptr;
93   LVLine *UpperLine = nullptr;
94 
95   // Active range:
96   // LowPC: an offset from an applicable base address, not a PC value.
97   // HighPC: an offset from an applicable base address, or a length.
98   LVAddress LowPC = 0;
99   LVAddress HighPC = 0;
100 
101   void setKind();
102 
103 public:
104   LVLocation() : LVObject() { setIsLocation(); }
105   LVLocation(const LVLocation &) = delete;
106   LVLocation &operator=(const LVLocation &) = delete;
107   virtual ~LVLocation() = default;
108 
109   PROPERTY(Property, IsAddressRange);
110   PROPERTY(Property, IsBaseClassOffset);
111   PROPERTY(Property, IsBaseClassStep);
112   PROPERTY_1(Property, IsClassOffset, IsLocationSimple);
113   PROPERTY_1(Property, IsFixedAddress, IsLocationSimple);
114   PROPERTY(Property, IsLocationSimple);
115   PROPERTY(Property, IsGapEntry);
116   PROPERTY(Property, IsOperationList);
117   PROPERTY(Property, IsOperation);
118   PROPERTY(Property, IsRegister);
119   PROPERTY_1(Property, IsStackOffset, IsLocationSimple);
120   PROPERTY(Property, IsDiscardedRange);
121   PROPERTY(Property, IsInvalidRange);
122   PROPERTY(Property, IsInvalidLower);
123   PROPERTY(Property, IsInvalidUpper);
124   PROPERTY(Property, IsCallSite);
125 
126   const char *kind() const override;
127   // Mark the locations that have only DW_OP_fbreg as stack offset based.
128   virtual void updateKind() {}
129 
130   // Line numbers for locations.
131   const LVLine *getLowerLine() const { return LowerLine; }
132   void setLowerLine(LVLine *Line) { LowerLine = Line; }
133   const LVLine *getUpperLine() const { return UpperLine; }
134   void setUpperLine(LVLine *Line) { UpperLine = Line; }
135 
136   // Addresses for locations.
137   LVAddress getLowerAddress() const override { return LowPC; }
138   void setLowerAddress(LVAddress Address) override { LowPC = Address; }
139   LVAddress getUpperAddress() const override { return HighPC; }
140   void setUpperAddress(LVAddress Address) override { HighPC = Address; }
141 
142   std::string getIntervalInfo() const;
143 
144   bool validateRanges();
145 
146   // In order to calculate a symbol coverage (percentage), take the ranges
147   // and obtain the number of units (bytes) covered by those ranges. We can't
148   // use the line numbers, because they can be zero or invalid.
149   // We return:
150   //   false: No locations or multiple locations.
151   //   true: a single location.
152   static bool calculateCoverage(LVLocations *Locations, unsigned &Factor,
153                                 float &Percentage);
154 
155   virtual void addObject(LVAddress LowPC, LVAddress HighPC,
156                          LVUnsigned SectionOffset, uint64_t LocDescOffset) {}
157   virtual void addObject(LVSmall Opcode, LVUnsigned Operand1,
158                          LVUnsigned Operand2) {}
159 
160   static void print(LVLocations *Locations, raw_ostream &OS, bool Full = true);
161   void printInterval(raw_ostream &OS, bool Full = true) const;
162   void printRaw(raw_ostream &OS, bool Full = true) const;
163   virtual void printRawExtra(raw_ostream &OS, bool Full = true) const {}
164 
165   void print(raw_ostream &OS, bool Full = true) const override;
166   void printExtra(raw_ostream &OS, bool Full = true) const override;
167 
168 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
169   void dump() const override { print(dbgs()); }
170 #endif
171 };
172 
173 class LVLocationSymbol final : public LVLocation {
174   // Location descriptors for the active range.
175   LVAutoOperations *Entries = nullptr;
176 
177   void updateKind() override;
178 
179 public:
180   LVLocationSymbol() : LVLocation() {}
181   LVLocationSymbol(const LVLocationSymbol &) = delete;
182   LVLocationSymbol &operator=(const LVLocationSymbol &) = delete;
183   ~LVLocationSymbol() { delete Entries; };
184 
185   void addObject(LVAddress LowPC, LVAddress HighPC, LVUnsigned SectionOffset,
186                  uint64_t LocDescOffset) override;
187   void addObject(LVSmall Opcode, LVUnsigned Operand1,
188                  LVUnsigned Operand2) override;
189 
190   void printRawExtra(raw_ostream &OS, bool Full = true) const override;
191   void printExtra(raw_ostream &OS, bool Full = true) const override;
192 };
193 
194 } // end namespace logicalview
195 } // end namespace llvm
196 
197 #endif // LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVLOCATION_H
198