/* xnu.c - load xnu kernel. Thanks to Florian Idelberger for all the
   time he spent testing this
 */
/*
 *  GRUB  --  GRand Unified Bootloader
 *  Copyright (C) 2009  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/>.
 */

#include <grub/file.h>
#include <grub/xnu.h>
#include <grub/cpu/xnu.h>
#include <grub/mm.h>
#include <grub/dl.h>
#include <grub/loader.h>
#include <grub/machoload.h>
#include <grub/macho.h>
#include <grub/cpu/macho.h>
#include <grub/command.h>
#include <grub/misc.h>
#include <grub/extcmd.h>
#include <grub/env.h>
#include <grub/i18n.h>
#include <grub/verify.h>
#include <grub/efi/sb.h>

GRUB_MOD_LICENSE ("GPLv3+");

#if defined (__i386) && !defined (GRUB_MACHINE_EFI)
#include <grub/autoefi.h>
#endif

struct grub_xnu_devtree_key *grub_xnu_devtree_root = 0;
static int driverspackagenum = 0;
static int driversnum = 0;
int grub_xnu_is_64bit = 0;
int grub_xnu_darwin_version = 0;

grub_addr_t grub_xnu_heap_target_start = 0;
grub_size_t grub_xnu_heap_size = 0;
struct grub_relocator *grub_xnu_relocator;

static grub_err_t
grub_xnu_register_memory (const char *prefix, int *suffix,
			  grub_addr_t addr, grub_size_t size);
grub_err_t
grub_xnu_heap_malloc (int size, void **src, grub_addr_t *target)
{
  grub_err_t err;
  grub_relocator_chunk_t ch;
  
  err = grub_relocator_alloc_chunk_addr (grub_xnu_relocator, &ch,
					 grub_xnu_heap_target_start
					 + grub_xnu_heap_size, size);
  if (err)
    return err;

  *src = get_virtual_current_address (ch);
  *target = grub_xnu_heap_target_start + grub_xnu_heap_size;
  grub_xnu_heap_size += size;
  grub_dprintf ("xnu", "val=%p\n", *src);
  return GRUB_ERR_NONE;
}

/* Make sure next block of the heap will be aligned.
   Please notice: aligned are pointers AFTER relocation
   and not the current ones. */
grub_err_t
grub_xnu_align_heap (int align)
{
  grub_xnu_heap_size
    = ALIGN_UP (grub_xnu_heap_target_start+ grub_xnu_heap_size, align)
    - grub_xnu_heap_target_start;
  return GRUB_ERR_NONE;
}

/* Free subtree pointed by CUR. */
void
grub_xnu_free_devtree (struct grub_xnu_devtree_key *cur)
{
  struct grub_xnu_devtree_key *d;
  while (cur)
    {
      grub_free (cur->name);
      if (cur->datasize == -1)
	grub_xnu_free_devtree (cur->first_child);
      else if (cur->data)
	grub_free (cur->data);
      d = cur->next;
      grub_free (cur);
      cur = d;
    }
}

/* Compute the size of device tree in xnu format. */
static grub_size_t
grub_xnu_writetree_get_size (struct grub_xnu_devtree_key *start,
			     const char *name)
{
  grub_size_t ret;
  struct grub_xnu_devtree_key *cur;

  /* Key header. */
  ret = 2 * sizeof (grub_uint32_t);

  /* "name" value. */
  ret += 32 + sizeof (grub_uint32_t)
    + grub_strlen (name) + 4
    - (grub_strlen (name) % 4);

  for (cur = start; cur; cur = cur->next)
    if (cur->datasize != -1)
      {
	int align_overhead;

	align_overhead = 4 - (cur->datasize % 4);
	if (align_overhead == 4)
	  align_overhead = 0;
	ret += 32 + sizeof (grub_uint32_t) + cur->datasize + align_overhead;
      }
    else
      ret += grub_xnu_writetree_get_size (cur->first_child, cur->name);
  return ret;
}

/* Write devtree in XNU format at curptr assuming the head is named NAME.*/
static void *
grub_xnu_writetree_toheap_real (void *curptr,
				struct grub_xnu_devtree_key *start,
				const char *name)
{
  struct grub_xnu_devtree_key *cur;
  int nkeys = 0, nvals = 0;
  for (cur = start; cur; cur = cur->next)
    {
      if (cur->datasize == -1)
	nkeys++;
      else
	nvals++;
    }
  /* For the name. */
  nvals++;

  *((grub_uint32_t *) curptr) = nvals;
  curptr = ((grub_uint32_t *) curptr) + 1;
  *((grub_uint32_t *) curptr) = nkeys;
  curptr = ((grub_uint32_t *) curptr) + 1;

  /* First comes "name" value. */
  grub_memset (curptr, 0, 32);
  grub_memcpy (curptr, "name", 4);
  curptr = ((grub_uint8_t *) curptr) + 32;
  *((grub_uint32_t *)curptr) = grub_strlen (name) + 1;
  curptr = ((grub_uint32_t *) curptr) + 1;
  grub_memcpy (curptr, name, grub_strlen (name));
  curptr = ((grub_uint8_t *) curptr) + grub_strlen (name);
  grub_memset (curptr, 0, 4 - (grub_strlen (name) % 4));
  curptr = ((grub_uint8_t *) curptr) + (4 - (grub_strlen (name) % 4));

  /* Then the other values. */
  for (cur = start; cur; cur = cur->next)
    if (cur->datasize != -1)
      {
	int align_overhead;

	align_overhead = 4 - (cur->datasize % 4);
	if (align_overhead == 4)
	  align_overhead = 0;
	grub_memset (curptr, 0, 32);
	grub_strncpy (curptr, cur->name, 31);
	curptr = ((grub_uint8_t *) curptr) + 32;
	*((grub_uint32_t *) curptr) = cur->datasize;
	curptr = ((grub_uint32_t *) curptr) + 1;
	grub_memcpy (curptr, cur->data, cur->datasize);
	curptr = ((grub_uint8_t *) curptr) + cur->datasize;
	grub_memset (curptr, 0, align_overhead);
	curptr = ((grub_uint8_t *) curptr) + align_overhead;
      }

  /* And then the keys. Recursively use this function. */
  for (cur = start; cur; cur = cur->next)
    if (cur->datasize == -1)
      {
	curptr = grub_xnu_writetree_toheap_real (curptr,
						 cur->first_child,
						 cur->name);
	if (!curptr)
	  return 0;
      }
  return curptr;
}

grub_err_t
grub_xnu_writetree_toheap (grub_addr_t *target, grub_size_t *size)
{
  struct grub_xnu_devtree_key *chosen;
  struct grub_xnu_devtree_key *memorymap;
  struct grub_xnu_devtree_key *driverkey;
  struct grub_xnu_extdesc *extdesc;
  grub_err_t err;
  void *src;

  err = grub_xnu_align_heap (GRUB_XNU_PAGESIZE);
  if (err)
    return err;

  /* Device tree itself is in the memory map of device tree. */
  /* Create a dummy value in memory-map. */
  chosen = grub_xnu_create_key (&grub_xnu_devtree_root, "chosen");
  if (! chosen)
    return grub_errno;
  memorymap = grub_xnu_create_key (&(chosen->first_child), "memory-map");
  if (! memorymap)
    return grub_errno;

  driverkey = (struct grub_xnu_devtree_key *) grub_malloc (sizeof (*driverkey));
  if (! driverkey)
    return grub_errno;
  driverkey->name = grub_strdup ("DeviceTree");
  if (! driverkey->name)
    return grub_errno;
  driverkey->datasize = sizeof (*extdesc);
  driverkey->next = memorymap->first_child;
  memorymap->first_child = driverkey;
  driverkey->data = extdesc
    = (struct grub_xnu_extdesc *) grub_malloc (sizeof (*extdesc));
  if (! driverkey->data)
    return grub_errno;

  /* Allocate the space based on the size with dummy value. */
  *size = grub_xnu_writetree_get_size (grub_xnu_devtree_root, "/");
  err = grub_xnu_heap_malloc (ALIGN_UP (*size + 1, GRUB_XNU_PAGESIZE),
			      &src, target);
  if (err)
    return err;

  /* Put real data in the dummy. */
  extdesc->addr = *target;
  extdesc->size = (grub_uint32_t) *size;

  /* Write the tree to heap. */
  grub_xnu_writetree_toheap_real (src, grub_xnu_devtree_root, "/");
  return GRUB_ERR_NONE;
}

/* Find a key or value in parent key. */
struct grub_xnu_devtree_key *
grub_xnu_find_key (struct grub_xnu_devtree_key *parent, const char *name)
{
  struct grub_xnu_devtree_key *cur;
  for (cur = parent; cur; cur = cur->next)
    if (grub_strcmp (cur->name, name) == 0)
      return cur;
  return 0;
}

struct grub_xnu_devtree_key *
grub_xnu_create_key (struct grub_xnu_devtree_key **parent, const char *name)
{
  struct grub_xnu_devtree_key *ret;
  ret = grub_xnu_find_key (*parent, name);
  if (ret)
    return ret;
  ret = (struct grub_xnu_devtree_key *) grub_zalloc (sizeof (*ret));
  if (! ret)
    return 0;
  ret->name = grub_strdup (name);
  if (! ret->name)
    {
      grub_free (ret);
      return 0;
    }
  ret->datasize = -1;
  ret->next = *parent;
  *parent = ret;
  return ret;
}

struct grub_xnu_devtree_key *
grub_xnu_create_value (struct grub_xnu_devtree_key **parent, const char *name)
{
  struct grub_xnu_devtree_key *ret;
  ret = grub_xnu_find_key (*parent, name);
  if (ret)
    {
      if (ret->datasize == -1)
	grub_xnu_free_devtree (ret->first_child);
      else if (ret->datasize)
	grub_free (ret->data);
      ret->datasize = 0;
      ret->data = 0;
      return ret;
    }
  ret = (struct grub_xnu_devtree_key *) grub_zalloc (sizeof (*ret));
  if (! ret)
    return 0;
  ret->name = grub_strdup (name);
  if (! ret->name)
    {
      grub_free (ret);
      return 0;
    }
  ret->next = *parent;
  *parent = ret;
  return ret;
}

static grub_err_t
grub_xnu_unload (void)
{
  grub_cpu_xnu_unload ();

  grub_xnu_free_devtree (grub_xnu_devtree_root);
  grub_xnu_devtree_root = 0;

  /* Free loaded image. */
  driversnum = 0;
  driverspackagenum = 0;
  grub_relocator_unload (grub_xnu_relocator);
  grub_xnu_relocator = NULL;
  grub_xnu_heap_target_start = 0;
  grub_xnu_heap_size = 0;
  grub_xnu_unlock ();
  return GRUB_ERR_NONE;
}

static grub_err_t
grub_cmd_xnu_kernel (grub_command_t cmd __attribute__ ((unused)),
		     int argc, char *args[])
{
  grub_err_t err;
  grub_macho_t macho;
  grub_uint32_t startcode, endcode;
  int i;
  char *ptr;
  void *loadaddr;
  grub_addr_t loadaddr_target;

  if (argc < 1)
    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));

  grub_xnu_unload ();

  macho = grub_macho_open (args[0], GRUB_FILE_TYPE_XNU_KERNEL, 0);
  if (! macho)
    return grub_errno;

  err = grub_macho_size32 (macho, &startcode, &endcode, GRUB_MACHO_NOBSS,
			   args[0]);
  if (err)
    {
      grub_macho_close (macho);
      grub_xnu_unload ();
      return err;
    }

  grub_dprintf ("xnu", "endcode = %lx, startcode = %lx\n",
		(unsigned long) endcode, (unsigned long) startcode);

  grub_xnu_relocator = grub_relocator_new ();
  if (!grub_xnu_relocator)
    return grub_errno;
  grub_xnu_heap_target_start = startcode;
  err = grub_xnu_heap_malloc (endcode - startcode, &loadaddr,
			      &loadaddr_target);

  if (err)
    {
      grub_macho_close (macho);
      grub_xnu_unload ();
      return err;
    }

  /* Load kernel. */
  err = grub_macho_load32 (macho, args[0], (char *) loadaddr - startcode,
			   GRUB_MACHO_NOBSS, &grub_xnu_darwin_version);
  if (err)
    {
      grub_macho_close (macho);
      grub_xnu_unload ();
      return err;
    }

  grub_xnu_entry_point = grub_macho_get_entry_point32 (macho, args[0]);
  if (! grub_xnu_entry_point)
    {
      grub_macho_close (macho);
      grub_xnu_unload ();
      return grub_error (GRUB_ERR_BAD_OS, "couldn't find entry point");
    }

  grub_macho_close (macho);

  err = grub_xnu_align_heap (GRUB_XNU_PAGESIZE);
  if (err)
    {
      grub_xnu_unload ();
      return err;
    }

  /* Copy parameters to kernel command line. */
  ptr = grub_xnu_cmdline;
  for (i = 1; i < argc; i++)
    {
      if (ptr + grub_strlen (args[i]) + 1
	  >= grub_xnu_cmdline + sizeof (grub_xnu_cmdline))
	break;
      grub_memcpy (ptr, args[i], grub_strlen (args[i]));
      ptr += grub_strlen (args[i]);
      *ptr = ' ';
      ptr++;
    }

  /* Replace last space by '\0'. */
  if (ptr != grub_xnu_cmdline)
    *(ptr - 1) = 0;

  err = grub_verify_string (grub_xnu_cmdline, GRUB_VERIFY_KERNEL_CMDLINE);
  if (err)
    return err;

#if defined (__i386) && !defined (GRUB_MACHINE_EFI)
  err = grub_efiemu_autocore ();
  if (err)
    return err;
#endif

  grub_loader_set (grub_xnu_boot, grub_xnu_unload, 0);

  grub_xnu_lock ();
  grub_xnu_is_64bit = 0;

  return 0;
}

static grub_err_t
grub_cmd_xnu_kernel64 (grub_command_t cmd __attribute__ ((unused)),
		       int argc, char *args[])
{
  grub_err_t err;
  grub_macho_t macho;
  grub_uint64_t startcode, endcode;
  int i;
  char *ptr;
  void *loadaddr;
  grub_addr_t loadaddr_target;

  if (argc < 1)
    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));

  grub_xnu_unload ();

  macho = grub_macho_open (args[0], GRUB_FILE_TYPE_XNU_KERNEL, 1);
  if (! macho)
    return grub_errno;

  err = grub_macho_size64 (macho, &startcode, &endcode, GRUB_MACHO_NOBSS,
			   args[0]);
  if (err)
    {
      grub_macho_close (macho);
      grub_xnu_unload ();
      return err;
    }

  startcode &= 0x0fffffff;
  endcode &= 0x0fffffff;

  grub_dprintf ("xnu", "endcode = %lx, startcode = %lx\n",
		(unsigned long) endcode, (unsigned long) startcode);

  grub_xnu_relocator = grub_relocator_new ();
  if (!grub_xnu_relocator)
    return grub_errno;
  grub_xnu_heap_target_start = startcode;
  err = grub_xnu_heap_malloc (endcode - startcode, &loadaddr,
			      &loadaddr_target);

  if (err)
    {
      grub_macho_close (macho);
      grub_xnu_unload ();
      return err;
    }

  /* Load kernel. */
  err = grub_macho_load64 (macho, args[0], (char *) loadaddr - startcode,
			   GRUB_MACHO_NOBSS, &grub_xnu_darwin_version);
  if (err)
    {
      grub_macho_close (macho);
      grub_xnu_unload ();
      return err;
    }

  grub_xnu_entry_point = grub_macho_get_entry_point64 (macho, args[0])
    & 0x0fffffff;
  if (! grub_xnu_entry_point)
    {
      grub_macho_close (macho);
      grub_xnu_unload ();
      return grub_error (GRUB_ERR_BAD_OS, "couldn't find entry point");
    }

  grub_macho_close (macho);

  err = grub_xnu_align_heap (GRUB_XNU_PAGESIZE);
  if (err)
    {
      grub_xnu_unload ();
      return err;
    }

  /* Copy parameters to kernel command line. */
  ptr = grub_xnu_cmdline;
  for (i = 1; i < argc; i++)
    {
      if (ptr + grub_strlen (args[i]) + 1
	  >= grub_xnu_cmdline + sizeof (grub_xnu_cmdline))
	break;
      grub_memcpy (ptr, args[i], grub_strlen (args[i]));
      ptr += grub_strlen (args[i]);
      *ptr = ' ';
      ptr++;
    }

  /* Replace last space by '\0'. */
  if (ptr != grub_xnu_cmdline)
    *(ptr - 1) = 0;

  err = grub_verify_string (grub_xnu_cmdline, GRUB_VERIFY_KERNEL_CMDLINE);
  if (err)
    return err;

#if defined (__i386) && !defined (GRUB_MACHINE_EFI)
  err = grub_efiemu_autocore ();
  if (err)
    return err;
#endif

  grub_loader_set (grub_xnu_boot, grub_xnu_unload, 0);

  grub_xnu_lock ();
  grub_xnu_is_64bit = 1;

  return 0;
}

/* Register a memory in a memory map under name PREFIXSUFFIX
   and increment SUFFIX. */
static grub_err_t
grub_xnu_register_memory (const char *prefix, int *suffix,
			  grub_addr_t addr, grub_size_t size)
{
  struct grub_xnu_devtree_key *chosen;
  struct grub_xnu_devtree_key *memorymap;
  struct grub_xnu_devtree_key *driverkey;
  struct grub_xnu_extdesc *extdesc;

  if (! grub_xnu_heap_size)
    return grub_error (GRUB_ERR_BAD_OS, N_("you need to load the kernel first"));

  chosen = grub_xnu_create_key (&grub_xnu_devtree_root, "chosen");
  if (! chosen)
    return grub_errno;
  memorymap = grub_xnu_create_key (&(chosen->first_child), "memory-map");
  if (! memorymap)
    return grub_errno;

  driverkey = (struct grub_xnu_devtree_key *) grub_malloc (sizeof (*driverkey));
  if (! driverkey)
    return grub_errno;
  if (suffix)
    driverkey->name = grub_xasprintf ("%s%d", prefix, (*suffix)++);
  else
    driverkey->name = grub_strdup (prefix);
  if (!driverkey->name)
    {
      grub_free (driverkey);
      return grub_errno;
    }
  driverkey->datasize = sizeof (*extdesc);
  driverkey->next = memorymap->first_child;
  driverkey->data = extdesc
    = (struct grub_xnu_extdesc *) grub_malloc (sizeof (*extdesc));
  if (! driverkey->data)
    {
      grub_free (driverkey->name);
      grub_free (driverkey);
      return grub_errno;
    }
  memorymap->first_child = driverkey;
  extdesc->addr = addr;
  extdesc->size = (grub_uint32_t) size;
  return GRUB_ERR_NONE;
}

static inline char *
get_name_ptr (char *name)
{
  char *p = name, *p2;
  /* Skip Info.plist.  */
  p2 = grub_strrchr (p, '/');
  if (!p2)
    return name;
  if (p2 == name)
    return name + 1;
  p = p2 - 1;

  p2 = grub_strrchr (p, '/');
  if (!p2)
    return name;
  if (p2 == name)
    return name + 1;
  if (grub_memcmp (p2, "/Contents/", sizeof ("/Contents/") - 1) != 0)
    return p2 + 1;

  p = p2 - 1;

  p2 = grub_strrchr (p, '/');
  if (!p2)
    return name;
  return p2 + 1;
}

/* Load .kext. */
static grub_err_t
grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile,
		      const char *filename)
{
  grub_macho_t macho;
  grub_err_t err;
  grub_file_t infoplist;
  struct grub_xnu_extheader *exthead;
  int neededspace = sizeof (*exthead);
  grub_uint8_t *buf;
  void *buf0;
  grub_addr_t buf_target;
  grub_size_t infoplistsize = 0, machosize = 0;
  char *name, *nameend;
  int namelen;

  name = get_name_ptr (infoplistname);
  nameend = grub_strchr (name, '/');

  if (nameend)
    namelen = nameend - name;
  else
    namelen = grub_strlen (name);

  neededspace += namelen + 1;

  if (! grub_xnu_heap_size)
    return grub_error (GRUB_ERR_BAD_OS, N_("you need to load the kernel first"));

  /* Compute the needed space. */
  if (binaryfile)
    {
      macho = grub_macho_file (binaryfile, filename, grub_xnu_is_64bit);
      if (!macho)
	grub_file_close (binaryfile);
      else
	{
	  if (grub_xnu_is_64bit)
	    machosize = grub_macho_filesize64 (macho);
	  else
	    machosize = grub_macho_filesize32 (macho);
	}
      neededspace += machosize;
    }
  else
    macho = 0;

  if (infoplistname)
    infoplist = grub_file_open (infoplistname, GRUB_FILE_TYPE_XNU_INFO_PLIST);
  else
    infoplist = 0;
  grub_errno = GRUB_ERR_NONE;
  if (infoplist)
    {
      infoplistsize = grub_file_size (infoplist);
      neededspace += infoplistsize + 1;
    }
  else
    infoplistsize = 0;

  /* Allocate the space. */
  err = grub_xnu_align_heap (GRUB_XNU_PAGESIZE);
  if (err)
    goto fail;
  err = grub_xnu_heap_malloc (neededspace, &buf0, &buf_target);
  if (err)
    goto fail;
  buf = buf0;

  exthead = (struct grub_xnu_extheader *) buf;
  grub_memset (exthead, 0, sizeof (*exthead));
  buf += sizeof (*exthead);

  /* Load the binary. */
  if (macho)
    {
      exthead->binaryaddr = buf_target + (buf - (grub_uint8_t *) buf0);
      exthead->binarysize = machosize;
      if (grub_xnu_is_64bit)
	err = grub_macho_readfile64 (macho, filename, buf);
      else
	err = grub_macho_readfile32 (macho, filename, buf);
      if (err)
	goto fail;
      grub_macho_close (macho);
      buf += machosize;
    }
  grub_errno = GRUB_ERR_NONE;

  /* Load the plist. */
  if (infoplist)
    {
      exthead->infoplistaddr = buf_target + (buf - (grub_uint8_t *) buf0);
      exthead->infoplistsize = infoplistsize + 1;
      if (grub_file_read (infoplist, buf, infoplistsize)
	  != (grub_ssize_t) (infoplistsize))
	{
	  grub_file_close (infoplist);
	  if (!grub_errno)
	    grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
			infoplistname);
	  return grub_errno;
	}
      grub_file_close (infoplist);
      buf[infoplistsize] = 0;
      buf += infoplistsize + 1;
    }
  grub_errno = GRUB_ERR_NONE;

  exthead->nameaddr = (buf - (grub_uint8_t *) buf0) + buf_target;
  exthead->namesize = namelen + 1;
  grub_memcpy (buf, name, namelen);
  buf[namelen] = 0;
  buf += namelen + 1;

  /* Announce to kernel */
  return grub_xnu_register_memory ("Driver-", &driversnum, buf_target,
				   neededspace);
fail:
  if (macho)
    grub_macho_close (macho);
  return err;
}

/* Load mkext. */
static grub_err_t
grub_cmd_xnu_mkext (grub_command_t cmd __attribute__ ((unused)),
		    int argc, char *args[])
{
  grub_file_t file;
  void *loadto;
  grub_addr_t loadto_target;
  grub_err_t err;
  grub_off_t readoff = 0;
  grub_ssize_t readlen = -1;
  struct grub_macho_fat_header head;
  struct grub_macho_fat_arch *archs;
  int narchs, i;

  if (argc != 1)
    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));

  if (! grub_xnu_heap_size)
    return grub_error (GRUB_ERR_BAD_OS, N_("you need to load the kernel first"));

  file = grub_file_open (args[0], GRUB_FILE_TYPE_XNU_MKEXT);
  if (! file)
    return grub_errno;

  /* Sometimes caches are fat binary. Errgh. */
  if (grub_file_read (file, &head, sizeof (head))
      != (grub_ssize_t) (sizeof (head)))
    {
      /* I don't know the internal structure of package but
	 can hardly imagine a valid package shorter than 20 bytes. */
      grub_file_close (file);
      if (!grub_errno)
	grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), args[0]);
      return grub_errno;
    }

  /* Find the corresponding architecture. */
  if (grub_be_to_cpu32 (head.magic) == GRUB_MACHO_FAT_MAGIC)
    {
      narchs = grub_be_to_cpu32 (head.nfat_arch);
      archs = grub_malloc (sizeof (struct grub_macho_fat_arch) * narchs);
      if (! archs)
	{
	  grub_file_close (file);
	  return grub_errno;

	}
      if (grub_file_read (file, archs,
			  sizeof (struct grub_macho_fat_arch) * narchs)
	  != (grub_ssize_t) sizeof(struct grub_macho_fat_arch) * narchs)
	{
	  grub_free (archs);
	  if (!grub_errno)
	    grub_error (GRUB_ERR_READ_ERROR, N_("premature end of file %s"),
			args[0]);
	  return grub_errno;
	}
      for (i = 0; i < narchs; i++)
	{
	  if (!grub_xnu_is_64bit && GRUB_MACHO_CPUTYPE_IS_HOST32
	      (grub_be_to_cpu32 (archs[i].cputype)))
	    {
	      readoff = grub_be_to_cpu32 (archs[i].offset);
	      readlen = grub_be_to_cpu32 (archs[i].size);
	    }
	  if (grub_xnu_is_64bit && GRUB_MACHO_CPUTYPE_IS_HOST64
	      (grub_be_to_cpu32 (archs[i].cputype)))
	    {
	      readoff = grub_be_to_cpu32 (archs[i].offset);
	      readlen = grub_be_to_cpu32 (archs[i].size);
	    }
	}
      grub_free (archs);
    }
  else
    {
      /* It's a flat file. Some sane people still exist. */
      readoff = 0;
      readlen = grub_file_size (file);
    }

  if (readlen == -1)
    {
      grub_file_close (file);
      return grub_error (GRUB_ERR_BAD_OS, "no suitable architecture is found");
    }

  /* Allocate space. */
  err = grub_xnu_align_heap (GRUB_XNU_PAGESIZE);
  if (err)
    {
      grub_file_close (file);
      return err;
    }

  err = grub_xnu_heap_malloc (readlen, &loadto, &loadto_target);
  if (err)
    {
      grub_file_close (file);
      return err;
    }

  /* Read the file. */
  grub_file_seek (file, readoff);
  if (grub_file_read (file, loadto, readlen) != (grub_ssize_t) (readlen))
    {
      grub_file_close (file);
      if (!grub_errno)
	grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), args[0]);
      return grub_errno;
    }
  grub_file_close (file);

  /* Pass it to kernel. */
  return grub_xnu_register_memory ("DriversPackage-", &driverspackagenum,
				   loadto_target, readlen);
}

static grub_err_t
grub_cmd_xnu_ramdisk (grub_command_t cmd __attribute__ ((unused)),
		      int argc, char *args[])
{
  grub_file_t file;
  void *loadto;
  grub_addr_t loadto_target;
  grub_err_t err;
  grub_size_t size;

  if (argc != 1)
    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));

  if (! grub_xnu_heap_size)
    return grub_error (GRUB_ERR_BAD_OS, N_("you need to load the kernel first"));

  file = grub_file_open (args[0], GRUB_FILE_TYPE_XNU_RAMDISK);
  if (! file)
    return grub_errno;

  err = grub_xnu_align_heap (GRUB_XNU_PAGESIZE);
  if (err)
    return err;

  size = grub_file_size (file);

  err = grub_xnu_heap_malloc (size, &loadto, &loadto_target);
  if (err)
    return err;
  if (grub_file_read (file, loadto, size) != (grub_ssize_t) (size))
    {
      grub_file_close (file);
      if (!grub_errno)
	grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), args[0]);
      return grub_errno;
    }
  return grub_xnu_register_memory ("RAMDisk", 0, loadto_target, size);
}

/* Returns true if the kext should be loaded according to plist
   and osbundlereq. Also fill BINNAME. */
static int
grub_xnu_check_os_bundle_required (char *plistname,
				   const char *osbundlereq,
				   char **binname)
{
  grub_file_t file;
  char *buf = 0, *tagstart = 0, *ptr1 = 0, *keyptr = 0;
  char *stringptr = 0, *ptr2 = 0;
  grub_size_t size;
  int depth = 0;
  int ret;
  int osbundlekeyfound = 0, binnamekeyfound = 0;
  if (binname)
    *binname = 0;

  file = grub_file_open (plistname, GRUB_FILE_TYPE_XNU_INFO_PLIST);
  if (! file)
    return 0;

  size = grub_file_size (file);
  buf = grub_malloc (size);
  if (! buf)
    {
      grub_file_close (file);
      return 0;
    }
  if (grub_file_read (file, buf, size) != (grub_ssize_t) (size))
    {
      grub_file_close (file);
      if (!grub_errno)
	grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), plistname);
      return 0;
    }
  grub_file_close (file);

  /* Set the return value for the case when no OSBundleRequired tag is found. */
  if (osbundlereq)
    ret = grub_strword (osbundlereq, "all") || grub_strword (osbundlereq, "-");
  else
    ret = 1;

  /* Parse plist. It's quite dirty and inextensible but does its job. */
  for (ptr1 = buf; ptr1 < buf + size; ptr1++)
    switch (*ptr1)
      {
      case '<':
	tagstart = ptr1;
	*ptr1 = 0;
	if (keyptr && depth == 4
	    && grub_strcmp (keyptr, "OSBundleRequired") == 0)
	  osbundlekeyfound = 1;
	if (keyptr && depth == 4 &&
	    grub_strcmp (keyptr, "CFBundleExecutable") == 0)
	  binnamekeyfound = 1;
	if (stringptr && osbundlekeyfound && osbundlereq && depth == 4)
	  {
	    for (ptr2 = stringptr; *ptr2; ptr2++)
	      *ptr2 = grub_tolower (*ptr2);
	    ret = grub_strword (osbundlereq, stringptr)
	      || grub_strword (osbundlereq, "all");
	  }
	if (stringptr && binnamekeyfound && binname && depth == 4)
	  {
	    if (*binname)
	      grub_free (*binname);
	    *binname = grub_strdup (stringptr);
	  }

	*ptr1 = '<';
	keyptr = 0;
	stringptr = 0;
	break;
      case '>':
	if (! tagstart)
	  {
	    grub_free (buf);
	    grub_error (GRUB_ERR_BAD_OS, "can't parse %s", plistname);
	    return 0;
	  }
	*ptr1 = 0;
	if (tagstart[1] == '?' || ptr1[-1] == '/')
	  {
	    osbundlekeyfound = 0;
	    *ptr1 = '>';
	    break;
	  }
	if (depth == 3 && grub_strcmp (tagstart + 1, "key") == 0)
	  keyptr = ptr1 + 1;
	if (depth == 3 && grub_strcmp (tagstart + 1, "string") == 0)
	  stringptr = ptr1 + 1;
	else if (grub_strcmp (tagstart + 1, "/key") != 0)
	  {
	    osbundlekeyfound = 0;
	    binnamekeyfound = 0;
	  }
	*ptr1 = '>';

	if (tagstart[1] == '/')
	  depth--;
	else
	  depth++;
	break;
      }
  grub_free (buf);

  return ret;
}

/* Context for grub_xnu_scan_dir_for_kexts.  */
struct grub_xnu_scan_dir_for_kexts_ctx
{
  char *dirname;
  const char *osbundlerequired;
  int maxrecursion;
};

/* Helper for grub_xnu_scan_dir_for_kexts.  */
static int
grub_xnu_scan_dir_for_kexts_load (const char *filename,
				  const struct grub_dirhook_info *info,
				  void *data)
{
  struct grub_xnu_scan_dir_for_kexts_ctx *ctx = data;
  char *newdirname;

  if (! info->dir)
    return 0;
  if (filename[0] == '.')
    return 0;

  if (grub_strlen (filename) < 5 ||
      grub_memcmp (filename + grub_strlen (filename) - 5, ".kext", 5) != 0)
    return 0;

  newdirname
    = grub_malloc (grub_strlen (ctx->dirname) + grub_strlen (filename) + 2);

  /* It's a .kext. Try to load it. */
  if (newdirname)
    {
      grub_strcpy (newdirname, ctx->dirname);
      newdirname[grub_strlen (newdirname) + 1] = 0;
      newdirname[grub_strlen (newdirname)] = '/';
      grub_strcpy (newdirname + grub_strlen (newdirname), filename);
      grub_xnu_load_kext_from_dir (newdirname, ctx->osbundlerequired,
				   ctx->maxrecursion);
      if (grub_errno == GRUB_ERR_BAD_OS)
	grub_errno = GRUB_ERR_NONE;
      grub_free (newdirname);
    }
  return 0;
}

/* Load all loadable kexts placed under DIRNAME and matching OSBUNDLEREQUIRED */
grub_err_t
grub_xnu_scan_dir_for_kexts (char *dirname, const char *osbundlerequired,
			     int maxrecursion)
{
  struct grub_xnu_scan_dir_for_kexts_ctx ctx = {
    .dirname = dirname,
    .osbundlerequired = osbundlerequired,
    .maxrecursion = maxrecursion
  };
  grub_device_t dev;
  char *device_name;
  grub_fs_t fs;
  const char *path;

  if (! grub_xnu_heap_size)
    return grub_error (GRUB_ERR_BAD_OS, N_("you need to load the kernel first"));

  device_name = grub_file_get_device_name (dirname);
  dev = grub_device_open (device_name);
  if (dev)
    {
      fs = grub_fs_probe (dev);
      path = grub_strchr (dirname, ')');
      if (! path)
	path = dirname;
      else
	path++;

      if (fs)
	(fs->dir) (dev, path, grub_xnu_scan_dir_for_kexts_load, &ctx);
      grub_device_close (dev);
    }
  grub_free (device_name);

  return GRUB_ERR_NONE;
}

/* Context for grub_xnu_load_kext_from_dir.  */
struct grub_xnu_load_kext_from_dir_ctx
{
  char *dirname;
  const char *osbundlerequired;
  int maxrecursion;
  char *plistname;
  char *newdirname;
  int usemacos;
};

/* Helper for grub_xnu_load_kext_from_dir.  */
static int
grub_xnu_load_kext_from_dir_load (const char *filename,
				  const struct grub_dirhook_info *info,
				  void *data)
{
  struct grub_xnu_load_kext_from_dir_ctx *ctx = data;

  if (grub_strlen (filename) > 15)
    return 0;
  grub_strcpy (ctx->newdirname + grub_strlen (ctx->dirname) + 1, filename);

  /* If the kext contains directory "Contents" all real stuff is in
     this directory. */
  if (info->dir && grub_strcasecmp (filename, "Contents") == 0)
    grub_xnu_load_kext_from_dir (ctx->newdirname, ctx->osbundlerequired,
				 ctx->maxrecursion - 1);

  /* Directory "Plugins" contains nested kexts. */
  if (info->dir && grub_strcasecmp (filename, "Plugins") == 0)
    grub_xnu_scan_dir_for_kexts (ctx->newdirname, ctx->osbundlerequired,
				 ctx->maxrecursion - 1);

  /* Directory "MacOS" contains executable, otherwise executable is
     on the top. */
  if (info->dir && grub_strcasecmp (filename, "MacOS") == 0)
    ctx->usemacos = 1;

  /* Info.plist is the file which governs our future actions. */
  if (! info->dir && grub_strcasecmp (filename, "Info.plist") == 0
      && ! ctx->plistname)
    ctx->plistname = grub_strdup (ctx->newdirname);
  return 0;
}

/* Load extension DIRNAME. (extensions are directories in xnu) */
grub_err_t
grub_xnu_load_kext_from_dir (char *dirname, const char *osbundlerequired,
			     int maxrecursion)
{
  struct grub_xnu_load_kext_from_dir_ctx ctx = {
    .dirname = dirname,
    .osbundlerequired = osbundlerequired,
    .maxrecursion = maxrecursion,
    .plistname = 0,
    .usemacos = 0
  };
  grub_device_t dev;
  char *newpath;
  char *device_name;
  grub_fs_t fs;
  const char *path;
  char *binsuffix;
  grub_file_t binfile;

  ctx.newdirname = grub_malloc (grub_strlen (dirname) + 20);
  if (! ctx.newdirname)
    return grub_errno;
  grub_strcpy (ctx.newdirname, dirname);
  ctx.newdirname[grub_strlen (dirname)] = '/';
  ctx.newdirname[grub_strlen (dirname) + 1] = 0;
  device_name = grub_file_get_device_name (dirname);
  dev = grub_device_open (device_name);
  if (dev)
    {
      fs = grub_fs_probe (dev);
      path = grub_strchr (dirname, ')');
      if (! path)
	path = dirname;
      else
	path++;

      newpath = grub_strchr (ctx.newdirname, ')');
      if (! newpath)
	newpath = ctx.newdirname;
      else
	newpath++;

      /* Look at the directory. */
      if (fs)
	(fs->dir) (dev, path, grub_xnu_load_kext_from_dir_load, &ctx);

      if (ctx.plistname && grub_xnu_check_os_bundle_required
	  (ctx.plistname, osbundlerequired, &binsuffix))
	{
	  if (binsuffix)
	    {
	      /* Open the binary. */
	      char *binname = grub_malloc (grub_strlen (dirname)
					   + grub_strlen (binsuffix)
					   + sizeof ("/MacOS/"));
	      grub_strcpy (binname, dirname);
	      if (ctx.usemacos)
		grub_strcpy (binname + grub_strlen (binname), "/MacOS/");
	      else
		grub_strcpy (binname + grub_strlen (binname), "/");
	      grub_strcpy (binname + grub_strlen (binname), binsuffix);
	      grub_dprintf ("xnu", "%s:%s\n", ctx.plistname, binname);
	      binfile = grub_file_open (binname, GRUB_FILE_TYPE_XNU_KEXT);
	      if (! binfile)
		grub_errno = GRUB_ERR_NONE;

	      /* Load the extension. */
	      grub_xnu_load_driver (ctx.plistname, binfile,
				    binname);
	      grub_free (binname);
	      grub_free (binsuffix);
	    }
	  else
	    {
	      grub_dprintf ("xnu", "%s:0\n", ctx.plistname);
	      grub_xnu_load_driver (ctx.plistname, 0, 0);
	    }
	}
      grub_free (ctx.plistname);
      grub_device_close (dev);
    }
  grub_free (device_name);

  return GRUB_ERR_NONE;
}


static int locked=0;
static grub_dl_t my_mod;

/* Load the kext. */
static grub_err_t
grub_cmd_xnu_kext (grub_command_t cmd __attribute__ ((unused)),
		   int argc, char *args[])
{
  grub_file_t binfile = 0;

  if (! grub_xnu_heap_size)
    return grub_error (GRUB_ERR_BAD_OS, N_("you need to load the kernel first"));

  if (argc == 2)
    {
      /* User explicitly specified plist and binary. */
      if (grub_strcmp (args[1], "-") != 0)
	{
	  binfile = grub_file_open (args[1], GRUB_FILE_TYPE_XNU_KEXT);
	  if (! binfile)
	    return grub_errno;
	}
      return grub_xnu_load_driver (grub_strcmp (args[0], "-") ? args[0] : 0,
				   binfile, args[1]);
    }

  /* load kext normally. */
  if (argc == 1)
    return grub_xnu_load_kext_from_dir (args[0], 0, 10);

  return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
}

/* Load a directory containing kexts. */
static grub_err_t
grub_cmd_xnu_kextdir (grub_command_t cmd __attribute__ ((unused)),
		      int argc, char *args[])
{
  if (argc != 1 && argc != 2)
    return grub_error (GRUB_ERR_BAD_ARGUMENT, "directory name required");

  if (! grub_xnu_heap_size)
    return grub_error (GRUB_ERR_BAD_OS, N_("you need to load the kernel first"));

  if (argc == 1)
    return grub_xnu_scan_dir_for_kexts (args[0],
					"console,root,local-root,network-root",
					10);
  else
    {
      char *osbundlerequired = grub_strdup (args[1]), *ptr;
      grub_err_t err;
      if (! osbundlerequired)
	return grub_errno;
      for (ptr = osbundlerequired; *ptr; ptr++)
	*ptr = grub_tolower (*ptr);
      err = grub_xnu_scan_dir_for_kexts (args[0], osbundlerequired, 10);
      grub_free (osbundlerequired);
      return err;
    }
}

static inline int
hextoval (char c)
{
  if (c >= '0' && c <= '9')
    return c - '0';
  if (c >= 'a' && c <= 'z')
    return c - 'a' + 10;
  if (c >= 'A' && c <= 'Z')
    return c - 'A' + 10;
  return 0;
}

static inline void
unescape (char *name, char *curdot, char *nextdot, int *len)
{
  char *ptr, *dptr;
  dptr = name;
  for (ptr = curdot; ptr < nextdot;)
    if (ptr + 2 < nextdot && *ptr == '%')
      {
	*dptr = (hextoval (ptr[1]) << 4) | (hextoval (ptr[2]));
	ptr += 3;
	dptr++;
      }
    else
      {
	*dptr = *ptr;
	ptr++;
	dptr++;
      }
  *len = dptr - name;
}

grub_err_t
grub_xnu_fill_devicetree (void)
{
  struct grub_env_var *var;
  FOR_SORTED_ENV (var)
  {
    char *nextdot = 0, *curdot;
    struct grub_xnu_devtree_key **curkey = &grub_xnu_devtree_root;
    struct grub_xnu_devtree_key *curvalue;
    char *name = 0, *data;
    int len;

    if (grub_memcmp (var->name, "XNU.DeviceTree.",
		     sizeof ("XNU.DeviceTree.") - 1) != 0)
      continue;

    curdot = var->name + sizeof ("XNU.DeviceTree.") - 1;
    nextdot = grub_strchr (curdot, '.');
    if (nextdot)
      nextdot++;
    while (nextdot)
      {
	name = grub_realloc (name, nextdot - curdot + 1);

	if (!name)
	  return grub_errno;

	unescape (name, curdot, nextdot, &len);
	name[len - 1] = 0;

	curkey = &(grub_xnu_create_key (curkey, name)->first_child);

	curdot = nextdot;
	nextdot = grub_strchr (nextdot, '.');
	if (nextdot)
	  nextdot++;
      }

    nextdot = curdot + grub_strlen (curdot) + 1;

    name = grub_realloc (name, nextdot - curdot + 1);
   
    if (!name)
      return grub_errno;
   
    unescape (name, curdot, nextdot, &len);
    name[len] = 0;

    curvalue = grub_xnu_create_value (curkey, name);
    if (!curvalue)
      return grub_errno;
    grub_free (name);
   
    data = grub_malloc (grub_strlen (var->value) + 1);
    if (!data)
      return grub_errno;
   
    unescape (data, var->value, var->value + grub_strlen (var->value),
	      &len);
    curvalue->datasize = len;
    curvalue->data = data;
  }

  return grub_errno;
}

struct grub_video_bitmap *grub_xnu_bitmap = 0;
grub_xnu_bitmap_mode_t grub_xnu_bitmap_mode;

/* Option array indices.  */
#define XNU_SPLASH_CMD_ARGINDEX_MODE 0

static const struct grub_arg_option xnu_splash_cmd_options[] =
  {
    {"mode", 'm', 0, N_("Background image mode."), N_("stretch|normal"),
     ARG_TYPE_STRING},
    {0, 0, 0, 0, 0, 0}
  };

static grub_err_t
grub_cmd_xnu_splash (grub_extcmd_context_t ctxt,
		     int argc, char *args[])
{
  grub_err_t err;
  if (argc != 1)
    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));

  if (! grub_xnu_heap_size)
    return grub_error (GRUB_ERR_BAD_OS, N_("you need to load the kernel first"));

  if (ctxt->state[XNU_SPLASH_CMD_ARGINDEX_MODE].set &&
      grub_strcmp (ctxt->state[XNU_SPLASH_CMD_ARGINDEX_MODE].arg,
		   "stretch") == 0)
    grub_xnu_bitmap_mode = GRUB_XNU_BITMAP_STRETCH;
  else
    grub_xnu_bitmap_mode = GRUB_XNU_BITMAP_CENTER;

  err = grub_video_bitmap_load (&grub_xnu_bitmap, args[0]);
  if (err)
    grub_xnu_bitmap = 0;

  return err;
}


#ifndef GRUB_MACHINE_EMU
static grub_err_t
grub_cmd_xnu_resume (grub_command_t cmd __attribute__ ((unused)),
		     int argc, char *args[])
{
  if (argc != 1)
    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));

  return grub_xnu_resume (args[0]);
}
#endif

void
grub_xnu_lock (void)
{
  if (!locked)
    grub_dl_ref (my_mod);
  locked = 1;
}

void
grub_xnu_unlock (void)
{
  if (locked)
    grub_dl_unref (my_mod);
  locked = 0;
}

static grub_command_t cmd_kernel64, cmd_kernel, cmd_mkext, cmd_kext;
static grub_command_t cmd_kextdir, cmd_ramdisk, cmd_resume;
static grub_extcmd_t cmd_splash;

GRUB_MOD_INIT(xnu)
{
  if (grub_efi_secure_boot())
    return;

  cmd_kernel = grub_register_command ("xnu_kernel", grub_cmd_xnu_kernel, 0,
				      N_("Load XNU image."));
  cmd_kernel64 = grub_register_command ("xnu_kernel64", grub_cmd_xnu_kernel64,
					0, N_("Load 64-bit XNU image."));
  cmd_mkext = grub_register_command ("xnu_mkext", grub_cmd_xnu_mkext, 0,
				     N_("Load XNU extension package."));
  cmd_kext = grub_register_command ("xnu_kext", grub_cmd_xnu_kext, 0,
				    N_("Load XNU extension."));
  cmd_kextdir = grub_register_command ("xnu_kextdir", grub_cmd_xnu_kextdir,
				       /* TRANSLATORS: OSBundleRequired is a
					  variable name in xnu extensions
					  manifests. It behaves mostly like
					  GNU/Linux runlevels.
				       */
				       N_("DIRECTORY [OSBundleRequired]"),
				       /* TRANSLATORS: There are many extensions
					  in extension directory.  */
				       N_("Load XNU extension directory."));
  cmd_ramdisk = grub_register_command ("xnu_ramdisk", grub_cmd_xnu_ramdisk, 0,
   /* TRANSLATORS: ramdisk here isn't identifier. It can be translated.  */
				       N_("Load XNU ramdisk. "
					  "It will be available in OS as md0."));
  cmd_splash = grub_register_extcmd ("xnu_splash",
				     grub_cmd_xnu_splash, 0, 0,
				     N_("Load a splash image for XNU."),
				     xnu_splash_cmd_options);

#ifndef GRUB_MACHINE_EMU
  cmd_resume = grub_register_command ("xnu_resume", grub_cmd_xnu_resume,
				      0, N_("Load an image of hibernated"
					    " XNU."));
#endif

  grub_cpu_xnu_init ();

  my_mod = mod;
}

GRUB_MOD_FINI(xnu)
{
  if (grub_efi_secure_boot())
    return;

#ifndef GRUB_MACHINE_EMU
  grub_unregister_command (cmd_resume);
#endif
  grub_unregister_command (cmd_mkext);
  grub_unregister_command (cmd_kext);
  grub_unregister_command (cmd_kextdir);
  grub_unregister_command (cmd_ramdisk);
  grub_unregister_command (cmd_kernel);
  grub_unregister_extcmd (cmd_splash);
  grub_unregister_command (cmd_kernel64);

  grub_cpu_xnu_fini ();
}
