xref: /llvm-project-15.0.7/lld/wasm/Writer.cpp (revision e00799ea)
1 //===- Writer.cpp ---------------------------------------------------------===//
2 //
3 //                             The LLVM Linker
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "Writer.h"
11 #include "Config.h"
12 #include "InputChunks.h"
13 #include "InputGlobal.h"
14 #include "OutputSections.h"
15 #include "OutputSegment.h"
16 #include "SymbolTable.h"
17 #include "WriterUtils.h"
18 #include "lld/Common/ErrorHandler.h"
19 #include "lld/Common/Memory.h"
20 #include "lld/Common/Strings.h"
21 #include "lld/Common/Threads.h"
22 #include "llvm/ADT/DenseSet.h"
23 #include "llvm/BinaryFormat/Wasm.h"
24 #include "llvm/Object/WasmTraits.h"
25 #include "llvm/Support/FileOutputBuffer.h"
26 #include "llvm/Support/Format.h"
27 #include "llvm/Support/FormatVariadic.h"
28 #include "llvm/Support/LEB128.h"
29 
30 #include <cstdarg>
31 #include <map>
32 
33 #define DEBUG_TYPE "lld"
34 
35 using namespace llvm;
36 using namespace llvm::wasm;
37 using namespace lld;
38 using namespace lld::wasm;
39 
40 static constexpr int kStackAlignment = 16;
41 static constexpr int kInitialTableOffset = 1;
42 static constexpr const char *kFunctionTableName = "__indirect_function_table";
43 
44 namespace {
45 
46 // An init entry to be written to either the synthetic init func or the
47 // linking metadata.
48 struct WasmInitEntry {
49   const FunctionSymbol *Sym;
50   uint32_t Priority;
51 };
52 
53 // The writer writes a SymbolTable result to a file.
54 class Writer {
55 public:
56   void run();
57 
58 private:
59   void openFile();
60 
61   uint32_t lookupType(const WasmSignature &Sig);
62   uint32_t registerType(const WasmSignature &Sig);
63 
64   void createCtorFunction();
65   void calculateInitFunctions();
66   void assignIndexes();
67   void calculateImports();
68   void calculateExports();
69   void assignSymtab();
70   void calculateTypes();
71   void createOutputSegments();
72   void layoutMemory();
73   void createHeader();
74   void createSections();
75   SyntheticSection *createSyntheticSection(uint32_t Type, StringRef Name = "");
76 
77   // Builtin sections
78   void createTypeSection();
79   void createFunctionSection();
80   void createTableSection();
81   void createGlobalSection();
82   void createExportSection();
83   void createImportSection();
84   void createMemorySection();
85   void createElemSection();
86   void createCodeSection();
87   void createDataSection();
88 
89   // Custom sections
90   void createRelocSections();
91   void createLinkingSection();
92   void createNameSection();
93 
94   void writeHeader();
95   void writeSections();
96 
97   uint64_t FileSize = 0;
98   uint32_t NumMemoryPages = 0;
99   uint32_t MaxMemoryPages = 0;
100 
101   std::vector<const WasmSignature *> Types;
102   DenseMap<WasmSignature, int32_t> TypeIndices;
103   std::vector<const Symbol *> ImportedSymbols;
104   unsigned NumImportedFunctions = 0;
105   unsigned NumImportedGlobals = 0;
106   std::vector<Symbol *> ExportedSymbols;
107   std::vector<const DefinedData *> DefinedFakeGlobals;
108   std::vector<InputGlobal *> InputGlobals;
109   std::vector<InputFunction *> InputFunctions;
110   std::vector<const FunctionSymbol *> IndirectFunctions;
111   std::vector<const Symbol *> SymtabEntries;
112   std::vector<WasmInitEntry> InitFunctions;
113 
114   // Elements that are used to construct the final output
115   std::string Header;
116   std::vector<OutputSection *> OutputSections;
117 
118   std::unique_ptr<FileOutputBuffer> Buffer;
119 
120   std::vector<OutputSegment *> Segments;
121   llvm::SmallDenseMap<StringRef, OutputSegment *> SegmentMap;
122 };
123 
124 } // anonymous namespace
125 
126 void Writer::createImportSection() {
127   uint32_t NumImports = ImportedSymbols.size();
128   if (Config->ImportMemory)
129     ++NumImports;
130   if (Config->ImportTable)
131     ++NumImports;
132 
133   if (NumImports == 0)
134     return;
135 
136   SyntheticSection *Section = createSyntheticSection(WASM_SEC_IMPORT);
137   raw_ostream &OS = Section->getStream();
138 
139   writeUleb128(OS, NumImports, "import count");
140 
141   if (Config->ImportMemory) {
142     WasmImport Import;
143     Import.Module = "env";
144     Import.Field = "memory";
145     Import.Kind = WASM_EXTERNAL_MEMORY;
146     Import.Memory.Flags = 0;
147     Import.Memory.Initial = NumMemoryPages;
148     if (MaxMemoryPages != 0) {
149       Import.Memory.Flags |= WASM_LIMITS_FLAG_HAS_MAX;
150       Import.Memory.Maximum = MaxMemoryPages;
151     }
152     writeImport(OS, Import);
153   }
154 
155   if (Config->ImportTable) {
156     uint32_t TableSize = kInitialTableOffset + IndirectFunctions.size();
157     WasmImport Import;
158     Import.Module = "env";
159     Import.Field = kFunctionTableName;
160     Import.Kind = WASM_EXTERNAL_TABLE;
161     Import.Table.ElemType = WASM_TYPE_ANYFUNC;
162     Import.Table.Limits = {WASM_LIMITS_FLAG_HAS_MAX, TableSize, TableSize};
163     writeImport(OS, Import);
164   }
165 
166   for (const Symbol *Sym : ImportedSymbols) {
167     WasmImport Import;
168     Import.Module = "env";
169     Import.Field = Sym->getName();
170     if (auto *FunctionSym = dyn_cast<FunctionSymbol>(Sym)) {
171       Import.Kind = WASM_EXTERNAL_FUNCTION;
172       Import.SigIndex = lookupType(*FunctionSym->getFunctionType());
173     } else {
174       auto *GlobalSym = cast<GlobalSymbol>(Sym);
175       Import.Kind = WASM_EXTERNAL_GLOBAL;
176       Import.Global = *GlobalSym->getGlobalType();
177     }
178     writeImport(OS, Import);
179   }
180 }
181 
182 void Writer::createTypeSection() {
183   SyntheticSection *Section = createSyntheticSection(WASM_SEC_TYPE);
184   raw_ostream &OS = Section->getStream();
185   writeUleb128(OS, Types.size(), "type count");
186   for (const WasmSignature *Sig : Types)
187     writeSig(OS, *Sig);
188 }
189 
190 void Writer::createFunctionSection() {
191   if (InputFunctions.empty())
192     return;
193 
194   SyntheticSection *Section = createSyntheticSection(WASM_SEC_FUNCTION);
195   raw_ostream &OS = Section->getStream();
196 
197   writeUleb128(OS, InputFunctions.size(), "function count");
198   for (const InputFunction *Func : InputFunctions)
199     writeUleb128(OS, lookupType(Func->Signature), "sig index");
200 }
201 
202 void Writer::createMemorySection() {
203   if (Config->ImportMemory)
204     return;
205 
206   SyntheticSection *Section = createSyntheticSection(WASM_SEC_MEMORY);
207   raw_ostream &OS = Section->getStream();
208 
209   bool HasMax = MaxMemoryPages != 0;
210   writeUleb128(OS, 1, "memory count");
211   writeUleb128(OS, HasMax ? static_cast<unsigned>(WASM_LIMITS_FLAG_HAS_MAX) : 0,
212                "memory limits flags");
213   writeUleb128(OS, NumMemoryPages, "initial pages");
214   if (HasMax)
215     writeUleb128(OS, MaxMemoryPages, "max pages");
216 }
217 
218 void Writer::createGlobalSection() {
219   unsigned NumGlobals = InputGlobals.size() + DefinedFakeGlobals.size();
220   if (NumGlobals == 0)
221     return;
222 
223   SyntheticSection *Section = createSyntheticSection(WASM_SEC_GLOBAL);
224   raw_ostream &OS = Section->getStream();
225 
226   writeUleb128(OS, NumGlobals, "global count");
227   for (const InputGlobal *G : InputGlobals)
228     writeGlobal(OS, G->Global);
229   for (const DefinedData *Sym : DefinedFakeGlobals) {
230     WasmGlobal Global;
231     Global.Type = {WASM_TYPE_I32, false};
232     Global.InitExpr.Opcode = WASM_OPCODE_I32_CONST;
233     Global.InitExpr.Value.Int32 = Sym->getVirtualAddress();
234     writeGlobal(OS, Global);
235   }
236 }
237 
238 void Writer::createTableSection() {
239   if (Config->ImportTable)
240     return;
241 
242   // Always output a table section (or table import), even if there are no
243   // indirect calls.  There are two reasons for this:
244   //  1. For executables it is useful to have an empty table slot at 0
245   //     which can be filled with a null function call handler.
246   //  2. If we don't do this, any program that contains a call_indirect but
247   //     no address-taken function will fail at validation time since it is
248   //     a validation error to include a call_indirect instruction if there
249   //     is not table.
250   uint32_t TableSize = kInitialTableOffset + IndirectFunctions.size();
251 
252   SyntheticSection *Section = createSyntheticSection(WASM_SEC_TABLE);
253   raw_ostream &OS = Section->getStream();
254 
255   writeUleb128(OS, 1, "table count");
256   WasmLimits Limits = {WASM_LIMITS_FLAG_HAS_MAX, TableSize, TableSize};
257   writeTableType(OS, WasmTable{WASM_TYPE_ANYFUNC, Limits});
258 }
259 
260 void Writer::createExportSection() {
261   bool ExportMemory = !Config->Relocatable && !Config->ImportMemory;
262   bool ExportTable = !Config->Relocatable && Config->ExportTable;
263 
264   uint32_t NumExports =
265       (ExportMemory ? 1 : 0) + (ExportTable ? 1 : 0) + ExportedSymbols.size();
266   if (!NumExports)
267     return;
268 
269   SyntheticSection *Section = createSyntheticSection(WASM_SEC_EXPORT);
270   raw_ostream &OS = Section->getStream();
271 
272   writeUleb128(OS, NumExports, "export count");
273 
274   if (ExportMemory)
275     writeExport(OS, {"memory", WASM_EXTERNAL_MEMORY, 0});
276   if (ExportTable)
277     writeExport(OS, {kFunctionTableName, WASM_EXTERNAL_TABLE, 0});
278 
279   unsigned FakeGlobalIndex = NumImportedGlobals + InputGlobals.size();
280 
281   for (const Symbol *Sym : ExportedSymbols) {
282     StringRef Name = Sym->getName();
283     WasmExport Export;
284     DEBUG(dbgs() << "Export: " << Name << "\n");
285 
286     if (auto *F = dyn_cast<DefinedFunction>(Sym))
287       Export = {Name, WASM_EXTERNAL_FUNCTION, F->getFunctionIndex()};
288     else if (auto *G = dyn_cast<DefinedGlobal>(Sym))
289       Export = {Name, WASM_EXTERNAL_GLOBAL, G->getGlobalIndex()};
290     else if (isa<DefinedData>(Sym))
291       Export = {Name, WASM_EXTERNAL_GLOBAL, FakeGlobalIndex++};
292     else
293       llvm_unreachable("unexpected symbol type");
294     writeExport(OS, Export);
295   }
296 }
297 
298 void Writer::createElemSection() {
299   if (IndirectFunctions.empty())
300     return;
301 
302   SyntheticSection *Section = createSyntheticSection(WASM_SEC_ELEM);
303   raw_ostream &OS = Section->getStream();
304 
305   writeUleb128(OS, 1, "segment count");
306   writeUleb128(OS, 0, "table index");
307   WasmInitExpr InitExpr;
308   InitExpr.Opcode = WASM_OPCODE_I32_CONST;
309   InitExpr.Value.Int32 = kInitialTableOffset;
310   writeInitExpr(OS, InitExpr);
311   writeUleb128(OS, IndirectFunctions.size(), "elem count");
312 
313   uint32_t TableIndex = kInitialTableOffset;
314   for (const FunctionSymbol *Sym : IndirectFunctions) {
315     assert(Sym->getTableIndex() == TableIndex);
316     writeUleb128(OS, Sym->getFunctionIndex(), "function index");
317     ++TableIndex;
318   }
319 }
320 
321 void Writer::createCodeSection() {
322   if (InputFunctions.empty())
323     return;
324 
325   log("createCodeSection");
326 
327   auto Section = make<CodeSection>(InputFunctions);
328   OutputSections.push_back(Section);
329 }
330 
331 void Writer::createDataSection() {
332   if (!Segments.size())
333     return;
334 
335   log("createDataSection");
336   auto Section = make<DataSection>(Segments);
337   OutputSections.push_back(Section);
338 }
339 
340 // Create relocations sections in the final output.
341 // These are only created when relocatable output is requested.
342 void Writer::createRelocSections() {
343   log("createRelocSections");
344   // Don't use iterator here since we are adding to OutputSection
345   size_t OrigSize = OutputSections.size();
346   for (size_t i = 0; i < OrigSize; i++) {
347     OutputSection *OSec = OutputSections[i];
348     uint32_t Count = OSec->numRelocations();
349     if (!Count)
350       continue;
351 
352     StringRef Name;
353     if (OSec->Type == WASM_SEC_DATA)
354       Name = "reloc.DATA";
355     else if (OSec->Type == WASM_SEC_CODE)
356       Name = "reloc.CODE";
357     else
358       llvm_unreachable("relocations only supported for code and data");
359 
360     SyntheticSection *Section = createSyntheticSection(WASM_SEC_CUSTOM, Name);
361     raw_ostream &OS = Section->getStream();
362     writeUleb128(OS, OSec->Type, "reloc section");
363     writeUleb128(OS, Count, "reloc count");
364     OSec->writeRelocations(OS);
365   }
366 }
367 
368 static uint32_t getWasmFlags(const Symbol *Sym) {
369   uint32_t Flags = 0;
370   if (Sym->isLocal())
371     Flags |= WASM_SYMBOL_BINDING_LOCAL;
372   if (Sym->isWeak())
373     Flags |= WASM_SYMBOL_BINDING_WEAK;
374   if (Sym->isHidden())
375     Flags |= WASM_SYMBOL_VISIBILITY_HIDDEN;
376   if (Sym->isUndefined())
377     Flags |= WASM_SYMBOL_UNDEFINED;
378   return Flags;
379 }
380 
381 // Some synthetic sections (e.g. "name" and "linking") have subsections.
382 // Just like the synthetic sections themselves these need to be created before
383 // they can be written out (since they are preceded by their length). This
384 // class is used to create subsections and then write them into the stream
385 // of the parent section.
386 class SubSection {
387 public:
388   explicit SubSection(uint32_t Type) : Type(Type) {}
389 
390   void writeTo(raw_ostream &To) {
391     OS.flush();
392     writeUleb128(To, Type, "subsection type");
393     writeUleb128(To, Body.size(), "subsection size");
394     To.write(Body.data(), Body.size());
395   }
396 
397 private:
398   uint32_t Type;
399   std::string Body;
400 
401 public:
402   raw_string_ostream OS{Body};
403 };
404 
405 // Create the custom "linking" section containing linker metadata.
406 // This is only created when relocatable output is requested.
407 void Writer::createLinkingSection() {
408   SyntheticSection *Section =
409       createSyntheticSection(WASM_SEC_CUSTOM, "linking");
410   raw_ostream &OS = Section->getStream();
411 
412   if (!Config->Relocatable)
413     return;
414 
415   if (!SymtabEntries.empty()) {
416     SubSection Sub(WASM_SYMBOL_TABLE);
417     writeUleb128(Sub.OS, SymtabEntries.size(), "num symbols");
418 
419     for (const Symbol *Sym : SymtabEntries) {
420       assert(Sym->isDefined() || Sym->isUndefined());
421       WasmSymbolType Kind = Sym->getWasmType();
422       uint32_t Flags = getWasmFlags(Sym);
423 
424       writeU8(Sub.OS, Kind, "sym kind");
425       writeUleb128(Sub.OS, Flags, "sym flags");
426 
427       if (auto *F = dyn_cast<FunctionSymbol>(Sym)) {
428         writeUleb128(Sub.OS, F->getFunctionIndex(), "index");
429         if (Sym->isDefined())
430           writeStr(Sub.OS, Sym->getName(), "sym name");
431       } else if (auto *G = dyn_cast<GlobalSymbol>(Sym)) {
432         writeUleb128(Sub.OS, G->getGlobalIndex(), "index");
433         if (Sym->isDefined())
434           writeStr(Sub.OS, Sym->getName(), "sym name");
435       } else {
436         assert(isa<DataSymbol>(Sym));
437         writeStr(Sub.OS, Sym->getName(), "sym name");
438         if (auto *DataSym = dyn_cast<DefinedData>(Sym)) {
439           writeUleb128(Sub.OS, DataSym->getOutputSegmentIndex(), "index");
440           writeUleb128(Sub.OS, DataSym->getOutputSegmentOffset(),
441                        "data offset");
442           writeUleb128(Sub.OS, DataSym->getSize(), "data size");
443         }
444       }
445     }
446 
447     Sub.writeTo(OS);
448   }
449 
450   if (Segments.size()) {
451     SubSection Sub(WASM_SEGMENT_INFO);
452     writeUleb128(Sub.OS, Segments.size(), "num data segments");
453     for (const OutputSegment *S : Segments) {
454       writeStr(Sub.OS, S->Name, "segment name");
455       writeUleb128(Sub.OS, S->Alignment, "alignment");
456       writeUleb128(Sub.OS, 0, "flags");
457     }
458     Sub.writeTo(OS);
459   }
460 
461   if (!InitFunctions.empty()) {
462     SubSection Sub(WASM_INIT_FUNCS);
463     writeUleb128(Sub.OS, InitFunctions.size(), "num init functions");
464     for (const WasmInitEntry &F : InitFunctions) {
465       writeUleb128(Sub.OS, F.Priority, "priority");
466       writeUleb128(Sub.OS, F.Sym->getOutputSymbolIndex(), "function index");
467     }
468     Sub.writeTo(OS);
469   }
470 
471   struct ComdatEntry {
472     unsigned Kind;
473     uint32_t Index;
474   };
475   std::map<StringRef, std::vector<ComdatEntry>> Comdats;
476 
477   for (const InputFunction *F : InputFunctions) {
478     StringRef Comdat = F->getComdatName();
479     if (!Comdat.empty())
480       Comdats[Comdat].emplace_back(
481           ComdatEntry{WASM_COMDAT_FUNCTION, F->getFunctionIndex()});
482   }
483   for (uint32_t I = 0; I < Segments.size(); ++I) {
484     const auto &InputSegments = Segments[I]->InputSegments;
485     if (InputSegments.empty())
486       continue;
487     StringRef Comdat = InputSegments[0]->getComdatName();
488 #ifndef NDEBUG
489     for (const InputSegment *IS : InputSegments)
490       assert(IS->getComdatName() == Comdat);
491 #endif
492     if (!Comdat.empty())
493       Comdats[Comdat].emplace_back(ComdatEntry{WASM_COMDAT_DATA, I});
494   }
495 
496   if (!Comdats.empty()) {
497     SubSection Sub(WASM_COMDAT_INFO);
498     writeUleb128(Sub.OS, Comdats.size(), "num comdats");
499     for (const auto &C : Comdats) {
500       writeStr(Sub.OS, C.first, "comdat name");
501       writeUleb128(Sub.OS, 0, "comdat flags"); // flags for future use
502       writeUleb128(Sub.OS, C.second.size(), "num entries");
503       for (const ComdatEntry &Entry : C.second) {
504         writeU8(Sub.OS, Entry.Kind, "entry kind");
505         writeUleb128(Sub.OS, Entry.Index, "entry index");
506       }
507     }
508     Sub.writeTo(OS);
509   }
510 }
511 
512 // Create the custom "name" section containing debug symbol names.
513 void Writer::createNameSection() {
514   unsigned NumNames = NumImportedFunctions;
515   for (const InputFunction *F : InputFunctions)
516     if (!F->getName().empty())
517       ++NumNames;
518 
519   if (NumNames == 0)
520     return;
521 
522   SyntheticSection *Section = createSyntheticSection(WASM_SEC_CUSTOM, "name");
523 
524   SubSection Sub(WASM_NAMES_FUNCTION);
525   writeUleb128(Sub.OS, NumNames, "name count");
526 
527   // Names must appear in function index order.  As it happens ImportedSymbols
528   // and InputFunctions are numbered in order with imported functions coming
529   // first.
530   for (const Symbol *S : ImportedSymbols) {
531     if (auto *F = dyn_cast<FunctionSymbol>(S)) {
532       writeUleb128(Sub.OS, F->getFunctionIndex(), "func index");
533       Optional<std::string> Name = demangleItanium(F->getName());
534       writeStr(Sub.OS, Name ? StringRef(*Name) : F->getName(), "symbol name");
535     }
536   }
537   for (const InputFunction *F : InputFunctions) {
538     if (!F->getName().empty()) {
539       writeUleb128(Sub.OS, F->getFunctionIndex(), "func index");
540       Optional<std::string> Name = demangleItanium(F->getName());
541       writeStr(Sub.OS, Name ? StringRef(*Name) : F->getName(), "symbol name");
542     }
543   }
544 
545   Sub.writeTo(Section->getStream());
546 }
547 
548 void Writer::writeHeader() {
549   memcpy(Buffer->getBufferStart(), Header.data(), Header.size());
550 }
551 
552 void Writer::writeSections() {
553   uint8_t *Buf = Buffer->getBufferStart();
554   parallelForEach(OutputSections, [Buf](OutputSection *S) { S->writeTo(Buf); });
555 }
556 
557 // Fix the memory layout of the output binary.  This assigns memory offsets
558 // to each of the input data sections as well as the explicit stack region.
559 // The memory layout is as follows, from low to high.
560 //  - initialized data (starting at Config->GlobalBase)
561 //  - BSS data (not currently implemented in llvm)
562 //  - explicit stack (Config->ZStackSize)
563 //  - heap start / unallocated
564 void Writer::layoutMemory() {
565   uint32_t MemoryPtr = 0;
566   MemoryPtr = Config->GlobalBase;
567   log("mem: global base = " + Twine(Config->GlobalBase));
568 
569   createOutputSegments();
570 
571   // Arbitrarily set __dso_handle handle to point to the start of the data
572   // segments.
573   if (WasmSym::DsoHandle)
574     WasmSym::DsoHandle->setVirtualAddress(MemoryPtr);
575 
576   for (OutputSegment *Seg : Segments) {
577     MemoryPtr = alignTo(MemoryPtr, Seg->Alignment);
578     Seg->StartVA = MemoryPtr;
579     log(formatv("mem: {0,-15} offset={1,-8} size={2,-8} align={3}", Seg->Name,
580                 MemoryPtr, Seg->Size, Seg->Alignment));
581     MemoryPtr += Seg->Size;
582   }
583 
584   // TODO: Add .bss space here.
585   if (WasmSym::DataEnd)
586     WasmSym::DataEnd->setVirtualAddress(MemoryPtr);
587 
588   log("mem: static data = " + Twine(MemoryPtr - Config->GlobalBase));
589 
590   // Stack comes after static data and bss
591   if (!Config->Relocatable) {
592     MemoryPtr = alignTo(MemoryPtr, kStackAlignment);
593     if (Config->ZStackSize != alignTo(Config->ZStackSize, kStackAlignment))
594       error("stack size must be " + Twine(kStackAlignment) + "-byte aligned");
595     log("mem: stack size  = " + Twine(Config->ZStackSize));
596     log("mem: stack base  = " + Twine(MemoryPtr));
597     MemoryPtr += Config->ZStackSize;
598     WasmSym::StackPointer->Global->Global.InitExpr.Value.Int32 = MemoryPtr;
599     log("mem: stack top   = " + Twine(MemoryPtr));
600 
601     // Set `__heap_base` to directly follow the end of the stack.  We don't
602     // allocate any heap memory up front, but instead really on the malloc/brk
603     // implementation growing the memory at runtime.
604     WasmSym::HeapBase->setVirtualAddress(MemoryPtr);
605     log("mem: heap base   = " + Twine(MemoryPtr));
606   }
607 
608   if (Config->InitialMemory != 0) {
609     if (Config->InitialMemory != alignTo(Config->InitialMemory, WasmPageSize))
610       error("initial memory must be " + Twine(WasmPageSize) + "-byte aligned");
611     if (MemoryPtr > Config->InitialMemory)
612       error("initial memory too small, " + Twine(MemoryPtr) + " bytes needed");
613     else
614       MemoryPtr = Config->InitialMemory;
615   }
616   uint32_t MemSize = alignTo(MemoryPtr, WasmPageSize);
617   NumMemoryPages = MemSize / WasmPageSize;
618   log("mem: total pages = " + Twine(NumMemoryPages));
619 
620   if (Config->MaxMemory != 0) {
621     if (Config->MaxMemory != alignTo(Config->MaxMemory, WasmPageSize))
622       error("maximum memory must be " + Twine(WasmPageSize) + "-byte aligned");
623     if (MemoryPtr > Config->MaxMemory)
624       error("maximum memory too small, " + Twine(MemoryPtr) + " bytes needed");
625     MaxMemoryPages = Config->MaxMemory / WasmPageSize;
626     log("mem: max pages   = " + Twine(MaxMemoryPages));
627   }
628 }
629 
630 SyntheticSection *Writer::createSyntheticSection(uint32_t Type,
631                                                  StringRef Name) {
632   auto Sec = make<SyntheticSection>(Type, Name);
633   log("createSection: " + toString(*Sec));
634   OutputSections.push_back(Sec);
635   return Sec;
636 }
637 
638 void Writer::createSections() {
639   // Known sections
640   createTypeSection();
641   createImportSection();
642   createFunctionSection();
643   createTableSection();
644   createMemorySection();
645   createGlobalSection();
646   createExportSection();
647   createElemSection();
648   createCodeSection();
649   createDataSection();
650 
651   // Custom sections
652   if (Config->Relocatable) {
653     createLinkingSection();
654     createRelocSections();
655   }
656   if (!Config->StripDebug && !Config->StripAll)
657     createNameSection();
658 
659   for (OutputSection *S : OutputSections) {
660     S->setOffset(FileSize);
661     S->finalizeContents();
662     FileSize += S->getSize();
663   }
664 }
665 
666 void Writer::calculateImports() {
667   for (Symbol *Sym : Symtab->getSymbols()) {
668     if (!Sym->isUndefined())
669       continue;
670     if (isa<DataSymbol>(Sym))
671       continue;
672     if (Sym->isWeak() && !Config->Relocatable)
673       continue;
674 
675     DEBUG(dbgs() << "import: " << Sym->getName() << "\n");
676     ImportedSymbols.emplace_back(Sym);
677     if (auto *F = dyn_cast<FunctionSymbol>(Sym))
678       F->setFunctionIndex(NumImportedFunctions++);
679     else
680       cast<GlobalSymbol>(Sym)->setGlobalIndex(NumImportedGlobals++);
681   }
682 }
683 
684 void Writer::calculateExports() {
685   if (Config->Relocatable)
686     return;
687 
688   for (Symbol *Sym : Symtab->getSymbols()) {
689     if (!Sym->isDefined())
690       continue;
691     if (Sym->isHidden() || Sym->isLocal())
692       continue;
693     if (!Sym->isLive())
694       continue;
695 
696     DEBUG(dbgs() << "exporting sym: " << Sym->getName() << "\n");
697 
698     if (auto *D = dyn_cast<DefinedData>(Sym))
699       DefinedFakeGlobals.emplace_back(D);
700     ExportedSymbols.emplace_back(Sym);
701   }
702 }
703 
704 void Writer::assignSymtab() {
705   if (!Config->Relocatable)
706     return;
707 
708   unsigned SymbolIndex = SymtabEntries.size();
709   for (ObjFile *File : Symtab->ObjectFiles) {
710     DEBUG(dbgs() << "Symtab entries: " << File->getName() << "\n");
711     for (Symbol *Sym : File->getSymbols()) {
712       if (Sym->getFile() != File)
713         continue;
714       // (Since this is relocatable output, GC is not performed so symbols must
715       // be live.)
716       assert(Sym->isLive());
717       Sym->setOutputSymbolIndex(SymbolIndex++);
718       SymtabEntries.emplace_back(Sym);
719     }
720   }
721 
722   // For the moment, relocatable output doesn't contain any synthetic functions,
723   // so no need to look through the Symtab for symbols not referenced by
724   // Symtab->ObjectFiles.
725 }
726 
727 uint32_t Writer::lookupType(const WasmSignature &Sig) {
728   auto It = TypeIndices.find(Sig);
729   if (It == TypeIndices.end()) {
730     error("type not found: " + toString(Sig));
731     return 0;
732   }
733   return It->second;
734 }
735 
736 uint32_t Writer::registerType(const WasmSignature &Sig) {
737   auto Pair = TypeIndices.insert(std::make_pair(Sig, Types.size()));
738   if (Pair.second) {
739     DEBUG(dbgs() << "type " << toString(Sig) << "\n");
740     Types.push_back(&Sig);
741   }
742   return Pair.first->second;
743 }
744 
745 void Writer::calculateTypes() {
746   // The output type section is the union of the following sets:
747   // 1. Any signature used in the TYPE relocation
748   // 2. The signatures of all imported functions
749   // 3. The signatures of all defined functions
750 
751   for (ObjFile *File : Symtab->ObjectFiles) {
752     ArrayRef<WasmSignature> Types = File->getWasmObj()->types();
753     for (uint32_t I = 0; I < Types.size(); I++)
754       if (File->TypeIsUsed[I])
755         File->TypeMap[I] = registerType(Types[I]);
756   }
757 
758   for (const Symbol *Sym : ImportedSymbols)
759     if (auto *F = dyn_cast<FunctionSymbol>(Sym))
760       registerType(*F->getFunctionType());
761 
762   for (const InputFunction *F : InputFunctions)
763     registerType(F->Signature);
764 }
765 
766 void Writer::assignIndexes() {
767   uint32_t FunctionIndex = NumImportedFunctions + InputFunctions.size();
768   auto AddDefinedFunction = [&](InputFunction *Func) {
769     if (!Func->Live)
770       return;
771     InputFunctions.emplace_back(Func);
772     Func->setFunctionIndex(FunctionIndex++);
773   };
774 
775   for (InputFunction *Func : Symtab->SyntheticFunctions)
776     AddDefinedFunction(Func);
777 
778   for (ObjFile *File : Symtab->ObjectFiles) {
779     DEBUG(dbgs() << "Functions: " << File->getName() << "\n");
780     for (InputFunction *Func : File->Functions)
781       AddDefinedFunction(Func);
782   }
783 
784   uint32_t TableIndex = kInitialTableOffset;
785   auto HandleRelocs = [&](InputChunk *Chunk) {
786     if (!Chunk->Live)
787       return;
788     ObjFile *File = Chunk->File;
789     ArrayRef<WasmSignature> Types = File->getWasmObj()->types();
790     for (const WasmRelocation &Reloc : Chunk->getRelocations()) {
791       if (Reloc.Type == R_WEBASSEMBLY_TABLE_INDEX_I32 ||
792           Reloc.Type == R_WEBASSEMBLY_TABLE_INDEX_SLEB) {
793         FunctionSymbol *Sym = File->getFunctionSymbol(Reloc.Index);
794         if (Sym->hasTableIndex() || !Sym->hasFunctionIndex())
795           continue;
796         Sym->setTableIndex(TableIndex++);
797         IndirectFunctions.emplace_back(Sym);
798       } else if (Reloc.Type == R_WEBASSEMBLY_TYPE_INDEX_LEB) {
799         // Mark target type as live
800         File->TypeMap[Reloc.Index] = registerType(Types[Reloc.Index]);
801         File->TypeIsUsed[Reloc.Index] = true;
802       } else if (Reloc.Type == R_WEBASSEMBLY_GLOBAL_INDEX_LEB) {
803         // Mark target global as live
804         GlobalSymbol *Sym = File->getGlobalSymbol(Reloc.Index);
805         if (auto *G = dyn_cast<DefinedGlobal>(Sym)) {
806           DEBUG(dbgs() << "marking global live: " << Sym->getName() << "\n");
807           G->Global->Live = true;
808         }
809       }
810     }
811   };
812 
813   for (ObjFile *File : Symtab->ObjectFiles) {
814     DEBUG(dbgs() << "Handle relocs: " << File->getName() << "\n");
815     for (InputChunk *Chunk : File->Functions)
816       HandleRelocs(Chunk);
817     for (InputChunk *Chunk : File->Segments)
818       HandleRelocs(Chunk);
819   }
820 
821   uint32_t GlobalIndex = NumImportedGlobals + InputGlobals.size();
822   auto AddDefinedGlobal = [&](InputGlobal *Global) {
823     if (Global->Live) {
824       DEBUG(dbgs() << "AddDefinedGlobal: " << GlobalIndex << "\n");
825       Global->setGlobalIndex(GlobalIndex++);
826       InputGlobals.push_back(Global);
827     }
828   };
829 
830   for (InputGlobal *Global : Symtab->SyntheticGlobals)
831     AddDefinedGlobal(Global);
832 
833   for (ObjFile *File : Symtab->ObjectFiles) {
834     DEBUG(dbgs() << "Globals: " << File->getName() << "\n");
835     for (InputGlobal *Global : File->Globals)
836       AddDefinedGlobal(Global);
837   }
838 }
839 
840 static StringRef getOutputDataSegmentName(StringRef Name) {
841   if (Config->Relocatable)
842     return Name;
843   if (Name.startswith(".text."))
844     return ".text";
845   if (Name.startswith(".data."))
846     return ".data";
847   if (Name.startswith(".bss."))
848     return ".bss";
849   return Name;
850 }
851 
852 void Writer::createOutputSegments() {
853   for (ObjFile *File : Symtab->ObjectFiles) {
854     for (InputSegment *Segment : File->Segments) {
855       if (!Segment->Live)
856         continue;
857       StringRef Name = getOutputDataSegmentName(Segment->getName());
858       OutputSegment *&S = SegmentMap[Name];
859       if (S == nullptr) {
860         DEBUG(dbgs() << "new segment: " << Name << "\n");
861         S = make<OutputSegment>(Name, Segments.size());
862         Segments.push_back(S);
863       }
864       S->addInputSegment(Segment);
865       DEBUG(dbgs() << "added data: " << Name << ": " << S->Size << "\n");
866     }
867   }
868 }
869 
870 static const int OPCODE_CALL = 0x10;
871 static const int OPCODE_END = 0xb;
872 
873 // Create synthetic "__wasm_call_ctors" function based on ctor functions
874 // in input object.
875 void Writer::createCtorFunction() {
876   // First write the body's contents to a string.
877   std::string BodyContent;
878   {
879     raw_string_ostream OS(BodyContent);
880     writeUleb128(OS, 0, "num locals");
881     for (const WasmInitEntry &F : InitFunctions) {
882       writeU8(OS, OPCODE_CALL, "CALL");
883       writeUleb128(OS, F.Sym->getFunctionIndex(), "function index");
884     }
885     writeU8(OS, OPCODE_END, "END");
886   }
887 
888   // Once we know the size of the body we can create the final function body
889   std::string FunctionBody;
890   {
891     raw_string_ostream OS(FunctionBody);
892     writeUleb128(OS, BodyContent.size(), "function size");
893     OS << BodyContent;
894   }
895 
896   ArrayRef<uint8_t> Body = toArrayRef(Saver.save(FunctionBody));
897   cast<SyntheticFunction>(WasmSym::CallCtors->Function)->setBody(Body);
898 }
899 
900 // Populate InitFunctions vector with init functions from all input objects.
901 // This is then used either when creating the output linking section or to
902 // synthesize the "__wasm_call_ctors" function.
903 void Writer::calculateInitFunctions() {
904   for (ObjFile *File : Symtab->ObjectFiles) {
905     const WasmLinkingData &L = File->getWasmObj()->linkingData();
906     for (const WasmInitFunc &F : L.InitFunctions) {
907       FunctionSymbol *Sym = File->getFunctionSymbol(F.Symbol);
908       if (*Sym->getFunctionType() != WasmSignature{{}, WASM_TYPE_NORESULT})
909         error("invalid signature for init func: " + toString(*Sym));
910       InitFunctions.emplace_back(WasmInitEntry{Sym, F.Priority});
911     }
912   }
913 
914   // Sort in order of priority (lowest first) so that they are called
915   // in the correct order.
916   std::stable_sort(InitFunctions.begin(), InitFunctions.end(),
917                    [](const WasmInitEntry &L, const WasmInitEntry &R) {
918                      return L.Priority < R.Priority;
919                    });
920 }
921 
922 void Writer::run() {
923   if (Config->Relocatable)
924     Config->GlobalBase = 0;
925 
926   log("-- calculateImports");
927   calculateImports();
928   log("-- assignIndexes");
929   assignIndexes();
930   log("-- calculateInitFunctions");
931   calculateInitFunctions();
932   if (!Config->Relocatable)
933     createCtorFunction();
934   log("-- calculateTypes");
935   calculateTypes();
936   log("-- layoutMemory");
937   layoutMemory();
938   log("-- calculateExports");
939   calculateExports();
940   log("-- assignSymtab");
941   assignSymtab();
942 
943   if (errorHandler().Verbose) {
944     log("Defined Functions: " + Twine(InputFunctions.size()));
945     log("Defined Globals  : " + Twine(InputGlobals.size()));
946     log("Function Imports : " + Twine(NumImportedFunctions));
947     log("Global Imports   : " + Twine(NumImportedGlobals));
948     for (ObjFile *File : Symtab->ObjectFiles)
949       File->dumpInfo();
950   }
951 
952   createHeader();
953   log("-- createSections");
954   createSections();
955 
956   log("-- openFile");
957   openFile();
958   if (errorCount())
959     return;
960 
961   writeHeader();
962 
963   log("-- writeSections");
964   writeSections();
965   if (errorCount())
966     return;
967 
968   if (Error E = Buffer->commit())
969     fatal("failed to write the output file: " + toString(std::move(E)));
970 }
971 
972 // Open a result file.
973 void Writer::openFile() {
974   log("writing: " + Config->OutputFile);
975 
976   Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
977       FileOutputBuffer::create(Config->OutputFile, FileSize,
978                                FileOutputBuffer::F_executable);
979 
980   if (!BufferOrErr)
981     error("failed to open " + Config->OutputFile + ": " +
982           toString(BufferOrErr.takeError()));
983   else
984     Buffer = std::move(*BufferOrErr);
985 }
986 
987 void Writer::createHeader() {
988   raw_string_ostream OS(Header);
989   writeBytes(OS, WasmMagic, sizeof(WasmMagic), "wasm magic");
990   writeU32(OS, WasmVersion, "wasm version");
991   OS.flush();
992   FileSize += Header.size();
993 }
994 
995 void lld::wasm::writeResult() { Writer().run(); }
996