Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 14 | pmbaty | 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 |