DIRECTORY AMBridge USING[ GFHFromTV, IsRemote, RemoteGFHFromTV, GetWorld, TVForGFHReferent, TVForRemoteGFHReferent, RemoteGlobalFrameHandle, nilRemoteGlobalFrameHandle ], AMModel USING[SectionObj, SectionClass, Context], AMModelLocation USING[CodeLocation], AMModelPrivate USING[ SectionRec, EPI, FGIToEPI, FGIToFirstPC, EPIToFirstPC, EPIToLastPC, PCOffset, GetModuleSTB ], AMTypes USING[Error], BcdDefs USING[VersionStamp, MTIndex, FTSelf, BcdBase], LoadState USING[ local, ModuleInfo, ConfigInfo, Acquire, Release, EnumerateAllModules, GlobalFrameToModule, Handle, ConfigID, ModuleIndex ], PrincOps USING[FrameCodeBase, BytePC, GlobalFrameHandle], RTSymbolDefs USING[SymbolTableBase], RTSymbols USING[ReleaseSTB], RTTypesPrivate USING[GetPc], RTTypesRemotePrivate USING[ GetRemoteGFHeader, GetRemotePc, AcquireRemoteBCD, ReleaseRemoteBCD ], Table USING[Base], WorldVM USING[ World, NoWorld, LocalWorld, Lock, Unlock, Loadstate, CurrentIncarnation, ShortAddress ]; AMModelLocationImpl: PROGRAM IMPORTS AMBridge, AMModel, AMModelPrivate, AMTypes, LoadState, RTSymbols, RTTypesPrivate, RTTypesRemotePrivate, WorldVM EXPORTS AMModel, AMModelLocation, AMModelPrivate = { OPEN AMBridge, AMModel, AMModelLocation, AMModelPrivate, AMTypes, RTSymbolDefs, RTSymbols, RTTypesPrivate, RTTypesRemotePrivate, PrincOps, WorldVM; Section: TYPE = REF SectionObj; SectionObj: PUBLIC TYPE = SectionRec; EntryLocations: PUBLIC PROC[section: Section] RETURNS[world: World, list: LIST OF CodeLocation _ NIL] = {[world: world, list: list] _ GetLocations[section]}; ExitLocations: PUBLIC PROC[section: Section] RETURNS[world: World, list: LIST OF CodeLocation _ NIL] = {[world: world, list: list] _ GetLocations[section: section, entry: FALSE]}; GetLocations: PROC[section: Section, entry: BOOL _ TRUE] RETURNS[world: World _ NoWorld[], list: LIST OF CodeLocation _ NIL] = { epi: EPI; firstPC: PCOffset; progContexts: LIST OF Context _ NIL; context: Context _ NIL; version: BcdDefs.VersionStamp; SELECT SectionClass[section] FROM statement => { statementSect: REF statement SectionObj = NARROW[section]; context _ statementSect.prog.someGFHTV; IF context = NIL THEN RETURN; -- section is not loaded version _ statementSect.prog.versionStamp; world _ GetWorld[context]; IF world = LocalWorld[] THEN { bcd: BcdDefs.BcdBase = GetLocalBCD[GFHFromTV[context]]; stb: SymbolTableBase _ GetModuleSTB[bcd, statementSect.prog.versionStamp]; { ENABLE UNWIND => ReleaseSTB[stb]; epi _ FGIToEPI[stb, statementSect.fgtIndex]; firstPC _ FGIToFirstPC[stb, statementSect.fgtIndex]; }; -- end ENABLE UNWIND ReleaseSTB[stb]; } -- end IF world = LocalWorld[] ELSE { -- remote world case bcd: BcdDefs.BcdBase = GetRemoteBCD[RemoteGFHFromTV[context]]; stb: SymbolTableBase _ GetModuleSTB[bcd, statementSect.prog.versionStamp ! UNWIND => ReleaseRemoteBCD[bcd]]; ReleaseRemoteBCD[bcd]; { ENABLE UNWIND => ReleaseSTB[stb]; epi _ FGIToEPI[stb, statementSect.fgtIndex]; firstPC _ FGIToFirstPC[stb, statementSect.fgtIndex]; }; -- end ENABLE UNWIND ReleaseSTB[stb]; }; }; proc => { procSect: REF proc SectionObj = NARROW[section]; context _ procSect.prog.someGFHTV; IF context = NIL THEN RETURN; -- section is not loaded version _ procSect.prog.versionStamp; epi _ procSect.entryPointIndex; world _ GetWorld[context]; IF world = LocalWorld[] THEN { bcd: BcdDefs.BcdBase = GetLocalBCD[GFHFromTV[context]]; stb: SymbolTableBase _ GetModuleSTB[bcd, procSect.prog.versionStamp]; { ENABLE UNWIND => ReleaseSTB[stb]; IF entry THEN firstPC _ EPIToFirstPC[stb, epi, TRUE] ELSE firstPC _ EPIToLastPC[stb, epi]; }; -- end ENABLE UNWIND ReleaseSTB[stb]; } ELSE { -- remote world case bcd: BcdDefs.BcdBase = GetRemoteBCD[RemoteGFHFromTV[context]]; stb: SymbolTableBase _ GetModuleSTB[bcd, procSect.prog.versionStamp ! UNWIND => ReleaseRemoteBCD[bcd]]; ReleaseRemoteBCD[bcd]; { ENABLE UNWIND => ReleaseSTB[stb]; IF entry THEN firstPC _ EPIToFirstPC[stb, epi, TRUE] ELSE firstPC _ EPIToLastPC[stb, epi]; }; -- end ENABLE UNWIND ReleaseSTB[stb]; }; }; ENDCASE => ERROR Error[ reason: typeFault, msg: "EntryLocation applied to a section neither for a statement nor a proc"]; progContexts _ ProgContextsForVersion[world: world, version: version]; IF progContexts = NIL THEN ERROR; FOR contextList: LIST OF Context _ progContexts, contextList.rest UNTIL contextList = NIL DO codeBase: PrincOps.FrameCodeBase; pc: PrincOps.BytePC; context: Context = contextList.first; found: BOOL _ FALSE; IF IsRemote[context] THEN { codeBase _ GetRemoteGFHeader[RemoteGFHFromTV[context]].code; pc _ [firstPC + GetRemotePc[RemoteGFHFromTV[context], epi]]; } ELSE { codeBase _ GFHFromTV[context].code; pc _ [firstPC + GetPc[GFHFromTV[context], epi]]; }; FOR cll: LIST OF CodeLocation _ list, cll.rest UNTIL cll = NIL DO IF cll.first.codeBase = codeBase THEN {found _ TRUE; EXIT}; ENDLOOP; IF NOT found THEN list _ CONS[[codeBase: codeBase, pc: pc], list]; ENDLOOP; }; -- end GetLocations ProgContextsForVersion: PROC[world: World, version: BcdDefs.VersionStamp] RETURNS[contexts: LIST OF Context _ NIL] = { IF world = LocalWorld[] THEN { forEachModule: PROC[ci: LoadState.ConfigID, mi: LoadState.ModuleIndex] RETURNS[stop: BOOL _ FALSE] = { bcd: BcdDefs.BcdBase = LoadState.local.ConfigInfo[ci].bcd; ftb: Table.Base _ LOOPHOLE[bcd + bcd.ftOffset]; mtb: Table.Base _ LOOPHOLE[bcd + bcd.mtOffset]; gfh: GlobalFrameHandle; mti: BcdDefs.MTIndex; [gfh: gfh, mti: mti] _ LoadState.local.ModuleInfo[ci, mi]; IF NOT loadStateHeld THEN ERROR; IF (IF mtb[mti].file = BcdDefs.FTSelf THEN bcd.version ELSE ftb[mtb[mti].file].version) = version THEN contexts _ CONS[TVForGFHReferent[gfh], contexts]; }; loadStateHeld: BOOL _ FALSE; LoadState.local.Acquire[]; loadStateHeld _ TRUE; [] _ LoadState.local.EnumerateAllModules[newestFirst, forEachModule ! ANY => {LoadState.local.Release[]; loadStateHeld _ FALSE}]; IF loadStateHeld THEN LoadState.local.Release[]; } -- end local case of ProgContextsForVersion ELSE { -- remote world case of ProgContextsForVersion Lock[world]; { ENABLE UNWIND => Unlock[world]; forEachModule: PROC[ci: LoadState.ConfigID, mi: LoadState.ModuleIndex] RETURNS[stop: BOOL _ FALSE] = { bcd: BcdDefs.BcdBase = AcquireRemoteBCD [world, WorldVM.CurrentIncarnation[world], newState.ConfigInfo[ci].bcd]; { ENABLE UNWIND => ReleaseRemoteBCD[bcd]; ftb: Table.Base _ LOOPHOLE[bcd + bcd.ftOffset]; mtb: Table.Base _ LOOPHOLE[bcd + bcd.mtOffset]; gfh: GlobalFrameHandle; rgfh: RemoteGlobalFrameHandle _ nilRemoteGlobalFrameHandle; mti: BcdDefs.MTIndex; [gfh: gfh, mti: mti] _ newState.ModuleInfo[ci, mi]; rgfh _ [world, WorldVM.CurrentIncarnation[world], LOOPHOLE[gfh, WorldVM.ShortAddress]]; IF NOT loadStateHeld THEN ERROR; IF (IF mtb[mti].file = BcdDefs.FTSelf THEN bcd.version ELSE ftb[mtb[mti].file].version) = version THEN contexts _ CONS[TVForRemoteGFHReferent[rgfh], contexts]; }; -- end ENABLE UNWIND => ReleaseRemoteBCD[bcd]; ReleaseRemoteBCD[bcd]; }; -- end forEachModule loadStateHeld: BOOL _ FALSE; newState: LoadState.Handle = WorldVM.Loadstate[world]; newState.Acquire[]; loadStateHeld _ TRUE; [] _ newState.EnumerateAllModules[newestFirst, forEachModule ! ANY => {newState.Release[]; loadStateHeld _ FALSE}]; IF loadStateHeld THEN newState.Release[]; }; -- end ENABLE UNWIND => Unlock[world]; Unlock[world]; }; -- end remote world case of ProgContextsForVersion }; -- end ProgContextsForVersion GetRemoteBCD: PUBLIC PROC[rgfh: RemoteGlobalFrameHandle] RETURNS[bcd: BcdDefs.BcdBase _ NIL] = { h: LoadState.Handle; WorldVM.Lock[rgfh.world]; h _ WorldVM.Loadstate[rgfh.world ! UNWIND => WorldVM.Unlock[rgfh.world]]; h.Acquire[]; { ENABLE UNWIND => {h.Release[]; WorldVM.Unlock[rgfh.world]}; gfh: GlobalFrameHandle = LOOPHOLE[rgfh.gfh]; bcd _ AcquireRemoteBCD[ rgfh.world, WorldVM.CurrentIncarnation[rgfh.world], h.ConfigInfo[h.GlobalFrameToModule[gfh].config].bcd ]; }; -- end ENABLE UNWIND h.Release[]; WorldVM.Unlock[rgfh.world]; }; GetLocalBCD: PUBLIC PROC[gfh: GlobalFrameHandle] RETURNS[bcd: BcdDefs.BcdBase] = { LoadState.local.Acquire[]; { ENABLE UNWIND => LoadState.local.Release[]; bcd _ LoadState.local.ConfigInfo[LoadState.local.GlobalFrameToModule[gfh].config].bcd; }; LoadState.local.Release[]; }; }. ,AMModelLocationImpl.mesa Last Modified On August 10, 1983 12:44 pm By Paul Rovner TYPEs either binder output bundle for a config, or compiler output bundle for a prog module, DEFs module, proc, or statement was: progContexts _ SourceSection[SectionSource[section], RootContext[world]].contexts; could be (restrict to one gf): progContexts _ CONS[context, NIL]; want to find all gf's for the indicated section Here with epi, firstPC and all progContext loadings of the section in the specified world This guy uses RTTypesRemotePrivate.AcquireRemoteBCD. BEWARE. Don't forget to release it via RTTypesRemotePrivate.ReleaseRemoteBCD GetRemoteBCD: PUBLIC PROC[world: World, rgfi: PrincOps.GFTIndex] RETURNS[bcd: BcdDefs.BcdBase _ NIL] = { Lock[world]; { ENABLE UNWIND => Unlock[world]; oldState: PilotLoadStateFormat.LoadState; newState: REF PilotLoadStateFormat.LoadStateObject; loadstateHeld: BOOL _ FALSE; newState _ Loadstate[world]; [] _ PilotLoadStateOps.InputLoadState[]; loadstateHeld _ TRUE; oldState _ PilotLoadStatePrivate.InstallLoadState[LOOPHOLE[newState]]; no error raised bcd _ AcquireRemoteBCD[ world, PilotLoadStateOps.AcquireBcd[PilotLoadStateOps.MapRealToConfig[rgfi].config] ! ANY => { [] _ PilotLoadStatePrivate.InstallLoadState[oldState]; PilotLoadStateOps.ReleaseLoadState[]; loadstateHeld _ FALSE; }]; IF loadstateHeld THEN { [] _ PilotLoadStatePrivate.InstallLoadState[oldState]; PilotLoadStateOps.ReleaseLoadState[]; loadstateHeld _ FALSE; }; IF bcd = NIL THEN ERROR; }; end ENABLE UNWIND => Unlock[world]; Unlock[world]; }; end GetRemoteBCD Κ X– "cedar" style˜Iprocšœ™Kšœ8™8K˜šΟk ˜ šœ œ˜Kšœ˜Kšœ˜—Kšœœ$˜1Kšœœ˜$šœœ˜Kšœ œK˜ZKšœ˜—Kšœœ˜Kšœœ)˜6šœ œ˜Kšœx˜xKšœ˜—Kšœ œ+˜9Kšœ œ˜$Kšœ œ ˜Kšœœ˜šœœ˜KšœB˜BKšœ˜—Kšœœ˜šœœ˜KšœU˜UKšœ˜——K˜šœ˜Kšœp˜wKšœ)˜0—K˜Kšœœ˜—™šœ™Kšœv™v—Kšœ œœ ˜Kšœ œœ˜%K˜šΟnœœœ˜-Kšœœœœ˜9Kšœ5˜5—K˜šž œœœ˜,Kšœœœœ˜9KšœDœ˜L—K˜šž œœœœ˜8Kšœ!œœœ˜GKšœœ˜ Kšœ˜Kšœœœ œ˜$Kšœœ˜Kšœ˜šœ˜!šœ˜Kšœœœ ˜:Kšœ'˜'Kš œ œœœΟc˜7Kšœ*˜*Kšœ˜Kšœ˜šœ˜Kšœ7˜7KšœJ˜Jšœœœ˜#Kšœ,˜,Kšœ4˜4—KšœŸ˜Kšœ˜KšœŸ˜ —šœŸ˜Kšœ>˜>šœH˜HKšœœ˜#—Kšœ˜šœœœ˜#Kšœ,˜,Kšœ4˜4—KšœŸ˜Kšœ˜Kšœ˜—Kšœ˜—šœ ˜ Kšœ œœ ˜0Kšœ"˜"Kš œ œœœŸ˜7Kšœ%˜%Kšœ˜Kšœ˜šœ˜šœ˜Kšœ7˜7KšœE˜Ešœœœ˜#Kšœœ"œ˜4Kšœ!˜%—KšœŸ˜Kšœ˜Kšœ˜—šœŸ˜Kšœ>˜>šœC˜CKšœœ˜#—Kšœ˜šœœœ˜#šœœ"œ˜4Kšœ!˜%——KšœŸ˜Kšœ˜Kšœ˜——Kšœ˜—šœ˜ šœ˜ Kšœ˜KšœN˜N———K˜šœF˜FKšœΙ™Ι—Kšœœœœ˜!™KšœY™Y—Kš œœœ*œ˜Yšœ˜Kšœ!˜!Kšœ˜Kšœ%˜%Kšœœœ˜Kšœ˜šœ˜Kšœ<˜Kš œœœ œœ˜>Kšœ˜—Kšœœœœ%˜BKšœ˜—KšœŸ˜—K˜šžœœ-˜IKšœ œœ œ˜,Kšœ˜šœ˜šœœ3˜FKšœœœ˜Kšœ:˜:Kšœœ˜/Kšœœ˜/Kšœ˜Kšœ˜Kšœ:˜:Kšœœœœ˜ šœœ˜%Kšœ ˜Kšœ&˜-—Kšœ œ"˜6Kšœ˜—Kšœœœ˜Kšœ˜Kšœœ˜šœC˜CKšœœ0œ˜=—Kšœœ˜0KšœŸ+˜.—šœŸ.˜5Kšœ ˜ šœœœ˜!šœœ3˜FKšœœœ˜šœ˜šœ˜KšœH˜H——šœœœ˜)Kšœœ˜/Kšœœ˜/Kšœ˜Kšœ;˜;Kšœ˜Kšœ3˜3šœ˜šœ ˜ Kšœ#˜#Kšœœ˜&——Kšœœœœ˜ šœœ˜%Kšœ ˜Kšœ&˜-—Kšœ œ)˜=—KšœŸ.˜2Kšœ˜KšœŸ˜—Kšœœœ˜Kšœ6˜6Kšœ˜Kšœœ˜šœ<˜