jhpb@granjon.ATT.COM (05/02/90)
This is a set of trivial patches to PERL patch level 18 to add unexec capability for AT&T 3B2 machines. It eliminates the need for the undump program (which I haven't seen a System V version of yet). The -u option or the undump operator cause an "a.out" to be produced in the current directory. Doing this is tremendously simplified by the fact that 3B2's keep the COFF header at the beginning of the text segment. This was developed for SVR3.2. Known bugs: undump with a label argument works; undump without a label doesn't work. I haven't looked to see why yet. If you fix this, post the patches, please. To install: Change to the source directory, then: touch unexec.c patch -p -N < thisfile You're on your own to link unexec() with PERL. I just compiled unexec.c by hand (cc -c unexec.c) and told Configure that unexec.o was an extra library that I wanted included. Joe Buehler jhpb@garage.att.com -------------------------------------------------------------------- *** temp.c Tue May 1 22:41:08 1990 --- eval.c Tue May 1 22:40:00 1990 *************** *** 1084,1090 goto_targ = Nullch; /* just restart from top */ if (optype == O_DUMP) { do_undump = 1; ! abort(); } longjmp(top_env, 1); case O_INDEX: --- 1084,1092 ----- goto_targ = Nullch; /* just restart from top */ if (optype == O_DUMP) { do_undump = 1; ! unexec(); ! exit(0); ! /* abort();*/ } longjmp(top_env, 1); case O_INDEX: *** temp.c Tue May 1 22:43:00 1990 --- perly.c Tue May 1 22:42:34 1990 *************** *** 648,654 } if (do_undump) { ! abort(); } just_doit: /* come here if running an undumped a.out */ --- 648,656 ----- } if (do_undump) { ! unexec(); ! exit(0); ! /* abort();*/ } just_doit: /* come here if running an undumped a.out */ *** /dev/null Tue May 1 22:35:00 1990 --- unexec.c Sat Apr 28 00:36:47 1990 *************** *** 1,0 --- 1,80 ----- + #include <stdio.h> + #include <fcntl.h> + #include <filehdr.h> + #include <aouthdr.h> + #include <scnhdr.h> + #include <memory.h> + + static int fdout = -1; + + extern _start(); + + void + unexec() + { + struct filehdr *f; + struct filehdr f2; + struct aouthdr *a; + struct aouthdr a2; + struct scnhdr *s; + struct scnhdr s2; + struct scnhdr text; + struct scnhdr data; + struct scnhdr bss; + struct scnhdr zero; + long start; + int i; + + fdout = open("a.out", O_WRONLY|O_CREAT, 0755); + + start = ((long)_start) & -256L; + + /* file header */ + f = (struct filehdr *)start; + memcpy(&f2, f, sizeof(f2)); + f2.f_symptr = 0; + f2.f_nsyms = 0; + + /* a.out header */ + a = (struct aouthdr *)(((char *)f) + sizeof(*f)); + memcpy(&a2, a, sizeof(a2)); + + s = (struct scnhdr *)(((char *)a) + sizeof(*a)); + for (i=0; i<f->f_nscns; ++i) { + memcpy(&s2, s, sizeof(s2)); + s2.s_relptr = 0; + s2.s_lnnoptr = 0; + s2.s_nreloc = 0; + s2.s_nlnno = 0; + if (!strncmp(s2.s_name, ".text", 5)) { + memcpy(&text, &s2, sizeof(text)); + } else if (!strncmp(s->s_name, ".data", 5)) { + memcpy(&data, &s2, sizeof(data)); + data.s_size = (long)sbrk(0) - data.s_vaddr; + a2.dsize = data.s_size; + } else if (!strncmp(s->s_name, ".bss", 4)) { + memcpy(&bss, &s2, sizeof(bss)); + } + ++s; + } + write(fdout, &f2, sizeof(f2)); + write(fdout, &a2, sizeof(a2)); + write(fdout, &text, sizeof(text)); + write(fdout, &data, sizeof(data)); + write(fdout, &bss, sizeof(bss)); + for (i=0; i<f->f_nscns - 3; ++i) { + write(fdout, &zero, sizeof(zero)); + } + write(fdout, text.s_vaddr, text.s_size); + write(fdout, data.s_vaddr, data.s_size); + } + #ifdef TEST + main() + { + static int i; + + printf("%d\n", ++i); + unexec(); + exit(0); + } + #endif