Index: tools/lld/COFF/Writer.cpp =================================================================== --- tools/lld/COFF/Writer.cpp +++ tools/lld/COFF/Writer.cpp @@ -177,6 +177,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 +298,10 @@ setSectionPermissions(); createSymbolAndStringTable(); + if (FileSize > UINT32_MAX) + fatal("image size (" + Twine::utohexstr(FileSize) + ") " + + "exceeds maximum allowable size (" + Twine::utohexstr(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 +578,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 +595,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.