/* Load runtime image of EFIemu. Functions specific to 32/64-bit mode */
/*
 *  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/err.h>
#include <grub/mm.h>
#include <grub/misc.h>
#include <grub/efiemu/efiemu.h>
#include <grub/cpu/efiemu.h>
#include <grub/elf.h>
#include <grub/i18n.h>

/* ELF symbols and their values */
static struct grub_efiemu_elf_sym *grub_efiemu_elfsyms = 0;
static int grub_efiemu_nelfsyms = 0;

/* Return the address of a section whose index is N.  */
static grub_err_t
grub_efiemu_get_section_addr (grub_efiemu_segment_t segs, unsigned n,
			      int *handle, grub_off_t *off)
{
  grub_efiemu_segment_t seg;

  for (seg = segs; seg; seg = seg->next)
    if (seg->section == n)
      {
	*handle = seg->handle;
	*off = seg->off;
	return GRUB_ERR_NONE;
      }

  return grub_error (GRUB_ERR_BAD_OS, "section %d not found", n);
}

grub_err_t
SUFFIX (grub_efiemu_loadcore_unload) (void)
{
  grub_free (grub_efiemu_elfsyms);
  grub_efiemu_elfsyms = 0;
  return GRUB_ERR_NONE;
}

/* Check if EHDR is a valid ELF header.  */
int
SUFFIX (grub_efiemu_check_header) (void *ehdr, grub_size_t size)
{
  Elf_Ehdr *e = ehdr;

  /* Check the header size.  */
  if (size < sizeof (Elf_Ehdr))
    return 0;

  /* Check the magic numbers.  */
  if (!SUFFIX (grub_arch_efiemu_check_header) (ehdr)
      || e->e_ident[EI_MAG0] != ELFMAG0
      || e->e_ident[EI_MAG1] != ELFMAG1
      || e->e_ident[EI_MAG2] != ELFMAG2
      || e->e_ident[EI_MAG3] != ELFMAG3
      || e->e_ident[EI_VERSION] != EV_CURRENT
      || e->e_version != EV_CURRENT)
    return 0;

  return 1;
}

/* Load all segments from memory specified by E.  */
static grub_err_t
grub_efiemu_load_segments (grub_efiemu_segment_t segs, const Elf_Ehdr *e)
{
  Elf_Shdr *s;
  grub_efiemu_segment_t cur;

  grub_dprintf ("efiemu", "loading segments\n");

  for (cur=segs; cur; cur = cur->next)
    {
      s = (Elf_Shdr *)cur->srcptr;

      if ((s->sh_flags & SHF_ALLOC) && s->sh_size)
	{
	  void *addr;

	  addr = (grub_uint8_t *) grub_efiemu_mm_obtain_request (cur->handle)
	    + cur->off;

	  switch (s->sh_type)
	    {
	    case SHT_PROGBITS:
	      grub_memcpy (addr, (char *) e + s->sh_offset, s->sh_size);
	      break;
	    case SHT_NOBITS:
	      grub_memset (addr, 0, s->sh_size);
	      break;
	    }
	}
    }

  return GRUB_ERR_NONE;
}

/* Get a string at offset OFFSET from strtab */
static char *
grub_efiemu_get_string (unsigned offset, const Elf_Ehdr *e)
{
  unsigned i;
  Elf_Shdr *s;

  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
       i < e->e_shnum;
       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
    if (s->sh_type == SHT_STRTAB && offset < s->sh_size)
      return (char *) e + s->sh_offset + offset;
  return 0;
}

/* Request memory for segments and fill segments info */
static grub_err_t
grub_efiemu_init_segments (grub_efiemu_segment_t *segs, const Elf_Ehdr *e)
{
  unsigned i;
  Elf_Shdr *s;

  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
       i < e->e_shnum;
       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
    {
      if (s->sh_flags & SHF_ALLOC)
	{
	  grub_efiemu_segment_t seg;
	  seg = (grub_efiemu_segment_t) grub_malloc (sizeof (*seg));
	  if (! seg)
	    return grub_errno;

	  if (s->sh_size)
	    {
	      seg->handle
		= grub_efiemu_request_memalign
		(s->sh_addralign, s->sh_size,
		 s->sh_flags & SHF_EXECINSTR ? GRUB_EFI_RUNTIME_SERVICES_CODE
		 : GRUB_EFI_RUNTIME_SERVICES_DATA);
	      if (seg->handle < 0)
		{
		  grub_free (seg);
		  return grub_errno;
		}
	      seg->off = 0;
	    }

	  /*
	     .text-physical doesn't need to be relocated when switching to
	     virtual mode
	   */
	  if (!grub_strcmp (grub_efiemu_get_string (s->sh_name, e),
			    ".text-physical"))
	    seg->ptv_rel_needed = 0;
	  else
	    seg->ptv_rel_needed = 1;
	  seg->size = s->sh_size;
	  seg->section = i;
	  seg->next = *segs;
	  seg->srcptr = s;
	  *segs = seg;
	}
    }

  return GRUB_ERR_NONE;
}

/* Count symbols and relocators and allocate/request memory for them */
static grub_err_t
grub_efiemu_count_symbols (const Elf_Ehdr *e)
{
  unsigned i;
  Elf_Shdr *s;
  int num = 0;

  /* Symbols */
  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
       i < e->e_shnum;
       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
    if (s->sh_type == SHT_SYMTAB)
      break;

  if (i == e->e_shnum)
    return grub_error (GRUB_ERR_BAD_OS, N_("no symbol table"));

  grub_efiemu_nelfsyms = (unsigned) s->sh_size / (unsigned) s->sh_entsize;
  grub_efiemu_elfsyms = (struct grub_efiemu_elf_sym *)
    grub_calloc (grub_efiemu_nelfsyms, sizeof (struct grub_efiemu_elf_sym));

  /* Relocators */
  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
       i < e->e_shnum;
       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
    if (s->sh_type == SHT_REL || s->sh_type == SHT_RELA)
      num += ((unsigned) s->sh_size) / ((unsigned) s->sh_entsize);

  grub_efiemu_request_symbols (num);

  return GRUB_ERR_NONE;
}

/* Fill grub_efiemu_elfsyms with symbol values */
static grub_err_t
grub_efiemu_resolve_symbols (grub_efiemu_segment_t segs, Elf_Ehdr *e)
{
  unsigned i;
  Elf_Shdr *s;
  Elf_Sym *sym;
  const char *str;
  Elf_Word size, entsize;

  grub_dprintf ("efiemu", "resolving symbols\n");

  for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
       i < e->e_shnum;
       i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
    if (s->sh_type == SHT_SYMTAB)
      break;

  if (i == e->e_shnum)
    return grub_error (GRUB_ERR_BAD_OS, N_("no symbol table"));

  sym = (Elf_Sym *) ((char *) e + s->sh_offset);
  size = s->sh_size;
  entsize = s->sh_entsize;

  s = (Elf_Shdr *) ((char *) e + e->e_shoff + e->e_shentsize * s->sh_link);
  str = (char *) e + s->sh_offset;

  for (i = 0;
       i < size / entsize;
       i++, sym = (Elf_Sym *) ((char *) sym + entsize))
    {
      unsigned char type = ELF_ST_TYPE (sym->st_info);
      unsigned char bind = ELF_ST_BIND (sym->st_info);
      int handle;
      grub_off_t off;
      grub_err_t err;
      const char *name = str + sym->st_name;
      grub_efiemu_elfsyms[i].section = sym->st_shndx;
      switch (type)
	{
	case STT_NOTYPE:
	  /* Resolve a global symbol.  */
	  if (sym->st_name != 0 && sym->st_shndx == 0)
	    {
	      err = grub_efiemu_resolve_symbol (name, &handle, &off);
	      if (err)
		return err;
	      grub_efiemu_elfsyms[i].handle = handle;
	      grub_efiemu_elfsyms[i].off = off;
	    }
	  else
	    sym->st_value = 0;
	  break;

	case STT_OBJECT:
	  err = grub_efiemu_get_section_addr (segs, sym->st_shndx,
					      &handle, &off);
	  if (err)
	    return err;

	  off += sym->st_value;
	  if (bind != STB_LOCAL)
	    {
	      err = grub_efiemu_register_symbol (name, handle, off);
	      if (err)
		return err;
	    }
	  grub_efiemu_elfsyms[i].handle = handle;
	  grub_efiemu_elfsyms[i].off = off;
	  break;

	case STT_FUNC:
	  err = grub_efiemu_get_section_addr (segs, sym->st_shndx,
					      &handle, &off);
	  if (err)
	    return err;

	  off += sym->st_value;
	  if (bind != STB_LOCAL)
	    {
	      err = grub_efiemu_register_symbol (name, handle, off);
	      if (err)
		return err;
	    }
	  grub_efiemu_elfsyms[i].handle = handle;
	  grub_efiemu_elfsyms[i].off = off;
	  break;

	case STT_SECTION:
	  err = grub_efiemu_get_section_addr (segs, sym->st_shndx,
					      &handle, &off);
	  if (err)
	    {
	      grub_efiemu_elfsyms[i].handle = 0;
	      grub_efiemu_elfsyms[i].off = 0;
	      grub_errno = GRUB_ERR_NONE;
	      break;
	    }

	  grub_efiemu_elfsyms[i].handle = handle;
	  grub_efiemu_elfsyms[i].off = off;
	  break;

	case STT_FILE:
	  grub_efiemu_elfsyms[i].handle = 0;
	  grub_efiemu_elfsyms[i].off = 0;
	  break;

	default:
	  return grub_error (GRUB_ERR_BAD_MODULE,
			     "unknown symbol type `%d'", (int) type);
	}
    }

  return GRUB_ERR_NONE;
}

/* Load runtime to the memory and request memory for definitive location*/
grub_err_t
SUFFIX (grub_efiemu_loadcore_init) (void *core, const char *filename,
				    grub_size_t core_size,
				    grub_efiemu_segment_t *segments)
{
  Elf_Ehdr *e = (Elf_Ehdr *) core;
  grub_err_t err;

  if (e->e_type != ET_REL)
    return grub_error (GRUB_ERR_BAD_MODULE, N_("this ELF file is not of the right type"));

  /* Make sure that every section is within the core.  */
  if ((grub_size_t) core_size < e->e_shoff + (grub_uint32_t) e->e_shentsize * e->e_shnum)
    return grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
		       filename);

  err = grub_efiemu_init_segments (segments, core);
  if (err)
    return err;
  err = grub_efiemu_count_symbols (core);
  if (err)
    return err;

  grub_efiemu_request_symbols (1);
  return GRUB_ERR_NONE;
}

/* Load runtime definitively */
grub_err_t
SUFFIX (grub_efiemu_loadcore_load) (void *core,
				    grub_size_t core_size
				    __attribute__ ((unused)),
				    grub_efiemu_segment_t segments)
{
  grub_err_t err;
  err = grub_efiemu_load_segments (segments, core);
  if (err)
    return err;

  err = grub_efiemu_resolve_symbols (segments, core);
  if (err)
    return err;

  err = SUFFIX (grub_arch_efiemu_relocate_symbols) (segments,
						    grub_efiemu_elfsyms,
						    core);
  if (err)
    return err;

  return GRUB_ERR_NONE;
}
