home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari FTP
/
ATARI_FTP_0693.zip
/
ATARI_FTP_0693
/
Tex
/
Tex29
/
StTeXsrc.zoo
/
etc
/
undump.c
< prev
Wrap
C/C++ Source or Header
|
1989-09-21
|
5KB
|
222 lines
/*
* undump new old <args>
* undump the memory image of old to new
* old is run with args, and when it exits, its memory image is
* undump'ed into new.
* Gcc probably required.
*
* ++jrb bammi@dsrgsun.ces.cwru.edu
*/
#include <stdio.h>
#include <basepage.h>
#include <st-out.h>
#include <osbind.h>
#include <string.h>
#define BSIZ 8192L
char buf[BSIZ];
char oldname[FILENAME_MAX], newname[FILENAME_MAX];
static unsigned long getlong(FILE *f)
{
unsigned long l;
if(fread(&l, sizeof l, 1, f) != 1)
{
fprintf(stderr,"%s: unexpected EOF\n", oldname);
exit(92);
}
return l;
}
static void copy(FILE *, FILE *, unsigned long);
static void makeenv(int, char **, char **);
int main(int argc, char **argv, char **envp)
{
FILE *new, *old;
FILE *fopen();
struct aexec newhead, oldhead;
BASEPAGE *bp;
long l;
unsigned long roffset, ul;
char *patchloc;
unsigned long getlong(FILE *);
/* chk args */
if(argc < 3)
{
fprintf(stderr,"usage: undump new old [args..]\n");
exit(1);
}
/* open files */
if((new = fopen(argv[1], "wb")) == NULL)
{
perror(argv[1]);
exit(2);
}
strncpy(newname, argv[1], FILENAME_MAX);
if((old = fopen(argv[2], "rb")) == NULL)
{
perror(argv[2]);
exit(3);
}
strncpy(oldname, argv[2], FILENAME_MAX);
/* read header from old */
if(fread(&oldhead, sizeof oldhead, 1, old) != 1)
{
perror(oldname);
exit(4);
}
if(A_BADMAG(oldhead)) /* check its magic # */
{
fprintf(stderr,"%s: bad magic number 0x%x\n", oldname,oldhead.a_magic);
exit(5);
}
/* make up new head */
newhead = oldhead;
newhead.a_data = oldhead.a_data + oldhead.a_bss;
newhead.a_bss = 0L;
/* write new head */
if(fwrite(&newhead, sizeof newhead, 1, new) != 1)
{
perror(newname);
exit(6);
}
/* pick up args and make env */
makeenv(argc, argv, envp);
/* &buf[0] == command tail, &buf[130] == envp */
/* load old into mem and grab basepage */
if((l = Pexec(PE_LOAD, oldname, buf, &buf[130])) < 0)
{
fprintf(stderr,"%s: could'nt load\n", oldname);
exit(7);
}
bp = (BASEPAGE *)l;
roffset = (unsigned long)(bp->p_tbase); /* grab reloc offset */
bzero(bp->p_bbase, bp->p_blen); /* not sure if this is needed */
/* now do the just go */
(void)Pexec(PE_GO, 0L, bp, 0L);
/* un-relocate stuff in the text and data segments in core,
and then dump it all into new */
/* seek to reloc part of old */
if(fseek(old, A_SYMOFF(oldhead) + oldhead.a_syms, SEEK_SET) < 0)
{
perror(oldname);
exit(8);
}
/* step through relocs, reading relocs from old, and unrelocating */
/* the corresponding items in core */
ul = getlong(old); /* initial off from begining of text */
patchloc = (char *)(roffset + ul);
while(1)
{
*((unsigned long *)patchloc) -= roffset; /* un-reloc */
more:
if((ul = (unsigned long)getc(old)) == 0)
break; /* all done */
if(ul == 1)
{
patchloc += 254L;
goto more;
}
else if(ul == 3)
{
fprintf(stderr,"WARNING: illegal reloc %ld (ignored)\n", ul);
goto more;
} /* note we let ul==2 pass thru */
patchloc += ul;
}
/* dump text+data+bss from core into new */
if(fwrite(bp->p_tbase, newhead.a_text + newhead.a_data, 1, new) != 1)
{
perror(newname);
exit(11);
}
if(fseek(old, A_SYMOFF(oldhead), SEEK_SET) < 0)
{
perror(oldname);
exit(12);
}
/* copy rest of old into new (ie. the symt if any and the reloc) */
copy(old, new, 0x7fffffffL);
fclose(new);
fclose(old);
return 0;
}
/*
* copy from -> to upto count bytes or EOF
*/
static void copy(FILE *from, FILE *to, unsigned long count)
{
register unsigned long n;
while(count > 0)
{
n = (count > BSIZ) ? BSIZ : count;
if((n = fread(buf, 1, n, from)) <= 0)
return;
if(fwrite(buf, 1, n, to) != n)
{
perror(newname);
exit(13);
}
count -= n;
}
}
extern char **environ;
static void makeenv(int argc, char **argv, char **envp)
{
int i, count, l;
char *p;
bzero(buf, 128L);
if(envp == NULL)
envp = environ;
p = &buf[130];
if(envp)
{
for(; *envp; envp++)
{
strcpy(p, *envp);
p += (strlen(*envp) + 1);
}
}
strcpy(p, "ARGV=");
p += (strlen(p) + 1);
strcpy(p, argv[2]);
p += (strlen(p) + 1);
strcpy(buf, " ");
for(count = 0, i = 3; i < argc; i++)
{
l = strlen(argv[i]);
if( (count += l) < 127)
{
strcat(buf, argv[i]);
if((i+1) < argc)
{
strcat(buf, " ");
count++;
}
}
strcpy(p, argv[i]);
p += (l+1);
}
*p++ = '\0'; *p = '\0';
buf[0] = strlen(&buf[1]);
}