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 ( 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 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue