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