DIRECTORY DebuggerFormat USING[ ExternalStateVector, Run, SwapInfo, VersionID, VMRunTable ], PrincOps USING[ PDA ], WorldVM USING[Address, CopyRead, World], WVMPrivate; WVMBackingMap: MONITOR IMPORTS WorldVM, WVMPrivate EXPORTS WVMPrivate, WorldVM = BEGIN VMBackingMapObject: PUBLIC TYPE = RECORD[ found: CARDINAL _ 0, -- maplog entries read in so far -- entries: REF DebuggerFormat.VMRunTable]; VMBackingMap: TYPE = REF VMBackingMapObject; CreateVMBackingMap: PUBLIC PROC[world: WorldVM.World] RETURNS[ VMBackingMap ] = BEGIN RETURN[NEW[VMBackingMapObject _ [0,NIL]]] END; ReadVMBackingMap: PUBLIC PROC[world: WorldVM.World, log: VMBackingMap] RETURNS[basic, real: WorldVM.Address] = BEGIN swapInfo: DebuggerFormat.SwapInfo; swapInfoAddr: WorldVM.Address = LOOPHOLE[@PrincOps.PDA.available]; esv: DebuggerFormat.ExternalStateVector; esvAddr: WorldVM.Address; WorldVM.CopyRead[world, swapInfoAddr, SIZE[DebuggerFormat.SwapInfo], @swapInfo]; esvAddr _ LOOPHOLE[swapInfo.externalStateVector]; WorldVM.CopyRead[world, esvAddr, SIZE[DebuggerFormat.ExternalStateVector], @esv]; basic _ WVMPrivate.PageAddress[esv.loadstatepage]; real _ LOOPHOLE[esv.loadState]; SELECT esv.versionident FROM DebuggerFormat.VersionID => BEGIN IF esv.vmRunTable # NIL THEN BEGIN temp: ARRAY [0..SIZE[DebuggerFormat.VMRunTable[0]]) OF WORD; cheat: POINTER TO DebuggerFormat.VMRunTable = LOOPHOLE[@temp]; WorldVM.CopyRead[world, LOOPHOLE[esv.vmRunTable, WorldVM.Address], SIZE[DebuggerFormat.VMRunTable[0]], @temp ]; log.entries _ NEW[DebuggerFormat.VMRunTable[cheat.length]]; WorldVM.CopyRead[world, LOOPHOLE[esv.vmRunTable, WorldVM.Address], SIZE[DebuggerFormat.VMRunTable[cheat.length]], LOOPHOLE[log.entries, LONG POINTER] ]; log.found _ log.entries.nRuns; END; END; ENDCASE => NULL; -- treat as if there was no maplog END; AddressFault: PUBLIC ERROR[mempage: WVMPrivate.PageNumber] = CODE; lastEntryIndex: CARDINAL _ 0; -- hint for log entry to try first -- GetVMBackingMapEntry: PUBLIC ENTRY PROC[log: VMBackingMap, mempage: WVMPrivate.PageNumber] RETURNS[ WVMPrivate.DiskAddress ] = BEGIN ENABLE UNWIND => NULL; entry: LONG POINTER TO DebuggerFormat.Run _ IF lastEntryIndex IN [0..log.found) -- lastEntryIndex may be for another log! THEN @log.entries[lastEntryIndex] ELSE NIL; IF entry = NIL OR mempage NOT IN [entry.page..entry.page+entry.count) THEN -- sigh! Need to search for it. -- BEGIN FOR i: CARDINAL IN [0..log.found) DO entry _ @log.entries[lastEntryIndex_i]; IF mempage IN [entry.page..entry.page+entry.count) THEN EXIT; REPEAT FINISHED => ERROR AddressFault[mempage] ENDLOOP; END; RETURN[[entry.deviceType, entry.deviceOrdinal, entry.diskPage, mempage-entry.page, entry.labelCheck]]; END; END. rCedar Remote Debugging: Map of VM backing file WVMBackingMap.mesa Andrew Birrell December 2, 1983 1:16 pm Ê’˜J˜Jšœ.™.Jšœ™Jšœ(™(J˜šÏk ˜ Jšœœ>˜RJšœ œœ˜Jšœœ˜(J˜ J˜—Jšœ˜Jšœ˜Jšœ˜J˜Jš˜J˜šœœœœ˜)JšœœÏc#˜8Jšœ œ˜(J˜—Jšœœœ˜,J˜šÏnœœœœ˜OJš˜Jšœœœ˜)Jšœ˜J˜—šŸœœœ)˜FJšœ ˜'Jš˜J˜"Jšœ œ œ ˜BJ˜(J˜šœ&œ˜DJ˜ —Jšœ œ˜1šœ!œ%˜JJ˜—J˜2Jšœœ˜šœ˜˜Jš˜Jšœ˜šœ˜ Jš œœœ œœ˜˜Jšœ"˜*Jšœ˜#J˜—Jšœœ*˜;˜Jšœ"˜*Jšœ*˜.Jšœœœ˜&—J˜Jšœ˜—Jšœ˜——Jšœœž"˜3Jšœ˜J˜—Jšœœœ#œ˜BJ˜Jšœœž%˜CJ˜šŸœœœœ3˜ZJšœ˜#Jš˜Jšœœœ˜šœœœœ˜+Jšœœž)˜MJšœ˜!Jšœœ˜ —Jšœ ˜Jšœ œœ%˜6šœž"˜'Jš˜Jšœœœ˜!šœ(˜*Jšœ œ%˜2Jšœœ˜ —Jšœœœ˜.Jšœ˜Jšœ˜—Jšœ`˜fJšœ˜J˜—Jšœ˜J˜J˜—…— Ž’