[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>
diff --git a/src/util/elf2efi.c b/src/util/elf2efi.c
index bacc08d..7c3e0b1 100644
--- a/src/util/elf2efi.c
+++ b/src/util/elf2efi.c
@@ -173,6 +173,9 @@
 /** Set PointerToRawData automatically */
 #define PTRD_AUTO 0xffffffffUL
 
+/** Number of data directory entries */
+#define NUMBER_OF_DIRECTORY_ENTRIES 8
+
 struct elf_file {
 	void *data;
 	size_t len;
@@ -209,7 +212,11 @@
 		.FileHeader = {
 			.TimeDateStamp = 0x10d1a884,
 			.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 |
 					     EFI_IMAGE_FILE_MACHINE |
 					     EFI_IMAGE_FILE_EXECUTABLE_IMAGE ),
@@ -222,8 +229,7 @@
 			.FileAlignment = EFI_FILE_ALIGN,
 			.SizeOfImage = EFI_IMAGE_ALIGN,
 			.SizeOfHeaders = sizeof ( efi_pe_header ),
-			.NumberOfRvaAndSizes =
-				EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES,
+			.NumberOfRvaAndSizes = NUMBER_OF_DIRECTORY_ENTRIES,
 		},
 	},
 };
@@ -1029,7 +1035,10 @@
 		eprintf ( "Could not rewind: %s\n", strerror ( errno ) );
 		exit ( 1 );
 	}
-	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" );
 		exit ( 1 );
 	}