1 //===- lib/MC/WasmObjectWriter.cpp - Wasm File Writer ---------------------===//
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 // This file implements Wasm object file writer information.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "llvm/ADT/STLExtras.h"
15 #include "llvm/ADT/SmallPtrSet.h"
16 #include "llvm/BinaryFormat/Wasm.h"
17 #include "llvm/MC/MCAsmBackend.h"
18 #include "llvm/MC/MCAsmInfo.h"
19 #include "llvm/MC/MCAsmLayout.h"
20 #include "llvm/MC/MCAssembler.h"
21 #include "llvm/MC/MCContext.h"
22 #include "llvm/MC/MCExpr.h"
23 #include "llvm/MC/MCFixupKindInfo.h"
24 #include "llvm/MC/MCObjectFileInfo.h"
25 #include "llvm/MC/MCObjectWriter.h"
26 #include "llvm/MC/MCSectionWasm.h"
27 #include "llvm/MC/MCSymbolWasm.h"
28 #include "llvm/MC/MCValue.h"
29 #include "llvm/MC/MCWasmObjectWriter.h"
30 #include "llvm/Support/Casting.h"
31 #include "llvm/Support/Debug.h"
32 #include "llvm/Support/ErrorHandling.h"
33 #include "llvm/Support/LEB128.h"
34 #include "llvm/Support/StringSaver.h"
35 #include <vector>
36 
37 using namespace llvm;
38 
39 #define DEBUG_TYPE "mc"
40 
41 namespace {
42 
43 // For patching purposes, we need to remember where each section starts, both
44 // for patching up the section size field, and for patching up references to
45 // locations within the section.
46 struct SectionBookkeeping {
47   // Where the size of the section is written.
48   uint64_t SizeOffset;
49   // Where the contents of the section starts (after the header).
50   uint64_t ContentsOffset;
51 };
52 
53 // The signature of a wasm function, in a struct capable of being used as a
54 // DenseMap key.
55 struct WasmFunctionType {
56   // Support empty and tombstone instances, needed by DenseMap.
57   enum { Plain, Empty, Tombstone } State;
58 
59   // The return types of the function.
60   SmallVector<wasm::ValType, 1> Returns;
61 
62   // The parameter types of the function.
63   SmallVector<wasm::ValType, 4> Params;
64 
65   WasmFunctionType() : State(Plain) {}
66 
67   bool operator==(const WasmFunctionType &Other) const {
68     return State == Other.State && Returns == Other.Returns &&
69            Params == Other.Params;
70   }
71 };
72 
73 // Traits for using WasmFunctionType in a DenseMap.
74 struct WasmFunctionTypeDenseMapInfo {
75   static WasmFunctionType getEmptyKey() {
76     WasmFunctionType FuncTy;
77     FuncTy.State = WasmFunctionType::Empty;
78     return FuncTy;
79   }
80   static WasmFunctionType getTombstoneKey() {
81     WasmFunctionType FuncTy;
82     FuncTy.State = WasmFunctionType::Tombstone;
83     return FuncTy;
84   }
85   static unsigned getHashValue(const WasmFunctionType &FuncTy) {
86     uintptr_t Value = FuncTy.State;
87     for (wasm::ValType Ret : FuncTy.Returns)
88       Value += DenseMapInfo<int32_t>::getHashValue(int32_t(Ret));
89     for (wasm::ValType Param : FuncTy.Params)
90       Value += DenseMapInfo<int32_t>::getHashValue(int32_t(Param));
91     return Value;
92   }
93   static bool isEqual(const WasmFunctionType &LHS,
94                       const WasmFunctionType &RHS) {
95     return LHS == RHS;
96   }
97 };
98 
99 // A wasm import to be written into the import section.
100 struct WasmImport {
101   StringRef ModuleName;
102   StringRef FieldName;
103   unsigned Kind;
104   int32_t Type;
105 };
106 
107 // A wasm function to be written into the function section.
108 struct WasmFunction {
109   int32_t Type;
110   const MCSymbolWasm *Sym;
111 };
112 
113 // A wasm export to be written into the export section.
114 struct WasmExport {
115   StringRef FieldName;
116   unsigned Kind;
117   uint32_t Index;
118 };
119 
120 // A wasm global to be written into the global section.
121 struct WasmGlobal {
122   wasm::ValType Type;
123   bool IsMutable;
124   bool HasImport;
125   uint64_t InitialValue;
126   uint32_t ImportIndex;
127 };
128 
129 // Information about a single relocation.
130 struct WasmRelocationEntry {
131   uint64_t Offset;                  // Where is the relocation.
132   const MCSymbolWasm *Symbol;       // The symbol to relocate with.
133   int64_t Addend;                   // A value to add to the symbol.
134   unsigned Type;                    // The type of the relocation.
135   const MCSectionWasm *FixupSection;// The section the relocation is targeting.
136 
137   WasmRelocationEntry(uint64_t Offset, const MCSymbolWasm *Symbol,
138                       int64_t Addend, unsigned Type,
139                       const MCSectionWasm *FixupSection)
140       : Offset(Offset), Symbol(Symbol), Addend(Addend), Type(Type),
141         FixupSection(FixupSection) {}
142 
143   bool hasAddend() const {
144     switch (Type) {
145     case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_LEB:
146     case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_SLEB:
147     case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_I32:
148       return true;
149     default:
150       return false;
151     }
152   }
153 
154   void print(raw_ostream &Out) const {
155     Out << "Off=" << Offset << ", Sym=" << *Symbol << ", Addend=" << Addend
156         << ", Type=" << Type << ", FixupSection=" << FixupSection;
157   }
158 
159 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
160   LLVM_DUMP_METHOD void dump() const { print(dbgs()); }
161 #endif
162 };
163 
164 #if !defined(NDEBUG)
165 raw_ostream &operator<<(raw_ostream &OS, const WasmRelocationEntry &Rel) {
166   Rel.print(OS);
167   return OS;
168 }
169 #endif
170 
171 class WasmObjectWriter : public MCObjectWriter {
172   /// Helper struct for containing some precomputed information on symbols.
173   struct WasmSymbolData {
174     const MCSymbolWasm *Symbol;
175     StringRef Name;
176 
177     // Support lexicographic sorting.
178     bool operator<(const WasmSymbolData &RHS) const { return Name < RHS.Name; }
179   };
180 
181   /// The target specific Wasm writer instance.
182   std::unique_ptr<MCWasmObjectTargetWriter> TargetObjectWriter;
183 
184   // Relocations for fixing up references in the code section.
185   std::vector<WasmRelocationEntry> CodeRelocations;
186 
187   // Relocations for fixing up references in the data section.
188   std::vector<WasmRelocationEntry> DataRelocations;
189 
190   // Index values to use for fixing up call_indirect type indices.
191   // Maps function symbols to the index of the type of the function
192   DenseMap<const MCSymbolWasm *, uint32_t> TypeIndices;
193   // Maps function symbols to the table element index space. Used
194   // for TABLE_INDEX relocation types (i.e. address taken functions).
195   DenseMap<const MCSymbolWasm *, uint32_t> IndirectSymbolIndices;
196   // Maps function/global symbols to the function/global index space.
197   DenseMap<const MCSymbolWasm *, uint32_t> SymbolIndices;
198 
199   DenseMap<WasmFunctionType, int32_t, WasmFunctionTypeDenseMapInfo>
200       FunctionTypeIndices;
201   SmallVector<WasmFunctionType, 4> FunctionTypes;
202 
203   // TargetObjectWriter wrappers.
204   bool is64Bit() const { return TargetObjectWriter->is64Bit(); }
205   unsigned getRelocType(const MCValue &Target, const MCFixup &Fixup) const {
206     return TargetObjectWriter->getRelocType(Target, Fixup);
207   }
208 
209   void startSection(SectionBookkeeping &Section, unsigned SectionId,
210                     const char *Name = nullptr);
211   void endSection(SectionBookkeeping &Section);
212 
213 public:
214   WasmObjectWriter(MCWasmObjectTargetWriter *MOTW, raw_pwrite_stream &OS)
215       : MCObjectWriter(OS, /*IsLittleEndian=*/true), TargetObjectWriter(MOTW) {}
216 
217 private:
218   ~WasmObjectWriter() override;
219 
220   void reset() override {
221     CodeRelocations.clear();
222     DataRelocations.clear();
223     TypeIndices.clear();
224     SymbolIndices.clear();
225     IndirectSymbolIndices.clear();
226     FunctionTypeIndices.clear();
227     FunctionTypes.clear();
228     MCObjectWriter::reset();
229   }
230 
231   void writeHeader(const MCAssembler &Asm);
232 
233   void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,
234                         const MCFragment *Fragment, const MCFixup &Fixup,
235                         MCValue Target, bool &IsPCRel,
236                         uint64_t &FixedValue) override;
237 
238   void executePostLayoutBinding(MCAssembler &Asm,
239                                 const MCAsmLayout &Layout) override;
240 
241   void writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override;
242 
243   void writeString(const StringRef Str) {
244     encodeULEB128(Str.size(), getStream());
245     writeBytes(Str);
246   }
247 
248   void writeValueType(wasm::ValType Ty) {
249     encodeSLEB128(int32_t(Ty), getStream());
250   }
251 
252   void writeTypeSection(const SmallVector<WasmFunctionType, 4> &FunctionTypes);
253   void writeImportSection(const SmallVector<WasmImport, 4> &Imports);
254   void writeFunctionSection(const SmallVector<WasmFunction, 4> &Functions);
255   void writeTableSection(uint32_t NumElements);
256   void writeMemorySection(const SmallVector<char, 0> &DataBytes);
257   void writeGlobalSection(const SmallVector<WasmGlobal, 4> &Globals);
258   void writeExportSection(const SmallVector<WasmExport, 4> &Exports);
259   void writeElemSection(const SmallVector<uint32_t, 4> &TableElems);
260   void writeCodeSection(const MCAssembler &Asm, const MCAsmLayout &Layout,
261                         const SmallVector<WasmFunction, 4> &Functions);
262   uint64_t
263   writeDataSection(const SmallVector<char, 0> &DataBytes);
264   void writeNameSection(const SmallVector<WasmFunction, 4> &Functions,
265                         const SmallVector<WasmImport, 4> &Imports,
266                         uint32_t NumFuncImports);
267   void writeCodeRelocSection();
268   void writeDataRelocSection(uint64_t DataSectionHeaderSize);
269   void writeLinkingMetaDataSection(uint32_t DataSize, uint32_t DataAlignment,
270                                    ArrayRef<StringRef> WeakSymbols,
271                                    bool HasStackPointer,
272                                    uint32_t StackPointerGlobal);
273 
274   void applyRelocations(ArrayRef<WasmRelocationEntry> Relocations,
275                         uint64_t ContentsOffset);
276 
277   void writeRelocations(ArrayRef<WasmRelocationEntry> Relocations,
278                         uint64_t HeaderSize);
279   uint32_t getRelocationIndexValue(const WasmRelocationEntry &RelEntry);
280   uint32_t getFunctionType(const MCSymbolWasm& Symbol);
281   uint32_t registerFunctionType(const MCSymbolWasm& Symbol);
282 };
283 
284 } // end anonymous namespace
285 
286 WasmObjectWriter::~WasmObjectWriter() {}
287 
288 // Return the padding size to write a 32-bit value into a 5-byte ULEB128.
289 static unsigned PaddingFor5ByteULEB128(uint32_t X) {
290   return X == 0 ? 4 : (4u - (31u - countLeadingZeros(X)) / 7u);
291 }
292 
293 // Return the padding size to write a 32-bit value into a 5-byte SLEB128.
294 static unsigned PaddingFor5ByteSLEB128(int32_t X) {
295   return 5 - getSLEB128Size(X);
296 }
297 
298 // Write out a section header and a patchable section size field.
299 void WasmObjectWriter::startSection(SectionBookkeeping &Section,
300                                     unsigned SectionId,
301                                     const char *Name) {
302   assert((Name != nullptr) == (SectionId == wasm::WASM_SEC_CUSTOM) &&
303          "Only custom sections can have names");
304 
305   DEBUG(dbgs() << "startSection " << SectionId << ": " << Name << "\n");
306   encodeULEB128(SectionId, getStream());
307 
308   Section.SizeOffset = getStream().tell();
309 
310   // The section size. We don't know the size yet, so reserve enough space
311   // for any 32-bit value; we'll patch it later.
312   encodeULEB128(UINT32_MAX, getStream());
313 
314   // The position where the section starts, for measuring its size.
315   Section.ContentsOffset = getStream().tell();
316 
317   // Custom sections in wasm also have a string identifier.
318   if (SectionId == wasm::WASM_SEC_CUSTOM) {
319     assert(Name);
320     writeString(StringRef(Name));
321   }
322 }
323 
324 // Now that the section is complete and we know how big it is, patch up the
325 // section size field at the start of the section.
326 void WasmObjectWriter::endSection(SectionBookkeeping &Section) {
327   uint64_t Size = getStream().tell() - Section.ContentsOffset;
328   if (uint32_t(Size) != Size)
329     report_fatal_error("section size does not fit in a uint32_t");
330 
331   DEBUG(dbgs() << "endSection size=" << Size << "\n");
332   unsigned Padding = PaddingFor5ByteULEB128(Size);
333 
334   // Write the final section size to the payload_len field, which follows
335   // the section id byte.
336   uint8_t Buffer[16];
337   unsigned SizeLen = encodeULEB128(Size, Buffer, Padding);
338   assert(SizeLen == 5);
339   getStream().pwrite((char *)Buffer, SizeLen, Section.SizeOffset);
340 }
341 
342 // Emit the Wasm header.
343 void WasmObjectWriter::writeHeader(const MCAssembler &Asm) {
344   writeBytes(StringRef(wasm::WasmMagic, sizeof(wasm::WasmMagic)));
345   writeLE32(wasm::WasmVersion);
346 }
347 
348 void WasmObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
349                                                 const MCAsmLayout &Layout) {
350 }
351 
352 void WasmObjectWriter::recordRelocation(MCAssembler &Asm,
353                                         const MCAsmLayout &Layout,
354                                         const MCFragment *Fragment,
355                                         const MCFixup &Fixup, MCValue Target,
356                                         bool &IsPCRel, uint64_t &FixedValue) {
357   const auto &FixupSection = cast<MCSectionWasm>(*Fragment->getParent());
358   uint64_t C = Target.getConstant();
359   uint64_t FixupOffset = Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
360   MCContext &Ctx = Asm.getContext();
361 
362   if (const MCSymbolRefExpr *RefB = Target.getSymB()) {
363     assert(RefB->getKind() == MCSymbolRefExpr::VK_None &&
364            "Should not have constructed this");
365 
366     // Let A, B and C being the components of Target and R be the location of
367     // the fixup. If the fixup is not pcrel, we want to compute (A - B + C).
368     // If it is pcrel, we want to compute (A - B + C - R).
369 
370     // In general, Wasm has no relocations for -B. It can only represent (A + C)
371     // or (A + C - R). If B = R + K and the relocation is not pcrel, we can
372     // replace B to implement it: (A - R - K + C)
373     if (IsPCRel) {
374       Ctx.reportError(
375           Fixup.getLoc(),
376           "No relocation available to represent this relative expression");
377       return;
378     }
379 
380     const auto &SymB = cast<MCSymbolWasm>(RefB->getSymbol());
381 
382     if (SymB.isUndefined()) {
383       Ctx.reportError(Fixup.getLoc(),
384                       Twine("symbol '") + SymB.getName() +
385                           "' can not be undefined in a subtraction expression");
386       return;
387     }
388 
389     assert(!SymB.isAbsolute() && "Should have been folded");
390     const MCSection &SecB = SymB.getSection();
391     if (&SecB != &FixupSection) {
392       Ctx.reportError(Fixup.getLoc(),
393                       "Cannot represent a difference across sections");
394       return;
395     }
396 
397     uint64_t SymBOffset = Layout.getSymbolOffset(SymB);
398     uint64_t K = SymBOffset - FixupOffset;
399     IsPCRel = true;
400     C -= K;
401   }
402 
403   // We either rejected the fixup or folded B into C at this point.
404   const MCSymbolRefExpr *RefA = Target.getSymA();
405   const auto *SymA = RefA ? cast<MCSymbolWasm>(&RefA->getSymbol()) : nullptr;
406 
407   bool ViaWeakRef = false;
408   if (SymA && SymA->isVariable()) {
409     const MCExpr *Expr = SymA->getVariableValue();
410     if (const auto *Inner = dyn_cast<MCSymbolRefExpr>(Expr)) {
411       if (Inner->getKind() == MCSymbolRefExpr::VK_WEAKREF) {
412         SymA = cast<MCSymbolWasm>(&Inner->getSymbol());
413         ViaWeakRef = true;
414       }
415     }
416   }
417 
418   // Put any constant offset in an addend. Offsets can be negative, and
419   // LLVM expects wrapping, in contrast to wasm's immediates which can't
420   // be negative and don't wrap.
421   FixedValue = 0;
422 
423   if (SymA) {
424     if (ViaWeakRef)
425       llvm_unreachable("weakref used in reloc not yet implemented");
426     else
427       SymA->setUsedInReloc();
428   }
429 
430   assert(!IsPCRel);
431   assert(SymA);
432 
433   unsigned Type = getRelocType(Target, Fixup);
434 
435   WasmRelocationEntry Rec(FixupOffset, SymA, C, Type, &FixupSection);
436   DEBUG(dbgs() << "WasmReloc: " << Rec << "\n");
437 
438   if (FixupSection.hasInstructions())
439     CodeRelocations.push_back(Rec);
440   else
441     DataRelocations.push_back(Rec);
442 }
443 
444 // Write X as an (unsigned) LEB value at offset Offset in Stream, padded
445 // to allow patching.
446 static void
447 WritePatchableLEB(raw_pwrite_stream &Stream, uint32_t X, uint64_t Offset) {
448   uint8_t Buffer[5];
449   unsigned Padding = PaddingFor5ByteULEB128(X);
450   unsigned SizeLen = encodeULEB128(X, Buffer, Padding);
451   assert(SizeLen == 5);
452   Stream.pwrite((char *)Buffer, SizeLen, Offset);
453 }
454 
455 // Write X as an signed LEB value at offset Offset in Stream, padded
456 // to allow patching.
457 static void
458 WritePatchableSLEB(raw_pwrite_stream &Stream, int32_t X, uint64_t Offset) {
459   uint8_t Buffer[5];
460   unsigned Padding = PaddingFor5ByteSLEB128(X);
461   unsigned SizeLen = encodeSLEB128(X, Buffer, Padding);
462   assert(SizeLen == 5);
463   Stream.pwrite((char *)Buffer, SizeLen, Offset);
464 }
465 
466 // Write X as a plain integer value at offset Offset in Stream.
467 static void WriteI32(raw_pwrite_stream &Stream, uint32_t X, uint64_t Offset) {
468   uint8_t Buffer[4];
469   support::endian::write32le(Buffer, X);
470   Stream.pwrite((char *)Buffer, sizeof(Buffer), Offset);
471 }
472 
473 // Compute a value to write into the code at the location covered
474 // by RelEntry. This value isn't used by the static linker, since
475 // we have addends; it just serves to make the code more readable
476 // and to make standalone wasm modules directly usable.
477 static uint32_t ProvisionalValue(const WasmRelocationEntry &RelEntry) {
478   const MCSymbolWasm *Sym = RelEntry.Symbol;
479 
480   // For undefined symbols, use a hopefully invalid value.
481   if (!Sym->isDefined(/*SetUsed=*/false))
482     return UINT32_MAX;
483 
484   const auto &Section = cast<MCSectionWasm>(RelEntry.Symbol->getSection(false));
485   uint64_t Address = Section.getSectionOffset() + RelEntry.Addend;
486 
487   // Ignore overflow. LLVM allows address arithmetic to silently wrap.
488   uint32_t Value = Address;
489 
490   return Value;
491 }
492 
493 uint32_t WasmObjectWriter::getRelocationIndexValue(
494     const WasmRelocationEntry &RelEntry) {
495   switch (RelEntry.Type) {
496   case wasm::R_WEBASSEMBLY_TABLE_INDEX_SLEB:
497   case wasm::R_WEBASSEMBLY_TABLE_INDEX_I32:
498     if (!IndirectSymbolIndices.count(RelEntry.Symbol))
499       report_fatal_error("symbol not found table index space: " +
500                          RelEntry.Symbol->getName());
501     return IndirectSymbolIndices[RelEntry.Symbol];
502   case wasm::R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
503   case wasm::R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
504   case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_LEB:
505   case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_SLEB:
506   case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_I32:
507     if (!SymbolIndices.count(RelEntry.Symbol))
508       report_fatal_error("symbol not found function/global index space: " +
509                          RelEntry.Symbol->getName());
510     return SymbolIndices[RelEntry.Symbol];
511   case wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB:
512     if (!TypeIndices.count(RelEntry.Symbol))
513       report_fatal_error("symbol not found in type index space: " +
514                          RelEntry.Symbol->getName());
515     return TypeIndices[RelEntry.Symbol];
516   default:
517     llvm_unreachable("invalid relocation type");
518   }
519 }
520 
521 // Apply the portions of the relocation records that we can handle ourselves
522 // directly.
523 void WasmObjectWriter::applyRelocations(
524     ArrayRef<WasmRelocationEntry> Relocations, uint64_t ContentsOffset) {
525   raw_pwrite_stream &Stream = getStream();
526   for (const WasmRelocationEntry &RelEntry : Relocations) {
527     uint64_t Offset = ContentsOffset +
528                       RelEntry.FixupSection->getSectionOffset() +
529                       RelEntry.Offset;
530 
531     DEBUG(dbgs() << "applyRelocation: " << RelEntry << "\n");
532     switch (RelEntry.Type) {
533     case wasm::R_WEBASSEMBLY_TABLE_INDEX_SLEB:
534     case wasm::R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
535     case wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB:
536     case wasm::R_WEBASSEMBLY_GLOBAL_INDEX_LEB: {
537       uint32_t Index = getRelocationIndexValue(RelEntry);
538       WritePatchableSLEB(Stream, Index, Offset);
539       break;
540     }
541     case wasm::R_WEBASSEMBLY_TABLE_INDEX_I32: {
542       uint32_t Index = getRelocationIndexValue(RelEntry);
543       WriteI32(Stream, Index, Offset);
544       break;
545     }
546     case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_SLEB: {
547       uint32_t Value = ProvisionalValue(RelEntry);
548       WritePatchableSLEB(Stream, Value, Offset);
549       break;
550     }
551     case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_LEB: {
552       uint32_t Value = ProvisionalValue(RelEntry);
553       WritePatchableLEB(Stream, Value, Offset);
554       break;
555     }
556     case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_I32: {
557       uint32_t Value = ProvisionalValue(RelEntry);
558       WriteI32(Stream, Value, Offset);
559       break;
560     }
561     default:
562       llvm_unreachable("invalid relocation type");
563     }
564   }
565 }
566 
567 // Write out the portions of the relocation records that the linker will
568 // need to handle.
569 void WasmObjectWriter::writeRelocations(
570     ArrayRef<WasmRelocationEntry> Relocations, uint64_t HeaderSize) {
571   raw_pwrite_stream &Stream = getStream();
572   for (const WasmRelocationEntry& RelEntry : Relocations) {
573 
574     uint64_t Offset = RelEntry.Offset +
575                       RelEntry.FixupSection->getSectionOffset() + HeaderSize;
576     uint32_t Index = getRelocationIndexValue(RelEntry);
577 
578     encodeULEB128(RelEntry.Type, Stream);
579     encodeULEB128(Offset, Stream);
580     encodeULEB128(Index, Stream);
581     if (RelEntry.hasAddend())
582       encodeSLEB128(RelEntry.Addend, Stream);
583   }
584 }
585 
586 void WasmObjectWriter::writeTypeSection(
587     const SmallVector<WasmFunctionType, 4> &FunctionTypes) {
588   if (FunctionTypes.empty())
589     return;
590 
591   SectionBookkeeping Section;
592   startSection(Section, wasm::WASM_SEC_TYPE);
593 
594   encodeULEB128(FunctionTypes.size(), getStream());
595 
596   for (const WasmFunctionType &FuncTy : FunctionTypes) {
597     encodeSLEB128(wasm::WASM_TYPE_FUNC, getStream());
598     encodeULEB128(FuncTy.Params.size(), getStream());
599     for (wasm::ValType Ty : FuncTy.Params)
600       writeValueType(Ty);
601     encodeULEB128(FuncTy.Returns.size(), getStream());
602     for (wasm::ValType Ty : FuncTy.Returns)
603       writeValueType(Ty);
604   }
605 
606   endSection(Section);
607 }
608 
609 
610 void WasmObjectWriter::writeImportSection(
611     const SmallVector<WasmImport, 4> &Imports) {
612   if (Imports.empty())
613     return;
614 
615   SectionBookkeeping Section;
616   startSection(Section, wasm::WASM_SEC_IMPORT);
617 
618   encodeULEB128(Imports.size(), getStream());
619   for (const WasmImport &Import : Imports) {
620     writeString(Import.ModuleName);
621     writeString(Import.FieldName);
622 
623     encodeULEB128(Import.Kind, getStream());
624 
625     switch (Import.Kind) {
626     case wasm::WASM_EXTERNAL_FUNCTION:
627       encodeULEB128(Import.Type, getStream());
628       break;
629     case wasm::WASM_EXTERNAL_GLOBAL:
630       encodeSLEB128(int32_t(Import.Type), getStream());
631       encodeULEB128(0, getStream()); // mutability
632       break;
633     default:
634       llvm_unreachable("unsupported import kind");
635     }
636   }
637 
638   endSection(Section);
639 }
640 
641 void WasmObjectWriter::writeFunctionSection(
642     const SmallVector<WasmFunction, 4> &Functions) {
643   if (Functions.empty())
644     return;
645 
646   SectionBookkeeping Section;
647   startSection(Section, wasm::WASM_SEC_FUNCTION);
648 
649   encodeULEB128(Functions.size(), getStream());
650   for (const WasmFunction &Func : Functions)
651     encodeULEB128(Func.Type, getStream());
652 
653   endSection(Section);
654 }
655 
656 void WasmObjectWriter::writeTableSection(uint32_t NumElements) {
657   // For now, always emit the table section, since indirect calls are not
658   // valid without it. In the future, we could perhaps be more clever and omit
659   // it if there are no indirect calls.
660 
661   SectionBookkeeping Section;
662   startSection(Section, wasm::WASM_SEC_TABLE);
663 
664   encodeULEB128(1, getStream());                       // The number of tables.
665                                                        // Fixed to 1 for now.
666   encodeSLEB128(wasm::WASM_TYPE_ANYFUNC, getStream()); // Type of table
667   encodeULEB128(0, getStream());                       // flags
668   encodeULEB128(NumElements, getStream());             // initial
669 
670   endSection(Section);
671 }
672 
673 void WasmObjectWriter::writeMemorySection(
674     const SmallVector<char, 0> &DataBytes) {
675   // For now, always emit the memory section, since loads and stores are not
676   // valid without it. In the future, we could perhaps be more clever and omit
677   // it if there are no loads or stores.
678   SectionBookkeeping Section;
679   uint32_t NumPages =
680       (DataBytes.size() + wasm::WasmPageSize - 1) / wasm::WasmPageSize;
681 
682   startSection(Section, wasm::WASM_SEC_MEMORY);
683   encodeULEB128(1, getStream()); // number of memory spaces
684 
685   encodeULEB128(0, getStream()); // flags
686   encodeULEB128(NumPages, getStream()); // initial
687 
688   endSection(Section);
689 }
690 
691 void WasmObjectWriter::writeGlobalSection(
692     const SmallVector<WasmGlobal, 4> &Globals) {
693   if (Globals.empty())
694     return;
695 
696   SectionBookkeeping Section;
697   startSection(Section, wasm::WASM_SEC_GLOBAL);
698 
699   encodeULEB128(Globals.size(), getStream());
700   for (const WasmGlobal &Global : Globals) {
701     writeValueType(Global.Type);
702     write8(Global.IsMutable);
703 
704     if (Global.HasImport) {
705       assert(Global.InitialValue == 0);
706       write8(wasm::WASM_OPCODE_GET_GLOBAL);
707       encodeULEB128(Global.ImportIndex, getStream());
708     } else {
709       assert(Global.ImportIndex == 0);
710       write8(wasm::WASM_OPCODE_I32_CONST);
711       encodeSLEB128(Global.InitialValue, getStream()); // offset
712     }
713     write8(wasm::WASM_OPCODE_END);
714   }
715 
716   endSection(Section);
717 }
718 
719 void WasmObjectWriter::writeExportSection(
720     const SmallVector<WasmExport, 4> &Exports) {
721   if (Exports.empty())
722     return;
723 
724   SectionBookkeeping Section;
725   startSection(Section, wasm::WASM_SEC_EXPORT);
726 
727   encodeULEB128(Exports.size(), getStream());
728   for (const WasmExport &Export : Exports) {
729     writeString(Export.FieldName);
730     encodeSLEB128(Export.Kind, getStream());
731     encodeULEB128(Export.Index, getStream());
732   }
733 
734   endSection(Section);
735 }
736 
737 void WasmObjectWriter::writeElemSection(
738     const SmallVector<uint32_t, 4> &TableElems) {
739   if (TableElems.empty())
740     return;
741 
742   SectionBookkeeping Section;
743   startSection(Section, wasm::WASM_SEC_ELEM);
744 
745   encodeULEB128(1, getStream()); // number of "segments"
746   encodeULEB128(0, getStream()); // the table index
747 
748   // init expr for starting offset
749   write8(wasm::WASM_OPCODE_I32_CONST);
750   encodeSLEB128(0, getStream());
751   write8(wasm::WASM_OPCODE_END);
752 
753   encodeULEB128(TableElems.size(), getStream());
754   for (uint32_t Elem : TableElems)
755     encodeULEB128(Elem, getStream());
756 
757   endSection(Section);
758 }
759 
760 void WasmObjectWriter::writeCodeSection(
761     const MCAssembler &Asm, const MCAsmLayout &Layout,
762     const SmallVector<WasmFunction, 4> &Functions) {
763   if (Functions.empty())
764     return;
765 
766   SectionBookkeeping Section;
767   startSection(Section, wasm::WASM_SEC_CODE);
768 
769   encodeULEB128(Functions.size(), getStream());
770 
771   for (const WasmFunction &Func : Functions) {
772     auto &FuncSection = static_cast<MCSectionWasm &>(Func.Sym->getSection());
773 
774     int64_t Size = 0;
775     if (!Func.Sym->getSize()->evaluateAsAbsolute(Size, Layout))
776       report_fatal_error(".size expression must be evaluatable");
777 
778     encodeULEB128(Size, getStream());
779 
780     FuncSection.setSectionOffset(getStream().tell() - Section.ContentsOffset);
781 
782     Asm.writeSectionData(&FuncSection, Layout);
783   }
784 
785   // Apply fixups.
786   applyRelocations(CodeRelocations, Section.ContentsOffset);
787 
788   endSection(Section);
789 }
790 
791 uint64_t WasmObjectWriter::writeDataSection(
792     const SmallVector<char, 0> &DataBytes) {
793   if (DataBytes.empty())
794     return 0;
795 
796   SectionBookkeeping Section;
797   startSection(Section, wasm::WASM_SEC_DATA);
798 
799   encodeULEB128(1, getStream()); // count
800   encodeULEB128(0, getStream()); // memory index
801   write8(wasm::WASM_OPCODE_I32_CONST);
802   encodeSLEB128(0, getStream()); // offset
803   write8(wasm::WASM_OPCODE_END);
804   encodeULEB128(DataBytes.size(), getStream()); // size
805   uint32_t HeaderSize = getStream().tell() - Section.ContentsOffset;
806   writeBytes(DataBytes); // data
807 
808   // Apply fixups.
809   applyRelocations(DataRelocations, Section.ContentsOffset + HeaderSize);
810 
811   endSection(Section);
812   return HeaderSize;
813 }
814 
815 void WasmObjectWriter::writeNameSection(
816     const SmallVector<WasmFunction, 4> &Functions,
817     const SmallVector<WasmImport, 4> &Imports,
818     unsigned NumFuncImports) {
819   uint32_t TotalFunctions = NumFuncImports + Functions.size();
820   if (TotalFunctions == 0)
821     return;
822 
823   SectionBookkeeping Section;
824   startSection(Section, wasm::WASM_SEC_CUSTOM, "name");
825   SectionBookkeeping SubSection;
826   startSection(SubSection, wasm::WASM_NAMES_FUNCTION);
827 
828   encodeULEB128(TotalFunctions, getStream());
829   uint32_t Index = 0;
830   for (const WasmImport &Import : Imports) {
831     if (Import.Kind == wasm::WASM_EXTERNAL_FUNCTION) {
832       encodeULEB128(Index, getStream());
833       writeString(Import.FieldName);
834       ++Index;
835     }
836   }
837   for (const WasmFunction &Func : Functions) {
838     encodeULEB128(Index, getStream());
839     writeString(Func.Sym->getName());
840     ++Index;
841   }
842 
843   endSection(SubSection);
844   endSection(Section);
845 }
846 
847 void WasmObjectWriter::writeCodeRelocSection() {
848   // See: https://github.com/WebAssembly/tool-conventions/blob/master/Linking.md
849   // for descriptions of the reloc sections.
850 
851   if (CodeRelocations.empty())
852     return;
853 
854   SectionBookkeeping Section;
855   startSection(Section, wasm::WASM_SEC_CUSTOM, "reloc.CODE");
856 
857   encodeULEB128(wasm::WASM_SEC_CODE, getStream());
858   encodeULEB128(CodeRelocations.size(), getStream());
859 
860   writeRelocations(CodeRelocations, 0);
861 
862   endSection(Section);
863 }
864 
865 void WasmObjectWriter::writeDataRelocSection(uint64_t DataSectionHeaderSize) {
866   // See: https://github.com/WebAssembly/tool-conventions/blob/master/Linking.md
867   // for descriptions of the reloc sections.
868 
869   if (DataRelocations.empty())
870     return;
871 
872   SectionBookkeeping Section;
873   startSection(Section, wasm::WASM_SEC_CUSTOM, "reloc.DATA");
874 
875   encodeULEB128(wasm::WASM_SEC_DATA, getStream());
876   encodeULEB128(DataRelocations.size(), getStream());
877 
878   writeRelocations(DataRelocations, DataSectionHeaderSize);
879 
880   endSection(Section);
881 }
882 
883 void WasmObjectWriter::writeLinkingMetaDataSection(
884     uint32_t DataSize, uint32_t DataAlignment, ArrayRef<StringRef> WeakSymbols,
885     bool HasStackPointer, uint32_t StackPointerGlobal) {
886   SectionBookkeeping Section;
887   startSection(Section, wasm::WASM_SEC_CUSTOM, "linking");
888   SectionBookkeeping SubSection;
889 
890   if (HasStackPointer) {
891     startSection(SubSection, wasm::WASM_STACK_POINTER);
892     encodeULEB128(StackPointerGlobal, getStream()); // id
893     endSection(SubSection);
894   }
895 
896   if (WeakSymbols.size() != 0) {
897     startSection(SubSection, wasm::WASM_SYMBOL_INFO);
898     encodeULEB128(WeakSymbols.size(), getStream());
899     for (const StringRef Export: WeakSymbols) {
900       writeString(Export);
901       encodeULEB128(wasm::WASM_SYMBOL_FLAG_WEAK, getStream());
902     }
903     endSection(SubSection);
904   }
905 
906   if (DataSize > 0) {
907     startSection(SubSection, wasm::WASM_DATA_SIZE);
908     encodeULEB128(DataSize, getStream());
909     endSection(SubSection);
910 
911     startSection(SubSection, wasm::WASM_DATA_ALIGNMENT);
912     encodeULEB128(DataAlignment, getStream());
913     endSection(SubSection);
914   }
915 
916   endSection(Section);
917 }
918 
919 uint32_t WasmObjectWriter::getFunctionType(const MCSymbolWasm& Symbol) {
920   assert(Symbol.isFunction());
921   assert(TypeIndices.count(&Symbol));
922   return TypeIndices[&Symbol];
923 }
924 
925 uint32_t WasmObjectWriter::registerFunctionType(const MCSymbolWasm& Symbol) {
926   assert(Symbol.isFunction());
927 
928   WasmFunctionType F;
929   if (Symbol.isVariable()) {
930     const MCExpr *Expr = Symbol.getVariableValue();
931     auto *Inner = dyn_cast<MCSymbolRefExpr>(Expr);
932     const auto *ResolvedSym = cast<MCSymbolWasm>(&Inner->getSymbol());
933     F.Returns = ResolvedSym->getReturns();
934     F.Params = ResolvedSym->getParams();
935   } else {
936     F.Returns = Symbol.getReturns();
937     F.Params = Symbol.getParams();
938   }
939 
940   auto Pair =
941       FunctionTypeIndices.insert(std::make_pair(F, FunctionTypes.size()));
942   if (Pair.second)
943     FunctionTypes.push_back(F);
944   TypeIndices[&Symbol] = Pair.first->second;
945 
946   DEBUG(dbgs() << "registerFunctionType: " << Symbol << " new:" << Pair.second << "\n");
947   DEBUG(dbgs() << "  -> type index: " << Pair.first->second << "\n");
948   return Pair.first->second;
949 }
950 
951 void WasmObjectWriter::writeObject(MCAssembler &Asm,
952                                    const MCAsmLayout &Layout) {
953   DEBUG(dbgs() << "WasmObjectWriter::writeObject\n");
954   MCContext &Ctx = Asm.getContext();
955   wasm::ValType PtrType = is64Bit() ? wasm::ValType::I64 : wasm::ValType::I32;
956 
957   // Collect information from the available symbols.
958   SmallVector<WasmFunction, 4> Functions;
959   SmallVector<uint32_t, 4> TableElems;
960   SmallVector<WasmGlobal, 4> Globals;
961   SmallVector<WasmImport, 4> Imports;
962   SmallVector<WasmExport, 4> Exports;
963   SmallVector<StringRef, 4> WeakSymbols;
964   SmallPtrSet<const MCSymbolWasm *, 4> IsAddressTaken;
965   unsigned NumFuncImports = 0;
966   unsigned NumGlobalImports = 0;
967   SmallVector<char, 0> DataBytes;
968   uint32_t DataAlignment = 1;
969   uint32_t StackPointerGlobal = 0;
970   bool HasStackPointer = false;
971 
972   // Populate the IsAddressTaken set.
973   for (const WasmRelocationEntry &RelEntry : CodeRelocations) {
974     switch (RelEntry.Type) {
975     case wasm::R_WEBASSEMBLY_TABLE_INDEX_SLEB:
976     case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_SLEB:
977       IsAddressTaken.insert(RelEntry.Symbol);
978       break;
979     default:
980       break;
981     }
982   }
983   for (const WasmRelocationEntry &RelEntry : DataRelocations) {
984     switch (RelEntry.Type) {
985     case wasm::R_WEBASSEMBLY_TABLE_INDEX_I32:
986     case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_I32:
987       IsAddressTaken.insert(RelEntry.Symbol);
988       break;
989     default:
990       break;
991     }
992   }
993 
994   // Populate the Imports set.
995   for (const MCSymbol &S : Asm.symbols()) {
996     const auto &WS = static_cast<const MCSymbolWasm &>(S);
997 
998     if (WS.isTemporary())
999       continue;
1000 
1001     if (WS.isFunction())
1002       registerFunctionType(WS);
1003 
1004     // If the symbol is not defined in this translation unit, import it.
1005     if (!WS.isDefined(/*SetUsed=*/false) || WS.isVariable()) {
1006       WasmImport Import;
1007       Import.ModuleName = WS.getModuleName();
1008       Import.FieldName = WS.getName();
1009 
1010       if (WS.isFunction()) {
1011         Import.Kind = wasm::WASM_EXTERNAL_FUNCTION;
1012         Import.Type = getFunctionType(WS);
1013         SymbolIndices[&WS] = NumFuncImports;
1014         ++NumFuncImports;
1015       } else {
1016         Import.Kind = wasm::WASM_EXTERNAL_GLOBAL;
1017         Import.Type = int32_t(PtrType);
1018         SymbolIndices[&WS] = NumGlobalImports;
1019         ++NumGlobalImports;
1020       }
1021 
1022       Imports.push_back(Import);
1023     }
1024   }
1025 
1026   // In the special .global_variables section, we've encoded global
1027   // variables used by the function. Translate them into the Globals
1028   // list.
1029   MCSectionWasm *GlobalVars = Ctx.getWasmSection(".global_variables", 0, 0);
1030   if (!GlobalVars->getFragmentList().empty()) {
1031     if (GlobalVars->getFragmentList().size() != 1)
1032       report_fatal_error("only one .global_variables fragment supported");
1033     const MCFragment &Frag = *GlobalVars->begin();
1034     if (Frag.hasInstructions() || Frag.getKind() != MCFragment::FT_Data)
1035       report_fatal_error("only data supported in .global_variables");
1036     const auto &DataFrag = cast<MCDataFragment>(Frag);
1037     if (!DataFrag.getFixups().empty())
1038       report_fatal_error("fixups not supported in .global_variables");
1039     const SmallVectorImpl<char> &Contents = DataFrag.getContents();
1040     for (const uint8_t *p = (const uint8_t *)Contents.data(),
1041                      *end = (const uint8_t *)Contents.data() + Contents.size();
1042          p != end; ) {
1043       WasmGlobal G;
1044       if (end - p < 3)
1045         report_fatal_error("truncated global variable encoding");
1046       G.Type = wasm::ValType(int8_t(*p++));
1047       G.IsMutable = bool(*p++);
1048       G.HasImport = bool(*p++);
1049       if (G.HasImport) {
1050         G.InitialValue = 0;
1051 
1052         WasmImport Import;
1053         Import.ModuleName = (const char *)p;
1054         const uint8_t *nul = (const uint8_t *)memchr(p, '\0', end - p);
1055         if (!nul)
1056           report_fatal_error("global module name must be nul-terminated");
1057         p = nul + 1;
1058         nul = (const uint8_t *)memchr(p, '\0', end - p);
1059         if (!nul)
1060           report_fatal_error("global base name must be nul-terminated");
1061         Import.FieldName = (const char *)p;
1062         p = nul + 1;
1063 
1064         Import.Kind = wasm::WASM_EXTERNAL_GLOBAL;
1065         Import.Type = int32_t(G.Type);
1066 
1067         G.ImportIndex = NumGlobalImports;
1068         ++NumGlobalImports;
1069 
1070         Imports.push_back(Import);
1071       } else {
1072         unsigned n;
1073         G.InitialValue = decodeSLEB128(p, &n);
1074         G.ImportIndex = 0;
1075         if ((ptrdiff_t)n > end - p)
1076           report_fatal_error("global initial value must be valid SLEB128");
1077         p += n;
1078       }
1079       Globals.push_back(G);
1080     }
1081   }
1082 
1083   // In the special .stack_pointer section, we've encoded the stack pointer
1084   // index.
1085   MCSectionWasm *StackPtr = Ctx.getWasmSection(".stack_pointer", 0, 0);
1086   if (!StackPtr->getFragmentList().empty()) {
1087     if (StackPtr->getFragmentList().size() != 1)
1088       report_fatal_error("only one .stack_pointer fragment supported");
1089     const MCFragment &Frag = *StackPtr->begin();
1090     if (Frag.hasInstructions() || Frag.getKind() != MCFragment::FT_Data)
1091       report_fatal_error("only data supported in .stack_pointer");
1092     const auto &DataFrag = cast<MCDataFragment>(Frag);
1093     if (!DataFrag.getFixups().empty())
1094       report_fatal_error("fixups not supported in .stack_pointer");
1095     const SmallVectorImpl<char> &Contents = DataFrag.getContents();
1096     if (Contents.size() != 4)
1097       report_fatal_error("only one entry supported in .stack_pointer");
1098     HasStackPointer = true;
1099     StackPointerGlobal = NumGlobalImports + *(const int32_t *)Contents.data();
1100   }
1101 
1102   // Handle regular defined and undefined symbols.
1103   for (const MCSymbol &S : Asm.symbols()) {
1104     // Ignore unnamed temporary symbols, which aren't ever exported, imported,
1105     // or used in relocations.
1106     if (S.isTemporary() && S.getName().empty())
1107       continue;
1108 
1109     const auto &WS = static_cast<const MCSymbolWasm &>(S);
1110     DEBUG(dbgs() << "MCSymbol: '" << S << "'"
1111                  << " isDefined=" << S.isDefined() << " isExternal="
1112                  << S.isExternal() << " isTemporary=" << S.isTemporary()
1113                  << " isFunction=" << WS.isFunction()
1114                  << " isWeak=" << WS.isWeak()
1115                  << " isVariable=" << WS.isVariable() << "\n");
1116 
1117     if (WS.isWeak())
1118       WeakSymbols.push_back(WS.getName());
1119 
1120     if (WS.isVariable())
1121       continue;
1122 
1123     unsigned Index;
1124 
1125     if (WS.isFunction()) {
1126       if (WS.isDefined(/*SetUsed=*/false)) {
1127         if (WS.getOffset() != 0)
1128           report_fatal_error(
1129               "function sections must contain one function each");
1130 
1131         if (WS.getSize() == 0)
1132           report_fatal_error(
1133               "function symbols must have a size set with .size");
1134 
1135         // A definition. Take the next available index.
1136         Index = NumFuncImports + Functions.size();
1137 
1138         // Prepare the function.
1139         WasmFunction Func;
1140         Func.Type = getFunctionType(WS);
1141         Func.Sym = &WS;
1142         SymbolIndices[&WS] = Index;
1143         Functions.push_back(Func);
1144       } else {
1145         // An import; the index was assigned above.
1146         Index = SymbolIndices.find(&WS)->second;
1147       }
1148 
1149       DEBUG(dbgs() << "  -> function index: " << Index << "\n");
1150 
1151       // If needed, prepare the function to be called indirectly.
1152       if (IsAddressTaken.count(&WS) != 0) {
1153         IndirectSymbolIndices[&WS] = TableElems.size();
1154         DEBUG(dbgs() << "  -> adding to table: " << TableElems.size() << "\n");
1155         TableElems.push_back(Index);
1156       }
1157     } else {
1158       if (WS.isTemporary() && !WS.getSize())
1159         continue;
1160 
1161       if (!WS.isDefined(/*SetUsed=*/false))
1162         continue;
1163 
1164       if (WS.getOffset() != 0)
1165         report_fatal_error("data sections must contain one variable each: " +
1166                            WS.getName());
1167       if (!WS.getSize())
1168         report_fatal_error("data symbols must have a size set with .size: " +
1169                            WS.getName());
1170 
1171       int64_t Size = 0;
1172       if (!WS.getSize()->evaluateAsAbsolute(Size, Layout))
1173         report_fatal_error(".size expression must be evaluatable");
1174 
1175       auto &DataSection = static_cast<MCSectionWasm &>(WS.getSection());
1176 
1177       if (uint64_t(Size) != Layout.getSectionFileSize(&DataSection))
1178         report_fatal_error("data sections must contain at most one variable");
1179 
1180       DataBytes.resize(alignTo(DataBytes.size(), DataSection.getAlignment()));
1181       DataAlignment = std::max(DataAlignment, DataSection.getAlignment());
1182 
1183       DataSection.setSectionOffset(DataBytes.size());
1184 
1185       for (const MCFragment &Frag : DataSection) {
1186         if (Frag.hasInstructions())
1187           report_fatal_error("only data supported in data sections");
1188 
1189         if (auto *Align = dyn_cast<MCAlignFragment>(&Frag)) {
1190           if (Align->getValueSize() != 1)
1191             report_fatal_error("only byte values supported for alignment");
1192           // If nops are requested, use zeros, as this is the data section.
1193           uint8_t Value = Align->hasEmitNops() ? 0 : Align->getValue();
1194           uint64_t Size = std::min<uint64_t>(alignTo(DataBytes.size(),
1195                                                      Align->getAlignment()),
1196                                              DataBytes.size() +
1197                                                  Align->getMaxBytesToEmit());
1198           DataBytes.resize(Size, Value);
1199         } else if (auto *Fill = dyn_cast<MCFillFragment>(&Frag)) {
1200           DataBytes.insert(DataBytes.end(), Fill->getSize(), Fill->getValue());
1201         } else {
1202           const auto &DataFrag = cast<MCDataFragment>(Frag);
1203           const SmallVectorImpl<char> &Contents = DataFrag.getContents();
1204 
1205           DataBytes.insert(DataBytes.end(), Contents.begin(), Contents.end());
1206         }
1207       }
1208 
1209       // For each global, prepare a corresponding wasm global holding its
1210       // address.  For externals these will also be named exports.
1211       Index = NumGlobalImports + Globals.size();
1212 
1213       WasmGlobal Global;
1214       Global.Type = PtrType;
1215       Global.IsMutable = false;
1216       Global.HasImport = false;
1217       Global.InitialValue = DataSection.getSectionOffset();
1218       Global.ImportIndex = 0;
1219       SymbolIndices[&WS] = Index;
1220       DEBUG(dbgs() << "  -> global index: " << Index << "\n");
1221       Globals.push_back(Global);
1222     }
1223 
1224     // If the symbol is visible outside this translation unit, export it.
1225     if ((WS.isExternal() && WS.isDefined(/*SetUsed=*/false))) {
1226       WasmExport Export;
1227       Export.FieldName = WS.getName();
1228       Export.Index = Index;
1229       if (WS.isFunction())
1230         Export.Kind = wasm::WASM_EXTERNAL_FUNCTION;
1231       else
1232         Export.Kind = wasm::WASM_EXTERNAL_GLOBAL;
1233       DEBUG(dbgs() << "  -> export " << Exports.size() << "\n");
1234       Exports.push_back(Export);
1235     }
1236   }
1237 
1238   // Handle weak aliases. We need to process these in a separate pass because
1239   // we need to have processed the target of the alias before the alias itself
1240   // and the symbols are not necessarily ordered in this way.
1241   for (const MCSymbol &S : Asm.symbols()) {
1242     if (!S.isVariable())
1243       continue;
1244     assert(S.isDefined(/*SetUsed=*/false));
1245 
1246     const auto &WS = static_cast<const MCSymbolWasm &>(S);
1247     // Find the target symbol of this weak alias and export that index
1248     const MCExpr *Expr = WS.getVariableValue();
1249     auto *Inner = dyn_cast<MCSymbolRefExpr>(Expr);
1250     const auto *ResolvedSym = cast<MCSymbolWasm>(&Inner->getSymbol());
1251     DEBUG(dbgs() << WS.getName() << ": weak alias of '" << *ResolvedSym << "'\n");
1252     assert(SymbolIndices.count(ResolvedSym) > 0);
1253     uint32_t Index = SymbolIndices.find(ResolvedSym)->second;
1254     DEBUG(dbgs() << "  -> index:" << Index << "\n");
1255 
1256     WasmExport Export;
1257     Export.FieldName = WS.getName();
1258     Export.Index = Index;
1259     if (WS.isFunction())
1260       Export.Kind = wasm::WASM_EXTERNAL_FUNCTION;
1261     else
1262       Export.Kind = wasm::WASM_EXTERNAL_GLOBAL;
1263     DEBUG(dbgs() << "  -> export " << Exports.size() << "\n");
1264     Exports.push_back(Export);
1265   }
1266 
1267   // Add types for indirect function calls.
1268   for (const WasmRelocationEntry &Fixup : CodeRelocations) {
1269     if (Fixup.Type != wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB)
1270       continue;
1271 
1272     registerFunctionType(*Fixup.Symbol);
1273   }
1274 
1275   // Write out the Wasm header.
1276   writeHeader(Asm);
1277 
1278   writeTypeSection(FunctionTypes);
1279   writeImportSection(Imports);
1280   writeFunctionSection(Functions);
1281   writeTableSection(TableElems.size());
1282   writeMemorySection(DataBytes);
1283   writeGlobalSection(Globals);
1284   writeExportSection(Exports);
1285   // TODO: Start Section
1286   writeElemSection(TableElems);
1287   writeCodeSection(Asm, Layout, Functions);
1288   uint64_t DataSectionHeaderSize = writeDataSection(DataBytes);
1289   writeNameSection(Functions, Imports, NumFuncImports);
1290   writeCodeRelocSection();
1291   writeDataRelocSection(DataSectionHeaderSize);
1292   writeLinkingMetaDataSection(DataBytes.size(), DataAlignment, WeakSymbols, HasStackPointer, StackPointerGlobal);
1293 
1294   // TODO: Translate the .comment section to the output.
1295   // TODO: Translate debug sections to the output.
1296 }
1297 
1298 MCObjectWriter *llvm::createWasmObjectWriter(MCWasmObjectTargetWriter *MOTW,
1299                                              raw_pwrite_stream &OS) {
1300   return new WasmObjectWriter(MOTW, OS);
1301 }
1302