mkimage.c: Split into separate files.

util/grub-mkimagexx.c is included in a special way into mkimage.c.
Interoperation between defines makes this very tricky. Instead
just have a clean interface and compile util/grub-mkimage*.c separately
from mkimage.c
This commit is contained in:
Vladimir Serbinenko 2016-02-18 20:26:44 +01:00
parent 2ebef43cf6
commit 36212460d3
6 changed files with 406 additions and 337 deletions

View file

@ -46,6 +46,7 @@
#include <grub/ia64/reloc.h>
#include <grub/osdep/hostfile.h>
#include <grub/util/install.h>
#include <grub/util/mkimage.h>
#define ALIGN_ADDR(x) (ALIGN_UP((x), image_target->voidp_sizeof))
@ -53,45 +54,13 @@
#include <lzma.h>
#endif
#pragma GCC diagnostic ignored "-Wcast-align"
#define TARGET_NO_FIELD 0xffffffff
/* use 2015-01-01T00:00:00+0000 as a stock timestamp */
#define STABLE_EMBEDDING_TIMESTAMP 1420070400
struct grub_install_image_target_desc
{
const char *dirname;
const char *names[6];
grub_size_t voidp_sizeof;
int bigendian;
enum {
IMAGE_I386_PC, IMAGE_EFI, IMAGE_COREBOOT,
IMAGE_SPARC64_AOUT, IMAGE_SPARC64_RAW, IMAGE_SPARC64_CDCORE,
IMAGE_I386_IEEE1275,
IMAGE_LOONGSON_ELF, IMAGE_QEMU, IMAGE_PPC, IMAGE_YEELOONG_FLASH,
IMAGE_FULOONG2F_FLASH, IMAGE_I386_PC_PXE, IMAGE_MIPS_ARC,
IMAGE_QEMU_MIPS_FLASH, IMAGE_UBOOT, IMAGE_XEN, IMAGE_I386_PC_ELTORITO
} id;
enum
{
PLATFORM_FLAGS_NONE = 0,
PLATFORM_FLAGS_DECOMPRESSORS = 2,
PLATFORM_FLAGS_MODULES_BEFORE_KERNEL = 4,
} flags;
unsigned total_module_size;
unsigned decompressor_compressed_size;
unsigned decompressor_uncompressed_size;
unsigned decompressor_uncompressed_addr;
unsigned link_align;
grub_uint16_t elf_target;
unsigned section_align;
signed vaddr_offset;
grub_uint64_t link_addr;
unsigned mod_gap, mod_align;
grub_compression_t default_compression;
grub_uint16_t pe_target;
};
#define EFI32_HEADER_SIZE ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE \
+ GRUB_PE32_SIGNATURE_SIZE \
+ sizeof (struct grub_pe32_coff_header) \
@ -603,119 +572,6 @@ static const struct grub_install_image_target_desc image_targets[] =
},
};
#define grub_target_to_host32(x) (grub_target_to_host32_real (image_target, (x)))
#define grub_host_to_target32(x) (grub_host_to_target32_real (image_target, (x)))
#define grub_target_to_host64(x) (grub_target_to_host64_real (image_target, (x)))
#define grub_host_to_target64(x) (grub_host_to_target64_real (image_target, (x)))
#define grub_host_to_target_addr(x) (grub_host_to_target_addr_real (image_target, (x)))
#define grub_target_to_host16(x) (grub_target_to_host16_real (image_target, (x)))
#define grub_host_to_target16(x) (grub_host_to_target16_real (image_target, (x)))
static inline grub_uint32_t
grub_target_to_host32_real (const struct grub_install_image_target_desc *image_target,
grub_uint32_t in)
{
if (image_target->bigendian)
return grub_be_to_cpu32 (in);
else
return grub_le_to_cpu32 (in);
}
static inline grub_uint64_t
grub_target_to_host64_real (const struct grub_install_image_target_desc *image_target,
grub_uint64_t in)
{
if (image_target->bigendian)
return grub_be_to_cpu64 (in);
else
return grub_le_to_cpu64 (in);
}
static inline grub_uint64_t
grub_host_to_target64_real (const struct grub_install_image_target_desc *image_target,
grub_uint64_t in)
{
if (image_target->bigendian)
return grub_cpu_to_be64 (in);
else
return grub_cpu_to_le64 (in);
}
static inline grub_uint32_t
grub_host_to_target32_real (const struct grub_install_image_target_desc *image_target,
grub_uint32_t in)
{
if (image_target->bigendian)
return grub_cpu_to_be32 (in);
else
return grub_cpu_to_le32 (in);
}
static inline grub_uint16_t
grub_target_to_host16_real (const struct grub_install_image_target_desc *image_target,
grub_uint16_t in)
{
if (image_target->bigendian)
return grub_be_to_cpu16 (in);
else
return grub_le_to_cpu16 (in);
}
static inline grub_uint16_t
grub_host_to_target16_real (const struct grub_install_image_target_desc *image_target,
grub_uint16_t in)
{
if (image_target->bigendian)
return grub_cpu_to_be16 (in);
else
return grub_cpu_to_le16 (in);
}
static inline grub_uint64_t
grub_host_to_target_addr_real (const struct grub_install_image_target_desc *image_target, grub_uint64_t in)
{
if (image_target->voidp_sizeof == 8)
return grub_host_to_target64_real (image_target, in);
else
return grub_host_to_target32_real (image_target, in);
}
static inline grub_uint64_t
grub_target_to_host_real (const struct grub_install_image_target_desc *image_target, grub_uint64_t in)
{
if (image_target->voidp_sizeof == 8)
return grub_target_to_host64_real (image_target, in);
else
return grub_target_to_host32_real (image_target, in);
}
#define GRUB_IEEE1275_NOTE_NAME "PowerPC"
#define GRUB_IEEE1275_NOTE_TYPE 0x1275
/* These structures are defined according to the CHRP binding to IEEE1275,
"Client Program Format" section. */
struct grub_ieee1275_note_desc
{
grub_uint32_t real_mode;
grub_uint32_t real_base;
grub_uint32_t real_size;
grub_uint32_t virt_base;
grub_uint32_t virt_size;
grub_uint32_t load_base;
};
struct grub_ieee1275_note
{
Elf32_Nhdr header;
char name[ALIGN_UP(sizeof (GRUB_IEEE1275_NOTE_NAME), 4)];
struct grub_ieee1275_note_desc descriptor;
};
#define GRUB_XEN_NOTE_NAME "Xen"
#define grub_target_to_host(val) grub_target_to_host_real(image_target, (val))
#include <grub/lib/LzmaEnc.h>
static void *SzAlloc(void *p __attribute__ ((unused)), size_t size) { return xmalloc(size); }
@ -830,111 +686,6 @@ compress_kernel (const struct grub_install_image_target_desc *image_target, char
*core_size = kernel_size;
}
struct fixup_block_list
{
struct fixup_block_list *next;
int state;
struct grub_pe32_fixup_block b;
};
/*
* R_ARM_THM_CALL/THM_JUMP24
*
* Relocate Thumb (T32) instruction set relative branches:
* B.W, BL and BLX
*/
static grub_err_t
grub_arm_reloc_thm_call (grub_uint16_t *target, Elf32_Addr sym_addr)
{
grub_int32_t offset;
offset = grub_arm_thm_call_get_offset (target);
grub_dprintf ("dl", " sym_addr = 0x%08x", sym_addr);
offset += sym_addr;
grub_dprintf("dl", " BL*: target=%p, sym_addr=0x%08x, offset=%d\n",
target, sym_addr, offset);
/* Keep traditional (pre-Thumb2) limits on blx. In any case if the kernel
is bigger than 2M (currently under 150K) then we probably have a problem
somewhere else. */
if (offset < -0x200000 || offset >= 0x200000)
return grub_error (GRUB_ERR_BAD_MODULE,
"THM_CALL Relocation out of range.");
grub_dprintf ("dl", " relative destination = %p",
(char *) target + offset);
return grub_arm_thm_call_set_offset (target, offset);
}
/*
* R_ARM_THM_JUMP19
*
* Relocate conditional Thumb (T32) B<c>.W
*/
static grub_err_t
grub_arm_reloc_thm_jump19 (grub_uint16_t *target, Elf32_Addr sym_addr)
{
grub_int32_t offset;
if (!(sym_addr & 1))
return grub_error (GRUB_ERR_BAD_MODULE,
"Relocation targeting wrong execution state");
offset = grub_arm_thm_jump19_get_offset (target);
/* Adjust and re-truncate offset */
offset += sym_addr;
if (!grub_arm_thm_jump19_check_offset (offset))
return grub_error (GRUB_ERR_BAD_MODULE,
"THM_JUMP19 Relocation out of range.");
grub_arm_thm_jump19_set_offset (target, offset);
return GRUB_ERR_NONE;
}
/*
* R_ARM_JUMP24
*
* Relocate ARM (A32) B
*/
static grub_err_t
grub_arm_reloc_jump24 (grub_uint32_t *target, Elf32_Addr sym_addr)
{
grub_int32_t offset;
if (sym_addr & 1)
return grub_error (GRUB_ERR_BAD_MODULE,
"Relocation targeting wrong execution state");
offset = grub_arm_jump24_get_offset (target);
offset += sym_addr;
if (!grub_arm_jump24_check_offset (offset))
return grub_error (GRUB_ERR_BAD_MODULE,
"JUMP24 Relocation out of range.");
grub_arm_jump24_set_offset (target, offset);
return GRUB_ERR_NONE;
}
#pragma GCC diagnostic ignored "-Wcast-align"
#define MKIMAGE_ELF32 1
#include "grub-mkimagexx.c"
#undef MKIMAGE_ELF32
#define MKIMAGE_ELF64 1
#include "grub-mkimagexx.c"
#undef MKIMAGE_ELF64
const struct grub_install_image_target_desc *
grub_install_get_image_target (const char *arg)
{
@ -1063,13 +814,13 @@ grub_install_generate_image (const char *dir, const char *prefix,
(unsigned long long) total_module_size);
if (image_target->voidp_sizeof == 4)
kernel_img = 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, &exec_size, &kernel_size, &bss_size,
total_module_size, &start_address, &rel_section,
&reloc_size, &align, image_target);
else
kernel_img = load_image64 (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_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;
@ -1890,11 +1641,11 @@ grub_install_generate_image (const char *dir, const char *prefix,
else
target_addr = image_target->link_addr;
if (image_target->voidp_sizeof == 4)
generate_elf32 (image_target, note, &core_img, &core_size,
target_addr, align, kernel_size, bss_size);
grub_mkimage_generate_elf32 (image_target, note, &core_img, &core_size,
target_addr, align, kernel_size, bss_size);
else
generate_elf64 (image_target, note, &core_img, &core_size,
target_addr, align, kernel_size, bss_size);
grub_mkimage_generate_elf64 (image_target, note, &core_img, &core_size,
target_addr, align, kernel_size, bss_size);
}
break;
}