Align final section to file alignment, not to virtual image size#124984
Align final section to file alignment, not to virtual image size#124984jkoritzinsky wants to merge 1 commit intodotnet:mainfrom
Conversation
|
Tagging subscribers to this area: @agocke, @dotnet/ilc-contrib |
There was a problem hiding this comment.
Pull request overview
This PR adjusts how PEObjectWriter determines the final on-disk size of emitted PE files so the file is padded only to file alignment, rather than being extended to the PE’s virtual image size (SizeOfImage), addressing reported self-contained app size regressions.
Changes:
- Stop padding the output stream length to
sizeOfImage. - Pad the final file length to
_peFileAlignmentinstead.
| Debug.Assert(outputFileStream.Position <= sizeOfImage); | ||
| outputFileStream.SetLength(sizeOfImage); | ||
| // Ensure that the final file size is aligned to file alignment. | ||
| long paddedSize = AlignmentHelper.AlignUp((int)outputFileStream.Position, (int)_peFileAlignment); |
There was a problem hiding this comment.
outputFileStream.Position is a long, but it’s cast to int before calling AlignmentHelper.AlignUp. If the output ever exceeds 2GB, this unchecked cast can wrap negative and lead to an incorrect paddedSize (potential truncation or an exception from SetLength). Consider computing the alignment using 64-bit arithmetic (or at least using a checked cast and throwing a clear error when the file is too large).
| long paddedSize = AlignmentHelper.AlignUp((int)outputFileStream.Position, (int)_peFileAlignment); | |
| long position = outputFileStream.Position; | |
| long fileAlignment = _peFileAlignment; | |
| Debug.Assert(fileAlignment > 0); | |
| long paddedSize = position; | |
| if (fileAlignment > 0) | |
| { | |
| long remainder = position % fileAlignment; | |
| if (remainder != 0) | |
| { | |
| paddedSize = position + (fileAlignment - remainder); | |
| } | |
| } |
| // Ensure that the final file size is aligned to file alignment. | ||
| long paddedSize = AlignmentHelper.AlignUp((int)outputFileStream.Position, (int)_peFileAlignment); | ||
|
|
||
| outputFileStream.SetLength(paddedSize); |
There was a problem hiding this comment.
The previous Debug.Assert(outputFileStream.Position <= sizeOfImage) was a useful invariant check that the writer didn’t emit more raw bytes than the SizeOfImage value recorded in the PE optional header. Even though the file should no longer be padded to sizeOfImage, it would still be valuable to keep an assertion (or equivalent validation) here to catch layout/emit bugs that would otherwise produce an invalid PE.
filipnavara
left a comment
There was a problem hiding this comment.
Looks good to me in principle.
Fixes #124980