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:
parent
2ebef43cf6
commit
36212460d3
6 changed files with 406 additions and 337 deletions
275
util/mkimage.c
275
util/mkimage.c
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue