grub-macho2img.c revision 2
1N/A/* macho2img.c - tool to convert Mach-O to raw imagw. */
1N/A/*
1N/A * GRUB -- GRand Unified Bootloader
1N/A * Copyright (C) 2009 Free Software Foundation, Inc.
1N/A *
1N/A * GRUB is free software: you can redistribute it and/or modify
1N/A * it under the terms of the GNU General Public License as published by
1N/A * the Free Software Foundation, either version 3 of the License, or
1N/A * (at your option) any later version.
1N/A *
1N/A * GRUB is distributed in the hope that it will be useful,
1N/A * but WITHOUT ANY WARRANTY; without even the implied warranty of
1N/A * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1N/A * GNU General Public License for more details.
1N/A *
1N/A * You should have received a copy of the GNU General Public License
1N/A * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
1N/A */
1N/A
1N/A#include <config.h>
1N/A
1N/A#include <grub/types.h>
1N/A#include <grub/macho.h>
1N/A#include <stdio.h>
1N/A#include <string.h>
1N/A#include <stdlib.h>
1N/A
1N/A/* Please don't internationalise this file. It's pointless. */
1N/A
1N/A/* XXX: this file assumes particular Mach-O layout and does no checks. */
1N/A/* However as build system ensures correct usage of this tool this
1N/A shouldn't be a problem. */
1N/A
1N/Aint
1N/Amain (int argc, char **argv)
1N/A{
1N/A FILE *in, *out;
1N/A int do_bss = 0;
1N/A char *buf;
1N/A int bufsize;
1N/A struct grub_macho_header32 *head;
1N/A struct grub_macho_segment32 *curcmd;
1N/A unsigned i;
1N/A unsigned bssstart = 0;
1N/A unsigned bssend = 0;
1N/A
1N/A if (argc && strcmp (argv[1], "--bss") == 0)
1N/A do_bss = 1;
1N/A if (argc < 2 + do_bss)
1N/A {
1N/A printf ("Usage: %s [--bss] filename.exec filename.img\n"
1N/A "Convert Mach-O into raw image\n", argv[0]);
1N/A return 0;
1N/A }
1N/A in = fopen (argv[1 + do_bss], "rb");
1N/A if (! in)
1N/A {
1N/A printf ("Couldn't open %s\n", argv[1 + do_bss]);
1N/A return 1;
1N/A }
1N/A out = fopen (argv[2 + do_bss], "wb");
1N/A if (! out)
1N/A {
1N/A fclose (in);
1N/A printf ("Couldn't open %s\n", argv[2 + do_bss]);
1N/A return 2;
1N/A }
1N/A fseek (in, 0, SEEK_END);
1N/A bufsize = ftell (in);
1N/A fseek (in, 0, SEEK_SET);
1N/A buf = malloc (bufsize);
1N/A if (! buf)
1N/A {
1N/A fclose (in);
1N/A fclose (out);
1N/A printf ("Couldn't allocate buffer\n");
1N/A return 3;
1N/A }
1N/A fread (buf, 1, bufsize, in);
1N/A head = (struct grub_macho_header32 *) buf;
1N/A if (grub_le_to_cpu32 (head->magic) != GRUB_MACHO_MAGIC32)
1N/A {
1N/A fclose (in);
1N/A fclose (out);
1N/A free (buf);
1N/A printf ("Invalid Mach-O file\n");
1N/A return 4;
1N/A }
1N/A curcmd = (struct grub_macho_segment32 *) (buf + sizeof (*head));
1N/A for (i = 0; i < grub_le_to_cpu32 (head->ncmds); i++,
1N/A curcmd = (struct grub_macho_segment32 *)
1N/A (((char *) curcmd) + curcmd->cmdsize))
1N/A {
1N/A if (curcmd->cmd != GRUB_MACHO_CMD_SEGMENT32)
1N/A continue;
1N/A fwrite (buf + grub_le_to_cpu32 (curcmd->fileoff), 1,
1N/A grub_le_to_cpu32 (curcmd->filesize), out);
1N/A if (grub_le_to_cpu32 (curcmd->vmsize)
1N/A > grub_le_to_cpu32 (curcmd->filesize))
1N/A {
1N/A bssstart = grub_le_to_cpu32 (curcmd->vmaddr)
1N/A + grub_le_to_cpu32 (curcmd->filesize) ;
1N/A bssend = grub_le_to_cpu32 (curcmd->vmaddr)
1N/A + grub_le_to_cpu32 (curcmd->vmsize) ;
1N/A }
1N/A }
1N/A if (do_bss)
1N/A {
1N/A grub_uint32_t tmp;
1N/A fseek (out, 0x5c, SEEK_SET);
1N/A tmp = grub_cpu_to_le32 (bssstart);
1N/A fwrite (&tmp, 4, 1, out);
1N/A tmp = grub_cpu_to_le32 (bssend);
1N/A fwrite (&tmp, 4, 1, out);
1N/A }
1N/A fclose (in);
1N/A fclose (out);
1N/A printf("macho2img complete\n");
1N/A return 0;
}