Lines Matching +full:- +full:- +full:require +full:- +full:hashes
1 //===- Writer.cpp ---------------------------------------------------------===//
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
137 for (InputChunk *section : file->customSections) {
139 if (section->discarded)
143 // avoid section re-numbering.
144 if (section->getSize() == 0)
146 StringRef name = section->name;
152 // These custom sections are generated by `clang -fembed-bitcode`.
177 out.linkingSec->addToSymtab(sym);
178 sec->sectionSym = sym;
195 uint32_t count = sec->getNumRelocations();
200 if (sec->type == WASM_SEC_DATA)
202 else if (sec->type == WASM_SEC_CODE)
204 else if (sec->type == WASM_SEC_CUSTOM)
205 name = saver().save("reloc." + sec->name);
216 const WasmProducerInfo &info = file->getWasmObj()->getProducerInfo();
217 out.producersSec->addInfo(info);
222 memcpy(buffer->getBufferStart(), header.data(), header.size());
226 uint8_t *buf = buffer->getBufferStart();
228 assert(s->isNeeded());
229 s->writeTo(buf);
243 std::vector<uint8_t> hashes(chunks.size() * hashBuf.size());
247 hashFn(hashes.data() + i * hashBuf.size(), chunks[i]);
251 hashFn(hashBuf.data(), hashes);
259 // Build a valid v5 UUID from a hardcoded (randomly-generated) namespace
283 if (!out.buildIdSec->isNeeded())
286 out.buildIdSec->writeBuildId(ctx.arg.buildIdVector);
291 size_t hashSize = out.buildIdSec->hashSize;
293 llvm::ArrayRef<uint8_t> buf{buffer->getBufferStart(), size_t(fileSize)};
315 out.buildIdSec->writeBuildId(buildId);
319 LLVM_DEBUG(dbgs() << "setGlobalPtr " << g->getName() << " -> " << memoryPtr << "\n");
320 g->global->setPointerValue(memoryPtr);
327 // - initialized data (starting at ctx.arg.globalBase)
328 // - BSS data (not currently implemented in llvm)
329 // - explicit stack (ctx.arg.ZStackSize)
330 // - heap start / unallocated
332 // The --stack-first option means that stack is placed before any static data.
344 WasmSym::stackLow->setVA(memoryPtr);
346 error("stack size must be " + Twine(stackAlignment) + "-byte aligned");
352 WasmSym::stackHigh->setVA(memoryPtr);
360 error("--global-base cannot be less than stack size when --stack-first is used");
371 WasmSym::globalBase->setVA(memoryPtr);
378 WasmSym::dsoHandle->setVA(dataStart);
380 out.dylinkSec->memAlign = 0;
382 out.dylinkSec->memAlign = std::max(out.dylinkSec->memAlign, seg->alignment);
383 memoryPtr = alignTo(memoryPtr, 1ULL << seg->alignment);
384 seg->startVA = memoryPtr;
385 log(formatv("mem: {0,-15} offset={1,-8} size={2,-8} align={3}", seg->name,
386 memoryPtr, seg->size, seg->alignment));
388 if (!ctx.arg.relocatable && seg->isTLS()) {
391 setGlobalPtr(tlsSize, seg->size);
395 setGlobalPtr(tlsAlign, int64_t{1} << seg->alignment);
403 memoryPtr += seg->size;
409 WasmSym::initMemoryFlag = symtab->addSyntheticDataSymbol(
411 WasmSym::initMemoryFlag->markLive();
412 WasmSym::initMemoryFlag->setVA(memoryPtr);
413 log(formatv("mem: {0,-15} offset={1,-8} size={2,-8} align={3}",
419 WasmSym::dataEnd->setVA(memoryPtr);
421 uint64_t staticDataSize = memoryPtr - dataStart;
424 out.dylinkSec->memSize = staticDataSize;
437 WasmSym::heapBase->setVA(memoryPtr);
449 error("initial heap must be " + Twine(WasmPageSize) + "-byte aligned");
450 uint64_t maxInitialHeap = maxMemorySetting - memoryPtr;
459 error("initial memory must be " + Twine(WasmPageSize) + "-byte aligned");
470 out.memorySec->numMemoryPages = memoryPtr / WasmPageSize;
471 log("mem: total pages = " + Twine(out.memorySec->numMemoryPages));
478 WasmSym::heapEnd->setVA(memoryPtr);
484 error("maximum memory must be " + Twine(WasmPageSize) + "-byte aligned");
506 out.memorySec->maxMemoryPages = maxMemory / WasmPageSize;
507 log("mem: max pages = " + Twine(out.memorySec->maxMemoryPages));
512 if (!sec->isNeeded())
515 sec->sectionIndex = outputSections.size();
525 StringRef name = seg->name;
529 uint64_t start = seg->startVA;
530 uint64_t stop = start + seg->size;
531 symtab->addOptionalDataSymbol(saver().save("__start_" + name), start);
532 symtab->addOptionalDataSymbol(saver().save("__stop_" + name), stop);
549 addSection(make<CodeSection>(out.functionSec->inputFunctions));
567 s->setOffset(fileSize);
568 s->finalizeContents();
569 fileSize += s->getSize();
576 SmallSet<std::string, 8> &allowed = out.targetFeaturesSec->features;
581 // contain the mutable-globals feature.
582 // TODO (https://github.com/llvm/llvm-project/issues/51681)
583 allowed.insert("mutable-globals");
603 StringRef fileName(file->getName());
604 for (auto &feature : file->getWasmObj()->getTargetFeatures()) {
620 return segment->live && segment->isTLS();
622 tlsUsed = tlsUsed || llvm::any_of(file->segments, isTLS);
633 if (disallowed.count("shared-mem"))
634 error("--shared-memory is disallowed by " + disallowed["shared-mem"] +
635 " because it was not compiled with 'atomics' or 'bulk-memory' "
638 for (auto feature : {"atomics", "bulk-memory"})
645 for (auto feature : {"atomics", "bulk-memory"})
648 "' feature must be used in order to use thread-local storage");
662 StringRef fileName(file->getName());
664 for (const auto &feature : file->getWasmObj()->getTargetFeatures()) {
671 ". Use --no-check-features to suppress.");
683 (ctx.arg.memoryImport.has_value() && !allowed.count("bulk-memory")))
686 if (allowed.count("extended-const"))
697 if (out.targetFeaturesSec->features.count("mutable-globals") == 0) {
698 for (const Symbol *sym : out.importSec->importedSymbols) {
700 if (global->getGlobalType()->Mutable) {
701 error(Twine("mutable global imported but 'mutable-globals' feature "
703 toString(*sym) + "`. Use --no-check-features to suppress.");
707 for (const Symbol *sym : out.exportSec->exportedSymbols) {
709 error(Twine("mutable global exported but 'mutable-globals' feature "
711 toString(*sym) + "`. Use --no-check-features to suppress.");
722 if (!sym->isLive())
724 if (!sym->isUsedInRegularObj)
730 if (ctx.arg.shared && sym->isWeak() && !sym->isUndefined() &&
731 !sym->isHidden())
733 if (sym->isShared())
735 if (!sym->isUndefined())
737 if (sym->isWeak() && !ctx.arg.relocatable && !ctx.isPic)
744 if (!f->isCalledDirectly)
751 if (ctx.arg.allowUndefinedSymbols.count(sym->getName()) != 0)
754 return sym->isImported();
758 // Some inputs require that the indirect function table be assigned to table
763 out.importSec->addImport(WasmSym::indirectFunctionTable);
765 for (Symbol *sym : symtab->symbols()) {
770 LLVM_DEBUG(dbgs() << "import: " << sym->getName() << "\n");
771 out.importSec->addImport(sym);
780 out.exportSec->exports.push_back(
785 out.importSec->getNumImportedGlobals() + out.globalSec->numGlobals();
787 for (Symbol *sym : symtab->symbols()) {
788 if (!sym->isExported())
790 if (!sym->isLive())
792 if (isa<SharedFunctionSymbol>(sym) || sym->isShared())
795 StringRef name = sym->getName();
799 if (std::optional<StringRef> exportName = f->function->getExportName()) {
802 export_ = {name, WASM_EXTERNAL_FUNCTION, f->getExportedFunctionIndex()};
804 if (g->getGlobalType()->Mutable && !g->getFile() && !g->forceExport) {
808 // Without this check `--export-all` would cause any program using the
810 // files were built with the `mutable-globals` feature.
813 export_ = {name, WASM_EXTERNAL_GLOBAL, g->getGlobalIndex()};
815 export_ = {name, WASM_EXTERNAL_TAG, t->getTagIndex()};
817 out.globalSec->dataAddressGlobals.push_back(d);
821 export_ = {name, WASM_EXTERNAL_TABLE, t->getTableNumber()};
824 out.exportSec->exports.push_back(export_);
825 out.exportSec->exportedSymbols.push_back(sym);
833 for (Symbol *sym : symtab->symbols())
834 if (sym->isUsedInRegularObj && sym->isLive() && !sym->isShared())
835 out.linkingSec->addToSymtab(sym);
838 LLVM_DEBUG(dbgs() << "Local symtab entries: " << file->getName() << "\n");
839 for (Symbol *sym : file->getSymbols())
840 if (sym->isLocal() && !isa<SectionSymbol>(sym) && sym->isLive())
841 out.linkingSec->addToSymtab(sym);
854 ArrayRef<WasmSignature> types = file->getWasmObj()->types();
856 if (file->typeIsUsed[i])
857 file->typeMap[i] = out.typeSec->registerType(types[i]);
860 for (const Symbol *sym : out.importSec->importedSymbols) {
862 out.typeSec->registerType(*f->signature);
864 out.typeSec->registerType(*t->signature);
867 for (const InputFunction *f : out.functionSec->inputFunctions)
868 out.typeSec->registerType(f->signature);
870 for (const InputTag *t : out.tagSec->inputTags)
871 out.typeSec->registerType(t->signature);
874 // In a command-style link, create a wrapper for each exported symbol
877 // This logic doesn't currently support Emscripten-style PIC mode.
887 for (Symbol *sym : symtab->symbols())
888 if (sym->isExported())
893 auto funcNameStr = (f->getName() + ".command_export").str();
897 auto func = make<SyntheticFunction>(*f->getSignature(), funcName);
898 if (f->function->getExportName())
899 func->setExportName(f->function->getExportName()->str());
901 func->setExportName(f->getName().str());
904 symtab->addSyntheticFunction(funcName, f->flags, func);
905 def->markLive();
907 def->flags |= WASM_SYMBOL_EXPORTED;
908 def->flags &= ~WASM_SYMBOL_VISIBILITY_HIDDEN;
909 def->forceExport = f->forceExport;
911 f->flags |= WASM_SYMBOL_VISIBILITY_HIDDEN;
912 f->flags &= ~WASM_SYMBOL_EXPORTED;
913 f->forceExport = false;
915 out.functionSec->addFunction(func);
917 createCommandExportWrapper(f->getFunctionIndex(), def);
926 !WasmSym::indirectFunctionTable->hasTableNumber()) {
927 // Processing -Bsymbolic relocations resulted in a late requirement that the
928 // indirect function table be present, and we are running in --import-table
931 out.importSec->addImport(WasmSym::indirectFunctionTable);
934 uint32_t tableSize = ctx.arg.tableBase + out.elemSec->numEntries();
936 if (WasmSym::indirectFunctionTable->isDefined() && !ctx.arg.growableTable) {
942 WasmSym::indirectFunctionTable->setLimits(limits);
947 LLVM_DEBUG(dbgs() << "scanRelocations: " << file->getName() << "\n");
948 for (InputChunk *chunk : file->functions)
950 for (InputChunk *chunk : file->segments)
952 for (auto &p : file->customSections)
960 out.importSec->seal();
963 out.functionSec->addFunction(func);
966 LLVM_DEBUG(dbgs() << "Functions: " << file->getName() << "\n");
967 for (InputFunction *func : file->functions)
968 out.functionSec->addFunction(func);
972 out.globalSec->addGlobal(global);
975 LLVM_DEBUG(dbgs() << "Globals: " << file->getName() << "\n");
976 for (InputGlobal *global : file->globals)
977 out.globalSec->addGlobal(global);
981 LLVM_DEBUG(dbgs() << "Tags: " << file->getName() << "\n");
982 for (InputTag *tag : file->tags)
983 out.tagSec->addTag(tag);
987 LLVM_DEBUG(dbgs() << "Tables: " << file->getName() << "\n");
988 for (InputTable *table : file->tables)
989 out.tableSec->addTable(table);
993 out.tableSec->addTable(table);
995 out.globalSec->assignIndexes();
996 out.tableSec->assignIndexes();
1021 s->initFlags = WASM_DATA_SEGMENT_IS_PASSIVE;
1023 s->isBss = true;
1030 for (InputChunk *segment : file->segments) {
1031 if (!segment->live)
1038 if (ctx.arg.relocatable && !segment->getComdatName().empty()) {
1045 s->addInputSegment(segment);
1060 return order(a->name) < order(b->name);
1064 segments[i]->index = i;
1067 LLVM_DEBUG(dbgs() << "-- finalize input semgments\n");
1069 seg->finalizeInputSegments();
1077 // available: https://github.com/WebAssembly/extended-const
1083 combined->startVA = segments[0]->startVA;
1086 for (InputChunk *inSeg : s->inputSegments) {
1088 inSeg->alignment = std::max(inSeg->alignment, s->alignment);
1091 uint64_t oldVA = inSeg->getVA();
1093 combined->addInputSegment(inSeg);
1095 uint64_t newVA = inSeg->getVA();
1096 LLVM_DEBUG(dbgs() << "added input segment. name=" << inSeg->name
1114 cast<SyntheticFunction>(func->function)->setBody(body);
1120 if (ctx.arg.memoryImport.has_value() && !segment->requiredInBinary())
1122 return segment->initFlags & WASM_DATA_SEGMENT_IS_PASSIVE;
1127 return this->needsPassiveInitialization(s);
1145 WasmSym::initMemory = symtab->addSyntheticFunction(
1148 WasmSym::initMemory->markLive();
1152 WasmSym::tlsBase->markLive();
1157 if (out.globalSec->needsTLSRelocations()) {
1158 WasmSym::applyGlobalTLSRelocs = symtab->addSyntheticFunction(
1162 WasmSym::applyGlobalTLSRelocs->markLive();
1164 WasmSym::tlsBase->markLive();
1168 if (segment->isTLS())
1169 for (const auto* is: segment->inputSegments)
1170 if (is->getRelocations().size())
1175 WasmSym::applyTLSRelocs = symtab->addSyntheticFunction(
1179 WasmSym::applyTLSRelocs->markLive();
1183 if (ctx.isPic && out.globalSec->needsRelocations()) {
1184 WasmSym::applyGlobalRelocs = symtab->addSyntheticFunction(
1187 WasmSym::applyGlobalRelocs->markLive();
1194 WasmSym::startFunction = symtab->addSyntheticFunction(
1197 WasmSym::startFunction->markLive();
1208 flagAddress = WasmSym::initMemoryFlag->getVA();
1214 // Initialize memory in a thread-safe manner. The thread that successfully
1243 // (i32.const -1u)
1252 // (i32.const -1)
1281 writeUleb128(os, WasmSym::memoryBase->getGlobalIndex(), "memory_base");
1322 // For non-BSS segments we do a memory.init. Both these
1325 writePtrConst(os, s->startVA, is64, "destination address");
1328 writeUleb128(os, WasmSym::memoryBase->getGlobalIndex(),
1337 if (ctx.arg.sharedMemory && s->isTLS()) {
1343 writePtrConst(os, s->startVA, is64, "destination address");
1346 writeUleb128(os, WasmSym::tlsBase->getGlobalIndex(),
1354 if (s->isBss) {
1356 writePtrConst(os, s->size, is64, "memory region size");
1357 writeU8(os, WASM_OPCODE_MISC_PREFIX, "bulk-memory prefix");
1362 writeI32Const(os, s->size, "memory region size");
1363 writeU8(os, WASM_OPCODE_MISC_PREFIX, "bulk-memory prefix");
1365 writeUleb128(os, s->index, "segment index immediate");
1381 writeI32Const(os, -1, "number of waiters");
1395 writeI64Const(os, -1, "timeout");
1407 if (needsPassiveInitialization(s) && !s->isBss) {
1410 if (ctx.arg.sharedMemory && s->isTLS())
1413 writeU8(os, WASM_OPCODE_MISC_PREFIX, "bulk-memory prefix");
1415 writeUleb128(os, s->index, "segment index immediate");
1435 writeUleb128(os, WasmSym::applyGlobalRelocs->getFunctionIndex(),
1438 writeUleb128(os, WasmSym::initMemory->getFunctionIndex(),
1450 // For -shared (PIC) output, we create create a synthetic function which will
1463 if (!ctx.arg.sharedMemory || !seg->isTLS())
1464 for (const InputChunk *inSeg : seg->inputSegments)
1465 generated |= inSeg->generateRelocationCode(os);
1475 // Function that applies relocations to data segment post-instantiation.
1477 auto def = symtab->addSyntheticFunction(
1481 def->markLive();
1493 if (seg->isTLS())
1494 for (const InputChunk *inSeg : seg->inputSegments)
1495 inSeg->generateRelocationCode(os);
1512 out.globalSec->generateRelocationCode(os, false);
1528 out.globalSec->generateRelocationCode(os, true);
1540 if (!WasmSym::callCtors->isLive() && initFunctions.empty())
1552 writeUleb128(os, f.sym->getFunctionIndex(), "function index");
1553 for (size_t i = 0; i < f.sym->signature->Returns.size(); i++) {
1575 // applies any runtime relocations in Emscripten-style PIC mode)
1576 if (WasmSym::callCtors->isLive()) {
1578 writeUleb128(os, WasmSym::callCtors->getFunctionIndex(),
1583 for (size_t i = 0; i < f->signature->Params.size(); ++i) {
1593 writeUleb128(os, callDtors->getFunctionIndex(), "function index");
1610 if (seg->name == ".tdata") {
1622 writeUleb128(os, WasmSym::tlsBase->getGlobalIndex(), "global index");
1630 writeI32Const(os, tlsSeg->size, "memory region size");
1632 writeU8(os, WASM_OPCODE_MISC_PREFIX, "bulk-memory prefix");
1634 writeUleb128(os, tlsSeg->index, "segment index immediate");
1640 writeUleb128(os, WasmSym::applyTLSRelocs->getFunctionIndex(),
1646 writeUleb128(os, WasmSym::applyGlobalTLSRelocs->getFunctionIndex(),
1659 if (!ctx.arg.relocatable && !WasmSym::callCtors->isLive())
1663 const WasmLinkingData &l = file->getWasmObj()->linkingData();
1665 FunctionSymbol *sym = file->getFunctionSymbol(f.Symbol);
1667 if (sym->isDiscarded() || !sym->isLive())
1669 if (sym->signature->Params.size() != 0)
1709 // For non-PIC, we start at 1 so that accessing table index 0 always traps.
1711 WasmSym::definedTableBase->setVA(ctx.arg.tableBase);
1713 log("-- createOutputSegments");
1715 log("-- createSyntheticSections");
1717 log("-- layoutMemory");
1729 Symbol *sym = symtab->find(pair.first());
1730 if (sym && sym->isDefined())
1731 sym->forceExport = true;
1737 Symbol *sym = symtab->find(name);
1738 if (!sym || !sym->isDefined()) {
1740 error(Twine("symbol exported via --export not found: ") + name);
1742 warn(Twine("symbol exported via --export not found: ") + name);
1746 log("-- populateTargetFeatures");
1756 log("-- combineOutputSegments");
1760 log("-- createSyntheticSectionsPostLayout");
1762 log("-- populateProducers");
1764 log("-- calculateImports");
1766 log("-- scanRelocations");
1768 log("-- finalizeIndirectFunctionTable");
1770 log("-- createSyntheticInitFunctions");
1772 log("-- assignIndexes");
1774 log("-- calculateInitFunctions");
1794 // the input objects or an explicit export from the command-line, we
1797 !WasmSym::callCtors->isUsedInRegularObj &&
1798 !WasmSym::callCtors->isExported()) {
1799 log("-- createCommandExportWrappers");
1804 if (WasmSym::initTLS && WasmSym::initTLS->isLive()) {
1805 log("-- createInitTLSFunction");
1812 log("-- calculateTypes");
1814 log("-- calculateExports");
1816 log("-- calculateCustomSections");
1818 log("-- populateSymtab");
1820 log("-- checkImportExportTargetFeatures");
1822 log("-- addSections");
1826 log("Defined Functions: " + Twine(out.functionSec->inputFunctions.size()));
1827 log("Defined Globals : " + Twine(out.globalSec->numGlobals()));
1828 log("Defined Tags : " + Twine(out.tagSec->inputTags.size()));
1829 log("Defined Tables : " + Twine(out.tableSec->inputTables.size()));
1831 Twine(out.importSec->getNumImportedFunctions()));
1832 log("Global Imports : " + Twine(out.importSec->getNumImportedGlobals()));
1833 log("Tag Imports : " + Twine(out.importSec->getNumImportedTags()));
1834 log("Table Imports : " + Twine(out.importSec->getNumImportedTables()));
1838 log("-- finalizeSections");
1841 log("-- writeMapFile");
1844 log("-- openFile");
1851 log("-- writeSections");
1857 if (Error e = buffer->commit())
1858 fatal("failed to write output '" + buffer->getPath() +