+2013-01-10 Vladimir Serbinenko <phcoder@gmail.com>
+
+ 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 <phcoder@gmail.com>
* grub-core/kern/disk.c (grub_disk_write): Fix sector number on 4K
#include <grub/command.h>
#include <grub/i18n.h>
#include <grub/net.h>
+#if defined (__i386__) || defined (__x86_64__)
+#include <grub/macho.h>
+#include <grub/i386/macho.h>
+#endif
GRUB_MOD_LICENSE ("GPLv3+");
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)
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"),
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)