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