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