Index: tools/lld/COFF/Writer.cpp =================================================================== --- tools/lld/COFF/Writer.cpp +++ tools/lld/COFF/Writer.cpp @@ -24,6 +24,7 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/Endian.h" #include "llvm/Support/FileOutputBuffer.h" +#include "llvm/Support/FormatVariadic.h" #include "llvm/Support/Parallel.h" #include "llvm/Support/RandomNumberGenerator.h" #include @@ -177,6 +178,9 @@ // by the loader. if (Header.SizeOfRawData == 0) return; + + // It is possible that this assignment could cause an overflow of the u32, + // but that should be caught by the FileSize check in OutputSection::run(). Header.PointerToRawData = Off; } @@ -295,6 +299,11 @@ setSectionPermissions(); createSymbolAndStringTable(); + if (FileSize > UINT32_MAX) + fatal(formatv( + "image size ({0}) exceeds maximum allowable size ({1})", + FileSize, UINT32_MAX)); + // We must do this before opening the output file, as it depends on being able // to read the contents of the existing output file. PreviousBuildId = loadExistingBuildId(Config->OutputFile); @@ -571,10 +580,8 @@ if (OutputSymtab.empty() && Strtab.empty()) return; - OutputSection *LastSection = OutputSections.back(); // We position the symbol table to be adjacent to the end of the last section. - uint64_t FileOff = LastSection->getFileOff() + - alignTo(LastSection->getRawSize(), SectorSize); + uint64_t FileOff = FileSize; PointerToSymbolTable = FileOff; FileOff += OutputSymtab.size() * sizeof(coff_symbol16); FileOff += 4 + Strtab.size(); @@ -590,7 +597,7 @@ SizeOfHeaders += Config->is64() ? sizeof(pe32plus_header) : sizeof(pe32_header); SizeOfHeaders = alignTo(SizeOfHeaders, SectorSize); - uint64_t RVA = 0x1000; // The first page is kept unmapped. + uint64_t RVA = PageSize; // The first page is kept unmapped. FileSize = SizeOfHeaders; // Move DISCARDABLE (or non-memory-mapped) sections to the end of file because // the loader cannot handle holes.