; ; Debug Kernal for PL/I Symbolic Debugger ; .enable lc ; ; This is the module that resides in the user task and performs ; whatever operations need to be performed on behalf of the debug task. ; ; Do not modify anything in this module without good familiarity ; with the code in DEBASM. ; .title debug .psect $deb$$ ;psect must have this name for debinit to work ;*************************************************************************** ; Version number - must be incremented any time a change is made which ; affects the interface with the debug task, including anything that ; changes the relative locations of words referred to by the debug task ; (note that a change in the executive macros could do this); so that ; trying to debug a task that has an obsolete version results in an ; error message rather than mysterious blow-ups. The safest thing is to ; increment on every edit and on each major release of the executive. ; The version number is in a global so debug task can tell (via external ; in debasm) the version number of the kernal in it. It is also stored ; in $db$vw so debug task can tell (by reading the .TSK) the version of ; kernal in user task. ; $db$vnm == 9. ;*************************************************************************** .globl $DSW .list meb ; ; macro for executive directives ; ; calling sequence: ; ; exec directive ; .macro exec direc args .mcall direc direc args .endm break: ;breakpoint traps will come here $db$snd:: mov $DSW,sndpkt ;dsw gets clobbered by our send & receive, must save exec DIR$ <#snddpb> bcs error $db$rcv:: exec STOP$S ;save a word, dont bother checking for error on STOP - ;can only occur if code is overwritten, & would ;probably also cause error on receive (such as no data) ;start-up entry point (TKB's "ODT xfer addr") - task execution starts here: $db$xf::exec DIR$ <#rcvdpb> ;receive instruction packet from debug task bcc $db$pkt ;no error - execute it $db$ndb::jmp (r0) ;no debugger - start task without it ; (assume the error was no packet to receive) ;changed to nop by code in first debugger message, ; so we fall through to error handler ;on error, return dsw as status so debugger can tell user what the error was error: exec EXST$S <$DSW> ;note: EXST can only fail if our code is overwritten ;first receive is from any task ;(first debugger message fills in the task name for subsequent receives) $db$rdpb:: rcvdpb: exec RCVD$ <,rcvpkt> $db$sdpb:: snddpb: exec SDAT$ <,sndpkt> ;debugger fills in task name before first send $db$ptn:: ;receive packet includes task name rcvpkt: $db$vw::.word $db$vn,0 ;store kernal version number (see note above) ;overwritten by debug rad50 task name on each receive $db$pkt:: ;code packet for send & receive sndpkt: .word 0,0,0,0,0,0,0,0,0,0,0,0,0 ;13 words endpkt: ;initialized to ensure mismatch on version number check by ;debinit in a newer debugger applied to an old user .TSK ;trap vector for SVDB$ - must be static since RSX vectors through here ; at the time of the trap $db$tv:: .word 0 ;dont want odd address traps .word 0 ;dont want memory protect traps .word break ;where to go on BPT & single instruct traps $db$qio:: ;..MAIN is address of main procedure for debugger initialization ;(function word is set by debugger before each QIO) ;PL/I always assigns TI: to lun 1 ;I/O status block is last 2 words of send/receive packet ;parms set up for SF.GMC/SF.SMC, buffer is word before I/O status block ;.sgd0, .auto, .STOP, .ERROR are addresses debug task needs ;(these parm positions not used by terminal driver for SF.GMC, IO.ATT) exec QIO$ <..MAIN,1,,,endpkt-4,,> $db$mnp == $db$qio + Q.IOFN ;where ..MAIN pointer is $db$sgp == $db$qio + Q.IOPL+<2*2> ;where segment descriptors pointer is $db$ovp == $db$qio + Q.IOPL+<3*2> ;where overlay loader pointer is $db$stp == $db$qio + Q.IOPL+<4*2> ;where .STOP pointer is $db$erp == $db$qio + Q.IOPL+<5*2> ;where .ERROR pointer is .globl ..MAIN, .STOP, .ERROR .psect $$SGD0,rw,d,ovr .sgd0: ;address of root segment descriptor (first item in psect $$SGD1 - cant ;map to it directly since it's CON rather than OVR, so we use $$SGD0, ;which immediately precedes it and is zero length) .psect $$AUTO,ro,i .auto: ;address of overlay loader. cant provide addr of $ALBP2 directly ;via global because non-overlaid tasks would then get an undefined .end $db$xf ;where to go on task start-up