-- FindSigs.Mesa Edited by Sandman on July 8, 1980 8:48 AM -- Copyright Xerox Corporation 1979, 1980 DIRECTORY AltoFileDefs USING [CFA], ControlDefs USING [ControlLink, PrefixHandle], FastDirDefs USING [StripSwitches, Cap], FrameOps USING [FrameSize], ImageDefs USING [StopMesa], ImageFileInfoDefs USING [ CodeSegForFrame, EnumerateGlobalFrames, FindAllSymbols, FrameToModuleName, GlobalFrameHandle, SetImage, SymbolSegForFrame, Version, VirtualGlobalFrame], IODefs USING [CR, SP], MiscDefs USING [CommandLineCFA], PrincOps USING [ControlLink], OutputDefs USING [ CloseOutput, OpenOutput, PutCR, PutChar, PutNumber, PutOctal, PutString, PutTime], SegmentDefs USING [ FileSegmentAddress, FileSegmentHandle, InsertFile, SwapIn, Unlock], StreamDefs USING [CreateByteStream, JumpToFA, Read, StreamHandle], String USING [AppendChar, AppendString, AppendSubString, SubStringDescriptor], SymbolTable USING [Acquire, Release, Base, TableForSegment], Symbols USING [BTIndex, HTIndex, ISEIndex, ISENull, BTNull, CBTIndex], Storage USING [CopyString, FreeString]; FindSigs: PROGRAM IMPORTS FastDirDefs, ImageDefs, OutputDefs, SegmentDefs, StreamDefs, String, SymbolTable, Storage, ImageFileInfoDefs, MiscDefs, FrameOps = BEGIN OPEN SegmentDefs; SigItem: TYPE = RECORD [name: STRING, desc: CARDINAL]; comstr: StreamDefs.StreamHandle ← GetCommandLineStream[]; sigdata: ARRAY [0..128) OF SigItem; nsigs: CARDINAL; symbols: SymbolTable.Base; PrintSignals: PROCEDURE [gfi: CARDINAL] = BEGIN tname: STRING ← [60]; sei: Symbols.ISEIndex; t, desc: CARDINAL; nsigs ← 0; FOR sei ← symbols.FirstCtxSe[symbols.stHandle.outerCtx], symbols.NextSe[sei] UNTIL sei = Symbols.ISENull DO OPEN id: symbols.seb[sei]; IF id.immutable THEN WITH symbols.seb[symbols.UnderType[id.idType]] SELECT FROM transfer => IF (mode = signal OR mode = error) AND symbols.seb[sei].idCtx = symbols.stHandle.outerCtx THEN BEGIN GetName[tname, symbols.seb[sei].hash]; desc ← symbols.seb[sei].idValue; t ← nsigs; WHILE t > 0 DO IF sigdata[t - 1].desc < desc THEN EXIT; sigdata[t] ← sigdata[t - 1]; t ← t - 1; ENDLOOP; nsigs ← nsigs + 1; sigdata[t] ← [Storage.CopyString[tname], desc]; END; ENDCASE; ENDLOOP; FOR t IN [0..nsigs) DO PutIdValue[sigdata[t].desc, gfi]; OutputDefs.PutString[" "L]; OutputDefs.PutString[sigdata[t].name]; OutputDefs.PutCR[]; Storage.FreeString[sigdata[t].name] ENDLOOP; RETURN END; PrintProcs: PROCEDURE [ gfi: CARDINAL, codeseg: FileSegmentHandle, offset: CARDINAL] = BEGIN OPEN symbols; bti, prev: Symbols.BTIndex; cp: ControlDefs.PrefixHandle ← NIL; IF codeseg # NIL THEN BEGIN SwapIn[codeseg]; cp ← FileSegmentAddress[codeseg] + offset; END; bti ← LOOPHOLE[0]; OutputDefs.PutCR[]; DO WITH bb[bti] SELECT FROM Callable => IF ~inline THEN Proc[LOOPHOLE[bti], gfi, cp]; ENDCASE; IF bb[bti].firstSon # Symbols.BTNull THEN bti ← bb[bti].firstSon ELSE DO prev ← bti; bti ← bb[bti].link.index; IF bti = Symbols.BTNull THEN GO TO Done; IF bb[prev].link.which # parent THEN EXIT; ENDLOOP; REPEAT Done => NULL; ENDLOOP; IF codeseg # NIL THEN Unlock[codeseg]; OutputDefs.PutCR[]; END; Proc: PROCEDURE [ bti: Symbols.CBTIndex, gfi: CARDINAL, cp: ControlDefs.PrefixHandle] = BEGIN OPEN symbols; isei: Symbols.ISEIndex ← bb[bti].id; fsi, origin: CARDINAL; WITH bb[bti].info SELECT FROM External => BEGIN OPEN OutputDefs; PutIdValue[seb[isei].idValue, gfi]; IF cp # NIL THEN BEGIN fsi ← cp.entry[bb[bti].entryIndex].info.framesize; PutNumber[fsi, [8, FALSE, TRUE, 3]]; PutNumber[FrameOps.FrameSize[fsi], [8, FALSE, TRUE, 5]]; origin ← cp.entry[bb[bti].entryIndex].initialpc; PutNumber[origin*2, [8, FALSE, TRUE, 5]]; END; PutNumber[bytes, [10, FALSE, TRUE, 4]]; PutString[" "L]; PutBodyName[isei]; PutCR[]; END; ENDCASE; RETURN END; PutBodyName: PROCEDURE [isei: Symbols.ISEIndex] = BEGIN OPEN symbols; name: STRING ← [60]; IF isei = Symbols.ISENull THEN name ← "(priv)"L ELSE GetName[name, seb[isei].hash]; OutputDefs.PutString[name]; END; PutIdValue: PROCEDURE [num, gfi: CARDINAL] = BEGIN OPEN OutputDefs; proc: ControlDefs.ControlLink; gfiOffset: CARDINAL ← LOOPHOLE[num, PrincOps.ControlLink].gfi; epOffset: CARDINAL ← LOOPHOLE[num, PrincOps.ControlLink].ep; proc ← [procedure[gfi: gfiOffset + gfi - 1, ep: epOffset, tag: procedure]]; PutString[" "L]; PutNumber[LOOPHOLE[proc], [8, FALSE, TRUE, 6]]; PutChar['B]; END; MungeModule: PROCEDURE [f: ImageFileInfoDefs.GlobalFrameHandle] RETURNS [BOOLEAN] = BEGIN OPEN ImageFileInfoDefs; Cleanup: PROCEDURE = BEGIN SymbolTable.Release[symbols] END; symseg, codeseg: FileSegmentHandle; offset: CARDINAL; modname: STRING ← [60]; BEGIN FrameToModuleName[f, modname ! ANY => GOTO badFrame]; OutputDefs.PutCR[]; OutputDefs.PutNumber[LOOPHOLE[f], [8, FALSE, TRUE, 6]]; OutputDefs.PutString["B "]; symseg ← SymbolSegForFrame[f ! ANY => GOTO badName]; IF symseg = NIL THEN BEGIN OPEN OutputDefs; PutString[modname]; PutString[" (cannot find symbols)"]; PutCR[]; RETURN[FALSE] END; symbols ← SymbolTable.Acquire[SymbolTable.TableForSegment[symseg]]; [seg: codeseg, offset: offset] ← CodeSegForFrame[f ! ANY => GOTO badName]; WITH symbols.bb[FIRST[Symbols.BTIndex]] SELECT FROM Callable => GetName[modname, symbols.seb[id].hash]; ENDCASE; OutputDefs.PutString[modname]; OutputDefs.PutCR[]; IF sigs THEN PrintSignals[ VirtualGlobalFrame[f].gfi ! ANY => BEGIN Cleanup[]; GOTO badName END]; IF procs THEN PrintProcs[ VirtualGlobalFrame[f].gfi, codeseg, offset ! ANY => BEGIN Cleanup[]; GOTO badName END]; Cleanup[]; EXITS badFrame => BEGIN OPEN OutputDefs; PutOctal[f]; PutString[" (problems encountered)"L]; END; badName => BEGIN OPEN OutputDefs; PutString[modname]; PutString[" (problems encountered)"L]; END; END; RETURN[FALSE] END; GetName: PROCEDURE [s: STRING, hti: Symbols.HTIndex] = BEGIN ss: String.SubStringDescriptor; symbols.SubStringForHash[@ss, hti]; s.length ← 0; String.AppendSubString[s, @ss]; END; sigs, procs: BOOLEAN; SetSwitches: PROCEDURE [root: STRING] = BEGIN i: CARDINAL; switches: STRING ← [10]; notMinus: BOOLEAN ← TRUE; sigs ← TRUE; procs ← FALSE; -- reset from last time FastDirDefs.StripSwitches[root, switches]; IF switches = NIL THEN RETURN; FOR i IN [0..switches.length) DO SELECT FastDirDefs.Cap[ switches[i]] FROM '- => BEGIN notMinus ← FALSE; LOOP END; 'P => procs ← notMinus; 'S => sigs ← notMinus; ENDCASE => LOOP; notMinus ← TRUE; ENDLOOP; END; CheckForExtension: PROCEDURE [name, ext: STRING] = BEGIN i: CARDINAL; FOR i IN [0..name.length) DO IF name[i] = '. THEN RETURN; ENDLOOP; String.AppendString[name, ext]; RETURN END; ProcessImage: PROCEDURE = BEGIN infile: STRING ← [40]; root: STRING ← [40]; i: CARDINAL; GetToken[infile]; WHILE infile.length # 0 DO SetSwitches[infile]; CheckForExtension[infile, ".image"]; FOR i IN [0..infile.length) DO IF infile[i] = '. THEN EXIT; String.AppendChar[root, infile[i]]; ENDLOOP; ImageFileInfoDefs.SetImage[infile]; ImageFileInfoDefs.FindAllSymbols[]; OutputDefs.OpenOutput[root, IF procs THEN ".procs"L ELSE ".signals."L]; WriteHerald[infile]; [] ← ImageFileInfoDefs.EnumerateGlobalFrames[MungeModule]; OutputDefs.CloseOutput[]; GetToken[infile]; root.length ← 0; ENDLOOP; END; WriteHerald: PROCEDURE [name: STRING] = BEGIN OPEN OutputDefs; PutString[name]; PutString[" -- "L]; PutTime[ImageFileInfoDefs.Version[].time]; PutCR[]; PutCR[]; PutCR[]; RETURN END; GetToken: PROCEDURE [token: STRING] = BEGIN c: CHARACTER; token.length ← 0; UNTIL comstr.endof[comstr] DO SELECT c ← comstr.get[ comstr] FROM IODefs.SP, IODefs.CR => IF token.length # 0 THEN RETURN; ENDCASE => String.AppendChar[token, c]; ENDLOOP; RETURN END; GetCommandLineStream: PROCEDURE RETURNS [s: StreamDefs.StreamHandle] = BEGIN OPEN StreamDefs; cfa: POINTER TO AltoFileDefs.CFA ← MiscDefs.CommandLineCFA[]; s ← CreateByteStream[SegmentDefs.InsertFile[@cfa.fp, Read], Read]; JumpToFA[s, @cfa.fa]; RETURN END; -- Main Body ProcessImage[]; ImageDefs.StopMesa[]; END...