.TITLE TSKIMG .IDENT "V1.1" .NLIST BEX,CND ; ; Author: D. Mischler 02-FEB-89 ; ; This module replaces DBG modules EXECUTE, INIT, SIM11 and ; TSKCOM. It causes DBG to operate on a task image file instead ; of an active task. The resulting utility manipulates task ; image files like ZAP (except overlays are not supported). ; This module must be assembled with the executive macro ; library (LB:[1,1]EXEMC.MLB) and the DBG prefix file. ; IMGLUN = TI+1 ; Task image file LUN. .MCALL DIR$,EXIT$S,GMCR$,GTSK$S,QIOW$,QIOW$S .MCALL CLOSE$,FDBDF$,FDOP$A,FDRC$A,NMBLK$,OPEN$ .MCALL CSI$,CSI$1,CSI$2,CSI$ND,CSI$SW .MCALL HDRDF$,LBLDF$ CSI$ HDRDF$ LBLDF$ .ASECT ; ; Mapping table format. ; .=0 M.IVBN: .BLKW 1 ; Image virtual block number. M.VBAS: .BLKW 1 ; Virtual base address. M.VMAX: .BLKW 1 ; Virtual maximum address. M.LEN: .PAGE .PSECT DATA,D,RW ; ; Address mapping tables and pointers. ; ASPTBL: .WORD ISMTBL,ISMTBL,0 ; Address space table. DSMTBL: .BLKW M.LEN+1 ; D space mapping tables. ISMTBL: .BLKW M.LEN+1 ; I space mapping tables. ; ; Data definitions. ; CURBLK: .WORD 0 ; VBN of buffered task image file block. GETMCR: GMCR$ ; Get MCR command line DPB. IMGBUF: .BLKW 256. ; Image file buffer. IMGCSI: .BLKB C.SIZE ; Image file CSI control block. IMGDFN: NMBLK$ ,TSK,0,SY,0 ; Default filename block for image file. IMGFDB: FDBDF$ ; Image file FDB. FDOP$A IMGLUN,IMGCSI+C.DSDS,IMGDFN,FO.MFY FDRC$A FD.RWM IMGRVB: QIOW$ IO.RVB,IMGLUN,IOEFN,,IMGSTS,, IMGSTS: .BLKW 2 ; Image file I/O status block. RDONLY: .WORD 0 ; Read-only access flag. SWITBL: CSI$SW RO,1,RDONLY ; Switch table entry for /RO switch. CSI$ND ERRBUF: .ASCIZ "177777" EXCERR: .ASCIZ "Not executable" FILERR: .ASCIZ "FCS error % on task image file" IMGERR: .ASCIZ "Task image file is bogus - exiting" INIMSG: .ASCII "Kludge-o-matic Task Zapper " VRSION: .ASCIZ "vrsion - tsknam" TSKPRM: .ASCII "Task image file? " TSKPRL = .-TSKPRM .EVEN .PAGE .PSECT CODE,I,RO ; ; Perform one-time initialization. ; On entry: R3 & R4 contain task version. ; On exit: Carry will always be clear. ; INIT:: MOV #VRSION,R0 ; Point to version number. MOV R3,R1 ; Get first version word. CALL $C5TA ; Make it ASCII. MOV R4,R1 ; Get second version word. CALL $C5TA ; Make it ASCII too. CALL U$RMTB ; Remove trailing blanks. MOV R0,-(SP) ; Save message pointer for later. GTSK$S #TRMBUF ; Get task parameters. MOV #LOGPRM,R0 ; Point to log file prompt. MOV TRMBUF,R1 ; Get hi word of task name. CALL $C5TA ; Convert it to ASCII. MOV #TRMPRM,R0 ; Point to terminal prompt. MOV TRMBUF,R1 ; Get hi word of task name. CALL $C5TA ; Convert it to ASCII. GETSKN: MOV #GETMCR,R0 ; Point to GMCR$ DPB. DIR$ R0 ; Get MCR command line, OK? BCC 10$ ; Yes, get target task name. MOV #<"D >,G.MCRB(R0) ; Set up a dummy command. MOV #TSKPRM,TRMOUT+Q.IOPL ; Stuff message address MOV #TSKPRL,TRMOUT+Q.IOPL+2 ; and length in DPB. DIR$ #TRMOUT ; Prompt for task name. SUB #4,SP ; Make room for an I/O status block. MOV SP,R5 ; Point to it. QIOW$S #IO.RLB,#TI,#IOEFN,,R5,,<#GETMCR+G.MCRB+2,#40.> MOV (SP)+,R0 ; Get completion status. ADD #2,(SP) ; Add extra characters to length. MOV (SP)+,$DSW ; Make it look like GMCR$ result. CMPB #IS.SUC,R0 ; Did any driver errors occur? BEQ 10$ ; No, parse result. CMPB #IE.EOF,R0 ; Did the user type ^Z? BNE GETSKN ; No, try again. EXIT$S ; Terminate. ; Parse command line for task image file name. 10$: MOV #GETMCR+G.MCRB,R0 ; Point to command line buffer. MOV $DSW,R1 ; Get command line length. ADD R0,R1 ; Point to end of buffer. CLRB (R1) ; Terminate buffer. CALL U$CLFX ; Fix up command line. CALL U$FNXT ; Point to task name, OK? BCS GETSKN ; No, try again. .PAGE ; ; Call CSI to parse file name. ; MOV R0,-(SP) ; Save filename string base address. 20$: TSTB (R0)+ ; Found end of string yet? BNE 20$ ; No, keep looking. DEC R0 ; Back up to terminator. SUB (SP),R0 ; Get filename string length. MOV R0,IMGCSI+C.CMLD ; Save length in CSI block. MOV #IMGCSI,R0 ; Point to CSI control block. MOV (SP)+,C.CMLD+2(R0) ; Save filename string address too. CSI$1 ; Perform syntax analysis, OK? BCS GETSKN ; No, complain. CSI$2 ,OUTPUT,#SWITBL ; Build data-set descriptor, OK? BCS GETSKN ; No, complain. MOVB #FO.MFY,IMGFDB+F.FACC ; Assume modify access. TST RDONLY ; Should file be read only? BEQ 30$ ; No, allow modify access to stand. MOVB #FO.RD,IMGFDB+F.FACC ; Set file access to read only. ; ; Attempt to open task image file. ; 30$: OPEN$ #IMGFDB ; Open the task image file, OK? BCC 40$ ; Yes, go on... MOV #ERRBUF,R0 ; Point to error code buffer. MOV IMGFDB+F.ERR,R1 ; Get error code. CLR R2 ; Suppress leading zeroes. CALL $CBOMG ; Convert code to octal. CLRB (R0) ; Terminate error code. MOV #ERRBUF,R0 ; Point to error code buffer. MOV #FILERR,R1 ; Point to file error message. CALL ERROR ; Display error. BR GETSKN ; Try again. ; ; The task image file looks OK. ; 40$: CALL IMGSET ; Set up image file handling, OK? BCS 110$ ; No, forget all about it. MOV (SP)+,R0 ; Pop initialization message pointer. MOVB #' ,(R0)+ ; Delimit version and file name. MOVB #'-,(R0)+ MOVB #' ,(R0)+ MOV IMGFDB+F.FNB+N.FNAM,R1 ; Get high word of task image name. CALL $C5TA ; Convert it to ASCII. MOV IMGFDB+F.FNB+N.FNAM+2,R1; Get next word of task image name. CALL $C5TA ; Convert it too. MOV IMGFDB+F.FNB+N.FNAM+4,R1; Get last word of task image name. CALL $C5TA ; Convert it. CLRB (R0) ; Terminate message. MOV #INIMSG,R1 ; Point to startup message. CALL LINOUT ; Display it. .PAGE ; ; Display task image virtual addresses. ; MOV #ISMTBL,R5 ; Point to I-space mapping table. MOV #TRMBUF,R0 ; Point to terminal buffer. MOVB #'I,(R0)+ ; Indicate this is I-space. CALL DSPADR ; Display I-space addresses. MOV #DSMTBL,R5 ; Point to D-space mapping table. TST (R5) ; Is D-space mapped over I-space? BEQ 50$ ; Yes, ignore it. MOV #TRMBUF,R0 ; Point to terminal buffer. MOVB #'D,(R0)+ ; Indicate this is D-space. CALL DSPADR ; Display D-space addresses. ; ; Modify DBGAID address violation SST vectors to catch illegal accesses. ; 50$: MOV $DBG$V,AIDOAV ; Save DBGAID odd address vector. MOV #OAVSST,$DBG$V ; Set up special vector. MOV $DBG$V+2,AIDMPV ; Save DBGAID memory protect vector. MOV #MPVSST,$DBG$V+2 ; Set up special vector. ; Initialize the free memory list. MOV #FREMEM,R0 ; Point to free memory list head. CLR (R0) ; Empty the free memory list. MOV 2(R0),R2 ; Get address of possible free memory. MOV R2,R1 ; Copy it. ADD #63.,R1 ; Adjust to next multiple of 64 bytes. BIC #63.,R1 MOV R1,2(R0) ; Save next free address. SUB R2,R1 ; Calculate size of free memory. CMP R1,#4 ; Is it usable? BLO 100$ ; No, throw it away. CALL $RLCB ; Put initial free memory on free list. 100$: CLC ; Indicate normal startup. RETURN ; ; Here if image file setup fails. ; 110$: MOV #IMGERR,R1 CALL ERROR JMP ABORT .PAGE ; ; Routine to initialize image file handling. ; On exit: Carry set if an error is detected. ; IMGSET: DIR$ #IMGRVB ; Read label block 0, OK? BCS 1$ ; No, can it. TSTB IMGSTS ; Success? BPL 2$ ; Yes, go ahead and look at it. 1$: JMP 120$ ; Exit with failure. 2$: MOV #IMGBUF,R0 ; Point to image file label block. MOV #ISMTBL,R2 ; Point to I-space mapping table. MOV L$BSA(R0),M.VBAS(R2) ; Save virtual base address. MOV L$BHGV(R0),M.VMAX(R2) ; Save I-space virtual maximum. MOV L$BHRB(R0),M.IVBN(R2) ; Set up I-space header VBN. INC M.IVBN(R2) CMPB L$BSYS(R0),#4 ; Does this task use M-PLUS features? BNE 100$ ; No, set up registers, etc. ; ; Here for a task which uses RSX-11M-PLUS features. ; MOV R0,R1 ; Copy label block pointer. ADD #340,R1 ; Skip over extra M-PLUS info. MOV L$BHRB(R1),M.IVBN(R2) ; Set up I-space header VBN. INC M.IVBN(R2) TST L$BHDB(R1) ; Does task have separate I/D space? BEQ 10$ ; No, skip over I/D space code. ; Set up data space mapping. MOV #DSMTBL,R3 ; Point to D-space mapping table. MOV R3,ASPTBL ; Enable I/D space separation. MOV L$BHDB(R1),M.IVBN(R3) ; Set up D-space header VBN. INC M.IVBN(R3) MOV M.VBAS(R2),M.VBAS(R3) ; Copy base virtual D-space address. MOV L$BDMV(R1),M.VMAX(R3) ; Set up maximum D-space address. ADD #M.LEN,R3 ; Point to D-space RO mapping section. ; Check for a multi-user task. 10$: ADD #M.LEN,R2 ; Point to I-space RO mapping section. MOV L$BROB(R1),M.IVBN(R2) ; Does task have a multi-user section? BEQ 20$ ; No, skip over multi-user code. ; Set up mapping for read-only task section. ADD #L$BLIB,R0 ; Point to library data. MOV R$LSA(R0),M.VBAS(R2) ; Set up RO section base address. MOV R$LHGV(R0),M.VMAX(R2) ; Set up RO section maximum address. TST L$BRDL(R1) ; Is there an RO data section? BEQ 20$ ; No, all done. ADD #28.,R0 ; Point to D-space RO description. TST (R0) ; Is name word empty? BNE 120$ ; No, something is wrong... MOV L$BROL(R1),R4 ; Get length of RO I-space. ASH #-3,R4 ; Get length in disk blocks. ADD M.IVBN(R2),R4 ; Get RO data section block number. MOV R4,M.IVBN(R3) ; Save block number. MOV R$LSA(R0),M.VBAS(R3) ; Set up RO D section base address. MOV R$LHGV(R0),M.VMAX(R3) ; Set up RO D section maximum address. 20$: .PAGE ; ; Read header block and set up register symbol addresses. ; 100$: MOV ASPTBL,R0 ; Point to D-space mapping table. MOV M.VBAS(R0),R5 ; Get task header address. CLR R0 ; Specify data access required. CALL T$MAP ; Point to start of task header, OK? BCS 120$ ; No, complain. MOV REGSYM,R2 ; Point to register symbols. MOV #<^rPS >,S.NAME(R2) ; PS is always lowest in a task. MOV R5,S.VALU(R2) ; Copy header base address. ADD #H.IPS,S.VALU(R2) ; Construct PS address. MOV (R2),R2 ; Point to next symbol. MOV #<^rPC >,S.NAME(R2) ; PC follows PS in task image. MOV R5,S.VALU(R2) ; Copy header base address. ADD #H.IPC,S.VALU(R2) ; Construct PC address. MOV (R2),R2 ; Point to next symbol. MOV #<^rSP >,S.NAME(R2) ; SP follows PC in task image. MOV R5,S.VALU(R2) ; Copy header base address. ADD #H.ISP,S.VALU(R2) ; Construct SP address. ADD H.HDLN(R1),R5 ; Get lowest address above header. SUB #16,R5 ; Get virtual address of R5. MOV #<^rR5 >,R4 ; Get register name in RAD50. MOV #6,R3 ; Get number of registers left. 110$: MOV (R2),R2 ; Point to next symbol. MOV R4,S.NAME(R2) ; Set up register name. MOV R5,S.VALU(R2) ; Set up value. SUB #<<^rR5 >-<^rR4 >>,R4 ; Set up next name. ADD #2,R5 ; Set up next address. SOB R3,110$ ; Do all registers. CLR (R2) ; Break off $DSW symbol. RETURN ; Here if problems are encountered. 120$: SEC RETURN ; ; Subroutine to display virtual addresses for an address space. ; DSPADR: MOVB #' ,(R0)+ ; Buffer a space. MOV M.VBAS(R5),R1 ; Get base virtual address. MOV OCTFMT,R2 ; Get format word. CALL $CBTA ; Convert value to octal. MOVB #'-,(R0)+ ; Buffer a hyphen. MOV M.VMAX(R5),R1 ; Get maximum virtual address. MOV OCTFMT,R2 ; Get format word. CALL $CBTA ; Convert value to octal. ADD #M.LEN,R5 ; Point to next section. TST (R5) ; End of address space? BNE DSPADR ; No, buffer next address range. CLRB (R0) ; Terminate buffer. MOV #TRMBUF,R1 ; Point to output buffer. CALLR LINOUT ; Dump line and return. .PAGE ; ; Subroutine to map a specified address in the target task. ; On entry: R0 contains desired address space. ; R5 contains desired target address. ; On exit: R1 contains debugger virtual address, carry set if error. ; R0 is destroyed by this routine. ; T$MAP:: MOV ASPTBL(R0),R0 ; Point to appropriate mapping info. 10$: CMP R5,M.VBAS(R0) ; Is virtual address too low? BLO 20$ ; Yes, try next address range. CMP R5,M.VMAX(R0) ; Is virtual address too high? BLOS 30$ ; No, map specified address. 20$: ADD #M.LEN,R0 ; Point to next address range. TST M.IVBN(R0) ; End of address range list? BNE 10$ ; No, see if it will map address. BR 60$ ; Exit with failure. ; Address is known to be mappable. 30$: MOV M.IVBN(R0),-(SP) ; Push appropriate header VBN. MOV R5,R1 ; Copy virtual address. SUB M.VBAS(R0),R1 ; Get block offset. CLR R0 ; Zero extend it. DIV #512.,R0 ; Get block number and offset. ADD (SP)+,R0 ; Correct virtual block number. CMP CURBLK,R0 ; Is correct block already in memory? BEQ 50$ ; Yes, just point to it. TST RDONLY ; Is file opened for reading only? BNE 40$ ; Yes, forget about writing. TST CURBLK ; Has a virtual block been loaded? BEQ 40$ ; No, no write is needed. MOV IMGRVB+Q.IOFN,-(SP) ; Preserve original I/O function. MOV #IO.WVB,IMGRVB+Q.IOFN ; Make DPB perform virtual write. DIR$ #IMGRVB ; Issue IO.WVB request. MOV (SP)+,IMGRVB+Q.IOFN ; Recover I/O function code. 40$: MOV R0,IMGRVB+Q.IOPL+10 ; Stuff VBN in QIO DPB. DIR$ #IMGRVB ; Issue IO.RVB, OK? BCS 60$ ; No, complain. TSTB IMGSTS ; Success? BMI 60$ ; No, complain. MOV R0,CURBLK ; Remember what block is in memory. 50$: ADD #IMGBUF,R1 ; Point to specified address. CLC ; Indicate success. RETURN ; Here if T$MAP fails. 60$: SEC RETURN .PAGE ; ; Routines that don't do anything to a file. ; GO:: SIMABO:: STEP:: X$STRT:: MOV #EXCERR,R1 ; Point to error message. CALLR ERROR ; DIsplay it and leave. ; ; Close the (possibly modified) task image file. ; T$EXIT:: TST RDONLY ; Is file opened for reading only? BNE 10$ ; Yes, forget about writing. TST CURBLK ; Is a virtual block buffered? BEQ 10$ ; No, just leave. MOV #IO.WVB,IMGRVB+Q.IOFN ; Set up for final write. DIR$ #IMGRVB ; Do it. 10$: CLOSE$ #IMGFDB ; Close up the file. RETURN .END