<<>> <> <> <> <<>> DIRECTORY TargetArchitecture, SPARCArchitecture, BreakWorldArchitecture, SPARCBreakWorldUtilities, SPARCManger; SPARCMangerImpl: CEDAR PROGRAM IMPORTS TargetArchitecture, SPARCArchitecture, BreakWorldArchitecture, SPARCBreakWorldUtilities, SPARCManger EXPORTS SPARCManger ~ { <> Install: PUBLIC PROCEDURE [ address: BreakWorldArchitecture.Address, manger: BreakWorldArchitecture.Address, patchCode: BreakWorldArchitecture.Address] RETURNS [] ~ { IF address.IsNullAddress[] THEN { ERROR SPARCManger.CantInstall[ code: $NullAddress, message: "Install[null address]"]; }; IF manger.IsNullAddress[] THEN { ERROR SPARCManger.CantInstall[ code: $NullAddress, message: "Install[null manger]"]; }; IF patchCode.IsNullAddress[] THEN { ERROR SPARCManger.CantInstall[ code: $NullAddress, message: "Install[null patchCode]"]; }; { instruction: SPARCArchitecture.SPARCInstruction ~ SPARCBreakWorldUtilities.SPARCInstructionFromBreakWorldAddress[address: address]; SELECT TRUE FROM SPARCArchitecture.IsCallInstruction[instruction: instruction] => { InstallCallManger[address: address, manger: manger, patchCode: patchCode]; }; SPARCArchitecture.IsDelayedBranchInstruction[instruction: instruction] => { InstallBranchManger[address: address, manger: manger, patchCode: patchCode]; }; SPARCArchitecture.IsJmplO7Instruction[instruction: instruction] => { InstallJmplO7Manger[address: address, manger: manger, patchCode: patchCode]; }; SPARCArchitecture.IsJmplG0Instruction[instruction: instruction] => { InstallJmplG0Manger[address: address, manger: manger, patchCode: patchCode]; }; SPARCArchitecture.IsDelayedControlTransfer[instruction: instruction] => { ERROR CantInstall[ code: $NotWithDelaySlot, message: "Cannot install manger for instruction with that kind of delay slot"]; }; ENDCASE => { InstallNormalManger[address: address, manger: manger, patchCode: patchCode]; }; }; }; InstallNormalManger: PROCEDURE [ address: BreakWorldArchitecture.Address, manger: BreakWorldArchitecture.Address, patchCode: BreakWorldArchitecture.Address] RETURNS [] ~ { errorCode: SPARCManger.ErrorCode _ SPARCManger.nullErrorCode; errorMessage: SPARCManger.ErrorMessage _ SPARCManger.nullErrorMessage; instructionAddress: SPARCArchitecture.SPARCAddress ~ SPARCBreakWorldUtilities.SPARCAddressFromBreakWorldAddress[address: address]; mangerSPARCAddress: SPARCArchitecture.SPARCAddress ~ SPARCBreakWorldUtilities.SPARCAddressFromBreakWorldAddress[address: manger]; normalManger: SPARCManger.NormalManger; { instruction: SPARCArchitecture.SPARCInstruction ~ SPARCBreakWorldUtilities.SPARCInstructionFromBreakWorldAddress[address: address]; instructionAddress: SPARCArchitecture.SPARCAddress ~ SPARCBreakWorldUtilities.SPARCAddressFromBreakWorldAddress[address: address]; sheepAddress: SPARCArchitecture.SPARCAddress ~ SPARCArchitecture.SPARCAddressFromDisplacement[ address: mangerSPARCAddress, displacement: SheepOffset[]]; relocated: SPARCArchitecture.SPARCInstruction ~ SPARCArchitecture.Relocate[ instruction: instruction, from: instructionAddress, to: sheepAddress ! SPARCArchitecture.CantRelocate => { errorCode _ $CantRelocate; errorMessage _ "Cannot relocate instruction at breakpoint address"; GO TO Cannot; }]; <> normalManger.sheep _ relocated; BreakWorldArchitecture.PokeInstruction[ pc: manger, displacement: SheepOffset[], instruction: SPARCArchitecture.TargetInstructionFromSPARCInstruction[ instruction: normalManger.sheep]]; EXITS Cannot => { ERROR CantInstall[code: errorCode, message: errorMessage]; }; }; { nextInstructionAddress: SPARCArchitecture.SPARCAddress ~ SPARCBreakWorldUtilities.SPARCAddressFromBreakWorldAddress[ address: BreakWorldArchitecture.NextInstruction[pc: address]]; normalContinueAddress: SPARCArchitecture.SPARCAddress ~ SPARCArchitecture.SPARCAddressFromDisplacement[ address: mangerSPARCAddress, displacement: NormalContinueOffset[]]; normalManger.normalContinue _ SPARCArchitecture.BAa[ pc: normalContinueAddress, to: nextInstructionAddress]; BreakWorldArchitecture.PokeInstruction[ pc: manger, displacement: NormalContinueOffset[], instruction: SPARCArchitecture.TargetInstructionFromSPARCInstruction[ instruction: normalManger.normalContinue]]; }; { normalManger.normalNoop _ SPARCArchitecture.Noop[]; BreakWorldArchitecture.PokeInstruction[ pc: manger, displacement: NormalNoopOffset[], instruction: SPARCArchitecture.TargetInstructionFromSPARCInstruction[ instruction: normalManger.normalNoop]]; }; { normalManger.tag _ SPARCArchitecture.Sethi[ hi: ORD[SPARCManger.MangerVariant.normal], dest: SPARCArchitecture.Register.global0]; BreakWorldArchitecture.PokeInstruction[ pc: manger, displacement: TagOffset[], instruction: SPARCArchitecture.TargetInstructionFromSPARCInstruction[ instruction: normalManger.tag]]; }; { <> patchSPARCAddress: SPARCArchitecture.SPARCAddress ~ SPARCBreakWorldUtilities.SPARCAddressFromBreakWorldAddress[address: patchCode]; instruction: SPARCArchitecture.SPARCInstruction ~ SPARCArchitecture.BAa[ pc: instructionAddress, to: patchSPARCAddress]; BreakWorldArchitecture.PokeInstruction[ pc: address, instruction: SPARCArchitecture.TargetInstructionFromSPARCInstruction[ instruction: instruction]]; <> }; }; InstallBranchManger: PROCEDURE [ address: BreakWorldArchitecture.Address, manger: BreakWorldArchitecture.Address, patchCode: BreakWorldArchitecture.Address] RETURNS [] ~ { errorCode: SPARCManger.ErrorCode _ SPARCManger.nullErrorCode; errorMessage: SPARCManger.ErrorMessage _ SPARCManger.nullErrorMessage; instructionAddress: SPARCArchitecture.SPARCAddress ~ SPARCBreakWorldUtilities.SPARCAddressFromBreakWorldAddress[address: address]; mangerSPARCAddress: SPARCArchitecture.SPARCAddress ~ SPARCBreakWorldUtilities.SPARCAddressFromBreakWorldAddress[address: manger]; branchManger: SPARCManger.BranchManger; branchDelayBreakWorldAddress: BreakWorldArchitecture.Address ~ BreakWorldArchitecture.NextInstruction[ pc: address]; branchContinueBreakWorldAddress: BreakWorldArchitecture.Address ~ BreakWorldArchitecture.NextInstruction[pc: branchDelayBreakWorldAddress]; { instruction: SPARCArchitecture.SPARCInstruction ~ SPARCBreakWorldUtilities.SPARCInstructionFromBreakWorldAddress[address: address]; instructionAddress: SPARCArchitecture.SPARCAddress ~ SPARCBreakWorldUtilities.SPARCAddressFromBreakWorldAddress[address: address]; dctiAddress: SPARCArchitecture.SPARCAddress ~ SPARCArchitecture.SPARCAddressFromDisplacement[ address: mangerSPARCAddress, displacement: DctiOffset[]]; relocated: SPARCArchitecture.SPARCInstruction ~ SPARCArchitecture.Relocate[ instruction: instruction, from: instructionAddress, to: dctiAddress ! SPARCArchitecture.CantRelocate => { errorCode _ $CantRelocate; errorMessage _ "Cannot relocate instruction at breakpoint address"; GO TO Cannot; }]; <> branchManger.dcti _ relocated; BreakWorldArchitecture.PokeInstruction[ pc: manger, displacement: DctiOffset[], instruction: SPARCArchitecture.TargetInstructionFromSPARCInstruction[ instruction: branchManger.dcti]]; EXITS Cannot => { ERROR CantInstall[code: errorCode, message: errorMessage]; }; }; { branchDelayInstructionAddress: SPARCArchitecture.SPARCAddress ~ SPARCBreakWorldUtilities.SPARCAddressFromBreakWorldAddress[ address: branchDelayBreakWorldAddress]; branchDelayAddress: SPARCArchitecture.SPARCAddress ~ SPARCArchitecture.SPARCAddressFromDisplacement[ address: mangerSPARCAddress, displacement: BranchDelayOffset[]]; branchDelayInstruction: SPARCArchitecture.SPARCInstruction ~ SPARCBreakWorldUtilities.SPARCInstructionFromBreakWorldAddress[ address: branchDelayBreakWorldAddress]; relocatedBranchDelayInstruction: SPARCArchitecture.SPARCInstruction ~ SPARCArchitecture.Relocate[ instruction: branchDelayInstruction, from: branchDelayInstructionAddress, to: branchDelayAddress ! SPARCArchitecture.CantRelocate => { errorCode _ $CantRelocate; errorMessage _ "Cannot relocate instruction in delay slot of breakpoint address"; GO TO Cannot; }]; branchManger.branchDelay _ relocatedBranchDelayInstruction; BreakWorldArchitecture.PokeInstruction[ pc: manger, displacement: BranchDelayOffset[], instruction: SPARCArchitecture.TargetInstructionFromSPARCInstruction[ instruction: branchManger.branchDelay]]; EXITS Cannot => { ERROR CantInstall[code: errorCode, message: errorMessage]; }; }; { branchContinueInstructionAddress: SPARCArchitecture.SPARCAddress ~ SPARCBreakWorldUtilities.SPARCAddressFromBreakWorldAddress[ address: branchContinueBreakWorldAddress]; branchContinueAddress: SPARCArchitecture.SPARCAddress ~ SPARCArchitecture.SPARCAddressFromDisplacement[ address: mangerSPARCAddress, displacement: BranchContinueOffset[]]; branchManger.branchContinue _ SPARCArchitecture.BAa[ pc: branchContinueAddress, to: branchContinueInstructionAddress]; BreakWorldArchitecture.PokeInstruction[ pc: manger, displacement: BranchContinueOffset[], instruction: SPARCArchitecture.TargetInstructionFromSPARCInstruction[ instruction: branchManger.branchContinue]]; }; { branchManger.tag _ SPARCArchitecture.Sethi[ hi: ORD[SPARCManger.MangerVariant.branch], dest: SPARCArchitecture.Register.global0]; BreakWorldArchitecture.PokeInstruction[ pc: manger, displacement: TagOffset[], instruction: SPARCArchitecture.TargetInstructionFromSPARCInstruction[ instruction: branchManger.tag]]; }; { <> patchSPARCAddress: SPARCArchitecture.SPARCAddress ~ SPARCBreakWorldUtilities.SPARCAddressFromBreakWorldAddress[address: patchCode]; instruction: SPARCArchitecture.SPARCInstruction ~ SPARCArchitecture.BAa[ pc: instructionAddress, to: patchSPARCAddress]; BreakWorldArchitecture.PokeInstruction[ pc: address, instruction: SPARCArchitecture.TargetInstructionFromSPARCInstruction[ instruction: instruction]]; <> }; }; InstallCallManger: PROCEDURE [ address: BreakWorldArchitecture.Address, manger: BreakWorldArchitecture.Address, patchCode: BreakWorldArchitecture.Address] RETURNS [] ~ { callManger: SPARCManger.CallManger; instruction: SPARCArchitecture.SPARCInstruction ~ SPARCBreakWorldUtilities.SPARCInstructionFromBreakWorldAddress[address: address]; instructionTargetAddress: TargetArchitecture.Address ~ BreakWorldArchitecture.TargetAddressFromBreakWorldAddress[address: address]; instructionAddress: SPARCArchitecture.SPARCAddress ~ SPARCArchitecture.SPARCAddressFromTargetAddress[address: instructionTargetAddress]; instructionDisp30: SPARCArchitecture.Disp30 ~ instruction.GetDisp30[]; byteDisplacement: TargetArchitecture.Displacement ~ instructionDisp30 * BYTES[SPARCArchitecture.SPARCInstruction]; destination: TargetArchitecture.Address ~ TargetArchitecture.AddressFromDisplacement[ address: instructionTargetAddress, displacement: byteDisplacement]; mangerSPARCAddress: SPARCArchitecture.SPARCAddress ~ SPARCBreakWorldUtilities.SPARCAddressFromBreakWorldAddress[address: manger]; { callManger.callAddrHi _ SPARCArchitecture.Sethi[ hi: SPARCArchitecture.Hi[value: LOOPHOLE[destination]], dest: SPARCArchitecture.Register.global1]; BreakWorldArchitecture.PokeInstruction[ pc: manger, displacement: CallAddrHiOffset[], instruction: SPARCArchitecture.TargetInstructionFromSPARCInstruction[ instruction: callManger.callAddrHi]]; }; { callManger.callJmp _ SPARCArchitecture.JmplConst[ source: SPARCArchitecture.Register.global1, constant: SPARCArchitecture.Lo[value: LOOPHOLE[destination]], dest: SPARCArchitecture.Register.global0]; BreakWorldArchitecture.PokeInstruction[ pc: manger, displacement: CallJmpOffset[], instruction: SPARCArchitecture.TargetInstructionFromSPARCInstruction[ instruction: callManger.callJmp]]; }; { callManger.callNoop _ SPARCArchitecture.Noop[]; BreakWorldArchitecture.PokeInstruction[ pc: manger, displacement: CallNoopOffset[], instruction: SPARCArchitecture.TargetInstructionFromSPARCInstruction[ instruction: callManger.callNoop]]; }; { callManger.tag _ SPARCArchitecture.Sethi[ hi: ORD[SPARCManger.MangerVariant.call], dest: SPARCArchitecture.Register.global0]; BreakWorldArchitecture.PokeInstruction[ pc: manger, displacement: TagOffset[], instruction: SPARCArchitecture.TargetInstructionFromSPARCInstruction[ instruction: callManger.tag]]; }; { <> patchSPARCAddress: SPARCArchitecture.SPARCAddress ~ SPARCBreakWorldUtilities.SPARCAddressFromBreakWorldAddress[address: patchCode]; instruction: SPARCArchitecture.SPARCInstruction ~ SPARCArchitecture.Call[ pc: instructionAddress, to: patchSPARCAddress]; BreakWorldArchitecture.PokeInstruction[ pc: address, instruction: SPARCArchitecture.TargetInstructionFromSPARCInstruction[ instruction: instruction]]; <> }; }; InstallJmplO7Manger: PROCEDURE [ address: BreakWorldArchitecture.Address, manger: BreakWorldArchitecture.Address, patchCode: BreakWorldArchitecture.Address] RETURNS [] ~ { jmplO7Manger: SPARCManger.JmplO7Manger; instructionAddress: SPARCArchitecture.SPARCAddress ~ SPARCBreakWorldUtilities.SPARCAddressFromBreakWorldAddress[address: address]; mangerSPARCAddress: SPARCArchitecture.SPARCAddress ~ SPARCBreakWorldUtilities.SPARCAddressFromBreakWorldAddress[address: manger]; { instruction: SPARCArchitecture.SPARCInstruction ~ SPARCBreakWorldUtilities.SPARCInstructionFromBreakWorldAddress[address: address]; jmplO7Manger.jmplO7Jmp _ SPARCArchitecture.SetRd[ instruction: instruction, rd: SPARCArchitecture.Register.global0]; BreakWorldArchitecture.PokeInstruction[ pc: manger, displacement: JmplO7JmpOffset[], instruction: SPARCArchitecture.TargetInstructionFromSPARCInstruction[ instruction: jmplO7Manger.jmplO7Jmp]]; }; { jmplO7Manger.jmplO7Noop _ SPARCArchitecture.Noop[]; BreakWorldArchitecture.PokeInstruction[ pc: manger, displacement: JmplO7NoopOffset[], instruction: SPARCArchitecture.TargetInstructionFromSPARCInstruction[ instruction: jmplO7Manger.jmplO7Noop]]; }; { jmplO7Manger.jmplO7Pad _ SPARCArchitecture.Noop[]; BreakWorldArchitecture.PokeInstruction[ pc: manger, displacement: JmplO7PadOffset[], instruction: SPARCArchitecture.TargetInstructionFromSPARCInstruction[ instruction: jmplO7Manger.jmplO7Pad]]; }; { jmplO7Manger.tag _ SPARCArchitecture.Sethi[ hi: ORD[SPARCManger.MangerVariant.jmplO7], dest: SPARCArchitecture.Register.global0]; BreakWorldArchitecture.PokeInstruction[ pc: manger, displacement: TagOffset[], instruction: SPARCArchitecture.TargetInstructionFromSPARCInstruction[ instruction: jmplO7Manger.tag]]; }; { <> patchSPARCAddress: SPARCArchitecture.SPARCAddress ~ SPARCBreakWorldUtilities.SPARCAddressFromBreakWorldAddress[address: patchCode]; instruction: SPARCArchitecture.SPARCInstruction ~ SPARCArchitecture.Call[ pc: instructionAddress, to: patchSPARCAddress]; BreakWorldArchitecture.PokeInstruction[ pc: address, instruction: SPARCArchitecture.TargetInstructionFromSPARCInstruction[ instruction: instruction]]; <> }; }; InstallJmplG0Manger: PROCEDURE [ address: BreakWorldArchitecture.Address, manger: BreakWorldArchitecture.Address, patchCode: BreakWorldArchitecture.Address] RETURNS [] ~ { errorCode: SPARCManger.ErrorCode _ SPARCManger.nullErrorCode; errorMessage: SPARCManger.ErrorMessage _ SPARCManger.nullErrorMessage; instructionAddress: SPARCArchitecture.SPARCAddress ~ SPARCBreakWorldUtilities.SPARCAddressFromBreakWorldAddress[address: address]; mangerSPARCAddress: SPARCArchitecture.SPARCAddress ~ SPARCBreakWorldUtilities.SPARCAddressFromBreakWorldAddress[address: manger]; jmplG0Manger: SPARCManger.JmplG0Manger; jmplG0DelayBreakWorldAddress: BreakWorldArchitecture.Address ~ BreakWorldArchitecture.NextInstruction[ pc: address]; { instruction: SPARCArchitecture.SPARCInstruction ~ SPARCBreakWorldUtilities.SPARCInstructionFromBreakWorldAddress[address: address]; jmplG0Manger.jmplG0Jmp _ instruction; <> BreakWorldArchitecture.PokeInstruction[ pc: manger, displacement: JmplG0JmpOffset[], instruction: SPARCArchitecture.TargetInstructionFromSPARCInstruction[ instruction: jmplG0Manger.jmplG0Jmp]]; }; { jmplG0DelayInstructionAddress: SPARCArchitecture.SPARCAddress ~ SPARCBreakWorldUtilities.SPARCAddressFromBreakWorldAddress[ address: jmplG0DelayBreakWorldAddress]; jmplG0DelayAddress: SPARCArchitecture.SPARCAddress ~ SPARCArchitecture.SPARCAddressFromDisplacement[ address: mangerSPARCAddress, displacement: JmplG0DelayOffset[]]; jmplG0DelayInstruction: SPARCArchitecture.SPARCInstruction ~ SPARCBreakWorldUtilities.SPARCInstructionFromBreakWorldAddress[ address: jmplG0DelayBreakWorldAddress]; relocatedJmplG0DelayInstruction: SPARCArchitecture.SPARCInstruction ~ SPARCArchitecture.Relocate[ instruction: jmplG0DelayInstruction, from: jmplG0DelayInstructionAddress, to: jmplG0DelayAddress ! SPARCArchitecture.CantRelocate => { errorCode _ $CantRelocate; errorMessage _ "Cannot relocate instruction in delay slot of breakpoint address"; GO TO Cannot; }]; jmplG0Manger.jmplG0Delay _ relocatedJmplG0DelayInstruction; BreakWorldArchitecture.PokeInstruction[ pc: manger, displacement: JmplG0DelayOffset[], instruction: SPARCArchitecture.TargetInstructionFromSPARCInstruction[ instruction: jmplG0Manger.jmplG0Delay]]; EXITS Cannot => { ERROR CantInstall[code: errorCode, message: errorMessage]; }; }; { jmplG0Manger.jmplG0Pad _ SPARCArchitecture.Noop[]; BreakWorldArchitecture.PokeInstruction[ pc: manger, displacement: JmplG0PadOffset[], instruction: SPARCArchitecture.TargetInstructionFromSPARCInstruction[ instruction: jmplG0Manger.jmplG0Pad]]; }; { jmplG0Manger.tag _ SPARCArchitecture.Sethi[ hi: ORD[SPARCManger.MangerVariant.jmplG0], dest: SPARCArchitecture.Register.global0]; BreakWorldArchitecture.PokeInstruction[ pc: manger, displacement: TagOffset[], instruction: SPARCArchitecture.TargetInstructionFromSPARCInstruction[ instruction: jmplG0Manger.tag]]; }; { <> patchSPARCAddress: SPARCArchitecture.SPARCAddress ~ SPARCBreakWorldUtilities.SPARCAddressFromBreakWorldAddress[address: patchCode]; instruction: SPARCArchitecture.SPARCInstruction ~ SPARCArchitecture.BAa[ pc: instructionAddress, to: patchSPARCAddress]; BreakWorldArchitecture.PokeInstruction[ pc: address, instruction: SPARCArchitecture.TargetInstructionFromSPARCInstruction[ instruction: instruction]]; <> }; }; Uninstall: PUBLIC PROCEDURE [ address: BreakWorldArchitecture.Address, manger: BreakWorldArchitecture.Address, patchCode: BreakWorldArchitecture.Address] ~ { tagInstruction: SPARCArchitecture.SPARCInstruction ~ SPARCBreakWorldUtilities.SPARCInstructionFromBreakWorldAddress[ address: manger, displacement: TagOffset[]]; SELECT tagInstruction.GetImm22[] FROM ORD[SPARCManger.MangerVariant.normal] => { UninstallNormal[address: address, manger: manger]; }; ORD[SPARCManger.MangerVariant.branch] => { UninstallBranch[address: address, manger: manger]; }; ORD[SPARCManger.MangerVariant.call] => { UninstallCall[address: address, manger: manger]; }; ORD[SPARCManger.MangerVariant.jmplO7] => { UninstallJmplO7[address: address, manger: manger]; }; ORD[SPARCManger.MangerVariant.jmplG0] => { UninstallJmplG0[address: address, manger: manger]; }; ENDCASE => { ERROR CantUninstall[ code: $UnknownTag, message: "Can't decode manger"]; }; }; UninstallNormal: PROCEDURE [ address: BreakWorldArchitecture.Address, manger: BreakWorldArchitecture.Address] ~ { errorCode: SPARCManger.ErrorCode _ SPARCManger.nullErrorCode; errorMessage: SPARCManger.ErrorMessage _ SPARCManger.nullErrorMessage; { -- extra scope to contain EXITS. instruction: SPARCArchitecture.SPARCInstruction ~ SPARCBreakWorldUtilities.SPARCInstructionFromBreakWorldAddress[ address: manger, displacement: SheepOffset[]]; mangerSPARCAddress: SPARCArchitecture.SPARCAddress ~ SPARCBreakWorldUtilities.SPARCAddressFromBreakWorldAddress[address: manger]; sheepAddress: SPARCArchitecture.SPARCAddress ~ SPARCArchitecture.SPARCAddressFromDisplacement[ address: mangerSPARCAddress, displacement: SheepOffset[]]; instructionAddress: SPARCArchitecture.SPARCAddress ~ SPARCBreakWorldUtilities.SPARCAddressFromBreakWorldAddress[address: address]; unrelocated: SPARCArchitecture.SPARCInstruction ~ SPARCArchitecture.Relocate[ instruction: instruction, from: sheepAddress, to: instructionAddress ! SPARCArchitecture.CantRelocate => { errorCode _ $CantRelocate; errorMessage _ "Cannot unrelocate instruction to breakpoint address"; GO TO Cannot; }]; <> BreakWorldArchitecture.PokeInstruction[ pc: address, instruction: SPARCArchitecture.TargetInstructionFromSPARCInstruction[ instruction: unrelocated]]; <> EXITS Cannot => { ERROR CantUninstall[code: errorCode, message: errorMessage]; }; }; RETURN; }; UninstallBranch: PROCEDURE [ address: BreakWorldArchitecture.Address, manger: BreakWorldArchitecture.Address] ~ { <> errorCode: SPARCManger.ErrorCode _ SPARCManger.nullErrorCode; errorMessage: SPARCManger.ErrorMessage _ SPARCManger.nullErrorMessage; { -- extra scope to contain EXITS. instruction: SPARCArchitecture.SPARCInstruction ~ SPARCBreakWorldUtilities.SPARCInstructionFromBreakWorldAddress[ address: manger, displacement: DctiOffset[]]; mangerSPARCAddress: SPARCArchitecture.SPARCAddress ~ SPARCBreakWorldUtilities.SPARCAddressFromBreakWorldAddress[address: manger]; dctiAddress: SPARCArchitecture.SPARCAddress ~ SPARCArchitecture.SPARCAddressFromDisplacement[ address: mangerSPARCAddress, displacement: DctiOffset[]]; instructionAddress: SPARCArchitecture.SPARCAddress ~ SPARCBreakWorldUtilities.SPARCAddressFromBreakWorldAddress[address: address]; unrelocated: SPARCArchitecture.SPARCInstruction ~ SPARCArchitecture.Relocate[ instruction: instruction, from: dctiAddress, to: instructionAddress ! SPARCArchitecture.CantRelocate => { errorCode _ $CantRelocate; errorMessage _ "Cannot unrelocate instruction to breakpoint address"; GO TO Cannot; }]; <> BreakWorldArchitecture.PokeInstruction[ pc: address, instruction: SPARCArchitecture.TargetInstructionFromSPARCInstruction[ instruction: unrelocated]]; <> EXITS Cannot => { ERROR CantUninstall[code: errorCode, message: errorMessage]; }; }; RETURN; }; UninstallCall: PROCEDURE [ address: BreakWorldArchitecture.Address, manger: BreakWorldArchitecture.Address] ~ { errorCode: SPARCManger.ErrorCode _ SPARCManger.nullErrorCode; errorMessage: SPARCManger.ErrorMessage _ SPARCManger.nullErrorMessage; callAddrHiInstruction: SPARCArchitecture.SPARCInstruction ~ SPARCBreakWorldUtilities.SPARCInstructionFromBreakWorldAddress[ address: manger, displacement: CallAddrHiOffset[]]; callAddrHi: SPARCArchitecture.Imm22 ~ callAddrHiInstruction.GetImm22[]; callAddrLoInstruction: SPARCArchitecture.SPARCInstruction ~ SPARCBreakWorldUtilities.SPARCInstructionFromBreakWorldAddress[ address: manger, displacement: CallJmpOffset[]]; callAddrLo: SPARCArchitecture.Simm13 ~ callAddrLoInstruction.GetSimm13[]; callAddr: SPARCArchitecture.SPARCAddress ~ LOOPHOLE[SPARCArchitecture.HiLo[hi: callAddrHi, lo: callAddrLo]]; instructionAddress: SPARCArchitecture.SPARCAddress ~ SPARCBreakWorldUtilities.SPARCAddressFromBreakWorldAddress[address: address]; callInstruction: SPARCArchitecture.SPARCInstruction ~ SPARCArchitecture.Call[ pc: instructionAddress, to: callAddr]; BreakWorldArchitecture.PokeInstruction[ pc: address, instruction: SPARCArchitecture.TargetInstructionFromSPARCInstruction[ instruction: callInstruction]]; <> RETURN; }; UninstallJmplO7: PROCEDURE [ address: BreakWorldArchitecture.Address, manger: BreakWorldArchitecture.Address] ~ { errorCode: SPARCManger.ErrorCode _ SPARCManger.nullErrorCode; errorMessage: SPARCManger.ErrorMessage _ SPARCManger.nullErrorMessage; jmplO7JmpInstruction: SPARCArchitecture.SPARCInstruction ~ SPARCBreakWorldUtilities.SPARCInstructionFromBreakWorldAddress[ address: manger, displacement: JmplO7JmpOffset[]]; jmplO7Instruction: SPARCArchitecture.SPARCInstruction ~ SPARCArchitecture.SetRd[ instruction: jmplO7JmpInstruction, rd: SPARCArchitecture.Register.out7]; BreakWorldArchitecture.PokeInstruction[ pc: address, instruction: SPARCArchitecture.TargetInstructionFromSPARCInstruction[ instruction: jmplO7Instruction]]; <> RETURN; }; UninstallJmplG0: PROCEDURE [ address: BreakWorldArchitecture.Address, manger: BreakWorldArchitecture.Address] ~ { errorCode: SPARCManger.ErrorCode _ SPARCManger.nullErrorCode; errorMessage: SPARCManger.ErrorMessage _ SPARCManger.nullErrorMessage; jmplG0JmpInstruction: SPARCArchitecture.SPARCInstruction ~ SPARCBreakWorldUtilities.SPARCInstructionFromBreakWorldAddress[ address: manger, displacement: JmplG0JmpOffset[]]; BreakWorldArchitecture.PokeInstruction[ pc: address, instruction: SPARCArchitecture.TargetInstructionFromSPARCInstruction[ instruction: jmplG0JmpInstruction]]; <> RETURN; }; <> SheepOffset: PROCEDURE [] RETURNS [TargetArchitecture.Displacement] ~ TRUSTED { offset: TargetArchitecture.Displacement _ TargetArchitecture.nullDisplacement; manger: SPARCManger.NormalManger; mangerAddress: LONG POINTER TO SPARCManger.NormalManger ~ @manger; mangerCard: CARD32 ~ LOOPHOLE[mangerAddress]; sheepAddress: LONG POINTER TO SPARCArchitecture.SPARCInstruction ~ @manger.sheep; sheepCard: CARD32 ~ LOOPHOLE[sheepAddress]; offset _ (sheepCard - mangerCard) * BYTES[UNIT]; RETURN [offset]; }; NormalContinueOffset: PROCEDURE [] RETURNS [TargetArchitecture.Displacement] ~ TRUSTED { offset: TargetArchitecture.Displacement _ TargetArchitecture.nullDisplacement; manger: SPARCManger.NormalManger; mangerAddress: LONG POINTER TO SPARCManger.NormalManger ~ @manger; mangerCard: CARD32 ~ LOOPHOLE[mangerAddress]; normalContinueAddress: LONG POINTER TO SPARCArchitecture.SPARCInstruction ~ @manger.normalContinue; normalContinueCard: CARD32 ~ LOOPHOLE[normalContinueAddress]; offset _ (normalContinueCard - mangerCard) * BYTES[UNIT]; RETURN [offset]; }; NormalNoopOffset: PROCEDURE [] RETURNS [TargetArchitecture.Displacement] ~ TRUSTED { offset: TargetArchitecture.Displacement _ TargetArchitecture.nullDisplacement; manger: SPARCManger.NormalManger; mangerAddress: LONG POINTER TO SPARCManger.NormalManger ~ @manger; mangerCard: CARD32 ~ LOOPHOLE[mangerAddress]; normalNoopAddress: LONG POINTER TO SPARCArchitecture.SPARCInstruction ~ @manger.normalNoop; normalNoopCard: CARD32 ~ LOOPHOLE[normalNoopAddress]; offset _ (normalNoopCard - mangerCard) * BYTES[UNIT]; RETURN [offset]; }; TagOffset: PROCEDURE [] RETURNS [TargetArchitecture.Displacement] ~ TRUSTED { offset: TargetArchitecture.Displacement _ TargetArchitecture.nullDisplacement; manger: SPARCManger.NormalManger; mangerAddress: LONG POINTER TO SPARCManger.NormalManger ~ @manger; mangerCard: CARD32 ~ LOOPHOLE[mangerAddress]; tagAddress: LONG POINTER TO SPARCArchitecture.SPARCInstruction ~ @manger.tag; tagCard: CARD32 ~ LOOPHOLE[tagAddress]; offset _ (tagCard - mangerCard) * BYTES[UNIT]; RETURN [offset]; }; DctiOffset: PROCEDURE [] RETURNS [TargetArchitecture.Displacement] ~ TRUSTED { offset: TargetArchitecture.Displacement _ TargetArchitecture.nullDisplacement; manger: SPARCManger.BranchManger; mangerAddress: LONG POINTER TO SPARCManger.BranchManger ~ @manger; mangerCard: CARD32 ~ LOOPHOLE[mangerAddress]; dctiAddress: LONG POINTER TO SPARCArchitecture.SPARCInstruction ~ @manger.dcti; dctiCard: CARD32 ~ LOOPHOLE[dctiAddress]; offset _ (dctiCard - mangerCard) * BYTES[UNIT]; RETURN [offset]; }; BranchDelayOffset: PROCEDURE [] RETURNS [TargetArchitecture.Displacement] ~ TRUSTED { offset: TargetArchitecture.Displacement _ TargetArchitecture.nullDisplacement; manger: SPARCManger.BranchManger; mangerAddress: LONG POINTER TO SPARCManger.BranchManger ~ @manger; mangerCard: CARD32 ~ LOOPHOLE[mangerAddress]; branchDelayAddress: LONG POINTER TO SPARCArchitecture.SPARCInstruction ~ @manger.branchDelay; branchDelayCard: CARD32 ~ LOOPHOLE[branchDelayAddress]; offset _ (branchDelayCard - mangerCard) * BYTES[UNIT]; RETURN [offset]; }; BranchContinueOffset: PROCEDURE [] RETURNS [TargetArchitecture.Displacement] ~ TRUSTED { offset: TargetArchitecture.Displacement _ TargetArchitecture.nullDisplacement; manger: SPARCManger.BranchManger; mangerAddress: LONG POINTER TO SPARCManger.BranchManger ~ @manger; mangerCard: CARD32 ~ LOOPHOLE[mangerAddress]; branchContinueAddress: LONG POINTER TO SPARCArchitecture.SPARCInstruction ~ @manger.branchContinue; branchContinueCard: CARD32 ~ LOOPHOLE[branchContinueAddress]; offset _ (branchContinueCard - mangerCard) * BYTES[UNIT]; RETURN [offset]; }; CallAddrHiOffset: PROCEDURE [] RETURNS [TargetArchitecture.Displacement] ~ TRUSTED { offset: TargetArchitecture.Displacement _ TargetArchitecture.nullDisplacement; manger: SPARCManger.CallManger; mangerAddress: LONG POINTER TO SPARCManger.CallManger ~ @manger; mangerCard: CARD32 ~ LOOPHOLE[mangerAddress]; callAddrHiAddress: LONG POINTER TO SPARCArchitecture.SPARCInstruction ~ @manger.callAddrHi; callAddrHiCard: CARD32 ~ LOOPHOLE[callAddrHiAddress]; offset _ (callAddrHiCard - mangerCard) * BYTES[UNIT]; RETURN [offset]; }; CallJmpOffset: PROCEDURE [] RETURNS [TargetArchitecture.Displacement] ~ TRUSTED { offset: TargetArchitecture.Displacement _ TargetArchitecture.nullDisplacement; manger: SPARCManger.CallManger; mangerAddress: LONG POINTER TO SPARCManger.CallManger ~ @manger; mangerCard: CARD32 ~ LOOPHOLE[mangerAddress]; callJmpAddress: LONG POINTER TO SPARCArchitecture.SPARCInstruction ~ @manger.callJmp; callJmpCard: CARD32 ~ LOOPHOLE[callJmpAddress]; offset _ (callJmpCard - mangerCard) * BYTES[UNIT]; RETURN [offset]; }; CallNoopOffset: PROCEDURE [] RETURNS [TargetArchitecture.Displacement] ~ TRUSTED { offset: TargetArchitecture.Displacement _ TargetArchitecture.nullDisplacement; manger: SPARCManger.CallManger; mangerAddress: LONG POINTER TO SPARCManger.CallManger ~ @manger; mangerCard: CARD32 ~ LOOPHOLE[mangerAddress]; callNoopAddress: LONG POINTER TO SPARCArchitecture.SPARCInstruction ~ @manger.callNoop; callNoopCard: CARD32 ~ LOOPHOLE[callNoopAddress]; offset _ (callNoopCard - mangerCard) * BYTES[UNIT]; RETURN [offset]; }; JmplO7JmpOffset: PROCEDURE [] RETURNS [TargetArchitecture.Displacement] ~ TRUSTED { offset: TargetArchitecture.Displacement _ TargetArchitecture.nullDisplacement; manger: SPARCManger.JmplO7Manger; mangerAddress: LONG POINTER TO SPARCManger.JmplO7Manger ~ @manger; mangerCard: CARD32 ~ LOOPHOLE[mangerAddress]; jmplO7JmpAddress: LONG POINTER TO SPARCArchitecture.SPARCInstruction ~ @manger.jmplO7Jmp; jmplO7JmpCard: CARD32 ~ LOOPHOLE[jmplO7JmpAddress]; offset _ (jmplO7JmpCard - mangerCard) * BYTES[UNIT]; RETURN [offset]; }; JmplO7NoopOffset: PROCEDURE [] RETURNS [TargetArchitecture.Displacement] ~ TRUSTED { offset: TargetArchitecture.Displacement _ TargetArchitecture.nullDisplacement; manger: SPARCManger.JmplO7Manger; mangerAddress: LONG POINTER TO SPARCManger.JmplO7Manger ~ @manger; mangerCard: CARD32 ~ LOOPHOLE[mangerAddress]; jmplO7NoopAddress: LONG POINTER TO SPARCArchitecture.SPARCInstruction ~ @manger.jmplO7Noop; jmplO7NoopCard: CARD32 ~ LOOPHOLE[jmplO7NoopAddress]; offset _ (jmplO7NoopCard - mangerCard) * BYTES[UNIT]; RETURN [offset]; }; JmplO7PadOffset: PROCEDURE [] RETURNS [TargetArchitecture.Displacement] ~ TRUSTED { offset: TargetArchitecture.Displacement _ TargetArchitecture.nullDisplacement; manger: SPARCManger.JmplO7Manger; mangerAddress: LONG POINTER TO SPARCManger.JmplO7Manger ~ @manger; mangerCard: CARD32 ~ LOOPHOLE[mangerAddress]; jmplO7PadAddress: LONG POINTER TO SPARCArchitecture.SPARCInstruction ~ @manger.jmplO7Pad; jmplO7PadCard: CARD32 ~ LOOPHOLE[jmplO7PadAddress]; offset _ (jmplO7PadCard - mangerCard) * BYTES[UNIT]; RETURN [offset]; }; JmplG0JmpOffset: PROCEDURE [] RETURNS [TargetArchitecture.Displacement] ~ TRUSTED { offset: TargetArchitecture.Displacement _ TargetArchitecture.nullDisplacement; manger: SPARCManger.JmplG0Manger; mangerAddress: LONG POINTER TO SPARCManger.JmplG0Manger ~ @manger; mangerCard: CARD32 ~ LOOPHOLE[mangerAddress]; jmplG0JmpAddress: LONG POINTER TO SPARCArchitecture.SPARCInstruction ~ @manger.jmplG0Jmp; jmplG0JmpCard: CARD32 ~ LOOPHOLE[jmplG0JmpAddress]; offset _ (jmplG0JmpCard - mangerCard) * BYTES[UNIT]; RETURN [offset]; }; JmplG0DelayOffset: PROCEDURE [] RETURNS [TargetArchitecture.Displacement] ~ TRUSTED { offset: TargetArchitecture.Displacement _ TargetArchitecture.nullDisplacement; manger: SPARCManger.JmplG0Manger; mangerAddress: LONG POINTER TO SPARCManger.JmplG0Manger ~ @manger; mangerCard: CARD32 ~ LOOPHOLE[mangerAddress]; jmplG0DelayAddress: LONG POINTER TO SPARCArchitecture.SPARCInstruction ~ @manger.jmplG0Delay; jmplG0DelayCard: CARD32 ~ LOOPHOLE[jmplG0DelayAddress]; offset _ (jmplG0DelayCard - mangerCard) * BYTES[UNIT]; RETURN [offset]; }; JmplG0PadOffset: PROCEDURE [] RETURNS [TargetArchitecture.Displacement] ~ TRUSTED { offset: TargetArchitecture.Displacement _ TargetArchitecture.nullDisplacement; manger: SPARCManger.JmplG0Manger; mangerAddress: LONG POINTER TO SPARCManger.JmplG0Manger ~ @manger; mangerCard: CARD32 ~ LOOPHOLE[mangerAddress]; jmplG0PadAddress: LONG POINTER TO SPARCArchitecture.SPARCInstruction ~ @manger.jmplG0Pad; jmplG0PadCard: CARD32 ~ LOOPHOLE[jmplG0PadAddress]; offset _ (jmplG0PadCard - mangerCard) * BYTES[UNIT]; RETURN [offset]; }; <> CantInstall: PUBLIC ERROR [ code: SPARCManger.ErrorCode, message: SPARCManger.ErrorMessage] ~ CODE; CantUninstall: PUBLIC ERROR [ code: SPARCManger.ErrorCode, message: SPARCManger.ErrorMessage] ~ CODE; }.