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