RS6000BreakpointImpl.mesa
Copyright Ó 1989, 1990, 1991, 1992, 1993 by Xerox Corporation. All rights reserved.
Peter B. Kessler, July 11, 1990 11:06 am PDT
Target-dependent implementation of the functions from Breakpoint.
Udagawa, August 14, 1991 12:46 pm PDT
Laurie Horton, February 26, 1993 12:08 pm PST
Katsuyuki Komatsu March 5, 1992 5:51 pm PST
DIRECTORY
Breakpoint,
BreakpointPrivate,
BreakWorldArchitecture,
Rope USING [ROPE],
RS6000Architecture,
RS6000Breakpoint,
RS6000BreakWorldUtilities,
RS6000Manger,
Shepherd,
TargetArchitecture;
RS6000BreakpointImpl: CEDAR PROGRAM
IMPORTS
Breakpoint, BreakpointPrivate, BreakWorldArchitecture, RS6000Architecture, RS6000BreakWorldUtilities, RS6000Manger, Shepherd, TargetArchitecture
~ {
"Public" Procedures registered with Breakpoint.
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]]];
}.