-- InitialPack.Mesa Edited by: -- Evans on May 19, 1980 4:33 PM -- Bruce on October 7, 1980 1:29 PM -- Sandman on July 30, 1980 9:49 AM -- Johnsson on July 15, 1980 2:54 PM -- Mark on August 20, 1980 8:32 PM DIRECTORY BP USING [BBHandle, BytePC, Conditionalize, FindBB, ResetBBs], Commands USING [Go, WriteError], Cursor USING [Set], DebugFormat USING [BBHandle, Foo], DebugOps USING [ BBHandle, Display, Foo, GFHandle, InvalidateFileCache, Numeric, ReadCodeByte, ShortCopyREAD, ShortCopyWRITE, ShortREAD, UserAborted], DI USING [ValFormat], DLoadState USING [Init], DOutput USING [Char, Decimal, EOL, Line, Octal, Text], DPsb USING [ResetCache], Drum USING [FlushCodeSegmentCache, FlushCoreCache, Initialize], DSyms USING [Clean, FreeItems, Prune], Dump USING [Num, ResetPrinters, UserText, XferFrame, XferName], Event USING [AddNotifier, Item, Masks, Notifier, Notify], Frames USING [FlushFrameCache, Invalid], Gf USING [FrameGfi], Init USING [ CheckMemory, CoreSwap, CoreSwapMessages, LoadStateReason, usermessage, WriteHerald], Lf USING [Display, GF, Handle, PC, Validate], Lookup USING [Signal, StateCtx], MachineDefs USING [BYTE, FHandle, GFHandle, ProcDesc], Mopcodes USING [zBRK], Pc USING [EvalStackEmpty, ResetCache], PrincOps USING [BYTE, BytePC, SignalDesc, StateVector, SVPointer], SDDefs USING [SD, sSignal], Source USING [ResetFrames], State USING [GetGS, GSHandle, Msg], Storage USING [FreeString], Symbols USING [ISEIndex, ISENull, RecordSENull], SymbolTable USING [Missing], TajoMisc USING [SetState], UserInput USING [ResetUserAbort]; InitialPack: PROGRAM IMPORTS BP, Commands, Cursor, DebugOps, DOutput, DPsb, Drum, DSyms, Dump, Event, Frames, Gf, Init, Lf, DLoadState, Lookup, Pc, Source, State, Storage, SymbolTable, TajoMisc, UserInput EXPORTS BP, Dump, Init = BEGIN OPEN Event, Init, MachineDefs, PrincOps; Debug: PUBLIC SIGNAL = CODE; UCS: PUBLIC SIGNAL = CODE; MapLog: PUBLIC SIGNAL = CODE; bootLoaded: PUBLIC BOOLEAN ← FALSE; data: State.GSHandle; event: Event.Item ← [eventMask: Event.Masks[newFiles], eventProc: Notify]; warning: PUBLIC CoreSwapMessages; RestartMsg: PUBLIC PROC = BEGIN OPEN DOutput; SELECT data.restartMsg FROM none => RETURN; interrupt => Line["*** interrupt ***"L]; punt => Line["*** Fatal System Error (Punt) ***"L]; bootloaded => Line["*** Debugger Bootloaded ***"L]; invalid => Line["*** Invalid Swap Reason - Context Invalid ***"L]; maplog => Line["*** Processing VM Map ***"L]; ENDCASE; data.restartMsg ← none; END; SaveSignallerGF: PROCEDURE = BEGIN pd: MachineDefs.ProcDesc ← DebugOps.ShortREAD[@SDDefs.SD[SDDefs.sSignal]]; data.sigGF ← Gf.FrameGfi[pd.gfi]; RETURN; END; BreakInstToState: PROCEDURE [sp: SVPointer, b: MachineDefs.BYTE] = BEGIN OPEN MachineDefs; state: StateVector; DebugOps.ShortCopyREAD[ from: sp, to: @state, nwords: SIZE[StateVector]]; state.instbyte ← b; DebugOps.ShortCopyWRITE[ to: sp, from: @state, nwords: SIZE[StateVector]]; RETURN END; CodeByteFromState: PROCEDURE [state: PrincOps.SVPointer] RETURNS [MachineDefs.BYTE] = BEGIN f: MachineDefs.FHandle = DebugOps.ShortREAD[@state.dest]; RETURN[DebugOps.ReadCodeByte[Lf.GF[f],Lf.PC[f]]] END; Validate: PUBLIC PROC [sv: PrincOps.SVPointer] RETURNS [BOOLEAN] = BEGIN RETURN[sv # NIL AND CodeByteFromState[sv] = Mopcodes.zBRK] END; Break: PUBLIC PROCEDURE = BEGIN OPEN MachineDefs; -- breakpoint interpreter sp: SVPointer = data.StatePtr; f: FHandle ← DebugOps.ShortREAD[@sp.dest]; gframe: GFHandle ← DebugOps.ShortREAD[@f.accesslink]; bp: DebugOps.BBHandle; IF ~Lf.Validate[f] THEN BEGIN DOutput.Text["Breakpoint"L]; Commands.Go[]; RETURN END; data.breakFrame ← f; IF (bp ← BP.FindBB[gframe, Lf.PC[f]]) = NIL THEN DOutput.Text["Breakpoint not found!"L] ELSE { DOutput.EOL[]; BreakInstToState[sp, bp.inst]; WriteBreakHerald[f,bp]}; Commands.Go[bp]; RETURN END; WriteBreakHerald: PROCEDURE [f: FHandle, b: DebugOps.BBHandle] = BEGIN OPEN DOutput; BreakNum: PROC = BEGIN Text[" #"L]; Decimal[b.num] END; IF b.bt.ex = octal THEN BEGIN Text["Octal-break"L]; BreakNum[]; Text[" in frame: "L]; Octal[Lf.GF[f]]; Text[", byte-pc: "L]; Octal[b.pc]; EOL[] END ELSE BEGIN Text[IF b.bt.bt = break THEN "Break"L ELSE "Trace"L]; BreakNum[]; Text[SELECT b.bt.ex FROM entry => " at entry to "L, exit => " at exit from "L, ENDCASE => " in "L]; Lf.Display[f]; IF b.condition # NIL AND DebugOps.Numeric[b.condition] THEN BEGIN s: STRING ← b.condition; BP.Conditionalize[b,s]; Storage.FreeString[s]; END; END; SELECT TRUE FROM Pc.EvalStackEmpty[] => NULL; b.bt.ex = entry AND b.symbolsAvailable => NULL; b.bt.ex = exit => NULL; ENDCASE => {EOL[]; Line[" Eval-Stack not empty!"L]}; RETURN END; UCSHandler: PUBLIC PROCEDURE = {DOutput.Text["*** uncaught SIGNAL "L]; Commands.Go[]}; Msg: PROCEDURE = INLINE BEGIN vf: DI.ValFormat = [none[]]; DOutput.Text[" msg = "L]; Dump.Num[DebugOps.ShortREAD[@data.StatePtr.stk[0]], vf]; RETURN END; PreDeclared: PROCEDURE [u: UNSPECIFIED] RETURNS [BOOLEAN] = BEGIN Sigs: ARRAY [0..3) OF INTEGER = [-1,3,5]; Names: ARRAY [0..3) OF STRING = ["ERROR"L, "UNWIND"L, "ABORTED"L]; FOR i: CARDINAL IN [0..3) DO IF Sigs[i] = u THEN {DOutput.Text[Names[i]]; RETURN[TRUE]}; ENDLOOP; RETURN[FALSE]; END; PrintUCS: PUBLIC PROCEDURE = BEGIN signal: PrincOps.SignalDesc ← data.signal; isei: Symbols.ISEIndex ← Symbols.ISENull; IF PreDeclared[signal] THEN RETURN; isei ← Lookup.Signal[signal]; Dump.XferName[signal, isei]; SignalCtxFromState[signal, data.StatePtr ! SymbolTable.Missing => {Msg[]; CONTINUE}]; Dump.XferFrame[signal]; RETURN; END; SignalCtxFromState: PUBLIC PROC [ cl: PrincOps.SignalDesc, sv: PrincOps.SVPointer] = BEGIN f: DebugOps.Foo ← Lookup.StateCtx[Lookup.Signal[cl], sv, in, 1]; IF f = NIL THEN ERROR SymbolTable.Missing[NIL]; IF f.tsei = Symbols.RecordSENull THEN RETURN; f.xfer ← FALSE; DebugOps.Display[f, TRUE ! Frames.Invalid => { DOutput.Char[' ]; DOutput.Octal[f]; Commands.WriteError[nGframe,FALSE]; CONTINUE}]; END; NewLoadState: PUBLIC PROCEDURE [why: LoadStateReason] = BEGIN DLoadState.Init[]; data.initBCD ← TRUE; SELECT why FROM debug => SIGNAL Debug; ucs => SIGNAL UCS; maplog => SIGNAL MapLog; ENDCASE => ERROR; END; CoreSwapMsg: PUBLIC PROC [msg: CoreSwapMessages] = BEGIN IF msg = none THEN RETURN; DOutput.Text[SELECT msg FROM cantSwap => "Core image not healthy, can't swap"L, evalstack => "Eval-Stack not empty!"L, interrupt => "*** interrupt ***"L, maplog => "*** Processing VM Map ***"L, ENDCASE => ERROR]; END; usermessage: PUBLIC STRING ← NIL; GetUserMessage: PUBLIC PROCEDURE = BEGIN OPEN MachineDefs; s: StateVector; DebugOps.ShortCopyREAD[ from: data.StatePtr, to: @s, nwords: SIZE[StateVector]]; Init.usermessage ← IF s.stkptr = 1 THEN s.stk[0] ELSE NIL; s.stkptr ← 0; DebugOps.ShortCopyWRITE[ from: @s, to: data.StatePtr, nwords: SIZE[StateVector]]; RETURN END; -- type: Cursor.Type = Cursor.UniqueType[]; FlushCaches: PUBLIC Event.Notifier = BEGIN -- toilet: Cursor.Object ← [ -- info: [type,8,8], -- array: [36B, 42B, 102B, 702B, 102B, 102B, 102B, 7702B, 70042B, -- 120142B, 114602B, 103002B, 60004B, 14004B, 3004B, 774B]]; -- Cursor.Store[@toilet]; SELECT why FROM newSession => BEGIN Cursor.Set[textPointer]; CheckMemory[]; DebugOps.InvalidateFileCache[]; Drum.FlushCodeSegmentCache[]; Drum.FlushCoreCache[]; Drum.Initialize[]; BP.ResetBBs[]; Source.ResetFrames[]; SaveSignallerGF[]; data.loggedIn ← FALSE; data.worryBreaks ← FALSE; Frames.FlushFrameCache[]; DPsb.ResetCache[]; FlushCaches[flushSymbols]; -- Cursor.Set[questionMark]; Event.Notify[why]; [] ← TajoMisc.SetState[on]; END; newFiles => BEGIN DebugOps.InvalidateFileCache[]; DSyms.Clean[]; END; flushSymbols => BEGIN DSyms.Prune[]; DSyms.FreeItems[]; Pc.ResetCache[]; Dump.ResetPrinters[]; END; resumeSession => BEGIN Frames.FlushFrameCache[]; DPsb.ResetCache[]; -- Cursor.Set[questionMark]; Event.Notify[why]; [] ← TajoMisc.SetState[on]; END; resumeDebuggee, abortSession => BEGIN -- Cursor.Set[questionMark]; Event.Notify[why]; -- Cursor.Store[@toilet]; Frames.FlushFrameCache[]; DPsb.ResetCache[]; Drum.FlushCodeSegmentCache[]; Drum.FlushCoreCache[]; END; ENDCASE; -- Cursor.Set[textPointer]; END; Notify: Event.Notifier = {IF why = newFiles THEN FlushCaches[why]}; DebugState: TYPE = {installing, initial, ucs, maplog}; StartDebugger: PUBLIC PROC [boot: BOOLEAN ← TRUE] = BEGIN case: DebugState ← installing; bootLoaded ← ~boot; data ← State.GetGS[]; DO Init.WriteHerald[TRUE]; DebugIt[case ! DebugOps.UserAborted => {UserInput.ResetUserAbort[]; RESUME}; Debug => {case ← initial; CONTINUE}; UCS => {case ← ucs; CONTINUE}; MapLog => {case ← maplog; CONTINUE}]; FlushCaches[newSession]; IF warning # none THEN {CoreSwapMsg[warning]; DOutput.EOL[]}; ENDLOOP; END; DebugIt: PROC [case: DebugState] = BEGIN Init.WriteHerald[]; SELECT case FROM installing => CoreSwap[install]; ucs => BEGIN UCSHandler[]; CoreSwap[resume] END; maplog => CoreSwap[proceed]; ENDCASE; DO IF Init.usermessage # NIL THEN Dump.UserText[Init.usermessage]; Commands.Go[]; CoreSwap[proceed]; ENDLOOP; END; Event.AddNotifier[@event]; END.