/* chainloader.c - boot another boot loader */
/*
 *  GRUB  --  GRand Unified Bootloader
 *  Copyright (C) 2002,2004,2006,2007,2008  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/>.
 */

/* TODO: support load options.  */

#include <grub/loader.h>
#include <grub/file.h>
#include <grub/err.h>
#include <grub/device.h>
#include <grub/disk.h>
#include <grub/misc.h>
#include <grub/charset.h>
#include <grub/mm.h>
#include <grub/types.h>
#include <grub/dl.h>
#include <grub/efi/api.h>
#include <grub/efi/efi.h>
#include <grub/efi/disk.h>
#include <grub/efi/pe32.h>
#include <grub/efi/linux.h>
#include <grub/efi/sb.h>
#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+");

static grub_dl_t my_mod;

static grub_efi_physical_address_t address;
static grub_efi_uintn_t pages;
static grub_ssize_t fsize;
static grub_efi_device_path_t *file_path;
static grub_efi_handle_t image_handle;
static grub_efi_char16_t *cmdline;
static grub_ssize_t cmdline_len;
static grub_efi_handle_t dev_handle;

static grub_efi_status_t (*entry_point) (grub_efi_handle_t image_handle, grub_efi_system_table_t *system_table);

static grub_err_t
grub_chainloader_unload (void)
{
  grub_efi_boot_services_t *b;

  b = grub_efi_system_table->boot_services;
  efi_call_1 (b->unload_image, image_handle);
  efi_call_2 (b->free_pages, address, pages);

  grub_free (file_path);
  grub_free (cmdline);
  cmdline = 0;
  file_path = 0;
  dev_handle = 0;

  grub_dl_unref (my_mod);
  return GRUB_ERR_NONE;
}

static grub_err_t
grub_chainloader_boot (void)
{
  grub_efi_boot_services_t *b;
  grub_efi_status_t status;
  grub_efi_uintn_t exit_data_size;
  grub_efi_char16_t *exit_data = NULL;

  b = grub_efi_system_table->boot_services;
  status = efi_call_3 (b->start_image, image_handle, &exit_data_size, &exit_data);
  if (status != GRUB_EFI_SUCCESS)
    {
      if (exit_data)
	{
	  char *buf;

	  buf = grub_malloc (exit_data_size * 4 + 1);
	  if (buf)
	    {
	      *grub_utf16_to_utf8 ((grub_uint8_t *) buf,
				   exit_data, exit_data_size) = 0;

	      grub_error (GRUB_ERR_BAD_OS, buf);
	      grub_free (buf);
	    }
	}
      else
	grub_error (GRUB_ERR_BAD_OS, "unknown error");
    }

  if (exit_data)
    efi_call_1 (b->free_pool, exit_data);

  grub_loader_unset ();

  return grub_errno;
}

static void
copy_file_path (grub_efi_file_path_device_path_t *fp,
		const char *str, grub_efi_uint16_t len)
{
  grub_efi_char16_t *p;
  grub_efi_uint16_t size;

  fp->header.type = GRUB_EFI_MEDIA_DEVICE_PATH_TYPE;
  fp->header.subtype = GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE;

  size = grub_utf8_to_utf16 (fp->path_name, len * GRUB_MAX_UTF16_PER_UTF8,
			     (const grub_uint8_t *) str, len, 0);
  for (p = fp->path_name; p < fp->path_name + size; p++)
    if (*p == '/')
      *p = '\\';

  /* File Path is NULL terminated */
  fp->path_name[size++] = '\0';
  fp->header.length = size * sizeof (grub_efi_char16_t) + sizeof (*fp);
}

static grub_efi_device_path_t *
make_file_path (grub_efi_device_path_t *dp, const char *filename)
{
  char *dir_start;
  char *dir_end;
  grub_size_t size;
  grub_efi_device_path_t *d;

  dir_start = grub_strchr (filename, ')');
  if (! dir_start)
    dir_start = (char *) filename;
  else
    dir_start++;

  dir_end = grub_strrchr (dir_start, '/');
  if (! dir_end)
    {
      grub_error (GRUB_ERR_BAD_FILENAME, "invalid EFI file path");
      return 0;
    }

  size = 0;
  d = dp;
  while (1)
    {
      size += GRUB_EFI_DEVICE_PATH_LENGTH (d);
      if ((GRUB_EFI_END_ENTIRE_DEVICE_PATH (d)))
	break;
      d = GRUB_EFI_NEXT_DEVICE_PATH (d);
    }

  /* File Path is NULL terminated. Allocate space for 2 extra characters */
  /* FIXME why we split path in two components? */
  file_path = grub_malloc (size
			   + ((grub_strlen (dir_start) + 2)
			      * GRUB_MAX_UTF16_PER_UTF8
			      * sizeof (grub_efi_char16_t))
			   + sizeof (grub_efi_file_path_device_path_t) * 2);
  if (! file_path)
    return 0;

  grub_memcpy (file_path, dp, size);

  /* Fill the file path for the directory.  */
  d = (grub_efi_device_path_t *) ((char *) file_path
				  + ((char *) d - (char *) dp));
  copy_file_path ((grub_efi_file_path_device_path_t *) d,
		  dir_start, dir_end - dir_start);

  /* Fill the file path for the file.  */
  d = GRUB_EFI_NEXT_DEVICE_PATH (d);
  copy_file_path ((grub_efi_file_path_device_path_t *) d,
		  dir_end + 1, grub_strlen (dir_end + 1));

  /* Fill the end of device path nodes.  */
  d = GRUB_EFI_NEXT_DEVICE_PATH (d);
  d->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
  d->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
  d->length = sizeof (*d);

  return file_path;
}

#define SHIM_LOCK_GUID \
  { 0x605dab50, 0xe046, 0x4300, { 0xab,0xb6,0x3d,0xd8,0x10,0xdd,0x8b,0x23 } }

typedef union
{
  struct grub_pe32_header_32 pe32;
  struct grub_pe32_header_64 pe32plus;
} grub_pe_header_t;

struct pe_coff_loader_image_context
{
  grub_efi_uint64_t image_address;
  grub_efi_uint64_t image_size;
  grub_efi_uint64_t entry_point;
  grub_efi_uintn_t size_of_headers;
  grub_efi_uint16_t image_type;
  grub_efi_uint16_t number_of_sections;
  grub_efi_uint32_t section_alignment;
  struct grub_pe32_section_table *first_section;
  struct grub_pe32_data_directory *reloc_dir;
  struct grub_pe32_data_directory *sec_dir;
  grub_efi_uint64_t number_of_rva_and_sizes;
  grub_pe_header_t *pe_hdr;
};

typedef struct pe_coff_loader_image_context pe_coff_loader_image_context_t;

struct grub_efi_shim_lock
{
  grub_efi_status_t (*verify)(void *buffer,
                              grub_efi_uint32_t size);
  grub_efi_status_t (*hash)(void *data,
                            grub_efi_int32_t datasize,
                            pe_coff_loader_image_context_t *context,
                            grub_efi_uint8_t *sha256hash,
                            grub_efi_uint8_t *sha1hash);
  grub_efi_status_t (*context)(void *data,
                               grub_efi_uint32_t size,
                               pe_coff_loader_image_context_t *context);
};

typedef struct grub_efi_shim_lock grub_efi_shim_lock_t;

static grub_efi_boolean_t
read_header (void *data, grub_efi_uint32_t size,
	     pe_coff_loader_image_context_t *context)
{
  grub_efi_guid_t guid = SHIM_LOCK_GUID;
  grub_efi_shim_lock_t *shim_lock;
  grub_efi_status_t status;

  shim_lock = grub_efi_locate_protocol (&guid, NULL);
  if (!shim_lock)
    {
      grub_dprintf ("chain", "no shim lock protocol");
      return 0;
    }

  status = shim_lock->context (data, size, context);

  if (status == GRUB_EFI_SUCCESS)
    {
      grub_dprintf ("chain", "context success\n");
      return 1;
    }

  switch (status)
    {
      case GRUB_EFI_UNSUPPORTED:
      grub_error (GRUB_ERR_BAD_ARGUMENT, "context error unsupported");
      break;
      case GRUB_EFI_INVALID_PARAMETER:
      grub_error (GRUB_ERR_BAD_ARGUMENT, "context error invalid parameter");
      break;
      default:
      grub_error (GRUB_ERR_BAD_ARGUMENT, "context error code");
      break;
    }

  return -1;
}

static void*
image_address (void *image, grub_efi_uint64_t sz, grub_efi_uint64_t adr)
{
  if (adr > sz)
    return NULL;

  return ((grub_uint8_t*)image + adr);
}

static int
image_is_64_bit (grub_pe_header_t *pe_hdr)
{
  /* .Magic is the same offset in all cases */
  if (pe_hdr->pe32plus.optional_header.magic == GRUB_PE32_PE64_MAGIC)
    return 1;
  return 0;
}

static const grub_uint16_t machine_type __attribute__((__unused__)) =
#if defined(__x86_64__)
  GRUB_PE32_MACHINE_X86_64;
#elif defined(__aarch64__)
  GRUB_PE32_MACHINE_ARM64;
#elif defined(__arm__)
  GRUB_PE32_MACHINE_ARMTHUMB_MIXED;
#elif defined(__i386__) || defined(__i486__) || defined(__i686__)
  GRUB_PE32_MACHINE_I386;
#elif defined(__ia64__)
  GRUB_PE32_MACHINE_IA64;
#else
#error this architecture is not supported by grub2
#endif

static grub_efi_status_t
relocate_coff (pe_coff_loader_image_context_t *context,
	       struct grub_pe32_section_table *section,
	       void *orig, void *data)
{
  struct grub_pe32_data_directory *reloc_base, *reloc_base_end;
  grub_efi_uint64_t adjust;
  struct grub_pe32_fixup_block *reloc, *reloc_end;
  char *fixup, *fixup_base, *fixup_data = NULL;
  grub_efi_uint16_t *fixup_16;
  grub_efi_uint32_t *fixup_32;
  grub_efi_uint64_t *fixup_64;
  grub_efi_uint64_t size = context->image_size;
  void *image_end = (char *)orig + size;
  int n = 0;

  if (image_is_64_bit (context->pe_hdr))
    context->pe_hdr->pe32plus.optional_header.image_base =
      (grub_uint64_t)(unsigned long)data;
  else
    context->pe_hdr->pe32.optional_header.image_base =
      (grub_uint32_t)(unsigned long)data;

  /* Alright, so here's how this works:
   *
   * context->reloc_dir gives us two things:
   * - the VA the table of base relocation blocks are (maybe) to be
   *   mapped at (reloc_dir->rva)
   * - the virtual size (reloc_dir->size)
   *
   * The .reloc section (section here) gives us some other things:
   * - the name! kind of. (section->name)
   * - the virtual size (section->virtual_size), which should be the same
   *   as RelocDir->Size
   * - the virtual address (section->virtual_address)
   * - the file section size (section->raw_data_size), which is
   *   a multiple of optional_header->file_alignment.  Only useful for image
   *   validation, not really useful for iteration bounds.
   * - the file address (section->raw_data_offset)
   * - a bunch of stuff we don't use that's 0 in our binaries usually
   * - Flags (section->characteristics)
   *
   * and then the thing that's actually at the file address is an array
   * of struct grub_pe32_fixup_block structs with some values packed behind
   * them.  The block_size field of this structure includes the
   * structure itself, and adding it to that structure's address will
   * yield the next entry in the array.
   */

  reloc_base = image_address (orig, size, section->raw_data_offset);
  reloc_base_end = image_address (orig, size, section->raw_data_offset
				  + section->virtual_size);

  grub_dprintf ("chain", "relocate_coff(): reloc_base %p reloc_base_end %p\n",
		reloc_base, reloc_base_end);

  if (!reloc_base && !reloc_base_end)
    return GRUB_EFI_SUCCESS;

  if (!reloc_base || !reloc_base_end)
    {
      grub_error (GRUB_ERR_BAD_ARGUMENT, "Reloc table overflows binary");
      return GRUB_EFI_UNSUPPORTED;
    }

  adjust = (grub_uint64_t)data - context->image_address;
  if (adjust == 0)
    return GRUB_EFI_SUCCESS;

  while (reloc_base < reloc_base_end)
    {
      grub_uint16_t *entry;
      reloc = (struct grub_pe32_fixup_block *)((char*)reloc_base);

      if ((reloc_base->size == 0) ||
	  (reloc_base->size > context->reloc_dir->size))
	{
	  grub_error (GRUB_ERR_BAD_ARGUMENT,
		      "Reloc %d block size %d is invalid\n", n,
		      reloc_base->size);
	  return GRUB_EFI_UNSUPPORTED;
	}

      entry = &reloc->entries[0];
      reloc_end = (struct grub_pe32_fixup_block *)
	((char *)reloc_base + reloc_base->size);

      if ((void *)reloc_end < data || (void *)reloc_end > image_end)
        {
          grub_error (GRUB_ERR_BAD_ARGUMENT, "Reloc entry %d overflows binary",
		      n);
          return GRUB_EFI_UNSUPPORTED;
        }

      fixup_base = image_address(data, size, reloc_base->rva);

      if (!fixup_base)
        {
          grub_error (GRUB_ERR_BAD_ARGUMENT, "Reloc %d Invalid fixupbase", n);
          return GRUB_EFI_UNSUPPORTED;
        }

      while ((void *)entry < (void *)reloc_end)
        {
          fixup = fixup_base + (*entry & 0xFFF);
          switch ((*entry) >> 12)
            {
              case GRUB_PE32_REL_BASED_ABSOLUTE:
                break;
              case GRUB_PE32_REL_BASED_HIGH:
                fixup_16 = (grub_uint16_t *)fixup;
                *fixup_16 = (grub_uint16_t)
		  (*fixup_16 + ((grub_uint16_t)((grub_uint32_t)adjust >> 16)));
                if (fixup_data != NULL)
                  {
                    *(grub_uint16_t *) fixup_data = *fixup_16;
                    fixup_data = fixup_data + sizeof (grub_uint16_t);
                  }
                break;
              case GRUB_PE32_REL_BASED_LOW:
                fixup_16 = (grub_uint16_t *)fixup;
                *fixup_16 = (grub_uint16_t) (*fixup_16 + (grub_uint16_t)adjust);
                if (fixup_data != NULL)
                  {
                    *(grub_uint16_t *) fixup_data = *fixup_16;
                    fixup_data = fixup_data + sizeof (grub_uint16_t);
                  }
                break;
              case GRUB_PE32_REL_BASED_HIGHLOW:
                fixup_32 = (grub_uint32_t *)fixup;
                *fixup_32 = *fixup_32 + (grub_uint32_t)adjust;
                if (fixup_data != NULL)
                  {
                    fixup_data = (char *)ALIGN_UP ((grub_addr_t)fixup_data, sizeof (grub_uint32_t));
                    *(grub_uint32_t *) fixup_data = *fixup_32;
                    fixup_data += sizeof (grub_uint32_t);
                  }
                break;
              case GRUB_PE32_REL_BASED_DIR64:
                fixup_64 = (grub_uint64_t *)fixup;
                *fixup_64 = *fixup_64 + (grub_uint64_t)adjust;
                if (fixup_data != NULL)
                  {
                    fixup_data = (char *)ALIGN_UP ((grub_addr_t)fixup_data, sizeof (grub_uint64_t));
                    *(grub_uint64_t *) fixup_data = *fixup_64;
                    fixup_data += sizeof (grub_uint64_t);
                  }
                break;
              default:
                grub_error (GRUB_ERR_BAD_ARGUMENT,
			    "Reloc %d unknown relocation type %d",
			    n, (*entry) >> 12);
                return GRUB_EFI_UNSUPPORTED;
            }
          entry += 1;
        }
      reloc_base = (struct grub_pe32_data_directory *)reloc_end;
      n++;
    }

  return GRUB_EFI_SUCCESS;
}

static grub_efi_device_path_t *
grub_efi_get_media_file_path (grub_efi_device_path_t *dp)
{
  while (1)
    {
      grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp);
      grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp);

      if (type == GRUB_EFI_END_DEVICE_PATH_TYPE)
        break;
      else if (type == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE
            && subtype == GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE)
      return dp;

      dp = GRUB_EFI_NEXT_DEVICE_PATH (dp);
    }

    return NULL;
}

static grub_efi_boolean_t
handle_image (void *data, grub_efi_uint32_t datasize)
{
  grub_efi_boot_services_t *b;
  grub_efi_loaded_image_t *li, li_bak;
  grub_efi_status_t efi_status;
  char *buffer = NULL;
  char *buffer_aligned = NULL;
  grub_efi_uint32_t i;
  struct grub_pe32_section_table *section;
  char *base, *end;
  pe_coff_loader_image_context_t context;
  grub_uint32_t section_alignment;
  grub_uint32_t buffer_size;
  int found_entry_point = 0;
  int rc;

  b = grub_efi_system_table->boot_services;

  rc = read_header (data, datasize, &context);
  if (rc < 0)
    {
      grub_dprintf ("chain", "Failed to read header\n");
      goto error_exit;
    }
  else if (rc == 0)
    {
      grub_dprintf ("chain", "Secure Boot is not enabled\n");
      return 0;
    }
  else
    {
      grub_dprintf ("chain", "Header read without error\n");
    }

  /*
   * The spec says, uselessly, of SectionAlignment:
   * =====
   * The alignment (in bytes) of sections when they are loaded into
   * memory. It must be greater than or equal to FileAlignment. The
   * default is the page size for the architecture.
   * =====
   * Which doesn't tell you whose responsibility it is to enforce the
   * "default", or when.  It implies that the value in the field must
   * be > FileAlignment (also poorly defined), but it appears visual
   * studio will happily write 512 for FileAlignment (its default) and
   * 0 for SectionAlignment, intending to imply PAGE_SIZE.
   *
   * We only support one page size, so if it's zero, nerf it to 4096.
   */
  section_alignment = context.section_alignment;
  if (section_alignment == 0)
    section_alignment = 4096;

  buffer_size = context.image_size + section_alignment;
  grub_dprintf ("chain", "image size is %08lx, datasize is %08x\n",
	       context.image_size, datasize);

  efi_status = efi_call_3 (b->allocate_pool, GRUB_EFI_LOADER_DATA,
			   buffer_size, &buffer);

  if (efi_status != GRUB_EFI_SUCCESS)
    {
      grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
      goto error_exit;
    }

  buffer_aligned = (char *)ALIGN_UP ((grub_addr_t)buffer, section_alignment);
  if (!buffer_aligned)
    {
      grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
      goto error_exit;
    }

  grub_memcpy (buffer_aligned, data, context.size_of_headers);

  entry_point = image_address (buffer_aligned, context.image_size,
			       context.entry_point);

  grub_dprintf ("chain", "entry_point: %p\n", entry_point);
  if (!entry_point)
    {
      grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid entry point");
      goto error_exit;
    }

  char *reloc_base, *reloc_base_end;
  grub_dprintf ("chain", "reloc_dir: %p reloc_size: 0x%08x\n",
		(void *)(unsigned long long)context.reloc_dir->rva,
		context.reloc_dir->size);
  reloc_base = image_address (buffer_aligned, context.image_size,
			      context.reloc_dir->rva);
  /* RelocBaseEnd here is the address of the last byte of the table */
  reloc_base_end = image_address (buffer_aligned, context.image_size,
				  context.reloc_dir->rva
				  + context.reloc_dir->size - 1);
  grub_dprintf ("chain", "reloc_base: %p reloc_base_end: %p\n",
		reloc_base, reloc_base_end);

  struct grub_pe32_section_table *reloc_section = NULL;

  section = context.first_section;
  for (i = 0; i < context.number_of_sections; i++, section++)
    {
      char name[9];

      base = image_address (buffer_aligned, context.image_size,
			    section->virtual_address);
      end = image_address (buffer_aligned, context.image_size,
			   section->virtual_address + section->virtual_size -1);

      grub_strncpy(name, section->name, 9);
      name[8] = '\0';
      grub_dprintf ("chain", "Section %d \"%s\" at %p..%p\n", i,
		   name, base, end);

      if (end < base)
	{
	  grub_dprintf ("chain", " base is %p but end is %p... bad.\n",
		       base, end);
	  grub_error (GRUB_ERR_BAD_ARGUMENT,
		      "Image has invalid negative size");
	  goto error_exit;
	}

      if (section->virtual_address <= context.entry_point &&
	  (section->virtual_address + section->raw_data_size - 1)
	  > context.entry_point)
	{
	  found_entry_point++;
	  grub_dprintf ("chain", " section contains entry point\n");
	}

      /* We do want to process .reloc, but it's often marked
       * discardable, so we don't want to memcpy it. */
      if (grub_memcmp (section->name, ".reloc\0\0", 8) == 0)
	{
	  if (reloc_section)
	    {
	      grub_error (GRUB_ERR_BAD_ARGUMENT,
			  "Image has multiple relocation sections");
	      goto error_exit;
	    }

	  /* If it has nonzero sizes, and our bounds check
	   * made sense, and the VA and size match RelocDir's
	   * versions, then we believe in this section table. */
	  if (section->raw_data_size && section->virtual_size &&
	      base && end && reloc_base == base && reloc_base_end == end)
	    {
	      grub_dprintf ("chain", " section is relocation section\n");
	      reloc_section = section;
	    }
	  else
	    {
	      grub_dprintf ("chain", " section is not reloc section?\n");
	      grub_dprintf ("chain", " rds: 0x%08x, vs: %08x\n",
			    section->raw_data_size, section->virtual_size);
	      grub_dprintf ("chain", " base: %p end: %p\n", base, end);
	      grub_dprintf ("chain", " reloc_base: %p reloc_base_end: %p\n",
			    reloc_base, reloc_base_end);
	    }
	}

      grub_dprintf ("chain", " Section characteristics are %08x\n",
		   section->characteristics);
      grub_dprintf ("chain", " Section virtual size: %08x\n",
		   section->virtual_size);
      grub_dprintf ("chain", " Section raw_data size: %08x\n",
		   section->raw_data_size);
      if (section->characteristics & GRUB_PE32_SCN_MEM_DISCARDABLE)
	{
	  grub_dprintf ("chain", " Discarding section\n");
	  continue;
	}

      if (!base || !end)
        {
	  grub_dprintf ("chain", " section is invalid\n");
          grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid section size");
          goto error_exit;
        }

      if (section->characteristics & GRUB_PE32_SCN_CNT_UNINITIALIZED_DATA)
	{
	  if (section->raw_data_size != 0)
	    grub_dprintf ("chain", " UNINITIALIZED_DATA section has data?\n");
	}
      else if (section->virtual_address < context.size_of_headers ||
	       section->raw_data_offset < context.size_of_headers)
	{
	  grub_error (GRUB_ERR_BAD_ARGUMENT,
		      "Section %d is inside image headers", i);
	  goto error_exit;
	}

      if (section->raw_data_size > 0)
	{
	  grub_dprintf ("chain", " copying 0x%08x bytes to %p\n",
			section->raw_data_size, base);
	  grub_memcpy (base,
		       (grub_efi_uint8_t*)data + section->raw_data_offset,
		       section->raw_data_size);
	}

      if (section->raw_data_size < section->virtual_size)
	{
	  grub_dprintf ("chain", " padding with 0x%08x bytes at %p\n",
			section->virtual_size - section->raw_data_size,
			base + section->raw_data_size);
	  grub_memset (base + section->raw_data_size, 0,
		       section->virtual_size - section->raw_data_size);
	}

      grub_dprintf ("chain", " finished section %s\n", name);
    }

  /* 5 == EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC */
  if (context.number_of_rva_and_sizes <= 5)
    {
      grub_dprintf ("chain", "image has no relocation entry\n");
      goto error_exit;
    }

  if (context.reloc_dir->size && reloc_section)
    {
      /* run the relocation fixups */
      efi_status = relocate_coff (&context, reloc_section, data,
				  buffer_aligned);

      if (efi_status != GRUB_EFI_SUCCESS)
	{
	  grub_error (GRUB_ERR_BAD_ARGUMENT, "relocation failed");
	  goto error_exit;
	}
    }

  if (!found_entry_point)
    {
      grub_error (GRUB_ERR_BAD_ARGUMENT, "entry point is not within sections");
      goto error_exit;
    }
  if (found_entry_point > 1)
    {
      grub_error (GRUB_ERR_BAD_ARGUMENT, "%d sections contain entry point",
		  found_entry_point);
      goto error_exit;
    }

  li = grub_efi_get_loaded_image (grub_efi_image_handle);
  if (!li)
    {
      grub_error (GRUB_ERR_BAD_ARGUMENT, "no loaded image available");
      goto error_exit;
    }

  grub_memcpy (&li_bak, li, sizeof (grub_efi_loaded_image_t));
  li->image_base = buffer_aligned;
  li->image_size = context.image_size;
  li->load_options = cmdline;
  li->load_options_size = cmdline_len;
  li->file_path = grub_efi_get_media_file_path (file_path);
  li->device_handle = dev_handle;
  if (!li->file_path)
    {
      grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no matching file path found");
      goto error_exit;
    }

  grub_dprintf ("chain", "booting via entry point\n");
  efi_status = efi_call_2 (entry_point, grub_efi_image_handle,
			   grub_efi_system_table);

  grub_dprintf ("chain", "entry_point returned %ld\n", efi_status);
  grub_memcpy (li, &li_bak, sizeof (grub_efi_loaded_image_t));
  efi_status = efi_call_1 (b->free_pool, buffer);

  return 1;

error_exit:
  grub_dprintf ("chain", "error_exit: grub_errno: %d\n", grub_errno);
  if (buffer)
      efi_call_1 (b->free_pool, buffer);

  return 0;
}

static grub_err_t
grub_secureboot_chainloader_unload (void)
{
  grub_efi_boot_services_t *b;

  b = grub_efi_system_table->boot_services;
  efi_call_2 (b->free_pages, address, pages);
  grub_free (file_path);
  grub_free (cmdline);
  cmdline = 0;
  file_path = 0;
  dev_handle = 0;

  grub_dl_unref (my_mod);
  return GRUB_ERR_NONE;
}

static grub_err_t
grub_load_and_start_image(void *boot_image)
{
  grub_efi_boot_services_t *b;
  grub_efi_status_t status;
  grub_efi_loaded_image_t *loaded_image;

  b = grub_efi_system_table->boot_services;

  status = efi_call_6 (b->load_image, 0, grub_efi_image_handle, file_path,
		       boot_image, fsize, &image_handle);
  if (status != GRUB_EFI_SUCCESS)
    {
      if (status == GRUB_EFI_OUT_OF_RESOURCES)
	grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of resources");
      else
	grub_error (GRUB_ERR_BAD_OS, "cannot load image");
      return -1;
    }

  /* LoadImage does not set a device handler when the image is
     loaded from memory, so it is necessary to set it explicitly here.
     This is a mess.  */
  loaded_image = grub_efi_get_loaded_image (image_handle);
  if (! loaded_image)
    {
      grub_error (GRUB_ERR_BAD_OS, "no loaded image available");
      return -1;
    }
  loaded_image->device_handle = dev_handle;

  if (cmdline)
    {
      loaded_image->load_options = cmdline;
      loaded_image->load_options_size = cmdline_len;
    }

  return 0;
}

static grub_err_t
grub_secureboot_chainloader_boot (void)
{
  int rc;
  rc = handle_image ((void *)address, fsize);
  if (rc == 0)
    {
      grub_load_and_start_image((void *)address);
    }

  grub_loader_unset ();
  return grub_errno;
}

static grub_err_t
grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
		      int argc, char *argv[])
{
  grub_file_t file = 0;
  grub_efi_status_t status;
  grub_efi_boot_services_t *b;
  grub_device_t dev = 0;
  grub_efi_device_path_t *dp = 0;
  char *filename;
  void *boot_image = 0;
  int rc;

  if (argc == 0)
    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
  filename = argv[0];

  grub_dl_ref (my_mod);

  /* Initialize some global variables.  */
  address = 0;
  image_handle = 0;
  file_path = 0;
  dev_handle = 0;

  b = grub_efi_system_table->boot_services;

  if (argc > 1)
    {
      int i;
      grub_efi_char16_t *p16;

      for (i = 1, cmdline_len = 0; i < argc; i++)
        cmdline_len += grub_strlen (argv[i]) + 1;

      cmdline_len *= sizeof (grub_efi_char16_t);
      cmdline = p16 = grub_malloc (cmdline_len);
      if (! cmdline)
        goto fail;

      for (i = 1; i < argc; i++)
        {
          char *p8;

          p8 = argv[i];
          while (*p8)
            *(p16++) = *(p8++);

          *(p16++) = ' ';
        }
      *(--p16) = 0;
    }

  file = grub_file_open (filename, GRUB_FILE_TYPE_EFI_CHAINLOADED_IMAGE);
  if (! file)
    goto fail;

  /* Get the device path from filename. */
  char *devname = grub_file_get_device_name (filename);
  dev = grub_device_open (devname);
  if (devname)
    grub_free (devname);
  if (! dev)
    goto fail;

  if (dev->disk)
    dev_handle = grub_efidisk_get_device_handle (dev->disk);
  else if (dev->net && dev->net->server)
    {
      grub_net_network_level_address_t addr;
      struct grub_net_network_level_interface *inf;
      grub_net_network_level_address_t gateway;
      grub_err_t err;

      err = grub_net_resolve_address (dev->net->server, &addr);
      if (err)
	goto fail;

      err = grub_net_route_address (addr, &gateway, &inf);
      if (err)
	goto fail;

      dev_handle = grub_efinet_get_device_handle (inf->card);
    }

  if (dev_handle)
    dp = grub_efi_get_device_path (dev_handle);

  if (! dp)
    {
      grub_error (GRUB_ERR_BAD_DEVICE, "not a valid root device");
      goto fail;
    }

  file_path = make_file_path (dp, filename);
  if (! file_path)
    goto fail;

  fsize = grub_file_size (file);
  if (!fsize)
    {
      grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
		  filename);
      goto fail;
    }
  pages = (((grub_efi_uintn_t) fsize + ((1 << 12) - 1)) >> 12);

  status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_ANY_PAGES,
			      GRUB_EFI_LOADER_CODE,
			      pages, &address);
  if (status != GRUB_EFI_SUCCESS)
    {
      grub_dprintf ("chain", "Failed to allocate %u pages\n",
		    (unsigned int) pages);
      grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
      goto fail;
    }

  boot_image = (void *) ((grub_addr_t) address);
  if (grub_file_read (file, boot_image, fsize) != fsize)
    {
      if (grub_errno == GRUB_ERR_NONE)
	grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
		    filename);

      goto fail;
    }

#if defined (__i386__) || defined (__x86_64__)
  if (fsize >= (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);

	  if (grub_efi_secure_boot())
	    {
	      grub_error (GRUB_ERR_BAD_OS,
			  "MACHO binaries are forbidden with Secure Boot");
	      goto fail;
	    }

	  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) fsize)
	    {
	      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);
	  fsize = grub_cpu_to_le32 (archs[i].size);
	}
    }
#endif

  rc = grub_linuxefi_secure_validate((void *)address, fsize);
  grub_dprintf ("chain", "linuxefi_secure_validate: %d\n", rc);
  if (rc > 0)
    {
      grub_file_close (file);
      grub_loader_set (grub_secureboot_chainloader_boot,
		       grub_secureboot_chainloader_unload, 0);
      return 0;
    }
  else if (rc == 0)
    {
      grub_load_and_start_image(boot_image);
      grub_file_close (file);
      grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 0);

      return 0;
    }
  // -1 fall-through to fail

  grub_file_close (file);
  grub_device_close (dev);

fail:
  if (dev)
    grub_device_close (dev);

  if (file)
    grub_file_close (file);

  grub_free (file_path);

  if (address)
    efi_call_2 (b->free_pages, address, pages);

  if (cmdline)
    grub_free (cmdline);

  grub_dl_unref (my_mod);

  return grub_errno;
}

static grub_command_t cmd;

GRUB_MOD_INIT(chainloader)
{
  cmd = grub_register_command ("chainloader", grub_cmd_chainloader,
			       0, N_("Load another boot loader."));
  my_mod = mod;
}

GRUB_MOD_FINI(chainloader)
{
  grub_unregister_command (cmd);
}
