-- File ModuleSymbolsImpl.Mesa -- Last edited by Lewis on 15-May-81 18:18:08 -- Last edited by Sweet on 2-Mar-81 15:15:02 DIRECTORY BcdDefs USING [ FTIndex, FTNull, FTSelf, MTIndex, SGIndex, SGNull, VersionStamp], Error USING [ErrorFile, WrongSymbolsVersion], FileTable USING [Build, Destroy, HandleForFile, UnknownFile], LongStorage USING [FreePages, Pages, PagesForWords], ModuleSymbols USING [KnownSymbolsInfo], PackageSymbols USING [ ConstRecord, InnerPackRecord, OPIndex, OPNull, OuterPackRecord], PackEnviron USING [Copy, SymbolSegmentBase, SymSegHandle], PackHeap USING [FreeSpace, GetSpace], Segments USING [ Address, BaseFromSegment, DeleteSegment, FHandle, MoveSegment, NewSegment, Read, SegmentAddress, SHandle, SwapIn, Unlock], SourceBcd USING [ bcdBases, bcdHeader, EnumerateModules, ModuleNum, ModuleNumForMti], Strings, SymbolPack, Symbols USING [HTIndex, HTNull, HTRecord], SymbolSegment USING [VersionID], SymbolTable USING [Base], Table; ModuleSymbolsImpl: PROGRAM IMPORTS Error, FileTable, LongStorage, PackEnviron, PackHeap, Segments, SourceBcd, ownSymbolPack: SymbolPack EXPORTS ModuleSymbols = BEGIN OPEN ModuleSymbols; InvalidSymbols: PUBLIC ERROR = CODE; SymbolsProblem: PUBLIC SIGNAL = CODE; 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; symbolSegmentOpen: BOOLEAN; currentFile: Segments.FHandle; currentSeg: Segments.SHandle; knownSymbols: LONG DESCRIPTOR FOR ARRAY OF ModuleSymbols.KnownSymbolsInfo; symbolPackStarted: BOOLEAN ← FALSE; Load: PUBLIC PROC [mti: BcdDefs.MTIndex] = BEGIN sgi: BcdDefs.SGIndex; fti: BcdDefs.FTIndex; loadedBefore: BOOLEAN; file: Segments.FHandle; base: CARDINAL; mNum: SourceBcd.ModuleNum; pSymPages: CARDINAL; codeVersion: BcdDefs.VersionStamp; handle: PackEnviron.SymSegHandle; sgi ← SourceBcd.bcdBases.mtb[mti].sseg; fti ← SourceBcd.bcdBases.mtb[mti].file; SELECT fti FROM BcdDefs.FTNull => {SIGNAL SymbolsProblem; RETURN}; BcdDefs.FTSelf => codeVersion ← SourceBcd.bcdHeader.version; ENDCASE => codeVersion ← SourceBcd.bcdBases.ftb[fti].version; IF symbolSegmentOpen OR sgi = BcdDefs.SGNull THEN {SIGNAL SymbolsProblem; RETURN} ELSE BEGIN mNum ← SourceBcd.ModuleNumForMti[mti]; [loadedBefore: loadedBefore, base: base, pages: pSymPages, file: file] ← knownSymbols[mNum]; IF file = currentFile THEN -- reuse (i.e. move) current file segment Segments.MoveSegment[ seg: currentSeg, base: base, pages: pSymPages] ELSE BEGIN IF currentSeg # NIL THEN Segments.DeleteSegment[currentSeg]; currentSeg ← Segments.NewSegment[ file: file, base: base, pages: pSymPages, access: Segments.Read]; END; symbolSegmentOpen ← TRUE; IF ~loadedBefore THEN BEGIN Segments.SwapIn[seg: currentSeg, base: PackEnviron.SymbolSegmentBase]; handle ← Segments.SegmentAddress[currentSeg]; IF handle.version # codeVersion THEN BEGIN Error.WrongSymbolsVersion[ class: error, module: mti, requiredVersion: codeVersion, actualVersion: handle.version]; Unload[]; ERROR InvalidSymbols; END; pSymPages ← LongStorage.PagesForWords[handle.constBlock.offset + handle.constBlock.size]; Segments.Unlock[currentSeg]; Segments.MoveSegment[ seg: currentSeg, base: Segments.BaseFromSegment[currentSeg], pages: pSymPages]; END; currentFile ← file; Segments.SwapIn[seg: currentSeg, base: PackEnviron.SymbolSegmentBase]; IF ~loadedBefore THEN BEGIN knownSymbols[mNum].pages ← pSymPages; knownSymbols[mNum].loadedBefore ← TRUE; END; InstallTable[ownSymbolPack, currentSeg ! ANY => Unload[]]; END; END; Unload: PUBLIC PROC = BEGIN IF symbolSegmentOpen THEN { Segments.Unlock[currentSeg]; IF BASE[outerPackArray] # NIL THEN PackHeap.FreeSpace[BASE[outerPackArray]]; outerPackArray ← DESCRIPTOR[NIL, 0]; IF BASE[innerPackArray] # NIL THEN PackHeap.FreeSpace[BASE[innerPackArray]]; innerPackArray ← DESCRIPTOR[NIL, 0]; IF BASE[constArray] # NIL THEN PackHeap.FreeSpace[BASE[constArray]]; constArray ← DESCRIPTOR[NIL, 0]; symbolSegmentOpen ← FALSE}; END; InstallTable: PROC [base: SymbolTable.Base, seg: Segments.SHandle] = BEGIN b: Segments.Address = Segments.SegmentAddress[seg]; tB: Table.Base = LOOPHOLE[b]; p: PackEnviron.SymSegHandle = b; IF p.versionIdent # SymbolSegment.VersionID THEN {Unload[]; ERROR InvalidSymbols}; base.cacheInfo ← NIL; base.hashVec ← b + p.hvBlock.offset; base.ht ← DESCRIPTOR[ b + p.htBlock.offset, p.htBlock.size / SIZE[Symbols.HTRecord]]; base.ssb ← b + p.ssBlock.offset; base.stHandle ← p; base.sourceFile ← NIL; base.notifier ← NullNotifier; outerPackArray ← DESCRIPTOR[ PackHeap.GetSpace[p.outerPackBlock.size], (p.outerPackBlock.size / SIZE[PackageSymbols.OuterPackRecord])]; PackEnviron.Copy[ from: (b + p.outerPackBlock.offset), to: BASE[outerPackArray], nwords: p.outerPackBlock.size]; innerPackArray ← DESCRIPTOR[ PackHeap.GetSpace[p.innerPackBlock.size], (p.innerPackBlock.size / SIZE[PackageSymbols.InnerPackRecord])]; PackEnviron.Copy[ from: (b + p.innerPackBlock.offset), to: BASE[innerPackArray], nwords: p.innerPackBlock.size]; constArray ← DESCRIPTOR[ PackHeap.GetSpace[p.constBlock.size], (p.constBlock.size / SIZE[PackageSymbols.ConstRecord])]; PackEnviron.Copy[ from: (b + p.constBlock.offset), to: BASE[constArray], nwords: p.constBlock.size]; END; NullNotifier: PROC [SymbolTable.Base] = {NULL}; FindProc: PUBLIC PROC [ ss: Strings.SubString] RETURNS [opi: PackageSymbols.OPIndex] = BEGIN 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]; END; Initialize: PUBLIC PROC [nModules: CARDINAL] = BEGIN FillInKnowledge: PROC [mti: BcdDefs.MTIndex] RETURNS [stop: BOOLEAN] = BEGIN mNum: SourceBcd.ModuleNum = SourceBcd.ModuleNumForMti[mti]; sgi: BcdDefs.SGIndex; file: Segments.FHandle ← NIL; base: CARDINAL; IF SourceBcd.bcdBases.mtb[mti].tableCompiled THEN -- ignore any symbols knownSymbols[mNum] ← [ loadedBefore: FALSE, file: NIL, base: 0, pages: 0] ELSE BEGIN sgi ← SourceBcd.bcdBases.mtb[mti].sseg; base ← SourceBcd.bcdBases.sgb[sgi].base; file ← FileTable.HandleForFile[SourceBcd.bcdBases.sgb[sgi].file ! FileTable.UnknownFile => BEGIN Error.ErrorFile[error, "was needed for symbols but could not be found"L, fti]; CONTINUE; END ]; knownSymbols[mNum] ← [ loadedBefore: FALSE, file: file, base: base, pages: 1]; END; RETURN[FALSE] END; FileTable.Build[]; symbolSegmentOpen ← FALSE; currentFile ← NIL; currentSeg ← NIL; knownSymbols ← DESCRIPTOR[ LongStorage.Pages[LongStorage.PagesForWords[nModules * SIZE[KnownSymbolsInfo]]], nModules]; SourceBcd.EnumerateModules[FillInKnowledge]; -- the array in FileTableImpl could go away now IF ~symbolPackStarted THEN {START ownSymbolPack; symbolPackStarted ← TRUE}; END; Finalize: PUBLIC PROC = BEGIN IF symbolSegmentOpen THEN Unload[]; IF currentSeg # NIL THEN Segments.DeleteSegment[currentSeg]; symbolSegmentOpen ← FALSE; LongStorage.FreePages[BASE[knownSymbols]]; FileTable.Destroy[]; currentFile ← NIL; currentSeg ← NIL; END; END.