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