[comp.lang.perl] unexec patches for 3B2

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