Blame SOURCES/0093-Support-Apple-FAT-binaries-on-non-Apple-platforms.patch

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