Commit fa575052 authored by Ard Biesheuvel's avatar Ard Biesheuvel Committed by Ingo Molnar
Browse files

x86/boot: Drop PE/COFF .reloc section



Ancient buggy EFI loaders may have required a .reloc section to be
present at some point in time, but this has not been true for a long
time so the .reloc section can just be dropped.

Signed-off-by: default avatarArd Biesheuvel <ardb@kernel.org>
Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
Link: https://lore.kernel.org/r/20230915171623.655440-16-ardb@google.com
parent efa089e6
Loading
Loading
Loading
Loading
+0 −20
Original line number Diff line number Diff line
@@ -155,26 +155,6 @@ section_table:
		IMAGE_SCN_MEM_READ		| \
		IMAGE_SCN_MEM_EXECUTE		# Characteristics

	#
	# The EFI application loader requires a relocation section
	# because EFI applications must be relocatable. The .reloc
	# offset & size fields are filled in by build.c.
	#
	.ascii	".reloc"
	.byte	0
	.byte	0
	.long	0
	.long	0
	.long	0				# SizeOfRawData
	.long	0				# PointerToRawData
	.long	0				# PointerToRelocations
	.long	0				# PointerToLineNumbers
	.word	0				# NumberOfRelocations
	.word	0				# NumberOfLineNumbers
	.long	IMAGE_SCN_CNT_INITIALIZED_DATA	| \
		IMAGE_SCN_MEM_READ		| \
		IMAGE_SCN_MEM_DISCARDABLE	# Characteristics

#ifdef CONFIG_EFI_MIXED
	#
	# The offset & size fields are filled in by build.c.
+2 −2
Original line number Diff line number Diff line
@@ -40,8 +40,8 @@ SECTIONS
		setup_sig = .;
		LONG(0x5a5aaa55)

		/* Reserve some extra space for the reloc and compat sections */
		setup_size = ALIGN(ABSOLUTE(.) + 64, 512);
		/* Reserve some extra space for the compat section */
		setup_size = ALIGN(ABSOLUTE(.) + 32, 512);
		setup_sects = ABSOLUTE(setup_size / 512);
	}

+5 −29
Original line number Diff line number Diff line
@@ -47,7 +47,6 @@ typedef unsigned int u32;
/* This must be large enough to hold the entire setup */
u8 buf[SETUP_SECT_MAX*512];

#define PECOFF_RELOC_RESERVE 0x20
#define PECOFF_COMPAT_RESERVE 0x20

static unsigned long efi32_pe_entry;
@@ -180,24 +179,13 @@ static void update_pecoff_section_header(char *section_name, u32 offset, u32 siz
	update_pecoff_section_header_fields(section_name, offset, size, size, offset);
}

static void update_pecoff_setup_and_reloc(unsigned int size)
static void update_pecoff_setup(unsigned int size)
{
	u32 setup_offset = 0x200;
	u32 reloc_offset = size - PECOFF_RELOC_RESERVE - PECOFF_COMPAT_RESERVE;
#ifdef CONFIG_EFI_MIXED
	u32 compat_offset = reloc_offset + PECOFF_RELOC_RESERVE;
#endif
	u32 setup_size = reloc_offset - setup_offset;
	u32 compat_offset = size - PECOFF_COMPAT_RESERVE;
	u32 setup_size = compat_offset - setup_offset;

	update_pecoff_section_header(".setup", setup_offset, setup_size);
	update_pecoff_section_header(".reloc", reloc_offset, PECOFF_RELOC_RESERVE);

	/*
	 * Modify .reloc section contents with a single entry. The
	 * relocation is applied to offset 10 of the relocation section.
	 */
	put_unaligned_le32(reloc_offset + 10, &buf[reloc_offset]);
	put_unaligned_le32(10, &buf[reloc_offset + 4]);

#ifdef CONFIG_EFI_MIXED
	update_pecoff_section_header(".compat", compat_offset, PECOFF_COMPAT_RESERVE);
@@ -214,21 +202,10 @@ static void update_pecoff_setup_and_reloc(unsigned int size)
#endif
}

static int reserve_pecoff_reloc_section(int c)
{
	/* Reserve 0x20 bytes for .reloc section */
	memset(buf+c, 0, PECOFF_RELOC_RESERVE);
	return PECOFF_RELOC_RESERVE;
}

#else

static inline void update_pecoff_setup_and_reloc(unsigned int size) {}
static inline void update_pecoff_setup(unsigned int size) {}

static inline int reserve_pecoff_reloc_section(int c)
{
	return 0;
}
#endif /* CONFIG_EFI_STUB */

static int reserve_pecoff_compat_section(int c)
@@ -307,7 +284,6 @@ int main(int argc, char ** argv)
	fclose(file);

	c += reserve_pecoff_compat_section(c);
	c += reserve_pecoff_reloc_section(c);

	/* Pad unused space with zeros */
	setup_sectors = (c + 511) / 512;
@@ -316,7 +292,7 @@ int main(int argc, char ** argv)
	i = setup_sectors*512;
	memset(buf+c, 0, i-c);

	update_pecoff_setup_and_reloc(i);
	update_pecoff_setup(i);

	/* Open and stat the kernel file */
	fd = open(argv[2], O_RDONLY);