[comp.lang.perl] dump for Apollos

vinoski@apollo.HP.COM (Stephen Vinoski) (07/26/90)

If you don't care about perl dump (perl -u) on Apollo Domain/OS, you
can ignore the rest of this message.



I've managed to get dumping working for Domain/OS.  I can't take much 
credit for the work, since most of it was taken from the GNU emacs
work Leonard Zubkoff has done for Apollo machines.  The following
information pertains to patchlevel 18:

1) You must completely rebuild perl using the -W0,-ncompress option to 
/bin/cc.  This will prevent the compiler from creating compressed data
sections in the object files, which are impossible to dump.

2) You must compile crt0.c and unexapollo.c.  These are provided in a
shar file below.

  cc -O -c -DAPOLLO -W0,-ncompress $(OTHER_CC_FLAGS) crt0.c
  cc -O -c -DAPOLLO -W0,-ncompress $(OTHER_CC_FLAGS) unexapollo.c

3) You must rebuild perly.c after applying the included patch.  Make
sure you use -DAPOLLO when compiling.

  cc -O -c -DAPOLLO -W0,-ncompress $(OTHER_CC_FLAGS) perly.c

4) You must also use the -YS,.  /bin/cc option so that it will use the
crt0.o startup function from the working directory (obtained in the
step above) instead of the /usr/lib/crt0.o startup function.  This is
necessary because the crt0.o that comes with the OS has a compressed
data section.  From my version of the Makefile:

perl: perl.o $(obj) crt0.o
	$(CC) -YS,. $(LARGE) $(LDFLAGS) $(obj) perl.o $(libs) -o perl

The "core" file produced in the working directory by "perl -u" is
ready to execute, no need for undump or anything like that.

These changes have been tested under sr10.2 and above on both PRISM
and Motorola machines.  Note that a correct image is dumped even if
the perl executable is a compound executable (cmpexe).

If you have any trouble, let me know.  One of these days when Larry
gets around to releasing metaconfig, I hope to make it do the right
thing for Domain/OS.


-steve

| Steve Vinoski  (508)256-6600 x5904       | Internet: vinoski@apollo.com     |
| Testability and Diagnostics              | UUCP: ...mit-eddie!apollo!vinoski|
| HP Apollo Division, Chelmsford, MA 01824 |       ...uw-beaver!apollo!vinoski|
| "A man's home is his coffin."   -Al Bundy                                   |


Patch for perly.c:

---- cut ---- cut ---- cut ---- cut ---- cut
*** perly.c.orig	Mon Jul 23 15:15:26 1990
--- perly.c	Tue Jul 24 13:02:23 1990
***************
*** 648,654 ****
--- 648,660 ----
      }
  
      if (do_undump)
+     {
+ #ifdef APOLLO
+         (void)sprintf(buf, "%s/perl", BIN);
+         unexec("./core", buf);
+ #endif
  	abort();
+     }
  
    just_doit:		/* come here if running an undumped a.out */
      argc--,argv++;	/* skip name of script */
---- cut ---- cut ---- cut ---- cut ---- cut


Shar file containing crt0.c and unexapollo.c:

#!/bin/sh
# This is a shell archive (shar 3.21)
# made 07/25/1990 19:24 UTC by vinoski@zep
# Source directory //zep/vinoski/src/perl/perl_orig
#
# existing files WILL be overwritten
#
# This shar contains:
# length  mode       name
# ------ ---------- ------------------------------------------
#  18191 -rwxrwxrwx crt0.c
#  11576 -rwxrwxrwx unexapollo.c
#
if touch 2>&1 | fgrep '[-amc]' > /dev/null
 then TOUCH=touch
 else TOUCH=true
fi
# ============= crt0.c ==============
echo "x - extracting crt0.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > crt0.c &&
X/*
X  Modified on 6-Jan-90 by Leonard N. Zubkoff:
X    Modified to work with Domain/OS SR10.2.
X*/
X
X/* C code startup routine.
X   Copyright (C) 1985, 1986 Free Software Foundation, Inc.
X
X		       NO WARRANTY
X
X  BECAUSE THIS PROGRAM IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY
XNO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW.  EXCEPT
XWHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC,
XRICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE THIS PROGRAM "AS IS"
XWITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
XBUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
XFITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY
XAND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE PROGRAM PROVE
XDEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
XCORRECTION.
X
X IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M.
XSTALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY
XWHO MAY MODIFY AND REDISTRIBUTE THIS PROGRAM AS PERMITTED BELOW, BE
XLIABLE TO YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR
XOTHER SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
XUSE OR INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR
XDATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR
XA FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) THIS
XPROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
XDAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.
X
X		GENERAL PUBLIC LICENSE TO COPY
X
X  1. You may copy and distribute verbatim copies of this source file
Xas you receive it, in any medium, provided that you conspicuously and
Xappropriately publish on each copy a valid copyright notice "Copyright
X(C) 1986 Free Software Foundation, Inc."; and include following the
Xcopyright notice a verbatim copy of the above disclaimer of warranty
Xand of this License.
X
X  2. You may modify your copy or copies of this source file or
Xany portion of it, and copy and distribute such modifications under
Xthe terms of Paragraph 1 above, provided that you also do the following:
X
X    a) cause the modified files to carry prominent notices stating
X    that you changed the files and the date of any change; and
X
X    b) cause the whole of any work that you distribute or publish,
X    that in whole or in part contains or is a derivative of this
X    program or any part thereof, to be licensed at no charge to all
X    third parties on terms identical to those contained in this
X    License Agreement (except that you may choose to grant more extensive
X    warranty protection to some or all third parties, at your option).
X
X    c) You may charge a distribution fee for the physical act of
X    transferring a copy, and you may at your option offer warranty
X    protection in exchange for a fee.
X
XMere aggregation of another unrelated program with this program (or its
Xderivative) on a volume of a storage or distribution medium does not bring
Xthe other program under the scope of these terms.
X
X  3. You may copy and distribute this program (or a portion or derivative
Xof it, under Paragraph 2) in object code or executable form under the terms
Xof Paragraphs 1 and 2 above provided that you also do one of the following:
X
X    a) accompany it with the complete corresponding machine-readable
X    source code, which must be distributed under the terms of
X    Paragraphs 1 and 2 above; or,
X
X    b) accompany it with a written offer, valid for at least three
X    years, to give any third party free (except for a nominal
X    shipping charge) a complete machine-readable copy of the
X    corresponding source code, to be distributed under the terms of
X    Paragraphs 1 and 2 above; or,
X
X    c) accompany it with the information you received as to where the
X    corresponding source code may be obtained.  (This alternative is
X    allowed only for noncommercial distribution and only if you
X    received the program in object code or executable form alone.)
X
XFor an executable file, complete source code means all the source code for
Xall modules it contains; but, as a special exception, it need not include
Xsource code for modules which are standard libraries that accompany the
Xoperating system on which the executable file runs.
X
X  4. You may not copy, sublicense, distribute or transfer this program
Xexcept as expressly provided under this License Agreement.  Any attempt
Xotherwise to copy, sublicense, distribute or transfer this program is void and
Xyour rights to use the program under this License agreement shall be
Xautomatically terminated.  However, parties who have received computer
Xsoftware programs from you with this License Agreement will not have
Xtheir licenses terminated so long as such parties remain in full compliance.
X
X  5. If you wish to incorporate parts of this program into other free
Xprograms whose distribution conditions are different, write to the Free
XSoftware Foundation at 675 Mass Ave, Cambridge, MA 02139.  We have not yet
Xworked out a simple rule that can be stated here, but we will often permit
Xthis.  We will be guided by the two goals of preserving the free status of
Xall derivatives of our free software and of promoting the sharing and reuse of
Xsoftware.
X
X
XIn other words, you are welcome to use, share and improve this program.
XYou are forbidden to forbid anyone else to use, share and improve
Xwhat you give them.   Help stamp out software-hoarding!  */
X
X
X/* The standard Vax 4.2 Unix crt0.c cannot be used for Emacs
X   because it makes `envron' an initialized variable.
X   It is easiest to have a special crt0.c on all machines
X   though I don't know whether other machines actually need it.  */
X
X/* On the vax and 68000, in BSD4.2 and USG5.2,
X   this is the data format on startup:
X  (vax) ap and fp are unpredictable as far as I know; don't use them.
X  sp ->  word containing argc
X         word pointing to first arg string
X	 [word pointing to next arg string]... 0 or more times
X	 0
XOptionally:
X	 [word pointing to environment variable]... 1 or more times
X	 ...
X	 0
XAnd always:
X	 first arg string
X	 [next arg string]... 0 or more times
X*/
X
X/* On the 16000, at least in the one 4.2 system I know about,
X  the initial data format is
X  sp ->  word containing argc
X         word containing argp
X         word pointing to first arg string, and so on as above
X*/
X
X#include "config.h"
X
X/*		********  WARNING ********
X    Do not insert any data definitions before data_start!
X    Since this is the first file linked, the address of the following
X    variable should correspond to the start of initialized data space.
X    On some systems this is a constant that is independent of the text
X    size for shared executables.  On others, it is a function of the
X    text size. In short, this seems to be the most portable way to
X    discover the start of initialized data space dynamically at runtime,
X    for either shared or unshared executables, on either swapping or
X    virtual systems.  It only requires that the linker allocate objects
X    in the order encountered, a reasonable model for most Unix systems.
X    Similarly, note that the address of _start() should be the start
X    of text space.   Fred Fish, UniSoft Systems Inc.  */
X
Xint data_start = 0;
X
X#ifdef NEED_ERRNO
Xint errno;
X#endif
X
X#ifndef DONT_NEED_ENVIRON
Xchar **environ;
X#endif
X
X#ifdef APOLLO
X/* Added by John Vasta, 19-Oct-89
X   Malloc, free, etc. are in shared libraries on the Apollo. Library references
X   to them are indirect so that they can be replaced by the user, just as if
X   they were statically linked. We set the pointer values here. (The regular
X   Apollo crt0.o file isn't used because it has a compressed data section which
X   interferes with the unexec process.) */
X
Xextern	char   *malloc(),      *(*_libc_malloc) ();
Xextern	void	free(),		(*_libc_free) ();
Xextern	char   *realloc(),     *(*_libc_realloc)();
X
Xextern	int	main();
Xstd_$call void	unix_$main();
X
X_start()
X{
X	_libc_malloc = malloc;
X	_libc_realloc = realloc;
X	_libc_free = free;
X
X	unix_$main(main);	/* no return */
X}
X#endif /* APOLLO */
X
X#if defined(orion) || defined(pyramid) || defined(celerity) || defined(ALLIANT) || defined(clipper)
X
X#ifdef ALLIANT
X/* _start must initialize _curbrk and _minbrk on the first startup;
X   when starting up after dumping, it must initialize them to what they were
X   before the dumping, since they are in the shared library and
X   are not dumped.  See ADJUST_EXEC_HEADER in m-alliant.h.  */
Xextern unsigned char *_curbrk, *_minbrk;
Xextern unsigned char end;
Xunsigned char *_setbrk = &end;
X#endif
X
X#ifndef DUMMIES
X#define DUMMIES
X#endif
X
X_start (DUMMIES argc, argv, envp)
X     int argc;
X     char **argv, **envp;
X{
X#ifdef ALLIANT
X  _curbrk = _setbrk;
X  _minbrk = _setbrk;
X#endif
X
X  environ = envp;
X
X  exit (main (argc, argv, envp));
X}
X
X#endif /* orion or pyramid or celerity or alliant or clipper */
X
X#if defined (ns16000) && !defined (sequent) && !defined (UMAX)
X
X_start ()
X{
X/* On 16000, _start pushes fp onto stack */
X  start1 ();
X}
X
X/* ignore takes care of skipping the fp value pushed in start.  */
Xstatic
Xstart1 (ignore, argc, argv)
X     int ignore;
X     int argc;
X     register char **argv;
X{
X  environ = argv + argc + 1;
X
X  if (environ == *argv)
X    environ--;
X  exit (main (argc, argv, environ));
X}
X#endif /* ns16000, not sequent and not UMAX */
X
X#ifdef UMAX
X_start()
X{
X	asm("	exit []			# undo enter");
X	asm("	.set	exitsc,1");
X	asm("	.set	sigcatchall,0x400");
X
X	asm("	.globl	_exit");
X	asm("	.globl	start");
X	asm("	.globl	__start");
X	asm("	.globl	_main");
X	asm("	.globl	_environ");
X	asm("	.globl	_sigvec");
X	asm("	.globl	sigentry");
X
X	asm("start:");
X	asm("	br	.xstart");
X	asm("	.org	0x20");
X	asm("	.double	p_glbl,0,0xf00000,0");
X	asm("	.org	0x30");
X	asm(".xstart:");
X	asm("	adjspb	$8");
X	asm("	movd	8(sp),0(sp)	# argc");
X	asm("	addr	12(sp),r0");
X	asm("	movd	r0,4(sp)	# argv");
X	asm("L1:");
X	asm("	movd	r0,r1");
X	asm("	addqd	$4,r0");
X	asm("	cmpqd	$0,0(r1)	# null args term ?");
X	asm("	bne	L1");
X	asm("	cmpd	r0,0(4(sp))	# end of 'env' or 'argv' ?");
X	asm("	blt	L2");
X	asm("	addqd	$-4,r0		# envp's are in list");
X	asm("L2:");
X	asm("	movd	r0,8(sp)	# env");
X	asm("	movd	r0,@_environ	# indir is 0 if no env ; not 0 if env");
X	asm("	movqd	$0,tos		# setup intermediate signal handler");
X	asm("	addr	@sv,tos");
X	asm("	movzwd	$sigcatchall,tos");
X	asm("	jsr	@_sigvec");
X	asm("	adjspb	$-12");
X	asm("	jsr	@_main");
X	asm("	adjspb	$-12");
X	asm("	movd	r0,tos");
X	asm("	jsr	@_exit");
X	asm("	adjspb	$-4");
X	asm("	addr	@exitsc,r0");
X	asm("	svc");
X	asm("	.align	4		# sigvec arg");
X	asm("sv:");
X	asm("	.double	sigentry");
X	asm("	.double	0");
X	asm("	.double	0");
X
X	asm("	.comm	p_glbl,1");
X}
X#endif /* UMAX */
X
X#ifdef CRT0_DUMMIES
X
X/* Define symbol "start": here; some systems want that symbol.  */
X#ifdef DOT_GLOBAL_START
Xasm("	.text		");
Xasm("	.globl start	");
Xasm("	start:		");
X#endif /* DOT_GLOBAL_START */
X
X#ifdef NODOT_GLOBAL_START
Xasm("	text		");
Xasm("	global start	");
Xasm("	start:		");
X#endif /* NODOT_GLOBAL_START */
X
X_start ()
X{
X/* On vax, nothing is pushed here  */
X/* On sequent, bogus fp is pushed here  */
X  start1 ();
X}
X
Xstatic
Xstart1 (CRT0_DUMMIES argc, xargv)
X     int argc;
X     char *xargv;
X{
X  register char **argv = &xargv;
X  environ = argv + argc + 1;
X
X  if ((char *)environ == xargv)
X    environ--;
X  exit (main (argc, argv, environ));
X}
X#else /* not CRT0_DUMMIES */
X
X/* "m68k" and "m68000" both stand for m68000 processors,
X   but with different program-entry conventions.
X   This is a kludge.  Now that the CRT0_DUMMIES mechanism above exists,
X   most of these machines could use the vax code above
X   with some suitable definition of CRT0_DUMMIES.
X   Then the symbol m68k could be flushed.
X   But I don't want to risk breaking these machines
X   in a version 17 patch release, so that change is being put off.  */
X
X#ifdef m68k			/* Can't do it all from C */
X	asm ("	global	_start");
X	asm ("	text");
X	asm ("_start:");
X#ifndef NU
X#ifdef STRIDE
X	asm ("	comm	havefpu%,2");
X#else /* m68k, not STRIDE */
X	asm ("  comm	splimit%,4");
X#endif /* STRIDE */
X	asm ("	global	exit");
X	asm ("	text");
X#ifdef STRIDE
X	asm ("	trap	&3");
X	asm ("	mov.w	%d0,havefpu%");
X#else /* m68k, not STRIDE */
X  	asm ("	mov.l	%d0,splimit%");
X#endif /* STRIDE */
X#endif /* not NU */
X	asm ("	jsr	start1");
X	asm ("	mov.l	%d0,(%sp)");
X	asm ("	jsr	exit");
X	asm ("	mov.l	&1,%d0");	/* d0 = 1 => exit */
X	asm ("	trap	&0");
X#else /* m68000, not m68k */
X
X#ifdef m68000
X
X#ifdef ISI68K
X/* Added by ESM Sun May 24 12:44:02 1987 to get new ISI library to work */
X#ifdef BSD4_3
Xstatic foo () {
X#endif
X	asm ("	.globl  is68020");
X	asm ("is68020:");
X#ifndef BSD4_3
X	asm ("	.long   0x00000000");
X	asm ("	.long   0xffffffff");
X/* End of stuff added by ESM */
X#endif
X	asm ("	.text");
X	asm ("	.globl	__start");
X	asm ("__start:");
X	asm ("	.word 0");
X	asm ("	link	fp,#0");
X	asm ("	jbsr	_start1");
X	asm ("	unlk	fp");
X	asm ("	rts");
X#ifdef BSD4_3
X      }
X#endif
X#else /* not ISI68K */
X
X_start ()
X{
X/* On 68000, _start pushes a6 onto stack  */
X  start1 ();
X}
X#endif /* not ISI68k */
X#endif /* m68000 */
X#endif /* m68k */
X
X#if defined(m68k) || defined(m68000)
X/* ignore takes care of skipping the a6 value pushed in start.  */
Xstatic
X#if defined(m68k)
Xstart1 (argc, xargv)
X#else
Xstart1 (ignore, argc, xargv)
X#endif
X     int argc;
X     char *xargv;
X{
X  register char **argv = &xargv;
X  environ = argv + argc + 1;
X
X  if ((char *)environ == xargv)
X    environ--;
X  exit (main (argc, argv, environ));
X}
X
X#endif /* m68k or m68000 */
X
X#endif /* not CRT0_DUMMIES */
X
X#ifdef hp9000s300
Xint argc_value;
Xchar **argv_value;
X#ifdef OLD_HP_ASSEMBLER
X	asm("   text");
X	asm("	globl __start");
X	asm("	globl _exit");
X	asm("	globl _main");
X	asm("__start");
X	asm("	dc.l	0");
X	asm("	subq.w	#0x1,d0");
X	asm("	move.w	d0,float_soft");
X	asm("	move.l	0x4(a7),d0");
X	asm("	beq.s	skip_1");
X	asm("	move.l	d0,a0");
X	asm("	clr.l	-0x4(a0)");
X	asm("skip_1");
X	asm("	move.l	a7,a0");
X	asm("	subq.l	#0x8,a7");
X	asm("	move.l	(a0),(a7)");
X	asm("	move.l	(a0),_argc_value");
X	asm("	addq.l	#0x4,a0");
X	asm("	move.l	a0,0x4(a7)");
X	asm("	move.l	a0,_argv_value");
X	asm("incr_loop");
X	asm("	tst.l	(a0)+");
X	asm("	bne.s	incr_loop");
X	asm("	move.l	0x4(a7),a1");
X	asm("	cmp.l	(a1),a0");
X	asm("	blt.s	skip_2");
X	asm("	subq.l	#0x4,a0");
X	asm("skip_2");
X	asm("	move.l	a0,0x8(a7)");
X	asm("	move.l	a0,_environ");
X	asm("	jsr	_main");
X	asm("	addq.l	#0x8,a7");
X	asm("	move.l	d0,-(a7)");
X	asm("	jsr	_exit");
X	asm("	move.w	#0x1,d0");
X	asm("	trap	#0x0");
X	asm("	comm	float_soft,4");
X/* float_soft is allocated in this way because C would
X   put an underscore character in its name otherwise. */
X
X#else /* new hp assembler */
X
X	asm("	text");
X        asm("   global  float_loc");
X        asm("   set     float_loc,0xFFFFB000");
X 	asm("	global	fpa_loc");
X	asm("	set	fpa_loc,0xfff08000");
X	asm("	global	__start");
X	asm("	global	_exit");
X	asm("	global	_main");
X	asm("__start:");
X	asm("	byte	0,0,0,0");
X	asm("	subq.w	&1,%d0");
X	asm("	mov.w	%d0,float_soft");
X	asm("	mov.w	%d1,flag_68881");
X#ifndef HPUX_68010
X	asm("	beq.b	skip_float");
X	asm("	fmov.l	&0x7400,%fpcr");
X/*	asm("	fmov.l	&0x7480,%fpcr"); */
X#endif /* HPUX_68010 */
X	asm("skip_float:");
X	asm("	mov.l	%a0,%d0");
X	asm("	add.l	%d0,%d0");
X	asm("	subx.w	%d1,%d1");
X	asm("	mov.w	%d1,flag_68010");
X	asm("	add.l	%d0,%d0");
X	asm("	subx.w	%d1,%d1");
X	asm("	mov.w	%d1,flag_fpa");
X	asm("	mov.l	4(%a7),%d0");
X	asm("	beq.b	skip_1");
X	asm("	mov.l	%d0,%a0");
X	asm("	clr.l	-4(%a0)");
X	asm("skip_1:");
X	asm("	mov.l	%a7,%a0");
X	asm("	subq.l	&8,%a7");
X	asm("	mov.l	(%a0),(%a7)");
X	asm("	mov.l	(%a0),_argc_value");
X	asm("	addq.l	&4,%a0");
X	asm("	mov.l	%a0,4(%a7)");
X	asm("	mov.l	%a0,_argv_value");
X	asm("incr_loop:");
X	asm("	tst.l	(%a0)+");
X	asm("	bne.b	incr_loop");
X	asm("	mov.l	4(%a7),%a1");
X	asm("	cmp.l	%a0,(%a1)");
X	asm("	blt.b	skip_2");
X	asm("	subq.l	&4,%a0");
X	asm("skip_2:");
X	asm("	mov.l	%a0,8(%a7)");
X	asm("	mov.l	%a0,_environ");
X	asm("	jsr	_main");
X	asm("	addq.l	&8,%a7");
X	asm("	mov.l	%d0,-(%a7)");
X	asm("	jsr	_exit");
X	asm("	mov.w	&1,%d0");
X	asm("	trap	&0");
X	asm("	comm	float_soft, 4");
X	asm("	comm	flag_68881, 4");
X	asm("	comm	flag_68010, 4");
X	asm("	comm	flag_fpa, 4");
X
X#endif /* new hp assembler */
X#endif /* hp9000s300 */
X
X#ifdef GOULD
X
X/* startup code has to be in near text rather
X   than fartext as allocated by the C compiler. */
X	asm("	.text");
X	asm("	.align	2");
X	asm("	.globl	__start");
X	asm("	.text");
X	asm("__start:");
X/* setup base register b1 (function base). */
X	asm("	.using	b1,.");
X	asm("	tpcbr	b1");
X/* setup base registers b3 through b7 (data references). */
X	asm("	file	basevals,b3");
X/* setup base register b2 (stack pointer); it should be
X   aligned on a 8-word boundary; but because it is pointing
X   to argc, its value should be remembered (in r5). */
X	asm("	movw	b2,r4");
X	asm("	movw	b2,r5");
X	asm("	andw	#~0x1f,r4");
X	asm("	movw	r4,b2");
X/* allocate stack frame to do some work. */
X	asm("	subea	16w,b2");
X/* initialize signal catching for UTX/32 1.2; this is
X   necessary to make restart from saved image work. */
X	asm("	movea	sigcatch,r1");
X	asm("	movw	r1,8w[b2]");
X	asm("	svc	#1,#150");
X/* setup address of argc for start1. */
X	asm("	movw	r5,8w[b2]");
X	asm("   func	#1,_start1");
X	asm("	halt");
X/* space for ld to store base register initial values. */
X	asm("	.align	5");
X	asm("basevals:");
X	asm("	.word	__base3,__base4,__base5,__base6,__base7");
X
Xstatic
Xstart1 (xargc)
X     int *xargc;
X{
X  register int	argc;
X  register char **argv;
X
X  argc = *xargc;
X  argv = (char **)(xargc) + 1;
X  environ = argv + argc + 1;
X
X  if (environ == argv)
X    environ--;
X  exit (main (argc, argv, environ));
X
X}
X
X#endif /* GOULD */
X
X#ifdef elxsi
Xextern int errno;
Xextern char **environ;
X
X_start()
X{
X  register int r;
X
X  errno = 0;
X  environ = *(&environ + 8);
X  _stdinit();
X  r = main(*(&environ + 6), *(&environ + 7), environ);
X  exit(r);
X  _exit(r);
X}
X#endif /* elxsi */
X
X
X#ifdef sparc
Xasm (".global __start");
Xasm (".text");
Xasm ("__start:");
Xasm ("	mov	0, %fp");
Xasm ("	ld	[%sp + 64], %o0");
Xasm ("	add	%sp, 68, %o1");
Xasm ("	sll	%o0, 2,	%o2");
Xasm ("	add	%o2, 4,	%o2");
Xasm ("	add	%o1, %o2, %o2");
Xasm ("	sethi	%hi(_environ), %o3");
Xasm ("	st	%o2, [%o3+%lo(_environ)]");
Xasm ("	andn	%sp, 7,	%sp");
Xasm ("	call	_main");
Xasm ("	sub	%sp, 24, %sp");
Xasm ("	call	__exit");
Xasm ("	nop");
X
X#endif /* sparc */
SHAR_EOF
$TOUCH -am 0724105290 crt0.c &&
chmod 0777 crt0.c ||
echo "restore of crt0.c failed"
set `wc -c crt0.c`;Wc_c=$1
if test "$Wc_c" != "18191"; then
	echo original size 18191, current size $Wc_c
fi
# ============= unexapollo.c ==============
echo "x - extracting unexapollo.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > unexapollo.c &&
X/*	UNEXAPOLLO -- COFF File UNEXEC for GNU Emacs on Apollo SR10.2	     */
X/*									     */
X/*	Copyright (C) 1988 by Leonard N. Zubkoff, All Rights Reserved	     */
X/*									     */
X/*	This software is provided free and without any warranty.	     */
X/*	Permission to copy for any purpose is hereby granted so		     */
X/*	long as this copyright notice remains intact.			     */
X/*									     */
X/*	Revision:	 4-Jan-90 12:33:26				     */
X/*									     */
X/*	Modified 25-Jun-90  vinoski@apollo.hp.com			     */
X/*	    augmented for perl dumping, handles compound executables	     */
X
X
X#define begin	    {
X#define end	    }
X#define then
X#define do
X#define hidden	    static
X#define visible
X#define procedure   void
X
X
X#include "config.h"
X#include <fcntl.h>
X
X
X#include <stdio.h>
X#include <a.out.h>
X#include <sys/file.h>
X#include <apollo/base.h>
X#include <apollo/ios.h>
X#include <apollo/type_uids.h>
X#include <apollo/dst.h>
X#include <apollo/sys/cmpexe.h>
X
X
X#define DST_RECORD_HDR_SIZE	2
X
Xhidden procedure error(char *);
X
Xvisible procedure unexec(char *TargetFileName,
X			 char *SourceFileName)
X    begin
X	struct filehdr FileHeader;
X	struct aouthdr DomainHeader;
X	struct scnhdr *Section, *Sections, *SectionsLimit;
X	struct scnhdr *DataSection, *RwdiSection, *BlocksSection;
X	struct reloc RelocEntry;
X	unsigned long DataSize, SourceFileOffsetPastRwdi;
X	unsigned char Buffer[4096];
X	long Delta, ByteCount, FirstChangedVaddr, i;
X	ios_$id_t TargetFile, SourceFile;
X	status_$t Status;
X	unsigned long OffsetToImage = 0, ImageSize = 0;
X	char *tag_name;
X	extern char *getenv(char *);
X	/* See if we're dealing with a cmpexe */
X	if (tag_name = getenv("ISP")) then
X	    begin
X		uid_$t type_uid;
X		cmpexe_$find_by_tag(SourceFileName,
X				    strlen(SourceFileName),
X				    tag_name,
X				    strlen(tag_name),
X				    &OffsetToImage,
X				    &ImageSize,
X				    &type_uid,
X				    &Status);
X		if (Status.all == cmpexe_$bad_format)
X		    begin
X			OffsetToImage = 0;
X			ImageSize = 0;
X		    end;
X	    end;
X	/* Open the Source File. */
X	if ((SourceFile = open(SourceFileName,O_RDONLY)) < 0) then
X	    error("cannot open source file for input");
X	/* Seek to the image we want */
X	if (lseek(SourceFile, OffsetToImage, L_SET) == -1)
X	    error("cannot seek to cmpexe image");
X	/* Read the File Header. */
X	if (read(SourceFile,&FileHeader,sizeof(FileHeader))
X		!= sizeof(FileHeader)) then
X	    error("cannot read file header");
X
X	/* Read the Domain Header. */
X	if (read(SourceFile,&DomainHeader,sizeof(DomainHeader))
X		!= sizeof(DomainHeader)) then
X	    error("cannot read domain header");
X	/* Read the Section Headers. */
X	Sections = (struct scnhdr *) malloc(FileHeader.f_nscns
X					    *sizeof(struct scnhdr));
X	if (Sections == (struct scnhdr *) 0) then
X	    error("cannot allocate section header storage");
X	SectionsLimit = Sections+FileHeader.f_nscns;
X	if (read(SourceFile,Sections,FileHeader.f_nscns*sizeof(struct scnhdr))
X		!= FileHeader.f_nscns*sizeof(struct scnhdr)) then
X	    error("cannot read section headers");
X	/* Compute the new Size of the Data Section. */
X	DataSize = sbrk(0)-DomainHeader.data_start;
X	/* Find and Deallocate the .rwdi Section Information. */
X	for (RwdiSection=Sections;
X	     RwdiSection != SectionsLimit; RwdiSection++) do
X		if (strcmp(RwdiSection->s_name,".rwdi") == 0) then
X		    begin
X			/* If there are relocation entries, we
X			   cannot "unrelocate" them. */
X			if (RwdiSection->s_nreloc)
X			    error (".rwdi section needs relocation - cannot dump");
X			Delta = DataSize-DomainHeader.dsize
X					-RwdiSection->s_size;
X			RwdiSection->s_paddr = 0;
X			RwdiSection->s_vaddr = 0;
X			RwdiSection->s_scnptr = 0;
X			RwdiSection->s_size = 0;
X			SourceFileOffsetPastRwdi = (RwdiSection+1)->s_scnptr;
X			break;
X		    end;
X	/* Skip over the Text Section Headers. */
X	for (Section=Sections;
X	     (Section->s_flags & STYP_TEXT) != 0; Section++) do ;
X	/* Increment the Relocation Pointers in Data Section Headers. */
X	for (; Section != SectionsLimit; Section++) do
X	    if ((Section->s_flags & STYP_DATA) != 0) then
X		begin
X		    DataSection = Section;
X		    DataSection->s_relptr += Delta;
X		end;
X	/* Increment the Size of the Last Data Section. */
X	DataSection->s_size += DataSize-DomainHeader.dsize;
X	/* Update the File Header and Domain Header. */
X	FileHeader.f_symptr += Delta;
X	DomainHeader.dsize = DataSize;
X	DomainHeader.bsize = 0;
X	DomainHeader.o_sri += Delta;
X	DomainHeader.o_inlib += Delta;
X
X	/* Skip over subsequent Bss Section Headers. */
X	for (Section=DataSection+1;
X	     (Section->s_flags & STYP_BSS) != 0; Section++) do ;
X	/* Update the remaining Section Headers. */
X	BlocksSection = (struct scnhdr *) 0;
X	FirstChangedVaddr = 0;
X	for (; Section != SectionsLimit; Section++) do
X	    begin
X		if (Section->s_paddr != 0) then
X		    Section->s_paddr += Delta;
X		if (Section->s_vaddr != 0) then
X		    begin
X			if (FirstChangedVaddr == 0) then
X			    FirstChangedVaddr = Section->s_vaddr;
X			Section->s_vaddr += Delta;
X		    end;
X		if (Section->s_scnptr != 0) then
X		    Section->s_scnptr += Delta;
X		if (strcmp (Section->s_name, ".blocks") == 0) then
X		    BlocksSection = Section;
X	    end;
X	/* Open the Target File. */
X	ios_$create(TargetFileName,strlen(TargetFileName),coff_$uid,
X		    ios_$recreate_mode,ios_$write_opt,&TargetFile,&Status);
X	if (Status.all != status_$ok) then
X	    error("cannot open target file for output");
X	/* Write the File Header. */
X	if (write(TargetFile,&FileHeader,sizeof(FileHeader))
X		!= sizeof(FileHeader)) then
X	    error("cannot write file header");
X	/* Write the Domain Header. */
X	if (write(TargetFile,&DomainHeader,sizeof(DomainHeader))
X		!= sizeof(DomainHeader)) then
X	    error("cannot write domain header");
X	/* Write the Section Headers. */
X	if (write(TargetFile,Sections,FileHeader.f_nscns*sizeof(struct scnhdr))
X		!= FileHeader.f_nscns*sizeof(struct scnhdr)) then
X	    error("cannot write section headers");
X	/* Copy the Allocated Sections. */
X	for (Section=Sections; Section != DataSection; Section++) do
X	    if (Section->s_scnptr != 0) then
X		CopyData(TargetFile,SourceFile,Section->s_size);
X	/* Write the Expanded Data Segment. */
X	if (write(TargetFile,DataSection->s_vaddr,
X		  DataSection->s_size) != DataSection->s_size) then
X	    error("cannot write new data section");
X	/* Skip over the Last Data Section and Copy until the .rwdi Section. */
X	if (lseek(SourceFile,DataSection->s_scnptr
X			     +OffsetToImage
X			     +DataSection->s_size,L_SET) == -1) then
X	    error("cannot seek past data section");
X	for (Section=DataSection+1; Section != RwdiSection; Section++) do
X	    if (Section->s_scnptr != 0) then
X		CopyData(TargetFile,SourceFile,Section->s_size);
X	/* Skip over the .rwdi Section and Copy Remainder of Source File. */
X	if (lseek(SourceFile,SourceFileOffsetPastRwdi
X			     +OffsetToImage,L_SET) == -1) then
X	    error("cannot seek past .rwdi section");
X	if (ImageSize) then
X	    begin
X		long cur_pos;
X		if ((cur_pos = lseek(SourceFile, 0, L_INCR)) == -1) then
X		    error("cannot find file pointer position");
X		cur_pos -= OffsetToImage;
X		while (cur_pos < ImageSize) do
X		    begin
X			unsigned long bufsize;
X			if ((ImageSize - cur_pos) > sizeof(Buffer)) then
X			    bufsize = sizeof(Buffer);
X			else
X			    bufsize = ImageSize - cur_pos;
X			if ((ByteCount = read(SourceFile,
X					      Buffer,
X					      bufsize)) != bufsize) then
X			    error("cannot read source file");
X			if (write(TargetFile,Buffer,bufsize) != bufsize) then
X			    error("cannot write data");
X			cur_pos += bufsize;
X		    end;
X	    end
X	else
X	    while ((ByteCount = read(SourceFile,Buffer,sizeof(Buffer))) > 0) do
X		if (write(TargetFile,Buffer,ByteCount) != ByteCount) then
X		    error("cannot write data");
X
X	/* Unrelocate .data references to Global Symbols. */
X	for (i=0; i<DataSection->s_nreloc; i++) do
X	    begin
X		if (lseek(SourceFile,DataSection->s_relptr
X				     +OffsetToImage
X				     +i*sizeof(struct reloc)-Delta,
X			  L_SET) == -1) then
X		    error("cannot seek to relocation info");
X		if (read(SourceFile,&RelocEntry,sizeof(RelocEntry))
X			!= sizeof(RelocEntry)) then
X		    error("cannot read reloc entry");
X		if (lseek(SourceFile,RelocEntry.r_vaddr-DataSection->s_vaddr
X				     +OffsetToImage
X				     +DataSection->s_scnptr,L_SET) == -1) then
X		    error("cannot seek to data element");
X		if (lseek(TargetFile,RelocEntry.r_vaddr-DataSection->s_vaddr
X				     +DataSection->s_scnptr,L_SET) == -1) then
X		    error("cannot seek to data element");
X		if (read(SourceFile,Buffer,4) != 4) then
X		    error("cannot read data element");
X		if (write(TargetFile,Buffer,4) != 4) then
X		    error("cannot write data element");
X	    end;
X	/* Correct virtual addresses in .blocks section. */
X	if (BlocksSection != (struct scnhdr *) 0) then
X	    begin
X		dst_rec_t DstRecord;
X		dst_rec_comp_unit_t *CompUnit;
X		unsigned short NumberOfSections;
X		unsigned long SectionBase;
X		unsigned long SectionOffset = 0;
X		/* Find section tables and update section base addresses. */
X		while (SectionOffset < BlocksSection->s_size) do
X		    begin
X			if (lseek(TargetFile,
X				  BlocksSection->s_scnptr+SectionOffset,
X				  L_SET) == -1) then
X			    error ("cannot seek to comp unit record");
X			/* Handle pad records before the comp unit record. */
X			if (read(TargetFile,&DstRecord,DST_RECORD_HDR_SIZE)
X				!= DST_RECORD_HDR_SIZE) then
X			    error("cannot read dst record tag");
X			if (DstRecord.rec_type == dst_typ_pad) then
X			    SectionOffset += DST_RECORD_HDR_SIZE;
X			else if (DstRecord.rec_type == dst_typ_comp_unit) then
X			    begin
X				CompUnit = &DstRecord.rec_data.comp_unit_;
X				if (read(TargetFile,CompUnit,sizeof(*CompUnit))
X					!= sizeof (*CompUnit)) then
X				    error("cannot read comp unit record");
X				if (lseek(TargetFile,BlocksSection->s_scnptr
X						     +SectionOffset
X						     +CompUnit->section_table
X						     +DST_RECORD_HDR_SIZE,
X					  L_SET) == -1) then
X				    error ("cannot seek to section table");
X
X				if (read(TargetFile,&NumberOfSections,
X					 sizeof(NumberOfSections))
X					!= sizeof(NumberOfSections)) then
X				    error("cannot read section table size");
X				for (i=0; i<NumberOfSections; i++) do
X				    begin
X					if (read(TargetFile,&SectionBase,
X						 sizeof(SectionBase))
X						!= sizeof(SectionBase)) then
X					    error("cannot read section \
X						   base value");
X					if (SectionBase < FirstChangedVaddr)
X					    then continue;
X					SectionBase += Delta;
X					if (lseek(TargetFile,
X						  -sizeof(SectionBase),
X						  L_INCR) == -1) then
X					    error("cannot seek to \
X						   section base value");
X					if (write(TargetFile,&SectionBase,
X						  sizeof(SectionBase))
X						!= sizeof(SectionBase)) then
X					    error("cannot write section base");
X				    end;
X				SectionOffset += CompUnit->data_size;
X			    end
X			else error("unexpected dst record type");
X		    end;
X	    end;
X	if (close(SourceFile) == -1) then
X	    error("cannot close source file");
X	if (close(TargetFile) == -1) then
X	    error("cannot close target file");
X    end
X
X
Xhidden CopyData(int TargetFile,
X		int SourceFile,
X		long TotalByteCount)
X    begin
X	unsigned char Buffer[4096];
X	long ByteCount;
X	while (TotalByteCount > 0) do
X	    begin
X		if (TotalByteCount > sizeof(Buffer)) then
X		    ByteCount = sizeof(Buffer);
X		else ByteCount = TotalByteCount;
X		if (read(SourceFile,Buffer,ByteCount) != ByteCount) then
X		    error("cannot read data");
X		if (write(TargetFile,Buffer,ByteCount) != ByteCount) then
X		    error("cannot write data");
X		TotalByteCount -= ByteCount;
X	    end;
X    end
X
X
Xhidden procedure error(char *errmsg)
X    begin
X	fprintf(stderr, "%s\n", errmsg);
X	exit(1);
X    end
SHAR_EOF
$TOUCH -am 0725152390 unexapollo.c &&
chmod 0777 unexapollo.c ||
echo "restore of unexapollo.c failed"
set `wc -c unexapollo.c`;Wc_c=$1
if test "$Wc_c" != "11576"; then
	echo original size 11576, current size $Wc_c
fi
exit 0
| Steve Vinoski  (508)256-6600 x5904       | Internet: vinoski@apollo.com     |
| Testability and Diagnostics              | UUCP: ...mit-eddie!apollo!vinoski|
| HP Apollo Division, Chelmsford, MA 01824 |       ...uw-beaver!apollo!vinoski|
| "A man's home is his coffin."   -Al Bundy                                   |

tchrist@convex.COM (Tom Christiansen) (07/26/90)

In article <4bce85bf.20b6d@apollo.HP.COM> vinoski@apollo.HP.COM (Stephen Vinoski) writes:
> I've managed to get dumping working for Domain/OS.  I can't take much 
> credit for the work, since most of it was taken from the GNU emacs
> work Leonard Zubkoff has done for Apollo machines.  The following
> information pertains to patchlevel 18:

....

> The "core" file produced in the working directory by "perl -u" is
> ready to execute, no need for undump or anything like that.

This is essentially what I've done for the Convex as well, and is
the version we'll be shipping to customers.

--tom
--

    Tom Christiansen                       {uunet,uiucdcs,sun}!convex!tchrist 
    Convex Computer Corporation                            tchrist@convex.COM
		 "EMACS belongs in <sys/errno.h>: Editor too big!"