mirror of https://github.com/ipxe/ipxe.git
[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>pull/1082/head
parent
b30a0987e2
commit
cc858acd32
|
@ -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 ( §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 ) ) {
|
||||
|
@ -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 ( §ion->hdr, sizeof ( section->hdr ),
|
||||
1, pe ) != 1 ) {
|
||||
perror ( "Could not write section header" );
|
||||
exit ( 1 );
|
||||
}
|
||||
count++;
|
||||
}
|
||||
assert ( count == pe_header->nt.FileHeader.NumberOfSections );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue