xref: /llvm-project-15.0.7/lld/wasm/Writer.cpp (revision 4bdb80fa)
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 
12 #include "llvm/ADT/DenseSet.h"
13 #include "Config.h"
14 #include "InputChunks.h"
15 #include "OutputSections.h"
16 #include "OutputSegment.h"
17 #include "SymbolTable.h"
18 #include "WriterUtils.h"
19 #include "lld/Common/ErrorHandler.h"
20 #include "lld/Common/Memory.h"
21 #include "lld/Common/Threads.h"
22 #include "llvm/Support/FileOutputBuffer.h"
23 #include "llvm/Support/Format.h"
24 #include "llvm/Support/FormatVariadic.h"
25 #include "llvm/Support/LEB128.h"
26 
27 #include <cstdarg>
28 #include <map>
29 
30 #define DEBUG_TYPE "lld"
31 
32 using namespace llvm;
33 using namespace llvm::wasm;
34 using namespace lld;
35 using namespace lld::wasm;
36 
37 static constexpr int kStackAlignment = 16;
38 
39 namespace {
40 
41 // Traits for using WasmSignature in a DenseMap.
42 struct WasmSignatureDenseMapInfo {
43   static WasmSignature getEmptyKey() {
44     WasmSignature Sig;
45     Sig.ReturnType = 1;
46     return Sig;
47   }
48   static WasmSignature getTombstoneKey() {
49     WasmSignature Sig;
50     Sig.ReturnType = 2;
51     return Sig;
52   }
53   static unsigned getHashValue(const WasmSignature &Sig) {
54     uintptr_t Value = 0;
55     Value += DenseMapInfo<int32_t>::getHashValue(Sig.ReturnType);
56     for (int32_t Param : Sig.ParamTypes)
57       Value += DenseMapInfo<int32_t>::getHashValue(Param);
58     return Value;
59   }
60   static bool isEqual(const WasmSignature &LHS, const WasmSignature &RHS) {
61     return LHS == RHS;
62   }
63 };
64 
65 // The writer writes a SymbolTable result to a file.
66 class Writer {
67 public:
68   void run();
69 
70 private:
71   void openFile();
72 
73   uint32_t lookupType(const WasmSignature &Sig);
74   uint32_t registerType(const WasmSignature &Sig);
75   void createCtorFunction();
76   void calculateInitFunctions();
77   void assignIndexes();
78   void calculateImports();
79   void calculateOffsets();
80   void calculateTypes();
81   void createOutputSegments();
82   void layoutMemory();
83   void createHeader();
84   void createSections();
85   SyntheticSection *createSyntheticSection(uint32_t Type,
86                                            StringRef Name = "");
87 
88   // Builtin sections
89   void createTypeSection();
90   void createFunctionSection();
91   void createTableSection();
92   void createGlobalSection();
93   void createExportSection();
94   void createImportSection();
95   void createMemorySection();
96   void createElemSection();
97   void createStartSection();
98   void createCodeSection();
99   void createDataSection();
100 
101   // Custom sections
102   void createRelocSections();
103   void createLinkingSection();
104   void createNameSection();
105 
106   void writeHeader();
107   void writeSections();
108 
109   uint64_t FileSize = 0;
110   uint32_t DataSize = 0;
111   uint32_t NumMemoryPages = 0;
112   uint32_t InitialTableOffset = 0;
113 
114   std::vector<const WasmSignature *> Types;
115   DenseMap<WasmSignature, int32_t, WasmSignatureDenseMapInfo> TypeIndices;
116   std::vector<const Symbol *> ImportedFunctions;
117   std::vector<const Symbol *> ImportedGlobals;
118   std::vector<const Symbol *> DefinedGlobals;
119   std::vector<InputFunction *> DefinedFunctions;
120   std::vector<const Symbol *> IndirectFunctions;
121   std::vector<WasmInitFunc> InitFunctions;
122 
123   // Elements that are used to construct the final output
124   std::string Header;
125   std::vector<OutputSection *> OutputSections;
126 
127   std::unique_ptr<FileOutputBuffer> Buffer;
128   std::unique_ptr<SyntheticFunction> CtorFunction;
129   std::string CtorFunctionBody;
130 
131   std::vector<OutputSegment *> Segments;
132   llvm::SmallDenseMap<StringRef, OutputSegment *> SegmentMap;
133 };
134 
135 } // anonymous namespace
136 
137 static void debugPrint(const char *fmt, ...) {
138   if (!errorHandler().Verbose)
139     return;
140   fprintf(stderr, "lld: ");
141   va_list ap;
142   va_start(ap, fmt);
143   vfprintf(stderr, fmt, ap);
144   va_end(ap);
145 }
146 
147 void Writer::createImportSection() {
148   uint32_t NumImports = ImportedFunctions.size() + ImportedGlobals.size();
149   if (Config->ImportMemory)
150     ++NumImports;
151 
152   if (NumImports == 0)
153     return;
154 
155   SyntheticSection *Section = createSyntheticSection(WASM_SEC_IMPORT);
156   raw_ostream &OS = Section->getStream();
157 
158   writeUleb128(OS, NumImports, "import count");
159 
160   for (const Symbol *Sym : ImportedFunctions) {
161     WasmImport Import;
162     Import.Module = "env";
163     Import.Field = Sym->getName();
164     Import.Kind = WASM_EXTERNAL_FUNCTION;
165     Import.SigIndex = lookupType(Sym->getFunctionType());
166     writeImport(OS, Import);
167   }
168 
169   if (Config->ImportMemory) {
170     WasmImport Import;
171     Import.Module = "env";
172     Import.Field = "memory";
173     Import.Kind = WASM_EXTERNAL_MEMORY;
174     Import.Memory.Flags = 0;
175     Import.Memory.Initial = NumMemoryPages;
176     writeImport(OS, Import);
177   }
178 
179   for (const Symbol *Sym : ImportedGlobals) {
180     WasmImport Import;
181     Import.Module = "env";
182     Import.Field = Sym->getName();
183     Import.Kind = WASM_EXTERNAL_GLOBAL;
184     Import.Global.Mutable = false;
185     Import.Global.Type = WASM_TYPE_I32;
186     writeImport(OS, Import);
187   }
188 }
189 
190 void Writer::createTypeSection() {
191   SyntheticSection *Section = createSyntheticSection(WASM_SEC_TYPE);
192   raw_ostream &OS = Section->getStream();
193   writeUleb128(OS, Types.size(), "type count");
194   for (const WasmSignature *Sig : Types)
195     writeSig(OS, *Sig);
196 }
197 
198 void Writer::createFunctionSection() {
199   if (DefinedFunctions.empty())
200     return;
201 
202   SyntheticSection *Section = createSyntheticSection(WASM_SEC_FUNCTION);
203   raw_ostream &OS = Section->getStream();
204 
205   writeUleb128(OS, DefinedFunctions.size(), "function count");
206   for (const InputFunction *Func : DefinedFunctions)
207     writeUleb128(OS, lookupType(Func->Signature), "sig index");
208 }
209 
210 void Writer::createMemorySection() {
211   if (Config->ImportMemory)
212     return;
213 
214   SyntheticSection *Section = createSyntheticSection(WASM_SEC_MEMORY);
215   raw_ostream &OS = Section->getStream();
216 
217   writeUleb128(OS, 1, "memory count");
218   writeUleb128(OS, 0, "memory limits flags");
219   writeUleb128(OS, NumMemoryPages, "initial pages");
220 }
221 
222 void Writer::createGlobalSection() {
223   if (DefinedGlobals.empty())
224     return;
225 
226   SyntheticSection *Section = createSyntheticSection(WASM_SEC_GLOBAL);
227   raw_ostream &OS = Section->getStream();
228 
229   writeUleb128(OS, DefinedGlobals.size(), "global count");
230   for (const Symbol *Sym : DefinedGlobals) {
231     WasmGlobal Global;
232     Global.Type = WASM_TYPE_I32;
233     Global.Mutable = Sym == Config->StackPointerSymbol;
234     Global.InitExpr.Opcode = WASM_OPCODE_I32_CONST;
235     Global.InitExpr.Value.Int32 = Sym->getVirtualAddress();
236     writeGlobal(OS, Global);
237   }
238 }
239 
240 void Writer::createTableSection() {
241   // Always output a table section, even if there are no indirect calls.
242   // There are two reasons for this:
243   //  1. For executables it is useful to have an empty table slot at 0
244   //     which can be filled with a null function call handler.
245   //  2. If we don't do this, any program that contains a call_indirect but
246   //     no address-taken function will fail at validation time since it is
247   //     a validation error to include a call_indirect instruction if there
248   //     is not table.
249   uint32_t TableSize = InitialTableOffset + IndirectFunctions.size();
250 
251   SyntheticSection *Section = createSyntheticSection(WASM_SEC_TABLE);
252   raw_ostream &OS = Section->getStream();
253 
254   writeUleb128(OS, 1, "table count");
255   writeSleb128(OS, WASM_TYPE_ANYFUNC, "table type");
256   writeUleb128(OS, WASM_LIMITS_FLAG_HAS_MAX, "table flags");
257   writeUleb128(OS, TableSize, "table initial size");
258   writeUleb128(OS, TableSize, "table max size");
259 }
260 
261 void Writer::createExportSection() {
262   bool ExportMemory = !Config->Relocatable && !Config->ImportMemory;
263   Symbol *EntrySym = Symtab->find(Config->Entry);
264   bool ExportEntry = !Config->Relocatable && EntrySym && EntrySym->isDefined();
265   bool ExportHidden = Config->EmitRelocs;
266 
267   uint32_t NumExports = ExportMemory ? 1 : 0;
268 
269   std::vector<const Symbol *> SymbolExports;
270   if (ExportEntry)
271     SymbolExports.emplace_back(EntrySym);
272 
273   for (const Symbol *Sym : Symtab->getSymbols()) {
274     if (Sym->isUndefined() || Sym->isGlobal())
275       continue;
276     if (Sym->isHidden() && !ExportHidden)
277       continue;
278     if (ExportEntry && Sym == EntrySym)
279       continue;
280     SymbolExports.emplace_back(Sym);
281   }
282 
283   for (const Symbol *Sym : DefinedGlobals) {
284     // Can't export the SP right now because it mutable and mutable globals
285     // connot be exported.
286     if (Sym == Config->StackPointerSymbol)
287       continue;
288     SymbolExports.emplace_back(Sym);
289   }
290 
291   NumExports += SymbolExports.size();
292   if (!NumExports)
293     return;
294 
295   SyntheticSection *Section = createSyntheticSection(WASM_SEC_EXPORT);
296   raw_ostream &OS = Section->getStream();
297 
298   writeUleb128(OS, NumExports, "export count");
299 
300   if (ExportMemory) {
301     WasmExport MemoryExport;
302     MemoryExport.Name = "memory";
303     MemoryExport.Kind = WASM_EXTERNAL_MEMORY;
304     MemoryExport.Index = 0;
305     writeExport(OS, MemoryExport);
306   }
307 
308   for (const Symbol *Sym : SymbolExports) {
309     DEBUG(dbgs() << "Export: " << Sym->getName() << "\n");
310     WasmExport Export;
311     Export.Name = Sym->getName();
312     Export.Index = Sym->getOutputIndex();
313     if (Sym->isFunction())
314       Export.Kind = WASM_EXTERNAL_FUNCTION;
315     else
316       Export.Kind = WASM_EXTERNAL_GLOBAL;
317     writeExport(OS, Export);
318   }
319 }
320 
321 void Writer::createStartSection() {}
322 
323 void Writer::createElemSection() {
324   if (IndirectFunctions.empty())
325     return;
326 
327   SyntheticSection *Section = createSyntheticSection(WASM_SEC_ELEM);
328   raw_ostream &OS = Section->getStream();
329 
330   writeUleb128(OS, 1, "segment count");
331   writeUleb128(OS, 0, "table index");
332   WasmInitExpr InitExpr;
333   InitExpr.Opcode = WASM_OPCODE_I32_CONST;
334   InitExpr.Value.Int32 = InitialTableOffset;
335   writeInitExpr(OS, InitExpr);
336   writeUleb128(OS, IndirectFunctions.size(), "elem count");
337 
338   uint32_t TableIndex = InitialTableOffset;
339   for (const Symbol *Sym : IndirectFunctions) {
340     assert(Sym->getTableIndex() == TableIndex);
341     writeUleb128(OS, Sym->getOutputIndex(), "function index");
342     ++TableIndex;
343   }
344 }
345 
346 void Writer::createCodeSection() {
347   if (DefinedFunctions.empty())
348     return;
349 
350   log("createCodeSection");
351 
352   auto Section = make<CodeSection>(DefinedFunctions);
353   OutputSections.push_back(Section);
354 }
355 
356 void Writer::createDataSection() {
357   if (!Segments.size())
358     return;
359 
360   log("createDataSection");
361   auto Section = make<DataSection>(Segments);
362   OutputSections.push_back(Section);
363 }
364 
365 // Create relocations sections in the final output.
366 // These are only created when relocatable output is requested.
367 void Writer::createRelocSections() {
368   log("createRelocSections");
369   // Don't use iterator here since we are adding to OutputSection
370   size_t OrigSize = OutputSections.size();
371   for (size_t i = 0; i < OrigSize; i++) {
372     OutputSection *S = OutputSections[i];
373     const char *name;
374     uint32_t Count = S->numRelocations();
375     if (!Count)
376       continue;
377 
378     if (S->Type == WASM_SEC_DATA)
379       name = "reloc.DATA";
380     else if (S->Type == WASM_SEC_CODE)
381       name = "reloc.CODE";
382     else
383       llvm_unreachable("relocations only supported for code and data");
384 
385     SyntheticSection *Section = createSyntheticSection(WASM_SEC_CUSTOM, name);
386     raw_ostream &OS = Section->getStream();
387     writeUleb128(OS, S->Type, "reloc section");
388     writeUleb128(OS, Count, "reloc count");
389     S->writeRelocations(OS);
390   }
391 }
392 
393 // Create the custom "linking" section containing linker metadata.
394 // This is only created when relocatable output is requested.
395 void Writer::createLinkingSection() {
396   SyntheticSection *Section =
397       createSyntheticSection(WASM_SEC_CUSTOM, "linking");
398   raw_ostream &OS = Section->getStream();
399 
400   SubSection DataSizeSubSection(WASM_DATA_SIZE);
401   writeUleb128(DataSizeSubSection.getStream(), DataSize, "data size");
402   DataSizeSubSection.finalizeContents();
403   DataSizeSubSection.writeToStream(OS);
404 
405   if (!Config->Relocatable)
406     return;
407 
408   if (Segments.size()) {
409     SubSection SubSection(WASM_SEGMENT_INFO);
410     writeUleb128(SubSection.getStream(), Segments.size(), "num data segments");
411     for (const OutputSegment *S : Segments) {
412       writeStr(SubSection.getStream(), S->Name, "segment name");
413       writeUleb128(SubSection.getStream(), S->Alignment, "alignment");
414       writeUleb128(SubSection.getStream(), 0, "flags");
415     }
416     SubSection.finalizeContents();
417     SubSection.writeToStream(OS);
418   }
419 
420   if (!InitFunctions.empty()) {
421     SubSection SubSection(WASM_INIT_FUNCS);
422     writeUleb128(SubSection.getStream(), InitFunctions.size(),
423                  "num init functionsw");
424     for (const WasmInitFunc &F : InitFunctions) {
425       writeUleb128(SubSection.getStream(), F.Priority, "priority");
426       writeUleb128(SubSection.getStream(), F.FunctionIndex, "function index");
427     }
428     SubSection.finalizeContents();
429     SubSection.writeToStream(OS);
430   }
431 
432   struct ComdatEntry { unsigned Kind; uint32_t Index; };
433   std::map<StringRef,std::vector<ComdatEntry>> Comdats;
434 
435   for (const InputFunction *F : DefinedFunctions) {
436     StringRef Comdat = F->getComdat();
437     if (!Comdat.empty())
438       Comdats[Comdat].emplace_back(
439           ComdatEntry{WASM_COMDAT_FUNCTION, F->getOutputIndex()});
440   }
441   for (uint32_t I = 0; I < Segments.size(); ++I) {
442     const auto &InputSegments = Segments[I]->InputSegments;
443     if (InputSegments.empty())
444       continue;
445     StringRef Comdat = InputSegments[0]->getComdat();
446 #ifndef NDEBUG
447     for (const InputSegment *IS : InputSegments)
448       assert(IS->getComdat() == Comdat);
449 #endif
450     if (!Comdat.empty())
451       Comdats[Comdat].emplace_back(ComdatEntry{WASM_COMDAT_DATA, I});
452   }
453 
454   if (!Comdats.empty()) {
455     SubSection SubSection(WASM_COMDAT_INFO);
456     writeUleb128(SubSection.getStream(), Comdats.size(), "num comdats");
457     for (const auto &C : Comdats) {
458       writeStr(SubSection.getStream(), C.first, "comdat name");
459       writeUleb128(SubSection.getStream(), 0, "comdat flags"); // flags for future use
460       writeUleb128(SubSection.getStream(), C.second.size(), "num entries");
461       for (const ComdatEntry &Entry : C.second) {
462         writeUleb128(SubSection.getStream(), Entry.Kind, "entry kind");
463         writeUleb128(SubSection.getStream(), Entry.Index, "entry index");
464       }
465     }
466     SubSection.finalizeContents();
467     SubSection.writeToStream(OS);
468   }
469 }
470 
471 // Create the custom "name" section containing debug symbol names.
472 void Writer::createNameSection() {
473   // Create an array of all function sorted by function index space
474   std::vector<const Symbol *> Names;
475 
476   auto AddToNames = [&](Symbol* S) {
477     if (!S->isFunction() || S->WrittenToNameSec)
478         return;
479     // We also need to guard against two different symbols (two different
480     // names) for the same wasm function.  While this is possible (aliases)
481     // it is not legal in the "name" section.
482     InputFunction *Function = S->getFunction();
483     if (Function) {
484       if (Function->WrittenToNameSec)
485         return;
486       Function->WrittenToNameSec = true;
487     }
488     S->WrittenToNameSec = true;
489     Names.emplace_back(S);
490   };
491 
492   for (ObjFile *File : Symtab->ObjectFiles) {
493     Names.reserve(Names.size() + File->getSymbols().size());
494     DEBUG(dbgs() << "adding names from: " << File->getName() << "\n");
495     for (Symbol *S : File->getSymbols()) {
496       if (S->isWeak())
497         continue;
498       AddToNames(S);
499     }
500   }
501 
502   DEBUG(dbgs() << "adding symtab names\n");
503   for (Symbol *S : Symtab->getSymbols()) {
504     DEBUG(dbgs() << "sym: " << S->getName() << "\n");
505     if (S->getFile())
506       continue;
507     AddToNames(S);
508   }
509 
510   SyntheticSection *Section = createSyntheticSection(WASM_SEC_CUSTOM, "name");
511 
512   std::sort(Names.begin(), Names.end(), [](const Symbol *A, const Symbol *B) {
513     return A->getOutputIndex() < B->getOutputIndex();
514   });
515 
516   SubSection FunctionSubsection(WASM_NAMES_FUNCTION);
517   raw_ostream &OS = FunctionSubsection.getStream();
518   writeUleb128(OS, Names.size(), "name count");
519 
520   // We have to iterate through the inputs twice so that all the imports
521   // appear first before any of the local function names.
522   for (const Symbol *S : Names) {
523     writeUleb128(OS, S->getOutputIndex(), "func index");
524     writeStr(OS, S->getName(), "symbol name");
525   }
526 
527   FunctionSubsection.finalizeContents();
528   FunctionSubsection.writeToStream(Section->getStream());
529 }
530 
531 void Writer::writeHeader() {
532   memcpy(Buffer->getBufferStart(), Header.data(), Header.size());
533 }
534 
535 void Writer::writeSections() {
536   uint8_t *Buf = Buffer->getBufferStart();
537   parallelForEach(OutputSections, [Buf](OutputSection *S) { S->writeTo(Buf); });
538 }
539 
540 // Fix the memory layout of the output binary.  This assigns memory offsets
541 // to each of the input data sections as well as the explicit stack region.
542 void Writer::layoutMemory() {
543   uint32_t MemoryPtr = 0;
544   if (!Config->Relocatable) {
545     MemoryPtr = Config->GlobalBase;
546     debugPrint("mem: global base = %d\n", Config->GlobalBase);
547   }
548 
549   createOutputSegments();
550 
551   // Static data comes first
552   for (OutputSegment *Seg : Segments) {
553     MemoryPtr = alignTo(MemoryPtr, Seg->Alignment);
554     Seg->StartVA = MemoryPtr;
555     debugPrint("mem: %-15s offset=%-8d size=%-8d align=%d\n",
556                Seg->Name.str().c_str(), MemoryPtr, Seg->Size, Seg->Alignment);
557     MemoryPtr += Seg->Size;
558   }
559 
560   DataSize = MemoryPtr;
561   if (!Config->Relocatable)
562     DataSize -= Config->GlobalBase;
563   debugPrint("mem: static data = %d\n", DataSize);
564 
565   // Stack comes after static data
566   if (!Config->Relocatable) {
567     MemoryPtr = alignTo(MemoryPtr, kStackAlignment);
568     if (Config->ZStackSize != alignTo(Config->ZStackSize, kStackAlignment))
569       error("stack size must be " + Twine(kStackAlignment) + "-byte aligned");
570     debugPrint("mem: stack size  = %d\n", Config->ZStackSize);
571     debugPrint("mem: stack base  = %d\n", MemoryPtr);
572     MemoryPtr += Config->ZStackSize;
573     Config->StackPointerSymbol->setVirtualAddress(MemoryPtr);
574     debugPrint("mem: stack top   = %d\n", MemoryPtr);
575     // Set `__heap_base` to directly follow the end of the stack.  We don't
576     // allocate any heap memory up front, but instead really on the malloc/brk
577     // implementation growing the memory at runtime.
578     Config->HeapBaseSymbol->setVirtualAddress(MemoryPtr);
579     debugPrint("mem: heap base   = %d\n", MemoryPtr);
580   }
581 
582   uint32_t MemSize = alignTo(MemoryPtr, WasmPageSize);
583   NumMemoryPages = MemSize / WasmPageSize;
584   debugPrint("mem: total pages = %d\n", NumMemoryPages);
585 }
586 
587 SyntheticSection *Writer::createSyntheticSection(uint32_t Type,
588                                                  StringRef Name) {
589   auto Sec = make<SyntheticSection>(Type, Name);
590   log("createSection: " + toString(*Sec));
591   OutputSections.push_back(Sec);
592   return Sec;
593 }
594 
595 void Writer::createSections() {
596   // Known sections
597   createTypeSection();
598   createImportSection();
599   createFunctionSection();
600   createTableSection();
601   createMemorySection();
602   createGlobalSection();
603   createExportSection();
604   createStartSection();
605   createElemSection();
606   createCodeSection();
607   createDataSection();
608 
609   // Custom sections
610   if (Config->EmitRelocs)
611     createRelocSections();
612   createLinkingSection();
613   if (!Config->StripDebug && !Config->StripAll)
614     createNameSection();
615 
616   for (OutputSection *S : OutputSections) {
617     S->setOffset(FileSize);
618     S->finalizeContents();
619     FileSize += S->getSize();
620   }
621 }
622 
623 void Writer::calculateImports() {
624   for (Symbol *Sym : Symtab->getSymbols()) {
625     if (!Sym->isUndefined() || Sym->isWeak())
626       continue;
627 
628     if (Sym->isFunction()) {
629       Sym->setOutputIndex(ImportedFunctions.size());
630       ImportedFunctions.push_back(Sym);
631     } else {
632       Sym->setOutputIndex(ImportedGlobals.size());
633       ImportedGlobals.push_back(Sym);
634     }
635   }
636 }
637 
638 uint32_t Writer::lookupType(const WasmSignature &Sig) {
639   auto It = TypeIndices.find(Sig);
640   if (It == TypeIndices.end()) {
641     error("type not found: " + toString(Sig));
642     return 0;
643   }
644   return It->second;
645 }
646 
647 uint32_t Writer::registerType(const WasmSignature &Sig) {
648   auto Pair = TypeIndices.insert(std::make_pair(Sig, Types.size()));
649   if (Pair.second) {
650     DEBUG(dbgs() << "type " << toString(Sig) << "\n");
651     Types.push_back(&Sig);
652   }
653   return Pair.first->second;
654 }
655 
656 void Writer::calculateTypes() {
657   for (ObjFile *File : Symtab->ObjectFiles) {
658     File->TypeMap.reserve(File->getWasmObj()->types().size());
659     for (const WasmSignature &Sig : File->getWasmObj()->types())
660       File->TypeMap.push_back(registerType(Sig));
661   }
662 
663   for (Symbol *Sym : Symtab->getSymbols())
664     if (Sym->isFunction())
665       registerType(Sym->getFunctionType());
666 }
667 
668 void Writer::assignIndexes() {
669   uint32_t GlobalIndex = ImportedGlobals.size() + DefinedGlobals.size();
670   uint32_t FunctionIndex = ImportedFunctions.size() + DefinedFunctions.size();
671 
672   if (Config->StackPointerSymbol) {
673     DefinedGlobals.emplace_back(Config->StackPointerSymbol);
674     Config->StackPointerSymbol->setOutputIndex(GlobalIndex++);
675   }
676 
677   if (Config->HeapBaseSymbol) {
678     DefinedGlobals.emplace_back(Config->HeapBaseSymbol);
679     Config->HeapBaseSymbol->setOutputIndex(GlobalIndex++);
680   }
681 
682   if (Config->EmitRelocs)
683     DefinedGlobals.reserve(Symtab->getSymbols().size());
684 
685   uint32_t TableIndex = InitialTableOffset;
686 
687   for (ObjFile *File : Symtab->ObjectFiles) {
688     if (Config->EmitRelocs) {
689       DEBUG(dbgs() << "Globals: " << File->getName() << "\n");
690       for (Symbol *Sym : File->getSymbols()) {
691         // Create wasm globals for data symbols defined in this file
692         if (!Sym->isDefined() || File != Sym->getFile())
693           continue;
694         if (Sym->isFunction())
695           continue;
696 
697         DefinedGlobals.emplace_back(Sym);
698         Sym->setOutputIndex(GlobalIndex++);
699       }
700     }
701   }
702 
703   for (ObjFile *File : Symtab->ObjectFiles) {
704     DEBUG(dbgs() << "Functions: " << File->getName() << "\n");
705     for (InputFunction *Func : File->Functions) {
706       if (Func->Discarded)
707         continue;
708       DefinedFunctions.emplace_back(Func);
709       Func->setOutputIndex(FunctionIndex++);
710     }
711   }
712 
713   for (ObjFile *File : Symtab->ObjectFiles) {
714     DEBUG(dbgs() << "Table Indexes: " << File->getName() << "\n");
715     for (Symbol *Sym : File->getTableSymbols()) {
716       if (Sym->hasTableIndex() || !Sym->hasOutputIndex())
717         continue;
718       Sym->setTableIndex(TableIndex++);
719       IndirectFunctions.emplace_back(Sym);
720     }
721   }
722 }
723 
724 static StringRef getOutputDataSegmentName(StringRef Name) {
725   if (Config->Relocatable)
726     return Name;
727 
728   for (StringRef V :
729        {".text.", ".rodata.", ".data.rel.ro.", ".data.", ".bss.rel.ro.",
730         ".bss.", ".init_array.", ".fini_array.", ".ctors.", ".dtors.", ".tbss.",
731         ".gcc_except_table.", ".tdata.", ".ARM.exidx.", ".ARM.extab."}) {
732     StringRef Prefix = V.drop_back();
733     if (Name.startswith(V) || Name == Prefix)
734       return Prefix;
735   }
736 
737   return Name;
738 }
739 
740 void Writer::createOutputSegments() {
741   for (ObjFile *File : Symtab->ObjectFiles) {
742     for (InputSegment *Segment : File->Segments) {
743       if (Segment->Discarded)
744         continue;
745       StringRef Name = getOutputDataSegmentName(Segment->getName());
746       OutputSegment *&S = SegmentMap[Name];
747       if (S == nullptr) {
748         DEBUG(dbgs() << "new segment: " << Name << "\n");
749         S = make<OutputSegment>(Name);
750         Segments.push_back(S);
751       }
752       S->addInputSegment(Segment);
753       DEBUG(dbgs() << "added data: " << Name << ": " << S->Size << "\n");
754     }
755   }
756 }
757 
758 static const int OPCODE_CALL = 0x10;
759 static const int OPCODE_END = 0xb;
760 
761 // Create synthetic "__wasm_call_ctors" function based on ctor functions
762 // in input object.
763 void Writer::createCtorFunction() {
764   uint32_t FunctionIndex = ImportedFunctions.size() + DefinedFunctions.size();
765   Config->CtorSymbol->setOutputIndex(FunctionIndex);
766 
767   // First write the body bytes to a string.
768   std::string FunctionBody;
769   static WasmSignature Signature = {{}, WASM_TYPE_NORESULT};
770   {
771     raw_string_ostream OS(FunctionBody);
772     writeUleb128(OS, 0, "num locals");
773     for (const WasmInitFunc &F : InitFunctions) {
774       writeU8(OS, OPCODE_CALL, "CALL");
775       writeUleb128(OS, F.FunctionIndex, "function index");
776     }
777     writeU8(OS, OPCODE_END, "END");
778   }
779 
780   // Once we know the size of the body we can create the final function body
781   raw_string_ostream OS(CtorFunctionBody);
782   writeUleb128(OS, FunctionBody.size(), "function size");
783   OS.flush();
784   CtorFunctionBody += FunctionBody;
785   ArrayRef<uint8_t> BodyArray(
786       reinterpret_cast<const uint8_t *>(CtorFunctionBody.data()),
787       CtorFunctionBody.size());
788   CtorFunction = llvm::make_unique<SyntheticFunction>(Signature, BodyArray);
789   DefinedFunctions.emplace_back(CtorFunction.get());
790 }
791 
792 // Populate InitFunctions vector with init functions from all input objects.
793 // This is then used either when creating the output linking section or to
794 // synthesize the "__wasm_call_ctors" function.
795 void Writer::calculateInitFunctions() {
796   for (ObjFile *File : Symtab->ObjectFiles) {
797     const WasmLinkingData &L = File->getWasmObj()->linkingData();
798     InitFunctions.reserve(InitFunctions.size() + L.InitFunctions.size());
799     for (const WasmInitFunc &F : L.InitFunctions)
800       InitFunctions.emplace_back(WasmInitFunc{
801           F.Priority, File->relocateFunctionIndex(F.FunctionIndex)});
802   }
803   // Sort in order of priority (lowest first) so that they are called
804   // in the correct order.
805   std::sort(InitFunctions.begin(), InitFunctions.end(),
806             [](const WasmInitFunc &L, const WasmInitFunc &R) {
807               return L.Priority < R.Priority;
808             });
809 }
810 
811 void Writer::run() {
812   if (!Config->Relocatable)
813     InitialTableOffset = 1;
814 
815   log("-- calculateTypes");
816   calculateTypes();
817   log("-- calculateImports");
818   calculateImports();
819   log("-- assignIndexes");
820   assignIndexes();
821   log("-- calculateInitFunctions");
822   calculateInitFunctions();
823   if (!Config->Relocatable)
824     createCtorFunction();
825 
826   if (errorHandler().Verbose) {
827     log("Defined Functions: " + Twine(DefinedFunctions.size()));
828     log("Defined Globals  : " + Twine(DefinedGlobals.size()));
829     log("Function Imports : " + Twine(ImportedFunctions.size()));
830     log("Global Imports   : " + Twine(ImportedGlobals.size()));
831     log("Total Imports    : " +
832         Twine(ImportedFunctions.size() + ImportedGlobals.size()));
833     for (ObjFile *File : Symtab->ObjectFiles)
834       File->dumpInfo();
835   }
836 
837   log("-- layoutMemory");
838   layoutMemory();
839 
840   createHeader();
841   log("-- createSections");
842   createSections();
843 
844   log("-- openFile");
845   openFile();
846   if (errorCount())
847     return;
848 
849   writeHeader();
850 
851   log("-- writeSections");
852   writeSections();
853   if (errorCount())
854     return;
855 
856   if (Error E = Buffer->commit())
857     fatal("failed to write the output file: " + toString(std::move(E)));
858 }
859 
860 // Open a result file.
861 void Writer::openFile() {
862   log("writing: " + Config->OutputFile);
863   ::remove(Config->OutputFile.str().c_str());
864 
865   Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
866       FileOutputBuffer::create(Config->OutputFile, FileSize,
867                                FileOutputBuffer::F_executable);
868 
869   if (!BufferOrErr)
870     error("failed to open " + Config->OutputFile + ": " +
871           toString(BufferOrErr.takeError()));
872   else
873     Buffer = std::move(*BufferOrErr);
874 }
875 
876 void Writer::createHeader() {
877   raw_string_ostream OS(Header);
878   writeBytes(OS, WasmMagic, sizeof(WasmMagic), "wasm magic");
879   writeU32(OS, WasmVersion, "wasm version");
880   OS.flush();
881   FileSize += Header.size();
882 }
883 
884 void lld::wasm::writeResult() { Writer().run(); }
885