<> <> <> <> DIRECTORY AMTypes USING[Error], BcdDefs USING[VersionStamp, NameRecord, MTIndex, SGIndex, SGNull, FTNull, FTSelf, VersionID, FTIndex, NullVersion], BcdOps USING[BcdBase, NameString, MTHandle, SGHandle, ProcessModules, FTHandle, ProcessFiles], BrandXSymbolDefs USING[rootBodyIndex, nullSymbolIndex, SymbolTableBase, SymbolModuleIndex], BrandYSymbolDefs USING[rootBodyIndex, nullSymbolIndex, SymbolTableBase, SymbolModuleIndex], CIFS USING[GetFC, Open, read, dontCheck, OpenFile], ConvertUnsafe USING[AppendRope, ToRope], File USING[Capability, nullCapability], FileSegment USING[Pages], LongString USING[AppendString], PilotLoadStateFormat USING[ModuleInfo, ConfigIndex], PilotLoadStateOps USING[InputLoadState, GetModule, AcquireBcd, ReleaseBcd, ReleaseLoadState, EnumerateBcds], PrincOps USING[GlobalFrameHandle], NewRCMapOps USING[EstablishOuter], Rope USING[ROPE, Flatten, Length, Fetch, Concat], RTFiles USING [SameFile], -- EXPORTS RTFilesExtra USING [], -- EXPORTS only RTFlags USING[checking], RTOS USING[EnumerateGlobalFrames, SameCode, UnRavelUSUs], RTSymbolDefs USING[SymbolTableBase, SymbolTableHandle, nullHandle, nullBase, SymbolModuleIndex], RTSymbolOps USING[STBToModuleName, STBVersion, SubStringForHash, NullModuleIndex, NullSth], RTSymbols USING[], -- EXPORTS only RTSymbolsPrivate USING[], -- EXPORTS only RTTypesBasicPrivate USING[SymbolTableIndex, MapStiStd, FindSTI, STDesc], Runtime USING[CallDebugger, ValidateGlobalFrame], Space USING[Map, LongPointer, Unmap, GetAttributes, GetWindow, GetHandle, PageFromLongPointer, Handle, Create, virtualMemory, Delete], Strings USING[SubStringDescriptor, AppendSubString, AppendString, EqualSubStrings], SymbolTable USING[SetCacheSize, Release, Acquire, Forget, anySpan], Table USING[Base], VersionMap USING[MapList], VersionMapDefaults USING[FileNameFromVersion, GetMapList]; RTGetSymbolsImpl: MONITOR IMPORTS AMTypes, BcdOps, CIFS, ConvertUnsafe, LongString, PilotLoadStateOps, NewRCMapOps, Rope, RTFiles, RTOS, RTSymbolOps, RTTypesBasicPrivate, Runtime, Space, Strings, SymbolTable, VersionMapDefaults EXPORTS RTFiles, RTFilesExtra, RTSymbols, RTSymbolsPrivate SHARES File = BEGIN OPEN bx: BrandXSymbolDefs, by: BrandYSymbolDefs, XSymbolTable: SymbolTable, YSymbolTable: SymbolTable, XRCMapOps: NewRCMapOps, YRCMapOps: NewRCMapOps, RTSymbolDefs, RTSymbolOps; <> onePageSpace: Space.Handle = Space.Create[size: 1, parent: Space.virtualMemory]; standardBCDSpaces: LIST OF Space.Handle _ NIL; standardBCDSpacePages: NAT = 20; standardBCDSpacesInUse: NAT _ 0; standardBCDSpacesHeld: NAT _ 0; biggerBCDSpacesInUse: NAT _ 0; OZ: BOOL _ FALSE; ROPE: TYPE = Rope.ROPE; -- PUBLIC PROCS -- Outer: PUBLIC PROC[stb: SymbolTableBase, mdi: SymbolModuleIndex, inner: PROC[base: SymbolTableBase], mesaSymbolsOK: BOOL _ FALSE] = {stb1: SymbolTableBase = AcquireSTBFromMDI[stb, mdi, mesaSymbolsOK]; inner[stb1 ! UNWIND => ReleaseSTB[stb1]]; ReleaseSTB[stb1]}; AcquireSTBForDefs: PUBLIC PROC[fileName: ROPE--ends with .bcd--] RETURNS[stb: SymbolTableBase] = { mn: STRING = [100]; dotFound: BOOL _ FALSE; FOR i: NAT IN [0..Rope.Length[fileName]) DO IF Rope.Fetch[fileName, i] = '. THEN {dotFound _ TRUE; EXIT}; ENDLOOP; IF NOT dotFound THEN fileName _ Rope.Concat[fileName, ".bcd"]; mn.length _ 0; ConvertUnsafe.AppendRope[from: fileName, to: LONG[mn]]; IF mn.length<=4 THEN ERROR AMTypes.Error[reason: noSymbols, msg: fileName]; mn.length _ mn.length-4; stb _ AcquireSTB[GetSTHForModule[stamp: BcdDefs.NullVersion, fileName: fileName, moduleName: ConvertUnsafe.ToRope[LONG[mn]]]]; IF NOT (WITH stb SELECT FROM t: SymbolTableBase.x => t.e.stHandle.definitionsFile, t: SymbolTableBase.y => t.e.stHandle.definitionsFile, ENDCASE => ERROR) THEN {ReleaseSTB[stb]; ERROR AMTypes.Error[reason: noSymbols, msg: Rope.Concat[fileName, " not a defs module"]]}; }; AcquireSTB: PUBLIC PROC[sth: SymbolTableHandle, mesaSymbolsOK: BOOL _ FALSE] RETURNS[stb: SymbolTableBase] = {stb _ WITH sth SELECT FROM t: SymbolTableHandle.x => [x[XSymbolTable.Acquire[t.e]]], t: SymbolTableHandle.y => [y[YSymbolTable.Acquire[t.e]]] ENDCASE => ERROR; IF mesaSymbolsOK THEN RETURN[stb]; <> <<(for RTSymbols clients only, NOT for AMTypes)>> IF NOT (WITH stb SELECT FROM t: SymbolTableBase.x => t.e.stHandle.extended, t: SymbolTableBase.y => t.e.stHandle.extended, ENDCASE => ERROR) -- symbol table made by an old version of the compiler OR (WITH stb SELECT FROM t: SymbolTableBase.x => t.e.bb[bx.rootBodyIndex].type = bx.nullSymbolIndex, t: SymbolTableBase.y => t.e.bb[by.rootBodyIndex].type = by.nullSymbolIndex, ENDCASE => ERROR) THEN {modName: ROPE = STBToModuleName[stb ! UNWIND => ReleaseSTB[stb]]; ReleaseSTB[stb]; ERROR AMTypes.Error[reason: noSymbols, msg: modName]} ELSE RETURN[stb]}; ReleaseSTB: PUBLIC PROC[stb: SymbolTableBase] = {WITH stb SELECT FROM t: SymbolTableBase.x => XSymbolTable.Release[t.e]; t: SymbolTableBase.y => YSymbolTable.Release[t.e] ENDCASE => ERROR}; STPages: PUBLIC PROC[sth: SymbolTableHandle] RETURNS[CARDINAL] = {RETURN[WITH sth SELECT FROM t: SymbolTableHandle.x => t.e.span.pages, t: SymbolTableHandle.y => t.e.span.pages, ENDCASE => ERROR]}; <> AcquireSTHFromSTX: PUBLIC PROC[stx: RTTypesBasicPrivate.SymbolTableIndex] RETURNS[sth: SymbolTableHandle _ nullHandle, moduleName: ROPE _ NIL] = {[sth, moduleName] _ DoAcquireSTHFromSTX[stx, TRUE]}; DoAcquireSTHFromSTX: PROC[stx: RTTypesBasicPrivate.SymbolTableIndex, invokeGetSTHForModule: BOOL _ FALSE] RETURNS[sth: SymbolTableHandle _ nullHandle, moduleName: ROPE _ NIL] = { symbolsStamp: BcdDefs.VersionStamp; bcd: BcdOps.BcdBase; IF NOT NullSth[RTTypesBasicPrivate.MapStiStd[stx].sth] THEN RETURN[sth: RTTypesBasicPrivate.MapStiStd[stx].sth]; symbolsStamp _ RTTypesBasicPrivate.MapStiStd[stx].symbolsStamp; bcd _ RTTypesBasicPrivate.MapStiStd[stx].bcd; IF bcd = NIL THEN {IF invokeGetSTHForModule THEN sth _ GetSTHForModule[stamp: symbolsStamp, fileName: NIL, moduleName: NIL ! ANY => CONTINUE] ELSE RETURN} ELSE {sgb: Table.Base = LOOPHOLE[bcd + bcd.sgOffset]; ftb: Table.Base = LOOPHOLE[bcd + bcd.ftOffset]; ssb: BcdOps.NameString = LOOPHOLE[bcd + bcd.ssOffset]; fti: BcdDefs.FTIndex; sgi: BcdDefs.SGIndex = RTTypesBasicPrivate.MapStiStd[stx].sgi; -- maybe SGNull <<(=> search the BCD's file table)>> IF sgi = BcdDefs.SGNull -- search the BCD's file table (find a DEFs) THEN { findSymbolFTI: PROC[ffth: BcdOps.FTHandle, ffti: BcdDefs.FTIndex] RETURNS[stop: BOOL] = { IF NOT EQStamps[ffth.version, symbolsStamp] THEN RETURN[FALSE]; moduleName _ GetModuleName[ssb, ffth.name]; sth _ GetSTHForModule[stamp: symbolsStamp, fileName: Rope.Concat[moduleName, ".bcd"], moduleName: moduleName ! AMTypes.Error => CONTINUE]; RETURN[TRUE]}; IF NOT invokeGetSTHForModule THEN RETURN; [] _ BcdOps.ProcessFiles[bcd, findSymbolFTI]; IF NullSth[sth] THEN sth _ GetSTHForModule[stamp: symbolsStamp, fileName: NIL, moduleName: NIL ! ANY => CONTINUE]; RTTypesBasicPrivate.MapStiStd[stx].sth _ sth; RETURN} ELSE fti _ sgb[sgi].file; IF fti = BcdDefs.FTSelf THEN {OPEN Space; file: File.Capability = FileFromBcdBase[bcd]; IF file # File.nullCapability THEN {p: FileSegment.Pages = [file: file, span: [base: sgb[sgi].base, pages: sgb[sgi].pages + sgb[sgi].extraPages]]; sth _ IF IsXBCD[bcd] THEN [x[p]] ELSE [y[p]]}; } ELSE { -- look for the specified file fileName: ROPE = GetFileName[ssb, ftb[fti].name]; moduleName _ GetModuleName[ssb, ftb[fti].name]; sth _ NewSymbolHandle[fileName: fileName, version: ftb[sgb[sgi].file].version, <> base: sgb[sgi].base, pages: sgb[sgi].pages + sgb[sgi].extraPages ! AMTypes.Error => CONTINUE] }; }; -- end ELSE (i.e. bcd # NIL) RTTypesBasicPrivate.MapStiStd[stx].sth _ sth; }; -- end DoAcquireSTHFromSTX <> NewSymbolHandle: PUBLIC PROC[fileName: ROPE, base: CARDINAL, pages: CARDINAL, version: BcdDefs.VersionStamp _ BcdDefs.NullVersion] RETURNS[sth: SymbolTableHandle _ nullHandle] = { file: File.Capability _ File.nullCapability; stb: SymbolTableBase; symbolsStamp: BcdDefs.VersionStamp; isXBCD: BOOL = TRUE; -- NOTE XXX IF EQStamps[version, BcdDefs.NullVersion] THEN file _ GetReadCapability[fileName ! ANY => CONTINUE] ELSE file _ AcquireFCFromVersion[version, fileName]; IF file = File.nullCapability THEN ERROR AMTypes.Error[reason: noSymbols, msg: fileName]; <> sth _ IF isXBCD THEN [x[[file: file, span: [base: base, pages: pages]]]] ELSE [y[[file: file, span: [base: base, pages: pages]]]]; stb _ AcquireSTB[sth]; symbolsStamp _ STBVersion[stb]; ReleaseSTB[stb]; [] _ RTTypesBasicPrivate.FindSTI[[symbolsStamp: symbolsStamp, sth: sth]]; }; -- end NewSymbolHandle IsFileInUse: PUBLIC PROC[file: File.Capability] RETURNS[found: BOOL _ FALSE] = { loadStateHeld: BOOL; p: PROC[c: PilotLoadStateFormat.ConfigIndex] RETURNS[stop: BOOL] = {OPEN Space; ptr: LONG POINTER = LOOPHOLE[PilotLoadStateOps.AcquireBcd[c]]; space: Handle _ RTOS.UnRavelUSUs[GetHandle[PageFromLongPointer[ptr]]]; PilotLoadStateOps.ReleaseBcd[LOOPHOLE[ptr]]; IF file.fID = GetWindow[space].file.fID THEN {found _ TRUE; RETURN[TRUE]} ELSE RETURN[FALSE]; }; <> IF IsFileUsed[file] THEN RETURN [TRUE]; <> XSymbolTable.Forget[[file: file, span: XSymbolTable.anySpan] ! ANY => {found _ TRUE; CONTINUE}]; IF found THEN RETURN; YSymbolTable.Forget[[file: file, span: YSymbolTable.anySpan] ! ANY => {found _ TRUE; CONTINUE}]; IF found THEN RETURN; <> [] _ PilotLoadStateOps.InputLoadState[]; loadStateHeld _ TRUE; [] _ PilotLoadStateOps.EnumerateBcds[recentfirst, p ! ANY => {loadStateHeld _ FALSE; PilotLoadStateOps.ReleaseLoadState[]}]; IF loadStateHeld THEN PilotLoadStateOps.ReleaseLoadState[]; IF found THEN RETURN; <> FOR x: NAT IN [1..RTTypesBasicPrivate.MapStiStd.length) DO sth: SymbolTableHandle; f: File.Capability; <> IF RTTypesBasicPrivate.MapStiStd[x] = NIL THEN EXIT; sth _ RTTypesBasicPrivate.MapStiStd[x].sth; IF NullSth[sth] THEN LOOP; <