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/MC/MCAsmBackend.h"
17 #include "llvm/MC/MCAsmInfo.h"
18 #include "llvm/MC/MCAsmLayout.h"
19 #include "llvm/MC/MCAssembler.h"
20 #include "llvm/MC/MCContext.h"
21 #include "llvm/MC/MCExpr.h"
22 #include "llvm/MC/MCFixupKindInfo.h"
23 #include "llvm/MC/MCObjectFileInfo.h"
24 #include "llvm/MC/MCObjectWriter.h"
25 #include "llvm/MC/MCSectionWasm.h"
26 #include "llvm/MC/MCSymbolWasm.h"
27 #include "llvm/MC/MCValue.h"
28 #include "llvm/MC/MCWasmObjectWriter.h"
29 #include "llvm/Support/Casting.h"
30 #include "llvm/Support/Debug.h"
31 #include "llvm/Support/ErrorHandling.h"
32 #include "llvm/Support/LEB128.h"
33 #include "llvm/Support/StringSaver.h"
34 #include "llvm/Support/Wasm.h"
35 #include <vector>
36 
37 using namespace llvm;
38 
39 #undef DEBUG_TYPE
40 #define DEBUG_TYPE "reloc-info"
41 
42 namespace {
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 // This record records information about a call_indirect which needs its
54 // type index fixed up once we've computed type indices.
55 struct TypeIndexFixup {
56   uint64_t Offset;
57   const MCSymbolWasm *Symbol;
58   const MCSectionWasm *FixupSection;
59   TypeIndexFixup(uint64_t O, const MCSymbolWasm *S, MCSectionWasm *F)
60     : Offset(O), Symbol(S), FixupSection(F) {}
61 };
62 
63 class WasmObjectWriter : public MCObjectWriter {
64   /// Helper struct for containing some precomputed information on symbols.
65   struct WasmSymbolData {
66     const MCSymbolWasm *Symbol;
67     StringRef Name;
68 
69     // Support lexicographic sorting.
70     bool operator<(const WasmSymbolData &RHS) const { return Name < RHS.Name; }
71   };
72 
73   /// The target specific Wasm writer instance.
74   std::unique_ptr<MCWasmObjectTargetWriter> TargetObjectWriter;
75 
76   // Relocations for fixing up references in the code section.
77   std::vector<WasmRelocationEntry> CodeRelocations;
78 
79   // Relocations for fixing up references in the data section.
80   std::vector<WasmRelocationEntry> DataRelocations;
81 
82   // Fixups for call_indirect type indices.
83   std::vector<TypeIndexFixup> TypeIndexFixups;
84 
85   // Index values to use for fixing up call_indirect type indices.
86   std::vector<uint32_t> TypeIndexFixupTypes;
87 
88   // TargetObjectWriter wrappers.
89   bool is64Bit() const { return TargetObjectWriter->is64Bit(); }
90   unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
91                         const MCFixup &Fixup, bool IsPCRel) const {
92     return TargetObjectWriter->getRelocType(Ctx, Target, Fixup, IsPCRel);
93   }
94 
95   void startSection(SectionBookkeeping &Section, unsigned SectionId,
96                     const char *Name = nullptr);
97   void endSection(SectionBookkeeping &Section);
98 
99 public:
100   WasmObjectWriter(MCWasmObjectTargetWriter *MOTW, raw_pwrite_stream &OS)
101       : MCObjectWriter(OS, /*IsLittleEndian=*/true), TargetObjectWriter(MOTW) {}
102 
103 private:
104   void reset() override {
105     MCObjectWriter::reset();
106   }
107 
108   ~WasmObjectWriter() override;
109 
110   void writeHeader(const MCAssembler &Asm);
111 
112   void writeValueType(wasm::ValType Ty) {
113     encodeSLEB128(int32_t(Ty), getStream());
114   }
115 
116   void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,
117                         const MCFragment *Fragment, const MCFixup &Fixup,
118                         MCValue Target, bool &IsPCRel,
119                         uint64_t &FixedValue) override;
120 
121   void executePostLayoutBinding(MCAssembler &Asm,
122                                 const MCAsmLayout &Layout) override;
123 
124   void writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override;
125 };
126 } // end anonymous namespace
127 
128 WasmObjectWriter::~WasmObjectWriter() {}
129 
130 // Return the padding size to write a 32-bit value into a 5-byte ULEB128.
131 static unsigned PaddingFor5ByteULEB128(uint32_t X) {
132   return X == 0 ? 4 : (4u - (31u - countLeadingZeros(X)) / 7u);
133 }
134 
135 // Return the padding size to write a 32-bit value into a 5-byte SLEB128.
136 static unsigned PaddingFor5ByteSLEB128(int32_t X) {
137   return 5 - getSLEB128Size(X);
138 }
139 
140 // Write out a section header and a patchable section size field.
141 void WasmObjectWriter::startSection(SectionBookkeeping &Section,
142                                     unsigned SectionId,
143                                     const char *Name) {
144   assert((Name != nullptr) == (SectionId == wasm::WASM_SEC_CUSTOM) &&
145          "Only custom sections can have names");
146 
147   encodeULEB128(SectionId, getStream());
148 
149   Section.SizeOffset = getStream().tell();
150 
151   // The section size. We don't know the size yet, so reserve enough space
152   // for any 32-bit value; we'll patch it later.
153   encodeULEB128(UINT32_MAX, getStream());
154 
155   // The position where the section starts, for measuring its size.
156   Section.ContentsOffset = getStream().tell();
157 
158   // Custom sections in wasm also have a string identifier.
159   if (SectionId == wasm::WASM_SEC_CUSTOM) {
160     encodeULEB128(strlen(Name), getStream());
161     writeBytes(Name);
162   }
163 }
164 
165 // Now that the section is complete and we know how big it is, patch up the
166 // section size field at the start of the section.
167 void WasmObjectWriter::endSection(SectionBookkeeping &Section) {
168   uint64_t Size = getStream().tell() - Section.ContentsOffset;
169   if (uint32_t(Size) != Size)
170     report_fatal_error("section size does not fit in a uint32_t");
171 
172   unsigned Padding = PaddingFor5ByteULEB128(Size);
173 
174   // Write the final section size to the payload_len field, which follows
175   // the section id byte.
176   uint8_t Buffer[16];
177   unsigned SizeLen = encodeULEB128(Size, Buffer, Padding);
178   assert(SizeLen == 5);
179   getStream().pwrite((char *)Buffer, SizeLen, Section.SizeOffset);
180 }
181 
182 // Emit the Wasm header.
183 void WasmObjectWriter::writeHeader(const MCAssembler &Asm) {
184   writeBytes(StringRef(wasm::WasmMagic, sizeof(wasm::WasmMagic)));
185   writeLE32(wasm::WasmVersion);
186 }
187 
188 void WasmObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
189                                                 const MCAsmLayout &Layout) {
190 }
191 
192 void WasmObjectWriter::recordRelocation(MCAssembler &Asm,
193                                         const MCAsmLayout &Layout,
194                                         const MCFragment *Fragment,
195                                         const MCFixup &Fixup, MCValue Target,
196                                         bool &IsPCRel, uint64_t &FixedValue) {
197   MCSectionWasm &FixupSection = cast<MCSectionWasm>(*Fragment->getParent());
198   uint64_t C = Target.getConstant();
199   uint64_t FixupOffset = Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
200   MCContext &Ctx = Asm.getContext();
201 
202   if (const MCSymbolRefExpr *RefB = Target.getSymB()) {
203     assert(RefB->getKind() == MCSymbolRefExpr::VK_None &&
204            "Should not have constructed this");
205 
206     // Let A, B and C being the components of Target and R be the location of
207     // the fixup. If the fixup is not pcrel, we want to compute (A - B + C).
208     // If it is pcrel, we want to compute (A - B + C - R).
209 
210     // In general, Wasm has no relocations for -B. It can only represent (A + C)
211     // or (A + C - R). If B = R + K and the relocation is not pcrel, we can
212     // replace B to implement it: (A - R - K + C)
213     if (IsPCRel) {
214       Ctx.reportError(
215           Fixup.getLoc(),
216           "No relocation available to represent this relative expression");
217       return;
218     }
219 
220     const auto &SymB = cast<MCSymbolWasm>(RefB->getSymbol());
221 
222     if (SymB.isUndefined()) {
223       Ctx.reportError(Fixup.getLoc(),
224                       Twine("symbol '") + SymB.getName() +
225                           "' can not be undefined in a subtraction expression");
226       return;
227     }
228 
229     assert(!SymB.isAbsolute() && "Should have been folded");
230     const MCSection &SecB = SymB.getSection();
231     if (&SecB != &FixupSection) {
232       Ctx.reportError(Fixup.getLoc(),
233                       "Cannot represent a difference across sections");
234       return;
235     }
236 
237     uint64_t SymBOffset = Layout.getSymbolOffset(SymB);
238     uint64_t K = SymBOffset - FixupOffset;
239     IsPCRel = true;
240     C -= K;
241   }
242 
243   // We either rejected the fixup or folded B into C at this point.
244   const MCSymbolRefExpr *RefA = Target.getSymA();
245   const auto *SymA = RefA ? cast<MCSymbolWasm>(&RefA->getSymbol()) : nullptr;
246 
247   bool ViaWeakRef = false;
248   if (SymA && SymA->isVariable()) {
249     const MCExpr *Expr = SymA->getVariableValue();
250     if (const auto *Inner = dyn_cast<MCSymbolRefExpr>(Expr)) {
251       if (Inner->getKind() == MCSymbolRefExpr::VK_WEAKREF) {
252         SymA = cast<MCSymbolWasm>(&Inner->getSymbol());
253         ViaWeakRef = true;
254       }
255     }
256   }
257 
258   // Put any constant offset in an addend. Offsets can be negative, and
259   // LLVM expects wrapping, in contrast to wasm's immediates which can't
260   // be negative and don't wrap.
261   FixedValue = 0;
262 
263   if (SymA) {
264     if (ViaWeakRef)
265       llvm_unreachable("weakref used in reloc not yet implemented");
266     else
267       SymA->setUsedInReloc();
268   }
269 
270   if (RefA) {
271     if (RefA->getKind() == MCSymbolRefExpr::VK_WebAssembly_TYPEINDEX) {
272       TypeIndexFixups.push_back(TypeIndexFixup(FixupOffset, SymA,
273                                                &FixupSection));
274       return;
275     }
276   }
277 
278   unsigned Type = getRelocType(Ctx, Target, Fixup, IsPCRel);
279 
280   WasmRelocationEntry Rec(FixupOffset, SymA, C, Type, &FixupSection);
281 
282   if (FixupSection.hasInstructions())
283     CodeRelocations.push_back(Rec);
284   else
285     DataRelocations.push_back(Rec);
286 }
287 
288 namespace {
289 
290 // The signature of a wasm function, in a struct capable of being used as a
291 // DenseMap key.
292 struct WasmFunctionType {
293   // Support empty and tombstone instances, needed by DenseMap.
294   enum { Plain, Empty, Tombstone } State;
295 
296   // The return types of the function.
297   SmallVector<wasm::ValType, 1> Returns;
298 
299   // The parameter types of the function.
300   SmallVector<wasm::ValType, 4> Params;
301 
302   WasmFunctionType() : State(Plain) {}
303 
304   bool operator==(const WasmFunctionType &Other) const {
305     return State == Other.State && Returns == Other.Returns &&
306            Params == Other.Params;
307   }
308 };
309 
310 // Traits for using WasmFunctionType in a DenseMap.
311 struct WasmFunctionTypeDenseMapInfo {
312   static WasmFunctionType getEmptyKey() {
313     WasmFunctionType FuncTy;
314     FuncTy.State = WasmFunctionType::Empty;
315     return FuncTy;
316   }
317   static WasmFunctionType getTombstoneKey() {
318     WasmFunctionType FuncTy;
319     FuncTy.State = WasmFunctionType::Tombstone;
320     return FuncTy;
321   }
322   static unsigned getHashValue(const WasmFunctionType &FuncTy) {
323     uintptr_t Value = FuncTy.State;
324     for (wasm::ValType Ret : FuncTy.Returns)
325       Value += DenseMapInfo<int32_t>::getHashValue(int32_t(Ret));
326     for (wasm::ValType Param : FuncTy.Params)
327       Value += DenseMapInfo<int32_t>::getHashValue(int32_t(Param));
328     return Value;
329   }
330   static bool isEqual(const WasmFunctionType &LHS,
331                       const WasmFunctionType &RHS) {
332     return LHS == RHS;
333   }
334 };
335 
336 // A wasm import to be written into the import section.
337 struct WasmImport {
338   StringRef ModuleName;
339   StringRef FieldName;
340   unsigned Kind;
341   int32_t Type;
342 };
343 
344 // A wasm function to be written into the function section.
345 struct WasmFunction {
346   int32_t Type;
347   const MCSymbolWasm *Sym;
348 };
349 
350 // A wasm export to be written into the export section.
351 struct WasmExport {
352   StringRef FieldName;
353   unsigned Kind;
354   uint32_t Index;
355 };
356 
357 // A wasm global to be written into the global section.
358 struct WasmGlobal {
359   wasm::ValType Type;
360   bool IsMutable;
361   uint32_t InitialValue;
362 };
363 
364 } // end anonymous namespace
365 
366 // Write X as an (unsigned) LEB value at offset Offset in Stream, padded
367 // to allow patching.
368 static void
369 WritePatchableLEB(raw_pwrite_stream &Stream, uint32_t X, uint64_t Offset) {
370   uint8_t Buffer[5];
371   unsigned Padding = PaddingFor5ByteULEB128(X);
372   unsigned SizeLen = encodeULEB128(X, Buffer, Padding);
373   assert(SizeLen == 5);
374   Stream.pwrite((char *)Buffer, SizeLen, Offset);
375 }
376 
377 // Write X as an signed LEB value at offset Offset in Stream, padded
378 // to allow patching.
379 static void
380 WritePatchableSLEB(raw_pwrite_stream &Stream, int32_t X, uint64_t Offset) {
381   uint8_t Buffer[5];
382   unsigned Padding = PaddingFor5ByteSLEB128(X);
383   unsigned SizeLen = encodeSLEB128(X, Buffer, Padding);
384   assert(SizeLen == 5);
385   Stream.pwrite((char *)Buffer, SizeLen, Offset);
386 }
387 
388 // Write X as a plain integer value at offset Offset in Stream.
389 static void WriteI32(raw_pwrite_stream &Stream, uint32_t X, uint64_t Offset) {
390   uint8_t Buffer[4];
391   support::endian::write32le(Buffer, X);
392   Stream.pwrite((char *)Buffer, sizeof(Buffer), Offset);
393 }
394 
395 // Compute a value to write into the code at the location covered
396 // by RelEntry. This value isn't used by the static linker, since
397 // we have addends; it just serves to make the code more readable
398 // and to make standalone wasm modules directly usable.
399 static uint32_t ProvisionalValue(const WasmRelocationEntry &RelEntry) {
400   const MCSymbolWasm *Sym = RelEntry.Symbol;
401 
402   // For undefined symbols, use a hopefully invalid value.
403   if (!Sym->isDefined(false))
404     return UINT32_MAX;
405 
406   MCSectionWasm &Section =
407     cast<MCSectionWasm>(RelEntry.Symbol->getSection(false));
408   uint64_t Address = Section.getSectionOffset() + RelEntry.Addend;
409 
410   // Ignore overflow. LLVM allows address arithmetic to silently wrap.
411   uint32_t Value = Address;
412 
413   return Value;
414 }
415 
416 // Apply the portions of the relocation records that we can handle ourselves
417 // directly.
418 static void ApplyRelocations(
419     ArrayRef<WasmRelocationEntry> Relocations,
420     raw_pwrite_stream &Stream,
421     DenseMap<const MCSymbolWasm *, uint32_t> &SymbolIndices,
422     uint64_t ContentsOffset)
423 {
424   for (const WasmRelocationEntry &RelEntry : Relocations) {
425     uint64_t Offset = ContentsOffset +
426                       RelEntry.FixupSection->getSectionOffset() +
427                       RelEntry.Offset;
428     switch (RelEntry.Type) {
429     case wasm::R_WEBASSEMBLY_FUNCTION_INDEX_LEB: {
430       uint32_t Index = SymbolIndices[RelEntry.Symbol];
431       assert(RelEntry.Addend == 0);
432 
433       WritePatchableLEB(Stream, Index, Offset);
434       break;
435     }
436     case wasm::R_WEBASSEMBLY_TABLE_INDEX_SLEB: {
437       uint32_t Index = SymbolIndices[RelEntry.Symbol];
438       assert(RelEntry.Addend == 0);
439 
440       WritePatchableSLEB(Stream, Index, Offset);
441       break;
442     }
443     case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_SLEB: {
444       uint32_t Value = ProvisionalValue(RelEntry);
445 
446       WritePatchableSLEB(Stream, Value, Offset);
447       break;
448     }
449     case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_LEB: {
450       uint32_t Value = ProvisionalValue(RelEntry);
451 
452       WritePatchableLEB(Stream, Value, Offset);
453       break;
454     }
455     case wasm::R_WEBASSEMBLY_TABLE_INDEX_I32: {
456       uint32_t Index = SymbolIndices[RelEntry.Symbol];
457       assert(RelEntry.Addend == 0);
458 
459       WriteI32(Stream, Index, Offset);
460       break;
461     }
462     case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_I32: {
463       uint32_t Value = ProvisionalValue(RelEntry);
464 
465       WriteI32(Stream, Value, Offset);
466       break;
467     }
468     default:
469       break;
470     }
471   }
472 }
473 
474 // Write out the portions of the relocation records that the linker will
475 // need to handle.
476 static void WriteRelocations(
477     ArrayRef<WasmRelocationEntry> Relocations,
478     raw_pwrite_stream &Stream,
479     DenseMap<const MCSymbolWasm *, uint32_t> &SymbolIndices)
480 {
481   for (const WasmRelocationEntry RelEntry : Relocations) {
482     encodeULEB128(RelEntry.Type, Stream);
483 
484     uint64_t Offset = RelEntry.Offset +
485                       RelEntry.FixupSection->getSectionOffset();
486     uint32_t Index = SymbolIndices[RelEntry.Symbol];
487     int64_t Addend = RelEntry.Addend;
488 
489     switch (RelEntry.Type) {
490     case wasm::R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
491     case wasm::R_WEBASSEMBLY_TABLE_INDEX_SLEB:
492     case wasm::R_WEBASSEMBLY_TABLE_INDEX_I32:
493       encodeULEB128(Offset, Stream);
494       encodeULEB128(Index, Stream);
495       assert(Addend == 0 && "addends not supported for functions");
496       break;
497     case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_LEB:
498     case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_SLEB:
499     case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_I32:
500       encodeULEB128(Offset, Stream);
501       encodeULEB128(Index, Stream);
502       encodeSLEB128(Addend, Stream);
503       break;
504     default:
505       llvm_unreachable("unsupported relocation type");
506     }
507   }
508 }
509 
510 void WasmObjectWriter::writeObject(MCAssembler &Asm,
511                                    const MCAsmLayout &Layout) {
512   MCContext &Ctx = Asm.getContext();
513   wasm::ValType PtrType = is64Bit() ? wasm::ValType::I64 : wasm::ValType::I32;
514 
515   // Collect information from the available symbols.
516   DenseMap<WasmFunctionType, int32_t, WasmFunctionTypeDenseMapInfo>
517       FunctionTypeIndices;
518   SmallVector<WasmFunctionType, 4> FunctionTypes;
519   SmallVector<WasmFunction, 4> Functions;
520   SmallVector<uint32_t, 4> TableElems;
521   SmallVector<WasmGlobal, 4> Globals;
522   SmallVector<WasmImport, 4> Imports;
523   SmallVector<WasmExport, 4> Exports;
524   DenseMap<const MCSymbolWasm *, uint32_t> SymbolIndices;
525   SmallPtrSet<const MCSymbolWasm *, 4> IsAddressTaken;
526   unsigned NumFuncImports = 0;
527   unsigned NumGlobalImports = 0;
528   SmallVector<char, 0> DataBytes;
529 
530   // Populate the IsAddressTaken set.
531   for (WasmRelocationEntry RelEntry : CodeRelocations) {
532     switch (RelEntry.Type) {
533     case wasm::R_WEBASSEMBLY_TABLE_INDEX_SLEB:
534     case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_SLEB:
535       IsAddressTaken.insert(RelEntry.Symbol);
536       break;
537     default:
538       break;
539     }
540   }
541   for (WasmRelocationEntry RelEntry : DataRelocations) {
542     switch (RelEntry.Type) {
543     case wasm::R_WEBASSEMBLY_TABLE_INDEX_I32:
544     case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_I32:
545       IsAddressTaken.insert(RelEntry.Symbol);
546       break;
547     default:
548       break;
549     }
550   }
551 
552   // Populate the Imports set.
553   for (const MCSymbol &S : Asm.symbols()) {
554     const auto &WS = static_cast<const MCSymbolWasm &>(S);
555     int32_t Type;
556 
557     if (WS.isFunction()) {
558       // Prepare the function's type, if we haven't seen it yet.
559       WasmFunctionType F;
560       F.Returns = WS.getReturns();
561       F.Params = WS.getParams();
562       auto Pair =
563           FunctionTypeIndices.insert(std::make_pair(F, FunctionTypes.size()));
564       if (Pair.second)
565         FunctionTypes.push_back(F);
566 
567       Type = Pair.first->second;
568     } else {
569       Type = int32_t(PtrType);
570     }
571 
572     // If the symbol is not defined in this translation unit, import it.
573     if (!WS.isTemporary() && !WS.isDefined(/*SetUsed=*/false)) {
574       WasmImport Import;
575       Import.ModuleName = WS.getModuleName();
576       Import.FieldName = WS.getName();
577 
578       if (WS.isFunction()) {
579         Import.Kind = wasm::WASM_EXTERNAL_FUNCTION;
580         Import.Type = Type;
581         SymbolIndices[&WS] = NumFuncImports;
582         ++NumFuncImports;
583       } else {
584         Import.Kind = wasm::WASM_EXTERNAL_GLOBAL;
585         Import.Type = Type;
586         SymbolIndices[&WS] = NumGlobalImports;
587         ++NumGlobalImports;
588       }
589 
590       Imports.push_back(Import);
591     }
592   }
593 
594   // In the special .global_variables section, we've encoded global
595   // variables used by the function. Translate them into the Globals
596   // list.
597   MCSectionWasm *GlobalVars = Ctx.getWasmSection(".global_variables", 0, 0);
598   if (!GlobalVars->getFragmentList().empty()) {
599     if (GlobalVars->getFragmentList().size() != 1)
600       report_fatal_error("only one .global_variables fragment supported");
601     const MCFragment &Frag = *GlobalVars->begin();
602     if (Frag.hasInstructions() || Frag.getKind() != MCFragment::FT_Data)
603       report_fatal_error("only data supported in .global_variables");
604     const MCDataFragment &DataFrag = cast<MCDataFragment>(Frag);
605     if (!DataFrag.getFixups().empty())
606       report_fatal_error("fixups not supported in .global_variables");
607     const SmallVectorImpl<char> &Contents = DataFrag.getContents();
608     for (char p : Contents) {
609       WasmGlobal G;
610       G.Type = wasm::ValType(p);
611       G.IsMutable = true;
612       G.InitialValue = 0;
613       Globals.push_back(G);
614     }
615   }
616 
617   // Handle defined symbols.
618   for (const MCSymbol &S : Asm.symbols()) {
619     // Ignore unnamed temporary symbols, which aren't ever exported, imported,
620     // or used in relocations.
621     if (S.isTemporary() && S.getName().empty())
622       continue;
623     const auto &WS = static_cast<const MCSymbolWasm &>(S);
624     unsigned Index;
625     if (WS.isFunction()) {
626       // Prepare the function's type, if we haven't seen it yet.
627       WasmFunctionType F;
628       F.Returns = WS.getReturns();
629       F.Params = WS.getParams();
630       auto Pair =
631           FunctionTypeIndices.insert(std::make_pair(F, FunctionTypes.size()));
632       if (Pair.second)
633         FunctionTypes.push_back(F);
634 
635       int32_t Type = Pair.first->second;
636 
637       if (WS.isDefined(/*SetUsed=*/false)) {
638         // A definition. Take the next available index.
639         Index = NumFuncImports + Functions.size();
640 
641         // Prepare the function.
642         WasmFunction Func;
643         Func.Type = Type;
644         Func.Sym = &WS;
645         SymbolIndices[&WS] = Index;
646         Functions.push_back(Func);
647       } else {
648         // An import; the index was assigned above.
649         Index = SymbolIndices.find(&WS)->second;
650       }
651 
652       // If needed, prepare the function to be called indirectly.
653       if (IsAddressTaken.count(&WS))
654         TableElems.push_back(Index);
655     } else {
656       // For now, ignore temporary non-function symbols.
657       if (S.isTemporary())
658         continue;
659 
660       if (WS.getOffset() != 0)
661         report_fatal_error("data sections must contain one variable each");
662       if (!WS.getSize())
663         report_fatal_error("data symbols must have a size set with .size");
664 
665       int64_t Size = 0;
666       if (!WS.getSize()->evaluateAsAbsolute(Size, Layout))
667         report_fatal_error(".size expression must be evaluatable");
668 
669       if (WS.isDefined(false)) {
670         MCSectionWasm &DataSection =
671             static_cast<MCSectionWasm &>(WS.getSection());
672 
673         if (uint64_t(Size) != Layout.getSectionFileSize(&DataSection))
674           report_fatal_error("data sections must contain at most one variable");
675 
676         DataBytes.resize(alignTo(DataBytes.size(), DataSection.getAlignment()));
677 
678         DataSection.setSectionOffset(DataBytes.size());
679 
680         for (MCSection::iterator I = DataSection.begin(), E = DataSection.end();
681              I != E; ++I) {
682           const MCFragment &Frag = *I;
683           if (Frag.hasInstructions())
684             report_fatal_error("only data supported in data sections");
685 
686           if (const MCAlignFragment *Align = dyn_cast<MCAlignFragment>(&Frag)) {
687             if (Align->getValueSize() != 1)
688               report_fatal_error("only byte values supported for alignment");
689             // If nops are requested, use zeros, as this is the data section.
690             uint8_t Value = Align->hasEmitNops() ? 0 : Align->getValue();
691             uint64_t Size = std::min<uint64_t>(alignTo(DataBytes.size(),
692                                                        Align->getAlignment()),
693                                                DataBytes.size() +
694                                                    Align->getMaxBytesToEmit());
695             DataBytes.resize(Size, Value);
696           } else if (const MCFillFragment *Fill =
697                                               dyn_cast<MCFillFragment>(&Frag)) {
698             DataBytes.insert(DataBytes.end(), Size, Fill->getValue());
699           } else {
700             const MCDataFragment &DataFrag = cast<MCDataFragment>(Frag);
701             const SmallVectorImpl<char> &Contents = DataFrag.getContents();
702 
703             DataBytes.insert(DataBytes.end(), Contents.begin(), Contents.end());
704           }
705         }
706 
707         // For each external global, prepare a corresponding wasm global
708         // holding its address.
709         if (WS.isExternal()) {
710           Index = NumGlobalImports + Globals.size();
711 
712           WasmGlobal Global;
713           Global.Type = PtrType;
714           Global.IsMutable = false;
715           Global.InitialValue = DataSection.getSectionOffset();
716           SymbolIndices[&WS] = Index;
717           Globals.push_back(Global);
718         }
719       }
720     }
721 
722     // If the symbol is visible outside this translation unit, export it.
723     if (WS.isExternal()) {
724       assert(WS.isDefined(false));
725       WasmExport Export;
726       Export.FieldName = WS.getName();
727       Export.Index = Index;
728 
729       if (WS.isFunction())
730         Export.Kind = wasm::WASM_EXTERNAL_FUNCTION;
731       else
732         Export.Kind = wasm::WASM_EXTERNAL_GLOBAL;
733 
734       Exports.push_back(Export);
735     }
736   }
737 
738   // Add types for indirect function calls.
739   for (const TypeIndexFixup &Fixup : TypeIndexFixups) {
740     WasmFunctionType F;
741     F.Returns = Fixup.Symbol->getReturns();
742     F.Params = Fixup.Symbol->getParams();
743     auto Pair =
744         FunctionTypeIndices.insert(std::make_pair(F, FunctionTypes.size()));
745     if (Pair.second)
746       FunctionTypes.push_back(F);
747 
748     TypeIndexFixupTypes.push_back(Pair.first->second);
749   }
750 
751   // Write out the Wasm header.
752   writeHeader(Asm);
753 
754   SectionBookkeeping Section;
755 
756   // === Type Section =========================================================
757   if (!FunctionTypes.empty()) {
758     startSection(Section, wasm::WASM_SEC_TYPE);
759 
760     encodeULEB128(FunctionTypes.size(), getStream());
761 
762     for (WasmFunctionType &FuncTy : FunctionTypes) {
763       encodeSLEB128(wasm::WASM_TYPE_FUNC, getStream());
764       encodeULEB128(FuncTy.Params.size(), getStream());
765       for (wasm::ValType Ty : FuncTy.Params)
766         writeValueType(Ty);
767       encodeULEB128(FuncTy.Returns.size(), getStream());
768       for (wasm::ValType Ty : FuncTy.Returns)
769         writeValueType(Ty);
770     }
771 
772     endSection(Section);
773   }
774 
775   // === Import Section ========================================================
776   if (!Imports.empty()) {
777     startSection(Section, wasm::WASM_SEC_IMPORT);
778 
779     encodeULEB128(Imports.size(), getStream());
780     for (const WasmImport &Import : Imports) {
781       StringRef ModuleName = Import.ModuleName;
782       encodeULEB128(ModuleName.size(), getStream());
783       writeBytes(ModuleName);
784 
785       StringRef FieldName = Import.FieldName;
786       encodeULEB128(FieldName.size(), getStream());
787       writeBytes(FieldName);
788 
789       encodeULEB128(Import.Kind, getStream());
790 
791       switch (Import.Kind) {
792       case wasm::WASM_EXTERNAL_FUNCTION:
793         encodeULEB128(Import.Type, getStream());
794         break;
795       case wasm::WASM_EXTERNAL_GLOBAL:
796         encodeSLEB128(Import.Type, getStream());
797         encodeULEB128(0, getStream()); // mutability
798         break;
799       default:
800         llvm_unreachable("unsupported import kind");
801       }
802     }
803 
804     endSection(Section);
805   }
806 
807   // === Function Section ======================================================
808   if (!Functions.empty()) {
809     startSection(Section, wasm::WASM_SEC_FUNCTION);
810 
811     encodeULEB128(Functions.size(), getStream());
812     for (const WasmFunction &Func : Functions)
813       encodeULEB128(Func.Type, getStream());
814 
815     endSection(Section);
816   }
817 
818   // === Table Section =========================================================
819   // For now, always emit the table section, since indirect calls are not
820   // valid without it. In the future, we could perhaps be more clever and omit
821   // it if there are no indirect calls.
822   startSection(Section, wasm::WASM_SEC_TABLE);
823 
824   // The number of tables, fixed to 1 for now.
825   encodeULEB128(1, getStream());
826 
827   encodeSLEB128(wasm::WASM_TYPE_ANYFUNC, getStream());
828 
829   encodeULEB128(0, getStream());                 // flags
830   encodeULEB128(TableElems.size(), getStream()); // initial
831 
832   endSection(Section);
833 
834   // === Memory Section ========================================================
835   // For now, always emit the memory section, since loads and stores are not
836   // valid without it. In the future, we could perhaps be more clever and omit
837   // it if there are no loads or stores.
838   startSection(Section, wasm::WASM_SEC_MEMORY);
839 
840   encodeULEB128(1, getStream()); // number of memory spaces
841 
842   encodeULEB128(0, getStream()); // flags
843   encodeULEB128(DataBytes.size(), getStream()); // initial
844 
845   endSection(Section);
846 
847   // === Global Section ========================================================
848   if (!Globals.empty()) {
849     startSection(Section, wasm::WASM_SEC_GLOBAL);
850 
851     encodeULEB128(Globals.size(), getStream());
852     for (const WasmGlobal &Global : Globals) {
853       writeValueType(Global.Type);
854       write8(Global.IsMutable);
855 
856       write8(wasm::WASM_OPCODE_I32_CONST);
857       encodeSLEB128(Global.InitialValue, getStream()); // offset
858       write8(wasm::WASM_OPCODE_END);
859     }
860 
861     endSection(Section);
862   }
863 
864   // === Export Section ========================================================
865   if (!Exports.empty()) {
866     startSection(Section, wasm::WASM_SEC_EXPORT);
867 
868     encodeULEB128(Exports.size(), getStream());
869     for (const WasmExport &Export : Exports) {
870       encodeULEB128(Export.FieldName.size(), getStream());
871       writeBytes(Export.FieldName);
872 
873       encodeSLEB128(Export.Kind, getStream());
874 
875       encodeULEB128(Export.Index, getStream());
876     }
877 
878     endSection(Section);
879   }
880 
881 #if 0 // TODO: Start Section
882   if (HaveStartFunction) {
883     // === Start Section =========================================================
884     startSection(Section, wasm::WASM_SEC_START);
885 
886     encodeSLEB128(StartFunction, getStream());
887 
888     endSection(Section);
889   }
890 #endif
891 
892   // === Elem Section ==========================================================
893   if (!TableElems.empty()) {
894     startSection(Section, wasm::WASM_SEC_ELEM);
895 
896     encodeULEB128(1, getStream()); // number of "segments"
897     encodeULEB128(0, getStream()); // the table index
898 
899     // init expr for starting offset
900     write8(wasm::WASM_OPCODE_I32_CONST);
901     encodeSLEB128(0, getStream());
902     write8(wasm::WASM_OPCODE_END);
903 
904     encodeULEB128(TableElems.size(), getStream());
905     for (uint32_t Elem : TableElems)
906       encodeULEB128(Elem, getStream());
907 
908     endSection(Section);
909   }
910 
911   // === Code Section ==========================================================
912   if (!Functions.empty()) {
913     startSection(Section, wasm::WASM_SEC_CODE);
914 
915     encodeULEB128(Functions.size(), getStream());
916 
917     for (const WasmFunction &Func : Functions) {
918       MCSectionWasm &FuncSection =
919           static_cast<MCSectionWasm &>(Func.Sym->getSection());
920 
921       if (Func.Sym->isVariable())
922         report_fatal_error("weak symbols not supported yet");
923 
924       if (Func.Sym->getOffset() != 0)
925         report_fatal_error("function sections must contain one function each");
926 
927       if (!Func.Sym->getSize())
928         report_fatal_error("function symbols must have a size set with .size");
929 
930       int64_t Size = 0;
931       if (!Func.Sym->getSize()->evaluateAsAbsolute(Size, Layout))
932         report_fatal_error(".size expression must be evaluatable");
933 
934       encodeULEB128(Size, getStream());
935 
936       FuncSection.setSectionOffset(getStream().tell() -
937                                    Section.ContentsOffset);
938 
939       Asm.writeSectionData(&FuncSection, Layout);
940     }
941 
942     // Apply the type index fixups for call_indirect etc. instructions.
943     for (size_t i = 0, e = TypeIndexFixups.size(); i < e; ++i) {
944       uint32_t Type = TypeIndexFixupTypes[i];
945       unsigned Padding = PaddingFor5ByteULEB128(Type);
946 
947       const TypeIndexFixup &Fixup = TypeIndexFixups[i];
948       uint64_t Offset = Fixup.Offset +
949                         Fixup.FixupSection->getSectionOffset();
950 
951       uint8_t Buffer[16];
952       unsigned SizeLen = encodeULEB128(Type, Buffer, Padding);
953       assert(SizeLen == 5);
954       getStream().pwrite((char *)Buffer, SizeLen,
955                          Section.ContentsOffset + Offset);
956     }
957 
958     // Apply fixups.
959     ApplyRelocations(CodeRelocations, getStream(), SymbolIndices,
960                      Section.ContentsOffset);
961 
962     endSection(Section);
963   }
964 
965   // === Data Section ==========================================================
966   if (!DataBytes.empty()) {
967     startSection(Section, wasm::WASM_SEC_DATA);
968 
969     encodeULEB128(1, getStream()); // count
970     encodeULEB128(0, getStream()); // memory index
971     write8(wasm::WASM_OPCODE_I32_CONST);
972     encodeSLEB128(0, getStream()); // offset
973     write8(wasm::WASM_OPCODE_END);
974     encodeULEB128(DataBytes.size(), getStream()); // size
975     writeBytes(DataBytes); // data
976 
977     // Apply fixups.
978     ApplyRelocations(DataRelocations, getStream(), SymbolIndices,
979                      Section.ContentsOffset);
980 
981     endSection(Section);
982   }
983 
984   // === Name Section ==========================================================
985   uint32_t TotalFunctions = NumFuncImports + Functions.size();
986   if (TotalFunctions != 0) {
987     startSection(Section, wasm::WASM_SEC_CUSTOM, "name");
988     SectionBookkeeping SubSection;
989     startSection(SubSection, wasm::WASM_NAMES_FUNCTION);
990 
991     encodeULEB128(TotalFunctions, getStream());
992     uint32_t Index = 0;
993     for (const WasmImport &Import : Imports) {
994       if (Import.Kind == wasm::WASM_EXTERNAL_FUNCTION) {
995         encodeULEB128(Index, getStream());
996         encodeULEB128(Import.FieldName.size(), getStream());
997         writeBytes(Import.FieldName);
998         ++Index;
999       }
1000     }
1001     for (const WasmFunction &Func : Functions) {
1002       encodeULEB128(Index, getStream());
1003       encodeULEB128(Func.Sym->getName().size(), getStream());
1004       writeBytes(Func.Sym->getName());
1005       ++Index;
1006     }
1007 
1008     endSection(SubSection);
1009     endSection(Section);
1010   }
1011 
1012   // See: https://github.com/WebAssembly/tool-conventions/blob/master/Linking.md
1013   // for descriptions of the reloc sections.
1014 
1015   // === Code Reloc Section ====================================================
1016   if (!CodeRelocations.empty()) {
1017     startSection(Section, wasm::WASM_SEC_CUSTOM, "reloc.CODE");
1018 
1019     encodeULEB128(wasm::WASM_SEC_CODE, getStream());
1020 
1021     encodeULEB128(CodeRelocations.size(), getStream());
1022 
1023     WriteRelocations(CodeRelocations, getStream(), SymbolIndices);
1024 
1025     endSection(Section);
1026   }
1027 
1028   // === Data Reloc Section ====================================================
1029   if (!DataRelocations.empty()) {
1030     startSection(Section, wasm::WASM_SEC_CUSTOM, "reloc.DATA");
1031 
1032     encodeULEB128(wasm::WASM_SEC_DATA, getStream());
1033 
1034     encodeULEB128(DataRelocations.size(), getStream());
1035 
1036     WriteRelocations(DataRelocations, getStream(), SymbolIndices);
1037 
1038     endSection(Section);
1039   }
1040 
1041   // TODO: Translate the .comment section to the output.
1042 
1043   // TODO: Translate debug sections to the output.
1044 }
1045 
1046 MCObjectWriter *llvm::createWasmObjectWriter(MCWasmObjectTargetWriter *MOTW,
1047                                              raw_pwrite_stream &OS) {
1048   return new WasmObjectWriter(MOTW, OS);
1049 }
1050