//===- WasmObjectFile.cpp - Wasm object file implementation ---------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/ADT/StringSwitch.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 "llvm/Support/ScopedPrinter.h"
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <cstring>
#include <system_error>

#define DEBUG_TYPE "wasm-object"

using namespace llvm;
using namespace object;

void WasmSymbol::print(raw_ostream &Out) const {
  Out << "Name=" << Info.Name
      << ", Kind=" << toString(wasm::WasmSymbolType(Info.Kind)) << ", Flags=0x"
      << Twine::utohexstr(Info.Flags);
  if (!isTypeData()) {
    Out << ", ElemIndex=" << Info.ElementIndex;
  } else if (isDefined()) {
    Out << ", Segment=" << Info.DataRef.Segment;
    Out << ", Offset=" << Info.DataRef.Offset;
    Out << ", Size=" << Info.DataRef.Size;
  }
}

#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void WasmSymbol::dump() const { print(dbgs()); }
#endif

Expected<std::unique_ptr<WasmObjectFile>>
ObjectFile::createWasmObjectFile(MemoryBufferRef Buffer) {
  Error Err = Error::success();
  auto ObjectFile = std::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(WasmObjectFile::ReadContext &Ctx) {
  if (Ctx.Ptr == Ctx.End)
    report_fatal_error("EOF while reading uint8");
  return *Ctx.Ptr++;
}

static uint32_t readUint32(WasmObjectFile::ReadContext &Ctx) {
  if (Ctx.Ptr + 4 > Ctx.End)
    report_fatal_error("EOF while reading uint32");
  uint32_t Result = support::endian::read32le(Ctx.Ptr);
  Ctx.Ptr += 4;
  return Result;
}

static int32_t readFloat32(WasmObjectFile::ReadContext &Ctx) {
  if (Ctx.Ptr + 4 > Ctx.End)
    report_fatal_error("EOF while reading float64");
  int32_t Result = 0;
  memcpy(&Result, Ctx.Ptr, sizeof(Result));
  Ctx.Ptr += sizeof(Result);
  return Result;
}

static int64_t readFloat64(WasmObjectFile::ReadContext &Ctx) {
  if (Ctx.Ptr + 8 > Ctx.End)
    report_fatal_error("EOF while reading float64");
  int64_t Result = 0;
  memcpy(&Result, Ctx.Ptr, sizeof(Result));
  Ctx.Ptr += sizeof(Result);
  return Result;
}

static uint64_t readULEB128(WasmObjectFile::ReadContext &Ctx) {
  unsigned Count;
  const char *Error = nullptr;
  uint64_t Result = decodeULEB128(Ctx.Ptr, &Count, Ctx.End, &Error);
  if (Error)
    report_fatal_error(Error);
  Ctx.Ptr += Count;
  return Result;
}

static StringRef readString(WasmObjectFile::ReadContext &Ctx) {
  uint32_t StringLen = readULEB128(Ctx);
  if (Ctx.Ptr + StringLen > Ctx.End)
    report_fatal_error("EOF while reading string");
  StringRef Return =
      StringRef(reinterpret_cast<const char *>(Ctx.Ptr), StringLen);
  Ctx.Ptr += StringLen;
  return Return;
}

static int64_t readLEB128(WasmObjectFile::ReadContext &Ctx) {
  unsigned Count;
  const char *Error = nullptr;
  uint64_t Result = decodeSLEB128(Ctx.Ptr, &Count, Ctx.End, &Error);
  if (Error)
    report_fatal_error(Error);
  Ctx.Ptr += Count;
  return Result;
}

static uint8_t readVaruint1(WasmObjectFile::ReadContext &Ctx) {
  int64_t Result = readLEB128(Ctx);
  if (Result > VARUINT1_MAX || Result < 0)
    report_fatal_error("LEB is outside Varuint1 range");
  return Result;
}

static int32_t readVarint32(WasmObjectFile::ReadContext &Ctx) {
  int64_t Result = readLEB128(Ctx);
  if (Result > INT32_MAX || Result < INT32_MIN)
    report_fatal_error("LEB is outside Varint32 range");
  return Result;
}

static uint32_t readVaruint32(WasmObjectFile::ReadContext &Ctx) {
  uint64_t Result = readULEB128(Ctx);
  if (Result > UINT32_MAX)
    report_fatal_error("LEB is outside Varuint32 range");
  return Result;
}

static int64_t readVarint64(WasmObjectFile::ReadContext &Ctx) {
  return readLEB128(Ctx);
}

static uint64_t readVaruint64(WasmObjectFile::ReadContext &Ctx) {
  return readULEB128(Ctx);
}

static uint8_t readOpcode(WasmObjectFile::ReadContext &Ctx) {
  return readUint8(Ctx);
}

static Error readInitExpr(wasm::WasmInitExpr &Expr,
                          WasmObjectFile::ReadContext &Ctx) {
  Expr.Opcode = readOpcode(Ctx);

  switch (Expr.Opcode) {
  case wasm::WASM_OPCODE_I32_CONST:
    Expr.Value.Int32 = readVarint32(Ctx);
    break;
  case wasm::WASM_OPCODE_I64_CONST:
    Expr.Value.Int64 = readVarint64(Ctx);
    break;
  case wasm::WASM_OPCODE_F32_CONST:
    Expr.Value.Float32 = readFloat32(Ctx);
    break;
  case wasm::WASM_OPCODE_F64_CONST:
    Expr.Value.Float64 = readFloat64(Ctx);
    break;
  case wasm::WASM_OPCODE_GLOBAL_GET:
    Expr.Value.Global = readULEB128(Ctx);
    break;
  case wasm::WASM_OPCODE_REF_NULL: {
    wasm::ValType Ty = static_cast<wasm::ValType>(readULEB128(Ctx));
    if (Ty != wasm::ValType::EXTERNREF) {
      return make_error<GenericBinaryError>("invalid type for ref.null",
                                            object_error::parse_failed);
    }
    break;
  }
  default:
    return make_error<GenericBinaryError>("invalid opcode in init_expr",
                                          object_error::parse_failed);
  }

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

static wasm::WasmLimits readLimits(WasmObjectFile::ReadContext &Ctx) {
  wasm::WasmLimits Result;
  Result.Flags = readVaruint32(Ctx);
  Result.Minimum = readVaruint64(Ctx);
  if (Result.Flags & wasm::WASM_LIMITS_FLAG_HAS_MAX)
    Result.Maximum = readVaruint64(Ctx);
  return Result;
}

static wasm::WasmTableType readTableType(WasmObjectFile::ReadContext &Ctx) {
  wasm::WasmTableType TableType;
  TableType.ElemType = readUint8(Ctx);
  TableType.Limits = readLimits(Ctx);
  return TableType;
}

static Error readSection(WasmSection &Section, WasmObjectFile::ReadContext &Ctx,
                         WasmSectionOrderChecker &Checker) {
  Section.Offset = Ctx.Ptr - Ctx.Start;
  Section.Type = readUint8(Ctx);
  LLVM_DEBUG(dbgs() << "readSection type=" << Section.Type << "\n");
  uint32_t Size = readVaruint32(Ctx);
  if (Size == 0)
    return make_error<StringError>("zero length section",
                                   object_error::parse_failed);
  if (Ctx.Ptr + Size > Ctx.End)
    return make_error<StringError>("section too large",
                                   object_error::parse_failed);
  if (Section.Type == wasm::WASM_SEC_CUSTOM) {
    WasmObjectFile::ReadContext SectionCtx;
    SectionCtx.Start = Ctx.Ptr;
    SectionCtx.Ptr = Ctx.Ptr;
    SectionCtx.End = Ctx.Ptr + Size;

    Section.Name = readString(SectionCtx);

    uint32_t SectionNameSize = SectionCtx.Ptr - SectionCtx.Start;
    Ctx.Ptr += SectionNameSize;
    Size -= SectionNameSize;
  }

  if (!Checker.isValidSectionOrder(Section.Type, Section.Name)) {
    return make_error<StringError>("out of order section type: " +
                                       llvm::to_string(Section.Type),
                                   object_error::parse_failed);
  }

  Section.Content = ArrayRef<uint8_t>(Ctx.Ptr, Size);
  Ctx.Ptr += Size;
  return Error::success();
}

WasmObjectFile::WasmObjectFile(MemoryBufferRef Buffer, Error &Err)
    : ObjectFile(Binary::ID_Wasm, Buffer) {
  ErrorAsOutParameter ErrAsOutParam(&Err);
  Header.Magic = getData().substr(0, 4);
  if (Header.Magic != StringRef("\0asm", 4)) {
    Err = make_error<StringError>("invalid magic number",
                                  object_error::parse_failed);
    return;
  }

  ReadContext Ctx;
  Ctx.Start = getData().bytes_begin();
  Ctx.Ptr = Ctx.Start + 4;
  Ctx.End = Ctx.Start + getData().size();

  if (Ctx.Ptr + 4 > Ctx.End) {
    Err = make_error<StringError>("missing version number",
                                  object_error::parse_failed);
    return;
  }

  Header.Version = readUint32(Ctx);
  if (Header.Version != wasm::WasmVersion) {
    Err = make_error<StringError>("invalid version number: " +
                                      Twine(Header.Version),
                                  object_error::parse_failed);
    return;
  }

  WasmSection Sec;
  WasmSectionOrderChecker Checker;
  while (Ctx.Ptr < Ctx.End) {
    if ((Err = readSection(Sec, Ctx, Checker)))
      return;
    if ((Err = parseSection(Sec)))
      return;

    Sections.push_back(Sec);
  }
}

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

Error WasmObjectFile::parseDylinkSection(ReadContext &Ctx) {
  // See https://github.com/WebAssembly/tool-conventions/blob/master/DynamicLinking.md
  HasDylinkSection = true;
  DylinkInfo.MemorySize = readVaruint32(Ctx);
  DylinkInfo.MemoryAlignment = readVaruint32(Ctx);
  DylinkInfo.TableSize = readVaruint32(Ctx);
  DylinkInfo.TableAlignment = readVaruint32(Ctx);
  uint32_t Count = readVaruint32(Ctx);
  while (Count--) {
    DylinkInfo.Needed.push_back(readString(Ctx));
  }
  if (Ctx.Ptr != Ctx.End)
    return make_error<GenericBinaryError>("dylink section ended prematurely",
                                          object_error::parse_failed);
  return Error::success();
}

Error WasmObjectFile::parseNameSection(ReadContext &Ctx) {
  llvm::DenseSet<uint64_t> SeenFunctions;
  llvm::DenseSet<uint64_t> SeenGlobals;
  llvm::DenseSet<uint64_t> SeenSegments;
  if (FunctionTypes.size() && !SeenCodeSection) {
    return make_error<GenericBinaryError>("names must come after code section",
                                          object_error::parse_failed);
  }

  while (Ctx.Ptr < Ctx.End) {
    uint8_t Type = readUint8(Ctx);
    uint32_t Size = readVaruint32(Ctx);
    const uint8_t *SubSectionEnd = Ctx.Ptr + Size;
    switch (Type) {
    case wasm::WASM_NAMES_FUNCTION:
    case wasm::WASM_NAMES_GLOBAL:
    case wasm::WASM_NAMES_DATA_SEGMENT: {
      uint32_t Count = readVaruint32(Ctx);
      while (Count--) {
        uint32_t Index = readVaruint32(Ctx);
        StringRef Name = readString(Ctx);
        wasm::NameType nameType = wasm::NameType::FUNCTION;
        if (Type == wasm::WASM_NAMES_FUNCTION) {
          if (!SeenFunctions.insert(Index).second)
            return make_error<GenericBinaryError>(
                "function named more than once", object_error::parse_failed);
          if (!isValidFunctionIndex(Index) || Name.empty())
            return make_error<GenericBinaryError>("invalid name entry",
                                                  object_error::parse_failed);

          if (isDefinedFunctionIndex(Index))
            getDefinedFunction(Index).DebugName = Name;
        } else if (Type == wasm::WASM_NAMES_GLOBAL) {
          nameType = wasm::NameType::GLOBAL;
          if (!SeenGlobals.insert(Index).second)
            return make_error<GenericBinaryError>("global named more than once",
                                                  object_error::parse_failed);
          if (!isValidGlobalIndex(Index) || Name.empty())
            return make_error<GenericBinaryError>("invalid name entry",
                                                  object_error::parse_failed);
        } else {
          nameType = wasm::NameType::DATA_SEGMENT;
          if (!SeenSegments.insert(Index).second)
            return make_error<GenericBinaryError>(
                "segment named more than once", object_error::parse_failed);
          if (Index > DataSegments.size())
            return make_error<GenericBinaryError>("invalid named data segment",
                                                  object_error::parse_failed);
        }
        DebugNames.push_back(wasm::WasmDebugName{nameType, Index, Name});
      }
      break;
    }
    // Ignore local names for now
    case wasm::WASM_NAMES_LOCAL:
    default:
      Ctx.Ptr += Size;
      break;
    }
    if (Ctx.Ptr != SubSectionEnd)
      return make_error<GenericBinaryError>(
          "name sub-section ended prematurely", object_error::parse_failed);
  }

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

Error WasmObjectFile::parseLinkingSection(ReadContext &Ctx) {
  HasLinkingSection = true;
  if (FunctionTypes.size() && !SeenCodeSection) {
    return make_error<GenericBinaryError>(
        "linking data must come after code section",
        object_error::parse_failed);
  }

  LinkingData.Version = readVaruint32(Ctx);
  if (LinkingData.Version != wasm::WasmMetadataVersion) {
    return make_error<GenericBinaryError>(
        "unexpected metadata version: " + Twine(LinkingData.Version) +
            " (Expected: " + Twine(wasm::WasmMetadataVersion) + ")",
        object_error::parse_failed);
  }

  const uint8_t *OrigEnd = Ctx.End;
  while (Ctx.Ptr < OrigEnd) {
    Ctx.End = OrigEnd;
    uint8_t Type = readUint8(Ctx);
    uint32_t Size = readVaruint32(Ctx);
    LLVM_DEBUG(dbgs() << "readSubsection type=" << int(Type) << " size=" << Size
                      << "\n");
    Ctx.End = Ctx.Ptr + Size;
    switch (Type) {
    case wasm::WASM_SYMBOL_TABLE:
      if (Error Err = parseLinkingSectionSymtab(Ctx))
        return Err;
      break;
    case wasm::WASM_SEGMENT_INFO: {
      uint32_t Count = readVaruint32(Ctx);
      if (Count > DataSegments.size())
        return make_error<GenericBinaryError>("too many segment names",
                                              object_error::parse_failed);
      for (uint32_t I = 0; I < Count; I++) {
        DataSegments[I].Data.Name = readString(Ctx);
        DataSegments[I].Data.Alignment = readVaruint32(Ctx);
        DataSegments[I].Data.LinkingFlags = readVaruint32(Ctx);
      }
      break;
    }
    case wasm::WASM_INIT_FUNCS: {
      uint32_t Count = readVaruint32(Ctx);
      LinkingData.InitFunctions.reserve(Count);
      for (uint32_t I = 0; I < Count; I++) {
        wasm::WasmInitFunc Init;
        Init.Priority = readVaruint32(Ctx);
        Init.Symbol = readVaruint32(Ctx);
        if (!isValidFunctionSymbol(Init.Symbol))
          return make_error<GenericBinaryError>("invalid function symbol: " +
                                                    Twine(Init.Symbol),
                                                object_error::parse_failed);
        LinkingData.InitFunctions.emplace_back(Init);
      }
      break;
    }
    case wasm::WASM_COMDAT_INFO:
      if (Error Err = parseLinkingSectionComdat(Ctx))
        return Err;
      break;
    default:
      Ctx.Ptr += Size;
      break;
    }
    if (Ctx.Ptr != Ctx.End)
      return make_error<GenericBinaryError>(
          "linking sub-section ended prematurely", object_error::parse_failed);
  }
  if (Ctx.Ptr != OrigEnd)
    return make_error<GenericBinaryError>("linking section ended prematurely",
                                          object_error::parse_failed);
  return Error::success();
}

Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) {
  uint32_t Count = readVaruint32(Ctx);
  LinkingData.SymbolTable.reserve(Count);
  Symbols.reserve(Count);
  StringSet<> SymbolNames;

  std::vector<wasm::WasmImport *> ImportedGlobals;
  std::vector<wasm::WasmImport *> ImportedFunctions;
  std::vector<wasm::WasmImport *> ImportedTags;
  std::vector<wasm::WasmImport *> ImportedTables;
  ImportedGlobals.reserve(Imports.size());
  ImportedFunctions.reserve(Imports.size());
  ImportedTags.reserve(Imports.size());
  ImportedTables.reserve(Imports.size());
  for (auto &I : Imports) {
    if (I.Kind == wasm::WASM_EXTERNAL_FUNCTION)
      ImportedFunctions.emplace_back(&I);
    else if (I.Kind == wasm::WASM_EXTERNAL_GLOBAL)
      ImportedGlobals.emplace_back(&I);
    else if (I.Kind == wasm::WASM_EXTERNAL_TAG)
      ImportedTags.emplace_back(&I);
    else if (I.Kind == wasm::WASM_EXTERNAL_TABLE)
      ImportedTables.emplace_back(&I);
  }

  while (Count--) {
    wasm::WasmSymbolInfo Info;
    const wasm::WasmSignature *Signature = nullptr;
    const wasm::WasmGlobalType *GlobalType = nullptr;
    const wasm::WasmTableType *TableType = nullptr;
    const wasm::WasmTagType *TagType = nullptr;

    Info.Kind = readUint8(Ctx);
    Info.Flags = readVaruint32(Ctx);
    bool IsDefined = (Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0;

    switch (Info.Kind) {
    case wasm::WASM_SYMBOL_TYPE_FUNCTION:
      Info.ElementIndex = readVaruint32(Ctx);
      if (!isValidFunctionIndex(Info.ElementIndex) ||
          IsDefined != isDefinedFunctionIndex(Info.ElementIndex))
        return make_error<GenericBinaryError>("invalid function symbol index",
                                              object_error::parse_failed);
      if (IsDefined) {
        Info.Name = readString(Ctx);
        unsigned FuncIndex = Info.ElementIndex - NumImportedFunctions;
        Signature = &Signatures[FunctionTypes[FuncIndex]];
        wasm::WasmFunction &Function = Functions[FuncIndex];
        if (Function.SymbolName.empty())
          Function.SymbolName = Info.Name;
      } else {
        wasm::WasmImport &Import = *ImportedFunctions[Info.ElementIndex];
        if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0) {
          Info.Name = readString(Ctx);
          Info.ImportName = Import.Field;
        } else {
          Info.Name = Import.Field;
        }
        Signature = &Signatures[Import.SigIndex];
        if (!Import.Module.empty()) {
          Info.ImportModule = Import.Module;
        }
      }
      break;

    case wasm::WASM_SYMBOL_TYPE_GLOBAL:
      Info.ElementIndex = readVaruint32(Ctx);
      if (!isValidGlobalIndex(Info.ElementIndex) ||
          IsDefined != isDefinedGlobalIndex(Info.ElementIndex))
        return make_error<GenericBinaryError>("invalid global symbol index",
                                              object_error::parse_failed);
      if (!IsDefined && (Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) ==
                            wasm::WASM_SYMBOL_BINDING_WEAK)
        return make_error<GenericBinaryError>("undefined weak global symbol",
                                              object_error::parse_failed);
      if (IsDefined) {
        Info.Name = readString(Ctx);
        unsigned GlobalIndex = Info.ElementIndex - NumImportedGlobals;
        wasm::WasmGlobal &Global = Globals[GlobalIndex];
        GlobalType = &Global.Type;
        if (Global.SymbolName.empty())
          Global.SymbolName = Info.Name;
      } else {
        wasm::WasmImport &Import = *ImportedGlobals[Info.ElementIndex];
        if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0) {
          Info.Name = readString(Ctx);
          Info.ImportName = Import.Field;
        } else {
          Info.Name = Import.Field;
        }
        GlobalType = &Import.Global;
        if (!Import.Module.empty()) {
          Info.ImportModule = Import.Module;
        }
      }
      break;

    case wasm::WASM_SYMBOL_TYPE_TABLE:
      Info.ElementIndex = readVaruint32(Ctx);
      if (!isValidTableNumber(Info.ElementIndex) ||
          IsDefined != isDefinedTableNumber(Info.ElementIndex))
        return make_error<GenericBinaryError>("invalid table symbol index",
                                              object_error::parse_failed);
      if (!IsDefined && (Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) ==
                            wasm::WASM_SYMBOL_BINDING_WEAK)
        return make_error<GenericBinaryError>("undefined weak table symbol",
                                              object_error::parse_failed);
      if (IsDefined) {
        Info.Name = readString(Ctx);
        unsigned TableNumber = Info.ElementIndex - NumImportedTables;
        wasm::WasmTable &Table = Tables[TableNumber];
        TableType = &Table.Type;
        if (Table.SymbolName.empty())
          Table.SymbolName = Info.Name;
      } else {
        wasm::WasmImport &Import = *ImportedTables[Info.ElementIndex];
        if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0) {
          Info.Name = readString(Ctx);
          Info.ImportName = Import.Field;
        } else {
          Info.Name = Import.Field;
        }
        TableType = &Import.Table;
        if (!Import.Module.empty()) {
          Info.ImportModule = Import.Module;
        }
      }
      break;

    case wasm::WASM_SYMBOL_TYPE_DATA:
      Info.Name = readString(Ctx);
      if (IsDefined) {
        auto Index = readVaruint32(Ctx);
        if (Index >= DataSegments.size())
          return make_error<GenericBinaryError>("invalid data symbol index",
                                                object_error::parse_failed);
        auto Offset = readVaruint64(Ctx);
        auto Size = readVaruint64(Ctx);
        size_t SegmentSize = DataSegments[Index].Data.Content.size();
        if (Offset > SegmentSize)
          return make_error<GenericBinaryError>(
              "invalid data symbol offset: `" + Info.Name + "` (offset: " +
                  Twine(Offset) + " segment size: " + Twine(SegmentSize) + ")",
              object_error::parse_failed);
        Info.DataRef = wasm::WasmDataReference{Index, Offset, Size};
      }
      break;

    case wasm::WASM_SYMBOL_TYPE_SECTION: {
      if ((Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) !=
          wasm::WASM_SYMBOL_BINDING_LOCAL)
        return make_error<GenericBinaryError>(
            "section symbols must have local binding",
            object_error::parse_failed);
      Info.ElementIndex = readVaruint32(Ctx);
      // Use somewhat unique section name as symbol name.
      StringRef SectionName = Sections[Info.ElementIndex].Name;
      Info.Name = SectionName;
      break;
    }

    case wasm::WASM_SYMBOL_TYPE_TAG: {
      Info.ElementIndex = readVaruint32(Ctx);
      if (!isValidTagIndex(Info.ElementIndex) ||
          IsDefined != isDefinedTagIndex(Info.ElementIndex))
        return make_error<GenericBinaryError>("invalid tag symbol index",
                                              object_error::parse_failed);
      if (!IsDefined && (Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) ==
                            wasm::WASM_SYMBOL_BINDING_WEAK)
        return make_error<GenericBinaryError>("undefined weak global symbol",
                                              object_error::parse_failed);
      if (IsDefined) {
        Info.Name = readString(Ctx);
        unsigned TagIndex = Info.ElementIndex - NumImportedTags;
        wasm::WasmTag &Tag = Tags[TagIndex];
        Signature = &Signatures[Tag.Type.SigIndex];
        TagType = &Tag.Type;
        if (Tag.SymbolName.empty())
          Tag.SymbolName = Info.Name;

      } else {
        wasm::WasmImport &Import = *ImportedTags[Info.ElementIndex];
        if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0) {
          Info.Name = readString(Ctx);
          Info.ImportName = Import.Field;
        } else {
          Info.Name = Import.Field;
        }
        TagType = &Import.Tag;
        Signature = &Signatures[TagType->SigIndex];
        if (!Import.Module.empty()) {
          Info.ImportModule = Import.Module;
        }
      }
      break;
    }

    default:
      return make_error<GenericBinaryError>("invalid symbol type: " +
                                                Twine(unsigned(Info.Kind)),
                                            object_error::parse_failed);
    }

    if ((Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) !=
            wasm::WASM_SYMBOL_BINDING_LOCAL &&
        !SymbolNames.insert(Info.Name).second)
      return make_error<GenericBinaryError>("duplicate symbol name " +
                                                Twine(Info.Name),
                                            object_error::parse_failed);
    LinkingData.SymbolTable.emplace_back(Info);
    Symbols.emplace_back(LinkingData.SymbolTable.back(), GlobalType, TableType,
                         TagType, Signature);
    LLVM_DEBUG(dbgs() << "Adding symbol: " << Symbols.back() << "\n");
  }

  return Error::success();
}

Error WasmObjectFile::parseLinkingSectionComdat(ReadContext &Ctx) {
  uint32_t ComdatCount = readVaruint32(Ctx);
  StringSet<> ComdatSet;
  for (unsigned ComdatIndex = 0; ComdatIndex < ComdatCount; ++ComdatIndex) {
    StringRef Name = readString(Ctx);
    if (Name.empty() || !ComdatSet.insert(Name).second)
      return make_error<GenericBinaryError>("bad/duplicate COMDAT name " +
                                                Twine(Name),
                                            object_error::parse_failed);
    LinkingData.Comdats.emplace_back(Name);
    uint32_t Flags = readVaruint32(Ctx);
    if (Flags != 0)
      return make_error<GenericBinaryError>("unsupported COMDAT flags",
                                            object_error::parse_failed);

    uint32_t EntryCount = readVaruint32(Ctx);
    while (EntryCount--) {
      unsigned Kind = readVaruint32(Ctx);
      unsigned Index = readVaruint32(Ctx);
      switch (Kind) {
      default:
        return make_error<GenericBinaryError>("invalid COMDAT entry type",
                                              object_error::parse_failed);
      case wasm::WASM_COMDAT_DATA:
        if (Index >= DataSegments.size())
          return make_error<GenericBinaryError>(
              "COMDAT data index out of range", object_error::parse_failed);
        if (DataSegments[Index].Data.Comdat != UINT32_MAX)
          return make_error<GenericBinaryError>("data segment in two COMDATs",
                                                object_error::parse_failed);
        DataSegments[Index].Data.Comdat = ComdatIndex;
        break;
      case wasm::WASM_COMDAT_FUNCTION:
        if (!isDefinedFunctionIndex(Index))
          return make_error<GenericBinaryError>(
              "COMDAT function index out of range", object_error::parse_failed);
        if (getDefinedFunction(Index).Comdat != UINT32_MAX)
          return make_error<GenericBinaryError>("function in two COMDATs",
                                                object_error::parse_failed);
        getDefinedFunction(Index).Comdat = ComdatIndex;
        break;
      case wasm::WASM_COMDAT_SECTION:
        if (Index >= Sections.size())
          return make_error<GenericBinaryError>(
              "COMDAT section index out of range", object_error::parse_failed);
        if (Sections[Index].Type != wasm::WASM_SEC_CUSTOM)
          return make_error<GenericBinaryError>(
              "non-custom section in a COMDAT", object_error::parse_failed);
        Sections[Index].Comdat = ComdatIndex;
        break;
      }
    }
  }
  return Error::success();
}

Error WasmObjectFile::parseProducersSection(ReadContext &Ctx) {
  llvm::SmallSet<StringRef, 3> FieldsSeen;
  uint32_t Fields = readVaruint32(Ctx);
  for (size_t I = 0; I < Fields; ++I) {
    StringRef FieldName = readString(Ctx);
    if (!FieldsSeen.insert(FieldName).second)
      return make_error<GenericBinaryError>(
          "producers section does not have unique fields",
          object_error::parse_failed);
    std::vector<std::pair<std::string, std::string>> *ProducerVec = nullptr;
    if (FieldName == "language") {
      ProducerVec = &ProducerInfo.Languages;
    } else if (FieldName == "processed-by") {
      ProducerVec = &ProducerInfo.Tools;
    } else if (FieldName == "sdk") {
      ProducerVec = &ProducerInfo.SDKs;
    } else {
      return make_error<GenericBinaryError>(
          "producers section field is not named one of language, processed-by, "
          "or sdk",
          object_error::parse_failed);
    }
    uint32_t ValueCount = readVaruint32(Ctx);
    llvm::SmallSet<StringRef, 8> ProducersSeen;
    for (size_t J = 0; J < ValueCount; ++J) {
      StringRef Name = readString(Ctx);
      StringRef Version = readString(Ctx);
      if (!ProducersSeen.insert(Name).second) {
        return make_error<GenericBinaryError>(
            "producers section contains repeated producer",
            object_error::parse_failed);
      }
      ProducerVec->emplace_back(std::string(Name), std::string(Version));
    }
  }
  if (Ctx.Ptr != Ctx.End)
    return make_error<GenericBinaryError>("producers section ended prematurely",
                                          object_error::parse_failed);
  return Error::success();
}

Error WasmObjectFile::parseTargetFeaturesSection(ReadContext &Ctx) {
  llvm::SmallSet<std::string, 8> FeaturesSeen;
  uint32_t FeatureCount = readVaruint32(Ctx);
  for (size_t I = 0; I < FeatureCount; ++I) {
    wasm::WasmFeatureEntry Feature;
    Feature.Prefix = readUint8(Ctx);
    switch (Feature.Prefix) {
    case wasm::WASM_FEATURE_PREFIX_USED:
    case wasm::WASM_FEATURE_PREFIX_REQUIRED:
    case wasm::WASM_FEATURE_PREFIX_DISALLOWED:
      break;
    default:
      return make_error<GenericBinaryError>("unknown feature policy prefix",
                                            object_error::parse_failed);
    }
    Feature.Name = std::string(readString(Ctx));
    if (!FeaturesSeen.insert(Feature.Name).second)
      return make_error<GenericBinaryError>(
          "target features section contains repeated feature \"" +
              Feature.Name + "\"",
          object_error::parse_failed);
    TargetFeatures.push_back(Feature);
  }
  if (Ctx.Ptr != Ctx.End)
    return make_error<GenericBinaryError>(
        "target features section ended prematurely",
        object_error::parse_failed);
  return Error::success();
}

Error WasmObjectFile::parseRelocSection(StringRef Name, ReadContext &Ctx) {
  uint32_t SectionIndex = readVaruint32(Ctx);
  if (SectionIndex >= Sections.size())
    return make_error<GenericBinaryError>("invalid section index",
                                          object_error::parse_failed);
  WasmSection &Section = Sections[SectionIndex];
  uint32_t RelocCount = readVaruint32(Ctx);
  uint32_t EndOffset = Section.Content.size();
  uint32_t PreviousOffset = 0;
  while (RelocCount--) {
    wasm::WasmRelocation Reloc = {};
    uint32_t type = readVaruint32(Ctx);
    Reloc.Type = type;
    Reloc.Offset = readVaruint32(Ctx);
    if (Reloc.Offset < PreviousOffset)
      return make_error<GenericBinaryError>("relocations not in offset order",
                                            object_error::parse_failed);
    PreviousOffset = Reloc.Offset;
    Reloc.Index = readVaruint32(Ctx);
    switch (type) {
    case wasm::R_WASM_FUNCTION_INDEX_LEB:
    case wasm::R_WASM_TABLE_INDEX_SLEB:
    case wasm::R_WASM_TABLE_INDEX_SLEB64:
    case wasm::R_WASM_TABLE_INDEX_I32:
    case wasm::R_WASM_TABLE_INDEX_I64:
    case wasm::R_WASM_TABLE_INDEX_REL_SLEB:
    case wasm::R_WASM_TABLE_INDEX_REL_SLEB64:
      if (!isValidFunctionSymbol(Reloc.Index))
        return make_error<GenericBinaryError>(
            "invalid relocation function index", object_error::parse_failed);
      break;
    case wasm::R_WASM_TABLE_NUMBER_LEB:
      if (!isValidTableSymbol(Reloc.Index))
        return make_error<GenericBinaryError>("invalid relocation table index",
                                              object_error::parse_failed);
      break;
    case wasm::R_WASM_TYPE_INDEX_LEB:
      if (Reloc.Index >= Signatures.size())
        return make_error<GenericBinaryError>("invalid relocation type index",
                                              object_error::parse_failed);
      break;
    case wasm::R_WASM_GLOBAL_INDEX_LEB:
      // R_WASM_GLOBAL_INDEX_LEB are can be used against function and data
      // symbols to refer to their GOT entries.
      if (!isValidGlobalSymbol(Reloc.Index) &&
          !isValidDataSymbol(Reloc.Index) &&
          !isValidFunctionSymbol(Reloc.Index))
        return make_error<GenericBinaryError>("invalid relocation global index",
                                              object_error::parse_failed);
      break;
    case wasm::R_WASM_GLOBAL_INDEX_I32:
      if (!isValidGlobalSymbol(Reloc.Index))
        return make_error<GenericBinaryError>("invalid relocation global index",
                                              object_error::parse_failed);
      break;
    case wasm::R_WASM_TAG_INDEX_LEB:
      if (!isValidTagSymbol(Reloc.Index))
        return make_error<GenericBinaryError>("invalid relocation tag index",
                                              object_error::parse_failed);
      break;
    case wasm::R_WASM_MEMORY_ADDR_LEB:
    case wasm::R_WASM_MEMORY_ADDR_SLEB:
    case wasm::R_WASM_MEMORY_ADDR_I32:
    case wasm::R_WASM_MEMORY_ADDR_REL_SLEB:
    case wasm::R_WASM_MEMORY_ADDR_TLS_SLEB:
    case wasm::R_WASM_MEMORY_ADDR_LOCREL_I32:
      if (!isValidDataSymbol(Reloc.Index))
        return make_error<GenericBinaryError>("invalid relocation data index",
                                              object_error::parse_failed);
      Reloc.Addend = readVarint32(Ctx);
      break;
    case wasm::R_WASM_MEMORY_ADDR_LEB64:
    case wasm::R_WASM_MEMORY_ADDR_SLEB64:
    case wasm::R_WASM_MEMORY_ADDR_I64:
    case wasm::R_WASM_MEMORY_ADDR_REL_SLEB64:
    case wasm::R_WASM_MEMORY_ADDR_TLS_SLEB64:
      if (!isValidDataSymbol(Reloc.Index))
        return make_error<GenericBinaryError>("invalid relocation data index",
                                              object_error::parse_failed);
      Reloc.Addend = readVarint64(Ctx);
      break;
    case wasm::R_WASM_FUNCTION_OFFSET_I32:
      if (!isValidFunctionSymbol(Reloc.Index))
        return make_error<GenericBinaryError>(
            "invalid relocation function index", object_error::parse_failed);
      Reloc.Addend = readVarint32(Ctx);
      break;
    case wasm::R_WASM_FUNCTION_OFFSET_I64:
      if (!isValidFunctionSymbol(Reloc.Index))
        return make_error<GenericBinaryError>(
            "invalid relocation function index", object_error::parse_failed);
      Reloc.Addend = readVarint64(Ctx);
      break;
    case wasm::R_WASM_SECTION_OFFSET_I32:
      if (!isValidSectionSymbol(Reloc.Index))
        return make_error<GenericBinaryError>(
            "invalid relocation section index", object_error::parse_failed);
      Reloc.Addend = readVarint32(Ctx);
      break;
    default:
      return make_error<GenericBinaryError>("invalid relocation type: " +
                                                Twine(type),
                                            object_error::parse_failed);
    }

    // Relocations must fit inside the section, and must appear in order.  They
    // also shouldn't overlap a function/element boundary, but we don't bother
    // to check that.
    uint64_t Size = 5;
    if (Reloc.Type == wasm::R_WASM_MEMORY_ADDR_LEB64 ||
        Reloc.Type == wasm::R_WASM_MEMORY_ADDR_SLEB64 ||
        Reloc.Type == wasm::R_WASM_MEMORY_ADDR_REL_SLEB64)
      Size = 10;
    if (Reloc.Type == wasm::R_WASM_TABLE_INDEX_I32 ||
        Reloc.Type == wasm::R_WASM_MEMORY_ADDR_I32 ||
        Reloc.Type == wasm::R_WASM_MEMORY_ADDR_LOCREL_I32 ||
        Reloc.Type == wasm::R_WASM_SECTION_OFFSET_I32 ||
        Reloc.Type == wasm::R_WASM_FUNCTION_OFFSET_I32 ||
        Reloc.Type == wasm::R_WASM_GLOBAL_INDEX_I32)
      Size = 4;
    if (Reloc.Type == wasm::R_WASM_TABLE_INDEX_I64 ||
        Reloc.Type == wasm::R_WASM_MEMORY_ADDR_I64 ||
        Reloc.Type == wasm::R_WASM_FUNCTION_OFFSET_I64)
      Size = 8;
    if (Reloc.Offset + Size > EndOffset)
      return make_error<GenericBinaryError>("invalid relocation offset",
                                            object_error::parse_failed);

    Section.Relocations.push_back(Reloc);
  }
  if (Ctx.Ptr != Ctx.End)
    return make_error<GenericBinaryError>("reloc section ended prematurely",
                                          object_error::parse_failed);
  return Error::success();
}

Error WasmObjectFile::parseCustomSection(WasmSection &Sec, ReadContext &Ctx) {
  if (Sec.Name == "dylink") {
    if (Error Err = parseDylinkSection(Ctx))
      return Err;
  } else if (Sec.Name == "name") {
    if (Error Err = parseNameSection(Ctx))
      return Err;
  } else if (Sec.Name == "linking") {
    if (Error Err = parseLinkingSection(Ctx))
      return Err;
  } else if (Sec.Name == "producers") {
    if (Error Err = parseProducersSection(Ctx))
      return Err;
  } else if (Sec.Name == "target_features") {
    if (Error Err = parseTargetFeaturesSection(Ctx))
      return Err;
  } else if (Sec.Name.startswith("reloc.")) {
    if (Error Err = parseRelocSection(Sec.Name, Ctx))
      return Err;
  }
  return Error::success();
}

Error WasmObjectFile::parseTypeSection(ReadContext &Ctx) {
  uint32_t Count = readVaruint32(Ctx);
  Signatures.reserve(Count);
  while (Count--) {
    wasm::WasmSignature Sig;
    uint8_t Form = readUint8(Ctx);
    if (Form != wasm::WASM_TYPE_FUNC) {
      return make_error<GenericBinaryError>("invalid signature type",
                                            object_error::parse_failed);
    }
    uint32_t ParamCount = readVaruint32(Ctx);
    Sig.Params.reserve(ParamCount);
    while (ParamCount--) {
      uint32_t ParamType = readUint8(Ctx);
      Sig.Params.push_back(wasm::ValType(ParamType));
    }
    uint32_t ReturnCount = readVaruint32(Ctx);
    while (ReturnCount--) {
      uint32_t ReturnType = readUint8(Ctx);
      Sig.Returns.push_back(wasm::ValType(ReturnType));
    }
    Signatures.push_back(std::move(Sig));
  }
  if (Ctx.Ptr != Ctx.End)
    return make_error<GenericBinaryError>("type section ended prematurely",
                                          object_error::parse_failed);
  return Error::success();
}

Error WasmObjectFile::parseImportSection(ReadContext &Ctx) {
  uint32_t Count = readVaruint32(Ctx);
  Imports.reserve(Count);
  for (uint32_t I = 0; I < Count; I++) {
    wasm::WasmImport Im;
    Im.Module = readString(Ctx);
    Im.Field = readString(Ctx);
    Im.Kind = readUint8(Ctx);
    switch (Im.Kind) {
    case wasm::WASM_EXTERNAL_FUNCTION:
      NumImportedFunctions++;
      Im.SigIndex = readVaruint32(Ctx);
      break;
    case wasm::WASM_EXTERNAL_GLOBAL:
      NumImportedGlobals++;
      Im.Global.Type = readUint8(Ctx);
      Im.Global.Mutable = readVaruint1(Ctx);
      break;
    case wasm::WASM_EXTERNAL_MEMORY:
      Im.Memory = readLimits(Ctx);
      if (Im.Memory.Flags & wasm::WASM_LIMITS_FLAG_IS_64)
        HasMemory64 = true;
      break;
    case wasm::WASM_EXTERNAL_TABLE: {
      Im.Table = readTableType(Ctx);
      NumImportedTables++;
      auto ElemType = Im.Table.ElemType;
      if (ElemType != wasm::WASM_TYPE_FUNCREF &&
          ElemType != wasm::WASM_TYPE_EXTERNREF)
        return make_error<GenericBinaryError>("invalid table element type",
                                              object_error::parse_failed);
      break;
    }
    case wasm::WASM_EXTERNAL_TAG:
      NumImportedTags++;
      Im.Tag.Attribute = readUint8(Ctx);
      Im.Tag.SigIndex = readVarint32(Ctx);
      break;
    default:
      return make_error<GenericBinaryError>("unexpected import kind",
                                            object_error::parse_failed);
    }
    Imports.push_back(Im);
  }
  if (Ctx.Ptr != Ctx.End)
    return make_error<GenericBinaryError>("import section ended prematurely",
                                          object_error::parse_failed);
  return Error::success();
}

Error WasmObjectFile::parseFunctionSection(ReadContext &Ctx) {
  uint32_t Count = readVaruint32(Ctx);
  FunctionTypes.reserve(Count);
  Functions.resize(Count);
  uint32_t NumTypes = Signatures.size();
  while (Count--) {
    uint32_t Type = readVaruint32(Ctx);
    if (Type >= NumTypes)
      return make_error<GenericBinaryError>("invalid function type",
                                            object_error::parse_failed);
    FunctionTypes.push_back(Type);
  }
  if (Ctx.Ptr != Ctx.End)
    return make_error<GenericBinaryError>("function section ended prematurely",
                                          object_error::parse_failed);
  return Error::success();
}

Error WasmObjectFile::parseTableSection(ReadContext &Ctx) {
  TableSection = Sections.size();
  uint32_t Count = readVaruint32(Ctx);
  Tables.reserve(Count);
  while (Count--) {
    wasm::WasmTable T;
    T.Type = readTableType(Ctx);
    T.Index = NumImportedTables + Tables.size();
    Tables.push_back(T);
    auto ElemType = Tables.back().Type.ElemType;
    if (ElemType != wasm::WASM_TYPE_FUNCREF &&
        ElemType != wasm::WASM_TYPE_EXTERNREF) {
      return make_error<GenericBinaryError>("invalid table element type",
                                            object_error::parse_failed);
    }
  }
  if (Ctx.Ptr != Ctx.End)
    return make_error<GenericBinaryError>("table section ended prematurely",
                                          object_error::parse_failed);
  return Error::success();
}

Error WasmObjectFile::parseMemorySection(ReadContext &Ctx) {
  uint32_t Count = readVaruint32(Ctx);
  Memories.reserve(Count);
  while (Count--) {
    auto Limits = readLimits(Ctx);
    if (Limits.Flags & wasm::WASM_LIMITS_FLAG_IS_64)
      HasMemory64 = true;
    Memories.push_back(Limits);
  }
  if (Ctx.Ptr != Ctx.End)
    return make_error<GenericBinaryError>("memory section ended prematurely",
                                          object_error::parse_failed);
  return Error::success();
}

Error WasmObjectFile::parseTagSection(ReadContext &Ctx) {
  TagSection = Sections.size();
  uint32_t Count = readVaruint32(Ctx);
  Tags.reserve(Count);
  while (Count--) {
    wasm::WasmTag Tag;
    Tag.Index = NumImportedTags + Tags.size();
    Tag.Type.Attribute = readUint8(Ctx);
    Tag.Type.SigIndex = readVaruint32(Ctx);
    Tags.push_back(Tag);
  }

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

Error WasmObjectFile::parseGlobalSection(ReadContext &Ctx) {
  GlobalSection = Sections.size();
  uint32_t Count = readVaruint32(Ctx);
  Globals.reserve(Count);
  while (Count--) {
    wasm::WasmGlobal Global;
    Global.Index = NumImportedGlobals + Globals.size();
    Global.Type.Type = readUint8(Ctx);
    Global.Type.Mutable = readVaruint1(Ctx);
    if (Error Err = readInitExpr(Global.InitExpr, Ctx))
      return Err;
    Globals.push_back(Global);
  }
  if (Ctx.Ptr != Ctx.End)
    return make_error<GenericBinaryError>("global section ended prematurely",
                                          object_error::parse_failed);
  return Error::success();
}

Error WasmObjectFile::parseExportSection(ReadContext &Ctx) {
  uint32_t Count = readVaruint32(Ctx);
  Exports.reserve(Count);
  for (uint32_t I = 0; I < Count; I++) {
    wasm::WasmExport Ex;
    Ex.Name = readString(Ctx);
    Ex.Kind = readUint8(Ctx);
    Ex.Index = readVaruint32(Ctx);
    switch (Ex.Kind) {
    case wasm::WASM_EXTERNAL_FUNCTION:

      if (!isDefinedFunctionIndex(Ex.Index))
        return make_error<GenericBinaryError>("invalid function export",
                                              object_error::parse_failed);
      getDefinedFunction(Ex.Index).ExportName = Ex.Name;
      break;
    case wasm::WASM_EXTERNAL_GLOBAL:
      if (!isValidGlobalIndex(Ex.Index))
        return make_error<GenericBinaryError>("invalid global export",
                                              object_error::parse_failed);
      break;
    case wasm::WASM_EXTERNAL_TAG:
      if (!isValidTagIndex(Ex.Index))
        return make_error<GenericBinaryError>("invalid tag export",
                                              object_error::parse_failed);
      break;
    case wasm::WASM_EXTERNAL_MEMORY:
    case wasm::WASM_EXTERNAL_TABLE:
      break;
    default:
      return make_error<GenericBinaryError>("unexpected export kind",
                                            object_error::parse_failed);
    }
    Exports.push_back(Ex);
  }
  if (Ctx.Ptr != Ctx.End)
    return make_error<GenericBinaryError>("export section ended prematurely",
                                          object_error::parse_failed);
  return Error::success();
}

bool WasmObjectFile::isValidFunctionIndex(uint32_t Index) const {
  return Index < NumImportedFunctions + FunctionTypes.size();
}

bool WasmObjectFile::isDefinedFunctionIndex(uint32_t Index) const {
  return Index >= NumImportedFunctions && isValidFunctionIndex(Index);
}

bool WasmObjectFile::isValidGlobalIndex(uint32_t Index) const {
  return Index < NumImportedGlobals + Globals.size();
}

bool WasmObjectFile::isValidTableNumber(uint32_t Index) const {
  return Index < NumImportedTables + Tables.size();
}

bool WasmObjectFile::isDefinedGlobalIndex(uint32_t Index) const {
  return Index >= NumImportedGlobals && isValidGlobalIndex(Index);
}

bool WasmObjectFile::isDefinedTableNumber(uint32_t Index) const {
  return Index >= NumImportedTables && isValidTableNumber(Index);
}

bool WasmObjectFile::isValidTagIndex(uint32_t Index) const {
  return Index < NumImportedTags + Tags.size();
}

bool WasmObjectFile::isDefinedTagIndex(uint32_t Index) const {
  return Index >= NumImportedTags && isValidTagIndex(Index);
}

bool WasmObjectFile::isValidFunctionSymbol(uint32_t Index) const {
  return Index < Symbols.size() && Symbols[Index].isTypeFunction();
}

bool WasmObjectFile::isValidTableSymbol(uint32_t Index) const {
  return Index < Symbols.size() && Symbols[Index].isTypeTable();
}

bool WasmObjectFile::isValidGlobalSymbol(uint32_t Index) const {
  return Index < Symbols.size() && Symbols[Index].isTypeGlobal();
}

bool WasmObjectFile::isValidTagSymbol(uint32_t Index) const {
  return Index < Symbols.size() && Symbols[Index].isTypeTag();
}

bool WasmObjectFile::isValidDataSymbol(uint32_t Index) const {
  return Index < Symbols.size() && Symbols[Index].isTypeData();
}

bool WasmObjectFile::isValidSectionSymbol(uint32_t Index) const {
  return Index < Symbols.size() && Symbols[Index].isTypeSection();
}

wasm::WasmFunction &WasmObjectFile::getDefinedFunction(uint32_t Index) {
  assert(isDefinedFunctionIndex(Index));
  return Functions[Index - NumImportedFunctions];
}

const wasm::WasmFunction &
WasmObjectFile::getDefinedFunction(uint32_t Index) const {
  assert(isDefinedFunctionIndex(Index));
  return Functions[Index - NumImportedFunctions];
}

wasm::WasmGlobal &WasmObjectFile::getDefinedGlobal(uint32_t Index) {
  assert(isDefinedGlobalIndex(Index));
  return Globals[Index - NumImportedGlobals];
}

wasm::WasmTag &WasmObjectFile::getDefinedTag(uint32_t Index) {
  assert(isDefinedTagIndex(Index));
  return Tags[Index - NumImportedTags];
}

Error WasmObjectFile::parseStartSection(ReadContext &Ctx) {
  StartFunction = readVaruint32(Ctx);
  if (!isValidFunctionIndex(StartFunction))
    return make_error<GenericBinaryError>("invalid start function",
                                          object_error::parse_failed);
  return Error::success();
}

Error WasmObjectFile::parseCodeSection(ReadContext &Ctx) {
  SeenCodeSection = true;
  CodeSection = Sections.size();
  uint32_t FunctionCount = readVaruint32(Ctx);
  if (FunctionCount != FunctionTypes.size()) {
    return make_error<GenericBinaryError>("invalid function count",
                                          object_error::parse_failed);
  }

  for (uint32_t i = 0; i < FunctionCount; i++) {
    wasm::WasmFunction& Function = Functions[i];
    const uint8_t *FunctionStart = Ctx.Ptr;
    uint32_t Size = readVaruint32(Ctx);
    const uint8_t *FunctionEnd = Ctx.Ptr + Size;

    Function.CodeOffset = Ctx.Ptr - FunctionStart;
    Function.Index = NumImportedFunctions + i;
    Function.CodeSectionOffset = FunctionStart - Ctx.Start;
    Function.Size = FunctionEnd - FunctionStart;

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

    uint32_t BodySize = FunctionEnd - Ctx.Ptr;
    Function.Body = ArrayRef<uint8_t>(Ctx.Ptr, BodySize);
    // This will be set later when reading in the linking metadata section.
    Function.Comdat = UINT32_MAX;
    Ctx.Ptr += BodySize;
    assert(Ctx.Ptr == FunctionEnd);
  }
  if (Ctx.Ptr != Ctx.End)
    return make_error<GenericBinaryError>("code section ended prematurely",
                                          object_error::parse_failed);
  return Error::success();
}

Error WasmObjectFile::parseElemSection(ReadContext &Ctx) {
  uint32_t Count = readVaruint32(Ctx);
  ElemSegments.reserve(Count);
  while (Count--) {
    wasm::WasmElemSegment Segment;
    Segment.Flags = readVaruint32(Ctx);

    uint32_t SupportedFlags = wasm::WASM_ELEM_SEGMENT_HAS_TABLE_NUMBER |
                              wasm::WASM_ELEM_SEGMENT_IS_PASSIVE |
                              wasm::WASM_ELEM_SEGMENT_HAS_INIT_EXPRS;
    if (Segment.Flags & ~SupportedFlags)
      return make_error<GenericBinaryError>(
          "Unsupported flags for element segment", object_error::parse_failed);

    if (Segment.Flags & wasm::WASM_ELEM_SEGMENT_HAS_TABLE_NUMBER)
      Segment.TableNumber = readVaruint32(Ctx);
    else
      Segment.TableNumber = 0;
    if (!isValidTableNumber(Segment.TableNumber))
      return make_error<GenericBinaryError>("invalid TableNumber",
                                            object_error::parse_failed);

    if (Segment.Flags & wasm::WASM_ELEM_SEGMENT_IS_PASSIVE) {
      Segment.Offset.Opcode = wasm::WASM_OPCODE_I32_CONST;
      Segment.Offset.Value.Int32 = 0;
    } else {
      if (Error Err = readInitExpr(Segment.Offset, Ctx))
        return Err;
    }

    if (Segment.Flags & wasm::WASM_ELEM_SEGMENT_MASK_HAS_ELEM_KIND) {
      Segment.ElemKind = readUint8(Ctx);
      if (Segment.Flags & wasm::WASM_ELEM_SEGMENT_HAS_INIT_EXPRS) {
        if (Segment.ElemKind != uint8_t(wasm::ValType::FUNCREF) &&
            Segment.ElemKind != uint8_t(wasm::ValType::EXTERNREF)) {
          return make_error<GenericBinaryError>("invalid reference type",
                                                object_error::parse_failed);
        }
      } else {
        if (Segment.ElemKind != 0)
          return make_error<GenericBinaryError>("invalid elemtype",
                                                object_error::parse_failed);
        Segment.ElemKind = uint8_t(wasm::ValType::FUNCREF);
      }
    } else {
      Segment.ElemKind = uint8_t(wasm::ValType::FUNCREF);
    }

    if (Segment.Flags & wasm::WASM_ELEM_SEGMENT_HAS_INIT_EXPRS)
      return make_error<GenericBinaryError>(
          "elem segment init expressions not yet implemented",
          object_error::parse_failed);

    uint32_t NumElems = readVaruint32(Ctx);
    while (NumElems--) {
      Segment.Functions.push_back(readVaruint32(Ctx));
    }
    ElemSegments.push_back(Segment);
  }
  if (Ctx.Ptr != Ctx.End)
    return make_error<GenericBinaryError>("elem section ended prematurely",
                                          object_error::parse_failed);
  return Error::success();
}

Error WasmObjectFile::parseDataSection(ReadContext &Ctx) {
  DataSection = Sections.size();
  uint32_t Count = readVaruint32(Ctx);
  if (DataCount && Count != DataCount.getValue())
    return make_error<GenericBinaryError>(
        "number of data segments does not match DataCount section");
  DataSegments.reserve(Count);
  while (Count--) {
    WasmSegment Segment;
    Segment.Data.InitFlags = readVaruint32(Ctx);
    Segment.Data.MemoryIndex =
        (Segment.Data.InitFlags & wasm::WASM_DATA_SEGMENT_HAS_MEMINDEX)
            ? readVaruint32(Ctx)
            : 0;
    if ((Segment.Data.InitFlags & wasm::WASM_DATA_SEGMENT_IS_PASSIVE) == 0) {
      if (Error Err = readInitExpr(Segment.Data.Offset, Ctx))
        return Err;
    } else {
      Segment.Data.Offset.Opcode = wasm::WASM_OPCODE_I32_CONST;
      Segment.Data.Offset.Value.Int32 = 0;
    }
    uint32_t Size = readVaruint32(Ctx);
    if (Size > (size_t)(Ctx.End - Ctx.Ptr))
      return make_error<GenericBinaryError>("invalid segment size",
                                            object_error::parse_failed);
    Segment.Data.Content = ArrayRef<uint8_t>(Ctx.Ptr, Size);
    // The rest of these Data fields are set later, when reading in the linking
    // metadata section.
    Segment.Data.Alignment = 0;
    Segment.Data.LinkingFlags = 0;
    Segment.Data.Comdat = UINT32_MAX;
    Segment.SectionOffset = Ctx.Ptr - Ctx.Start;
    Ctx.Ptr += Size;
    DataSegments.push_back(Segment);
  }
  if (Ctx.Ptr != Ctx.End)
    return make_error<GenericBinaryError>("data section ended prematurely",
                                          object_error::parse_failed);
  return Error::success();
}

Error WasmObjectFile::parseDataCountSection(ReadContext &Ctx) {
  DataCount = readVaruint32(Ctx);
  return Error::success();
}

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

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

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

  LLVM_DEBUG(dbgs() << "getSymbolFlags: ptr=" << &Sym << " " << Sym << "\n");
  if (Sym.isBindingWeak())
    Result |= SymbolRef::SF_Weak;
  if (!Sym.isBindingLocal())
    Result |= SymbolRef::SF_Global;
  if (Sym.isHidden())
    Result |= SymbolRef::SF_Hidden;
  if (!Sym.isDefined())
    Result |= SymbolRef::SF_Undefined;
  if (Sym.isTypeFunction())
    Result |= SymbolRef::SF_Executable;
  return Result;
}

basic_symbol_iterator WasmObjectFile::symbol_begin() const {
  DataRefImpl Ref;
  Ref.d.a = 1; // Arbitrary non-zero value so that Ref.p is non-null
  Ref.d.b = 0; // Symbol index
  return BasicSymbolRef(Ref, this);
}

basic_symbol_iterator WasmObjectFile::symbol_end() const {
  DataRefImpl Ref;
  Ref.d.a = 1; // Arbitrary non-zero value so that Ref.p is non-null
  Ref.d.b = Symbols.size(); // Symbol index
  return BasicSymbolRef(Ref, this);
}

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

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

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

Expected<uint64_t> WasmObjectFile::getSymbolAddress(DataRefImpl Symb) const {
  auto &Sym = getWasmSymbol(Symb);
  if (Sym.Info.Kind == wasm::WASM_SYMBOL_TYPE_FUNCTION &&
      isDefinedFunctionIndex(Sym.Info.ElementIndex))
    return getDefinedFunction(Sym.Info.ElementIndex).CodeSectionOffset;
  else
    return getSymbolValue(Symb);
}

uint64_t WasmObjectFile::getWasmSymbolValue(const WasmSymbol &Sym) const {
  switch (Sym.Info.Kind) {
  case wasm::WASM_SYMBOL_TYPE_FUNCTION:
  case wasm::WASM_SYMBOL_TYPE_GLOBAL:
  case wasm::WASM_SYMBOL_TYPE_TAG:
  case wasm::WASM_SYMBOL_TYPE_TABLE:
    return Sym.Info.ElementIndex;
  case wasm::WASM_SYMBOL_TYPE_DATA: {
    // The value of a data symbol is the segment offset, plus the symbol
    // offset within the segment.
    uint32_t SegmentIndex = Sym.Info.DataRef.Segment;
    const wasm::WasmDataSegment &Segment = DataSegments[SegmentIndex].Data;
    if (Segment.Offset.Opcode == wasm::WASM_OPCODE_I32_CONST) {
      return Segment.Offset.Value.Int32 + Sym.Info.DataRef.Offset;
    } else if (Segment.Offset.Opcode == wasm::WASM_OPCODE_I64_CONST) {
      return Segment.Offset.Value.Int64 + Sym.Info.DataRef.Offset;
    } else {
      llvm_unreachable("unknown init expr opcode");
    }
  }
  case wasm::WASM_SYMBOL_TYPE_SECTION:
    return 0;
  }
  llvm_unreachable("invalid symbol type");
}

uint64_t WasmObjectFile::getSymbolValueImpl(DataRefImpl Symb) const {
  return getWasmSymbolValue(getWasmSymbol(Symb));
}

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.Info.Kind) {
  case wasm::WASM_SYMBOL_TYPE_FUNCTION:
    return SymbolRef::ST_Function;
  case wasm::WASM_SYMBOL_TYPE_GLOBAL:
    return SymbolRef::ST_Other;
  case wasm::WASM_SYMBOL_TYPE_DATA:
    return SymbolRef::ST_Data;
  case wasm::WASM_SYMBOL_TYPE_SECTION:
    return SymbolRef::ST_Debug;
  case wasm::WASM_SYMBOL_TYPE_TAG:
    return SymbolRef::ST_Other;
  case wasm::WASM_SYMBOL_TYPE_TABLE:
    return SymbolRef::ST_Other;
  }

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

Expected<section_iterator>
WasmObjectFile::getSymbolSection(DataRefImpl Symb) const {
  const WasmSymbol &Sym = getWasmSymbol(Symb);
  if (Sym.isUndefined())
    return section_end();

  DataRefImpl Ref;
  Ref.d.a = getSymbolSectionIdImpl(Sym);
  return section_iterator(SectionRef(Ref, this));
}

uint32_t WasmObjectFile::getSymbolSectionId(SymbolRef Symb) const {
  const WasmSymbol &Sym = getWasmSymbol(Symb);
  return getSymbolSectionIdImpl(Sym);
}

uint32_t WasmObjectFile::getSymbolSectionIdImpl(const WasmSymbol &Sym) const {
  switch (Sym.Info.Kind) {
  case wasm::WASM_SYMBOL_TYPE_FUNCTION:
    return CodeSection;
  case wasm::WASM_SYMBOL_TYPE_GLOBAL:
    return GlobalSection;
  case wasm::WASM_SYMBOL_TYPE_DATA:
    return DataSection;
  case wasm::WASM_SYMBOL_TYPE_SECTION:
    return Sym.Info.ElementIndex;
  case wasm::WASM_SYMBOL_TYPE_TAG:
    return TagSection;
  case wasm::WASM_SYMBOL_TYPE_TABLE:
    return TableSection;
  default:
    llvm_unreachable("unknown WasmSymbol::SymbolType");
  }
}

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

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

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();
}

Expected<ArrayRef<uint8_t>>
WasmObjectFile::getSectionContents(DataRefImpl Sec) 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).
  return S.Content;
}

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; }

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 Ref) const {
  const wasm::WasmRelocation &Rel = getWasmRelocation(Ref);
  if (Rel.Type == wasm::R_WASM_TYPE_INDEX_LEB)
    return symbol_end();
  DataRefImpl Sym;
  Sym.d.a = 1;
  Sym.d.b = Rel.Index;
  return symbol_iterator(SymbolRef(Sym, this));
}

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.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 HasMemory64 ? 8 : 4;
}

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

Triple::ArchType WasmObjectFile::getArch() const {
  return HasMemory64 ? Triple::wasm64 : Triple::wasm32;
}

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

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

bool WasmObjectFile::isSharedObject() const { return HasDylinkSection; }

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];
}

int WasmSectionOrderChecker::getSectionOrder(unsigned ID,
                                             StringRef CustomSectionName) {
  switch (ID) {
  case wasm::WASM_SEC_CUSTOM:
    return StringSwitch<unsigned>(CustomSectionName)
        .Case("dylink", WASM_SEC_ORDER_DYLINK)
        .Case("linking", WASM_SEC_ORDER_LINKING)
        .StartsWith("reloc.", WASM_SEC_ORDER_RELOC)
        .Case("name", WASM_SEC_ORDER_NAME)
        .Case("producers", WASM_SEC_ORDER_PRODUCERS)
        .Case("target_features", WASM_SEC_ORDER_TARGET_FEATURES)
        .Default(WASM_SEC_ORDER_NONE);
  case wasm::WASM_SEC_TYPE:
    return WASM_SEC_ORDER_TYPE;
  case wasm::WASM_SEC_IMPORT:
    return WASM_SEC_ORDER_IMPORT;
  case wasm::WASM_SEC_FUNCTION:
    return WASM_SEC_ORDER_FUNCTION;
  case wasm::WASM_SEC_TABLE:
    return WASM_SEC_ORDER_TABLE;
  case wasm::WASM_SEC_MEMORY:
    return WASM_SEC_ORDER_MEMORY;
  case wasm::WASM_SEC_GLOBAL:
    return WASM_SEC_ORDER_GLOBAL;
  case wasm::WASM_SEC_EXPORT:
    return WASM_SEC_ORDER_EXPORT;
  case wasm::WASM_SEC_START:
    return WASM_SEC_ORDER_START;
  case wasm::WASM_SEC_ELEM:
    return WASM_SEC_ORDER_ELEM;
  case wasm::WASM_SEC_CODE:
    return WASM_SEC_ORDER_CODE;
  case wasm::WASM_SEC_DATA:
    return WASM_SEC_ORDER_DATA;
  case wasm::WASM_SEC_DATACOUNT:
    return WASM_SEC_ORDER_DATACOUNT;
  case wasm::WASM_SEC_TAG:
    return WASM_SEC_ORDER_TAG;
  default:
    return WASM_SEC_ORDER_NONE;
  }
}

// Represents the edges in a directed graph where any node B reachable from node
// A is not allowed to appear before A in the section ordering, but may appear
// afterward.
int WasmSectionOrderChecker::DisallowedPredecessors
    [WASM_NUM_SEC_ORDERS][WASM_NUM_SEC_ORDERS] = {
        // WASM_SEC_ORDER_NONE
        {},
        // WASM_SEC_ORDER_TYPE
        {WASM_SEC_ORDER_TYPE, WASM_SEC_ORDER_IMPORT},
        // WASM_SEC_ORDER_IMPORT
        {WASM_SEC_ORDER_IMPORT, WASM_SEC_ORDER_FUNCTION},
        // WASM_SEC_ORDER_FUNCTION
        {WASM_SEC_ORDER_FUNCTION, WASM_SEC_ORDER_TABLE},
        // WASM_SEC_ORDER_TABLE
        {WASM_SEC_ORDER_TABLE, WASM_SEC_ORDER_MEMORY},
        // WASM_SEC_ORDER_MEMORY
        {WASM_SEC_ORDER_MEMORY, WASM_SEC_ORDER_TAG},
        // WASM_SEC_ORDER_TAG
        {WASM_SEC_ORDER_TAG, WASM_SEC_ORDER_GLOBAL},
        // WASM_SEC_ORDER_GLOBAL
        {WASM_SEC_ORDER_GLOBAL, WASM_SEC_ORDER_EXPORT},
        // WASM_SEC_ORDER_EXPORT
        {WASM_SEC_ORDER_EXPORT, WASM_SEC_ORDER_START},
        // WASM_SEC_ORDER_START
        {WASM_SEC_ORDER_START, WASM_SEC_ORDER_ELEM},
        // WASM_SEC_ORDER_ELEM
        {WASM_SEC_ORDER_ELEM, WASM_SEC_ORDER_DATACOUNT},
        // WASM_SEC_ORDER_DATACOUNT
        {WASM_SEC_ORDER_DATACOUNT, WASM_SEC_ORDER_CODE},
        // WASM_SEC_ORDER_CODE
        {WASM_SEC_ORDER_CODE, WASM_SEC_ORDER_DATA},
        // WASM_SEC_ORDER_DATA
        {WASM_SEC_ORDER_DATA, WASM_SEC_ORDER_LINKING},

        // Custom Sections
        // WASM_SEC_ORDER_DYLINK
        {WASM_SEC_ORDER_DYLINK, WASM_SEC_ORDER_TYPE},
        // WASM_SEC_ORDER_LINKING
        {WASM_SEC_ORDER_LINKING, WASM_SEC_ORDER_RELOC, WASM_SEC_ORDER_NAME},
        // WASM_SEC_ORDER_RELOC (can be repeated)
        {},
        // WASM_SEC_ORDER_NAME
        {WASM_SEC_ORDER_NAME, WASM_SEC_ORDER_PRODUCERS},
        // WASM_SEC_ORDER_PRODUCERS
        {WASM_SEC_ORDER_PRODUCERS, WASM_SEC_ORDER_TARGET_FEATURES},
        // WASM_SEC_ORDER_TARGET_FEATURES
        {WASM_SEC_ORDER_TARGET_FEATURES}};

bool WasmSectionOrderChecker::isValidSectionOrder(unsigned ID,
                                                  StringRef CustomSectionName) {
  int Order = getSectionOrder(ID, CustomSectionName);
  if (Order == WASM_SEC_ORDER_NONE)
    return true;

  // Disallowed predecessors we need to check for
  SmallVector<int, WASM_NUM_SEC_ORDERS> WorkList;

  // Keep track of completed checks to avoid repeating work
  bool Checked[WASM_NUM_SEC_ORDERS] = {};

  int Curr = Order;
  while (true) {
    // Add new disallowed predecessors to work list
    for (size_t I = 0;; ++I) {
      int Next = DisallowedPredecessors[Curr][I];
      if (Next == WASM_SEC_ORDER_NONE)
        break;
      if (Checked[Next])
        continue;
      WorkList.push_back(Next);
      Checked[Next] = true;
    }

    if (WorkList.empty())
      break;

    // Consider next disallowed predecessor
    Curr = WorkList.pop_back_val();
    if (Seen[Curr])
      return false;
  }

  // Have not seen any disallowed predecessors
  Seen[Order] = true;
  return true;
}
