/* Tool to make gzipped second stage binary
   
   Copyright (C) 1996,1998 Jakub Jelinek
   
   This program 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 2 of the License, or
   (at your option) any later version.
   
   This program 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 this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
   USA.  */

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <arpa/inet.h>

FILE *f, *e;
unsigned char buffer[2048];
unsigned char buffer2[2048];
unsigned short diffs[4][2048];
int ndiffs[4];
unsigned int lastv[4];
unsigned int curoff;
unsigned int prevlen;
unsigned int prevoff;

#define MAX_CHANGE	65535

void save(FILE *out, int len, int type)
{
    int i, j, k;
    int curlen = len;

    while (len > 0) {
        i = 2048;
        if (len < i) i = len;
        if (fread (buffer, 1, i, f) != i) {
	    fprintf(stderr, "read %d from arg3 type %d failed\n", i, type);
	    exit(1);
	}
        if (fread (buffer2, 1, i, e) != i) {
	    fprintf(stderr, "read %d from arg4 type %d failed\n", i, type);
	    exit(1);
	}
        for (j = 0; j < i; j++) {
    	    if (buffer[j] != buffer2[j]) {
		if (buffer2[j] == buffer[j] + 4) {
		    if (curoff + j > lastv[type] + MAX_CHANGE) {
			if (type || !prevlen || curoff + j >= prevoff + MAX_CHANGE)
			    goto bad1;
			k = lastv[type] + MAX_CHANGE;
			if (k < prevoff - prevlen)
			    goto bad1;
			if (k >= prevoff)
			    k = prevoff - 1;
			diffs[type][ndiffs[type]] = htons(k - lastv[type]);
			lastv[type] = k;
			ndiffs[type]++;
		    }
		    diffs[type][ndiffs[type]] = htons(curoff + j - lastv[type]);
		    lastv[type] = curoff + j;
		    ndiffs[type]++;
		} else if (buffer2[j] == buffer[j] + 16) {
		    if (curoff + j > lastv[type+1] + MAX_CHANGE) {
			if (type || !prevlen || curoff + j >= prevoff + MAX_CHANGE)
			    goto bad2;
			k = lastv[type+1] + MAX_CHANGE;
			if (k < prevoff - prevlen)
			    goto bad2;
			if (k >= prevoff)
			    k = prevoff - 1;
			diffs[type+1][ndiffs[type+1]] =
				htons(k - lastv[type+1]);
			lastv[type+1] = k;
			ndiffs[type+1]++;
		    }
		    diffs[type+1][ndiffs[type+1]] =
			htons(curoff + j - lastv[type+1]);
		    lastv[type+1] = curoff + j;
		    ndiffs[type+1]++;
		} else {
		    fprintf(stderr, "Strange, small and large images differ in something"
			    " different to R_SPARC_32 and R_SPARC_HI22\n");
		    exit(1);
		}
	    }
        }
	if (fwrite (buffer, 1, i, out) != i) {
	    fprintf(stderr, "write %d failed\n", i);
	    exit(1);
	}
        len -= i;
        curoff += i;
    }
    prevlen = curlen;
    prevoff = curoff;
    return;
bad2:
    type++;
bad1:
    fprintf(stderr, "Distance between two changes larger than %dK %d %d %d\n",
	    MAX_CHANGE / 1024, type, curoff + j, lastv[type]);
    exit(1);
}

int main(int argc, char **argv)
{
    FILE *g, *h;
    int reloc = SMALL_RELOC;
    int first_start, first_end, second_start, second_end;
    int end, rodata_start, rodata_end;
    int net = 0;
    int i = 1;
    char sym[256];
    unsigned int addr;

    if (!strcmp (argv[i], "-a")) {
	net = 1;
	i++;
    }

    f = fopen(argv[i++], "r");
    while (fgets (buffer, 256, f)) {
	char sym[256];
	unsigned int addr;

	if (sscanf(buffer, "%x %*c %s\n", &addr, sym) == 2) {
	    if (!strcmp (sym, "start"))
		reloc = addr;
	    else if (!strcmp (sym, "main_text_start"))
		first_start = addr -  reloc;
	    else if (!strcmp (sym, "main_text_end"))
		first_end = addr - reloc;
	    else if (!strcmp (sym, "main_data_start"))
		second_start = addr - reloc;
	    else if (!strcmp (sym, "main_data_end"))
		second_end = addr - reloc;
	    else if (!strcmp (sym, "main_rodata_start"))
		rodata_start = addr - reloc;
	    else if (!strcmp (sym, "main_rodata_end"))
		rodata_end = addr - reloc;
	    else if (!strcmp (sym, "__bss_start"))
		end = addr - reloc;
	}
    }
    fclose (f);
    f = fopen(argv[i++], "r");
    e = fopen(argv[i++], "r");
    g = fopen(argv[i++], "w");
    h = fopen(argv[i++], "w");
    if (fread(buffer, 1, 32, f) != 32) exit(1);
    if (fread(buffer2, 1, 32, e) != 32) exit(1);
    if (memcmp(buffer, buffer2, 32)) {
    	fprintf(stderr, "Strange. Images for 2.5MB and 3.5MB differ in a.out header\n");
    	exit(1);
    }

    if (!net) {
       memset (buffer, 0, 2048);
       if (fwrite(buffer, 1, 2048, g) != 2048) exit(1);
    } else {
       if (fwrite (buffer, 1, 32, g) != 32) exit(1);
    }

    save (g, first_start, 0);
    save (h, first_end - first_start, 2);
    save (g, rodata_start - first_end, 0);
    save (h, rodata_end - rodata_start, 2);
    save (g, second_start - rodata_end, 0);
    save (h, second_end - second_start, 2);
    save (g, end - second_end, 0);
    fwrite(diffs[0], 2, ndiffs[0]+1, g);
    fwrite(diffs[1], 2, ndiffs[1]+1, g);
    fwrite(diffs[2], 2, ndiffs[2]+1, h);
    fwrite(diffs[3], 2, ndiffs[3]+1, h);
    fclose (f);
    fclose (e);
    fclose (g);
    fclose (h);
    exit (0);
}
