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