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