// 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.

#ifndef SRC_DEVELOPER_DEBUG_ZXDB_SYMBOLS_DWARF_EXPR_EVAL_H_
#define SRC_DEVELOPER_DEBUG_ZXDB_SYMBOLS_DWARF_EXPR_EVAL_H_

#include <stdint.h>

#include <memory>
#include <vector>

#include "lib/fit/function.h"
#include "src/developer/debug/shared/register_id.h"
#include "src/developer/debug/zxdb/common/data_extractor.h"
#include "src/developer/debug/zxdb/common/err.h"
#include "src/developer/debug/zxdb/common/err_or.h"
#include "src/developer/debug/zxdb/common/int128_t.h"
#include "src/developer/debug/zxdb/common/tagged_data_builder.h"
#include "src/developer/debug/zxdb/symbols/arch.h"
#include "src/developer/debug/zxdb/symbols/dwarf_expr.h"
#include "src/developer/debug/zxdb/symbols/dwarf_stack_entry.h"
#include "src/developer/debug/zxdb/symbols/symbol_context.h"
#include "src/lib/fxl/macros.h"
#include "src/lib/fxl/memory/ref_ptr.h"
#include "src/lib/fxl/memory/weak_ptr.h"

namespace zxdb {

class SymbolDataProvider;

// This class evaluates DWARF expressions. These expressions are used to encode the locations of
// variables and a few other nontrivial lookups.
//
// This class is complicated by supporting asynchronous interactions with the debugged program. This
// means that accessing register and memory data (which may be required to evaluate the expression)
// may be asynchronous.
//
//  eval_ = std::make_unique<DwarfExprEval>();
//  eval_.eval(..., [](DwarfExprEval* eval, const Err& err) {
//    if (err.has_error()) {
//      // Handle error.
//    } else {
//      ... use eval->GetResult() ...
//    }
//  });
class DwarfExprEval {
 public:
  // Type of completion from a call. Async completion will happen in a callback
  // in the future.
  enum class Completion { kSync, kAsync };

  // A DWARF expression can compute either the address of the desired object in the debugged
  // programs address space, or it can compute the actual value of the object (because it may not
  // exist in memory).
  enum class ResultType {
    // The return value from GetResult() is a pointer to the result in memory. The caller will need
    // to know the size and type of this result from the context.
    kPointer,

    // The return value from GetResult() is the resulting value itself. Most results will need
    // to be truncated to the correct size (the caller needs to know the size and type from the
    // context).
    kValue,

    // The result is stored in a data block returned by result_data(). It can be any size. Do not
    // call GetResult() as the stack normally has no data on it in this case.
    kData
  };

  enum class StringOutput {
    kNone,     // Don't do string output.
    kLiteral,  // Outputs exact DWARF opcodes and values.
    kPretty,   // Decodes values and register names.
  };

  using SignedType = DwarfStackEntry::SignedType;
  using UnsignedType = DwarfStackEntry::UnsignedType;

  using CompletionCallback = fit::callback<void(DwarfExprEval* eval, const Err& err)>;

  DwarfExprEval();
  ~DwarfExprEval();

  // Pushes a value on the stack. Call before Eval() for the cases where an expression requires
  // some initial state.
  void Push(DwarfStackEntry value);

  // Clears any existing values in the stack.
  void Clear() { stack_.clear(); }

  // A complete expression has finished executing but may or may not have had an error. A successful
  // expression indicates execution is complete and there is a valid result to read.
  bool is_complete() const { return is_complete_; }
  bool is_success() const { return is_success_; }

  // Valid when is_success(), this indicates how to interpret the value from GetResult().
  ResultType GetResultType() const;

  // Valid when is_success() and type() == kPointer/kValue. Returns the result of evaluating the
  // expression. The meaning will be dependent on the context of the expression being evaluated.
  // Most results will be smaller than this in which case they will use only the low bits.
  DwarfStackEntry GetResult() const;

  // Destructively returns the generated data buffer. Valid when is_success() and type() == kData.
  TaggedData TakeResultData();

  // When the result is computed, this will indicate if the result is directly from a register,
  // and if it is, which one. If the current result was the result of some computation and has no
  // direct register source, it will be RegisterID::kUnknown.
  debug::RegisterID current_register_id() const { return current_register_id_; }

  // When the result is computed, this will indicate whether it's from a constant source (encoded in
  // the DWARF expression) or is the result of reading some memory or registers.
  bool result_is_constant() const { return result_is_constant_; }

  // Evaluates the expression using the current stack. If the stack needs initial setup, callers
  // should call Push() first, or Clear() if there might be unwanted data.
  //
  // This will take a reference to the SymbolDataProvider until the computation is complete.
  //
  // The symbol context is used to evaluate relative addresses. It should be the context associated
  // with the module that this expression is from. Normally this will be retrieved from the
  // symbol that generated the dwarf expression (see DwarfExpr::source()).
  //
  // The return value will indicate if the request completed synchronously. In synchronous
  // completion the callback will have been called reentrantly from within the stack of this
  // function. This does not indicate success as it could succeed or fail both synchronously and
  // asynchronously.
  //
  // This class must not be deleted from within the completion callback.
  Completion Eval(fxl::RefPtr<SymbolDataProvider> data_provider,
                  const SymbolContext& symbol_context, DwarfExpr expr, CompletionCallback cb);

  // Converts the given DWARF expression to a string. The result values on this class won't be
  // set since the expression won't actually be evaluated.
  //
  // The data_provider is required to get the current architecture for pretty-printing register
  // names. To disable this, pass the default SymbolDataProvider implementation.
  //
  // When "pretty" mode is enabled, operations will be simplified and platform register names will
  // be substituted.
  std::string ToString(fxl::RefPtr<SymbolDataProvider> data_provider,
                       const SymbolContext& symbol_context, DwarfExpr expr, bool pretty);

 private:
  void SetUp(fxl::RefPtr<SymbolDataProvider> data_provider, const SymbolContext& symbol_context,
             DwarfExpr expr, CompletionCallback cb);

  // Evaluates the next phases of the expression until an asynchronous operation is required.
  // Returns the value of |is_complete| because |this| could be deleted by the time this method
  // returns.
  bool ContinueEval();

  // Evaluates a single operation.
  Completion EvalOneOp();

  // Adds a register's contents + an offset to the stack. Use 0 for the offset to get the raw
  // register value.
  Completion PushRegisterWithOffset(int dwarf_register_number, int128_t offset);

  // These read constant data from the current index in the stream. The size of the data is in
  // byte_size, and the result will be extended to a stack entry according to the type.
  //
  // They return true if the value was read, false if there wasn't enough data (they will issue the
  // error internally, the calling code should just return on failure).
  bool ReadSigned(int byte_size, SignedType* output);
  bool ReadUnsigned(int byte_size, UnsignedType* output);

  // Reads a signed or unsigned LEB constant from the stream. They return true if the value was
  // read, false if there wasn't enough data (they will issue the error internally, the calling code
  // should just return on failure).
  bool ReadLEBSigned(SignedType* output);
  bool ReadLEBUnsigned(UnsignedType* output);

  // Schedules an asynchronous memory read. If there is any failure, including short reads, this
  // will report it and fail evaluation.
  //
  // If the correct amount of memory is read, it will issue the callback with the data and then
  // continue evaluation.
  void ReadMemory(TargetPointer address, uint32_t byte_size,
                  fit::callback<void(DwarfExprEval* eval, std::vector<uint8_t> value)> on_success);

  // Reports the given error. Always returns "kSync" so the caller can do "return ReportError()"
  // which would be the common case.
  Completion ReportError(const std::string& msg);
  Completion ReportError(const Err& err);
  void ReportStackUnderflow();
  void ReportUnimplementedOpcode(uint8_t op);

  // Executes the given unary operation with the top stack entry as the parameter and pushes the
  // result.
  Completion OpUnary(ErrOr<DwarfStackEntry> (*op)(const DwarfStackEntry&), const char* op_name);

  // Executes the given binary operation by popping the top two stack entries as parameters (the
  // first is the next-to-top, the second is the top) and pushing the result on the stack.
  Completion OpBinary(ErrOr<DwarfStackEntry> (*op)(const DwarfStackEntry&, const DwarfStackEntry&),
                      const char* op_name);

  // Implements DW_OP_addrx and DW_OP_constx (corresponding to the given result types). The type
  // of the result on the stack will be set to the given result type, and kPointer result types
  // will be relocated according to the module's address offset.
  Completion OpAddrBase(ResultType result_type, const char* op_name);

  // Operations. On call, the data extractor will read at the byte following the opcode, and on
  // return it will point to the next instruction (any parameters will be consumed).
  //
  // Some functions handle more than one opcode. In these cases, the opcode name for string output
  // is passed in as op_name.
  Completion OpAddr();
  Completion OpBitPiece();
  Completion OpBra();
  Completion OpBreg(uint8_t op);
  Completion OpCFA();
  Completion OpDeref(uint32_t byte_size, const char* op_name, bool string_include_size);
  Completion OpDerefSize();
  Completion OpDrop();
  Completion OpDup();
  Completion OpEntryValue(const char* op_name);
  Completion OpFbreg();
  Completion OpImplicitPointer(const char* op_name);
  Completion OpImplicitValue();
  Completion OpRegx();
  Completion OpBregx();
  Completion OpOver();
  Completion OpPick();
  Completion OpPiece();
  Completion OpPlusUconst();
  Completion OpPushSigned(int byte_count, const char* op_name);
  Completion OpPushUnsigned(int byte_count, const char* op_name);
  Completion OpPushLEBSigned();
  Completion OpPushLEBUnsigned();
  Completion OpRot();
  Completion OpSkip();
  Completion OpStackValue();
  Completion OpSwap();
  Completion OpTlsAddr(const char* op_name);

  // Adjusts the instruction offset by the given amount, handling out-of-bounds as appropriate. This
  // is the backend for jumps and branches.
  void Skip(int128_t amount);

  // Returns true if generating a string rather than evaluating an expression.
  bool is_string_output() const { return string_output_mode_ != StringOutput::kNone; }

  // Returns a user-readable name for the current architecture's given DWARF register. For
  // stringinfying DWARF expressions.
  std::string GetRegisterName(int reg_number) const;

  // Append an operation to the description in is_string_output() mode (will assert if used outside
  // of this mode).
  //
  // When in kPretty output mode, the second parameter will be used if present. Otherwise the first
  // parameter will be used. The first output should be the actual DWARF operatiors, while the
  // second one can have another level of decode.
  //
  // Always returns "sync" completion so it can be used like "return AppendString(...)" from the
  // opcode handlers.
  Completion AppendString(const std::string& op_output,
                          const std::string& nice_output = std::string());

  fxl::RefPtr<SymbolDataProvider> data_provider_;
  SymbolContext symbol_context_;

  // The expression. See also data_extractor_ which points into here.
  DwarfExpr expr_;

  // Determines if a string describing the expression is being generated instead of evaluating
  // the expression. See is_string_output() and AppendString().
  StringOutput string_output_mode_ = StringOutput::kNone;
  std::string string_output_;  // Result when string_output_mode_ != kNone;

  CompletionCallback completion_callback_;  // Null in string printing mode (it's synchronous).
  bool in_completion_callback_ = false;     // To check for lifetime errors.

  DataExtractor data_extractor_;

  // The result type. Normally expressions compute pointers unless explicitly tagged as a value.
  // This tracks the current "simple" expression result type. For "composite" operations that
  // use one or more DW_OP_[bit_]piece there will be nonempty result_data_ rather than writing
  // "kData" here.
  //
  // This needs to be separate because there can be multiple simple expressions independent of the
  // result_data_ in the composite case. So this value will never be "kData".
  ResultType result_type_ = ResultType::kPointer;

  // Indicates that execution is complete. When this is true, the callback will have been issued. A
  // complete expression could have stopped on error or success (see is_success_).
  bool is_complete_ = false;

  // Indicates that the expression is complete and that there is a result value.
  bool is_success_ = false;

  std::vector<DwarfStackEntry> stack_;

  // Tracks the result when generating composite descriptions via DW_OP_[bit_]piece. A nonempty
  // contents indicates that the final result is of type "kData" (see result_type_ for more).
  //
  // TODO(bug 39630) we will need to track source information (memory address or register ID) for
  // each subrange in this block to support writing to the generated object.
  TaggedDataBuilder result_data_;

  // Set when a register value is pushed on the stack and cleared when anything else happens. This
  // allows the user of the expression to determine if the result of the expression is directly from
  // a register (say, to support writing to that value in the future).
  debug::RegisterID current_register_id_ = debug::RegisterID::kUnknown;

  // Tracks whether the current expression uses only constant data. Any operations that read memory
  // or registers should clear this.
  bool result_is_constant_ = true;

  // The nested evaluator for executing DW_OP_entry_value expressions.
  std::unique_ptr<DwarfExprEval> nested_eval_;

  fxl::WeakPtrFactory<DwarfExprEval> weak_factory_;

  FXL_DISALLOW_COPY_AND_ASSIGN(DwarfExprEval);
};

}  // namespace zxdb

#endif  // SRC_DEVELOPER_DEBUG_ZXDB_SYMBOLS_DWARF_EXPR_EVAL_H_
