Lines Matching +full:dll +full:- +full:config

1 //===- Writer.cpp ---------------------------------------------------------===//
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
12 #include "Config.h"
13 #include "DLL.h"
50 /* To re-generate DOSProgram:
56 ; Point ds:dx at the $-terminated string.
67 $ nasm -fbin /tmp/DOSProgram.asm -o /tmp/DOSProgram.bin
68 $ xxd -i /tmp/DOSProgram.bin
104 uint64_t offs = os->getFileOff() + (c->getRVA() - os->getRVA());
105 fillEntry(d, record.first, c->getSize(), c->getRVA(), offs);
110 // FIXME: The COFF spec allows either a 0-sized entry to just say
111 // "the timestamp field is really a hash", or a 4-byte size field
113 // lowest 4 bytes usually being the timestamp in little-endian order).
127 d->Characteristics = 0;
128 d->TimeDateStamp = 0;
129 d->MajorVersion = 0;
130 d->MinorVersion = 0;
131 d->Type = debugType;
132 d->SizeOfData = size;
133 d->AddressOfRawData = rva;
134 d->PointerToRawData = offs;
136 timeDateStamps.push_back(&d->TimeDateStamp);
150 return sizeof(codeview::DebugInfo) + ctx.config.pdbAltPath.size() + 1;
160 if (!ctx.config.pdbAltPath.empty())
161 memcpy(p, ctx.config.pdbAltPath.data(), ctx.config.pdbAltPath.size());
162 p[ctx.config.pdbAltPath.size()] = '\0';
327 // are entirely linker-generated we can keep track of their locations using
358 chunks.insert(chunks.end(), other->chunks.begin(), other->chunks.end());
359 other->chunks.clear();
360 contribSections.insert(contribSections.end(), other->contribSections.begin(),
361 other->contribSections.end());
362 other->contribSections.clear();
366 if (other->header.Characteristics & IMAGE_SCN_CNT_CODE) {
379 encodeSectionName(hdr->Name, stringTableOff);
382 (hdr->Characteristics & IMAGE_SCN_MEM_DISCARDABLE) == 0);
383 strncpy(hdr->Name, name.data(),
395 if (ctx.config.machine == ARMNT) {
406 } else if (ctx.config.machine == ARM64) {
428 Defined *&lastThunk = lastThunks[target->getRVA()];
429 if (lastThunk && isInRange(type, lastThunk->getRVA(), p, margin))
432 switch (ctx.config.machine) {
452 // range, but only barely, also get thunks - in case other added thunks makes
465 for (size_t i = 0; i != os->chunks.size(); ++i) {
466 SectionChunk *sc = dyn_cast_or_null<SectionChunk>(os->chunks[i]);
474 size_t thunkInsertionRVA = sc->getRVA() + sc->getSize() + thunksSize;
475 ObjFile *file = sc->file;
478 file->getCOFFObj()->getRelocations(sc->header);
481 Symbol *relocTarget = file->getSymbol(rel.SymbolTableIndex);
487 uint64_t p = sc->getRVA() + rel.VirtualAddress + thunksSize;
493 uint64_t s = sym->getRVA();
501 Chunk *thunkChunk = thunk->getChunk();
502 thunkChunk->setRVA(
504 os->chunks.insert(os->chunks.begin() + thunkInsertionSpot, thunkChunk);
506 thunksSize += thunkChunk->getSize();
507 thunkInsertionRVA += thunkChunk->getSize();
515 uint32_t &thunkSymbolIndex = insertion.first->second;
517 thunkSymbolIndex = file->addRangeThunkSymbol(thunk);
525 ArrayRef<coff_relocation> curRelocs = sc->getRelocs();
542 if (nextReplacement != endReplacement && nextReplacement->first == i) {
543 newRelocs[i].SymbolTableIndex = nextReplacement->second;
548 sc->setRelocs(newRelocs);
555 if (!isArm64EC(ctx.config.machine))
573 for (Chunk *c : sec->chunks) {
576 if (isa<SectionChunk>(c) && !c->getSize())
579 std::optional<chpe_range_type> chunkType = c->getArm64ECRangeType();
592 cast<DefinedAbsolute>(tableCountSym)->setVA(codeMap.size());
602 ArrayRef<coff_relocation> relocs = sc->getRelocs();
604 Symbol *relocTarget = sc->file->getSymbol(rel.SymbolTableIndex);
610 uint64_t p = sc->getRVA() + rel.VirtualAddress;
611 uint64_t s = sym->getRVA();
623 if (ctx.config.machine != ARMNT && ctx.config.machine != ARM64)
628 sec->origChunks = sec->chunks;
629 origNumChunks += sec->chunks.size();
644 if (!verifyRanges(sec->chunks)) {
648 numChunks += sec->chunks.size();
653 log("Added " + Twine(numChunks - origNumChunks) + " thunks with " +
666 sec->chunks = sec->origChunks;
692 if (!ctx.config.writeCheckSum) {
698 // https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#checksum
699 uint32_t *buf = (uint32_t *)buffer->getBufferStart();
700 uint32_t size = (uint32_t)(buffer->getBufferSize());
714 count -= 2;
717 // Add left-over byte, if any
721 // Fold 32-bit sum to 16 bits
727 peHeader->CheckSum = sum;
757 openFile(ctx.config.outputFile);
758 if (ctx.config.is64()) {
773 if (!ctx.config.pdbPath.empty() && ctx.config.debug) {
775 createPDB(ctx, sectionTable, buildId->buildId);
789 if (auto e = buffer->commit())
790 fatal("failed to write output '" + buffer->getPath() +
806 if (sec->sym)
807 return ctx.config.order.lookup(sec->sym->getName());
821 StringRef curName = pSec->name;
825 if (pSec->characteristics == chars)
827 PartialSection *destSec = createPartialSection(pSec->name, chars);
828 destSec->chunks.insert(destSec->chunks.end(), pSec->chunks.begin(),
829 pSec->chunks.end());
830 pSec->chunks.clear();
856 if (!pSec->name.starts_with(".idata"))
859 if (!pSec->chunks.empty())
861 llvm::stable_sort(pSec->chunks, [&](Chunk *s, Chunk *t) {
873 (sc1->file->parentName + "/" + sc1->file->getName()).str();
875 (sc2->file->parentName + "/" + sc2->file->getName()).str();
893 pSec->chunks.insert(pSec->chunks.end(), v.begin(), v.end());
912 if (!importDirs->chunks.empty())
913 importTableStart = importDirs->chunks.front();
914 for (Chunk *c : importDirs->chunks)
915 importTableSize += c->getSize();
919 if (!importAddresses->chunks.empty())
920 iatStart = importAddresses->chunks.front();
921 for (Chunk *c : importAddresses->chunks)
922 iatSize += c->getSize();
935 // .tls$$<symbol> (where non-comdat .tls symbols are otherwise stored in
942 if (!sc || !sc->isCOMDAT())
950 if (!ctx.config.callGraphProfile.empty()) {
954 if (DefinedRegular *sym = it.first->sym)
955 ctx.config.order[sym->getName()] = it.second;
958 if (!ctx.config.order.empty())
960 sortBySectionOrder(it.second->chunks);
1003 if (sc && !sc->live) {
1004 if (ctx.config.verbose)
1005 sc->printDiscardedMessage();
1008 StringRef name = c->getSectionName();
1009 if (shouldStripSectionSuffix(sc, name, ctx.config.mingw))
1013 tlsAlignment = std::max(tlsAlignment, c->getAlignment());
1016 c->getOutputCharacteristics());
1017 pSec->chunks.push_back(c);
1042 StringRef name = getOutputSectionName(pSec->name);
1043 uint32_t outChars = pSec->characteristics;
1052 log("Processing section " + pSec->name + " -> " + name);
1054 sortCRTSectionChunks(pSec->chunks);
1058 for (Chunk *c : pSec->chunks)
1059 sec->addChunk(c);
1061 sec->addContributingPartialSection(pSec);
1066 // Move DISCARDABLE (or non-memory-mapped) sections to the end of file
1069 if (s->header.Characteristics & IMAGE_SCN_MEM_DISCARDABLE) {
1072 // .debug_* - thus try to avoid leaving holes after stripping.
1073 if (s->name.starts_with(".debug_"))
1077 // .rsrc should come at the end of the non-discardable sections because its
1092 Configuration *config = &ctx.config;
1096 p->finalizeContents();
1097 rdataSec->addChunk(p);
1101 // Create thunks for locally-dllimported symbols.
1104 rdataSec->addChunk(c);
1108 debugInfoSec = config->mingw ? buildidSec : rdataSec;
1109 if (config->buildIDHash != BuildIDHash::None || config->debug ||
1110 config->repro || config->cetCompat) {
1112 make<DebugDirectoryChunk>(ctx, debugRecords, config->repro);
1113 debugDirectory->setAlignment(4);
1114 debugInfoSec->addChunk(debugDirectory);
1117 if (config->debug || config->buildIDHash != BuildIDHash::None) {
1125 replaceSymbol<DefinedSynthetic>(buildidSym, buildidSym->getName(),
1129 if (config->cetCompat) {
1137 r.second->setAlignment(4);
1138 debugInfoSec->addChunk(r.second);
1141 // Create SEH table. x86-only.
1142 if (config->safeSEH)
1146 if (config->guardCF != GuardCFLevel::Off)
1149 if (isArm64EC(config->machine))
1152 if (config->autoImport)
1155 if (config->mingw)
1159 // Create .idata section for the DLL-imported symbol table.
1160 // The format of this section is inherently Windows-specific.
1166 // the same order as in the command line. (That affects DLL
1167 // initialization order, and this ordering is MSVC-compatible.)
1169 if (!file->live)
1172 std::string dll = StringRef(file->dllName).lower();
1173 if (ctx.config.dllOrder.count(dll) == 0)
1174 ctx.config.dllOrder[dll] = ctx.config.dllOrder.size();
1176 if (file->impSym && !isa<DefinedImportData>(file->impSym))
1177 fatal(toString(ctx, *file->impSym) + " was replaced");
1178 DefinedImportData *impSym = cast_or_null<DefinedImportData>(file->impSym);
1179 if (ctx.config.delayLoads.count(StringRef(file->dllName).lower())) {
1180 if (!file->thunkSym)
1181 fatal("cannot delay-load " + toString(file) +
1196 if (!file->live)
1199 if (!file->thunkSym)
1202 if (!isa<DefinedImportThunk>(file->thunkSym))
1203 fatal(toString(ctx, *file->thunkSym) + " was replaced");
1204 DefinedImportThunk *thunk = cast<DefinedImportThunk>(file->thunkSym);
1205 if (file->thunkLive)
1206 textSec->addChunk(thunk->getChunk());
1210 Defined *helper = cast<Defined>(ctx.config.delayLoadHelper);
1213 didatSec->addChunk(c);
1215 dataSec->addChunk(c);
1217 textSec->addChunk(c);
1219 pdataSec->addChunk(c);
1221 rdataSec->addChunk(c);
1227 if (!edataSec->chunks.empty()) {
1230 if (ctx.config.hadExplicitExports)
1232 } else if (!ctx.config.exports.empty()) {
1234 edataSec->addChunk(c);
1236 if (!edataSec->chunks.empty()) {
1237 edataStart = edataSec->chunks.front();
1238 edataEnd = edataSec->chunks.back();
1241 for (auto e : ctx.config.exports)
1242 if (e.sym && e.sym->getName().starts_with("??_G"))
1255 return s->chunks.empty();
1264 auto isEmpty = [](OutputSection *s) { return s->getVirtualSize() == 0; };
1274 os->sectionIndex = idx;
1275 for (Chunk *c : os->chunks)
1276 c->setOutputSectionIdx(idx);
1284 for (SectionChunk *sc : mc->sections)
1285 if (sc && sc->live)
1286 sc->setOutputSectionIdx(mc->getOutputSectionIdx());
1299 switch (def->kind()) {
1302 // Note: COFF symbol can only store 32-bit values, so 64-bit absolute
1304 sym.Value = da->getVA();
1314 Chunk *c = def->getChunk();
1321 sym.Value = def->getRVA() - os->getRVA();
1322 sym.SectionNumber = os->sectionIndex;
1331 if (def->isRuntimePseudoReloc)
1334 StringRef name = def->getName();
1344 COFFSymbolRef ref = d->getCOFFSymbol();
1347 } else if (def->kind() == Symbol::DefinedImportThunkKind) {
1362 // supported by writing a non-standard string table, but this string table is
1367 // non-discardable sections have their names truncated, to ensure that any
1370 if (sec->name.size() <= COFF::NameSize)
1372 if ((sec->header.Characteristics & IMAGE_SCN_MEM_DISCARDABLE) == 0)
1374 if (ctx.config.warnLongSectionNames) {
1375 warn("section name " + sec->name +
1376 " is longer than 8 characters and will use a non-standard string "
1379 sec->setStringTableOff(addEntryToStringTable(sec->name));
1382 if (ctx.config.writeSymtab) {
1384 for (Symbol *b : file->getSymbols()) {
1386 if (!d || d->writtenToSymtab)
1388 d->writtenToSymtab = true;
1390 COFFSymbolRef symRef = dc->getCOFFSymbol();
1400 if (!dthunk->wrappedSym->writtenToSymtab) {
1401 dthunk->wrappedSym->writtenToSymtab = true;
1403 createSymbol(dthunk->wrappedSym))
1419 fileSize = alignTo(fileOff, ctx.config.fileAlign);
1424 if (!pdataSec->chunks.empty()) {
1425 if (isArm64EC(ctx.config.machine)) {
1428 llvm::stable_sort(pdataSec->chunks, [=](const Chunk *a, const Chunk *b) {
1429 return (a->getMachine() == AMD64) < (b->getMachine() == AMD64);
1432 for (auto chunk : pdataSec->chunks) {
1433 if (chunk->getMachine() == AMD64) {
1435 hybridPdata.last = pdataSec->chunks.back();
1444 pdata.first = pdataSec->chunks.front();
1445 pdata.last = pdataSec->chunks.back();
1449 for (auto &p : ctx.config.merge) {
1457 auto i = ctx.config.merge.find(toName);
1458 if (i == ctx.config.merge.end())
1460 toName = i->second;
1467 from->name = toName;
1470 to->merge(from);
1478 if (!isArm64EC(ctx.config.machine))
1482 if (sec->isCodeSection())
1483 llvm::stable_sort(sec->chunks, [=](const Chunk *a, const Chunk *b) {
1484 std::optional<chpe_range_type> aType = a->getArm64ECRangeType(),
1485 bType = b->getArm64ECRangeType();
1491 // Visits all sections to assign incremental, non-overlapping RVAs and
1495 Configuration *config = &ctx.config;
1505 config->is64() ? sizeof(pe32plus_header) : sizeof(pe32_header);
1506 sizeOfHeaders = alignTo(sizeOfHeaders, config->fileAlign);
1510 uint64_t rva = alignTo(sizeOfHeaders, config->align);
1513 llvm::TimeTraceScope timeScope("Section: ", sec->name);
1517 sec->header.VirtualAddress = rva;
1521 uint32_t padding = sec->isCodeSection() ? config->functionPadMin : 0;
1524 for (Chunk *c : sec->chunks) {
1526 if (isArm64EC(ctx.config.machine) && sec->isCodeSection()) {
1527 std::optional<chpe_range_type> rangeType = c->getArm64ECRangeType();
1533 if (padding && c->isHotPatchable())
1537 if (c->getEntryThunk())
1539 virtualSize = alignTo(virtualSize, c->getAlignment());
1540 c->setRVA(rva + virtualSize);
1541 virtualSize += c->getSize();
1542 if (c->hasData)
1543 rawSize = alignTo(virtualSize, config->fileAlign);
1546 error("section larger than 4 GiB: " + sec->name);
1547 sec->header.VirtualSize = virtualSize;
1548 sec->header.SizeOfRawData = rawSize;
1550 sec->header.PointerToRawData = fileSize;
1551 rva += alignTo(virtualSize, config->align);
1552 fileSize += alignTo(rawSize, config->fileAlign);
1554 sizeOfImage = alignTo(rva, config->align);
1559 mc->assignSubsectionRVAs();
1564 // executable consists of an MS-DOS MZ executable. If the executable is run
1568 Configuration *config = &ctx.config;
1569 uint8_t *buf = buffer->getBufferStart();
1572 dos->Magic[0] = 'M';
1573 dos->Magic[1] = 'Z';
1574 dos->UsedBytesInTheLastPage = dosStubSize % 512;
1575 dos->FileSizeInPages = divideCeil(dosStubSize, 512);
1576 dos->HeaderSizeInParagraphs = sizeof(dos_header) / 16;
1578 dos->AddressOfRelocationTable = sizeof(dos_header);
1579 dos->AddressOfNewExeHeader = dosStubSize;
1592 switch (config->machine) {
1594 coff->Machine = AMD64;
1597 coff->Machine = ARM64;
1600 coff->Machine = config->machine;
1602 coff->NumberOfSections = ctx.outputSections.size();
1603 coff->Characteristics = IMAGE_FILE_EXECUTABLE_IMAGE;
1604 if (config->largeAddressAware)
1605 coff->Characteristics |= IMAGE_FILE_LARGE_ADDRESS_AWARE;
1606 if (!config->is64())
1607 coff->Characteristics |= IMAGE_FILE_32BIT_MACHINE;
1608 if (config->dll)
1609 coff->Characteristics |= IMAGE_FILE_DLL;
1610 if (config->driverUponly)
1611 coff->Characteristics |= IMAGE_FILE_UP_SYSTEM_ONLY;
1612 if (!config->relocatable)
1613 coff->Characteristics |= IMAGE_FILE_RELOCS_STRIPPED;
1614 if (config->swaprunCD)
1615 coff->Characteristics |= IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP;
1616 if (config->swaprunNet)
1617 coff->Characteristics |= IMAGE_FILE_NET_RUN_FROM_SWAP;
1618 coff->SizeOfOptionalHeader =
1624 pe->Magic = config->is64() ? PE32Header::PE32_PLUS : PE32Header::PE32;
1631 pe->MajorLinkerVersion = 14;
1632 pe->MinorLinkerVersion = 0;
1634 pe->ImageBase = config->imageBase;
1635 pe->SectionAlignment = config->align;
1636 pe->FileAlignment = config->fileAlign;
1637 pe->MajorImageVersion = config->majorImageVersion;
1638 pe->MinorImageVersion = config->minorImageVersion;
1639 pe->MajorOperatingSystemVersion = config->majorOSVersion;
1640 pe->MinorOperatingSystemVersion = config->minorOSVersion;
1641 pe->MajorSubsystemVersion = config->majorSubsystemVersion;
1642 pe->MinorSubsystemVersion = config->minorSubsystemVersion;
1643 pe->Subsystem = config->subsystem;
1644 pe->SizeOfImage = sizeOfImage;
1645 pe->SizeOfHeaders = sizeOfHeaders;
1646 if (!config->noEntry) {
1647 Defined *entry = cast<Defined>(config->entry);
1648 pe->AddressOfEntryPoint = entry->getRVA();
1650 if (config->machine == ARMNT)
1651 pe->AddressOfEntryPoint |= 1;
1653 pe->SizeOfStackReserve = config->stackReserve;
1654 pe->SizeOfStackCommit = config->stackCommit;
1655 pe->SizeOfHeapReserve = config->heapReserve;
1656 pe->SizeOfHeapCommit = config->heapCommit;
1657 if (config->appContainer)
1658 pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_APPCONTAINER;
1659 if (config->driverWdm)
1660 pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_WDM_DRIVER;
1661 if (config->dynamicBase)
1662 pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE;
1663 if (config->highEntropyVA)
1664 pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA;
1665 if (!config->allowBind)
1666 pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_NO_BIND;
1667 if (config->nxCompat)
1668 pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_NX_COMPAT;
1669 if (!config->allowIsolation)
1670 pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION;
1671 if (config->guardCF != GuardCFLevel::Off)
1672 pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_GUARD_CF;
1673 if (config->integrityCheck)
1674 pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY;
1675 if (setNoSEHCharacteristic || config->noSEH)
1676 pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_NO_SEH;
1677 if (config->terminalServerAware)
1678 pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE;
1679 pe->NumberOfRvaAndSize = numberOfDataDirectory;
1680 if (textSec->getVirtualSize()) {
1681 pe->BaseOfCode = textSec->getRVA();
1682 pe->SizeOfCode = textSec->getRawSize();
1684 pe->SizeOfInitializedData = getSizeOfInitializedData();
1690 dir[EXPORT_TABLE].RelativeVirtualAddress = edataStart->getRVA();
1692 edataEnd->getRVA() + edataEnd->getSize() - edataStart->getRVA();
1695 dir[IMPORT_TABLE].RelativeVirtualAddress = importTableStart->getRVA();
1699 dir[IAT].RelativeVirtualAddress = iatStart->getRVA();
1702 if (rsrcSec->getVirtualSize()) {
1703 dir[RESOURCE_TABLE].RelativeVirtualAddress = rsrcSec->getRVA();
1704 dir[RESOURCE_TABLE].Size = rsrcSec->getVirtualSize();
1708 ctx.config.machine == ARM64EC ? hybridPdata : pdata;
1711 exceptionTable.first->getRVA();
1712 dir[EXCEPTION_TABLE].Size = exceptionTable.last->getRVA() +
1713 exceptionTable.last->getSize() -
1714 exceptionTable.first->getRVA();
1716 if (relocSec->getVirtualSize()) {
1717 dir[BASE_RELOCATION_TABLE].RelativeVirtualAddress = relocSec->getRVA();
1718 dir[BASE_RELOCATION_TABLE].Size = relocSec->getVirtualSize();
1722 dir[TLS_TABLE].RelativeVirtualAddress = b->getRVA();
1723 dir[TLS_TABLE].Size = config->is64()
1729 dir[DEBUG_DIRECTORY].RelativeVirtualAddress = debugDirectory->getRVA();
1730 dir[DEBUG_DIRECTORY].Size = debugDirectory->getSize();
1734 SectionChunk *sc = b->getChunk();
1735 assert(b->getRVA() >= sc->getRVA());
1736 uint64_t offsetInChunk = b->getRVA() - sc->getRVA();
1737 if (!sc->hasData || offsetInChunk + 4 > sc->getSize())
1740 ArrayRef<uint8_t> secContents = sc->getContents();
1743 if (offsetInChunk + loadConfigSize > sc->getSize())
1745 dir[LOAD_CONFIG_TABLE].RelativeVirtualAddress = b->getRVA();
1757 sec->writeHeaderTo(buf, config->debug);
1761 buf - ctx.outputSections.size() * sizeof(coff_section), buf);
1766 coff->PointerToSymbolTable = pointerToSymbolTable;
1768 coff->NumberOfSymbols = numberOfSymbols;
1770 buffer->getBufferStart() + coff->PointerToSymbolTable);
1790 if (!file->hasSafeSEH())
1791 error("/safeseh: " + file->getName() + " is not compatible with SEH");
1792 markSymbolsForRVATable(file, file->getSXDataChunks(), handlers);
1796 // there is no load config object to point to the table of handlers.
1808 Chunk *c = s->getChunk();
1812 c = sc->repl; // Look through ICF replacement.
1813 uint32_t off = s->getRVA() - (c ? c->getRVA() : 0);
1824 switch (s->kind()) {
1855 if (d->getCOFFSymbol().getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION) {
1856 SectionChunk *sc = dyn_cast<SectionChunk>(d->getChunk());
1857 if (sc && sc->live &&
1858 sc->getOutputCharacteristics() & IMAGE_SCN_MEM_EXECUTE)
1867 // mark the relocation target as address-taken.
1870 for (Chunk *c : file->getChunks()) {
1874 if (!sc || !sc->live)
1877 for (const coff_relocation &reloc : sc->getRelocs()) {
1878 if (ctx.config.machine == I386 &&
1884 Symbol *ref = sc->file->getSymbol(reloc.SymbolTableIndex);
1891 // address-taken functions. It is sorted and uniqued, just like the safe SEH
1894 Configuration *config = &ctx.config;
1906 // possibly address-taken.
1907 if (file->hasGuardCF()) {
1908 markSymbolsForRVATable(file, file->getGuardFidChunks(), addressTakenSyms);
1909 markSymbolsForRVATable(file, file->getGuardIATChunks(), giatsRVASet);
1910 getSymbolsFromSections(file, file->getGuardIATChunks(), giatsSymbols);
1911 markSymbolsForRVATable(file, file->getGuardLJmpChunks(), longJmpTargets);
1917 if (file->hasGuardEHCont())
1918 markSymbolsForRVATable(file, file->getGuardEHContChunks(), ehContTargets);
1921 // Mark the image entry as address-taken.
1922 if (config->entry)
1923 maybeAddAddressTakenFunction(addressTakenSyms, config->entry);
1925 // Mark exported symbols in executable sections as address-taken.
1926 for (Export &e : config->exports)
1930 // thunk (e.g. because the DLL that defines it will be delay-loaded) and, if
1934 if (di->loadThunkSym)
1935 addSymbolToRVASet(addressTakenSyms, di->loadThunkSym);
1939 // Ensure sections referenced in the gfid table are 16-byte aligned.
1941 if (c.inputChunk->getAlignment() < 16)
1942 c.inputChunk->setAlignment(16);
1952 if (config->guardCF & GuardCFLevel::LongJmp)
1957 if (config->guardCF & GuardCFLevel::EHCont)
1961 // Set __guard_flags, which will be used in the load config to indicate that
1965 if (config->guardCF & GuardCFLevel::LongJmp)
1967 if (config->guardCF & GuardCFLevel::EHCont)
1970 cast<DefinedAbsolute>(flagSym)->setVA(guardFlags);
1983 // mark the virtual member functions as address-taken by the vtable.
1984 if (!c->live)
1988 ArrayRef<uint8_t> data = c->getContents();
1990 warn("ignoring " + c->getSectionName() +
1999 ArrayRef<Symbol *> objSymbols = file->getSymbols();
2003 c->getSectionName() + " in object " + toString(file));
2007 if (s->isLive())
2039 rdataSec->addChunk(tableChunk);
2043 replaceSymbol<DefinedSynthetic>(t, t->getName(), tableChunk);
2044 cast<DefinedAbsolute>(c)->setVA(tableChunk->getSize() / (hasFlag ? 5 : 4));
2050 rdataSec->addChunk(codeMapChunk);
2052 replaceSymbol<DefinedSynthetic>(codeMapSym, codeMapSym->getName(),
2056 // MinGW specific. Gather all relocations that are imported from a DLL even
2065 if (!sc || !sc->live)
2069 if (sc->header->Characteristics & IMAGE_SCN_MEM_DISCARDABLE)
2071 sc->getRuntimePseudoRelocs(rels);
2074 if (!ctx.config.pseudoRelocs) {
2078 error("automatic dllimport of " + rpr.sym->getName() + " in " +
2079 toString(rpr.target->file) + " requires pseudo relocations");
2094 rdataSec->addChunk(table);
2096 rdataSec->addChunk(endOfList);
2101 replaceSymbol<DefinedSynthetic>(headSym, headSym->getName(), table);
2102 replaceSymbol<DefinedSynthetic>(endSym, endSym->getName(), endOfList);
2107 // a (uintptr_t)-1 at the start and a (uintptr_t)0 at the end.
2111 AbsolutePointerChunk *ctorListHead = make<AbsolutePointerChunk>(ctx, -1);
2113 AbsolutePointerChunk *dtorListHead = make<AbsolutePointerChunk>(ctx, -1);
2115 ctorsSec->insertChunkAtStart(ctorListHead);
2116 ctorsSec->addChunk(ctorListEnd);
2117 dtorsSec->insertChunkAtStart(dtorListHead);
2118 dtorsSec->addChunk(dtorListEnd);
2122 replaceSymbol<DefinedSynthetic>(ctorListSym, ctorListSym->getName(),
2124 replaceSymbol<DefinedSynthetic>(dtorListSym, dtorListSym->getName(),
2132 for (auto &p : ctx.config.section) {
2136 if (sec->name == name)
2137 sec->setPermissions(perm);
2143 if (!isArm64EC(ctx.config.machine))
2154 ->setVA(pdata.last->getRVA() + pdata.last->getSize() -
2155 pdata.first->getRVA());
2162 uint8_t *buf = buffer->getBufferStart();
2164 uint8_t *secBuf = buf + sec->getFileOff();
2170 if ((sec->header.Characteristics & IMAGE_SCN_CNT_CODE) &&
2171 (ctx.config.machine == AMD64 || ctx.config.machine == I386)) {
2173 for (Chunk *c : sec->chunks) {
2174 uint32_t off = c->getRVA() - sec->getRVA();
2175 memset(secBuf + prevEnd, 0xCC, off - prevEnd);
2176 prevEnd = off + c->getSize();
2178 memset(secBuf + prevEnd, 0xCC, sec->getRawSize() - prevEnd);
2181 parallelForEach(sec->chunks, [&](Chunk *c) {
2182 c->writeTo(secBuf + c->getRVA() - sec->getRVA());
2196 Configuration *config = &ctx.config;
2197 bool generateSyntheticBuildId = config->buildIDHash == BuildIDHash::Binary;
2200 // BuildId->BuildId was filled in when the PDB was written.
2208 reinterpret_cast<const char *>(buffer->getBufferStart()),
2209 buffer->getBufferSize());
2211 uint32_t timestamp = config->timestamp;
2214 if (config->repro || generateSyntheticBuildId)
2217 if (config->repro)
2221 buildId->buildId->PDB70.CVSignature = OMF::Signature::PDB70;
2222 buildId->buildId->PDB70.Age = 1;
2223 memcpy(buildId->buildId->PDB70.Signature, &hash, 8);
2225 memcpy(&buildId->buildId->PDB70.Signature[8], "LLD PDB.", 8);
2229 debugDirectory->setTimeDateStamp(timestamp);
2231 uint8_t *buf = buffer->getBufferStart();
2235 coffHeader->TimeDateStamp = timestamp;
2247 return buffer->getBufferStart() + os->getFileOff() + c->getRVA() -
2248 os->getRVA();
2251 uint8_t *end = bufAddr(exceptionTable.last) + exceptionTable.last->getSize();
2252 if ((end - begin) % sizeof(T) != 0) {
2253 fatal("unexpected .pdata size: " + Twine(end - begin) +
2273 switch (ctx.config.machine) {
2310 assert(sa && sb && "Non-section chunks in CRT section!");
2312 StringRef sAObj = sa->file->mb.getBufferIdentifier();
2313 StringRef sBObj = sb->file->mb.getBufferIdentifier();
2315 return sAObj == sBObj && sa->getSectionNumber() < sb->getSectionNumber();
2319 if (ctx.config.verbose) {
2322 log(" " + sc->file->mb.getBufferIdentifier().str() +
2323 ", SectionID: " + Twine(sc->getSectionNumber()));
2330 if (sec->name == name)
2338 if (s->header.Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA)
2339 res += s->getRawSize();
2345 if (!ctx.config.relocatable)
2347 relocSec->chunks.clear();
2350 if (sec->header.Characteristics & IMAGE_SCN_MEM_DISCARDABLE)
2352 llvm::TimeTraceScope timeScope("Base relocations: ", sec->name);
2354 for (Chunk *c : sec->chunks)
2355 c->getBaserels(&v);
2365 const uint32_t mask = ~uint32_t(pageSize - 1);
2372 relocSec->addChunk(make<BaserelChunk>(page, &v[i], &v[0] + j));
2378 relocSec->addChunk(make<BaserelChunk>(page, &v[i], &v[0] + j));
2393 return it->second;
2403 OutputSection *sec = ctx.getOutputSection(tlsSym->getChunk());
2404 assert(sec && tlsSym->getRVA() >= sec->getRVA() &&
2407 uint8_t *secBuf = buffer->getBufferStart() + sec->getFileOff();
2408 uint64_t tlsOffset = tlsSym->getRVA() - sec->getRVA();
2409 uint64_t directorySize = ctx.config.is64()
2413 if (tlsOffset + directorySize > sec->getRawSize())
2416 if (ctx.config.is64()) {
2419 tlsDir->setAlignment(tlsAlignment);
2423 tlsDir->setAlignment(tlsAlignment);
2431 if (ctx.config.guardCF != GuardCFLevel::Off)
2436 OutputSection *sec = ctx.getOutputSection(b->getChunk());
2437 uint8_t *buf = buffer->getBufferStart();
2438 uint8_t *secBuf = buf + sec->getFileOff();
2439 uint8_t *symBuf = secBuf + (b->getRVA() - sec->getRVA());
2440 uint32_t expectedAlign = ctx.config.is64() ? 8 : 4;
2441 if (b->getChunk()->getAlignment() < expectedAlign)
2444 Twine(b->getChunk()->getAlignment()) + " instead)");
2445 else if (!isAligned(Align(expectedAlign), b->getRVA()))
2447 Twine::utohexstr(b->getRVA()) + " not aligned to " +
2450 if (ctx.config.is64())
2457 if (ctx.config.dependentLoadFlags)
2458 loadConfig->DependentLoadFlags = ctx.config.dependentLoadFlags;
2465 size_t loadConfigSize = loadConfig->Size;
2478 if (loadConfig->field != ctx.config.imageBase + s->getRVA()) \
2483 if (loadConfig->field != s->getVA()) \
2486 if (ctx.config.guardCF == GuardCFLevel::Off)
2497 if (!(ctx.config.guardCF & GuardCFLevel::LongJmp))
2503 if (!(ctx.config.guardCF & GuardCFLevel::EHCont))