mirror of
https://github.com/ipxe/ipxe
synced 2026-04-16 03:00:10 +03:00
[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>
This commit is contained in:
+28
-22
@@ -642,6 +642,8 @@ static struct pe_section * process_section ( struct elf_file *elf,
|
|||||||
if ( shdr->sh_type == SHT_PROGBITS ) {
|
if ( shdr->sh_type == SHT_PROGBITS ) {
|
||||||
if ( opts->hybrid ) {
|
if ( opts->hybrid ) {
|
||||||
new->hdr.PointerToRawData = elf_lma ( elf, shdr, name );
|
new->hdr.PointerToRawData = elf_lma ( elf, shdr, name );
|
||||||
|
if ( new->hdr.PointerToRawData == 0 )
|
||||||
|
new->hidden = 1;
|
||||||
} else {
|
} else {
|
||||||
new->hdr.PointerToRawData = PTRD_AUTO;
|
new->hdr.PointerToRawData = PTRD_AUTO;
|
||||||
}
|
}
|
||||||
@@ -1024,28 +1026,6 @@ static void write_pe_file ( struct pe_header *pe_header,
|
|||||||
section->fixup ( section );
|
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 */
|
/* Write sections */
|
||||||
for ( section = pe_sections ; section ; section = section->next ) {
|
for ( section = pe_sections ; section ; section = section->next ) {
|
||||||
if ( section->hdr.PointerToRawData & ( EFI_FILE_ALIGN - 1 ) ) {
|
if ( section->hdr.PointerToRawData & ( EFI_FILE_ALIGN - 1 ) ) {
|
||||||
@@ -1069,6 +1049,32 @@ static void write_pe_file ( struct pe_header *pe_header,
|
|||||||
exit ( 1 );
|
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 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user