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