remote/sameWorld case selection
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];
assumes that creation of h set the version number
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;
waits for change from old values or timeout
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;
This is here to provide compatibility with remote nubs that are versions 4 and 5.
eventually we will re-write to explicitly use the new version 6 operations
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;
These two constants come from /jaune/xrhome/DEVELOPMENT/INCLUDE/xr/IncrementalLoad.h
don't forget that the bottom bit should be ignored, as it is the "external" bit.
symId
= 0, is ignored
# 0, search starts with given symId
pattern
either a rope with no asterisk
exact match required
or a rope with at least one period and exactly one asterisk as the last character
asterisk is a wild card
caseSensitive
if true, capitalization must match
wantedTypes
-1 for all types are acceptable
t for a specific type (external bit is ignored)
ignoreClasses
0 accept all types
1 ignore internals
2 ignore externals
3 ignore all types (very fast!)
numToSkip
presumed non negative
search starts with most recent matching entry
if 0, accept first matching entry
if 1, skip first matching entry, look for next older matching entry
etc.
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]];
symId
= 0, search starts with the entry with greatest value less or equal to given val.
# 0, search starts with given symId
wantedTypes
(see LookupMatchingSymEntryByName)
ignoreClasses
0(see LookupMatchingSymEntryByName)
numToSkip
if zero, finds entry with greatest value less or equal to given val
if greater than zero, searches by increasing value
if negative, searches by decreasing value
if several entries have same value, then think of the key as the pair <value, entry time). These keys are ordered by value first, then by entry time. The search key is <the given val, now>.
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;
remote procedures
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;
We use this to wait for a call from some thread
This is probably not what we shall use in the future
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;
WaitSig actually returns a second param, DBStat, but this param is not interesting for the present application.
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];
Really, shouldn't this show up as rc # ok??
RETURN[block16.val[0]]
};
a mild sanity check due to funny things happening with gnu.
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 remoteByteAddress < 1000 THEN RemoteAddrFault[address];
a mild sanity check due to funny things happening with gnu.
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];
Really, shouldn't this show up as rc # ok??
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 remoteByteAddress < 1000 THEN RemoteAddrFault[address];
a mild sanity check due to funny things happening with gnu.
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 remoteByteAddress < 1000 THEN RemoteAddrFault[address];
a mild sanity check due to funny things happening with gnu.
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];
Is this how I deliver a Bool? Barry says 1 is true, 0 is false.
Alan agrees. (the comments in his dot h files of the form Return ( (success) ? 0 : -1 ) are a standard convention for system calls, they are NOT returning a Boolean.)
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;
waits for change from old values or timeout
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]];
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;