//===-- DWARFExpression.cpp -----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "llvm/DebugInfo/DWARF/DWARFExpressionPrinter.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
#include "llvm/DebugInfo/DWARF/LowLevel/DWARFExpression.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/FormatVariadic.h"
#include <cassert>
#include <cstdint>

using namespace llvm;
using namespace dwarf;

namespace llvm {

typedef DWARFExpression::Operation Op;
typedef Op::Description Desc;

static void prettyPrintBaseTypeRef(DWARFUnit *U, raw_ostream &OS,
                                   DIDumpOptions DumpOpts,
                                   ArrayRef<uint64_t> Operands,
                                   unsigned Operand) {
  assert(Operand < Operands.size() && "operand out of bounds");
  if (!U) {
    OS << formatv(" <base_type ref: {0:x}>", Operands[Operand]);
    return;
  }
  auto Die = U->getDIEForOffset(U->getOffset() + Operands[Operand]);
  if (Die && Die.getTag() == dwarf::DW_TAG_base_type) {
    OS << " (";
    if (DumpOpts.Verbose)
      OS << formatv("{0:x8} -> ", Operands[Operand]);
    OS << formatv("{0:x8})", U->getOffset() + Operands[Operand]);
    if (auto Name = dwarf::toString(Die.find(dwarf::DW_AT_name)))
      OS << " \"" << *Name << "\"";
  } else {
    OS << formatv(" <invalid base_type ref: {0:x}>", Operands[Operand]);
  }
}

static bool printOp(const DWARFExpression::Operation *Op, raw_ostream &OS,
                    DIDumpOptions DumpOpts, const DWARFExpression *Expr,
                    DWARFUnit *U) {
  if (Op->isError()) {
    if (!DumpOpts.PrintRegisterOnly)
      OS << "<decoding error>";
    return false;
  }

  std::optional<unsigned> SubOpcode = Op->getSubCode();

  // In "register-only" mode, still show simple constant-valued locations.
  // This lets clients print annotations like "i = 0" when the location is
  // a constant (e.g. DW_OP_constu/consts ... DW_OP_stack_value).
  // We continue to suppress all other non-register ops in this mode.
  if (DumpOpts.PrintRegisterOnly) {
    // First, try pretty-printing registers (existing behavior below also does
    // this, but we need to short-circuit here to avoid printing opcode names).
    if ((Op->getCode() >= DW_OP_breg0 && Op->getCode() <= DW_OP_breg31) ||
        (Op->getCode() >= DW_OP_reg0 && Op->getCode() <= DW_OP_reg31) ||
        Op->getCode() == DW_OP_bregx || Op->getCode() == DW_OP_regx ||
        Op->getCode() == DW_OP_regval_type ||
        SubOpcode == DW_OP_LLVM_call_frame_entry_reg ||
        SubOpcode == DW_OP_LLVM_aspace_bregx) {
      if (prettyPrintRegisterOp(U, OS, DumpOpts, Op->getCode(),
                                Op->getRawOperands()))
        return true;
      // If we couldn't pretty-print, fall through and suppress.
    }

    // Show constants (decimal), suppress everything else.
    if (Op->getCode() == DW_OP_constu) {
      OS << (uint64_t)Op->getRawOperand(0);
      return true;
    }
    if (Op->getCode() == DW_OP_consts) {
      OS << (int64_t)Op->getRawOperand(0);
      return true;
    }
    if (Op->getCode() >= DW_OP_lit0 && Op->getCode() <= DW_OP_lit31) {
      OS << (unsigned)(Op->getCode() - DW_OP_lit0);
      return true;
    }
    if (Op->getCode() == DW_OP_stack_value)
      return true; // metadata; don't print a token

    return true; // suppress other opcodes silently in register-only mode
  }

  if (!DumpOpts.PrintRegisterOnly) {
    StringRef Name = OperationEncodingString(Op->getCode());
    assert(!Name.empty() && "DW_OP has no name!");
    OS << Name;

    if (SubOpcode) {
      StringRef SubName = SubOperationEncodingString(Op->getCode(), *SubOpcode);
      assert(!SubName.empty() && "DW_OP SubOp has no name!");
      OS << ' ' << SubName;
    }
  }

  if ((Op->getCode() >= DW_OP_breg0 && Op->getCode() <= DW_OP_breg31) ||
      (Op->getCode() >= DW_OP_reg0 && Op->getCode() <= DW_OP_reg31) ||
      Op->getCode() == DW_OP_bregx || Op->getCode() == DW_OP_regx ||
      Op->getCode() == DW_OP_regval_type ||
      SubOpcode == DW_OP_LLVM_call_frame_entry_reg ||
      SubOpcode == DW_OP_LLVM_aspace_bregx)
    if (prettyPrintRegisterOp(U, OS, DumpOpts, Op->getCode(),
                              Op->getRawOperands()))
      return true;

  if (!DumpOpts.PrintRegisterOnly) {
    for (unsigned Operand = 0; Operand < Op->getDescription().Op.size();
         ++Operand) {
      unsigned Size = Op->getDescription().Op[Operand];
      unsigned Signed = Size & DWARFExpression::Operation::SignBit;

      if (Size == DWARFExpression::Operation::SizeSubOpLEB) {
        assert(Operand == 0 && "DW_OP SubOp must be the first operand");
        assert(SubOpcode && "DW_OP SubOp description is inconsistent");
      } else if (Size == DWARFExpression::Operation::BaseTypeRef && U) {
        // For DW_OP_convert the operand may be 0 to indicate that conversion to
        // the generic type should be done. The same holds for
        // DW_OP_reinterpret, which is currently not supported.
        if (Op->getCode() == DW_OP_convert && Op->getRawOperand(Operand) == 0)
          OS << " 0x0";
        else
          prettyPrintBaseTypeRef(U, OS, DumpOpts, Op->getRawOperands(),
                                 Operand);
      } else if (Size == DWARFExpression::Operation::WasmLocationArg) {
        assert(Operand == 1);
        switch (Op->getRawOperand(0)) {
        case 0:
        case 1:
        case 2:
        case 3: // global as uint32
        case 4:
          OS << formatv(" {0:x}", Op->getRawOperand(Operand));
          break;
        default:
          assert(false);
        }
      } else if (Size == DWARFExpression::Operation::SizeBlock) {
        uint64_t Offset = Op->getRawOperand(Operand);
        for (unsigned i = 0; i < Op->getRawOperand(Operand - 1); ++i)
          OS << formatv(" {0:x2}",
                        static_cast<uint8_t>(Expr->getData()[Offset++]));
      } else {
        if (Signed)
          OS << formatv(" {0:+d}", (int64_t)Op->getRawOperand(Operand));
        else if (Op->getCode() != DW_OP_entry_value &&
                 Op->getCode() != DW_OP_GNU_entry_value)
          OS << formatv(" {0:x}", Op->getRawOperand(Operand));
      }
    }
  }
  return true;
}

void printDwarfExpression(const DWARFExpression *E, raw_ostream &OS,
                          DIDumpOptions DumpOpts, DWARFUnit *U, bool IsEH) {
  uint32_t EntryValExprSize = 0;
  uint64_t EntryValStartOffset = 0;
  if (E->getData().empty())
    OS << "<empty>";

  for (auto &Op : *E) {
    DumpOpts.IsEH = IsEH;
    if (!printOp(&Op, OS, DumpOpts, E, U) && !DumpOpts.PrintRegisterOnly) {
      uint64_t FailOffset = Op.getEndOffset();
      while (FailOffset < E->getData().size())
        OS << formatv(" {0:x-2}",
                      static_cast<uint8_t>(E->getData()[FailOffset++]));
      return;
    }
    if (!DumpOpts.PrintRegisterOnly) {
      if (Op.getCode() == DW_OP_entry_value ||
          Op.getCode() == DW_OP_GNU_entry_value) {
        OS << "(";
        EntryValExprSize = Op.getRawOperand(0);
        EntryValStartOffset = Op.getEndOffset();
        continue;
      }

      if (EntryValExprSize) {
        EntryValExprSize -= Op.getEndOffset() - EntryValStartOffset;
        if (EntryValExprSize == 0)
          OS << ")";
      }

      if (Op.getEndOffset() < E->getData().size())
        OS << ", ";
    }
  }
}

/// A user-facing string representation of a DWARF expression. This might be an
/// Address expression, in which case it will be implicitly dereferenced, or a
/// Value expression.
struct PrintedExpr {
  enum ExprKind {
    Address,
    Value,
  };
  ExprKind Kind;
  SmallString<16> String;

  PrintedExpr(ExprKind K = Address) : Kind(K) {}
};

static bool printCompactDWARFExpr(
    raw_ostream &OS, DWARFExpression::iterator I,
    const DWARFExpression::iterator E,
    std::function<StringRef(uint64_t RegNum, bool IsEH)> GetNameForDWARFReg =
        nullptr) {
  SmallVector<PrintedExpr, 4> Stack;

  auto UnknownOpcode = [](raw_ostream &OS, uint8_t Opcode,
                          std::optional<unsigned> SubOpcode) -> bool {
    // If we hit an unknown operand, we don't know its effect on the stack,
    // so bail out on the whole expression.
    OS << "<unknown op " << dwarf::OperationEncodingString(Opcode) << " ("
       << (int)Opcode;
    if (SubOpcode)
      OS << ") subop " << dwarf::SubOperationEncodingString(Opcode, *SubOpcode)
         << " (" << *SubOpcode;
    OS << ")>";
    return false;
  };

  while (I != E) {
    const DWARFExpression::Operation &Op = *I;
    uint8_t Opcode = Op.getCode();
    switch (Opcode) {
    case dwarf::DW_OP_regx: {
      // DW_OP_regx: A register, with the register num given as an operand.
      // Printed as the plain register name.
      uint64_t DwarfRegNum = Op.getRawOperand(0);
      auto RegName = GetNameForDWARFReg(DwarfRegNum, false);
      if (RegName.empty())
        return false;
      raw_svector_ostream S(Stack.emplace_back(PrintedExpr::Value).String);
      S << RegName;
      break;
    }
    case dwarf::DW_OP_bregx: {
      int DwarfRegNum = Op.getRawOperand(0);
      int64_t Offset = Op.getRawOperand(1);
      auto RegName = GetNameForDWARFReg(DwarfRegNum, false);
      if (RegName.empty())
        return false;
      raw_svector_ostream S(Stack.emplace_back().String);
      S << RegName;
      if (Offset)
        S << formatv("{0:+d}", Offset);
      break;
    }
    case dwarf::DW_OP_entry_value:
    case dwarf::DW_OP_GNU_entry_value: {
      // DW_OP_entry_value contains a sub-expression which must be rendered
      // separately.
      uint64_t SubExprLength = Op.getRawOperand(0);
      DWARFExpression::iterator SubExprEnd = I.skipBytes(SubExprLength);
      ++I;
      raw_svector_ostream S(Stack.emplace_back().String);
      S << "entry(";
      printCompactDWARFExpr(S, I, SubExprEnd, GetNameForDWARFReg);
      S << ")";
      I = SubExprEnd;
      continue;
    }
    case dwarf::DW_OP_stack_value: {
      // The top stack entry should be treated as the actual value of tne
      // variable, rather than the address of the variable in memory.
      assert(!Stack.empty());
      Stack.back().Kind = PrintedExpr::Value;
      break;
    }
    case dwarf::DW_OP_nop: {
      break;
    }
    case dwarf::DW_OP_LLVM_user: {
      std::optional<unsigned> SubOpcode = Op.getSubCode();
      if (SubOpcode == dwarf::DW_OP_LLVM_nop)
        break;
      return UnknownOpcode(OS, Opcode, SubOpcode);
    }
    default:
      if (Opcode >= dwarf::DW_OP_reg0 && Opcode <= dwarf::DW_OP_reg31) {
        // DW_OP_reg<N>: A register, with the register num implied by the
        // opcode. Printed as the plain register name.
        uint64_t DwarfRegNum = Opcode - dwarf::DW_OP_reg0;
        auto RegName = GetNameForDWARFReg(DwarfRegNum, false);
        if (RegName.empty())
          return false;
        raw_svector_ostream S(Stack.emplace_back(PrintedExpr::Value).String);
        S << RegName;
      } else if (Opcode >= dwarf::DW_OP_breg0 &&
                 Opcode <= dwarf::DW_OP_breg31) {
        int DwarfRegNum = Opcode - dwarf::DW_OP_breg0;
        int64_t Offset = Op.getRawOperand(0);
        auto RegName = GetNameForDWARFReg(DwarfRegNum, false);
        if (RegName.empty())
          return false;
        raw_svector_ostream S(Stack.emplace_back().String);
        S << RegName;
        if (Offset)
          S << formatv("{0:+d}", Offset);
      } else {
        return UnknownOpcode(OS, Opcode, std::nullopt);
      }
      break;
    }
    ++I;
  }

  if (Stack.size() != 1) {
    OS << "<stack of size " << Stack.size() << ", expected 1>";
    return false;
  }

  if (Stack.front().Kind == PrintedExpr::Address)
    OS << "[" << Stack.front().String << "]";
  else
    OS << Stack.front().String;

  return true;
}

bool printDwarfExpressionCompact(
    const DWARFExpression *E, raw_ostream &OS,
    std::function<StringRef(uint64_t RegNum, bool IsEH)> GetNameForDWARFReg) {
  return printCompactDWARFExpr(OS, E->begin(), E->end(), GetNameForDWARFReg);
}

bool prettyPrintRegisterOp(DWARFUnit *U, raw_ostream &OS,
                           DIDumpOptions DumpOpts, uint8_t Opcode,
                           ArrayRef<uint64_t> Operands) {
  if (!DumpOpts.GetNameForDWARFReg)
    return false;

  uint64_t DwarfRegNum;
  unsigned OpNum = 0;

  std::optional<unsigned> SubOpcode;
  if (Opcode == DW_OP_LLVM_user)
    SubOpcode = Operands[OpNum++];

  if (Opcode == DW_OP_bregx || Opcode == DW_OP_regx ||
      Opcode == DW_OP_regval_type || SubOpcode == DW_OP_LLVM_aspace_bregx ||
      SubOpcode == DW_OP_LLVM_call_frame_entry_reg)
    DwarfRegNum = Operands[OpNum++];
  else if (Opcode >= DW_OP_breg0 && Opcode < DW_OP_bregx)
    DwarfRegNum = Opcode - DW_OP_breg0;
  else
    DwarfRegNum = Opcode - DW_OP_reg0;

  auto RegName = DumpOpts.GetNameForDWARFReg(DwarfRegNum, DumpOpts.IsEH);
  if (!RegName.empty()) {
    if ((Opcode >= DW_OP_breg0 && Opcode <= DW_OP_breg31) ||
        Opcode == DW_OP_bregx || SubOpcode == DW_OP_LLVM_aspace_bregx)
      OS << ' ' << RegName << formatv("{0:+d}", int64_t(Operands[OpNum]));
    else
      OS << ' ' << RegName.data();

    if (Opcode == DW_OP_regval_type)
      prettyPrintBaseTypeRef(U, OS, DumpOpts, Operands, 1);
    return true;
  }

  return false;
}

} // namespace llvm
