MIPSManger.mesa
Copyright Ó 1992 by Xerox Corporation. All rights reserved.
Katsuyuki Komatsu August 5, 1992 6:02 pm PDT
Jas, October 19, 1992 5:11 pm PDT
DIRECTORY
MIPSArchitecture USING [MIPSInstruction, MIPSContents],
BreakWorldArchitecture USING [Address],
Rope USING [ROPE];
MIPSManger: CEDAR DEFINITIONS ~ {
Mangers come in (for now) five flavors:
normal for ordinary instructions (non-delayed control transfers),
branch for simple delayed control transfers (e.g. conditional control transfers),
call for jump and link & jump and link register instruction (e.g. calls),
jump for jump instruction (e.g. unconditional control transfers).
The tag for which kind of manger it is is kept in the ``tag'' field of the manger. The tag is used to figure out how to put the original instruction back when the breakpoint is removed.
Normal instruction stream:  becomes:  normal manger:
norm1    j patch  norm1
norm2    noop   norm2
continue:   continue:   j continue
      noop
-- This is the normal case, we just jump to the patch to exeucte the instructions.
Branch instruction stream:  becomes:  branch manger:
bcc target   j patch  bcc target
delaySlot   noop   delaySlot
continue:   continue:   j continue
      noop
-- With a simple delay slot, we just jump to a copy (relocated) of the instruction and its delay slot. If the branch falls through, we just transfer back to the main code stream.
Call instruction stream:  becomes:  call manger:
jal(r) target  jal patch  j(r) target
delaySlot   delaySlot  noop
-- The trick here is to call the patch, thus setting up the return address because the callee probably uses it (e.g. to return, or return aggregate results, etc.). We allow the instruction in the delay slot to execute (what if it messes with the return address? So be it, that's what it wanted to do.). In the manger, we jmpl to the callee without setting the return address.
Jump instruction stream:  becomes:  jump manger:
j(r) target   j patch  j(r) target
delaySlot   delaySlot  noop
-- This is just a computed delayed transfer. We branch to a copy of the instruction. We allow the instruction in the delay slot to execute.
The breakpointPC is necessary for the MIPS breakpoints due to the their implementation of a virtual fp. A mapping from the patch code back to where the breakpoint was set.
Types
Manger: TYPE ~ MACHINE DEPENDENT RECORD [
variants: SELECT COMPUTED MangerVariant FROM
Manger variants are ``computed'' by examining the ``tag'' field.
normal => [
no delay slot
sheep1: MIPSArchitecture.MIPSInstruction,
sheep2: MIPSArchitecture.MIPSInstruction,
normalContinue: MIPSArchitecture.MIPSInstruction,
normalNoop: MIPSArchitecture.MIPSInstruction,
tag: MIPSArchitecture.MIPSInstruction,
breakpointPC: MIPSArchitecture.MIPSContents],
branch => [
has simple delay slot
branchB: MIPSArchitecture.MIPSInstruction,
branchDelay: MIPSArchitecture.MIPSInstruction,
branchContinue: MIPSArchitecture.MIPSInstruction,
branchNoop: MIPSArchitecture.MIPSInstruction,
tag: MIPSArchitecture.MIPSInstruction,
breakpointPC: MIPSArchitecture.MIPSContents],
call => [
has delay slot, and have to get return address pointed to breakpoint address, since callee computes return point.
Use a call to get to the patch.
callJ: MIPSArchitecture.MIPSInstruction,
callNoop: MIPSArchitecture.MIPSInstruction,
dummy1: MIPSArchitecture.MIPSInstruction,
dummy2: MIPSArchitecture.MIPSInstruction,
tag: MIPSArchitecture.MIPSInstruction,
breakpointPC: MIPSArchitecture.MIPSContents],
jump => [
has delay slot, and is an unconditional branch.
jumpJ: MIPSArchitecture.MIPSInstruction,
jumpNoop: MIPSArchitecture.MIPSInstruction,
dummy1: MIPSArchitecture.MIPSInstruction,
dummy2: MIPSArchitecture.MIPSInstruction,
tag: MIPSArchitecture.MIPSInstruction,
breakpointPC: MIPSArchitecture.MIPSContents]
ENDCASE
];
MangerVariant: TYPE ~ {
noneOfTheAbove, normal, branch, call, jump
};
NormalManger: TYPE ~ Manger.normal;
BranchManger: TYPE ~ Manger.branch;
CallManger: TYPE ~ Manger.call;
JumpManger: TYPE ~ Manger.jump;
Procedures
Install: PROCEDURE [
address: BreakWorldArchitecture.Address,
manger: BreakWorldArchitecture.Address,
patchCode: BreakWorldArchitecture.Address]
RETURNS [];
Uninstall: PROCEDURE [
address: BreakWorldArchitecture.Address,
manger: BreakWorldArchitecture.Address,
patchCode: BreakWorldArchitecture.Address]
RETURNS [];
Errors
ErrorCode: TYPE ~ ATOM ← nullErrorCode;
nullErrorCode: ErrorCode ~ NIL;
ErrorMessage: TYPE ~ Rope.ROPE ← nullErrorMessage;
nullErrorMessage: ErrorMessage ~ NIL;
CantInstall: ERROR [code: ErrorCode, message: ErrorMessage];
CantUninstall: ERROR [code: ErrorCode, message: ErrorMessage];
}.