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 "InputEvent.h" 17 #include "InputGlobal.h" 18 #include "OutputSegment.h" 19 #include "SymbolTable.h" 20 #include "llvm/Support/Path.h" 21 22 using namespace llvm; 23 using namespace llvm::wasm; 24 25 using namespace lld; 26 using namespace lld::wasm; 27 28 OutStruct lld::wasm::out; 29 30 namespace { 31 32 // Some synthetic sections (e.g. "name" and "linking") have subsections. 33 // Just like the synthetic sections themselves these need to be created before 34 // they can be written out (since they are preceded by their length). This 35 // class is used to create subsections and then write them into the stream 36 // of the parent section. 37 class SubSection { 38 public: 39 explicit SubSection(uint32_t type) : type(type) {} 40 41 void writeTo(raw_ostream &to) { 42 os.flush(); 43 writeUleb128(to, type, "subsection type"); 44 writeUleb128(to, body.size(), "subsection size"); 45 to.write(body.data(), body.size()); 46 } 47 48 private: 49 uint32_t type; 50 std::string body; 51 52 public: 53 raw_string_ostream os{body}; 54 }; 55 56 } // namespace 57 58 void DylinkSection::writeBody() { 59 raw_ostream &os = bodyOutputStream; 60 61 writeUleb128(os, memSize, "MemSize"); 62 writeUleb128(os, memAlign, "MemAlign"); 63 writeUleb128(os, out.elemSec->numEntries(), "TableSize"); 64 writeUleb128(os, 0, "TableAlign"); 65 writeUleb128(os, symtab->sharedFiles.size(), "Needed"); 66 for (auto *so : symtab->sharedFiles) 67 writeStr(os, llvm::sys::path::filename(so->getName()), "so name"); 68 } 69 70 uint32_t TypeSection::registerType(const WasmSignature &sig) { 71 auto pair = typeIndices.insert(std::make_pair(sig, types.size())); 72 if (pair.second) { 73 LLVM_DEBUG(llvm::dbgs() << "type " << toString(sig) << "\n"); 74 types.push_back(&sig); 75 } 76 return pair.first->second; 77 } 78 79 uint32_t TypeSection::lookupType(const WasmSignature &sig) { 80 auto it = typeIndices.find(sig); 81 if (it == typeIndices.end()) { 82 error("type not found: " + toString(sig)); 83 return 0; 84 } 85 return it->second; 86 } 87 88 void TypeSection::writeBody() { 89 writeUleb128(bodyOutputStream, types.size(), "type count"); 90 for (const WasmSignature *sig : types) 91 writeSig(bodyOutputStream, *sig); 92 } 93 94 uint32_t ImportSection::getNumImports() const { 95 assert(isSealed); 96 uint32_t numImports = importedSymbols.size() + gotSymbols.size(); 97 if (config->importMemory) 98 ++numImports; 99 if (config->importTable) 100 ++numImports; 101 return numImports; 102 } 103 104 void ImportSection::addGOTEntry(Symbol *sym) { 105 assert(!isSealed); 106 if (sym->hasGOTIndex()) 107 return; 108 sym->setGOTIndex(numImportedGlobals++); 109 gotSymbols.push_back(sym); 110 } 111 112 void ImportSection::addImport(Symbol *sym) { 113 assert(!isSealed); 114 importedSymbols.emplace_back(sym); 115 if (auto *f = dyn_cast<FunctionSymbol>(sym)) 116 f->setFunctionIndex(numImportedFunctions++); 117 else if (auto *g = dyn_cast<GlobalSymbol>(sym)) 118 g->setGlobalIndex(numImportedGlobals++); 119 else 120 cast<EventSymbol>(sym)->setEventIndex(numImportedEvents++); 121 } 122 123 void ImportSection::writeBody() { 124 raw_ostream &os = bodyOutputStream; 125 126 writeUleb128(os, getNumImports(), "import count"); 127 128 if (config->importMemory) { 129 WasmImport import; 130 import.Module = defaultModule; 131 import.Field = "memory"; 132 import.Kind = WASM_EXTERNAL_MEMORY; 133 import.Memory.Flags = 0; 134 import.Memory.Initial = out.memorySec->numMemoryPages; 135 if (out.memorySec->maxMemoryPages != 0 || config->sharedMemory) { 136 import.Memory.Flags |= WASM_LIMITS_FLAG_HAS_MAX; 137 import.Memory.Maximum = out.memorySec->maxMemoryPages; 138 } 139 if (config->sharedMemory) 140 import.Memory.Flags |= WASM_LIMITS_FLAG_IS_SHARED; 141 writeImport(os, import); 142 } 143 144 if (config->importTable) { 145 uint32_t tableSize = out.elemSec->elemOffset + out.elemSec->numEntries(); 146 WasmImport import; 147 import.Module = defaultModule; 148 import.Field = functionTableName; 149 import.Kind = WASM_EXTERNAL_TABLE; 150 import.Table.ElemType = WASM_TYPE_FUNCREF; 151 import.Table.Limits = {0, tableSize, 0}; 152 writeImport(os, import); 153 } 154 155 for (const Symbol *sym : importedSymbols) { 156 WasmImport import; 157 if (auto *f = dyn_cast<UndefinedFunction>(sym)) { 158 import.Field = f->importName; 159 import.Module = f->importModule; 160 } else if (auto *g = dyn_cast<UndefinedGlobal>(sym)) { 161 import.Field = g->importName; 162 import.Module = g->importModule; 163 } else { 164 import.Field = sym->getName(); 165 import.Module = defaultModule; 166 } 167 168 if (auto *functionSym = dyn_cast<FunctionSymbol>(sym)) { 169 import.Kind = WASM_EXTERNAL_FUNCTION; 170 import.SigIndex = out.typeSec->lookupType(*functionSym->signature); 171 } else if (auto *globalSym = dyn_cast<GlobalSymbol>(sym)) { 172 import.Kind = WASM_EXTERNAL_GLOBAL; 173 import.Global = *globalSym->getGlobalType(); 174 } else { 175 auto *eventSym = cast<EventSymbol>(sym); 176 import.Kind = WASM_EXTERNAL_EVENT; 177 import.Event.Attribute = eventSym->getEventType()->Attribute; 178 import.Event.SigIndex = out.typeSec->lookupType(*eventSym->signature); 179 } 180 writeImport(os, import); 181 } 182 183 for (const Symbol *sym : gotSymbols) { 184 WasmImport import; 185 import.Kind = WASM_EXTERNAL_GLOBAL; 186 import.Global = {WASM_TYPE_I32, true}; 187 if (isa<DataSymbol>(sym)) 188 import.Module = "GOT.mem"; 189 else 190 import.Module = "GOT.func"; 191 import.Field = sym->getName(); 192 writeImport(os, import); 193 } 194 } 195 196 void FunctionSection::writeBody() { 197 raw_ostream &os = bodyOutputStream; 198 199 writeUleb128(os, inputFunctions.size(), "function count"); 200 for (const InputFunction *func : inputFunctions) 201 writeUleb128(os, out.typeSec->lookupType(func->signature), "sig index"); 202 } 203 204 void FunctionSection::addFunction(InputFunction *func) { 205 if (!func->live) 206 return; 207 uint32_t functionIndex = 208 out.importSec->getNumImportedFunctions() + inputFunctions.size(); 209 inputFunctions.emplace_back(func); 210 func->setFunctionIndex(functionIndex); 211 } 212 213 void TableSection::writeBody() { 214 uint32_t tableSize = out.elemSec->elemOffset + out.elemSec->numEntries(); 215 216 raw_ostream &os = bodyOutputStream; 217 writeUleb128(os, 1, "table count"); 218 WasmLimits limits = {WASM_LIMITS_FLAG_HAS_MAX, tableSize, tableSize}; 219 writeTableType(os, WasmTable{WASM_TYPE_FUNCREF, limits}); 220 } 221 222 void MemorySection::writeBody() { 223 raw_ostream &os = bodyOutputStream; 224 225 bool hasMax = maxMemoryPages != 0 || config->sharedMemory; 226 writeUleb128(os, 1, "memory count"); 227 unsigned flags = 0; 228 if (hasMax) 229 flags |= WASM_LIMITS_FLAG_HAS_MAX; 230 if (config->sharedMemory) 231 flags |= WASM_LIMITS_FLAG_IS_SHARED; 232 writeUleb128(os, flags, "memory limits flags"); 233 writeUleb128(os, numMemoryPages, "initial pages"); 234 if (hasMax) 235 writeUleb128(os, maxMemoryPages, "max pages"); 236 } 237 238 void GlobalSection::writeBody() { 239 raw_ostream &os = bodyOutputStream; 240 241 writeUleb128(os, numGlobals(), "global count"); 242 for (const InputGlobal *g : inputGlobals) 243 writeGlobal(os, g->global); 244 for (const DefinedData *sym : definedFakeGlobals) { 245 WasmGlobal global; 246 global.Type = {WASM_TYPE_I32, false}; 247 global.InitExpr.Opcode = WASM_OPCODE_I32_CONST; 248 global.InitExpr.Value.Int32 = sym->getVirtualAddress(); 249 writeGlobal(os, global); 250 } 251 } 252 253 void GlobalSection::addGlobal(InputGlobal *global) { 254 if (!global->live) 255 return; 256 uint32_t globalIndex = 257 out.importSec->getNumImportedGlobals() + inputGlobals.size(); 258 LLVM_DEBUG(dbgs() << "addGlobal: " << globalIndex << "\n"); 259 global->setGlobalIndex(globalIndex); 260 out.globalSec->inputGlobals.push_back(global); 261 } 262 263 void EventSection::writeBody() { 264 raw_ostream &os = bodyOutputStream; 265 266 writeUleb128(os, inputEvents.size(), "event count"); 267 for (InputEvent *e : inputEvents) { 268 e->event.Type.SigIndex = out.typeSec->lookupType(e->signature); 269 writeEvent(os, e->event); 270 } 271 } 272 273 void EventSection::addEvent(InputEvent *event) { 274 if (!event->live) 275 return; 276 uint32_t eventIndex = 277 out.importSec->getNumImportedEvents() + inputEvents.size(); 278 LLVM_DEBUG(dbgs() << "addEvent: " << eventIndex << "\n"); 279 event->setEventIndex(eventIndex); 280 inputEvents.push_back(event); 281 } 282 283 void ExportSection::writeBody() { 284 raw_ostream &os = bodyOutputStream; 285 286 writeUleb128(os, exports.size(), "export count"); 287 for (const WasmExport &export_ : exports) 288 writeExport(os, export_); 289 } 290 291 void ElemSection::addEntry(FunctionSymbol *sym) { 292 if (sym->hasTableIndex()) 293 return; 294 sym->setTableIndex(elemOffset + indirectFunctions.size()); 295 indirectFunctions.emplace_back(sym); 296 } 297 298 void ElemSection::writeBody() { 299 raw_ostream &os = bodyOutputStream; 300 301 writeUleb128(os, 1, "segment count"); 302 writeUleb128(os, 0, "table index"); 303 WasmInitExpr initExpr; 304 if (config->isPic) { 305 initExpr.Opcode = WASM_OPCODE_GLOBAL_GET; 306 initExpr.Value.Global = WasmSym::tableBase->getGlobalIndex(); 307 } else { 308 initExpr.Opcode = WASM_OPCODE_I32_CONST; 309 initExpr.Value.Int32 = elemOffset; 310 } 311 writeInitExpr(os, initExpr); 312 writeUleb128(os, indirectFunctions.size(), "elem count"); 313 314 uint32_t tableIndex = elemOffset; 315 for (const FunctionSymbol *sym : indirectFunctions) { 316 assert(sym->getTableIndex() == tableIndex); 317 writeUleb128(os, sym->getFunctionIndex(), "function index"); 318 ++tableIndex; 319 } 320 } 321 322 void DataCountSection::writeBody() { 323 writeUleb128(bodyOutputStream, numSegments, "data count"); 324 } 325 326 bool DataCountSection::isNeeded() const { 327 return numSegments && config->passiveSegments; 328 } 329 330 static uint32_t getWasmFlags(const Symbol *sym) { 331 uint32_t flags = 0; 332 if (sym->isLocal()) 333 flags |= WASM_SYMBOL_BINDING_LOCAL; 334 if (sym->isWeak()) 335 flags |= WASM_SYMBOL_BINDING_WEAK; 336 if (sym->isHidden()) 337 flags |= WASM_SYMBOL_VISIBILITY_HIDDEN; 338 if (sym->isUndefined()) 339 flags |= WASM_SYMBOL_UNDEFINED; 340 if (auto *f = dyn_cast<UndefinedFunction>(sym)) { 341 if (f->getName() != f->importName) 342 flags |= WASM_SYMBOL_EXPLICIT_NAME; 343 } else if (auto *g = dyn_cast<UndefinedGlobal>(sym)) { 344 if (g->getName() != g->importName) 345 flags |= WASM_SYMBOL_EXPLICIT_NAME; 346 } 347 return flags; 348 } 349 350 void LinkingSection::writeBody() { 351 raw_ostream &os = bodyOutputStream; 352 353 writeUleb128(os, WasmMetadataVersion, "Version"); 354 355 if (!symtabEntries.empty()) { 356 SubSection sub(WASM_SYMBOL_TABLE); 357 writeUleb128(sub.os, symtabEntries.size(), "num symbols"); 358 359 for (const Symbol *sym : symtabEntries) { 360 assert(sym->isDefined() || sym->isUndefined()); 361 WasmSymbolType kind = sym->getWasmType(); 362 uint32_t flags = getWasmFlags(sym); 363 364 writeU8(sub.os, kind, "sym kind"); 365 writeUleb128(sub.os, flags, "sym flags"); 366 367 if (auto *f = dyn_cast<FunctionSymbol>(sym)) { 368 writeUleb128(sub.os, f->getFunctionIndex(), "index"); 369 if (sym->isDefined() || (flags & WASM_SYMBOL_EXPLICIT_NAME) != 0) 370 writeStr(sub.os, sym->getName(), "sym name"); 371 } else if (auto *g = dyn_cast<GlobalSymbol>(sym)) { 372 writeUleb128(sub.os, g->getGlobalIndex(), "index"); 373 if (sym->isDefined() || (flags & WASM_SYMBOL_EXPLICIT_NAME) != 0) 374 writeStr(sub.os, sym->getName(), "sym name"); 375 } else if (auto *e = dyn_cast<EventSymbol>(sym)) { 376 writeUleb128(sub.os, e->getEventIndex(), "index"); 377 if (sym->isDefined() || (flags & WASM_SYMBOL_EXPLICIT_NAME) != 0) 378 writeStr(sub.os, sym->getName(), "sym name"); 379 } else if (isa<DataSymbol>(sym)) { 380 writeStr(sub.os, sym->getName(), "sym name"); 381 if (auto *dataSym = dyn_cast<DefinedData>(sym)) { 382 writeUleb128(sub.os, dataSym->getOutputSegmentIndex(), "index"); 383 writeUleb128(sub.os, dataSym->getOutputSegmentOffset(), 384 "data offset"); 385 writeUleb128(sub.os, dataSym->getSize(), "data size"); 386 } 387 } else { 388 auto *s = cast<OutputSectionSymbol>(sym); 389 writeUleb128(sub.os, s->section->sectionIndex, "sym section index"); 390 } 391 } 392 393 sub.writeTo(os); 394 } 395 396 if (dataSegments.size()) { 397 SubSection sub(WASM_SEGMENT_INFO); 398 writeUleb128(sub.os, dataSegments.size(), "num data segments"); 399 for (const OutputSegment *s : dataSegments) { 400 writeStr(sub.os, s->name, "segment name"); 401 writeUleb128(sub.os, s->alignment, "alignment"); 402 writeUleb128(sub.os, 0, "flags"); 403 } 404 sub.writeTo(os); 405 } 406 407 if (!initFunctions.empty()) { 408 SubSection sub(WASM_INIT_FUNCS); 409 writeUleb128(sub.os, initFunctions.size(), "num init functions"); 410 for (const WasmInitEntry &f : initFunctions) { 411 writeUleb128(sub.os, f.priority, "priority"); 412 writeUleb128(sub.os, f.sym->getOutputSymbolIndex(), "function index"); 413 } 414 sub.writeTo(os); 415 } 416 417 struct ComdatEntry { 418 unsigned kind; 419 uint32_t index; 420 }; 421 std::map<StringRef, std::vector<ComdatEntry>> comdats; 422 423 for (const InputFunction *f : out.functionSec->inputFunctions) { 424 StringRef comdat = f->getComdatName(); 425 if (!comdat.empty()) 426 comdats[comdat].emplace_back( 427 ComdatEntry{WASM_COMDAT_FUNCTION, f->getFunctionIndex()}); 428 } 429 for (uint32_t i = 0; i < dataSegments.size(); ++i) { 430 const auto &inputSegments = dataSegments[i]->inputSegments; 431 if (inputSegments.empty()) 432 continue; 433 StringRef comdat = inputSegments[0]->getComdatName(); 434 #ifndef NDEBUG 435 for (const InputSegment *isec : inputSegments) 436 assert(isec->getComdatName() == comdat); 437 #endif 438 if (!comdat.empty()) 439 comdats[comdat].emplace_back(ComdatEntry{WASM_COMDAT_DATA, i}); 440 } 441 442 if (!comdats.empty()) { 443 SubSection sub(WASM_COMDAT_INFO); 444 writeUleb128(sub.os, comdats.size(), "num comdats"); 445 for (const auto &c : comdats) { 446 writeStr(sub.os, c.first, "comdat name"); 447 writeUleb128(sub.os, 0, "comdat flags"); // flags for future use 448 writeUleb128(sub.os, c.second.size(), "num entries"); 449 for (const ComdatEntry &entry : c.second) { 450 writeU8(sub.os, entry.kind, "entry kind"); 451 writeUleb128(sub.os, entry.index, "entry index"); 452 } 453 } 454 sub.writeTo(os); 455 } 456 } 457 458 void LinkingSection::addToSymtab(Symbol *sym) { 459 sym->setOutputSymbolIndex(symtabEntries.size()); 460 symtabEntries.emplace_back(sym); 461 } 462 463 unsigned NameSection::numNames() const { 464 unsigned numNames = out.importSec->getNumImportedFunctions(); 465 for (const InputFunction *f : out.functionSec->inputFunctions) 466 if (!f->getName().empty() || !f->getDebugName().empty()) 467 ++numNames; 468 469 return numNames; 470 } 471 472 // Create the custom "name" section containing debug symbol names. 473 void NameSection::writeBody() { 474 SubSection sub(WASM_NAMES_FUNCTION); 475 writeUleb128(sub.os, numNames(), "name count"); 476 477 // Names must appear in function index order. As it happens importedSymbols 478 // and inputFunctions are numbered in order with imported functions coming 479 // first. 480 for (const Symbol *s : out.importSec->importedSymbols) { 481 if (auto *f = dyn_cast<FunctionSymbol>(s)) { 482 writeUleb128(sub.os, f->getFunctionIndex(), "func index"); 483 writeStr(sub.os, toString(*s), "symbol name"); 484 } 485 } 486 for (const InputFunction *f : out.functionSec->inputFunctions) { 487 if (!f->getName().empty()) { 488 writeUleb128(sub.os, f->getFunctionIndex(), "func index"); 489 if (!f->getDebugName().empty()) { 490 writeStr(sub.os, f->getDebugName(), "symbol name"); 491 } else { 492 writeStr(sub.os, maybeDemangleSymbol(f->getName()), "symbol name"); 493 } 494 } 495 } 496 497 sub.writeTo(bodyOutputStream); 498 } 499 500 void ProducersSection::addInfo(const WasmProducerInfo &info) { 501 for (auto &producers : 502 {std::make_pair(&info.Languages, &languages), 503 std::make_pair(&info.Tools, &tools), std::make_pair(&info.SDKs, &sDKs)}) 504 for (auto &producer : *producers.first) 505 if (producers.second->end() == 506 llvm::find_if(*producers.second, 507 [&](std::pair<std::string, std::string> seen) { 508 return seen.first == producer.first; 509 })) 510 producers.second->push_back(producer); 511 } 512 513 void ProducersSection::writeBody() { 514 auto &os = bodyOutputStream; 515 writeUleb128(os, fieldCount(), "field count"); 516 for (auto &field : 517 {std::make_pair("language", languages), 518 std::make_pair("processed-by", tools), std::make_pair("sdk", sDKs)}) { 519 if (field.second.empty()) 520 continue; 521 writeStr(os, field.first, "field name"); 522 writeUleb128(os, field.second.size(), "number of entries"); 523 for (auto &entry : field.second) { 524 writeStr(os, entry.first, "producer name"); 525 writeStr(os, entry.second, "producer version"); 526 } 527 } 528 } 529 530 void TargetFeaturesSection::writeBody() { 531 SmallVector<std::string, 8> emitted(features.begin(), features.end()); 532 llvm::sort(emitted); 533 auto &os = bodyOutputStream; 534 writeUleb128(os, emitted.size(), "feature count"); 535 for (auto &feature : emitted) { 536 writeU8(os, WASM_FEATURE_PREFIX_USED, "feature used prefix"); 537 writeStr(os, feature, "feature name"); 538 } 539 } 540 541 void RelocSection::writeBody() { 542 uint32_t count = sec->getNumRelocations(); 543 assert(sec->sectionIndex != UINT32_MAX); 544 writeUleb128(bodyOutputStream, sec->sectionIndex, "reloc section"); 545 writeUleb128(bodyOutputStream, count, "reloc count"); 546 sec->writeRelocations(bodyOutputStream); 547 } 548