summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Brown2023-11-22 16:38:22 +0100
committerMichael Brown2023-11-23 14:37:47 +0100
commitcc858acd3205b18934ffff19ac55f8987e9c6135 (patch)
tree36c4e8eea840c42e3c803bf7d04407ad03ae4858
parent[efi] Use load memory address as file offset for hybrid binaries (diff)
downloadipxe-cc858acd3205b18934ffff19ac55f8987e9c6135.tar.gz
ipxe-cc858acd3205b18934ffff19ac55f8987e9c6135.tar.xz
ipxe-cc858acd3205b18934ffff19ac55f8987e9c6135.zip
[efi] Write out PE header only after writing sections
Hybrid bzImage and UEFI binaries (such as wimboot) include a bzImage header within a section starting at offset zero, with the PE header effectively occupying unused space within this section. Allow for this by treating a section placed at offset zero as hidden, and by deferring the writing of the PE header until after the output sections have been written. Signed-off-by: Michael Brown <mcb30@ipxe.org>
-rw-r--r--src/util/elf2efi.c50
1 files changed, 28 insertions, 22 deletions
diff --git a/src/util/elf2efi.c b/src/util/elf2efi.c
index 682580f4..a8074915 100644
--- a/src/util/elf2efi.c
+++ b/src/util/elf2efi.c
@@ -642,6 +642,8 @@ static struct pe_section * process_section ( struct elf_file *elf,
if ( shdr->sh_type == SHT_PROGBITS ) {
if ( opts->hybrid ) {
new->hdr.PointerToRawData = elf_lma ( elf, shdr, name );
+ if ( new->hdr.PointerToRawData == 0 )
+ new->hidden = 1;
} else {
new->hdr.PointerToRawData = PTRD_AUTO;
}
@@ -1024,28 +1026,6 @@ static void write_pe_file ( struct pe_header *pe_header,
section->fixup ( section );
}
- /* Write file header */
- 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 );
- }
-
- /* Write section headers */
- for ( section = pe_sections ; section ; section = section->next ) {
- if ( section->hidden )
- continue;
- if ( fwrite ( &section->hdr, sizeof ( section->hdr ),
- 1, pe ) != 1 ) {
- perror ( "Could not write section header" );
- exit ( 1 );
- }
- count++;
- }
- assert ( count == pe_header->nt.FileHeader.NumberOfSections );
-
/* Write sections */
for ( section = pe_sections ; section ; section = section->next ) {
if ( section->hdr.PointerToRawData & ( EFI_FILE_ALIGN - 1 ) ) {
@@ -1069,6 +1049,32 @@ static void write_pe_file ( struct pe_header *pe_header,
exit ( 1 );
}
}
+
+ /* Write file header */
+ if ( fseek ( pe, 0, SEEK_SET ) != 0 ) {
+ eprintf ( "Could not rewind: %s\n", strerror ( errno ) );
+ exit ( 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 );
+ }
+
+ /* Write section headers */
+ for ( section = pe_sections ; section ; section = section->next ) {
+ if ( section->hidden )
+ continue;
+ if ( fwrite ( &section->hdr, sizeof ( section->hdr ),
+ 1, pe ) != 1 ) {
+ perror ( "Could not write section header" );
+ exit ( 1 );
+ }
+ count++;
+ }
+ assert ( count == pe_header->nt.FileHeader.NumberOfSections );
}
/**