From eff0832b0fa01eaff18eb19a57ca5574dadbae9b Mon Sep 17 00:00:00 2001 From: Tess Strickland Date: Thu, 20 Feb 2025 08:09:53 -0800 Subject: [PATCH] [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 Commit-Queue: Tess Strickland --- pkg/dart2native/lib/dart2native_pe.dart | 35 ++++++++++++++----------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/pkg/dart2native/lib/dart2native_pe.dart b/pkg/dart2native/lib/dart2native_pe.dart index 9d2b8a11ee1..15a8fc5f260 100644 --- a/pkg/dart2native/lib/dart2native_pe.dart +++ b/pkg/dart2native/lib/dart2native_pe.dart @@ -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 write(RandomAccessFile output) async { @@ -311,13 +310,6 @@ class PortableExecutable { source, headers, fileHeaderOffset, sectionContentsOffset); } - Future _fileAlignSectionEnd(RandomAccessFile output) async { - final current = await output.position(); - final padding = - align(current, headers.optionalHeader.fileAlignment) - current; - await output.writeFrom(Uint8List(padding)); - } - Future 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(); } }