148095Sbostic /*-
2*62145Sbostic  * Copyright (c) 1980, 1993
3*62145Sbostic  *	The Regents of the University of California.  All rights reserved.
448095Sbostic  *
548095Sbostic  * %sccs.include.redist.c%
622518Sdist  */
75516Slinton 
822518Sdist #ifndef lint
9*62145Sbostic static char sccsid[] = "@(#)entry.c	8.1 (Berkeley) 06/06/93";
1048095Sbostic #endif /* not lint */
1148095Sbostic 
125516Slinton /*
135516Slinton  * routines to deal with the entry addresses of blocks
145516Slinton  */
155516Slinton 
165516Slinton #include "defs.h"
175516Slinton #include "runtime.h"
185516Slinton #include "frame.rep"
195516Slinton #include "machine.h"
205516Slinton #include "process.h"
215516Slinton #include "sym.h"
225516Slinton #include "source.h"
235516Slinton #include "object.h"
245516Slinton #include "process/pxinfo.h"
255516Slinton #include "process/process.rep"
265516Slinton 
275516Slinton /*
285516Slinton  * Return the address of the beginning of the procedure/function
295516Slinton  * associated with the given frame.
305516Slinton  */
315516Slinton 
entry(frp)325516Slinton ADDRESS entry(frp)
335516Slinton register FRAME *frp;
345516Slinton {
355516Slinton 	return(frp->blockp - 2 - ENDOFF);
365516Slinton }
375516Slinton 
385516Slinton /*
395516Slinton  * Find the entry address of the caller of the current block.
405516Slinton  * This is only called in connection with breakpoints.
415516Slinton  *
425516Slinton  * This routine assumes it is at the very beginning of the block.
435516Slinton  */
445516Slinton 
caller_addr()455516Slinton ADDRESS caller_addr()
465516Slinton {
475516Slinton 	FRAME *frp;
485516Slinton 
495516Slinton 	if ((frp = curframe()) == NIL) {
505516Slinton 		panic("caller_addr(main program)");
515516Slinton 	}
525516Slinton 	frp = nextframe(frp);
535516Slinton 	if (frp == NIL) {
545516Slinton 		return(codeloc(program));
555516Slinton 	} else {
565516Slinton 		return(entry(frp));
575516Slinton 	}
585516Slinton }
595516Slinton 
605516Slinton /*
615516Slinton  * Find the return address of the current procedure/function.
625516Slinton  *
635516Slinton  * There are two special cases:
645516Slinton  *
655516Slinton  *	we're right at the beginning of the main program
665516Slinton  *	we're right at the beginning of some procedure or function
675516Slinton  *
685516Slinton  * The first one is handled by returning the last instruction in
695516Slinton  * the object code.  In the second case, we get the return address
705516Slinton  * directly from the process' stack.
715516Slinton  */
725516Slinton 
return_addr()735516Slinton ADDRESS return_addr()
745516Slinton {
755516Slinton 	ADDRESS addr;
765516Slinton 	FRAME *frp, frame;
775516Slinton 
785516Slinton 	if (pc == codeloc(program)) {
795516Slinton 		addr = lastaddr();
805516Slinton 	} else {
815516Slinton 		frp = curframe();
825516Slinton 		if (frp == NIL) {
835516Slinton 			dread(&frame, (ADDRESS) process->sp, sizeof(FRAME));
845516Slinton 			addr = frame.save_pc - ENDOFF;
855516Slinton 		} else {
865516Slinton 			addr = frp->save_pc;
875516Slinton 		}
885516Slinton 	}
895516Slinton 	return addr;
905516Slinton }
915516Slinton 
925516Slinton /*
935516Slinton  * Calculate the entry address for a procedure or function parameter,
945516Slinton  * given the address of the descriptor.
955516Slinton  */
965516Slinton 
fparamaddr(a)975516Slinton ADDRESS fparamaddr(a)
985516Slinton ADDRESS a;
995516Slinton {
1005516Slinton 	ADDRESS r;
1015516Slinton 
1025516Slinton 	dread(&r, a, sizeof(r));
1035516Slinton 	return (r - ENDOFF);
1045516Slinton }
105