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