| From f60ba9e5945892e835e53f0619406d96002f7f70 Mon Sep 17 00:00:00 2001 |
| From: Peter Jones <pjones@redhat.com> |
| 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 <pjones@redhat.com> |
| Signed-off-by: Javier Martinez Canillas <javierm@redhat.com> |
| Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> |
| Signed-off-by: Stefan SΓΈrensen <stefan.sorensen@spectralink.com> |
| --- |
| util/mkimage.c | 143 +++++++++++++++++++++++++++++++-------------------------- |
| 1 file changed, 77 insertions(+), 66 deletions(-) |
| |
| diff --git a/util/mkimage.c b/util/mkimage.c |
| index 853a521..8b475a6 100644 |
| --- a/util/mkimage.c |
| +++ b/util/mkimage.c |
| @@ -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); |
| - |
| - 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); |
| - |
| - 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); |
| + 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); |
| + |
| free (core_img); |
| core_img = pe_img; |
| core_size = pe_size; |
| -- |
| 2.14.2 |
| |