1*5514Slinton /* Copyright (c) 1982 Regents of the University of California */
2*5514Slinton 
3*5514Slinton static char sccsid[] = "@(#)address.c 1.1 01/18/82";
4*5514Slinton 
5*5514Slinton /*
6*5514Slinton  * Some machine and runtime dependent manipulation of a symbol.
7*5514Slinton  */
8*5514Slinton 
9*5514Slinton #include "defs.h"
10*5514Slinton #include "runtime.h"
11*5514Slinton #include "sym.h"
12*5514Slinton #include "machine.h"
13*5514Slinton #include "process.h"
14*5514Slinton #include "object.h"
15*5514Slinton #include "mappings.h"
16*5514Slinton #include "sym/classes.h"
17*5514Slinton #include "frame.rep"
18*5514Slinton #include "sym/sym.rep"
19*5514Slinton 
20*5514Slinton /*
21*5514Slinton  * Calculate the address of a symbol.
22*5514Slinton  * If frame is not NIL, then it is the frame associated with the
23*5514Slinton  * activation in which the symbol we're interested in is defined.
24*5514Slinton  */
25*5514Slinton 
26*5514Slinton ADDRESS address(s, frame)
27*5514Slinton register SYM *s;
28*5514Slinton FRAME *frame;
29*5514Slinton {
30*5514Slinton 	SYM *f;
31*5514Slinton 	FRAME *frp;
32*5514Slinton 	ADDRESS r, *dp, *disp;
33*5514Slinton 	short offs;
34*5514Slinton 
35*5514Slinton 	f = s->func;
36*5514Slinton 	if (s->class == FVAR) {
37*5514Slinton 		offs = f->symvalue.offset;
38*5514Slinton 	} else {
39*5514Slinton 		offs = s->symvalue.offset;
40*5514Slinton 	}
41*5514Slinton 	if (f == program) {
42*5514Slinton 		r = (ADDRESS) dispval(MAINBLK) + offs;
43*5514Slinton 	} else if (f == curfunc && frame == NIL) {
44*5514Slinton 		dp = curdp();
45*5514Slinton 		disp = contents(dp);
46*5514Slinton 		r = (ADDRESS) disp + offs;
47*5514Slinton 	} else {
48*5514Slinton 		if (frame == NIL) {
49*5514Slinton 			frp = findframe(s->func);
50*5514Slinton 			if (frp == NIL) {
51*5514Slinton 				panic("address: findframe returned NIL");
52*5514Slinton 			}
53*5514Slinton 		} else {
54*5514Slinton 			frp = frame;
55*5514Slinton 		}
56*5514Slinton 		r = stkaddr(frp, s->blkno) + offs;
57*5514Slinton 	}
58*5514Slinton 	return r;
59*5514Slinton }
60*5514Slinton 
61*5514Slinton /*
62*5514Slinton  * The next three routines assume the procedure entry code is
63*5514Slinton  *
64*5514Slinton  *		f:	tra4	A
65*5514Slinton  *			...
66*5514Slinton  *		A:	beg
67*5514Slinton  *		B:	<code for first line>
68*5514Slinton  *
69*5514Slinton  * Pi gives f, we compute and store A with "findbeginning(f)",
70*5514Slinton  * (retrieved by "codeloc(f)"), B is computed by "firstline(f)".
71*5514Slinton  *
72*5514Slinton  * The procedure "runtofirst" assumes you're at A and want to step to B.
73*5514Slinton  * It should be changed to a nop if A is equal to B.
74*5514Slinton  */
75*5514Slinton 
76*5514Slinton /*
77*5514Slinton  * Find the beginning of a procedure or function.  This is a destructive
78*5514Slinton  * routine, it changes the value associated with the procedure symbol.
79*5514Slinton  * Should only be called once per symbol.
80*5514Slinton  */
81*5514Slinton 
82*5514Slinton findbeginning(f)
83*5514Slinton SYM *f;
84*5514Slinton {
85*5514Slinton 	f->symvalue.funcv.codeloc = nextaddr(f->symvalue.funcv.codeloc, FALSE);
86*5514Slinton }
87*5514Slinton 
88*5514Slinton /*
89*5514Slinton  * Find the object code associated with the first line of a block.
90*5514Slinton  */
91*5514Slinton 
92*5514Slinton ADDRESS firstline(f)
93*5514Slinton SYM *f;
94*5514Slinton {
95*5514Slinton 	ADDRESS addr;
96*5514Slinton 
97*5514Slinton 	addr = codeloc(f);
98*5514Slinton 	while (linelookup(addr) == 0) {
99*5514Slinton 		addr = nextaddr(addr, FALSE);
100*5514Slinton 	}
101*5514Slinton 	return(addr);
102*5514Slinton }
103*5514Slinton 
104*5514Slinton /*
105*5514Slinton  * Catcher drops strike three ...
106*5514Slinton  */
107*5514Slinton 
108*5514Slinton runtofirst()
109*5514Slinton {
110*5514Slinton 	stepto(firstline(curfunc));
111*5514Slinton }
112*5514Slinton 
113*5514Slinton /*
114*5514Slinton  * Calculate the address of the last line in the program.
115*5514Slinton  * This is assumed to be at the physical end.
116*5514Slinton  */
117*5514Slinton 
118*5514Slinton ADDRESS lastaddr()
119*5514Slinton {
120*5514Slinton 	if (objsize == 0) {
121*5514Slinton 		panic("lastaddr: objsize = 0!");
122*5514Slinton 	}
123*5514Slinton 	return(objsize - sizeof(short));
124*5514Slinton }
125