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