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