Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

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