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