xref: /llvm-project/lld/wasm/SyntheticSections.cpp (revision 9fdc38c81c7d1b61cb0750e5f5b273d6d1877513)
1 //===- SyntheticSections.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 // This file contains linker-synthesized sections.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "SyntheticSections.h"
14 
15 #include "InputChunks.h"
16 #include "InputElement.h"
17 #include "OutputSegment.h"
18 #include "SymbolTable.h"
19 #include "llvm/Support/Path.h"
20 #include <optional>
21 
22 using namespace llvm;
23 using namespace llvm::wasm;
24 
25 namespace lld::wasm {
26 
27 OutStruct out;
28 
29 namespace {
30 
31 // Some synthetic sections (e.g. "name" and "linking") have subsections.
32 // Just like the synthetic sections themselves these need to be created before
33 // they can be written out (since they are preceded by their length). This
34 // class is used to create subsections and then write them into the stream
35 // of the parent section.
36 class SubSection {
37 public:
38   explicit SubSection(uint32_t type) : type(type) {}
39 
40   void writeTo(raw_ostream &to) {
41     writeUleb128(to, type, "subsection type");
42     writeUleb128(to, body.size(), "subsection size");
43     to.write(body.data(), body.size());
44   }
45 
46 private:
47   uint32_t type;
48   std::string body;
49 
50 public:
51   raw_string_ostream os{body};
52 };
53 
54 } // namespace
55 
56 bool DylinkSection::isNeeded() const {
57   return ctx.isPic ||
58          ctx.arg.unresolvedSymbols == UnresolvedPolicy::ImportDynamic ||
59          !ctx.sharedFiles.empty();
60 }
61 
62 void DylinkSection::writeBody() {
63   raw_ostream &os = bodyOutputStream;
64 
65   {
66     SubSection sub(WASM_DYLINK_MEM_INFO);
67     writeUleb128(sub.os, memSize, "MemSize");
68     writeUleb128(sub.os, memAlign, "MemAlign");
69     writeUleb128(sub.os, out.elemSec->numEntries(), "TableSize");
70     writeUleb128(sub.os, 0, "TableAlign");
71     sub.writeTo(os);
72   }
73 
74   if (ctx.sharedFiles.size()) {
75     SubSection sub(WASM_DYLINK_NEEDED);
76     writeUleb128(sub.os, ctx.sharedFiles.size(), "Needed");
77     for (auto *so : ctx.sharedFiles)
78       writeStr(sub.os, llvm::sys::path::filename(so->getName()), "so name");
79     sub.writeTo(os);
80   }
81 
82   // Under certain circumstances we need to include extra information about our
83   // exports and/or imports to the dynamic linker.
84   // For exports we need to notify the linker when an export is TLS since the
85   // exported value is relative to __tls_base rather than __memory_base.
86   // For imports we need to notify the dynamic linker when an import is weak
87   // so that knows not to report an error for such symbols.
88   std::vector<const Symbol *> importInfo;
89   std::vector<const Symbol *> exportInfo;
90   for (const Symbol *sym : symtab->symbols()) {
91     if (sym->isLive()) {
92       if (sym->isExported() && sym->isTLS() && isa<DefinedData>(sym)) {
93         exportInfo.push_back(sym);
94       }
95       if (sym->isUndefWeak()) {
96         importInfo.push_back(sym);
97       }
98     }
99   }
100 
101   if (!exportInfo.empty()) {
102     SubSection sub(WASM_DYLINK_EXPORT_INFO);
103     writeUleb128(sub.os, exportInfo.size(), "num exports");
104 
105     for (const Symbol *sym : exportInfo) {
106       LLVM_DEBUG(llvm::dbgs() << "export info: " << toString(*sym) << "\n");
107       StringRef name = sym->getName();
108       if (auto *f = dyn_cast<DefinedFunction>(sym)) {
109         if (std::optional<StringRef> exportName =
110                 f->function->getExportName()) {
111           name = *exportName;
112         }
113       }
114       writeStr(sub.os, name, "sym name");
115       writeUleb128(sub.os, sym->flags, "sym flags");
116     }
117 
118     sub.writeTo(os);
119   }
120 
121   if (!importInfo.empty()) {
122     SubSection sub(WASM_DYLINK_IMPORT_INFO);
123     writeUleb128(sub.os, importInfo.size(), "num imports");
124 
125     for (const Symbol *sym : importInfo) {
126       LLVM_DEBUG(llvm::dbgs() << "imports info: " << toString(*sym) << "\n");
127       StringRef module = sym->importModule.value_or(defaultModule);
128       StringRef name = sym->importName.value_or(sym->getName());
129       writeStr(sub.os, module, "import module");
130       writeStr(sub.os, name, "import name");
131       writeUleb128(sub.os, sym->flags, "sym flags");
132     }
133 
134     sub.writeTo(os);
135   }
136 }
137 
138 uint32_t TypeSection::registerType(const WasmSignature &sig) {
139   auto pair = typeIndices.insert(std::make_pair(sig, types.size()));
140   if (pair.second) {
141     LLVM_DEBUG(llvm::dbgs() << "registerType " << toString(sig) << "\n");
142     types.push_back(&sig);
143   }
144   return pair.first->second;
145 }
146 
147 uint32_t TypeSection::lookupType(const WasmSignature &sig) {
148   auto it = typeIndices.find(sig);
149   if (it == typeIndices.end()) {
150     error("type not found: " + toString(sig));
151     return 0;
152   }
153   return it->second;
154 }
155 
156 void TypeSection::writeBody() {
157   writeUleb128(bodyOutputStream, types.size(), "type count");
158   for (const WasmSignature *sig : types)
159     writeSig(bodyOutputStream, *sig);
160 }
161 
162 uint32_t ImportSection::getNumImports() const {
163   assert(isSealed);
164   uint32_t numImports = importedSymbols.size() + gotSymbols.size();
165   if (ctx.arg.memoryImport.has_value())
166     ++numImports;
167   return numImports;
168 }
169 
170 void ImportSection::addGOTEntry(Symbol *sym) {
171   assert(!isSealed);
172   if (sym->hasGOTIndex())
173     return;
174   LLVM_DEBUG(dbgs() << "addGOTEntry: " << toString(*sym) << "\n");
175   sym->setGOTIndex(numImportedGlobals++);
176   if (ctx.isPic) {
177     // Any symbol that is assigned an normal GOT entry must be exported
178     // otherwise the dynamic linker won't be able create the entry that contains
179     // it.
180     sym->forceExport = true;
181   }
182   gotSymbols.push_back(sym);
183 }
184 
185 void ImportSection::addImport(Symbol *sym) {
186   assert(!isSealed);
187   StringRef module = sym->importModule.value_or(defaultModule);
188   StringRef name = sym->importName.value_or(sym->getName());
189   if (auto *f = dyn_cast<FunctionSymbol>(sym)) {
190     ImportKey<WasmSignature> key(*(f->getSignature()), module, name);
191     auto entry = importedFunctions.try_emplace(key, numImportedFunctions);
192     if (entry.second) {
193       importedSymbols.emplace_back(sym);
194       f->setFunctionIndex(numImportedFunctions++);
195     } else {
196       f->setFunctionIndex(entry.first->second);
197     }
198   } else if (auto *g = dyn_cast<GlobalSymbol>(sym)) {
199     ImportKey<WasmGlobalType> key(*(g->getGlobalType()), module, name);
200     auto entry = importedGlobals.try_emplace(key, numImportedGlobals);
201     if (entry.second) {
202       importedSymbols.emplace_back(sym);
203       g->setGlobalIndex(numImportedGlobals++);
204     } else {
205       g->setGlobalIndex(entry.first->second);
206     }
207   } else if (auto *t = dyn_cast<TagSymbol>(sym)) {
208     ImportKey<WasmSignature> key(*(t->getSignature()), module, name);
209     auto entry = importedTags.try_emplace(key, numImportedTags);
210     if (entry.second) {
211       importedSymbols.emplace_back(sym);
212       t->setTagIndex(numImportedTags++);
213     } else {
214       t->setTagIndex(entry.first->second);
215     }
216   } else {
217     assert(TableSymbol::classof(sym));
218     auto *table = cast<TableSymbol>(sym);
219     ImportKey<WasmTableType> key(*(table->getTableType()), module, name);
220     auto entry = importedTables.try_emplace(key, numImportedTables);
221     if (entry.second) {
222       importedSymbols.emplace_back(sym);
223       table->setTableNumber(numImportedTables++);
224     } else {
225       table->setTableNumber(entry.first->second);
226     }
227   }
228 }
229 
230 void ImportSection::writeBody() {
231   raw_ostream &os = bodyOutputStream;
232 
233   writeUleb128(os, getNumImports(), "import count");
234 
235   bool is64 = ctx.arg.is64.value_or(false);
236 
237   if (ctx.arg.memoryImport) {
238     WasmImport import;
239     import.Module = ctx.arg.memoryImport->first;
240     import.Field = ctx.arg.memoryImport->second;
241     import.Kind = WASM_EXTERNAL_MEMORY;
242     import.Memory.Flags = 0;
243     import.Memory.Minimum = out.memorySec->numMemoryPages;
244     if (out.memorySec->maxMemoryPages != 0 || ctx.arg.sharedMemory) {
245       import.Memory.Flags |= WASM_LIMITS_FLAG_HAS_MAX;
246       import.Memory.Maximum = out.memorySec->maxMemoryPages;
247     }
248     if (ctx.arg.sharedMemory)
249       import.Memory.Flags |= WASM_LIMITS_FLAG_IS_SHARED;
250     if (is64)
251       import.Memory.Flags |= WASM_LIMITS_FLAG_IS_64;
252     writeImport(os, import);
253   }
254 
255   for (const Symbol *sym : importedSymbols) {
256     WasmImport import;
257     import.Field = sym->importName.value_or(sym->getName());
258     import.Module = sym->importModule.value_or(defaultModule);
259 
260     if (auto *functionSym = dyn_cast<FunctionSymbol>(sym)) {
261       import.Kind = WASM_EXTERNAL_FUNCTION;
262       import.SigIndex = out.typeSec->lookupType(*functionSym->signature);
263     } else if (auto *globalSym = dyn_cast<GlobalSymbol>(sym)) {
264       import.Kind = WASM_EXTERNAL_GLOBAL;
265       import.Global = *globalSym->getGlobalType();
266     } else if (auto *tagSym = dyn_cast<TagSymbol>(sym)) {
267       import.Kind = WASM_EXTERNAL_TAG;
268       import.SigIndex = out.typeSec->lookupType(*tagSym->signature);
269     } else {
270       auto *tableSym = cast<TableSymbol>(sym);
271       import.Kind = WASM_EXTERNAL_TABLE;
272       import.Table = *tableSym->getTableType();
273     }
274     writeImport(os, import);
275   }
276 
277   for (const Symbol *sym : gotSymbols) {
278     WasmImport import;
279     import.Kind = WASM_EXTERNAL_GLOBAL;
280     auto ptrType = is64 ? WASM_TYPE_I64 : WASM_TYPE_I32;
281     import.Global = {static_cast<uint8_t>(ptrType), true};
282     if (isa<DataSymbol>(sym))
283       import.Module = "GOT.mem";
284     else
285       import.Module = "GOT.func";
286     import.Field = sym->getName();
287     writeImport(os, import);
288   }
289 }
290 
291 void FunctionSection::writeBody() {
292   raw_ostream &os = bodyOutputStream;
293 
294   writeUleb128(os, inputFunctions.size(), "function count");
295   for (const InputFunction *func : inputFunctions)
296     writeUleb128(os, out.typeSec->lookupType(func->signature), "sig index");
297 }
298 
299 void FunctionSection::addFunction(InputFunction *func) {
300   if (!func->live)
301     return;
302   uint32_t functionIndex =
303       out.importSec->getNumImportedFunctions() + inputFunctions.size();
304   inputFunctions.emplace_back(func);
305   func->setFunctionIndex(functionIndex);
306 }
307 
308 void TableSection::writeBody() {
309   raw_ostream &os = bodyOutputStream;
310 
311   writeUleb128(os, inputTables.size(), "table count");
312   for (const InputTable *table : inputTables)
313     writeTableType(os, table->getType());
314 }
315 
316 void TableSection::addTable(InputTable *table) {
317   if (!table->live)
318     return;
319   // Some inputs require that the indirect function table be assigned to table
320   // number 0.
321   if (ctx.legacyFunctionTable &&
322       isa<DefinedTable>(WasmSym::indirectFunctionTable) &&
323       cast<DefinedTable>(WasmSym::indirectFunctionTable)->table == table) {
324     if (out.importSec->getNumImportedTables()) {
325       // Alack!  Some other input imported a table, meaning that we are unable
326       // to assign table number 0 to the indirect function table.
327       for (const auto *culprit : out.importSec->importedSymbols) {
328         if (isa<UndefinedTable>(culprit)) {
329           error("object file not built with 'reference-types' or "
330                 "'call-indirect-overlong' feature conflicts with import of "
331                 "table " +
332                 culprit->getName() + " by file " +
333                 toString(culprit->getFile()));
334           return;
335         }
336       }
337       llvm_unreachable("failed to find conflicting table import");
338     }
339     inputTables.insert(inputTables.begin(), table);
340     return;
341   }
342   inputTables.push_back(table);
343 }
344 
345 void TableSection::assignIndexes() {
346   uint32_t tableNumber = out.importSec->getNumImportedTables();
347   for (InputTable *t : inputTables)
348     t->assignIndex(tableNumber++);
349 }
350 
351 void MemorySection::writeBody() {
352   raw_ostream &os = bodyOutputStream;
353 
354   bool hasMax = maxMemoryPages != 0 || ctx.arg.sharedMemory;
355   writeUleb128(os, 1, "memory count");
356   unsigned flags = 0;
357   if (hasMax)
358     flags |= WASM_LIMITS_FLAG_HAS_MAX;
359   if (ctx.arg.sharedMemory)
360     flags |= WASM_LIMITS_FLAG_IS_SHARED;
361   if (ctx.arg.is64.value_or(false))
362     flags |= WASM_LIMITS_FLAG_IS_64;
363   writeUleb128(os, flags, "memory limits flags");
364   writeUleb128(os, numMemoryPages, "initial pages");
365   if (hasMax)
366     writeUleb128(os, maxMemoryPages, "max pages");
367 }
368 
369 void TagSection::writeBody() {
370   raw_ostream &os = bodyOutputStream;
371 
372   writeUleb128(os, inputTags.size(), "tag count");
373   for (InputTag *t : inputTags) {
374     writeUleb128(os, 0, "tag attribute"); // Reserved "attribute" field
375     writeUleb128(os, out.typeSec->lookupType(t->signature), "sig index");
376   }
377 }
378 
379 void TagSection::addTag(InputTag *tag) {
380   if (!tag->live)
381     return;
382   uint32_t tagIndex = out.importSec->getNumImportedTags() + inputTags.size();
383   LLVM_DEBUG(dbgs() << "addTag: " << tagIndex << "\n");
384   tag->assignIndex(tagIndex);
385   inputTags.push_back(tag);
386 }
387 
388 void GlobalSection::assignIndexes() {
389   uint32_t globalIndex = out.importSec->getNumImportedGlobals();
390   for (InputGlobal *g : inputGlobals)
391     g->assignIndex(globalIndex++);
392   for (Symbol *sym : internalGotSymbols)
393     sym->setGOTIndex(globalIndex++);
394   isSealed = true;
395 }
396 
397 static void ensureIndirectFunctionTable() {
398   if (!WasmSym::indirectFunctionTable)
399     WasmSym::indirectFunctionTable =
400         symtab->resolveIndirectFunctionTable(/*required =*/true);
401 }
402 
403 void GlobalSection::addInternalGOTEntry(Symbol *sym) {
404   assert(!isSealed);
405   if (sym->requiresGOT)
406     return;
407   LLVM_DEBUG(dbgs() << "addInternalGOTEntry: " << sym->getName() << " "
408                     << toString(sym->kind()) << "\n");
409   sym->requiresGOT = true;
410   if (auto *F = dyn_cast<FunctionSymbol>(sym)) {
411     ensureIndirectFunctionTable();
412     out.elemSec->addEntry(F);
413   }
414   internalGotSymbols.push_back(sym);
415 }
416 
417 void GlobalSection::generateRelocationCode(raw_ostream &os, bool TLS) const {
418   assert(!ctx.arg.extendedConst);
419   bool is64 = ctx.arg.is64.value_or(false);
420   unsigned opcode_ptr_const = is64 ? WASM_OPCODE_I64_CONST
421                                    : WASM_OPCODE_I32_CONST;
422   unsigned opcode_ptr_add = is64 ? WASM_OPCODE_I64_ADD
423                                  : WASM_OPCODE_I32_ADD;
424 
425   for (const Symbol *sym : internalGotSymbols) {
426     if (TLS != sym->isTLS())
427       continue;
428 
429     if (auto *d = dyn_cast<DefinedData>(sym)) {
430       // Get __memory_base
431       writeU8(os, WASM_OPCODE_GLOBAL_GET, "GLOBAL_GET");
432       if (sym->isTLS())
433         writeUleb128(os, WasmSym::tlsBase->getGlobalIndex(), "__tls_base");
434       else
435         writeUleb128(os, WasmSym::memoryBase->getGlobalIndex(),
436                      "__memory_base");
437 
438       // Add the virtual address of the data symbol
439       writeU8(os, opcode_ptr_const, "CONST");
440       writeSleb128(os, d->getVA(), "offset");
441     } else if (auto *f = dyn_cast<FunctionSymbol>(sym)) {
442       if (f->isStub)
443         continue;
444       // Get __table_base
445       writeU8(os, WASM_OPCODE_GLOBAL_GET, "GLOBAL_GET");
446       writeUleb128(os, WasmSym::tableBase->getGlobalIndex(), "__table_base");
447 
448       // Add the table index to __table_base
449       writeU8(os, opcode_ptr_const, "CONST");
450       writeSleb128(os, f->getTableIndex(), "offset");
451     } else {
452       assert(isa<UndefinedData>(sym) || isa<SharedData>(sym));
453       continue;
454     }
455     writeU8(os, opcode_ptr_add, "ADD");
456     writeU8(os, WASM_OPCODE_GLOBAL_SET, "GLOBAL_SET");
457     writeUleb128(os, sym->getGOTIndex(), "got_entry");
458   }
459 }
460 
461 void GlobalSection::writeBody() {
462   raw_ostream &os = bodyOutputStream;
463 
464   writeUleb128(os, numGlobals(), "global count");
465   for (InputGlobal *g : inputGlobals) {
466     writeGlobalType(os, g->getType());
467     writeInitExpr(os, g->getInitExpr());
468   }
469   bool is64 = ctx.arg.is64.value_or(false);
470   uint8_t itype = is64 ? WASM_TYPE_I64 : WASM_TYPE_I32;
471   for (const Symbol *sym : internalGotSymbols) {
472     bool mutable_ = false;
473     if (!sym->isStub) {
474       // In the case of dynamic linking, unless we have 'extended-const'
475       // available, these global must to be mutable since they get updated to
476       // the correct runtime value during `__wasm_apply_global_relocs`.
477       if (!ctx.arg.extendedConst && ctx.isPic && !sym->isTLS())
478         mutable_ = true;
479       // With multi-theadeding any TLS globals must be mutable since they get
480       // set during `__wasm_apply_global_tls_relocs`
481       if (ctx.arg.sharedMemory && sym->isTLS())
482         mutable_ = true;
483     }
484     WasmGlobalType type{itype, mutable_};
485     writeGlobalType(os, type);
486 
487     bool useExtendedConst = false;
488     uint32_t globalIdx;
489     int64_t offset;
490     if (ctx.arg.extendedConst && ctx.isPic) {
491       if (auto *d = dyn_cast<DefinedData>(sym)) {
492         if (!sym->isTLS()) {
493           globalIdx = WasmSym::memoryBase->getGlobalIndex();
494           offset = d->getVA();
495           useExtendedConst = true;
496         }
497       } else if (auto *f = dyn_cast<FunctionSymbol>(sym)) {
498         if (!sym->isStub) {
499           globalIdx = WasmSym::tableBase->getGlobalIndex();
500           offset = f->getTableIndex();
501           useExtendedConst = true;
502         }
503       }
504     }
505     if (useExtendedConst) {
506       // We can use an extended init expression to add a constant
507       // offset of __memory_base/__table_base.
508       writeU8(os, WASM_OPCODE_GLOBAL_GET, "global get");
509       writeUleb128(os, globalIdx, "literal (global index)");
510       if (offset) {
511         writePtrConst(os, offset, is64, "offset");
512         writeU8(os, is64 ? WASM_OPCODE_I64_ADD : WASM_OPCODE_I32_ADD, "add");
513       }
514       writeU8(os, WASM_OPCODE_END, "opcode:end");
515     } else {
516       WasmInitExpr initExpr;
517       if (auto *d = dyn_cast<DefinedData>(sym))
518         // In the sharedMemory case TLS globals are set during
519         // `__wasm_apply_global_tls_relocs`, but in the non-shared case
520         // we know the absolute value at link time.
521         initExpr = intConst(d->getVA(/*absolute=*/!ctx.arg.sharedMemory), is64);
522       else if (auto *f = dyn_cast<FunctionSymbol>(sym))
523         initExpr = intConst(f->isStub ? 0 : f->getTableIndex(), is64);
524       else {
525         assert(isa<UndefinedData>(sym) || isa<SharedData>(sym));
526         initExpr = intConst(0, is64);
527       }
528       writeInitExpr(os, initExpr);
529     }
530   }
531   for (const DefinedData *sym : dataAddressGlobals) {
532     WasmGlobalType type{itype, false};
533     writeGlobalType(os, type);
534     writeInitExpr(os, intConst(sym->getVA(), is64));
535   }
536 }
537 
538 void GlobalSection::addGlobal(InputGlobal *global) {
539   assert(!isSealed);
540   if (!global->live)
541     return;
542   inputGlobals.push_back(global);
543 }
544 
545 void ExportSection::writeBody() {
546   raw_ostream &os = bodyOutputStream;
547 
548   writeUleb128(os, exports.size(), "export count");
549   for (const WasmExport &export_ : exports)
550     writeExport(os, export_);
551 }
552 
553 bool StartSection::isNeeded() const {
554   return WasmSym::startFunction != nullptr;
555 }
556 
557 void StartSection::writeBody() {
558   raw_ostream &os = bodyOutputStream;
559   writeUleb128(os, WasmSym::startFunction->getFunctionIndex(),
560                "function index");
561 }
562 
563 void ElemSection::addEntry(FunctionSymbol *sym) {
564   // Don't add stub functions to the wasm table.  The address of all stub
565   // functions should be zero and they should they don't appear in the table.
566   // They only exist so that the calls to missing functions can validate.
567   if (sym->hasTableIndex() || sym->isStub)
568     return;
569   sym->setTableIndex(ctx.arg.tableBase + indirectFunctions.size());
570   indirectFunctions.emplace_back(sym);
571 }
572 
573 void ElemSection::writeBody() {
574   raw_ostream &os = bodyOutputStream;
575 
576   assert(WasmSym::indirectFunctionTable);
577   writeUleb128(os, 1, "segment count");
578   uint32_t tableNumber = WasmSym::indirectFunctionTable->getTableNumber();
579   uint32_t flags = 0;
580   if (tableNumber)
581     flags |= WASM_ELEM_SEGMENT_HAS_TABLE_NUMBER;
582   writeUleb128(os, flags, "elem segment flags");
583   if (flags & WASM_ELEM_SEGMENT_HAS_TABLE_NUMBER)
584     writeUleb128(os, tableNumber, "table number");
585 
586   WasmInitExpr initExpr;
587   initExpr.Extended = false;
588   if (ctx.isPic) {
589     initExpr.Inst.Opcode = WASM_OPCODE_GLOBAL_GET;
590     initExpr.Inst.Value.Global = WasmSym::tableBase->getGlobalIndex();
591   } else {
592     bool is64 = ctx.arg.is64.value_or(false);
593     initExpr = intConst(ctx.arg.tableBase, is64);
594   }
595   writeInitExpr(os, initExpr);
596 
597   if (flags & WASM_ELEM_SEGMENT_MASK_HAS_ELEM_DESC) {
598     // We only write active function table initializers, for which the elem kind
599     // is specified to be written as 0x00 and interpreted to mean "funcref".
600     const uint8_t elemKind = 0;
601     writeU8(os, elemKind, "elem kind");
602   }
603 
604   writeUleb128(os, indirectFunctions.size(), "elem count");
605   uint32_t tableIndex = ctx.arg.tableBase;
606   for (const FunctionSymbol *sym : indirectFunctions) {
607     assert(sym->getTableIndex() == tableIndex);
608     (void) tableIndex;
609     writeUleb128(os, sym->getFunctionIndex(), "function index");
610     ++tableIndex;
611   }
612 }
613 
614 DataCountSection::DataCountSection(ArrayRef<OutputSegment *> segments)
615     : SyntheticSection(llvm::wasm::WASM_SEC_DATACOUNT),
616       numSegments(llvm::count_if(segments, [](OutputSegment *const segment) {
617         return segment->requiredInBinary();
618       })) {}
619 
620 void DataCountSection::writeBody() {
621   writeUleb128(bodyOutputStream, numSegments, "data count");
622 }
623 
624 bool DataCountSection::isNeeded() const {
625   return numSegments && ctx.arg.sharedMemory;
626 }
627 
628 void LinkingSection::writeBody() {
629   raw_ostream &os = bodyOutputStream;
630 
631   writeUleb128(os, WasmMetadataVersion, "Version");
632 
633   if (!symtabEntries.empty()) {
634     SubSection sub(WASM_SYMBOL_TABLE);
635     writeUleb128(sub.os, symtabEntries.size(), "num symbols");
636 
637     for (const Symbol *sym : symtabEntries) {
638       assert(sym->isDefined() || sym->isUndefined());
639       WasmSymbolType kind = sym->getWasmType();
640       uint32_t flags = sym->flags;
641 
642       writeU8(sub.os, kind, "sym kind");
643       writeUleb128(sub.os, flags, "sym flags");
644 
645       if (auto *f = dyn_cast<FunctionSymbol>(sym)) {
646         if (auto *d = dyn_cast<DefinedFunction>(sym)) {
647           writeUleb128(sub.os, d->getExportedFunctionIndex(), "index");
648         } else {
649           writeUleb128(sub.os, f->getFunctionIndex(), "index");
650         }
651         if (sym->isDefined() || (flags & WASM_SYMBOL_EXPLICIT_NAME) != 0)
652           writeStr(sub.os, sym->getName(), "sym name");
653       } else if (auto *g = dyn_cast<GlobalSymbol>(sym)) {
654         writeUleb128(sub.os, g->getGlobalIndex(), "index");
655         if (sym->isDefined() || (flags & WASM_SYMBOL_EXPLICIT_NAME) != 0)
656           writeStr(sub.os, sym->getName(), "sym name");
657       } else if (auto *t = dyn_cast<TagSymbol>(sym)) {
658         writeUleb128(sub.os, t->getTagIndex(), "index");
659         if (sym->isDefined() || (flags & WASM_SYMBOL_EXPLICIT_NAME) != 0)
660           writeStr(sub.os, sym->getName(), "sym name");
661       } else if (auto *t = dyn_cast<TableSymbol>(sym)) {
662         writeUleb128(sub.os, t->getTableNumber(), "table number");
663         if (sym->isDefined() || (flags & WASM_SYMBOL_EXPLICIT_NAME) != 0)
664           writeStr(sub.os, sym->getName(), "sym name");
665       } else if (isa<DataSymbol>(sym)) {
666         writeStr(sub.os, sym->getName(), "sym name");
667         if (auto *dataSym = dyn_cast<DefinedData>(sym)) {
668           if (dataSym->segment) {
669             writeUleb128(sub.os, dataSym->getOutputSegmentIndex(), "index");
670             writeUleb128(sub.os, dataSym->getOutputSegmentOffset(),
671                          "data offset");
672           } else {
673             writeUleb128(sub.os, 0, "index");
674             writeUleb128(sub.os, dataSym->getVA(), "data offset");
675           }
676           writeUleb128(sub.os, dataSym->getSize(), "data size");
677         }
678       } else {
679         auto *s = cast<OutputSectionSymbol>(sym);
680         writeUleb128(sub.os, s->section->sectionIndex, "sym section index");
681       }
682     }
683 
684     sub.writeTo(os);
685   }
686 
687   if (dataSegments.size()) {
688     SubSection sub(WASM_SEGMENT_INFO);
689     writeUleb128(sub.os, dataSegments.size(), "num data segments");
690     for (const OutputSegment *s : dataSegments) {
691       writeStr(sub.os, s->name, "segment name");
692       writeUleb128(sub.os, s->alignment, "alignment");
693       writeUleb128(sub.os, s->linkingFlags, "flags");
694     }
695     sub.writeTo(os);
696   }
697 
698   if (!initFunctions.empty()) {
699     SubSection sub(WASM_INIT_FUNCS);
700     writeUleb128(sub.os, initFunctions.size(), "num init functions");
701     for (const WasmInitEntry &f : initFunctions) {
702       writeUleb128(sub.os, f.priority, "priority");
703       writeUleb128(sub.os, f.sym->getOutputSymbolIndex(), "function index");
704     }
705     sub.writeTo(os);
706   }
707 
708   struct ComdatEntry {
709     unsigned kind;
710     uint32_t index;
711   };
712   std::map<StringRef, std::vector<ComdatEntry>> comdats;
713 
714   for (const InputFunction *f : out.functionSec->inputFunctions) {
715     StringRef comdat = f->getComdatName();
716     if (!comdat.empty())
717       comdats[comdat].emplace_back(
718           ComdatEntry{WASM_COMDAT_FUNCTION, f->getFunctionIndex()});
719   }
720   for (uint32_t i = 0; i < dataSegments.size(); ++i) {
721     const auto &inputSegments = dataSegments[i]->inputSegments;
722     if (inputSegments.empty())
723       continue;
724     StringRef comdat = inputSegments[0]->getComdatName();
725 #ifndef NDEBUG
726     for (const InputChunk *isec : inputSegments)
727       assert(isec->getComdatName() == comdat);
728 #endif
729     if (!comdat.empty())
730       comdats[comdat].emplace_back(ComdatEntry{WASM_COMDAT_DATA, i});
731   }
732 
733   if (!comdats.empty()) {
734     SubSection sub(WASM_COMDAT_INFO);
735     writeUleb128(sub.os, comdats.size(), "num comdats");
736     for (const auto &c : comdats) {
737       writeStr(sub.os, c.first, "comdat name");
738       writeUleb128(sub.os, 0, "comdat flags"); // flags for future use
739       writeUleb128(sub.os, c.second.size(), "num entries");
740       for (const ComdatEntry &entry : c.second) {
741         writeU8(sub.os, entry.kind, "entry kind");
742         writeUleb128(sub.os, entry.index, "entry index");
743       }
744     }
745     sub.writeTo(os);
746   }
747 }
748 
749 void LinkingSection::addToSymtab(Symbol *sym) {
750   sym->setOutputSymbolIndex(symtabEntries.size());
751   symtabEntries.emplace_back(sym);
752 }
753 
754 unsigned NameSection::numNamedFunctions() const {
755   unsigned numNames = out.importSec->getNumImportedFunctions();
756 
757   for (const InputFunction *f : out.functionSec->inputFunctions)
758     if (!f->name.empty() || !f->debugName.empty())
759       ++numNames;
760 
761   return numNames;
762 }
763 
764 unsigned NameSection::numNamedGlobals() const {
765   unsigned numNames = out.importSec->getNumImportedGlobals();
766 
767   for (const InputGlobal *g : out.globalSec->inputGlobals)
768     if (!g->getName().empty())
769       ++numNames;
770 
771   numNames += out.globalSec->internalGotSymbols.size();
772   return numNames;
773 }
774 
775 unsigned NameSection::numNamedDataSegments() const {
776   unsigned numNames = 0;
777 
778   for (const OutputSegment *s : segments)
779     if (!s->name.empty() && s->requiredInBinary())
780       ++numNames;
781 
782   return numNames;
783 }
784 
785 // Create the custom "name" section containing debug symbol names.
786 void NameSection::writeBody() {
787   {
788     SubSection sub(WASM_NAMES_MODULE);
789     StringRef moduleName = ctx.arg.soName;
790     if (ctx.arg.soName.empty())
791       moduleName = llvm::sys::path::filename(ctx.arg.outputFile);
792     writeStr(sub.os, moduleName, "module name");
793     sub.writeTo(bodyOutputStream);
794   }
795 
796   unsigned count = numNamedFunctions();
797   if (count) {
798     SubSection sub(WASM_NAMES_FUNCTION);
799     writeUleb128(sub.os, count, "name count");
800 
801     // Function names appear in function index order.  As it happens
802     // importedSymbols and inputFunctions are numbered in order with imported
803     // functions coming first.
804     for (const Symbol *s : out.importSec->importedSymbols) {
805       if (auto *f = dyn_cast<FunctionSymbol>(s)) {
806         writeUleb128(sub.os, f->getFunctionIndex(), "func index");
807         writeStr(sub.os, toString(*s), "symbol name");
808       }
809     }
810     for (const InputFunction *f : out.functionSec->inputFunctions) {
811       if (!f->name.empty()) {
812         writeUleb128(sub.os, f->getFunctionIndex(), "func index");
813         if (!f->debugName.empty()) {
814           writeStr(sub.os, f->debugName, "symbol name");
815         } else {
816           writeStr(sub.os, maybeDemangleSymbol(f->name), "symbol name");
817         }
818       }
819     }
820     sub.writeTo(bodyOutputStream);
821   }
822 
823   count = numNamedGlobals();
824   if (count) {
825     SubSection sub(WASM_NAMES_GLOBAL);
826     writeUleb128(sub.os, count, "name count");
827 
828     for (const Symbol *s : out.importSec->importedSymbols) {
829       if (auto *g = dyn_cast<GlobalSymbol>(s)) {
830         writeUleb128(sub.os, g->getGlobalIndex(), "global index");
831         writeStr(sub.os, toString(*s), "symbol name");
832       }
833     }
834     for (const Symbol *s : out.importSec->gotSymbols) {
835       writeUleb128(sub.os, s->getGOTIndex(), "global index");
836       writeStr(sub.os, toString(*s), "symbol name");
837     }
838     for (const InputGlobal *g : out.globalSec->inputGlobals) {
839       if (!g->getName().empty()) {
840         writeUleb128(sub.os, g->getAssignedIndex(), "global index");
841         writeStr(sub.os, maybeDemangleSymbol(g->getName()), "symbol name");
842       }
843     }
844     for (Symbol *s : out.globalSec->internalGotSymbols) {
845       writeUleb128(sub.os, s->getGOTIndex(), "global index");
846       if (isa<FunctionSymbol>(s))
847         writeStr(sub.os, "GOT.func.internal." + toString(*s), "symbol name");
848       else
849         writeStr(sub.os, "GOT.data.internal." + toString(*s), "symbol name");
850     }
851 
852     sub.writeTo(bodyOutputStream);
853   }
854 
855   count = numNamedDataSegments();
856   if (count) {
857     SubSection sub(WASM_NAMES_DATA_SEGMENT);
858     writeUleb128(sub.os, count, "name count");
859 
860     for (OutputSegment *s : segments) {
861       if (!s->name.empty() && s->requiredInBinary()) {
862         writeUleb128(sub.os, s->index, "global index");
863         writeStr(sub.os, s->name, "segment name");
864       }
865     }
866 
867     sub.writeTo(bodyOutputStream);
868   }
869 }
870 
871 void ProducersSection::addInfo(const WasmProducerInfo &info) {
872   for (auto &producers :
873        {std::make_pair(&info.Languages, &languages),
874         std::make_pair(&info.Tools, &tools), std::make_pair(&info.SDKs, &sDKs)})
875     for (auto &producer : *producers.first)
876       if (llvm::none_of(*producers.second,
877                         [&](std::pair<std::string, std::string> seen) {
878                           return seen.first == producer.first;
879                         }))
880         producers.second->push_back(producer);
881 }
882 
883 void ProducersSection::writeBody() {
884   auto &os = bodyOutputStream;
885   writeUleb128(os, fieldCount(), "field count");
886   for (auto &field :
887        {std::make_pair("language", languages),
888         std::make_pair("processed-by", tools), std::make_pair("sdk", sDKs)}) {
889     if (field.second.empty())
890       continue;
891     writeStr(os, field.first, "field name");
892     writeUleb128(os, field.second.size(), "number of entries");
893     for (auto &entry : field.second) {
894       writeStr(os, entry.first, "producer name");
895       writeStr(os, entry.second, "producer version");
896     }
897   }
898 }
899 
900 void TargetFeaturesSection::writeBody() {
901   SmallVector<std::string, 8> emitted(features.begin(), features.end());
902   llvm::sort(emitted);
903   auto &os = bodyOutputStream;
904   writeUleb128(os, emitted.size(), "feature count");
905   for (auto &feature : emitted) {
906     writeU8(os, WASM_FEATURE_PREFIX_USED, "feature used prefix");
907     writeStr(os, feature, "feature name");
908   }
909 }
910 
911 void RelocSection::writeBody() {
912   uint32_t count = sec->getNumRelocations();
913   assert(sec->sectionIndex != UINT32_MAX);
914   writeUleb128(bodyOutputStream, sec->sectionIndex, "reloc section");
915   writeUleb128(bodyOutputStream, count, "reloc count");
916   sec->writeRelocations(bodyOutputStream);
917 }
918 
919 static size_t getHashSize() {
920   switch (ctx.arg.buildId) {
921   case BuildIdKind::Fast:
922   case BuildIdKind::Uuid:
923     return 16;
924   case BuildIdKind::Sha1:
925     return 20;
926   case BuildIdKind::Hexstring:
927     return ctx.arg.buildIdVector.size();
928   case BuildIdKind::None:
929     return 0;
930   }
931   llvm_unreachable("build id kind not implemented");
932 }
933 
934 BuildIdSection::BuildIdSection()
935     : SyntheticSection(llvm::wasm::WASM_SEC_CUSTOM, buildIdSectionName),
936       hashSize(getHashSize()) {}
937 
938 void BuildIdSection::writeBody() {
939   LLVM_DEBUG(llvm::dbgs() << "BuildId writebody\n");
940   // Write hash size
941   auto &os = bodyOutputStream;
942   writeUleb128(os, hashSize, "build id size");
943   writeBytes(os, std::vector<char>(hashSize, ' ').data(), hashSize,
944              "placeholder");
945 }
946 
947 void BuildIdSection::writeBuildId(llvm::ArrayRef<uint8_t> buf) {
948   assert(buf.size() == hashSize);
949   LLVM_DEBUG(dbgs() << "buildid write " << buf.size() << " "
950                     << hashPlaceholderPtr << '\n');
951   memcpy(hashPlaceholderPtr, buf.data(), hashSize);
952 }
953 
954 } // namespace wasm::lld
955