MBDebug.mesa
Edited by Sandman on 28-Jan-81 10:42:17
Edited by Lewis on 25-Sep-81 15:33:42
Edited by Levin on April 5, 1983 2:33 pm
DIRECTORY
BcdDefs USING [
Base, CTIndex, CTNull, FPIndex, FTIndex, FTSelf, MTIndex, NameRecord, NTIndex, SGIndex, SpaceID, SPIndex],
BcdOps USING [
BcdBase, CTHandle, FPHandle, MTHandle, NameString, NTHandle, ProcessConfigs, ProcessFramePacks, ProcessModules, ProcessNames, ProcessSegs, ProcessSpaces, SGHandle, SPHandle],
BootFile USING [Header],
LongString USING [AppendLongNumber, EquivalentSubStrings, SubStringDescriptor],
MB USING [BIndex, Handle, MT, VirtualGlobalFrame],
MBOut USING [Char, CR, Line, LongNumber, Number, NumberFormat, Spaces, Text, Time],
MBVM USING [Seg],
PrincOps USING [GlobalFrameHandle],
Segments USING [FHandle, NameForFile],
StartList USING [
Base, BootLocation, Entry, Header, Index, SwapUnitInfo, SpaceType, StartIndex, StateVectorCounts, Switches];
MBDebug: PROGRAM
IMPORTS BcdOps, MB, MBOut, Segments, String: LongString
EXPORTS MB =
BEGIN
octal: MBOut.NumberFormat =
MBOut.NumberFormat[base: 8, unsigned: TRUE, zerofill: FALSE, columns: 1];
data: MB.Handle ← NIL;
InitDebug: PUBLIC PROC [h: MB.Handle] = {data ← h};
FinishDebug: PUBLIC PROC = {data ← NIL};
DumpSegs: PUBLIC PROC [segs: LONG DESCRIPTOR FOR ARRAY OF MBVM.Seg, msg: STRING] = {
OPEN MBOut;
FileName: PROC [f: Segments.FHandle] = {
name: STRING ← [40];
nss: String.SubStringDescriptor ← [base: name, offset: , length: 4];
bcdss: String.SubStringDescriptor ← [base: ".bcd"L, offset: 0, length: 4];
Segments.NameForFile[name, f];
IF name[name.length-1] = '. THEN name.length ← name.length - 1;
IF name.length > 4 THEN {
nss.offset ← name.length - 4;
IF String.EquivalentSubStrings[@nss, @bcdss] THEN name.length ← name.length - 4;
};
Text[name];
};
DumpSeg: PROC [s: MBVM.Seg] = {
Text["Seg["L];
LongNumber[s, octal];
Text["] type: "L];
WITH seg: s SELECT FROM
data => Text["data"L];
code => Text["code"L];
file => Text["file"L];
ENDCASE;
Text[", vmpage: "L];
Number[s.base, octal];
Text[", info: "L];
DumpSwapUnitInfo[s.info];
Text[", scriptIndex: "L];
Number[s.index, octal];
Text[", booted: "L];
Boolean[s.bootLoaded];
CR[];
WITH seg: s SELECT FROM
data => NULL;
code => {
Text[" location: "L];
FileName[seg.file]; Char['(]; LongNumber[seg.file, octal]; Char[')];
Char['[]; Number[seg.fileBase, octal]; Char[',];
Number[s.pages, octal]; Char[']]; CR[];
};
file => {
Text[" location: "L];
FileName[seg.file]; Char['(]; LongNumber[seg.file, octal]; Char[')];
Char['[]; Number[seg.fileBase, octal]; Char[',];
Number[s.pages, octal]; Char[']]; CR[];
};
ENDCASE;
};
CR[];
Text["SEGMENT TABLE JUST BEFORE "L]; Text[msg]; Char[':]; CR[];
CR[];
FOR i: CARDINAL IN [0..LENGTH[segs]) DO DumpSeg[segs[i]]; ENDLOOP;
};
DumpSwapUnitInfo: PROC [info: StartList.SwapUnitInfo] = {
OPEN MBOut;
Char['[];
Text["readOnly: "L];
Boolean[info.readOnly];
Text[", "L];
MBOut.Text[SELECT info.state FROM
resident => "resident"L,
residentDescriptor => "residentDescriptor"L,
ENDCASE => "swappable"L];
Char[']];
};
DumpInputBcds: PUBLIC PROC = {
OPEN BcdDefs, BcdOps, MBOut;
CR[];
Line["INPUT BCDS:"L];
CR[];
FOR i: MB.BIndex IN [0..data.inputBCDs.nBcds) DO
bcd: BcdBase = data.inputBCDs.bcds[i].bcd;
ctb: Base = LOOPHOLE[bcd + bcd.ctOffset];
mtb: Base = LOOPHOLE[bcd + bcd.mtOffset];
ftb: Base = LOOPHOLE[bcd + bcd.ftOffset];
ssb: NameString = LOOPHOLE[bcd + bcd.ssOffset];
level: CARDINAL ← 2;
DumpName: PROC [name: NameRecord] RETURNS [length: CARDINAL] = {
length ← ssb.size[name];
FOR i: CARDINAL IN [name..name+length) DO
Char[ssb.string[i]];
ENDLOOP;
};
DumpCTName: PROC [cti: CTIndex] RETURNS [length: CARDINAL ← 0] = {
cth: CTHandle = @ctb[cti];
IF cth.namedInstance THEN {
FindConfigInstanceName: PROC [nth: NTHandle, nti: NTIndex] RETURNS [BOOL] = {
WITH namee: nth.item SELECT FROM
config => IF namee.cti = cti THEN {length ← DumpName[nth.name]; RETURN[TRUE]};
ENDCASE;
RETURN[FALSE]
};
[] ← ProcessNames[bcd, FindConfigInstanceName];
Text[": "L]; length ← length + 2};
length ← length + DumpName[cth.name];
};
DumpMTName: PROC [mti: MTIndex] RETURNS [length: CARDINAL ← 0] = {
mth: MTHandle = @mtb[mti];
IF mth.namedInstance THEN {
FindModuleInstanceName: PROC [nth: NTHandle, nti: NTIndex] RETURNS [BOOL] = {
WITH namee: nth.item SELECT FROM
module =>
IF namee.mti = mti THEN {length ← DumpName[nth.name]; RETURN[TRUE]};
ENDCASE;
RETURN[FALSE]
};
[] ← ProcessNames[bcd, FindModuleInstanceName];
Text[": "L]; length ← length + 2;
};
length ← length + DumpName[mth.name];
};
DumpConfigsWithParent: PROC [parentConfig: CTIndex] = {
DumpConfigsWithinParent: PROC [cth: CTHandle, cti: CTIndex] RETURNS [BOOL] = {
IF cth.config = parentConfig THEN {
Spaces[level];
[] ← DumpCTName[cti];
IF cth.nControls > 0 THEN {
Text[" control list:"L];
FOR i: CARDINAL IN [0..cth.nControls) DO
Spaces[1];
WITH cItem: cth.controls[i] SELECT FROM
module => [] ← DumpMTName[cItem.mti];
config => [] ← DumpCTName[cItem.cti];
ENDCASE;
ENDLOOP;
};
CR[];
level ← level + 2;
DumpConfigsWithParent[cti];
level ← level - 2;
};
RETURN[FALSE]
};
DumpModulesWithinParent: PROC [mth: MTHandle, mti: MTIndex] RETURNS [BOOL] = {
IF mth.config = parentConfig THEN {
nameLength: CARDINAL;
Spaces[level];
nameLength ← DumpMTName[mti];
Text[" links: "L];
Text[SELECT mth.linkLoc FROM frame => "frame"L, ENDCASE => "code"L];
Text[", framesize: "L];
Number[mth.framesize, octal];
Text[", residentFrame: "L];
Boolean[mth.residentFrame];
Text[", packageable: "L];
Boolean[mth.packageable];
Text[", nGFI: "L];
Number[mth.ngfi, octal];
Char[',]; CR[];
Spaces[level+nameLength+2];
Text["code: ["L];
Text["sgi: "L];
Number[mth.code.sgi, octal];
Text[", linkspace: "L];
Boolean[mth.code.linkspace];
Text[", packed: "L];
Boolean[mth.code.packed];
Text[", offset: "L];
Number[mth.code.offset, octal];
IF mth.packageable THEN {
Text[", length: "L];
Number[mth.code.length, octal];
};
Text["]"L];
CR[];
};
RETURN[FALSE]
};
[] ← ProcessModules[bcd, DumpModulesWithinParent];
[] ← ProcessConfigs[bcd, DumpConfigsWithinParent];
};
DumpSegment: PROC [sgh: SGHandle, sgi: SGIndex] RETURNS [BOOL] = {
IF sgh.class = code THEN {
DumpCodePacksInSegment: PROC [sph: SPHandle, spi: SPIndex] RETURNS [BOOL] = {
IF sph.seg = sgi THEN {
FOR i: CARDINAL IN [0..sph.length) DO
space: SpaceID = sph.spaces[i];
Spaces[4];
[] ← DumpName[space.name];
Text[" resident: "L]; Boolean[space.resident];
Text[", relative location: ["L]; Number[space.offset, octal];
Char[',]; Number[space.pages, octal]; Char[']];
CR[];
ENDLOOP;
};
RETURN[FALSE]
};
Text[" Code Segment [sgi: "L]; Number[sgi, octal];
Text["], location: "L];
IF sgh.file = FTSelf THEN Text["(self)"L] ELSE [] ← DumpName[ftb[sgh.file].name];
Char['[]; Number[sgh.base, octal]; Char[',]; Number[sgh.pages, octal];
Char['+]; Number[sgh.extraPages, octal]; Char[']];
CR[];
[] ← ProcessSpaces[bcd, DumpCodePacksInSegment];
};
RETURN[FALSE]
};
DumpFramePack: PROC [fph: FPHandle, fpi: FPIndex] RETURNS [BOOL] = {
Text[" Frame Pack "L]; [] ← DumpName[fph.name]; CR[];
FOR i: CARDINAL IN [0..fph.length) DO
Spaces[4]; [] ← DumpMTName[fph.modules[i]]; CR[];
ENDLOOP;
RETURN[FALSE]
};
DumpSwapUnits: PROC = {
Text[" BCD is "L]; Number[bcd.nPages, octal]; Text[" pages"L]; CR[];
Text[" BCD header occupies [1,"L]; Number[bcd.nPages-bcd.rtPages.pages, octal];
Char[']]; CR[];
IF bcd.rtPages.pages = 0 THEN {Text[" No RT extension"L]; CR[]}
ELSE {
Text[" RT extension occupies ["L]; Number[1+bcd.rtPages.relPageBase, octal];
Char[',]; Number[bcd.rtPages.pages, octal]; Char[']]; CR[];
};
};
Text["Configurations and Modules in "L];
Text[data.inputBCDs.bcds[i].name]; Char[':]; CR[];
DumpConfigsWithParent[CTNull];
CR[];
Text["Code Segments, Code Packs, and Frame Packs in "L];
Text[data.inputBCDs.bcds[i].name]; Char[':]; CR[];
DumpSwapUnits[];
[] ← ProcessSegs[bcd, DumpSegment];
[] ← ProcessFramePacks[bcd, DumpFramePack];
CR[];
ENDLOOP;
};
DumpStartList: PUBLIC PROC = {
OPEN MBOut;
base: StartList.Base ← data.scriptBase;
p: StartList.Index ← StartList.StartIndex;
CR[];
Line["START LIST:"L];
CR[];
DumpStartListHeader[];
Line["Script"L];
DO
WITH e: base[p] SELECT FROM
space => {
OPEN e;
Text[" Space["L];
Number[p, octal];
Text["] type: "L];
DumpSpaceType[type];
Text[", backingStore: "L];
Text[IF backingStore = self THEN "self"L ELSE "null"L];
Text[", booted: "L];
Boolean[bootLoaded];
CR[];
Spaces[14];
Text["vmpage: "L];
Number[vmpage, octal];
Text[", pages: "L];
Number[pages, octal];
IF backingStore = self THEN {
Text[", backingPage: "L];
Number[backingPage, octal];
};
CR[];
p ← p + SIZE[space StartList.Entry];
};
swapUnit => {
OPEN e;
Text[" SwapUnit["L];
Number[p, octal];
Text["] parent: "L];
Number[parent, octal];
Text[", base: "L];
Number[base, octal];
Text[", pages: "L];
Number[pages, octal];
Text[", info: "L];
DumpSwapUnitInfo[info];
CR[];
p ← p + SIZE[swapUnit StartList.Entry];
};
stop => {Line[" Stop"L]; EXIT};
ENDCASE => {Line["**Unknown BootScript Type"L]; EXIT};
ENDLOOP;
CR[];
};
DumpSpaceType: PROC [type: StartList.SpaceType] = {
OPEN MBOut;
Char['[];
WITH type SELECT FROM
empty => Text["empty[]"L];
unitary => {Text["unitary[swapUnit: "L]; Number[swapUnit, octal]; Char[']]};
family => {
Text["family[resDescChildren: "L]; Boolean[anyResidentDescriptorChildren]; Char[']]};
ENDCASE;
Char[']];
};
DumpStartListHeader: PROC = {
OPEN MBOut;
h: LONG POINTER TO StartList.Header ← data.header;
Line["Header"L];
Text[" version: "L];
Number[h.version, octal];
CR[];
Text[" table: "L];
Number[h.table, octal];
CR[];
Text[" loadState: "L];
Number[h.loadState, octal];
CR[];
Text[" initLoadState: "L];
Number[h.initLoadState, octal];
CR[];
Text[" mdsBase: "L];
Number[h.mdsBase, octal];
CR[];
Text[" pdaPages: "L];
Number[h.pdaPages, octal];
CR[];
Text[" lastVMPage: "L];
Number[h.lastVMPage, octal];
CR[];
Text[" lastBootLoadedPage: "L];
Number[h.lastBootLoadedPage, octal];
CR[];
Text[" stateVectorCounts: "L];
DumpStateVectorCount[@h.stateVectorCounts];
CR[];
Text[" switches: "L];
DumpSwitches[@h.switches];
CR[];
Text[" locDebuggerMicrocode: "L];
DumpBootLocation[@h.locDebuggerMicrocode];
CR[];
Text[" locDebuggerGerm: "L];
DumpBootLocation[@h.locDebuggerGerm];
CR[];
Text[" locDebugger: "L];
DumpBootLocation[@h.locDebugger];
CR[];
Text[" locDebuggee: "L];
DumpBootLocation[@h.locDebuggee];
CR[];
};
DumpStateVectorCount: PROC [svc: LONG POINTER TO StartList.StateVectorCounts] = {
OPEN MBOut;
Char['[];
FOR i: CARDINAL IN [0..SIZE[StartList.StateVectorCounts]) DO
IF i # 0 THEN Text[", "L];
Number[svc[i], octal];
ENDLOOP;
Char[']];
};
DumpSwitches: PROC [s: LONG POINTER TO StartList.Switches] = {
OPEN MBOut;
Char['[];
Number[s.a, octal];
Text[", "L];
Number[s.b, octal];
Text[", "L];
Number[s.c, octal];
Text[", "L];
Number[s.d, octal];
Char[']];
};
DumpBootLocation: PROC [bl: LONG POINTER TO StartList.BootLocation] = {
OPEN MBOut;
Char['[];
FOR i: CARDINAL IN [0..SIZE[StartList.BootLocation]) DO
IF i # 0 THEN Text[", "L];
Number[bl[i], octal];
ENDLOOP;
Char[']];
};
DumpBootHeader: PUBLIC PROC = {
OPEN MBOut;
h: LONG POINTER TO BootFile.Header ← data.bootHeader;
CR[];
CR[];
Line["BOOTFILE HEADER:"L];
Text[" version: "L];
Number[h.version, octal];
CR[];
Text[" creationDate: "L];
Time[h.creationDate];
Text[" pStartListHeader: "L];
Number[h.pStartListHeader, octal];
CR[];
Text[" inLoadMode: "L];
Text[(SELECT h.inLoadMode FROM load => "load"L, ENDCASE => "restore"L)];
CR[];
Text[" continuation: "L];
WITH h.continuation SELECT FROM
initial => {
Text["initial[mdsi: "L]; Number[mdsi, octal];
Text[", destination: "L]; Number[destination, octal]; Char[']];
};
ENDCASE => Text["unexpected variant!!!"L];
CR[];
Text[" countData: "L];
Number[h.countData, octal];
CR[];
CR[];
};
Boolean: PROC [b: BOOLEAN] = {MBOut.Char[IF b THEN 'T ELSE 'F]};
DumpFrames: PUBLIC PROC = {
OPEN MBOut;
CR[];
Line["GLOBAL FRAMES AT COMPLETION OF LOADING:"L];
CR[];
FOR i: MB.BIndex IN [0..data.inputBCDs.nBcds) DO
mt: MB.MT = data.inputBCDs.bcds[i].mt;
Text[data.inputBCDs.bcds[i].name]; CR[];
FOR gfi: CARDINAL IN [1..LENGTH[mt]) DO
frame: PrincOps.GlobalFrameHandle;
s: STRING ← [20];
IF mt[gfi].mth.gfi # gfi THEN LOOP;
frame ← mt[gfi].frame;
Text[" Frame["L];
Number[frame, octal];
Text["] gfi: "L];
Number[MB.VirtualGlobalFrame[frame].gfi, octal];
Text[", shared: "L];
Boolean[MB.VirtualGlobalFrame[frame].shared];
Text[", alloced: "L];
Boolean[MB.VirtualGlobalFrame[frame].alloced];
Text[", codelinks: "L];
Boolean[MB.VirtualGlobalFrame[frame].codelinks];
Text[", codebase: "L];
String.AppendLongNumber[s, MB.VirtualGlobalFrame[frame].code.longbase, 8];
Text[s];
CR[];
ENDLOOP;
CR[];
ENDLOOP;
};
END.