-- FindProcImpl.mesa
-- Sweet, 6-Oct-83 16:59:47
DIRECTORY
FindProc
MFile USING [Handle];
FindProc: PROGRAM
IMPORTS LoadState
EXPORTS FindProc = {
Lookup: PUBLIC PROC [
gFrame: LONG POINTER, procName: LONG STRING, objectFile: MFile.Handle ← NIL]
RETURNS [p: PROCEDURE = {
procSS: String.SubStringDescriptor ← [
base: procName, offset: 0, length: procName.length];
bcd: BcdOps.BcdBase;
info: LoadStateFormat.ModuleInfo;
frame: PrincOps.GlobalFrameHandle ←
SpecialRuntime.GlobalFrameFromProgram[gFrame];
loadState: LoadStateFormat.Handle;
bcdInfo: LoadState.LPBcdInfoTable ← NIL;
link: PrincOps.ControlLink;
mtb, enb, sgb, ftb: Table.Base;
mti: BcdDefs.MTIndex;
mth: BcdOps.MTHandle;
ssb: LONG POINTER TO BcdDefs.PackedString;
ep: CARDINAL;
fileName: STRING ← [60];
fileVersion: BcdDefs.VersionStamp;
symsBase, symsPages: CARDINAL;
BEGIN -- make bcdInfo visible in exits
Runtime.ValidateGlobalFrame[frame ! Runtime.InvalidFrame => GO TO notFound];
[loadState, bcdInfo] ← LoadState.LockBcdInfo[];
BEGIN ENABLE UNWIND => IF bcdInfo # NIL THEN LoadState.UnlockBcdInfo[];
info ← LoadState.GetModuleInfo[frame];
bcd ← bcdInfo[info.index].base;
mtb ← bcd + bcd.mtOffset;
sgb ← bcd + bcd.sgOffset;
ftb ← bcd + bcd.ftOffset;
ssb ← LOOPHOLE[bcd + bcd.ssOffset];
mti ← BcdDefs.MTIndex.FIRST + (info.cgfi - 1) * BcdDefs.MTRecord.SIZE;
mth ← @mtb[mti];
fileVersion ← ftb[mth.file].version;
AppendName[fileName, ssb, ftb[sgb[mth.sseg].file].name !
String.StringBoundsFault => GO TO notFound];
symsBase
LoadState.UnlockBcdInfo[];
info ← LoadState.GetModuleInfo[frame];
bcd ← bcdInfo[info.index].base;
enb ← bcd + bcd.enOffset;
END; -- ENABLE UNWIND
IF bcdInfo # NIL THEN LoadState.UnlockBcdInfo[];
RETURN [LOOPHOLE[link]];
EXITS
notFound => {IF bcdInfo # NIL THEN LoadState.UnlockBcdInfo[]; RETURN [NIL]};
END; -- make bcdInfo visible in exits
};
SubStringForName: PROC [
ss: String.SubString,
ssb: LONG POINTER TO BcdDefs.PackedString,
name: BcdDefs.NameRecord] = {
ss.base ← @ssb.string;
ssb.offset ← name;
ssb.length ← ssb.size[name]};
AppendName: PROC [
str: LONG STRING, ssb: LONG POINTER TO BcdDefs.PackedString,
name: BcdDefs.NameRecord] = {
desc: String.SubStrinDescriptor;
SubStringForName[@desc, ssb, name];
String.AppendSubString[str, @desc]};
}.