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