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 ~ { SetBreakpoint: BreakpointPrivate.SetBreakProcType ~ { break: Breakpoint.Break ¬ Breakpoint.nullBreak; patch: Shepherd.Patch ¬ Shepherd.nullPatch; errorCode: Breakpoint.ErrorCode ¬ Breakpoint.nullErrorCode; errorMessage: Breakpoint.ErrorMessage ¬ Breakpoint.nullErrorMessage; 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"]; }; }; { -- 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 => { 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"; 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]]; }; { 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]]; 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]]; }; { 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.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]]; }; { 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 ~ { 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]; }; }; }; }; 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]; }; 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]; }; 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]; }; BreakpointPrivate.RegisterTargetBreaks[NEW[BreakpointPrivate.TargetBreaksBody ¬ [ "RS6000", SetBreakpoint, ClearBreakpoint]]]; }. ζ 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 "Public" Procedures registered with Breakpoint. 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] 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; }; CheckForDelaySlot[address: address]; -- 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]; }; Generate the code in the patch. 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. Need to construct a mnemonic constant for 248. blClientProcAddress: RS6000Architecture.RS6000Address ~ RS6000Architecture.RS6000AddressFromDisplacement[ address: patchRS6000Address, displacement: Bl2Offset[]]; closureCaller.bl2 _ RS6000Architecture.B[pc: blClientProcAddress, to: clientProcAddress, abs: FALSE, link: TRUE]; BreakWorldArchitecture.PokeInstruction[ pc: patchAddress, displacement: Bl2Offset[], instruction: RS6000Architecture.TargetInstructionFromRS6000Instruction[ instruction: closureCaller.bl2]]; 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. PROCEDURE [break: Break] RETURNS []; 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]; } 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]; }; 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]; }; Main code Κ(–"cedarcode" style•NewlineDelimiter ™unit™Icodešœ ΠerœI™TLšœ,™,L™L™AL™%L™-L™+L™šΟk ˜ L˜Lšœ ˜ Lšœ˜Lšœ˜Lšœžœžœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ ˜ Lšœ ˜ Lšœ˜L˜L˜——šΠlnœžœžœ˜$šžœ˜L–0 bp restIndentšœ˜—L˜Lšœ˜Ihead™/šΟn œ(˜5Lšž œ™žœ™ΌL˜/L˜+L˜;L˜Dš œž œ,žœ™U™3LšœS™S—™7šœA™ALšœ!žœ(™N——™7šœA™ALšœ!žœ(™N——šžœKžœ™Sšžœ™LšœG™G—L™—Lšžœ™L™—L˜šžœžœ˜!šžœ˜LšœK˜K—L˜—šžœžœ˜#šžœ˜Lšœ˜LšœJ˜J—L˜—˜˜5L˜/—L˜šžœ(žœ˜0šžœ˜Lšœ˜LšœK˜K—L˜—L˜—L™$šœΟc˜!˜Lšœžœ˜:šœ˜L˜L˜Lšžœžœ˜ Lšœ˜—šœ˜L˜L˜Lšžœžœ˜ Lšœ˜—šœ˜L˜L˜Lšžœžœ˜ Lšœ˜—šœ˜L˜L˜Lšžœžœ˜ Lšœ˜—šœ˜L˜L˜Lšžœžœ˜ Lšœ˜—Lšœ˜—šœ˜Lšœ˜Lšœ ˜ Lšœ˜Lšœ#˜#Lšœ˜Lšœ˜—L˜T˜˜L˜L˜Lšžœžœ˜ L˜——šž˜˜ ™J™@—šžœžœžœ™!Jšœ$™$J™—Lšžœ<˜AL˜——L˜—Lšžœ ˜Lšœ˜L˜š œž œβžœ˜‚šžœžœ˜!LšžœI˜NL˜—šžœžœ˜LšžœE˜JL˜—šžœžœ˜#LšžœK˜PL˜—šœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜Lšœ˜—Lšœ.˜.L˜L˜—š œž œήžœ˜‹šžœžœ˜!šžœ˜LšœB˜B—L˜—šžœžœ˜#šžœ˜LšœD˜D—L˜—šžœžœ˜šžœ˜Lšœ>˜>—L˜—˜˜6LšœO˜O—Lšœžœžœ˜>šœ.˜.LšœT˜T—Lšœžœžœ ˜.Lšœ[˜[˜7LšœT˜T—šœ žœ˜Lšœ&˜&Lšœ0˜0Lšœ/˜/Lšœ$˜$—šœ žœ˜Lšœ-˜-Lšœ/˜/Lšœ$˜$—šœ5˜5LšœV˜V—šœžœžœž˜:L• CharProps8PostfixXeroxCharCodesPostfixXeroxCharCodesšœ˜L–8PostfixXeroxCharCodesPostfixXeroxCharCodes šœ ˜ L–8PostfixXeroxCharCodesPostfixXeroxCharCodesšœ#˜#L–PostfixXeroxCharCodesšžœ˜—šœžœžœž˜=L–8PostfixXeroxCharCodesPostfixXeroxCharCodesšœ˜L–8PostfixXeroxCharCodesPostfixXeroxCharCodes šœ#˜#L–8PostfixXeroxCharCodesPostfixXeroxCharCodesšœ&˜&L–PostfixXeroxCharCodesšžœ˜—L˜L™Lšœ.˜.L˜L˜;L˜D˜šœž˜ ˜$L˜L˜ELšžœžœ˜ L˜—˜!L˜L˜LLšžœžœ˜ L˜—˜)L˜L˜cLšžœžœ˜ L˜—˜-L˜L˜jLšžœžœ˜ L˜—L˜——L˜˜L˜Sšœ'˜'Lšœ˜Lšœ˜šœG˜GLšœ!˜!——L˜—˜L˜Tšœ'˜'Lšœ˜Lšœ˜šœG˜GLšœ!˜!——L˜—˜LšœFžœ˜Mšœ'˜'Lšœ˜Lšœ˜šœG˜GLšœ#˜#——L˜—L˜˜L˜Ršœ'˜'Lšœ,˜,šœG˜GLšœ ˜ ——L˜—˜˜,LšœB˜B—šœ'˜'Lšœ˜Lšœ˜šœG˜GLšœ"˜"——L˜—˜˜2LšœH˜H—šœ'˜'Lšœ˜Lšœ˜šœG˜GLšœ#˜#——L˜—˜L˜Sšœ'˜'Lšœ-˜-šœG˜GLšœ!˜!——L˜—˜šœ6™6šœ1™1Lšœ7™7——šœ4™4šœ=™=šœ/™/šœC™CLšœ™—Lšœ™———L™šžœ'žœ™/šžœ™Lšœ&™&Lšœ3™3—L™——™LšœYžœžœ™lšœ'™'Lšœ™Lšœ™šœG™GLšœ ™ ——L™L™fL™LšœFžœ˜Mšœ'˜'L˜.šœG˜GL˜"——L™LšœHžœ˜Ošœ'˜'L˜/šœG˜GL˜#L˜——LšœHžœ˜Ošœ'˜'L˜/šœG˜GL˜#——L˜Lšœ<žœ˜Cšœ'˜'L˜.šœG˜GL˜"L˜——L™.L˜Nšœ'˜'L˜.šœG˜GL˜"——L˜L˜—˜˜+Lšœ:˜:—šœ'˜'Lšœ˜Lšœ˜šœG˜GLšœ!˜!——L˜—˜˜1Lšœ@˜@—šœ'˜'Lšœ˜Lšœ˜šœG˜GLšœ"˜"——L˜—˜˜,Lšœ5˜5—šœ'˜'Lšœ˜Lšœ˜šœG˜GLšœ"˜"——L˜—˜˜2Lšœ;˜;—šœ'˜'Lšœ˜Lšœ˜šœG˜GLšœ#˜#——L˜—˜šœ8™8šœ1™1Lšœ8™8——šœ6˜6šœ=˜=Lšœ˜——Lšœžœžœ˜—šœ'˜'Lšœ˜L˜šœG˜GL˜"——L˜˜2L˜D—šœ'˜'Lšœ˜L˜šœG˜GL˜#——L˜L˜LšœGžœ˜Nšœ'˜'Lšœ˜L˜šœG˜GL˜$——L˜L˜/šœ'˜'Lšœ˜L˜šœG˜GL˜"———˜L˜L™—˜šœ9™9šœ1™1L™8——šœ7™7šœ=™=šœ/™/šœC™CLšœ™—Lšœ ™ ———L™šžœ*žœ™2šžœ™Lšœ)™)Lšœ6™6—L™——™L™jL™L™L˜Lšœ'˜'Lšœ˜L˜šœG˜GL˜!L˜——LšœFžœ˜Mšœ'˜'L˜.šœG˜GL˜"L˜——LšœHžœ˜Ošœ'˜'L˜/šœG˜GL˜#——L˜LšœHžœ˜Ošœ'˜'L˜/šœG˜GL˜#——L˜Lšœ5žœžœžœžœžœžœžœžœžœ˜|šœ'˜'L˜/šœG˜GL˜#——L˜—˜L˜Pšœ'˜'Lšœ˜Lšœ˜šœG˜GLšœ˜——L˜—˜LšœGžœ˜Nšœ'˜'Lšœ˜Lšœ˜šœG˜GLšœ#˜#——L˜—˜L˜Ršœ'˜'Lšœ˜Lšœ˜šœG˜GLšœ ˜ ——L˜—˜L˜Lšœ'˜'Lšœ˜Lšœ˜šœG˜GLšœ ˜ ——L˜—L˜—šž˜˜ Lšžœ<˜AL˜—L˜—L˜—˜L˜—š  œž œCžœ˜išžœžœ˜!LšžœO˜TL˜—šžœžœ˜LšžœK˜PL˜—˜šœQ˜QLšœ˜—šœ_˜_Lšœ9˜9—L˜?L˜HL˜šœ‘˜!šœ˜LšœD˜Dšœ˜L˜L˜Lšžœžœ˜ Lšœ˜——šž˜˜ Lšžœ<˜AL˜——L˜—L˜—L˜L˜—š œ*˜9Jšž œžœ™$L˜;L˜Dšžœ&žœ˜.LšžœL˜QL˜—šœ‘˜LšœT˜TL˜@L˜Lšœ*˜*šœ"˜"˜L˜L˜Lšžœžœ˜ L˜—˜L˜L˜Lšžœžœ˜ L˜——šœ#˜#šœ˜L˜L˜Lšžœžœ˜ L˜——šž˜˜ Lšžœ>˜CL˜——Lšœ˜—Lšœ˜L˜—š  œž œE˜Yšžœžœ˜LšžœG˜LL˜—šžœžœ˜!LšžœK˜PL˜—˜šœQ˜QLšœ˜—šœ_˜_Lšœ9˜9—L˜?L˜HL˜šœ‘˜šœ˜LšœD˜D˜!L˜L˜Lšžœžœ˜ L˜——šž˜šœ ˜ Lšžœ>˜CLšœ˜——L˜—L˜—L˜L˜——™š œž œžœ%žœ™UL™*šœžœžœžœ ™CL™ —Lšœžœžœ™7Lšœžœžœ™6šœ)™)Lšœ)žœžœ™5—L™Lšžœ ™L™—š  œž œžœ%žœ˜NLšœ*˜*šœžœžœžœ ˜CLšœ ˜ —Lšœžœžœ˜7šœ žœžœžœ(˜CLšœ˜—Lšœ žœžœ ˜'šœ)˜)Lšœžœžœ˜*—L˜Lšžœ ˜Lšœ˜—š  œž œžœ%žœ˜NLšœ*˜*šœžœžœžœ ˜CLšœ ˜ —Lšœžœžœ˜7šœ žœžœžœ(˜CLšœ˜—Lšœ žœžœ ˜'šœ)˜)Lšœžœžœ˜*—L˜Lšžœ ˜Lšœ˜—š  œž œžœ%žœ˜PLšœ*˜*šœžœžœžœ ˜CLšœ ˜ —Lšœžœžœ˜7šœžœžœžœ(˜ELšœ!˜!—Lšœ žœžœ˜+šœ)˜)Lšœ žœžœ˜,—L˜Lšžœ ˜Lšœ˜—š œž œžœ%žœ˜MLšœ*˜*šœžœžœžœ ˜CLšœ ˜ —Lšœžœžœ˜7šœ žœžœžœ(˜BLšœ˜—Lšœžœžœ ˜%šœ)˜)Lšœžœžœ˜)—L˜Lšžœ ˜Lšœ˜—š  œž œžœ%žœ˜OLšœ*˜*šœžœžœžœ ˜CLšœ ˜ —Lšœžœžœ˜7šœ žœžœžœ(˜DLšœ ˜ —Lšœ žœžœ˜)šœ)˜)Lšœžœžœ˜+—L˜Lšžœ ˜Lšœ˜—š  œž œžœ%žœ˜PLšœ*˜*šœžœžœžœ ˜CLšœ ˜ —Lšœžœžœ˜7šœžœžœžœ(˜ELšœ!˜!—Lšœ žœžœ˜+šœ)˜)Lšœ žœžœ˜,—L˜Lšžœ ˜Lšœ˜—š  œž œžœ%žœ˜NLšœ*˜*šœžœžœžœ ˜CLšœ ˜ —Lšœžœžœ˜7šœ žœžœžœ(˜CLšœ˜—Lšœ žœžœ ˜'šœ)˜)Lšœžœžœ˜*—L˜Lšžœ ˜Lšœ˜—š œž œžœ%žœ™MLšœ*™*šœžœžœžœ ™CLšœ ™ —Lšœžœžœ™7šœ žœžœžœ(™BLšœ™—Lšœžœžœ ™%šœ)™)Lšœžœžœ™)—L™Lšžœ ™Lšœ™—š  œž œžœ%žœ˜OLšœ*˜*šœžœžœžœ ˜CLšœ ˜ —Lšœžœžœ˜7šœ žœžœžœ(˜DLšœ ˜ —Lšœ žœžœ˜)šœ)˜)Lšœžœžœ˜+—L˜Lšžœ ˜Lšœ˜—š  œž œžœ%žœ˜PLšœ*˜*šœžœžœžœ ˜CLšœ ˜ —Lšœžœžœ˜7šœžœžœžœ(˜ELšœ!˜!—Lšœ žœžœ˜+šœ)˜)Lšœ žœžœ˜,—L˜Lšžœ ˜Lšœ˜—š  œž œžœ%žœ˜PLšœ*˜*šœžœžœžœ ˜CLšœ ˜ —Lšœžœžœ˜7šœžœžœžœ(˜ELšœ!˜!—Lšœ žœžœ˜+šœ)˜)Lšœ žœžœ˜,—L˜Lšžœ ˜Lšœ˜—š  œž œžœ%žœ˜OLšœ*˜*šœžœžœžœ ˜CLšœ ˜ —Lšœžœžœ˜7šœ žœžœžœ(˜DLšœ ˜ —Lšœ žœžœ˜)šœ)˜)Lšœžœžœ˜+—L˜Lšžœ ˜Lšœ˜—š  œž œžœ%žœ˜OLšœ*˜*šœžœžœžœ ˜CLšœ ˜ —Lšœžœžœ˜7šœ žœžœžœ(˜DLšœ ˜ —Lšœ žœžœ˜)šœ)˜)Lšœžœžœ˜+—L˜Lšžœ ˜Lšœ˜—š  œž œžœ%žœ˜OLšœ*˜*šœžœžœžœ ˜CLšœ ˜ —Lšœžœžœ˜7šœ žœžœžœ(˜DLšœ ˜ —Lšœ žœžœ˜)šœ)˜)Lšœžœžœ˜+—L˜Lšžœ ˜Lšœ˜—š  œž œžœ%žœ˜PLšœ*˜*šœžœžœžœ ˜CLšœ ˜ —Lšœžœžœ˜7šœžœžœžœ(˜ELšœ!˜!—Lšœ žœžœ˜+šœ)˜)Lšœ žœžœ˜,—L˜Lšžœ ˜Lšœ˜—š  œž œžœ%žœ˜PLšœ*˜*šœžœžœžœ ˜CLšœ ˜ —Lšœžœžœ˜7šœžœžœžœ(˜ELšœ!˜!—Lšœ žœžœ˜+šœ)˜)Lšœ žœžœ˜,—L˜Lšžœ ˜Lšœ˜—š  œž œžœ%žœ˜PLšœ*˜*šœžœžœžœ ˜CLšœ ˜ —Lšœžœžœ˜7šœžœžœžœ(˜ELšœ!˜!—Lšœ žœžœ˜+šœ)˜)Lšœ žœžœ˜,—L˜Lšžœ ˜Lšœ˜—š  œž œžœ%žœ˜NLšœ*˜*šœžœžœžœ ˜CLšœ ˜ —Lšœžœžœ˜7šœ žœžœžœ(˜CLšœ˜—Lšœ žœžœ ˜'šœ)˜)Lšœžœžœ˜*—L˜Lšžœ ˜Lšœ˜—š  œž œžœ%žœ˜OLšœ*˜*šœžœžœžœ ˜CLšœ ˜ —Lšœžœžœ˜7šœ žœžœžœ(˜DLšœ ˜ —Lšœ žœžœ˜)šœ)˜)Lšœžœžœ˜+—L˜Lšžœ ˜Lšœ˜—š  œž œžœ%žœ˜OLšœ*˜*šœžœžœžœ ˜CLšœ ˜ —Lšœžœžœ˜7šœ žœžœžœ(˜DLšœ ˜ —Lšœ žœžœ˜)šœ)˜)Lšœžœžœ˜+—L˜Lšžœ ˜Lšœ˜—š  œž œžœ%žœ˜PLšœ*˜*šœžœžœžœ ˜CLšœ ˜ —Lšœžœžœ˜7šœžœžœžœ(˜ELšœ!˜!—Lšœ žœžœ˜+šœ)˜)Lšœ žœžœ˜,—L˜Lšžœ ˜Lšœ˜—š  œž œžœ%žœ™NLšœ*™*šœžœžœžœ ™CLšœ ™ —Lšœžœžœ™7šœ žœžœžœ(™CLšœ™—Lšœ žœžœ ™'šœ)™)Lšœžœžœ™*—L™Lšžœ ™Lšœ™—š  œž œžœ%žœ˜OLšœ*˜*šœžœžœžœ ˜CLšœ ˜ —Lšœžœžœ˜7šœ žœžœžœ(˜DL˜ —Lšœ žœžœ˜)šœ)˜)Lšœžœžœ˜+—L˜Lšžœ ˜Lšœ˜—š  œž œžœ%žœ˜PLšœ*˜*šœžœžœžœ ˜CLšœ ˜ —Lšœžœžœ˜7šœžœžœžœ(˜EL˜!—Lšœ žœžœ˜+šœ)˜)Lšœ žœžœ˜,—L˜Lšžœ ˜Lšœ˜—š  œž œžœ%žœ˜QLšœ*˜*šœžœžœžœ ˜CLšœ ˜ —Lšœžœžœ˜7šœžœžœžœ(˜FL˜"—Lšœ žœžœ˜-šœ)˜)Lšœ!žœžœ˜-—L˜Lšžœ ˜Lšœ˜—š  œž œžœ%žœ˜OLšœ*˜*šœžœžœžœ ˜CLšœ ˜ —Lšœžœžœ˜7šœ žœžœžœ(˜DL˜ —Lšœ žœžœ˜)šœ)˜)Lšœžœžœ˜+—L˜Lšžœ ˜Lšœ˜—š  œž œžœ%žœ˜PLšœ*˜*šœžœžœžœ ˜CLšœ ˜ —Lšœžœžœ˜7šœžœžœžœ(˜EL˜!—Lšœ žœžœ˜+šœ)˜)Lšœ žœžœ˜,—L˜Lšžœ ˜Lšœ˜—š  œž œžœ%žœ˜QLšœ*˜*šœžœžœžœ ˜CLšœ ˜ —Lšœžœžœ˜7šœžœžœžœ(˜FL˜"—Lšœ žœžœ˜-šœ)˜)Lšœ!žœžœ˜-—L˜Lšžœ ˜Lšœ˜—š  œž œžœ%žœ˜OLšœ*˜*šœžœžœžœ ˜CLšœ ˜ —Lšœžœžœ˜7šœ žœžœžœ(˜DL˜ —Lšœ žœžœ˜)šœ)˜)Lšœžœžœ˜+—L˜Lšžœ ˜Lšœ˜—š  œž œžœ%žœ˜NLšœ*˜*šœžœžœžœ ˜CLšœ ˜ —Lšœžœžœ˜7šœ žœžœžœ(˜CL˜—Lšœ žœžœ ˜'šœ)˜)Lšœžœžœ˜*—L˜Lšžœ ˜Lšœ˜—š œž œžœ%žœ˜LLšœ*˜*šœžœžœžœ ˜CLšœ ˜ —Lšœžœžœ˜7šœ žœžœžœ(˜ALšœ˜—Lšœžœžœ ˜#šœ)˜)Lšœžœžœ˜(—L˜Lšžœ ˜Lšœ˜—š  œž œžœ%žœ˜PLšœ*˜*šœžœžœžœ ˜CLšœ ˜ —Lšœžœžœ˜7šœžœžœžœ(˜ELšœ!˜!—Lšœ žœžœ˜+šœ)˜)Lšœ žœžœ˜,—L˜Lšžœ ˜Lšœ˜—š œž œžœ%žœ˜MLšœ*˜*šœžœžœžœ ˜CLšœ ˜ —Lšœžœžœ˜7šœ žœžœžœ(˜BLšœ˜—Lšœžœžœ ˜%šœ)˜)Lšœžœžœ˜)—L˜Lšžœ ˜Lšœ˜—š œž œžœ%žœ˜MLšœ*˜*šœžœžœžœ ˜CLšœ ˜ —Lšœžœžœ˜7šœ žœžœžœ(˜BLšœ˜—Lšœžœžœ ˜%šœ)˜)Lšœžœžœ˜)—L˜Lšžœ ˜Lšœ˜—™L™—š  œž œžœ%žœ˜QLšœ*˜*šœžœžœžœ ˜CLšœ ˜ —Lšœžœžœ˜7šœžœžœžœ˜5Lšœ˜—Lšœ žœžœ˜-šœ)˜)Lšœ!žœžœ˜-—L˜Lšžœ ˜Lšœ˜L˜—L™ ™šœ'žœ'˜QLšœ ˜ Lšœ˜Lšœ˜———K˜—L˜—…—ŒΪΚΦ