DWARFExpression.h 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===--- DWARFExpression.h - DWARF Expression handling ----------*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #ifndef LLVM_DEBUGINFO_DWARF_DWARFEXPRESSION_H
  14. #define LLVM_DEBUGINFO_DWARF_DWARFEXPRESSION_H
  15. #include "llvm/ADT/ArrayRef.h"
  16. #include "llvm/ADT/Optional.h"
  17. #include "llvm/ADT/iterator.h"
  18. #include "llvm/ADT/iterator_range.h"
  19. #include "llvm/BinaryFormat/Dwarf.h"
  20. #include "llvm/DebugInfo/DIContext.h"
  21. #include "llvm/Support/DataExtractor.h"
  22. namespace llvm {
  23. class DWARFUnit;
  24. class MCRegisterInfo;
  25. class raw_ostream;
  26. class DWARFExpression {
  27. public:
  28. class iterator;
  29. /// This class represents an Operation in the Expression. Each operation can
  30. /// have up to 2 oprerands.
  31. ///
  32. /// An Operation can be in Error state (check with isError()). This
  33. /// means that it couldn't be decoded successfully and if it is the
  34. /// case, all others fields contain undefined values.
  35. class Operation {
  36. public:
  37. /// Size and signedness of expression operations' operands.
  38. enum Encoding : uint8_t {
  39. Size1 = 0,
  40. Size2 = 1,
  41. Size4 = 2,
  42. Size8 = 3,
  43. SizeLEB = 4,
  44. SizeAddr = 5,
  45. SizeRefAddr = 6,
  46. SizeBlock = 7, ///< Preceding operand contains block size
  47. BaseTypeRef = 8,
  48. WasmLocationArg = 30,
  49. SignBit = 0x80,
  50. SignedSize1 = SignBit | Size1,
  51. SignedSize2 = SignBit | Size2,
  52. SignedSize4 = SignBit | Size4,
  53. SignedSize8 = SignBit | Size8,
  54. SignedSizeLEB = SignBit | SizeLEB,
  55. SizeNA = 0xFF ///< Unused operands get this encoding.
  56. };
  57. enum DwarfVersion : uint8_t {
  58. DwarfNA, ///< Serves as a marker for unused entries
  59. Dwarf2 = 2,
  60. Dwarf3,
  61. Dwarf4,
  62. Dwarf5
  63. };
  64. /// Description of the encoding of one expression Op.
  65. struct Description {
  66. DwarfVersion Version; ///< Dwarf version where the Op was introduced.
  67. Encoding Op[2]; ///< Encoding for Op operands, or SizeNA.
  68. Description(DwarfVersion Version = DwarfNA, Encoding Op1 = SizeNA,
  69. Encoding Op2 = SizeNA)
  70. : Version(Version) {
  71. Op[0] = Op1;
  72. Op[1] = Op2;
  73. }
  74. };
  75. private:
  76. friend class DWARFExpression::iterator;
  77. uint8_t Opcode; ///< The Op Opcode, DW_OP_<something>.
  78. Description Desc;
  79. bool Error = false;
  80. uint64_t EndOffset;
  81. uint64_t Operands[2];
  82. uint64_t OperandEndOffsets[2];
  83. public:
  84. const Description &getDescription() const { return Desc; }
  85. uint8_t getCode() const { return Opcode; }
  86. uint64_t getRawOperand(unsigned Idx) const { return Operands[Idx]; }
  87. uint64_t getOperandEndOffset(unsigned Idx) const {
  88. return OperandEndOffsets[Idx];
  89. }
  90. uint64_t getEndOffset() const { return EndOffset; }
  91. bool isError() const { return Error; }
  92. bool print(raw_ostream &OS, DIDumpOptions DumpOpts,
  93. const DWARFExpression *Expr, const MCRegisterInfo *RegInfo,
  94. DWARFUnit *U, bool isEH) const;
  95. /// Verify \p Op. Does not affect the return of \a isError().
  96. static bool verify(const Operation &Op, DWARFUnit *U);
  97. private:
  98. bool extract(DataExtractor Data, uint8_t AddressSize, uint64_t Offset,
  99. Optional<dwarf::DwarfFormat> Format);
  100. };
  101. /// An iterator to go through the expression operations.
  102. class iterator
  103. : public iterator_facade_base<iterator, std::forward_iterator_tag,
  104. const Operation> {
  105. friend class DWARFExpression;
  106. const DWARFExpression *Expr;
  107. uint64_t Offset;
  108. Operation Op;
  109. iterator(const DWARFExpression *Expr, uint64_t Offset)
  110. : Expr(Expr), Offset(Offset) {
  111. Op.Error =
  112. Offset >= Expr->Data.getData().size() ||
  113. !Op.extract(Expr->Data, Expr->AddressSize, Offset, Expr->Format);
  114. }
  115. public:
  116. iterator &operator++() {
  117. Offset = Op.isError() ? Expr->Data.getData().size() : Op.EndOffset;
  118. Op.Error =
  119. Offset >= Expr->Data.getData().size() ||
  120. !Op.extract(Expr->Data, Expr->AddressSize, Offset, Expr->Format);
  121. return *this;
  122. }
  123. const Operation &operator*() const { return Op; }
  124. iterator skipBytes(uint64_t Add) const {
  125. return iterator(Expr, Op.EndOffset + Add);
  126. }
  127. // Comparison operators are provided out of line.
  128. friend bool operator==(const iterator &, const iterator &);
  129. };
  130. DWARFExpression(DataExtractor Data, uint8_t AddressSize,
  131. Optional<dwarf::DwarfFormat> Format = None)
  132. : Data(Data), AddressSize(AddressSize), Format(Format) {
  133. assert(AddressSize == 8 || AddressSize == 4 || AddressSize == 2);
  134. }
  135. iterator begin() const { return iterator(this, 0); }
  136. iterator end() const { return iterator(this, Data.getData().size()); }
  137. void print(raw_ostream &OS, DIDumpOptions DumpOpts,
  138. const MCRegisterInfo *RegInfo, DWARFUnit *U,
  139. bool IsEH = false) const;
  140. /// Print the expression in a format intended to be compact and useful to a
  141. /// user, but not perfectly unambiguous, or capable of representing every
  142. /// valid DWARF expression. Returns true if the expression was sucessfully
  143. /// printed.
  144. bool printCompact(raw_ostream &OS, const MCRegisterInfo &RegInfo);
  145. bool verify(DWARFUnit *U);
  146. bool operator==(const DWARFExpression &RHS) const;
  147. StringRef getData() const { return Data.getData(); }
  148. private:
  149. DataExtractor Data;
  150. uint8_t AddressSize;
  151. Optional<dwarf::DwarfFormat> Format;
  152. };
  153. inline bool operator==(const DWARFExpression::iterator &LHS,
  154. const DWARFExpression::iterator &RHS) {
  155. return LHS.Expr == RHS.Expr && LHS.Offset == RHS.Offset;
  156. }
  157. }
  158. #endif
  159. #ifdef __GNUC__
  160. #pragma GCC diagnostic pop
  161. #endif