// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/developer/debug/zxdb/symbols/dwarf_expr_eval.h"

#include <inttypes.h>
#include <lib/syslog/cpp/macros.h>
#include <stdlib.h>

#include <limits>
#include <utility>

#include "llvm/BinaryFormat/Dwarf.h"
#include "src/developer/debug/shared/message_loop.h"
#include "src/developer/debug/shared/register_info.h"
#include "src/developer/debug/zxdb/common/string_util.h"
#include "src/developer/debug/zxdb/symbols/arch.h"
#include "src/developer/debug/zxdb/symbols/module_symbols.h"
#include "src/developer/debug/zxdb/symbols/symbol_data_provider.h"
#include "src/lib/fxl/strings/string_printf.h"

namespace zxdb {

namespace {

// GNU DWARF operation extensions.
constexpr uint8_t DW_OP_GNU_push_tls_address = 0xe0;
constexpr uint8_t DW_OP_GNU_uninit = 0xf0;
constexpr uint8_t DW_OP_GNU_encoded_addr = 0xf1;
constexpr uint8_t DW_OP_GNU_implicit_pointer = 0xf2;
constexpr uint8_t DW_OP_GNU_entry_value = 0xf3;
constexpr uint8_t DW_OP_GNU_const_type = 0xf4;
constexpr uint8_t DW_OP_GNU_regval_type = 0xf5;
constexpr uint8_t DW_OP_GNU_deref_type = 0xf6;
constexpr uint8_t DW_OP_GNU_convert = 0xf7;
constexpr uint8_t DW_OP_GNU_reinterpret = 0xf9;
constexpr uint8_t DW_OP_GNU_parameter_ref = 0xfa;
constexpr uint8_t DW_OP_GNU_addr_index = 0xfb;
constexpr uint8_t DW_OP_GNU_const_index = 0xfc;
constexpr uint8_t DW_OP_GNU_variable_value = 0xfd;

// For debug printing expression integer values, this uses hex for all but the smallest numbers
// which is what we usually expect for printing address arithmetic.
std::string ExprIntToString(uint128_t v) {
  if (v > 1024)
    return to_hex_string(v);  // Use hex for very large values (probably addresses).
  return to_string(v);
}
std::string ExprIntToString(int128_t v) {
  if (v > 1024)
    return to_hex_string(v);  // Use hex for very large values (probably addresses).
  if (v < -1024)
    return std::string("-") + to_hex_string(-v);
  return to_string(v);
}

// Makes a string expressing adding or subtracting the given constant value.
std::string MakeAddString(DwarfExprEval::SignedType val) {
  if (val < 0)
    return " - " + to_string(-val);
  return " + " + to_string(val);
}

// These macros declare functions to implement arithmetic operators that will work on typed stack
// entries as well as generic values. I suspect this could be written using "template templates" but
// this is mostly boring code used only in this one file and the straightforward #define / custom
// approach is simpler and more maintainable overall.
//
// Before calling these functions, the caller will verify that the types of the two arguments (in
// the case of binary operators) match.
//
// The macros take a validator function which is used for checking for divide-by-zero. In other
// cases, this validator always returns no error.
#define DEFINE_BINARY_OPERATOR(fn_name, bin_operator, validator)                                \
  ErrOr<DwarfStackEntry> fn_name(const DwarfStackEntry& a, const DwarfStackEntry& b) {          \
    if (Err e = validator(a, b); e.has_error())                                                 \
      return e;                                                                                 \
                                                                                                \
    if (a.TreatAsSigned())                                                                      \
      return DwarfStackEntry(a.type_ref(), a.signed_value() bin_operator b.signed_value());     \
    if (a.TreatAsUnsigned())                                                                    \
      return DwarfStackEntry(a.type_ref(), a.unsigned_value() bin_operator b.unsigned_value()); \
    if (a.TreatAsFloat())                                                                       \
      return DwarfStackEntry(a.type_ref(), a.float_value() bin_operator b.float_value());       \
    if (a.TreatAsDouble())                                                                      \
      return DwarfStackEntry(a.type_ref(), a.double_value() bin_operator b.double_value());     \
                                                                                                \
    FX_NOTREACHED();                                                                            \
    return Err("Internal type error.");                                                         \
  }

// Like DEFINE_BINARY_OPERATOR but doesn't support floating point types. Returns an error if the
// input is floating-point
#define DEFINE_INTEGRAL_BINARY_OPERATOR(fn_name, bin_operator, validator)                       \
  ErrOr<DwarfStackEntry> fn_name(const DwarfStackEntry& a, const DwarfStackEntry& b) {          \
    if (Err e = validator(a, b); e.has_error())                                                 \
      return e;                                                                                 \
                                                                                                \
    if (a.TreatAsSigned())                                                                      \
      return DwarfStackEntry(a.type_ref(), a.signed_value() bin_operator b.signed_value());     \
    if (a.TreatAsUnsigned())                                                                    \
      return DwarfStackEntry(a.type_ref(), a.unsigned_value() bin_operator b.unsigned_value()); \
                                                                                                \
    return Err("Requires integral type.");                                                      \
  }

// Like DEFINE_BINARY_OPERATOR but casts the result to a 0 or 1 generic value to implement
// comparison operations.
#define DEFINE_COMPARISON_OPERATOR(fn_name, bin_operator)                              \
  ErrOr<DwarfStackEntry> fn_name(const DwarfStackEntry& a, const DwarfStackEntry& b) { \
    bool result = false;                                                               \
                                                                                       \
    if (a.TreatAsSigned()) {                                                           \
      result = a.signed_value() bin_operator b.signed_value();                         \
    } else if (a.TreatAsUnsigned()) {                                                  \
      result = a.unsigned_value() bin_operator b.unsigned_value();                     \
    } else if (a.TreatAsFloat()) {                                                     \
      result = a.float_value() bin_operator b.float_value();                           \
    } else if (a.TreatAsDouble()) {                                                    \
      result = a.double_value() bin_operator b.double_value();                         \
    } else {                                                                           \
      FX_NOTREACHED();                                                                 \
      return Err("Internal type error.");                                              \
    }                                                                                  \
                                                                                       \
    return DwarfStackEntry(result ? 1 : 0);                                            \
  }

#define DEFINE_INTEGRAL_UNARY_OPERATOR(fn_name, un_operator)                \
  ErrOr<DwarfStackEntry> fn_name(const DwarfStackEntry& a) {                \
    if (a.TreatAsSigned())                                                  \
      return DwarfStackEntry(a.type_ref(), un_operator a.signed_value());   \
    if (a.TreatAsUnsigned())                                                \
      return DwarfStackEntry(a.type_ref(), un_operator a.unsigned_value()); \
                                                                            \
    FX_NOTREACHED();                                                        \
    return Err("Internal type error.");                                     \
  }

Err NoValidator(const DwarfStackEntry&, const DwarfStackEntry& b) { return Err(); }

Err NonzeroDenominatorValidator(const DwarfStackEntry&, const DwarfStackEntry& b) {
  if (b.IsZero())
    return Err("Divide by zero.");
  return Err();
}

// From the DWARF spec:
//
//   Operations other than DW_OP_abs, DW_OP_div, DW_OP_minus, DW_OP_mul, DW_OP_neg and DW_OP_plus
//   require integral types of the operand (either integral base type or the generic type).
//
// We could allow modulo for floating point values also but the spec says not to.
DEFINE_BINARY_OPERATOR(DwarfOperatorPlus, +, NoValidator)
DEFINE_BINARY_OPERATOR(DwarfOperatorMinus, -, NoValidator)
DEFINE_BINARY_OPERATOR(DwarfOperatorTimes, *, NoValidator)
DEFINE_INTEGRAL_BINARY_OPERATOR(DwarfOperatorMod, %, NonzeroDenominatorValidator)

DEFINE_COMPARISON_OPERATOR(DwarfOperatorEquals, ==)
DEFINE_COMPARISON_OPERATOR(DwarfOperatorNotEquals, !=)
DEFINE_COMPARISON_OPERATOR(DwarfOperatorLessEquals, <=)
DEFINE_COMPARISON_OPERATOR(DwarfOperatorGreaterEquals, >=)
DEFINE_COMPARISON_OPERATOR(DwarfOperatorLess, <)
DEFINE_COMPARISON_OPERATOR(DwarfOperatorGreater, >)

DEFINE_INTEGRAL_BINARY_OPERATOR(DwarfOperatorShiftLeft, <<, NoValidator)
DEFINE_INTEGRAL_BINARY_OPERATOR(DwarfOperatorShiftRight, >>, NoValidator)
DEFINE_INTEGRAL_BINARY_OPERATOR(DwarfOperatorBitOr, |, NoValidator)
DEFINE_INTEGRAL_BINARY_OPERATOR(DwarfOperatorBitAnd, &, NoValidator)
DEFINE_INTEGRAL_BINARY_OPERATOR(DwarfOperatorBitXor, ^, NoValidator)

DEFINE_INTEGRAL_UNARY_OPERATOR(DwarfOperatorBitNot, ~)

// The "DW_OP_div" specifies signed division in the generic type case (actually it specifies signed
// division for all cases, but if the values are typed unsigned, we do unsigned division because it
// seems to make more sense). This is implemented using the macro for the common cases, but a
// custom wrapper implementation that catches the generic case.
DEFINE_BINARY_OPERATOR(DwarfOperatorDivideTyped, /, NonzeroDenominatorValidator)
ErrOr<DwarfStackEntry> DwarfOperatorDivide(const DwarfStackEntry& a, const DwarfStackEntry& b) {
  if (a.is_generic()) {
    if (Err e = NonzeroDenominatorValidator(a, b); e.has_error())
      return e;
    return DwarfStackEntry(static_cast<DwarfStackEntry::SignedType>(a.unsigned_value()) /
                           static_cast<DwarfStackEntry::SignedType>(b.unsigned_value()));
  }
  return DwarfOperatorDivideTyped(a, b);
}

// Negation requires that "generic" values are casted to signed.
//
// There is a question on how to define negation of an explicitly unsigned value. The spec doesn't
// say anything. This currently defines it as a no-op, but it could also be like the generic case
// where the bits are reinterpreted. Probably this will not be emitted by a compiler so it won't
// matter.
ErrOr<DwarfStackEntry> DwarfOperatorNeg(const DwarfStackEntry& a) {
  if (a.is_generic())
    return DwarfStackEntry(static_cast<uint128_t>(-static_cast<int128_t>(a.unsigned_value())));

  if (a.TreatAsSigned())
    return DwarfStackEntry(a.type_ref(), -a.signed_value());
  if (a.TreatAsUnsigned())
    return DwarfStackEntry(a.type_ref(), a.unsigned_value());  // No-op, see above.
  if (a.TreatAsFloat())
    return DwarfStackEntry(a.type_ref(), -a.float_value());
  if (a.TreatAsDouble())
    return DwarfStackEntry(a.type_ref(), -a.double_value());

  FX_NOTREACHED();
  return Err("Internal type error");
}

// This one is an operator to DWARF but not C++. Generic values get treated as signed.
ErrOr<DwarfStackEntry> DwarfOperatorAbs(const DwarfStackEntry& a) {
  if (a.is_generic()) {
    auto as_signed = static_cast<DwarfStackEntry::SignedType>(a.unsigned_value());
    return as_signed < 0 ? DwarfStackEntry(static_cast<DwarfStackEntry::UnsignedType>(-as_signed))
                         : a;
  }

  // Explicit types. The DWARF spec doesn't separate out non-generic types so technically the
  // requirement that the result is "interpreted as signed" applies, but I don't think they meant
  // that if the value has an explicitly defined unsigned type.
  if (a.TreatAsSigned()) {
    if (a.signed_value() < 0)
      return DwarfStackEntry(a.type_ref(), -a.signed_value());
    return DwarfStackEntry(a.type_ref(), a.signed_value());
  }
  if (a.TreatAsUnsigned())
    return DwarfStackEntry(a.type_ref(), a.unsigned_value());  // No-op.
  if (a.TreatAsFloat())
    return DwarfStackEntry(a.type_ref(), fabsf(a.float_value()));
  if (a.TreatAsDouble())
    return DwarfStackEntry(a.type_ref(), fabs(a.double_value()));

  FX_NOTREACHED();
  return Err("Internal type error");
}

// This does a sign-extended shift right. When the type is known, we do the same thing as a regular
// shift right (sign-extended only for signed types). I'm assuming that the DWARF spec's
// description of reinterpreting as a signed type only applies to generic types.
ErrOr<DwarfStackEntry> DwarfOperatorShiftRightArithmetically(const DwarfStackEntry& a,
                                                             const DwarfStackEntry& b) {
  if (a.is_generic()) {
    return DwarfStackEntry(static_cast<uint128_t>(static_cast<int128_t>(a.unsigned_value()) >>
                                                  static_cast<int128_t>(b.unsigned_value())));
  }
  return DwarfOperatorShiftRight(a, b);
}

}  // namespace

DwarfExprEval::DwarfExprEval()
    : symbol_context_(SymbolContext::ForRelativeAddresses()), weak_factory_(this) {}

DwarfExprEval::~DwarfExprEval() {
  // This assertion verifies that this class was not accidentally deleted from
  // within the completion callback. This class is not set up to handle this
  // case.
  FX_CHECK(!in_completion_callback_);
}

void DwarfExprEval::Push(DwarfStackEntry value) { stack_.push_back(value); }

DwarfExprEval::ResultType DwarfExprEval::GetResultType() const {
  FX_DCHECK(is_complete_);
  FX_DCHECK(is_success_);

  if (!result_data_.empty())
    return ResultType::kData;
  return result_type_;
}

DwarfStackEntry DwarfExprEval::GetResult() const {
  FX_DCHECK(is_complete_);
  FX_DCHECK(is_success_);
  return stack_.back();
}

TaggedData DwarfExprEval::TakeResultData() {
  FX_DCHECK(is_complete_);
  FX_DCHECK(GetResultType() == ResultType::kData);
  return result_data_.TakeData();
}

DwarfExprEval::Completion DwarfExprEval::Eval(fxl::RefPtr<SymbolDataProvider> data_provider,
                                              const SymbolContext& symbol_context, DwarfExpr expr,
                                              CompletionCallback cb) {
  SetUp(std::move(data_provider), symbol_context, expr, std::move(cb));

  // Note: ContinueEval() may call callback, which may delete |this|.
  return ContinueEval() ? Completion::kSync : Completion::kAsync;
}

std::string DwarfExprEval::ToString(fxl::RefPtr<SymbolDataProvider> data_provider,
                                    const SymbolContext& symbol_context, DwarfExpr expr,
                                    bool pretty) {
  SetUp(std::move(data_provider), symbol_context, expr, nullptr);
  result_data_ = TaggedDataBuilder();

  string_output_mode_ = pretty ? StringOutput::kPretty : StringOutput::kLiteral;
  string_output_.clear();

  bool is_complete = ContinueEval();
  FX_DCHECK(is_complete);  // Always expect string printing mode to complete.

  std::string result = std::move(string_output_);
  string_output_mode_ = StringOutput::kNone;
  string_output_.clear();

  return result;
}

void DwarfExprEval::SetUp(fxl::RefPtr<SymbolDataProvider> data_provider,
                          const SymbolContext& symbol_context, DwarfExpr expr,
                          CompletionCallback cb) {
  is_complete_ = false;
  data_provider_ = std::move(data_provider);
  symbol_context_ = symbol_context;
  expr_ = std::move(expr);
  completion_callback_ = std::move(cb);
  data_extractor_ = DataExtractor(expr_.data());
}

bool DwarfExprEval::ContinueEval() {
  // To allow interruption, only a certain number of instructions will be
  // executed in sequence without posting back to the message loop. This
  // gives calling code the chance to cancel long or hung executions. Since
  // most programs are 1-4 instructions, the threshold can be low.
  constexpr int kMaxInstructionsAtOnce = 32;
  int instruction_count = 0;

  do {
    // Check for successfully reaching the end of the stream.
    if (!is_complete_ && data_extractor_.done()) {
      if (is_string_output())
        return true;  // Only expecting to produce a string.

      data_provider_.reset();
      is_complete_ = true;
      Err err;
      if (stack_.empty() && result_data_.empty()) {
        // Failure to compute any values.
        err = Err("DWARF expression produced no results.");
        is_success_ = false;
      } else {
        is_success_ = true;
      }

      in_completion_callback_ = true;
      completion_callback_(this, err);
      completion_callback_ = {};
      in_completion_callback_ = false;
      return is_complete_;
    }

    if (instruction_count == kMaxInstructionsAtOnce) {
      // Enough instructions have run at once. Schedule a callback to continue
      // execution in the message loop.
      debug::MessageLoop::Current()->PostTask(FROM_HERE,
                                              [weak_eval = weak_factory_.GetWeakPtr()]() {
                                                if (weak_eval)
                                                  weak_eval->ContinueEval();
                                              });
      return is_complete_;
    }
    instruction_count++;
  } while (!is_complete_ && EvalOneOp() == Completion::kSync);
  return is_complete_;
}

DwarfExprEval::Completion DwarfExprEval::EvalOneOp() {
  FX_DCHECK(!is_complete_);
  FX_DCHECK(!data_extractor_.done());

  // Clear any current register information. See current_register_id_ declaration for more.
  current_register_id_ = debug::RegisterID::kUnknown;

  // Opcode is next byte in the data buffer. Consume it (we already checked there's data).
  uint8_t op = *data_extractor_.Read<uint8_t>();

  // Literals 0-31.
  if (op >= llvm::dwarf::DW_OP_lit0 && op <= llvm::dwarf::DW_OP_lit31) {
    int literal_value = op - llvm::dwarf::DW_OP_lit0;
    if (is_string_output()) {
      return AppendString("DW_OP_lit" + std::to_string(literal_value),
                          "push(" + std::to_string(literal_value) + ")");
    } else {
      Push(DwarfStackEntry(literal_value));
    }
    return Completion::kSync;
  }

  // Registers 0-31.
  if (op >= llvm::dwarf::DW_OP_reg0 && op <= llvm::dwarf::DW_OP_reg31) {
    int reg_index = op - llvm::dwarf::DW_OP_reg0;
    if (is_string_output())
      return AppendString("DW_OP_reg" + std::to_string(reg_index), GetRegisterName(reg_index));

    result_type_ = ResultType::kValue;
    return PushRegisterWithOffset(reg_index, 0);
  }

  // Base register with SLEB128 offset.
  if (op >= llvm::dwarf::DW_OP_breg0 && op <= llvm::dwarf::DW_OP_breg31)
    return OpBreg(op);

  switch (op) {
    case llvm::dwarf::DW_OP_addr:
      return OpAddr();
    case llvm::dwarf::DW_OP_deref:
      return OpDeref(sizeof(TargetPointer), "DW_OP_deref", false);
    case llvm::dwarf::DW_OP_const1u:
      return OpPushUnsigned(1, "DW_OP_const1u");
    case llvm::dwarf::DW_OP_const1s:
      return OpPushSigned(1, "DW_OP_const1s");
    case llvm::dwarf::DW_OP_const2u:
      return OpPushUnsigned(2, "DW_OP_const2u");
    case llvm::dwarf::DW_OP_const2s:
      return OpPushSigned(2, "DW_OP_const2s");
    case llvm::dwarf::DW_OP_const4u:
      return OpPushUnsigned(4, "DW_OP_const4u");
    case llvm::dwarf::DW_OP_const4s:
      return OpPushSigned(4, "DW_OP_const4s");
    case llvm::dwarf::DW_OP_const8u:
      return OpPushUnsigned(8, "DW_OP_const8u");
    case llvm::dwarf::DW_OP_const8s:
      return OpPushSigned(8, "DW_OP_const8s");
    case llvm::dwarf::DW_OP_constu:
      return OpPushLEBUnsigned();
    case llvm::dwarf::DW_OP_consts:
      return OpPushLEBSigned();
    case llvm::dwarf::DW_OP_dup:
      return OpDup();
    case llvm::dwarf::DW_OP_drop:
      return OpDrop();
    case llvm::dwarf::DW_OP_over:
      return OpOver();
    case llvm::dwarf::DW_OP_pick:
      return OpPick();
    case llvm::dwarf::DW_OP_swap:
      return OpSwap();
    case llvm::dwarf::DW_OP_rot:
      return OpRot();
    case llvm::dwarf::DW_OP_xderef:
      // We don't have multiple address spaces.
      return ReportError("DW_OP_xderef opcode is not applicable to this platform.");
    case llvm::dwarf::DW_OP_abs:
      return OpUnary(&DwarfOperatorAbs, "DW_OP_abs");
    case llvm::dwarf::DW_OP_and:
      return OpBinary(&DwarfOperatorBitAnd, "DW_OP_and");
    case llvm::dwarf::DW_OP_div:
      return OpBinary(&DwarfOperatorDivide, "DW_OP_div");
    case llvm::dwarf::DW_OP_minus:
      return OpBinary(&DwarfOperatorMinus, "DW_OP_minus");
    case llvm::dwarf::DW_OP_mod:
      return OpBinary(&DwarfOperatorMod, "DW_OP_mod");
    case llvm::dwarf::DW_OP_mul:
      return OpBinary(&DwarfOperatorTimes, "DW_OP_mul");
    case llvm::dwarf::DW_OP_neg:
      return OpUnary(&DwarfOperatorNeg, "DW_OP_neg");
    case llvm::dwarf::DW_OP_not:
      return OpUnary(&DwarfOperatorBitNot, "DW_OP_not");
    case llvm::dwarf::DW_OP_or:
      return OpBinary(&DwarfOperatorBitOr, "DW_OP_or");
    case llvm::dwarf::DW_OP_plus:
      return OpBinary(&DwarfOperatorPlus, "DW_OP_plus");
    case llvm::dwarf::DW_OP_plus_uconst:
      return OpPlusUconst();
    case llvm::dwarf::DW_OP_shl:
      return OpBinary(&DwarfOperatorShiftLeft, "DW_OP_shl");
    case llvm::dwarf::DW_OP_shr:
      return OpBinary(&DwarfOperatorShiftRight, "DW_OP_shr");
    case llvm::dwarf::DW_OP_shra:
      return OpBinary(&DwarfOperatorShiftRightArithmetically, "DW_OP_shra");
    case llvm::dwarf::DW_OP_xor:
      return OpBinary(&DwarfOperatorBitXor, "DW_OP_xor");
    case llvm::dwarf::DW_OP_bra:
      return OpBra();
    case llvm::dwarf::DW_OP_eq:
      return OpBinary(&DwarfOperatorEquals, "DW_OP_eq");
    case llvm::dwarf::DW_OP_ge:
      return OpBinary(&DwarfOperatorGreaterEquals, "DW_OP_ge");
    case llvm::dwarf::DW_OP_gt:
      return OpBinary(&DwarfOperatorGreater, "DW_OP_gt");
    case llvm::dwarf::DW_OP_le:
      return OpBinary(&DwarfOperatorLessEquals, "DW_OP_le");
    case llvm::dwarf::DW_OP_lt:
      return OpBinary(&DwarfOperatorLess, "DW_OP_lt");
    case llvm::dwarf::DW_OP_ne:
      return OpBinary(&DwarfOperatorNotEquals, "DW_OP_ne");
    case llvm::dwarf::DW_OP_skip:
      return OpSkip();
      // DW_OP_lit*, DW_OP_reg*, and DW_OP_breg* are handled at the top of the function.
    case llvm::dwarf::DW_OP_regx:
      return OpRegx();
    case llvm::dwarf::DW_OP_fbreg:
      return OpFbreg();
    case llvm::dwarf::DW_OP_bregx:
      return OpBregx();
    case llvm::dwarf::DW_OP_piece:
      return OpPiece();
    case llvm::dwarf::DW_OP_deref_size:
      return OpDerefSize();
    case llvm::dwarf::DW_OP_xderef_size:
      // We don't have multiple address spaces.
      return ReportError("DW_OP_xderef_size opcode is not applicable to this platform.");
    case llvm::dwarf::DW_OP_nop:
      if (is_string_output())
        AppendString("DW_OP_nop");
      return Completion::kSync;

    // DWARF 3 additions.
    case llvm::dwarf::DW_OP_push_object_address:
      return ReportError("Unimplemented DW_OP_push_object_address opcode.");
    case llvm::dwarf::DW_OP_call2:     // 2-byte offset of DIE.
    case llvm::dwarf::DW_OP_call4:     // 4-byte offset of DIE.
    case llvm::dwarf::DW_OP_call_ref:  // 4- or 8-byte offset of DIE.
      return ReportError("Unimplemented DWARF expression procedure call operation.");
    case llvm::dwarf::DW_OP_form_tls_address:
      return OpTlsAddr("DW_OP_form_tls_address");
    case llvm::dwarf::DW_OP_call_frame_cfa:
      return OpCFA();
    case llvm::dwarf::DW_OP_bit_piece:
      return OpBitPiece();

    // DWARF 4 additions.
    case llvm::dwarf::DW_OP_implicit_value:
      return OpImplicitValue();
    case llvm::dwarf::DW_OP_stack_value:
      return OpStackValue();

    // DWARF 5 additions.
    case llvm::dwarf::DW_OP_implicit_pointer:
      return OpImplicitPointer("DW_OP_implicit_pointer");
    case llvm::dwarf::DW_OP_addrx:
      return OpAddrBase(ResultType::kPointer, "DW_OP_addrx");
    case llvm::dwarf::DW_OP_constx:
      return OpAddrBase(ResultType::kValue, "DW_OP_constx");
    case llvm::dwarf::DW_OP_entry_value:
      return OpEntryValue("DW_OP_entry_value");
    case llvm::dwarf::DW_OP_const_type:
    case llvm::dwarf::DW_OP_regval_type:
    case llvm::dwarf::DW_OP_deref_type:
    case llvm::dwarf::DW_OP_xderef_type:
    case llvm::dwarf::DW_OP_convert:
    case llvm::dwarf::DW_OP_reinterpret:
      return ReportError("Unimplemented DWARF 5 'type' opcode (http://fxbug.dev/79529).");

    // GNU extensions.
    case DW_OP_GNU_push_tls_address:
      return OpTlsAddr("DW_OP_GNU_push_tls_address");
    case DW_OP_GNU_uninit:
      // Reports that the variable is uninitialized (as opposed to optimized out).
      return ReportError("Unimplemented DW_OP_GNU_uninit opcode.");
    case DW_OP_GNU_encoded_addr:
      return ReportError("Unimplemented DW_OP_GNU_encoded_addr opcode.");
    case DW_OP_GNU_implicit_pointer:
      return OpImplicitPointer("DW_OP_GNU_implicit_pointer");
    case DW_OP_GNU_entry_value:
      return OpEntryValue("DW_OP_GNU_entry_value");
    case DW_OP_GNU_const_type:
    case DW_OP_GNU_regval_type:
    case DW_OP_GNU_deref_type:
    case DW_OP_GNU_convert:
    case DW_OP_GNU_reinterpret:
      return ReportError("Unimplemented GNU 'type' opcode (http://fxbug.dev/79529).");
    case DW_OP_GNU_parameter_ref:
      return ReportError("Unimplemented DW_OP_GNU_parameter_ref opcode.");
    case DW_OP_GNU_addr_index:
      return ReportError("Unimplemented DW_OP_GNU_addr_index opcode.");
    case DW_OP_GNU_const_index:
      return ReportError("Unimplemented DW_OP_GNU_const_index opcode.");
    case DW_OP_GNU_variable_value:
      return ReportError("Unimplemented DW_OP_GNU_variable_value opcode.");

    default:
      // Invalid or unknown opcode.
      if (is_string_output()) {
        AppendString("INVALID_OPCODE(" + to_hex_string(op) + ")");
      } else {
        ReportError(fxl::StringPrintf("Invalid opcode 0x%x in DWARF expression.", op));
      }
      return Completion::kSync;
  }
}

DwarfExprEval::Completion DwarfExprEval::PushRegisterWithOffset(int dwarf_register_number,
                                                                SignedType offset) {
  // Reading register data means the result is not constant.
  result_is_constant_ = false;

  const debug::RegisterInfo* reg_info =
      debug::DWARFToRegisterInfo(data_provider_->GetArch(), dwarf_register_number);
  if (!reg_info) {
    ReportError(fxl::StringPrintf("Register %d not known.", dwarf_register_number));
    return Completion::kSync;
  }

  // This function doesn't set the result_type_ because it is called from different contexts. The
  // callers should set the result_type_ as appropriate for their operation.
  if (auto reg_data = data_provider_->GetRegister(reg_info->id)) {
    // State known synchronously (could be available or known unavailable).
    if (reg_data->empty()) {
      ReportError(fxl::StringPrintf("Register %d not available.", dwarf_register_number));
    } else {
      // This truncates to 128 bits and converts from little-endian. DWARF doesn't seem to use the
      // stack machine for vector computations (it's not specified that the stack items are large
      // enough). When it uses a stack register for a floating-point scalar computation, it just
      // uses the low bits.
      UnsignedType reg_value = 0;
      memcpy(&reg_value, reg_data->data(), std::min(sizeof(UnsignedType), reg_data->size()));
      Push(DwarfStackEntry(reg_value + offset));

      // When the current value represents a register, save that fact.
      if (offset == 0)
        current_register_id_ = reg_info->id;
    }
    return Completion::kSync;
  }

  // Must request async.
  data_provider_->GetRegisterAsync(
      reg_info->id, [reg_id = reg_info->id, weak_eval = weak_factory_.GetWeakPtr(), offset](
                        const Err& err, std::vector<uint8_t> reg_data) {
        if (!weak_eval)
          return;
        if (err.has_error()) {
          weak_eval->ReportError(err);
          return;
        }

        // Truncate/convert from little-endian as above.
        UnsignedType reg_value = 0;
        memcpy(&reg_value, reg_data.data(), std::min(sizeof(UnsignedType), reg_data.size()));
        weak_eval->Push(DwarfStackEntry(static_cast<UnsignedType>(reg_value + offset)));

        // When the current value represents a register, save that fact.
        if (offset == 0)
          weak_eval->current_register_id_ = reg_id;

        // Picks up processing at the next instruction.
        weak_eval->ContinueEval();
      });

  return Completion::kAsync;
}

bool DwarfExprEval::ReadSigned(int byte_size, SignedType* output) {
  switch (byte_size) {
    case 1:
      if (auto v = data_extractor_.Read<int8_t>()) {
        *output = *v;
        return true;
      }
      break;
    case 2:
      if (auto v = data_extractor_.Read<int16_t>()) {
        *output = *v;
        return true;
      }
      break;
    case 4:
      if (auto v = data_extractor_.Read<int32_t>()) {
        *output = *v;
        return true;
      }
      break;
    case 8:
      if (auto v = data_extractor_.Read<int64_t>()) {
        *output = *v;
        return true;
      }
      break;
  }

  ReportError("Bad number format in DWARF expression.");
  return false;
}

bool DwarfExprEval::ReadUnsigned(int byte_size, UnsignedType* output) {
  switch (byte_size) {
    case 1:
      if (auto v = data_extractor_.Read<uint8_t>()) {
        *output = *v;
        return true;
      }
      break;
    case 2:
      if (auto v = data_extractor_.Read<uint16_t>()) {
        *output = *v;
        return true;
      }
      break;
    case 4:
      if (auto v = data_extractor_.Read<uint32_t>()) {
        *output = *v;
        return true;
      }
      break;
    case 8:
      if (auto v = data_extractor_.Read<uint64_t>()) {
        *output = *v;
        return true;
      }
      break;
  }

  ReportError("Bad number format in DWARF expression.");
  return false;
}

bool DwarfExprEval::ReadLEBSigned(SignedType* output) {
  if (auto result = data_extractor_.ReadSleb128()) {
    *output = *result;
    return true;
  }
  ReportError("Bad number format in DWARF expression.");
  return false;
}

bool DwarfExprEval::ReadLEBUnsigned(UnsignedType* output) {
  if (auto result = data_extractor_.ReadUleb128()) {
    *output = *result;
    return true;
  }
  ReportError("Bad number format in DWARF expression.");
  return false;
}

void DwarfExprEval::ReadMemory(
    TargetPointer address, uint32_t byte_size,
    fit::callback<void(DwarfExprEval* eval, std::vector<uint8_t> value)> on_success) {
  // Reading memory means the result is not constant.
  result_is_constant_ = false;

  data_provider_->GetMemoryAsync(
      address, byte_size,
      [address, byte_size, weak_eval = weak_factory_.GetWeakPtr(),
       on_success = std::move(on_success)](const Err& err, std::vector<uint8_t> value) mutable {
        if (!weak_eval) {
          return;
        } else if (err.has_error()) {
          weak_eval->ReportError(err);
        } else if (value.size() != byte_size) {
          weak_eval->ReportError(
              fxl::StringPrintf("Invalid pointer 0x%" PRIx64 ".", static_cast<uint64_t>(address)));
        } else {
          on_success(weak_eval.get(), std::move(value));

          // Picks up processing at the next instruction.
          weak_eval->ContinueEval();
        }
      });
}

DwarfExprEval::Completion DwarfExprEval::ReportError(const std::string& msg) {
  return ReportError(Err(msg));
}

DwarfExprEval::Completion DwarfExprEval::ReportError(const Err& err) {
  if (is_string_output())
    AppendString("ERROR: \"" + err.msg() + "\"");

  data_provider_.reset();
  is_complete_ = true;

  // Wrap completion callback with the flag to catch deletions from within the callback.
  in_completion_callback_ = true;
  if (completion_callback_)
    completion_callback_(this, err);
  completion_callback_ = {};
  in_completion_callback_ = false;

  return Completion::kSync;
}

void DwarfExprEval::ReportStackUnderflow() { ReportError("Stack underflow for DWARF expression."); }

DwarfExprEval::Completion DwarfExprEval::OpUnary(
    ErrOr<DwarfStackEntry> (*op)(const DwarfStackEntry&), const char* op_name) {
  if (is_string_output())
    return AppendString(op_name);

  if (stack_.empty()) {
    ReportStackUnderflow();
  } else {
    ErrOr<DwarfStackEntry> result = op(stack_.back());
    if (result.ok()) {
      stack_.back() = std::move(result.value());
    } else {
      ReportError("Error evaluating " + std::string(op_name) +
                  " in DWARF expression: " + result.err().msg());
    }
  }
  return Completion::kSync;
}

DwarfExprEval::Completion DwarfExprEval::OpBinary(
    ErrOr<DwarfStackEntry> (*op)(const DwarfStackEntry&, const DwarfStackEntry&),
    const char* op_name) {
  if (is_string_output())
    return AppendString(op_name);

  if (stack_.size() < 2) {
    ReportStackUnderflow();
  } else {
    DwarfStackEntry b = stack_.back();
    stack_.pop_back();
    DwarfStackEntry a = stack_.back();
    stack_.pop_back();

    if (!a.SameTypeAs(b)) {
      ReportError(std::string(op_name) + " called on incompatible types " + a.GetTypeDescription() +
                  " and " + b.GetTypeDescription());
      return Completion::kSync;
    }

    ErrOr<DwarfStackEntry> result = op(a, b);
    if (result.ok()) {
      stack_.push_back(std::move(result.value()));
    } else {
      ReportError("Error evaluating " + std::string(op_name) +
                  " in DWARF expression: " + result.err().msg());
    }
  }
  return Completion::kSync;
}

// ULEB128 index into the .debug_addr section where a machine address-length value is stored. The
// index is relative to the value of the DW_AT_addr_base attribute of the compilation unit.
//
// result_type == kAddress corresponds to DW_OP_addrx
// result_type == kValue corresponds to DW_OP_constx.
DwarfExprEval::Completion DwarfExprEval::OpAddrBase(ResultType result_type, const char* op_name) {
  fxl::WeakPtr<ModuleSymbols> module_symbols = expr_.source().Get()->GetModuleSymbols();
  if (!module_symbols)
    return ReportError(std::string("DWARF expression used ") + op_name +
                       "but no symbols are available.");

  // The index in the expression is inside the table identified by the DW_AT_addr_base of the
  // compilation unit.
  std::optional<uint64_t> base = expr_.GetAddrBase();
  if (!base) {
    return ReportError(std::string("DWARF expression used ") + op_name +
                       " but no addr_base is available.");
  }

  UnsignedType addr_table_index;
  if (!ReadLEBUnsigned(&addr_table_index))
    return Completion::kSync;

  std::optional<uint64_t> result_or =
      module_symbols->GetDebugAddrEntry(*base, static_cast<uint64_t>(addr_table_index));
  if (!result_or)
    return ReportError("Unable to read .debug_addr section to evaluate expression.");

  result_type_ = result_type;
  if (result_type == ResultType::kPointer) {
    // Addresses need to be relocated according to the module offset.
    UnsignedType new_entry = symbol_context_.RelativeToAbsolute(result_or.value());
    if (is_string_output()) {
      AppendString(std::string(op_name) + "(" + ExprIntToString(addr_table_index) +
                   ", with addr_base=" + to_hex_string(*base) + ") -> rel=" +
                   to_hex_string(result_or.value()) + ", abs=" + to_hex_string(new_entry));
    } else {
      Push(DwarfStackEntry(new_entry));
    }
  } else {
    // Constants are ready to use.
    UnsignedType new_entry = static_cast<UnsignedType>(result_or.value());
    if (is_string_output()) {
      AppendString(std::string(op_name) + "(" + ExprIntToString(addr_table_index) +
                   ", with addr_base=" + to_hex_string(*base) + ") -> " + to_hex_string(new_entry));
    } else {
      Push(DwarfStackEntry(new_entry));
    }
  }

  return Completion::kSync;
}

// 1 parameter: unsigned the size of a pointer. This is relative to the load address of the current
// module. It is used to for globals and statics.
DwarfExprEval::Completion DwarfExprEval::OpAddr() {
  UnsignedType offset;
  if (!ReadUnsigned(kTargetPointerSize, &offset))
    return Completion::kSync;

  TargetPointer address = symbol_context_.RelativeToAbsolute(static_cast<TargetPointer>(offset));

  if (is_string_output()) {
    if (symbol_context_.is_relative() || string_output_mode_ == StringOutput::kLiteral)
      return AppendString("DW_OP_addr(" + to_hex_string(offset) + ")");

    // Show final address since we know it.
    return AppendString("push(" + to_hex_string(address) + ")");
  }

  Push(DwarfStackEntry(address));
  return Completion::kSync;
}

// ULEB128 size + ULEB128 offset.
DwarfExprEval::Completion DwarfExprEval::OpBitPiece() {
  UnsignedType size;
  if (!ReadLEBUnsigned(&size))
    return Completion::kSync;

  UnsignedType offset;
  if (!ReadLEBUnsigned(&offset))
    return Completion::kSync;

  if (is_string_output())
    return AppendString("DW_OP_bit_piece(" + ExprIntToString(size) + ", " +
                        ExprIntToString(offset) + ")");

  // Clang will generate bit_piece operations to make 80-bit long double constants, but the
  // expressions are invalid: https://bugs.llvm.org/show_bug.cgi?id=43682
  // We were able to get GCC to generate a piece operation for:
  //   void foo(int x, int y) {
  //     struct { int x:3, :3, y:3; } s = {x, y};
  //   }
  // That also seems invalid. So we're waiting for a clearly valid example in the wild before
  // spending time trying to implement this.
  return ReportError(
      "The DWARF encoding for this symbol uses DW_OP_bit_piece which is unimplemented.\n"
      "Please file a bit with a repro case so we can implement it properly.");
}

// 1 parameter: 2 byte signed integer constant.
DwarfExprEval::Completion DwarfExprEval::OpBra() {
  // "The 2-byte constant is the number of bytes of the DWARF expression to skip forward or backward
  // from the current operation, beginning after the 2-byte constant."
  SignedType skip_amount = 0;
  if (!ReadSigned(2, &skip_amount))
    return Completion::kSync;

  if (is_string_output())
    return AppendString("DW_OP_bra(" + ExprIntToString(skip_amount) + ")");

  if (stack_.empty()) {
    ReportStackUnderflow();
    return Completion::kSync;
  }

  // 0 @ top of stack means don't take the branch.
  DwarfStackEntry condition = stack_.back();
  stack_.pop_back();
  if (condition.IsZero())
    return Completion::kSync;

  // Otherwise take the branch.
  Skip(skip_amount);
  return Completion::kSync;
}

// 1 parameter: SLEB128 offset added to base register.
DwarfExprEval::Completion DwarfExprEval::OpBreg(uint8_t op) {
  int reg_index = op - llvm::dwarf::DW_OP_breg0;

  SignedType offset = 0;
  if (!ReadLEBSigned(&offset))
    return Completion::kSync;

  if (is_string_output()) {
    return AppendString(
        "DW_OP_breg" + std::to_string(reg_index) + "(" + ExprIntToString(offset) + ")",
        GetRegisterName(reg_index) + MakeAddString(offset));
  }

  result_type_ = ResultType::kPointer;
  return PushRegisterWithOffset(reg_index, offset);
}

DwarfExprEval::Completion DwarfExprEval::OpCFA() {
  if (is_string_output())
    return AppendString("DW_OP_call_frame_cfa");

  // Reading the CFA means the result is not constant.
  result_is_constant_ = false;

  if (UnsignedType cfa = data_provider_->GetCanonicalFrameAddress())
    Push(DwarfStackEntry(cfa));
  else
    ReportError("Frame address is 0.");
  return Completion::kSync;
}

DwarfExprEval::Completion DwarfExprEval::OpDrop() {
  if (is_string_output())
    return AppendString("DW_OP_drop");

  if (stack_.empty())
    ReportStackUnderflow();
  else
    stack_.pop_back();
  return Completion::kSync;
}

DwarfExprEval::Completion DwarfExprEval::OpDup() {
  if (is_string_output())
    return AppendString("DW_OP_dup");

  if (stack_.empty())
    ReportStackUnderflow();
  else
    stack_.push_back(stack_.back());
  return Completion::kSync;
}

DwarfExprEval::Completion DwarfExprEval::OpEntryValue(const char* op_name) {
  // A ULEB128 length followed by a sub-expression of that length. This sub-expression is evaluated
  // in a separate stack using the register values that were present at the beginning of the
  // function.
  UnsignedType length;
  if (!ReadLEBUnsigned(&length))
    return Completion::kSync;
  if (length == 0 || !data_extractor_.CanRead(static_cast<size_t>(length)))
    return ReportError("DW_OP_entry_value sub expression is a bad length.");

  // Read the DWARF expression to evaluate.
  std::vector<uint8_t> sub_expr_bytes(static_cast<size_t>(length));
  if (!data_extractor_.ReadBytes(sub_expr_bytes.size(), sub_expr_bytes.data()))
    return ReportError("Not enough data for DW_OP_entry_value.");

  DwarfExpr sub_expr(std::move(sub_expr_bytes), expr_.source());
  FX_DCHECK(!nested_eval_);
  nested_eval_ = std::make_unique<DwarfExprEval>();

  if (is_string_output()) {
    std::string nested_str(op_name);
    nested_str += "(";

    // For string output the data provider doesn't matter, so keep using ours since the entry
    // provider might not be available.
    nested_str += nested_eval_->ToString(data_provider_, symbol_context_, std::move(sub_expr),
                                         string_output_mode_ == StringOutput::kPretty);

    nested_str += ")";
    AppendString(nested_str);
    nested_eval_.reset();
    return Completion::kSync;
  }

  // Get the data provider for the nested context.
  auto entry_data_provider = data_provider_->GetEntryDataProvider();
  if (!entry_data_provider)
    return ReportError("Can not compute function entry values in this context.");

  // Since we own the nested evaluator, it's OK to capture |this| in the callback.
  //
  // The nested evaluator may complete synchronously (the common case) or not. We need to know that
  // from the callback to know whether to call ContinueEval() or not, and this information isn't
  // passed to the callback. The shared boolean allows us to track this.
  auto is_async_completion = std::make_shared<bool>(false);
  Completion completion = nested_eval_->Eval(
      std::move(entry_data_provider), symbol_context_, std::move(sub_expr),
      [this, is_async_completion](DwarfExprEval* nested, const Err& err) {
        // TODO(brettw) do we need to call ContinueEval on error? What about in other cases this
        // comes up? They may be wrong.
        if (err.has_error()) {
          ReportError(err);
        } else if (nested->GetResultType() == ResultType::kData) {
          // The nested expression is expected to produce exactly one stack entry, not data.
          ReportError("DWARF entry value expression produced an incorrect result type.");
        } else {
          // Success case, save the result.
          Push(DwarfStackEntry(nested->GetResult()));
        }

        if (*is_async_completion) {
          // The nested_eval_ needs to be cleared before continuing, but we can't delete it from
          // within its own callback. Schedule it to be deleted from the message loop.
          debug::MessageLoop::Current()->PostTask(FROM_HERE,
                                                  [old_eval = std::move(nested_eval_)]() {});
          ContinueEval();
        }
      });

  if (completion == Completion::kSync) {
    nested_eval_.reset();
  } else {
    *is_async_completion = true;
  }
  return completion;
}

// 1 parameter: Signed LEB128 offset from frame base pointer.
DwarfExprEval::Completion DwarfExprEval::OpFbreg() {
  // Reading the frame base means the result is not constant.
  result_is_constant_ = false;

  SignedType offset = 0;
  if (!ReadLEBSigned(&offset))
    return Completion::kSync;

  if (is_string_output()) {
    return AppendString("DW_OP_fbreg(" + ExprIntToString(offset) + ")",
                        "frame_base" + MakeAddString(offset));
  }

  if (auto bp = data_provider_->GetFrameBase()) {
    // Available synchronously.

    // Certain problems can cause the BP to be set to 0 which is obviously
    // invalid, report that error specifically.
    if (*bp == 0)
      return ReportError("Base Pointer is 0, can't evaluate.");

    result_type_ = ResultType::kPointer;
    Push(DwarfStackEntry(*bp + offset));
    return Completion::kSync;
  }

  // Must request async.
  data_provider_->GetFrameBaseAsync(
      [weak_eval = weak_factory_.GetWeakPtr(), offset](const Err& err, UnsignedType value) {
        if (!weak_eval)
          return;
        if (err.has_error()) {
          weak_eval->ReportError(err);
          return;
        }

        if (value == 0) {
          weak_eval->ReportError("Base Pointer is 0, can't evaluate.");
          return;
        }

        weak_eval->result_type_ = ResultType::kPointer;
        weak_eval->Push(DwarfStackEntry(static_cast<UnsignedType>(value + offset)));

        // Picks up processing at the next instruction.
        weak_eval->ContinueEval();
      });

  return Completion::kAsync;
}

// 2 parameters: 8-byte unsigned DIE offset containing the value, SLEB128 offset from that value.
DwarfExprEval::Completion DwarfExprEval::OpImplicitPointer(const char* op_name) {
  // GCC generates this when a pointer has been optimized out, but it still can provide the value of
  // the thing that it pointed to. We don't implement this.
  UnsignedType die_offset;
  if (!ReadUnsigned(8, &die_offset))
    return Completion::kSync;

  SignedType value_offset;
  if (!ReadLEBSigned(&value_offset))
    return Completion::kSync;

  if (is_string_output()) {
    return AppendString(std::string(op_name) + "(" + to_hex_string(die_offset) + ", " +
                        ExprIntToString(value_offset) + ")");
  }

  return ReportError("Optimized out (DW_OP_implicit_pointer)");
}

// 2 parameters: ULEB128 length, followed by that much data (in machine-endianness).
DwarfExprEval::Completion DwarfExprEval::OpImplicitValue() {
  UnsignedType len = 0;
  if (!ReadLEBUnsigned(&len))
    return Completion::kSync;
  if (len > sizeof(UnsignedType))
    return ReportError(fxl::StringPrintf("DWARF implicit value length too long: 0x%x.",
                                         static_cast<unsigned>(len)));

  UnsignedType value = 0;
  if (!data_extractor_.ReadBytes(static_cast<size_t>(len), &value))
    return ReportError("Not enough data for DWARF implicit value.");

  if (is_string_output()) {
    return AppendString(
        "DW_OP_implicit_value(" + ExprIntToString(len) + ", " + to_hex_string(value) + ")",
        "push(" + to_hex_string(value) + ")");
  }

  Push(DwarfStackEntry(value));
  result_type_ = ResultType::kValue;
  return Completion::kSync;
}

// 1 parameter: ULEB128 constant indexing the register.
DwarfExprEval::Completion DwarfExprEval::OpRegx() {
  UnsignedType reg = 0;
  if (!ReadLEBUnsigned(&reg))
    return Completion::kSync;

  if (is_string_output()) {
    return AppendString("DW_OP_regx(" + ExprIntToString(reg) + ")",
                        GetRegisterName(static_cast<int>(reg)));
  }

  result_type_ = ResultType::kValue;
  return PushRegisterWithOffset(static_cast<int>(reg), 0);
}

// 2 parameters: ULEB128 register number + SLEB128 offset.
DwarfExprEval::Completion DwarfExprEval::OpBregx() {
  UnsignedType reg_val = 0;
  if (!ReadLEBUnsigned(&reg_val))
    return Completion::kSync;
  int reg = static_cast<int>(reg_val);

  SignedType offset = 0;
  if (!ReadLEBSigned(&offset))
    return Completion::kSync;

  if (is_string_output()) {
    return AppendString("DW_OP_bregx(" + std::to_string(reg) + ", " + ExprIntToString(offset) + ")",
                        GetRegisterName(reg) + MakeAddString(offset));
  }

  result_type_ = ResultType::kPointer;
  return PushRegisterWithOffset(reg, offset);
}

// Pops the stack and pushes an given-sized value from memory at that location.
DwarfExprEval::Completion DwarfExprEval::OpDeref(uint32_t byte_size, const char* op_name,
                                                 bool string_include_size) {
  if (is_string_output()) {
    if (string_include_size)
      return AppendString(std::string(op_name) + "(" + std::to_string(byte_size) + ")");
    return AppendString(op_name);
  }

  if (stack_.empty()) {
    ReportStackUnderflow();
    return Completion::kSync;
  }

  if (byte_size == 0 || byte_size > sizeof(UnsignedType))
    return ReportError(fxl::StringPrintf("Invalid DWARF expression read size: %u", byte_size));

  DwarfStackEntry addr = stack_.back();
  stack_.pop_back();
  if (!addr.TreatAsUnsigned())
    return ReportError("DW_OP_deref trying to dereference a non-unsigned value.");

  ReadMemory(addr.unsigned_value(), byte_size, [](DwarfExprEval* eval, std::vector<uint8_t> data) {
    // Success. This assumes little-endian and copies starting from the low bytes. The data will
    // have already been validated to be the correct size so we know it will fit in a UnsignedType.
    FX_DCHECK(data.size() <= sizeof(UnsignedType));
    UnsignedType to_push = 0;
    memcpy(&to_push, data.data(), data.size());
    eval->Push(DwarfStackEntry(to_push));
  });
  return Completion::kAsync;
}

DwarfExprEval::Completion DwarfExprEval::OpDerefSize() {
  // The operand is a 1-byte unsigned constant following the opcode.
  UnsignedType byte_size = 0;
  if (!ReadUnsigned(1, &byte_size))
    return Completion::kSync;

  // The generic deref path can handle the rest.
  return OpDeref(static_cast<uint32_t>(byte_size), "DW_OP_deref_size", true);
}

DwarfExprEval::Completion DwarfExprEval::OpOver() {
  if (is_string_output())
    return AppendString("DW_OP_over");

  // Duplicates the next-to-top over the top item.
  if (stack_.size() < 2)
    ReportStackUnderflow();
  else
    Push(stack_[stack_.size() - 2]);
  return Completion::kSync;
}

// 1 parameter: 1-byte stack index from the top to push.
DwarfExprEval::Completion DwarfExprEval::OpPick() {
  UnsignedType index = 0;
  if (!ReadUnsigned(1, &index))
    return Completion::kSync;

  if (is_string_output())
    return AppendString("DW_OP_pick(" + ExprIntToString(index) + ")");

  if (stack_.size() <= index) {
    ReportStackUnderflow();
    return Completion::kSync;
  }

  // Index is from end (0 = last item).
  Push(stack_[stack_.size() - 1 - index]);
  return Completion::kSync;
}

// 1 paramter: ULEB size of item in bytes.
DwarfExprEval::Completion DwarfExprEval::OpPiece() {
  UnsignedType byte_size = 0;
  if (!ReadLEBUnsigned(&byte_size))
    return Completion::kSync;

  // Upper-bound sanity check on the piece size to guard against corrupted or malicious data.
  constexpr UnsignedType kMaxPieceSize = 16384;
  if (byte_size > kMaxPieceSize) {
    return ReportError(
        fxl::StringPrintf("DWARF expression listed a data size of %d which is too large.",
                          static_cast<int>(byte_size)));
  }

  if (is_string_output())
    return AppendString("DW_OP_piece(" + ExprIntToString(byte_size) + ")");

  if (stack_.empty()) {
    // Defining a piece with no previous data on the stack means to write that many bytes that
    // have no known value.
    result_data_.AppendUnknown(byte_size);
    return Completion::kSync;
  }

  DwarfStackEntry source = stack_.back();
  stack_.pop_back();

  if (result_type_ == ResultType::kValue) {
    // Simple case where the source of the "piece" is the value at the top of the stack.
    if (byte_size > sizeof(UnsignedType)) {
      return ReportError(
          fxl::StringPrintf("DWARF expression listed a data size of %d which is too large.",
                            static_cast<int>(byte_size)));
    }

    size_t source_valid_bytes = source.GetByteSize();
    if (byte_size > source_valid_bytes)
      return ReportError("DW_OP_piece attempting to read more bytes than are valid.");

    // We want the low bytes, this assumes little-endian.
    UnsignedType source_value = source.unsigned_value();
    uint8_t source_as_bytes[sizeof(UnsignedType)];
    memcpy(&source_as_bytes, &source_value, sizeof(UnsignedType));
    result_data_.Append(std::begin(source_as_bytes), &source_as_bytes[byte_size]);

    // Reset the expression state to start a new one.
    result_type_ = ResultType::kPointer;
    return Completion::kSync;
  }

  // This is the more complex case where the top of the stack is a pointer to the value in memory.
  // We read that many bytes from memory and add it to the result data.
  if (!source.TreatAsUnsigned())
    return ReportError("DW_OP_piece attempting to dereference invalid type.");
  ReadMemory(source.unsigned_value(), byte_size,
             [](DwarfExprEval* eval, std::vector<uint8_t> data) {
               // Success. Copy to the result.
               eval->result_data_.Append(data);

               // Reset the expression state to start a new one.
               eval->result_type_ = ResultType::kPointer;
             });

  // The ReadMemory call will complete asynchronously.
  return Completion::kAsync;
}

DwarfExprEval::Completion DwarfExprEval::OpPlusUconst() {
  // "Pops the top stack entry, adds it to the unsigned LEB128 constant operand [...] and pushes the
  // result."
  UnsignedType param = 0;
  if (!ReadLEBUnsigned(&param))
    return Completion::kSync;

  if (is_string_output()) {
    return AppendString("DW_OP_plus_uconst(" + ExprIntToString(param) + ")",
                        "+ " + ExprIntToString(param));
  }

  if (stack_.empty()) {
    ReportStackUnderflow();
  } else {
    DwarfStackEntry top = stack_.back();
    stack_.pop_back();

    // "interpreted as the same type as the operand popped from the top of the stack."
    if (top.TreatAsUnsigned()) {
      Push(DwarfStackEntry(top.type_ref(), top.unsigned_value() + param));
    } else if (top.TreatAsSigned()) {
      Push(DwarfStackEntry(top.type_ref(), top.signed_value() + static_cast<SignedType>(param)));
    } else if (top.TreatAsFloat()) {
      Push(DwarfStackEntry(top.type_ref(), top.float_value() + static_cast<float>(param)));
    } else if (top.TreatAsDouble()) {
      Push(DwarfStackEntry(top.type_ref(), top.double_value() + static_cast<double>(param)));
    }
  }
  return Completion::kSync;
}

DwarfExprEval::Completion DwarfExprEval::OpPushSigned(int byte_count, const char* op_name) {
  SignedType value = 0;
  if (!ReadSigned(byte_count, &value))
    return Completion::kSync;

  if (is_string_output()) {
    return AppendString(std::string(op_name) + "(" + ExprIntToString(value) + ")",
                        "push(" + ExprIntToString(value) + ")");
  }

  Push(DwarfStackEntry(static_cast<UnsignedType>(value)));
  return Completion::kSync;
}

DwarfExprEval::Completion DwarfExprEval::OpPushUnsigned(int byte_count, const char* op_name) {
  UnsignedType value = 0;
  if (!ReadUnsigned(byte_count, &value))
    return Completion::kSync;

  if (is_string_output()) {
    return AppendString(std::string(op_name) + "(" + ExprIntToString(value) + ")",
                        "push(" + ExprIntToString(value) + ")");
  }

  Push(DwarfStackEntry(value));
  return Completion::kSync;
}

DwarfExprEval::Completion DwarfExprEval::OpPushLEBSigned() {
  SignedType value = 0;
  if (!ReadLEBSigned(&value))
    return Completion::kSync;

  if (is_string_output())
    return AppendString("DW_OP_consts(" + ExprIntToString(value) + ")",
                        "push(" + ExprIntToString(value) + ")");

  Push(DwarfStackEntry(static_cast<UnsignedType>(value)));
  return Completion::kSync;
}

DwarfExprEval::Completion DwarfExprEval::OpPushLEBUnsigned() {
  UnsignedType value = 0;
  if (!ReadLEBUnsigned(&value))
    return Completion::kSync;

  if (is_string_output()) {
    return AppendString("DW_OP_constu(" + ExprIntToString(value) + ")",
                        "push(" + ExprIntToString(value) + ")");
  }

  Push(DwarfStackEntry(value));
  return Completion::kSync;
}

DwarfExprEval::Completion DwarfExprEval::OpRot() {
  if (is_string_output())
    return AppendString("DW_OP_rot");

  // Rotates the top 3 entries "down" with wraparound. "The entry at the top of the stack becomes
  // the third stack entry, the second entry becomes the top of the stack, and the third entry
  // becomes the second entry."
  if (stack_.size() < 3) {
    ReportStackUnderflow();
  } else {
    DwarfStackEntry top = stack_[stack_.size() - 1];
    DwarfStackEntry one_back = stack_[stack_.size() - 2];
    DwarfStackEntry two_back = stack_[stack_.size() - 3];

    stack_[stack_.size() - 1] = std::move(one_back);
    stack_[stack_.size() - 2] = std::move(two_back);
    stack_[stack_.size() - 3] = std::move(top);
  }
  return Completion::kSync;
}

// 1 parameter: 2-byte signed constant.
DwarfExprEval::Completion DwarfExprEval::OpSkip() {
  SignedType skip_amount = 0;
  if (!ReadSigned(2, &skip_amount))
    return Completion::kSync;

  if (is_string_output()) {
    return AppendString("DW_OP_skip(" + ExprIntToString(skip_amount) + ")");

    // Don't actually execute the skip in printing mode, because it could skip backwards to do a
    // loop and we would keep printing from there.
  }

  Skip(skip_amount);
  return Completion::kSync;
}

DwarfExprEval::Completion DwarfExprEval::OpStackValue() {
  if (is_string_output())
    return AppendString("DW_OP_stack_value");

  // "Specifies that the object does not exist in memory but rather is a constant value. The value
  // from the top of the stack is the value to be used. This is the actual object value and not the
  // location."
  result_type_ = ResultType::kValue;
  return Completion::kSync;
}

DwarfExprEval::Completion DwarfExprEval::OpSwap() {
  if (is_string_output())
    return AppendString("DW_OP_swap");

  if (stack_.size() < 2)
    ReportStackUnderflow();
  else
    std::swap(stack_[stack_.size() - 1], stack_[stack_.size() - 2]);
  return Completion::kSync;
}

DwarfExprEval::Completion DwarfExprEval::OpTlsAddr(const char* op_name) {
  if (is_string_output())
    return AppendString(op_name);

  if (stack_.size() < 1) {
    ReportStackUnderflow();
    return Completion::kSync;
  }

  DwarfStackEntry entry = stack_.back();
  stack_.pop_back();
  if (!entry.TreatAsUnsigned())
    return ReportError("Non-unsigned type parameter on stack when computing TLS.");
  UnsignedType tls_offset = entry.unsigned_value();

  auto debug_address = data_provider_->GetDebugAddressForContext(symbol_context_);

  if (!debug_address)
    return ReportError("Debug address unavailable.");

  data_provider_->GetTLSSegment(
      symbol_context_, [tls_offset, weak_eval = weak_factory_.GetWeakPtr()](ErrOr<uint64_t> value) {
        if (!weak_eval) {
          return;
        }

        if (value.has_error()) {
          weak_eval->ReportError(value.err());
          return;
        }

        weak_eval->Push(DwarfStackEntry(static_cast<UnsignedType>(value.value()) + tls_offset));
        weak_eval->ContinueEval();
      });

  return Completion::kAsync;
}

void DwarfExprEval::Skip(SignedType amount) {
  SignedType new_index = static_cast<SignedType>(data_extractor_.cur()) + amount;
  if (new_index < 0) {
    // Skip before beginning is an error.
    ReportError("DWARF expression skips out-of-bounds.");
  }

  // The Seek() call will clamp to the end which will just mark the expression terminated.
  data_extractor_.Seek(static_cast<size_t>(new_index));
}

std::string DwarfExprEval::GetRegisterName(int reg_number) const {
  const debug::RegisterInfo* reg_info =
      data_provider_ ? debug::DWARFToRegisterInfo(data_provider_->GetArch(), reg_number) : nullptr;
  if (!reg_info)  // Fall back on reporting the register
    return "dwarf_register(" + std::to_string(reg_number) + ")";

  return "register(" + reg_info->name + ")";
}

DwarfExprEval::Completion DwarfExprEval::AppendString(const std::string& op_output,
                                                      const std::string& nice_output) {
  FX_DCHECK(is_string_output());  // Must be in string output mode.

  if (!string_output_.empty())
    string_output_.append(", ");

  if (string_output_mode_ == StringOutput::kPretty && !nice_output.empty()) {
    string_output_.append(nice_output);
  } else {
    string_output_.append(op_output);
  }

  return Completion::kSync;
}

}  // namespace zxdb
