-- SymsXD.Mesa Edited by: -- Bruce September 2, 1980 2:20 PM -- Sandman July 17, 1980 11:10 AM -- Johnsson July 21, 1980 5:19 PM DIRECTORY BcdDefs USING [Base, BCD, FTNull, FTSelf, GFTIndex, MTIndex, NullVersion, SGIndex, SGNull, VersionID, VersionStamp], BcdOps USING [BcdBase, FTHandle, MTHandle, NameString, ProcessModules, SGHandle], DebugOps USING [CacheNewFile, FileName, InvalidateFileCache, UserAborted], DLoadState USING [Acquire, AcquireBcd, Invalid, MapRealToConfig, Release, ReleaseBcd], DOutput USING [Blanks, Char, Text], DSymOps USING [CacheItem, DeleteItem, StripExtension, SymHandle, SymRec], DSyms USING [FindFrame, Item], Frames USING [Invalid], Gf USING [File, GFI, Original], ImageDefs USING [ImageVersion], Lookup USING [Fail], MachineDefs USING [ConfigIndex, FileHandle, FSHandle, GFHandle, GFTIndex, NullConfig, PageSize], SegmentDefs USING [DefaultAccess, DeleteFileSegment, FileError, FileHandle, FileNameError, FileSegmentAddress, FileSegmentHandle, LongVMtoFileSegment, MoveFileSegment, NewFile, NewFileSegment, OldFileOnly, PageNumber, Read, SwapIn, SwapOut, Unlock], Storage USING [Pages], String USING [AppendString], Strings USING [AppendSubString, SubStringDescriptor], SymbolOps USING [EnterString], Symbols USING [HTIndex, HTNull], SymbolTable USING [Missing], Table USING [Base, Region], UserInput USING [userAbort]; SymsXD: PROGRAM IMPORTS BcdOps, DLoadState, Strings, DSymOps, DSyms, DebugOps, DOutput, Frames, Gf, ImageDefs, Lookup, SegmentDefs, Storage, String, SymbolOps, SymbolTable, UserInput EXPORTS DSymOps = BEGIN OPEN DSymOps, DSyms, MachineDefs; myVersion: PUBLIC BcdDefs.VersionStamp ← ImageDefs.ImageVersion[]; CantAttach: ERROR = CODE; SymbolTableProblem: ERROR = CODE; SymbolSegForFrame: PUBLIC PROCEDURE [h: SymHandle] = BEGIN cgfi: GFTIndex; config: ConfigIndex; ssb: BcdOps.NameString; bcd: BcdOps.BcdBase; cdesc, segdesc: BcdDefs.SGIndex; FindModule: PROCEDURE [mth: BcdOps.MTHandle, mti: BcdDefs.MTIndex] RETURNS [BOOLEAN] = BEGIN ssd: Strings.SubStringDescriptor; IF cgfi IN [mth.gfi..mth.gfi+mth.ngfi) THEN BEGIN IF h.hti = Symbols.HTNull THEN { ssd ← [base: @ssb.string, offset: mth.name, length: ssb.size[mth.name]]; h.hti ← SymbolOps.EnterString[@ssd]}; cdesc ← mth.code.sgi; segdesc ← mth.sseg; h.jumped ← mth.crossJumped; SELECT mth.file FROM BcdDefs.FTNull, BcdDefs.FTSelf => NULL; ENDCASE => { f: BcdOps.FTHandle = @LOOPHOLE[bcd+bcd.ftOffset, BcdDefs.Base][mth.file]; h.version ← f.version}; RETURN[TRUE]; END; IF UserInput.userAbort THEN SIGNAL DebugOps.UserAborted; RETURN[FALSE]; END; [] ← DLoadState.Acquire[ ! DLoadState.Invalid => GOTO nil]; [cgfi,config] ← DLoadState.MapRealToConfig[Gf.GFI[Gf.Original[h.gf]]]; IF config = NullConfig THEN { DLoadState.Release[]; ERROR Frames.Invalid[h.gf]}; bcd ← DLoadState.AcquireBcd[config]; ssb ← LOOPHOLE[bcd+bcd.ssOffset]; [] ← BcdOps.ProcessModules[bcd, FindModule ! UNWIND => Cleanup[bcd]]; FindSeg[h, bcd, segdesc, cdesc ! SegmentDefs.FileNameError, SegmentDefs.FileError => {Cleanup[bcd]; GOTO nil}; UNWIND => Cleanup[bcd]]; Cleanup[bcd]; IF h.hti = Symbols.HTNull THEN ERROR Frames.Invalid[h.gf]; EXITS nil => RETURN; END; FindSeg: PROCEDURE [h: SymHandle, bcd: BcdOps.BcdBase, syms, code: BcdDefs.SGIndex] = BEGIN OPEN SegmentDefs; sgb: BcdDefs.Base = LOOPHOLE[bcd+bcd.sgOffset]; sgh: BcdOps.SGHandle = @sgb[syms]; file: SegmentDefs.FileHandle ← NIL; f: BcdOps.FTHandle = @LOOPHOLE[bcd+bcd.ftOffset, BcdDefs.Base][sgh.file]; symsbcd: BcdOps.BcdBase; SELECT sgh.file FROM BcdDefs.FTNull => RETURN; BcdDefs.FTSelf => BEGIN bcdseg: FSHandle ← LongVMtoFileSegment[bcd]; h.seg ← NewFileSegment[bcdseg.file, sgh.base, sgh.pages+sgh.extraPages, Read]; h.fgt ← sgh.extraPages # 0; h.version ← f.version; RETURN; END; sgb[code].file => file ← Gf.File[h.gf]; ENDCASE; IF file = NIL THEN file ← OpenFile[bcd,f]; h.seg ← NewFileSegment[file, 1, 1, Read]; SwapIn[h.seg]; symsbcd ← FileSegmentAddress[h.seg]; IF symsbcd.version # f.version THEN { Unlock[h.seg]; DeleteFileSegment[h.seg]; h.seg ← NIL; IncorrectVersion[file]; RETURN}; Unlock[h.seg]; MoveFileSegment[h.seg, sgh.base, sgh.pages+sgh.extraPages]; h.fgt ← sgh.extraPages # 0; RETURN; END; OpenFile: PROC [bcd: BcdOps.BcdBase, f: BcdOps.FTHandle] RETURNS [fh: SegmentDefs.FileHandle] = { ssb: BcdOps.NameString = LOOPHOLE[bcd+bcd.ssOffset]; ss: Strings.SubStringDescriptor ← [@ssb.string, f.name, ssb.size[f.name]]; name: STRING ← [40]; Strings.AppendSubString[name, @ss]; CheckExtension[name]; fh ← DebugOps.CacheNewFile[name, SegmentDefs.DefaultAccess] }; Cleanup: PROC [bcd: BcdOps.BcdBase] = {DLoadState.ReleaseBcd[bcd]; DLoadState.Release[]}; IncorrectVersion: PROC [file: SegmentDefs.FileHandle] = BEGIN OPEN DOutput; name: STRING ← [40]; DebugOps.FileName[name, file]; Char[' ]; Text[name]; Text[" referenced in different versions! "L]; END; CheckExtension: PROCEDURE [s: STRING] = BEGIN i: CARDINAL; FOR i DECREASING IN [1..s.length) DO IF s[i] = '. THEN RETURN; ENDLOOP; String.AppendString[s,".bcd"L]; END; AttachSyms: PUBLIC PROC [gf: GFHandle, file: STRING] = BEGIN syms: Item; mod: STRING ← [40]; rec: SymRec ← [gf: gf, hti: Symbols.HTNull]; fh: FileHandle; String.AppendString[mod,file]; DSymOps.StripExtension[mod]; String.AppendString[mod,".bcd"L]; fh ← SegmentDefs.NewFile[mod,SegmentDefs.Read,SegmentDefs.OldFileOnly ! SegmentDefs.FileNameError => {SIGNAL Lookup.Fail[mod]; CONTINUE}]; IF gf # NIL AND (syms ← FindFrame[gf]) # NIL THEN DSymOps.DeleteItem[syms]; CompilerSeg[@rec,fh ! CantAttach => BEGIN OPEN DOutput; Blanks[1]; Text[mod]; Text[" is a definitions file!"L]; GOTO bad END]; [] ← CacheItem[@rec ! SymbolTable.Missing => BEGIN OPEN DOutput; Blanks[1]; Text[mod]; Text[" does not have a valid symbol table!"L]; CONTINUE END]; DebugOps.InvalidateFileCache[]; EXITS bad => NULL END; CompilerSeg: PROC [h: SymHandle, file: FileHandle] = BEGIN OPEN SegmentDefs; sgh: BcdOps.SGHandle; mth: BcdOps.MTHandle; ssb: BcdOps.NameString; sSeg: BcdDefs.SGIndex; bcdPages: CARDINAL ← 1; bcd: BcdOps.BcdBase; headerSeg: FSHandle ← NewFileSegment[file, 1, bcdPages, Read]; ssd: Strings.SubStringDescriptor; BEGIN DO SwapIn[headerSeg]; bcd ← FileSegmentAddress[headerSeg]; IF bcd.versionIdent # BcdDefs.VersionID THEN GOTO nogood; IF bcdPages = bcd.nPages THEN EXIT; bcdPages ← bcd.nPages; Unlock[headerSeg]; SwapOut[headerSeg]; MoveFileSegment[headerSeg, 1, bcdPages]; ENDLOOP; IF bcd.nConfigs # 0 THEN GOTO nogood; IF bcd.definitions AND h.gf # NIL THEN {CleanupSeg[headerSeg]; ERROR CantAttach}; mth ← @LOOPHOLE[bcd+bcd.mtOffset,Table.Base][FIRST[BcdDefs.MTIndex]]; sSeg ← mth.sseg; h.jumped ← mth.crossJumped; sgh ← @LOOPHOLE[bcd+bcd.sgOffset,Table.Base][sSeg]; IF sSeg=BcdDefs.SGNull OR sgh.pages = 0 OR sgh.file # BcdDefs.FTSelf THEN GOTO nogood; ssb ← LOOPHOLE[bcd+bcd.ssOffset]; ssd ← [base: @ssb.string, offset: mth.name, length: ssb.size[mth.name]]; h.hti ← SymbolOps.EnterString[@ssd]; h.version ← bcd.version; h.seg ← NewFileSegment[file, sgh.base, sgh.pages+sgh.extraPages, Read]; h.fgt ← sgh.extraPages # 0; CleanupSeg[headerSeg]; EXITS nogood => CleanupSeg[headerSeg]; END; END; CleanupSeg: PROCEDURE [seg: FSHandle] = BEGIN SegmentDefs.Unlock[seg]; SegmentDefs.DeleteFileSegment[seg]; END; SymbolTablePages: CARDINAL = 25; SymbolTableSize: CARDINAL = SymbolTablePages*MachineDefs.PageSize; GetRegion: PUBLIC PROCEDURE RETURNS [r: Table.Region] = { r.origin ← LOOPHOLE[Storage.Pages[SymbolTablePages], Table.Base]; r.size ← SymbolTableSize}; END...