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