]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[efi] Allow for sections to be excluded from the generated PE file
authorMichael Brown <mcb30@ipxe.org>
Mon, 10 Apr 2023 15:55:28 +0000 (16:55 +0100)
committerMichael Brown <mcb30@ipxe.org>
Mon, 10 Apr 2023 16:02:45 +0000 (17:02 +0100)
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.  This section
should not appear as a named section in the resulting PE file.

Allow for the existence of hidden sections that do not result in a
section header being written to the PE file.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/util/elf2efi.c

index 61ac0e277fde03b5ffb3fda018a8238deca35051..5b3e785f53bb7b63a7973fe39da5034aa77c4c46 100644 (file)
@@ -181,6 +181,7 @@ struct pe_section {
        struct pe_section *next;
        EFI_IMAGE_SECTION_HEADER hdr;
        void ( * fixup ) ( struct pe_section *section );
+       int hidden;
        uint8_t contents[0];
 };
 
@@ -641,10 +642,12 @@ static struct pe_section * process_section ( struct elf_file *elf,
        /* Update RVA limits */
        start = new->hdr.VirtualAddress;
        end = ( start + new->hdr.Misc.VirtualSize );
-       if ( ( ! *applicable_start ) || ( *applicable_start >= start ) )
-               *applicable_start = start;
-       if ( *applicable_end < end )
-               *applicable_end = end;
+       if ( ! new->hidden ) {
+               if ( ( ! *applicable_start ) || ( *applicable_start >= start ) )
+                       *applicable_start = start;
+               if ( *applicable_end < end )
+                       *applicable_end = end;
+       }
        if ( data_start < code_end )
                data_start = code_end;
        if ( data_mid < data_start )
@@ -664,8 +667,11 @@ static struct pe_section * process_section ( struct elf_file *elf,
                ( data_end - data_mid );
 
        /* Update remaining file header fields */
-       pe_header->nt.FileHeader.NumberOfSections++;
-       pe_header->nt.OptionalHeader.SizeOfHeaders += sizeof ( new->hdr );
+       if ( ! new->hidden ) {
+               pe_header->nt.FileHeader.NumberOfSections++;
+               pe_header->nt.OptionalHeader.SizeOfHeaders +=
+                       sizeof ( new->hdr );
+       }
        pe_header->nt.OptionalHeader.SizeOfImage =
                efi_image_align ( data_end );
 
@@ -935,6 +941,7 @@ static void write_pe_file ( struct pe_header *pe_header,
                            FILE *pe ) {
        struct pe_section *section;
        unsigned long fpos = 0;
+       unsigned int count = 0;
 
        /* Align length of headers */
        fpos = pe_header->nt.OptionalHeader.SizeOfHeaders =
@@ -962,12 +969,16 @@ static void write_pe_file ( struct pe_header *pe_header,
 
        /* 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 ) {