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