Home | History | Annotate | Download | only in Object
      1 //===- WasmObjectFile.cpp - Wasm object file implementation ---------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #include "llvm/ADT/ArrayRef.h"
     11 #include "llvm/ADT/DenseSet.h"
     12 #include "llvm/ADT/STLExtras.h"
     13 #include "llvm/ADT/StringRef.h"
     14 #include "llvm/ADT/StringSet.h"
     15 #include "llvm/ADT/Triple.h"
     16 #include "llvm/BinaryFormat/Wasm.h"
     17 #include "llvm/MC/SubtargetFeature.h"
     18 #include "llvm/Object/Binary.h"
     19 #include "llvm/Object/Error.h"
     20 #include "llvm/Object/ObjectFile.h"
     21 #include "llvm/Object/SymbolicFile.h"
     22 #include "llvm/Object/Wasm.h"
     23 #include "llvm/Support/Endian.h"
     24 #include "llvm/Support/Error.h"
     25 #include "llvm/Support/ErrorHandling.h"
     26 #include "llvm/Support/LEB128.h"
     27 #include <algorithm>
     28 #include <cassert>
     29 #include <cstdint>
     30 #include <cstring>
     31 #include <system_error>
     32 
     33 #define DEBUG_TYPE "wasm-object"
     34 
     35 using namespace llvm;
     36 using namespace object;
     37 
     38 void WasmSymbol::print(raw_ostream &Out) const {
     39   Out << "Name=" << Info.Name
     40   << ", Kind=" << toString(wasm::WasmSymbolType(Info.Kind))
     41   << ", Flags=" << Info.Flags;
     42   if (!isTypeData()) {
     43     Out << ", ElemIndex=" << Info.ElementIndex;
     44   } else if (isDefined()) {
     45     Out << ", Segment=" << Info.DataRef.Segment;
     46     Out << ", Offset=" << Info.DataRef.Offset;
     47     Out << ", Size=" << Info.DataRef.Size;
     48   }
     49 }
     50 
     51 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
     52 LLVM_DUMP_METHOD void WasmSymbol::dump() const { print(dbgs()); }
     53 #endif
     54 
     55 Expected<std::unique_ptr<WasmObjectFile>>
     56 ObjectFile::createWasmObjectFile(MemoryBufferRef Buffer) {
     57   Error Err = Error::success();
     58   auto ObjectFile = llvm::make_unique<WasmObjectFile>(Buffer, Err);
     59   if (Err)
     60     return std::move(Err);
     61 
     62   return std::move(ObjectFile);
     63 }
     64 
     65 #define VARINT7_MAX ((1<<7)-1)
     66 #define VARINT7_MIN (-(1<<7))
     67 #define VARUINT7_MAX (1<<7)
     68 #define VARUINT1_MAX (1)
     69 
     70 static uint8_t readUint8(WasmObjectFile::ReadContext &Ctx) {
     71   if (Ctx.Ptr == Ctx.End)
     72     report_fatal_error("EOF while reading uint8");
     73   return *Ctx.Ptr++;
     74 }
     75 
     76 static uint32_t readUint32(WasmObjectFile::ReadContext &Ctx) {
     77   if (Ctx.Ptr + 4 > Ctx.End)
     78     report_fatal_error("EOF while reading uint32");
     79   uint32_t Result = support::endian::read32le(Ctx.Ptr);
     80   Ctx.Ptr += 4;
     81   return Result;
     82 }
     83 
     84 static int32_t readFloat32(WasmObjectFile::ReadContext &Ctx) {
     85   int32_t Result = 0;
     86   memcpy(&Result, Ctx.Ptr, sizeof(Result));
     87   Ctx.Ptr += sizeof(Result);
     88   return Result;
     89 }
     90 
     91 static int64_t readFloat64(WasmObjectFile::ReadContext &Ctx) {
     92   int64_t Result = 0;
     93   memcpy(&Result, Ctx.Ptr, sizeof(Result));
     94   Ctx.Ptr += sizeof(Result);
     95   return Result;
     96 }
     97 
     98 static uint64_t readULEB128(WasmObjectFile::ReadContext &Ctx) {
     99   unsigned Count;
    100   const char* Error = nullptr;
    101   uint64_t Result = decodeULEB128(Ctx.Ptr, &Count, Ctx.End, &Error);
    102   if (Error)
    103     report_fatal_error(Error);
    104   Ctx.Ptr += Count;
    105   return Result;
    106 }
    107 
    108 static StringRef readString(WasmObjectFile::ReadContext &Ctx) {
    109   uint32_t StringLen = readULEB128(Ctx);
    110   if (Ctx.Ptr + StringLen > Ctx.End)
    111     report_fatal_error("EOF while reading string");
    112   StringRef Return =
    113       StringRef(reinterpret_cast<const char *>(Ctx.Ptr), StringLen);
    114   Ctx.Ptr += StringLen;
    115   return Return;
    116 }
    117 
    118 static int64_t readLEB128(WasmObjectFile::ReadContext &Ctx) {
    119   unsigned Count;
    120   const char* Error = nullptr;
    121   uint64_t Result = decodeSLEB128(Ctx.Ptr, &Count, Ctx.End, &Error);
    122   if (Error)
    123     report_fatal_error(Error);
    124   Ctx.Ptr += Count;
    125   return Result;
    126 }
    127 
    128 static uint8_t readVaruint1(WasmObjectFile::ReadContext &Ctx) {
    129   int64_t result = readLEB128(Ctx);
    130   if (result > VARUINT1_MAX || result < 0)
    131     report_fatal_error("LEB is outside Varuint1 range");
    132   return result;
    133 }
    134 
    135 static int32_t readVarint32(WasmObjectFile::ReadContext &Ctx) {
    136   int64_t result = readLEB128(Ctx);
    137   if (result > INT32_MAX || result < INT32_MIN)
    138     report_fatal_error("LEB is outside Varint32 range");
    139   return result;
    140 }
    141 
    142 static uint32_t readVaruint32(WasmObjectFile::ReadContext &Ctx) {
    143   uint64_t result = readULEB128(Ctx);
    144   if (result > UINT32_MAX)
    145     report_fatal_error("LEB is outside Varuint32 range");
    146   return result;
    147 }
    148 
    149 static int64_t readVarint64(WasmObjectFile::ReadContext &Ctx) {
    150   return readLEB128(Ctx);
    151 }
    152 
    153 static uint8_t readOpcode(WasmObjectFile::ReadContext &Ctx) {
    154   return readUint8(Ctx);
    155 }
    156 
    157 static Error readInitExpr(wasm::WasmInitExpr &Expr,
    158                           WasmObjectFile::ReadContext &Ctx) {
    159   Expr.Opcode = readOpcode(Ctx);
    160 
    161   switch (Expr.Opcode) {
    162   case wasm::WASM_OPCODE_I32_CONST:
    163     Expr.Value.Int32 = readVarint32(Ctx);
    164     break;
    165   case wasm::WASM_OPCODE_I64_CONST:
    166     Expr.Value.Int64 = readVarint64(Ctx);
    167     break;
    168   case wasm::WASM_OPCODE_F32_CONST:
    169     Expr.Value.Float32 = readFloat32(Ctx);
    170     break;
    171   case wasm::WASM_OPCODE_F64_CONST:
    172     Expr.Value.Float64 = readFloat64(Ctx);
    173     break;
    174   case wasm::WASM_OPCODE_GET_GLOBAL:
    175     Expr.Value.Global = readULEB128(Ctx);
    176     break;
    177   default:
    178     return make_error<GenericBinaryError>("Invalid opcode in init_expr",
    179                                           object_error::parse_failed);
    180   }
    181 
    182   uint8_t EndOpcode = readOpcode(Ctx);
    183   if (EndOpcode != wasm::WASM_OPCODE_END) {
    184     return make_error<GenericBinaryError>("Invalid init_expr",
    185                                           object_error::parse_failed);
    186   }
    187   return Error::success();
    188 }
    189 
    190 static wasm::WasmLimits readLimits(WasmObjectFile::ReadContext &Ctx) {
    191   wasm::WasmLimits Result;
    192   Result.Flags = readVaruint1(Ctx);
    193   Result.Initial = readVaruint32(Ctx);
    194   if (Result.Flags & wasm::WASM_LIMITS_FLAG_HAS_MAX)
    195     Result.Maximum = readVaruint32(Ctx);
    196   return Result;
    197 }
    198 
    199 static wasm::WasmTable readTable(WasmObjectFile::ReadContext &Ctx) {
    200   wasm::WasmTable Table;
    201   Table.ElemType = readUint8(Ctx);
    202   Table.Limits = readLimits(Ctx);
    203   return Table;
    204 }
    205 
    206 static Error readSection(WasmSection &Section,
    207                          WasmObjectFile::ReadContext &Ctx) {
    208   Section.Offset = Ctx.Ptr - Ctx.Start;
    209   Section.Type = readUint8(Ctx);
    210   LLVM_DEBUG(dbgs() << "readSection type=" << Section.Type << "\n");
    211   uint32_t Size = readVaruint32(Ctx);
    212   if (Size == 0)
    213     return make_error<StringError>("Zero length section",
    214                                    object_error::parse_failed);
    215   if (Ctx.Ptr + Size > Ctx.End)
    216     return make_error<StringError>("Section too large",
    217                                    object_error::parse_failed);
    218   if (Section.Type == wasm::WASM_SEC_CUSTOM) {
    219     const uint8_t *NameStart = Ctx.Ptr;
    220     Section.Name = readString(Ctx);
    221     Size -= Ctx.Ptr - NameStart;
    222   }
    223   Section.Content = ArrayRef<uint8_t>(Ctx.Ptr, Size);
    224   Ctx.Ptr += Size;
    225   return Error::success();
    226 }
    227 
    228 WasmObjectFile::WasmObjectFile(MemoryBufferRef Buffer, Error &Err)
    229     : ObjectFile(Binary::ID_Wasm, Buffer) {
    230   ErrorAsOutParameter ErrAsOutParam(&Err);
    231   Header.Magic = getData().substr(0, 4);
    232   if (Header.Magic != StringRef("\0asm", 4)) {
    233     Err = make_error<StringError>("Bad magic number",
    234                                   object_error::parse_failed);
    235     return;
    236   }
    237 
    238   ReadContext Ctx;
    239   Ctx.Start = getPtr(0);
    240   Ctx.Ptr = Ctx.Start + 4;
    241   Ctx.End = Ctx.Start + getData().size();
    242 
    243   if (Ctx.Ptr + 4 > Ctx.End) {
    244     Err = make_error<StringError>("Missing version number",
    245                                   object_error::parse_failed);
    246     return;
    247   }
    248 
    249   Header.Version = readUint32(Ctx);
    250   if (Header.Version != wasm::WasmVersion) {
    251     Err = make_error<StringError>("Bad version number",
    252                                   object_error::parse_failed);
    253     return;
    254   }
    255 
    256   WasmSection Sec;
    257   while (Ctx.Ptr < Ctx.End) {
    258     if ((Err = readSection(Sec, Ctx)))
    259       return;
    260     if ((Err = parseSection(Sec)))
    261       return;
    262 
    263     Sections.push_back(Sec);
    264   }
    265 }
    266 
    267 Error WasmObjectFile::parseSection(WasmSection &Sec) {
    268   ReadContext Ctx;
    269   Ctx.Start = Sec.Content.data();
    270   Ctx.End = Ctx.Start + Sec.Content.size();
    271   Ctx.Ptr = Ctx.Start;
    272   switch (Sec.Type) {
    273   case wasm::WASM_SEC_CUSTOM:
    274     return parseCustomSection(Sec, Ctx);
    275   case wasm::WASM_SEC_TYPE:
    276     return parseTypeSection(Ctx);
    277   case wasm::WASM_SEC_IMPORT:
    278     return parseImportSection(Ctx);
    279   case wasm::WASM_SEC_FUNCTION:
    280     return parseFunctionSection(Ctx);
    281   case wasm::WASM_SEC_TABLE:
    282     return parseTableSection(Ctx);
    283   case wasm::WASM_SEC_MEMORY:
    284     return parseMemorySection(Ctx);
    285   case wasm::WASM_SEC_GLOBAL:
    286     return parseGlobalSection(Ctx);
    287   case wasm::WASM_SEC_EXPORT:
    288     return parseExportSection(Ctx);
    289   case wasm::WASM_SEC_START:
    290     return parseStartSection(Ctx);
    291   case wasm::WASM_SEC_ELEM:
    292     return parseElemSection(Ctx);
    293   case wasm::WASM_SEC_CODE:
    294     return parseCodeSection(Ctx);
    295   case wasm::WASM_SEC_DATA:
    296     return parseDataSection(Ctx);
    297   default:
    298     return make_error<GenericBinaryError>("Bad section type",
    299                                           object_error::parse_failed);
    300   }
    301 }
    302 
    303 Error WasmObjectFile::parseNameSection(ReadContext &Ctx) {
    304   llvm::DenseSet<uint64_t> Seen;
    305   if (Functions.size() != FunctionTypes.size()) {
    306     return make_error<GenericBinaryError>("Names must come after code section",
    307                                           object_error::parse_failed);
    308   }
    309 
    310   while (Ctx.Ptr < Ctx.End) {
    311     uint8_t Type = readUint8(Ctx);
    312     uint32_t Size = readVaruint32(Ctx);
    313     const uint8_t *SubSectionEnd = Ctx.Ptr + Size;
    314     switch (Type) {
    315     case wasm::WASM_NAMES_FUNCTION: {
    316       uint32_t Count = readVaruint32(Ctx);
    317       while (Count--) {
    318         uint32_t Index = readVaruint32(Ctx);
    319         if (!Seen.insert(Index).second)
    320           return make_error<GenericBinaryError>("Function named more than once",
    321                                                 object_error::parse_failed);
    322         StringRef Name = readString(Ctx);
    323         if (!isValidFunctionIndex(Index) || Name.empty())
    324           return make_error<GenericBinaryError>("Invalid name entry",
    325                                                 object_error::parse_failed);
    326         DebugNames.push_back(wasm::WasmFunctionName{Index, Name});
    327         if (isDefinedFunctionIndex(Index))
    328           getDefinedFunction(Index).DebugName = Name;
    329       }
    330       break;
    331     }
    332     // Ignore local names for now
    333     case wasm::WASM_NAMES_LOCAL:
    334     default:
    335       Ctx.Ptr += Size;
    336       break;
    337     }
    338     if (Ctx.Ptr != SubSectionEnd)
    339       return make_error<GenericBinaryError>("Name sub-section ended prematurely",
    340                                             object_error::parse_failed);
    341   }
    342 
    343   if (Ctx.Ptr != Ctx.End)
    344     return make_error<GenericBinaryError>("Name section ended prematurely",
    345                                           object_error::parse_failed);
    346   return Error::success();
    347 }
    348 
    349 Error WasmObjectFile::parseLinkingSection(ReadContext &Ctx) {
    350   HasLinkingSection = true;
    351   if (Functions.size() != FunctionTypes.size()) {
    352     return make_error<GenericBinaryError>(
    353         "Linking data must come after code section", object_error::parse_failed);
    354   }
    355 
    356   LinkingData.Version = readVaruint32(Ctx);
    357   if (LinkingData.Version != wasm::WasmMetadataVersion) {
    358     return make_error<GenericBinaryError>(
    359         "Unexpected metadata version: " + Twine(LinkingData.Version) +
    360             " (Expected: " + Twine(wasm::WasmMetadataVersion) + ")",
    361         object_error::parse_failed);
    362   }
    363 
    364   const uint8_t *OrigEnd = Ctx.End;
    365   while (Ctx.Ptr < OrigEnd) {
    366     Ctx.End = OrigEnd;
    367     uint8_t Type = readUint8(Ctx);
    368     uint32_t Size = readVaruint32(Ctx);
    369     LLVM_DEBUG(dbgs() << "readSubsection type=" << int(Type) << " size=" << Size
    370                       << "\n");
    371     Ctx.End = Ctx.Ptr + Size;
    372     switch (Type) {
    373     case wasm::WASM_SYMBOL_TABLE:
    374       if (Error Err = parseLinkingSectionSymtab(Ctx))
    375         return Err;
    376       break;
    377     case wasm::WASM_SEGMENT_INFO: {
    378       uint32_t Count = readVaruint32(Ctx);
    379       if (Count > DataSegments.size())
    380         return make_error<GenericBinaryError>("Too many segment names",
    381                                               object_error::parse_failed);
    382       for (uint32_t i = 0; i < Count; i++) {
    383         DataSegments[i].Data.Name = readString(Ctx);
    384         DataSegments[i].Data.Alignment = readVaruint32(Ctx);
    385         DataSegments[i].Data.Flags = readVaruint32(Ctx);
    386       }
    387       break;
    388     }
    389     case wasm::WASM_INIT_FUNCS: {
    390       uint32_t Count = readVaruint32(Ctx);
    391       LinkingData.InitFunctions.reserve(Count);
    392       for (uint32_t i = 0; i < Count; i++) {
    393         wasm::WasmInitFunc Init;
    394         Init.Priority = readVaruint32(Ctx);
    395         Init.Symbol = readVaruint32(Ctx);
    396         if (!isValidFunctionSymbol(Init.Symbol))
    397           return make_error<GenericBinaryError>("Invalid function symbol: " +
    398                                                     Twine(Init.Symbol),
    399                                                 object_error::parse_failed);
    400         LinkingData.InitFunctions.emplace_back(Init);
    401       }
    402       break;
    403     }
    404     case wasm::WASM_COMDAT_INFO:
    405       if (Error Err = parseLinkingSectionComdat(Ctx))
    406         return Err;
    407       break;
    408     default:
    409       Ctx.Ptr += Size;
    410       break;
    411     }
    412     if (Ctx.Ptr != Ctx.End)
    413       return make_error<GenericBinaryError>(
    414           "Linking sub-section ended prematurely", object_error::parse_failed);
    415   }
    416   if (Ctx.Ptr != OrigEnd)
    417     return make_error<GenericBinaryError>("Linking section ended prematurely",
    418                                           object_error::parse_failed);
    419   return Error::success();
    420 }
    421 
    422 Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) {
    423   uint32_t Count = readVaruint32(Ctx);
    424   LinkingData.SymbolTable.reserve(Count);
    425   Symbols.reserve(Count);
    426   StringSet<> SymbolNames;
    427 
    428   std::vector<wasm::WasmImport *> ImportedGlobals;
    429   std::vector<wasm::WasmImport *> ImportedFunctions;
    430   ImportedGlobals.reserve(Imports.size());
    431   ImportedFunctions.reserve(Imports.size());
    432   for (auto &I : Imports) {
    433     if (I.Kind == wasm::WASM_EXTERNAL_FUNCTION)
    434       ImportedFunctions.emplace_back(&I);
    435     else if (I.Kind == wasm::WASM_EXTERNAL_GLOBAL)
    436       ImportedGlobals.emplace_back(&I);
    437   }
    438 
    439   while (Count--) {
    440     wasm::WasmSymbolInfo Info;
    441     const wasm::WasmSignature *FunctionType = nullptr;
    442     const wasm::WasmGlobalType *GlobalType = nullptr;
    443 
    444     Info.Kind = readUint8(Ctx);
    445     Info.Flags = readVaruint32(Ctx);
    446     bool IsDefined = (Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0;
    447 
    448     switch (Info.Kind) {
    449     case wasm::WASM_SYMBOL_TYPE_FUNCTION:
    450       Info.ElementIndex = readVaruint32(Ctx);
    451       if (!isValidFunctionIndex(Info.ElementIndex) ||
    452           IsDefined != isDefinedFunctionIndex(Info.ElementIndex))
    453         return make_error<GenericBinaryError>("invalid function symbol index",
    454                                               object_error::parse_failed);
    455       if (IsDefined) {
    456         Info.Name = readString(Ctx);
    457         unsigned FuncIndex = Info.ElementIndex - NumImportedFunctions;
    458         FunctionType = &Signatures[FunctionTypes[FuncIndex]];
    459         wasm::WasmFunction &Function = Functions[FuncIndex];
    460         if (Function.SymbolName.empty())
    461           Function.SymbolName = Info.Name;
    462       } else {
    463         wasm::WasmImport &Import = *ImportedFunctions[Info.ElementIndex];
    464         FunctionType = &Signatures[Import.SigIndex];
    465         Info.Name = Import.Field;
    466         Info.Module = Import.Module;
    467       }
    468       break;
    469 
    470     case wasm::WASM_SYMBOL_TYPE_GLOBAL:
    471       Info.ElementIndex = readVaruint32(Ctx);
    472       if (!isValidGlobalIndex(Info.ElementIndex) ||
    473           IsDefined != isDefinedGlobalIndex(Info.ElementIndex))
    474         return make_error<GenericBinaryError>("invalid global symbol index",
    475                                               object_error::parse_failed);
    476       if (!IsDefined &&
    477           (Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) ==
    478               wasm::WASM_SYMBOL_BINDING_WEAK)
    479         return make_error<GenericBinaryError>("undefined weak global symbol",
    480                                               object_error::parse_failed);
    481       if (IsDefined) {
    482         Info.Name = readString(Ctx);
    483         unsigned GlobalIndex = Info.ElementIndex - NumImportedGlobals;
    484         wasm::WasmGlobal &Global = Globals[GlobalIndex];
    485         GlobalType = &Global.Type;
    486         if (Global.SymbolName.empty())
    487           Global.SymbolName = Info.Name;
    488       } else {
    489         wasm::WasmImport &Import = *ImportedGlobals[Info.ElementIndex];
    490         Info.Name = Import.Field;
    491         GlobalType = &Import.Global;
    492       }
    493       break;
    494 
    495     case wasm::WASM_SYMBOL_TYPE_DATA:
    496       Info.Name = readString(Ctx);
    497       if (IsDefined) {
    498         uint32_t Index = readVaruint32(Ctx);
    499         if (Index >= DataSegments.size())
    500           return make_error<GenericBinaryError>("invalid data symbol index",
    501                                                 object_error::parse_failed);
    502         uint32_t Offset = readVaruint32(Ctx);
    503         uint32_t Size = readVaruint32(Ctx);
    504         if (Offset + Size > DataSegments[Index].Data.Content.size())
    505           return make_error<GenericBinaryError>("invalid data symbol offset",
    506                                                 object_error::parse_failed);
    507         Info.DataRef = wasm::WasmDataReference{Index, Offset, Size};
    508       }
    509       break;
    510 
    511     case wasm::WASM_SYMBOL_TYPE_SECTION: {
    512       if ((Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) !=
    513           wasm::WASM_SYMBOL_BINDING_LOCAL)
    514         return make_error<GenericBinaryError>(
    515             "Section symbols must have local binding",
    516             object_error::parse_failed);
    517       Info.ElementIndex = readVaruint32(Ctx);
    518       // Use somewhat unique section name as symbol name.
    519       StringRef SectionName = Sections[Info.ElementIndex].Name;
    520       Info.Name = SectionName;
    521       break;
    522     }
    523 
    524     default:
    525       return make_error<GenericBinaryError>("Invalid symbol type",
    526                                             object_error::parse_failed);
    527     }
    528 
    529     if ((Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) !=
    530             wasm::WASM_SYMBOL_BINDING_LOCAL &&
    531         !SymbolNames.insert(Info.Name).second)
    532       return make_error<GenericBinaryError>("Duplicate symbol name " +
    533                                                 Twine(Info.Name),
    534                                             object_error::parse_failed);
    535     LinkingData.SymbolTable.emplace_back(Info);
    536     Symbols.emplace_back(LinkingData.SymbolTable.back(), FunctionType,
    537                          GlobalType);
    538     LLVM_DEBUG(dbgs() << "Adding symbol: " << Symbols.back() << "\n");
    539   }
    540 
    541   return Error::success();
    542 }
    543 
    544 Error WasmObjectFile::parseLinkingSectionComdat(ReadContext &Ctx) {
    545   uint32_t ComdatCount = readVaruint32(Ctx);
    546   StringSet<> ComdatSet;
    547   for (unsigned ComdatIndex = 0; ComdatIndex < ComdatCount; ++ComdatIndex) {
    548     StringRef Name = readString(Ctx);
    549     if (Name.empty() || !ComdatSet.insert(Name).second)
    550       return make_error<GenericBinaryError>("Bad/duplicate COMDAT name " + Twine(Name),
    551                                             object_error::parse_failed);
    552     LinkingData.Comdats.emplace_back(Name);
    553     uint32_t Flags = readVaruint32(Ctx);
    554     if (Flags != 0)
    555       return make_error<GenericBinaryError>("Unsupported COMDAT flags",
    556                                             object_error::parse_failed);
    557 
    558     uint32_t EntryCount = readVaruint32(Ctx);
    559     while (EntryCount--) {
    560       unsigned Kind = readVaruint32(Ctx);
    561       unsigned Index = readVaruint32(Ctx);
    562       switch (Kind) {
    563       default:
    564         return make_error<GenericBinaryError>("Invalid COMDAT entry type",
    565                                               object_error::parse_failed);
    566       case wasm::WASM_COMDAT_DATA:
    567         if (Index >= DataSegments.size())
    568           return make_error<GenericBinaryError>("COMDAT data index out of range",
    569                                                 object_error::parse_failed);
    570         if (DataSegments[Index].Data.Comdat != UINT32_MAX)
    571           return make_error<GenericBinaryError>("Data segment in two COMDATs",
    572                                                 object_error::parse_failed);
    573         DataSegments[Index].Data.Comdat = ComdatIndex;
    574         break;
    575       case wasm::WASM_COMDAT_FUNCTION:
    576         if (!isDefinedFunctionIndex(Index))
    577           return make_error<GenericBinaryError>("COMDAT function index out of range",
    578                                                 object_error::parse_failed);
    579         if (getDefinedFunction(Index).Comdat != UINT32_MAX)
    580           return make_error<GenericBinaryError>("Function in two COMDATs",
    581                                                 object_error::parse_failed);
    582         getDefinedFunction(Index).Comdat = ComdatIndex;
    583         break;
    584       }
    585     }
    586   }
    587   return Error::success();
    588 }
    589 
    590 Error WasmObjectFile::parseRelocSection(StringRef Name, ReadContext &Ctx) {
    591   uint32_t SectionIndex = readVaruint32(Ctx);
    592   if (SectionIndex >= Sections.size())
    593     return make_error<GenericBinaryError>("Invalid section index",
    594                                           object_error::parse_failed);
    595   WasmSection& Section = Sections[SectionIndex];
    596   uint32_t RelocCount = readVaruint32(Ctx);
    597   uint32_t EndOffset = Section.Content.size();
    598   while (RelocCount--) {
    599     wasm::WasmRelocation Reloc = {};
    600     Reloc.Type = readVaruint32(Ctx);
    601     Reloc.Offset = readVaruint32(Ctx);
    602     Reloc.Index = readVaruint32(Ctx);
    603     switch (Reloc.Type) {
    604     case wasm::R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
    605     case wasm::R_WEBASSEMBLY_TABLE_INDEX_SLEB:
    606     case wasm::R_WEBASSEMBLY_TABLE_INDEX_I32:
    607       if (!isValidFunctionSymbol(Reloc.Index))
    608         return make_error<GenericBinaryError>("Bad relocation function index",
    609                                               object_error::parse_failed);
    610       break;
    611     case wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB:
    612       if (Reloc.Index >= Signatures.size())
    613         return make_error<GenericBinaryError>("Bad relocation type index",
    614                                               object_error::parse_failed);
    615       break;
    616     case wasm::R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
    617       if (!isValidGlobalSymbol(Reloc.Index))
    618         return make_error<GenericBinaryError>("Bad relocation global index",
    619                                               object_error::parse_failed);
    620       break;
    621     case wasm::R_WEBASSEMBLY_MEMORY_ADDR_LEB:
    622     case wasm::R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
    623     case wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32:
    624       if (!isValidDataSymbol(Reloc.Index))
    625         return make_error<GenericBinaryError>("Bad relocation data index",
    626                                               object_error::parse_failed);
    627       Reloc.Addend = readVarint32(Ctx);
    628       break;
    629     case wasm::R_WEBASSEMBLY_FUNCTION_OFFSET_I32:
    630       if (!isValidFunctionSymbol(Reloc.Index))
    631         return make_error<GenericBinaryError>("Bad relocation function index",
    632                                               object_error::parse_failed);
    633       Reloc.Addend = readVarint32(Ctx);
    634       break;
    635     case wasm::R_WEBASSEMBLY_SECTION_OFFSET_I32:
    636       if (!isValidSectionSymbol(Reloc.Index))
    637         return make_error<GenericBinaryError>("Bad relocation section index",
    638                                               object_error::parse_failed);
    639       Reloc.Addend = readVarint32(Ctx);
    640       break;
    641     default:
    642       return make_error<GenericBinaryError>("Bad relocation type: " +
    643                                                 Twine(Reloc.Type),
    644                                             object_error::parse_failed);
    645     }
    646 
    647     // Relocations must fit inside the section, and must appear in order.  They
    648     // also shouldn't overlap a function/element boundary, but we don't bother
    649     // to check that.
    650     uint64_t Size = 5;
    651     if (Reloc.Type == wasm::R_WEBASSEMBLY_TABLE_INDEX_I32 ||
    652         Reloc.Type == wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32 ||
    653         Reloc.Type == wasm::R_WEBASSEMBLY_SECTION_OFFSET_I32 ||
    654         Reloc.Type == wasm::R_WEBASSEMBLY_FUNCTION_OFFSET_I32)
    655       Size = 4;
    656     if (Reloc.Offset + Size > EndOffset)
    657       return make_error<GenericBinaryError>("Bad relocation offset",
    658                                             object_error::parse_failed);
    659 
    660     Section.Relocations.push_back(Reloc);
    661   }
    662   if (Ctx.Ptr != Ctx.End)
    663     return make_error<GenericBinaryError>("Reloc section ended prematurely",
    664                                           object_error::parse_failed);
    665   return Error::success();
    666 }
    667 
    668 Error WasmObjectFile::parseCustomSection(WasmSection &Sec, ReadContext &Ctx) {
    669   if (Sec.Name == "name") {
    670     if (Error Err = parseNameSection(Ctx))
    671       return Err;
    672   } else if (Sec.Name == "linking") {
    673     if (Error Err = parseLinkingSection(Ctx))
    674       return Err;
    675   } else if (Sec.Name.startswith("reloc.")) {
    676     if (Error Err = parseRelocSection(Sec.Name, Ctx))
    677       return Err;
    678   }
    679   return Error::success();
    680 }
    681 
    682 Error WasmObjectFile::parseTypeSection(ReadContext &Ctx) {
    683   uint32_t Count = readVaruint32(Ctx);
    684   Signatures.reserve(Count);
    685   while (Count--) {
    686     wasm::WasmSignature Sig;
    687     Sig.ReturnType = wasm::WASM_TYPE_NORESULT;
    688     uint8_t Form = readUint8(Ctx);
    689     if (Form != wasm::WASM_TYPE_FUNC) {
    690       return make_error<GenericBinaryError>("Invalid signature type",
    691                                             object_error::parse_failed);
    692     }
    693     uint32_t ParamCount = readVaruint32(Ctx);
    694     Sig.ParamTypes.reserve(ParamCount);
    695     while (ParamCount--) {
    696       uint32_t ParamType = readUint8(Ctx);
    697       Sig.ParamTypes.push_back(ParamType);
    698     }
    699     uint32_t ReturnCount = readVaruint32(Ctx);
    700     if (ReturnCount) {
    701       if (ReturnCount != 1) {
    702         return make_error<GenericBinaryError>(
    703             "Multiple return types not supported", object_error::parse_failed);
    704       }
    705       Sig.ReturnType = readUint8(Ctx);
    706     }
    707     Signatures.push_back(Sig);
    708   }
    709   if (Ctx.Ptr != Ctx.End)
    710     return make_error<GenericBinaryError>("Type section ended prematurely",
    711                                           object_error::parse_failed);
    712   return Error::success();
    713 }
    714 
    715 Error WasmObjectFile::parseImportSection(ReadContext &Ctx) {
    716   uint32_t Count = readVaruint32(Ctx);
    717   Imports.reserve(Count);
    718   for (uint32_t i = 0; i < Count; i++) {
    719     wasm::WasmImport Im;
    720     Im.Module = readString(Ctx);
    721     Im.Field = readString(Ctx);
    722     Im.Kind = readUint8(Ctx);
    723     switch (Im.Kind) {
    724     case wasm::WASM_EXTERNAL_FUNCTION:
    725       NumImportedFunctions++;
    726       Im.SigIndex = readVaruint32(Ctx);
    727       break;
    728     case wasm::WASM_EXTERNAL_GLOBAL:
    729       NumImportedGlobals++;
    730       Im.Global.Type = readUint8(Ctx);
    731       Im.Global.Mutable = readVaruint1(Ctx);
    732       break;
    733     case wasm::WASM_EXTERNAL_MEMORY:
    734       Im.Memory = readLimits(Ctx);
    735       break;
    736     case wasm::WASM_EXTERNAL_TABLE:
    737       Im.Table = readTable(Ctx);
    738       if (Im.Table.ElemType != wasm::WASM_TYPE_ANYFUNC)
    739         return make_error<GenericBinaryError>("Invalid table element type",
    740                                               object_error::parse_failed);
    741       break;
    742     default:
    743       return make_error<GenericBinaryError>(
    744           "Unexpected import kind", object_error::parse_failed);
    745     }
    746     Imports.push_back(Im);
    747   }
    748   if (Ctx.Ptr != Ctx.End)
    749     return make_error<GenericBinaryError>("Import section ended prematurely",
    750                                           object_error::parse_failed);
    751   return Error::success();
    752 }
    753 
    754 Error WasmObjectFile::parseFunctionSection(ReadContext &Ctx) {
    755   uint32_t Count = readVaruint32(Ctx);
    756   FunctionTypes.reserve(Count);
    757   uint32_t NumTypes = Signatures.size();
    758   while (Count--) {
    759     uint32_t Type = readVaruint32(Ctx);
    760     if (Type >= NumTypes)
    761       return make_error<GenericBinaryError>("Invalid function type",
    762                                             object_error::parse_failed);
    763     FunctionTypes.push_back(Type);
    764   }
    765   if (Ctx.Ptr != Ctx.End)
    766     return make_error<GenericBinaryError>("Function section ended prematurely",
    767                                           object_error::parse_failed);
    768   return Error::success();
    769 }
    770 
    771 Error WasmObjectFile::parseTableSection(ReadContext &Ctx) {
    772   uint32_t Count = readVaruint32(Ctx);
    773   Tables.reserve(Count);
    774   while (Count--) {
    775     Tables.push_back(readTable(Ctx));
    776     if (Tables.back().ElemType != wasm::WASM_TYPE_ANYFUNC) {
    777       return make_error<GenericBinaryError>("Invalid table element type",
    778                                             object_error::parse_failed);
    779     }
    780   }
    781   if (Ctx.Ptr != Ctx.End)
    782     return make_error<GenericBinaryError>("Table section ended prematurely",
    783                                           object_error::parse_failed);
    784   return Error::success();
    785 }
    786 
    787 Error WasmObjectFile::parseMemorySection(ReadContext &Ctx) {
    788   uint32_t Count = readVaruint32(Ctx);
    789   Memories.reserve(Count);
    790   while (Count--) {
    791     Memories.push_back(readLimits(Ctx));
    792   }
    793   if (Ctx.Ptr != Ctx.End)
    794     return make_error<GenericBinaryError>("Memory section ended prematurely",
    795                                           object_error::parse_failed);
    796   return Error::success();
    797 }
    798 
    799 Error WasmObjectFile::parseGlobalSection(ReadContext &Ctx) {
    800   GlobalSection = Sections.size();
    801   uint32_t Count = readVaruint32(Ctx);
    802   Globals.reserve(Count);
    803   while (Count--) {
    804     wasm::WasmGlobal Global;
    805     Global.Index = NumImportedGlobals + Globals.size();
    806     Global.Type.Type = readUint8(Ctx);
    807     Global.Type.Mutable = readVaruint1(Ctx);
    808     if (Error Err = readInitExpr(Global.InitExpr, Ctx))
    809       return Err;
    810     Globals.push_back(Global);
    811   }
    812   if (Ctx.Ptr != Ctx.End)
    813     return make_error<GenericBinaryError>("Global section ended prematurely",
    814                                           object_error::parse_failed);
    815   return Error::success();
    816 }
    817 
    818 Error WasmObjectFile::parseExportSection(ReadContext &Ctx) {
    819   uint32_t Count = readVaruint32(Ctx);
    820   Exports.reserve(Count);
    821   for (uint32_t i = 0; i < Count; i++) {
    822     wasm::WasmExport Ex;
    823     Ex.Name = readString(Ctx);
    824     Ex.Kind = readUint8(Ctx);
    825     Ex.Index = readVaruint32(Ctx);
    826     switch (Ex.Kind) {
    827     case wasm::WASM_EXTERNAL_FUNCTION:
    828       if (!isValidFunctionIndex(Ex.Index))
    829         return make_error<GenericBinaryError>("Invalid function export",
    830                                               object_error::parse_failed);
    831       break;
    832     case wasm::WASM_EXTERNAL_GLOBAL:
    833       if (!isValidGlobalIndex(Ex.Index))
    834         return make_error<GenericBinaryError>("Invalid global export",
    835                                               object_error::parse_failed);
    836       break;
    837     case wasm::WASM_EXTERNAL_MEMORY:
    838     case wasm::WASM_EXTERNAL_TABLE:
    839       break;
    840     default:
    841       return make_error<GenericBinaryError>(
    842           "Unexpected export kind", object_error::parse_failed);
    843     }
    844     Exports.push_back(Ex);
    845   }
    846   if (Ctx.Ptr != Ctx.End)
    847     return make_error<GenericBinaryError>("Export section ended prematurely",
    848                                           object_error::parse_failed);
    849   return Error::success();
    850 }
    851 
    852 bool WasmObjectFile::isValidFunctionIndex(uint32_t Index) const {
    853   return Index < NumImportedFunctions + FunctionTypes.size();
    854 }
    855 
    856 bool WasmObjectFile::isDefinedFunctionIndex(uint32_t Index) const {
    857   return Index >= NumImportedFunctions && isValidFunctionIndex(Index);
    858 }
    859 
    860 bool WasmObjectFile::isValidGlobalIndex(uint32_t Index) const {
    861   return Index < NumImportedGlobals + Globals.size();
    862 }
    863 
    864 bool WasmObjectFile::isDefinedGlobalIndex(uint32_t Index) const {
    865   return Index >= NumImportedGlobals && isValidGlobalIndex(Index);
    866 }
    867 
    868 bool WasmObjectFile::isValidFunctionSymbol(uint32_t Index) const {
    869   return Index < Symbols.size() && Symbols[Index].isTypeFunction();
    870 }
    871 
    872 bool WasmObjectFile::isValidGlobalSymbol(uint32_t Index) const {
    873   return Index < Symbols.size() && Symbols[Index].isTypeGlobal();
    874 }
    875 
    876 bool WasmObjectFile::isValidDataSymbol(uint32_t Index) const {
    877   return Index < Symbols.size() && Symbols[Index].isTypeData();
    878 }
    879 
    880 bool WasmObjectFile::isValidSectionSymbol(uint32_t Index) const {
    881   return Index < Symbols.size() && Symbols[Index].isTypeSection();
    882 }
    883 
    884 wasm::WasmFunction &WasmObjectFile::getDefinedFunction(uint32_t Index) {
    885   assert(isDefinedFunctionIndex(Index));
    886   return Functions[Index - NumImportedFunctions];
    887 }
    888 
    889 wasm::WasmGlobal &WasmObjectFile::getDefinedGlobal(uint32_t Index) {
    890   assert(isDefinedGlobalIndex(Index));
    891   return Globals[Index - NumImportedGlobals];
    892 }
    893 
    894 Error WasmObjectFile::parseStartSection(ReadContext &Ctx) {
    895   StartFunction = readVaruint32(Ctx);
    896   if (!isValidFunctionIndex(StartFunction))
    897     return make_error<GenericBinaryError>("Invalid start function",
    898                                           object_error::parse_failed);
    899   return Error::success();
    900 }
    901 
    902 Error WasmObjectFile::parseCodeSection(ReadContext &Ctx) {
    903   CodeSection = Sections.size();
    904   uint32_t FunctionCount = readVaruint32(Ctx);
    905   if (FunctionCount != FunctionTypes.size()) {
    906     return make_error<GenericBinaryError>("Invalid function count",
    907                                           object_error::parse_failed);
    908   }
    909 
    910   while (FunctionCount--) {
    911     wasm::WasmFunction Function;
    912     const uint8_t *FunctionStart = Ctx.Ptr;
    913     uint32_t Size = readVaruint32(Ctx);
    914     const uint8_t *FunctionEnd = Ctx.Ptr + Size;
    915 
    916     Function.CodeOffset = Ctx.Ptr - FunctionStart;
    917     Function.Index = NumImportedFunctions + Functions.size();
    918     Function.CodeSectionOffset = FunctionStart - Ctx.Start;
    919     Function.Size = FunctionEnd - FunctionStart;
    920 
    921     uint32_t NumLocalDecls = readVaruint32(Ctx);
    922     Function.Locals.reserve(NumLocalDecls);
    923     while (NumLocalDecls--) {
    924       wasm::WasmLocalDecl Decl;
    925       Decl.Count = readVaruint32(Ctx);
    926       Decl.Type = readUint8(Ctx);
    927       Function.Locals.push_back(Decl);
    928     }
    929 
    930     uint32_t BodySize = FunctionEnd - Ctx.Ptr;
    931     Function.Body = ArrayRef<uint8_t>(Ctx.Ptr, BodySize);
    932     // This will be set later when reading in the linking metadata section.
    933     Function.Comdat = UINT32_MAX;
    934     Ctx.Ptr += BodySize;
    935     assert(Ctx.Ptr == FunctionEnd);
    936     Functions.push_back(Function);
    937   }
    938   if (Ctx.Ptr != Ctx.End)
    939     return make_error<GenericBinaryError>("Code section ended prematurely",
    940                                           object_error::parse_failed);
    941   return Error::success();
    942 }
    943 
    944 Error WasmObjectFile::parseElemSection(ReadContext &Ctx) {
    945   uint32_t Count = readVaruint32(Ctx);
    946   ElemSegments.reserve(Count);
    947   while (Count--) {
    948     wasm::WasmElemSegment Segment;
    949     Segment.TableIndex = readVaruint32(Ctx);
    950     if (Segment.TableIndex != 0) {
    951       return make_error<GenericBinaryError>("Invalid TableIndex",
    952                                             object_error::parse_failed);
    953     }
    954     if (Error Err = readInitExpr(Segment.Offset, Ctx))
    955       return Err;
    956     uint32_t NumElems = readVaruint32(Ctx);
    957     while (NumElems--) {
    958       Segment.Functions.push_back(readVaruint32(Ctx));
    959     }
    960     ElemSegments.push_back(Segment);
    961   }
    962   if (Ctx.Ptr != Ctx.End)
    963     return make_error<GenericBinaryError>("Elem section ended prematurely",
    964                                           object_error::parse_failed);
    965   return Error::success();
    966 }
    967 
    968 Error WasmObjectFile::parseDataSection(ReadContext &Ctx) {
    969   DataSection = Sections.size();
    970   uint32_t Count = readVaruint32(Ctx);
    971   DataSegments.reserve(Count);
    972   while (Count--) {
    973     WasmSegment Segment;
    974     Segment.Data.MemoryIndex = readVaruint32(Ctx);
    975     if (Error Err = readInitExpr(Segment.Data.Offset, Ctx))
    976       return Err;
    977     uint32_t Size = readVaruint32(Ctx);
    978     if (Size > (size_t)(Ctx.End - Ctx.Ptr))
    979       return make_error<GenericBinaryError>("Invalid segment size",
    980                                             object_error::parse_failed);
    981     Segment.Data.Content = ArrayRef<uint8_t>(Ctx.Ptr, Size);
    982     // The rest of these Data fields are set later, when reading in the linking
    983     // metadata section.
    984     Segment.Data.Alignment = 0;
    985     Segment.Data.Flags = 0;
    986     Segment.Data.Comdat = UINT32_MAX;
    987     Segment.SectionOffset = Ctx.Ptr - Ctx.Start;
    988     Ctx.Ptr += Size;
    989     DataSegments.push_back(Segment);
    990   }
    991   if (Ctx.Ptr != Ctx.End)
    992     return make_error<GenericBinaryError>("Data section ended prematurely",
    993                                           object_error::parse_failed);
    994   return Error::success();
    995 }
    996 
    997 const uint8_t *WasmObjectFile::getPtr(size_t Offset) const {
    998   return reinterpret_cast<const uint8_t *>(getData().data() + Offset);
    999 }
   1000 
   1001 const wasm::WasmObjectHeader &WasmObjectFile::getHeader() const {
   1002   return Header;
   1003 }
   1004 
   1005 void WasmObjectFile::moveSymbolNext(DataRefImpl &Symb) const { Symb.d.a++; }
   1006 
   1007 uint32_t WasmObjectFile::getSymbolFlags(DataRefImpl Symb) const {
   1008   uint32_t Result = SymbolRef::SF_None;
   1009   const WasmSymbol &Sym = getWasmSymbol(Symb);
   1010 
   1011   LLVM_DEBUG(dbgs() << "getSymbolFlags: ptr=" << &Sym << " " << Sym << "\n");
   1012   if (Sym.isBindingWeak())
   1013     Result |= SymbolRef::SF_Weak;
   1014   if (!Sym.isBindingLocal())
   1015     Result |= SymbolRef::SF_Global;
   1016   if (Sym.isHidden())
   1017     Result |= SymbolRef::SF_Hidden;
   1018   if (!Sym.isDefined())
   1019     Result |= SymbolRef::SF_Undefined;
   1020   if (Sym.isTypeFunction())
   1021     Result |= SymbolRef::SF_Executable;
   1022   return Result;
   1023 }
   1024 
   1025 basic_symbol_iterator WasmObjectFile::symbol_begin() const {
   1026   DataRefImpl Ref;
   1027   Ref.d.a = 0;
   1028   return BasicSymbolRef(Ref, this);
   1029 }
   1030 
   1031 basic_symbol_iterator WasmObjectFile::symbol_end() const {
   1032   DataRefImpl Ref;
   1033   Ref.d.a = Symbols.size();
   1034   return BasicSymbolRef(Ref, this);
   1035 }
   1036 
   1037 const WasmSymbol &WasmObjectFile::getWasmSymbol(const DataRefImpl &Symb) const {
   1038   return Symbols[Symb.d.a];
   1039 }
   1040 
   1041 const WasmSymbol &WasmObjectFile::getWasmSymbol(const SymbolRef &Symb) const {
   1042   return getWasmSymbol(Symb.getRawDataRefImpl());
   1043 }
   1044 
   1045 Expected<StringRef> WasmObjectFile::getSymbolName(DataRefImpl Symb) const {
   1046   return getWasmSymbol(Symb).Info.Name;
   1047 }
   1048 
   1049 Expected<uint64_t> WasmObjectFile::getSymbolAddress(DataRefImpl Symb) const {
   1050   return getSymbolValue(Symb);
   1051 }
   1052 
   1053 uint64_t WasmObjectFile::getWasmSymbolValue(const WasmSymbol& Sym) const {
   1054   switch (Sym.Info.Kind) {
   1055   case wasm::WASM_SYMBOL_TYPE_FUNCTION:
   1056   case wasm::WASM_SYMBOL_TYPE_GLOBAL:
   1057     return Sym.Info.ElementIndex;
   1058   case wasm::WASM_SYMBOL_TYPE_DATA: {
   1059     // The value of a data symbol is the segment offset, plus the symbol
   1060     // offset within the segment.
   1061     uint32_t SegmentIndex = Sym.Info.DataRef.Segment;
   1062     const wasm::WasmDataSegment &Segment = DataSegments[SegmentIndex].Data;
   1063     assert(Segment.Offset.Opcode == wasm::WASM_OPCODE_I32_CONST);
   1064     return Segment.Offset.Value.Int32 + Sym.Info.DataRef.Offset;
   1065   }
   1066   case wasm::WASM_SYMBOL_TYPE_SECTION:
   1067     return 0;
   1068   }
   1069   llvm_unreachable("invalid symbol type");
   1070 }
   1071 
   1072 uint64_t WasmObjectFile::getSymbolValueImpl(DataRefImpl Symb) const {
   1073   return getWasmSymbolValue(getWasmSymbol(Symb));
   1074 }
   1075 
   1076 uint32_t WasmObjectFile::getSymbolAlignment(DataRefImpl Symb) const {
   1077   llvm_unreachable("not yet implemented");
   1078   return 0;
   1079 }
   1080 
   1081 uint64_t WasmObjectFile::getCommonSymbolSizeImpl(DataRefImpl Symb) const {
   1082   llvm_unreachable("not yet implemented");
   1083   return 0;
   1084 }
   1085 
   1086 Expected<SymbolRef::Type>
   1087 WasmObjectFile::getSymbolType(DataRefImpl Symb) const {
   1088   const WasmSymbol &Sym = getWasmSymbol(Symb);
   1089 
   1090   switch (Sym.Info.Kind) {
   1091   case wasm::WASM_SYMBOL_TYPE_FUNCTION:
   1092     return SymbolRef::ST_Function;
   1093   case wasm::WASM_SYMBOL_TYPE_GLOBAL:
   1094     return SymbolRef::ST_Other;
   1095   case wasm::WASM_SYMBOL_TYPE_DATA:
   1096     return SymbolRef::ST_Data;
   1097   case wasm::WASM_SYMBOL_TYPE_SECTION:
   1098     return SymbolRef::ST_Debug;
   1099   }
   1100 
   1101   llvm_unreachable("Unknown WasmSymbol::SymbolType");
   1102   return SymbolRef::ST_Other;
   1103 }
   1104 
   1105 Expected<section_iterator>
   1106 WasmObjectFile::getSymbolSection(DataRefImpl Symb) const {
   1107   const WasmSymbol& Sym = getWasmSymbol(Symb);
   1108   if (Sym.isUndefined())
   1109     return section_end();
   1110 
   1111   DataRefImpl Ref;
   1112   switch (Sym.Info.Kind) {
   1113   case wasm::WASM_SYMBOL_TYPE_FUNCTION:
   1114     Ref.d.a = CodeSection;
   1115     break;
   1116   case wasm::WASM_SYMBOL_TYPE_GLOBAL:
   1117     Ref.d.a = GlobalSection;
   1118     break;
   1119   case wasm::WASM_SYMBOL_TYPE_DATA:
   1120     Ref.d.a = DataSection;
   1121     break;
   1122   case wasm::WASM_SYMBOL_TYPE_SECTION: {
   1123     Ref.d.a = Sym.Info.ElementIndex;
   1124     break;
   1125   }
   1126   default:
   1127     llvm_unreachable("Unknown WasmSymbol::SymbolType");
   1128   }
   1129   return section_iterator(SectionRef(Ref, this));
   1130 }
   1131 
   1132 void WasmObjectFile::moveSectionNext(DataRefImpl &Sec) const { Sec.d.a++; }
   1133 
   1134 std::error_code WasmObjectFile::getSectionName(DataRefImpl Sec,
   1135                                                StringRef &Res) const {
   1136   const WasmSection &S = Sections[Sec.d.a];
   1137 #define ECase(X)                                                               \
   1138   case wasm::WASM_SEC_##X:                                                     \
   1139     Res = #X;                                                                  \
   1140     break
   1141   switch (S.Type) {
   1142     ECase(TYPE);
   1143     ECase(IMPORT);
   1144     ECase(FUNCTION);
   1145     ECase(TABLE);
   1146     ECase(MEMORY);
   1147     ECase(GLOBAL);
   1148     ECase(EXPORT);
   1149     ECase(START);
   1150     ECase(ELEM);
   1151     ECase(CODE);
   1152     ECase(DATA);
   1153   case wasm::WASM_SEC_CUSTOM:
   1154     Res = S.Name;
   1155     break;
   1156   default:
   1157     return object_error::invalid_section_index;
   1158   }
   1159 #undef ECase
   1160   return std::error_code();
   1161 }
   1162 
   1163 uint64_t WasmObjectFile::getSectionAddress(DataRefImpl Sec) const { return 0; }
   1164 
   1165 uint64_t WasmObjectFile::getSectionIndex(DataRefImpl Sec) const {
   1166   return Sec.d.a;
   1167 }
   1168 
   1169 uint64_t WasmObjectFile::getSectionSize(DataRefImpl Sec) const {
   1170   const WasmSection &S = Sections[Sec.d.a];
   1171   return S.Content.size();
   1172 }
   1173 
   1174 std::error_code WasmObjectFile::getSectionContents(DataRefImpl Sec,
   1175                                                    StringRef &Res) const {
   1176   const WasmSection &S = Sections[Sec.d.a];
   1177   // This will never fail since wasm sections can never be empty (user-sections
   1178   // must have a name and non-user sections each have a defined structure).
   1179   Res = StringRef(reinterpret_cast<const char *>(S.Content.data()),
   1180                   S.Content.size());
   1181   return std::error_code();
   1182 }
   1183 
   1184 uint64_t WasmObjectFile::getSectionAlignment(DataRefImpl Sec) const {
   1185   return 1;
   1186 }
   1187 
   1188 bool WasmObjectFile::isSectionCompressed(DataRefImpl Sec) const {
   1189   return false;
   1190 }
   1191 
   1192 bool WasmObjectFile::isSectionText(DataRefImpl Sec) const {
   1193   return getWasmSection(Sec).Type == wasm::WASM_SEC_CODE;
   1194 }
   1195 
   1196 bool WasmObjectFile::isSectionData(DataRefImpl Sec) const {
   1197   return getWasmSection(Sec).Type == wasm::WASM_SEC_DATA;
   1198 }
   1199 
   1200 bool WasmObjectFile::isSectionBSS(DataRefImpl Sec) const { return false; }
   1201 
   1202 bool WasmObjectFile::isSectionVirtual(DataRefImpl Sec) const { return false; }
   1203 
   1204 bool WasmObjectFile::isSectionBitcode(DataRefImpl Sec) const { return false; }
   1205 
   1206 relocation_iterator WasmObjectFile::section_rel_begin(DataRefImpl Ref) const {
   1207   DataRefImpl RelocRef;
   1208   RelocRef.d.a = Ref.d.a;
   1209   RelocRef.d.b = 0;
   1210   return relocation_iterator(RelocationRef(RelocRef, this));
   1211 }
   1212 
   1213 relocation_iterator WasmObjectFile::section_rel_end(DataRefImpl Ref) const {
   1214   const WasmSection &Sec = getWasmSection(Ref);
   1215   DataRefImpl RelocRef;
   1216   RelocRef.d.a = Ref.d.a;
   1217   RelocRef.d.b = Sec.Relocations.size();
   1218   return relocation_iterator(RelocationRef(RelocRef, this));
   1219 }
   1220 
   1221 void WasmObjectFile::moveRelocationNext(DataRefImpl &Rel) const {
   1222   Rel.d.b++;
   1223 }
   1224 
   1225 uint64_t WasmObjectFile::getRelocationOffset(DataRefImpl Ref) const {
   1226   const wasm::WasmRelocation &Rel = getWasmRelocation(Ref);
   1227   return Rel.Offset;
   1228 }
   1229 
   1230 symbol_iterator WasmObjectFile::getRelocationSymbol(DataRefImpl Ref) const {
   1231   const wasm::WasmRelocation &Rel = getWasmRelocation(Ref);
   1232   if (Rel.Type == wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB)
   1233     return symbol_end();
   1234   DataRefImpl Sym;
   1235   Sym.d.a = Rel.Index;
   1236   Sym.d.b = 0;
   1237   return symbol_iterator(SymbolRef(Sym, this));
   1238 }
   1239 
   1240 uint64_t WasmObjectFile::getRelocationType(DataRefImpl Ref) const {
   1241   const wasm::WasmRelocation &Rel = getWasmRelocation(Ref);
   1242   return Rel.Type;
   1243 }
   1244 
   1245 void WasmObjectFile::getRelocationTypeName(
   1246     DataRefImpl Ref, SmallVectorImpl<char> &Result) const {
   1247   const wasm::WasmRelocation& Rel = getWasmRelocation(Ref);
   1248   StringRef Res = "Unknown";
   1249 
   1250 #define WASM_RELOC(name, value)  \
   1251   case wasm::name:              \
   1252     Res = #name;               \
   1253     break;
   1254 
   1255   switch (Rel.Type) {
   1256 #include "llvm/BinaryFormat/WasmRelocs.def"
   1257   }
   1258 
   1259 #undef WASM_RELOC
   1260 
   1261   Result.append(Res.begin(), Res.end());
   1262 }
   1263 
   1264 section_iterator WasmObjectFile::section_begin() const {
   1265   DataRefImpl Ref;
   1266   Ref.d.a = 0;
   1267   return section_iterator(SectionRef(Ref, this));
   1268 }
   1269 
   1270 section_iterator WasmObjectFile::section_end() const {
   1271   DataRefImpl Ref;
   1272   Ref.d.a = Sections.size();
   1273   return section_iterator(SectionRef(Ref, this));
   1274 }
   1275 
   1276 uint8_t WasmObjectFile::getBytesInAddress() const { return 4; }
   1277 
   1278 StringRef WasmObjectFile::getFileFormatName() const { return "WASM"; }
   1279 
   1280 Triple::ArchType WasmObjectFile::getArch() const { return Triple::wasm32; }
   1281 
   1282 SubtargetFeatures WasmObjectFile::getFeatures() const {
   1283   return SubtargetFeatures();
   1284 }
   1285 
   1286 bool WasmObjectFile::isRelocatableObject() const {
   1287   return HasLinkingSection;
   1288 }
   1289 
   1290 const WasmSection &WasmObjectFile::getWasmSection(DataRefImpl Ref) const {
   1291   assert(Ref.d.a < Sections.size());
   1292   return Sections[Ref.d.a];
   1293 }
   1294 
   1295 const WasmSection &
   1296 WasmObjectFile::getWasmSection(const SectionRef &Section) const {
   1297   return getWasmSection(Section.getRawDataRefImpl());
   1298 }
   1299 
   1300 const wasm::WasmRelocation &
   1301 WasmObjectFile::getWasmRelocation(const RelocationRef &Ref) const {
   1302   return getWasmRelocation(Ref.getRawDataRefImpl());
   1303 }
   1304 
   1305 const wasm::WasmRelocation &
   1306 WasmObjectFile::getWasmRelocation(DataRefImpl Ref) const {
   1307   assert(Ref.d.a < Sections.size());
   1308   const WasmSection& Sec = Sections[Ref.d.a];
   1309   assert(Ref.d.b < Sec.Relocations.size());
   1310   return Sec.Relocations[Ref.d.b];
   1311 }
   1312