-- FindBcdSigs.Mesa Edited by Sandman on August 22, 1980 8:46 AM -- Copyright Xerox Corporation 1979, 1980 DIRECTORY AltoFileDefs USING [CFA], BcdDefs USING [MTIndex], BcdOps USING [BcdBase, MTHandle, NameString, ProcessModules], ControlDefs USING [ControlLink, PrefixHandle], FastDirDefs USING [StripSwitches, Cap], FrameOps USING [FrameSize], ImageDefs USING [StopMesa], BcdInfoDefs USING [CodeForModule, FindAllFiles, SetBcd, SymbolsForModule], IODefs USING [CR, SP, WriteChar, WriteString], MiscDefs USING [CommandLineCFA], OutputDefs USING [ CloseOutput, OpenOutput, PutCR, PutChar, PutNumber, PutOctal, PutString, PutTime], PrincOps USING [ControlLink], SegmentDefs USING [ FileSegmentHandle, FileSegmentAddress, InsertFile, SwapIn, Unlock], StreamDefs USING [CreateByteStream, JumpToFA, Read, StreamHandle], String USING [ AppendChar, AppendString, AppendSubString, InvalidNumber, StringToOctal, SubStringDescriptor], SymbolTable USING [Acquire, Release, Base, TableForSegment], Symbols USING [BTIndex, HTIndex, ISEIndex, ISENull, BTNull, CBTIndex], Storage USING [CopyString, FreeString]; FindBcdSigs: PROGRAM IMPORTS BcdOps, FastDirDefs, ImageDefs, OutputDefs, SegmentDefs, StreamDefs, String, SymbolTable, Storage, BcdInfoDefs, MiscDefs, IODefs, FrameOps = BEGIN OPEN SegmentDefs, OutputDefs; SigItem: TYPE = RECORD [name: STRING, desc: CARDINAL]; altoCode: BOOLEAN; 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; cd: ControlDefs.ControlLink; po: PrincOps.ControlLink; gfiOffset: CARDINAL ← LOOPHOLE[num, PrincOps.ControlLink].gfi; epOffset: CARDINAL ← LOOPHOLE[num, PrincOps.ControlLink].ep; cd ← [procedure[gfi: gfiOffset + gfi - 1, ep: epOffset, tag: procedure]]; po ← [procedure[gfi: gfiOffset + gfi - 1, ep: epOffset, tag: TRUE]]; PutString[" "L]; PutNumber[ IF altoCode THEN LOOPHOLE[cd] ELSE LOOPHOLE[po], [8, FALSE, TRUE, 6]]; PutChar['B]; END; MungeModule: PROCEDURE [mth: BcdOps.MTHandle, mti: BcdDefs.MTIndex] RETURNS [BOOLEAN] = BEGIN OPEN BcdInfoDefs; Cleanup: PROCEDURE = BEGIN SymbolTable.Release[symbols] END; symseg, codeseg: FileSegmentHandle; BEGIN OutputDefs.PutCR[]; WriteModuleName[bcd: bcd, mth: mth]; PutChar[IODefs.SP]; PutChar['[]; IF (altoCode ← mth.altoCode) THEN PutOctal[ ControlDefs.ControlLink[ procedure[gfi: mth.gfi + offset, ep: 0, tag: frame]]] ELSE PutOctal[ PrincOps.ControlLink[ procedure[gfi: mth.gfi + offset, ep: 0, tag: FALSE]]]; PutChar[']]; symseg ← SymbolsForModule[mti: mti ! ANY => GOTO badName]; IF symseg = NIL THEN BEGIN PutString[" (cannot find symbols)"]; PutCR[]; RETURN[FALSE] END; symbols ← SymbolTable.Acquire[SymbolTable.TableForSegment[symseg]]; codeseg ← CodeForModule[mti: mti ! ANY => GOTO badName]; OutputDefs.PutCR[]; IF sigs THEN PrintSignals[mth.gfi + offset ! ANY => BEGIN Cleanup[]; GOTO badName END]; IF procs THEN PrintProcs[ mth.gfi + offset, codeseg, mth.code.offset ! ANY => BEGIN Cleanup[]; GOTO badName END]; Cleanup[]; EXITS badName => BEGIN PutString[" (problems encountered)"L]; END; END; RETURN[FALSE] END; WriteModuleName: PROCEDURE [bcd: BcdOps.BcdBase, mth: BcdOps.MTHandle] = BEGIN ssb: BcdOps.NameString ← LOOPHOLE[bcd + bcd.ssOffset]; i: CARDINAL; FOR i IN [mth.name..mth.name + ssb.size[mth.name]) DO PutChar[ssb.string.text[i]]; ENDLOOP; END; GetName: PROCEDURE [s: STRING, hti: Symbols.HTIndex] = BEGIN ss: String.SubStringDescriptor; symbols.SubStringForHash[@ss, hti]; s.length ← 0; String.AppendSubString[s, @ss]; END; offset: CARDINAL; sigs, procs, number, procdesc, controllink: BOOLEAN; SetSwitches: PROCEDURE [root: STRING] = BEGIN i: CARDINAL; switches: STRING ← [10]; notMinus: BOOLEAN ← TRUE; sigs ← TRUE; number ← procdesc ← 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; 'N => number ← TRUE; 'C => controllink ← TRUE; 'X => procdesc ← TRUE; 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; bcd: BcdOps.BcdBase; ProcessBcd: PROCEDURE = BEGIN infile: STRING ← [40]; root: STRING ← [40]; i: CARDINAL; offset ← 0; DO root.length ← 0; GetToken[infile]; IF infile.length = 0 THEN EXIT; SetSwitches[infile]; IF number OR procdesc THEN BEGIN OPEN String; offset ← StringToOctal[ infile ! InvalidNumber => BEGIN offset ← 0; LOOP END]; IF procdesc THEN offset ← offset/200B; IF controllink THEN offset ← offset/100B; offset ← offset - 1; LOOP; END; CheckForExtension[infile, ".bcd"]; FOR i IN [0..infile.length) DO IF infile[i] = '. THEN EXIT; String.AppendChar[root, infile[i]]; ENDLOOP; bcd ← BcdInfoDefs.SetBcd[infile]; IF bcd # NIL THEN BEGIN BcdInfoDefs.FindAllFiles[]; OpenOutput[root, IF procs THEN ".procs"L ELSE ".signals."L]; WriteHerald[infile]; [] ← BcdOps.ProcessModules[bcd, MungeModule]; CloseOutput[]; END ELSE BEGIN OPEN IODefs; WriteChar['!]; WriteString[infile] END; offset ← 0; ENDLOOP; END; WriteHerald: PROCEDURE [name: STRING] = BEGIN OPEN OutputDefs; PutString[name]; PutString[" -- "L]; PutTime[bcd.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 ProcessBcd[]; ImageDefs.StopMesa[]; END...