DWARFExpression.h 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  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_DWARFEXPRESSION_H
  14. #define LLVM_DEBUGINFO_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;
  80. uint64_t EndOffset;
  81. uint64_t Operands[2];
  82. uint64_t OperandEndOffsets[2];
  83. public:
  84. Description &getDescription() { return Desc; }
  85. uint8_t getCode() { return Opcode; }
  86. uint64_t getRawOperand(unsigned Idx) { return Operands[Idx]; }
  87. uint64_t getOperandEndOffset(unsigned Idx) { return OperandEndOffsets[Idx]; }
  88. uint64_t getEndOffset() { return EndOffset; }
  89. bool extract(DataExtractor Data, uint8_t AddressSize, uint64_t Offset,
  90. Optional<dwarf::DwarfFormat> Format);
  91. bool isError() { return Error; }
  92. bool print(raw_ostream &OS, DIDumpOptions DumpOpts,
  93. const DWARFExpression *Expr, const MCRegisterInfo *RegInfo,
  94. DWARFUnit *U, bool isEH);
  95. bool verify(DWARFUnit *U);
  96. };
  97. /// An iterator to go through the expression operations.
  98. class iterator
  99. : public iterator_facade_base<iterator, std::forward_iterator_tag,
  100. Operation> {
  101. friend class DWARFExpression;
  102. const DWARFExpression *Expr;
  103. uint64_t Offset;
  104. Operation Op;
  105. iterator(const DWARFExpression *Expr, uint64_t Offset)
  106. : Expr(Expr), Offset(Offset) {
  107. Op.Error =
  108. Offset >= Expr->Data.getData().size() ||
  109. !Op.extract(Expr->Data, Expr->AddressSize, Offset, Expr->Format);
  110. }
  111. public:
  112. class Operation &operator++() {
  113. Offset = Op.isError() ? Expr->Data.getData().size() : Op.EndOffset;
  114. Op.Error =
  115. Offset >= Expr->Data.getData().size() ||
  116. !Op.extract(Expr->Data, Expr->AddressSize, Offset, Expr->Format);
  117. return Op;
  118. }
  119. class Operation &operator*() {
  120. return Op;
  121. }
  122. iterator skipBytes(uint64_t Add) {
  123. return iterator(Expr, Op.EndOffset + Add);
  124. }
  125. // Comparison operators are provided out of line.
  126. friend bool operator==(const iterator &, const iterator &);
  127. };
  128. DWARFExpression(DataExtractor Data, uint8_t AddressSize,
  129. Optional<dwarf::DwarfFormat> Format = None)
  130. : Data(Data), AddressSize(AddressSize), Format(Format) {
  131. assert(AddressSize == 8 || AddressSize == 4 || AddressSize == 2);
  132. }
  133. iterator begin() const { return iterator(this, 0); }
  134. iterator end() const { return iterator(this, Data.getData().size()); }
  135. void print(raw_ostream &OS, DIDumpOptions DumpOpts,
  136. const MCRegisterInfo *RegInfo, DWARFUnit *U,
  137. bool IsEH = false) const;
  138. /// Print the expression in a format intended to be compact and useful to a
  139. /// user, but not perfectly unambiguous, or capable of representing every
  140. /// valid DWARF expression. Returns true if the expression was sucessfully
  141. /// printed.
  142. bool printCompact(raw_ostream &OS, const MCRegisterInfo &RegInfo);
  143. bool verify(DWARFUnit *U);
  144. private:
  145. DataExtractor Data;
  146. uint8_t AddressSize;
  147. Optional<dwarf::DwarfFormat> Format;
  148. };
  149. inline bool operator==(const DWARFExpression::iterator &LHS,
  150. const DWARFExpression::iterator &RHS) {
  151. return LHS.Expr == RHS.Expr && LHS.Offset == RHS.Offset;
  152. }
  153. }
  154. #endif
  155. #ifdef __GNUC__
  156. #pragma GCC diagnostic pop
  157. #endif