Cedar Remote Debugging: Map of VM backing file
WVMBackingMap.mesa
Andrew Birrell December 2, 1983 1:16 pm
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.