/*
 * Copyright 2016 WebAssembly Community Group participants
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "wabt/binary-reader-objdump.h"

#include <algorithm>
#include <cassert>
#include <cinttypes>
#include <cstdio>
#include <cstring>
#include <vector>

#if HAVE_STRCASECMP
#include <strings.h>
#endif

#include "wabt/binary-reader-nop.h"
#include "wabt/filenames.h"
#include "wabt/literal.h"
#include "wabt/string-util.h"

namespace wabt {

namespace {

class BinaryReaderObjdumpBase : public BinaryReaderNop {
 public:
  BinaryReaderObjdumpBase(const uint8_t* data,
                          size_t size,
                          ObjdumpOptions* options,
                          ObjdumpState* state);

  bool OnError(const Error&) override;

  Result BeginModule(uint32_t version) override;
  Result BeginSection(Index section_index,
                      BinarySection section_type,
                      Offset size) override;

  Result OnOpcode(Opcode Opcode) override;
  Result OnRelocCount(Index count, Index section_index) override;

 protected:
  std::string_view GetTypeName(Index index) const;
  std::string_view GetFunctionName(Index index) const;
  std::string_view GetGlobalName(Index index) const;
  std::string_view GetLocalName(Index function_index, Index local_index) const;
  std::string_view GetSectionName(Index index) const;
  std::string_view GetTagName(Index index) const;
  std::string_view GetSymbolName(Index index) const;
  std::string_view GetSegmentName(Index index) const;
  std::string_view GetTableName(Index index) const;
  void PrintRelocation(const Reloc& reloc, Offset offset) const;
  Offset GetPrintOffset(Offset offset) const;
  Offset GetSectionStart(BinarySection section_code) const {
    return section_starts_[static_cast<size_t>(section_code)];
  }

  ObjdumpOptions* options_;
  ObjdumpState* objdump_state_;
  const uint8_t* data_;
  size_t size_;
  bool print_details_ = false;
  BinarySection reloc_section_ = BinarySection::Invalid;
  Offset section_starts_[kBinarySectionCount];
  // Map of section index to section type
  std::vector<BinarySection> section_types_;
  bool section_found_ = false;
  std::string module_name_;
  Opcode current_opcode = Opcode::Unreachable;

  std::unique_ptr<FileStream> err_stream_;
};

BinaryReaderObjdumpBase::BinaryReaderObjdumpBase(const uint8_t* data,
                                                 size_t size,
                                                 ObjdumpOptions* options,
                                                 ObjdumpState* objdump_state)
    : options_(options),
      objdump_state_(objdump_state),
      data_(data),
      size_(size),
      err_stream_(FileStream::CreateStderr()) {
  ZeroMemory(section_starts_);
}

Result BinaryReaderObjdumpBase::BeginSection(Index section_index,
                                             BinarySection section_code,
                                             Offset size) {
  section_starts_[static_cast<size_t>(section_code)] = state->offset;
  section_types_.push_back(section_code);
  return Result::Ok;
}

bool BinaryReaderObjdumpBase::OnError(const Error&) {
  // Tell the BinaryReader that this error is "handled" for all passes other
  // than the prepass. When the error is handled the default message will be
  // suppressed.
  return options_->mode != ObjdumpMode::Prepass;
}

Result BinaryReaderObjdumpBase::BeginModule(uint32_t version) {
  switch (options_->mode) {
    case ObjdumpMode::Headers:
      printf("\n");
      printf("Sections:\n\n");
      break;
    case ObjdumpMode::Details:
      printf("\n");
      printf("Section Details:\n\n");
      break;
    case ObjdumpMode::Disassemble:
      printf("\n");
      printf("Code Disassembly:\n\n");
      break;
    case ObjdumpMode::Prepass: {
      std::string_view basename = GetBasename(options_->filename);
      if (basename == "-") {
        basename = "<stdin>";
      }
      printf("%s:\tfile format wasm %#x\n", std::string(basename).c_str(),
             version);
      break;
    }
    case ObjdumpMode::RawData:
      break;
  }

  return Result::Ok;
}

std::string_view BinaryReaderObjdumpBase::GetTypeName(Index index) const {
  return objdump_state_->type_names.Get(index);
}

std::string_view BinaryReaderObjdumpBase::GetFunctionName(Index index) const {
  return objdump_state_->function_names.Get(index);
}

std::string_view BinaryReaderObjdumpBase::GetGlobalName(Index index) const {
  return objdump_state_->global_names.Get(index);
}

std::string_view BinaryReaderObjdumpBase::GetLocalName(
    Index function_index,
    Index local_index) const {
  return objdump_state_->local_names.Get(function_index, local_index);
}

std::string_view BinaryReaderObjdumpBase::GetSectionName(Index index) const {
  return objdump_state_->section_names.Get(index);
}

std::string_view BinaryReaderObjdumpBase::GetTagName(Index index) const {
  return objdump_state_->tag_names.Get(index);
}

std::string_view BinaryReaderObjdumpBase::GetSegmentName(Index index) const {
  return objdump_state_->segment_names.Get(index);
}

std::string_view BinaryReaderObjdumpBase::GetTableName(Index index) const {
  return objdump_state_->table_names.Get(index);
}

std::string_view BinaryReaderObjdumpBase::GetSymbolName(
    Index symbol_index) const {
  if (symbol_index >= objdump_state_->symtab.size())
    return "<illegal_symbol_index>";
  ObjdumpSymbol& sym = objdump_state_->symtab[symbol_index];
  switch (sym.kind) {
    case SymbolType::Function:
      return GetFunctionName(sym.index);
    case SymbolType::Data:
      return sym.name;
    case SymbolType::Global:
      return GetGlobalName(sym.index);
    case SymbolType::Section:
      return GetSectionName(sym.index);
    case SymbolType::Tag:
      return GetTagName(sym.index);
    case SymbolType::Table:
      return GetTableName(sym.index);
  }
  WABT_UNREACHABLE;
}

void BinaryReaderObjdumpBase::PrintRelocation(const Reloc& reloc,
                                              Offset offset) const {
  printf("           %06" PRIzx ": %-18s %" PRIindex, offset,
         GetRelocTypeName(reloc.type), reloc.index);
  if (reloc.addend) {
    printf(" + %d", reloc.addend);
  }
  if (reloc.type != RelocType::TypeIndexLEB) {
    printf(" <" PRIstringview ">",
           WABT_PRINTF_STRING_VIEW_ARG(GetSymbolName(reloc.index)));
  }
  printf("\n");
}

Offset BinaryReaderObjdumpBase::GetPrintOffset(Offset offset) const {
  return options_->section_offsets
             ? offset - GetSectionStart(BinarySection::Code)
             : offset;
}

Result BinaryReaderObjdumpBase::OnOpcode(Opcode opcode) {
  current_opcode = opcode;
  return Result::Ok;
}

Result BinaryReaderObjdumpBase::OnRelocCount(Index count, Index section_index) {
  if (section_index >= section_types_.size()) {
    err_stream_->Writef("invalid relocation section index: %" PRIindex "\n",
                        section_index);
    reloc_section_ = BinarySection::Invalid;
    return Result::Error;
  }
  reloc_section_ = section_types_[section_index];
  return Result::Ok;
}

class BinaryReaderObjdumpPrepass : public BinaryReaderObjdumpBase {
 public:
  using BinaryReaderObjdumpBase::BinaryReaderObjdumpBase;

  Result BeginSection(Index section_index,
                      BinarySection section_code,
                      Offset size) override {
    BinaryReaderObjdumpBase::BeginSection(section_index, section_code, size);
    if (section_code != BinarySection::Custom) {
      objdump_state_->section_names.Set(section_index,
                                        wabt::GetSectionName(section_code));
    }
    return Result::Ok;
  }

  Result BeginCustomSection(Index section_index,
                            Offset size,
                            std::string_view section_name) override {
    objdump_state_->section_names.Set(section_index, section_name);
    return Result::Ok;
  }

  Result OnFunctionName(Index index, std::string_view name) override {
    SetFunctionName(index, name);
    return Result::Ok;
  }

  Result OnFuncType(Index index,
                    Index param_count,
                    Type* param_types,
                    Index result_count,
                    Type* result_types) override {
    objdump_state_->function_param_counts[index] = param_count;
    return Result::Ok;
  }

  Result OnNameEntry(NameSectionSubsection type,
                     Index index,
                     std::string_view name) override {
    switch (type) {
      // TODO(sbc): remove OnFunctionName in favor of just using
      // OnNameEntry so that this works
      /*
      case NameSectionSubsection::Function:
        SetFunctionName(index, name);
        break;
      */
      case NameSectionSubsection::Type:
        SetTypeName(index, name);
        break;
      case NameSectionSubsection::Global:
        SetGlobalName(index, name);
        break;
      case NameSectionSubsection::Table:
        SetTableName(index, name);
        break;
      case NameSectionSubsection::DataSegment:
        SetSegmentName(index, name);
        break;
      case NameSectionSubsection::Tag:
        SetTagName(index, name);
        break;
      default:
        break;
    }
    return Result::Ok;
  }

  Result OnLocalName(Index function_index,
                     Index local_index,
                     std::string_view local_name) override {
    SetLocalName(function_index, local_index, local_name);
    return Result::Ok;
  }

  Result OnSymbolCount(Index count) override {
    objdump_state_->symtab.resize(count);
    return Result::Ok;
  }

  Result OnDataSymbol(Index index,
                      uint32_t flags,
                      std::string_view name,
                      Index segment,
                      uint32_t offset,
                      uint32_t size) override {
    objdump_state_->symtab[index] = {SymbolType::Data, std::string(name), 0};
    return Result::Ok;
  }

  Result OnFunctionSymbol(Index index,
                          uint32_t flags,
                          std::string_view name,
                          Index func_index) override {
    if (!name.empty()) {
      SetFunctionName(func_index, name);
    }
    objdump_state_->symtab[index] = {SymbolType::Function, std::string(name),
                                     func_index};
    return Result::Ok;
  }

  Result OnGlobalSymbol(Index index,
                        uint32_t flags,
                        std::string_view name,
                        Index global_index) override {
    if (!name.empty()) {
      SetGlobalName(global_index, name);
    }
    objdump_state_->symtab[index] = {SymbolType::Global, std::string(name),
                                     global_index};
    return Result::Ok;
  }

  Result OnSectionSymbol(Index index,
                         uint32_t flags,
                         Index section_index) override {
    objdump_state_->symtab[index] = {SymbolType::Section,
                                     std::string(GetSectionName(section_index)),
                                     section_index};
    return Result::Ok;
  }

  Result OnTagSymbol(Index index,
                     uint32_t flags,
                     std::string_view name,
                     Index tag_index) override {
    if (!name.empty()) {
      SetTagName(tag_index, name);
    }
    objdump_state_->symtab[index] = {SymbolType::Tag, std::string(name),
                                     tag_index};
    return Result::Ok;
  }

  Result OnTableSymbol(Index index,
                       uint32_t flags,
                       std::string_view name,
                       Index table_index) override {
    if (!name.empty()) {
      SetTableName(table_index, name);
    }
    objdump_state_->symtab[index] = {SymbolType::Table, std::string(name),
                                     table_index};
    return Result::Ok;
  }

  Result OnImportFunc(Index import_index,
                      std::string_view module_name,
                      std::string_view field_name,
                      Index func_index,
                      Index sig_index) override {
    SetFunctionName(func_index, module_name + "." + field_name);
    return Result::Ok;
  }

  Result OnImportTag(Index import_index,
                     std::string_view module_name,
                     std::string_view field_name,
                     Index tag_index,
                     Index sig_index) override {
    SetTagName(tag_index, module_name + "." + field_name);
    return Result::Ok;
  }

  Result OnImportGlobal(Index import_index,
                        std::string_view module_name,
                        std::string_view field_name,
                        Index global_index,
                        Type type,
                        bool mutable_) override {
    SetGlobalName(global_index, module_name + "." + field_name);
    return Result::Ok;
  }

  Result OnImportTable(Index import_index,
                       std::string_view module_name,
                       std::string_view field_name,
                       Index table_index,
                       Type elem_type,
                       const Limits* elem_limits) override {
    SetTableName(table_index, module_name + "." + field_name);
    return Result::Ok;
  }

  Result OnExport(Index index,
                  ExternalKind kind,
                  Index item_index,
                  std::string_view name) override {
    if (kind == ExternalKind::Func) {
      SetFunctionName(item_index, name);
    } else if (kind == ExternalKind::Global) {
      SetGlobalName(item_index, name);
    }
    return Result::Ok;
  }

  Result OnReloc(RelocType type,
                 Offset offset,
                 Index index,
                 uint32_t addend) override;

  Result OnModuleName(std::string_view name) override {
    if (options_->mode == ObjdumpMode::Prepass) {
      printf("module name: <" PRIstringview ">\n",
             WABT_PRINTF_STRING_VIEW_ARG(name));
    }
    return Result::Ok;
  }

  Result OnSegmentInfo(Index index,
                       std::string_view name,
                       Address alignment_log2,
                       uint32_t flags) override {
    SetSegmentName(index, name);
    return Result::Ok;
  }

 protected:
  void SetTypeName(Index index, std::string_view name);
  void SetFunctionName(Index index, std::string_view name);
  void SetGlobalName(Index index, std::string_view name);
  void SetLocalName(Index function_index,
                    Index local_index,
                    std::string_view name);
  void SetTagName(Index index, std::string_view name);
  void SetTableName(Index index, std::string_view name);
  void SetSegmentName(Index index, std::string_view name);
};

void BinaryReaderObjdumpPrepass::SetTypeName(Index index,
                                             std::string_view name) {
  objdump_state_->type_names.Set(index, name);
}

void BinaryReaderObjdumpPrepass::SetFunctionName(Index index,
                                                 std::string_view name) {
  objdump_state_->function_names.Set(index, name);
}

void BinaryReaderObjdumpPrepass::SetGlobalName(Index index,
                                               std::string_view name) {
  objdump_state_->global_names.Set(index, name);
}

void BinaryReaderObjdumpPrepass::SetLocalName(Index function_index,
                                              Index local_index,
                                              std::string_view name) {
  objdump_state_->local_names.Set(function_index, local_index, name);
}

void BinaryReaderObjdumpPrepass::SetTagName(Index index,
                                            std::string_view name) {
  objdump_state_->tag_names.Set(index, name);
}

void BinaryReaderObjdumpPrepass::SetTableName(Index index,
                                              std::string_view name) {
  objdump_state_->table_names.Set(index, name);
}

void BinaryReaderObjdumpPrepass::SetSegmentName(Index index,
                                                std::string_view name) {
  objdump_state_->segment_names.Set(index, name);
}

Result BinaryReaderObjdumpPrepass::OnReloc(RelocType type,
                                           Offset offset,
                                           Index index,
                                           uint32_t addend) {
  BinaryReaderObjdumpBase::OnReloc(type, offset, index, addend);
  if (reloc_section_ == BinarySection::Code) {
    objdump_state_->code_relocations.emplace_back(type, offset, index, addend);
  } else if (reloc_section_ == BinarySection::Data) {
    objdump_state_->data_relocations.emplace_back(type, offset, index, addend);
  }
  return Result::Ok;
}

class BinaryReaderObjdumpDisassemble : public BinaryReaderObjdumpBase {
 public:
  using BinaryReaderObjdumpBase::BinaryReaderObjdumpBase;

  std::string BlockSigToString(Type type) const;

  Result OnFunction(Index index, Index sig_index) override;

  Result BeginFunctionBody(Index index, Offset size) override;
  Result EndFunctionBody(Index index) override;

  Result OnLocalDeclCount(Index count) override;
  Result OnLocalDecl(Index decl_index, Index count, Type type) override;

  Result OnOpcode(Opcode Opcode) override;
  Result OnOpcodeBare() override;
  Result OnOpcodeIndex(Index value) override;
  Result OnOpcodeIndexIndex(Index value, Index value2) override;
  Result OnOpcodeUint32(uint32_t value) override;
  Result OnOpcodeUint32Uint32(uint32_t value, uint32_t value2) override;
  Result OnCallIndirectExpr(uint32_t sig_indix, uint32_t table_index) override;
  Result OnOpcodeUint32Uint32Uint32(uint32_t value,
                                    uint32_t value2,
                                    uint32_t value3) override;
  Result OnOpcodeUint32Uint32Uint32Uint32(uint32_t value,
                                          uint32_t value2,
                                          uint32_t value3,
                                          uint32_t value4) override;
  Result OnOpcodeUint64(uint64_t value) override;
  Result OnOpcodeF32(uint32_t value) override;
  Result OnOpcodeF64(uint64_t value) override;
  Result OnOpcodeV128(v128 value) override;
  Result OnOpcodeBlockSig(Type sig_type) override;
  Result OnOpcodeType(Type type) override;

  Result OnTryTableExpr(Type sig_type,
                        const CatchClauseVector& catches) override;
  Result OnBrTableExpr(Index num_targets,
                       Index* target_depths,
                       Index default_target_depth) override;
  Result OnDelegateExpr(Index) override;
  Result OnEndExpr() override;

 private:
  void LogOpcode(const char* fmt, ...);

  Offset current_opcode_offset = 0;
  Offset last_opcode_end = 0;
  int indent_level = 0;
  Index next_reloc = 0;
  Index current_function_index = 0;
  Index local_index_ = 0;
  bool in_function_body = false;
  bool skip_next_opcode_ = false;
};

std::string BinaryReaderObjdumpDisassemble::BlockSigToString(Type type) const {
  if (type.IsIndex()) {
    return StringPrintf("type[%d]", type.GetIndex());
  } else if (type == Type::Void) {
    return "";
  } else {
    return type.GetName();
  }
}

Result BinaryReaderObjdumpDisassemble::OnOpcode(Opcode opcode) {
  BinaryReaderObjdumpBase::OnOpcode(opcode);
  if (!in_function_body) {
    return Result::Ok;
  }
  if (options_->debug) {
    const char* opcode_name = opcode.GetName();
    err_stream_->Writef("on_opcode: %#" PRIzx ": %s\n", state->offset,
                        opcode_name);
  }

  if (last_opcode_end) {
    // Takes care of cases where opcode's bytes was a non-canonical leb128
    // encoding. In this case, opcode.GetLength() under-reports the length,
    // since it canonicalizes the opcode.
    if (state->offset < last_opcode_end + opcode.GetLength()) {
      Opcode missing_opcode = Opcode::FromCode(data_[last_opcode_end]);
      const char* opcode_name = missing_opcode.GetName();
      fprintf(stderr,
              "error: %#" PRIzx " missing opcode callback at %#" PRIzx
              " (%#02x=%s)\n",
              state->offset, last_opcode_end + 1, data_[last_opcode_end],
              opcode_name);
      return Result::Error;
    }
  }

  current_opcode_offset = state->offset;
  return Result::Ok;
}

#define IMMEDIATE_OCTET_COUNT 9

Result BinaryReaderObjdumpDisassemble::OnLocalDeclCount(Index count) {
  if (!in_function_body) {
    return Result::Ok;
  }
  current_opcode_offset = state->offset;
  return Result::Ok;
}

Result BinaryReaderObjdumpDisassemble::OnLocalDecl(Index decl_index,
                                                   Index count,
                                                   Type type) {
  if (!in_function_body) {
    return Result::Ok;
  }
  Offset offset = current_opcode_offset;
  size_t data_size = state->offset - offset;

  printf(" %06" PRIzx ":", GetPrintOffset(offset));
  for (size_t i = 0; i < data_size && i < IMMEDIATE_OCTET_COUNT;
       i++, offset++) {
    printf(" %02x", data_[offset]);
  }
  for (size_t i = data_size; i < IMMEDIATE_OCTET_COUNT; i++) {
    printf("   ");
  }
  printf(" | local[");
  if (count > 0) {
    printf("%" PRIindex, local_index_);

    if (count != 1) {
      printf("..%" PRIindex "", local_index_ + count - 1);
    }
    local_index_ += count;
  }
  printf("] type=%s\n", type.GetName().c_str());

  last_opcode_end = current_opcode_offset + data_size;
  current_opcode_offset = last_opcode_end;

  return Result::Ok;
}

void BinaryReaderObjdumpDisassemble::LogOpcode(const char* fmt, ...) {
  // BinaryReaderObjdumpDisassemble is only used to disassembly function bodies
  // so this should never be called for instructions outside of function bodies
  // (i.e. init expresions).
  assert(in_function_body);
  if (skip_next_opcode_) {
    skip_next_opcode_ = false;
    return;
  }
  const Offset immediate_len = state->offset - current_opcode_offset;
  const Offset opcode_size = current_opcode.GetLength();
  const Offset total_size = opcode_size + immediate_len;
  // current_opcode_offset has already read past this opcode; rewind it by the
  // size of this opcode, which may be more than one byte.
  Offset offset = current_opcode_offset - opcode_size;
  const Offset offset_end = offset + total_size;

  bool first_line = true;
  while (offset < offset_end) {
    // Print bytes, but only display a maximum of IMMEDIATE_OCTET_COUNT on each
    // line.
    printf(" %06" PRIzx ":", GetPrintOffset(offset));
    size_t i;
    for (i = 0; offset < offset_end && i < IMMEDIATE_OCTET_COUNT;
         ++i, ++offset) {
      printf(" %02x", data_[offset]);
    }
    // Fill the rest of the remaining space with spaces.
    for (; i < IMMEDIATE_OCTET_COUNT; ++i) {
      printf("   ");
    }
    printf(" | ");

    if (first_line) {
      first_line = false;

      // Print disassembly.
      int indent_level = this->indent_level;
      switch (current_opcode) {
        case Opcode::Else:
        case Opcode::Catch:
        case Opcode::CatchAll:
          indent_level--;
          break;
        default:
          break;
      }
      for (int j = 0; j < indent_level; j++) {
        printf("  ");
      }

      const char* opcode_name = current_opcode.GetName();
      printf("%s", opcode_name);
      if (fmt) {
        printf(" ");
        va_list args;
        va_start(args, fmt);
        vprintf(fmt, args);
        va_end(args);
      }
    }

    printf("\n");
  }

  last_opcode_end = state->offset;

  // Print relocation after then full (potentially multi-line) instruction.
  if (options_->relocs &&
      next_reloc < objdump_state_->code_relocations.size()) {
    const Reloc& reloc = objdump_state_->code_relocations[next_reloc];
    Offset code_start = GetSectionStart(BinarySection::Code);
    Offset abs_offset = code_start + reloc.offset;
    if (last_opcode_end > abs_offset) {
      PrintRelocation(reloc, abs_offset);
      next_reloc++;
    }
  }
}

Result BinaryReaderObjdumpDisassemble::OnOpcodeBare() {
  if (!in_function_body) {
    return Result::Ok;
  }
  LogOpcode(0, nullptr);
  return Result::Ok;
}

Result BinaryReaderObjdumpDisassemble::OnOpcodeIndex(Index value) {
  if (!in_function_body) {
    return Result::Ok;
  }
  std::string_view name;
  if (current_opcode == Opcode::Call &&
      !(name = GetFunctionName(value)).empty()) {
    LogOpcode("%d <" PRIstringview ">", value,
              WABT_PRINTF_STRING_VIEW_ARG(name));
  } else if (current_opcode == Opcode::Throw &&
             !(name = GetTagName(value)).empty()) {
    LogOpcode("%d <" PRIstringview ">", value,
              WABT_PRINTF_STRING_VIEW_ARG(name));
  } else if ((current_opcode == Opcode::GlobalGet ||
              current_opcode == Opcode::GlobalSet) &&
             !(name = GetGlobalName(value)).empty()) {
    LogOpcode("%d <" PRIstringview ">", value,
              WABT_PRINTF_STRING_VIEW_ARG(name));
  } else if ((current_opcode == Opcode::LocalGet ||
              current_opcode == Opcode::LocalSet) &&
             !(name = GetLocalName(current_function_index, value)).empty()) {
    LogOpcode("%d <" PRIstringview ">", value,
              WABT_PRINTF_STRING_VIEW_ARG(name));
  } else {
    LogOpcode("%d", value);
  }
  return Result::Ok;
}

Result BinaryReaderObjdumpDisassemble::OnOpcodeIndexIndex(Index value,
                                                          Index value2) {
  if (!in_function_body) {
    return Result::Ok;
  }
  LogOpcode("%" PRIindex " %" PRIindex, value, value2);
  return Result::Ok;
}

Result BinaryReaderObjdumpDisassemble::OnOpcodeUint32(uint32_t value) {
  if (!in_function_body) {
    return Result::Ok;
  }
  std::string_view name;
  if (current_opcode == Opcode::DataDrop &&
      !(name = GetSegmentName(value)).empty()) {
    LogOpcode("%d <" PRIstringview ">", value,
              WABT_PRINTF_STRING_VIEW_ARG(name));
  } else {
    LogOpcode("%u", value);
  }
  return Result::Ok;
}

Result BinaryReaderObjdumpDisassemble::OnOpcodeUint32Uint32(uint32_t value,
                                                            uint32_t value2) {
  if (!in_function_body)
    return Result::Ok;
  std::string_view name;
  if (current_opcode == Opcode::MemoryInit &&
      !(name = GetSegmentName(value)).empty()) {
    LogOpcode("%u %u <" PRIstringview ">", value, value2,
              WABT_PRINTF_STRING_VIEW_ARG(name));
  } else {
    LogOpcode("%u %u", value, value2);
  }
  return Result::Ok;
}

Result BinaryReaderObjdumpDisassemble::OnCallIndirectExpr(
    uint32_t sig_index,
    uint32_t table_index) {
  std::string_view table_name = GetTableName(table_index);
  std::string_view type_name = GetTypeName(sig_index);
  if (!type_name.empty() && !table_name.empty()) {
    LogOpcode("%u <" PRIstringview "> (type %u <" PRIstringview ">)",
              table_index, WABT_PRINTF_STRING_VIEW_ARG(table_name), sig_index,
              WABT_PRINTF_STRING_VIEW_ARG(type_name));
  } else if (!table_name.empty()) {
    LogOpcode("%u <" PRIstringview "> (type %u)", table_index,
              WABT_PRINTF_STRING_VIEW_ARG(table_name), sig_index);
  } else if (!type_name.empty()) {
    LogOpcode("%u (type %u <" PRIstringview ">)", table_index, sig_index,
              WABT_PRINTF_STRING_VIEW_ARG(type_name));
  } else {
    LogOpcode("%u (type %u)", table_index, sig_index);
  }
  skip_next_opcode_ = true;
  return Result::Ok;
}

Result BinaryReaderObjdumpDisassemble::OnOpcodeUint32Uint32Uint32(
    uint32_t value,
    uint32_t value2,
    uint32_t value3) {
  if (!in_function_body) {
    return Result::Ok;
  }
  LogOpcode("%u %u %u", value, value2, value3);
  return Result::Ok;
}

Result BinaryReaderObjdumpDisassemble::OnOpcodeUint32Uint32Uint32Uint32(
    uint32_t value,
    uint32_t value2,
    uint32_t value3,
    uint32_t value4) {
  if (!in_function_body) {
    return Result::Ok;
  }
  LogOpcode("%u %u %u %u", value, value2, value3, value4);
  return Result::Ok;
}

Result BinaryReaderObjdumpDisassemble::OnOpcodeUint64(uint64_t value) {
  if (!in_function_body) {
    return Result::Ok;
  }
  LogOpcode("%" PRIu64, value);
  return Result::Ok;
}

Result BinaryReaderObjdumpDisassemble::OnOpcodeF32(uint32_t value) {
  if (!in_function_body) {
    return Result::Ok;
  }
  char buffer[WABT_MAX_FLOAT_HEX];
  WriteFloatHex(buffer, sizeof(buffer), value);
  LogOpcode(buffer);
  return Result::Ok;
}

Result BinaryReaderObjdumpDisassemble::OnOpcodeF64(uint64_t value) {
  if (!in_function_body) {
    return Result::Ok;
  }
  char buffer[WABT_MAX_DOUBLE_HEX];
  WriteDoubleHex(buffer, sizeof(buffer), value);
  LogOpcode(buffer);
  return Result::Ok;
}

Result BinaryReaderObjdumpDisassemble::OnOpcodeV128(v128 value) {
  if (!in_function_body) {
    return Result::Ok;
  }
  // v128 is always dumped as i32x4:
  LogOpcode("0x%08x 0x%08x 0x%08x 0x%08x", value.u32(0), value.u32(1),
            value.u32(2), value.u32(3));
  return Result::Ok;
}

Result BinaryReaderObjdumpDisassemble::OnOpcodeType(Type type) {
  if (!in_function_body) {
    return Result::Ok;
  }
  if (current_opcode == Opcode::SelectT) {
    LogOpcode(type.GetName().c_str());
  } else {
    LogOpcode(type.GetRefKindName());
  }
  return Result::Ok;
}

Result BinaryReaderObjdumpDisassemble::OnTryTableExpr(
    Type sig_type,
    const CatchClauseVector& catches) {
  if (!in_function_body) {
    return Result::Ok;
  }

  std::string buffer = std::string();

  if (sig_type != Type::Void) {
    buffer.append(BlockSigToString(sig_type).c_str()).append(" ");
  }

  for (auto& catch_ : catches) {
    switch (catch_.kind) {
      case CatchKind::Catch:
        buffer.append("catch ");
        break;
      case CatchKind::CatchRef:
        buffer.append("catch_ref ");
        break;
      case CatchKind::CatchAll:
        buffer.append("catch_all ");
        break;
      case CatchKind::CatchAllRef:
        buffer.append("catch_all_ref ");
        break;
    }
    if (catch_.kind == CatchKind::Catch || catch_.kind == CatchKind::CatchRef) {
      buffer.append(std::to_string(catch_.tag));
    }
    buffer.append(" ").append(std::to_string(catch_.depth)).append(" ");
  }

  if (!buffer.empty()) {
    // remove trailing space
    buffer.pop_back();
  }

  LogOpcode("%s", buffer.c_str());
  indent_level++;
  return Result::Ok;
}

Result BinaryReaderObjdumpDisassemble::OnBrTableExpr(
    Index num_targets,
    Index* target_depths,
    Index default_target_depth) {
  if (!in_function_body) {
    return Result::Ok;
  }

  std::string buffer = std::string();
  for (Index i = 0; i < num_targets; i++) {
    buffer.append(std::to_string(target_depths[i])).append(" ");
  }
  buffer.append(std::to_string(default_target_depth));

  LogOpcode("%s", buffer.c_str());
  return Result::Ok;
}

Result BinaryReaderObjdumpDisassemble::OnDelegateExpr(Index depth) {
  if (!in_function_body) {
    return Result::Ok;
  }
  // Because `delegate` ends the block we need to dedent here, and
  // we don't need to dedent it in LogOpcode.
  if (indent_level > 0) {
    indent_level--;
  }
  return Result::Ok;
}

Result BinaryReaderObjdumpDisassemble::OnEndExpr() {
  if (!in_function_body) {
    return Result::Ok;
  }
  if (indent_level > 0) {
    indent_level--;
  }
  LogOpcode(0, nullptr);
  return Result::Ok;
}

Result BinaryReaderObjdumpDisassemble::OnFunction(Index index,
                                                  Index sig_index) {
  objdump_state_->function_types[index] = sig_index;
  return Result::Ok;
}

Result BinaryReaderObjdumpDisassemble::BeginFunctionBody(Index index,
                                                         Offset size) {
  printf("%06" PRIzx " func[%" PRIindex "]", GetPrintOffset(state->offset),
         index);
  auto name = GetFunctionName(index);
  if (!name.empty()) {
    printf(" <" PRIstringview ">", WABT_PRINTF_STRING_VIEW_ARG(name));
  }
  printf(":\n");

  last_opcode_end = 0;
  in_function_body = true;
  current_function_index = index;
  auto type_index = objdump_state_->function_types[index];
  local_index_ = objdump_state_->function_param_counts[type_index];
  return Result::Ok;
}

Result BinaryReaderObjdumpDisassemble::EndFunctionBody(Index index) {
  assert(in_function_body);
  in_function_body = false;
  return Result::Ok;
}

Result BinaryReaderObjdumpDisassemble::OnOpcodeBlockSig(Type sig_type) {
  if (!in_function_body) {
    return Result::Ok;
  }
  if (sig_type != Type::Void) {
    LogOpcode("%s", BlockSigToString(sig_type).c_str());
  } else {
    LogOpcode(nullptr);
  }
  indent_level++;
  return Result::Ok;
}

enum class InitExprType {
  Invalid,
  I32,
  F32,
  I64,
  F64,
  V128,
  Global,
  FuncRef,
  // TODO: There isn't a nullref anymore, this just represents ref.null of some
  // type T.
  NullRef,
};

struct InitInst {
  Opcode opcode;
  union {
    Index index;
    uint32_t i32;
    uint32_t f32;
    uint64_t i64;
    uint64_t f64;
    v128 v128_v;
    Type type;
  } imm;
};

struct InitExpr {
  InitExprType type;
  std::vector<InitInst> insts;
};

class BinaryReaderObjdump : public BinaryReaderObjdumpBase {
 public:
  BinaryReaderObjdump(const uint8_t* data,
                      size_t size,
                      ObjdumpOptions* options,
                      ObjdumpState* state);

  Result EndModule() override;
  Result BeginSection(Index section_index,
                      BinarySection section_type,
                      Offset size) override;
  Result BeginCustomSection(Index section_index,
                            Offset size,
                            std::string_view section_name) override;

  Result OnTypeCount(Index count) override;
  Result OnFuncType(Index index,
                    Index param_count,
                    Type* param_types,
                    Index result_count,
                    Type* result_types) override;
  Result OnStructType(Index index, Index field_count, TypeMut* fields) override;
  Result OnArrayType(Index index, TypeMut field) override;

  Result OnImportCount(Index count) override;
  Result OnImportFunc(Index import_index,
                      std::string_view module_name,
                      std::string_view field_name,
                      Index func_index,
                      Index sig_index) override;
  Result OnImportTable(Index import_index,
                       std::string_view module_name,
                       std::string_view field_name,
                       Index table_index,
                       Type elem_type,
                       const Limits* elem_limits) override;
  Result OnImportMemory(Index import_index,
                        std::string_view module_name,
                        std::string_view field_name,
                        Index memory_index,
                        const Limits* page_limits,
                        uint32_t page_size) override;
  Result OnImportGlobal(Index import_index,
                        std::string_view module_name,
                        std::string_view field_name,
                        Index global_index,
                        Type type,
                        bool mutable_) override;
  Result OnImportTag(Index import_index,
                     std::string_view module_name,
                     std::string_view field_name,
                     Index tag_index,
                     Index sig_index) override;

  Result OnFunctionCount(Index count) override;
  Result OnFunction(Index index, Index sig_index) override;

  Result OnTableCount(Index count) override;
  Result OnTable(Index index,
                 Type elem_type,
                 const Limits* elem_limits) override;

  Result OnMemoryCount(Index count) override;
  Result OnMemory(Index index,
                  const Limits* limits,
                  uint32_t page_size) override;

  Result OnGlobalCount(Index count) override;
  Result BeginGlobal(Index index, Type type, bool mutable_) override;

  Result OnExportCount(Index count) override;
  Result OnExport(Index index,
                  ExternalKind kind,
                  Index item_index,
                  std::string_view name) override;

  Result OnStartFunction(Index func_index) override;
  Result OnDataCount(Index count) override;

  Result OnFunctionBodyCount(Index count) override;
  Result BeginFunctionBody(Index index, Offset size) override;

  Result OnElemSegmentCount(Index count) override;
  Result BeginElemSegment(Index index,
                          Index table_index,
                          uint8_t flags) override;
  Result OnElemSegmentElemType(Index index, Type elem_type) override;
  Result OnElemSegmentElemExprCount(Index index, Index count) override;

  void BeginInitExpr() { current_init_expr_.insts.clear(); }

  Result BeginElemSegmentInitExpr(Index index) override {
    reading_elem_init_expr_ = true;
    BeginInitExpr();
    return Result::Ok;
  }

  Result EndElemSegmentInitExpr(Index index) override { return EndInitExpr(); }

  Result BeginDataSegmentInitExpr(Index index) override {
    reading_data_init_expr_ = true;
    BeginInitExpr();
    return Result::Ok;
  }

  Result EndDataSegmentInitExpr(Index index) override { return EndInitExpr(); }

  Result BeginGlobalInitExpr(Index index) override {
    reading_global_init_expr_ = true;
    BeginInitExpr();
    return Result::Ok;
  }

  Result EndGlobalInitExpr(Index index) override { return EndInitExpr(); }

  Result BeginElemExpr(Index elem_index, Index expr_index) override {
    reading_elem_expr_ = true;
    elem_index_ = expr_index;
    BeginInitExpr();
    return Result::Ok;
  }

  Result EndElemExpr(Index elem_index, Index expr_index) override {
    assert(expr_index == elem_index_);
    return EndInitExpr();
  }

  Result OnDataSegmentCount(Index count) override;
  Result BeginDataSegment(Index index,
                          Index memory_index,
                          uint8_t flags) override;
  Result OnDataSegmentData(Index index,
                           const void* data,
                           Address size) override;

  Result OnModuleName(std::string_view name) override;
  Result OnFunctionName(Index function_index,
                        std::string_view function_name) override;
  Result OnLocalName(Index function_index,
                     Index local_index,
                     std::string_view local_name) override;
  Result OnNameEntry(NameSectionSubsection type,
                     Index index,
                     std::string_view name) override;

  Result OnDylinkInfo(uint32_t mem_size,
                      uint32_t mem_align_log2,
                      uint32_t table_size,
                      uint32_t table_align_log2) override;
  Result OnDylinkNeededCount(Index count) override;
  Result OnDylinkNeeded(std::string_view so_name) override;
  Result OnDylinkImportCount(Index count) override;
  Result OnDylinkExportCount(Index count) override;
  Result OnDylinkImport(std::string_view module,
                        std::string_view name,
                        uint32_t flags) override;
  Result OnDylinkExport(std::string_view name, uint32_t flags) override;

  Result OnRelocCount(Index count, Index section_index) override;
  Result OnReloc(RelocType type,
                 Offset offset,
                 Index index,
                 uint32_t addend) override;

  Result OnFeature(uint8_t prefix, std::string_view name) override;

  Result OnSymbolCount(Index count) override;
  Result OnDataSymbol(Index index,
                      uint32_t flags,
                      std::string_view name,
                      Index segment,
                      uint32_t offset,
                      uint32_t size) override;
  Result OnFunctionSymbol(Index index,
                          uint32_t flags,
                          std::string_view name,
                          Index func_index) override;
  Result OnGlobalSymbol(Index index,
                        uint32_t flags,
                        std::string_view name,
                        Index global_index) override;
  Result OnSectionSymbol(Index index,
                         uint32_t flags,
                         Index section_index) override;
  Result OnTagSymbol(Index index,
                     uint32_t flags,
                     std::string_view name,
                     Index tag_index) override;
  Result OnTableSymbol(Index index,
                       uint32_t flags,
                       std::string_view name,
                       Index table_index) override;
  Result OnSegmentInfoCount(Index count) override;
  Result OnSegmentInfo(Index index,
                       std::string_view name,
                       Address alignment_log2,
                       uint32_t flags) override;
  Result OnInitFunctionCount(Index count) override;
  Result OnInitFunction(uint32_t priority, Index symbol_index) override;
  Result OnComdatCount(Index count) override;
  Result OnComdatBegin(std::string_view name,
                       uint32_t flags,
                       Index count) override;
  Result OnComdatEntry(ComdatType kind, Index index) override;

  Result OnTagCount(Index count) override;
  Result OnTagType(Index index, Index sig_index) override;

  Result OnOpcode(Opcode Opcode) override;
  Result OnI32ConstExpr(uint32_t value) override;
  Result OnI64ConstExpr(uint64_t value) override;
  Result OnF32ConstExpr(uint32_t value) override;
  Result OnF64ConstExpr(uint64_t value) override;
  Result OnRefFuncExpr(Index func_index) override;
  Result OnRefNullExpr(Type type) override;
  Result OnGlobalGetExpr(Index global_index) override;
  Result OnCodeMetadataCount(Index function_index, Index count) override;
  Result OnCodeMetadata(Offset code_offset,
                        const void* data,
                        Address size) override;

 private:
  Result EndInitExpr();
  bool ShouldPrintDetails();
  void PrintDetails(const char* fmt, ...);
  Result PrintSymbolFlags(uint32_t flags);
  Result PrintSegmentFlags(uint32_t flags);
  void PrintInitExpr(const InitExpr& expr,
                     bool as_unsigned = false,
                     bool with_prefix = true);
  Result OnCount(Index count);

  std::unique_ptr<FileStream> out_stream_;
  Index elem_index_ = 0;
  Index table_index_ = 0;
  Index next_data_reloc_ = 0;
  bool reading_elem_init_expr_ = false;
  bool reading_data_init_expr_ = false;
  bool reading_global_init_expr_ = false;
  bool reading_elem_expr_ = false;
  InitExpr current_init_expr_{};
  uint8_t data_flags_ = 0;
  uint8_t elem_flags_ = 0;
  Index data_mem_index_ = 0;
  uint64_t data_offset_ = 0;
  uint64_t elem_offset_ = 0;

  bool ReadingInitExpr() {
    return reading_elem_init_expr_ || reading_data_init_expr_ ||
           reading_global_init_expr_ || reading_elem_expr_;
  }
};

BinaryReaderObjdump::BinaryReaderObjdump(const uint8_t* data,
                                         size_t size,
                                         ObjdumpOptions* options,
                                         ObjdumpState* objdump_state)
    : BinaryReaderObjdumpBase(data, size, options, objdump_state),
      out_stream_(FileStream::CreateStdout()) {}

Result BinaryReaderObjdump::BeginCustomSection(Index section_index,
                                               Offset size,
                                               std::string_view section_name) {
  PrintDetails(" - name: \"" PRIstringview "\"\n",
               WABT_PRINTF_STRING_VIEW_ARG(section_name));
  if (options_->mode == ObjdumpMode::Headers) {
    printf("\"" PRIstringview "\"\n",
           WABT_PRINTF_STRING_VIEW_ARG(section_name));
  }
  return Result::Ok;
}

Result BinaryReaderObjdump::BeginSection(Index section_index,
                                         BinarySection section_code,
                                         Offset size) {
  BinaryReaderObjdumpBase::BeginSection(section_index, section_code, size);

  // |section_name| and |match_name| are identical for known sections. For
  // custom sections, |section_name| is "Custom", but |match_name| is the name
  // of the custom section.
  const char* section_name = wabt::GetSectionName(section_code);
  std::string match_name(GetSectionName(section_index));

  bool section_match = !options_->section_name ||
                       !strcasecmp(options_->section_name, match_name.c_str());
  if (section_match) {
    section_found_ = true;
  }

  switch (options_->mode) {
    case ObjdumpMode::Headers:
      printf("%9s start=%#010" PRIzx " end=%#010" PRIzx " (size=%#010" PRIoffset
             ") ",
             section_name, state->offset, state->offset + size, size);
      break;
    case ObjdumpMode::Details:
      if (section_match) {
        printf("%s", section_name);
        // All known section types except the Start and DataCount sections have
        // a count in which case this line gets completed in OnCount().
        if (section_code == BinarySection::Start ||
            section_code == BinarySection::DataCount ||
            section_code == BinarySection::Custom) {
          printf(":\n");
        }
        print_details_ = true;
      } else {
        print_details_ = false;
      }
      break;
    case ObjdumpMode::RawData:
      if (section_match) {
        printf("\nContents of section %s:\n", section_name);
        out_stream_->WriteMemoryDump(data_ + state->offset, size, state->offset,
                                     PrintChars::Yes);
      }
      break;
    case ObjdumpMode::Prepass:
    case ObjdumpMode::Disassemble:
      break;
  }
  return Result::Ok;
}

bool BinaryReaderObjdump::ShouldPrintDetails() {
  if (options_->mode != ObjdumpMode::Details) {
    return false;
  }
  return print_details_;
}

void WABT_PRINTF_FORMAT(2, 3) BinaryReaderObjdump::PrintDetails(const char* fmt,
                                                                ...) {
  if (!ShouldPrintDetails()) {
    return;
  }
  va_list args;
  va_start(args, fmt);
  vprintf(fmt, args);
  va_end(args);
}

Result BinaryReaderObjdump::OnCount(Index count) {
  if (options_->mode == ObjdumpMode::Headers) {
    printf("count: %" PRIindex "\n", count);
  } else if (options_->mode == ObjdumpMode::Details && print_details_) {
    printf("[%" PRIindex "]:\n", count);
  }
  return Result::Ok;
}

Result BinaryReaderObjdump::EndModule() {
  if (options_->section_name && !section_found_) {
    err_stream_->Writef("Section not found: %s\n", options_->section_name);
    return Result::Error;
  }

  if (options_->relocs && ShouldPrintDetails()) {
    if (next_data_reloc_ != objdump_state_->data_relocations.size()) {
      err_stream_->Writef("Data reloctions outside of segments!:\n");
      for (size_t i = next_data_reloc_;
           i < objdump_state_->data_relocations.size(); i++) {
        const Reloc& reloc = objdump_state_->data_relocations[i];
        PrintRelocation(reloc, reloc.offset);
      }

      return Result::Error;
    }
  }

  return Result::Ok;
}

Result BinaryReaderObjdump::OnTypeCount(Index count) {
  return OnCount(count);
}

Result BinaryReaderObjdump::OnFuncType(Index index,
                                       Index param_count,
                                       Type* param_types,
                                       Index result_count,
                                       Type* result_types) {
  if (!ShouldPrintDetails()) {
    return Result::Ok;
  }
  printf(" - type[%" PRIindex "] (", index);
  for (Index i = 0; i < param_count; i++) {
    if (i != 0) {
      printf(", ");
    }
    printf("%s", param_types[i].GetName().c_str());
  }
  printf(") -> ");
  switch (result_count) {
    case 0:
      printf("nil");
      break;
    case 1:
      printf("%s", result_types[0].GetName().c_str());
      break;
    default:
      printf("(");
      for (Index i = 0; i < result_count; i++) {
        if (i != 0) {
          printf(", ");
        }
        printf("%s", result_types[i].GetName().c_str());
      }
      printf(")");
      break;
  }
  printf("\n");
  return Result::Ok;
}

Result BinaryReaderObjdump::OnStructType(Index index,
                                         Index field_count,
                                         TypeMut* fields) {
  if (!ShouldPrintDetails()) {
    return Result::Ok;
  }
  printf(" - type[%" PRIindex "] (struct", index);
  for (Index i = 0; i < field_count; i++) {
    if (fields[i].mutable_) {
      printf(" (mut");
    }
    printf(" %s", fields[i].type.GetName().c_str());
    if (fields[i].mutable_) {
      printf(")");
    }
  }
  printf(")\n");
  return Result::Ok;
}

Result BinaryReaderObjdump::OnArrayType(Index index, TypeMut field) {
  if (!ShouldPrintDetails()) {
    return Result::Ok;
  }
  printf(" - type[%" PRIindex "] (array", index);
  if (field.mutable_) {
    printf(" (mut");
  }
  printf(" %s", field.type.GetName().c_str());
  if (field.mutable_) {
    printf(")");
  }
  printf(")\n");
  return Result::Ok;
}

Result BinaryReaderObjdump::OnFunctionCount(Index count) {
  return OnCount(count);
}

Result BinaryReaderObjdump::OnFunction(Index index, Index sig_index) {
  PrintDetails(" - func[%" PRIindex "] sig=%" PRIindex, index, sig_index);
  auto name = GetFunctionName(index);
  if (!name.empty()) {
    PrintDetails(" <" PRIstringview ">", WABT_PRINTF_STRING_VIEW_ARG(name));
  }
  PrintDetails("\n");
  objdump_state_->function_types[index] = sig_index;
  return Result::Ok;
}

Result BinaryReaderObjdump::OnFunctionBodyCount(Index count) {
  return OnCount(count);
}

Result BinaryReaderObjdump::BeginFunctionBody(Index index, Offset size) {
  PrintDetails(" - func[%" PRIindex "] size=%" PRIzd, index, size);
  auto name = GetFunctionName(index);
  if (!name.empty()) {
    PrintDetails(" <" PRIstringview ">", WABT_PRINTF_STRING_VIEW_ARG(name));
  }
  PrintDetails("\n");
  return Result::Ok;
}

Result BinaryReaderObjdump::OnStartFunction(Index func_index) {
  if (options_->mode == ObjdumpMode::Headers) {
    printf("start: %" PRIindex "\n", func_index);
  } else {
    PrintDetails(" - start function: %" PRIindex, func_index);
    auto name = GetFunctionName(func_index);
    if (!name.empty()) {
      PrintDetails(" <" PRIstringview ">", WABT_PRINTF_STRING_VIEW_ARG(name));
    }
    PrintDetails("\n");
  }
  return Result::Ok;
}

Result BinaryReaderObjdump::OnDataCount(Index count) {
  if (options_->mode == ObjdumpMode::Headers) {
    printf("count: %" PRIindex "\n", count);
  } else {
    PrintDetails(" - data count: %" PRIindex "\n", count);
  }
  return Result::Ok;
}

Result BinaryReaderObjdump::OnImportCount(Index count) {
  return OnCount(count);
}

Result BinaryReaderObjdump::OnImportFunc(Index import_index,
                                         std::string_view module_name,
                                         std::string_view field_name,
                                         Index func_index,
                                         Index sig_index) {
  PrintDetails(" - func[%" PRIindex "] sig=%" PRIindex, func_index, sig_index);
  auto name = GetFunctionName(func_index);
  if (!name.empty()) {
    PrintDetails(" <" PRIstringview ">", WABT_PRINTF_STRING_VIEW_ARG(name));
  }
  PrintDetails(" <- " PRIstringview "." PRIstringview "\n",
               WABT_PRINTF_STRING_VIEW_ARG(module_name),
               WABT_PRINTF_STRING_VIEW_ARG(field_name));
  return Result::Ok;
}

Result BinaryReaderObjdump::OnImportTable(Index import_index,
                                          std::string_view module_name,
                                          std::string_view field_name,
                                          Index table_index,
                                          Type elem_type,
                                          const Limits* elem_limits) {
  PrintDetails(" - table[%" PRIindex "] type=%s initial=%" PRId64, table_index,
               elem_type.GetName().c_str(), elem_limits->initial);
  if (elem_limits->has_max) {
    PrintDetails(" max=%" PRId64, elem_limits->max);
  }
  if (elem_limits->is_64) {
    PrintDetails(" i64");
  }
  PrintDetails(" <- " PRIstringview "." PRIstringview "\n",
               WABT_PRINTF_STRING_VIEW_ARG(module_name),
               WABT_PRINTF_STRING_VIEW_ARG(field_name));
  return Result::Ok;
}

Result BinaryReaderObjdump::OnImportMemory(Index import_index,
                                           std::string_view module_name,
                                           std::string_view field_name,
                                           Index memory_index,
                                           const Limits* page_limits,
                                           uint32_t page_size) {
  PrintDetails(" - memory[%" PRIindex "] pages: initial=%" PRId64, memory_index,
               page_limits->initial);
  if (page_limits->has_max) {
    PrintDetails(" max=%" PRId64, page_limits->max);
  }
  if (page_limits->is_shared) {
    PrintDetails(" shared");
  }
  if (page_limits->is_64) {
    PrintDetails(" i64");
  }
  if (page_size != WABT_DEFAULT_PAGE_SIZE) {
    PrintDetails(" (pagesize %u)", page_size);
  }
  PrintDetails(" <- " PRIstringview "." PRIstringview "\n",
               WABT_PRINTF_STRING_VIEW_ARG(module_name),
               WABT_PRINTF_STRING_VIEW_ARG(field_name));
  return Result::Ok;
}

Result BinaryReaderObjdump::OnImportGlobal(Index import_index,
                                           std::string_view module_name,
                                           std::string_view field_name,
                                           Index global_index,
                                           Type type,
                                           bool mutable_) {
  PrintDetails(" - global[%" PRIindex "] %s mutable=%d", global_index,
               type.GetName().c_str(), mutable_);
  PrintDetails(" <- " PRIstringview "." PRIstringview "\n",
               WABT_PRINTF_STRING_VIEW_ARG(module_name),
               WABT_PRINTF_STRING_VIEW_ARG(field_name));
  return Result::Ok;
}

Result BinaryReaderObjdump::OnImportTag(Index import_index,
                                        std::string_view module_name,
                                        std::string_view field_name,
                                        Index tag_index,
                                        Index sig_index) {
  PrintDetails(" - tag[%" PRIindex "] sig=%" PRIindex, tag_index, sig_index);
  auto name = GetTagName(tag_index);
  if (!name.empty()) {
    PrintDetails(" <" PRIstringview ">", WABT_PRINTF_STRING_VIEW_ARG(name));
  }
  PrintDetails(" <- " PRIstringview "." PRIstringview "\n",
               WABT_PRINTF_STRING_VIEW_ARG(module_name),
               WABT_PRINTF_STRING_VIEW_ARG(field_name));
  return Result::Ok;
}

Result BinaryReaderObjdump::OnMemoryCount(Index count) {
  return OnCount(count);
}

Result BinaryReaderObjdump::OnMemory(Index index,
                                     const Limits* page_limits,
                                     uint32_t page_size) {
  PrintDetails(" - memory[%" PRIindex "] pages: initial=%" PRId64, index,
               page_limits->initial);
  if (page_limits->has_max) {
    PrintDetails(" max=%" PRId64, page_limits->max);
  }
  if (page_limits->is_shared) {
    PrintDetails(" shared");
  }
  if (page_limits->is_64) {
    PrintDetails(" i64");
  }
  if (page_size != WABT_DEFAULT_PAGE_SIZE) {
    PrintDetails(" (pagesize %u)", page_size);
  }
  PrintDetails("\n");
  return Result::Ok;
}

Result BinaryReaderObjdump::OnTableCount(Index count) {
  return OnCount(count);
}

Result BinaryReaderObjdump::OnTable(Index index,
                                    Type elem_type,
                                    const Limits* elem_limits) {
  PrintDetails(" - table[%" PRIindex "] type=%s initial=%" PRId64, index,
               elem_type.GetName().c_str(), elem_limits->initial);
  if (elem_limits->has_max) {
    PrintDetails(" max=%" PRId64, elem_limits->max);
  }
  auto name = GetTableName(index);
  if (!name.empty()) {
    PrintDetails(" <" PRIstringview ">", WABT_PRINTF_STRING_VIEW_ARG(name));
  }
  if (elem_limits->is_64) {
    PrintDetails(" i64");
  }
  PrintDetails("\n");
  return Result::Ok;
}

Result BinaryReaderObjdump::OnExportCount(Index count) {
  return OnCount(count);
}

Result BinaryReaderObjdump::OnExport(Index index,
                                     ExternalKind kind,
                                     Index item_index,
                                     std::string_view name) {
  PrintDetails(" - %s[%" PRIindex "]", GetKindName(kind), item_index);
  if (kind == ExternalKind::Func) {
    auto name = GetFunctionName(item_index);
    if (!name.empty()) {
      PrintDetails(" <" PRIstringview ">", WABT_PRINTF_STRING_VIEW_ARG(name));
    }
  }

  PrintDetails(" -> \"" PRIstringview "\"\n",
               WABT_PRINTF_STRING_VIEW_ARG(name));
  return Result::Ok;
}

Result BinaryReaderObjdump::OnElemSegmentCount(Index count) {
  return OnCount(count);
}

Result BinaryReaderObjdump::BeginElemSegment(Index index,
                                             Index table_index,
                                             uint8_t flags) {
  table_index_ = table_index;
  elem_index_ = 0;
  elem_flags_ = flags;
  return Result::Ok;
}

Result BinaryReaderObjdump::OnElemSegmentElemType(Index index, Type elem_type) {
  // TODO: Add support for this.
  return Result::Ok;
}

Result BinaryReaderObjdump::OnElemSegmentElemExprCount(Index index,
                                                       Index count) {
  PrintDetails(" - segment[%" PRIindex "] flags=%d table=%" PRIindex
               " count=%" PRIindex,
               index, elem_flags_, table_index_, count);
  if (elem_flags_ & SegPassive) {
    PrintDetails("\n");
  } else {
    PrintInitExpr(current_init_expr_, /*as_unsigned=*/true);
  }
  return Result::Ok;
}

Result BinaryReaderObjdump::OnGlobalCount(Index count) {
  return OnCount(count);
}

Result BinaryReaderObjdump::BeginGlobal(Index index, Type type, bool mutable_) {
  PrintDetails(" - global[%" PRIindex "] %s mutable=%d", index,
               type.GetName().c_str(), mutable_);
  std::string_view name = GetGlobalName(index);
  if (!name.empty()) {
    PrintDetails(" <" PRIstringview ">", WABT_PRINTF_STRING_VIEW_ARG(name));
  }
  return Result::Ok;
}

void BinaryReaderObjdump::PrintInitExpr(const InitExpr& expr,
                                        bool as_unsigned,
                                        bool with_prefix) {
  if (with_prefix) {
    PrintDetails(" - init ");
  }

  if (expr.insts.empty()) {
    PrintDetails("<EMPTY>\n");
    return;
  }

  // We have two different way to print init expressions.  One for
  // extended expressions involving more than one instruction, and
  // a short form for the more traditional single instruction form.
  if (expr.insts.size() > 1) {
    PrintDetails("(");
    bool first = true;
    for (auto& inst : expr.insts) {
      if (!first) {
        PrintDetails(", ");
      }
      first = false;
      PrintDetails("%s", inst.opcode.GetName());
      switch (inst.opcode) {
        case Opcode::I32Const:
          PrintDetails(" %d", inst.imm.i32);
          break;
        case Opcode::I64Const:
          PrintDetails(" %" PRId64, inst.imm.i64);
          break;
        case Opcode::F32Const: {
          char buffer[WABT_MAX_FLOAT_HEX];
          WriteFloatHex(buffer, sizeof(buffer), inst.imm.f32);
          PrintDetails(" %s\n", buffer);
          break;
        }
        case Opcode::F64Const: {
          char buffer[WABT_MAX_DOUBLE_HEX];
          WriteDoubleHex(buffer, sizeof(buffer), inst.imm.f64);
          PrintDetails(" %s\n", buffer);
          break;
        }
        case Opcode::GlobalGet: {
          PrintDetails(" %" PRIindex, inst.imm.index);
          std::string_view name = GetGlobalName(inst.imm.index);
          if (!name.empty()) {
            PrintDetails(" <" PRIstringview ">",
                         WABT_PRINTF_STRING_VIEW_ARG(name));
          }
          break;
        }
        default:
          break;
      }
    }
    PrintDetails(")\n");
    return;
  }

  switch (expr.type) {
    case InitExprType::I32:
      if (as_unsigned) {
        PrintDetails("i32=%u\n", expr.insts[0].imm.i32);
      } else {
        PrintDetails("i32=%d\n", expr.insts[0].imm.i32);
      }
      break;
    case InitExprType::I64:
      if (as_unsigned) {
        PrintDetails("i64=%" PRIu64 "\n", expr.insts[0].imm.i64);
      } else {
        PrintDetails("i64=%" PRId64 "\n", expr.insts[0].imm.i64);
      }
      break;
    case InitExprType::F64: {
      char buffer[WABT_MAX_DOUBLE_HEX];
      WriteDoubleHex(buffer, sizeof(buffer), expr.insts[0].imm.f64);
      PrintDetails("f64=%s\n", buffer);
      break;
    }
    case InitExprType::F32: {
      char buffer[WABT_MAX_FLOAT_HEX];
      WriteFloatHex(buffer, sizeof(buffer), expr.insts[0].imm.f32);
      PrintDetails("f32=%s\n", buffer);
      break;
    }
    case InitExprType::V128: {
      PrintDetails(
          "v128=0x%08x 0x%08x 0x%08x 0x%08x \n",
          expr.insts[0].imm.v128_v.u32(0), expr.insts[0].imm.v128_v.u32(1),
          expr.insts[0].imm.v128_v.u32(2), expr.insts[0].imm.v128_v.u32(3));
      break;
    }
    case InitExprType::Global: {
      PrintDetails("global=%" PRIindex, expr.insts[0].imm.index);
      std::string_view name = GetGlobalName(expr.insts[0].imm.index);
      if (!name.empty()) {
        PrintDetails(" <" PRIstringview ">", WABT_PRINTF_STRING_VIEW_ARG(name));
      }
      PrintDetails("\n");
      break;
    }
    case InitExprType::FuncRef: {
      PrintDetails("ref.func:%" PRIindex, expr.insts[0].imm.index);
      std::string_view name = GetFunctionName(expr.insts[0].imm.index);
      if (!name.empty()) {
        PrintDetails(" <" PRIstringview ">", WABT_PRINTF_STRING_VIEW_ARG(name));
      }
      PrintDetails("\n");
      break;
    }
    case InitExprType::NullRef:
      PrintDetails("ref.null %s\n", expr.insts[0].imm.type.GetName().c_str());
      break;
    case InitExprType::Invalid:
      PrintDetails("<INVALID>\n");
      break;
  }
}

static void InitExprToConstOffset(const InitExpr& expr, uint64_t* out_offset) {
  if (expr.insts.size() == 1) {
    switch (expr.type) {
      case InitExprType::I32:
        *out_offset = expr.insts[0].imm.i32;
        break;
      case InitExprType::I64:
        *out_offset = expr.insts[0].imm.i64;
        break;
      default:
        break;
    }
  }
}

Result BinaryReaderObjdump::EndInitExpr() {
  if (reading_data_init_expr_) {
    reading_data_init_expr_ = false;
    InitExprToConstOffset(current_init_expr_, &data_offset_);
  } else if (reading_elem_init_expr_) {
    reading_elem_init_expr_ = false;
    InitExprToConstOffset(current_init_expr_, &elem_offset_);
  } else if (reading_global_init_expr_) {
    reading_global_init_expr_ = false;
    PrintInitExpr(current_init_expr_);
  } else if (reading_elem_expr_) {
    reading_elem_expr_ = false;
    PrintDetails("  - elem[%" PRIu64 "] = ", elem_offset_ + elem_index_);
    PrintInitExpr(current_init_expr_, /*as_unsigned=*/false,
                  /*with_prefix=*/false);
  } else {
    WABT_UNREACHABLE;
  }
  return Result::Ok;
}

Result BinaryReaderObjdump::OnI32ConstExpr(uint32_t value) {
  if (ReadingInitExpr()) {
    current_init_expr_.type = InitExprType::I32;
    current_init_expr_.insts.back().imm.i32 = value;
  }
  return Result::Ok;
}

Result BinaryReaderObjdump::OnI64ConstExpr(uint64_t value) {
  if (ReadingInitExpr()) {
    current_init_expr_.type = InitExprType::I64;
    current_init_expr_.insts.back().imm.i64 = value;
  }
  return Result::Ok;
}

Result BinaryReaderObjdump::OnF32ConstExpr(uint32_t value) {
  if (ReadingInitExpr()) {
    current_init_expr_.type = InitExprType::F32;
    current_init_expr_.insts.back().imm.f32 = value;
  }
  return Result::Ok;
}

Result BinaryReaderObjdump::OnF64ConstExpr(uint64_t value) {
  if (ReadingInitExpr()) {
    current_init_expr_.type = InitExprType::F64;
    current_init_expr_.insts.back().imm.f64 = value;
  }
  return Result::Ok;
}

Result BinaryReaderObjdump::OnRefFuncExpr(Index func_index) {
  if (ReadingInitExpr()) {
    current_init_expr_.type = InitExprType::FuncRef;
    current_init_expr_.insts.back().imm.index = func_index;
  }
  return Result::Ok;
}

Result BinaryReaderObjdump::OnRefNullExpr(Type type) {
  if (ReadingInitExpr()) {
    current_init_expr_.type = InitExprType::NullRef;
    current_init_expr_.insts.back().imm.type = type;
  }
  return Result::Ok;
}

Result BinaryReaderObjdump::OnOpcode(Opcode opcode) {
  BinaryReaderObjdumpBase::OnOpcode(opcode);
  if (ReadingInitExpr() && opcode != Opcode::End) {
    InitInst i;
    i.opcode = current_opcode;
    current_init_expr_.insts.push_back(i);
  }
  return Result::Ok;
}

Result BinaryReaderObjdump::OnGlobalGetExpr(Index global_index) {
  if (ReadingInitExpr()) {
    current_init_expr_.type = InitExprType::Global;
    current_init_expr_.insts.back().imm.index = global_index;
  }
  return Result::Ok;
}

Result BinaryReaderObjdump::OnModuleName(std::string_view name) {
  PrintDetails(" - module <" PRIstringview ">\n",
               WABT_PRINTF_STRING_VIEW_ARG(name));
  return Result::Ok;
}

Result BinaryReaderObjdump::OnFunctionName(Index index, std::string_view name) {
  PrintDetails(" - func[%" PRIindex "] <" PRIstringview ">\n", index,
               WABT_PRINTF_STRING_VIEW_ARG(name));
  return Result::Ok;
}

Result BinaryReaderObjdump::OnNameEntry(NameSectionSubsection type,
                                        Index index,
                                        std::string_view name) {
  PrintDetails(" - %s[%" PRIindex "] <" PRIstringview ">\n",
               GetNameSectionSubsectionName(type), index,
               WABT_PRINTF_STRING_VIEW_ARG(name));
  return Result::Ok;
}

Result BinaryReaderObjdump::OnLocalName(Index func_index,
                                        Index local_index,
                                        std::string_view name) {
  if (!name.empty()) {
    PrintDetails(" - func[%" PRIindex "] local[%" PRIindex "] <" PRIstringview
                 ">\n",
                 func_index, local_index, WABT_PRINTF_STRING_VIEW_ARG(name));
  }
  return Result::Ok;
}

Result BinaryReaderObjdump::OnDataSegmentCount(Index count) {
  return OnCount(count);
}

Result BinaryReaderObjdump::BeginDataSegment(Index index,
                                             Index memory_index,
                                             uint8_t flags) {
  data_mem_index_ = memory_index;
  data_flags_ = flags;
  return Result::Ok;
}

Result BinaryReaderObjdump::OnDataSegmentData(Index index,
                                              const void* src_data,
                                              Address size) {
  if (!ShouldPrintDetails()) {
    return Result::Ok;
  }

  PrintDetails(" - segment[%" PRIindex "]", index);
  auto name = GetSegmentName(index);
  if (!name.empty()) {
    PrintDetails(" <" PRIstringview ">", WABT_PRINTF_STRING_VIEW_ARG(name));
  }
  if (data_flags_ & SegPassive) {
    PrintDetails(" passive");
  } else {
    PrintDetails(" memory=%" PRIindex, data_mem_index_);
  }
  PrintDetails(" size=%" PRIaddress, size);
  if (data_flags_ & SegPassive) {
    PrintDetails("\n");
  } else {
    PrintInitExpr(current_init_expr_, /*as_unsigned=*/true);
  }

  out_stream_->WriteMemoryDump(src_data, size, data_offset_, PrintChars::Yes,
                               "  - ");

  // Print relocations from this segment.
  if (!options_->relocs) {
    return Result::Ok;
  }

  Offset data_start = GetSectionStart(BinarySection::Data);
  Offset segment_start = state->offset - size;
  Offset segment_offset = segment_start - data_start;
  while (next_data_reloc_ < objdump_state_->data_relocations.size()) {
    const Reloc& reloc = objdump_state_->data_relocations[next_data_reloc_];
    Offset abs_offset = data_start + reloc.offset;
    if (abs_offset > state->offset) {
      break;
    }
    PrintRelocation(reloc, reloc.offset - segment_offset + data_offset_);
    next_data_reloc_++;
  }

  return Result::Ok;
}

Result BinaryReaderObjdump::OnDylinkInfo(uint32_t mem_size,
                                         uint32_t mem_align_log2,
                                         uint32_t table_size,
                                         uint32_t table_align_log2) {
  PrintDetails(" - mem_size     : %u\n", mem_size);
  PrintDetails(" - mem_p2align  : %u\n", mem_align_log2);
  PrintDetails(" - table_size   : %u\n", table_size);
  PrintDetails(" - table_p2align: %u\n", table_align_log2);
  return Result::Ok;
}

Result BinaryReaderObjdump::OnDylinkNeededCount(Index count) {
  if (count) {
    PrintDetails(" - needed_dynlibs[%u]:\n", count);
  }
  return Result::Ok;
}

Result BinaryReaderObjdump::OnDylinkImportCount(Index count) {
  PrintDetails(" - imports[%u]:\n", count);
  return Result::Ok;
}

Result BinaryReaderObjdump::OnDylinkExportCount(Index count) {
  PrintDetails(" - exports[%u]:\n", count);
  return Result::Ok;
}

Result BinaryReaderObjdump::OnDylinkExport(std::string_view name,
                                           uint32_t flags) {
  PrintDetails("  - " PRIstringview, WABT_PRINTF_STRING_VIEW_ARG(name));
  return PrintSymbolFlags(flags);
}

Result BinaryReaderObjdump::OnDylinkImport(std::string_view module,
                                           std::string_view name,
                                           uint32_t flags) {
  PrintDetails("  - " PRIstringview "." PRIstringview,
               WABT_PRINTF_STRING_VIEW_ARG(module),
               WABT_PRINTF_STRING_VIEW_ARG(name));
  return PrintSymbolFlags(flags);
}

Result BinaryReaderObjdump::OnDylinkNeeded(std::string_view so_name) {
  PrintDetails("  - " PRIstringview "\n", WABT_PRINTF_STRING_VIEW_ARG(so_name));
  return Result::Ok;
}

Result BinaryReaderObjdump::OnRelocCount(Index count, Index section_index) {
  BinaryReaderObjdumpBase::OnRelocCount(count, section_index);
  PrintDetails("  - relocations for section: %d (" PRIstringview ") [%d]\n",
               section_index,
               WABT_PRINTF_STRING_VIEW_ARG(GetSectionName(section_index)),
               count);
  return Result::Ok;
}

Result BinaryReaderObjdump::OnReloc(RelocType type,
                                    Offset offset,
                                    Index index,
                                    uint32_t addend) {
  Offset total_offset = GetSectionStart(reloc_section_) + offset;
  PrintDetails("   - %-18s offset=%#08" PRIoffset "(file=%#08" PRIoffset ") ",
               GetRelocTypeName(type), offset, total_offset);
  if (type == RelocType::TypeIndexLEB) {
    PrintDetails("type=%" PRIindex, index);
  } else {
    PrintDetails("symbol=%" PRIindex " <" PRIstringview ">", index,
                 WABT_PRINTF_STRING_VIEW_ARG(GetSymbolName(index)));
  }

  if (addend) {
    int32_t signed_addend = static_cast<int32_t>(addend);
    if (signed_addend < 0) {
      PrintDetails("-");
      signed_addend = -signed_addend;
    } else {
      PrintDetails("+");
    }
    PrintDetails("%#x", signed_addend);
  }
  PrintDetails("\n");
  return Result::Ok;
}

Result BinaryReaderObjdump::OnFeature(uint8_t prefix, std::string_view name) {
  PrintDetails("  - [%c] " PRIstringview "\n", prefix,
               WABT_PRINTF_STRING_VIEW_ARG(name));
  return Result::Ok;
}

Result BinaryReaderObjdump::OnSymbolCount(Index count) {
  PrintDetails("  - symbol table [count=%d]\n", count);
  return Result::Ok;
}

Result BinaryReaderObjdump::PrintSymbolFlags(uint32_t flags) {
  if (flags > WABT_SYMBOL_FLAG_MAX) {
    err_stream_->Writef("Unknown symbols flags: %x\n", flags);
    return Result::Error;
  }

  const char* binding_name = nullptr;
  SymbolBinding binding =
      static_cast<SymbolBinding>(flags & WABT_SYMBOL_MASK_BINDING);
  switch (binding) {
    case SymbolBinding::Global:
      binding_name = "global";
      break;
    case SymbolBinding::Local:
      binding_name = "local";
      break;
    case SymbolBinding::Weak:
      binding_name = "weak";
      break;
  }
  flags &= ~WABT_SYMBOL_MASK_BINDING;

  const char* vis_name = nullptr;
  SymbolVisibility vis =
      static_cast<SymbolVisibility>(flags & WABT_SYMBOL_MASK_VISIBILITY);
  switch (vis) {
    case SymbolVisibility::Hidden:
      vis_name = "hidden";
      break;
    case SymbolVisibility::Default:
      vis_name = "default";
      break;
  }
  flags &= ~WABT_SYMBOL_MASK_VISIBILITY;

  PrintDetails(" [");
  if (flags & WABT_SYMBOL_FLAG_UNDEFINED) {
    PrintDetails(" undefined");
    flags &= ~WABT_SYMBOL_FLAG_UNDEFINED;
  }
  if (flags & WABT_SYMBOL_FLAG_EXPORTED) {
    PrintDetails(" exported");
    flags &= ~WABT_SYMBOL_FLAG_EXPORTED;
  }
  if (flags & WABT_SYMBOL_FLAG_EXPLICIT_NAME) {
    PrintDetails(" explicit_name");
    flags &= ~WABT_SYMBOL_FLAG_EXPLICIT_NAME;
  }
  if (flags & WABT_SYMBOL_FLAG_NO_STRIP) {
    PrintDetails(" no_strip");
    flags &= ~WABT_SYMBOL_FLAG_NO_STRIP;
  }
  if (flags & WABT_SYMBOL_FLAG_TLS) {
    PrintDetails(" tls");
    flags &= ~WABT_SYMBOL_FLAG_TLS;
  }
  if (flags & WABT_SYMBOL_FLAG_ABS) {
    PrintDetails(" abs");
    flags &= ~WABT_SYMBOL_FLAG_ABS;
  }
  if (flags != 0) {
    PrintDetails(" unknown_flags=%#x", flags);
  }
  PrintDetails(" binding=%s vis=%s ]\n", binding_name, vis_name);
  return Result::Ok;
}

Result BinaryReaderObjdump::PrintSegmentFlags(uint32_t flags) {
  if (flags > WABT_SYMBOL_FLAG_MAX) {
    err_stream_->Writef("Unknown symbols flags: %x\n", flags);
    return Result::Error;
  }
  PrintDetails(" [");
  if (flags & WABT_SEGMENT_FLAG_STRINGS) {
    PrintDetails(" STRINGS");
    flags &= ~WABT_SEGMENT_FLAG_STRINGS;
  }
  if (flags & WABT_SEGMENT_FLAG_TLS) {
    PrintDetails(" TLS");
    flags &= ~WABT_SEGMENT_FLAG_TLS;
  }
  if (flags & WASM_SEGMENT_FLAG_RETAIN) {
    PrintDetails(" RETAIN");
    flags &= ~WASM_SEGMENT_FLAG_RETAIN;
  }
  if (flags != 0) {
    PrintDetails(" unknown_flags=%#x", flags);
  }
  PrintDetails(" ]\n");
  return Result::Ok;
}

Result BinaryReaderObjdump::OnDataSymbol(Index index,
                                         uint32_t flags,
                                         std::string_view name,
                                         Index segment,
                                         uint32_t offset,
                                         uint32_t size) {
  PrintDetails("   - %d: D <" PRIstringview ">", index,
               WABT_PRINTF_STRING_VIEW_ARG(name));
  if (!(flags & WABT_SYMBOL_FLAG_UNDEFINED)) {
    if (flags & WABT_SYMBOL_FLAG_ABS) {
      PrintDetails(" address=%d size=%d", offset, size);
    } else {
      PrintDetails(" segment=%" PRIindex " offset=%d size=%d", segment, offset,
                   size);
    }
  }
  return PrintSymbolFlags(flags);
}

Result BinaryReaderObjdump::OnFunctionSymbol(Index index,
                                             uint32_t flags,
                                             std::string_view name,
                                             Index func_index) {
  if (name.empty()) {
    name = GetFunctionName(func_index);
  }
  PrintDetails("   - %d: F <" PRIstringview "> func=%" PRIindex, index,
               WABT_PRINTF_STRING_VIEW_ARG(name), func_index);
  return PrintSymbolFlags(flags);
}

Result BinaryReaderObjdump::OnGlobalSymbol(Index index,
                                           uint32_t flags,
                                           std::string_view name,
                                           Index global_index) {
  if (name.empty()) {
    name = GetGlobalName(global_index);
  }
  PrintDetails("   - %d: G <" PRIstringview "> global=%" PRIindex, index,
               WABT_PRINTF_STRING_VIEW_ARG(name), global_index);
  return PrintSymbolFlags(flags);
}

Result BinaryReaderObjdump::OnSectionSymbol(Index index,
                                            uint32_t flags,
                                            Index section_index) {
  auto sym_name = GetSectionName(section_index);
  assert(!sym_name.empty());
  PrintDetails("   - %d: S <" PRIstringview "> section=%" PRIindex, index,
               WABT_PRINTF_STRING_VIEW_ARG(sym_name), section_index);
  return PrintSymbolFlags(flags);
}

Result BinaryReaderObjdump::OnTagSymbol(Index index,
                                        uint32_t flags,
                                        std::string_view name,
                                        Index tag_index) {
  if (name.empty()) {
    name = GetTagName(tag_index);
  }
  PrintDetails("   - %d: E <" PRIstringview "> tag=%" PRIindex, index,
               WABT_PRINTF_STRING_VIEW_ARG(name), tag_index);
  return PrintSymbolFlags(flags);
}

Result BinaryReaderObjdump::OnTableSymbol(Index index,
                                          uint32_t flags,
                                          std::string_view name,
                                          Index table_index) {
  if (name.empty()) {
    name = GetTableName(table_index);
  }
  PrintDetails("   - %d: T <" PRIstringview "> table=%" PRIindex, index,
               WABT_PRINTF_STRING_VIEW_ARG(name), table_index);
  return PrintSymbolFlags(flags);
}

Result BinaryReaderObjdump::OnSegmentInfoCount(Index count) {
  PrintDetails("  - segment info [count=%d]\n", count);
  return Result::Ok;
}

Result BinaryReaderObjdump::OnSegmentInfo(Index index,
                                          std::string_view name,
                                          Address alignment_log2,
                                          uint32_t flags) {
  PrintDetails("   - %d: " PRIstringview " p2align=%" PRIaddress, index,
               WABT_PRINTF_STRING_VIEW_ARG(name), alignment_log2);
  return PrintSegmentFlags(flags);
}

Result BinaryReaderObjdump::OnInitFunctionCount(Index count) {
  PrintDetails("  - init functions [count=%d]\n", count);
  return Result::Ok;
}

Result BinaryReaderObjdump::OnInitFunction(uint32_t priority,
                                           Index symbol_index) {
  PrintDetails("   - %d: priority=%d", symbol_index, priority);
  auto name = GetSymbolName(symbol_index);
  if (!name.empty()) {
    PrintDetails(" <" PRIstringview ">", WABT_PRINTF_STRING_VIEW_ARG(name));
  }
  PrintDetails("\n");
  return Result::Ok;
}

Result BinaryReaderObjdump::OnComdatCount(Index count) {
  PrintDetails("  - comdat groups [count=%d]\n", count);
  return Result::Ok;
}

Result BinaryReaderObjdump::OnComdatBegin(std::string_view name,
                                          uint32_t flags,
                                          Index count) {
  PrintDetails("   - " PRIstringview ": [count=%d]\n",
               WABT_PRINTF_STRING_VIEW_ARG(name), count);
  return Result::Ok;
}

Result BinaryReaderObjdump::OnComdatEntry(ComdatType kind, Index index) {
  switch (kind) {
    case ComdatType::Data: {
      PrintDetails("    - segment[%" PRIindex "]", index);
      auto name = GetSegmentName(index);
      if (!name.empty()) {
        PrintDetails(" <" PRIstringview ">", WABT_PRINTF_STRING_VIEW_ARG(name));
      }
      break;
    }
    case ComdatType::Function: {
      PrintDetails("    - func[%" PRIindex "]", index);
      auto name = GetFunctionName(index);
      if (!name.empty()) {
        PrintDetails(" <" PRIstringview ">", WABT_PRINTF_STRING_VIEW_ARG(name));
      }
      break;
    }
  }
  PrintDetails("\n");
  return Result::Ok;
}

Result BinaryReaderObjdump::OnTagCount(Index count) {
  return OnCount(count);
}

Result BinaryReaderObjdump::OnTagType(Index index, Index sig_index) {
  if (!ShouldPrintDetails()) {
    return Result::Ok;
  }
  printf(" - tag[%" PRIindex "] sig=%" PRIindex "\n", index, sig_index);
  return Result::Ok;
}

Result BinaryReaderObjdump::OnCodeMetadataCount(Index function_index,
                                                Index count) {
  if (!ShouldPrintDetails()) {
    return Result::Ok;
  }
  printf("   - func[%" PRIindex "]", function_index);
  auto name = GetFunctionName(function_index);
  if (!name.empty()) {
    printf(" <" PRIstringview ">", WABT_PRINTF_STRING_VIEW_ARG(name));
  }
  printf(":\n");
  return Result::Ok;
}
Result BinaryReaderObjdump::OnCodeMetadata(Offset code_offset,
                                           const void* data,
                                           Address size) {
  if (!ShouldPrintDetails()) {
    return Result::Ok;
  }
  printf("    - meta[%" PRIzx "]:\n", code_offset);

  out_stream_->WriteMemoryDump(data, size, 0, PrintChars::Yes, "     - ");
  return Result::Ok;
}

}  // end anonymous namespace

std::string_view ObjdumpNames::Get(Index index) const {
  auto iter = names.find(index);
  if (iter == names.end())
    return std::string_view();
  return iter->second;
}

void ObjdumpNames::Set(Index index, std::string_view name) {
  names[index] = std::string(name);
}

std::string_view ObjdumpLocalNames::Get(Index function_index,
                                        Index local_index) const {
  auto iter = names.find(std::pair<Index, Index>(function_index, local_index));
  if (iter == names.end())
    return std::string_view();
  return iter->second;
}

void ObjdumpLocalNames::Set(Index function_index,
                            Index local_index,
                            std::string_view name) {
  names[std::pair<Index, Index>(function_index, local_index)] =
      std::string(name);
}

Result ReadBinaryObjdump(const uint8_t* data,
                         size_t size,
                         ObjdumpOptions* options,
                         ObjdumpState* state) {
  Features features;
  features.EnableAll();
  const bool kReadDebugNames = true;
  const bool kStopOnFirstError = false;
  const bool kFailOnCustomSectionError = false;
  ReadBinaryOptions read_options(features, options->log_stream, kReadDebugNames,
                                 kStopOnFirstError, kFailOnCustomSectionError);

  switch (options->mode) {
    case ObjdumpMode::Prepass: {
      read_options.skip_function_bodies = true;
      BinaryReaderObjdumpPrepass reader(data, size, options, state);
      return ReadBinary(data, size, &reader, read_options);
    }
    case ObjdumpMode::Disassemble: {
      BinaryReaderObjdumpDisassemble reader(data, size, options, state);
      return ReadBinary(data, size, &reader, read_options);
    }
    default: {
      read_options.skip_function_bodies = true;
      BinaryReaderObjdump reader(data, size, options, state);
      return ReadBinary(data, size, &reader, read_options);
    }
  }
}

}  // namespace wabt
