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
address(s,frame)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
findbeginning(f)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
firstline(f)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
runtofirst()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
lastaddr()128 ADDRESS lastaddr()
129 {
130 if (objsize == 0) {
131 panic("lastaddr: objsize = 0!");
132 }
133 return(objsize - sizeof(short));
134 }
135