Пример #1
0
static char *
grub_gettext_getstr_from_position (struct grub_gettext_context *ctx,
				   grub_off_t off,
				   grub_size_t position)
{
  grub_off_t internal_position;
  grub_size_t length;
  grub_off_t offset;
  char *translation;
  struct string_descriptor desc;
  grub_err_t err;

  internal_position = (off + position * sizeof (desc));

  err = grub_gettext_pread (ctx->fd_mo, (char *) &desc,
			    sizeof (desc), internal_position);
  if (err)
    return NULL;
  length = grub_cpu_to_le32 (desc.length);
  offset = grub_cpu_to_le32 (desc.offset);

  translation = grub_malloc (length + 1);
  if (!translation)
    return NULL;

  err = grub_gettext_pread (ctx->fd_mo, translation, length, offset);
  if (err)
    {
      grub_free (translation);
      return NULL;
    }
  translation[length] = '\0';

  return translation;
}
Пример #2
0
static struct grub_archelp_data *
grub_cbfs_mount (grub_disk_t disk)
{
  struct cbfs_file hd;
  struct grub_archelp_data *data = NULL;
  grub_uint32_t ptr;
  grub_off_t header_off;
  struct cbfs_header head;

  if (grub_disk_get_size (disk) == GRUB_DISK_SIZE_UNKNOWN)
    goto fail;

  if (grub_disk_read (disk, grub_disk_get_size (disk) - 1,
		      GRUB_DISK_SECTOR_SIZE - sizeof (ptr),
		      sizeof (ptr), &ptr))
    goto fail;

  ptr = grub_cpu_to_le32 (ptr);
  header_off = (grub_disk_get_size (disk) << GRUB_DISK_SECTOR_BITS)
    + (grub_int32_t) ptr;

  if (grub_disk_read (disk, 0, header_off,
		      sizeof (head), &head))
    goto fail;

  if (!validate_head (&head))
    goto fail;

  data = (struct grub_archelp_data *) grub_zalloc (sizeof (*data));
  if (!data)
    goto fail;

  data->cbfs_start = (grub_disk_get_size (disk) << GRUB_DISK_SECTOR_BITS)
    - (grub_be_to_cpu32 (head.romsize) - grub_be_to_cpu32 (head.offset));
  data->cbfs_end = (grub_disk_get_size (disk) << GRUB_DISK_SECTOR_BITS)
    - grub_be_to_cpu32 (head.bootblocksize);
  data->cbfs_align = grub_be_to_cpu32 (head.align);

  if (data->cbfs_start >= (grub_disk_get_size (disk) << GRUB_DISK_SECTOR_BITS))
    goto fail;
  if (data->cbfs_end > (grub_disk_get_size (disk) << GRUB_DISK_SECTOR_BITS))
    data->cbfs_end = (grub_disk_get_size (disk) << GRUB_DISK_SECTOR_BITS);

  data->next_hofs = data->cbfs_start;

  if (grub_disk_read (disk, 0, data->cbfs_start, sizeof (hd), &hd))
    goto fail;

  if (grub_memcmp (hd.magic, CBFS_FILE_MAGIC, sizeof (CBFS_FILE_MAGIC) - 1))
    goto fail;

  data->disk = disk;

  return data;

fail:
  grub_free (data);
  grub_error (GRUB_ERR_BAD_FS, "not a cbfs filesystem");
  return 0;
}
Пример #3
0
static grub_uint32_t
grub_gettext_get_info (int offset)
{
  grub_uint32_t value;

  grub_gettext_pread (fd_mo, (char *) &value, 4, offset);

  value = grub_cpu_to_le32 (value);
  return value;
}
Пример #4
0
grub_elf_t
grub_xen_file (grub_file_t file)
{
  grub_elf_t elf;
  struct linux_kernel_header lh;
  grub_file_t off_file;

  elf = grub_elf_file (file, file->name);
  if (elf)
    return elf;
  grub_errno = GRUB_ERR_NONE;

  if (grub_file_seek (file, 0) == (grub_off_t) -1)
    goto fail;

  if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh))
    goto fail;

  if (lh.boot_flag != grub_cpu_to_le16 (0xaa55)
      || lh.header != grub_cpu_to_le32 (GRUB_LINUX_MAGIC_SIGNATURE)
      || grub_le_to_cpu16 (lh.version) < 0x0208)
    {
      grub_error (GRUB_ERR_BAD_OS, "version too old for xen boot");
      return NULL;
    }

  if (lh.payload_length < 4)
    {
      grub_error (GRUB_ERR_BAD_OS, "payload too short");
      return NULL;
    }

  grub_dprintf ("xen", "found bzimage payload 0x%llx-0x%llx\n",
		(unsigned long long) (lh.setup_sects + 1) * 512
		+ lh.payload_offset,
		(unsigned long long) lh.payload_length - 4);

  off_file = grub_file_offset_open (file, (lh.setup_sects + 1) * 512
				    + lh.payload_offset,
				    lh.payload_length - 4);
  if (!off_file)
    goto fail;

  elf = grub_elf_file (off_file, file->name);
  if (elf)
    return elf;
  grub_file_offset_close (off_file);

fail:
  grub_error (GRUB_ERR_BAD_OS, "not xen image");
  return NULL;
}
Пример #5
0
static const char *
grub_gettext_gettranslation_from_position (int position)
{
  int offsettranslation;
  int internal_position;
  grub_uint32_t length, offset;
  char *translation;

  offsettranslation = grub_gettext_get_info (GETTEXT_OFFSET_TRANSLATION);

  internal_position = offsettranslation + position * 8;

  grub_gettext_pread (fd_mo, (char *) &length, 4, internal_position);
  length = grub_cpu_to_le32 (length);

  grub_gettext_pread (fd_mo, (char *) &offset, 4, internal_position + 4);
  offset = grub_cpu_to_le32 (offset);

  translation = grub_malloc (length + 1);
  grub_gettext_getstring_from_offset (offset, length, translation);

  return translation;
}
Пример #6
0
static void
grub_ohci_writereg32 (struct grub_ohci *o,
                      grub_ohci_reg_t reg, grub_uint32_t val)
{
    *(o->iobase + reg) = grub_cpu_to_le32 (val);
}
Пример #7
0
static void
write_fat (FILE *in32, FILE *in64, FILE *out, const char *out_filename,
	   const char *name32, const char *name64)
{
  struct grub_macho_fat_header head;
  struct grub_macho_fat_arch arch32, arch64;
  grub_uint32_t size32, size64;
  char *buf;

  fseek (in32, 0, SEEK_END);
  size32 = ftell (in32);
  fseek (in32, 0, SEEK_SET);
  fseek (in64, 0, SEEK_END);
  size64 = ftell (in64);
  fseek (in64, 0, SEEK_SET);

  head.magic = grub_cpu_to_le32_compile_time (GRUB_MACHO_FAT_EFI_MAGIC);
  head.nfat_arch = grub_cpu_to_le32_compile_time (2);
  arch32.cputype = grub_cpu_to_le32_compile_time (GRUB_MACHO_CPUTYPE_IA32);
  arch32.cpusubtype = grub_cpu_to_le32_compile_time (3);
  arch32.offset = grub_cpu_to_le32_compile_time (sizeof (head)
						 + sizeof (arch32)
						 + sizeof (arch64));
  arch32.size = grub_cpu_to_le32 (size32);
  arch32.align = 0;

  arch64.cputype = grub_cpu_to_le32_compile_time (GRUB_MACHO_CPUTYPE_AMD64);
  arch64.cpusubtype = grub_cpu_to_le32_compile_time (3);
  arch64.offset = grub_cpu_to_le32 (sizeof (head) + sizeof (arch32)
				    + sizeof (arch64) + size32);
  arch64.size = grub_cpu_to_le32 (size64);
  arch64.align = 0;
  if (fwrite (&head, 1, sizeof (head), out) != sizeof (head)
      || fwrite (&arch32, 1, sizeof (arch32), out) != sizeof (arch32)
      || fwrite (&arch64, 1, sizeof (arch64), out) != sizeof (arch64))
    {
      if (out_filename)
	grub_util_error ("cannot write to `%s': %s",
			 out_filename, strerror (errno));
      else
	grub_util_error ("cannot write to the stdout: %s", strerror (errno));
    }

  buf = xmalloc (size32);
  if (fread (buf, 1, size32, in32) != size32)
    grub_util_error (_("cannot read `%s': %s"), name32,
                     strerror (errno));
  if (fwrite (buf, 1, size32, out) != size32)
    {
      if (out_filename)
	grub_util_error ("cannot write to `%s': %s", 
			 out_filename, strerror (errno));
      else
	grub_util_error ("cannot write to the stdout: %s", strerror (errno));
    }
  free (buf);

  buf = xmalloc (size64);
  if (fread (buf, 1, size64, in64) != size64)
    grub_util_error (_("cannot read `%s': %s"), name64,
                     strerror (errno));
  if (fwrite (buf, 1, size64, out) != size64)
    {
      if (out_filename)
	grub_util_error ("cannot write to `%s': %s",
			 out_filename, strerror (errno));
      else
	grub_util_error ("cannot write to the stdout: %s", strerror (errno));
    }
  free (buf);
}
Пример #8
0
static grub_err_t
bsdlabel_partition_map_iterate (grub_disk_t disk,
				int (*hook) (grub_disk_t disk,
					     const grub_partition_t partition))
{
  struct grub_partition_bsd_disk_label label;
  struct grub_partition p;
  grub_disk_addr_t delta = 0;
  unsigned pos;

  /* Read the BSD label.  */
  if (grub_disk_read (disk, GRUB_PC_PARTITION_BSD_LABEL_SECTOR,
		      0, sizeof (label), &label))
    return grub_errno;

  /* Check if it is valid.  */
  if (label.magic != grub_cpu_to_le32 (GRUB_PC_PARTITION_BSD_LABEL_MAGIC))
    return grub_error (GRUB_ERR_BAD_PART_TABLE, "no signature");

  /* A kludge to determine a base of be.offset.  */
  if (GRUB_PC_PARTITION_BSD_LABEL_WHOLE_DISK_PARTITION
      < grub_cpu_to_le16 (label.num_partitions))
    {
      struct grub_partition_bsd_entry whole_disk_be;

      pos = sizeof (label) + GRUB_PC_PARTITION_BSD_LABEL_SECTOR
	* GRUB_DISK_SECTOR_SIZE + sizeof (struct grub_partition_bsd_entry)
	* GRUB_PC_PARTITION_BSD_LABEL_WHOLE_DISK_PARTITION;

      if (grub_disk_read (disk, pos / GRUB_DISK_SECTOR_SIZE,
			  pos % GRUB_DISK_SECTOR_SIZE, sizeof (whole_disk_be),
			  &whole_disk_be))
	return grub_errno;

      delta = grub_le_to_cpu32 (whole_disk_be.offset);
    }

  pos = sizeof (label) + GRUB_PC_PARTITION_BSD_LABEL_SECTOR
    * GRUB_DISK_SECTOR_SIZE;

  for (p.number = 0;
       p.number < grub_cpu_to_le16 (label.num_partitions);
       p.number++, pos += sizeof (struct grub_partition_bsd_entry))
    {
      struct grub_partition_bsd_entry be;

      if (p.number == GRUB_PC_PARTITION_BSD_LABEL_WHOLE_DISK_PARTITION)
	continue;

      p.offset = pos / GRUB_DISK_SECTOR_SIZE;
      p.index = pos % GRUB_DISK_SECTOR_SIZE;

      if (grub_disk_read (disk, p.offset, p.index, sizeof (be),  &be))
	return grub_errno;

      p.start = grub_le_to_cpu32 (be.offset);
      p.len = grub_le_to_cpu32 (be.size);
      p.partmap = &grub_bsdlabel_partition_map;

      grub_dprintf ("partition",
		    "partition %d: type 0x%x, start 0x%llx, len 0x%llx\n",
		    p.number, be.fs_type,
		    (unsigned long long) p.start,
		    (unsigned long long) p.len);

      if (p.len == 0)
	continue;

      if (p.start < delta)
	{
#ifdef GRUB_UTIL
	  char *partname;
#endif
	  grub_dprintf ("partition",
			"partition %d: invalid start (found 0x%llx, wanted >= 0x%llx)\n",
			p.number,
			(unsigned long long) p.start,
			(unsigned long long) delta);
#ifdef GRUB_UTIL
	  /* disk->partition != NULL as 0 < delta */
	  partname = grub_partition_get_name (disk->partition);
	  grub_util_warn ("Discarding improperly nested partition (%s,%s,%s%d)",
			  disk->name, partname, p.partmap->name, p.number + 1);
	  grub_free (partname);
#endif
	  continue;
	}

      p.start -= delta;

      if (hook (disk, &p))
	return grub_errno;
    }

  return GRUB_ERR_NONE;
}
Пример #9
0
int
main (int argc, char **argv)
{
  FILE *in, *out;
  int do_bss = 0;
  char *buf;
  int bufsize;
  struct grub_macho_header32 *head;
  struct grub_macho_segment32 *curcmd;
  unsigned i;
  unsigned bssstart = 0;
  unsigned bssend = 0;

  if (argc && strcmp (argv[1], "--bss") == 0)
    do_bss = 1;
  if (argc < 2 + do_bss)
    {
      printf ("Usage: %s [--bss] filename.exec filename.img\n"
	      "Convert Mach-O into raw image\n", argv[0]);
      return 0;
    }
  in = fopen (argv[1 + do_bss], "rb");
  if (! in)
    {
      printf ("Couldn't open %s\n", argv[1 + do_bss]);
      return 1;
    }
  out = fopen (argv[2 + do_bss], "wb");
  if (! out)
    {
      fclose (in);
      printf ("Couldn't open %s\n", argv[2 + do_bss]);
      return 2;
    }
  fseek (in, 0, SEEK_END);
  bufsize = ftell (in);
  fseek (in, 0, SEEK_SET);
  buf = malloc (bufsize);
  if (! buf)
    {
      fclose (in);
      fclose (out);
      printf ("Couldn't allocate buffer\n");
      return 3;
    }
  fread (buf, 1, bufsize, in);
  head = (struct grub_macho_header32 *) buf;
  if (grub_le_to_cpu32 (head->magic) != GRUB_MACHO_MAGIC32)
    {
      fclose (in);
      fclose (out);
      free (buf);
      printf ("Invalid Mach-O fle\n");
      return 4;
    }
  curcmd = (struct grub_macho_segment32 *) (buf + sizeof (*head));
  for (i = 0; i < grub_le_to_cpu32 (head->ncmds); i++,
	 curcmd = (struct grub_macho_segment32 *)
	 (((char *) curcmd) + curcmd->cmdsize))
    {
      if (curcmd->cmd != GRUB_MACHO_CMD_SEGMENT32)
	continue;
      fwrite (buf + grub_le_to_cpu32 (curcmd->fileoff), 1,
	      grub_le_to_cpu32 (curcmd->filesize), out);
      if (grub_le_to_cpu32 (curcmd->vmsize)
	  > grub_le_to_cpu32 (curcmd->filesize))
	{
	  bssstart = grub_le_to_cpu32 (curcmd->vmaddr)
	    + grub_le_to_cpu32 (curcmd->filesize) ;
	  bssend = grub_le_to_cpu32 (curcmd->vmaddr)
	    + grub_le_to_cpu32 (curcmd->vmsize) ;
	}
    }
  if (do_bss)
    {
      grub_uint32_t tmp;
      fseek (out, 0x5c, SEEK_SET);
      tmp = grub_cpu_to_le32 (bssstart);
      fwrite (&tmp, 4, 1, out);
      tmp = grub_cpu_to_le32 (bssend);
      fwrite (&tmp, 4, 1, out);
    }
  fclose (in);
  fclose (out);
  printf("macho2img complete\n");
  return 0;
}
Пример #10
0
  int iterate_env (struct grub_env_var *var)
  {
    char *guid, *attr, *name, *varname;
    struct efi_variable *efivar;
    int len = 0;
    int i;
    grub_uint64_t guidcomp;

    if (grub_memcmp (var->name, "EfiEmu.pnvram.",
		     sizeof ("EfiEmu.pnvram.") - 1) != 0)
      return 0;

    guid = var->name + sizeof ("EfiEmu.pnvram.") - 1;

    attr = grub_strchr (guid, '.');
    if (!attr)
      return 0;
    attr++;

    name = grub_strchr (attr, '.');
    if (!name)
      return 0;
    name++;

    efivar = (struct efi_variable *) nvramptr;
    if (nvramptr - nvram + sizeof (struct efi_variable) > nvramsize)
      {
	grub_error (GRUB_ERR_OUT_OF_MEMORY,
		    "too many NVRAM variables for reserved variable space."
		    " Try increasing EfiEmu.pnvram.size");
	return 1;
      }

    nvramptr += sizeof (struct efi_variable);

    efivar->guid.data1 = grub_cpu_to_le32 (grub_strtoul (guid, &guid, 16));
    if (*guid != '-')
      return 0;
    guid++;

    efivar->guid.data2 = grub_cpu_to_le16 (grub_strtoul (guid, &guid, 16));
    if (*guid != '-')
      return 0;
    guid++;

    efivar->guid.data3 = grub_cpu_to_le16 (grub_strtoul (guid, &guid, 16));
    if (*guid != '-')
      return 0;
    guid++;

    guidcomp = grub_strtoull (guid, 0, 16);
    for (i = 0; i < 8; i++)
      efivar->guid.data4[i] = (guidcomp >> (56 - 8 * i)) & 0xff;

    efivar->attributes = grub_strtoull (attr, 0, 16);

    varname = grub_malloc (grub_strlen (name) + 1);
    if (! varname)
      return 1;

    if (unescape (name, varname, varname + grub_strlen (name) + 1, &len))
      return 1;

    len = grub_utf8_to_utf16 ((grub_uint16_t *) nvramptr,
			      (nvramsize - (nvramptr - nvram)) / 2,
			      (grub_uint8_t *) varname, len, NULL);

    nvramptr += 2 * len;
    *((grub_uint16_t *) nvramptr) = 0;
    nvramptr += 2;
    efivar->namelen = 2 * len + 2;

    if (unescape (var->value, nvramptr, nvram + nvramsize, &len))
      {
	efivar->namelen = 0;
	return 1;
      }

    nvramptr += len;

    efivar->size = len;

    return 0;
  }
Пример #11
0
static grub_err_t
pc_partition_map_iterate (grub_disk_t disk,
			  int (*hook) (grub_disk_t disk,
				       const grub_partition_t partition))
{
  struct grub_partition p;
  struct grub_pc_partition pcdata;
  struct grub_pc_partition_mbr mbr;
  struct grub_pc_partition_disk_label label;
  struct grub_disk raw;

  /* Enforce raw disk access.  */
  raw = *disk;
  raw.partition = 0;
  
  p.offset = 0;
  pcdata.ext_offset = 0;
  pcdata.dos_part = -1;
  p.data = &pcdata;
  p.partmap = &grub_pc_partition_map;
  
  while (1)
    {
      int i;
      struct grub_pc_partition_entry *e;
      
      /* Read the MBR.  */
      if (grub_disk_read (&raw, p.offset, 0, sizeof (mbr), (char *) &mbr))
	goto finish;

      /* Check if it is valid.  */
      if (mbr.signature != grub_cpu_to_le16 (GRUB_PC_PARTITION_SIGNATURE))
	return grub_error (GRUB_ERR_BAD_PART_TABLE, "no signature");

      /* Analyze DOS partitions.  */
      for (p.index = 0; p.index < 4; p.index++)
	{
	  e = mbr.entries + p.index;
	  
	  p.start = p.offset + grub_le_to_cpu32 (e->start);
	  p.len = grub_le_to_cpu32 (e->length);
	  pcdata.bsd_part = -1;
	  pcdata.dos_type = e->type;
	  pcdata.bsd_type = -1;

	  grub_dprintf ("partition",
			"partition %d: flag 0x%x, type 0x%x, start 0x%llx, len 0x%llx\n",
			p.index, e->flag, pcdata.dos_type,
			(unsigned long long) p.start,
			(unsigned long long) p.len);

	  /* If this is a GPT partition, this MBR is just a dummy.  */
	  if (e->type == GRUB_PC_PARTITION_TYPE_GPT_DISK && p.index == 0)
	    return grub_error (GRUB_ERR_BAD_PART_TABLE, "dummy mbr");

	  /* If this partition is a normal one, call the hook.  */
	  if (! grub_pc_partition_is_empty (e->type)
	      && ! grub_pc_partition_is_extended (e->type))
	    {
	      pcdata.dos_part++;
	      
	      if (hook (disk, &p))
		return 1;

	      /* Check if this is a BSD partition.  */
	      if (grub_pc_partition_is_bsd (e->type))
		{
		  /* Check if the BSD label is within the DOS partition.  */
		  if (p.len <= GRUB_PC_PARTITION_BSD_LABEL_SECTOR)
		    return grub_error (GRUB_ERR_BAD_PART_TABLE,
				       "no space for disk label");

		  /* Read the BSD label.  */
		  if (grub_disk_read (&raw,
				      (p.start
				       + GRUB_PC_PARTITION_BSD_LABEL_SECTOR),
				      0,
				      sizeof (label),
				      (char *) &label))
		    goto finish;

		  /* Check if it is valid.  */
		  if (label.magic
		      != grub_cpu_to_le32 (GRUB_PC_PARTITION_BSD_LABEL_MAGIC))
		    return grub_error (GRUB_ERR_BAD_PART_TABLE,
				       "invalid disk label magic 0x%x",
				       label.magic);

		  for (pcdata.bsd_part = 0;
		       pcdata.bsd_part < grub_cpu_to_le16 (label.num_partitions);
		       pcdata.bsd_part++)
		    {
		      struct grub_pc_partition_bsd_entry *be
			= label.entries + pcdata.bsd_part;

		      p.start = grub_le_to_cpu32 (be->offset);
		      p.len = grub_le_to_cpu32 (be->size);
		      pcdata.bsd_type = be->fs_type;
		      
		      if (be->fs_type != GRUB_PC_PARTITION_BSD_TYPE_UNUSED)
			if (hook (disk, &p))
			  return 1;
		    }
		}
	    }
	  else if (pcdata.dos_part < 4)
	    /* If this partition is a logical one, shouldn't increase the
	       partition number.  */
	    pcdata.dos_part++;
	}

      /* Find an extended partition.  */
      for (i = 0; i < 4; i++)
	{
	  e = mbr.entries + i;
	  
	  if (grub_pc_partition_is_extended (e->type))
	    {
	      p.offset = pcdata.ext_offset + grub_le_to_cpu32 (e->start);
	      if (! pcdata.ext_offset)
		pcdata.ext_offset = p.offset;

	      break;
	    }
	}

      /* If no extended partition, the end.  */
      if (i == 4)
	break;
    }

 finish:
  return grub_errno;
}