//===- WasmObjectFile.cpp - Wasm object file implementation ---------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
#include "llvm/BinaryFormat/Wasm.h"
#include "llvm/MC/SubtargetFeature.h"
#include "llvm/Object/Binary.h"
#include "llvm/Object/Error.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Object/SymbolicFile.h"
#include "llvm/Object/Wasm.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/LEB128.h"
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <cstring>
#include <system_error>

#define DEBUG_TYPE "wasm-object"

using namespace llvm;
using namespace object;

Expected<std::unique_ptr<WasmObjectFile>>
ObjectFile::createWasmObjectFile(MemoryBufferRef Buffer) {
  Error Err = Error::success();
  auto ObjectFile = llvm::make_unique<WasmObjectFile>(Buffer, Err);
  if (Err)
    return std::move(Err);

  return std::move(ObjectFile);
}

#define VARINT7_MAX ((1<<7)-1)
#define VARINT7_MIN (-(1<<7))
#define VARUINT7_MAX (1<<7)
#define VARUINT1_MAX (1)

static uint8_t readUint8(const uint8_t *&Ptr) { return *Ptr++; }

static uint32_t readUint32(const uint8_t *&Ptr) {
  uint32_t Result = support::endian::read32le(Ptr);
  Ptr += sizeof(Result);
  return Result;
}

static int32_t readFloat32(const uint8_t *&Ptr) {
  int32_t Result = 0;
  memcpy(&Result, Ptr, sizeof(Result));
  Ptr += sizeof(Result);
  return Result;
}

static int64_t readFloat64(const uint8_t *&Ptr) {
  int64_t Result = 0;
  memcpy(&Result, Ptr, sizeof(Result));
  Ptr += sizeof(Result);
  return Result;
}

static uint64_t readULEB128(const uint8_t *&Ptr) {
  unsigned Count;
  uint64_t Result = decodeULEB128(Ptr, &Count);
  Ptr += Count;
  return Result;
}

static StringRef readString(const uint8_t *&Ptr) {
  uint32_t StringLen = readULEB128(Ptr);
  StringRef Return = StringRef(reinterpret_cast<const char *>(Ptr), StringLen);
  Ptr += StringLen;
  return Return;
}

static int64_t readLEB128(const uint8_t *&Ptr) {
  unsigned Count;
  uint64_t Result = decodeSLEB128(Ptr, &Count);
  Ptr += Count;
  return Result;
}

static uint8_t readVaruint1(const uint8_t *&Ptr) {
  int64_t result = readLEB128(Ptr);
  assert(result <= VARUINT1_MAX && result >= 0);
  return result;
}

static int8_t readVarint7(const uint8_t *&Ptr) {
  int64_t result = readLEB128(Ptr);
  assert(result <= VARINT7_MAX && result >= VARINT7_MIN);
  return result;
}

static uint8_t readVaruint7(const uint8_t *&Ptr) {
  uint64_t result = readULEB128(Ptr);
  assert(result <= VARUINT7_MAX);
  return result;
}

static int32_t readVarint32(const uint8_t *&Ptr) {
  int64_t result = readLEB128(Ptr);
  assert(result <= INT32_MAX && result >= INT32_MIN);
  return result;
}

static uint32_t readVaruint32(const uint8_t *&Ptr) {
  uint64_t result = readULEB128(Ptr);
  assert(result <= UINT32_MAX);
  return result;
}

static int64_t readVarint64(const uint8_t *&Ptr) {
  return readLEB128(Ptr);
}

static uint8_t readOpcode(const uint8_t *&Ptr) {
  return readUint8(Ptr);
}

static Error readInitExpr(wasm::WasmInitExpr &Expr, const uint8_t *&Ptr) {
  Expr.Opcode = readOpcode(Ptr);

  switch (Expr.Opcode) {
  case wasm::WASM_OPCODE_I32_CONST:
    Expr.Value.Int32 = readVarint32(Ptr);
    break;
  case wasm::WASM_OPCODE_I64_CONST:
    Expr.Value.Int64 = readVarint64(Ptr);
    break;
  case wasm::WASM_OPCODE_F32_CONST:
    Expr.Value.Float32 = readFloat32(Ptr);
    break;
  case wasm::WASM_OPCODE_F64_CONST:
    Expr.Value.Float64 = readFloat64(Ptr);
    break;
  case wasm::WASM_OPCODE_GET_GLOBAL:
    Expr.Value.Global = readULEB128(Ptr);
    break;
  default:
    return make_error<GenericBinaryError>("Invalid opcode in init_expr",
                                          object_error::parse_failed);
  }

  uint8_t EndOpcode = readOpcode(Ptr);
  if (EndOpcode != wasm::WASM_OPCODE_END) {
    return make_error<GenericBinaryError>("Invalid init_expr",
                                          object_error::parse_failed);
  }
  return Error::success();
}

static wasm::WasmLimits readLimits(const uint8_t *&Ptr) {
  wasm::WasmLimits Result;
  Result.Flags = readVaruint1(Ptr);
  Result.Initial = readVaruint32(Ptr);
  if (Result.Flags & wasm::WASM_LIMITS_FLAG_HAS_MAX)
    Result.Maximum = readVaruint32(Ptr);
  return Result;
}

static wasm::WasmTable readTable(const uint8_t *&Ptr) {
  wasm::WasmTable Table;
  Table.ElemType = readVarint7(Ptr);
  Table.Limits = readLimits(Ptr);
  return Table;
}

static Error readSection(WasmSection &Section, const uint8_t *&Ptr,
                         const uint8_t *Start) {
  // TODO(sbc): Avoid reading past EOF in the case of malformed files.
  Section.Offset = Ptr - Start;
  Section.Type = readVaruint7(Ptr);
  uint32_t Size = readVaruint32(Ptr);
  if (Size == 0)
    return make_error<StringError>("Zero length section",
                                   object_error::parse_failed);
  Section.Content = ArrayRef<uint8_t>(Ptr, Size);
  Ptr += Size;
  return Error::success();
}

WasmObjectFile::WasmObjectFile(MemoryBufferRef Buffer, Error &Err)
    : ObjectFile(Binary::ID_Wasm, Buffer) {
  LinkingData.DataAlignment = 0;
  LinkingData.DataSize = 0;

  ErrorAsOutParameter ErrAsOutParam(&Err);
  Header.Magic = getData().substr(0, 4);
  if (Header.Magic != StringRef("\0asm", 4)) {
    Err = make_error<StringError>("Bad magic number",
                                  object_error::parse_failed);
    return;
  }
  const uint8_t *Ptr = getPtr(4);
  Header.Version = readUint32(Ptr);
  if (Header.Version != wasm::WasmVersion) {
    Err = make_error<StringError>("Bad version number",
                                  object_error::parse_failed);
    return;
  }

  const uint8_t *Eof = getPtr(getData().size());
  WasmSection Sec;
  while (Ptr < Eof) {
    if ((Err = readSection(Sec, Ptr, getPtr(0))))
      return;
    if ((Err = parseSection(Sec)))
      return;

    Sections.push_back(Sec);
  }
}

Error WasmObjectFile::parseSection(WasmSection &Sec) {
  const uint8_t* Start = Sec.Content.data();
  const uint8_t* End = Start + Sec.Content.size();
  switch (Sec.Type) {
  case wasm::WASM_SEC_CUSTOM:
    return parseCustomSection(Sec, Start, End);
  case wasm::WASM_SEC_TYPE:
    return parseTypeSection(Start, End);
  case wasm::WASM_SEC_IMPORT:
    return parseImportSection(Start, End);
  case wasm::WASM_SEC_FUNCTION:
    return parseFunctionSection(Start, End);
  case wasm::WASM_SEC_TABLE:
    return parseTableSection(Start, End);
  case wasm::WASM_SEC_MEMORY:
    return parseMemorySection(Start, End);
  case wasm::WASM_SEC_GLOBAL:
    return parseGlobalSection(Start, End);
  case wasm::WASM_SEC_EXPORT:
    return parseExportSection(Start, End);
  case wasm::WASM_SEC_START:
    return parseStartSection(Start, End);
  case wasm::WASM_SEC_ELEM:
    return parseElemSection(Start, End);
  case wasm::WASM_SEC_CODE:
    return parseCodeSection(Start, End);
  case wasm::WASM_SEC_DATA:
    return parseDataSection(Start, End);
  default:
    return make_error<GenericBinaryError>("Bad section type",
                                          object_error::parse_failed);
  }
}

Error WasmObjectFile::parseNameSection(const uint8_t *Ptr, const uint8_t *End) {
  while (Ptr < End) {
    uint8_t Type = readVarint7(Ptr);
    uint32_t Size = readVaruint32(Ptr);
    const uint8_t *SubSectionEnd = Ptr + Size;
    switch (Type) {
    case wasm::WASM_NAMES_FUNCTION: {
      uint32_t Count = readVaruint32(Ptr);
      while (Count--) {
        uint32_t Index = readVaruint32(Ptr);
        StringRef Name = readString(Ptr);
        if (!Name.empty())
          Symbols.emplace_back(Name,
                               WasmSymbol::SymbolType::DEBUG_FUNCTION_NAME,
                               Sections.size(), Index);
      }
      break;
    }
    // Ignore local names for now
    case wasm::WASM_NAMES_LOCAL:
    default:
      Ptr += Size;
      break;
    }
    if (Ptr != SubSectionEnd)
      return make_error<GenericBinaryError>("Name sub-section ended prematurely",
                                            object_error::parse_failed);
  }

  if (Ptr != End)
    return make_error<GenericBinaryError>("Name section ended prematurely",
                                          object_error::parse_failed);
  return Error::success();
}

Error WasmObjectFile::parseLinkingSection(const uint8_t *Ptr,
                                          const uint8_t *End) {
  HasLinkingSection = true;
  while (Ptr < End) {
    uint8_t Type = readVarint7(Ptr);
    uint32_t Size = readVaruint32(Ptr);
    const uint8_t *SubSectionEnd = Ptr + Size;
    switch (Type) {
    case wasm::WASM_SYMBOL_INFO: {
      uint32_t Count = readVaruint32(Ptr);
      while (Count--) {
        StringRef Symbol = readString(Ptr);
        DEBUG(dbgs() << "reading syminfo: " << Symbol << "\n");
        uint32_t Flags = readVaruint32(Ptr);
        auto iter = SymbolMap.find(Symbol);
        if (iter == SymbolMap.end()) {
          return make_error<GenericBinaryError>(
              "Invalid symbol name in linking section: " + Symbol,
              object_error::parse_failed);
        }
        uint32_t SymIndex = iter->second;
        assert(SymIndex < Symbols.size());
        Symbols[SymIndex].Flags = Flags;
        DEBUG(dbgs() << "Set symbol flags index:"
                     << SymIndex << " name:"
                     << Symbols[SymIndex].Name << " exptected:"
                     << Symbol << " flags: " << Flags << "\n");
      }
      break;
    }
    case wasm::WASM_DATA_SIZE:
      LinkingData.DataSize = readVaruint32(Ptr);
      break;
    case wasm::WASM_DATA_ALIGNMENT:
      LinkingData.DataAlignment = readVaruint32(Ptr);
      break;
    case wasm::WASM_STACK_POINTER:
    default:
      Ptr += Size;
      break;
    }
    if (Ptr != SubSectionEnd)
      return make_error<GenericBinaryError>(
          "Linking sub-section ended prematurely", object_error::parse_failed);
  }
  if (Ptr != End)
    return make_error<GenericBinaryError>("Linking section ended prematurely",
                                          object_error::parse_failed);
  return Error::success();
}

WasmSection* WasmObjectFile::findCustomSectionByName(StringRef Name) {
  for (WasmSection& Section : Sections) {
    if (Section.Type == wasm::WASM_SEC_CUSTOM && Section.Name == Name)
      return &Section;
  }
  return nullptr;
}

WasmSection* WasmObjectFile::findSectionByType(uint32_t Type) {
  assert(Type != wasm::WASM_SEC_CUSTOM);
  for (WasmSection& Section : Sections) {
    if (Section.Type == Type)
      return &Section;
  }
  return nullptr;
}

Error WasmObjectFile::parseRelocSection(StringRef Name, const uint8_t *Ptr,
                                        const uint8_t *End) {
  uint8_t SectionCode = readVarint7(Ptr);
  WasmSection* Section = nullptr;
  if (SectionCode == wasm::WASM_SEC_CUSTOM) {
    StringRef Name = readString(Ptr);
    Section = findCustomSectionByName(Name);
  } else {
    Section = findSectionByType(SectionCode);
  }
  if (!Section)
    return make_error<GenericBinaryError>("Invalid section code",
                                          object_error::parse_failed);
  uint32_t RelocCount = readVaruint32(Ptr);
  while (RelocCount--) {
    wasm::WasmRelocation Reloc;
    memset(&Reloc, 0, sizeof(Reloc));
    Reloc.Type = readVaruint32(Ptr);
    Reloc.Offset = readVaruint32(Ptr);
    Reloc.Index = readVaruint32(Ptr);
    switch (Reloc.Type) {
    case wasm::R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
    case wasm::R_WEBASSEMBLY_TABLE_INDEX_SLEB:
    case wasm::R_WEBASSEMBLY_TABLE_INDEX_I32:
    case wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB:
    case wasm::R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
      break;
    case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_LEB:
    case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_SLEB:
    case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_I32:
      Reloc.Addend = readVarint32(Ptr);
      break;
    default:
      return make_error<GenericBinaryError>("Bad relocation type: " +
                                                Twine(Reloc.Type),
                                            object_error::parse_failed);
    }
    Section->Relocations.push_back(Reloc);
  }
  if (Ptr != End)
    return make_error<GenericBinaryError>("Reloc section ended prematurely",
                                          object_error::parse_failed);
  return Error::success();
}

Error WasmObjectFile::parseCustomSection(WasmSection &Sec,
                                         const uint8_t *Ptr, const uint8_t *End) {
  Sec.Name = readString(Ptr);
  if (Sec.Name == "name") {
    if (Error Err = parseNameSection(Ptr, End))
      return Err;
  } else if (Sec.Name == "linking") {
    if (Error Err = parseLinkingSection(Ptr, End))
      return Err;
  } else if (Sec.Name.startswith("reloc.")) {
    if (Error Err = parseRelocSection(Sec.Name, Ptr, End))
      return Err;
  }
  return Error::success();
}

Error WasmObjectFile::parseTypeSection(const uint8_t *Ptr, const uint8_t *End) {
  uint32_t Count = readVaruint32(Ptr);
  Signatures.reserve(Count);
  while (Count--) {
    wasm::WasmSignature Sig;
    Sig.ReturnType = wasm::WASM_TYPE_NORESULT;
    int8_t Form = readVarint7(Ptr);
    if (Form != wasm::WASM_TYPE_FUNC) {
      return make_error<GenericBinaryError>("Invalid signature type",
                                            object_error::parse_failed);
    }
    uint32_t ParamCount = readVaruint32(Ptr);
    Sig.ParamTypes.reserve(ParamCount);
    while (ParamCount--) {
      uint32_t ParamType = readVarint7(Ptr);
      Sig.ParamTypes.push_back(ParamType);
    }
    uint32_t ReturnCount = readVaruint32(Ptr);
    if (ReturnCount) {
      if (ReturnCount != 1) {
        return make_error<GenericBinaryError>(
            "Multiple return types not supported", object_error::parse_failed);
      }
      Sig.ReturnType = readVarint7(Ptr);
    }
    Signatures.push_back(Sig);
  }
  if (Ptr != End)
    return make_error<GenericBinaryError>("Type section ended prematurely",
                                          object_error::parse_failed);
  return Error::success();
}

Error WasmObjectFile::parseImportSection(const uint8_t *Ptr, const uint8_t *End) {
  uint32_t Count = readVaruint32(Ptr);
  Imports.reserve(Count);
  for (uint32_t i = 0; i < Count; i++) {
    wasm::WasmImport Im;
    Im.Module = readString(Ptr);
    Im.Field = readString(Ptr);
    Im.Kind = readUint8(Ptr);
    switch (Im.Kind) {
    case wasm::WASM_EXTERNAL_FUNCTION:
      Im.SigIndex = readVaruint32(Ptr);
      SymbolMap.try_emplace(Im.Field, Symbols.size());
      Symbols.emplace_back(Im.Field, WasmSymbol::SymbolType::FUNCTION_IMPORT,
                           Sections.size(), i);
      DEBUG(dbgs() << "Adding import: " << Symbols.back()
                   << " sym index:" << Symbols.size() << "\n");
      break;
    case wasm::WASM_EXTERNAL_GLOBAL:
      Im.Global.Type = readVarint7(Ptr);
      Im.Global.Mutable = readVaruint1(Ptr);
      SymbolMap.try_emplace(Im.Field, Symbols.size());
      Symbols.emplace_back(Im.Field, WasmSymbol::SymbolType::GLOBAL_IMPORT,
                           Sections.size(), i);
      DEBUG(dbgs() << "Adding import: " << Symbols.back()
                   << " sym index:" << Symbols.size() << "\n");
      break;
    case wasm::WASM_EXTERNAL_MEMORY:
      Im.Memory = readLimits(Ptr);
      break;
    case wasm::WASM_EXTERNAL_TABLE:
      Im.Table = readTable(Ptr);
      if (Im.Table.ElemType != wasm::WASM_TYPE_ANYFUNC) {
        return make_error<GenericBinaryError>("Invalid table element type",
                                              object_error::parse_failed);
      }
      break;
    default:
      return make_error<GenericBinaryError>(
          "Unexpected import kind", object_error::parse_failed);
    }
    Imports.push_back(Im);
  }
  if (Ptr != End)
    return make_error<GenericBinaryError>("Import section ended prematurely",
                                          object_error::parse_failed);
  return Error::success();
}

Error WasmObjectFile::parseFunctionSection(const uint8_t *Ptr, const uint8_t *End) {
  uint32_t Count = readVaruint32(Ptr);
  FunctionTypes.reserve(Count);
  while (Count--) {
    FunctionTypes.push_back(readVaruint32(Ptr));
  }
  if (Ptr != End)
    return make_error<GenericBinaryError>("Function section ended prematurely",
                                          object_error::parse_failed);
  return Error::success();
}

Error WasmObjectFile::parseTableSection(const uint8_t *Ptr, const uint8_t *End) {
  uint32_t Count = readVaruint32(Ptr);
  Tables.reserve(Count);
  while (Count--) {
    Tables.push_back(readTable(Ptr));
    if (Tables.back().ElemType != wasm::WASM_TYPE_ANYFUNC) {
      return make_error<GenericBinaryError>("Invalid table element type",
                                            object_error::parse_failed);
    }
  }
  if (Ptr != End)
    return make_error<GenericBinaryError>("Table section ended prematurely",
                                          object_error::parse_failed);
  return Error::success();
}

Error WasmObjectFile::parseMemorySection(const uint8_t *Ptr, const uint8_t *End) {
  uint32_t Count = readVaruint32(Ptr);
  Memories.reserve(Count);
  while (Count--) {
    Memories.push_back(readLimits(Ptr));
  }
  if (Ptr != End)
    return make_error<GenericBinaryError>("Memory section ended prematurely",
                                          object_error::parse_failed);
  return Error::success();
}

Error WasmObjectFile::parseGlobalSection(const uint8_t *Ptr, const uint8_t *End) {
  uint32_t Count = readVaruint32(Ptr);
  Globals.reserve(Count);
  while (Count--) {
    wasm::WasmGlobal Global;
    Global.Type = readVarint7(Ptr);
    Global.Mutable = readVaruint1(Ptr);
    if (Error Err = readInitExpr(Global.InitExpr, Ptr))
      return Err;
    Globals.push_back(Global);
  }
  if (Ptr != End)
    return make_error<GenericBinaryError>("Global section ended prematurely",
                                          object_error::parse_failed);
  return Error::success();
}

Error WasmObjectFile::parseExportSection(const uint8_t *Ptr, const uint8_t *End) {
  uint32_t Count = readVaruint32(Ptr);
  Exports.reserve(Count);
  for (uint32_t i = 0; i < Count; i++) {
    wasm::WasmExport Ex;
    Ex.Name = readString(Ptr);
    Ex.Kind = readUint8(Ptr);
    Ex.Index = readVaruint32(Ptr);
    WasmSymbol::SymbolType ExportType;
    bool MakeSymbol = false;
    switch (Ex.Kind) {
    case wasm::WASM_EXTERNAL_FUNCTION:
      ExportType = WasmSymbol::SymbolType::FUNCTION_EXPORT;
      MakeSymbol = true;
      break;
    case wasm::WASM_EXTERNAL_GLOBAL:
      ExportType = WasmSymbol::SymbolType::GLOBAL_EXPORT;
      MakeSymbol = true;
      break;
    case wasm::WASM_EXTERNAL_MEMORY:
    case wasm::WASM_EXTERNAL_TABLE:
      break;
    default:
      return make_error<GenericBinaryError>(
          "Unexpected export kind", object_error::parse_failed);
    }
    if (MakeSymbol) {
      auto Pair = SymbolMap.try_emplace(Ex.Name, Symbols.size());
      if (Pair.second) {
        Symbols.emplace_back(Ex.Name, ExportType,
                             Sections.size(), i);
        DEBUG(dbgs() << "Adding export: " << Symbols.back()
                     << " sym index:" << Symbols.size() << "\n");
      } else {
        uint32_t SymIndex = Pair.first->second;
        Symbols[SymIndex] = WasmSymbol(Ex.Name, ExportType, Sections.size(), i);
        DEBUG(dbgs() << "Replacing existing symbol:  " << Symbols[SymIndex]
                     << " sym index:" << SymIndex << "\n");
      }
    }
    Exports.push_back(Ex);
  }
  if (Ptr != End)
    return make_error<GenericBinaryError>("Export section ended prematurely",
                                          object_error::parse_failed);
  return Error::success();
}

Error WasmObjectFile::parseStartSection(const uint8_t *Ptr, const uint8_t *End) {
  StartFunction = readVaruint32(Ptr);
  if (StartFunction >= FunctionTypes.size())
    return make_error<GenericBinaryError>("Invalid start function",
                                          object_error::parse_failed);
  return Error::success();
}

Error WasmObjectFile::parseCodeSection(const uint8_t *Ptr, const uint8_t *End) {
  uint32_t FunctionCount = readVaruint32(Ptr);
  if (FunctionCount != FunctionTypes.size()) {
    return make_error<GenericBinaryError>("Invalid function count",
                                          object_error::parse_failed);
  }

  CodeSection = ArrayRef<uint8_t>(Ptr, End - Ptr);

  while (FunctionCount--) {
    wasm::WasmFunction Function;
    uint32_t FunctionSize = readVaruint32(Ptr);
    const uint8_t *FunctionEnd = Ptr + FunctionSize;

    uint32_t NumLocalDecls = readVaruint32(Ptr);
    Function.Locals.reserve(NumLocalDecls);
    while (NumLocalDecls--) {
      wasm::WasmLocalDecl Decl;
      Decl.Count = readVaruint32(Ptr);
      Decl.Type = readVarint7(Ptr);
      Function.Locals.push_back(Decl);
    }

    uint32_t BodySize = FunctionEnd - Ptr;
    Function.Body = ArrayRef<uint8_t>(Ptr, BodySize);
    Ptr += BodySize;
    assert(Ptr == FunctionEnd);
    Functions.push_back(Function);
  }
  if (Ptr != End)
    return make_error<GenericBinaryError>("Code section ended prematurely",
                                          object_error::parse_failed);
  return Error::success();
}

Error WasmObjectFile::parseElemSection(const uint8_t *Ptr, const uint8_t *End) {
  uint32_t Count = readVaruint32(Ptr);
  ElemSegments.reserve(Count);
  while (Count--) {
    wasm::WasmElemSegment Segment;
    Segment.TableIndex = readVaruint32(Ptr);
    if (Segment.TableIndex != 0) {
      return make_error<GenericBinaryError>("Invalid TableIndex",
                                            object_error::parse_failed);
    }
    if (Error Err = readInitExpr(Segment.Offset, Ptr))
      return Err;
    uint32_t NumElems = readVaruint32(Ptr);
    while (NumElems--) {
      Segment.Functions.push_back(readVaruint32(Ptr));
    }
    ElemSegments.push_back(Segment);
  }
  if (Ptr != End)
    return make_error<GenericBinaryError>("Elem section ended prematurely",
                                          object_error::parse_failed);
  return Error::success();
}

Error WasmObjectFile::parseDataSection(const uint8_t *Ptr, const uint8_t *End) {
  const uint8_t *Start = Ptr;
  uint32_t Count = readVaruint32(Ptr);
  DataSegments.reserve(Count);
  while (Count--) {
    WasmSegment Segment;
    Segment.Data.MemoryIndex = readVaruint32(Ptr);
    if (Error Err = readInitExpr(Segment.Data.Offset, Ptr))
      return Err;
    uint32_t Size = readVaruint32(Ptr);
    Segment.Data.Content = ArrayRef<uint8_t>(Ptr, Size);
    Segment.SectionOffset = Ptr - Start;
    Ptr += Size;
    DataSegments.push_back(Segment);
  }
  if (Ptr != End)
    return make_error<GenericBinaryError>("Data section ended prematurely",
                                          object_error::parse_failed);
  return Error::success();
}

const uint8_t *WasmObjectFile::getPtr(size_t Offset) const {
  return reinterpret_cast<const uint8_t *>(getData().substr(Offset, 1).data());
}

const wasm::WasmObjectHeader &WasmObjectFile::getHeader() const {
  return Header;
}

void WasmObjectFile::moveSymbolNext(DataRefImpl &Symb) const { Symb.d.a++; }

uint32_t WasmObjectFile::getSymbolFlags(DataRefImpl Symb) const {
  uint32_t Result = SymbolRef::SF_None;
  const WasmSymbol &Sym = getWasmSymbol(Symb);

  DEBUG(dbgs() << "getSymbolFlags: ptr=" << &Sym << " " << Sym << "\n");
  if (Sym.Flags & wasm::WASM_SYMBOL_FLAG_WEAK)
    Result |= SymbolRef::SF_Weak;

  switch (Sym.Type) {
  case WasmSymbol::SymbolType::FUNCTION_IMPORT:
    Result |= SymbolRef::SF_Undefined | SymbolRef::SF_Executable;
    break;
  case WasmSymbol::SymbolType::FUNCTION_EXPORT:
    Result |= SymbolRef::SF_Global | SymbolRef::SF_Executable;
    break;
  case WasmSymbol::SymbolType::DEBUG_FUNCTION_NAME:
    Result |= SymbolRef::SF_Executable;
    Result |= SymbolRef::SF_FormatSpecific;
    break;
  case WasmSymbol::SymbolType::GLOBAL_IMPORT:
    Result |= SymbolRef::SF_Undefined;
    break;
  case WasmSymbol::SymbolType::GLOBAL_EXPORT:
    Result |= SymbolRef::SF_Global;
    break;
  }

  return Result;
}

basic_symbol_iterator WasmObjectFile::symbol_begin() const {
  DataRefImpl Ref;
  Ref.d.a = 0;
  return BasicSymbolRef(Ref, this);
}

basic_symbol_iterator WasmObjectFile::symbol_end() const {
  DataRefImpl Ref;
  Ref.d.a = Symbols.size();
  return BasicSymbolRef(Ref, this);
}

const WasmSymbol &WasmObjectFile::getWasmSymbol(const DataRefImpl &Symb) const {
  return Symbols[Symb.d.a];
}

const WasmSymbol &WasmObjectFile::getWasmSymbol(const SymbolRef &Symb) const {
  return getWasmSymbol(Symb.getRawDataRefImpl());
}

Expected<StringRef> WasmObjectFile::getSymbolName(DataRefImpl Symb) const {
  return getWasmSymbol(Symb).Name;
}

Expected<uint64_t> WasmObjectFile::getSymbolAddress(DataRefImpl Symb) const {
  return getSymbolValue(Symb);
}

uint64_t WasmObjectFile::getSymbolValueImpl(DataRefImpl Symb) const {
  const WasmSymbol& Sym = getWasmSymbol(Symb);
  switch (Sym.Type) {
  case WasmSymbol::SymbolType::FUNCTION_IMPORT:
  case WasmSymbol::SymbolType::GLOBAL_IMPORT:
    return 0;
  case WasmSymbol::SymbolType::FUNCTION_EXPORT:
  case WasmSymbol::SymbolType::GLOBAL_EXPORT:
    return Exports[Sym.ElementIndex].Index;
  case WasmSymbol::SymbolType::DEBUG_FUNCTION_NAME:
    return Sym.ElementIndex;
  }
  llvm_unreachable("invalid symbol type");
}

uint32_t WasmObjectFile::getSymbolAlignment(DataRefImpl Symb) const {
  llvm_unreachable("not yet implemented");
  return 0;
}

uint64_t WasmObjectFile::getCommonSymbolSizeImpl(DataRefImpl Symb) const {
  llvm_unreachable("not yet implemented");
  return 0;
}

Expected<SymbolRef::Type>
WasmObjectFile::getSymbolType(DataRefImpl Symb) const {
  const WasmSymbol &Sym = getWasmSymbol(Symb);

  switch (Sym.Type) {
  case WasmSymbol::SymbolType::FUNCTION_IMPORT:
  case WasmSymbol::SymbolType::FUNCTION_EXPORT:
  case WasmSymbol::SymbolType::DEBUG_FUNCTION_NAME:
    return SymbolRef::ST_Function;
  case WasmSymbol::SymbolType::GLOBAL_IMPORT:
  case WasmSymbol::SymbolType::GLOBAL_EXPORT:
    return SymbolRef::ST_Data;
  }

  llvm_unreachable("Unknown WasmSymbol::SymbolType");
  return SymbolRef::ST_Other;
}

Expected<section_iterator>
WasmObjectFile::getSymbolSection(DataRefImpl Symb) const {
  DataRefImpl Ref;
  Ref.d.a = getWasmSymbol(Symb).Section;
  return section_iterator(SectionRef(Ref, this));
}

void WasmObjectFile::moveSectionNext(DataRefImpl &Sec) const { Sec.d.a++; }

std::error_code WasmObjectFile::getSectionName(DataRefImpl Sec,
                                               StringRef &Res) const {
  const WasmSection &S = Sections[Sec.d.a];
#define ECase(X)                                                               \
  case wasm::WASM_SEC_##X:                                                     \
    Res = #X;                                                                  \
    break
  switch (S.Type) {
    ECase(TYPE);
    ECase(IMPORT);
    ECase(FUNCTION);
    ECase(TABLE);
    ECase(MEMORY);
    ECase(GLOBAL);
    ECase(EXPORT);
    ECase(START);
    ECase(ELEM);
    ECase(CODE);
    ECase(DATA);
  case wasm::WASM_SEC_CUSTOM:
    Res = S.Name;
    break;
  default:
    return object_error::invalid_section_index;
  }
#undef ECase
  return std::error_code();
}

uint64_t WasmObjectFile::getSectionAddress(DataRefImpl Sec) const { return 0; }

uint64_t WasmObjectFile::getSectionIndex(DataRefImpl Sec) const {
  return Sec.d.a;
}

uint64_t WasmObjectFile::getSectionSize(DataRefImpl Sec) const {
  const WasmSection &S = Sections[Sec.d.a];
  return S.Content.size();
}

std::error_code WasmObjectFile::getSectionContents(DataRefImpl Sec,
                                                   StringRef &Res) const {
  const WasmSection &S = Sections[Sec.d.a];
  // This will never fail since wasm sections can never be empty (user-sections
  // must have a name and non-user sections each have a defined structure).
  Res = StringRef(reinterpret_cast<const char *>(S.Content.data()),
                  S.Content.size());
  return std::error_code();
}

uint64_t WasmObjectFile::getSectionAlignment(DataRefImpl Sec) const {
  return 1;
}

bool WasmObjectFile::isSectionCompressed(DataRefImpl Sec) const {
  return false;
}

bool WasmObjectFile::isSectionText(DataRefImpl Sec) const {
  return getWasmSection(Sec).Type == wasm::WASM_SEC_CODE;
}

bool WasmObjectFile::isSectionData(DataRefImpl Sec) const {
  return getWasmSection(Sec).Type == wasm::WASM_SEC_DATA;
}

bool WasmObjectFile::isSectionBSS(DataRefImpl Sec) const { return false; }

bool WasmObjectFile::isSectionVirtual(DataRefImpl Sec) const { return false; }

bool WasmObjectFile::isSectionBitcode(DataRefImpl Sec) const { return false; }

relocation_iterator WasmObjectFile::section_rel_begin(DataRefImpl Ref) const {
  DataRefImpl RelocRef;
  RelocRef.d.a = Ref.d.a;
  RelocRef.d.b = 0;
  return relocation_iterator(RelocationRef(RelocRef, this));
}

relocation_iterator WasmObjectFile::section_rel_end(DataRefImpl Ref) const {
  const WasmSection &Sec = getWasmSection(Ref);
  DataRefImpl RelocRef;
  RelocRef.d.a = Ref.d.a;
  RelocRef.d.b = Sec.Relocations.size();
  return relocation_iterator(RelocationRef(RelocRef, this));
}

void WasmObjectFile::moveRelocationNext(DataRefImpl &Rel) const {
  Rel.d.b++;
}

uint64_t WasmObjectFile::getRelocationOffset(DataRefImpl Ref) const {
  const wasm::WasmRelocation &Rel = getWasmRelocation(Ref);
  return Rel.Offset;
}

symbol_iterator WasmObjectFile::getRelocationSymbol(DataRefImpl Rel) const {
  llvm_unreachable("not yet implemented");
  SymbolRef Ref;
  return symbol_iterator(Ref);
}

uint64_t WasmObjectFile::getRelocationType(DataRefImpl Ref) const {
  const wasm::WasmRelocation &Rel = getWasmRelocation(Ref);
  return Rel.Type;
}

void WasmObjectFile::getRelocationTypeName(
    DataRefImpl Ref, SmallVectorImpl<char> &Result) const {
  const wasm::WasmRelocation& Rel = getWasmRelocation(Ref);
  StringRef Res = "Unknown";

#define WASM_RELOC(name, value)  \
  case wasm::name:              \
    Res = #name;               \
    break;

  switch (Rel.Type) {
#include "llvm/BinaryFormat/WasmRelocs/WebAssembly.def"
  }

#undef WASM_RELOC

  Result.append(Res.begin(), Res.end());
}

section_iterator WasmObjectFile::section_begin() const {
  DataRefImpl Ref;
  Ref.d.a = 0;
  return section_iterator(SectionRef(Ref, this));
}

section_iterator WasmObjectFile::section_end() const {
  DataRefImpl Ref;
  Ref.d.a = Sections.size();
  return section_iterator(SectionRef(Ref, this));
}

uint8_t WasmObjectFile::getBytesInAddress() const { return 4; }

StringRef WasmObjectFile::getFileFormatName() const { return "WASM"; }

unsigned WasmObjectFile::getArch() const { return Triple::wasm32; }

SubtargetFeatures WasmObjectFile::getFeatures() const {
  return SubtargetFeatures();
}

bool WasmObjectFile::isRelocatableObject() const {
  return HasLinkingSection;
}

const WasmSection &WasmObjectFile::getWasmSection(DataRefImpl Ref) const {
  assert(Ref.d.a < Sections.size());
  return Sections[Ref.d.a];
}

const WasmSection &
WasmObjectFile::getWasmSection(const SectionRef &Section) const {
  return getWasmSection(Section.getRawDataRefImpl());
}

const wasm::WasmRelocation &
WasmObjectFile::getWasmRelocation(const RelocationRef &Ref) const {
  return getWasmRelocation(Ref.getRawDataRefImpl());
}

const wasm::WasmRelocation &
WasmObjectFile::getWasmRelocation(DataRefImpl Ref) const {
  assert(Ref.d.a < Sections.size());
  const WasmSection& Sec = Sections[Ref.d.a];
  assert(Ref.d.b < Sec.Relocations.size());
  return Sec.Relocations[Ref.d.b];
}
