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::numImports() 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, numImports(), "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->numImportedFunctions() + 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->numImportedGlobals() + 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 = Out.ImportSec->numImportedEvents() + InputEvents.size(); 277 LLVM_DEBUG(dbgs() << "addEvent: " << EventIndex << "\n"); 278 Event->setEventIndex(EventIndex); 279 InputEvents.push_back(Event); 280 } 281 282 void ExportSection::writeBody() { 283 raw_ostream &OS = BodyOutputStream; 284 285 writeUleb128(OS, Exports.size(), "export count"); 286 for (const WasmExport &Export : Exports) 287 writeExport(OS, Export); 288 } 289 290 void ElemSection::addEntry(FunctionSymbol *Sym) { 291 if (Sym->hasTableIndex()) 292 return; 293 Sym->setTableIndex(ElemOffset + IndirectFunctions.size()); 294 IndirectFunctions.emplace_back(Sym); 295 } 296 297 void ElemSection::writeBody() { 298 raw_ostream &OS = BodyOutputStream; 299 300 writeUleb128(OS, 1, "segment count"); 301 writeUleb128(OS, 0, "table index"); 302 WasmInitExpr InitExpr; 303 if (Config->Pic) { 304 InitExpr.Opcode = WASM_OPCODE_GLOBAL_GET; 305 InitExpr.Value.Global = WasmSym::TableBase->getGlobalIndex(); 306 } else { 307 InitExpr.Opcode = WASM_OPCODE_I32_CONST; 308 InitExpr.Value.Int32 = ElemOffset; 309 } 310 writeInitExpr(OS, InitExpr); 311 writeUleb128(OS, IndirectFunctions.size(), "elem count"); 312 313 uint32_t TableIndex = ElemOffset; 314 for (const FunctionSymbol *Sym : IndirectFunctions) { 315 assert(Sym->getTableIndex() == TableIndex); 316 writeUleb128(OS, Sym->getFunctionIndex(), "function index"); 317 ++TableIndex; 318 } 319 } 320 321 void DataCountSection::writeBody() { 322 writeUleb128(BodyOutputStream, NumSegments, "data count"); 323 } 324 325 bool DataCountSection::isNeeded() const { 326 return NumSegments && Out.TargetFeaturesSec->Features.count("bulk-memory"); 327 } 328 329 static uint32_t getWasmFlags(const Symbol *Sym) { 330 uint32_t Flags = 0; 331 if (Sym->isLocal()) 332 Flags |= WASM_SYMBOL_BINDING_LOCAL; 333 if (Sym->isWeak()) 334 Flags |= WASM_SYMBOL_BINDING_WEAK; 335 if (Sym->isHidden()) 336 Flags |= WASM_SYMBOL_VISIBILITY_HIDDEN; 337 if (Sym->isUndefined()) 338 Flags |= WASM_SYMBOL_UNDEFINED; 339 if (auto *F = dyn_cast<UndefinedFunction>(Sym)) { 340 if (F->getName() != F->ImportName) 341 Flags |= WASM_SYMBOL_EXPLICIT_NAME; 342 } else if (auto *G = dyn_cast<UndefinedGlobal>(Sym)) { 343 if (G->getName() != G->ImportName) 344 Flags |= WASM_SYMBOL_EXPLICIT_NAME; 345 } 346 return Flags; 347 } 348 349 void LinkingSection::writeBody() { 350 raw_ostream &OS = BodyOutputStream; 351 352 writeUleb128(OS, WasmMetadataVersion, "Version"); 353 354 if (!SymtabEntries.empty()) { 355 SubSection Sub(WASM_SYMBOL_TABLE); 356 writeUleb128(Sub.OS, SymtabEntries.size(), "num symbols"); 357 358 for (const Symbol *Sym : SymtabEntries) { 359 assert(Sym->isDefined() || Sym->isUndefined()); 360 WasmSymbolType Kind = Sym->getWasmType(); 361 uint32_t Flags = getWasmFlags(Sym); 362 363 writeU8(Sub.OS, Kind, "sym kind"); 364 writeUleb128(Sub.OS, Flags, "sym flags"); 365 366 if (auto *F = dyn_cast<FunctionSymbol>(Sym)) { 367 writeUleb128(Sub.OS, F->getFunctionIndex(), "index"); 368 if (Sym->isDefined() || (Flags & WASM_SYMBOL_EXPLICIT_NAME) != 0) 369 writeStr(Sub.OS, Sym->getName(), "sym name"); 370 } else if (auto *G = dyn_cast<GlobalSymbol>(Sym)) { 371 writeUleb128(Sub.OS, G->getGlobalIndex(), "index"); 372 if (Sym->isDefined() || (Flags & WASM_SYMBOL_EXPLICIT_NAME) != 0) 373 writeStr(Sub.OS, Sym->getName(), "sym name"); 374 } else if (auto *E = dyn_cast<EventSymbol>(Sym)) { 375 writeUleb128(Sub.OS, E->getEventIndex(), "index"); 376 if (Sym->isDefined() || (Flags & WASM_SYMBOL_EXPLICIT_NAME) != 0) 377 writeStr(Sub.OS, Sym->getName(), "sym name"); 378 } else if (isa<DataSymbol>(Sym)) { 379 writeStr(Sub.OS, Sym->getName(), "sym name"); 380 if (auto *DataSym = dyn_cast<DefinedData>(Sym)) { 381 writeUleb128(Sub.OS, DataSym->getOutputSegmentIndex(), "index"); 382 writeUleb128(Sub.OS, DataSym->getOutputSegmentOffset(), 383 "data offset"); 384 writeUleb128(Sub.OS, DataSym->getSize(), "data size"); 385 } 386 } else { 387 auto *S = cast<OutputSectionSymbol>(Sym); 388 writeUleb128(Sub.OS, S->Section->SectionIndex, "sym section index"); 389 } 390 } 391 392 Sub.writeTo(OS); 393 } 394 395 if (DataSegments.size()) { 396 SubSection Sub(WASM_SEGMENT_INFO); 397 writeUleb128(Sub.OS, DataSegments.size(), "num data segments"); 398 for (const OutputSegment *S : DataSegments) { 399 writeStr(Sub.OS, S->Name, "segment name"); 400 writeUleb128(Sub.OS, S->Alignment, "alignment"); 401 writeUleb128(Sub.OS, 0, "flags"); 402 } 403 Sub.writeTo(OS); 404 } 405 406 if (!InitFunctions.empty()) { 407 SubSection Sub(WASM_INIT_FUNCS); 408 writeUleb128(Sub.OS, InitFunctions.size(), "num init functions"); 409 for (const WasmInitEntry &F : InitFunctions) { 410 writeUleb128(Sub.OS, F.Priority, "priority"); 411 writeUleb128(Sub.OS, F.Sym->getOutputSymbolIndex(), "function index"); 412 } 413 Sub.writeTo(OS); 414 } 415 416 struct ComdatEntry { 417 unsigned Kind; 418 uint32_t Index; 419 }; 420 std::map<StringRef, std::vector<ComdatEntry>> Comdats; 421 422 for (const InputFunction *F : Out.FunctionSec->InputFunctions) { 423 StringRef Comdat = F->getComdatName(); 424 if (!Comdat.empty()) 425 Comdats[Comdat].emplace_back( 426 ComdatEntry{WASM_COMDAT_FUNCTION, F->getFunctionIndex()}); 427 } 428 for (uint32_t I = 0; I < DataSegments.size(); ++I) { 429 const auto &InputSegments = DataSegments[I]->InputSegments; 430 if (InputSegments.empty()) 431 continue; 432 StringRef Comdat = InputSegments[0]->getComdatName(); 433 #ifndef NDEBUG 434 for (const InputSegment *IS : InputSegments) 435 assert(IS->getComdatName() == Comdat); 436 #endif 437 if (!Comdat.empty()) 438 Comdats[Comdat].emplace_back(ComdatEntry{WASM_COMDAT_DATA, I}); 439 } 440 441 if (!Comdats.empty()) { 442 SubSection Sub(WASM_COMDAT_INFO); 443 writeUleb128(Sub.OS, Comdats.size(), "num comdats"); 444 for (const auto &C : Comdats) { 445 writeStr(Sub.OS, C.first, "comdat name"); 446 writeUleb128(Sub.OS, 0, "comdat flags"); // flags for future use 447 writeUleb128(Sub.OS, C.second.size(), "num entries"); 448 for (const ComdatEntry &Entry : C.second) { 449 writeU8(Sub.OS, Entry.Kind, "entry kind"); 450 writeUleb128(Sub.OS, Entry.Index, "entry index"); 451 } 452 } 453 Sub.writeTo(OS); 454 } 455 } 456 457 void LinkingSection::addToSymtab(Symbol *Sym) { 458 Sym->setOutputSymbolIndex(SymtabEntries.size()); 459 SymtabEntries.emplace_back(Sym); 460 } 461 462 unsigned NameSection::numNames() const { 463 unsigned NumNames = Out.ImportSec->numImportedFunctions(); 464 for (const InputFunction *F : Out.FunctionSec->InputFunctions) 465 if (!F->getName().empty() || !F->getDebugName().empty()) 466 ++NumNames; 467 468 return NumNames; 469 } 470 471 // Create the custom "name" section containing debug symbol names. 472 void NameSection::writeBody() { 473 SubSection Sub(WASM_NAMES_FUNCTION); 474 writeUleb128(Sub.OS, numNames(), "name count"); 475 476 // Names must appear in function index order. As it happens ImportedSymbols 477 // and InputFunctions are numbered in order with imported functions coming 478 // first. 479 for (const Symbol *S : Out.ImportSec->ImportedSymbols) { 480 if (auto *F = dyn_cast<FunctionSymbol>(S)) { 481 writeUleb128(Sub.OS, F->getFunctionIndex(), "func index"); 482 writeStr(Sub.OS, toString(*S), "symbol name"); 483 } 484 } 485 for (const InputFunction *F : Out.FunctionSec->InputFunctions) { 486 if (!F->getName().empty()) { 487 writeUleb128(Sub.OS, F->getFunctionIndex(), "func index"); 488 if (!F->getDebugName().empty()) { 489 writeStr(Sub.OS, F->getDebugName(), "symbol name"); 490 } else { 491 writeStr(Sub.OS, maybeDemangleSymbol(F->getName()), "symbol name"); 492 } 493 } 494 } 495 496 Sub.writeTo(BodyOutputStream); 497 } 498 499 void ProducersSection::addInfo(const WasmProducerInfo &Info) { 500 for (auto &Producers : 501 {std::make_pair(&Info.Languages, &Languages), 502 std::make_pair(&Info.Tools, &Tools), std::make_pair(&Info.SDKs, &SDKs)}) 503 for (auto &Producer : *Producers.first) 504 if (Producers.second->end() == 505 llvm::find_if(*Producers.second, 506 [&](std::pair<std::string, std::string> Seen) { 507 return Seen.first == Producer.first; 508 })) 509 Producers.second->push_back(Producer); 510 } 511 512 void ProducersSection::writeBody() { 513 auto &OS = BodyOutputStream; 514 writeUleb128(OS, fieldCount(), "field count"); 515 for (auto &Field : 516 {std::make_pair("language", Languages), 517 std::make_pair("processed-by", Tools), std::make_pair("sdk", SDKs)}) { 518 if (Field.second.empty()) 519 continue; 520 writeStr(OS, Field.first, "field name"); 521 writeUleb128(OS, Field.second.size(), "number of entries"); 522 for (auto &Entry : Field.second) { 523 writeStr(OS, Entry.first, "producer name"); 524 writeStr(OS, Entry.second, "producer version"); 525 } 526 } 527 } 528 529 void TargetFeaturesSection::writeBody() { 530 SmallVector<std::string, 8> Emitted(Features.begin(), Features.end()); 531 llvm::sort(Emitted); 532 auto &OS = BodyOutputStream; 533 writeUleb128(OS, Emitted.size(), "feature count"); 534 for (auto &Feature : Emitted) { 535 writeU8(OS, WASM_FEATURE_PREFIX_USED, "feature used prefix"); 536 writeStr(OS, Feature, "feature name"); 537 } 538 } 539 540 void RelocSection::writeBody() { 541 uint32_t Count = Sec->numRelocations(); 542 assert(Sec->SectionIndex != UINT32_MAX); 543 writeUleb128(BodyOutputStream, Sec->SectionIndex, "reloc section"); 544 writeUleb128(BodyOutputStream, Count, "reloc count"); 545 Sec->writeRelocations(BodyOutputStream); 546 } 547