Now that we know how to intercept SVC calls we can try something more interesting. When a program is assembled the various macro contained in the source code have to be read from the macro library. As the assembler reads these macros they are located using SVC 18 (FIND/BLDL). By intercepting SVC 18 we can list the macros as they are being accessed by the assembler.
First we need to look at the input registers to SVC 18. Register zero points to a parameter list and register one contains a DCB address or zero. If the request is for BLDL then the contents register one will be positive. If the request is for find then contents of register one will be negative. For this excercise we only care about FIND and not BLDL so we can ignore the parameter list for BLDL. For a FIND request register zero points to an eight-byte member name.
Now all we have to do is intercept calls to SVC 18 and print out the member name each time we encounter a FIND request. In order for the assembler to work we will have to reissue the SVC call so the real SVC 18 can locate the member in the PDS.
MVI 18(R2),X'00' INTERCEPT SVC 18 BLDL/FIND
First we include SVC 18 in our list of intercepted SVC calls in the screen table. By setting the corresponding byte in the screen table to X’00’ instead of X’80’ we will cause SVC 18 to be intercepted.
CLI 0(R9),18 BLDL/FIND BE SVC18
In our SVC processing routine we need to check for SVC number 18 as the interrupt code in the RB.
SVC18 DS 0H LR R8,R0 SAVE R0 LR R9,R1 SAVE R1 LR R10,R15 SAVE R15
To process our SVC 18 interrupt we first save the parameter registers passed to the SVC routine.
LTR R1,R1 BP SKIP18 BRANCH IF BLDL
Now we check to see if the request is for BLDL or for FIND. For now we will ignore BLDL requests.
ST R0,FWORD SAVE R0 CONTENTS UNPK WORK(9),FWORD(5) UNPACK TR WORK(8),HEXTAB-C'0' MVC WTO18+18(8),WORK * ST R1,FWORD UNPK WORK(9),FWORD(5) TR WORK(8),HEXTAB-C'0' MVC WTO18+30(8),WORK * MVC WTO18+39(8),0(R8) COPY FIND MEMBER NAME * * 8.10...15...20...25...30...35...40...45...50 WTO18 WTO 'SVC 18 R0=******** R1=******** ********', ROUTCDE=(1,11)
If it is a FIND request we make the contents of registers zero and one printable. We do this by first storing the contents of the register into a full word. Next we unpack the full word and finally we have to translate it to make it printable. The result is copied into the message area of a WTO along with the member name which is pointed to by register zero (which was copied into register 8 for save keeping). One think to note here is that we are not writing reentrant code. This is not the way a SVC routine should be written but for now we can get away with it.
SKIP18 DS 0H LR R0,R8 LR R1,R9 LR R15,R10 NI TCBFLGS7,255-(TCBSVCS) TURN OFF SVC SCREENING SVC 18 OI TCBFLGS7,TCBSVCS TURN ON SVC SCREENING LR R14,R11 RESTORE RETURN ADDRESS BR R14 RETURN TO CALLER
Finally we reissue the SVC call. First we restore the parameter registers. In order to allow the SVC call to actually go through instead of being intercepted again, and causing an endless loop, we have to temporarly disable screening by clearing the TCBSVCS bit. Once we issue the SVC we can once again set the bit to resume screening. All that remins is to do is to restore the return address and return to the caller.
MODESET MODE=PROB GIVE UP SUPERVISOR STATE
In our previous test of SVC screening we reset the APF Authorization bit in the JSCB using my User SVC 245 after getting into supervisor state using MODESET. Before transfering control to the assembler we need to issue MODESET to restore us to problem state.
LR R1,R9 RESTORE PARM REG LINK EP=IFOX00 TRANSFER CONTROL TO ASSEMBLER
Before calling the assember we need to restore the parameter register contents which was saved off in register nine.
JOB 6911 $HASP373 RUNSVX STARTED - INIT 12 - CLASS A - SYS TCS3 JOB 6911 6.02.51 0.00.00 0.00.00 0000 RUNSVX COMPRESS JOB 6911 SVC 18 R0=00096C68 R1=FFF69718 IHARB JOB 6911 SVC 18 R0=00096C68 R1=FFF69718 IKJRB JOB 6911 SVC 18 R0=00096C68 R1=FFF69718 IEZXRB JOB 6911 SVC 18 R0=00096C68 R1=FFF69718 IEZBITS JOB 6911 SVC 18 R0=00096C68 R1=FFF69718 IKJTCB JOB 6911 SVC 18 R0=00096C68 R1=FFF69718 TESTAUTH JOB 6911 SVC 18 R0=00096C68 R1=FFF69718 IHBERMAC JOB 6911 SVC 18 R0=00096C68 R1=FFF69718 WTO JOB 6911 SVC 18 R0=00096C68 R1=FFF69718 IHBINNRA JOB 6911 SVC 18 R0=00096C68 R1=FFF69718 DETACH JOB 6911 SVC 18 R0=00096C68 R1=FFF69718 WAIT JOB 6911 SVC 18 R0=00096C68 R1=FFF69718 ATTACH JOB 6911 SVC 18 R0=00096C68 R1=FFF69718 IHBOPLST JOB 6911 SVC 18 R0=00096C68 R1=FFF69718 GETMAIN JOB 6911 SVC 18 R0=00096C68 R1=FFF69718 MODESET JOB 6911 SVC 18 R0=00096C68 R1=FFF69718 SAVE JOB 6911 6.02.51 0.00.00 0.00.00 0000 RUNSVX ASM JOB 6911 6.02.51 0.00.00 0.00.00 0000 RUNSVX ######## JOB 6911 $HASP395 RUNSVX ENDED
After assembling and link editing I modified my assembler JCL and replaced the assembler program name (EXEC PGM=IFOX00) with my SVC screening program (EXEC PGM=SVCX) and added a STEPLIB. Here are the results of running it. We get a list of all the macros, including the inner macros, that were used in the assembly.