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