1 //===- Writer.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 #include "Writer.h" 10 #include "Config.h" 11 #include "InputChunks.h" 12 #include "InputEvent.h" 13 #include "InputGlobal.h" 14 #include "OutputSections.h" 15 #include "OutputSegment.h" 16 #include "Relocations.h" 17 #include "SymbolTable.h" 18 #include "SyntheticSections.h" 19 #include "WriterUtils.h" 20 #include "lld/Common/ErrorHandler.h" 21 #include "lld/Common/Memory.h" 22 #include "lld/Common/Strings.h" 23 #include "lld/Common/Threads.h" 24 #include "llvm/ADT/DenseSet.h" 25 #include "llvm/ADT/SmallSet.h" 26 #include "llvm/ADT/SmallVector.h" 27 #include "llvm/ADT/StringMap.h" 28 #include "llvm/BinaryFormat/Wasm.h" 29 #include "llvm/Object/WasmTraits.h" 30 #include "llvm/Support/FileOutputBuffer.h" 31 #include "llvm/Support/Format.h" 32 #include "llvm/Support/FormatVariadic.h" 33 #include "llvm/Support/LEB128.h" 34 35 #include <cstdarg> 36 #include <map> 37 38 #define DEBUG_TYPE "lld" 39 40 using namespace llvm; 41 using namespace llvm::wasm; 42 using namespace lld; 43 using namespace lld::wasm; 44 45 static constexpr int StackAlignment = 16; 46 47 namespace { 48 49 // The writer writes a SymbolTable result to a file. 50 class Writer { 51 public: 52 void run(); 53 54 private: 55 void openFile(); 56 57 void createInitMemoryFunction(); 58 void createApplyRelocationsFunction(); 59 void createCallCtorsFunction(); 60 61 void assignIndexes(); 62 void populateSymtab(); 63 void populateProducers(); 64 void populateTargetFeatures(); 65 void calculateInitFunctions(); 66 void calculateImports(); 67 void calculateExports(); 68 void calculateCustomSections(); 69 void calculateTypes(); 70 void createOutputSegments(); 71 void layoutMemory(); 72 void createHeader(); 73 74 void addSection(OutputSection *Sec); 75 76 void addSections(); 77 void addStartStopSymbols(const InputSegment *Seg); 78 79 void createCustomSections(); 80 void createSyntheticSections(); 81 void finalizeSections(); 82 83 // Custom sections 84 void createRelocSections(); 85 86 void writeHeader(); 87 void writeSections(); 88 89 uint64_t FileSize = 0; 90 uint32_t TableBase = 0; 91 92 std::vector<WasmInitEntry> InitFunctions; 93 llvm::StringMap<std::vector<InputSection *>> CustomSectionMapping; 94 95 // Elements that are used to construct the final output 96 std::string Header; 97 std::vector<OutputSection *> OutputSections; 98 99 std::unique_ptr<FileOutputBuffer> Buffer; 100 101 std::vector<OutputSegment *> Segments; 102 llvm::SmallDenseMap<StringRef, OutputSegment *> SegmentMap; 103 }; 104 105 } // anonymous namespace 106 107 void Writer::calculateCustomSections() { 108 log("calculateCustomSections"); 109 bool StripDebug = Config->StripDebug || Config->StripAll; 110 for (ObjFile *File : Symtab->ObjectFiles) { 111 for (InputSection *Section : File->CustomSections) { 112 StringRef Name = Section->getName(); 113 // These custom sections are known the linker and synthesized rather than 114 // blindly copied 115 if (Name == "linking" || Name == "name" || Name == "producers" || 116 Name == "target_features" || Name.startswith("reloc.")) 117 continue; 118 // .. or it is a debug section 119 if (StripDebug && Name.startswith(".debug_")) 120 continue; 121 CustomSectionMapping[Name].push_back(Section); 122 } 123 } 124 } 125 126 void Writer::createCustomSections() { 127 log("createCustomSections"); 128 for (auto &Pair : CustomSectionMapping) { 129 StringRef Name = Pair.first(); 130 LLVM_DEBUG(dbgs() << "createCustomSection: " << Name << "\n"); 131 132 OutputSection *Sec = make<CustomSection>(Name, Pair.second); 133 if (Config->Relocatable || Config->EmitRelocs) { 134 auto *Sym = make<OutputSectionSymbol>(Sec); 135 Out.LinkingSec->addToSymtab(Sym); 136 Sec->SectionSym = Sym; 137 } 138 addSection(Sec); 139 } 140 } 141 142 // Create relocations sections in the final output. 143 // These are only created when relocatable output is requested. 144 void Writer::createRelocSections() { 145 log("createRelocSections"); 146 // Don't use iterator here since we are adding to OutputSection 147 size_t OrigSize = OutputSections.size(); 148 for (size_t I = 0; I < OrigSize; I++) { 149 LLVM_DEBUG(dbgs() << "check section " << I << "\n"); 150 OutputSection *Sec = OutputSections[I]; 151 152 // Count the number of needed sections. 153 uint32_t Count = Sec->numRelocations(); 154 if (!Count) 155 continue; 156 157 StringRef Name; 158 if (Sec->Type == WASM_SEC_DATA) 159 Name = "reloc.DATA"; 160 else if (Sec->Type == WASM_SEC_CODE) 161 Name = "reloc.CODE"; 162 else if (Sec->Type == WASM_SEC_CUSTOM) 163 Name = Saver.save("reloc." + Sec->Name); 164 else 165 llvm_unreachable( 166 "relocations only supported for code, data, or custom sections"); 167 168 addSection(make<RelocSection>(Name, Sec)); 169 } 170 } 171 172 void Writer::populateProducers() { 173 for (ObjFile *File : Symtab->ObjectFiles) { 174 const WasmProducerInfo &Info = File->getWasmObj()->getProducerInfo(); 175 Out.ProducersSec->addInfo(Info); 176 } 177 } 178 179 void Writer::writeHeader() { 180 memcpy(Buffer->getBufferStart(), Header.data(), Header.size()); 181 } 182 183 void Writer::writeSections() { 184 uint8_t *Buf = Buffer->getBufferStart(); 185 parallelForEach(OutputSections, [Buf](OutputSection *S) { 186 assert(S->isNeeded()); 187 S->writeTo(Buf); 188 }); 189 } 190 191 // Fix the memory layout of the output binary. This assigns memory offsets 192 // to each of the input data sections as well as the explicit stack region. 193 // The default memory layout is as follows, from low to high. 194 // 195 // - initialized data (starting at Config->GlobalBase) 196 // - BSS data (not currently implemented in llvm) 197 // - explicit stack (Config->ZStackSize) 198 // - heap start / unallocated 199 // 200 // The --stack-first option means that stack is placed before any static data. 201 // This can be useful since it means that stack overflow traps immediately 202 // rather than overwriting global data, but also increases code size since all 203 // static data loads and stores requires larger offsets. 204 void Writer::layoutMemory() { 205 uint32_t MemoryPtr = 0; 206 207 auto PlaceStack = [&]() { 208 if (Config->Relocatable || Config->Shared) 209 return; 210 MemoryPtr = alignTo(MemoryPtr, StackAlignment); 211 if (Config->ZStackSize != alignTo(Config->ZStackSize, StackAlignment)) 212 error("stack size must be " + Twine(StackAlignment) + "-byte aligned"); 213 log("mem: stack size = " + Twine(Config->ZStackSize)); 214 log("mem: stack base = " + Twine(MemoryPtr)); 215 MemoryPtr += Config->ZStackSize; 216 auto *SP = cast<DefinedGlobal>(WasmSym::StackPointer); 217 SP->Global->Global.InitExpr.Value.Int32 = MemoryPtr; 218 log("mem: stack top = " + Twine(MemoryPtr)); 219 }; 220 221 if (Config->StackFirst) { 222 PlaceStack(); 223 } else { 224 MemoryPtr = Config->GlobalBase; 225 log("mem: global base = " + Twine(Config->GlobalBase)); 226 } 227 228 if (WasmSym::GlobalBase) 229 WasmSym::GlobalBase->setVirtualAddress(Config->GlobalBase); 230 231 uint32_t DataStart = MemoryPtr; 232 233 // Arbitrarily set __dso_handle handle to point to the start of the data 234 // segments. 235 if (WasmSym::DsoHandle) 236 WasmSym::DsoHandle->setVirtualAddress(DataStart); 237 238 Out.DylinkSec->MemAlign = 0; 239 for (OutputSegment *Seg : Segments) { 240 Out.DylinkSec->MemAlign = std::max(Out.DylinkSec->MemAlign, Seg->Alignment); 241 MemoryPtr = alignTo(MemoryPtr, 1ULL << Seg->Alignment); 242 Seg->StartVA = MemoryPtr; 243 log(formatv("mem: {0,-15} offset={1,-8} size={2,-8} align={3}", Seg->Name, 244 MemoryPtr, Seg->Size, Seg->Alignment)); 245 MemoryPtr += Seg->Size; 246 } 247 248 // TODO: Add .bss space here. 249 if (WasmSym::DataEnd) 250 WasmSym::DataEnd->setVirtualAddress(MemoryPtr); 251 252 log("mem: static data = " + Twine(MemoryPtr - DataStart)); 253 254 if (Config->Shared) { 255 Out.DylinkSec->MemSize = MemoryPtr; 256 return; 257 } 258 259 if (!Config->StackFirst) 260 PlaceStack(); 261 262 // Set `__heap_base` to directly follow the end of the stack or global data. 263 // The fact that this comes last means that a malloc/brk implementation 264 // can grow the heap at runtime. 265 log("mem: heap base = " + Twine(MemoryPtr)); 266 if (WasmSym::HeapBase) 267 WasmSym::HeapBase->setVirtualAddress(MemoryPtr); 268 269 if (Config->InitialMemory != 0) { 270 if (Config->InitialMemory != alignTo(Config->InitialMemory, WasmPageSize)) 271 error("initial memory must be " + Twine(WasmPageSize) + "-byte aligned"); 272 if (MemoryPtr > Config->InitialMemory) 273 error("initial memory too small, " + Twine(MemoryPtr) + " bytes needed"); 274 else 275 MemoryPtr = Config->InitialMemory; 276 } 277 Out.DylinkSec->MemSize = MemoryPtr; 278 Out.MemorySec->NumMemoryPages = 279 alignTo(MemoryPtr, WasmPageSize) / WasmPageSize; 280 log("mem: total pages = " + Twine(Out.MemorySec->NumMemoryPages)); 281 282 // Check max if explicitly supplied or required by shared memory 283 if (Config->MaxMemory != 0 || Config->SharedMemory) { 284 if (Config->MaxMemory != alignTo(Config->MaxMemory, WasmPageSize)) 285 error("maximum memory must be " + Twine(WasmPageSize) + "-byte aligned"); 286 if (MemoryPtr > Config->MaxMemory) 287 error("maximum memory too small, " + Twine(MemoryPtr) + " bytes needed"); 288 Out.MemorySec->MaxMemoryPages = Config->MaxMemory / WasmPageSize; 289 log("mem: max pages = " + Twine(Out.MemorySec->MaxMemoryPages)); 290 } 291 } 292 293 void Writer::addSection(OutputSection *Sec) { 294 if (!Sec->isNeeded()) 295 return; 296 log("addSection: " + toString(*Sec)); 297 Sec->SectionIndex = OutputSections.size(); 298 OutputSections.push_back(Sec); 299 } 300 301 // If a section name is valid as a C identifier (which is rare because of 302 // the leading '.'), linkers are expected to define __start_<secname> and 303 // __stop_<secname> symbols. They are at beginning and end of the section, 304 // respectively. This is not requested by the ELF standard, but GNU ld and 305 // gold provide the feature, and used by many programs. 306 void Writer::addStartStopSymbols(const InputSegment *Seg) { 307 StringRef S = Seg->getName(); 308 LLVM_DEBUG(dbgs() << "addStartStopSymbols: " << S << "\n"); 309 if (!isValidCIdentifier(S)) 310 return; 311 uint32_t Start = Seg->OutputSeg->StartVA + Seg->OutputSegmentOffset; 312 uint32_t Stop = Start + Seg->getSize(); 313 Symtab->addOptionalDataSymbol(Saver.save("__start_" + S), Start); 314 Symtab->addOptionalDataSymbol(Saver.save("__stop_" + S), Stop); 315 } 316 317 void Writer::addSections() { 318 addSection(Out.DylinkSec); 319 addSection(Out.TypeSec); 320 addSection(Out.ImportSec); 321 addSection(Out.FunctionSec); 322 addSection(Out.TableSec); 323 addSection(Out.MemorySec); 324 addSection(Out.GlobalSec); 325 addSection(Out.EventSec); 326 addSection(Out.ExportSec); 327 addSection(Out.ElemSec); 328 addSection(Out.DataCountSec); 329 330 addSection(make<CodeSection>(Out.FunctionSec->InputFunctions)); 331 addSection(make<DataSection>(Segments)); 332 333 createCustomSections(); 334 335 addSection(Out.LinkingSec); 336 if (Config->EmitRelocs || Config->Relocatable) { 337 createRelocSections(); 338 } 339 340 addSection(Out.NameSec); 341 addSection(Out.ProducersSec); 342 addSection(Out.TargetFeaturesSec); 343 } 344 345 void Writer::finalizeSections() { 346 for (OutputSection *S : OutputSections) { 347 S->setOffset(FileSize); 348 S->finalizeContents(); 349 FileSize += S->getSize(); 350 } 351 } 352 353 void Writer::populateTargetFeatures() { 354 StringMap<std::string> Used; 355 StringMap<std::string> Required; 356 StringMap<std::string> Disallowed; 357 358 // Only infer used features if user did not specify features 359 bool InferFeatures = !Config->Features.hasValue(); 360 361 if (!InferFeatures) { 362 for (auto &Feature : Config->Features.getValue()) 363 Out.TargetFeaturesSec->Features.insert(Feature); 364 // No need to read or check features 365 if (!Config->CheckFeatures) 366 return; 367 } 368 369 // Find the sets of used, required, and disallowed features 370 for (ObjFile *File : Symtab->ObjectFiles) { 371 StringRef FileName(File->getName()); 372 for (auto &Feature : File->getWasmObj()->getTargetFeatures()) { 373 switch (Feature.Prefix) { 374 case WASM_FEATURE_PREFIX_USED: 375 Used.insert({Feature.Name, FileName}); 376 break; 377 case WASM_FEATURE_PREFIX_REQUIRED: 378 Used.insert({Feature.Name, FileName}); 379 Required.insert({Feature.Name, FileName}); 380 break; 381 case WASM_FEATURE_PREFIX_DISALLOWED: 382 Disallowed.insert({Feature.Name, FileName}); 383 break; 384 default: 385 error("Unrecognized feature policy prefix " + 386 std::to_string(Feature.Prefix)); 387 } 388 } 389 } 390 391 if (InferFeatures) 392 Out.TargetFeaturesSec->Features.insert(Used.keys().begin(), 393 Used.keys().end()); 394 395 if (Out.TargetFeaturesSec->Features.count("atomics") && 396 !Config->SharedMemory) { 397 if (InferFeatures) 398 error(Twine("'atomics' feature is used by ") + Used["atomics"] + 399 ", so --shared-memory must be used"); 400 else 401 error("'atomics' feature is used, so --shared-memory must be used"); 402 } 403 404 if (!Config->CheckFeatures) 405 return; 406 407 if (Disallowed.count("atomics") && Config->SharedMemory) 408 error("'atomics' feature is disallowed by " + Disallowed["atomics"] + 409 ", so --shared-memory must not be used"); 410 411 if (!Used.count("bulk-memory") && Config->PassiveSegments) 412 error("'bulk-memory' feature must be used in order to emit passive " 413 "segments"); 414 415 // Validate that used features are allowed in output 416 if (!InferFeatures) { 417 for (auto &Feature : Used.keys()) { 418 if (!Out.TargetFeaturesSec->Features.count(Feature)) 419 error(Twine("Target feature '") + Feature + "' used by " + 420 Used[Feature] + " is not allowed."); 421 } 422 } 423 424 // Validate the required and disallowed constraints for each file 425 for (ObjFile *File : Symtab->ObjectFiles) { 426 StringRef FileName(File->getName()); 427 SmallSet<std::string, 8> ObjectFeatures; 428 for (auto &Feature : File->getWasmObj()->getTargetFeatures()) { 429 if (Feature.Prefix == WASM_FEATURE_PREFIX_DISALLOWED) 430 continue; 431 ObjectFeatures.insert(Feature.Name); 432 if (Disallowed.count(Feature.Name)) 433 error(Twine("Target feature '") + Feature.Name + "' used in " + 434 FileName + " is disallowed by " + Disallowed[Feature.Name] + 435 ". Use --no-check-features to suppress."); 436 } 437 for (auto &Feature : Required.keys()) { 438 if (!ObjectFeatures.count(Feature)) 439 error(Twine("Missing target feature '") + Feature + "' in " + FileName + 440 ", required by " + Required[Feature] + 441 ". Use --no-check-features to suppress."); 442 } 443 } 444 } 445 446 void Writer::calculateImports() { 447 for (Symbol *Sym : Symtab->getSymbols()) { 448 if (!Sym->isUndefined()) 449 continue; 450 if (Sym->isWeak() && !Config->Relocatable) 451 continue; 452 if (!Sym->isLive()) 453 continue; 454 if (!Sym->IsUsedInRegularObj) 455 continue; 456 // We don't generate imports for data symbols. They however can be imported 457 // as GOT entries. 458 if (isa<DataSymbol>(Sym)) 459 continue; 460 461 LLVM_DEBUG(dbgs() << "import: " << Sym->getName() << "\n"); 462 Out.ImportSec->addImport(Sym); 463 } 464 } 465 466 void Writer::calculateExports() { 467 if (Config->Relocatable) 468 return; 469 470 if (!Config->Relocatable && !Config->ImportMemory) 471 Out.ExportSec->Exports.push_back( 472 WasmExport{"memory", WASM_EXTERNAL_MEMORY, 0}); 473 474 if (!Config->Relocatable && Config->ExportTable) 475 Out.ExportSec->Exports.push_back( 476 WasmExport{FunctionTableName, WASM_EXTERNAL_TABLE, 0}); 477 478 unsigned FakeGlobalIndex = 479 Out.ImportSec->numImportedGlobals() + Out.GlobalSec->InputGlobals.size(); 480 481 for (Symbol *Sym : Symtab->getSymbols()) { 482 if (!Sym->isExported()) 483 continue; 484 if (!Sym->isLive()) 485 continue; 486 487 StringRef Name = Sym->getName(); 488 WasmExport Export; 489 if (auto *F = dyn_cast<DefinedFunction>(Sym)) { 490 Export = {Name, WASM_EXTERNAL_FUNCTION, F->getFunctionIndex()}; 491 } else if (auto *G = dyn_cast<DefinedGlobal>(Sym)) { 492 // TODO(sbc): Remove this check once to mutable global proposal is 493 // implement in all major browsers. 494 // See: https://github.com/WebAssembly/mutable-global 495 if (G->getGlobalType()->Mutable) { 496 // Only the __stack_pointer should ever be create as mutable. 497 assert(G == WasmSym::StackPointer); 498 continue; 499 } 500 Export = {Name, WASM_EXTERNAL_GLOBAL, G->getGlobalIndex()}; 501 } else if (auto *E = dyn_cast<DefinedEvent>(Sym)) { 502 Export = {Name, WASM_EXTERNAL_EVENT, E->getEventIndex()}; 503 } else { 504 auto *D = cast<DefinedData>(Sym); 505 Out.GlobalSec->DefinedFakeGlobals.emplace_back(D); 506 Export = {Name, WASM_EXTERNAL_GLOBAL, FakeGlobalIndex++}; 507 } 508 509 LLVM_DEBUG(dbgs() << "Export: " << Name << "\n"); 510 Out.ExportSec->Exports.push_back(Export); 511 } 512 } 513 514 void Writer::populateSymtab() { 515 if (!Config->Relocatable && !Config->EmitRelocs) 516 return; 517 518 for (Symbol *Sym : Symtab->getSymbols()) 519 if (Sym->IsUsedInRegularObj && Sym->isLive()) 520 Out.LinkingSec->addToSymtab(Sym); 521 522 for (ObjFile *File : Symtab->ObjectFiles) { 523 LLVM_DEBUG(dbgs() << "Local symtab entries: " << File->getName() << "\n"); 524 for (Symbol *Sym : File->getSymbols()) 525 if (Sym->isLocal() && !isa<SectionSymbol>(Sym) && Sym->isLive()) 526 Out.LinkingSec->addToSymtab(Sym); 527 } 528 } 529 530 void Writer::calculateTypes() { 531 // The output type section is the union of the following sets: 532 // 1. Any signature used in the TYPE relocation 533 // 2. The signatures of all imported functions 534 // 3. The signatures of all defined functions 535 // 4. The signatures of all imported events 536 // 5. The signatures of all defined events 537 538 for (ObjFile *File : Symtab->ObjectFiles) { 539 ArrayRef<WasmSignature> Types = File->getWasmObj()->types(); 540 for (uint32_t I = 0; I < Types.size(); I++) 541 if (File->TypeIsUsed[I]) 542 File->TypeMap[I] = Out.TypeSec->registerType(Types[I]); 543 } 544 545 for (const Symbol *Sym : Out.ImportSec->ImportedSymbols) { 546 if (auto *F = dyn_cast<FunctionSymbol>(Sym)) 547 Out.TypeSec->registerType(*F->Signature); 548 else if (auto *E = dyn_cast<EventSymbol>(Sym)) 549 Out.TypeSec->registerType(*E->Signature); 550 } 551 552 for (const InputFunction *F : Out.FunctionSec->InputFunctions) 553 Out.TypeSec->registerType(F->Signature); 554 555 for (const InputEvent *E : Out.EventSec->InputEvents) 556 Out.TypeSec->registerType(E->Signature); 557 } 558 559 static void scanRelocations() { 560 for (ObjFile *File : Symtab->ObjectFiles) { 561 LLVM_DEBUG(dbgs() << "scanRelocations: " << File->getName() << "\n"); 562 for (InputChunk *Chunk : File->Functions) 563 scanRelocations(Chunk); 564 for (InputChunk *Chunk : File->Segments) 565 scanRelocations(Chunk); 566 for (auto &P : File->CustomSections) 567 scanRelocations(P); 568 } 569 } 570 571 void Writer::assignIndexes() { 572 // Seal the import section, since other index spaces such as function and 573 // global are effected by the number of imports. 574 Out.ImportSec->seal(); 575 576 for (InputFunction *Func : Symtab->SyntheticFunctions) 577 Out.FunctionSec->addFunction(Func); 578 579 for (ObjFile *File : Symtab->ObjectFiles) { 580 LLVM_DEBUG(dbgs() << "Functions: " << File->getName() << "\n"); 581 for (InputFunction *Func : File->Functions) 582 Out.FunctionSec->addFunction(Func); 583 } 584 585 for (InputGlobal *Global : Symtab->SyntheticGlobals) 586 Out.GlobalSec->addGlobal(Global); 587 588 for (ObjFile *File : Symtab->ObjectFiles) { 589 LLVM_DEBUG(dbgs() << "Globals: " << File->getName() << "\n"); 590 for (InputGlobal *Global : File->Globals) 591 Out.GlobalSec->addGlobal(Global); 592 } 593 594 for (ObjFile *File : Symtab->ObjectFiles) { 595 LLVM_DEBUG(dbgs() << "Events: " << File->getName() << "\n"); 596 for (InputEvent *Event : File->Events) 597 Out.EventSec->addEvent(Event); 598 } 599 } 600 601 static StringRef getOutputDataSegmentName(StringRef Name) { 602 // With PIC code we currently only support a single data segment since 603 // we only have a single __memory_base to use as our base address. 604 if (Config->Pic) 605 return "data"; 606 if (!Config->MergeDataSegments) 607 return Name; 608 if (Name.startswith(".text.")) 609 return ".text"; 610 if (Name.startswith(".data.")) 611 return ".data"; 612 if (Name.startswith(".bss.")) 613 return ".bss"; 614 if (Name.startswith(".rodata.")) 615 return ".rodata"; 616 return Name; 617 } 618 619 void Writer::createOutputSegments() { 620 for (ObjFile *File : Symtab->ObjectFiles) { 621 for (InputSegment *Segment : File->Segments) { 622 if (!Segment->Live) 623 continue; 624 StringRef Name = getOutputDataSegmentName(Segment->getName()); 625 OutputSegment *&S = SegmentMap[Name]; 626 if (S == nullptr) { 627 LLVM_DEBUG(dbgs() << "new segment: " << Name << "\n"); 628 S = make<OutputSegment>(Name, Segments.size()); 629 if (Config->PassiveSegments) 630 S->InitFlags = WASM_SEGMENT_IS_PASSIVE; 631 Segments.push_back(S); 632 } 633 S->addInputSegment(Segment); 634 LLVM_DEBUG(dbgs() << "added data: " << Name << ": " << S->Size << "\n"); 635 } 636 } 637 } 638 639 static void CreateFunction(DefinedFunction *Func, StringRef BodyContent) { 640 std::string FunctionBody; 641 { 642 raw_string_ostream OS(FunctionBody); 643 writeUleb128(OS, BodyContent.size(), "function size"); 644 OS << BodyContent; 645 } 646 ArrayRef<uint8_t> Body = arrayRefFromStringRef(Saver.save(FunctionBody)); 647 cast<SyntheticFunction>(Func->Function)->setBody(Body); 648 } 649 650 void Writer::createInitMemoryFunction() { 651 LLVM_DEBUG(dbgs() << "createInitMemoryFunction\n"); 652 std::string BodyContent; 653 { 654 raw_string_ostream OS(BodyContent); 655 writeUleb128(OS, 0, "num locals"); 656 657 // initialize passive data segments 658 for (const OutputSegment *S : Segments) { 659 if (S->InitFlags & WASM_SEGMENT_IS_PASSIVE) { 660 // destination address 661 writeU8(OS, WASM_OPCODE_I32_CONST, "i32.const"); 662 writeUleb128(OS, S->StartVA, "destination address"); 663 // source segment offset 664 writeU8(OS, WASM_OPCODE_I32_CONST, "i32.const"); 665 writeUleb128(OS, 0, "segment offset"); 666 // memory region size 667 writeU8(OS, WASM_OPCODE_I32_CONST, "i32.const"); 668 writeUleb128(OS, S->Size, "memory region size"); 669 // memory.init instruction 670 writeU8(OS, WASM_OPCODE_MISC_PREFIX, "bulk-memory prefix"); 671 writeUleb128(OS, WASM_OPCODE_MEMORY_INIT, "MEMORY.INIT"); 672 writeUleb128(OS, S->Index, "segment index immediate"); 673 writeU8(OS, 0, "memory index immediate"); 674 // data.drop instruction 675 writeU8(OS, WASM_OPCODE_MISC_PREFIX, "bulk-memory prefix"); 676 writeUleb128(OS, WASM_OPCODE_DATA_DROP, "DATA.DROP"); 677 writeUleb128(OS, S->Index, "segment index immediate"); 678 } 679 } 680 writeU8(OS, WASM_OPCODE_END, "END"); 681 } 682 683 CreateFunction(WasmSym::InitMemory, BodyContent); 684 } 685 686 // For -shared (PIC) output, we create create a synthetic function which will 687 // apply any relocations to the data segments on startup. This function is 688 // called __wasm_apply_relocs and is added at the beginning of __wasm_call_ctors 689 // before any of the constructors run. 690 void Writer::createApplyRelocationsFunction() { 691 LLVM_DEBUG(dbgs() << "createApplyRelocationsFunction\n"); 692 // First write the body's contents to a string. 693 std::string BodyContent; 694 { 695 raw_string_ostream OS(BodyContent); 696 writeUleb128(OS, 0, "num locals"); 697 for (const OutputSegment *Seg : Segments) 698 for (const InputSegment *InSeg : Seg->InputSegments) 699 InSeg->generateRelocationCode(OS); 700 writeU8(OS, WASM_OPCODE_END, "END"); 701 } 702 703 CreateFunction(WasmSym::ApplyRelocs, BodyContent); 704 } 705 706 // Create synthetic "__wasm_call_ctors" function based on ctor functions 707 // in input object. 708 void Writer::createCallCtorsFunction() { 709 if (!WasmSym::CallCtors->isLive()) 710 return; 711 712 // First write the body's contents to a string. 713 std::string BodyContent; 714 { 715 raw_string_ostream OS(BodyContent); 716 writeUleb128(OS, 0, "num locals"); 717 718 if (Config->PassiveSegments) { 719 writeU8(OS, WASM_OPCODE_CALL, "CALL"); 720 writeUleb128(OS, WasmSym::InitMemory->getFunctionIndex(), 721 "function index"); 722 } 723 724 if (Config->Pic) { 725 writeU8(OS, WASM_OPCODE_CALL, "CALL"); 726 writeUleb128(OS, WasmSym::ApplyRelocs->getFunctionIndex(), 727 "function index"); 728 } 729 730 // Call constructors 731 for (const WasmInitEntry &F : InitFunctions) { 732 writeU8(OS, WASM_OPCODE_CALL, "CALL"); 733 writeUleb128(OS, F.Sym->getFunctionIndex(), "function index"); 734 } 735 writeU8(OS, WASM_OPCODE_END, "END"); 736 } 737 738 CreateFunction(WasmSym::CallCtors, BodyContent); 739 } 740 741 // Populate InitFunctions vector with init functions from all input objects. 742 // This is then used either when creating the output linking section or to 743 // synthesize the "__wasm_call_ctors" function. 744 void Writer::calculateInitFunctions() { 745 if (!Config->Relocatable && !WasmSym::CallCtors->isLive()) 746 return; 747 748 for (ObjFile *File : Symtab->ObjectFiles) { 749 const WasmLinkingData &L = File->getWasmObj()->linkingData(); 750 for (const WasmInitFunc &F : L.InitFunctions) { 751 FunctionSymbol *Sym = File->getFunctionSymbol(F.Symbol); 752 // comdat exclusions can cause init functions be discarded. 753 if (Sym->isDiscarded()) 754 continue; 755 assert(Sym->isLive()); 756 if (*Sym->Signature != WasmSignature{{}, {}}) 757 error("invalid signature for init func: " + toString(*Sym)); 758 InitFunctions.emplace_back(WasmInitEntry{Sym, F.Priority}); 759 } 760 } 761 762 // Sort in order of priority (lowest first) so that they are called 763 // in the correct order. 764 llvm::stable_sort(InitFunctions, 765 [](const WasmInitEntry &L, const WasmInitEntry &R) { 766 return L.Priority < R.Priority; 767 }); 768 } 769 770 void Writer::createSyntheticSections() { 771 Out.DylinkSec = make<DylinkSection>(); 772 Out.TypeSec = make<TypeSection>(); 773 Out.ImportSec = make<ImportSection>(); 774 Out.FunctionSec = make<FunctionSection>(); 775 Out.TableSec = make<TableSection>(); 776 Out.MemorySec = make<MemorySection>(); 777 Out.GlobalSec = make<GlobalSection>(); 778 Out.EventSec = make<EventSection>(); 779 Out.ExportSec = make<ExportSection>(); 780 Out.ElemSec = make<ElemSection>(TableBase); 781 Out.DataCountSec = make<DataCountSection>(Segments.size()); 782 Out.LinkingSec = make<LinkingSection>(InitFunctions, Segments); 783 Out.NameSec = make<NameSection>(); 784 Out.ProducersSec = make<ProducersSection>(); 785 Out.TargetFeaturesSec = make<TargetFeaturesSection>(); 786 } 787 788 void Writer::run() { 789 if (Config->Relocatable || Config->Pic) 790 Config->GlobalBase = 0; 791 792 // For PIC code the table base is assigned dynamically by the loader. 793 // For non-PIC, we start at 1 so that accessing table index 0 always traps. 794 if (!Config->Pic) 795 TableBase = 1; 796 797 log("-- createOutputSegments"); 798 createOutputSegments(); 799 log("-- createSyntheticSections"); 800 createSyntheticSections(); 801 log("-- populateProducers"); 802 populateProducers(); 803 log("-- populateTargetFeatures"); 804 populateTargetFeatures(); 805 log("-- calculateImports"); 806 calculateImports(); 807 log("-- layoutMemory"); 808 layoutMemory(); 809 810 if (!Config->Relocatable) { 811 // Create linker synthesized __start_SECNAME/__stop_SECNAME symbols 812 // This has to be done after memory layout is performed. 813 for (const OutputSegment *Seg : Segments) 814 for (const InputSegment *S : Seg->InputSegments) 815 addStartStopSymbols(S); 816 } 817 818 log("-- scanRelocations"); 819 scanRelocations(); 820 log("-- assignIndexes"); 821 assignIndexes(); 822 log("-- calculateInitFunctions"); 823 calculateInitFunctions(); 824 825 if (!Config->Relocatable) { 826 // Create linker synthesized functions 827 if (Config->PassiveSegments) 828 createInitMemoryFunction(); 829 if (Config->Pic) 830 createApplyRelocationsFunction(); 831 createCallCtorsFunction(); 832 833 // Make sure we have resolved all symbols. 834 if (!Config->AllowUndefined) 835 Symtab->reportRemainingUndefines(); 836 837 if (errorCount()) 838 return; 839 } 840 841 log("-- calculateTypes"); 842 calculateTypes(); 843 log("-- calculateExports"); 844 calculateExports(); 845 log("-- calculateCustomSections"); 846 calculateCustomSections(); 847 log("-- populateSymtab"); 848 populateSymtab(); 849 log("-- addSections"); 850 addSections(); 851 852 if (errorHandler().Verbose) { 853 log("Defined Functions: " + Twine(Out.FunctionSec->InputFunctions.size())); 854 log("Defined Globals : " + Twine(Out.GlobalSec->InputGlobals.size())); 855 log("Defined Events : " + Twine(Out.EventSec->InputEvents.size())); 856 log("Function Imports : " + Twine(Out.ImportSec->numImportedFunctions())); 857 log("Global Imports : " + Twine(Out.ImportSec->numImportedGlobals())); 858 log("Event Imports : " + Twine(Out.ImportSec->numImportedEvents())); 859 for (ObjFile *File : Symtab->ObjectFiles) 860 File->dumpInfo(); 861 } 862 863 createHeader(); 864 log("-- finalizeSections"); 865 finalizeSections(); 866 867 log("-- openFile"); 868 openFile(); 869 if (errorCount()) 870 return; 871 872 writeHeader(); 873 874 log("-- writeSections"); 875 writeSections(); 876 if (errorCount()) 877 return; 878 879 if (Error E = Buffer->commit()) 880 fatal("failed to write the output file: " + toString(std::move(E))); 881 } 882 883 // Open a result file. 884 void Writer::openFile() { 885 log("writing: " + Config->OutputFile); 886 887 Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr = 888 FileOutputBuffer::create(Config->OutputFile, FileSize, 889 FileOutputBuffer::F_executable); 890 891 if (!BufferOrErr) 892 error("failed to open " + Config->OutputFile + ": " + 893 toString(BufferOrErr.takeError())); 894 else 895 Buffer = std::move(*BufferOrErr); 896 } 897 898 void Writer::createHeader() { 899 raw_string_ostream OS(Header); 900 writeBytes(OS, WasmMagic, sizeof(WasmMagic), "wasm magic"); 901 writeU32(OS, WasmVersion, "wasm version"); 902 OS.flush(); 903 FileSize += Header.size(); 904 } 905 906 void lld::wasm::writeResult() { Writer().run(); } 907