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 = { 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 ] = { RETURN[NEW[VMBackingMapObject _ [0,NIL]]] }; ReadVMBackingMap: PUBLIC PROC[world: WorldVM.World, log: VMBackingMap] RETURNS[basic, real: WorldVM.Address] = { 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 => { IF esv.vmRunTable # NIL THEN { 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; }; }; ENDCASE => NULL; -- treat as if there was no maplog }; 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 ] = { 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 { 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; }; RETURN[[entry.deviceType, entry.deviceOrdinal, entry.diskPage, mempage-entry.page, entry.labelCheck]]; }; }. μWVMBackingMap.mesa: Map of VM backing file Copyright c 1985 by Xerox Corporation. All rights reserved. Andrew Birrell December 2, 1983 1:16 pm Russ Atkinson (RRA) February 6, 1985 9:28:10 pm PST sigh! Need to search for it. -- ΚZ˜codešœ*™*Kšœ Οmœ1™˜RKšœ žœžœ˜Kšœžœ˜(K˜ K˜—šœž˜Kšžœ˜Kšžœžœ˜—K˜šœžœžœžœ˜)KšœžœΟc#˜8Kšœ žœ˜(K˜—Kšœžœžœ˜,K˜šΟnœžœžœžœ˜QKšžœžœžœ˜)Kšœ˜K˜—š œžœžœ)žœ"˜pK˜"Kšœ žœ žœ ˜BK˜(K˜šœ&žœ˜DK˜ —Kšœ žœ˜1šœ!žœ%˜JK˜—K˜2Kšœžœ˜šžœž˜šœ˜šžœžœ˜Kš œžœžœ žœžœ˜˜Kšžœ"˜*Kšžœ˜#K˜—Kšœžœ*˜;˜Kšžœ"˜*Kšžœ*˜.Kšžœžœžœ˜&—K˜Kšœ˜—Kšœ˜——KšžœžœŸ"˜3Kšœ˜K˜—Kšœžœžœ#žœ˜BK˜KšœžœŸ%˜CK˜š  œžœžœžœ3žœ˜€Kšžœžœžœ˜šœžœžœžœ˜+KšžœžœŸ)˜MKšžœ˜!Kšžœžœ˜ —šžœ ž˜Kšžœ žœžœ%˜6šžœ˜Kšœ™šžœžœžœž˜$Kšœ'˜'Kšžœ žœ&žœžœ˜=Kšžœžœžœ˜.Kšžœ˜—Kšœ˜——Kšžœ`˜fKšœ˜K˜—Kšœ˜K˜K˜—…— @†