xref: /llvm-project-15.0.7/lld/wasm/Writer.cpp (revision fe5eaab2)
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 "Relocations.h"
17 #include "SymbolTable.h"
18 #include "SyntheticSections.h"
19 #include "WriterUtils.h"
20 #include "lld/Common/ErrorHandler.h"
21 #include "lld/Common/Memory.h"
22 #include "lld/Common/Strings.h"
23 #include "lld/Common/Threads.h"
24 #include "llvm/ADT/DenseSet.h"
25 #include "llvm/ADT/SmallSet.h"
26 #include "llvm/ADT/SmallVector.h"
27 #include "llvm/ADT/StringMap.h"
28 #include "llvm/BinaryFormat/Wasm.h"
29 #include "llvm/Object/WasmTraits.h"
30 #include "llvm/Support/FileOutputBuffer.h"
31 #include "llvm/Support/Format.h"
32 #include "llvm/Support/FormatVariadic.h"
33 #include "llvm/Support/LEB128.h"
34 
35 #include <cstdarg>
36 #include <map>
37 
38 #define DEBUG_TYPE "lld"
39 
40 using namespace llvm;
41 using namespace llvm::wasm;
42 using namespace lld;
43 using namespace lld::wasm;
44 
45 static constexpr int StackAlignment = 16;
46 
47 namespace {
48 
49 // The writer writes a SymbolTable result to a file.
50 class Writer {
51 public:
52   void run();
53 
54 private:
55   void openFile();
56 
57   void createApplyRelocationsFunction();
58   void createCallCtorsFunction();
59 
60   void assignIndexes();
61   void populateSymtab();
62   void populateProducers();
63   void populateTargetFeatures();
64   void calculateInitFunctions();
65   void calculateImports();
66   void calculateExports();
67   void calculateCustomSections();
68   void calculateTypes();
69   void createOutputSegments();
70   void layoutMemory();
71   void createHeader();
72 
73   void addSection(OutputSection *Sec);
74 
75   void addSections();
76   void addStartStopSymbols(const InputSegment *Seg);
77 
78   void createCustomSections();
79   void createSyntheticSections();
80   void finalizeSections();
81 
82   // Custom sections
83   void createRelocSections();
84 
85   void writeHeader();
86   void writeSections();
87 
88   uint64_t FileSize = 0;
89   uint32_t TableBase = 0;
90 
91   std::vector<WasmInitEntry> InitFunctions;
92   llvm::StringMap<std::vector<InputSection *>> CustomSectionMapping;
93 
94   // Elements that are used to construct the final output
95   std::string Header;
96   std::vector<OutputSection *> OutputSections;
97 
98   std::unique_ptr<FileOutputBuffer> Buffer;
99 
100   std::vector<OutputSegment *> Segments;
101   llvm::SmallDenseMap<StringRef, OutputSegment *> SegmentMap;
102 };
103 
104 } // anonymous namespace
105 
106 void Writer::calculateCustomSections() {
107   log("calculateCustomSections");
108   bool StripDebug = Config->StripDebug || Config->StripAll;
109   for (ObjFile *File : Symtab->ObjectFiles) {
110     for (InputSection *Section : File->CustomSections) {
111       StringRef Name = Section->getName();
112       // These custom sections are known the linker and synthesized rather than
113       // blindly copied
114       if (Name == "linking" || Name == "name" || Name == "producers" ||
115           Name == "target_features" || Name.startswith("reloc."))
116         continue;
117       // .. or it is a debug section
118       if (StripDebug && Name.startswith(".debug_"))
119         continue;
120       CustomSectionMapping[Name].push_back(Section);
121     }
122   }
123 }
124 
125 void Writer::createCustomSections() {
126   log("createCustomSections");
127   for (auto &Pair : CustomSectionMapping) {
128     StringRef Name = Pair.first();
129     LLVM_DEBUG(dbgs() << "createCustomSection: " << Name << "\n");
130 
131     OutputSection *Sec = make<CustomSection>(Name, Pair.second);
132     if (Config->Relocatable || Config->EmitRelocs) {
133       auto *Sym = make<OutputSectionSymbol>(Sec);
134       Out.LinkingSec->addToSymtab(Sym);
135       Sec->SectionSym = Sym;
136     }
137     addSection(Sec);
138   }
139 }
140 
141 // Create relocations sections in the final output.
142 // These are only created when relocatable output is requested.
143 void Writer::createRelocSections() {
144   log("createRelocSections");
145   // Don't use iterator here since we are adding to OutputSection
146   size_t OrigSize = OutputSections.size();
147   for (size_t I = 0; I < OrigSize; I++) {
148     LLVM_DEBUG(dbgs() << "check section " << I << "\n");
149     OutputSection *Sec = OutputSections[I];
150 
151     // Count the number of needed sections.
152     uint32_t Count = Sec->numRelocations();
153     if (!Count)
154       continue;
155 
156     StringRef Name;
157     if (Sec->Type == WASM_SEC_DATA)
158       Name = "reloc.DATA";
159     else if (Sec->Type == WASM_SEC_CODE)
160       Name = "reloc.CODE";
161     else if (Sec->Type == WASM_SEC_CUSTOM)
162       Name = Saver.save("reloc." + Sec->Name);
163     else
164       llvm_unreachable(
165           "relocations only supported for code, data, or custom sections");
166 
167     addSection(make<RelocSection>(Name, Sec));
168   }
169 }
170 
171 void Writer::populateProducers() {
172   for (ObjFile *File : Symtab->ObjectFiles) {
173     const WasmProducerInfo &Info = File->getWasmObj()->getProducerInfo();
174     Out.ProducersSec->addInfo(Info);
175   }
176 }
177 
178 void Writer::writeHeader() {
179   memcpy(Buffer->getBufferStart(), Header.data(), Header.size());
180 }
181 
182 void Writer::writeSections() {
183   uint8_t *Buf = Buffer->getBufferStart();
184   parallelForEach(OutputSections, [Buf](OutputSection *S) {
185     assert(S->isNeeded());
186     S->writeTo(Buf);
187   });
188 }
189 
190 // Fix the memory layout of the output binary.  This assigns memory offsets
191 // to each of the input data sections as well as the explicit stack region.
192 // The default memory layout is as follows, from low to high.
193 //
194 //  - initialized data (starting at Config->GlobalBase)
195 //  - BSS data (not currently implemented in llvm)
196 //  - explicit stack (Config->ZStackSize)
197 //  - heap start / unallocated
198 //
199 // The --stack-first option means that stack is placed before any static data.
200 // This can be useful since it means that stack overflow traps immediately
201 // rather than overwriting global data, but also increases code size since all
202 // static data loads and stores requires larger offsets.
203 void Writer::layoutMemory() {
204   uint32_t MemoryPtr = 0;
205 
206   auto PlaceStack = [&]() {
207     if (Config->Relocatable || Config->Shared)
208       return;
209     MemoryPtr = alignTo(MemoryPtr, StackAlignment);
210     if (Config->ZStackSize != alignTo(Config->ZStackSize, StackAlignment))
211       error("stack size must be " + Twine(StackAlignment) + "-byte aligned");
212     log("mem: stack size  = " + Twine(Config->ZStackSize));
213     log("mem: stack base  = " + Twine(MemoryPtr));
214     MemoryPtr += Config->ZStackSize;
215     auto *SP = cast<DefinedGlobal>(WasmSym::StackPointer);
216     SP->Global->Global.InitExpr.Value.Int32 = MemoryPtr;
217     log("mem: stack top   = " + Twine(MemoryPtr));
218   };
219 
220   if (Config->StackFirst) {
221     PlaceStack();
222   } else {
223     MemoryPtr = Config->GlobalBase;
224     log("mem: global base = " + Twine(Config->GlobalBase));
225   }
226 
227   uint32_t DataStart = MemoryPtr;
228 
229   // Arbitrarily set __dso_handle handle to point to the start of the data
230   // segments.
231   if (WasmSym::DsoHandle)
232     WasmSym::DsoHandle->setVirtualAddress(DataStart);
233 
234   Out.DylinkSec->MemAlign = 0;
235   for (OutputSegment *Seg : Segments) {
236     Out.DylinkSec->MemAlign = std::max(Out.DylinkSec->MemAlign, Seg->Alignment);
237     MemoryPtr = alignTo(MemoryPtr, 1ULL << Seg->Alignment);
238     Seg->StartVA = MemoryPtr;
239     log(formatv("mem: {0,-15} offset={1,-8} size={2,-8} align={3}", Seg->Name,
240                 MemoryPtr, Seg->Size, Seg->Alignment));
241     MemoryPtr += Seg->Size;
242   }
243 
244   // TODO: Add .bss space here.
245   if (WasmSym::DataEnd)
246     WasmSym::DataEnd->setVirtualAddress(MemoryPtr);
247 
248   log("mem: static data = " + Twine(MemoryPtr - DataStart));
249 
250   if (Config->Shared) {
251     Out.DylinkSec->MemSize = MemoryPtr;
252     return;
253   }
254 
255   if (!Config->StackFirst)
256     PlaceStack();
257 
258   // Set `__heap_base` to directly follow the end of the stack or global data.
259   // The fact that this comes last means that a malloc/brk implementation
260   // can grow the heap at runtime.
261   if (!Config->Relocatable) {
262     WasmSym::HeapBase->setVirtualAddress(MemoryPtr);
263     log("mem: heap base   = " + Twine(MemoryPtr));
264   }
265 
266   if (Config->InitialMemory != 0) {
267     if (Config->InitialMemory != alignTo(Config->InitialMemory, WasmPageSize))
268       error("initial memory must be " + Twine(WasmPageSize) + "-byte aligned");
269     if (MemoryPtr > Config->InitialMemory)
270       error("initial memory too small, " + Twine(MemoryPtr) + " bytes needed");
271     else
272       MemoryPtr = Config->InitialMemory;
273   }
274   Out.DylinkSec->MemSize = MemoryPtr;
275   Out.MemorySec->NumMemoryPages =
276       alignTo(MemoryPtr, WasmPageSize) / WasmPageSize;
277   log("mem: total pages = " + Twine(Out.MemorySec->NumMemoryPages));
278 
279   // Check max if explicitly supplied or required by shared memory
280   if (Config->MaxMemory != 0 || Config->SharedMemory) {
281     if (Config->MaxMemory != alignTo(Config->MaxMemory, WasmPageSize))
282       error("maximum memory must be " + Twine(WasmPageSize) + "-byte aligned");
283     if (MemoryPtr > Config->MaxMemory)
284       error("maximum memory too small, " + Twine(MemoryPtr) + " bytes needed");
285     Out.MemorySec->MaxMemoryPages = Config->MaxMemory / WasmPageSize;
286     log("mem: max pages   = " + Twine(Out.MemorySec->MaxMemoryPages));
287   }
288 }
289 
290 void Writer::addSection(OutputSection *Sec) {
291   if (!Sec->isNeeded())
292     return;
293   log("addSection: " + toString(*Sec));
294   Sec->SectionIndex = OutputSections.size();
295   OutputSections.push_back(Sec);
296 }
297 
298 // If a section name is valid as a C identifier (which is rare because of
299 // the leading '.'), linkers are expected to define __start_<secname> and
300 // __stop_<secname> symbols. They are at beginning and end of the section,
301 // respectively. This is not requested by the ELF standard, but GNU ld and
302 // gold provide the feature, and used by many programs.
303 void Writer::addStartStopSymbols(const InputSegment *Seg) {
304   StringRef S = Seg->getName();
305   LLVM_DEBUG(dbgs() << "addStartStopSymbols: " << S << "\n");
306   if (!isValidCIdentifier(S))
307     return;
308   uint32_t Start = Seg->OutputSeg->StartVA + Seg->OutputSegmentOffset;
309   uint32_t Stop = Start + Seg->getSize();
310   Symtab->addOptionalDataSymbol(Saver.save("__start_" + S), Start, 0);
311   Symtab->addOptionalDataSymbol(Saver.save("__stop_" + S), Stop, 0);
312 }
313 
314 void Writer::addSections() {
315   addSection(Out.DylinkSec);
316   addSection(Out.TypeSec);
317   addSection(Out.ImportSec);
318   addSection(Out.FunctionSec);
319   addSection(Out.TableSec);
320   addSection(Out.MemorySec);
321   addSection(Out.GlobalSec);
322   addSection(Out.EventSec);
323   addSection(Out.ExportSec);
324   addSection(Out.ElemSec);
325   addSection(Out.DataCountSec);
326 
327   addSection(make<CodeSection>(Out.FunctionSec->InputFunctions));
328   addSection(make<DataSection>(Segments));
329 
330   createCustomSections();
331 
332   addSection(Out.LinkingSec);
333   if (Config->EmitRelocs || Config->Relocatable) {
334     createRelocSections();
335   }
336 
337   addSection(Out.NameSec);
338   addSection(Out.ProducersSec);
339   addSection(Out.TargetFeaturesSec);
340 }
341 
342 void Writer::finalizeSections() {
343   for (OutputSection *S : OutputSections) {
344     S->setOffset(FileSize);
345     S->finalizeContents();
346     FileSize += S->getSize();
347   }
348 }
349 
350 void Writer::populateTargetFeatures() {
351   SmallSet<std::string, 8> Used;
352   SmallSet<std::string, 8> Required;
353   SmallSet<std::string, 8> Disallowed;
354 
355   // Only infer used features if user did not specify features
356   bool InferFeatures = !Config->Features.hasValue();
357 
358   if (!InferFeatures) {
359     for (auto &Feature : Config->Features.getValue())
360       Out.TargetFeaturesSec->Features.insert(Feature);
361     // No need to read or check features
362     if (!Config->CheckFeatures)
363       return;
364   }
365 
366   // Find the sets of used, required, and disallowed features
367   for (ObjFile *File : Symtab->ObjectFiles) {
368     for (auto &Feature : File->getWasmObj()->getTargetFeatures()) {
369       switch (Feature.Prefix) {
370       case WASM_FEATURE_PREFIX_USED:
371         Used.insert(Feature.Name);
372         break;
373       case WASM_FEATURE_PREFIX_REQUIRED:
374         Used.insert(Feature.Name);
375         Required.insert(Feature.Name);
376         break;
377       case WASM_FEATURE_PREFIX_DISALLOWED:
378         Disallowed.insert(Feature.Name);
379         break;
380       default:
381         error("Unrecognized feature policy prefix " +
382               std::to_string(Feature.Prefix));
383       }
384     }
385   }
386 
387   if (InferFeatures)
388     Out.TargetFeaturesSec->Features.insert(Used.begin(), Used.end());
389 
390   if (Out.TargetFeaturesSec->Features.count("atomics") && !Config->SharedMemory)
391     error("'atomics' feature is used, so --shared-memory must be used");
392 
393   if (!Config->CheckFeatures)
394     return;
395 
396   if (Disallowed.count("atomics") && Config->SharedMemory)
397     error(
398         "'atomics' feature is disallowed, so --shared-memory must not be used");
399 
400   // Validate that used features are allowed in output
401   if (!InferFeatures) {
402     for (auto &Feature : Used) {
403       if (!Out.TargetFeaturesSec->Features.count(Feature))
404         error(Twine("Target feature '") + Feature + "' is not allowed.");
405     }
406   }
407 
408   // Validate the required and disallowed constraints for each file
409   for (ObjFile *File : Symtab->ObjectFiles) {
410     SmallSet<std::string, 8> ObjectFeatures;
411     for (auto &Feature : File->getWasmObj()->getTargetFeatures()) {
412       if (Feature.Prefix == WASM_FEATURE_PREFIX_DISALLOWED)
413         continue;
414       ObjectFeatures.insert(Feature.Name);
415       if (Disallowed.count(Feature.Name))
416         error(Twine("Target feature '") + Feature.Name +
417               "' is disallowed. Use --no-check-features to suppress.");
418     }
419     for (auto &Feature : Required) {
420       if (!ObjectFeatures.count(Feature))
421         error(Twine("Missing required target feature '") + Feature +
422               "'. Use --no-check-features to suppress.");
423     }
424   }
425 }
426 
427 void Writer::calculateImports() {
428   for (Symbol *Sym : Symtab->getSymbols()) {
429     if (!Sym->isUndefined())
430       continue;
431     if (Sym->isWeak() && !Config->Relocatable)
432       continue;
433     if (!Sym->isLive())
434       continue;
435     if (!Sym->IsUsedInRegularObj)
436       continue;
437     // We don't generate imports for data symbols. They however can be imported
438     // as GOT entries.
439     if (isa<DataSymbol>(Sym))
440       continue;
441 
442     LLVM_DEBUG(dbgs() << "import: " << Sym->getName() << "\n");
443     Out.ImportSec->addImport(Sym);
444   }
445 }
446 
447 void Writer::calculateExports() {
448   if (Config->Relocatable)
449     return;
450 
451   if (!Config->Relocatable && !Config->ImportMemory)
452     Out.ExportSec->Exports.push_back(
453         WasmExport{"memory", WASM_EXTERNAL_MEMORY, 0});
454 
455   if (!Config->Relocatable && Config->ExportTable)
456     Out.ExportSec->Exports.push_back(
457         WasmExport{FunctionTableName, WASM_EXTERNAL_TABLE, 0});
458 
459   unsigned FakeGlobalIndex =
460       Out.ImportSec->numImportedGlobals() + Out.GlobalSec->InputGlobals.size();
461 
462   for (Symbol *Sym : Symtab->getSymbols()) {
463     if (!Sym->isExported())
464       continue;
465     if (!Sym->isLive())
466       continue;
467 
468     StringRef Name = Sym->getName();
469     WasmExport Export;
470     if (auto *F = dyn_cast<DefinedFunction>(Sym)) {
471       Export = {Name, WASM_EXTERNAL_FUNCTION, F->getFunctionIndex()};
472     } else if (auto *G = dyn_cast<DefinedGlobal>(Sym)) {
473       // TODO(sbc): Remove this check once to mutable global proposal is
474       // implement in all major browsers.
475       // See: https://github.com/WebAssembly/mutable-global
476       if (G->getGlobalType()->Mutable) {
477         // Only the __stack_pointer should ever be create as mutable.
478         assert(G == WasmSym::StackPointer);
479         continue;
480       }
481       Export = {Name, WASM_EXTERNAL_GLOBAL, G->getGlobalIndex()};
482     } else if (auto *E = dyn_cast<DefinedEvent>(Sym)) {
483       Export = {Name, WASM_EXTERNAL_EVENT, E->getEventIndex()};
484     } else {
485       auto *D = cast<DefinedData>(Sym);
486       Out.GlobalSec->DefinedFakeGlobals.emplace_back(D);
487       Export = {Name, WASM_EXTERNAL_GLOBAL, FakeGlobalIndex++};
488     }
489 
490     LLVM_DEBUG(dbgs() << "Export: " << Name << "\n");
491     Out.ExportSec->Exports.push_back(Export);
492   }
493 }
494 
495 void Writer::populateSymtab() {
496   if (!Config->Relocatable && !Config->EmitRelocs)
497     return;
498 
499   for (Symbol *Sym : Symtab->getSymbols())
500     if (Sym->IsUsedInRegularObj && Sym->isLive())
501       Out.LinkingSec->addToSymtab(Sym);
502 
503   for (ObjFile *File : Symtab->ObjectFiles) {
504     LLVM_DEBUG(dbgs() << "Local symtab entries: " << File->getName() << "\n");
505     for (Symbol *Sym : File->getSymbols())
506       if (Sym->isLocal() && !isa<SectionSymbol>(Sym) && Sym->isLive())
507         Out.LinkingSec->addToSymtab(Sym);
508   }
509 }
510 
511 void Writer::calculateTypes() {
512   // The output type section is the union of the following sets:
513   // 1. Any signature used in the TYPE relocation
514   // 2. The signatures of all imported functions
515   // 3. The signatures of all defined functions
516   // 4. The signatures of all imported events
517   // 5. The signatures of all defined events
518 
519   for (ObjFile *File : Symtab->ObjectFiles) {
520     ArrayRef<WasmSignature> Types = File->getWasmObj()->types();
521     for (uint32_t I = 0; I < Types.size(); I++)
522       if (File->TypeIsUsed[I])
523         File->TypeMap[I] = Out.TypeSec->registerType(Types[I]);
524   }
525 
526   for (const Symbol *Sym : Out.ImportSec->ImportedSymbols) {
527     if (auto *F = dyn_cast<FunctionSymbol>(Sym))
528       Out.TypeSec->registerType(*F->Signature);
529     else if (auto *E = dyn_cast<EventSymbol>(Sym))
530       Out.TypeSec->registerType(*E->Signature);
531   }
532 
533   for (const InputFunction *F : Out.FunctionSec->InputFunctions)
534     Out.TypeSec->registerType(F->Signature);
535 
536   for (const InputEvent *E : Out.EventSec->InputEvents)
537     Out.TypeSec->registerType(E->Signature);
538 }
539 
540 static void scanRelocations() {
541   for (ObjFile *File : Symtab->ObjectFiles) {
542     LLVM_DEBUG(dbgs() << "scanRelocations: " << File->getName() << "\n");
543     for (InputChunk *Chunk : File->Functions)
544       scanRelocations(Chunk);
545     for (InputChunk *Chunk : File->Segments)
546       scanRelocations(Chunk);
547     for (auto &P : File->CustomSections)
548       scanRelocations(P);
549   }
550 }
551 
552 void Writer::assignIndexes() {
553   // Seal the import section, since other index spaces such as function and
554   // global are effected by the number of imports.
555   Out.ImportSec->seal();
556 
557   for (InputFunction *Func : Symtab->SyntheticFunctions)
558     Out.FunctionSec->addFunction(Func);
559 
560   for (ObjFile *File : Symtab->ObjectFiles) {
561     LLVM_DEBUG(dbgs() << "Functions: " << File->getName() << "\n");
562     for (InputFunction *Func : File->Functions)
563       Out.FunctionSec->addFunction(Func);
564   }
565 
566   for (InputGlobal *Global : Symtab->SyntheticGlobals)
567     Out.GlobalSec->addGlobal(Global);
568 
569   for (ObjFile *File : Symtab->ObjectFiles) {
570     LLVM_DEBUG(dbgs() << "Globals: " << File->getName() << "\n");
571     for (InputGlobal *Global : File->Globals)
572       Out.GlobalSec->addGlobal(Global);
573   }
574 
575   for (ObjFile *File : Symtab->ObjectFiles) {
576     LLVM_DEBUG(dbgs() << "Events: " << File->getName() << "\n");
577     for (InputEvent *Event : File->Events)
578       Out.EventSec->addEvent(Event);
579   }
580 }
581 
582 static StringRef getOutputDataSegmentName(StringRef Name) {
583   // With PIC code we currently only support a single data segment since
584   // we only have a single __memory_base to use as our base address.
585   if (Config->Pic)
586     return "data";
587   if (!Config->MergeDataSegments)
588     return Name;
589   if (Name.startswith(".text."))
590     return ".text";
591   if (Name.startswith(".data."))
592     return ".data";
593   if (Name.startswith(".bss."))
594     return ".bss";
595   if (Name.startswith(".rodata."))
596     return ".rodata";
597   return Name;
598 }
599 
600 void Writer::createOutputSegments() {
601   for (ObjFile *File : Symtab->ObjectFiles) {
602     for (InputSegment *Segment : File->Segments) {
603       if (!Segment->Live)
604         continue;
605       StringRef Name = getOutputDataSegmentName(Segment->getName());
606       OutputSegment *&S = SegmentMap[Name];
607       if (S == nullptr) {
608         LLVM_DEBUG(dbgs() << "new segment: " << Name << "\n");
609         S = make<OutputSegment>(Name, Segments.size());
610         Segments.push_back(S);
611       }
612       S->addInputSegment(Segment);
613       LLVM_DEBUG(dbgs() << "added data: " << Name << ": " << S->Size << "\n");
614     }
615   }
616 }
617 
618 // For -shared (PIC) output, we create create a synthetic function which will
619 // apply any relocations to the data segments on startup.  This function is
620 // called __wasm_apply_relocs and is added at the very beginning of
621 // __wasm_call_ctors before any of the constructors run.
622 void Writer::createApplyRelocationsFunction() {
623   LLVM_DEBUG(dbgs() << "createApplyRelocationsFunction\n");
624   // First write the body's contents to a string.
625   std::string BodyContent;
626   {
627     raw_string_ostream OS(BodyContent);
628     writeUleb128(OS, 0, "num locals");
629     for (const OutputSegment *Seg : Segments)
630       for (const InputSegment *InSeg : Seg->InputSegments)
631         InSeg->generateRelocationCode(OS);
632     writeU8(OS, WASM_OPCODE_END, "END");
633   }
634 
635   // Once we know the size of the body we can create the final function body
636   std::string FunctionBody;
637   {
638     raw_string_ostream OS(FunctionBody);
639     writeUleb128(OS, BodyContent.size(), "function size");
640     OS << BodyContent;
641   }
642 
643   ArrayRef<uint8_t> Body = arrayRefFromStringRef(Saver.save(FunctionBody));
644   cast<SyntheticFunction>(WasmSym::ApplyRelocs->Function)->setBody(Body);
645 }
646 
647 // Create synthetic "__wasm_call_ctors" function based on ctor functions
648 // in input object.
649 void Writer::createCallCtorsFunction() {
650   if (!WasmSym::CallCtors->isLive())
651     return;
652 
653   // First write the body's contents to a string.
654   std::string BodyContent;
655   {
656     raw_string_ostream OS(BodyContent);
657     writeUleb128(OS, 0, "num locals");
658     if (Config->Pic) {
659       writeU8(OS, WASM_OPCODE_CALL, "CALL");
660       writeUleb128(OS, WasmSym::ApplyRelocs->getFunctionIndex(),
661                    "function index");
662     }
663     for (const WasmInitEntry &F : InitFunctions) {
664       writeU8(OS, WASM_OPCODE_CALL, "CALL");
665       writeUleb128(OS, F.Sym->getFunctionIndex(), "function index");
666     }
667     writeU8(OS, WASM_OPCODE_END, "END");
668   }
669 
670   // Once we know the size of the body we can create the final function body
671   std::string FunctionBody;
672   {
673     raw_string_ostream OS(FunctionBody);
674     writeUleb128(OS, BodyContent.size(), "function size");
675     OS << BodyContent;
676   }
677 
678   ArrayRef<uint8_t> Body = arrayRefFromStringRef(Saver.save(FunctionBody));
679   cast<SyntheticFunction>(WasmSym::CallCtors->Function)->setBody(Body);
680 }
681 
682 // Populate InitFunctions vector with init functions from all input objects.
683 // This is then used either when creating the output linking section or to
684 // synthesize the "__wasm_call_ctors" function.
685 void Writer::calculateInitFunctions() {
686   if (!Config->Relocatable && !WasmSym::CallCtors->isLive())
687     return;
688 
689   for (ObjFile *File : Symtab->ObjectFiles) {
690     const WasmLinkingData &L = File->getWasmObj()->linkingData();
691     for (const WasmInitFunc &F : L.InitFunctions) {
692       FunctionSymbol *Sym = File->getFunctionSymbol(F.Symbol);
693       assert(Sym->isLive());
694       if (*Sym->Signature != WasmSignature{{}, {}})
695         error("invalid signature for init func: " + toString(*Sym));
696       InitFunctions.emplace_back(WasmInitEntry{Sym, F.Priority});
697     }
698   }
699 
700   // Sort in order of priority (lowest first) so that they are called
701   // in the correct order.
702   llvm::stable_sort(InitFunctions,
703                     [](const WasmInitEntry &L, const WasmInitEntry &R) {
704                       return L.Priority < R.Priority;
705                     });
706 }
707 
708 void Writer::createSyntheticSections() {
709   Out.DylinkSec = make<DylinkSection>();
710   Out.TypeSec = make<TypeSection>();
711   Out.ImportSec = make<ImportSection>();
712   Out.FunctionSec = make<FunctionSection>();
713   Out.TableSec = make<TableSection>();
714   Out.MemorySec = make<MemorySection>();
715   Out.GlobalSec = make<GlobalSection>();
716   Out.EventSec = make<EventSection>();
717   Out.ExportSec = make<ExportSection>();
718   Out.ElemSec = make<ElemSection>(TableBase);
719   Out.DataCountSec = make<DataCountSection>(Segments.size());
720   Out.LinkingSec = make<LinkingSection>(InitFunctions, Segments);
721   Out.NameSec = make<NameSection>();
722   Out.ProducersSec = make<ProducersSection>();
723   Out.TargetFeaturesSec = make<TargetFeaturesSection>();
724 }
725 
726 void Writer::run() {
727   if (Config->Relocatable || Config->Pic)
728     Config->GlobalBase = 0;
729 
730   // For PIC code the table base is assigned dynamically by the loader.
731   // For non-PIC, we start at 1 so that accessing table index 0 always traps.
732   if (!Config->Pic)
733     TableBase = 1;
734 
735   log("-- createOutputSegments");
736   createOutputSegments();
737   log("-- createSyntheticSections");
738   createSyntheticSections();
739   log("-- populateProducers");
740   populateProducers();
741   log("-- populateTargetFeatures");
742   populateTargetFeatures();
743   log("-- calculateImports");
744   calculateImports();
745   log("-- layoutMemory");
746   layoutMemory();
747 
748   if (!Config->Relocatable) {
749     // Create linker synthesized __start_SECNAME/__stop_SECNAME symbols
750     // This has to be done after memory layout is performed.
751     for (const OutputSegment *Seg : Segments)
752       for (const InputSegment *S : Seg->InputSegments)
753         addStartStopSymbols(S);
754   }
755 
756   log("-- scanRelocations");
757   scanRelocations();
758   log("-- assignIndexes");
759   assignIndexes();
760   log("-- calculateInitFunctions");
761   calculateInitFunctions();
762 
763   if (!Config->Relocatable) {
764     // Create linker synthesized functions
765     if (Config->Pic)
766       createApplyRelocationsFunction();
767     createCallCtorsFunction();
768 
769     // Make sure we have resolved all symbols.
770     if (!Config->AllowUndefined)
771       Symtab->reportRemainingUndefines();
772 
773     if (errorCount())
774       return;
775   }
776 
777   log("-- calculateTypes");
778   calculateTypes();
779   log("-- calculateExports");
780   calculateExports();
781   log("-- calculateCustomSections");
782   calculateCustomSections();
783   log("-- populateSymtab");
784   populateSymtab();
785   log("-- addSections");
786   addSections();
787 
788   if (errorHandler().Verbose) {
789     log("Defined Functions: " + Twine(Out.FunctionSec->InputFunctions.size()));
790     log("Defined Globals  : " + Twine(Out.GlobalSec->InputGlobals.size()));
791     log("Defined Events   : " + Twine(Out.EventSec->InputEvents.size()));
792     log("Function Imports : " + Twine(Out.ImportSec->numImportedFunctions()));
793     log("Global Imports   : " + Twine(Out.ImportSec->numImportedGlobals()));
794     log("Event Imports    : " + Twine(Out.ImportSec->numImportedEvents()));
795     for (ObjFile *File : Symtab->ObjectFiles)
796       File->dumpInfo();
797   }
798 
799   createHeader();
800   log("-- finalizeSections");
801   finalizeSections();
802 
803   log("-- openFile");
804   openFile();
805   if (errorCount())
806     return;
807 
808   writeHeader();
809 
810   log("-- writeSections");
811   writeSections();
812   if (errorCount())
813     return;
814 
815   if (Error E = Buffer->commit())
816     fatal("failed to write the output file: " + toString(std::move(E)));
817 }
818 
819 // Open a result file.
820 void Writer::openFile() {
821   log("writing: " + Config->OutputFile);
822 
823   Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
824       FileOutputBuffer::create(Config->OutputFile, FileSize,
825                                FileOutputBuffer::F_executable);
826 
827   if (!BufferOrErr)
828     error("failed to open " + Config->OutputFile + ": " +
829           toString(BufferOrErr.takeError()));
830   else
831     Buffer = std::move(*BufferOrErr);
832 }
833 
834 void Writer::createHeader() {
835   raw_string_ostream OS(Header);
836   writeBytes(OS, WasmMagic, sizeof(WasmMagic), "wasm magic");
837   writeU32(OS, WasmVersion, "wasm version");
838   OS.flush();
839   FileSize += Header.size();
840 }
841 
842 void lld::wasm::writeResult() { Writer().run(); }
843