xref: /llvm-project-15.0.7/lld/wasm/Writer.cpp (revision 6f4fb4e7)
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 
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->getNumRelocations();
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->isPic)
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   if (WasmSym::globalBase)
228     WasmSym::globalBase->setVirtualAddress(config->globalBase);
229 
230   uint32_t dataStart = memoryPtr;
231 
232   // Arbitrarily set __dso_handle handle to point to the start of the data
233   // segments.
234   if (WasmSym::dsoHandle)
235     WasmSym::dsoHandle->setVirtualAddress(dataStart);
236 
237   out.dylinkSec->memAlign = 0;
238   for (OutputSegment *seg : segments) {
239     out.dylinkSec->memAlign = std::max(out.dylinkSec->memAlign, seg->alignment);
240     memoryPtr = alignTo(memoryPtr, 1ULL << seg->alignment);
241     seg->startVA = memoryPtr;
242     log(formatv("mem: {0,-15} offset={1,-8} size={2,-8} align={3}", seg->name,
243                 memoryPtr, seg->size, seg->alignment));
244     memoryPtr += seg->size;
245   }
246 
247   // TODO: Add .bss space here.
248   if (WasmSym::dataEnd)
249     WasmSym::dataEnd->setVirtualAddress(memoryPtr);
250 
251   log("mem: static data = " + Twine(memoryPtr - dataStart));
252 
253   if (config->shared) {
254     out.dylinkSec->memSize = memoryPtr;
255     return;
256   }
257 
258   if (!config->stackFirst)
259     placeStack();
260 
261   // Set `__heap_base` to directly follow the end of the stack or global data.
262   // The fact that this comes last means that a malloc/brk implementation
263   // can grow the heap at runtime.
264   log("mem: heap base   = " + Twine(memoryPtr));
265   if (WasmSym::heapBase)
266     WasmSym::heapBase->setVirtualAddress(memoryPtr);
267 
268   if (config->initialMemory != 0) {
269     if (config->initialMemory != alignTo(config->initialMemory, WasmPageSize))
270       error("initial memory must be " + Twine(WasmPageSize) + "-byte aligned");
271     if (memoryPtr > config->initialMemory)
272       error("initial memory too small, " + Twine(memoryPtr) + " bytes needed");
273     else
274       memoryPtr = config->initialMemory;
275   }
276   out.dylinkSec->memSize = memoryPtr;
277   out.memorySec->numMemoryPages =
278       alignTo(memoryPtr, WasmPageSize) / WasmPageSize;
279   log("mem: total pages = " + Twine(out.memorySec->numMemoryPages));
280 
281   // Check max if explicitly supplied or required by shared memory
282   if (config->maxMemory != 0 || config->sharedMemory) {
283     if (config->maxMemory != alignTo(config->maxMemory, WasmPageSize))
284       error("maximum memory must be " + Twine(WasmPageSize) + "-byte aligned");
285     if (memoryPtr > config->maxMemory)
286       error("maximum memory too small, " + Twine(memoryPtr) + " bytes needed");
287     out.memorySec->maxMemoryPages = config->maxMemory / WasmPageSize;
288     log("mem: max pages   = " + Twine(out.memorySec->maxMemoryPages));
289   }
290 }
291 
292 void Writer::addSection(OutputSection *sec) {
293   if (!sec->isNeeded())
294     return;
295   log("addSection: " + toString(*sec));
296   sec->sectionIndex = outputSections.size();
297   outputSections.push_back(sec);
298 }
299 
300 // If a section name is valid as a C identifier (which is rare because of
301 // the leading '.'), linkers are expected to define __start_<secname> and
302 // __stop_<secname> symbols. They are at beginning and end of the section,
303 // respectively. This is not requested by the ELF standard, but GNU ld and
304 // gold provide the feature, and used by many programs.
305 static void addStartStopSymbols(const OutputSegment *seg) {
306   StringRef name = seg->name;
307   if (!isValidCIdentifier(name))
308     return;
309   LLVM_DEBUG(dbgs() << "addStartStopSymbols: " << name << "\n");
310   uint32_t start = seg->startVA;
311   uint32_t stop = start + seg->size;
312   symtab->addOptionalDataSymbol(saver.save("__start_" + name), start);
313   symtab->addOptionalDataSymbol(saver.save("__stop_" + name), stop);
314 }
315 
316 void Writer::addSections() {
317   addSection(out.dylinkSec);
318   addSection(out.typeSec);
319   addSection(out.importSec);
320   addSection(out.functionSec);
321   addSection(out.tableSec);
322   addSection(out.memorySec);
323   addSection(out.globalSec);
324   addSection(out.eventSec);
325   addSection(out.exportSec);
326   addSection(out.elemSec);
327   addSection(out.dataCountSec);
328 
329   addSection(make<CodeSection>(out.functionSec->inputFunctions));
330   addSection(make<DataSection>(segments));
331 
332   createCustomSections();
333 
334   addSection(out.linkingSec);
335   if (config->emitRelocs || config->relocatable) {
336     createRelocSections();
337   }
338 
339   addSection(out.nameSec);
340   addSection(out.producersSec);
341   addSection(out.targetFeaturesSec);
342 }
343 
344 void Writer::finalizeSections() {
345   for (OutputSection *s : outputSections) {
346     s->setOffset(fileSize);
347     s->finalizeContents();
348     fileSize += s->getSize();
349   }
350 }
351 
352 void Writer::populateTargetFeatures() {
353   StringMap<std::string> used;
354   StringMap<std::string> required;
355   StringMap<std::string> disallowed;
356 
357   // Only infer used features if user did not specify features
358   bool inferFeatures = !config->features.hasValue();
359 
360   if (!inferFeatures) {
361     for (auto &feature : config->features.getValue())
362       out.targetFeaturesSec->features.insert(feature);
363     // No need to read or check features
364     if (!config->checkFeatures)
365       return;
366   }
367 
368   // Find the sets of used, required, and disallowed features
369   for (ObjFile *file : symtab->objectFiles) {
370     StringRef fileName(file->getName());
371     for (auto &feature : file->getWasmObj()->getTargetFeatures()) {
372       switch (feature.Prefix) {
373       case WASM_FEATURE_PREFIX_USED:
374         used.insert({feature.Name, fileName});
375         break;
376       case WASM_FEATURE_PREFIX_REQUIRED:
377         used.insert({feature.Name, fileName});
378         required.insert({feature.Name, fileName});
379         break;
380       case WASM_FEATURE_PREFIX_DISALLOWED:
381         disallowed.insert({feature.Name, fileName});
382         break;
383       default:
384         error("Unrecognized feature policy prefix " +
385               std::to_string(feature.Prefix));
386       }
387     }
388   }
389 
390   if (inferFeatures)
391     out.targetFeaturesSec->features.insert(used.keys().begin(),
392                                            used.keys().end());
393 
394   if (out.targetFeaturesSec->features.count("atomics") &&
395       !config->sharedMemory) {
396     if (inferFeatures)
397       error(Twine("'atomics' feature is used by ") + used["atomics"] +
398             ", so --shared-memory must be used");
399     else
400       error("'atomics' feature is used, so --shared-memory must be used");
401   }
402 
403   if (!config->checkFeatures)
404     return;
405 
406   if (disallowed.count("atomics") && config->sharedMemory)
407     error("'atomics' feature is disallowed by " + disallowed["atomics"] +
408           ", so --shared-memory must not be used");
409 
410   if (!used.count("bulk-memory") && config->passiveSegments)
411     error("'bulk-memory' feature must be used in order to emit passive "
412           "segments");
413 
414   // Validate that used features are allowed in output
415   if (!inferFeatures) {
416     for (auto &feature : used.keys()) {
417       if (!out.targetFeaturesSec->features.count(feature))
418         error(Twine("Target feature '") + feature + "' used by " +
419               used[feature] + " is not allowed.");
420     }
421   }
422 
423   // Validate the required and disallowed constraints for each file
424   for (ObjFile *file : symtab->objectFiles) {
425     StringRef fileName(file->getName());
426     SmallSet<std::string, 8> objectFeatures;
427     for (auto &feature : file->getWasmObj()->getTargetFeatures()) {
428       if (feature.Prefix == WASM_FEATURE_PREFIX_DISALLOWED)
429         continue;
430       objectFeatures.insert(feature.Name);
431       if (disallowed.count(feature.Name))
432         error(Twine("Target feature '") + feature.Name + "' used in " +
433               fileName + " is disallowed by " + disallowed[feature.Name] +
434               ". Use --no-check-features to suppress.");
435     }
436     for (auto &feature : required.keys()) {
437       if (!objectFeatures.count(feature))
438         error(Twine("Missing target feature '") + feature + "' in " + fileName +
439               ", required by " + required[feature] +
440               ". Use --no-check-features to suppress.");
441     }
442   }
443 }
444 
445 void Writer::calculateImports() {
446   for (Symbol *sym : symtab->getSymbols()) {
447     if (!sym->isUndefined())
448       continue;
449     if (sym->isWeak() && !config->relocatable)
450       continue;
451     if (!sym->isLive())
452       continue;
453     if (!sym->isUsedInRegularObj)
454       continue;
455     // We don't generate imports for data symbols. They however can be imported
456     // as GOT entries.
457     if (isa<DataSymbol>(sym))
458       continue;
459 
460     LLVM_DEBUG(dbgs() << "import: " << sym->getName() << "\n");
461     out.importSec->addImport(sym);
462   }
463 }
464 
465 void Writer::calculateExports() {
466   if (config->relocatable)
467     return;
468 
469   if (!config->relocatable && !config->importMemory)
470     out.exportSec->exports.push_back(
471         WasmExport{"memory", WASM_EXTERNAL_MEMORY, 0});
472 
473   if (!config->relocatable && config->exportTable)
474     out.exportSec->exports.push_back(
475         WasmExport{functionTableName, WASM_EXTERNAL_TABLE, 0});
476 
477   unsigned fakeGlobalIndex = out.importSec->getNumImportedGlobals() +
478                              out.globalSec->inputGlobals.size();
479 
480   for (Symbol *sym : symtab->getSymbols()) {
481     if (!sym->isExported())
482       continue;
483     if (!sym->isLive())
484       continue;
485 
486     StringRef name = sym->getName();
487     WasmExport export_;
488     if (auto *f = dyn_cast<DefinedFunction>(sym)) {
489       export_ = {name, WASM_EXTERNAL_FUNCTION, f->getFunctionIndex()};
490     } else if (auto *g = dyn_cast<DefinedGlobal>(sym)) {
491       // TODO(sbc): Remove this check once to mutable global proposal is
492       // implement in all major browsers.
493       // See: https://github.com/WebAssembly/mutable-global
494       if (g->getGlobalType()->Mutable) {
495         // Only the __stack_pointer should ever be create as mutable.
496         assert(g == WasmSym::stackPointer);
497         continue;
498       }
499       export_ = {name, WASM_EXTERNAL_GLOBAL, g->getGlobalIndex()};
500     } else if (auto *e = dyn_cast<DefinedEvent>(sym)) {
501       export_ = {name, WASM_EXTERNAL_EVENT, e->getEventIndex()};
502     } else {
503       auto *d = cast<DefinedData>(sym);
504       out.globalSec->definedFakeGlobals.emplace_back(d);
505       export_ = {name, WASM_EXTERNAL_GLOBAL, fakeGlobalIndex++};
506     }
507 
508     LLVM_DEBUG(dbgs() << "Export: " << name << "\n");
509     out.exportSec->exports.push_back(export_);
510   }
511 }
512 
513 void Writer::populateSymtab() {
514   if (!config->relocatable && !config->emitRelocs)
515     return;
516 
517   for (Symbol *sym : symtab->getSymbols())
518     if (sym->isUsedInRegularObj && sym->isLive())
519       out.linkingSec->addToSymtab(sym);
520 
521   for (ObjFile *file : symtab->objectFiles) {
522     LLVM_DEBUG(dbgs() << "Local symtab entries: " << file->getName() << "\n");
523     for (Symbol *sym : file->getSymbols())
524       if (sym->isLocal() && !isa<SectionSymbol>(sym) && sym->isLive())
525         out.linkingSec->addToSymtab(sym);
526   }
527 }
528 
529 void Writer::calculateTypes() {
530   // The output type section is the union of the following sets:
531   // 1. Any signature used in the TYPE relocation
532   // 2. The signatures of all imported functions
533   // 3. The signatures of all defined functions
534   // 4. The signatures of all imported events
535   // 5. The signatures of all defined events
536 
537   for (ObjFile *file : symtab->objectFiles) {
538     ArrayRef<WasmSignature> types = file->getWasmObj()->types();
539     for (uint32_t i = 0; i < types.size(); i++)
540       if (file->typeIsUsed[i])
541         file->typeMap[i] = out.typeSec->registerType(types[i]);
542   }
543 
544   for (const Symbol *sym : out.importSec->importedSymbols) {
545     if (auto *f = dyn_cast<FunctionSymbol>(sym))
546       out.typeSec->registerType(*f->signature);
547     else if (auto *e = dyn_cast<EventSymbol>(sym))
548       out.typeSec->registerType(*e->signature);
549   }
550 
551   for (const InputFunction *f : out.functionSec->inputFunctions)
552     out.typeSec->registerType(f->signature);
553 
554   for (const InputEvent *e : out.eventSec->inputEvents)
555     out.typeSec->registerType(e->signature);
556 }
557 
558 static void scanRelocations() {
559   for (ObjFile *file : symtab->objectFiles) {
560     LLVM_DEBUG(dbgs() << "scanRelocations: " << file->getName() << "\n");
561     for (InputChunk *chunk : file->functions)
562       scanRelocations(chunk);
563     for (InputChunk *chunk : file->segments)
564       scanRelocations(chunk);
565     for (auto &p : file->customSections)
566       scanRelocations(p);
567   }
568 }
569 
570 void Writer::assignIndexes() {
571   // Seal the import section, since other index spaces such as function and
572   // global are effected by the number of imports.
573   out.importSec->seal();
574 
575   for (InputFunction *func : symtab->syntheticFunctions)
576     out.functionSec->addFunction(func);
577 
578   for (ObjFile *file : symtab->objectFiles) {
579     LLVM_DEBUG(dbgs() << "Functions: " << file->getName() << "\n");
580     for (InputFunction *func : file->functions)
581       out.functionSec->addFunction(func);
582   }
583 
584   for (InputGlobal *global : symtab->syntheticGlobals)
585     out.globalSec->addGlobal(global);
586 
587   for (ObjFile *file : symtab->objectFiles) {
588     LLVM_DEBUG(dbgs() << "Globals: " << file->getName() << "\n");
589     for (InputGlobal *global : file->globals)
590       out.globalSec->addGlobal(global);
591   }
592 
593   for (ObjFile *file : symtab->objectFiles) {
594     LLVM_DEBUG(dbgs() << "Events: " << file->getName() << "\n");
595     for (InputEvent *event : file->events)
596       out.eventSec->addEvent(event);
597   }
598 }
599 
600 static StringRef getOutputDataSegmentName(StringRef name) {
601   // With PIC code we currently only support a single data segment since
602   // we only have a single __memory_base to use as our base address.
603   if (config->isPic)
604     return ".data";
605   if (!config->mergeDataSegments)
606     return name;
607   if (name.startswith(".text."))
608     return ".text";
609   if (name.startswith(".data."))
610     return ".data";
611   if (name.startswith(".bss."))
612     return ".bss";
613   if (name.startswith(".rodata."))
614     return ".rodata";
615   return name;
616 }
617 
618 void Writer::createOutputSegments() {
619   for (ObjFile *file : symtab->objectFiles) {
620     for (InputSegment *segment : file->segments) {
621       if (!segment->live)
622         continue;
623       StringRef name = getOutputDataSegmentName(segment->getName());
624       OutputSegment *&s = segmentMap[name];
625       if (s == nullptr) {
626         LLVM_DEBUG(dbgs() << "new segment: " << name << "\n");
627         s = make<OutputSegment>(name, segments.size());
628         if (config->passiveSegments)
629           s->initFlags = WASM_SEGMENT_IS_PASSIVE;
630         segments.push_back(s);
631       }
632       s->addInputSegment(segment);
633       LLVM_DEBUG(dbgs() << "added data: " << name << ": " << s->size << "\n");
634     }
635   }
636 }
637 
638 static void createFunction(DefinedFunction *func, StringRef bodyContent) {
639   std::string functionBody;
640   {
641     raw_string_ostream os(functionBody);
642     writeUleb128(os, bodyContent.size(), "function size");
643     os << bodyContent;
644   }
645   ArrayRef<uint8_t> body = arrayRefFromStringRef(saver.save(functionBody));
646   cast<SyntheticFunction>(func->function)->setBody(body);
647 }
648 
649 void Writer::createInitMemoryFunction() {
650   LLVM_DEBUG(dbgs() << "createInitMemoryFunction\n");
651   std::string bodyContent;
652   {
653     raw_string_ostream os(bodyContent);
654     writeUleb128(os, 0, "num locals");
655 
656     // initialize passive data segments
657     for (const OutputSegment *s : segments) {
658       if (s->initFlags & WASM_SEGMENT_IS_PASSIVE) {
659         // destination address
660         writeU8(os, WASM_OPCODE_I32_CONST, "i32.const");
661         writeUleb128(os, s->startVA, "destination address");
662         // source segment offset
663         writeU8(os, WASM_OPCODE_I32_CONST, "i32.const");
664         writeUleb128(os, 0, "segment offset");
665         // memory region size
666         writeU8(os, WASM_OPCODE_I32_CONST, "i32.const");
667         writeUleb128(os, s->size, "memory region size");
668         // memory.init instruction
669         writeU8(os, WASM_OPCODE_MISC_PREFIX, "bulk-memory prefix");
670         writeUleb128(os, WASM_OPCODE_MEMORY_INIT, "MEMORY.INIT");
671         writeUleb128(os, s->index, "segment index immediate");
672         writeU8(os, 0, "memory index immediate");
673         // data.drop instruction
674         writeU8(os, WASM_OPCODE_MISC_PREFIX, "bulk-memory prefix");
675         writeUleb128(os, WASM_OPCODE_DATA_DROP, "DATA.DROP");
676         writeUleb128(os, s->index, "segment index immediate");
677       }
678     }
679     writeU8(os, WASM_OPCODE_END, "END");
680   }
681 
682   createFunction(WasmSym::initMemory, bodyContent);
683 }
684 
685 // For -shared (PIC) output, we create create a synthetic function which will
686 // apply any relocations to the data segments on startup.  This function is
687 // called __wasm_apply_relocs and is added at the beginning of __wasm_call_ctors
688 // before any of the constructors run.
689 void Writer::createApplyRelocationsFunction() {
690   LLVM_DEBUG(dbgs() << "createApplyRelocationsFunction\n");
691   // First write the body's contents to a string.
692   std::string bodyContent;
693   {
694     raw_string_ostream os(bodyContent);
695     writeUleb128(os, 0, "num locals");
696     for (const OutputSegment *seg : segments)
697       for (const InputSegment *inSeg : seg->inputSegments)
698         inSeg->generateRelocationCode(os);
699     writeU8(os, WASM_OPCODE_END, "END");
700   }
701 
702   createFunction(WasmSym::applyRelocs, bodyContent);
703 }
704 
705 // Create synthetic "__wasm_call_ctors" function based on ctor functions
706 // in input object.
707 void Writer::createCallCtorsFunction() {
708   if (!WasmSym::callCtors->isLive())
709     return;
710 
711   // First write the body's contents to a string.
712   std::string bodyContent;
713   {
714     raw_string_ostream os(bodyContent);
715     writeUleb128(os, 0, "num locals");
716 
717     if (config->passiveSegments) {
718       writeU8(os, WASM_OPCODE_CALL, "CALL");
719       writeUleb128(os, WasmSym::initMemory->getFunctionIndex(),
720                    "function index");
721     }
722 
723     if (config->isPic) {
724       writeU8(os, WASM_OPCODE_CALL, "CALL");
725       writeUleb128(os, WasmSym::applyRelocs->getFunctionIndex(),
726                    "function index");
727     }
728 
729     // Call constructors
730     for (const WasmInitEntry &f : initFunctions) {
731       writeU8(os, WASM_OPCODE_CALL, "CALL");
732       writeUleb128(os, f.sym->getFunctionIndex(), "function index");
733     }
734     writeU8(os, WASM_OPCODE_END, "END");
735   }
736 
737   createFunction(WasmSym::callCtors, bodyContent);
738 }
739 
740 // Populate InitFunctions vector with init functions from all input objects.
741 // This is then used either when creating the output linking section or to
742 // synthesize the "__wasm_call_ctors" function.
743 void Writer::calculateInitFunctions() {
744   if (!config->relocatable && !WasmSym::callCtors->isLive())
745     return;
746 
747   for (ObjFile *file : symtab->objectFiles) {
748     const WasmLinkingData &l = file->getWasmObj()->linkingData();
749     for (const WasmInitFunc &f : l.InitFunctions) {
750       FunctionSymbol *sym = file->getFunctionSymbol(f.Symbol);
751       // comdat exclusions can cause init functions be discarded.
752       if (sym->isDiscarded())
753         continue;
754       assert(sym->isLive());
755       if (*sym->signature != WasmSignature{{}, {}})
756         error("invalid signature for init func: " + toString(*sym));
757       initFunctions.emplace_back(WasmInitEntry{sym, f.Priority});
758     }
759   }
760 
761   // Sort in order of priority (lowest first) so that they are called
762   // in the correct order.
763   llvm::stable_sort(initFunctions,
764                     [](const WasmInitEntry &l, const WasmInitEntry &r) {
765                       return l.priority < r.priority;
766                     });
767 }
768 
769 void Writer::createSyntheticSections() {
770   out.dylinkSec = make<DylinkSection>();
771   out.typeSec = make<TypeSection>();
772   out.importSec = make<ImportSection>();
773   out.functionSec = make<FunctionSection>();
774   out.tableSec = make<TableSection>();
775   out.memorySec = make<MemorySection>();
776   out.globalSec = make<GlobalSection>();
777   out.eventSec = make<EventSection>();
778   out.exportSec = make<ExportSection>();
779   out.elemSec = make<ElemSection>(tableBase);
780   out.dataCountSec = make<DataCountSection>(segments.size());
781   out.linkingSec = make<LinkingSection>(initFunctions, segments);
782   out.nameSec = make<NameSection>();
783   out.producersSec = make<ProducersSection>();
784   out.targetFeaturesSec = make<TargetFeaturesSection>();
785 }
786 
787 void Writer::run() {
788   if (config->relocatable || config->isPic)
789     config->globalBase = 0;
790 
791   // For PIC code the table base is assigned dynamically by the loader.
792   // For non-PIC, we start at 1 so that accessing table index 0 always traps.
793   if (!config->isPic)
794     tableBase = 1;
795 
796   log("-- createOutputSegments");
797   createOutputSegments();
798   log("-- createSyntheticSections");
799   createSyntheticSections();
800   log("-- populateProducers");
801   populateProducers();
802   log("-- populateTargetFeatures");
803   populateTargetFeatures();
804   log("-- calculateImports");
805   calculateImports();
806   log("-- layoutMemory");
807   layoutMemory();
808 
809   if (!config->relocatable) {
810     // Create linker synthesized __start_SECNAME/__stop_SECNAME symbols
811     // This has to be done after memory layout is performed.
812     for (const OutputSegment *seg : segments)
813       addStartStopSymbols(seg);
814   }
815 
816   log("-- scanRelocations");
817   scanRelocations();
818   log("-- assignIndexes");
819   assignIndexes();
820   log("-- calculateInitFunctions");
821   calculateInitFunctions();
822 
823   if (!config->relocatable) {
824     // Create linker synthesized functions
825     if (config->passiveSegments)
826       createInitMemoryFunction();
827     if (config->isPic)
828       createApplyRelocationsFunction();
829     createCallCtorsFunction();
830   }
831 
832   log("-- calculateTypes");
833   calculateTypes();
834   log("-- calculateExports");
835   calculateExports();
836   log("-- calculateCustomSections");
837   calculateCustomSections();
838   log("-- populateSymtab");
839   populateSymtab();
840   log("-- addSections");
841   addSections();
842 
843   if (errorHandler().verbose) {
844     log("Defined Functions: " + Twine(out.functionSec->inputFunctions.size()));
845     log("Defined Globals  : " + Twine(out.globalSec->inputGlobals.size()));
846     log("Defined Events   : " + Twine(out.eventSec->inputEvents.size()));
847     log("Function Imports : " +
848         Twine(out.importSec->getNumImportedFunctions()));
849     log("Global Imports   : " + Twine(out.importSec->getNumImportedGlobals()));
850     log("Event Imports    : " + Twine(out.importSec->getNumImportedEvents()));
851     for (ObjFile *file : symtab->objectFiles)
852       file->dumpInfo();
853   }
854 
855   createHeader();
856   log("-- finalizeSections");
857   finalizeSections();
858 
859   log("-- openFile");
860   openFile();
861   if (errorCount())
862     return;
863 
864   writeHeader();
865 
866   log("-- writeSections");
867   writeSections();
868   if (errorCount())
869     return;
870 
871   if (Error e = buffer->commit())
872     fatal("failed to write the output file: " + toString(std::move(e)));
873 }
874 
875 // Open a result file.
876 void Writer::openFile() {
877   log("writing: " + config->outputFile);
878 
879   Expected<std::unique_ptr<FileOutputBuffer>> bufferOrErr =
880       FileOutputBuffer::create(config->outputFile, fileSize,
881                                FileOutputBuffer::F_executable);
882 
883   if (!bufferOrErr)
884     error("failed to open " + config->outputFile + ": " +
885           toString(bufferOrErr.takeError()));
886   else
887     buffer = std::move(*bufferOrErr);
888 }
889 
890 void Writer::createHeader() {
891   raw_string_ostream os(header);
892   writeBytes(os, WasmMagic, sizeof(WasmMagic), "wasm magic");
893   writeU32(os, WasmVersion, "wasm version");
894   os.flush();
895   fileSize += header.size();
896 }
897 
898 void lld::wasm::writeResult() { Writer().run(); }
899