-- 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.