//===-- WasmDumper.cpp - Wasm-specific object file dumper -----------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements the Wasm-specific dumper for llvm-readobj.
//
//===----------------------------------------------------------------------===//

#include "ObjDumper.h"
#include "llvm-readobj.h"
#include "llvm/Object/Wasm.h"
#include "llvm/Support/ScopedPrinter.h"

using namespace llvm;
using namespace object;

namespace {

static const EnumEntry<unsigned> WasmSymbolTypes[] = {
#define ENUM_ENTRY(X)                                                          \
  { #X, wasm::WASM_SYMBOL_TYPE_##X }
    ENUM_ENTRY(FUNCTION), ENUM_ENTRY(DATA),  ENUM_ENTRY(GLOBAL),
    ENUM_ENTRY(SECTION),  ENUM_ENTRY(EVENT),
#undef ENUM_ENTRY
};

static const EnumEntry<uint32_t> WasmSectionTypes[] = {
#define ENUM_ENTRY(X)                                                          \
  { #X, wasm::WASM_SEC_##X }
    ENUM_ENTRY(CUSTOM),   ENUM_ENTRY(TYPE),      ENUM_ENTRY(IMPORT),
    ENUM_ENTRY(FUNCTION), ENUM_ENTRY(TABLE),     ENUM_ENTRY(MEMORY),
    ENUM_ENTRY(GLOBAL),   ENUM_ENTRY(EVENT),     ENUM_ENTRY(EXPORT),
    ENUM_ENTRY(START),    ENUM_ENTRY(ELEM),      ENUM_ENTRY(CODE),
    ENUM_ENTRY(DATA),     ENUM_ENTRY(DATACOUNT),
#undef ENUM_ENTRY
};

static const EnumEntry<unsigned> WasmSymbolFlags[] = {
#define ENUM_ENTRY(X)                                                          \
  { #X, wasm::WASM_SYMBOL_##X }
  ENUM_ENTRY(BINDING_GLOBAL),
  ENUM_ENTRY(BINDING_WEAK),
  ENUM_ENTRY(BINDING_LOCAL),
  ENUM_ENTRY(VISIBILITY_DEFAULT),
  ENUM_ENTRY(VISIBILITY_HIDDEN),
  ENUM_ENTRY(UNDEFINED),
  ENUM_ENTRY(EXPORTED),
  ENUM_ENTRY(EXPLICIT_NAME),
  ENUM_ENTRY(NO_STRIP),
#undef ENUM_ENTRY
};

class WasmDumper : public ObjDumper {
public:
  WasmDumper(const WasmObjectFile *Obj, ScopedPrinter &Writer)
      : ObjDumper(Writer, Obj->getFileName()), Obj(Obj) {}

  void printFileHeaders() override;
  void printSectionHeaders() override;
  void printRelocations() override;
  void printUnwindInfo() override { llvm_unreachable("unimplemented"); }
  void printStackMap() const override { llvm_unreachable("unimplemented"); }

protected:
  void printSymbol(const SymbolRef &Sym);
  void printRelocation(const SectionRef &Section, const RelocationRef &Reloc);

private:
  void printSymbols() override;
  void printDynamicSymbols() override { llvm_unreachable("unimplemented"); }

  const WasmObjectFile *Obj;
};

void WasmDumper::printFileHeaders() {
  W.printHex("Version", Obj->getHeader().Version);
}

void WasmDumper::printRelocation(const SectionRef &Section,
                                 const RelocationRef &Reloc) {
  SmallString<64> RelocTypeName;
  uint64_t RelocType = Reloc.getType();
  Reloc.getTypeName(RelocTypeName);
  const wasm::WasmRelocation &WasmReloc = Obj->getWasmRelocation(Reloc);

  StringRef SymName;
  symbol_iterator SI = Reloc.getSymbol();
  if (SI != Obj->symbol_end())
    SymName = unwrapOrError(Obj->getFileName(), SI->getName());

  bool HasAddend = wasm::relocTypeHasAddend(static_cast<uint32_t>(RelocType));

  if (opts::ExpandRelocs) {
    DictScope Group(W, "Relocation");
    W.printNumber("Type", RelocTypeName, RelocType);
    W.printHex("Offset", Reloc.getOffset());
    if (!SymName.empty())
      W.printString("Symbol", SymName);
    else
      W.printHex("Index", WasmReloc.Index);
    if (HasAddend)
      W.printNumber("Addend", WasmReloc.Addend);
  } else {
    raw_ostream &OS = W.startLine();
    OS << W.hex(Reloc.getOffset()) << " " << RelocTypeName << " ";
    if (!SymName.empty())
      OS << SymName;
    else
      OS << WasmReloc.Index;
    if (HasAddend)
      OS << " " << WasmReloc.Addend;
    OS << "\n";
  }
}

void WasmDumper::printRelocations() {
  ListScope D(W, "Relocations");

  int SectionNumber = 0;
  for (const SectionRef &Section : Obj->sections()) {
    bool PrintedGroup = false;
    StringRef Name = unwrapOrError(Obj->getFileName(), Section.getName());

    ++SectionNumber;

    for (const RelocationRef &Reloc : Section.relocations()) {
      if (!PrintedGroup) {
        W.startLine() << "Section (" << SectionNumber << ") " << Name << " {\n";
        W.indent();
        PrintedGroup = true;
      }

      printRelocation(Section, Reloc);
    }

    if (PrintedGroup) {
      W.unindent();
      W.startLine() << "}\n";
    }
  }
}

void WasmDumper::printSymbols() {
  ListScope Group(W, "Symbols");

  for (const SymbolRef &Symbol : Obj->symbols())
    printSymbol(Symbol);
}

void WasmDumper::printSectionHeaders() {
  ListScope Group(W, "Sections");
  for (const SectionRef &Section : Obj->sections()) {
    const WasmSection &WasmSec = Obj->getWasmSection(Section);
    DictScope SectionD(W, "Section");
    W.printEnum("Type", WasmSec.Type, makeArrayRef(WasmSectionTypes));
    W.printNumber("Size", static_cast<uint64_t>(WasmSec.Content.size()));
    W.printNumber("Offset", WasmSec.Offset);
    switch (WasmSec.Type) {
    case wasm::WASM_SEC_CUSTOM:
      W.printString("Name", WasmSec.Name);
      if (WasmSec.Name == "linking") {
        const wasm::WasmLinkingData &LinkingData = Obj->linkingData();
        if (!LinkingData.InitFunctions.empty()) {
          ListScope Group(W, "InitFunctions");
          for (const wasm::WasmInitFunc &F : LinkingData.InitFunctions)
            W.startLine() << F.Symbol << " (priority=" << F.Priority << ")\n";
        }
      }
      break;
    case wasm::WASM_SEC_DATA: {
      ListScope Group(W, "Segments");
      for (const WasmSegment &Segment : Obj->dataSegments()) {
        const wasm::WasmDataSegment &Seg = Segment.Data;
        DictScope Group(W, "Segment");
        if (!Seg.Name.empty())
          W.printString("Name", Seg.Name);
        W.printNumber("Size", static_cast<uint64_t>(Seg.Content.size()));
        if (Seg.Offset.Opcode == wasm::WASM_OPCODE_I32_CONST)
          W.printNumber("Offset", Seg.Offset.Value.Int32);
        else if (Seg.Offset.Opcode == wasm::WASM_OPCODE_I64_CONST)
          W.printNumber("Offset", Seg.Offset.Value.Int64);
        else
          llvm_unreachable("unknown init expr opcode");
      }
      break;
    }
    case wasm::WASM_SEC_MEMORY:
      ListScope Group(W, "Memories");
      for (const wasm::WasmLimits &Memory : Obj->memories()) {
        DictScope Group(W, "Memory");
        W.printNumber("InitialPages", Memory.Initial);
        if (Memory.Flags & wasm::WASM_LIMITS_FLAG_HAS_MAX) {
          W.printNumber("MaxPages", WasmSec.Offset);
        }
      }
      break;
    }

    if (opts::SectionRelocations) {
      ListScope D(W, "Relocations");
      for (const RelocationRef &Reloc : Section.relocations())
        printRelocation(Section, Reloc);
    }

    if (opts::SectionData) {
      W.printBinaryBlock("SectionData", WasmSec.Content);
    }
  }
}

void WasmDumper::printSymbol(const SymbolRef &Sym) {
  DictScope D(W, "Symbol");
  WasmSymbol Symbol = Obj->getWasmSymbol(Sym.getRawDataRefImpl());
  W.printString("Name", Symbol.Info.Name);
  W.printEnum("Type", Symbol.Info.Kind, makeArrayRef(WasmSymbolTypes));
  W.printFlags("Flags", Symbol.Info.Flags, makeArrayRef(WasmSymbolFlags));

  if (Symbol.Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) {
    if (Symbol.Info.ImportName) {
      W.printString("ImportName", *Symbol.Info.ImportName);
    }
    if (Symbol.Info.ImportModule) {
      W.printString("ImportModule", *Symbol.Info.ImportModule);
    }
  }
  if (Symbol.Info.Kind != wasm::WASM_SYMBOL_TYPE_DATA) {
    W.printHex("ElementIndex", Symbol.Info.ElementIndex);
  } else if (!(Symbol.Info.Flags & wasm::WASM_SYMBOL_UNDEFINED)) {
    W.printHex("Offset", Symbol.Info.DataRef.Offset);
    W.printHex("Segment", Symbol.Info.DataRef.Segment);
    W.printHex("Size", Symbol.Info.DataRef.Size);
  }
}

} // namespace

namespace llvm {

std::unique_ptr<ObjDumper> createWasmDumper(const object::WasmObjectFile &Obj,
                                            ScopedPrinter &Writer) {
  return std::make_unique<WasmDumper>(&Obj, Writer);
}

} // namespace llvm
