<<>> <> <> <> <> <<>> DIRECTORY BreakWorldArchitecture, TargetArchitecture, Breakpoint, Rope USING [ROPE]; BreakWorldArchitectureImpl: CEDAR PROGRAM IMPORTS TargetArchitecture, Breakpoint, BreakWorldArchitecture EXPORTS BreakWorldArchitecture ~ { <> BreakWorld: PUBLIC TYPE ~ REF BreakWorldRep _ BreakWorldArchitecture.nullBreakWorld; BreakWorldRep: PUBLIC TYPE ~ RECORD [ worldAccess: BreakWorldArchitecture.WorldAccess, breakAccess: BreakWorldArchitecture.BreakAccess ]; <> CreateBreakWorld: PUBLIC PROCEDURE [ name: Rope.ROPE, peekContents: BreakWorldArchitecture.PeekContentsProc, pokeContents: BreakWorldArchitecture.PokeContentsProc, getProcAddress: BreakWorldArchitecture.GetProcAddressProc, getProcDataSegment: BreakWorldArchitecture.GetProcDataSegmentProc, getPatchArea: BreakWorldArchitecture.GetPatchAreaProc, monitoredCall: BreakWorldArchitecture.MonitoredCallProc, worldAccessData: BreakWorldArchitecture.WorldAccessData] RETURNS [BreakWorldArchitecture.BreakWorld] ~ { worldAccess: BreakWorldArchitecture.WorldAccess ~ CreateWorldAccess[ name: name, peekContents: peekContents, pokeContents: pokeContents, getProcAddress: getProcAddress, getProcDataSegment: getProcDataSegment, getPatchArea: getPatchArea, monitoredCall: monitoredCall, worldAccessData: worldAccessData]; breakWorld: BreakWorldArchitecture.BreakWorld ~ BreakWorldFromWorldAccess[ worldAccess: worldAccess]; IF worldAccess = BreakWorldArchitecture.nullWorldAccess THEN { ERROR BreakWorldArchitecture.Cant[ code: $NullWorldAccess, message: "CreateBreakWorld[nullWorldAccess]"]; }; IF breakWorld = BreakWorldArchitecture.nullBreakWorld THEN { ERROR BreakWorldArchitecture.Cant[ code: $NullBreakWorld, message: "CreateBreakWorld[nullBreakWorld]"]; }; RETURN [breakWorld]; }; CreateWorldAccess: PUBLIC PROCEDURE [ name: Rope.ROPE, peekContents: BreakWorldArchitecture.PeekContentsProc, pokeContents: BreakWorldArchitecture.PokeContentsProc, getProcAddress: BreakWorldArchitecture.GetProcAddressProc, getProcDataSegment: BreakWorldArchitecture.GetProcDataSegmentProc, getPatchArea: BreakWorldArchitecture.GetPatchAreaProc, monitoredCall: BreakWorldArchitecture.MonitoredCallProc, worldAccessData: BreakWorldArchitecture.WorldAccessData] RETURNS [BreakWorldArchitecture.WorldAccess] ~ { procs: BreakWorldArchitecture.WorldAccessProcs ~ NEW[BreakWorldArchitecture.WorldAccessProcsRep _ [ peekContents: peekContents, pokeContents: pokeContents, getProcAddress: getProcAddress, getProcDataSegment: getProcDataSegment, getPatchArea: getPatchArea, monitoredCall: monitoredCall]]; worldAccess: BreakWorldArchitecture.WorldAccess ~ NEW[BreakWorldArchitecture.WorldAccessRep _ [name: name, procs: procs, data: worldAccessData]]; IF procs = BreakWorldArchitecture.nullWorldAccessProcs THEN { ERROR BreakWorldArchitecture.Cant[ code: $NullWorldAccessProcs, message: "CreateWorldAccess[nullWorldAccessProcs]"]; }; IF worldAccess = BreakWorldArchitecture.nullWorldAccess THEN { ERROR BreakWorldArchitecture.Cant[ code: $NullWorldAccess, message: "CreateWorldAccess[nullWorldAccess]"]; }; RETURN [worldAccess]; }; IsNullBreakWorld: PUBLIC PROCEDURE [breakWorld: BreakWorldArchitecture.BreakWorld] RETURNS [BOOLEAN] ~ { RETURN [breakWorld = BreakWorldArchitecture.nullBreakWorld]; }; BreakWorldFromWorldAccess: PUBLIC PROCEDURE [ worldAccess: BreakWorldArchitecture.WorldAccess] RETURNS [BreakWorldArchitecture.BreakWorld] ~ { breakAccess: BreakWorldArchitecture.BreakAccess ~ Breakpoint.NewBreakAccess[]; breakWorld: BreakWorldArchitecture.BreakWorld ~ NEW[BreakWorldRep _ [ worldAccess: worldAccess, breakAccess: breakAccess]]; IF worldAccess = BreakWorldArchitecture.nullWorldAccess THEN { ERROR BreakWorldArchitecture.Cant[ code: $NullWorldAccess, message: "BreakWorldFromWorldAccess[nullWorldAccess]"]; }; IF breakAccess = BreakWorldArchitecture.nullBreakAccess THEN { ERROR BreakWorldArchitecture.Cant[ code: $NullBreakAccess, message: "BreakWorldFromWorldAccess[nullBreakAccess]"]; }; IF breakWorld.IsNullBreakWorld[] THEN { ERROR BreakWorldArchitecture.Cant[ code: $NullBreakWorld, message: "BreakWorldFromWorldAccess[nullBreakWorld]"]; }; RETURN [breakWorld]; }; WorldAccessFromBreakWorld: PUBLIC PROCEDURE [ breakWorld: BreakWorldArchitecture.BreakWorld] RETURNS [BreakWorldArchitecture.WorldAccess] ~ { IF breakWorld.IsNullBreakWorld[] THEN { ERROR BreakWorldArchitecture.Cant[ code: $NullBreakWorld, message: "WorldAccessFromBreakWorld[nullBreakWorld]"]; }; RETURN [breakWorld.worldAccess]; }; BreakAccessFromBreakWorld: PUBLIC PROCEDURE [ breakWorld: BreakWorldArchitecture.BreakWorld] RETURNS [BreakWorldArchitecture.BreakAccess] ~ { IF breakWorld.IsNullBreakWorld[] THEN { ERROR BreakWorldArchitecture.Cant[ code: $NullBreakWorld, message: "BreakAccessFromBreakWorld[nullBreakWorld]"]; }; RETURN [breakWorld.breakAccess]; }; PeekContents: PUBLIC PROCEDURE [ address: BreakWorldArchitecture.Address, displacement: TargetArchitecture.Displacement _ TargetArchitecture.nullDisplacement] RETURNS [TargetArchitecture.Contents] ~ { breakWorld: BreakWorldArchitecture.BreakWorld ~ address.BreakWorldFromBreakWorldAddress[]; worldAccess: BreakWorldArchitecture.WorldAccess ~ breakWorld.WorldAccessFromBreakWorld[]; peekContents: BreakWorldArchitecture.PeekContentsProc ~ worldAccess.procs.peekContents; displaced: BreakWorldArchitecture.Address ~ AddressFromDisplacement[ address: address, displacement: displacement]; contents: TargetArchitecture.Contents ~ peekContents[address: displaced]; RETURN [contents]; }; PokeContents: PUBLIC PROCEDURE [ address: BreakWorldArchitecture.Address, displacement: TargetArchitecture.Displacement _ TargetArchitecture.nullDisplacement, contents: TargetArchitecture.Contents] RETURNS [] ~ { breakWorld: BreakWorldArchitecture.BreakWorld ~ address.BreakWorldFromBreakWorldAddress[]; worldAccess: BreakWorldArchitecture.WorldAccess ~ breakWorld.WorldAccessFromBreakWorld[]; pokeContents: BreakWorldArchitecture.PokeContentsProc ~ worldAccess.procs.pokeContents; displaced: BreakWorldArchitecture.Address ~ AddressFromDisplacement[ address: address, displacement: displacement]; pokeContents[address: displaced, contents: contents]; RETURN; }; GetProcAddress: PUBLIC PROCEDURE [ breakWorld: BreakWorldArchitecture.BreakWorld, procName: Rope.ROPE] RETURNS [BreakWorldArchitecture.Address] ~ { worldAccess: BreakWorldArchitecture.WorldAccess ~ breakWorld.WorldAccessFromBreakWorld[]; getProcAddress: BreakWorldArchitecture.GetProcAddressProc ~ worldAccess.procs.getProcAddress; address: BreakWorldArchitecture.Address ~ getProcAddress[breakWorld: breakWorld, procName: procName]; RETURN [address]; }; GetProcDataSegment: PUBLIC PROCEDURE [ breakWorld: BreakWorldArchitecture.BreakWorld, address: BreakWorldArchitecture.Address] RETURNS [BreakWorldArchitecture.Address] ~ { worldAccess: BreakWorldArchitecture.WorldAccess ~ breakWorld.WorldAccessFromBreakWorld[]; getProcDataSegment: BreakWorldArchitecture.GetProcDataSegmentProc ~ worldAccess.procs.getProcDataSegment; dataSegment: BreakWorldArchitecture.Address ~ getProcDataSegment[breakWorld: breakWorld, address: address]; RETURN [dataSegment]; }; GetPatchArea: PUBLIC PROCEDURE [address: BreakWorldArchitecture.Address] RETURNS [BreakWorldArchitecture.PatchArea] ~ { breakWorld: BreakWorldArchitecture.BreakWorld ~ address.BreakWorldFromBreakWorldAddress[]; worldAccess: BreakWorldArchitecture.WorldAccess ~ breakWorld.WorldAccessFromBreakWorld[]; getPatchArea: BreakWorldArchitecture.GetPatchAreaProc ~ worldAccess.procs.getPatchArea; patchAreaRep: BreakWorldArchitecture.PatchAreaRep ~ getPatchArea[address: address]; patchArea: BreakWorldArchitecture.PatchArea _ BreakWorldArchitecture.nullPatchArea; IF patchAreaRep.address.IsNullAddress[] THEN { ERROR BreakWorldArchitecture.Cant[ code: $NullAddress, message: "patchAreaRep.address.IsNullAddress"]; }; IF patchAreaRep.byteSize = 0 THEN { ERROR BreakWorldArchitecture.Cant[ code: $ZeroLengthPatchArea, message: "zero length patchAreaRep.address"]; }; patchArea _ NEW[BreakWorldArchitecture.PatchAreaRep _ patchAreaRep]; RETURN [patchArea]; }; MonitoredCall: PUBLIC PROCEDURE [ address: BreakWorldArchitecture.Address, proc: PROCEDURE [] RETURNS []] RETURNS [] ~ { breakWorld: BreakWorldArchitecture.BreakWorld ~ address.BreakWorldFromBreakWorldAddress[]; worldAccess: BreakWorldArchitecture.WorldAccess ~ breakWorld.WorldAccessFromBreakWorld[]; monitoredCall: BreakWorldArchitecture.MonitoredCallProc ~ worldAccess.procs.monitoredCall; monitoredCall[address: address, proc: proc]; RETURN; }; IsNullPatchArea: PUBLIC PROCEDURE [patchArea: BreakWorldArchitecture.PatchArea] RETURNS [BOOLEAN] ~ { RETURN [patchArea = BreakWorldArchitecture.nullPatchArea]; }; NewAddress: PUBLIC PROCEDURE [ breakWorld: BreakWorldArchitecture.BreakWorld, address: TargetArchitecture.Address] RETURNS [BreakWorldArchitecture.Address] ~ { new: BreakWorldArchitecture.Address _ NEW[BreakWorldArchitecture.AddressRep _ [ breakWorld: breakWorld, address: address]]; IF breakWorld.IsNullBreakWorld[] THEN { ERROR BreakWorldArchitecture.Cant[ code: $NullBreakWorld, message: "NewAddress[nullBreakWorld]"]; }; IF address.IsNullAddress[] THEN { ERROR BreakWorldArchitecture.Cant[ code: $NullAddress, message: "NewAddress[nullAddress]"]; }; RETURN [new]; }; IsNullAddress: PUBLIC PROCEDURE [address: BreakWorldArchitecture.Address] RETURNS [BOOLEAN] ~ { RETURN [address = BreakWorldArchitecture.nullAddress]; }; AddressEqual: PUBLIC PROCEDURE [ this: BreakWorldArchitecture.Address, that: BreakWorldArchitecture.Address] RETURNS [BOOLEAN] ~ { IF this.IsNullAddress[] THEN { ERROR BreakWorldArchitecture.Cant[ code: $NullAddress, message: "AddressEqual[this.IsNullAddress]"]; }; IF that.IsNullAddress[] THEN { ERROR BreakWorldArchitecture.Cant[ code: $NullAddress, message: "AddressEqual[that.IsNullAddress]"]; }; RETURN [(this.breakWorld = that.breakWorld) AND (this.address = that.address)]; }; AddressFromDisplacement: PUBLIC PROCEDURE [ address: BreakWorldArchitecture.Address, displacement: TargetArchitecture.Displacement] RETURNS [BreakWorldArchitecture.Address] ~ { targetAddress: TargetArchitecture.Address ~ TargetAddressFromBreakWorldAddress[address: address]; displaced: TargetArchitecture.Address ~ TargetArchitecture.AddressFromDisplacement[ address: targetAddress, displacement: displacement]; breakWorldDisplaced: BreakWorldArchitecture.Address ~ NewAddress[ breakWorld: address.BreakWorldFromBreakWorldAddress[], address: displaced]; RETURN [breakWorldDisplaced]; }; TargetAddressFromBreakWorldAddress: PUBLIC PROCEDURE [ address: BreakWorldArchitecture.Address] RETURNS [TargetArchitecture.Address] ~ { IF address.IsNullAddress[] THEN { ERROR BreakWorldArchitecture.Cant[ code: $NullAddress, message: "TargetAddressFromBreakWorldAddress[nullAddress]"]; }; RETURN [address.address]; }; BreakWorldFromBreakWorldAddress: PUBLIC PROCEDURE [address: BreakWorldArchitecture.Address] RETURNS [BreakWorldArchitecture.BreakWorld] ~ { IF address.IsNullAddress[] THEN { ERROR BreakWorldArchitecture.Cant[ code: $NullAddress, message: "BreakWorldFromBreakWorldAddress[nullAddress]"]; }; RETURN [address.breakWorld]; }; NextInstruction: PUBLIC PROCEDURE [pc: BreakWorldArchitecture.Address] RETURNS [BreakWorldArchitecture.Address] ~ { nextTargetAddress: TargetArchitecture.Address ~ TargetArchitecture.NextInstruction[pc: pc.TargetAddressFromBreakWorldAddress[]]; nextAddress: BreakWorldArchitecture.Address ~ NewAddress[ breakWorld: pc.BreakWorldFromBreakWorldAddress[], address: nextTargetAddress]; RETURN [nextAddress]; }; PrevInstruction: PUBLIC PROCEDURE [pc: BreakWorldArchitecture.Address] RETURNS [BreakWorldArchitecture.Address] ~ { prevTargetAddress: TargetArchitecture.Address ~ TargetArchitecture.PrevInstruction[pc: pc.TargetAddressFromBreakWorldAddress[]]; prevAddress: BreakWorldArchitecture.Address ~ NewAddress[ breakWorld: pc.BreakWorldFromBreakWorldAddress[], address: prevTargetAddress]; RETURN [prevAddress]; }; PeekInstruction: PUBLIC PROCEDURE [ pc: BreakWorldArchitecture.Address, displacement: TargetArchitecture.Displacement _ TargetArchitecture.nullDisplacement] RETURNS [TargetArchitecture.Instruction] ~ { contents: TargetArchitecture.Contents ~ BreakWorldArchitecture.PeekContents[address: pc, displacement: displacement]; instruction: TargetArchitecture.Instruction ~ contents.InstructionFromContents[]; RETURN [instruction]; }; PokeInstruction: PUBLIC PROCEDURE [ pc: BreakWorldArchitecture.Address, displacement: TargetArchitecture.Displacement _ TargetArchitecture.nullDisplacement, instruction: TargetArchitecture.Instruction] RETURNS [] ~ { contents: TargetArchitecture.Contents ~ instruction.ContentsFromInstruction[]; BreakWorldArchitecture.PokeContents[ address: pc, displacement: displacement, contents: contents]; RETURN; }; <> Cant: PUBLIC ERROR [ code: BreakWorldArchitecture.ErrorCode, message: BreakWorldArchitecture.ErrorMessage] ~ CODE; WouldBlock: PUBLIC ERROR [message: BreakWorldArchitecture.ErrorMessage] ~ CODE; <> }.