[efi] Shrink size of data directory in PE header

Hybrid bzImage and UEFI binaries (such as wimboot) require the PE
header to be kept as small as possible, since the bzImage header
starts at a fixed offset 0x1f1.

The EFI_IMAGE_OPTIONAL_HEADER structures in PeImage.h define an
optional header containing 16 data directory entries, of which the
last eight are unused in binaries that we create.  Shrink the data
directory to contain only the first eight entries, to minimise the
overall size of the PE header.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
pull/963/head
Michael Brown 2023-04-10 16:44:36 +01:00
parent 0d04635ef0
commit 1e4c3789e9
1 changed files with 13 additions and 4 deletions

View File

@ -168,6 +168,9 @@
*/ */
#define EFI_IMAGE_ALIGN 0x1000 #define EFI_IMAGE_ALIGN 0x1000
/** Number of data directory entries */
#define NUMBER_OF_DIRECTORY_ENTRIES 8
struct elf_file { struct elf_file {
void *data; void *data;
size_t len; size_t len;
@ -204,7 +207,11 @@ static struct pe_header efi_pe_header = {
.FileHeader = { .FileHeader = {
.TimeDateStamp = 0x10d1a884, .TimeDateStamp = 0x10d1a884,
.SizeOfOptionalHeader = .SizeOfOptionalHeader =
sizeof ( efi_pe_header.nt.OptionalHeader ), ( sizeof ( efi_pe_header.nt.OptionalHeader ) -
( ( EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES -
NUMBER_OF_DIRECTORY_ENTRIES ) *
sizeof ( efi_pe_header.nt.OptionalHeader.
DataDirectory[0] ) ) ),
.Characteristics = ( EFI_IMAGE_FILE_DLL | .Characteristics = ( EFI_IMAGE_FILE_DLL |
EFI_IMAGE_FILE_MACHINE | EFI_IMAGE_FILE_MACHINE |
EFI_IMAGE_FILE_EXECUTABLE_IMAGE ), EFI_IMAGE_FILE_EXECUTABLE_IMAGE ),
@ -217,8 +224,7 @@ static struct pe_header efi_pe_header = {
.FileAlignment = EFI_FILE_ALIGN, .FileAlignment = EFI_FILE_ALIGN,
.SizeOfImage = EFI_IMAGE_ALIGN, .SizeOfImage = EFI_IMAGE_ALIGN,
.SizeOfHeaders = sizeof ( efi_pe_header ), .SizeOfHeaders = sizeof ( efi_pe_header ),
.NumberOfRvaAndSizes = .NumberOfRvaAndSizes = NUMBER_OF_DIRECTORY_ENTRIES,
EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES,
}, },
}, },
}; };
@ -930,7 +936,10 @@ static void write_pe_file ( struct pe_header *pe_header,
} }
/* Write file header */ /* Write file header */
if ( fwrite ( pe_header, sizeof ( *pe_header ), 1, pe ) != 1 ) { if ( fwrite ( pe_header,
( offsetof ( typeof ( *pe_header ), nt.OptionalHeader ) +
pe_header->nt.FileHeader.SizeOfOptionalHeader ),
1, pe ) != 1 ) {
perror ( "Could not write PE header" ); perror ( "Could not write PE header" );
exit ( 1 ); exit ( 1 );
} }