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 bool DylinkSection::isNeeded() const { 58 return config->isPic || 59 config->unresolvedSymbols == UnresolvedPolicy::ImportDynamic || 60 !symtab->sharedFiles.empty(); 61 } 62 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.getValueOr(defaultModule); 128 StringRef name = sym->importName.getValueOr(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 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 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 156 void TypeSection::writeBody() { 157 writeUleb128(bodyOutputStream, types.size(), "type count"); 158 for (const WasmSignature *sig : types) 159 writeSig(bodyOutputStream, *sig); 160 } 161 162 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 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 185 void ImportSection::addImport(Symbol *sym) { 186 assert(!isSealed); 187 StringRef module = sym->importModule.getValueOr(defaultModule); 188 StringRef name = sym->importName.getValueOr(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 230 void ImportSection::writeBody() { 231 raw_ostream &os = bodyOutputStream; 232 233 writeUleb128(os, getNumImports(), "import count"); 234 235 bool is64 = config->is64.getValueOr(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.getValueOr(sym->getName()); 258 import.Module = sym->importModule.getValueOr(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 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 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 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 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 344 void TableSection::assignIndexes() { 345 uint32_t tableNumber = out.importSec->getNumImportedTables(); 346 for (InputTable *t : inputTables) 347 t->assignIndex(tableNumber++); 348 } 349 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.getValueOr(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 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 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 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 396 static void ensureIndirectFunctionTable() { 397 if (!WasmSym::indirectFunctionTable) 398 WasmSym::indirectFunctionTable = 399 symtab->resolveIndirectFunctionTable(/*required =*/true); 400 } 401 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 416 void GlobalSection::generateRelocationCode(raw_ostream &os, bool TLS) const { 417 assert(!config->extendedConst); 418 bool is64 = config->is64.getValueOr(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 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.getValueOr(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 519 void GlobalSection::addGlobal(InputGlobal *global) { 520 assert(!isSealed); 521 if (!global->live) 522 return; 523 inputGlobals.push_back(global); 524 } 525 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 534 bool StartSection::isNeeded() const { 535 return WasmSym::startFunction != nullptr; 536 } 537 538 void StartSection::writeBody() { 539 raw_ostream &os = bodyOutputStream; 540 writeUleb128(os, WasmSym::startFunction->getFunctionIndex(), 541 "function index"); 542 } 543 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 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.getValueOr(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 writeUleb128(os, sym->getFunctionIndex(), "function index"); 593 ++tableIndex; 594 } 595 } 596 597 DataCountSection::DataCountSection(ArrayRef<OutputSegment *> segments) 598 : SyntheticSection(llvm::wasm::WASM_SEC_DATACOUNT), 599 numSegments(std::count_if(segments.begin(), segments.end(), 600 [](OutputSegment *const segment) { 601 return segment->requiredInBinary(); 602 })) {} 603 604 void DataCountSection::writeBody() { 605 writeUleb128(bodyOutputStream, numSegments, "data count"); 606 } 607 608 bool DataCountSection::isNeeded() const { 609 return numSegments && config->sharedMemory; 610 } 611 612 void LinkingSection::writeBody() { 613 raw_ostream &os = bodyOutputStream; 614 615 writeUleb128(os, WasmMetadataVersion, "Version"); 616 617 if (!symtabEntries.empty()) { 618 SubSection sub(WASM_SYMBOL_TABLE); 619 writeUleb128(sub.os, symtabEntries.size(), "num symbols"); 620 621 for (const Symbol *sym : symtabEntries) { 622 assert(sym->isDefined() || sym->isUndefined()); 623 WasmSymbolType kind = sym->getWasmType(); 624 uint32_t flags = sym->flags; 625 626 writeU8(sub.os, kind, "sym kind"); 627 writeUleb128(sub.os, flags, "sym flags"); 628 629 if (auto *f = dyn_cast<FunctionSymbol>(sym)) { 630 if (auto *d = dyn_cast<DefinedFunction>(sym)) { 631 writeUleb128(sub.os, d->getExportedFunctionIndex(), "index"); 632 } else { 633 writeUleb128(sub.os, f->getFunctionIndex(), "index"); 634 } 635 if (sym->isDefined() || (flags & WASM_SYMBOL_EXPLICIT_NAME) != 0) 636 writeStr(sub.os, sym->getName(), "sym name"); 637 } else if (auto *g = dyn_cast<GlobalSymbol>(sym)) { 638 writeUleb128(sub.os, g->getGlobalIndex(), "index"); 639 if (sym->isDefined() || (flags & WASM_SYMBOL_EXPLICIT_NAME) != 0) 640 writeStr(sub.os, sym->getName(), "sym name"); 641 } else if (auto *t = dyn_cast<TagSymbol>(sym)) { 642 writeUleb128(sub.os, t->getTagIndex(), "index"); 643 if (sym->isDefined() || (flags & WASM_SYMBOL_EXPLICIT_NAME) != 0) 644 writeStr(sub.os, sym->getName(), "sym name"); 645 } else if (auto *t = dyn_cast<TableSymbol>(sym)) { 646 writeUleb128(sub.os, t->getTableNumber(), "table number"); 647 if (sym->isDefined() || (flags & WASM_SYMBOL_EXPLICIT_NAME) != 0) 648 writeStr(sub.os, sym->getName(), "sym name"); 649 } else if (isa<DataSymbol>(sym)) { 650 writeStr(sub.os, sym->getName(), "sym name"); 651 if (auto *dataSym = dyn_cast<DefinedData>(sym)) { 652 writeUleb128(sub.os, dataSym->getOutputSegmentIndex(), "index"); 653 writeUleb128(sub.os, dataSym->getOutputSegmentOffset(), 654 "data offset"); 655 writeUleb128(sub.os, dataSym->getSize(), "data size"); 656 } 657 } else { 658 auto *s = cast<OutputSectionSymbol>(sym); 659 writeUleb128(sub.os, s->section->sectionIndex, "sym section index"); 660 } 661 } 662 663 sub.writeTo(os); 664 } 665 666 if (dataSegments.size()) { 667 SubSection sub(WASM_SEGMENT_INFO); 668 writeUleb128(sub.os, dataSegments.size(), "num data segments"); 669 for (const OutputSegment *s : dataSegments) { 670 writeStr(sub.os, s->name, "segment name"); 671 writeUleb128(sub.os, s->alignment, "alignment"); 672 writeUleb128(sub.os, s->linkingFlags, "flags"); 673 } 674 sub.writeTo(os); 675 } 676 677 if (!initFunctions.empty()) { 678 SubSection sub(WASM_INIT_FUNCS); 679 writeUleb128(sub.os, initFunctions.size(), "num init functions"); 680 for (const WasmInitEntry &f : initFunctions) { 681 writeUleb128(sub.os, f.priority, "priority"); 682 writeUleb128(sub.os, f.sym->getOutputSymbolIndex(), "function index"); 683 } 684 sub.writeTo(os); 685 } 686 687 struct ComdatEntry { 688 unsigned kind; 689 uint32_t index; 690 }; 691 std::map<StringRef, std::vector<ComdatEntry>> comdats; 692 693 for (const InputFunction *f : out.functionSec->inputFunctions) { 694 StringRef comdat = f->getComdatName(); 695 if (!comdat.empty()) 696 comdats[comdat].emplace_back( 697 ComdatEntry{WASM_COMDAT_FUNCTION, f->getFunctionIndex()}); 698 } 699 for (uint32_t i = 0; i < dataSegments.size(); ++i) { 700 const auto &inputSegments = dataSegments[i]->inputSegments; 701 if (inputSegments.empty()) 702 continue; 703 StringRef comdat = inputSegments[0]->getComdatName(); 704 #ifndef NDEBUG 705 for (const InputChunk *isec : inputSegments) 706 assert(isec->getComdatName() == comdat); 707 #endif 708 if (!comdat.empty()) 709 comdats[comdat].emplace_back(ComdatEntry{WASM_COMDAT_DATA, i}); 710 } 711 712 if (!comdats.empty()) { 713 SubSection sub(WASM_COMDAT_INFO); 714 writeUleb128(sub.os, comdats.size(), "num comdats"); 715 for (const auto &c : comdats) { 716 writeStr(sub.os, c.first, "comdat name"); 717 writeUleb128(sub.os, 0, "comdat flags"); // flags for future use 718 writeUleb128(sub.os, c.second.size(), "num entries"); 719 for (const ComdatEntry &entry : c.second) { 720 writeU8(sub.os, entry.kind, "entry kind"); 721 writeUleb128(sub.os, entry.index, "entry index"); 722 } 723 } 724 sub.writeTo(os); 725 } 726 } 727 728 void LinkingSection::addToSymtab(Symbol *sym) { 729 sym->setOutputSymbolIndex(symtabEntries.size()); 730 symtabEntries.emplace_back(sym); 731 } 732 733 unsigned NameSection::numNamedFunctions() const { 734 unsigned numNames = out.importSec->getNumImportedFunctions(); 735 736 for (const InputFunction *f : out.functionSec->inputFunctions) 737 if (!f->getName().empty() || !f->getDebugName().empty()) 738 ++numNames; 739 740 return numNames; 741 } 742 743 unsigned NameSection::numNamedGlobals() const { 744 unsigned numNames = out.importSec->getNumImportedGlobals(); 745 746 for (const InputGlobal *g : out.globalSec->inputGlobals) 747 if (!g->getName().empty()) 748 ++numNames; 749 750 numNames += out.globalSec->internalGotSymbols.size(); 751 return numNames; 752 } 753 754 unsigned NameSection::numNamedDataSegments() const { 755 unsigned numNames = 0; 756 757 for (const OutputSegment *s : segments) 758 if (!s->name.empty() && s->requiredInBinary()) 759 ++numNames; 760 761 return numNames; 762 } 763 764 // Create the custom "name" section containing debug symbol names. 765 void NameSection::writeBody() { 766 unsigned count = numNamedFunctions(); 767 if (count) { 768 SubSection sub(WASM_NAMES_FUNCTION); 769 writeUleb128(sub.os, count, "name count"); 770 771 // Function names appear in function index order. As it happens 772 // importedSymbols and inputFunctions are numbered in order with imported 773 // functions coming first. 774 for (const Symbol *s : out.importSec->importedSymbols) { 775 if (auto *f = dyn_cast<FunctionSymbol>(s)) { 776 writeUleb128(sub.os, f->getFunctionIndex(), "func index"); 777 writeStr(sub.os, toString(*s), "symbol name"); 778 } 779 } 780 for (const InputFunction *f : out.functionSec->inputFunctions) { 781 if (!f->getName().empty()) { 782 writeUleb128(sub.os, f->getFunctionIndex(), "func index"); 783 if (!f->getDebugName().empty()) { 784 writeStr(sub.os, f->getDebugName(), "symbol name"); 785 } else { 786 writeStr(sub.os, maybeDemangleSymbol(f->getName()), "symbol name"); 787 } 788 } 789 } 790 sub.writeTo(bodyOutputStream); 791 } 792 793 count = numNamedGlobals(); 794 if (count) { 795 SubSection sub(WASM_NAMES_GLOBAL); 796 writeUleb128(sub.os, count, "name count"); 797 798 for (const Symbol *s : out.importSec->importedSymbols) { 799 if (auto *g = dyn_cast<GlobalSymbol>(s)) { 800 writeUleb128(sub.os, g->getGlobalIndex(), "global index"); 801 writeStr(sub.os, toString(*s), "symbol name"); 802 } 803 } 804 for (const Symbol *s : out.importSec->gotSymbols) { 805 writeUleb128(sub.os, s->getGOTIndex(), "global index"); 806 writeStr(sub.os, toString(*s), "symbol name"); 807 } 808 for (const InputGlobal *g : out.globalSec->inputGlobals) { 809 if (!g->getName().empty()) { 810 writeUleb128(sub.os, g->getAssignedIndex(), "global index"); 811 writeStr(sub.os, maybeDemangleSymbol(g->getName()), "symbol name"); 812 } 813 } 814 for (Symbol *s : out.globalSec->internalGotSymbols) { 815 writeUleb128(sub.os, s->getGOTIndex(), "global index"); 816 if (isa<FunctionSymbol>(s)) 817 writeStr(sub.os, "GOT.func.internal." + toString(*s), "symbol name"); 818 else 819 writeStr(sub.os, "GOT.data.internal." + toString(*s), "symbol name"); 820 } 821 822 sub.writeTo(bodyOutputStream); 823 } 824 825 count = numNamedDataSegments(); 826 if (count) { 827 SubSection sub(WASM_NAMES_DATA_SEGMENT); 828 writeUleb128(sub.os, count, "name count"); 829 830 for (OutputSegment *s : segments) { 831 if (!s->name.empty() && s->requiredInBinary()) { 832 writeUleb128(sub.os, s->index, "global index"); 833 writeStr(sub.os, s->name, "segment name"); 834 } 835 } 836 837 sub.writeTo(bodyOutputStream); 838 } 839 } 840 841 void ProducersSection::addInfo(const WasmProducerInfo &info) { 842 for (auto &producers : 843 {std::make_pair(&info.Languages, &languages), 844 std::make_pair(&info.Tools, &tools), std::make_pair(&info.SDKs, &sDKs)}) 845 for (auto &producer : *producers.first) 846 if (producers.second->end() == 847 llvm::find_if(*producers.second, 848 [&](std::pair<std::string, std::string> seen) { 849 return seen.first == producer.first; 850 })) 851 producers.second->push_back(producer); 852 } 853 854 void ProducersSection::writeBody() { 855 auto &os = bodyOutputStream; 856 writeUleb128(os, fieldCount(), "field count"); 857 for (auto &field : 858 {std::make_pair("language", languages), 859 std::make_pair("processed-by", tools), std::make_pair("sdk", sDKs)}) { 860 if (field.second.empty()) 861 continue; 862 writeStr(os, field.first, "field name"); 863 writeUleb128(os, field.second.size(), "number of entries"); 864 for (auto &entry : field.second) { 865 writeStr(os, entry.first, "producer name"); 866 writeStr(os, entry.second, "producer version"); 867 } 868 } 869 } 870 871 void TargetFeaturesSection::writeBody() { 872 SmallVector<std::string, 8> emitted(features.begin(), features.end()); 873 llvm::sort(emitted); 874 auto &os = bodyOutputStream; 875 writeUleb128(os, emitted.size(), "feature count"); 876 for (auto &feature : emitted) { 877 writeU8(os, WASM_FEATURE_PREFIX_USED, "feature used prefix"); 878 writeStr(os, feature, "feature name"); 879 } 880 } 881 882 void RelocSection::writeBody() { 883 uint32_t count = sec->getNumRelocations(); 884 assert(sec->sectionIndex != UINT32_MAX); 885 writeUleb128(bodyOutputStream, sec->sectionIndex, "reloc section"); 886 writeUleb128(bodyOutputStream, count, "reloc count"); 887 sec->writeRelocations(bodyOutputStream); 888 } 889 890 } // namespace wasm 891 } // namespace lld 892