Re:
> Is there a simple way to check an address in a 'c' program to see that is
> in my address space and will not cause a TRAP65 'Invalid data address' when
> passed to a system routine (like _doprnt)?
Good question :)
There's probably no *simple* way ... that's one of the things
I'd asked for when I proposed a memory manager API some years ago.
There are three basic reasons an address might trap:
1) it isn't properly aligned:
- it isn't 8-byte aligned, but the code expected it to be (e.g.,
code is doing quad load/store)
- it isn't 4-byte aligned, but the code expected it to be (e.g.,
code is doing LDW or STW)
- it isn't 2-byte aligned, but the code expected it to be (e.g.,
code is doing LDH or STH)
This you can check for ahead of time, by checking the bottom one, two
or three bits of the address.
2) it's a valid address, but secured so that you can't access it
from the ring level you are running at (e.g., OS data)
This can be checked, in user mode, by using the PROBER or PROBEW
instructions. IIRC, there are ways of emitting this instruction from
both C/ix and gcc, but I can't recall them just now. The Pascal and
SPLash! compilers both have constructs to emit those
instructions.
3) the address is "bad" (isn't a valid/allocated virtual address)
The OS has several routines, which require priv mode access to use,
that can check a virtual address. (e.g., probe_t ())
With Pascal, I can check the second and third cases:
$standard_level 'os_features'$
$type_coercion 'representation'$
$subprogram$
function is_address_readable (ptr : localanyptr) : boolean;
type
char_ptr_type = ^ char;
var
c : char;
begin
try
begin
c := char_ptr_type (ptr)^; {NOTE: may cause a trap!}
is_address_readable := true;
end
recover
is_address_readable := false;
end {is_address_readable proc};
Note that I wouldn't use this code if I expected it would be called
a *lot* (thousands of times) *and* there was a fairly good probability
that the address might be bad. I.e., trapping isn't cheap ... it
takes about 3 milliseconds on an HP 3000/968.
If you have Pascal, you can compile that and link it into your C program
and use it:
extern int is_address_readable (char *c);
...
if (! is_address_readable (&foo))
QUIT (101);
Stan Sieler [log in to unmask]
www.allegro.com/sieler/wanted/index.html www.allegro.com/sieler
* To join/leave the list, search archives, change list settings, *
* etc., please visit http://raven.utc.edu/archives/hp3000-l.html *
|