[dart2native] Remove unnecessary error in PE creation.
After writing the new PE header and original section contents of the dartaotruntime PE executable, pad to the expected file offset of the new section being added, not just to file alignment. Also fixes a case where the new section's file offset returned from appendSnapshotAndWrite could be incorrect if the header size changed, which causes the file offsets for all sections, including the new one, to be updated. TEST=pkg/dartdev/test/commands/compile_test.dart Change-Id: I060176f6771e9138f8d1a99590d455fc76bb573e Cq-Include-Trybots: luci.dart.try:pkg-win-release-try,pkg-win-release-arm64-try Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/410720 Reviewed-by: Slava Egorov <vegorov@google.com> Commit-Queue: Tess Strickland <sstrickl@google.com>
This commit is contained in:
committed by
Commit Queue
parent
2c62efb890
commit
eff0832b0f
@@ -218,9 +218,8 @@ class CoffHeaders {
|
||||
|
||||
// Add a section header for the new "snapshot" section with the given length.
|
||||
//
|
||||
// Returns offset at which the section is expected to be located in the
|
||||
// file.
|
||||
int addSnapshotSectionHeader(int length) {
|
||||
// Returns the new section header.
|
||||
CoffSectionHeader addSnapshotSectionHeader(int length) {
|
||||
final oldHeadersSize = optionalHeader.headersSize;
|
||||
final address =
|
||||
align(sectionTable.addressEnd, optionalHeader.sectionAlignment);
|
||||
@@ -270,7 +269,7 @@ class CoffHeaders {
|
||||
newHeader.virtualAddress + newHeader.virtualSize,
|
||||
optionalHeader.sectionAlignment);
|
||||
|
||||
return offset;
|
||||
return newHeader;
|
||||
}
|
||||
|
||||
Future<void> write(RandomAccessFile output) async {
|
||||
@@ -311,13 +310,6 @@ class PortableExecutable {
|
||||
source, headers, fileHeaderOffset, sectionContentsOffset);
|
||||
}
|
||||
|
||||
Future<void> _fileAlignSectionEnd(RandomAccessFile output) async {
|
||||
final current = await output.position();
|
||||
final padding =
|
||||
align(current, headers.optionalHeader.fileAlignment) - current;
|
||||
await output.writeFrom(Uint8List(padding));
|
||||
}
|
||||
|
||||
Future<void> appendSnapshotAndWrite(File output, File snapshot) async {
|
||||
final stream = await output.open(mode: FileMode.write);
|
||||
// Write MS-DOS stub.
|
||||
@@ -325,22 +317,33 @@ class PortableExecutable {
|
||||
// Write headers with additional snapshot section.
|
||||
final snapshotBytes = await snapshot.readAsBytes();
|
||||
final oldOffsetEnd = headers.sectionTable.offsetEnd;
|
||||
final expectedSnapshotOffset =
|
||||
final snapshotSectionHeader =
|
||||
headers.addSnapshotSectionHeader(snapshotBytes.length);
|
||||
await headers.write(stream);
|
||||
// Write original section contents with alignment padding.
|
||||
// Write original section contents.
|
||||
await stream.writeFrom(source, sourceSectionContentsOffset, oldOffsetEnd);
|
||||
await _fileAlignSectionEnd(stream);
|
||||
var currentOffset = await stream.position();
|
||||
// Pad the original contents to the file offset of the new section.
|
||||
final expectedSnapshotOffset = snapshotSectionHeader.fileOffset;
|
||||
if (currentOffset < expectedSnapshotOffset) {
|
||||
final padding = expectedSnapshotOffset - currentOffset;
|
||||
await stream.writeFrom(Uint8List(padding));
|
||||
currentOffset = await stream.position();
|
||||
}
|
||||
// Verify that snapshot section will start at the expected offset
|
||||
// and throw an error otherwise.
|
||||
final currentOffset = await stream.position();
|
||||
if (expectedSnapshotOffset != currentOffset) {
|
||||
throw StateError('Unexpected snapshot section offset: '
|
||||
'expected $expectedSnapshotOffset, got $currentOffset');
|
||||
}
|
||||
// Write snapshot with alignment padding.
|
||||
await stream.writeFrom(snapshotBytes);
|
||||
await _fileAlignSectionEnd(stream);
|
||||
currentOffset = await stream.position();
|
||||
final padding = align(currentOffset, headers.optionalHeader.fileAlignment) -
|
||||
currentOffset;
|
||||
if (padding > 0) {
|
||||
await stream.writeFrom(Uint8List(padding));
|
||||
}
|
||||
await stream.close();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user