util/mkimage: Refactor section setup to use a helper

Add a init_pe_section() helper function to setup PE sections. This makes
the code simpler and easier to read.

Signed-off-by: Peter Jones <pjones@redhat.com>
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
This commit is contained in:
Peter Jones 2021-02-15 14:58:06 +01:00 committed by Daniel Kiper
parent ff406eff25
commit f60ba9e594

View File

@ -816,6 +816,38 @@ grub_install_get_image_targets_string (void)
return formats;
}
/*
* The image_target parameter is used by the grub_host_to_target32() macro.
*/
static struct grub_pe32_section_table *
init_pe_section(const struct grub_install_image_target_desc *image_target,
struct grub_pe32_section_table *section,
const char * const name,
grub_uint32_t *vma, grub_uint32_t vsz, grub_uint32_t valign,
grub_uint32_t *rda, grub_uint32_t rsz,
grub_uint32_t characteristics)
{
size_t len = strlen (name);
if (len > sizeof (section->name))
grub_util_error (_("section name %s length is bigger than %lu"),
name, (unsigned long) sizeof (section->name));
memcpy (section->name, name, len);
section->virtual_address = grub_host_to_target32 (*vma);
section->virtual_size = grub_host_to_target32 (vsz);
(*vma) = ALIGN_UP (*vma + vsz, valign);
section->raw_data_offset = grub_host_to_target32 (*rda);
section->raw_data_size = grub_host_to_target32 (rsz);
(*rda) = ALIGN_UP (*rda + rsz, GRUB_PE32_FILE_ALIGNMENT);
section->characteristics = grub_host_to_target32 (characteristics);
return section + 1;
}
/*
* tmp_ is just here so the compiler knows we'll never derefernce a NULL.
* It should get fully optimized away.
@ -1257,17 +1289,13 @@ grub_install_generate_image (const char *dir, const char *prefix,
break;
case IMAGE_EFI:
{
void *pe_img;
grub_uint8_t *header;
void *sections;
char *pe_img, *header;
struct grub_pe32_section_table *section;
size_t scn_size;
size_t pe_size;
grub_uint32_t vma, raw_data;
size_t pe_size, header_size;
struct grub_pe32_coff_header *c;
struct grub_pe32_section_table *text_section, *data_section;
struct grub_pe32_section_table *mods_section, *reloc_section;
static const grub_uint8_t stub[] = GRUB_PE32_MSDOS_STUB;
int header_size;
int reloc_addr;
struct grub_pe32_optional_header *o32 = NULL;
struct grub_pe64_optional_header *o64 = NULL;
@ -1276,17 +1304,12 @@ grub_install_generate_image (const char *dir, const char *prefix,
else
header_size = EFI64_HEADER_SIZE;
reloc_addr = ALIGN_UP (header_size + core_size,
GRUB_PE32_FILE_ALIGNMENT);
vma = raw_data = header_size;
pe_size = ALIGN_UP (header_size + core_size, GRUB_PE32_FILE_ALIGNMENT) +
ALIGN_UP (layout.reloc_size, GRUB_PE32_FILE_ALIGNMENT);
header = pe_img = xcalloc (1, pe_size);
pe_size = ALIGN_UP (reloc_addr + layout.reloc_size,
GRUB_PE32_FILE_ALIGNMENT);
pe_img = xmalloc (reloc_addr + layout.reloc_size);
memset (pe_img, 0, header_size);
memcpy ((char *) pe_img + header_size, core_img, core_size);
memset ((char *) pe_img + header_size + core_size, 0, reloc_addr - (header_size + core_size));
memcpy ((char *) pe_img + reloc_addr, layout.reloc_section, layout.reloc_size);
header = pe_img;
memcpy (pe_img + raw_data, core_img, core_size);
/* The magic. */
memcpy (header, stub, GRUB_PE32_MSDOS_STUB_SIZE);
@ -1319,18 +1342,17 @@ grub_install_generate_image (const char *dir, const char *prefix,
o32->magic = grub_host_to_target16 (GRUB_PE32_PE32_MAGIC);
o32->data_base = grub_host_to_target32 (header_size + layout.exec_size);
sections = o32 + 1;
section = (struct grub_pe32_section_table *)(o32 + 1);
}
else
{
c->optional_header_size = grub_host_to_target16 (sizeof (struct grub_pe64_optional_header));
o64 = (struct grub_pe64_optional_header *)
(header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE +
sizeof (struct grub_pe32_coff_header));
o64->magic = grub_host_to_target16 (GRUB_PE32_PE64_MAGIC);
sections = o64 + 1;
section = (struct grub_pe32_section_table *)(o64 + 1);
}
PE_OHDR (o32, o64, header_size) = grub_host_to_target32 (header_size);
@ -1350,58 +1372,47 @@ grub_install_generate_image (const char *dir, const char *prefix,
PE_OHDR (o32, o64, num_data_directories) = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES);
/* The sections. */
PE_OHDR (o32, o64, code_base) = grub_host_to_target32 (header_size);
PE_OHDR (o32, o64, code_base) = grub_host_to_target32 (vma);
PE_OHDR (o32, o64, code_size) = grub_host_to_target32 (layout.exec_size);
text_section = sections;
strcpy (text_section->name, ".text");
text_section->virtual_size = grub_host_to_target32 (layout.exec_size);
text_section->virtual_address = grub_host_to_target32 (header_size);
text_section->raw_data_size = grub_host_to_target32 (layout.exec_size);
text_section->raw_data_offset = grub_host_to_target32 (header_size);
text_section->characteristics = grub_cpu_to_le32_compile_time (
GRUB_PE32_SCN_CNT_CODE
| GRUB_PE32_SCN_MEM_EXECUTE
| GRUB_PE32_SCN_MEM_READ);
section = init_pe_section (image_target, section, ".text",
&vma, layout.exec_size,
image_target->section_align,
&raw_data, layout.exec_size,
GRUB_PE32_SCN_CNT_CODE |
GRUB_PE32_SCN_MEM_EXECUTE |
GRUB_PE32_SCN_MEM_READ);
scn_size = ALIGN_UP (layout.kernel_size - layout.exec_size, GRUB_PE32_FILE_ALIGNMENT);
PE_OHDR (o32, o64, data_size) = grub_host_to_target32 (scn_size +
ALIGN_UP (total_module_size,
GRUB_PE32_FILE_ALIGNMENT));
data_section = text_section + 1;
strcpy (data_section->name, ".data");
data_section->virtual_size = grub_host_to_target32 (layout.kernel_size - layout.exec_size);
data_section->virtual_address = grub_host_to_target32 (header_size + layout.exec_size);
data_section->raw_data_size = grub_host_to_target32 (layout.kernel_size - layout.exec_size);
data_section->raw_data_offset = grub_host_to_target32 (header_size + layout.exec_size);
data_section->characteristics
= grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_CNT_INITIALIZED_DATA
| GRUB_PE32_SCN_MEM_READ
| GRUB_PE32_SCN_MEM_WRITE);
section = init_pe_section (image_target, section, ".data",
&vma, scn_size, image_target->section_align,
&raw_data, scn_size,
GRUB_PE32_SCN_CNT_INITIALIZED_DATA |
GRUB_PE32_SCN_MEM_READ |
GRUB_PE32_SCN_MEM_WRITE);
mods_section = data_section + 1;
strcpy (mods_section->name, "mods");
mods_section->virtual_size = grub_host_to_target32 (reloc_addr - layout.kernel_size - header_size);
mods_section->virtual_address = grub_host_to_target32 (header_size + layout.kernel_size + layout.bss_size);
mods_section->raw_data_size = grub_host_to_target32 (reloc_addr - layout.kernel_size - header_size);
mods_section->raw_data_offset = grub_host_to_target32 (header_size + layout.kernel_size);
mods_section->characteristics
= grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_CNT_INITIALIZED_DATA
| GRUB_PE32_SCN_MEM_READ
| GRUB_PE32_SCN_MEM_WRITE);
scn_size = pe_size - layout.reloc_size - raw_data;
section = init_pe_section (image_target, section, "mods",
&vma, scn_size, image_target->section_align,
&raw_data, scn_size,
GRUB_PE32_SCN_CNT_INITIALIZED_DATA |
GRUB_PE32_SCN_MEM_READ |
GRUB_PE32_SCN_MEM_WRITE);
scn_size = layout.reloc_size;
PE_OHDR (o32, o64, base_relocation_table.rva) = grub_host_to_target32 (vma);
PE_OHDR (o32, o64, base_relocation_table.size) = grub_host_to_target32 (scn_size);
memcpy (pe_img + raw_data, layout.reloc_section, scn_size);
init_pe_section (image_target, section, ".reloc",
&vma, scn_size, image_target->section_align,
&raw_data, scn_size,
GRUB_PE32_SCN_CNT_INITIALIZED_DATA |
GRUB_PE32_SCN_MEM_DISCARDABLE |
GRUB_PE32_SCN_MEM_READ);
PE_OHDR (o32, o64, base_relocation_table.rva) = grub_host_to_target32 (reloc_addr);
PE_OHDR (o32, o64, base_relocation_table.size) = grub_host_to_target32 (layout.reloc_size);
reloc_section = mods_section + 1;
strcpy (reloc_section->name, ".reloc");
reloc_section->virtual_size = grub_host_to_target32 (layout.reloc_size);
reloc_section->virtual_address = grub_host_to_target32 (reloc_addr + layout.bss_size);
reloc_section->raw_data_size = grub_host_to_target32 (layout.reloc_size);
reloc_section->raw_data_offset = grub_host_to_target32 (reloc_addr);
reloc_section->characteristics
= grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_CNT_INITIALIZED_DATA
| GRUB_PE32_SCN_MEM_DISCARDABLE
| GRUB_PE32_SCN_MEM_READ);
free (core_img);
core_img = pe_img;
core_size = pe_size;