]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[efi] Do not align VirtualSize for .reloc and .debug sections
authorMichael Brown <mcb30@ipxe.org>
Tue, 11 Jan 2022 15:27:14 +0000 (15:27 +0000)
committerMichael Brown <mcb30@ipxe.org>
Tue, 11 Jan 2022 15:27:14 +0000 (15:27 +0000)
As of commit f1e9e2b ("[efi] Align EFI image sections by page size"),
the VirtualSize fields for the .reloc and .debug sections have been
rounded up to the (4kB) image alignment.  This breaks the PE
relocation logic in the UEFI shim, which requires the VirtualSize
field to exactly match the size as recorded in the data directory.

Fix by setting the VirtualSize field to the unaligned size of the
section, as is already done for normal PE sections (i.e. those other
than .reloc and .debug).

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

index 8af53aeb41d464ee4a02b9231fddfc40627514a4..08d790f1e5df1a124f11d5105292e2c74053e069 100644 (file)
@@ -753,15 +753,13 @@ static struct pe_section *
 create_reloc_section ( struct pe_header *pe_header,
                       struct pe_relocs *pe_reltab ) {
        struct pe_section *reloc;
-       size_t section_rawsz;
        size_t section_memsz;
        size_t section_filesz;
        EFI_IMAGE_DATA_DIRECTORY *relocdir;
 
        /* Allocate PE section */
-       section_rawsz = output_pe_reltab ( pe_reltab, NULL );
-       section_filesz = efi_file_align ( section_rawsz );
-       section_memsz = efi_image_align ( section_rawsz );
+       section_memsz = output_pe_reltab ( pe_reltab, NULL );
+       section_filesz = efi_file_align ( section_memsz );
        reloc = xmalloc ( sizeof ( *reloc ) + section_filesz );
        memset ( reloc, 0, sizeof ( *reloc ) + section_filesz );
 
@@ -782,11 +780,12 @@ create_reloc_section ( struct pe_header *pe_header,
        /* Update file header details */
        pe_header->nt.FileHeader.NumberOfSections++;
        pe_header->nt.OptionalHeader.SizeOfHeaders += sizeof ( reloc->hdr );
-       pe_header->nt.OptionalHeader.SizeOfImage += section_memsz;
+       pe_header->nt.OptionalHeader.SizeOfImage +=
+               efi_image_align ( section_memsz );
        relocdir = &(pe_header->nt.OptionalHeader.DataDirectory
                     [EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC]);
        relocdir->VirtualAddress = reloc->hdr.VirtualAddress;
-       relocdir->Size = section_rawsz;
+       relocdir->Size = section_memsz;
 
        return reloc;
 }
@@ -824,8 +823,8 @@ create_debug_section ( struct pe_header *pe_header, const char *filename ) {
        } *contents;
 
        /* Allocate PE section */
-       section_memsz = efi_image_align ( sizeof ( *contents ) );
-       section_filesz = efi_file_align ( sizeof ( *contents ) );
+       section_memsz = sizeof ( *contents );
+       section_filesz = efi_file_align ( section_memsz );
        debug = xmalloc ( sizeof ( *debug ) + section_filesz );
        memset ( debug, 0, sizeof ( *debug ) + section_filesz );
        contents = ( void * ) debug->contents;
@@ -857,7 +856,8 @@ create_debug_section ( struct pe_header *pe_header, const char *filename ) {
        /* Update file header details */
        pe_header->nt.FileHeader.NumberOfSections++;
        pe_header->nt.OptionalHeader.SizeOfHeaders += sizeof ( debug->hdr );
-       pe_header->nt.OptionalHeader.SizeOfImage += section_memsz;
+       pe_header->nt.OptionalHeader.SizeOfImage +=
+               efi_image_align ( section_memsz );
        debugdir = &(pe_header->nt.OptionalHeader.DataDirectory
                     [EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);
        debugdir->VirtualAddress = debug->hdr.VirtualAddress;