diff options
author | Michael Brown <mcb30@ipxe.org> | 2023-04-05 14:11:29 +0100 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2023-04-10 17:03:43 +0100 |
commit | 1f2a29edb016abcf22132c50f2ca7d360c1ef1d0 (patch) | |
tree | bd8c9a7eb98b63f8baf2b45db35e6f32fb6778e7 | |
parent | bf67db1ab56c202d5d78a4e2e17687c2a0b2b66e (diff) | |
download | ipxe-1f2a29edb016abcf22132c50f2ca7d360c1ef1d0.tar.gz |
[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.c | 50 |
1 files changed, 28 insertions, 22 deletions
diff --git a/src/util/elf2efi.c b/src/util/elf2efi.c index 893d4e30b..5e17751bd 100644 --- a/src/util/elf2efi.c +++ b/src/util/elf2efi.c @@ -636,6 +636,8 @@ static struct pe_section * process_section ( struct elf_file *elf, new->hdr.SizeOfRawData = section_filesz; if ( shdr->sh_type == SHT_PROGBITS ) { new->hdr.PointerToRawData = elf_lma ( elf, shdr, name ); + if ( new->hdr.PointerToRawData == 0 ) + new->hidden = 1; } /* Fill in section characteristics and update RVA limits */ @@ -1013,28 +1015,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 ( §ion->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 ) ) { @@ -1058,6 +1038,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 ( §ion->hdr, sizeof ( section->hdr ), + 1, pe ) != 1 ) { + perror ( "Could not write section header" ); + exit ( 1 ); + } + count++; + } + assert ( count == pe_header->nt.FileHeader.NumberOfSections ); } /** |