OSDN Git Service

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