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
|
@ -172,6 +172,8 @@ program = {
|
||||||
|
|
||||||
common = util/grub-mkimage.c;
|
common = util/grub-mkimage.c;
|
||||||
common = util/mkimage.c;
|
common = util/mkimage.c;
|
||||||
|
common = util/grub-mkimage32.c;
|
||||||
|
common = util/grub-mkimage64.c;
|
||||||
common = util/resolve.c;
|
common = util/resolve.c;
|
||||||
common = grub-core/kern/emu/argp_common.c;
|
common = grub-core/kern/emu/argp_common.c;
|
||||||
common = grub-core/osdep/init.c;
|
common = grub-core/osdep/init.c;
|
||||||
|
@ -510,6 +512,8 @@ program = {
|
||||||
common = util/render-label.c;
|
common = util/render-label.c;
|
||||||
common = util/glue-efi.c;
|
common = util/glue-efi.c;
|
||||||
common = util/mkimage.c;
|
common = util/mkimage.c;
|
||||||
|
common = util/grub-mkimage32.c;
|
||||||
|
common = util/grub-mkimage64.c;
|
||||||
common = util/grub-install-common.c;
|
common = util/grub-install-common.c;
|
||||||
common = util/setup_bios.c;
|
common = util/setup_bios.c;
|
||||||
common = util/setup_sparc.c;
|
common = util/setup_sparc.c;
|
||||||
|
@ -552,6 +556,8 @@ program = {
|
||||||
common = util/render-label.c;
|
common = util/render-label.c;
|
||||||
common = util/glue-efi.c;
|
common = util/glue-efi.c;
|
||||||
common = util/mkimage.c;
|
common = util/mkimage.c;
|
||||||
|
common = util/grub-mkimage32.c;
|
||||||
|
common = util/grub-mkimage64.c;
|
||||||
common = util/grub-install-common.c;
|
common = util/grub-install-common.c;
|
||||||
common = util/setup_bios.c;
|
common = util/setup_bios.c;
|
||||||
common = util/setup_sparc.c;
|
common = util/setup_sparc.c;
|
||||||
|
@ -595,6 +601,8 @@ program = {
|
||||||
common = util/grub-install.c;
|
common = util/grub-install.c;
|
||||||
common = util/probe.c;
|
common = util/probe.c;
|
||||||
common = util/mkimage.c;
|
common = util/mkimage.c;
|
||||||
|
common = util/grub-mkimage32.c;
|
||||||
|
common = util/grub-mkimage64.c;
|
||||||
common = util/grub-install-common.c;
|
common = util/grub-install-common.c;
|
||||||
common = util/setup_bios.c;
|
common = util/setup_bios.c;
|
||||||
common = util/setup_sparc.c;
|
common = util/setup_sparc.c;
|
||||||
|
@ -632,6 +640,8 @@ program = {
|
||||||
common = util/grub-mknetdir.c;
|
common = util/grub-mknetdir.c;
|
||||||
|
|
||||||
common = util/mkimage.c;
|
common = util/mkimage.c;
|
||||||
|
common = util/grub-mkimage32.c;
|
||||||
|
common = util/grub-mkimage64.c;
|
||||||
common = util/grub-install-common.c;
|
common = util/grub-install-common.c;
|
||||||
common = util/setup_bios.c;
|
common = util/setup_bios.c;
|
||||||
common = util/setup_sparc.c;
|
common = util/setup_sparc.c;
|
||||||
|
|
170
include/grub/util/mkimage.h
Normal file
170
include/grub/util/mkimage.h
Normal file
|
@ -0,0 +1,170 @@
|
||||||
|
/*
|
||||||
|
* GRUB -- GRand Unified Bootloader
|
||||||
|
* Copyright (C) 2013 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* GRUB is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GRUB is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GRUB_UTIL_MKIMAGE_HEADER
|
||||||
|
#define GRUB_UTIL_MKIMAGE_HEADER 1
|
||||||
|
|
||||||
|
/* Private header. Use only in mkimage-related sources. */
|
||||||
|
char *
|
||||||
|
grub_mkimage_load_image32 (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,
|
||||||
|
const struct grub_install_image_target_desc *image_target);
|
||||||
|
char *
|
||||||
|
grub_mkimage_load_image64 (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,
|
||||||
|
const struct grub_install_image_target_desc *image_target);
|
||||||
|
void
|
||||||
|
grub_mkimage_generate_elf32 (const struct grub_install_image_target_desc *image_target,
|
||||||
|
int note, char **core_img, size_t *core_size,
|
||||||
|
Elf32_Addr target_addr, grub_size_t align,
|
||||||
|
size_t kernel_size, size_t bss_size);
|
||||||
|
void
|
||||||
|
grub_mkimage_generate_elf64 (const struct grub_install_image_target_desc *image_target,
|
||||||
|
int note, char **core_img, size_t *core_size,
|
||||||
|
Elf64_Addr target_addr, grub_size_t align,
|
||||||
|
size_t kernel_size, size_t bss_size);
|
||||||
|
|
||||||
|
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 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_target_to_host(val) grub_target_to_host_real(image_target, (val))
|
||||||
|
|
||||||
|
#endif
|
22
util/grub-mkimage32.c
Normal file
22
util/grub-mkimage32.c
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
#define MKIMAGE_ELF32 1
|
||||||
|
|
||||||
|
# define SUFFIX(x) x ## 32
|
||||||
|
# define ELFCLASSXX ELFCLASS32
|
||||||
|
# define Elf_Ehdr Elf32_Ehdr
|
||||||
|
# define Elf_Phdr Elf32_Phdr
|
||||||
|
# define Elf_Nhdr Elf32_Nhdr
|
||||||
|
# define Elf_Addr Elf32_Addr
|
||||||
|
# define Elf_Sym Elf32_Sym
|
||||||
|
# define Elf_Off Elf32_Off
|
||||||
|
# define Elf_Shdr Elf32_Shdr
|
||||||
|
# define Elf_Rela Elf32_Rela
|
||||||
|
# define Elf_Rel Elf32_Rel
|
||||||
|
# define Elf_Word Elf32_Word
|
||||||
|
# define Elf_Half Elf32_Half
|
||||||
|
# define Elf_Section Elf32_Section
|
||||||
|
# define ELF_R_SYM(val) ELF32_R_SYM(val)
|
||||||
|
# define ELF_R_TYPE(val) ELF32_R_TYPE(val)
|
||||||
|
# define ELF_ST_TYPE(val) ELF32_ST_TYPE(val)
|
||||||
|
#define XEN_NOTE_SIZE 132
|
||||||
|
|
||||||
|
#include "grub-mkimagexx.c"
|
22
util/grub-mkimage64.c
Normal file
22
util/grub-mkimage64.c
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
#define MKIMAGE_ELF64 1
|
||||||
|
|
||||||
|
# define SUFFIX(x) x ## 64
|
||||||
|
# define ELFCLASSXX ELFCLASS64
|
||||||
|
# define Elf_Ehdr Elf64_Ehdr
|
||||||
|
# define Elf_Phdr Elf64_Phdr
|
||||||
|
# define Elf_Nhdr Elf64_Nhdr
|
||||||
|
# define Elf_Addr Elf64_Addr
|
||||||
|
# define Elf_Sym Elf64_Sym
|
||||||
|
# define Elf_Off Elf64_Off
|
||||||
|
# define Elf_Shdr Elf64_Shdr
|
||||||
|
# define Elf_Rela Elf64_Rela
|
||||||
|
# define Elf_Rel Elf64_Rel
|
||||||
|
# define Elf_Word Elf64_Word
|
||||||
|
# define Elf_Half Elf64_Half
|
||||||
|
# define Elf_Section Elf64_Section
|
||||||
|
# define ELF_R_SYM(val) ELF64_R_SYM(val)
|
||||||
|
# define ELF_R_TYPE(val) ELF64_R_TYPE(val)
|
||||||
|
# define ELF_ST_TYPE(val) ELF64_ST_TYPE(val)
|
||||||
|
#define XEN_NOTE_SIZE 120
|
||||||
|
|
||||||
|
#include "grub-mkimagexx.c"
|
|
@ -17,58 +17,172 @@
|
||||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#undef ELF_R_SYM
|
#include <config.h>
|
||||||
#undef ELF_R_TYPE
|
#include <grub/types.h>
|
||||||
|
#include <grub/elf.h>
|
||||||
|
#include <grub/aout.h>
|
||||||
|
#include <grub/i18n.h>
|
||||||
|
#include <grub/kernel.h>
|
||||||
|
#include <grub/disk.h>
|
||||||
|
#include <grub/emu/misc.h>
|
||||||
|
#include <grub/util/misc.h>
|
||||||
|
#include <grub/util/resolve.h>
|
||||||
|
#include <grub/misc.h>
|
||||||
|
#include <grub/offsets.h>
|
||||||
|
#include <grub/crypto.h>
|
||||||
|
#include <grub/dl.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <multiboot.h>
|
||||||
|
|
||||||
#if defined(MKIMAGE_ELF32)
|
#include <stdio.h>
|
||||||
# define SUFFIX(x) x ## 32
|
#include <unistd.h>
|
||||||
# define ELFCLASSXX ELFCLASS32
|
#include <string.h>
|
||||||
# define Elf_Ehdr Elf32_Ehdr
|
#include <stdlib.h>
|
||||||
# define Elf_Phdr Elf32_Phdr
|
#include <assert.h>
|
||||||
# define Elf_Nhdr Elf32_Nhdr
|
#include <grub/efi/pe32.h>
|
||||||
# define Elf_Addr Elf32_Addr
|
#include <grub/uboot/image.h>
|
||||||
# define Elf_Sym Elf32_Sym
|
#include <grub/arm/reloc.h>
|
||||||
# define Elf_Off Elf32_Off
|
#include <grub/arm64/reloc.h>
|
||||||
# define Elf_Shdr Elf32_Shdr
|
#include <grub/ia64/reloc.h>
|
||||||
# define Elf_Rela Elf32_Rela
|
#include <grub/osdep/hostfile.h>
|
||||||
# define Elf_Rel Elf32_Rel
|
#include <grub/util/install.h>
|
||||||
# define Elf_Word Elf32_Word
|
#include <grub/util/mkimage.h>
|
||||||
# define Elf_Half Elf32_Half
|
|
||||||
# define Elf_Section Elf32_Section
|
#pragma GCC diagnostic ignored "-Wcast-align"
|
||||||
# define ELF_R_SYM(val) ELF32_R_SYM(val)
|
|
||||||
# define ELF_R_TYPE(val) ELF32_R_TYPE(val)
|
|
||||||
# define ELF_ST_TYPE(val) ELF32_ST_TYPE(val)
|
|
||||||
#define XEN_NOTE_SIZE 132
|
|
||||||
#elif defined(MKIMAGE_ELF64)
|
|
||||||
# define SUFFIX(x) x ## 64
|
|
||||||
# define ELFCLASSXX ELFCLASS64
|
|
||||||
# define Elf_Ehdr Elf64_Ehdr
|
|
||||||
# define Elf_Phdr Elf64_Phdr
|
|
||||||
# define Elf_Nhdr Elf64_Nhdr
|
|
||||||
# define Elf_Addr Elf64_Addr
|
|
||||||
# define Elf_Sym Elf64_Sym
|
|
||||||
# define Elf_Off Elf64_Off
|
|
||||||
# define Elf_Shdr Elf64_Shdr
|
|
||||||
# define Elf_Rela Elf64_Rela
|
|
||||||
# define Elf_Rel Elf64_Rel
|
|
||||||
# define Elf_Word Elf64_Word
|
|
||||||
# define Elf_Half Elf64_Half
|
|
||||||
# define Elf_Section Elf64_Section
|
|
||||||
# define ELF_R_SYM(val) ELF64_R_SYM(val)
|
|
||||||
# define ELF_R_TYPE(val) ELF64_R_TYPE(val)
|
|
||||||
# define ELF_ST_TYPE(val) ELF64_ST_TYPE(val)
|
|
||||||
#define XEN_NOTE_SIZE 120
|
|
||||||
#else
|
|
||||||
#error "I'm confused"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static Elf_Addr SUFFIX (entry_point);
|
static Elf_Addr SUFFIX (entry_point);
|
||||||
|
|
||||||
static void
|
/* These structures are defined according to the CHRP binding to IEEE1275,
|
||||||
SUFFIX (generate_elf) (const struct grub_install_image_target_desc *image_target,
|
"Client Program Format" section. */
|
||||||
int note, char **core_img, size_t *core_size,
|
|
||||||
Elf_Addr target_addr, grub_size_t align,
|
struct grub_ieee1275_note_desc
|
||||||
size_t kernel_size, size_t bss_size)
|
{
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define GRUB_IEEE1275_NOTE_NAME "PowerPC"
|
||||||
|
#define GRUB_IEEE1275_NOTE_TYPE 0x1275
|
||||||
|
|
||||||
|
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"
|
||||||
|
|
||||||
|
struct fixup_block_list
|
||||||
|
{
|
||||||
|
struct fixup_block_list *next;
|
||||||
|
int state;
|
||||||
|
struct grub_pe32_fixup_block b;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define ALIGN_ADDR(x) (ALIGN_UP((x), image_target->voidp_sizeof))
|
||||||
|
|
||||||
|
#ifdef MKIMAGE_ELF32
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc *image_target,
|
||||||
|
int note, char **core_img, size_t *core_size,
|
||||||
|
Elf_Addr target_addr, grub_size_t align,
|
||||||
|
size_t kernel_size, size_t bss_size)
|
||||||
{
|
{
|
||||||
char *elf_img;
|
char *elf_img;
|
||||||
size_t program_size;
|
size_t program_size;
|
||||||
|
@ -1457,13 +1571,13 @@ SUFFIX (locate_sections) (const char *kernel_path,
|
||||||
return section_addresses;
|
return section_addresses;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *
|
char *
|
||||||
SUFFIX (load_image) (const char *kernel_path, size_t *exec_size,
|
SUFFIX (grub_mkimage_load_image) (const char *kernel_path, size_t *exec_size,
|
||||||
size_t *kernel_sz, size_t *bss_size,
|
size_t *kernel_sz, size_t *bss_size,
|
||||||
size_t total_module_size, grub_uint64_t *start,
|
size_t total_module_size, grub_uint64_t *start,
|
||||||
void **reloc_section, size_t *reloc_size,
|
void **reloc_section, size_t *reloc_size,
|
||||||
size_t *align,
|
size_t *align,
|
||||||
const struct grub_install_image_target_desc *image_target)
|
const struct grub_install_image_target_desc *image_target)
|
||||||
{
|
{
|
||||||
char *kernel_img, *out_img;
|
char *kernel_img, *out_img;
|
||||||
const char *strtab;
|
const char *strtab;
|
||||||
|
@ -1671,23 +1785,3 @@ SUFFIX (load_image) (const char *kernel_path, size_t *exec_size,
|
||||||
|
|
||||||
return out_img;
|
return out_img;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#undef SUFFIX
|
|
||||||
#undef ELFCLASSXX
|
|
||||||
#undef Elf_Ehdr
|
|
||||||
#undef Elf_Phdr
|
|
||||||
#undef Elf_Nhdr
|
|
||||||
#undef Elf_Shdr
|
|
||||||
#undef Elf_Addr
|
|
||||||
#undef Elf_Sym
|
|
||||||
#undef Elf_Off
|
|
||||||
#undef Elf_Rela
|
|
||||||
#undef Elf_Rel
|
|
||||||
#undef ELF_R_TYPE
|
|
||||||
#undef ELF_R_SYM
|
|
||||||
#undef Elf_Word
|
|
||||||
#undef Elf_Half
|
|
||||||
#undef Elf_Section
|
|
||||||
#undef ELF_ST_TYPE
|
|
||||||
#undef XEN_NOTE_SIZE
|
|
||||||
|
|
275
util/mkimage.c
275
util/mkimage.c
|
@ -46,6 +46,7 @@
|
||||||
#include <grub/ia64/reloc.h>
|
#include <grub/ia64/reloc.h>
|
||||||
#include <grub/osdep/hostfile.h>
|
#include <grub/osdep/hostfile.h>
|
||||||
#include <grub/util/install.h>
|
#include <grub/util/install.h>
|
||||||
|
#include <grub/util/mkimage.h>
|
||||||
|
|
||||||
#define ALIGN_ADDR(x) (ALIGN_UP((x), image_target->voidp_sizeof))
|
#define ALIGN_ADDR(x) (ALIGN_UP((x), image_target->voidp_sizeof))
|
||||||
|
|
||||||
|
@ -53,45 +54,13 @@
|
||||||
#include <lzma.h>
|
#include <lzma.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#pragma GCC diagnostic ignored "-Wcast-align"
|
||||||
|
|
||||||
#define TARGET_NO_FIELD 0xffffffff
|
#define TARGET_NO_FIELD 0xffffffff
|
||||||
|
|
||||||
/* use 2015-01-01T00:00:00+0000 as a stock timestamp */
|
/* use 2015-01-01T00:00:00+0000 as a stock timestamp */
|
||||||
#define STABLE_EMBEDDING_TIMESTAMP 1420070400
|
#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 \
|
#define EFI32_HEADER_SIZE ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE \
|
||||||
+ GRUB_PE32_SIGNATURE_SIZE \
|
+ GRUB_PE32_SIGNATURE_SIZE \
|
||||||
+ sizeof (struct grub_pe32_coff_header) \
|
+ 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>
|
#include <grub/lib/LzmaEnc.h>
|
||||||
|
|
||||||
static void *SzAlloc(void *p __attribute__ ((unused)), size_t size) { return xmalloc(size); }
|
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;
|
*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 *
|
const struct grub_install_image_target_desc *
|
||||||
grub_install_get_image_target (const char *arg)
|
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);
|
(unsigned long long) total_module_size);
|
||||||
|
|
||||||
if (image_target->voidp_sizeof == 4)
|
if (image_target->voidp_sizeof == 4)
|
||||||
kernel_img = load_image32 (kernel_path, &exec_size, &kernel_size, &bss_size,
|
kernel_img = grub_mkimage_load_image32 (kernel_path, &exec_size, &kernel_size, &bss_size,
|
||||||
total_module_size, &start_address, &rel_section,
|
total_module_size, &start_address, &rel_section,
|
||||||
&reloc_size, &align, image_target);
|
&reloc_size, &align, image_target);
|
||||||
else
|
else
|
||||||
kernel_img = load_image64 (kernel_path, &exec_size, &kernel_size, &bss_size,
|
kernel_img = grub_mkimage_load_image64 (kernel_path, &exec_size, &kernel_size, &bss_size,
|
||||||
total_module_size, &start_address, &rel_section,
|
total_module_size, &start_address, &rel_section,
|
||||||
&reloc_size, &align, image_target);
|
&reloc_size, &align, image_target);
|
||||||
if (image_target->id == IMAGE_XEN && align < 4096)
|
if (image_target->id == IMAGE_XEN && align < 4096)
|
||||||
align = 4096;
|
align = 4096;
|
||||||
|
|
||||||
|
@ -1890,11 +1641,11 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||||
else
|
else
|
||||||
target_addr = image_target->link_addr;
|
target_addr = image_target->link_addr;
|
||||||
if (image_target->voidp_sizeof == 4)
|
if (image_target->voidp_sizeof == 4)
|
||||||
generate_elf32 (image_target, note, &core_img, &core_size,
|
grub_mkimage_generate_elf32 (image_target, note, &core_img, &core_size,
|
||||||
target_addr, align, kernel_size, bss_size);
|
target_addr, align, kernel_size, bss_size);
|
||||||
else
|
else
|
||||||
generate_elf64 (image_target, note, &core_img, &core_size,
|
grub_mkimage_generate_elf64 (image_target, note, &core_img, &core_size,
|
||||||
target_addr, align, kernel_size, bss_size);
|
target_addr, align, kernel_size, bss_size);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue