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%
622516Sdist  */
75514Slinton 
822516Sdist #ifndef lint
9*62145Sbostic static char sccsid[] = "@(#)address.c	8.1 (Berkeley) 06/06/93";
1048095Sbostic #endif /* not lint */
115514Slinton 
125514Slinton /*
135514Slinton  * Some machine and runtime dependent manipulation of a symbol.
145514Slinton  */
155514Slinton 
165514Slinton #include "defs.h"
175514Slinton #include "runtime.h"
185514Slinton #include "sym.h"
195514Slinton #include "machine.h"
205514Slinton #include "process.h"
215514Slinton #include "object.h"
225514Slinton #include "mappings.h"
235514Slinton #include "sym/classes.h"
245514Slinton #include "frame.rep"
255514Slinton #include "sym/sym.rep"
265514Slinton 
275514Slinton /*
285514Slinton  * Calculate the address of a symbol.
295514Slinton  * If frame is not NIL, then it is the frame associated with the
305514Slinton  * activation in which the symbol we're interested in is defined.
315514Slinton  */
325514Slinton 
address(s,frame)335514Slinton ADDRESS address(s, frame)
345514Slinton register SYM *s;
355514Slinton FRAME *frame;
365514Slinton {
376082Slinton     SYM *f;
386082Slinton     FRAME *frp;
396082Slinton     ADDRESS r, *dp, *disp;
406082Slinton     short offs;
415514Slinton 
426082Slinton     f = s->func;
436082Slinton     if (s->class == FVAR) {
446082Slinton 	offs = f->symvalue.offset;
456082Slinton     } else {
466082Slinton 	offs = s->symvalue.offset;
476082Slinton     }
486082Slinton     if (f == program) {
496082Slinton 	r = (ADDRESS) dispval(MAINBLK) + offs;
506082Slinton     } else if (f == curfunc && frame == NIL) {
516082Slinton 	dp = curdp();
526082Slinton 	disp = contents(dp);
536082Slinton 	r = (ADDRESS) disp + offs;
546082Slinton     } else {
556082Slinton 	if (frame == NIL) {
566082Slinton 	    frp = findframe(s->func);
576082Slinton 	    if (frp == NIL) {
586082Slinton 		panic("address: findframe returned NIL");
596082Slinton 	    }
605514Slinton 	} else {
616082Slinton 	    frp = frame;
625514Slinton 	}
636082Slinton 	r = stkaddr(frp, s->blkno) + offs;
646082Slinton     }
656082Slinton     return r;
665514Slinton }
675514Slinton 
685514Slinton /*
695514Slinton  * The next three routines assume the procedure entry code is
705514Slinton  *
716082Slinton  *      f:  tra4    A
726082Slinton  *          ...
736082Slinton  *      A:  beg
746082Slinton  *      B:  <code for first line>
755514Slinton  *
765514Slinton  * Pi gives f, we compute and store A with "findbeginning(f)",
775514Slinton  * (retrieved by "codeloc(f)"), B is computed by "firstline(f)".
785514Slinton  *
795514Slinton  * The procedure "runtofirst" assumes you're at A and want to step to B.
805514Slinton  * It should be changed to a nop if A is equal to B.
815514Slinton  */
825514Slinton 
835514Slinton /*
845514Slinton  * Find the beginning of a procedure or function.  This is a destructive
855514Slinton  * routine, it changes the value associated with the procedure symbol.
865514Slinton  * Should only be called once per symbol.
875514Slinton  */
885514Slinton 
findbeginning(f)895514Slinton findbeginning(f)
905514Slinton SYM *f;
915514Slinton {
926082Slinton     f->symvalue.funcv.codeloc = nextaddr(f->symvalue.funcv.codeloc, FALSE);
935514Slinton }
945514Slinton 
955514Slinton /*
965514Slinton  * Find the object code associated with the first line of a block.
975514Slinton  */
985514Slinton 
firstline(f)995514Slinton ADDRESS firstline(f)
1005514Slinton SYM *f;
1015514Slinton {
1026082Slinton     ADDRESS addr;
1035514Slinton 
1046082Slinton     addr = codeloc(f);
1056082Slinton     while (linelookup(addr) == 0) {
1066082Slinton 	if (isendofproc(addr)) {
1076082Slinton 	    return -1;
1085514Slinton 	}
1096082Slinton 	addr = nextaddr(addr, FALSE);
1106082Slinton     }
1116082Slinton     return addr;
1125514Slinton }
1135514Slinton 
1145514Slinton /*
1155514Slinton  * Catcher drops strike three ...
1165514Slinton  */
1175514Slinton 
runtofirst()1185514Slinton runtofirst()
1195514Slinton {
1206082Slinton     stepto(firstline(curfunc));
1215514Slinton }
1225514Slinton 
1235514Slinton /*
1245514Slinton  * Calculate the address of the last line in the program.
1255514Slinton  * This is assumed to be at the physical end.
1265514Slinton  */
1275514Slinton 
lastaddr()1285514Slinton ADDRESS lastaddr()
1295514Slinton {
1306082Slinton     if (objsize == 0) {
1316082Slinton 	panic("lastaddr: objsize = 0!");
1326082Slinton     }
1336082Slinton     return(objsize - sizeof(short));
1345514Slinton }
135