/*-=-=-=-=-=-=-=-=-=-=-=- RCCL/RCI Notice of Copyright -=-=-=-=-=-=-=-=-=-=-*
 *									    *
 *	Copyright (C) 1987, 1991 by Mike Parker.			    *
 *									    *
 *	Information on copyright permissions, as well as a complete	    *
 *	disclaimer of warranty, is given in the file COPYRIGHT.		    *
 *									    *
 *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/

#include <stdio.h>
#include <a.out.h>
#include <sys/types.h>
#include <sys/file.h>

#define USERSTACK 65536

#define ROUNDUP(val,x) ((x)*(((val)+((x)-1))/(x)))

extern char **argvec;

char *xfn;
int xfd;
struct exec hdr;
struct nlist nl[2];
int xsize;
char *xbuf;

char *sbrk();

Read(buf,nb)
char *buf;
int nb;
{
 char *bp;
 int did;
 int left;

 left = nb;
 bp = buf;
 while (left > 0)
  { did = read(xfd,bp,left);
    if (did < 0)
     { fprintf(stderr,"%s: can't read %s: ",argvec[0],xfn);
       perror((char *)0);
       exit(1);
     }
    if (did == 0)
     { fprintf(stderr,"%s: unexpected eof (file too small?) on %s\n",
							argvec[0],xfn);
       exit(1);
     }
    bp += did;
    left -= did;
  }
}

main(ac,av)
int ac;
char **av;
{
 int i;

 if (ac != 3)
  { fprintf(stderr,"Usage: %s <a.out> <entrypoint>\n",argvec[0]);
    exit(1);
  }
 xfn = av[1];
 xfd = open(xfn,O_RDONLY,0);
 if (xfd < 0)
  { fprintf(stderr,"%s: can't open %s: ",argvec[0],xfn);
    perror((char *)0);
    exit(1);
  }
 nl[0].n_un.n_name = av[2];
 nl[1].n_un.n_name = 0;
 if (nlist(av[1],nl) != 0)
  { fprintf(stderr,"%s: can't find entry point %s\n",argvec[0],av[2]);
    exit(1);
  }
 lseek(xfd,(off_t)0,L_SET);
 Read((char *)&hdr,sizeof(hdr));
 if (hdr.a_magic == OMAGIC)
  { xsize = hdr.a_text + hdr.a_data;
  }
 else
  { xsize = ROUNDUP(hdr.a_text,1024) + ROUNDUP(hdr.a_data,1024);
  }
 xbuf = sbrk(xsize+4); /* 4 slop for printing */
 if (xbuf == (char *)-1)
  { fprintf(stderr,"%s: can't get %d bytes for image: ",argvec[0],xsize+4);
    perror((char *)0);
    exit(1);
  }
 switch (hdr.a_magic)
  { default:
       fprintf(stderr,"%s: bad magic number\n",argvec[0]);
       break;
    case OMAGIC:
       lseek(xfd,(off_t)N_TXTOFF(hdr),L_SET);
       Read(xbuf,(int)hdr.a_text);
       Read(xbuf+hdr.a_text,(int)hdr.a_data);
       printf("\
	.globl	_utextsize\n\
_utextsize:\n\
	.long		0\n\
	.globl	_udatasize\n\
_udatasize:\n\
	.long		%d\n\
	.globl	_ubsssize\n\
_ubsssize:\n\
	.long		%d\n\
",(int)(hdr.a_text+hdr.a_data),(int)hdr.a_bss);
       break;
    case NMAGIC: case ZMAGIC:
       lseek(xfd,(off_t)N_TXTOFF(hdr),L_SET);
       Read(xbuf,(int)hdr.a_text);
       Read(xbuf+ROUNDUP(hdr.a_text,1024),(int)hdr.a_data);
       printf("\
	.globl	_utextsize\n\
_utextsize:\n\
	.long		%d\n\
	.globl	_udatasize\n\
_udatasize:\n\
	.long		%d\n\
	.globl	_ubsssize\n\
_ubsssize:\n\
	.long		%d\n\
",	(int)ROUNDUP(hdr.a_text,1024),
	(int)ROUNDUP(hdr.a_data,1024),
	(int)ROUNDUP(hdr.a_bss,1024) );
       break;
  }
 printf("\
	.globl	_uentry\n\
_uentry:\n\
	.long		%ld\n\
	.globl	_ustacksize\n\
_ustacksize:\n\
	.long		%d\n\
	.globl	_uimage\n\
_uimage:\n\
",(long int)nl[0].n_value,USERSTACK);
 for (i=0;i<xsize;i+=4)
  { printf("\
	.long		%d\n\
",*(long int *)&xbuf[i]);
  }
 exit(0);
}
