SetBreakpoint: BreakpointPrivate.SetBreakProcType ~ {
PROCEDURE [
address: BreakWorldArchitecture.Address,
clientData: Breakpoint.ClientData,
breakProc: Breakpoint.BreakProc,
breakProcDataSegment: BreakWorldArchitecture.Address,
breakData: Breakpoint.BreakData,
damages: TargetArchitecture.RegisterClass ← TargetArchitecture.RegisterClass.all]
RETURNS [Breakpoint.Break]
break: Breakpoint.Break ¬ Breakpoint.nullBreak;
patch: Shepherd.Patch ¬ Shepherd.nullPatch;
errorCode: Breakpoint.ErrorCode ¬ Breakpoint.nullErrorCode;
errorMessage: Breakpoint.ErrorMessage ¬ Breakpoint.nullErrorMessage;
CheckForDelaySlot: PROCEDURE [address: BreakWorldArchitecture.Address]
RETURNS [] ~{
instruction: RS6000Architecture.RS6000Instruction ~
RS6000BreakWorldUtilities.RS6000InstructionFromBreakWorldAddress[address: address];
prevInstruction: RS6000Architecture.RS6000Instruction ~
RS6000BreakWorldUtilities.RS6000InstructionFromBreakWorldAddress[
address: address, displacement: -BYTES[RS6000Architecture.RS6000Instruction]];
nextInstruction: RS6000Architecture.RS6000Instruction ~
RS6000BreakWorldUtilities.RS6000InstructionFromBreakWorldAddress[
address: address, displacement: +BYTES[RS6000Architecture.RS6000Instruction]];
IF RS6000Architecture.IsDelayedControlTransfer[instruction: prevInstruction] THEN {
ERROR Breakpoint.CantSet[
code: $NotInDelaySlot, message: "Cannot set breakpoint in delay slot"];
};
RETURN;
};
IF address.IsNullAddress[]
THEN {
ERROR Breakpoint.CantSet[
code: $NotAtNullAddress, message: "Cannot set breakpoint at null address"];
};
IF breakProc.IsNullAddress[]
THEN {
ERROR Breakpoint.CantSet[
code: $NotWithNullAddress,
message: "Cannot set breakpoint with null break procedure world address"];
};
{
breakProcTargetAddress: TargetArchitecture.Address ~
breakProc.TargetAddressFromBreakWorldAddress[];
IF breakProcTargetAddress.IsNullAddress[]
THEN {
ERROR Breakpoint.CantSet[
code: $NotWithNullAddress,
message: "Cannot set breakpoint with null break procedure target address"];
};
};
CheckForDelaySlot[address: address];
{
-- extra scope to contain EXITS
patch ¬ Shepherd.ReservePatch[
pc: address, codeSize: BYTES[RS6000Breakpoint.PatchStruct]
! Shepherd.NoMeadow => {
errorCode ¬ $NoMeadow;
errorMessage ¬ message;
GO TO Cannot;
};
Shepherd.BusyMeadow => {
errorCode ¬ $BusyMeadow;
errorMessage ¬ message;
GO TO Cannot;
};
Shepherd.BusyPC => {
errorCode ¬ $BusyPC;
errorMessage ¬ message;
GO TO Cannot;
};
Shepherd.NoRoom => {
errorCode ¬ $NoRoom;
errorMessage ¬ message;
GO TO Cannot;
};
Shepherd.CantReach => {
errorCode ¬ $CantReach;
errorMessage ¬ message;
GO TO Cannot;
};
];
Install[
address: address,
patch: patch,
breakProc: breakProc,
breakProcTOC: breakProcDataSegment,
breakData: breakData,
damages: damages];
break ¬ Breakpoint.NewBreak[address: address, patch: patch, clientData: clientData];
Breakpoint.RememberBreak[break
! Breakpoint.Cant => {
errorCode ¬ $CantRemember;
errorMessage ¬ message;
GO TO Cannot;
};];
EXITS
Cannot => {
-- Can't deallocate patches.
Well, I could just clear the size and address, but is that safe?
IF NOT patch.IsNullPatch[] THEN {
Shepherd.ReleasePatch[patch: patch];
};
ERROR Breakpoint.CantSet[code: errorCode, message: errorMessage];
};
};
RETURN [break];
};
Install:
PROCEDURE [
address: BreakWorldArchitecture.Address,
patch: Shepherd.Patch,
breakProc: Breakpoint.BreakProc,
breakProcTOC: BreakWorldArchitecture.Address,
breakData: Breakpoint.BreakData,
damages: TargetArchitecture.RegisterClass]
RETURNS [] ~ {
IF address.IsNullAddress[]
THEN {
ERROR Breakpoint.CantSet[code: $NullAddress, message: "Install[nullAddress]"];
};
IF patch.IsNullPatch[]
THEN {
ERROR Breakpoint.CantSet[code: $NullPatch, message: "Install[nullPatch]"];
};
IF breakProc.IsNullAddress[]
THEN {
ERROR Breakpoint.CantSet[code: $NullAddress, message: "Install[nullBreakProc]"];
};
InstallClosureCaller[
address: address,
patch: patch,
breakProc: breakProc,
breakProcTOC: breakProcTOC,
breakData: breakData,
damages: damages];
InstallManger[address: address, patch: patch];
};
InstallClosureCaller:
PROCEDURE [
address: BreakWorldArchitecture.Address,
patch: Shepherd.Patch,
breakProc: Breakpoint.BreakProc,
breakProcTOC: BreakWorldArchitecture.Address,
breakData: Breakpoint.BreakData,
damages: TargetArchitecture.RegisterClass]
RETURNS [] ~ {
IF address.IsNullAddress[]
THEN {
ERROR Breakpoint.CantSet[
code: $NullAddress, message: "InstallClosureCaller[nullAddress]"];
};
IF breakProc.IsNullAddress[]
THEN {
ERROR Breakpoint.CantSet[
code: $NullAddress, message: "InstallClosureCaller[nullBreakProc]"];
};
IF patch.IsNullPatch[]
THEN {
ERROR Breakpoint.CantSet[
code: $NullPatch, message: "InstallClosureCaller[nullPatch]"];
};
{
instructionAddress: RS6000Architecture.RS6000Address ~
RS6000BreakWorldUtilities.RS6000AddressFromBreakWorldAddress[address: address];
instructionAddressCard: CARD32 ~ LOOPHOLE[instructionAddress];
tocAddress: RS6000Architecture.RS6000Address ~
RS6000BreakWorldUtilities.RS6000AddressFromBreakWorldAddress[address: breakProcTOC];
tocAddressCard: CARD32 ~ LOOPHOLE[tocAddress];
patchAddress: BreakWorldArchitecture.Address ~ Shepherd.CodeAddressFromPatch[patch: patch];
patchRS6000Address: RS6000Architecture.RS6000Address ~
RS6000BreakWorldUtilities.RS6000AddressFromBreakWorldAddress[address: patchAddress];
frameSize:
INT ~
RS6000Architecture.stackPointerOffset
+ RS6000Architecture.stackAllocationForArgument
+ RS6000Architecture.stackAllocationForLinkArea
+ RS6000Breakpoint.registerSaveArea;
gprSaveArea:
INT ~
RS6000Architecture.stackAllocationForArgument
+ RS6000Architecture.stackAllocationForLinkArea
+ RS6000Breakpoint.registerSaveArea;
damagesRegisters: RS6000Architecture.RegisterClass ~
RS6000Architecture.RS6000RegisterClassFromTargetRegisterClass[registerClass: damages];
registerSaveName: Rope.
ROPE ~
SELECT damagesRegisters
FROM
none => ".save←regs←none",
globals => ".save←regs←globals",
globalsAndIns => ".save←regs←mini",
ENDCASE => ".save←regs";
registerRestoreName: Rope.
ROPE ~
SELECT damagesRegisters
FROM
none => ".restore←regs←none",
globals => ".restore←regs←globals",
globalsAndIns => ".restore←regs←mini",
ENDCASE => ".restore←regs";
Generate the code in the patch.
closureCaller: RS6000Breakpoint.ClosureCaller;
errorCode: Breakpoint.ErrorCode ¬ Breakpoint.nullErrorCode;
errorMessage: Breakpoint.ErrorMessage ¬ Breakpoint.nullErrorMessage;
{
{
ENABLE {
RS6000Architecture.CantRelocate => {
errorCode ¬ $CantSet;
errorMessage ¬ "Cannot relocate instruction (RS6000BreakpointImpl).";
GO TO Cannot;
};
RS6000Architecture.CantReach => {
errorCode ¬ $CantSet;
errorMessage ¬ "pc-relative branch is out of range (RS6000BreakpointImpl).";
GO TO Cannot;
};
RS6000Architecture.NullRS6000Address => {
errorCode ¬ $CantSet;
errorMessage ¬ "A null address was supplied to breakpoint code generation (RS6000BreakpointImpl).";
GO TO Cannot;
};
RS6000Architecture.NullRS6000Instruction => {
errorCode ¬ $CantSet;
errorMessage ¬ "A null instruction was encountered in breakpoint code generation (RS6000BreakpointImpl).";
GO TO Cannot;
};
};
{
closureCaller.stu ¬ RS6000Architecture.Stu[rs: gpr1, offset: -frameSize, ra: gpr1];
BreakWorldArchitecture.PokeInstruction[
pc: patchAddress,
displacement: StuOffset[],
instruction: RS6000Architecture.TargetInstructionFromRS6000Instruction[
instruction: closureCaller.stu]];
};
{
closureCaller.stm ¬ RS6000Architecture.Stm[rs: gpr0, offset: gprSaveArea, ra: gpr1];
BreakWorldArchitecture.PokeInstruction[
pc: patchAddress,
displacement: StmOffset[],
instruction: RS6000Architecture.TargetInstructionFromRS6000Instruction[
instruction: closureCaller.stm]];
};
{
closureCaller.mfspr ¬ RS6000Architecture.Mfspr[rt: gpr0, spr: lr, rc: FALSE];
BreakWorldArchitecture.PokeInstruction[
pc: patchAddress,
displacement: MfsprOffset[],
instruction: RS6000Architecture.TargetInstructionFromRS6000Instruction[
instruction: closureCaller.mfspr]];
};
{
closureCaller.st ¬ RS6000Architecture.St[rs: gpr0, offset: frameSize-4, ra: gpr1];
BreakWorldArchitecture.PokeInstruction[
pc: patchAddress, displacement: StOffset[],
instruction: RS6000Architecture.TargetInstructionFromRS6000Instruction[
instruction: closureCaller.st]];
};
{
closureCaller.liu0 ¬ RS6000Architecture.Liu[
rt: gpr0, upper: RS6000Architecture.High[instructionAddressCard]];
BreakWorldArchitecture.PokeInstruction[
pc: patchAddress,
displacement: Liu0Offset[],
instruction: RS6000Architecture.TargetInstructionFromRS6000Instruction[
instruction: closureCaller.liu0]];
};
{
closureCaller.oril0 ¬ RS6000Architecture.OrLConst[
ra: gpr0, rs: gpr0, ui: RS6000Architecture.Low[instructionAddressCard]];
BreakWorldArchitecture.PokeInstruction[
pc: patchAddress,
displacement: Oril0Offset[],
instruction: RS6000Architecture.TargetInstructionFromRS6000Instruction[
instruction: closureCaller.oril0]];
};
{
closureCaller.st0 ¬ RS6000Architecture.St[rs: gpr0, offset: frameSize+8, ra: gpr1];
BreakWorldArchitecture.PokeInstruction[
pc: patchAddress, displacement: St0Offset[],
instruction: RS6000Architecture.TargetInstructionFromRS6000Instruction[
instruction: closureCaller.st0]];
};
{
blSaveRegsAddress: RS6000Architecture.RS6000Address ~
RS6000Architecture.RS6000AddressFromDisplacement[
address: patchRS6000Address, displacement: BlOffset[]];
saveRegsAddress: RS6000Architecture.RS6000Address ~
RS6000BreakWorldUtilities.RS6000AddressFromBreakWorldAddress[
address: BreakWorldArchitecture.GetProcAddress[
breakWorld: BreakWorldArchitecture.BreakWorldFromBreakWorldAddress[
address: address],
procName: registerSaveName]];
IF saveRegsAddress.IsNullRS6000Address[] THEN {
ERROR Breakpoint.CantSet[
code: $CantFindRegisterSaveProcedure,
message: "Can't find the register save procedure"];
};
closureCaller.bl ← RS6000Architecture.B[pc: blSaveRegsAddress, to: saveRegsAddress, abs: FALSE, link: TRUE];
BreakWorldArchitecture.PokeInstruction[
pc: patchAddress,
displacement: BlOffset[],
instruction: RS6000Architecture.TargetInstructionFromRS6000Instruction[
instruction: closureCaller.bl]];
The registerSaveName procedure was moved INLINE because it was a cheap as doing an out-of-module call.
closureCaller.mfmq ¬ RS6000Architecture.Mfspr[rt: gpr31, spr: mq, rc: FALSE];
BreakWorldArchitecture.PokeInstruction[
pc: patchAddress, displacement: MfmqOffset[],
instruction: RS6000Architecture.TargetInstructionFromRS6000Instruction[
instruction: closureCaller.mfmq]];
closureCaller.mfxer ¬ RS6000Architecture.Mfspr[rt: gpr30, spr: xfr, rc: FALSE];
BreakWorldArchitecture.PokeInstruction[
pc: patchAddress, displacement: MfxerOffset[],
instruction: RS6000Architecture.TargetInstructionFromRS6000Instruction[
instruction: closureCaller.mfxer]];
closureCaller.mfctr ¬ RS6000Architecture.Mfspr[rt: gpr29, spr: ctr, rc: FALSE];
BreakWorldArchitecture.PokeInstruction[
pc: patchAddress, displacement: MfctrOffset[],
instruction: RS6000Architecture.TargetInstructionFromRS6000Instruction[
instruction: closureCaller.mfctr]];
closureCaller.mfcr ¬ RS6000Architecture.Mfcr[rs: gpr28, rc: FALSE];
BreakWorldArchitecture.PokeInstruction[
pc: patchAddress, displacement: MfcrOffset[],
instruction: RS6000Architecture.TargetInstructionFromRS6000Instruction[
instruction: closureCaller.mfcr]];
Need to construct a mnemonic constant for 248.
closureCaller.stm1 ¬ RS6000Architecture.Stm[rs: gpr28, offset: 248, ra: gpr1];
BreakWorldArchitecture.PokeInstruction[
pc: patchAddress, displacement: Stm1Offset[],
instruction: RS6000Architecture.TargetInstructionFromRS6000Instruction[
instruction: closureCaller.stm1]];
};
{
closureCaller.liu ¬ RS6000Architecture.Liu[
rt: gpr2, upper: RS6000Architecture.High[tocAddressCard]];
BreakWorldArchitecture.PokeInstruction[
pc: patchAddress,
displacement: LiuOffset[],
instruction: RS6000Architecture.TargetInstructionFromRS6000Instruction[
instruction: closureCaller.liu]];
};
{
closureCaller.oril ¬ RS6000Architecture.OrLConst[
ra: gpr2, rs: gpr2, ui: RS6000Architecture.Low[tocAddressCard]];
BreakWorldArchitecture.PokeInstruction[
pc: patchAddress,
displacement: OrilOffset[],
instruction: RS6000Architecture.TargetInstructionFromRS6000Instruction[
instruction: closureCaller.oril]];
};
{
closureCaller.liu2 ¬ RS6000Architecture.Liu[
rt: gpr3, upper: RS6000Architecture.High[breakData]];
BreakWorldArchitecture.PokeInstruction[
pc: patchAddress,
displacement: Liu2Offset[],
instruction: RS6000Architecture.TargetInstructionFromRS6000Instruction[
instruction: closureCaller.liu2]];
};
{
closureCaller.oril2 ¬ RS6000Architecture.OrLConst[
ra: gpr3, rs: gpr3, ui: RS6000Architecture.Low[breakData]];
BreakWorldArchitecture.PokeInstruction[
pc: patchAddress,
displacement: Oril2Offset[],
instruction: RS6000Architecture.TargetInstructionFromRS6000Instruction[
instruction: closureCaller.oril2]];
};
{
blClientProcAddress: RS6000Architecture.RS6000Address ~
RS6000Architecture.RS6000AddressFromDisplacement[
address: patchRS6000Address, displacement: Bl2Offset[]];
clientProcAddress: RS6000Architecture.RS6000Address ~
RS6000BreakWorldUtilities.RS6000AddressFromBreakWorldAddress[
address: breakProc];
clientProcAddressCard: CARD32 ~ LOOPHOLE[clientProcAddress];
IF clientProcAddress.IsNullRS6000Address[]
THEN {
ERROR Breakpoint.CantSet[
code: $CantFindClientProc,
message: "Can't find the register save procedure"];
};
closureCaller.bl2 ← RS6000Architecture.B[pc: blClientProcAddress, to: clientProcAddress, abs: FALSE, link: TRUE];
BreakWorldArchitecture.PokeInstruction[
pc: patchAddress,
displacement: Bl2Offset[],
instruction: RS6000Architecture.TargetInstructionFromRS6000Instruction[
instruction: closureCaller.bl2]];
closureCaller.liu3 ¬ RS6000Architecture.Liu[
rt: gpr0, upper: RS6000Architecture.High[clientProcAddressCard]];
BreakWorldArchitecture.PokeInstruction[
pc: patchAddress,
displacement: Liu3Offset[],
instruction: RS6000Architecture.TargetInstructionFromRS6000Instruction[
instruction: closureCaller.liu3]];
closureCaller.oril3 ¬ RS6000Architecture.OrLConst[
ra: gpr0, rs: gpr0, ui: RS6000Architecture.Low[clientProcAddressCard]];
BreakWorldArchitecture.PokeInstruction[
pc: patchAddress,
displacement: Oril3Offset[],
instruction: RS6000Architecture.TargetInstructionFromRS6000Instruction[
instruction: closureCaller.oril3]];
closureCaller.mtspr3 ¬ RS6000Architecture.Mtspr[rt: gpr0, spr: ctr, rc: FALSE];
BreakWorldArchitecture.PokeInstruction[
pc: patchAddress,
displacement: Mtspr3Offset[],
instruction: RS6000Architecture.TargetInstructionFromRS6000Instruction[
instruction: closureCaller.mtspr3]];
{
restoreAddress: RS6000Architecture.RS6000Address ~
RS6000Architecture.RS6000AddressFromDisplacement[
address: patchRS6000Address, displacement: Lm1Offset[]];
restoreAddressCard:
CARD32 ~
LOOPHOLE[restoreAddress];
closureCaller.liu4 ¬ RS6000Architecture.Liu[
rt: gpr0, upper: RS6000Architecture.High[restoreAddressCard]];
BreakWorldArchitecture.PokeInstruction[
pc: patchAddress,
displacement: Liu4Offset[],
instruction: RS6000Architecture.TargetInstructionFromRS6000Instruction[
instruction: closureCaller.liu4]];
closureCaller.oril4 ¬ RS6000Architecture.OrLConst[
ra: gpr0, rs: gpr0, ui: RS6000Architecture.Low[restoreAddressCard]];
BreakWorldArchitecture.PokeInstruction[
pc: patchAddress,
displacement: Oril4Offset[],
instruction: RS6000Architecture.TargetInstructionFromRS6000Instruction[
instruction: closureCaller.oril4]];
};
closureCaller.mtspr4 ¬ RS6000Architecture.Mtspr[rt: gpr0, spr: lr, rc: FALSE];
BreakWorldArchitecture.PokeInstruction[
pc: patchAddress,
displacement: Mtspr4Offset[],
instruction: RS6000Architecture.TargetInstructionFromRS6000Instruction[
instruction: closureCaller.mtspr4]];
closureCaller.bctr ¬ RS6000Architecture.Bctr[];
BreakWorldArchitecture.PokeInstruction[
pc: patchAddress,
displacement: BctrOffset[],
instruction: RS6000Architecture.TargetInstructionFromRS6000Instruction[
instruction: closureCaller.bctr]];
{
blRestoreRegsAddress: RS6000Architecture.RS6000Address ~
RS6000Architecture.RS6000AddressFromDisplacement[
address: patchRS6000Address, displacement: Lm1Offset[]];
restoreRegsAddress: RS6000Architecture.RS6000Address ~
RS6000BreakWorldUtilities.RS6000AddressFromBreakWorldAddress[
address: BreakWorldArchitecture.GetProcAddress[
breakWorld: BreakWorldArchitecture.BreakWorldFromBreakWorldAddress[
address: address],
procName: registerRestoreName]];
IF restoreRegsAddress.IsNullRS6000Address[] THEN {
ERROR Breakpoint.CantSet[
code: $CantFindRegisterRestoreProcedure,
message: "Can't find the register restore procedure"];
};
The registerRestoreName procedure was moved INLINE because it was as cheap as doing an out-of-module call.
Need a mnemonic for 248.
closureCaller.lm1 ¬ RS6000Architecture.Lm[rt: gpr28, offset: 248, ra: gpr1];
BreakWorldArchitecture.PokeInstruction[
pc: patchAddress,
displacement: Lm1Offset[],
instruction: RS6000Architecture.TargetInstructionFromRS6000Instruction[
instruction: closureCaller.lm1]];
closureCaller.mtmq ¬ RS6000Architecture.Mtspr[rt: gpr31, spr: mq, rc: FALSE];
BreakWorldArchitecture.PokeInstruction[
pc: patchAddress, displacement: MtmqOffset[],
instruction: RS6000Architecture.TargetInstructionFromRS6000Instruction[
instruction: closureCaller.mtmq]];
closureCaller.mtxer ¬ RS6000Architecture.Mtspr[rt: gpr30, spr: xfr, rc: FALSE];
BreakWorldArchitecture.PokeInstruction[
pc: patchAddress, displacement: MtxerOffset[],
instruction: RS6000Architecture.TargetInstructionFromRS6000Instruction[
instruction: closureCaller.mtxer]];
closureCaller.mtctr ¬ RS6000Architecture.Mtspr[rt: gpr29, spr: ctr, rc: FALSE];
BreakWorldArchitecture.PokeInstruction[
pc: patchAddress, displacement: MtctrOffset[],
instruction: RS6000Architecture.TargetInstructionFromRS6000Instruction[
instruction: closureCaller.mtctr]];
closureCaller.mtcrf ¬ RS6000Architecture.Mtcrf[fxm: [TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE], rs: gpr28, rc: FALSE];
BreakWorldArchitecture.PokeInstruction[
pc: patchAddress, displacement: MtcrfOffset[],
instruction: RS6000Architecture.TargetInstructionFromRS6000Instruction[
instruction: closureCaller.mtcrf]];
};
{
closureCaller.l ¬ RS6000Architecture.L[rt: gpr0, offset: frameSize-4, ra: gpr1];
BreakWorldArchitecture.PokeInstruction[
pc: patchAddress,
displacement: LOffset[],
instruction: RS6000Architecture.TargetInstructionFromRS6000Instruction[
instruction: closureCaller.l]];
};
{
closureCaller.mtspr ¬ RS6000Architecture.Mtspr[rt: gpr0, spr: ctr, rc: FALSE];
BreakWorldArchitecture.PokeInstruction[
pc: patchAddress,
displacement: MtsprOffset[],
instruction: RS6000Architecture.TargetInstructionFromRS6000Instruction[
instruction: closureCaller.mtspr]];
};
{
closureCaller.lm ¬ RS6000Architecture.Lm[rt: gpr0, offset: gprSaveArea, ra: gpr1];
BreakWorldArchitecture.PokeInstruction[
pc: patchAddress,
displacement: LmOffset[],
instruction: RS6000Architecture.TargetInstructionFromRS6000Instruction[
instruction: closureCaller.lm]];
};
{
closureCaller.ai ¬ RS6000Architecture.Ai[rt: gpr1, ra: gpr1, si: frameSize];
BreakWorldArchitecture.PokeInstruction[
pc: patchAddress,
displacement: AiOffset[],
instruction: RS6000Architecture.TargetInstructionFromRS6000Instruction[
instruction: closureCaller.ai]];
};
};
EXITS
Cannot => {
ERROR Breakpoint.CantSet[code: errorCode, message: errorMessage];
};
};
};
InstallManger:
PROCEDURE [
address: BreakWorldArchitecture.Address, patch: Shepherd.Patch]
RETURNS [] ~ {
IF address.IsNullAddress[]
THEN {
ERROR Breakpoint.CantSet[code: $NullAddress, message: "InstallManger[nullAddress]"];
};
IF patch.IsNullPatch[]
THEN {
ERROR Breakpoint.CantSet[code: $NullPatch, message: "InstallManger[nullPatch]"];
};
{
patchCodeAddress: BreakWorldArchitecture.Address ~ Shepherd.CodeAddressFromPatch[
patch: patch];
mangerAddress: BreakWorldArchitecture.Address ~ BreakWorldArchitecture.AddressFromDisplacement[
address: patchCodeAddress, displacement: MangerOffset[]];
errorCode: RS6000Manger.ErrorCode ¬ RS6000Manger.nullErrorCode;
errorMessage: RS6000Manger.ErrorMessage ¬ RS6000Manger.nullErrorMessage;
{
--Extra scope to contain EXITS.
RS6000Manger.Install[
address: address, manger: mangerAddress, patchCode: patchCodeAddress
! RS6000Manger.CantInstall => {
errorCode ¬ code;
errorMessage ¬ message;
GO TO Cannot;
}];
EXITS
Cannot => {
ERROR Breakpoint.CantSet[code: errorCode, message: errorMessage];
};
};
};
};
ClearBreakpoint: BreakpointPrivate.ClearBreakProcType ~ {
PROCEDURE [break: Break] RETURNS [];
errorCode: Breakpoint.ErrorCode ¬ Breakpoint.nullErrorCode;
errorMessage: Breakpoint.ErrorMessage ¬ Breakpoint.nullErrorMessage;
IF Breakpoint.IsNullBreak[break: break]
THEN {
ERROR Breakpoint.CantClear[code: $NullBreak, message: "Cannot clear null break"];
};
{
-- extra scope for EXITS
address: BreakWorldArchitecture.Address ~ Breakpoint.AddressFromBreak[break: break];
patch: Shepherd.Patch ¬ Breakpoint.PatchFromBreak[break: break];
Uninstall[patch: patch, address: address];
Shepherd.ReleasePatch[patch: patch
! Shepherd.NoMeadow => {
errorCode ¬ $NoMeadow;
errorMessage ¬ message;
GO TO Cannot;
};
Shepherd.BusyMeadow => {
errorCode ¬ $BusyMeadow;
errorMessage ¬ message;
GO TO Cannot;
};];
Breakpoint.ForgetBreak[break: break
! Breakpoint.Cant => {
errorCode ¬ $CantForget;
errorMessage ¬ message;
GO TO Cannot;
}];
EXITS
Cannot => {
ERROR Breakpoint.CantClear[code: errorCode, message: errorMessage];
};
};
};
Uninstall:
PROCEDURE [patch: Shepherd.Patch, address: BreakWorldArchitecture.Address] ~ {
IF patch.IsNullPatch[]
THEN {
ERROR Breakpoint.CantSet[code: $NullPatch, message: "Uninstall[nullPatch]"];
};
IF address.IsNullAddress[]
THEN {
ERROR Breakpoint.CantSet[code: $NullAddress, message: "Uninstall[nullAddress]"];
};
{
patchCodeAddress: BreakWorldArchitecture.Address ~ Shepherd.CodeAddressFromPatch[
patch: patch];
mangerAddress: BreakWorldArchitecture.Address ~ BreakWorldArchitecture.AddressFromDisplacement[
address: patchCodeAddress, displacement: MangerOffset[]];
errorCode: RS6000Manger.ErrorCode ¬ RS6000Manger.nullErrorCode;
errorMessage: RS6000Manger.ErrorMessage ¬ RS6000Manger.nullErrorMessage;
{
-- Extra scope for EXITS
RS6000Manger.Uninstall[
address: address, manger: mangerAddress, patchCode: patchCodeAddress
! RS6000Manger.CantUninstall => {
errorCode ¬ code;
errorMessage ¬ message;
GO TO Cannot;
}];
EXITS
Cannot => {
ERROR Breakpoint.CantClear[code: errorCode, message: errorMessage];
};
};
};
};
PatchStruct offset procedures.
PatchInstrOffset: PROCEDURE []
RETURNS [TargetArchitecture.Displacement] ~ TRUSTED {
patchStruct: RS6000Breakpoint.PatchStruct;
patchStructAddress: LONG POINTER TO RS6000Breakpoint.PatchStruct ~
@patchStruct;
patchStructCard: CARD32 ~ LOOPHOLE[patchStructAddress];
whichInstrAddrCard: CARD32 ~ LOOPHOLE[whichInstrAddr];
offset: TargetArchitecture.Displacement ~
(whichInstrAddrCard - patchStructCard) * BYTES[UNIT];
RETURN [offset];
}
StuOffset:
PROCEDURE []
RETURNS [TargetArchitecture.Displacement] ~
TRUSTED {
patchStruct: RS6000Breakpoint.PatchStruct;
patchStructAddress:
LONG
POINTER
TO RS6000Breakpoint.PatchStruct ~
@patchStruct;
patchStructCard: CARD32 ~ LOOPHOLE[patchStructAddress];
stuAddress:
LONG
POINTER
TO RS6000Architecture.RS6000Instruction ~
@patchStruct.closureCaller.stu;
stuCard: CARD32 ~ LOOPHOLE[stuAddress];
offset: TargetArchitecture.Displacement ~
(stuCard - patchStructCard) * BYTES[UNIT];
RETURN [offset];
};
StmOffset:
PROCEDURE []
RETURNS [TargetArchitecture.Displacement] ~
TRUSTED {
patchStruct: RS6000Breakpoint.PatchStruct;
patchStructAddress:
LONG
POINTER
TO RS6000Breakpoint.PatchStruct ~
@patchStruct;
patchStructCard: CARD32 ~ LOOPHOLE[patchStructAddress];
stmAddress:
LONG
POINTER
TO RS6000Architecture.RS6000Instruction ~
@patchStruct.closureCaller.stm;
stmCard: CARD32 ~ LOOPHOLE[stmAddress];
offset: TargetArchitecture.Displacement ~
(stmCard - patchStructCard) * BYTES[UNIT];
RETURN [offset];
};
MfsprOffset:
PROCEDURE []
RETURNS [TargetArchitecture.Displacement] ~
TRUSTED {
patchStruct: RS6000Breakpoint.PatchStruct;
patchStructAddress:
LONG
POINTER
TO RS6000Breakpoint.PatchStruct ~
@patchStruct;
patchStructCard: CARD32 ~ LOOPHOLE[patchStructAddress];
mfsprAddress:
LONG
POINTER
TO RS6000Architecture.RS6000Instruction ~
@patchStruct.closureCaller.mfspr;
mfsprCard: CARD32 ~ LOOPHOLE[mfsprAddress];
offset: TargetArchitecture.Displacement ~
(mfsprCard - patchStructCard) * BYTES[UNIT];
RETURN [offset];
};
StOffset:
PROCEDURE []
RETURNS [TargetArchitecture.Displacement] ~
TRUSTED {
patchStruct: RS6000Breakpoint.PatchStruct;
patchStructAddress:
LONG
POINTER
TO RS6000Breakpoint.PatchStruct ~
@patchStruct;
patchStructCard: CARD32 ~ LOOPHOLE[patchStructAddress];
stAddress:
LONG
POINTER
TO RS6000Architecture.RS6000Instruction ~
@patchStruct.closureCaller.st;
stCard: CARD32 ~ LOOPHOLE[stAddress];
offset: TargetArchitecture.Displacement ~
(stCard - patchStructCard) * BYTES[UNIT];
RETURN [offset];
};
Liu0Offset:
PROCEDURE []
RETURNS [TargetArchitecture.Displacement] ~
TRUSTED {
patchStruct: RS6000Breakpoint.PatchStruct;
patchStructAddress:
LONG
POINTER
TO RS6000Breakpoint.PatchStruct ~
@patchStruct;
patchStructCard: CARD32 ~ LOOPHOLE[patchStructAddress];
liu0Address:
LONG
POINTER
TO RS6000Architecture.RS6000Instruction ~
@patchStruct.closureCaller.liu0;
liu0Card: CARD32 ~ LOOPHOLE[liu0Address];
offset: TargetArchitecture.Displacement ~
(liu0Card - patchStructCard) * BYTES[UNIT];
RETURN [offset];
};
Oril0Offset:
PROCEDURE []
RETURNS [TargetArchitecture.Displacement] ~
TRUSTED {
patchStruct: RS6000Breakpoint.PatchStruct;
patchStructAddress:
LONG
POINTER
TO RS6000Breakpoint.PatchStruct ~
@patchStruct;
patchStructCard: CARD32 ~ LOOPHOLE[patchStructAddress];
oril0Address:
LONG
POINTER
TO RS6000Architecture.RS6000Instruction ~
@patchStruct.closureCaller.oril0;
oril0Card: CARD32 ~ LOOPHOLE[oril0Address];
offset: TargetArchitecture.Displacement ~
(oril0Card - patchStructCard) * BYTES[UNIT];
RETURN [offset];
};
St0Offset:
PROCEDURE []
RETURNS [TargetArchitecture.Displacement] ~
TRUSTED {
patchStruct: RS6000Breakpoint.PatchStruct;
patchStructAddress:
LONG
POINTER
TO RS6000Breakpoint.PatchStruct ~
@patchStruct;
patchStructCard: CARD32 ~ LOOPHOLE[patchStructAddress];
st0Address:
LONG
POINTER
TO RS6000Architecture.RS6000Instruction ~
@patchStruct.closureCaller.st0;
st0Card: CARD32 ~ LOOPHOLE[st0Address];
offset: TargetArchitecture.Displacement ~
(st0Card - patchStructCard) * BYTES[UNIT];
RETURN [offset];
};
BlOffset: PROCEDURE []
RETURNS [TargetArchitecture.Displacement] ~ TRUSTED {
patchStruct: RS6000Breakpoint.PatchStruct;
patchStructAddress: LONG POINTER TO RS6000Breakpoint.PatchStruct ~
@patchStruct;
patchStructCard: CARD32 ~ LOOPHOLE[patchStructAddress];
blAddress: LONG POINTER TO RS6000Architecture.RS6000Instruction ~
@patchStruct.closureCaller.bl;
blCard: CARD32 ~ LOOPHOLE[blAddress];
offset: TargetArchitecture.Displacement ~
(blCard - patchStructCard) * BYTES[UNIT];
RETURN [offset];
};
MfmqOffset:
PROCEDURE []
RETURNS [TargetArchitecture.Displacement] ~
TRUSTED {
patchStruct: RS6000Breakpoint.PatchStruct;
patchStructAddress:
LONG
POINTER
TO RS6000Breakpoint.PatchStruct ~
@patchStruct;
patchStructCard: CARD32 ~ LOOPHOLE[patchStructAddress];
mfmqAddress:
LONG
POINTER
TO RS6000Architecture.RS6000Instruction ~
@patchStruct.closureCaller.mfmq;
mfmqCard: CARD32 ~ LOOPHOLE[mfmqAddress];
offset: TargetArchitecture.Displacement ~
(mfmqCard - patchStructCard) * BYTES[UNIT];
RETURN [offset];
};
MfxerOffset:
PROCEDURE []
RETURNS [TargetArchitecture.Displacement] ~
TRUSTED {
patchStruct: RS6000Breakpoint.PatchStruct;
patchStructAddress:
LONG
POINTER
TO RS6000Breakpoint.PatchStruct ~
@patchStruct;
patchStructCard: CARD32 ~ LOOPHOLE[patchStructAddress];
mfxerAddress:
LONG
POINTER
TO RS6000Architecture.RS6000Instruction ~
@patchStruct.closureCaller.mfxer;
mfxerCard: CARD32 ~ LOOPHOLE[mfxerAddress];
offset: TargetArchitecture.Displacement ~
(mfxerCard - patchStructCard) * BYTES[UNIT];
RETURN [offset];
};
MfctrOffset:
PROCEDURE []
RETURNS [TargetArchitecture.Displacement] ~
TRUSTED {
patchStruct: RS6000Breakpoint.PatchStruct;
patchStructAddress:
LONG
POINTER
TO RS6000Breakpoint.PatchStruct ~
@patchStruct;
patchStructCard: CARD32 ~ LOOPHOLE[patchStructAddress];
mfctrAddress:
LONG
POINTER
TO RS6000Architecture.RS6000Instruction ~
@patchStruct.closureCaller.mfctr;
mfctrCard: CARD32 ~ LOOPHOLE[mfctrAddress];
offset: TargetArchitecture.Displacement ~
(mfctrCard - patchStructCard) * BYTES[UNIT];
RETURN [offset];
};
MfcrOffset:
PROCEDURE []
RETURNS [TargetArchitecture.Displacement] ~
TRUSTED {
patchStruct: RS6000Breakpoint.PatchStruct;
patchStructAddress:
LONG
POINTER
TO RS6000Breakpoint.PatchStruct ~
@patchStruct;
patchStructCard: CARD32 ~ LOOPHOLE[patchStructAddress];
mfcrAddress:
LONG
POINTER
TO RS6000Architecture.RS6000Instruction ~
@patchStruct.closureCaller.mfcr;
mfcrCard: CARD32 ~ LOOPHOLE[mfcrAddress];
offset: TargetArchitecture.Displacement ~
(mfcrCard - patchStructCard) * BYTES[UNIT];
RETURN [offset];
};
Stm1Offset:
PROCEDURE []
RETURNS [TargetArchitecture.Displacement] ~
TRUSTED {
patchStruct: RS6000Breakpoint.PatchStruct;
patchStructAddress:
LONG
POINTER
TO RS6000Breakpoint.PatchStruct ~
@patchStruct;
patchStructCard: CARD32 ~ LOOPHOLE[patchStructAddress];
stm1Address:
LONG
POINTER
TO RS6000Architecture.RS6000Instruction ~
@patchStruct.closureCaller.stm1;
stm1Card: CARD32 ~ LOOPHOLE[stm1Address];
offset: TargetArchitecture.Displacement ~
(stm1Card - patchStructCard) * BYTES[UNIT];
RETURN [offset];
};
MtmqOffset:
PROCEDURE []
RETURNS [TargetArchitecture.Displacement] ~
TRUSTED {
patchStruct: RS6000Breakpoint.PatchStruct;
patchStructAddress:
LONG
POINTER
TO RS6000Breakpoint.PatchStruct ~
@patchStruct;
patchStructCard: CARD32 ~ LOOPHOLE[patchStructAddress];
mtmqAddress:
LONG
POINTER
TO RS6000Architecture.RS6000Instruction ~
@patchStruct.closureCaller.mtmq;
mtmqCard: CARD32 ~ LOOPHOLE[mtmqAddress];
offset: TargetArchitecture.Displacement ~
(mtmqCard - patchStructCard) * BYTES[UNIT];
RETURN [offset];
};
MtxerOffset:
PROCEDURE []
RETURNS [TargetArchitecture.Displacement] ~
TRUSTED {
patchStruct: RS6000Breakpoint.PatchStruct;
patchStructAddress:
LONG
POINTER
TO RS6000Breakpoint.PatchStruct ~
@patchStruct;
patchStructCard: CARD32 ~ LOOPHOLE[patchStructAddress];
mtxerAddress:
LONG
POINTER
TO RS6000Architecture.RS6000Instruction ~
@patchStruct.closureCaller.mtxer;
mtxerCard: CARD32 ~ LOOPHOLE[mtxerAddress];
offset: TargetArchitecture.Displacement ~
(mtxerCard - patchStructCard) * BYTES[UNIT];
RETURN [offset];
};
MtctrOffset:
PROCEDURE []
RETURNS [TargetArchitecture.Displacement] ~
TRUSTED {
patchStruct: RS6000Breakpoint.PatchStruct;
patchStructAddress:
LONG
POINTER
TO RS6000Breakpoint.PatchStruct ~
@patchStruct;
patchStructCard: CARD32 ~ LOOPHOLE[patchStructAddress];
mtctrAddress:
LONG
POINTER
TO RS6000Architecture.RS6000Instruction ~
@patchStruct.closureCaller.mtctr;
mtctrCard: CARD32 ~ LOOPHOLE[mtctrAddress];
offset: TargetArchitecture.Displacement ~
(mtctrCard - patchStructCard) * BYTES[UNIT];
RETURN [offset];
};
MtcrfOffset:
PROCEDURE []
RETURNS [TargetArchitecture.Displacement] ~
TRUSTED {
patchStruct: RS6000Breakpoint.PatchStruct;
patchStructAddress:
LONG
POINTER
TO RS6000Breakpoint.PatchStruct ~
@patchStruct;
patchStructCard: CARD32 ~ LOOPHOLE[patchStructAddress];
mtcrfAddress:
LONG
POINTER
TO RS6000Architecture.RS6000Instruction ~
@patchStruct.closureCaller.mtcrf;
mtcrfCard: CARD32 ~ LOOPHOLE[mtcrfAddress];
offset: TargetArchitecture.Displacement ~
(mtcrfCard - patchStructCard) * BYTES[UNIT];
RETURN [offset];
};
LiuOffset:
PROCEDURE []
RETURNS [TargetArchitecture.Displacement] ~
TRUSTED {
patchStruct: RS6000Breakpoint.PatchStruct;
patchStructAddress:
LONG
POINTER
TO RS6000Breakpoint.PatchStruct ~
@patchStruct;
patchStructCard: CARD32 ~ LOOPHOLE[patchStructAddress];
liuAddress:
LONG
POINTER
TO RS6000Architecture.RS6000Instruction ~
@patchStruct.closureCaller.liu;
liuCard: CARD32 ~ LOOPHOLE[liuAddress];
offset: TargetArchitecture.Displacement ~
(liuCard - patchStructCard) * BYTES[UNIT];
RETURN [offset];
};
OrilOffset:
PROCEDURE []
RETURNS [TargetArchitecture.Displacement] ~
TRUSTED {
patchStruct: RS6000Breakpoint.PatchStruct;
patchStructAddress:
LONG
POINTER
TO RS6000Breakpoint.PatchStruct ~
@patchStruct;
patchStructCard: CARD32 ~ LOOPHOLE[patchStructAddress];
orilAddress:
LONG
POINTER
TO RS6000Architecture.RS6000Instruction ~
@patchStruct.closureCaller.oril;
orilCard: CARD32 ~ LOOPHOLE[orilAddress];
offset: TargetArchitecture.Displacement ~
(orilCard - patchStructCard) * BYTES[UNIT];
RETURN [offset];
};
Liu2Offset:
PROCEDURE []
RETURNS [TargetArchitecture.Displacement] ~
TRUSTED {
patchStruct: RS6000Breakpoint.PatchStruct;
patchStructAddress:
LONG
POINTER
TO RS6000Breakpoint.PatchStruct ~
@patchStruct;
patchStructCard: CARD32 ~ LOOPHOLE[patchStructAddress];
liu2Address:
LONG
POINTER
TO RS6000Architecture.RS6000Instruction ~
@patchStruct.closureCaller.liu2;
liu2Card: CARD32 ~ LOOPHOLE[liu2Address];
offset: TargetArchitecture.Displacement ~
(liu2Card - patchStructCard) * BYTES[UNIT];
RETURN [offset];
};
Oril2Offset:
PROCEDURE []
RETURNS [TargetArchitecture.Displacement] ~
TRUSTED {
patchStruct: RS6000Breakpoint.PatchStruct;
patchStructAddress:
LONG
POINTER
TO RS6000Breakpoint.PatchStruct ~
@patchStruct;
patchStructCard: CARD32 ~ LOOPHOLE[patchStructAddress];
oril2Address:
LONG
POINTER
TO RS6000Architecture.RS6000Instruction ~
@patchStruct.closureCaller.oril2;
oril2Card: CARD32 ~ LOOPHOLE[oril2Address];
offset: TargetArchitecture.Displacement ~
(oril2Card - patchStructCard) * BYTES[UNIT];
RETURN [offset];
};
Bl2Offset: PROCEDURE []
RETURNS [TargetArchitecture.Displacement] ~ TRUSTED {
patchStruct: RS6000Breakpoint.PatchStruct;
patchStructAddress: LONG POINTER TO RS6000Breakpoint.PatchStruct ~
@patchStruct;
patchStructCard: CARD32 ~ LOOPHOLE[patchStructAddress];
bl2Address: LONG POINTER TO RS6000Architecture.RS6000Instruction ~
@patchStruct.closureCaller.bl2;
bl2Card: CARD32 ~ LOOPHOLE[bl2Address];
offset: TargetArchitecture.Displacement ~
(bl2Card - patchStructCard) * BYTES[UNIT];
RETURN [offset];
};
Liu3Offset:
PROCEDURE []
RETURNS [TargetArchitecture.Displacement] ~
TRUSTED {
patchStruct: RS6000Breakpoint.PatchStruct;
patchStructAddress:
LONG
POINTER
TO RS6000Breakpoint.PatchStruct ~
@patchStruct;
patchStructCard: CARD32 ~ LOOPHOLE[patchStructAddress];
liu3Address:
LONG
POINTER
TO RS6000Architecture.RS6000Instruction ~
@patchStruct.closureCaller.liu3;
liu3Card: CARD32 ~ LOOPHOLE[liu3Address];
offset: TargetArchitecture.Displacement ~
(liu3Card - patchStructCard) * BYTES[UNIT];
RETURN [offset];
};
Oril3Offset:
PROCEDURE []
RETURNS [TargetArchitecture.Displacement] ~
TRUSTED {
patchStruct: RS6000Breakpoint.PatchStruct;
patchStructAddress:
LONG
POINTER
TO RS6000Breakpoint.PatchStruct ~
@patchStruct;
patchStructCard: CARD32 ~ LOOPHOLE[patchStructAddress];
oril3Address:
LONG
POINTER
TO RS6000Architecture.RS6000Instruction ~
@patchStruct.closureCaller.oril3;
oril3Card: CARD32 ~ LOOPHOLE[oril3Address];
offset: TargetArchitecture.Displacement ~
(oril3Card - patchStructCard) * BYTES[UNIT];
RETURN [offset];
};
Mtspr3Offset:
PROCEDURE []
RETURNS [TargetArchitecture.Displacement] ~
TRUSTED {
patchStruct: RS6000Breakpoint.PatchStruct;
patchStructAddress:
LONG
POINTER
TO RS6000Breakpoint.PatchStruct ~
@patchStruct;
patchStructCard: CARD32 ~ LOOPHOLE[patchStructAddress];
mtspr3Address:
LONG
POINTER
TO RS6000Architecture.RS6000Instruction ~
@patchStruct.closureCaller.mtspr3;
mtspr3Card: CARD32 ~ LOOPHOLE[mtspr3Address];
offset: TargetArchitecture.Displacement ~
(mtspr3Card - patchStructCard) * BYTES[UNIT];
RETURN [offset];
};
Liu4Offset:
PROCEDURE []
RETURNS [TargetArchitecture.Displacement] ~
TRUSTED {
patchStruct: RS6000Breakpoint.PatchStruct;
patchStructAddress:
LONG
POINTER
TO RS6000Breakpoint.PatchStruct ~
@patchStruct;
patchStructCard: CARD32 ~ LOOPHOLE[patchStructAddress];
liu4Address:
LONG
POINTER
TO RS6000Architecture.RS6000Instruction ~
@patchStruct.closureCaller.liu4;
liu4Card: CARD32 ~ LOOPHOLE[liu4Address];
offset: TargetArchitecture.Displacement ~
(liu4Card - patchStructCard) * BYTES[UNIT];
RETURN [offset];
};
Oril4Offset:
PROCEDURE []
RETURNS [TargetArchitecture.Displacement] ~
TRUSTED {
patchStruct: RS6000Breakpoint.PatchStruct;
patchStructAddress:
LONG
POINTER
TO RS6000Breakpoint.PatchStruct ~
@patchStruct;
patchStructCard: CARD32 ~ LOOPHOLE[patchStructAddress];
oril4Address:
LONG
POINTER
TO RS6000Architecture.RS6000Instruction ~
@patchStruct.closureCaller.oril4;
oril4Card: CARD32 ~ LOOPHOLE[oril4Address];
offset: TargetArchitecture.Displacement ~
(oril4Card - patchStructCard) * BYTES[UNIT];
RETURN [offset];
};
Mtspr4Offset:
PROCEDURE []
RETURNS [TargetArchitecture.Displacement] ~
TRUSTED {
patchStruct: RS6000Breakpoint.PatchStruct;
patchStructAddress:
LONG
POINTER
TO RS6000Breakpoint.PatchStruct ~
@patchStruct;
patchStructCard: CARD32 ~ LOOPHOLE[patchStructAddress];
mtspr4Address:
LONG
POINTER
TO RS6000Architecture.RS6000Instruction ~
@patchStruct.closureCaller.mtspr4;
mtspr4Card: CARD32 ~ LOOPHOLE[mtspr4Address];
offset: TargetArchitecture.Displacement ~
(mtspr4Card - patchStructCard) * BYTES[UNIT];
RETURN [offset];
};
BctrOffset:
PROCEDURE []
RETURNS [TargetArchitecture.Displacement] ~
TRUSTED {
patchStruct: RS6000Breakpoint.PatchStruct;
patchStructAddress:
LONG
POINTER
TO RS6000Breakpoint.PatchStruct ~
@patchStruct;
patchStructCard: CARD32 ~ LOOPHOLE[patchStructAddress];
bctrAddress:
LONG
POINTER
TO RS6000Architecture.RS6000Instruction ~
@patchStruct.closureCaller.bctr;
bctrCard: CARD32 ~ LOOPHOLE[bctrAddress];
offset: TargetArchitecture.Displacement ~
(bctrCard - patchStructCard) * BYTES[UNIT];
RETURN [offset];
};
Lm1Offset:
PROCEDURE []
RETURNS [TargetArchitecture.Displacement] ~
TRUSTED {
patchStruct: RS6000Breakpoint.PatchStruct;
patchStructAddress:
LONG
POINTER
TO RS6000Breakpoint.PatchStruct ~
@patchStruct;
patchStructCard: CARD32 ~ LOOPHOLE[patchStructAddress];
lm1Address:
LONG
POINTER
TO RS6000Architecture.RS6000Instruction ~
@patchStruct.closureCaller.lm1;
lm1Card: CARD32 ~ LOOPHOLE[lm1Address];
offset: TargetArchitecture.Displacement ~
(lm1Card - patchStructCard) * BYTES[UNIT];
RETURN [offset];
};
LOffset:
PROCEDURE []
RETURNS [TargetArchitecture.Displacement] ~
TRUSTED {
patchStruct: RS6000Breakpoint.PatchStruct;
patchStructAddress:
LONG
POINTER
TO RS6000Breakpoint.PatchStruct ~
@patchStruct;
patchStructCard: CARD32 ~ LOOPHOLE[patchStructAddress];
lAddress:
LONG
POINTER
TO RS6000Architecture.RS6000Instruction ~
@patchStruct.closureCaller.l;
lCard: CARD32 ~ LOOPHOLE[lAddress];
offset: TargetArchitecture.Displacement ~
(lCard - patchStructCard) * BYTES[UNIT];
RETURN [offset];
};
MtsprOffset:
PROCEDURE []
RETURNS [TargetArchitecture.Displacement] ~
TRUSTED {
patchStruct: RS6000Breakpoint.PatchStruct;
patchStructAddress:
LONG
POINTER
TO RS6000Breakpoint.PatchStruct ~
@patchStruct;
patchStructCard: CARD32 ~ LOOPHOLE[patchStructAddress];
mtsprAddress:
LONG
POINTER
TO RS6000Architecture.RS6000Instruction ~
@patchStruct.closureCaller.mtspr;
mtsprCard: CARD32 ~ LOOPHOLE[mtsprAddress];
offset: TargetArchitecture.Displacement ~
(mtsprCard - patchStructCard) * BYTES[UNIT];
RETURN [offset];
};
LmOffset:
PROCEDURE []
RETURNS [TargetArchitecture.Displacement] ~
TRUSTED {
patchStruct: RS6000Breakpoint.PatchStruct;
patchStructAddress:
LONG
POINTER
TO RS6000Breakpoint.PatchStruct ~
@patchStruct;
patchStructCard: CARD32 ~ LOOPHOLE[patchStructAddress];
lmAddress:
LONG
POINTER
TO RS6000Architecture.RS6000Instruction ~
@patchStruct.closureCaller.lm;
lmCard: CARD32 ~ LOOPHOLE[lmAddress];
offset: TargetArchitecture.Displacement ~
(lmCard - patchStructCard) * BYTES[UNIT];
RETURN [offset];
};
AiOffset:
PROCEDURE []
RETURNS [TargetArchitecture.Displacement] ~
TRUSTED {
patchStruct: RS6000Breakpoint.PatchStruct;
patchStructAddress:
LONG
POINTER
TO RS6000Breakpoint.PatchStruct ~
@patchStruct;
patchStructCard: CARD32 ~ LOOPHOLE[patchStructAddress];
aiAddress:
LONG
POINTER
TO RS6000Architecture.RS6000Instruction ~
@patchStruct.closureCaller.ai;
aiCard: CARD32 ~ LOOPHOLE[aiAddress];
offset: TargetArchitecture.Displacement ~
(aiCard - patchStructCard) * BYTES[UNIT];
RETURN [offset];
};
MangerOffset:
PROCEDURE []
RETURNS [TargetArchitecture.Displacement] ~
TRUSTED {
patchStruct: RS6000Breakpoint.PatchStruct;
patchStructAddress:
LONG
POINTER
TO RS6000Breakpoint.PatchStruct ~
@patchStruct;
patchStructCard: CARD32 ~ LOOPHOLE[patchStructAddress];
mangerAddress:
LONG
POINTER
TO RS6000Manger.Manger ~
@patchStruct.manger;
mangerCard: CARD32 ~ LOOPHOLE[mangerAddress];
offset: TargetArchitecture.Displacement ~
(mangerCard - patchStructCard) * BYTES[UNIT];
RETURN [offset];
};
Main code
BreakpointPrivate.RegisterTargetBreaks[
NEW[BreakpointPrivate.TargetBreaksBody ¬ [
"RS6000",
SetBreakpoint,
ClearBreakpoint]]];
}.