Commit | Line | Data |
---|---|---|
4e4050a1 ML |
1 | /* Copyright (c) 1982 Regents of the University of California */ |
2 | ||
b0231b44 | 3 | static char sccsid[] = "@(#)nextaddr.c 1.4 %G%"; |
4e4050a1 ML |
4 | |
5 | /* | |
6 | * Calculate the next address that will be executed from the current one. | |
7 | * | |
8 | * If the next address depends on runtime data (e.g. a conditional | |
9 | * branch will depend on the value on top of the stack), | |
10 | * we must execute up to the given address with "stepto". | |
11 | * | |
12 | * If the second argument is TRUE, we treat a CALL instruction as | |
13 | * straight line rather than following it as a branch. | |
14 | */ | |
15 | ||
16 | #include "defs.h" | |
17 | #include "machine.h" | |
18 | #include "process.h" | |
19 | #include "breakpoint.h" | |
20 | #include "sym.h" | |
21 | #include "pxops.h" | |
22 | #include "optab.h" | |
23 | #include "mappings.h" | |
24 | #include "runtime.h" | |
25 | #include "process/pxinfo.h" | |
26 | #include "process/process.rep" | |
27 | ||
28 | LOCAL ADDRESS docase(), dofor(); | |
29 | ||
30 | ADDRESS nextaddr(beginaddr, isnext) | |
31 | ADDRESS beginaddr; | |
32 | BOOLEAN isnext; | |
33 | { | |
635ecd43 ML |
34 | register PXOP op; |
35 | ADDRESS addr; | |
36 | short offset; | |
37 | int nextbyte; | |
38 | SYM *s; | |
39 | union { | |
40 | short word; | |
41 | char byte[2]; | |
42 | } o; | |
43 | ||
44 | addr = beginaddr; | |
45 | iread(&o.word, addr, sizeof(o.word)); | |
46 | op = (PXOP) o.byte[0]; | |
47 | nextbyte = o.byte[1]; | |
48 | addr += sizeof(short); | |
49 | switch(op) { | |
50 | ||
51 | # if (isvaxpx) | |
52 | /* | |
53 | * The version of px on the VAX assumes that the instruction | |
54 | * at the entry point of a function is a TRA4 to the beginning | |
55 | * of the block. | |
56 | */ | |
57 | # endif | |
58 | case O_CALL: { | |
59 | ADDRESS eaddr; | |
60 | ||
61 | if (isnext) { | |
62 | addr += sizeof(int); | |
63 | } else { | |
64 | # if (isvaxpx) | |
65 | iread(&eaddr, addr, sizeof(eaddr)); | |
66 | addr = eaddr + sizeof(short); | |
67 | iread(&addr, addr, sizeof(addr)); | |
68 | # else | |
69 | iread(&offset, addr, sizeof(offset)); | |
70 | addr += offset; | |
71 | # endif | |
72 | stepto(addr); | |
73 | if (linelookup(addr) == 0) { | |
74 | bpact(); | |
75 | addr = pc; | |
4e4050a1 | 76 | } |
635ecd43 ML |
77 | if (ss_lines && trcond()) { |
78 | s = whatblock(addr); | |
79 | if (s == NIL) { | |
80 | panic("bad call addr"); | |
81 | } | |
82 | printentry(s); | |
83 | } | |
84 | } | |
85 | break; | |
86 | } | |
4e4050a1 | 87 | |
635ecd43 ML |
88 | # if (isvaxpx) |
89 | case O_FCALL: { | |
90 | ADDRESS eaddr; | |
91 | ADDRESS *fparam; | |
92 | ||
93 | if (!isnext) { | |
94 | stepto(addr - sizeof(short)); | |
95 | dread(&fparam, process->sp + sizeof(ADDRESS), sizeof(fparam)); | |
96 | dread(&eaddr, fparam, sizeof(eaddr)); | |
97 | addr = eaddr - ENDOFF; | |
98 | stepto(addr); | |
99 | if (linelookup(addr) == 0) { | |
100 | bpact(); | |
101 | addr = pc; | |
4e4050a1 | 102 | } |
635ecd43 ML |
103 | if (ss_lines && trcond()) { |
104 | s = whatblock(addr); | |
105 | if (s == NIL) { | |
106 | panic("bad call addr"); | |
107 | } | |
108 | printentry(s); | |
109 | } | |
110 | } | |
111 | break; | |
112 | } | |
113 | # endif | |
114 | ||
115 | case O_END: | |
116 | if ((addr - sizeof(short)) == lastaddr()) { | |
117 | stepto(addr - sizeof(short)); | |
118 | endprogram(); | |
119 | } else { | |
120 | addr = return_addr(); | |
121 | s = whatblock(pc); | |
122 | stepto(addr); | |
123 | if (ss_lines && trcond()) { | |
124 | printexit(s); | |
125 | } | |
126 | if (linelookup(addr) == 0) { | |
127 | bpact(); | |
128 | addr = pc; | |
129 | } | |
130 | } | |
131 | break; | |
132 | ||
133 | # if (isvaxpx) | |
134 | case O_TRA4: | |
135 | case O_GOTO: | |
136 | iread(&addr, addr, sizeof(addr)); | |
137 | break; | |
138 | # endif | |
139 | ||
140 | case O_TRA: | |
141 | iread(&offset, addr, sizeof(offset)); | |
142 | addr += offset; | |
143 | break; | |
144 | ||
145 | case O_CON: { | |
146 | short consize; | |
147 | ||
148 | if (nextbyte == 0) { | |
149 | iread(&consize, addr, sizeof(consize)); | |
150 | addr += sizeof(consize); | |
151 | } else { | |
152 | consize = nextbyte; | |
153 | } | |
154 | addr += consize; | |
155 | break; | |
156 | } | |
4e4050a1 | 157 | |
635ecd43 ML |
158 | case O_CASE1OP: |
159 | addr = docase(nextbyte, 1, addr); | |
160 | break; | |
4e4050a1 | 161 | |
635ecd43 ML |
162 | case O_CASE2OP: |
163 | addr = docase(nextbyte, 2, addr); | |
164 | break; | |
4e4050a1 | 165 | |
635ecd43 ML |
166 | case O_CASE4OP: |
167 | addr = docase(nextbyte, 4, addr); | |
168 | break; | |
4e4050a1 | 169 | |
635ecd43 ML |
170 | case O_FOR1U: |
171 | addr = dofor(2, addr, nextbyte, 1); | |
172 | break; | |
4e4050a1 | 173 | |
635ecd43 ML |
174 | case O_FOR2U: |
175 | addr = dofor(2, addr, nextbyte, 1); | |
176 | break; | |
4e4050a1 | 177 | |
635ecd43 ML |
178 | case O_FOR4U: |
179 | addr = dofor(4, addr, nextbyte, 1); | |
180 | break; | |
4e4050a1 | 181 | |
635ecd43 ML |
182 | case O_FOR1D: |
183 | addr = dofor(2, addr, nextbyte, -1); | |
184 | break; | |
4e4050a1 | 185 | |
635ecd43 ML |
186 | case O_FOR2D: |
187 | addr = dofor(2, addr, nextbyte, -1); | |
188 | break; | |
4e4050a1 | 189 | |
635ecd43 ML |
190 | case O_FOR4D: |
191 | addr = dofor(4, addr, nextbyte, -1); | |
192 | break; | |
4e4050a1 | 193 | |
635ecd43 ML |
194 | case O_IF: |
195 | stepto(addr - sizeof(short)); | |
196 | dread(&offset, process->sp, sizeof(offset)); | |
197 | if (offset == 0) { | |
198 | iread(&offset, addr, sizeof(offset)); | |
199 | addr += offset; | |
200 | } else { | |
201 | addr += sizeof(offset); | |
202 | } | |
203 | break; | |
204 | ||
205 | default: { | |
206 | # if (isvaxpx) | |
207 | int i; | |
208 | ||
209 | for (i = 0; optab[op].argtype[i] != 0; i++) { | |
210 | switch(optab[op].argtype[i]) { | |
211 | case ADDR4: | |
212 | case LWORD: | |
213 | addr += 4; | |
4e4050a1 ML |
214 | break; |
215 | ||
635ecd43 | 216 | case SUBOP: |
4e4050a1 ML |
217 | break; |
218 | ||
635ecd43 ML |
219 | case ADDR2: |
220 | case HWORD: | |
221 | case PSUBOP: | |
222 | case DISP: | |
223 | case VLEN: | |
224 | if (i != 0 || nextbyte == 0) { | |
225 | addr += sizeof(short); | |
4e4050a1 ML |
226 | } |
227 | break; | |
228 | ||
635ecd43 ML |
229 | case STRING: { |
230 | char c; | |
231 | ||
232 | while (nextbyte > 0) { | |
233 | iread(&c, addr, 1); | |
234 | if (c == '\0') { | |
235 | break; | |
236 | } | |
237 | nextbyte--; | |
238 | addr++; | |
4e4050a1 | 239 | } |
635ecd43 ML |
240 | addr++; |
241 | if ((addr&1) != 0) { | |
242 | addr++; | |
4e4050a1 | 243 | } |
4e4050a1 | 244 | break; |
635ecd43 ML |
245 | } |
246 | ||
247 | default: | |
248 | panic("bad argtype"); | |
249 | /*NOTREACHED*/ | |
4e4050a1 | 250 | } |
635ecd43 ML |
251 | } |
252 | # else | |
253 | int oplen; | |
254 | ||
255 | oplen = optab[op].nargs; | |
256 | if (oplen < 0) { | |
257 | oplen = (-oplen) - 1; | |
258 | } else if (oplen > 0 && nextbyte != 0) { | |
259 | oplen--; | |
260 | } | |
261 | oplen *= sizeof(int); | |
262 | switch (op) { | |
263 | case O_BEG: | |
264 | case O_NODUMP: | |
265 | oplen += 10; | |
266 | break; | |
267 | ||
268 | case O_CON: | |
269 | oplen += ((nextbyte + 1)&~1); | |
270 | break; | |
271 | } | |
272 | addr += oplen; | |
273 | # endif | |
274 | break; | |
4e4050a1 | 275 | } |
635ecd43 ML |
276 | } |
277 | return addr; | |
4e4050a1 ML |
278 | } |
279 | ||
280 | /* | |
281 | * Find the next address that will be executed after the | |
282 | * case statement at the given address. | |
283 | */ | |
284 | ||
285 | LOCAL ADDRESS docase(ncases, size, addr) | |
286 | int ncases; | |
287 | int size; | |
288 | ADDRESS addr; | |
289 | { | |
635ecd43 ML |
290 | register ADDRESS i; |
291 | ADDRESS firstval, lastval, jmptable; | |
292 | short offset; | |
293 | long swtval, caseval; | |
294 | ||
295 | stepto(addr - 2); | |
296 | if (ncases == 0) { | |
297 | iread(&ncases, addr, sizeof(ncases)); | |
298 | addr += sizeof(short); | |
299 | } | |
300 | jmptable = addr; | |
301 | firstval = jmptable + ncases*sizeof(short); | |
302 | lastval = firstval + ncases*size; | |
303 | if (size <= 2) { | |
304 | dread(&swtval, process->sp, 2); | |
305 | } else { | |
306 | dread(&swtval, process->sp, size); | |
307 | } | |
308 | for (i = firstval; i < lastval; i += size) { | |
309 | iread(&caseval, i, size); | |
310 | if (cmp(&swtval, &caseval, size) == 0) { | |
311 | i = ((i - firstval) / size) * sizeof(offset); | |
312 | iread(&offset, jmptable + i, sizeof(offset)); | |
313 | addr = jmptable + offset; | |
314 | return addr; | |
4e4050a1 | 315 | } |
635ecd43 ML |
316 | } |
317 | return((lastval+1)&~1); | |
4e4050a1 ML |
318 | } |
319 | ||
320 | LOCAL ADDRESS dofor(size, addr, subop, incr) | |
321 | int size; | |
322 | ADDRESS addr; | |
323 | short subop; | |
324 | int incr; | |
325 | { | |
635ecd43 ML |
326 | register PROCESS *p; |
327 | long i, limit, lower; | |
328 | ADDRESS valaddr; | |
329 | short offset; | |
330 | ||
331 | stepto(addr - sizeof(short)); | |
332 | p = process; | |
333 | i = limit = 0; | |
334 | if (subop == 0) { | |
4e4050a1 | 335 | addr += size; |
635ecd43 ML |
336 | } |
337 | dread(&valaddr, p->sp, sizeof(valaddr)); | |
338 | dread(&i, valaddr, size); | |
339 | dread(&limit, p->sp + sizeof(valaddr), size); | |
340 | i += (incr << (8*(sizeof(i) - size))); | |
341 | addr += size; | |
cf2f3812 | 342 | |
4e4050a1 ML |
343 | /* |
344 | * It is very slow to go through the loop again and again. | |
cf2f3812 ML |
345 | * If it is desired to just skip to the end, the next 4 lines |
346 | * should be skipped. | |
347 | */ | |
635ecd43 ML |
348 | if ((incr > 0 && i < limit) || (incr < 0 && i > limit)) { |
349 | iread(&offset, addr, sizeof(offset)); | |
350 | return(addr + offset); | |
351 | } else { | |
635ecd43 | 352 | return(addr + sizeof(short)); |
635ecd43 | 353 | } |
4e4050a1 | 354 | } |
b0231b44 ML |
355 | |
356 | /* | |
357 | * Determine whether or not the given address corresponds to the | |
358 | * end of a procedure. | |
359 | */ | |
360 | ||
361 | BOOLEAN isendofproc(addr) | |
362 | ADDRESS addr; | |
363 | { | |
364 | PXOP op; | |
365 | ||
366 | iread(&op, addr, sizeof(op)); | |
367 | return (op == O_END); | |
368 | } |