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