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; }
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; }
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; }
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; }
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; }
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); }
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); }
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; }
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; }
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; }
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; }