MVS TOOLS AND TRICKS OF THE TRADE May 1994 Sam Golob MVS Systems Programmer sbgolob@cbttape.org Sam Golob is a Senior Systems Programmer ASSEMBLING PROGRAM PATCHES - THE ASMTOZAP PROGRAM I'm appalled by the fact that we Systems Programmers don't get enough of a chance to strut our skills, nowadays. I admit that in today's world of "vendor products for everything", a lot of our work is done by installing software through "slapping it in", and in a sense, it's probably better. At least, the site has an out-of-house fall guy to blame a failure on. However, from our point of view, it's still disappointing that we don't get many of the customization opportunities we had in previous times. So, FWIW (for what it's worth), I'm going to present a technique in this issue which many people might say is outdated. However, I don't think so. I am a firm believer that in the systems programming business, any procedure you know will eventually find its place. There will be a certain need, or a certain emergency, in which you can save your installation "n times ten thousand dollars", just because you know something. This technique is no exception. Our subject deals with non-trivial patches to existing load modules. We may legitimately ask ourselves why such an action might be necessary in today's day and age. One answer is that we may want to add new function to a supported module that comes from an established vendor such as IBM. IBM may not want to support this extra function, but in reality, it is easy to add. When IBM changes its supported module, we would like to correspondingly change our extra piece of code, without having to laboriously fit a patch in machine language. We would rather want our shop to be able to make a quick change, and slip it in. The ASMTOZAP program from Howard Gilbert (of Yale University) usually allows us to do this. ASMTOZAP is an amazing piece of work. Even though there are other programs which claim to do the same thing, I advise you to accept no substitutes, and to use only Howard's program. ASMTOZAP allows us to write patch code in good old assembler language, using all the IBM macros. We start with assembler code, and end up with a zap input deck. Here's how it works. We code our patch instructions, to eventually be placed in the inside of a target module, in assembler language. However, ASMTOZAP control cards are coded in the assembler source as comments. These control cards tell the ASMTOZAP program how to construct its output deck. They tell ASMTOZAP where the VER cards of the zap code will start, where the VER will stop, where the REP cards will start and stop, and they can cause ASMTOZAP to punch any arbitrary output cards you want. ORG and EQU statements are used to control where in the load module the zap will fit. Here's what you do. You code your source deck and assemble it. Then you run the assembler SYSPRINT listing as input into the ASMTOZAP program. ASMTOZAP output is a superzap (AMASPZAP) input deck or an SMP/E usermod that will apply the patch. All this will become clear from looking at the figures. See Figures 1 and 2 for ASMTOZAP assembly source and the zap patch resulting from it. See Figures 3 and 4 for sample JCL that executes the process. Installing and Using the ASMTOZAP program. The ASMTOZAP program is written in PL/1. There is a load module on File 035 of the CBT MVS Utilities Tape (available from NaSPA) which can be used immediately, provided you have the Transient Library for the PL/1 Optimizing Compiler. PL/1 source code is on File 044 of the CBT Tape, and also on File 369. Howard Gilbert told me that his intent was to write for the Optimizing Compiler. However, with Howard's help, I have done some experimentation with the free PL1/F Compiler and Library on File 092 of the CBT Tape, using procedure PL1LFCL taken from File 091. With the removal of a few lines of code from the PL/1 source, it is possible to compile cleanly using free PL1/F, and the resulting load module works logically the same as the Optimizing load module, except for return codes. As of this writing, I am preparing the PL1/F version of the ASMTOZAP program for inclusion on the CBT Tape. It should get onto Version 367. For PL1/F, the code to remove is: The %PAGE statement, the environment material on the DCL OUT definition, and the calls to PLIRETC (return code processing). Using PL1/F compilation, ASMTOZAP is within reach of all MVS shops. Your installation does not have to buy any part of PL/1 from IBM. ASMTOZAP input is assembly SYSPRINT output resulting from the assembly of your mod. Figure 3 gives some JCL to run the assembly. Figure 4 shows sample JCL that can be used when actually running the ASMTOZAP program to produce the zap. Now, we're going to talk about the ASMTOZAP control cards. I'm going to paraphrase Howard Gilbert's own words from the remarks in his source code, because he himself documents the working of this code very clearly: The purpose of this utility is to convert an assembler listing dataset into a formatted IMASPZAP input deck or SMP PTF. It is useful in preparing, maintaining, and documenting those installation modifications which cannot be installed except by modifying IBM code. One can make free use of macros, literals, and other convenience features in preparing the deck. Control cards in special assembler comment form provide flexibility in modification design, and control over output. Control cards included in the assembler deck all begin with the characters *ZAP. The purpose of the control cards is to interrupt and resume generation of zap output. Statements which do not generate object code (comments, ORG, DS, EQU, etc.) are transferred to the output as zap comment cards, unless output generation is currently paused. Other statements (instructions, DC, CCW, etc.) are transferred to the output as VER or REP cards if output generation has been (re)started in either VER mode or REP mode. The cards governing this are: '*ZAP START VER', '*ZAP START REP', and '*ZAP PAUSE'. Zap generation is initally paused. A '*ZAP START' card is valid, and (re)starts generation in REP or VER mode, whichever was last active. When the zap is done, a '*ZAP END' card will terminate a scan of the listing and close the output file. This stops the generation of the zap, so that comments describing later support code (register equates, a description of the CVT DSECT, etc.) do not clutter up the zap statements which will be produced. The '*ZAP CARD' control card allows arbitrary text to be reproduced in the output. The characters up to the space after "CARD" are stripped off and the remainder of the card up to column 72 is reproduced in the output deck. This is primarily for NAME, DUMP, and SMP/E control cards. Figures 1 and 2 show how *ZAP CARD statements are used to produce "SMP-ready" usermod input, directly from the assembly source code. A handy feat indeed. To Conclude ... Set up ASMTOZAP on your system and play with it. Sample source decks for ASMTOZAP can be found on File 369 of the CBT tape, because Planning Research Corporation (the submittors of File 369) packaged many of their mods in ASMTOZAP format. You can assemble these and generate the zaps for practice, although they will probably not fit on your system (nor would you likely want them there). Once you are familiar with how ASMTOZAP works, the possibilities for finding occasion to use it will open up. It'll begin to dawn on you that ASMTOZAP can be a really helpful tool. Good luck and happy exploring. See you next time. * * * * * * * * * * * * * * * * * * * * * * * Figure 1. Illustration of ASMTOZAP assembler source code. Please excuse the age of this code. However, this source had easily been adapted for later versions of the underlying IBM code, by changing a few ORG's or EQU's usually. In the case of this particular zap, IBM made the underlying code OCO, and drastically modified some of the logic. But various versions of this zap have been operational at some sites for over fifteen years. *------- MVS/370 VERSION OF I/O COUNT ZAP. FROM FILE 369 OF CBT TAPE. *------- *------- TITLE LM02301...I/O COUNT IN MSG IEF285I *------- *ZAP CARD ++ USERMOD(LM02301) /* I.O COUNTS IN IEF285I */. *ZAP CARD ++ VER(Z038) FMID(EBB1102) PRE(JBB1326). *ZAP CARD ++ ZAP (IEFAB4B0). *ZAP CARD NAME IEFAB4B0 *ZAP CARD EXPAND IEFAB4B0(128) LM02301A CSECT IEFAB4B0 DS 0H PRINT ON,GEN,DATA ORG @PSTART USING *,@12 USING @DATD,@11 *ZAP START VER ORG CLRKEY STC @02,@OLDKEY ORG CLRTXT MVC MSGBUFFR+1(73),MSGBUFFR BLANK ENTIRE BUFFER ORG STEAL MVI MSGDISP+1,C' ' DISPLACED INSTRUCTION ORG @EL00001 IC @02,@OLDKEY ORG @SIZDATD DC AL1(230),AL3(@ENDATD-@DATD) ORG PATCH DC 4F'0' *ZAP START REP ORG CLRKEY STC @02,@NEWKEY ORG CLRTXT MVC MSGBUFFR+1(78),MSGBUFFR BLANK ENTIRE BUFFER ORG STEAL B PATCH * - - - - - - - - - LINES ELIMINATED FOR BREVITY - - - - - - - - - - * PATEXIT MVI MSGDISP+1,C' ' DISPLACED INSTRUCTION B MAINLINE * EDMSK1 DC X'60206B2020206B202120' *ZAP END @DATD DSECT ORG @DATD+X'48' @PC00001 DS 5F ORG @DATD+X'B4' MSGLNGTH DS F DS 2F MSGBUFFR DS C ORG @DATD+X'F7' MSGDISP DS X ORG @DATD+X'105' MSGCOUNT DS CL6 @OLDKEY DS AL1 @ENDATD EQU * ORG @DATD+X'120' @NEWKEY DS AL1 DS D ALIGN TO DUBBLEWORD FOR GETMAIN @NEWDATD EQU * SPACE LM02301A CSECT * ***** EQUATES FOR DSECTS I'M TOO LAZY TO DO THE DROPS * ***** 'N USINGS FOR. DSABTIOT EQU X'10' TIOPSTTB EQU X'12' JSCBTCBP EQU X'D0' ' JSCTMCOR EQU X'14C' ' TCBTCT EQU X'A4' TCTIOTBL EQU X'C' TCTDCBTD EQU X'8' TCTIOTSD EQU X'2' TCTDCTR EQU X'4' * * ***** EQUATES FOR LOCATIONS WITHIN IEFAB4B0 @PSTART EQU IEFAB4B0+X'1C' CLRKEY EQU IEFAB4B0+X'52' CLRTXT EQU IEFAB4B0+X'76' STEAL EQU IEFAB4B0+X'156' @EL00001 EQU IEFAB4B0+X'2EE' @SIZDATD EQU IEFAB4B0+X'3E8' PATCH EQU IEFAB4B0+X'45C' * ***** AND OF COURSE, THE REGISTERS @01 EQU 01 @02 EQU 02 @04 EQU 04 @05 EQU 05 @06 EQU 06 @10 EQU 10 @11 EQU 11 @12 EQU 12 @13 EQU 13 END * * * * * * * * * * * * * * * * * * * * * * * Figure 2. Illustration of the AMASPZAP input produced by the ASMTOZAP program from the source in Figure 1. Of course, this output was formatted as SMP/E ++ZAP input instead, by using the *ZAP CARD control cards. Notice the one-to-one correspondence between the assembler source lines and these output lines. Also please notice how the ZAP CARD, START VER, and START REP control cards determine the appearance of the output deck. ++ USERMOD(LM02301) /* I.O COUNTS IN IEF285I */. ++ VER(Z038) FMID(EBB1102) PRE(JBB1326). ++ ZAP (IEFAB4B0). NAME IEFAB4B0 EXPAND IEFAB4B0(128) * ORG CLRKEY VER 0052 4220,B10B STC @02,@OLDKEY * ORG CLRTXT VER 0076 D248,B0C1,B0C0 MVC MSGBUFFR+1(73),MSGBUFFR BLANK ENTIRE BUFFER * ORG STEAL VER 0156 9240,B0F8 MVI MSGDISP+1,C' ' DISPLACED INSTRUCTION * ORG @EL00001 VER 02EE 4320,B10B IC @02,@OLDKEY * ORG @SIZDATD VER 03E8 E600,010C DC AL1(230),AL3(@ENDATD-@DATD) * ORG PATCH VER 045C 0000,0000,0000,0000 DC 4F'0' VER 0464 0000,0000,0000,0000 * ORG CLRKEY REP 0052 4220,B120 STC @02,@NEWKEY * ORG CLRTXT REP 0076 D24D,B0C1,B0C0 MVC MSGBUFFR+1(78),MSGBUFFR BLANK ENTIRE BUFFER * ORG STEAL REP 0156 47F0,C440 B PATCH * - - - - - - - - - LINES ELIMINATED FOR BREVITY - - - - - - - - - - * * PATEXIT EQU * REP 04E2 9240,B0F8 MVI MSGDISP+1,C' ' DISPLACED INSTRUCTION REP 04E6 47F0,C13E B MAINLINE * * EDMSK1 EQU * REP 04EA 6020,6B20,2020,6B20 DC X'60206B2020206B202120' REP 04F2 2120 * DECK PRODUCED BY THE ASMTOZAP UTILITY 85/12/16 165820 * * * * * * * * * * * * * * * * * * * * * * * Figure 3. Illustration of Assembly JCL that produces a machine readable listing. This SYSPRINT listing is input to the ASMTOZAP step in Figure 4. //SBHCSCH JOB (A006,SYTM,99,99),S-GOLOB, // CLASS=Q,MSGCLASS=V,NOTIFY=&SYSUID /*DIST ROOM-25 //ASMHC PROC MAC='SYS1.MODGEN', // MAC1='SYS1.MACLIB', // MAC2='SYS1.AMODGEN', // MAC3='SYS1.ATSOMAC', // OUT='*', // REG=4M //* -------------------------------------------------- *// //* ASSEMBLER H PROC - ASSEMBLE (COMPILE) ONLY //* -------------------------------------------------- *// //ASM EXEC PGM=IEV90, //* PARM='OBJECT,NODECK', // REGION=® //SYSLIB DD DSN=&MAC,DISP=SHR // DD DSN=&MAC1,DISP=SHR // DD DSN=&MAC2,DISP=SHR // DD DSN=&MAC3,DISP=SHR //SYSPUNCH DD DUMMY //SYSUT1 DD DSN=&&SYSUT1, // UNIT=VIO, // SPACE=(CYL,(05,01)) //SYSPRINT DD SYSOUT=&OUT // PEND //* //S01ASM EXEC ASMHC //SYSIN DD DISP=SHR,DSN=SBHCSC.FILE369.PDS(LM01603) //SYSPRINT DD DISP=SHR,DSN=SBHCSC.ASMOUT(ZAPINO) <== FB,LRECL=121 * * * * * * * * * * * * * * * * * * * * * * * Figure 4. JCL to run ASMTOZAP. Input is a machine readable copy of the assembler listing of the ASMTOZAP source deck. Output is a generated zap. //SBHCSCZ JOB (A006,SYTM,99,99),S-GOLOB,REGION=8M, 00010000 // CLASS=S,MSGCLASS=V,NOTIFY=&SYSUID 00020000 /*DIST ROOM-25 00030000 //******************************************************************// 00040000 //* ASMTOZAP EXECUTION - FILE 044 OF CBT367 TAPE *// 00050000 //******************************************************************// 00090000 //* 00100000 //COPY1 EXEC PGM=ASMTOZAP //STEPLIB DD DISP=SHR,DSN=SBHCSC.A.LOAD //* DD DISP=SHR,DSN=SBHCSC.PPILIB <== PL1 LIBRARY IF NEEDED //SYSPRINT DD SYSOUT=* //PL1DUMP DD SYSOUT=* //IN DD DISP=SHR,DSN=SBHCSC.ASMOUT(ZAPINO) <== LRECL=121 //OUT DD DISP=SHR,DSN=SBHCSC.ZAPOUT(ZAPOUTF) <== LRECL=80 //* 00100000