Index: lld/COFF/Config.h =================================================================== --- lld/COFF/Config.h +++ lld/COFF/Config.h @@ -180,6 +180,7 @@ std::string MapFile; uint64_t ImageBase = -1; + uint64_t FileAlignment = 512; uint64_t StackReserve = 1024 * 1024; uint64_t StackCommit = 4096; uint64_t HeapReserve = 1024 * 1024; Index: lld/COFF/Driver.cpp =================================================================== --- lld/COFF/Driver.cpp +++ lld/COFF/Driver.cpp @@ -1186,6 +1186,9 @@ if (auto *Arg = Args.getLastArg(OPT_base)) parseNumbers(Arg->getValue(), &Config->ImageBase); + if (auto *Arg = Args.getLastArg(OPT_filealign)) + parseNumbers(Arg->getValue(), &Config->FileAlignment); + // Handle /stack if (auto *Arg = Args.getLastArg(OPT_stack)) parseNumbers(Arg->getValue(), &Config->StackReserve, &Config->StackCommit); Index: lld/COFF/Options.td =================================================================== --- lld/COFF/Options.td +++ lld/COFF/Options.td @@ -32,6 +32,7 @@ def export : P<"export", "Export a function">; // No help text because /failifmismatch is not intended to be used by the user. def failifmismatch : P<"failifmismatch", "">; +def filealign : P<"filealign", "Section alignment in the output file">; def functionpadmin : F<"functionpadmin">; def functionpadmin_opt : P<"functionpadmin", "Prepares an image for hotpatching">; def guard : P<"guard", "Control flow guard">; Index: lld/COFF/Writer.cpp =================================================================== --- lld/COFF/Writer.cpp +++ lld/COFF/Writer.cpp @@ -73,7 +73,6 @@ static_assert(sizeof(DOSProgram) % 8 == 0, "DOSProgram size must be multiple of 8"); -static const int SectorSize = 512; static const int DOSStubSize = sizeof(dos_header) + sizeof(DOSProgram); static_assert(DOSStubSize % 8 == 0, "DOSStub size must be multiple of 8"); @@ -1096,7 +1095,7 @@ PointerToSymbolTable = FileOff; FileOff += OutputSymtab.size() * sizeof(coff_symbol16); FileOff += 4 + Strtab.size(); - FileSize = alignTo(FileOff, SectorSize); + FileSize = alignTo(FileOff, Config->FileAlignment); } void Writer::mergeSections() { @@ -1138,7 +1137,7 @@ sizeof(coff_section) * OutputSections.size(); SizeOfHeaders += Config->is64() ? sizeof(pe32plus_header) : sizeof(pe32_header); - SizeOfHeaders = alignTo(SizeOfHeaders, SectorSize); + SizeOfHeaders = alignTo(SizeOfHeaders, Config->FileAlignment); uint64_t RVA = PageSize; // The first page is kept unmapped. FileSize = SizeOfHeaders; @@ -1164,7 +1163,7 @@ C->finalizeContents(); VirtualSize += C->getSize(); if (C->hasData()) - RawSize = alignTo(VirtualSize, SectorSize); + RawSize = alignTo(VirtualSize, Config->FileAlignment); } if (VirtualSize > UINT32_MAX) error("section larger than 4 GiB: " + Sec->Name); @@ -1173,7 +1172,7 @@ if (RawSize != 0) Sec->Header.PointerToRawData = FileSize; RVA += alignTo(VirtualSize, PageSize); - FileSize += alignTo(RawSize, SectorSize); + FileSize += alignTo(RawSize, Config->FileAlignment); } SizeOfImage = alignTo(RVA, PageSize); } @@ -1240,7 +1239,7 @@ PE->ImageBase = Config->ImageBase; PE->SectionAlignment = PageSize; - PE->FileAlignment = SectorSize; + PE->FileAlignment = Config->FileAlignment; PE->MajorImageVersion = Config->MajorImageVersion; PE->MinorImageVersion = Config->MinorImageVersion; PE->MajorOperatingSystemVersion = Config->MajorOSVersion;