Path: utzoo!utgpu!water!watmath!clyde!att!osu-cis!tut.cis.ohio-state.edu!mailrus!uwmcsd1!marque!uunet!cme-durer!libes
From: libes@cme-durer.ARPA (Don Libes)
Newsgroups: comp.unix.questions
Subject: Re: Core files ... it works
Keywords: core data bss XINU
Message-ID: <496@muffin.cme-durer.ARPA>
Date: 3 Jul 88 17:00:18 GMT
References: <344@ajpo.sei.cmu.edu> <441@anagld.UUCP> <790@scubed.UUCP> <11954@mimsy.UUCP> <796@scubed.UUCP> <537@philmds.UUCP> <797@scubed.UUCP> <6053@megaron.arizona.edu>
Reply-To: libes@muffin (Don Libes)
Organization: National Bureau of Standards, Gaithersburg, MD
Lines: 69

In article <6053@megaron.arizona.edu> laidbak!lm@sun.com writes:
>In article <797@scubed.UUCP> warner@scubed.UUCP (Ken Warner) writes:
>>The next thing I want to do is save the stack and registers at a particular, 
>>known state and restore the stack and registers on start-up.  
>>
>>How can one get the contents of the registers, including the pc, fp and sp
>>registers?  How can these be restored?
>
>I had to do this for a thread library that I wrote for the Vax (Mt Xinu, 4.3).
>I've attached the code below.  You should be able to see how to do what you want
>from this code (on a vax).   If you do get a Sun version working I'd like a
>copy...

Here's how to restore all the registers on a Sun.  This is extracted
from code I wrote to get XINU running on top of UNIX.  This was
written up as part of a larger article on XINU in the July/August '87
;login:.  The code to save the registers is a little easier.  If you want
the whole XINU package, you can get anonymous ftp it from cme-durer.arpa.
It's called xinu.shar.Z.  Source is only 16Kb (compressed).

You can think of XINU as a thread library if you like.

static int *new_sp;		/* new stack pointer register to be loaded */
static int (*new_pc)();		/* new program counter register to be loaded */
static int new_signal_mask;	/* new signal mask to be loaded */

int restore()
{
	register struct pentry *nptr;	/* pointer to new process entry */

	.
	.  a lot of stuff omitted here 
	.

	/* at this point, nptr->pregs = a4@ */
	/* you may have to modify the following assembler if this is */
	/* not the case */

	/* restart the new process */

	/* prepare pc, sp and interrupt mask for rte() to use */
	new_sp = nptr->sp;	/* movl a4@(60),_new_sp */
	new_pc = nptr->pc;	/* movl a4@(64),_new_pc */
	new_signal_mask = nptr->signal_mask;
	/* load rest of registers directly except for a7 (sp) */
	asm("moveml	a4@,#0xfff");		/* d0-d7,a0-a3 */
	asm("movl	a4@(56),a6");		/* restore a6 */
	asm("movl	a4@(52),a5");		/* restore a5 */
	asm("movl	a4@(48),a4");		/* restore a4 */

	kill(getpid(),RTE);	/* this is caught by rte() below */
}

/* This routine is necessary to load the signal mask at the same time as */
/* we load the new pc and sp. */
/* ARGSUSED */
static void rte(sig,code,scp)
int sig;
int code;
struct sigcontext *scp;
{
	scp->sc_sp = (int)new_sp;
	scp->sc_pc = (int)new_pc;
	scp->sc_mask = new_signal_mask;

	/* No need to reload ps, as no one looks at it anyway, upon return. */
}

Don Libes          cme-durer.arpa      ...!uunet!cme-durer!libes