1 /* save (III) J. Gillogly 2 * save user core image for restarting 3 * usage: save(<command file (argv[0] from main)>,<output file>) 4 * bugs 5 * - impure code (i.e. changes in instructions) is not handled 6 * (but people that do that get what they deserve) 7 */ 8 9 static char sccsid[] = " save.c 4.3 89/03/05 "; 10 11 #include <sys/file.h> 12 #include <a.out.h> 13 int filesize; /* accessible to caller */ 14 15 char *sbrk(); 16 17 save(cmdfile,outfile) /* save core image */ 18 char *cmdfile,*outfile; 19 { register char *c; 20 register int i,fd; 21 int fdaout; 22 struct exec header; 23 int counter; 24 char buff[512],pwbuf[120]; 25 fdaout = open(cmdfile, O_RDONLY, 0); /* open command */ 26 if (fdaout<0) return(-1); /* can do nothing without text */ 27 if ((fd=creat(outfile,0755))== -1) 28 { printf("Cannot create %s\n",outfile); 29 return(-1); 30 } 31 /* can get the text segment from the command that we were 32 * called with, and change all data from uninitialized to 33 * initialized. It will start at the top again, so the user 34 * is responsible for checking whether it was restarted 35 * could ignore sbrks and breaks for the first pass 36 */ 37 read(fdaout,&header,sizeof header);/* get the header */ 38 header.a_bss = 0; /* no data uninitialized */ 39 header.a_syms = 0; /* throw away symbol table */ 40 switch (header.a_magic) /* find data segment */ 41 { case 0407: /* non sharable code */ 42 c = (char *) header.a_text;/* data starts right after text */ 43 header.a_data=sbrk(0)-c; /* current size (incl allocs) */ 44 break; 45 case 0410: /* sharable code */ 46 c = (char *) 47 #ifdef pdp11 48 (header.a_text /* starts after text */ 49 & 0160000) /* on an 8K boundary */ 50 + 020000; /* i.e. the next one up */ 51 #endif 52 #ifdef vax 53 (header.a_text /* starts after text */ 54 & 037777776000) /* on an 1K boundary */ 55 + 02000; /* i.e. the next one up */ 56 #endif 57 #ifdef tahoe 58 (header.a_text /* starts after text */ 59 & 037777776000) /* on an 1K boundary */ 60 + 02000; /* i.e. the next one up */ 61 #endif 62 #ifdef z8000 63 (header.a_text /* starts after text */ 64 & 0174000) /* on an 2K boundary */ 65 + 004000; /* i.e. the next one up */ 66 #endif 67 header.a_data=sbrk(0)-c; /* current size (incl allocs) */ 68 break; 69 case 0411: /* sharable with split i/d */ 70 c = 0; /* can't reach text */ 71 header.a_data=(int)sbrk(0);/* current size (incl allocs) */ 72 break; 73 case 0413: 74 c = (char *) header.a_text;/* starts after text */ 75 lseek(fdaout, 1024L, 0); /* skip unused part of 1st block*/ 76 } 77 if (header.a_data<0) /* data area very big */ 78 return(-1); /* fail for now */ 79 80 filesize=sizeof header+header.a_text+header.a_data; 81 write(fd,&header,sizeof header); /* make the new header */ 82 if (header.a_magic==0413) 83 lseek(fd, 1024L, 0); /* Start on 1K boundary */ 84 counter=header.a_text; /* size of text */ 85 while (counter>512) /* copy 512-byte blocks */ 86 { read(fdaout,buff,512); /* as long as possible */ 87 write(fd,buff,512); 88 counter -= 512; 89 } 90 read(fdaout,buff,counter); /* then pick up the rest */ 91 write(fd,buff,counter); 92 write(fd,c,header.a_data); /* write all data in 1 glob */ 93 close(fd); 94 } 95