* Copyright (c) 1980 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
static char sccsid
[] = "@(#)nextaddr.c 5.1 (Berkeley) 6/6/85";
* Calculate the next address that will be executed from the current one.
* If the next address depends on runtime data (e.g. a conditional
* branch will depend on the value on top of the stack),
* we must execute up to the given address with "stepto".
* If the second argument is TRUE, we treat a CALL instruction as
* straight line rather than following it as a branch.
#include "process/pxinfo.h"
#include "process/process.rep"
LOCAL ADDRESS
docase(), dofor();
ADDRESS
nextaddr(beginaddr
, isnext
)
iread(&o
.word
, addr
, sizeof(o
.word
));
* The version of px on the VAX assumes that the instruction
* at the entry point of a function is a TRA4 to the beginning
iread(&eaddr
, addr
, sizeof(eaddr
));
addr
= eaddr
+ sizeof(short);
iread(&addr
, addr
, sizeof(addr
));
iread(&offset
, addr
, sizeof(offset
));
if (linelookup(addr
) == 0) {
if (ss_lines
&& trcond()) {
stepto(addr
- sizeof(short));
dread(&fparam
, process
->sp
+ sizeof(ADDRESS
), sizeof(fparam
));
dread(&eaddr
, fparam
, sizeof(eaddr
));
if (linelookup(addr
) == 0) {
if (ss_lines
&& trcond()) {
if ((addr
- sizeof(short)) == lastaddr()) {
stepto(addr
- sizeof(short));
if (ss_lines
&& trcond()) {
if (linelookup(addr
) == 0) {
iread(&addr
, addr
, sizeof(addr
));
iread(&offset
, addr
, sizeof(offset
));
iread(&consize
, addr
, sizeof(consize
));
addr
= docase(nextbyte
, 1, addr
);
addr
= docase(nextbyte
, 2, addr
);
addr
= docase(nextbyte
, 4, addr
);
addr
= dofor(2, addr
, nextbyte
, 1);
addr
= dofor(2, addr
, nextbyte
, 1);
addr
= dofor(4, addr
, nextbyte
, 1);
addr
= dofor(2, addr
, nextbyte
, -1);
addr
= dofor(2, addr
, nextbyte
, -1);
addr
= dofor(4, addr
, nextbyte
, -1);
stepto(addr
- sizeof(short));
dread(&offset
, process
->sp
, sizeof(offset
));
iread(&offset
, addr
, sizeof(offset
));
for (i
= 0; optab
[op
].argtype
[i
] != 0; i
++) {
switch(optab
[op
].argtype
[i
]) {
if (i
!= 0 || nextbyte
== 0) {
} else if (oplen
> 0 && nextbyte
!= 0) {
oplen
+= ((nextbyte
+ 1)&~1);
* Find the next address that will be executed after the
* case statement at the given address.
LOCAL ADDRESS
docase(ncases
, size
, addr
)
ADDRESS firstval
, lastval
, jmptable
;
iread(&ncases
, addr
, sizeof(ncases
));
firstval
= jmptable
+ ncases
*sizeof(short);
lastval
= firstval
+ ncases
*size
;
dread(&swtval
, process
->sp
, 2);
dread(&swtval
, process
->sp
, size
);
for (i
= firstval
; i
< lastval
; i
+= size
) {
iread(&caseval
, i
, size
);
if (cmp(&swtval
, &caseval
, size
) == 0) {
i
= ((i
- firstval
) / size
) * sizeof(offset
);
iread(&offset
, jmptable
+ i
, sizeof(offset
));
addr
= jmptable
+ offset
;
LOCAL ADDRESS
dofor(size
, addr
, subop
, incr
)
stepto(addr
- sizeof(short));
dread(&valaddr
, p
->sp
, sizeof(valaddr
));
dread(&i
, valaddr
, size
);
dread(&limit
, p
->sp
+ sizeof(valaddr
), size
);
i
+= (incr
<< (8*(sizeof(i
) - size
)));
* It is very slow to go through the loop again and again.
* If it is desired to just skip to the end, the next 4 lines
if ((incr
> 0 && i
< limit
) || (incr
< 0 && i
> limit
)) {
iread(&offset
, addr
, sizeof(offset
));
return(addr
+ sizeof(short));
* Determine whether or not the given address corresponds to the
BOOLEAN
isendofproc(addr
)
iread(&op
, addr
, sizeof(op
));