}
}
-static Elf_Addr
-finish_reloc_translation (struct translate_context *ctx, void **out,
+static void
+finish_reloc_translation (struct translate_context *ctx,
+ struct grub_mkimage_layout *layout,
const struct grub_install_image_target_desc *image_target)
{
ctx->current_address = add_fixup_entry (&ctx->lst, 0, 0, 1, ctx->current_address, image_target);
{
grub_uint8_t *ptr;
- ptr = *out = xmalloc (ctx->current_address);
+ layout->reloc_section = ptr = xmalloc (ctx->current_address);
for (ctx->lst = ctx->lst0; ctx->lst; ctx->lst = ctx->lst->next)
if (ctx->lst->state)
{
memcpy (ptr, &ctx->lst->b, grub_target_to_host32 (ctx->lst->b.block_size));
ptr += grub_target_to_host32 (ctx->lst->b.block_size);
}
- assert ((ctx->current_address + (grub_uint8_t *) *out) == ptr);
+ assert ((ctx->current_address + (grub_uint8_t *) layout->reloc_section) == ptr);
}
for (ctx->lst = ctx->lst0; ctx->lst; )
ctx->lst = next;
}
- return ctx->current_address;
+ layout->reloc_size = ctx->current_address;
}
static void
}
/* Make a .reloc section. */
-static Elf_Addr
-make_reloc_section (Elf_Ehdr *e, void **out,
+static void
+make_reloc_section (Elf_Ehdr *e, struct grub_mkimage_layout *layout,
Elf_Addr *section_addresses, Elf_Shdr *sections,
Elf_Half section_entsize, Elf_Half num_sections,
const char *strtab,
translate_reloc_jumpers (&ctx, jumpers, njumpers,
image_target);
- return finish_reloc_translation (&ctx, out, image_target);
+ finish_reloc_translation (&ctx, layout, image_target);
}
/* Determine if this section is a text section. Return false if this
SUFFIX (locate_sections) (const char *kernel_path,
Elf_Shdr *sections, Elf_Half section_entsize,
Elf_Half num_sections, const char *strtab,
- size_t *exec_size, size_t *kernel_sz,
- size_t *all_align,
+ struct grub_mkimage_layout *layout,
const struct grub_install_image_target_desc *image_target)
{
int i;
Elf_Addr *section_addresses;
Elf_Shdr *s;
- *all_align = 1;
+ layout->align = 1;
/* Page-aligning simplifies relocation handling. */
if (image_target->elf_target == EM_AARCH64)
- *all_align = 4096;
+ layout->align = 4096;
section_addresses = xmalloc (sizeof (*section_addresses) * num_sections);
memset (section_addresses, 0, sizeof (*section_addresses) * num_sections);
i < num_sections;
i++, s = (Elf_Shdr *) ((char *) s + section_entsize))
if ((grub_target_to_host (s->sh_flags) & SHF_ALLOC)
- && grub_host_to_target32 (s->sh_addralign) > *all_align)
- *all_align = grub_host_to_target32 (s->sh_addralign);
+ && grub_host_to_target32 (s->sh_addralign) > layout->align)
+ layout->align = grub_host_to_target32 (s->sh_addralign);
/* .text */
current_address = ALIGN_UP (current_address + image_target->vaddr_offset,
image_target->section_align)
- image_target->vaddr_offset;
- *exec_size = current_address;
+ layout->exec_size = current_address;
/* .data */
for (i = 0, s = sections;
current_address = ALIGN_UP (current_address + image_target->vaddr_offset,
image_target->section_align) - image_target->vaddr_offset;
- *kernel_sz = current_address;
+ layout->kernel_size = current_address;
return section_addresses;
}
char *
-SUFFIX (grub_mkimage_load_image) (const char *kernel_path, size_t *exec_size,
- size_t *kernel_sz, size_t *bss_size,
- size_t total_module_size, grub_uint64_t *start,
- void **reloc_section, size_t *reloc_size,
- size_t *align,
+SUFFIX (grub_mkimage_load_image) (const char *kernel_path,
+ size_t total_module_size,
+ struct grub_mkimage_layout *layout,
const struct grub_install_image_target_desc *image_target)
{
char *kernel_img, *out_img;
Elf_Off section_offset;
Elf_Half section_entsize;
grub_size_t kernel_size;
- grub_size_t ia64jmp_off = 0, tramp_off = 0, ia64_got_off = 0;
- unsigned ia64jmpnum = 0;
Elf_Shdr *symtab_section = 0;
- grub_size_t got = 0;
- *start = 0;
+ grub_memset (layout, 0, sizeof (*layout));
+
+ layout->start_address = 0;
kernel_size = grub_util_get_image_size (kernel_path);
kernel_img = xmalloc (kernel_size);
section_addresses = SUFFIX (locate_sections) (kernel_path,
sections, section_entsize,
num_sections, strtab,
- exec_size, kernel_sz, align,
+ layout,
image_target);
section_vaddresses = xmalloc (sizeof (*section_addresses) * num_sections);
if (image_target->id != IMAGE_EFI)
{
- Elf_Addr current_address = *kernel_sz;
+ Elf_Addr current_address = layout->kernel_size;
for (i = 0, s = sections;
i < num_sections;
current_address = ALIGN_UP (current_address + image_target->vaddr_offset,
image_target->section_align)
- image_target->vaddr_offset;
- *bss_size = current_address - *kernel_sz;
+ layout->bss_size = current_address - layout->kernel_size;
}
else
- *bss_size = 0;
+ layout->bss_size = 0;
if (image_target->id == IMAGE_SPARC64_AOUT
|| image_target->id == IMAGE_SPARC64_RAW
|| image_target->id == IMAGE_SPARC64_CDCORE)
- *kernel_sz = ALIGN_UP (*kernel_sz, image_target->mod_align);
+ layout->kernel_size = ALIGN_UP (layout->kernel_size, image_target->mod_align);
if (image_target->id == IMAGE_EFI)
{
{
grub_size_t tramp;
- *kernel_sz = ALIGN_UP (*kernel_sz, 16);
+ layout->kernel_size = ALIGN_UP (layout->kernel_size, 16);
tramp = arm_get_trampoline_size (e, sections, section_entsize,
num_sections, image_target);
- tramp_off = *kernel_sz;
- *kernel_sz += ALIGN_UP (tramp, 16);
+ layout->tramp_off = layout->kernel_size;
+ layout->kernel_size += ALIGN_UP (tramp, 16);
}
#endif
{
grub_size_t tramp;
- *kernel_sz = ALIGN_UP (*kernel_sz, 16);
+ layout->kernel_size = ALIGN_UP (layout->kernel_size, 16);
- grub_ia64_dl_get_tramp_got_size (e, &tramp, &got);
+ grub_ia64_dl_get_tramp_got_size (e, &tramp, &layout->got_size);
- tramp_off = *kernel_sz;
- *kernel_sz += ALIGN_UP (tramp, 16);
+ layout->tramp_off = layout->kernel_size;
+ layout->kernel_size += ALIGN_UP (tramp, 16);
- ia64jmp_off = *kernel_sz;
- ia64jmpnum = SUFFIX (count_funcs) (e, symtab_section,
+ layout->ia64jmp_off = layout->kernel_size;
+ layout->ia64jmpnum = SUFFIX (count_funcs) (e, symtab_section,
image_target);
- *kernel_sz += 16 * ia64jmpnum;
+ layout->kernel_size += 16 * layout->ia64jmpnum;
- ia64_got_off = *kernel_sz;
- *kernel_sz += ALIGN_UP (got, 16);
+ layout->ia64_got_off = layout->kernel_size;
+ layout->kernel_size += ALIGN_UP (layout->got_size, 16);
}
#endif
}
else
{
- *reloc_size = 0;
- *reloc_section = NULL;
+ layout->reloc_size = 0;
+ layout->reloc_section = NULL;
}
- out_img = xmalloc (*kernel_sz + total_module_size);
- memset (out_img, 0, *kernel_sz + total_module_size);
+ out_img = xmalloc (layout->kernel_size + total_module_size);
+ memset (out_img, 0, layout->kernel_size + total_module_size);
if (image_target->id == IMAGE_EFI)
{
- *start = SUFFIX (relocate_symbols) (e, sections, symtab_section,
+ layout->start_address = SUFFIX (relocate_symbols) (e, sections, symtab_section,
section_vaddresses, section_entsize,
num_sections,
- (char *) out_img + ia64jmp_off,
- ia64jmp_off
+ (char *) out_img + layout->ia64jmp_off,
+ layout->ia64jmp_off
+ image_target->vaddr_offset,
image_target);
- if (*start == 0)
+ if (layout->start_address == 0)
grub_util_error ("start symbol is not defined");
- SUFFIX (entry_point) = (Elf_Addr) *start;
+ SUFFIX (entry_point) = (Elf_Addr) layout->start_address;
/* Resolve addresses in the virtual address space. */
SUFFIX (relocate_addresses) (e, sections, section_addresses,
section_entsize,
num_sections, strtab,
- out_img, tramp_off, ia64_got_off,
+ out_img, layout->tramp_off,
+ layout->ia64_got_off,
image_target);
- *reloc_size = SUFFIX (make_reloc_section) (e, reloc_section,
- section_vaddresses, sections,
- section_entsize, num_sections,
- strtab, ia64jmp_off
- + image_target->vaddr_offset,
- 2 * ia64jmpnum + (got / 8),
- image_target);
+ make_reloc_section (e, layout,
+ section_vaddresses, sections,
+ section_entsize, num_sections,
+ strtab, layout->ia64jmp_off
+ + image_target->vaddr_offset,
+ 2 * layout->ia64jmpnum + (layout->got_size / 8),
+ image_target);
}
for (i = 0, s = sections;
grub_compression_t comp)
{
char *kernel_img, *core_img;
- size_t kernel_size, total_module_size, core_size, exec_size;
+ size_t total_module_size, core_size;
size_t memdisk_size = 0, config_size = 0;
size_t prefix_size = 0;
char *kernel_path;
size_t offset;
struct grub_util_path_list *path_list, *p;
- size_t bss_size;
- grub_uint64_t start_address;
- void *rel_section = 0;
- size_t reloc_size = 0, align;
size_t decompress_size = 0;
+ struct grub_mkimage_layout layout;
if (comp == GRUB_COMPRESSION_AUTO)
comp = image_target->default_compression;
(unsigned long long) total_module_size);
if (image_target->voidp_sizeof == 4)
- kernel_img = grub_mkimage_load_image32 (kernel_path, &exec_size, &kernel_size, &bss_size,
- total_module_size, &start_address, &rel_section,
- &reloc_size, &align, image_target);
+ kernel_img = grub_mkimage_load_image32 (kernel_path, total_module_size,
+ &layout, image_target);
else
- kernel_img = grub_mkimage_load_image64 (kernel_path, &exec_size, &kernel_size, &bss_size,
- total_module_size, &start_address, &rel_section,
- &reloc_size, &align, image_target);
- if (image_target->id == IMAGE_XEN && align < 4096)
- align = 4096;
+ kernel_img = grub_mkimage_load_image64 (kernel_path, total_module_size,
+ &layout, image_target);
+ if (image_target->id == IMAGE_XEN && layout.align < 4096)
+ layout.align = 4096;
if ((image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS)
&& (image_target->total_module_size != TARGET_NO_FIELD))
if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL)
{
- memmove (kernel_img + total_module_size, kernel_img, kernel_size);
+ memmove (kernel_img + total_module_size, kernel_img, layout.kernel_size);
memset (kernel_img, 0, total_module_size);
}
if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL)
modinfo = (struct grub_module_info64 *) kernel_img;
else
- modinfo = (struct grub_module_info64 *) (kernel_img + kernel_size);
+ modinfo = (struct grub_module_info64 *) (kernel_img + layout.kernel_size);
modinfo->magic = grub_host_to_target32 (GRUB_MODULE_MAGIC);
modinfo->offset = grub_host_to_target_addr (sizeof (struct grub_module_info64));
modinfo->size = grub_host_to_target_addr (total_module_size);
if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL)
offset = sizeof (struct grub_module_info64);
else
- offset = kernel_size + sizeof (struct grub_module_info64);
+ offset = layout.kernel_size + sizeof (struct grub_module_info64);
}
else
{
if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL)
modinfo = (struct grub_module_info32 *) kernel_img;
else
- modinfo = (struct grub_module_info32 *) (kernel_img + kernel_size);
+ modinfo = (struct grub_module_info32 *) (kernel_img + layout.kernel_size);
modinfo->magic = grub_host_to_target32 (GRUB_MODULE_MAGIC);
modinfo->offset = grub_host_to_target_addr (sizeof (struct grub_module_info32));
modinfo->size = grub_host_to_target_addr (total_module_size);
if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL)
offset = sizeof (struct grub_module_info32);
else
- offset = kernel_size + sizeof (struct grub_module_info32);
+ offset = layout.kernel_size + sizeof (struct grub_module_info32);
}
for (p = path_list; p; p = p->next)
grub_util_info ("kernel_img=%p, kernel_size=0x%" GRUB_HOST_PRIxLONG_LONG,
kernel_img,
- (unsigned long long) kernel_size);
- compress_kernel (image_target, kernel_img, kernel_size + total_module_size,
+ (unsigned long long) layout.kernel_size);
+ compress_kernel (image_target, kernel_img, layout.kernel_size + total_module_size,
&core_img, &core_size, comp);
free (kernel_img);
if (image_target->decompressor_uncompressed_size != TARGET_NO_FIELD)
*((grub_uint32_t *) (decompress_img
+ image_target->decompressor_uncompressed_size))
- = grub_host_to_target32 (kernel_size + total_module_size);
+ = grub_host_to_target32 (layout.kernel_size + total_module_size);
if (image_target->decompressor_uncompressed_addr != TARGET_NO_FIELD)
{
case IMAGE_I386_PC_ELTORITO:
if (GRUB_KERNEL_I386_PC_LINK_ADDR + core_size > 0x78000
|| (core_size > (0xffff << GRUB_DISK_SECTOR_BITS))
- || (kernel_size + bss_size + GRUB_KERNEL_I386_PC_LINK_ADDR > 0x68000))
+ || (layout.kernel_size + layout.bss_size
+ + GRUB_KERNEL_I386_PC_LINK_ADDR > 0x68000))
grub_util_error (_("core image is too big (0x%x > 0x%x)"),
GRUB_KERNEL_I386_PC_LINK_ADDR + (unsigned) core_size,
0x78000);
/* fallthrough */
case IMAGE_COREBOOT:
case IMAGE_QEMU:
- if (kernel_size + bss_size + GRUB_KERNEL_I386_PC_LINK_ADDR > 0x68000)
+ if (layout.kernel_size + layout.bss_size + GRUB_KERNEL_I386_PC_LINK_ADDR > 0x68000)
grub_util_error (_("kernel image is too big (0x%x > 0x%x)"),
- (unsigned) kernel_size + (unsigned) bss_size
+ (unsigned) layout.kernel_size + (unsigned) layout.bss_size
+ GRUB_KERNEL_I386_PC_LINK_ADDR,
0x68000);
break;
reloc_addr = ALIGN_UP (header_size + core_size,
image_target->section_align);
- pe_size = ALIGN_UP (reloc_addr + reloc_size,
+ pe_size = ALIGN_UP (reloc_addr + layout.reloc_size,
image_target->section_align);
- pe_img = xmalloc (reloc_addr + reloc_size);
+ 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, rel_section, reloc_size);
+ memcpy ((char *) pe_img + reloc_addr, layout.reloc_section, layout.reloc_size);
header = pe_img;
/* The magic. */
(header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE
+ sizeof (struct grub_pe32_coff_header));
o->magic = grub_host_to_target16 (GRUB_PE32_PE32_MAGIC);
- o->code_size = grub_host_to_target32 (exec_size);
- o->data_size = grub_cpu_to_le32 (reloc_addr - exec_size
+ o->code_size = grub_host_to_target32 (layout.exec_size);
+ o->data_size = grub_cpu_to_le32 (reloc_addr - layout.exec_size
- header_size);
- o->bss_size = grub_cpu_to_le32 (bss_size);
- o->entry_addr = grub_cpu_to_le32 (start_address);
+ o->bss_size = grub_cpu_to_le32 (layout.bss_size);
+ o->entry_addr = grub_cpu_to_le32 (layout.start_address);
o->code_base = grub_cpu_to_le32 (header_size);
- o->data_base = grub_host_to_target32 (header_size + exec_size);
+ o->data_base = grub_host_to_target32 (header_size + layout.exec_size);
o->image_base = 0;
o->section_alignment = grub_host_to_target32 (image_target->section_align);
o->num_data_directories = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES);
o->base_relocation_table.rva = grub_host_to_target32 (reloc_addr);
- o->base_relocation_table.size = grub_host_to_target32 (reloc_size);
+ o->base_relocation_table.size = grub_host_to_target32 (layout.reloc_size);
sections = o + 1;
}
else
(header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE
+ sizeof (struct grub_pe32_coff_header));
o->magic = grub_host_to_target16 (GRUB_PE32_PE64_MAGIC);
- o->code_size = grub_host_to_target32 (exec_size);
- o->data_size = grub_cpu_to_le32 (reloc_addr - exec_size
+ o->code_size = grub_host_to_target32 (layout.exec_size);
+ o->data_size = grub_cpu_to_le32 (reloc_addr - layout.exec_size
- header_size);
- o->bss_size = grub_cpu_to_le32 (bss_size);
- o->entry_addr = grub_cpu_to_le32 (start_address);
+ o->bss_size = grub_cpu_to_le32 (layout.bss_size);
+ o->entry_addr = grub_cpu_to_le32 (layout.start_address);
o->code_base = grub_cpu_to_le32 (header_size);
o->image_base = 0;
o->section_alignment = grub_host_to_target32 (image_target->section_align);
= grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES);
o->base_relocation_table.rva = grub_host_to_target32 (reloc_addr);
- o->base_relocation_table.size = grub_host_to_target32 (reloc_size);
+ o->base_relocation_table.size = grub_host_to_target32 (layout.reloc_size);
sections = o + 1;
}
/* The sections. */
text_section = sections;
strcpy (text_section->name, ".text");
- text_section->virtual_size = grub_cpu_to_le32 (exec_size);
+ text_section->virtual_size = grub_cpu_to_le32 (layout.exec_size);
text_section->virtual_address = grub_cpu_to_le32 (header_size);
- text_section->raw_data_size = grub_cpu_to_le32 (exec_size);
+ text_section->raw_data_size = grub_cpu_to_le32 (layout.exec_size);
text_section->raw_data_offset = grub_cpu_to_le32 (header_size);
text_section->characteristics = grub_cpu_to_le32_compile_time (
GRUB_PE32_SCN_CNT_CODE
data_section = text_section + 1;
strcpy (data_section->name, ".data");
- data_section->virtual_size = grub_cpu_to_le32 (kernel_size - exec_size);
- data_section->virtual_address = grub_cpu_to_le32 (header_size + exec_size);
- data_section->raw_data_size = grub_cpu_to_le32 (kernel_size - exec_size);
- data_section->raw_data_offset = grub_cpu_to_le32 (header_size + exec_size);
+ data_section->virtual_size = grub_cpu_to_le32 (layout.kernel_size - layout.exec_size);
+ data_section->virtual_address = grub_cpu_to_le32 (header_size + layout.exec_size);
+ data_section->raw_data_size = grub_cpu_to_le32 (layout.kernel_size - layout.exec_size);
+ data_section->raw_data_offset = grub_cpu_to_le32 (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
#if 0
bss_section = data_section + 1;
strcpy (bss_section->name, ".bss");
- bss_section->virtual_size = grub_cpu_to_le32 (bss_size);
- bss_section->virtual_address = grub_cpu_to_le32 (header_size + kernel_size);
+ bss_section->virtual_size = grub_cpu_to_le32 (layout.bss_size);
+ bss_section->virtual_address = grub_cpu_to_le32 (header_size + layout.kernel_size);
bss_section->raw_data_size = 0;
bss_section->raw_data_offset = 0;
bss_section->characteristics
mods_section = data_section + 1;
strcpy (mods_section->name, "mods");
- mods_section->virtual_size = grub_cpu_to_le32 (reloc_addr - kernel_size - header_size);
- mods_section->virtual_address = grub_cpu_to_le32 (header_size + kernel_size + bss_size);
- mods_section->raw_data_size = grub_cpu_to_le32 (reloc_addr - kernel_size - header_size);
- mods_section->raw_data_offset = grub_cpu_to_le32 (header_size + kernel_size);
+ mods_section->virtual_size = grub_cpu_to_le32 (reloc_addr - layout.kernel_size - header_size);
+ mods_section->virtual_address = grub_cpu_to_le32 (header_size + layout.kernel_size + layout.bss_size);
+ mods_section->raw_data_size = grub_cpu_to_le32 (reloc_addr - layout.kernel_size - header_size);
+ mods_section->raw_data_offset = grub_cpu_to_le32 (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
reloc_section = mods_section + 1;
strcpy (reloc_section->name, ".reloc");
- reloc_section->virtual_size = grub_cpu_to_le32 (reloc_size);
- reloc_section->virtual_address = grub_cpu_to_le32 (reloc_addr + bss_size);
- reloc_section->raw_data_size = grub_cpu_to_le32 (reloc_size);
+ reloc_section->virtual_size = grub_cpu_to_le32 (layout.reloc_size);
+ reloc_section->virtual_address = grub_cpu_to_le32 (reloc_addr + layout.bss_size);
+ reloc_section->raw_data_size = grub_cpu_to_le32 (layout.reloc_size);
reloc_section->raw_data_offset = grub_cpu_to_le32 (reloc_addr);
reloc_section->characteristics
= grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_CNT_INITIALIZED_DATA
target_addr = (image_target->link_addr - decompress_size);
else
target_addr = ALIGN_UP (image_target->link_addr
- + kernel_size + total_module_size, 32);
+ + layout.kernel_size + total_module_size, 32);
ecoff_img = xmalloc (program_size + sizeof (*head) + sizeof (*section));
grub_memset (ecoff_img, 0, program_size + sizeof (*head) + sizeof (*section));
target_addr = (image_target->link_addr - decompress_size);
else
target_addr = ALIGN_UP (image_target->link_addr
- + kernel_size + total_module_size, 32);
+ + layout.kernel_size + total_module_size, 32);
}
else
target_addr = image_target->link_addr;
if (image_target->voidp_sizeof == 4)
grub_mkimage_generate_elf32 (image_target, note, &core_img, &core_size,
- target_addr, align, kernel_size, bss_size);
+ target_addr, layout.align, layout.kernel_size, layout.bss_size);
else
grub_mkimage_generate_elf64 (image_target, note, &core_img, &core_size,
- target_addr, align, kernel_size, bss_size);
+ target_addr, layout.align, layout.kernel_size, layout.bss_size);
}
break;
}
grub_util_write_image (core_img, core_size, out, outname);
free (core_img);
free (kernel_path);
- free (rel_section);
+ free (layout.reloc_section);
grub_util_free_path_list (path_list);
}