xref: /llvm-project-15.0.7/lld/wasm/Writer.cpp (revision d3d0ecbf)
1 //===- Writer.cpp ---------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "Writer.h"
10 #include "Config.h"
11 #include "InputChunks.h"
12 #include "InputEvent.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/SmallSet.h"
24 #include "llvm/ADT/SmallVector.h"
25 #include "llvm/ADT/StringMap.h"
26 #include "llvm/BinaryFormat/Wasm.h"
27 #include "llvm/Object/WasmTraits.h"
28 #include "llvm/Support/FileOutputBuffer.h"
29 #include "llvm/Support/Format.h"
30 #include "llvm/Support/FormatVariadic.h"
31 #include "llvm/Support/LEB128.h"
32 #include "llvm/Support/Path.h"
33 
34 #include <cstdarg>
35 #include <map>
36 
37 #define DEBUG_TYPE "lld"
38 
39 using namespace llvm;
40 using namespace llvm::wasm;
41 using namespace lld;
42 using namespace lld::wasm;
43 
44 static constexpr int StackAlignment = 16;
45 static constexpr const char *FunctionTableName = "__indirect_function_table";
46 const char *lld::wasm::DefaultModule = "env";
47 
48 namespace {
49 
50 // An init entry to be written to either the synthetic init func or the
51 // linking metadata.
52 struct WasmInitEntry {
53   const FunctionSymbol *Sym;
54   uint32_t Priority;
55 };
56 
57 // The writer writes a SymbolTable result to a file.
58 class Writer {
59 public:
60   void run();
61 
62 private:
63   void openFile();
64 
65   uint32_t lookupType(const WasmSignature &Sig);
66   uint32_t registerType(const WasmSignature &Sig);
67 
68   void createApplyRelocationsFunction();
69   void createCallCtorsFunction();
70 
71   void calculateInitFunctions();
72   void processRelocations(InputChunk *Chunk);
73   void assignIndexes();
74   void calculateTargetFeatures();
75   void calculateImports();
76   void calculateExports();
77   void calculateCustomSections();
78   void assignSymtab();
79   void calculateTypes();
80   void createOutputSegments();
81   void layoutMemory();
82   void createHeader();
83   void createSections();
84   SyntheticSection *createSyntheticSection(uint32_t Type, StringRef Name = "");
85 
86   // Builtin sections
87   void createTypeSection();
88   void createFunctionSection();
89   void createTableSection();
90   void createGlobalSection();
91   void createEventSection();
92   void createExportSection();
93   void createImportSection();
94   void createMemorySection();
95   void createElemSection();
96   void createDataCountSection();
97   void createCodeSection();
98   void createDataSection();
99   void createCustomSections();
100 
101   // Custom sections
102   void createDylinkSection();
103   void createRelocSections();
104   void createLinkingSection();
105   void createNameSection();
106   void createProducersSection();
107   void createTargetFeaturesSection();
108 
109   void writeHeader();
110   void writeSections();
111 
112   uint64_t FileSize = 0;
113   uint32_t TableBase = 0;
114   uint32_t NumMemoryPages = 0;
115   uint32_t MaxMemoryPages = 0;
116   // Memory size and aligment. Written to the "dylink" section
117   // when build with -shared or -pie.
118   uint32_t MemAlign = 0;
119   uint32_t MemSize = 0;
120 
121   std::vector<const WasmSignature *> Types;
122   DenseMap<WasmSignature, int32_t> TypeIndices;
123   std::vector<const Symbol *> ImportedSymbols;
124   std::vector<const Symbol *> GOTSymbols;
125   unsigned NumImportedFunctions = 0;
126   unsigned NumImportedGlobals = 0;
127   unsigned NumImportedEvents = 0;
128   std::vector<WasmExport> Exports;
129   std::vector<const DefinedData *> DefinedFakeGlobals;
130   std::vector<InputGlobal *> InputGlobals;
131   std::vector<InputFunction *> InputFunctions;
132   std::vector<InputEvent *> InputEvents;
133   std::vector<const FunctionSymbol *> IndirectFunctions;
134   std::vector<const Symbol *> SymtabEntries;
135   std::vector<WasmInitEntry> InitFunctions;
136 
137   llvm::StringMap<std::vector<InputSection *>> CustomSectionMapping;
138   llvm::StringMap<SectionSymbol *> CustomSectionSymbols;
139   llvm::SmallSet<std::string, 8> TargetFeatures;
140 
141   // Elements that are used to construct the final output
142   std::string Header;
143   std::vector<OutputSection *> OutputSections;
144 
145   std::unique_ptr<FileOutputBuffer> Buffer;
146 
147   std::vector<OutputSegment *> Segments;
148   llvm::SmallDenseMap<StringRef, OutputSegment *> SegmentMap;
149 };
150 
151 } // anonymous namespace
152 
153 void Writer::createImportSection() {
154   uint32_t NumImports = ImportedSymbols.size() + GOTSymbols.size();
155   if (Config->ImportMemory)
156     ++NumImports;
157   if (Config->ImportTable)
158     ++NumImports;
159 
160   if (NumImports == 0)
161     return;
162 
163   SyntheticSection *Section = createSyntheticSection(WASM_SEC_IMPORT);
164   raw_ostream &OS = Section->getStream();
165 
166   writeUleb128(OS, NumImports, "import count");
167 
168   if (Config->ImportMemory) {
169     WasmImport Import;
170     Import.Module = DefaultModule;
171     Import.Field = "memory";
172     Import.Kind = WASM_EXTERNAL_MEMORY;
173     Import.Memory.Flags = 0;
174     Import.Memory.Initial = NumMemoryPages;
175     if (MaxMemoryPages != 0 || Config->SharedMemory) {
176       Import.Memory.Flags |= WASM_LIMITS_FLAG_HAS_MAX;
177       Import.Memory.Maximum = MaxMemoryPages;
178     }
179     if (Config->SharedMemory)
180       Import.Memory.Flags |= WASM_LIMITS_FLAG_IS_SHARED;
181     writeImport(OS, Import);
182   }
183 
184   if (Config->ImportTable) {
185     uint32_t TableSize = TableBase + IndirectFunctions.size();
186     WasmImport Import;
187     Import.Module = DefaultModule;
188     Import.Field = FunctionTableName;
189     Import.Kind = WASM_EXTERNAL_TABLE;
190     Import.Table.ElemType = WASM_TYPE_FUNCREF;
191     Import.Table.Limits = {0, TableSize, 0};
192     writeImport(OS, Import);
193   }
194 
195   for (const Symbol *Sym : ImportedSymbols) {
196     WasmImport Import;
197     if (auto *F = dyn_cast<UndefinedFunction>(Sym)) {
198       Import.Field = F->ImportName;
199       Import.Module = F->ImportModule;
200     } else if (auto *G = dyn_cast<UndefinedGlobal>(Sym)) {
201       Import.Field = G->ImportName;
202       Import.Module = G->ImportModule;
203     } else {
204       Import.Field = Sym->getName();
205       Import.Module = DefaultModule;
206     }
207 
208     if (auto *FunctionSym = dyn_cast<FunctionSymbol>(Sym)) {
209       Import.Kind = WASM_EXTERNAL_FUNCTION;
210       Import.SigIndex = lookupType(*FunctionSym->Signature);
211     } else if (auto *GlobalSym = dyn_cast<GlobalSymbol>(Sym)) {
212       Import.Kind = WASM_EXTERNAL_GLOBAL;
213       Import.Global = *GlobalSym->getGlobalType();
214     } else {
215       auto *EventSym = cast<EventSymbol>(Sym);
216       Import.Kind = WASM_EXTERNAL_EVENT;
217       Import.Event.Attribute = EventSym->getEventType()->Attribute;
218       Import.Event.SigIndex = lookupType(*EventSym->Signature);
219     }
220     writeImport(OS, Import);
221   }
222 
223   for (const Symbol *Sym : GOTSymbols) {
224     WasmImport Import;
225     Import.Kind = WASM_EXTERNAL_GLOBAL;
226     Import.Global = {WASM_TYPE_I32, true};
227     if (isa<DataSymbol>(Sym))
228       Import.Module = "GOT.mem";
229     else
230       Import.Module = "GOT.func";
231     Import.Field = Sym->getName();
232     writeImport(OS, Import);
233   }
234 }
235 
236 void Writer::createTypeSection() {
237   SyntheticSection *Section = createSyntheticSection(WASM_SEC_TYPE);
238   raw_ostream &OS = Section->getStream();
239   writeUleb128(OS, Types.size(), "type count");
240   for (const WasmSignature *Sig : Types)
241     writeSig(OS, *Sig);
242 }
243 
244 void Writer::createFunctionSection() {
245   if (InputFunctions.empty())
246     return;
247 
248   SyntheticSection *Section = createSyntheticSection(WASM_SEC_FUNCTION);
249   raw_ostream &OS = Section->getStream();
250 
251   writeUleb128(OS, InputFunctions.size(), "function count");
252   for (const InputFunction *Func : InputFunctions)
253     writeUleb128(OS, lookupType(Func->Signature), "sig index");
254 }
255 
256 void Writer::createMemorySection() {
257   if (Config->ImportMemory)
258     return;
259 
260   SyntheticSection *Section = createSyntheticSection(WASM_SEC_MEMORY);
261   raw_ostream &OS = Section->getStream();
262 
263   bool HasMax = MaxMemoryPages != 0 || Config->SharedMemory;
264   writeUleb128(OS, 1, "memory count");
265   unsigned Flags = 0;
266   if (HasMax)
267     Flags |= WASM_LIMITS_FLAG_HAS_MAX;
268   if (Config->SharedMemory)
269     Flags |= WASM_LIMITS_FLAG_IS_SHARED;
270   writeUleb128(OS, Flags, "memory limits flags");
271   writeUleb128(OS, NumMemoryPages, "initial pages");
272   if (HasMax)
273     writeUleb128(OS, MaxMemoryPages, "max pages");
274 }
275 
276 void Writer::createGlobalSection() {
277   unsigned NumGlobals = InputGlobals.size() + DefinedFakeGlobals.size();
278   if (NumGlobals == 0)
279     return;
280 
281   SyntheticSection *Section = createSyntheticSection(WASM_SEC_GLOBAL);
282   raw_ostream &OS = Section->getStream();
283 
284   writeUleb128(OS, NumGlobals, "global count");
285   for (const InputGlobal *G : InputGlobals)
286     writeGlobal(OS, G->Global);
287   for (const DefinedData *Sym : DefinedFakeGlobals) {
288     WasmGlobal Global;
289     Global.Type = {WASM_TYPE_I32, false};
290     Global.InitExpr.Opcode = WASM_OPCODE_I32_CONST;
291     Global.InitExpr.Value.Int32 = Sym->getVirtualAddress();
292     writeGlobal(OS, Global);
293   }
294 }
295 
296 // The event section contains a list of declared wasm events associated with the
297 // module. Currently the only supported event kind is exceptions. A single event
298 // entry represents a single event with an event tag. All C++ exceptions are
299 // represented by a single event. An event entry in this section contains
300 // information on what kind of event it is (e.g. exception) and the type of
301 // values contained in a single event object. (In wasm, an event can contain
302 // multiple values of primitive types. But for C++ exceptions, we just throw a
303 // pointer which is an i32 value (for wasm32 architecture), so the signature of
304 // C++ exception is (i32)->(void), because all event types are assumed to have
305 // void return type to share WasmSignature with functions.)
306 void Writer::createEventSection() {
307   unsigned NumEvents = InputEvents.size();
308   if (NumEvents == 0)
309     return;
310 
311   SyntheticSection *Section = createSyntheticSection(WASM_SEC_EVENT);
312   raw_ostream &OS = Section->getStream();
313 
314   writeUleb128(OS, NumEvents, "event count");
315   for (InputEvent *E : InputEvents) {
316     E->Event.Type.SigIndex = lookupType(E->Signature);
317     writeEvent(OS, E->Event);
318   }
319 }
320 
321 void Writer::createTableSection() {
322   if (Config->ImportTable)
323     return;
324 
325   // Always output a table section (or table import), even if there are no
326   // indirect calls.  There are two reasons for this:
327   //  1. For executables it is useful to have an empty table slot at 0
328   //     which can be filled with a null function call handler.
329   //  2. If we don't do this, any program that contains a call_indirect but
330   //     no address-taken function will fail at validation time since it is
331   //     a validation error to include a call_indirect instruction if there
332   //     is not table.
333   uint32_t TableSize = TableBase + IndirectFunctions.size();
334 
335   SyntheticSection *Section = createSyntheticSection(WASM_SEC_TABLE);
336   raw_ostream &OS = Section->getStream();
337 
338   writeUleb128(OS, 1, "table count");
339   WasmLimits Limits = {WASM_LIMITS_FLAG_HAS_MAX, TableSize, TableSize};
340   writeTableType(OS, WasmTable{WASM_TYPE_FUNCREF, Limits});
341 }
342 
343 void Writer::createExportSection() {
344   if (!Exports.size())
345     return;
346 
347   SyntheticSection *Section = createSyntheticSection(WASM_SEC_EXPORT);
348   raw_ostream &OS = Section->getStream();
349 
350   writeUleb128(OS, Exports.size(), "export count");
351   for (const WasmExport &Export : Exports)
352     writeExport(OS, Export);
353 }
354 
355 void Writer::calculateCustomSections() {
356   log("calculateCustomSections");
357   bool StripDebug = Config->StripDebug || Config->StripAll;
358   for (ObjFile *File : Symtab->ObjectFiles) {
359     for (InputSection *Section : File->CustomSections) {
360       StringRef Name = Section->getName();
361       // These custom sections are known the linker and synthesized rather than
362       // blindly copied
363       if (Name == "linking" || Name == "name" || Name == "producers" ||
364           Name == "target_features" || Name.startswith("reloc."))
365         continue;
366       // .. or it is a debug section
367       if (StripDebug && Name.startswith(".debug_"))
368         continue;
369       CustomSectionMapping[Name].push_back(Section);
370     }
371   }
372 }
373 
374 void Writer::createCustomSections() {
375   log("createCustomSections");
376   for (auto &Pair : CustomSectionMapping) {
377     StringRef Name = Pair.first();
378 
379     auto P = CustomSectionSymbols.find(Name);
380     if (P != CustomSectionSymbols.end()) {
381       uint32_t SectionIndex = OutputSections.size();
382       P->second->setOutputSectionIndex(SectionIndex);
383     }
384 
385     LLVM_DEBUG(dbgs() << "createCustomSection: " << Name << "\n");
386     OutputSections.push_back(make<CustomSection>(Name, Pair.second));
387   }
388 }
389 
390 void Writer::createElemSection() {
391   if (IndirectFunctions.empty())
392     return;
393 
394   SyntheticSection *Section = createSyntheticSection(WASM_SEC_ELEM);
395   raw_ostream &OS = Section->getStream();
396 
397   writeUleb128(OS, 1, "segment count");
398   writeUleb128(OS, 0, "table index");
399   WasmInitExpr InitExpr;
400   if (Config->Pic) {
401     InitExpr.Opcode = WASM_OPCODE_GLOBAL_GET;
402     InitExpr.Value.Global = WasmSym::TableBase->getGlobalIndex();
403   } else {
404     InitExpr.Opcode = WASM_OPCODE_I32_CONST;
405     InitExpr.Value.Int32 = TableBase;
406   }
407   writeInitExpr(OS, InitExpr);
408   writeUleb128(OS, IndirectFunctions.size(), "elem count");
409 
410   uint32_t TableIndex = TableBase;
411   for (const FunctionSymbol *Sym : IndirectFunctions) {
412     assert(Sym->getTableIndex() == TableIndex);
413     writeUleb128(OS, Sym->getFunctionIndex(), "function index");
414     ++TableIndex;
415   }
416 }
417 
418 void Writer::createDataCountSection() {
419   if (!Segments.size() || !TargetFeatures.count("bulk-memory"))
420     return;
421 
422   log("createDataCountSection");
423   SyntheticSection *Section = createSyntheticSection(WASM_SEC_DATACOUNT);
424   raw_ostream &OS = Section->getStream();
425   writeUleb128(OS, Segments.size(), "data count");
426 }
427 
428 void Writer::createCodeSection() {
429   if (InputFunctions.empty())
430     return;
431 
432   log("createCodeSection");
433 
434   auto Section = make<CodeSection>(InputFunctions);
435   OutputSections.push_back(Section);
436 }
437 
438 void Writer::createDataSection() {
439   if (!Segments.size())
440     return;
441 
442   log("createDataSection");
443   auto Section = make<DataSection>(Segments);
444   OutputSections.push_back(Section);
445 }
446 
447 // Create relocations sections in the final output.
448 // These are only created when relocatable output is requested.
449 void Writer::createRelocSections() {
450   log("createRelocSections");
451   // Don't use iterator here since we are adding to OutputSection
452   size_t OrigSize = OutputSections.size();
453   for (size_t I = 0; I < OrigSize; I++) {
454     OutputSection *OSec = OutputSections[I];
455     uint32_t Count = OSec->numRelocations();
456     if (!Count)
457       continue;
458 
459     StringRef Name;
460     if (OSec->Type == WASM_SEC_DATA)
461       Name = "reloc.DATA";
462     else if (OSec->Type == WASM_SEC_CODE)
463       Name = "reloc.CODE";
464     else if (OSec->Type == WASM_SEC_CUSTOM)
465       Name = Saver.save("reloc." + OSec->Name);
466     else
467       llvm_unreachable(
468           "relocations only supported for code, data, or custom sections");
469 
470     SyntheticSection *Section = createSyntheticSection(WASM_SEC_CUSTOM, Name);
471     raw_ostream &OS = Section->getStream();
472     writeUleb128(OS, I, "reloc section");
473     writeUleb128(OS, Count, "reloc count");
474     OSec->writeRelocations(OS);
475   }
476 }
477 
478 static uint32_t getWasmFlags(const Symbol *Sym) {
479   uint32_t Flags = 0;
480   if (Sym->isLocal())
481     Flags |= WASM_SYMBOL_BINDING_LOCAL;
482   if (Sym->isWeak())
483     Flags |= WASM_SYMBOL_BINDING_WEAK;
484   if (Sym->isHidden())
485     Flags |= WASM_SYMBOL_VISIBILITY_HIDDEN;
486   if (Sym->isUndefined())
487     Flags |= WASM_SYMBOL_UNDEFINED;
488   if (auto *F = dyn_cast<UndefinedFunction>(Sym)) {
489     if (F->getName() != F->ImportName)
490       Flags |= WASM_SYMBOL_EXPLICIT_NAME;
491   } else if (auto *G = dyn_cast<UndefinedGlobal>(Sym)) {
492     if (G->getName() != G->ImportName)
493       Flags |= WASM_SYMBOL_EXPLICIT_NAME;
494   }
495   return Flags;
496 }
497 
498 // Some synthetic sections (e.g. "name" and "linking") have subsections.
499 // Just like the synthetic sections themselves these need to be created before
500 // they can be written out (since they are preceded by their length). This
501 // class is used to create subsections and then write them into the stream
502 // of the parent section.
503 class SubSection {
504 public:
505   explicit SubSection(uint32_t Type) : Type(Type) {}
506 
507   void writeTo(raw_ostream &To) {
508     OS.flush();
509     writeUleb128(To, Type, "subsection type");
510     writeUleb128(To, Body.size(), "subsection size");
511     To.write(Body.data(), Body.size());
512   }
513 
514 private:
515   uint32_t Type;
516   std::string Body;
517 
518 public:
519   raw_string_ostream OS{Body};
520 };
521 
522 // Create the custom "dylink" section containing information for the dynamic
523 // linker.
524 // See
525 // https://github.com/WebAssembly/tool-conventions/blob/master/DynamicLinking.md
526 void Writer::createDylinkSection() {
527   SyntheticSection *Section = createSyntheticSection(WASM_SEC_CUSTOM, "dylink");
528   raw_ostream &OS = Section->getStream();
529 
530   writeUleb128(OS, MemSize, "MemSize");
531   writeUleb128(OS, MemAlign, "MemAlign");
532   writeUleb128(OS, IndirectFunctions.size(), "TableSize");
533   writeUleb128(OS, 0, "TableAlign");
534   writeUleb128(OS, Symtab->SharedFiles.size(), "Needed");
535   for (auto *SO : Symtab->SharedFiles)
536     writeStr(OS, llvm::sys::path::filename(SO->getName()), "so name");
537 }
538 
539 // Create the custom "linking" section containing linker metadata.
540 // This is only created when relocatable output is requested.
541 void Writer::createLinkingSection() {
542   SyntheticSection *Section =
543       createSyntheticSection(WASM_SEC_CUSTOM, "linking");
544   raw_ostream &OS = Section->getStream();
545 
546   writeUleb128(OS, WasmMetadataVersion, "Version");
547 
548   if (!SymtabEntries.empty()) {
549     SubSection Sub(WASM_SYMBOL_TABLE);
550     writeUleb128(Sub.OS, SymtabEntries.size(), "num symbols");
551 
552     for (const Symbol *Sym : SymtabEntries) {
553       assert(Sym->isDefined() || Sym->isUndefined());
554       WasmSymbolType Kind = Sym->getWasmType();
555       uint32_t Flags = getWasmFlags(Sym);
556 
557       writeU8(Sub.OS, Kind, "sym kind");
558       writeUleb128(Sub.OS, Flags, "sym flags");
559 
560       if (auto *F = dyn_cast<FunctionSymbol>(Sym)) {
561         writeUleb128(Sub.OS, F->getFunctionIndex(), "index");
562         if (Sym->isDefined() ||
563             (Flags & WASM_SYMBOL_EXPLICIT_NAME) != 0)
564           writeStr(Sub.OS, Sym->getName(), "sym name");
565       } else if (auto *G = dyn_cast<GlobalSymbol>(Sym)) {
566         writeUleb128(Sub.OS, G->getGlobalIndex(), "index");
567         if (Sym->isDefined() ||
568             (Flags & WASM_SYMBOL_EXPLICIT_NAME) != 0)
569           writeStr(Sub.OS, Sym->getName(), "sym name");
570       } else if (auto *E = dyn_cast<EventSymbol>(Sym)) {
571         writeUleb128(Sub.OS, E->getEventIndex(), "index");
572         if (Sym->isDefined() ||
573             (Flags & WASM_SYMBOL_EXPLICIT_NAME) != 0)
574           writeStr(Sub.OS, Sym->getName(), "sym name");
575       } else if (isa<DataSymbol>(Sym)) {
576         writeStr(Sub.OS, Sym->getName(), "sym name");
577         if (auto *DataSym = dyn_cast<DefinedData>(Sym)) {
578           writeUleb128(Sub.OS, DataSym->getOutputSegmentIndex(), "index");
579           writeUleb128(Sub.OS, DataSym->getOutputSegmentOffset(),
580                        "data offset");
581           writeUleb128(Sub.OS, DataSym->getSize(), "data size");
582         }
583       } else {
584         auto *S = cast<SectionSymbol>(Sym);
585         writeUleb128(Sub.OS, S->getOutputSectionIndex(), "sym section index");
586       }
587     }
588 
589     Sub.writeTo(OS);
590   }
591 
592   if (Segments.size()) {
593     SubSection Sub(WASM_SEGMENT_INFO);
594     writeUleb128(Sub.OS, Segments.size(), "num data segments");
595     for (const OutputSegment *S : Segments) {
596       writeStr(Sub.OS, S->Name, "segment name");
597       writeUleb128(Sub.OS, S->Alignment, "alignment");
598       writeUleb128(Sub.OS, 0, "flags");
599     }
600     Sub.writeTo(OS);
601   }
602 
603   if (!InitFunctions.empty()) {
604     SubSection Sub(WASM_INIT_FUNCS);
605     writeUleb128(Sub.OS, InitFunctions.size(), "num init functions");
606     for (const WasmInitEntry &F : InitFunctions) {
607       writeUleb128(Sub.OS, F.Priority, "priority");
608       writeUleb128(Sub.OS, F.Sym->getOutputSymbolIndex(), "function index");
609     }
610     Sub.writeTo(OS);
611   }
612 
613   struct ComdatEntry {
614     unsigned Kind;
615     uint32_t Index;
616   };
617   std::map<StringRef, std::vector<ComdatEntry>> Comdats;
618 
619   for (const InputFunction *F : InputFunctions) {
620     StringRef Comdat = F->getComdatName();
621     if (!Comdat.empty())
622       Comdats[Comdat].emplace_back(
623           ComdatEntry{WASM_COMDAT_FUNCTION, F->getFunctionIndex()});
624   }
625   for (uint32_t I = 0; I < Segments.size(); ++I) {
626     const auto &InputSegments = Segments[I]->InputSegments;
627     if (InputSegments.empty())
628       continue;
629     StringRef Comdat = InputSegments[0]->getComdatName();
630 #ifndef NDEBUG
631     for (const InputSegment *IS : InputSegments)
632       assert(IS->getComdatName() == Comdat);
633 #endif
634     if (!Comdat.empty())
635       Comdats[Comdat].emplace_back(ComdatEntry{WASM_COMDAT_DATA, I});
636   }
637 
638   if (!Comdats.empty()) {
639     SubSection Sub(WASM_COMDAT_INFO);
640     writeUleb128(Sub.OS, Comdats.size(), "num comdats");
641     for (const auto &C : Comdats) {
642       writeStr(Sub.OS, C.first, "comdat name");
643       writeUleb128(Sub.OS, 0, "comdat flags"); // flags for future use
644       writeUleb128(Sub.OS, C.second.size(), "num entries");
645       for (const ComdatEntry &Entry : C.second) {
646         writeU8(Sub.OS, Entry.Kind, "entry kind");
647         writeUleb128(Sub.OS, Entry.Index, "entry index");
648       }
649     }
650     Sub.writeTo(OS);
651   }
652 }
653 
654 // Create the custom "name" section containing debug symbol names.
655 void Writer::createNameSection() {
656   unsigned NumNames = NumImportedFunctions;
657   for (const InputFunction *F : InputFunctions)
658     if (!F->getName().empty() || !F->getDebugName().empty())
659       ++NumNames;
660 
661   if (NumNames == 0)
662     return;
663 
664   SyntheticSection *Section = createSyntheticSection(WASM_SEC_CUSTOM, "name");
665 
666   SubSection Sub(WASM_NAMES_FUNCTION);
667   writeUleb128(Sub.OS, NumNames, "name count");
668 
669   // Names must appear in function index order.  As it happens ImportedSymbols
670   // and InputFunctions are numbered in order with imported functions coming
671   // first.
672   for (const Symbol *S : ImportedSymbols) {
673     if (auto *F = dyn_cast<FunctionSymbol>(S)) {
674       writeUleb128(Sub.OS, F->getFunctionIndex(), "func index");
675       writeStr(Sub.OS, toString(*S), "symbol name");
676     }
677   }
678   for (const InputFunction *F : InputFunctions) {
679     if (!F->getName().empty()) {
680       writeUleb128(Sub.OS, F->getFunctionIndex(), "func index");
681       if (!F->getDebugName().empty()) {
682         writeStr(Sub.OS, F->getDebugName(), "symbol name");
683       } else {
684         writeStr(Sub.OS, maybeDemangleSymbol(F->getName()), "symbol name");
685       }
686     }
687   }
688 
689   Sub.writeTo(Section->getStream());
690 }
691 
692 void Writer::createProducersSection() {
693   SmallVector<std::pair<std::string, std::string>, 8> Languages;
694   SmallVector<std::pair<std::string, std::string>, 8> Tools;
695   SmallVector<std::pair<std::string, std::string>, 8> SDKs;
696   for (ObjFile *File : Symtab->ObjectFiles) {
697     const WasmProducerInfo &Info = File->getWasmObj()->getProducerInfo();
698     for (auto &Producers : {std::make_pair(&Info.Languages, &Languages),
699                             std::make_pair(&Info.Tools, &Tools),
700                             std::make_pair(&Info.SDKs, &SDKs)})
701       for (auto &Producer : *Producers.first)
702         if (Producers.second->end() ==
703             llvm::find_if(*Producers.second,
704                           [&](std::pair<std::string, std::string> Seen) {
705                             return Seen.first == Producer.first;
706                           }))
707           Producers.second->push_back(Producer);
708   }
709   int FieldCount =
710       int(!Languages.empty()) + int(!Tools.empty()) + int(!SDKs.empty());
711   if (FieldCount == 0)
712     return;
713   SyntheticSection *Section =
714       createSyntheticSection(WASM_SEC_CUSTOM, "producers");
715   auto &OS = Section->getStream();
716   writeUleb128(OS, FieldCount, "field count");
717   for (auto &Field :
718        {std::make_pair("language", Languages),
719         std::make_pair("processed-by", Tools), std::make_pair("sdk", SDKs)}) {
720     if (Field.second.empty())
721       continue;
722     writeStr(OS, Field.first, "field name");
723     writeUleb128(OS, Field.second.size(), "number of entries");
724     for (auto &Entry : Field.second) {
725       writeStr(OS, Entry.first, "producer name");
726       writeStr(OS, Entry.second, "producer version");
727     }
728   }
729 }
730 
731 void Writer::createTargetFeaturesSection() {
732   if (TargetFeatures.empty())
733     return;
734 
735   SmallVector<std::string, 8> Emitted(TargetFeatures.begin(),
736                                       TargetFeatures.end());
737   llvm::sort(Emitted);
738   SyntheticSection *Section =
739       createSyntheticSection(WASM_SEC_CUSTOM, "target_features");
740   auto &OS = Section->getStream();
741   writeUleb128(OS, Emitted.size(), "feature count");
742   for (auto &Feature : Emitted) {
743     writeU8(OS, WASM_FEATURE_PREFIX_USED, "feature used prefix");
744     writeStr(OS, Feature, "feature name");
745   }
746 }
747 
748 void Writer::writeHeader() {
749   memcpy(Buffer->getBufferStart(), Header.data(), Header.size());
750 }
751 
752 void Writer::writeSections() {
753   uint8_t *Buf = Buffer->getBufferStart();
754   parallelForEach(OutputSections, [Buf](OutputSection *S) { S->writeTo(Buf); });
755 }
756 
757 // Fix the memory layout of the output binary.  This assigns memory offsets
758 // to each of the input data sections as well as the explicit stack region.
759 // The default memory layout is as follows, from low to high.
760 //
761 //  - initialized data (starting at Config->GlobalBase)
762 //  - BSS data (not currently implemented in llvm)
763 //  - explicit stack (Config->ZStackSize)
764 //  - heap start / unallocated
765 //
766 // The --stack-first option means that stack is placed before any static data.
767 // This can be useful since it means that stack overflow traps immediately
768 // rather than overwriting global data, but also increases code size since all
769 // static data loads and stores requires larger offsets.
770 void Writer::layoutMemory() {
771   createOutputSegments();
772 
773   uint32_t MemoryPtr = 0;
774 
775   auto PlaceStack = [&]() {
776     if (Config->Relocatable || Config->Shared)
777       return;
778     MemoryPtr = alignTo(MemoryPtr, StackAlignment);
779     if (Config->ZStackSize != alignTo(Config->ZStackSize, StackAlignment))
780       error("stack size must be " + Twine(StackAlignment) + "-byte aligned");
781     log("mem: stack size  = " + Twine(Config->ZStackSize));
782     log("mem: stack base  = " + Twine(MemoryPtr));
783     MemoryPtr += Config->ZStackSize;
784     auto *SP = cast<DefinedGlobal>(WasmSym::StackPointer);
785     SP->Global->Global.InitExpr.Value.Int32 = MemoryPtr;
786     log("mem: stack top   = " + Twine(MemoryPtr));
787   };
788 
789   if (Config->StackFirst) {
790     PlaceStack();
791   } else {
792     MemoryPtr = Config->GlobalBase;
793     log("mem: global base = " + Twine(Config->GlobalBase));
794   }
795 
796   uint32_t DataStart = MemoryPtr;
797 
798   // Arbitrarily set __dso_handle handle to point to the start of the data
799   // segments.
800   if (WasmSym::DsoHandle)
801     WasmSym::DsoHandle->setVirtualAddress(DataStart);
802 
803   MemAlign = 0;
804   for (OutputSegment *Seg : Segments) {
805     MemAlign = std::max(MemAlign, Seg->Alignment);
806     MemoryPtr = alignTo(MemoryPtr, 1ULL << Seg->Alignment);
807     Seg->StartVA = MemoryPtr;
808     log(formatv("mem: {0,-15} offset={1,-8} size={2,-8} align={3}", Seg->Name,
809                 MemoryPtr, Seg->Size, Seg->Alignment));
810     MemoryPtr += Seg->Size;
811   }
812 
813   // TODO: Add .bss space here.
814   if (WasmSym::DataEnd)
815     WasmSym::DataEnd->setVirtualAddress(MemoryPtr);
816 
817   log("mem: static data = " + Twine(MemoryPtr - DataStart));
818 
819   if (Config->Shared) {
820     MemSize = MemoryPtr;
821     return;
822   }
823 
824   if (!Config->StackFirst)
825     PlaceStack();
826 
827   // Set `__heap_base` to directly follow the end of the stack or global data.
828   // The fact that this comes last means that a malloc/brk implementation
829   // can grow the heap at runtime.
830   if (!Config->Relocatable) {
831     WasmSym::HeapBase->setVirtualAddress(MemoryPtr);
832     log("mem: heap base   = " + Twine(MemoryPtr));
833   }
834 
835   if (Config->InitialMemory != 0) {
836     if (Config->InitialMemory != alignTo(Config->InitialMemory, WasmPageSize))
837       error("initial memory must be " + Twine(WasmPageSize) + "-byte aligned");
838     if (MemoryPtr > Config->InitialMemory)
839       error("initial memory too small, " + Twine(MemoryPtr) + " bytes needed");
840     else
841       MemoryPtr = Config->InitialMemory;
842   }
843   MemSize = MemoryPtr;
844   NumMemoryPages = alignTo(MemoryPtr, WasmPageSize) / WasmPageSize;
845   log("mem: total pages = " + Twine(NumMemoryPages));
846 
847   // Check max if explicitly supplied or required by shared memory
848   if (Config->MaxMemory != 0 || Config->SharedMemory) {
849     if (Config->MaxMemory != alignTo(Config->MaxMemory, WasmPageSize))
850       error("maximum memory must be " + Twine(WasmPageSize) + "-byte aligned");
851     if (MemoryPtr > Config->MaxMemory)
852       error("maximum memory too small, " + Twine(MemoryPtr) + " bytes needed");
853     MaxMemoryPages = Config->MaxMemory / WasmPageSize;
854     log("mem: max pages   = " + Twine(MaxMemoryPages));
855   }
856 }
857 
858 SyntheticSection *Writer::createSyntheticSection(uint32_t Type,
859                                                  StringRef Name) {
860   auto Sec = make<SyntheticSection>(Type, Name);
861   log("createSection: " + toString(*Sec));
862   OutputSections.push_back(Sec);
863   return Sec;
864 }
865 
866 void Writer::createSections() {
867   // Known sections
868   if (Config->Pic)
869     createDylinkSection();
870   createTypeSection();
871   createImportSection();
872   createFunctionSection();
873   createTableSection();
874   createMemorySection();
875   createGlobalSection();
876   createEventSection();
877   createExportSection();
878   createElemSection();
879   createDataCountSection();
880   createCodeSection();
881   createDataSection();
882   createCustomSections();
883 
884   // Custom sections
885   if (Config->Relocatable) {
886     createLinkingSection();
887     createRelocSections();
888   }
889 
890   if (!Config->StripDebug && !Config->StripAll)
891     createNameSection();
892 
893   if (!Config->StripAll) {
894     createProducersSection();
895     createTargetFeaturesSection();
896   }
897 
898   for (OutputSection *S : OutputSections) {
899     S->setOffset(FileSize);
900     S->finalizeContents();
901     FileSize += S->getSize();
902   }
903 }
904 
905 void Writer::calculateTargetFeatures() {
906   SmallSet<std::string, 8> Used;
907   SmallSet<std::string, 8> Required;
908   SmallSet<std::string, 8> Disallowed;
909 
910   // Only infer used features if user did not specify features
911   bool InferFeatures = !Config->Features.hasValue();
912 
913   if (!InferFeatures) {
914     for (auto &Feature : Config->Features.getValue())
915       TargetFeatures.insert(Feature);
916     // No need to read or check features
917     if (!Config->CheckFeatures)
918       return;
919   }
920 
921   // Find the sets of used, required, and disallowed features
922   for (ObjFile *File : Symtab->ObjectFiles) {
923     for (auto &Feature : File->getWasmObj()->getTargetFeatures()) {
924       switch (Feature.Prefix) {
925       case WASM_FEATURE_PREFIX_USED:
926         Used.insert(Feature.Name);
927         break;
928       case WASM_FEATURE_PREFIX_REQUIRED:
929         Used.insert(Feature.Name);
930         Required.insert(Feature.Name);
931         break;
932       case WASM_FEATURE_PREFIX_DISALLOWED:
933         Disallowed.insert(Feature.Name);
934         break;
935       default:
936         error("Unrecognized feature policy prefix " +
937               std::to_string(Feature.Prefix));
938       }
939     }
940   }
941 
942   if (InferFeatures)
943     TargetFeatures.insert(Used.begin(), Used.end());
944 
945   if (TargetFeatures.count("atomics") && !Config->SharedMemory)
946     error("'atomics' feature is used, so --shared-memory must be used");
947 
948   if (!Config->CheckFeatures)
949     return;
950 
951   if (Disallowed.count("atomics") && Config->SharedMemory)
952     error(
953         "'atomics' feature is disallowed, so --shared-memory must not be used");
954 
955   // Validate that used features are allowed in output
956   if (!InferFeatures) {
957     for (auto &Feature : Used) {
958       if (!TargetFeatures.count(Feature))
959         error(Twine("Target feature '") + Feature + "' is not allowed.");
960     }
961   }
962 
963   // Validate the required and disallowed constraints for each file
964   for (ObjFile *File : Symtab->ObjectFiles) {
965     SmallSet<std::string, 8> ObjectFeatures;
966     for (auto &Feature : File->getWasmObj()->getTargetFeatures()) {
967       if (Feature.Prefix == WASM_FEATURE_PREFIX_DISALLOWED)
968         continue;
969       ObjectFeatures.insert(Feature.Name);
970       if (Disallowed.count(Feature.Name))
971         error(Twine("Target feature '") + Feature.Name +
972               "' is disallowed. Use --no-check-features to suppress.");
973     }
974     for (auto &Feature : Required) {
975       if (!ObjectFeatures.count(Feature))
976         error(Twine("Missing required target feature '") + Feature +
977               "'. Use --no-check-features to suppress.");
978     }
979   }
980 }
981 
982 void Writer::calculateImports() {
983   for (Symbol *Sym : Symtab->getSymbols()) {
984     if (!Sym->isUndefined())
985       continue;
986     if (Sym->isWeak() && !Config->Relocatable)
987       continue;
988     if (!Sym->isLive())
989       continue;
990     if (!Sym->IsUsedInRegularObj)
991       continue;
992     // We don't generate imports for data symbols. They however can be imported
993     // as GOT entries.
994     if (isa<DataSymbol>(Sym))
995       continue;
996 
997     LLVM_DEBUG(dbgs() << "import: " << Sym->getName() << "\n");
998     ImportedSymbols.emplace_back(Sym);
999     if (auto *F = dyn_cast<FunctionSymbol>(Sym))
1000       F->setFunctionIndex(NumImportedFunctions++);
1001     else if (auto *G = dyn_cast<GlobalSymbol>(Sym))
1002       G->setGlobalIndex(NumImportedGlobals++);
1003     else
1004       cast<EventSymbol>(Sym)->setEventIndex(NumImportedEvents++);
1005   }
1006 }
1007 
1008 void Writer::calculateExports() {
1009   if (Config->Relocatable)
1010     return;
1011 
1012   if (!Config->Relocatable && !Config->ImportMemory)
1013     Exports.push_back(WasmExport{"memory", WASM_EXTERNAL_MEMORY, 0});
1014 
1015   if (!Config->Relocatable && Config->ExportTable)
1016     Exports.push_back(WasmExport{FunctionTableName, WASM_EXTERNAL_TABLE, 0});
1017 
1018   unsigned FakeGlobalIndex = NumImportedGlobals + InputGlobals.size();
1019 
1020   for (Symbol *Sym : Symtab->getSymbols()) {
1021     if (!Sym->isExported())
1022       continue;
1023     if (!Sym->isLive())
1024       continue;
1025 
1026     StringRef Name = Sym->getName();
1027     WasmExport Export;
1028     if (auto *F = dyn_cast<DefinedFunction>(Sym)) {
1029       Export = {Name, WASM_EXTERNAL_FUNCTION, F->getFunctionIndex()};
1030     } else if (auto *G = dyn_cast<DefinedGlobal>(Sym)) {
1031       // TODO(sbc): Remove this check once to mutable global proposal is
1032       // implement in all major browsers.
1033       // See: https://github.com/WebAssembly/mutable-global
1034       if (G->getGlobalType()->Mutable) {
1035         // Only the __stack_pointer should ever be create as mutable.
1036         assert(G == WasmSym::StackPointer);
1037         continue;
1038       }
1039       Export = {Name, WASM_EXTERNAL_GLOBAL, G->getGlobalIndex()};
1040     } else if (auto *E = dyn_cast<DefinedEvent>(Sym)) {
1041       Export = {Name, WASM_EXTERNAL_EVENT, E->getEventIndex()};
1042     } else {
1043       auto *D = cast<DefinedData>(Sym);
1044       DefinedFakeGlobals.emplace_back(D);
1045       Export = {Name, WASM_EXTERNAL_GLOBAL, FakeGlobalIndex++};
1046     }
1047 
1048     LLVM_DEBUG(dbgs() << "Export: " << Name << "\n");
1049     Exports.push_back(Export);
1050   }
1051 }
1052 
1053 void Writer::assignSymtab() {
1054   if (!Config->Relocatable)
1055     return;
1056 
1057   StringMap<uint32_t> SectionSymbolIndices;
1058 
1059   unsigned SymbolIndex = SymtabEntries.size();
1060 
1061   auto AddSymbol = [&](Symbol *Sym) {
1062     if (auto *S = dyn_cast<SectionSymbol>(Sym)) {
1063       StringRef Name = S->getName();
1064       if (CustomSectionMapping.count(Name) == 0)
1065         return;
1066 
1067       auto SSI = SectionSymbolIndices.find(Name);
1068       if (SSI != SectionSymbolIndices.end()) {
1069         Sym->setOutputSymbolIndex(SSI->second);
1070         return;
1071       }
1072 
1073       SectionSymbolIndices[Name] = SymbolIndex;
1074       CustomSectionSymbols[Name] = cast<SectionSymbol>(Sym);
1075 
1076       Sym->markLive();
1077     }
1078 
1079     // (Since this is relocatable output, GC is not performed so symbols must
1080     // be live.)
1081     assert(Sym->isLive());
1082     Sym->setOutputSymbolIndex(SymbolIndex++);
1083     SymtabEntries.emplace_back(Sym);
1084   };
1085 
1086   for (Symbol *Sym : Symtab->getSymbols())
1087     if (Sym->IsUsedInRegularObj)
1088       AddSymbol(Sym);
1089 
1090   for (ObjFile *File : Symtab->ObjectFiles) {
1091     LLVM_DEBUG(dbgs() << "Local symtab entries: " << File->getName() << "\n");
1092     for (Symbol *Sym : File->getSymbols())
1093       if (Sym->isLocal())
1094         AddSymbol(Sym);
1095   }
1096 }
1097 
1098 uint32_t Writer::lookupType(const WasmSignature &Sig) {
1099   auto It = TypeIndices.find(Sig);
1100   if (It == TypeIndices.end()) {
1101     error("type not found: " + toString(Sig));
1102     return 0;
1103   }
1104   return It->second;
1105 }
1106 
1107 uint32_t Writer::registerType(const WasmSignature &Sig) {
1108   auto Pair = TypeIndices.insert(std::make_pair(Sig, Types.size()));
1109   if (Pair.second) {
1110     LLVM_DEBUG(dbgs() << "type " << toString(Sig) << "\n");
1111     Types.push_back(&Sig);
1112   }
1113   return Pair.first->second;
1114 }
1115 
1116 void Writer::calculateTypes() {
1117   // The output type section is the union of the following sets:
1118   // 1. Any signature used in the TYPE relocation
1119   // 2. The signatures of all imported functions
1120   // 3. The signatures of all defined functions
1121   // 4. The signatures of all imported events
1122   // 5. The signatures of all defined events
1123 
1124   for (ObjFile *File : Symtab->ObjectFiles) {
1125     ArrayRef<WasmSignature> Types = File->getWasmObj()->types();
1126     for (uint32_t I = 0; I < Types.size(); I++)
1127       if (File->TypeIsUsed[I])
1128         File->TypeMap[I] = registerType(Types[I]);
1129   }
1130 
1131   for (const Symbol *Sym : ImportedSymbols) {
1132     if (auto *F = dyn_cast<FunctionSymbol>(Sym))
1133       registerType(*F->Signature);
1134     else if (auto *E = dyn_cast<EventSymbol>(Sym))
1135       registerType(*E->Signature);
1136   }
1137 
1138   for (const InputFunction *F : InputFunctions)
1139     registerType(F->Signature);
1140 
1141   for (const InputEvent *E : InputEvents)
1142     registerType(E->Signature);
1143 }
1144 
1145 void Writer::processRelocations(InputChunk *Chunk) {
1146   if (!Chunk->Live)
1147     return;
1148   ObjFile *File = Chunk->File;
1149   ArrayRef<WasmSignature> Types = File->getWasmObj()->types();
1150   for (const WasmRelocation &Reloc : Chunk->getRelocations()) {
1151     switch (Reloc.Type) {
1152     case R_WASM_TABLE_INDEX_I32:
1153     case R_WASM_TABLE_INDEX_SLEB:
1154     case R_WASM_TABLE_INDEX_REL_SLEB: {
1155       FunctionSymbol *Sym = File->getFunctionSymbol(Reloc.Index);
1156       if (Sym->hasTableIndex() || !Sym->hasFunctionIndex())
1157         continue;
1158       Sym->setTableIndex(TableBase + IndirectFunctions.size());
1159       IndirectFunctions.emplace_back(Sym);
1160       break;
1161     }
1162     case R_WASM_TYPE_INDEX_LEB:
1163       // Mark target type as live
1164       File->TypeMap[Reloc.Index] = registerType(Types[Reloc.Index]);
1165       File->TypeIsUsed[Reloc.Index] = true;
1166       break;
1167     case R_WASM_GLOBAL_INDEX_LEB: {
1168       auto* Sym = File->getSymbols()[Reloc.Index];
1169       if (!isa<GlobalSymbol>(Sym) && !Sym->isInGOT()) {
1170         Sym->setGOTIndex(NumImportedGlobals++);
1171         GOTSymbols.push_back(Sym);
1172       }
1173       break;
1174     }
1175     case R_WASM_MEMORY_ADDR_SLEB:
1176     case R_WASM_MEMORY_ADDR_LEB:
1177     case R_WASM_MEMORY_ADDR_REL_SLEB: {
1178       if (!Config->Relocatable) {
1179         auto* Sym = File->getSymbols()[Reloc.Index];
1180         if (Sym->isUndefined() && !Sym->isWeak()) {
1181           error(toString(File) + ": cannot resolve relocation of type " +
1182                 relocTypeToString(Reloc.Type) +
1183                 " against undefined (non-weak) data symbol: " + toString(*Sym));
1184         }
1185       }
1186       break;
1187     }
1188     }
1189 
1190     if (Config->Pic) {
1191       switch (Reloc.Type) {
1192       case R_WASM_TABLE_INDEX_SLEB:
1193       case R_WASM_MEMORY_ADDR_SLEB:
1194       case R_WASM_MEMORY_ADDR_LEB: {
1195         // Certain relocation types can't be used when building PIC output, since
1196         // they would require absolute symbol addresses at link time.
1197         Symbol *Sym = File->getSymbols()[Reloc.Index];
1198         error(toString(File) + ": relocation " +
1199               relocTypeToString(Reloc.Type) + " cannot be used againt symbol " +
1200               toString(*Sym) + "; recompile with -fPIC");
1201         break;
1202       }
1203       case R_WASM_TABLE_INDEX_I32:
1204       case R_WASM_MEMORY_ADDR_I32: {
1205         // These relocation types are only present in the data section and
1206         // will be converted into code by `generateRelocationCode`.  This code
1207         // requires the symbols to have GOT entires.
1208         auto* Sym = File->getSymbols()[Reloc.Index];
1209         if (!Sym->isHidden() && !Sym->isLocal() && !Sym->isInGOT()) {
1210           Sym->setGOTIndex(NumImportedGlobals++);
1211           GOTSymbols.push_back(Sym);
1212         }
1213         break;
1214       }
1215       }
1216     }
1217   }
1218 }
1219 
1220 void Writer::assignIndexes() {
1221   assert(InputFunctions.empty());
1222   uint32_t FunctionIndex = NumImportedFunctions;
1223   auto AddDefinedFunction = [&](InputFunction *Func) {
1224     if (!Func->Live)
1225       return;
1226     InputFunctions.emplace_back(Func);
1227     Func->setFunctionIndex(FunctionIndex++);
1228   };
1229 
1230   for (InputFunction *Func : Symtab->SyntheticFunctions)
1231     AddDefinedFunction(Func);
1232 
1233   for (ObjFile *File : Symtab->ObjectFiles) {
1234     LLVM_DEBUG(dbgs() << "Functions: " << File->getName() << "\n");
1235     for (InputFunction *Func : File->Functions)
1236       AddDefinedFunction(Func);
1237   }
1238 
1239   for (ObjFile *File : Symtab->ObjectFiles) {
1240     LLVM_DEBUG(dbgs() << "Handle relocs: " << File->getName() << "\n");
1241     for (InputChunk *Chunk : File->Functions)
1242       processRelocations(Chunk);
1243     for (InputChunk *Chunk : File->Segments)
1244       processRelocations(Chunk);
1245     for (auto &P : File->CustomSections)
1246       processRelocations(P);
1247   }
1248 
1249   assert(InputGlobals.empty());
1250   uint32_t GlobalIndex = NumImportedGlobals;
1251   auto AddDefinedGlobal = [&](InputGlobal *Global) {
1252     if (Global->Live) {
1253       LLVM_DEBUG(dbgs() << "AddDefinedGlobal: " << GlobalIndex << "\n");
1254       Global->setGlobalIndex(GlobalIndex++);
1255       InputGlobals.push_back(Global);
1256     }
1257   };
1258 
1259   for (InputGlobal *Global : Symtab->SyntheticGlobals)
1260     AddDefinedGlobal(Global);
1261 
1262   for (ObjFile *File : Symtab->ObjectFiles) {
1263     LLVM_DEBUG(dbgs() << "Globals: " << File->getName() << "\n");
1264     for (InputGlobal *Global : File->Globals)
1265       AddDefinedGlobal(Global);
1266   }
1267 
1268   assert(InputEvents.empty());
1269   uint32_t EventIndex = NumImportedEvents;
1270   auto AddDefinedEvent = [&](InputEvent *Event) {
1271     if (Event->Live) {
1272       LLVM_DEBUG(dbgs() << "AddDefinedEvent: " << EventIndex << "\n");
1273       Event->setEventIndex(EventIndex++);
1274       InputEvents.push_back(Event);
1275     }
1276   };
1277 
1278   for (ObjFile *File : Symtab->ObjectFiles) {
1279     LLVM_DEBUG(dbgs() << "Events: " << File->getName() << "\n");
1280     for (InputEvent *Event : File->Events)
1281       AddDefinedEvent(Event);
1282   }
1283 }
1284 
1285 static StringRef getOutputDataSegmentName(StringRef Name) {
1286   // With PIC code we currently only support a single data segment since
1287   // we only have a single __memory_base to use as our base address.
1288   if (Config->Pic)
1289     return "data";
1290   if (!Config->MergeDataSegments)
1291     return Name;
1292   if (Name.startswith(".text."))
1293     return ".text";
1294   if (Name.startswith(".data."))
1295     return ".data";
1296   if (Name.startswith(".bss."))
1297     return ".bss";
1298   if (Name.startswith(".rodata."))
1299     return ".rodata";
1300   return Name;
1301 }
1302 
1303 void Writer::createOutputSegments() {
1304   for (ObjFile *File : Symtab->ObjectFiles) {
1305     for (InputSegment *Segment : File->Segments) {
1306       if (!Segment->Live)
1307         continue;
1308       StringRef Name = getOutputDataSegmentName(Segment->getName());
1309       OutputSegment *&S = SegmentMap[Name];
1310       if (S == nullptr) {
1311         LLVM_DEBUG(dbgs() << "new segment: " << Name << "\n");
1312         S = make<OutputSegment>(Name, Segments.size());
1313         Segments.push_back(S);
1314       }
1315       S->addInputSegment(Segment);
1316       LLVM_DEBUG(dbgs() << "added data: " << Name << ": " << S->Size << "\n");
1317     }
1318   }
1319 }
1320 
1321 // For -shared (PIC) output, we create create a synthetic function which will
1322 // apply any relocations to the data segments on startup.  This function is
1323 // called __wasm_apply_relocs and is added at the very beginning of
1324 // __wasm_call_ctors before any of the constructors run.
1325 void Writer::createApplyRelocationsFunction() {
1326   LLVM_DEBUG(dbgs() << "createApplyRelocationsFunction\n");
1327   // First write the body's contents to a string.
1328   std::string BodyContent;
1329   {
1330     raw_string_ostream OS(BodyContent);
1331     writeUleb128(OS, 0, "num locals");
1332     for (const OutputSegment *Seg : Segments)
1333       for (const InputSegment *InSeg : Seg->InputSegments)
1334         InSeg->generateRelocationCode(OS);
1335     writeU8(OS, WASM_OPCODE_END, "END");
1336   }
1337 
1338   // Once we know the size of the body we can create the final function body
1339   std::string FunctionBody;
1340   {
1341     raw_string_ostream OS(FunctionBody);
1342     writeUleb128(OS, BodyContent.size(), "function size");
1343     OS << BodyContent;
1344   }
1345 
1346   ArrayRef<uint8_t> Body = arrayRefFromStringRef(Saver.save(FunctionBody));
1347   cast<SyntheticFunction>(WasmSym::ApplyRelocs->Function)->setBody(Body);
1348 }
1349 
1350 // Create synthetic "__wasm_call_ctors" function based on ctor functions
1351 // in input object.
1352 void Writer::createCallCtorsFunction() {
1353   if (!WasmSym::CallCtors->isLive())
1354     return;
1355 
1356   // First write the body's contents to a string.
1357   std::string BodyContent;
1358   {
1359     raw_string_ostream OS(BodyContent);
1360     writeUleb128(OS, 0, "num locals");
1361     if (Config->Pic) {
1362       writeU8(OS, WASM_OPCODE_CALL, "CALL");
1363       writeUleb128(OS, WasmSym::ApplyRelocs->getFunctionIndex(),
1364                    "function index");
1365     }
1366     for (const WasmInitEntry &F : InitFunctions) {
1367       writeU8(OS, WASM_OPCODE_CALL, "CALL");
1368       writeUleb128(OS, F.Sym->getFunctionIndex(), "function index");
1369     }
1370     writeU8(OS, WASM_OPCODE_END, "END");
1371   }
1372 
1373   // Once we know the size of the body we can create the final function body
1374   std::string FunctionBody;
1375   {
1376     raw_string_ostream OS(FunctionBody);
1377     writeUleb128(OS, BodyContent.size(), "function size");
1378     OS << BodyContent;
1379   }
1380 
1381   ArrayRef<uint8_t> Body = arrayRefFromStringRef(Saver.save(FunctionBody));
1382   cast<SyntheticFunction>(WasmSym::CallCtors->Function)->setBody(Body);
1383 }
1384 
1385 // Populate InitFunctions vector with init functions from all input objects.
1386 // This is then used either when creating the output linking section or to
1387 // synthesize the "__wasm_call_ctors" function.
1388 void Writer::calculateInitFunctions() {
1389   if (!Config->Relocatable && !WasmSym::CallCtors->isLive())
1390     return;
1391 
1392   for (ObjFile *File : Symtab->ObjectFiles) {
1393     const WasmLinkingData &L = File->getWasmObj()->linkingData();
1394     for (const WasmInitFunc &F : L.InitFunctions) {
1395       FunctionSymbol *Sym = File->getFunctionSymbol(F.Symbol);
1396       assert(Sym->isLive());
1397       if (*Sym->Signature != WasmSignature{{}, {}})
1398         error("invalid signature for init func: " + toString(*Sym));
1399       InitFunctions.emplace_back(WasmInitEntry{Sym, F.Priority});
1400     }
1401   }
1402 
1403   // Sort in order of priority (lowest first) so that they are called
1404   // in the correct order.
1405   llvm::stable_sort(InitFunctions,
1406                     [](const WasmInitEntry &L, const WasmInitEntry &R) {
1407                       return L.Priority < R.Priority;
1408                     });
1409 }
1410 
1411 void Writer::run() {
1412   if (Config->Relocatable || Config->Pic)
1413     Config->GlobalBase = 0;
1414 
1415   // For PIC code the table base is assigned dynamically by the loader.
1416   // For non-PIC, we start at 1 so that accessing table index 0 always traps.
1417   if (!Config->Pic)
1418     TableBase = 1;
1419 
1420   log("-- calculateTargetFeatures");
1421   calculateTargetFeatures();
1422   log("-- calculateImports");
1423   calculateImports();
1424   log("-- assignIndexes");
1425   assignIndexes();
1426   log("-- calculateInitFunctions");
1427   calculateInitFunctions();
1428   log("-- calculateTypes");
1429   calculateTypes();
1430   log("-- layoutMemory");
1431   layoutMemory();
1432   if (!Config->Relocatable) {
1433     if (Config->Pic)
1434       createApplyRelocationsFunction();
1435     createCallCtorsFunction();
1436   }
1437   log("-- calculateExports");
1438   calculateExports();
1439   log("-- calculateCustomSections");
1440   calculateCustomSections();
1441   log("-- assignSymtab");
1442   assignSymtab();
1443 
1444   if (errorHandler().Verbose) {
1445     log("Defined Functions: " + Twine(InputFunctions.size()));
1446     log("Defined Globals  : " + Twine(InputGlobals.size()));
1447     log("Defined Events   : " + Twine(InputEvents.size()));
1448     log("Function Imports : " + Twine(NumImportedFunctions));
1449     log("Global Imports   : " + Twine(NumImportedGlobals));
1450     log("Event Imports    : " + Twine(NumImportedEvents));
1451     for (ObjFile *File : Symtab->ObjectFiles)
1452       File->dumpInfo();
1453   }
1454 
1455   createHeader();
1456   log("-- createSections");
1457   createSections();
1458 
1459   log("-- openFile");
1460   openFile();
1461   if (errorCount())
1462     return;
1463 
1464   writeHeader();
1465 
1466   log("-- writeSections");
1467   writeSections();
1468   if (errorCount())
1469     return;
1470 
1471   if (Error E = Buffer->commit())
1472     fatal("failed to write the output file: " + toString(std::move(E)));
1473 }
1474 
1475 // Open a result file.
1476 void Writer::openFile() {
1477   log("writing: " + Config->OutputFile);
1478 
1479   Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
1480       FileOutputBuffer::create(Config->OutputFile, FileSize,
1481                                FileOutputBuffer::F_executable);
1482 
1483   if (!BufferOrErr)
1484     error("failed to open " + Config->OutputFile + ": " +
1485           toString(BufferOrErr.takeError()));
1486   else
1487     Buffer = std::move(*BufferOrErr);
1488 }
1489 
1490 void Writer::createHeader() {
1491   raw_string_ostream OS(Header);
1492   writeBytes(OS, WasmMagic, sizeof(WasmMagic), "wasm magic");
1493   writeU32(OS, WasmVersion, "wasm version");
1494   OS.flush();
1495   FileSize += Header.size();
1496 }
1497 
1498 void lld::wasm::writeResult() { Writer().run(); }
1499