From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Mon, 15 Feb 2021 14:58:06 +0100 Subject: [PATCH] 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 Signed-off-by: Javier Martinez Canillas Reviewed-by: Daniel Kiper --- util/mkimage.c | 141 +++++++++++++++++++++++++++++++-------------------------- 1 file changed, 76 insertions(+), 65 deletions(-) diff --git a/util/mkimage.c b/util/mkimage.c index f22b398d9..0f5ae2a76 100644 --- a/util/mkimage.c +++ b/util/mkimage.c @@ -771,6 +771,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. @@ -1245,17 +1277,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; @@ -1264,17 +1292,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, - image_target->section_align); + 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, - image_target->section_align); - 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); @@ -1307,18 +1330,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); @@ -1338,58 +1360,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); - - 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); + 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); + + 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;