-- File: ModuleNameImpl.mesa
-- last edited by Levin: 10-Mar-81 15:06:03
-- edited by Brotz, April 2, 1981 9:14 AM
DIRECTORY
BcdDefs USING [MTIndex],
BcdOps USING [BcdBase, MTHandle, NameString, ProcessModules],
ControlDefs USING [
ControlLink, FrameCodeBase, GFT, GFTIndex, GFTItem, GlobalFrameHandle,
NullGlobalFrame],
FrameDefs USING [GlobalFrame, InvalidGlobalFrame, SwapInCode],
FrameOps USING [CodeHandle],
LoadStateOps USING [
AcquireBcd, ConfigIndex, InputLoadState, MapRealToConfig, NullConfig, ReleaseBcd,
ReleaseLoadState],
ModuleName USING [],
SDDefs USING [SD, sGFTLength],
SegmentDefs USING [FileSegmentHandle, Unlock],
String USING [AppendChar, AppendOctal, AppendSubString, SubStringDescriptor];
ModuleNameImpl: PROGRAM
IMPORTS BcdOps, FrameDefs, FrameOps, LoadStateOps, SegmentDefs, String
EXPORTS ModuleName =
BEGIN OPEN ControlDefs;
ControlLinkToModuleName: PUBLIC PROCEDURE [link: ControlLink, s: STRING] =
BEGIN OPEN FrameDefs;
s.length ← 0;
GlobalFrameToModuleName
[GlobalFrame[link ! InvalidGlobalFrame => CONTINUE], s
! ANY => CONTINUE];
END;
GlobalFrameToModuleName: PUBLIC PROCEDURE [f: GlobalFrameHandle, s: STRING] =
BEGIN
s.length ← 0;
FrameToName[f, s ! ANY => CONTINUE];
IF s.length = 0 THEN {String.AppendChar[s, '?]; AppendBracketed[s, f]};
END;
FrameToName: PROCEDURE [f: GlobalFrameHandle, s: STRING] =
BEGIN OPEN BcdDefs, BcdOps, LoadStateOps;
cgfi: GFTIndex;
config: ConfigIndex;
ssb: NameString;
bcd: BcdBase;
FindModuleString: PROCEDURE [mth: MTHandle, mti: MTIndex] RETURNS [BOOLEAN] =
BEGIN
ssd: String.SubStringDescriptor;
IF cgfi IN [mth.gfi..mth.gfi+mth.ngfi) THEN
BEGIN OPEN String;
ssd ← [base: @ssb.string, offset: mth.name, length: ssb.size[mth.name]];
AppendSubString[s, @ssd];
IF f.copied THEN AppendBracketed[s, f.gfi];
RETURN[TRUE]
END;
RETURN[FALSE];
END;
[] ← InputLoadState[];
[cgfi, config] ← MapRealToConfig[(IF f.copied THEN FindOriginal[f] ELSE f).gfi];
IF config = NullConfig THEN {ReleaseLoadState[]; RETURN};
bcd ← AcquireBcd[config];
ssb ← LOOPHOLE[bcd + bcd.ssOffset];
[] ← ProcessModules[bcd, FindModuleString];
ReleaseBcd[bcd];
ReleaseLoadState[];
END;
AppendBracketed: PROCEDURE [s: STRING, value: UNSPECIFIED] =
{OPEN String; AppendChar[s, '[]; AppendOctal[s, value]; AppendChar[s, ']]};
FindOriginal: PROCEDURE [copy: GlobalFrameHandle] RETURNS [GlobalFrameHandle] =
BEGIN
Original: PROCEDURE [f: GlobalFrameHandle] RETURNS [BOOLEAN] =
{RETURN[f ~= copy AND ~f.copied AND SameModule[copy, f]]};
RETURN[ReverseEnumerateGFT[Original]]
END;
SameModule: PROCEDURE [f1, f2: GlobalFrameHandle] RETURNS [same: BOOLEAN] =
BEGIN
o1, o2: BOOLEAN;
seg1, seg2: SegmentDefs.FileSegmentHandle;
fcb1, fcb2: FrameCodeBase;
seg1 ← FrameOps.CodeHandle[f1];
seg2 ← FrameOps.CodeHandle[f2];
IF seg1 ~= seg2 THEN RETURN[FALSE];
fcb1 ← f1.code; fcb2 ← f2.code;
IF (o1 ← f1.code.out) AND (o2 ← f2.code.out) THEN RETURN[f1.code = f2.code];
FrameDefs.SwapInCode[f1];
FrameDefs.SwapInCode[f2];
same ← f1.code = f2.code;
SegmentDefs.Unlock[seg1];
SegmentDefs.Unlock[seg2];
IF ~f1.started THEN f1.code ← fcb1;
IF ~f2.started THEN f2.code ← fcb2;
END;
ReverseEnumerateGFT: PROCEDURE [proc: PROCEDURE [GlobalFrameHandle] RETURNS [BOOLEAN]]
RETURNS [frame: GlobalFrameHandle] =
BEGIN
gft: POINTER TO ARRAY [0..0) OF GFTItem ← GFT;
FOR i: GFTIndex DECREASING IN [0..SDDefs.SD[SDDefs.sGFTLength]) DO
frame ← gft[i].frame;
IF frame ~= NullGlobalFrame AND gft[i].epbase = 0 AND proc[frame] THEN RETURN;
ENDLOOP;
RETURN[NullGlobalFrame]
END;
END.