<<>> <> <> <> <> <> <> <> <> <> <> <> DIRECTORY CirioDeltaFace USING[SameWorldGetFileEntry, SameWorldLookupMatchingSymEntryByName, SameWorldLookupMatchingSymEntryByValue, SameWorldLookupSymEntryByID, SameWorldLookupSymEntryByName, SameWorldLookupSymEntryByValue, SameWorldPCtoInfo], CirioNub USING[Block16, Block32, Block32Record, Call, CallResult, Create, Destroy, Error, Handle, ProcID, PutBlock32, PutCard32, PutInt32, PutBlock8Cnt, PutBlock8Next, PutRope, ReturnCode, StartCall], CirioNubAccess USING[AllocatedBytes, Field, Fields, FileEntry, FileEntryBody, Handle, HandleBody, PCInfo, PCInfoBody, ProcRep, RemoteAddress, SizeList, SymEntry, SymEntryBody, ThreadInfo, Typecode, Typestring], CirioNubAccessPrivate USING[AllocatedItems, AllocHandleBody --, HandleBody--], CirioTargets, Convert USING[<>RopeFromCard], ConvertUnsafe, GenericCall, IO, MesaLoadState, NetworkName USING [Error, AddressFromName], PBasics USING [RawBytes, RawChars], PCRMonitorDefs USING [MonitorLock, Thread, nullHolder], PFS USING [PathFromRope], PFSNames USING [PATH], RefText USING[InlineAppendChar, New], Rope, SafeStorage, SameWorldMonitoredCallOps USING [MonitoredCall]<< , Arpa USING[Address, nullAddress] , ConvertExtras USING[ArpaAddressFromRope, RopeFromArpaAddress] , SunYPAgent USING[Handle, Match, ObtainHandle, TextSeq, Tokenize] >>; CirioNubAccessImpl: CEDAR MONITOR LOCKS h USING h: Handle IMPORTS CirioDeltaFace, CirioNub, CirioTargets, Convert, ConvertUnsafe, GenericCall, IO, MesaLoadState, NetworkName, PFS, RefText, Rope, SameWorldMonitoredCallOps<<, ConvertExtras, SunYPAgent>> EXPORTS CirioNubAccess = BEGIN <> <<>> <> <> <> <> <> <> <<>> <> <<[palain-uX]<>jaune>xrhome>DEVELOPMENT>INCLUDE>xr>Threads.h>> <<[palain-uX]<>jaune>xrhome>DEVELOPMENT>INCLUDE>xr>ThreadsBackdoor.h>> <<>> <> <> <> <> <> <<>> <> <> <> <<>> <> <<>> <<>> <> <<>> CirioNubBase: CirioNub.ProcID = 0; CedarCirioNubBase: CirioNub.ProcID = 64; <<>> <> <<>> Error: PUBLIC ERROR [codes: LIST OF ATOM, msg: Rope.ROPE] = CODE; RemoteNilFault: PUBLIC ERROR[addr: CirioNubAccess.RemoteAddress] = CODE; RemoteAddrFault: PUBLIC ERROR[addr: CirioNubAccess.RemoteAddress] = CODE; RemoteMonitorWouldBlock: PUBLIC ERROR[addr: CirioNubAccess.RemoteAddress] = CODE; <> <> <<>> Handle: TYPE = CirioNubAccess.Handle; HandleBody: TYPE = CirioNubAccess.HandleBody; <<>> <> <<>> RemoteBody: TYPE = RECORD[nub: CirioNub.Handle]; <<>> CreateRemoteNub: PUBLIC PROC[debuggee: Rope.ROPE _ NIL, port: CARDINAL _ 0, timeoutMsec: INT _ INT.LAST] RETURNS [Handle] = BEGIN proposedVersionNumber: CARD _ 7; addrRope: Rope.ROPE _ NameToAddress[debuggee]; longAddr: Rope.ROPE _ Rope.Cat[addrRope, ":", Convert.RopeFromCard[port]]; nub: CirioNub.Handle _ CirioNub.Create[NIL, longAddr, timeoutMsec]; h: Handle _ NEW[HandleBody _ [live: TRUE, version: 0, allocatedItems: NIL, contents: NEW[RemoteBody _ [nub]], target: NIL]]; IF NOT Null[h, proposedVersionNumber !UNWIND => CirioNub.Destroy[nub]] THEN { CirioNub.Destroy[nub]; h _ NIL; ERROR CirioNub.Error[$protocolVersionMismatch]}; h.target _ CirioTargets.CreateTarget[h]; RETURN[h]; END; CreateSameWorldNub: PUBLIC PROC RETURNS [Handle] = BEGIN proposedVersionNumber: CARD _ 7; h: Handle _ NEW[HandleBody_[live: TRUE, version: 0, allocatedItems: NIL, contents: NIL, target: NIL ]]; IF NOT Null[h, proposedVersionNumber] THEN ERROR Error[LIST[$protocolMismatch], IO.PutFR["the debuggee doesn't want to speak version %g of the DebugNub protocol", [cardinal[proposedVersionNumber]] ]]; h.target _ CirioTargets.CreateTarget[h]; RETURN[h]; END; <> DestroyNub: PUBLIC ENTRY PROC[h: Handle] = BEGIN ENABLE UNWIND => NULL; IF NOT h.live THEN ERROR Error[LIST[$notLive], "attempt to use a dead connection"]; IF h.allocatedItems # NIL THEN FOR I: CARD IN [0..h.allocatedItems.nSlots) DO IF h.allocatedItems[I] # NIL THEN InnerReleaseAllocatedBytes[h, h.allocatedItems[I]] ENDLOOP; h.live _ FALSE; IF h.contents # NIL THEN RemoteDestroyNub[NARROW[h.contents, REF RemoteBody].nub] ELSE RETURN; END; GetProtocolVersionNumber: PUBLIC ENTRY PROC[h: Handle] RETURNS[CARD] = BEGIN ENABLE UNWIND => NULL; RETURN[h.version]; <> END; Null: PUBLIC ENTRY PROC[h: Handle, proposedVersionNumber: CARD] RETURNS[BOOLEAN] = BEGIN ENABLE UNWIND => NULL; IF NOT h.live THEN ERROR Error[LIST[$notLive], "attempt to use a dead connection"]; IF proposedVersionNumber # 4 AND proposedVersionNumber # 5 AND proposedVersionNumber # 6 AND proposedVersionNumber # 7 THEN ERROR Error[LIST[$protocolMismatch], IO.PutFR["attempt to use a non-current (<4 or >7) version of the protocol (%g)", [cardinal[proposedVersionNumber]] ]]; IF h.contents # NIL THEN BEGIN h.version _ RemoteNull[NARROW[h.contents, REF RemoteBody].nub, proposedVersionNumber]; IF h.version # 4 AND h.version # 5 AND h.version # 6 AND h.version # 7 THEN ERROR Error[LIST[$protocolMismatch], IO.PutFR["debuggee uses a non-current (<4 or >7) version of the protocol (%g)", [cardinal[h.version]] ]]; RETURN[TRUE] END ELSE BEGIN h.version _ MIN[6, proposedVersionNumber]; RETURN[h.version = 4 OR h.version = 5 OR h.version = 6 OR h.version = 7]; END; END; WaitSig: PUBLIC ENTRY PROC[h: Handle, timeoutMilliSec: CARD] RETURNS[gotResponse: BOOLEAN] = BEGIN ENABLE UNWIND => NULL; IF NOT h.live THEN ERROR Error[LIST[$notLive], "attempt to use a dead connection"]; IF h.contents # NIL THEN RETURN[RemoteWaitSig[NARROW[h.contents, REF RemoteBody].nub, timeoutMilliSec]] ELSE ERROR Error[LIST[$unimplemented, $local, $WaitSig], "CirioNubAccess.WaitSig is not implemented for local debugging"]; END; SetDBStat: PUBLIC ENTRY PROC[h: Handle, dbStat: INT32, timeoutMilliSec: CARD] RETURNS[ok: BOOLEAN] = BEGIN ENABLE UNWIND => NULL; IF NOT h.live THEN ERROR Error[LIST[$notLive], "attempt to use a dead connection"]; IF h.contents # NIL THEN RETURN[RemoteSetDBStat[NARROW[h.contents, REF RemoteBody].nub, dbStat, timeoutMilliSec]] ELSE ERROR Error[LIST[$unimplemented, $local, $SetDBStat], "CirioNubAccess.SetDBStat is not implemented for local debugging"]; END; ReadBytes: PUBLIC PROC[address: CirioNubAccess.RemoteAddress, count: INT] RETURNS[REF TEXT] = BEGIN Inner: ENTRY PROC[h: Handle] RETURNS[REF TEXT] = BEGIN ENABLE UNWIND => NULL; IF address.nil THEN RemoteNilFault[address]; IF NOT address.valid THEN RemoteAddrFault[address]; IF NOT address.h.live THEN ERROR Error[LIST[$notLive], "attempt to use a dead connection"]; IF address.h.contents # NIL THEN RETURN[RemoteReadBytes[nub: NARROW[address.h.contents, REF RemoteBody].nub, address: address, count: count]] ELSE RETURN[SameWorldReadBytes[address: address, count: count]]; END; RETURN[Inner[address.h]]; END; Read16BitsAsCardinal: PUBLIC PROC[address: CirioNubAccess.RemoteAddress] RETURNS[CARDINAL] = BEGIN Inner: ENTRY PROC[h: Handle] RETURNS[CARDINAL] = BEGIN ENABLE UNWIND => NULL; IF address.nil THEN RemoteNilFault[address]; IF NOT address.valid THEN RemoteAddrFault[address]; IF NOT address.h.live THEN ERROR Error[LIST[$notLive], "attempt to use a dead connection"]; IF address.h.contents # NIL THEN RETURN[RemoteRead16BitsAsCardinal[nub: NARROW[address.h.contents, REF RemoteBody].nub, address: address]] ELSE RETURN[SameWorldRead16BitsAsCardinal[address: address]]; END; RETURN[Inner[address.h]]; END; Read32BitsAsCard: PUBLIC PROC[address: CirioNubAccess.RemoteAddress] RETURNS[CARD] = BEGIN Inner: ENTRY PROC[h: Handle] RETURNS[CARD] = BEGIN ENABLE UNWIND => NULL; IF address.nil THEN RemoteNilFault[address]; IF NOT address.valid THEN RemoteAddrFault[address]; IF NOT address.h.live THEN ERROR Error[LIST[$notLive], "attempt to use a dead connection"]; IF address.h.contents # NIL THEN RETURN[RemoteRead32BitsAsCard[nub: NARROW[address.h.contents, REF RemoteBody].nub, address: address]] ELSE RETURN[SameWorldRead32BitsAsCard[address: address]]; END; RETURN[Inner[address.h]]; END; WriteCardAs32Bits: PUBLIC PROC[address: CirioNubAccess.RemoteAddress, card: CARD32] = BEGIN Inner: ENTRY PROC[h: Handle] = BEGIN ENABLE UNWIND => NULL; IF address.nil THEN RemoteNilFault[address]; IF NOT address.valid THEN RemoteAddrFault[address]; IF NOT address.h.live THEN ERROR Error[LIST[$notLive], "attempt to use a dead connection"]; IF address.h.contents # NIL THEN RemoteWriteCardAs32Bits[nub: NARROW[address.h.contents, REF RemoteBody].nub, address: address, card: card] ELSE SameWorldWriteCardAs32Bits[address: address, card: card]; END; Inner[address.h]; END; Read4Bytes: PUBLIC PROC[address: CirioNubAccess.RemoteAddress] RETURNS[PACKED ARRAY [0..3] OF BYTE] = BEGIN text: REF TEXT _ ReadBytes[address, 4]; IF text.length # 4 THEN ERROR Error[LIST[$cantHappen], "ReadBytes[.., 4] returned a REF TEXT whose length wasn't 4"]; RETURN[[ORD[text[0]], ORD[text[1]], ORD[text[2]], ORD[text[3]]]]; END; Write4Bytes: PUBLIC PROC[address: CirioNubAccess.RemoteAddress, bytes: PACKED ARRAY [0..3] OF BYTE] = BEGIN Inner: ENTRY PROC[h: Handle] = BEGIN ENABLE UNWIND => NULL; IF address.nil THEN RemoteNilFault[address]; IF NOT address.valid THEN RemoteAddrFault[address]; IF NOT address.h.live THEN ERROR Error[LIST[$notLive], "attempt to use a dead connection"]; IF address.h.contents # NIL THEN RemoteWrite4Bytes[nub: NARROW[address.h.contents, REF RemoteBody].nub, address: address, bytes: bytes] ELSE SameWorldWrite4Bytes[address: address, bytes: bytes]; END; Inner[address.h]; END; GetThreads: PUBLIC ENTRY PROC[h: Handle, lowIndex, highIndex: CARD] RETURNS[LIST OF REF CirioNubAccess.ThreadInfo] = BEGIN ENABLE UNWIND => NULL; IF NOT h.live THEN ERROR Error[LIST[$notLive], "attempt to use a dead connection"]; IF h.contents # NIL THEN RETURN[RemoteGetThreads[NARROW[h.contents, REF RemoteBody].nub, lowIndex, highIndex]] ELSE ERROR Error[LIST[$unimplemented, $local, $GetThreads], "CirioNubAccess.GetThreads is not implemented for local debugging"]; END; PCtoInfo: PUBLIC ENTRY PROC[h: Handle, pc: CARD] RETURNS[CirioNubAccess.PCInfo] = BEGIN ENABLE UNWIND => NULL; IF NOT h.live THEN ERROR Error[LIST[$notLive], "attempt to use a dead connection"]; IF h.contents # NIL THEN RETURN[RemotePCtoInfo[NARROW[h.contents, REF RemoteBody].nub, pc]] ELSE RETURN[CirioDeltaFace.SameWorldPCtoInfo[pc]]; END; KillWorld: PUBLIC ENTRY PROC[h: Handle] = BEGIN ENABLE UNWIND => NULL; IF NOT h.live THEN ERROR Error[LIST[$notLive], "attempt to use a dead connection"]; IF h.contents # NIL THEN RemoteKillWorld[NARROW[h.contents, REF RemoteBody].nub] ELSE ERROR Error[LIST[$unimplemented, $local, $KillWorld], "CirioNubAccess.KillWorld is not implemented for local debugging"]; END; IssueThreadCommand: PUBLIC ENTRY PROC[h: Handle, threadIndex: CARD, setFreeze: BOOL, freeze: BOOL, setMsg: BOOL, msg: INT] RETURNS[success: BOOLEAN] = BEGIN ENABLE UNWIND => NULL; IF NOT h.live THEN ERROR Error[LIST[$notLive], "attempt to use a dead connection"]; IF h.contents # NIL THEN RETURN[RemoteIssueThreadCommand[NARROW[h.contents, REF RemoteBody].nub, threadIndex, setFreeze, freeze, setMsg, msg]] ELSE ERROR Error[LIST[$unimplemented, $local, $IssueThreadCommand], "CirioNubAccess.IssueThreadCommand is not implemented for local debugging"]; END; <> GetDBStat: PUBLIC ENTRY PROC[h: Handle, oldStat: INT32, oldExamineeIndex: INT, timeoutMsec: CARD] RETURNS[dbStab: INT32, examineeIndex: INT32] = BEGIN ENABLE UNWIND => NULL; IF NOT h.live THEN ERROR Error[LIST[$notLive], "attempt to use a dead connection"]; IF h.contents # NIL THEN BEGIN [dbStab, examineeIndex] _ RemoteGetDBStat[NARROW[h.contents, REF RemoteBody].nub, oldStat, oldExamineeIndex, timeoutMsec]; RETURN; END ELSE ERROR Error[LIST[$unimplemented, $local, $GetDBStat], "CirioNubAccess.GetDBStat is not implemented for local debugging"]; END; Call: PUBLIC PROC [h: Handle, proc: CirioNubAccess.ProcRep, formalArgSizes, formalRetSizes: CirioNubAccess.SizeList, actualArgs, actualRets: CirioNubAccess.Fields] ~ { IF h.contents # NIL THEN ERROR Error[LIST[$unimplemented, $remote, $Call], "CirioNubAccess.Call is not implemented for remote debugging"]; TRUSTED {GenericCall.Call[LOOPHOLE[proc], formalArgSizes, formalRetSizes, ConvertFields[actualArgs], ConvertFields[actualRets]]}; RETURN}; ConvertFields: PROC [cfs: CirioNubAccess.Fields] RETURNS [gfs: GenericCall.Fields] ~ { gfs _ NEW [GenericCall.FieldSeq[cfs.length]]; FOR i: NAT IN [0..gfs.length) DO cf: CirioNubAccess.Field ~ cfs[i]; gfs[i] _ [address: cf.address, bitOffset: cf.bitOffset, bits: cf.bits]; ENDLOOP; RETURN}; GetFileEntry: PUBLIC ENTRY PROC[h: Handle, seqNum: CARD] RETURNS[CirioNubAccess.FileEntry] = BEGIN ENABLE UNWIND => NULL; IF NOT h.live THEN ERROR Error[LIST[$notLive], "attempt to use a dead connection"]; IF h.contents # NIL THEN SELECT h.version FROM 0 => ERROR Error[LIST[$noVersionYet], "CirioNubAccess.GetFileEntry called on a Handle whose version has not yet been determined"]; 4 => RETURN[RemoteGetFileEntry4[NARROW[h.contents, REF RemoteBody].nub, seqNum]]; 5, 6, 7 => RETURN[RemoteGetFileEntry5[NARROW[h.contents, REF RemoteBody].nub, seqNum]] ENDCASE => ERROR Error[LIST[$protocolMismatch], IO.PutFR["CirioNubAccess.GetFileEntry called on a handle whose version, %g, is not in the current range, [4..7]", [cardinal[h.version]] ]] ELSE RETURN[CirioDeltaFace.SameWorldGetFileEntry[seqNum]]; END; LookupSymEntryByName: PUBLIC ENTRY PROC[h: Handle, sym: Rope.ROPE, caseSensitive: BOOLEAN, externOnly: BOOLEAN, numToSkip: INT] RETURNS[CirioNubAccess.SymEntry] = BEGIN ENABLE UNWIND => NULL; IF NOT h.live THEN ERROR Error[LIST[$notLive], "attempt to use a dead connection"]; IF h.contents # NIL THEN RETURN[RemoteLookupSymEntryByName[NARROW[h.contents, REF RemoteBody].nub, sym, caseSensitive, externOnly, numToSkip]] ELSE RETURN[CirioDeltaFace.SameWorldLookupSymEntryByName[sym, caseSensitive, externOnly, numToSkip]]; END; LookupSymEntryByValue: PUBLIC ENTRY PROC[h: Handle, val: CARD, numToSkip: INT] RETURNS[CirioNubAccess.SymEntry] = BEGIN ENABLE UNWIND => NULL; IF NOT h.live THEN ERROR Error[LIST[$notLive], "attempt to use a dead connection"]; IF h.contents # NIL THEN RETURN[RemoteLookupSymEntryByValue[NARROW[h.contents, REF RemoteBody].nub, val, numToSkip]] ELSE RETURN[CirioDeltaFace.SameWorldLookupSymEntryByValue[val, numToSkip]]; END; LookupSymEntryByID: PUBLIC ENTRY PROC[h: Handle, symID: CARD] RETURNS[CirioNubAccess.SymEntry] = BEGIN ENABLE UNWIND => NULL; IF NOT h.live THEN ERROR Error[LIST[$notLive], "attempt to use a dead connection"]; IF h.contents # NIL THEN RETURN[RemoteLookupSymEntryByID[NARROW[h.contents, REF RemoteBody].nub, symID]] ELSE RETURN[CirioDeltaFace.SameWorldLookupSymEntryByID[symID]]; END; <> <> LookupFileEntryByStemName: PUBLIC PROC[h: Handle, stemName: Rope.ROPE, numToSkip: INT] RETURNS[CirioNubAccess.SymEntry] = BEGIN IF NOT h.live THEN ERROR Error[LIST[$notLive], "attempt to use a dead connection"]; SELECT h.version FROM 0 => ERROR Error[LIST[$noVersionYet], "CirioNubAccess.LookupFileEntryByStemName called on a Handle whose version has not yet been determined"]; 4, 5 => BEGIN direction: INT _ IF numToSkip < 0 THEN -1 ELSE 1; nSkipped: INT _ 0; FOR skip: INT _ 0, skip + direction DO entry: CirioNubAccess.SymEntry _ LookupSymEntryByName[h, Rope.Cat[stemName, ".c2c.o"], FALSE, FALSE, skip]; IF entry = NIL THEN RETURN[entry]; -- no such file in the load state IF entry.type # ModuleType AND entry.type # (ModuleType+1) THEN LOOP; IF nSkipped = numToSkip THEN RETURN[entry]; nSkipped _ nSkipped + direction; ENDLOOP; END; 6, 7 => RETURN[LookupMatchingSymEntryByName[h, 0, Rope.Cat[stemName, ".*"], FALSE, ModuleType, 0, numToSkip]]; ENDCASE => ERROR Error[LIST[$protocolMismatch], IO.PutFR["CirioNubAccess.LookupFileEntryByStemName called on a handle whose version, %g, is not in the current range, [4..7]", [cardinal[h.version]] ]] END; ModuleType: CARD = 1eH; TextType: CARD = 4; <> <> <> <<= 0, is ignored>> <<# 0, search starts with given symId>> <<>> <> <> <> <> <> <<>> <> <> <<>> <> <<-1 for all types are acceptable>> <> <<>> <> <<0 accept all types>> <<1 ignore internals>> <<2 ignore externals>> <<3 ignore all types (very fast!)>> <<>> <> <> <> <> <> <> <<>> LookupMatchingSymEntryByName: PUBLIC ENTRY PROC[h: Handle, symID: CARD, pattern: Rope.ROPE, caseSensitive: BOOLEAN, wantedTypes: CARD, ignoreClasses: CARD, numToSkip: INT] RETURNS[CirioNubAccess.SymEntry] = BEGIN ENABLE UNWIND => NULL; IF NOT h.live THEN ERROR Error[LIST[$notLive], "attempt to use a dead connection"]; IF h.version < 6 THEN ERROR Error[LIST[$protocolMismatch], IO.PutFR["CirioNubAccess.LookupMatchingSymEntryByName called on a Handle whose version, %g, is less than 6", [cardinal[h.version]] ]]; IF h.contents # NIL THEN RETURN[RemoteLookupMatchingSymEntryByName[NARROW[h.contents, REF RemoteBody].nub, symID, pattern, caseSensitive, wantedTypes, ignoreClasses, numToSkip]] ELSE RETURN[CirioDeltaFace.SameWorldLookupMatchingSymEntryByName[symID, pattern, caseSensitive, wantedTypes, ignoreClasses, numToSkip]]; END; <> <<= 0, search starts with the entry with greatest value less or equal to given val.>> <<# 0, search starts with given symId>> <<>> <> <> <<>> <<>> <> <<(see LookupMatchingSymEntryByName)>> <<>> <> <<0(see LookupMatchingSymEntryByName)>> <<>> <> <> <> <> <.>> LookupMatchingSymEntryByValue: PUBLIC ENTRY PROC[h: Handle, symID: CARD, val: CARD, wantedTypes: CARD, ignoreClasses: CARD, numToSkip: INT] RETURNS[CirioNubAccess.SymEntry] = BEGIN ENABLE UNWIND => NULL; IF NOT h.live THEN ERROR Error[LIST[$notLive], "attempt to use a dead connection"]; IF h.version < 6 THEN ERROR Error[LIST[$protocolMismatch], IO.PutFR["CirioNubAccess.LookupMatchingSymEntryByValue called on a Handle whose version, %g, is less than 6", [cardinal[h.version]] ]]; IF h.contents # NIL THEN RETURN[RemoteLookupMatchingSymEntryByValue[NARROW[h.contents, REF RemoteBody].nub, symID, val, wantedTypes, ignoreClasses, numToSkip]] ELSE RETURN[CirioDeltaFace.SameWorldLookupMatchingSymEntryByValue[symID, val, wantedTypes, ignoreClasses, numToSkip]]; END; AllocHandle: TYPE = REF AllocHandleBody; AllocHandleBody: PUBLIC TYPE = CirioNubAccessPrivate.AllocHandleBody; AllocateBytes: PUBLIC ENTRY PROC[h: Handle, nBytes: CARD] RETURNS[CirioNubAccess.AllocatedBytes] = BEGIN ENABLE UNWIND => NULL; IF NOT h.live THEN ERROR Error[LIST[$notLive], "attempt to use a dead connection"]; IF h.version < 6 THEN ERROR Error[LIST[$protocolMismatch], IO.PutFR["CirioNubAccess.AllocateBytes called on a Handle whose version, %g, is less than 6", [cardinal[h.version]] ]]; IF h.contents # NIL THEN ERROR Error[LIST[$unimplemented, $remote, $AllocateBytes], "CirioNubAccess.AllocateBytes not implemented for remote debugging"] ELSE BEGIN ah: REF CirioNubAccessPrivate.AllocHandleBody _ GetAnAllocHandle[h]; byteAddress: CARD; [ah.data, byteAddress] _ SameWorldAllocateBytes[nBytes]; RETURN[[ah, [h, byteAddress, 0, FALSE, TRUE]]]; END; END; GetAnAllocHandle: PROC[h: Handle] RETURNS[REF CirioNubAccessPrivate.AllocHandleBody] = BEGIN index: CARD; -- will be filled in IF h.allocatedItems = NIL THEN BEGIN count: CARD _ 100; new: REF CirioNubAccessPrivate.AllocatedItems _ NEW[CirioNubAccessPrivate.AllocatedItems[count]]; new.earlyFreeSlots _ NIL; new.firstLateFreeSlot _ 0; FOR I: CARD IN [0..count) DO new[I] _ NIL ENDLOOP; h.allocatedItems _ new; END; IF h.allocatedItems.earlyFreeSlots # NIL THEN BEGIN index _ h.allocatedItems.earlyFreeSlots.first; h.allocatedItems.earlyFreeSlots _ h.allocatedItems.earlyFreeSlots.rest; END ELSE BEGIN IF h.allocatedItems.firstLateFreeSlot = h.allocatedItems.nSlots THEN BEGIN newCount: CARD _ h.allocatedItems.nSlots*2; new: REF CirioNubAccessPrivate.AllocatedItems _ NEW[CirioNubAccessPrivate.AllocatedItems[newCount]]; new.earlyFreeSlots _ NIL; new.firstLateFreeSlot _ h.allocatedItems.nSlots; FOR I: CARD IN [0..h.allocatedItems.nSlots) DO new[I] _ h.allocatedItems[I] ENDLOOP; FOR I: CARD IN [h.allocatedItems.nSlots..newCount) DO new[I] _ NIL ENDLOOP; h.allocatedItems _ new; END; <> BEGIN index _ h.allocatedItems.firstLateFreeSlot; h.allocatedItems.firstLateFreeSlot _ h.allocatedItems.firstLateFreeSlot+1; END; END; <<>> <> BEGIN ah: REF AllocHandleBody _ NEW[CirioNubAccessPrivate.AllocHandleBody_[h, index, NIL]]; IF h.allocatedItems[index] # NIL THEN ERROR Error[LIST[$cantHappen], "CirioNubAccessImpl.GetAnAllocHandle computed used an index that's not free"]; h.allocatedItems[index] _ ah; RETURN[ah]; END; END; ReleaseAllocatedBytes: PUBLIC PROC[allocHandle: AllocHandle] = { Inner: ENTRY PROC[h: Handle] = { ENABLE UNWIND => NULL; InnerReleaseAllocatedBytes[h, allocHandle]; RETURN}; Inner[allocHandle.h]; RETURN}; InnerReleaseAllocatedBytes: INTERNAL PROC[h: Handle, allocHandle: AllocHandle] ~ { IF NOT h.live THEN ERROR Error[LIST[$notLive], "attempt to use a dead connection"]; IF h.version < 6 THEN ERROR Error[LIST[$protocolMismatch], IO.PutFR["CirioNubAccess.ReleaseAllocatedBytes called on a Handle whose version, %g, is less than 6", [cardinal[h.version]] ]]; ReleaseAnAllocHandle[h, allocHandle]; IF h.contents # NIL THEN Error[LIST[$unimplemented, $remote, $ReleaseAllocatedBytes], "CirioNubAccess.ReleaseAllocatedBytes not implemented for remote debugging"] ELSE SameWorldReleaseAllocatedBytes[allocHandle.data]; RETURN}; ReleaseAnAllocHandle: PROC[h: Handle, ah: REF CirioNubAccessPrivate.AllocHandleBody] = BEGIN IF ah.h # h THEN ERROR; IF h.allocatedItems[ah.index] # ah THEN ERROR Error[LIST[$cantHappen], "attempt to free a broken AllocHandle"]; h.allocatedItems.earlyFreeSlots _ CONS[ah.index, h.allocatedItems.earlyFreeSlots]; h.allocatedItems[ah.index] _ NIL; END; MonitoredCall: PUBLIC PROC[ address: CirioNubAccess.RemoteAddress, proc: PROCEDURE [] RETURNS []] RETURNS [] = BEGIN Inner: -- ENTRY -- PROC[h: Handle] = <> BEGIN ENABLE UNWIND => NULL; IF address.nil THEN RemoteNilFault[address]; IF NOT address.valid THEN RemoteAddrFault[address]; IF NOT address.bitOffset = 0 THEN RemoteAddrFault[address]; IF NOT address.h.live THEN ERROR Error[LIST[$notLive], "attempt to use a dead connection"]; IF address.h.contents # NIL THEN RemoteMonitoredCall[address: address, proc: proc] ELSE SameWorldMonitoredCall[address: address, proc: proc]; END; Inner[h: address.h]; END; GetConcreteTypecode: PUBLIC PROC[h: Handle, opaque: CirioNubAccess.Typecode] RETURNS[concrete: CirioNubAccess.Typecode, whyNot: Rope.ROPE] ~ { IF NOT h.live THEN ERROR Error[LIST[$notLive], "attempt to use a dead connection"]; <> IF h.contents#NIL THEN { IF h.version <7 THEN RETURN[[0], IO.PutFR["CirioNubAccess.RemoteGetConcreteTypecode called on a Handle whose version, %g, is less than 7", [cardinal[h.version]] ]]; concrete _ RemoteGetConcreteTypecode[h, opaque]; RETURN[concrete, NIL]; } ELSE { ans: SafeStorage.Type ~ MesaLoadState.ConcreteTypeFromAbstractType[VAL[opaque]]; RETURN[[ans.ORD], NIL]}; }; GetTypestring: PUBLIC PROC[h: Handle, code: CirioNubAccess.Typecode] RETURNS[string: CirioNubAccess.Typestring, whyNot: Rope.ROPE] ~ { IF NOT h.live THEN ERROR Error[LIST[$notLive], "attempt to use a dead connection"]; <> IF h.contents#NIL THEN { IF h.version <7 THEN RETURN[NIL, IO.PutFR["CirioNubAccess.RemoteGetTypestring called on a Handle whose version, %g, is less than 7", [cardinal[h.version]] ]]; string _ RemoteGetTypestring[h, code]; RETURN[string, NIL]; } ELSE { ts: STRING ~ MesaLoadState.TypeStringFromType[VAL[code]]; ans: Rope.ROPE _ NIL; TRUSTED {ans _ ConvertUnsafe.SubStringToRope[[ts, 0, ts.length]]}; RETURN[ans, NIL]}; }; GetTypecode: PUBLIC PROC[h: Handle, string: CirioNubAccess.Typestring] RETURNS [code: CirioNubAccess.Typecode, whyNot: Rope.ROPE _ NIL] ~ { IF NOT h.live THEN ERROR Error[LIST[$notLive], "attempt to use a dead connection"]; <> IF h.contents#NIL THEN { IF h.version <7 THEN RETURN[[0], IO.PutFR["CirioNubAccess.RemoteGetTypecode called on a Handle whose version, %g, is less than 7", [cardinal[h.version]] ]]; code _ RemoteGetTypecode[h, string]; RETURN[code, NIL]; } ELSE { ts: REF TEXT ~ RefText.New[string.Length]; ans: SafeStorage.Type; [] _ Rope.AppendChars[ts, string]; ans _ MesaLoadState.TypeFromTypeString[LOOPHOLE[ts, STRING]]; RETURN[[ans.ORD], NIL]}; }; GetInstructionSetAndOperatingSystem: PUBLIC ENTRY PROC [h: Handle] RETURNS[instrSet, opSys: Rope.ROPE] ~ { <<>> ENABLE UNWIND => NULL; GetInstrSetAndOpSys: CirioNub.ProcID = CirioNubBase + 30; rc: CirioNub.ReturnCode; result: CirioNub.CallResult; nub: CirioNub.Handle; <> <> <<>> instrSet3:Rope.ROPE _ "RS6000"; opSys3:Rope.ROPE _ "AIX"; instrSet _ "SPARC"; opSys _ "SunOS4"; IF NOT h.live THEN ERROR Error[LIST[$notLive], "attempt to use a dead connection"]; IF h.version < 7 THEN RETURN; nub _ NARROW[h.contents, REF RemoteBody].nub; CirioNub.StartCall[nub, GetInstrSetAndOpSys]; [rc, result] _ CirioNub.Call[nub]; IF rc # ok THEN ERROR Error[LIST[$something], Rope.Cat["Can't determine the InstructionSet name or OperatingSystem name of the remote target. ReturnCode is ", GetReturnCodeRope[rc], "."]]; IF result.count # 2 THEN ERROR Error[LIST[$something], "Can't determine the InstructionSet name or OperatingSystem name of the remote target. Wrong number of arguments returned."]; instrSet _ Rope.FromRefText[NARROW[result.val[0]]]; opSys _ Rope.FromRefText[NARROW[result.val[1]]]; RETURN; }; <> RemoteDestroyNub: PROC[nub: CirioNub.Handle] = {CirioNub.Destroy[nub]}; RemoteNull: PROC[nub: CirioNub.Handle, proposedVersionNumber: CARD] RETURNS[actualVersionNumber: CARD32] = BEGIN CirioNubNull: CirioNub.ProcID = CirioNubBase + 0; rc: CirioNub.ReturnCode; result: CirioNub.CallResult; CirioNub.StartCall[nub, CirioNubNull]; CirioNub.PutCard32[nub, proposedVersionNumber]; [rc, result] _ CirioNub.Call[nub]; IF rc # ok THEN ERROR Error[LIST[$something], Rope.Cat["Can't get remote DebugNub version number. ReturnCode is ", GetReturnCodeRope[rc], "."]]; IF result.count # 1 THEN ERROR Error[LIST[$something], "Can't get remote DebugNub version number. Wrong number of arguments returned."]; actualVersionNumber _ NARROW[result[0], REF CARD32]^; END; <> <> RemoteWaitSig: PROC[nub: CirioNub.Handle, timeoutMilliSec: CARD] RETURNS[gotResponse: BOOLEAN] = BEGIN CirioNubWaitSig: CirioNub.ProcID = CirioNubBase + 1; rc: CirioNub.ReturnCode; result: CirioNub.CallResult; CirioNub.StartCall[nub, CirioNubWaitSig]; CirioNub.PutCard32[nub, timeoutMilliSec]; [rc, result] _ CirioNub.Call[nub]; IF rc # ok THEN ERROR Error[LIST[$something], Rope.Cat["Error calling WaitSig in the remote target. ReturnCode is ", GetReturnCodeRope[rc], "."]]; IF result.count # 2 THEN ERROR Error[LIST[$something], "Error calling WaitSig in the remote target. Wrong number of arguments returned."]; gotResponse _ (NARROW[result.val[0], REF INT32])^ = 0; <> <<>> END; RemoteSetDBStat: PROC[nub: CirioNub.Handle, dbStat: INT32, timeoutMilliSec: CARD] RETURNS[ok: BOOLEAN] = BEGIN CirioNubSetDBStat: CirioNub.ProcID = CirioNubBase + 2; rc: CirioNub.ReturnCode; result: CirioNub.CallResult; CirioNub.StartCall[nub, CirioNubSetDBStat]; CirioNub.PutInt32[nub, dbStat]; CirioNub.PutCard32[nub, timeoutMilliSec]; [rc, result] _ CirioNub.Call[nub]; IF rc # ok THEN ERROR Error[LIST[$something], Rope.Cat["Error calling SetDBStat in the remote target. ReturnCode is ", GetReturnCodeRope[rc], "."]]; IF result.count # 1 THEN ERROR Error[LIST[$something], "Error calling SetDBStat in the remote target. Wrong number of arguments returned."]; ok _ (NARROW[result.val[0], REF INT32])^ = 0; END; RemoteReadBytes: PROC[nub: CirioNub.Handle, address: CirioNubAccess.RemoteAddress, count: INT] RETURNS[REF TEXT] = { CirioNubGetBytes: CirioNub.ProcID = CirioNubBase + 3; rc: CirioNub.ReturnCode; result: CirioNub.CallResult; text: REF TEXT; IF address.nil THEN RemoteNilFault[address]; IF NOT address.valid THEN RemoteAddrFault[address]; IF address.valid THEN BEGIN CirioNub.StartCall[nub, CirioNubGetBytes]; CirioNub.PutCard32[nub, address.byteAddress+(address.bitOffset/8)]; CirioNub.PutInt32[nub, count]; -- asking for count bytes [rc, result] _ CirioNub.Call[nub]; IF rc # ok THEN ERROR Error[LIST[$something], Rope.Cat["Error calling GetBytes in the remote target. ReturnCode is ", GetReturnCodeRope[rc], "."]]; IF result.count # 1 THEN ERROR Error[LIST[$something], "Error calling GetBytes in the remote target. Wrong number of arguments returned."]; text _ NARROW[result.val[0]]; RETURN[text] END ELSE RETURN[NIL]; }; <<>> RemoteRead16BitsAsCardinal: PROC[nub: CirioNub.Handle, address: CirioNubAccess.RemoteAddress] RETURNS[CARDINAL] = { CirioNubGetWords16: CirioNub.ProcID = CirioNubBase + 5; rc: CirioNub.ReturnCode; result: CirioNub.CallResult; block16: CirioNub.Block16; remoteByteAddress: CARD _ address.byteAddress+address.bitOffset/8; IF address.nil THEN RemoteNilFault[address]; IF NOT address.valid THEN RemoteAddrFault[address]; CirioNub.StartCall[nub, CirioNubGetWords16]; CirioNub.PutCard32[nub, remoteByteAddress]; CirioNub.PutInt32[nub, 2]; -- asking for 2 bytes [rc, result] _ CirioNub.Call[nub]; IF rc # ok THEN ERROR Error[LIST[$something], Rope.Cat["Error calling GetWords16 in the remote target. ReturnCode is ", GetReturnCodeRope[rc], "."]]; IF result.count # 1 THEN ERROR Error[LIST[$something], "Error calling GetWords16 in the remote target. Wrong number of arguments returned."]; block16 _ NARROW[result.val[0]]; IF block16.count # 1 THEN RemoteAddrFault[address]; <> RETURN[block16.val[0]] }; <> RemoteAddressRangeCheck: PROC[remoteByteAddress: CARD] RETURNS[BOOL] = { RETURN[remoteByteAddress > 0 AND remoteByteAddress < 1000]}; RemoteRead32BitsAsCard: PROC[nub: CirioNub.Handle, address: CirioNubAccess.RemoteAddress] RETURNS[CARD] = { CirioNubGetWords32: CirioNub.ProcID = CirioNubBase + 7; rc: CirioNub.ReturnCode; result: CirioNub.CallResult; block32: CirioNub.Block32; remoteByteAddress: CARD _ address.byteAddress+address.bitOffset/8; IF address.nil THEN RemoteNilFault[address]; IF NOT address.valid THEN RemoteAddrFault[address]; <> <> IF RemoteAddressRangeCheck[remoteByteAddress] THEN RemoteAddrFault[address]; CirioNub.StartCall[nub, CirioNubGetWords32]; CirioNub.PutCard32[nub, remoteByteAddress]; CirioNub.PutInt32[nub, 4]; -- asking for 4 bytes [rc, result] _ CirioNub.Call[nub]; IF rc # ok THEN ERROR Error[LIST[$something], Rope.Cat["Error calling GetWords32 in the remote target. ReturnCode is ", GetReturnCodeRope[rc], "."]]; IF result.count # 1 THEN ERROR Error[LIST[$something], "Error calling GetWords32 in the remote target. Wrong number of arguments returned."]; block32 _ NARROW[result.val[0]]; IF block32.count # 1 THEN RemoteAddrFault[address]; <> RETURN[block32.val[0]] }; RemoteWriteCardAs32Bits: PROC[nub: CirioNub.Handle, address: CirioNubAccess.RemoteAddress, card: CARD32] = { CirioNubPutWords32: CirioNub.ProcID = CirioNubBase + 8; rc: CirioNub.ReturnCode; result: CirioNub.CallResult; block32: CirioNub.Block32 _ NEW[CirioNub.Block32Record[1]]; remoteByteAddress: CARD _ address.byteAddress+address.bitOffset/8; block32.count _ 1; block32[0] _ card; IF address.nil THEN RemoteNilFault[address]; IF NOT address.valid THEN RemoteAddrFault[address]; <> <> IF RemoteAddressRangeCheck[remoteByteAddress] THEN RemoteAddrFault[address]; CirioNub.StartCall[nub, CirioNubPutWords32]; CirioNub.PutCard32[nub, remoteByteAddress]; CirioNub.PutBlock32[nub, block32]; [rc, result] _ CirioNub.Call[nub]; IF rc # ok THEN ERROR Error[LIST[$something], Rope.Cat["Error calling PutWords32 in the remote target. ReturnCode is ", GetReturnCodeRope[rc], "."]]; }; RemoteWrite4Bytes: PROC[nub: CirioNub.Handle, address: CirioNubAccess.RemoteAddress, bytes: PACKED ARRAY [0..3] OF BYTE] = { CirioNubPutBytes: CirioNub.ProcID = CirioNubBase + 4; rc: CirioNub.ReturnCode; result: CirioNub.CallResult; remoteByteAddress: CARD _ address.byteAddress+address.bitOffset/8; IF address.nil THEN RemoteNilFault[address]; IF NOT address.valid THEN RemoteAddrFault[address]; <> <> IF RemoteAddressRangeCheck[remoteByteAddress] THEN RemoteAddrFault[address]; <<>> CirioNub.StartCall[nub, CirioNubPutBytes]; CirioNub.PutCard32[nub, remoteByteAddress]; CirioNub.PutBlock8Cnt[nub, 4]; FOR I: CARDINAL IN [0..4) DO CirioNub.PutBlock8Next[nub, bytes[I]]; ENDLOOP; [rc, result] _ CirioNub.Call[nub]; IF rc # ok THEN ERROR Error[LIST[$something], Rope.Cat["Error calling PutBytes in the remote target. ReturnCode is ", GetReturnCodeRope[rc], "."]]; }; RemoteGetThreads: PROC[nub: CirioNub.Handle, lowIndex, highIndex: CARD] RETURNS[LIST OF REF CirioNubAccess.ThreadInfo] = BEGIN CirioNubGetThreads: CirioNub.ProcID = CirioNubBase + 9; rc: CirioNub.ReturnCode; result: CirioNub.CallResult; nBlocks: INTEGER; cardsPerBlock: CARD = 9; block32: CirioNub.Block32; list: LIST OF REF CirioNubAccess.ThreadInfo _ NIL; CirioNub.StartCall[nub, CirioNubGetThreads]; CirioNub.PutCard32[nub, lowIndex]; CirioNub.PutCard32[nub, highIndex]; [rc, result] _ CirioNub.Call[nub]; IF rc # ok THEN ERROR Error[LIST[$something], "something in CirioNubAccessImpl"]; IF result.count # 1 THEN ERROR Error[LIST[$something], Rope.Cat["Error calling GetThreads in the remote target. ReturnCode is ", GetReturnCodeRope[rc], "."]]; block32 _ NARROW[result.val[0]]; IF block32.count MOD cardsPerBlock # 0 THEN ERROR Error[LIST[$something], "something in CirioNubAccessImpl"]; nBlocks _ block32.count/cardsPerBlock; FOR I: INTEGER DECREASING IN [0..nBlocks) DO blockX: CARD _ I*cardsPerBlock; oneThread: REF CirioNubAccess.ThreadInfo _ NEW[CirioNubAccess.ThreadInfo _[ index: block32.val[blockX], gen: block32.val[blockX+1], schedState: block32.val[blockX+2], priority: block32.val[blockX+3], dbgMsg: LOOPHOLE[block32.val[blockX+4], INT32], frozen: block32.val[blockX+5] # 0, pc: block32.val[blockX+6], stackPointer: block32.val[blockX+7], framePointer: block32.val[blockX+8]]]; list _ CONS[oneThread, list] ENDLOOP; RETURN[list] END; RemotePCtoInfo: PROC[nub: CirioNub.Handle, pc: CARD] RETURNS[CirioNubAccess.PCInfo] = BEGIN CirioNubPCToInfo: CirioNub.ProcID = CirioNubBase + 10; rc: CirioNub.ReturnCode; result: CirioNub.CallResult; info: CirioNubAccess.PCInfo _ NEW[CirioNubAccess.PCInfoBody]; CirioNub.StartCall[nub, CirioNubPCToInfo]; CirioNub.PutCard32[nub, pc]; [rc, result] _ CirioNub.Call[nub]; IF rc # ok THEN ERROR Error[LIST[$something], Rope.Cat["Error calling PCToInfo in the remote target. ReturnCode is ", GetReturnCodeRope[rc], "."]]; IF result.count # 6 THEN ERROR Error[LIST[$something], "Error calling PCToInfo in the remote target. Wrong number of arguments returned."]; info.procName _ Rope.FromRefText[NARROW[result.val[0]]]; info.procSymID _ NARROW[result.val[1], REF CARD]^; info.fileName _ PFS.PathFromRope[ Rope.FromRefText[NARROW[result.val[2]]]]; info.fileSeqNum _ NARROW[result.val[3], REF CARD]^; info.guessedEmbeddedFileName _ PFS.PathFromRope [Rope.FromRefText[NARROW[result.val[4]]]]; info.guessedEmbeddedFileSymID _ NARROW[result.val[5], REF CARD]^; RETURN[info]; END; RemoteKillWorld: PROC[nub: CirioNub.Handle] = BEGIN CirioNubKillWorld: CirioNub.ProcID = CirioNubBase + 11; rc: CirioNub.ReturnCode; result: CirioNub.CallResult; CirioNub.StartCall[nub, CirioNubKillWorld]; [rc, result] _ CirioNub.Call[nub]; IF rc # ok THEN ERROR Error[LIST[$something], Rope.Cat["Error calling KillWorld in the remote target. ReturnCode is ", GetReturnCodeRope[rc], "."]]; IF result.count # 0 THEN ERROR Error[LIST[$something], "Error calling KillWorld in the remote target. Wrong number of arguments returned."]; END; RemoteIssueThreadCommand: PROC[nub: CirioNub.Handle, threadIndex: CARD, setFreeze: BOOL, freeze: BOOL, setMsg: BOOL, msg: INT] RETURNS[success: BOOLEAN] = BEGIN CirioIssueThreadCommand: CirioNub.ProcID = CirioNubBase + 18; rc: CirioNub.ReturnCode; result: CirioNub.CallResult; CirioNub.StartCall[nub, CirioIssueThreadCommand]; CirioNub.PutCard32[nub, threadIndex]; CirioNub.PutCard32[nub, IF setFreeze THEN 1 ELSE 0]; <> <> CirioNub.PutCard32[nub, IF freeze THEN 1 ELSE 0]; CirioNub.PutCard32[nub, IF setMsg THEN 1 ELSE 0]; CirioNub.PutCard32[nub, LOOPHOLE[msg, CARD]]; [rc, result] _ CirioNub.Call[nub]; IF rc # ok THEN ERROR Error[LIST[$something], Rope.Cat["Error calling IssueThreadCommand in the remote target. ReturnCode is ", GetReturnCodeRope[rc], "."]]; IF result.count # 1 THEN ERROR Error[LIST[$something], "Error calling IssueThreadCommand in the remote target. Wrong number of arguments returned."]; RETURN[NARROW[result.val[0], REF INT]^ = 0] END; <> RemoteGetDBStat: PROC[nub: CirioNub.Handle, oldStat: INT32, oldExamineeIndex: INT, timeoutMsec: CARD] RETURNS[dbStab: INT32, examineeIndex: INT32] = BEGIN CirioGetDBStat: CirioNub.ProcID = CirioNubBase + 19; rc: CirioNub.ReturnCode; result: CirioNub.CallResult; CirioNub.StartCall[nub, CirioGetDBStat]; CirioNub.PutInt32[nub, oldStat]; CirioNub.PutInt32[nub, oldExamineeIndex]; CirioNub.PutCard32[nub, timeoutMsec]; [rc, result] _ CirioNub.Call[nub]; IF rc # ok THEN ERROR Error[LIST[$something], Rope.Cat["Error calling GetDBStat in the remote target. ReturnCode is ", GetReturnCodeRope[rc], "."]]; IF result.count # 2 THEN ERROR Error[LIST[$something], "Error calling GetDBStat in the remote target. Wrong number of arguments returned."]; RETURN[NARROW[result.val[0], REF INT]^, NARROW[result.val[1], REF INT]^] END; RemoteGetFileEntry4: PROC[nub: CirioNub.Handle, seqNum: CARD] RETURNS[CirioNubAccess.FileEntry] = BEGIN CirioNubGetFileEntry: CirioNub.ProcID = CirioNubBase + 20; rc: CirioNub.ReturnCode; result: CirioNub.CallResult; entry: CirioNubAccess.FileEntry _ NEW[CirioNubAccess.FileEntryBody]; CirioNub.StartCall[nub, CirioNubGetFileEntry]; CirioNub.PutCard32[nub, seqNum]; [rc, result] _ CirioNub.Call[nub]; IF rc # ok THEN ERROR Error[LIST[$something], Rope.Cat["Error calling GetFileEntry in the remote target. ReturnCode is ", GetReturnCodeRope[rc], "."]]; IF result.count # 21 THEN ERROR Error[LIST[$something], "Error calling GetFileEntry in the remote target. Wrong number of arguments returned."]; entry.seqNum _ NARROW[result.val[0], REF CARD]^; entry.commitPoint _ NARROW[result.val[1], REF CARD]^ # 0; entry.fileName _ PFS.PathFromRope[ Rope.FromRefText[NARROW[result.val[2]]]]; entry.fOffset _ NARROW[result.val[3], REF CARD]^; entry.fmagic _ NARROW[result.val[4], REF CARD]^; entry.size _ NARROW[result.val[5], REF CARD]^; entry.mtime _ NARROW[result.val[6], REF CARD]^; entry.smagic _ NARROW[result.val[7], REF CARD]^; entry.stamp _ Rope.FromRefText[NARROW[result.val[8]]]; entry.readerData _ NARROW[result.val[9], REF CARD]^; entry.readerDataSize _ NARROW[result.val[10], REF CARD]^; entry.patchReloc _ NARROW[result.val[11], REF CARD]^; entry.patchSize _ NARROW[result.val[12], REF CARD]^; entry.textReloc _ NARROW[result.val[13], REF CARD]^; entry.textSize _ NARROW[result.val[14], REF CARD]^; entry.dataReloc _ NARROW[result.val[15], REF CARD]^; entry.dataSize _ NARROW[result.val[16], REF CARD]^; entry.bssReloc _ NARROW[result.val[17], REF CARD]^; entry.bssSize _ NARROW[result.val[18], REF CARD]^; entry.commonReloc _ NARROW[result.val[19], REF CARD]^; entry.commonSize _ NARROW[result.val[20], REF CARD]^; RETURN[entry]; END; RemoteGetFileEntry5: PROC[nub: CirioNub.Handle, seqNum: CARD] RETURNS[CirioNubAccess.FileEntry] = BEGIN CirioNubGetFileEntry: CirioNub.ProcID = CirioNubBase + 20; rc: CirioNub.ReturnCode; result: CirioNub.CallResult; entry: CirioNubAccess.FileEntry _ NEW[CirioNubAccess.FileEntryBody]; stampAddr: CARD32; stampSize: CARD32; CirioNub.StartCall[nub, CirioNubGetFileEntry]; CirioNub.PutCard32[nub, seqNum]; [rc, result] _ CirioNub.Call[nub]; IF rc # ok THEN ERROR Error[LIST[$something], Rope.Cat["Error calling GetFileEntry in the remote target. ReturnCode is ", GetReturnCodeRope[rc], "."]]; IF result.count # 22 THEN ERROR Error[LIST[$something], "Error calling GetFileEntry in the remote target. Wrong number of arguments returned."]; entry.seqNum _ NARROW[result.val[0], REF CARD]^; entry.commitPoint _ NARROW[result.val[1], REF CARD]^ # 0; entry.fileName _ PFS.PathFromRope[ Rope.FromRefText[NARROW[result.val[2]]]]; entry.fOffset _ NARROW[result.val[3], REF CARD]^; entry.fmagic _ NARROW[result.val[4], REF CARD]^; entry.size _ NARROW[result.val[5], REF CARD]^; entry.mtime _ NARROW[result.val[6], REF CARD]^; entry.smagic _ NARROW[result.val[7], REF CARD]^; stampAddr _ NARROW[result.val[8], REF CARD]^; stampSize _ NARROW[result.val[9], REF CARD]^; entry.stamp _ NIL; <<(we should read in the stamp at this point)>> entry.readerData _ NARROW[result.val[10], REF CARD]^; entry.readerDataSize _ NARROW[result.val[11], REF CARD]^; entry.patchReloc _ NARROW[result.val[12], REF CARD]^; entry.patchSize _ NARROW[result.val[13], REF CARD]^; entry.textReloc _ NARROW[result.val[14], REF CARD]^; entry.textSize _ NARROW[result.val[15], REF CARD]^; entry.dataReloc _ NARROW[result.val[16], REF CARD]^; entry.dataSize _ NARROW[result.val[17], REF CARD]^; entry.bssReloc _ NARROW[result.val[18], REF CARD]^; entry.bssSize _ NARROW[result.val[19], REF CARD]^; entry.commonReloc _ NARROW[result.val[20], REF CARD]^; entry.commonSize _ NARROW[result.val[21], REF CARD]^; RETURN[entry]; END; RemoteLookupSymEntryByName: PROC[nub: CirioNub.Handle, sym: Rope.ROPE, caseSensitive: BOOLEAN, externOnly: BOOLEAN, numToSkip: INT] RETURNS[CirioNubAccess.SymEntry] = BEGIN CirioNubLookupSymEntryByName: CirioNub.ProcID = CirioNubBase + 21; rc: CirioNub.ReturnCode; result: CirioNub.CallResult; CirioNub.StartCall[nub, CirioNubLookupSymEntryByName]; CirioNub.PutRope[nub, sym]; CirioNub.PutCard32[nub, IF caseSensitive THEN 1 ELSE 0]; CirioNub.PutCard32[nub, IF externOnly THEN 1 ELSE 0]; CirioNub.PutInt32[nub, numToSkip]; [rc, result] _ CirioNub.Call[nub]; IF rc # ok THEN ERROR Error[LIST[$something], Rope.Cat["Error calling LookupSymEntryByName in the remote target. ReturnCode is ", GetReturnCodeRope[rc], "."]]; RETURN[RemoteComputeSymEntry[result]]; END; RemoteLookupSymEntryByValue: PROC[nub: CirioNub.Handle, val: CARD, numToSkip: INT] RETURNS[CirioNubAccess.SymEntry] = BEGIN CirioNubLookupSymEntryByValue: CirioNub.ProcID = CirioNubBase + 22; rc: CirioNub.ReturnCode; result: CirioNub.CallResult; CirioNub.StartCall[nub, CirioNubLookupSymEntryByValue]; CirioNub.PutCard32[nub, val]; CirioNub.PutInt32[nub, numToSkip]; [rc, result] _ CirioNub.Call[nub]; IF rc # ok THEN ERROR Error[LIST[$something], Rope.Cat["Error calling LookupSymEntryByValue in the remote target. ReturnCode is ", GetReturnCodeRope[rc], "."]]; RETURN[RemoteComputeSymEntry[result]]; END; RemoteLookupSymEntryByID: PROC[nub: CirioNub.Handle, symID: CARD] RETURNS[CirioNubAccess.SymEntry] = BEGIN CirioNubLookupSymEntryByID: CirioNub.ProcID = CirioNubBase + 23; rc: CirioNub.ReturnCode; result: CirioNub.CallResult; CirioNub.StartCall[nub, CirioNubLookupSymEntryByID]; CirioNub.PutCard32[nub, symID]; [rc, result] _ CirioNub.Call[nub]; IF rc # ok THEN ERROR Error[LIST[$something], Rope.Cat["Error calling LookupSymEntryByID in the remote target. ReturnCode is ", GetReturnCodeRope[rc], "."]]; RETURN[RemoteComputeSymEntry[result]]; END; RemoteLookupMatchingSymEntryByName: PROC[nub: CirioNub.Handle, symID: CARD, sym: Rope.ROPE, caseSensitive: BOOLEAN, wantedTypes: CARD, ignoredClasses: CARD, numToSkip: INT] RETURNS[CirioNubAccess.SymEntry] = BEGIN CirioNubLookupMatchingSymEntryByName: CirioNub.ProcID = CirioNubBase + 26; rc: CirioNub.ReturnCode; result: CirioNub.CallResult; CirioNub.StartCall[nub, CirioNubLookupMatchingSymEntryByName]; CirioNub.PutCard32[nub, symID]; CirioNub.PutRope[nub, sym]; CirioNub.PutCard32[nub, IF caseSensitive THEN 1 ELSE 0]; CirioNub.PutCard32[nub, wantedTypes]; CirioNub.PutCard32[nub, ignoredClasses]; CirioNub.PutInt32[nub, numToSkip]; [rc, result] _ CirioNub.Call[nub]; IF rc # ok THEN ERROR Error[LIST[$something], Rope.Cat["Error calling LookupMatchingSymEntryByName in the remote target. ReturnCode is ", GetReturnCodeRope[rc], "."]]; RETURN[RemoteComputeSymEntry[result]]; END; RemoteLookupMatchingSymEntryByValue: PROC[nub: CirioNub.Handle, symID: CARD, val: CARD, wantedTypes: CARD, ignoredClasses: CARD, numToSkip: INT] RETURNS[CirioNubAccess.SymEntry] = BEGIN CirioNubLookupMatchingSymEntryByValue: CirioNub.ProcID = CirioNubBase + 27; rc: CirioNub.ReturnCode; result: CirioNub.CallResult; CirioNub.StartCall[nub, CirioNubLookupMatchingSymEntryByValue]; CirioNub.PutCard32[nub, symID]; CirioNub.PutCard32[nub, val]; CirioNub.PutCard32[nub, wantedTypes]; CirioNub.PutCard32[nub, ignoredClasses]; CirioNub.PutInt32[nub, numToSkip]; [rc, result] _ CirioNub.Call[nub]; IF rc # ok THEN ERROR Error[LIST[$something], Rope.Cat["Error calling LookupMatchingSymEntryByValue in the remote target. ReturnCode is ", GetReturnCodeRope[rc], "."]]; RETURN[RemoteComputeSymEntry[result]]; END; RemoteComputeSymEntry: PROC[result: CirioNub.CallResult] RETURNS[CirioNubAccess.SymEntry] = BEGIN IF result.count < 1 THEN ERROR Error[LIST[$something], "something in CirioNubAccessImpl"]; BEGIN errCode: INT32 _ NARROW[result.val[0], REF INT32]^; SELECT errCode FROM 0 => BEGIN entry: CirioNubAccess.SymEntry _ NEW[CirioNubAccess.SymEntryBody]; IF result.count # 7 THEN ERROR Error[LIST[$something], "something in CirioNubAccessImpl"]; entry.symID _ NARROW[result.val[1], REF CARD]^; entry.name _ Rope.FromRefText[NARROW[result.val[2]]]; entry.type _ NARROW[result.val[3], REF CARD]^; entry.value _ NARROW[result.val[4], REF CARD]^; entry.size _ NARROW[result.val[5], REF CARD]^; entry.fileSeqNum _ NARROW[result.val[6], REF CARD]^; RETURN[entry]; END; ENDCASE => RETURN[NIL]; END; END; RemoteMonitoredCall: PROC[ address: CirioNubAccess.RemoteAddress, proc: PROC[] RETURNS[]] RETURNS [] = BEGIN HolderOffset: PROCEDURE[] RETURNS [INT] ~ TRUSTED { <> <> sampleMonitorLock: PCRMonitorDefs.MonitorLock; sampleAddress: LONG POINTER TO PCRMonitorDefs.MonitorLock ~ @sampleMonitorLock; sampleAddressCard: CARD32 ~ LOOPHOLE[sampleAddress]; holderAddress: LONG POINTER TO PCRMonitorDefs.Thread ~ @sampleMonitorLock.holder; holderAddressCard: CARD32 ~ LOOPHOLE[holderAddress]; offset: INT ~ (holderAddressCard - sampleAddressCard) * BYTES[UNIT]; RETURN [offset]; }; holderAddress: CirioNubAccess.RemoteAddress ~ [ h: address.h, byteAddress: address.byteAddress + HolderOffset[], bitOffset: address.bitOffset, nil: address.nil, valid: address.valid]; holder: PCRMonitorDefs.Thread ~ LOOPHOLE[Read32BitsAsCard[address: holderAddress]]; IF holder = PCRMonitorDefs.nullHolder THEN { <> proc[]; } ELSE { <> ERROR RemoteMonitorWouldBlock[addr: address]; }; END; RemoteGetConcreteTypecode: PROC[h: Handle, opaque: CirioNubAccess.Typecode] RETURNS[concrete: CirioNubAccess.Typecode] ~ { nub: CirioNub.Handle ~ NARROW[h.contents, REF RemoteBody].nub; rc: CirioNub.ReturnCode; result: CirioNub.CallResult; CedarCirioNubGetConcreteTypecode: CirioNub.ProcID = CedarCirioNubBase+3; CirioNub.StartCall[nub, CedarCirioNubGetConcreteTypecode]; CirioNub.PutCard32[nub, opaque]; [rc, result] _ CirioNub.Call[nub]; IF rc # ok THEN ERROR Error[LIST[$something], Rope.Cat["Error calling GetConcreteTypecode in the remote target. ReturnCode is ", GetReturnCodeRope[rc], "."]]; IF result.count # 1 THEN ERROR Error[LIST[$something], "Error calling GetConcreteTypecode in the remote target. Wrong number of arguments returned."]; concrete _ [NARROW[result.val[0], REF CARD32]^]; RETURN; }; RemoteGetTypestring: PUBLIC PROC[h: Handle, code: CirioNubAccess.Typecode] RETURNS[string: CirioNubAccess.Typestring] ~ { nub: CirioNub.Handle ~ NARROW[h.contents, REF RemoteBody].nub; rc: CirioNub.ReturnCode; result: CirioNub.CallResult; CedarCirioNubGetTypestring: CirioNub.ProcID = CedarCirioNubBase+1; CirioNub.StartCall[nub, CedarCirioNubGetTypestring]; CirioNub.PutCard32[nub, code]; [rc, result] _ CirioNub.Call[nub]; IF rc # ok THEN ERROR Error[LIST[$something], Rope.Cat["Error calling GetTypestring in the remote target. ReturnCode is ", GetReturnCodeRope[rc], "."]]; IF result.count # 1 THEN ERROR Error[LIST[$something], "Error calling GetTypestring in the remote target. Wrong number of arguments returned."]; string _ Rope.FromRefText[NARROW[result.val[0]]]; RETURN; }; RemoteGetTypecode: PROC[h: Handle, string: CirioNubAccess.Typestring] RETURNS[code: CirioNubAccess.Typecode] ~ { nub: CirioNub.Handle ~ NARROW[h.contents, REF RemoteBody].nub; rc: CirioNub.ReturnCode; result: CirioNub.CallResult; found: BOOL; CedarCirioNubGetTypecode: CirioNub.ProcID = CedarCirioNubBase+2; CirioNub.StartCall[nub, CedarCirioNubGetTypecode]; CirioNub.PutCard32[nub, Rope.Length[string]]; CirioNub.PutRope[nub, string]; [rc, result] _ CirioNub.Call[nub]; IF rc # ok THEN ERROR Error[LIST[$something], Rope.Cat["Error calling GetTypecode in the remote target. ReturnCode is ", GetReturnCodeRope[rc], "."]]; IF result.count # 2 THEN ERROR Error[LIST[$something], "Error calling GetTypecode in the remote target. Wrong number of arguments returned."]; found _ NARROW[result.val[0], REF CARD32]^ # 0; code _ IF found THEN [NARROW[result.val[1], REF CARD32]^] ELSE [0]; RETURN; }; <> <> CHARPtr: TYPE ~ RECORD [ptr: LONG POINTER TO PBasics.RawChars _ NIL]; SameWorldReadBytes: PROC[address: CirioNubAccess.RemoteAddress, count: INT] RETURNS[REF TEXT] = TRUSTED { bitsPerByte: CARD = BITS[BYTE]; text: REF TEXT _ RefText.New[count]; byteAddress: CHARPtr; IF address.nil THEN RemoteNilFault[address]; IF NOT address.valid THEN RemoteAddrFault[address]; IF address.valid THEN BEGIN byteAddress _ LOOPHOLE[address.byteAddress + address.bitOffset/bitsPerByte]; <> <> FOR i: CARD IN [0..CARD[count]) DO text _ RefText.InlineAppendChar[text, byteAddress[i]]; ENDLOOP; RETURN[text]; END ELSE RETURN[NIL]; }; CARD16Ptr: TYPE ~ LONG POINTER TO CARD16; SameWorldRead16BitsAsCardinal: PROC[address: CirioNubAccess.RemoteAddress] RETURNS[CARDINAL] = TRUSTED { bitsPerByte: CARD = BITS[BYTE]; card16: CARD16; byteAddress: CARD16Ptr _ LOOPHOLE[address.byteAddress + (address.bitOffset/bitsPerByte), CARD16Ptr] ; IF address.nil THEN RemoteNilFault[address]; IF NOT address.valid THEN RemoteAddrFault[address]; card16 _ byteAddress^; RETURN[LOOPHOLE[card16]]; }; CARD32Ptr: TYPE ~ LONG POINTER TO CARD32; <> LocalAddressRangeCheck: PROC[byteAddress: CARD] RETURNS[BOOL] = { RETURN[byteAddress> 0 AND byteAddress < 1000]}; SameWorldRead32BitsAsCard: PROC[address: CirioNubAccess.RemoteAddress] RETURNS[CARD] = TRUSTED { bitsPerByte: CARD = BITS[BYTE]; byteAddress: CARD32Ptr _ LOOPHOLE[address.byteAddress + (address.bitOffset/bitsPerByte), CARD32Ptr]; IF address.nil THEN RemoteNilFault[address]; IF NOT address.valid THEN RemoteAddrFault[address]; <> <> IF LocalAddressRangeCheck[LOOPHOLE[byteAddress, CARD]] THEN RemoteAddrFault[address]; <<>> RETURN[LOOPHOLE[byteAddress^]]; }; SameWorldWriteCardAs32Bits: PROC[address: CirioNubAccess.RemoteAddress, card: CARD32] = TRUSTED { bitsPerByte: CARD = BITS[BYTE]; byteAddress: CARD32Ptr _ LOOPHOLE[address.byteAddress + (address.bitOffset/bitsPerByte), CARD32Ptr]; IF address.nil THEN RemoteNilFault[address]; IF NOT address.valid THEN RemoteAddrFault[address]; <> <> IF LocalAddressRangeCheck[LOOPHOLE[byteAddress, CARD]] THEN RemoteAddrFault[address]; <<>> byteAddress^ _ card; }; BYTEPtr: TYPE ~ RECORD [ptr: LONG POINTER TO PBasics.RawBytes _ NIL]; SameWorldWrite4Bytes: PROC[address: CirioNubAccess.RemoteAddress, bytes: PACKED ARRAY [0..3] OF BYTE] = TRUSTED { bitsPerByte: CARD = BITS[BYTE]; byteAddress: BYTEPtr; IF address.nil THEN RemoteNilFault[address]; IF NOT address.valid THEN RemoteAddrFault[address]; byteAddress _ LOOPHOLE[address.byteAddress + address.bitOffset/bitsPerByte]; <> <> <> <> IF LocalAddressRangeCheck[LOOPHOLE[byteAddress, CARD]] THEN RemoteAddrFault[address]; <<>> FOR i: CARDINAL IN [0..4) DO byteAddress[i] _ bytes[i]; ENDLOOP; }; UntypedDataHolder: TYPE = RECORD[SEQUENCE nCard32: CARDINAL OF CARD32]; SameWorldAllocateBytes: PROC[nBytes: CARD] RETURNS[data: REF ANY, byteAddr: CARD] = BEGIN stuff: REF UntypedDataHolder _ NEW[UntypedDataHolder[((nBytes+3)/4)+1]]; <> GetByteAddress: PROC RETURNS[CARD] = TRUSTED {RETURN[LOOPHOLE[@stuff[0]]]}; RETURN[stuff, GetByteAddress[]]; END; <> SameWorldReleaseAllocatedBytes: PROC[data: REF ANY] = BEGIN NULL END; SameWorldMonitoredCall: PROC[ address: CirioNubAccess.RemoteAddress, proc: PROC[] RETURNS []] RETURNS [] = SameWorldMonitoredCallOps.MonitoredCall; <<>> <> <<>> <<>> <> <> <> <> NameToAddress: PUBLIC PROC [name: Rope.ROPE] RETURNS [addr: Rope.ROPE] = { <> addr _ NetworkName.AddressFromName[$ARPA, name, NIL, host ! NetworkName.Error => Error[CONS[$debuggeeNameLookupError, codes], IO.PutFR["%g looking up target %g", [rope[msg]], [rope[name]] ]] ].addr; << <> { ENABLE Convert.Error => CONTINUE; a: Arpa.Address _ ConvertExtras.ArpaAddressFromRope[name]; IF a # Arpa.nullAddress THEN RETURN[ ConvertExtras.RopeFromArpaAddress[a] ] }; <> { h: SunYPAgent.Handle ~ SunYPAgent.ObtainHandle[]; val: REF TEXT ~ SunYPAgent.Match[h: h, map: "hosts.byname", key: name]; textseq: SunYPAgent.TextSeq ~ SunYPAgent.Tokenize[in: val]; RETURN[Rope.FromRefText[textseq[0]]]; }>> RETURN}; GetReturnCodeRope: PROC [rc: CirioNub.ReturnCode] RETURNS [rcRope: Rope.ROPE] = { <> SELECT rc FROM ok => rcRope _ "ok"; noProc => rcRope _ "noProc"; badArgs => rcRope _ "badArgs"; failure => rcRope _ "failure"; commError => rcRope _ "commError"; protocolError => rcRope _ "protocolError"; spaceError => rcRope _ "spaceError"; last => rcRope _ "last"; ENDCASE => rcRope _ "unParsed ReturnCode"; RETURN}; END.. March 10, 1992 3:06:44 pm PSTMarch 10, 1992 3:06:46 pm PST