From 9b1eeacef1a590c4bb1cd99f24b7038e77c3de33 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 10 Jan 2013 12:50:01 +0100 Subject: [PATCH 093/471] Support Apple FAT binaries on non-Apple platforms. * include/grub/macho.h (GRUB_MACHO_FAT_EFI_MAGIC): New define. * include/grub/i386/macho.h (GRUB_MACHO_CPUTYPE_IS_HOST_CURRENT): Likewise. * grub-core/loader/efi/chainloader.c (grub_cmd_chainloader): Parse Apple FAT binaries. --- ChangeLog | 10 ++++++++ grub-core/loader/efi/chainloader.c | 48 +++++++++++++++++++++++++++++++++++--- include/grub/i386/macho.h | 5 ++++ include/grub/macho.h | 1 + 4 files changed, 61 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 48d297d..4567cae 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,15 @@ 2013-01-10 Vladimir Serbinenko + Support Apple FAT binaries on non-Apple platforms. + + * include/grub/macho.h (GRUB_MACHO_FAT_EFI_MAGIC): New define. + * include/grub/i386/macho.h (GRUB_MACHO_CPUTYPE_IS_HOST_CURRENT): + Likewise. + * grub-core/loader/efi/chainloader.c (grub_cmd_chainloader): Parse + Apple FAT binaries. + +2013-01-10 Vladimir Serbinenko + * grub-core/kern/disk.c (grub_disk_write): Fix sector number on 4K sector devices. diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c index 3f3e6e3..c0fed80 100644 --- a/grub-core/loader/efi/chainloader.c +++ b/grub-core/loader/efi/chainloader.c @@ -35,6 +35,10 @@ #include #include #include +#if defined (__i386__) || defined (__x86_64__) +#include +#include +#endif GRUB_MOD_LICENSE ("GPLv3+"); @@ -198,6 +202,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), grub_efi_device_path_t *dp = 0; grub_efi_loaded_image_t *loaded_image; char *filename; + void *boot_image = 0; grub_efi_handle_t dev_handle = 0; if (argc == 0) @@ -278,7 +283,8 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), goto fail; } - if (grub_file_read (file, (void *) ((grub_addr_t) address), size) != size) + boot_image = (void *) ((grub_addr_t) address); + if (grub_file_read (file, boot_image, size) != size) { if (grub_errno == GRUB_ERR_NONE) grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), @@ -287,9 +293,45 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), goto fail; } +#if defined (__i386__) || defined (__x86_64__) + if (size >= (grub_ssize_t) sizeof (struct grub_macho_fat_header)) + { + struct grub_macho_fat_header *head = boot_image; + if (head->magic + == grub_cpu_to_le32_compile_time (GRUB_MACHO_FAT_EFI_MAGIC)) + { + grub_uint32_t i; + struct grub_macho_fat_arch *archs + = (struct grub_macho_fat_arch *) (head + 1); + for (i = 0; i < grub_cpu_to_le32 (head->nfat_arch); i++) + { + if (GRUB_MACHO_CPUTYPE_IS_HOST_CURRENT (archs[i].cputype)) + break; + } + if (i == grub_cpu_to_le32 (head->nfat_arch)) + { + grub_error (GRUB_ERR_BAD_OS, "no compatible arch found"); + goto fail; + } + if (grub_cpu_to_le32 (archs[i].offset) + > ~grub_cpu_to_le32 (archs[i].size) + || grub_cpu_to_le32 (archs[i].offset) + + grub_cpu_to_le32 (archs[i].size) + > (grub_size_t) size) + { + grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), + filename); + goto fail; + } + boot_image = (char *) boot_image + grub_cpu_to_le32 (archs[i].offset); + size = grub_cpu_to_le32 (archs[i].size); + } + } +#endif + status = efi_call_6 (b->load_image, 0, grub_efi_image_handle, file_path, - (void *) ((grub_addr_t) address), size, - &image_handle); + boot_image, size, + &image_handle); if (status != GRUB_EFI_SUCCESS) { if (status == GRUB_EFI_OUT_OF_RESOURCES) diff --git a/include/grub/i386/macho.h b/include/grub/i386/macho.h index f22c211..5ee9f9e 100644 --- a/include/grub/i386/macho.h +++ b/include/grub/i386/macho.h @@ -23,6 +23,11 @@ #define GRUB_MACHO_CPUTYPE_IS_HOST32(x) ((x)==0x00000007) #define GRUB_MACHO_CPUTYPE_IS_HOST64(x) ((x)==0x01000007) +#ifdef __x86_64__ +#define GRUB_MACHO_CPUTYPE_IS_HOST_CURRENT(x) ((x)==0x01000007) +#else +#define GRUB_MACHO_CPUTYPE_IS_HOST_CURRENT(x) ((x)==0x00000007) +#endif struct grub_macho_thread32 { diff --git a/include/grub/macho.h b/include/grub/macho.h index 6a98b6e..21f0714 100644 --- a/include/grub/macho.h +++ b/include/grub/macho.h @@ -27,6 +27,7 @@ struct grub_macho_fat_header grub_uint32_t nfat_arch; } __attribute__ ((packed)); #define GRUB_MACHO_FAT_MAGIC 0xcafebabe +#define GRUB_MACHO_FAT_EFI_MAGIC 0x0ef1fab9 typedef grub_uint32_t grub_macho_cpu_type_t; typedef grub_uint32_t grub_macho_cpu_subtype_t; -- 1.8.2.1