-- File ModuleSymbolsImpl.mesa -- Last edited by Lewis on 5-Jan-82 19:46:02 -- Last edited by Satterthwaite, December 27, 1982 9:44 am DIRECTORY BcdDefs USING [FTIndex, FTNull, FTSelf, MTIndex, SGIndex, SGNull, VersionStamp], CIFS: TYPE USING [OpenFile, GetFC], Environment USING [PageCount, wordsPerPage], Error USING [ErrorFile, WrongSymbolsVersion], FileTable USING [Build, Destroy, HandleForFile, UnknownFile], ModuleSymbols USING [], PackageSymbols, PackagerDefs USING [globalData], PrincOps USING [BytePC], SourceBcd USING [ bcdBases, bcdHeader, EnumerateModules, ModuleNum, ModuleNumForMti], Space: TYPE USING [ Handle, nullHandle, virtualMemory, CopyIn, Create, Delete, LongPointer, Map], String USING [SubString], SymbolPack, Symbols USING [HTIndex, HTNull, HTRecord], SymbolSegment USING [STHeader, VersionID], SymbolTable USING [Base], Table USING [Base]; ModuleSymbolsImpl: PROGRAM IMPORTS CIFS, Error, FileTable, PackagerDefs, SourceBcd, Space, ownSymbolPack: SymbolPack EXPORTS ModuleSymbols = BEGIN OPEN ModuleSymbols; InvalidSymbols: PUBLIC ERROR = CODE; SymbolsProblem: PUBLIC SIGNAL = CODE; symSeg: Space.Handle _ Space.nullHandle; symSegSize: Environment.PageCount _ 0; header: LONG POINTER TO SymbolSegment.STHeader _ NIL; symbolPackStarted: BOOL _ FALSE; nullFile: CIFS.OpenFile = NIL; SymbolInfoMap: TYPE = RECORD [ SEQUENCE length: CARDINAL OF KnownSymbolsInfo]; KnownSymbolsInfo: TYPE = RECORD [ loadedBefore: BOOL, file: CIFS.OpenFile, base, pages: CARDINAL]; knownSymbols: LONG POINTER TO SymbolInfoMap _ NIL; -- NB: the REFs here are protected by FileTableImpl outerPackArray: PUBLIC LONG DESCRIPTOR FOR ARRAY OF PackageSymbols.OuterPackRecord; innerPackArray: PUBLIC LONG DESCRIPTOR FOR ARRAY OF PackageSymbols.InnerPackRecord; constArray: PUBLIC LONG DESCRIPTOR FOR ARRAY OF PackageSymbols.ConstRecord; loadCodeOffsetTable: PUBLIC PackageSymbols.PCSeq; loadCodeByteOffsetTable: PUBLIC PackageSymbols.PCSeq; jumpIndirectTable: PUBLIC PackageSymbols.JISeq; Load: PUBLIC PROC [mti: BcdDefs.MTIndex] = { ENABLE UNWIND => Unload[]; sgi: BcdDefs.SGIndex = SourceBcd.bcdBases.mtb[mti].sseg; fti: BcdDefs.FTIndex = SourceBcd.bcdBases.mtb[mti].file; mNum: SourceBcd.ModuleNum; -- known information about module mti base, pSymPages: CARDINAL; file: CIFS.OpenFile; codeVersion: BcdDefs.VersionStamp; PagesForWords: PROC [nWords: CARDINAL] RETURNS [Environment.PageCount] = INLINE BEGIN RETURN [(nWords + (Environment.wordsPerPage-1))/Environment.wordsPerPage] END; SELECT fti FROM BcdDefs.FTNull => {SIGNAL SymbolsProblem; RETURN}; BcdDefs.FTSelf => codeVersion _ SourceBcd.bcdHeader.version; ENDCASE => codeVersion _ SourceBcd.bcdBases.ftb[fti].version; IF sgi = BcdDefs.SGNull THEN {SIGNAL SymbolsProblem; RETURN}; mNum _ SourceBcd.ModuleNumForMti[mti]; [base: base, pages: pSymPages, file: file] _ knownSymbols[mNum]; IF pSymPages > symSegSize THEN GrowSeg[minPages: pSymPages]; symSeg.CopyIn[window: [file: file.GetFC, base: base]]; IF ~knownSymbols[mNum].loadedBefore THEN { IF header.version # codeVersion THEN { Error.WrongSymbolsVersion[ class: error, module: mti, requiredVersion: codeVersion, actualVersion: header.version]; Unload[]; ERROR InvalidSymbols}; pSymPages _ PagesForWords[header.constBlock.offset + header.constBlock.size]; IF pSymPages > symSegSize THEN GrowSeg[minPages: pSymPages]; symSeg.CopyIn[window: [file: file.GetFC, base: base]]; knownSymbols[mNum].pages _ pSymPages; knownSymbols[mNum].loadedBefore _ TRUE}; InstallTable[ownSymbolPack ! ANY => Unload[]]}; Unload: PUBLIC PROC = { outerPackArray _ NIL; innerPackArray _ NIL; constArray _ NIL; loadCodeOffsetTable _ NIL; loadCodeByteOffsetTable _ NIL; jumpIndirectTable _ NIL}; InstallTable: PROC [base: SymbolTable.Base] = { b: LONG POINTER = LOOPHOLE[header]; tB: Table.Base = LOOPHOLE[b]; pCard: LONG POINTER TO CARDINAL; IF header.versionIdent # SymbolSegment.VersionID THEN ERROR InvalidSymbols; base.cacheInfo _ NIL; base.hashVec _ b + header.hvBlock.offset; base.ht _ DESCRIPTOR[ b + header.htBlock.offset, header.htBlock.size/SIZE[Symbols.HTRecord]]; base.ssb _ b + header.ssBlock.offset; base.stHandle _ header; base.sourceFile _ NIL; base.notifier _ base.NullNotifier; outerPackArray _ DESCRIPTOR[ b + header.outerPackBlock.offset, (header.outerPackBlock.size / SIZE[PackageSymbols.OuterPackRecord])]; innerPackArray _ DESCRIPTOR[ b + header.innerPackBlock.offset, (header.innerPackBlock.size / SIZE[PackageSymbols.InnerPackRecord])]; pCard _ LOOPHOLE[b + header.constBlock.offset]; constArray _ DESCRIPTOR[pCard+1, pCard^]; loadCodeOffsetTable _ LOOPHOLE[pCard + 1 + pCard^ * SIZE[PackageSymbols.ConstRecord]]; loadCodeByteOffsetTable _ LOOPHOLE[loadCodeOffsetTable + 1 + loadCodeOffsetTable.length * SIZE[PrincOps.BytePC]]; jumpIndirectTable _ LOOPHOLE[loadCodeByteOffsetTable + 1 + loadCodeByteOffsetTable.length * SIZE[PrincOps.BytePC]]}; FindProc: PUBLIC PROC [ ss: String.SubString] RETURNS [opi: PackageSymbols.OPIndex] = { hti: Symbols.HTIndex = ownSymbolPack.FindString[ss]; l, u, i: PackageSymbols.OPIndex; IF hti = Symbols.HTNull THEN RETURN[PackageSymbols.OPNull]; l _ 1; u _ (LENGTH[outerPackArray] - 1); WHILE l <= u DO i _ CARDINAL[l+u]/2; SELECT outerPackArray[i].hti FROM > hti => u _ i-1; < hti => l _ i+1; ENDCASE => RETURN[i]; ENDLOOP; RETURN[PackageSymbols.OPNull]}; Initialize: PUBLIC PROC [nModules: CARDINAL] = { FillInKnowledge: PROC [mti: BcdDefs.MTIndex] RETURNS [stop: BOOL_FALSE] = { mNum: SourceBcd.ModuleNum = SourceBcd.ModuleNumForMti[mti]; sgi: BcdDefs.SGIndex; base: CARDINAL; file: CIFS.OpenFile _ nullFile; IF SourceBcd.bcdBases.mtb[mti].tableCompiled THEN -- ignore any symbols knownSymbols[mNum] _ [loadedBefore: FALSE, file: nullFile, base: 0, pages: 0] ELSE { sgi _ SourceBcd.bcdBases.mtb[mti].sseg; base _ SourceBcd.bcdBases.sgb[sgi].base; file _ FileTable.HandleForFile[SourceBcd.bcdBases.sgb[sgi].file ! FileTable.UnknownFile => { Error.ErrorFile[ error, "was needed for symbols but could not be found"L, fti]; CONTINUE} ]; knownSymbols[mNum] _ [loadedBefore: FALSE, file: file, base: base, pages: 1]}; RETURN}; FileTable.Build[]; CreateSeg[]; knownSymbols _ PackagerDefs.globalData.zone.NEW[SymbolInfoMap[nModules]]; SourceBcd.EnumerateModules[FillInKnowledge]; IF ~symbolPackStarted THEN {START ownSymbolPack; symbolPackStarted _ TRUE}}; Finalize: PUBLIC PROC = { Unload[]; IF knownSymbols # NIL THEN { FOR i: CARDINAL IN [0..knownSymbols.length) DO knownSymbols[i].file _ nullFile; ENDLOOP; PackagerDefs.globalData.zone.FREE[@knownSymbols]}; FileTable.Destroy[]; DestroySeg[]}; -- Input segment operations CreateSeg: PROC = { IF symSeg # Space.nullHandle THEN ERROR SymbolsProblem; symSegSize _ 30; symSeg _ Space.Create[size: symSegSize, parent: Space.virtualMemory]; -- file: NIL, release: [], -- fileBase: 0, pages: symSegSize, swapInfo: [uniform[size: 3]]]; symSeg.Map[]; header _ symSeg.LongPointer}; GrowSeg: PROC [minPages: Environment.PageCount] = { Space.Delete[symSeg]; symSegSize _ ((minPages+2)/3 * 3); symSeg _ Space.Create[size: symSegSize, parent: Space.virtualMemory]; -- MSegment.Reset[ -- segment: symSeg, pages: symSegSize, swapInfo: [uniform[size: 4]]]; symSeg.Map[]; header _ symSeg.LongPointer}; DestroySeg: PROC = { IF symSeg # Space.nullHandle THEN { Space.Delete[symSeg]; symSeg _ Space.nullHandle; symSegSize _ 0; header _ NIL}}; END.