DIRECTORY
AMEvents USING [Booted, Debugged, Debugging],
AMTypes USING [Error, ErrorReason],
AMViewerOps USING [SourceError],
BBSafety USING [],
CIFS USING [Error],
Convert USING [ValueToRope],
PageFault USING [AddressFault],
Rope USING [Cat, Concat, ROPE],
RTQuanta USING [QuantumSize],
RTTypesBasic USING [InvalidType],
RTTypesRemotePrivate USING [ValidateRemoteRef],
RTZones USING [MapQZf, mzVacant],
Runtime
USING
[BoundsFault, CallDebugger, ControlFault, DivideCheck, PointerFault, StartFault, StackError, UnboundProcedure, ZeroDivisor],
RuntimeInternal USING [SendMsgSignal],
Space USING [InsufficientSpace],
WorldVM
USING
[Address, AddressFault, BadWorld, CurrentIncarnation, LocalWorld, Read, World],
WriteFault USING [WriteProtectFault];
BBSafetyImpl:
CEDAR
MONITOR
IMPORTS
AMEvents, AMTypes, AMViewerOps, CIFS, Convert, PageFault, Rope, RTTypesBasic, RTTypesRemotePrivate, RTZones, Runtime, RuntimeInternal, Space, WorldVM, WriteFault
EXPORTS BBSafety
= BEGIN OPEN Rope, AMTypes, WorldVM;
Global Variables
alwaysRejectAny: BOOL ← FALSE;
OZ: BOOL ← FALSE; -- used to enter debugger when a signal/error occurs
lastAnyMsg, lastAnySignal: CARDINAL ← 0; -- useful for debugging ANY errors
lagMsg: ROPE ← NIL; -- used to usually avoid GC of error message
lagLagMsg: ROPE ← NIL; -- nothing like being safe...
IsValidRef:
PUBLIC
PROC [world: World, ref: Address]
RETURNS [
BOOL] =
TRUSTED {
returns TRUE iff the address is valid AND the zone map has an entry for the address
[] ← WorldVM.Read[world, ref ! ABORTED => GO TO abort; ANY => GO TO bad];
IF world = WorldVM.LocalWorld[]
THEN {
zi: LONG CARDINAL ← ref / RTQuanta.QuantumSize;
IF zi >= RTZones.MapQZf.length THEN RETURN [FALSE];
RETURN [RTZones.MapQZf[LOOPHOLE[zi, Pair].lo] # RTZones.mzVacant];
}
ELSE {
RTTypesRemotePrivate.ValidateRemoteRef
[[world, WorldVM.CurrentIncarnation[world], ref]
! ABORTED => GO TO abort; ANY => GO TO bad]};
RETURN [
TRUE];
EXITS
bad => RETURN [FALSE];
abort => ERROR ABORTED;
};
IsValidAddr:
PUBLIC
PROC [world: World, addr: Address]
RETURNS [
BOOL] =
TRUSTED {
returns TRUE iff the page map has an entry for the address
[] ← WorldVM.Read[world, addr ! ABORTED => GO TO abort; ANY => GO TO bad];
RETURN [TRUE];
EXITS
bad => RETURN [FALSE];
abort => ERROR ABORTED;
};