MVS TOOLS AND TRICKS OF THE TRADE May 1989 Sam Golob MVS Systems Programmer DELINK AND RELINK OF LOAD MODULES This monthly column is for sharing practical advice and techniques which can be employed in your shop. Our current article lends itself to the rare attribute of having a title. It is called "DELINK AND RELINK". We shall discuss some aspects of the fine art of manipulating load modules and their CSECTs. The two software tools needed for the discussion can be found on the Connecticut Bank and Trust Company MVS Tape that is obtainable online, at www.cbttape.org. The required tools are the DELINK0 program, on File 316 of the "CBT" tape, and the "PDS" program, on File 182 of that tape, with needed utilities on Files 296 and 112. The PDS program is an enormously useful multipurpose utility workbench. We will basically consider only one feature of it here. A full course on the uses of PDS was printed in "Technical Support" in a series of three articles from the JANUARY thru MARCH issues in 1988. That course material is also distributed in the PDS install library on the CBT tape, file 182, so it is not hard to get. Let us begin our discussion with the DELINK0 program, an old IBM field service utility in the public domain. DELINK0 is a program that converts a LOAD MODULE CSECT into an OBJECT DECK, doing the OPPOSITE OF THE LINKAGE EDITOR. DELINK0 was originally available only in object code from IBM, but accurate disassembled assembly language source is found on the CBT tape file 316, courtesy of the efforts of Bill Godfrey of Plannning Research Corporation in Maryland. With credits now given, we ask: what useful purpose can object code have, that is better than load module format for executable code? I have found several wonderful purposes for having object code. They are: A. Isolating and re-installing "nucleus-type SVC programs" from a copy of your nucleus. Source for these currently running SVCs may be long gone to the trash can, and the only way of keeping these SVCs around, is on copies of your nucleus. If you're doing a CBIPO, reinstalling these SVC's may be a problem. Also, having such critical programs buried inside a big old nucleus doesn't give you too comfortable a feeling about the stability of your shop. B. Backing out PTF maintenance that was ACCEPTed already with SMP. RESTOREing the PTF is not possible. But creating an APAR or USERMOD having good, but BACK-LEVEL object code to APPLY in place of the ACCEPTED code, may be just what is needed to keep your shop going, while keeping SMP happy. C. Just plain old packaging. Object code fits neatly on a source code PDS, while load modules have a "funny format". Good old LRECL 80 may just suit your purposes better. We shall talk about these nice roles for object code, and how the DELINK0 program does the job of generating the object deck(s) you need. Somewhere down the line, these techniques could save your shop and your neck. Obtaining a back-level CSECT (Case B above) is easier than isolating an SVC from the nucleus (Case A), so we'll talk about Case B first, while giving a true-to-life example. Recently, I installed PSF release 1.2.1 (fmid HAF1220) software, to drive our 3800 model 3 printers. Ultimately, I RECEIVEd, APPLYed, and ACCEPTed the base function, the cum tape PTFs, and all the HIPER PTFs mentioned in the PSP bucket at install time. Good sound procedure? It seemed OK. IBM said all the PTFs were clean. Well, not quite. It turned out that one of the PTFs was PE (in error) and it caused a critical problem with our print jobs. Since the module that had the error had been ACCEPTed, I couldn't RESTORE its PTF off my system using SMP. I was undaunted. Even though IBM hadn't come up with a fix as yet, I asked LEVEL 2 for the highest HEALTHY level of the offending module. I figured that if ITS object code could be found inside of a PTF, I could make my own USERMOD, TO LOOK LIKE A PTF and APPLY that code to replace the bad module on my system. IBM came back with the answer that the BASE LEVEL OF THE MODULE was the highest (reasonably) healthy level. NOW I had a problem. The BASE LEVEL CODE is found only in LOAD MODULE FORMAT on the RELFILEs that came with the original shipment of the product. Luckily, they were still on my disk pack (although I could easily load them up from the RELFILE tape if they had been gone from disk by now. (You SMP-knowledgeable people, please note that I was averse to making a separate TXLIB just to linkedit this piece of code from LOAD MODULE format.) So what are we leading up to? USE DELINK0 to CONVERT THE LOAD MODULE on the RELFILE to OBJECT FORMAT. Dump the resulting OBJECT DECK into a USERMOD. Give the USERMOD a SYSMOD ID equal to the APAR number of the problem, and PRE the PTF that was in error. APPLY the USERMOD, which fixes the system problem. When IBM comes up with the PTF to replace this module's code, THAT PTF should SUP our USERMOD's APAR id number, and we'll be in the clear. HO HO. We've backed out an ACCEPTed sysmod (which IBM says you can't do). See Example 1 for concreteness. Needless to say, in our case, the technique worked out fine, and the printer purred along without coughing any more, happily ever after (up to this writing). Story number two. This is a tale of "saving the SVC code for re-install in a new NUCLEUS". I might think that we should use DELINK0 as in the previous case. The problem is that DELINK0 doesn't have the capacity to take input from a load module as large (or anywhere nearly as large) as the nucleus module, IEANUC01, which is huge. (A copy of) IEANUC01 must be cut down to size (very much) before DELINK0 will handle it. What do we do? We re-linkedit the COPY of IEANUC01 with many REPLACE linkedit control cards, to dummy out the unwanted CSECTs of the NUCLEUS, which means most of them. This will take a lot of REPLACE cards, and several linkedit runs, because the linkage editor cannot handle so many REPLACE cards at one time. Eventually, we are left with a piece of IEANUC01 that is a shadow of its former self, and which contains, basically only SVCs or any other CSECTs we would like to isolate. THEN we use DELINK0, and lo and behold, it works. (It really should...) NOW we have made object decks for each SVC, and we can construct USERMODs to re-install each one (Example 2). The IPO and CBIPO literature have helpful material in their DOCLIB to show how to install a user SVC in the nucleus. After all the user SVCs in the nucleus have been re-installed with SMP, the resulting NEW NUCLEUS is IPLed, and it should work as before. At least in my case it did. Just save the old nucleus in SYS1.NUCLEUS as an alternate; perhaps call it IEANUC02. It could then be IPLed as alternate nucleus 2 in case of a problem. So much for DELINK. I promised you RELINK, and I'm obligated to deliver. RELINK depends on a feature of the public-domain "PDS" product, which I urge everyone to acquire. PDS is assembled from SOURCE. Just send Arnold Casinghino thirty dollars and a cartridge or 2400 foot reel, and you'll get the entire CBT tape. PDS is on file 182, and necessary utilities are on files 296 and 112. Our concentration will be on the MAP subcommand of PDS. MAP operates on LOAD MODULES ONLY. The MAP subcommand WITHOUT OPERANDS, will produce an AMBLIST-type CSECT MAP of a load module or GROUP OF LOAD MODULES. This is very helpful in doing a DELINK of the module by showing us the names of the component CSECTs to delink. For the RELINK function, the amazing, unique MAP with RELINK operand is required. A picture of an execution of PDS will illustrate this best (see Example 4). MAP with RELINK instantly GENERATES COMPLETE, ACCURATE EXECUTABLE RELINKEIT JCL FOR ANY LOAD MODULE, or GROUP OF LOAD MODULES IN A LOAD LIBRARY, INCLUDING ALL ALIAS NAMES AND LOAD MODULE ATTRIBUTES. I have used MAP with RELINK in several amazing ways: A. To reblock entire load libraries in a short time, using the Linkage Editor itself. B. To relinkedit a load module from the separate CSECT object modules created by DELINK0. C. To upgrade the linkage editing of old products. For example, I re-linkedited the 779 modules of the old PL1 F compiler and library with the DFP linkage editor, in less than an hour, on my first try. Let's do another real-life example to illustrate Case A. A software vendor sent its load library to me blocked 6144, which I found inconvenient, because the short blocks made it difficult to apply many (necessary) zaps using "Full Screen Zap" (CBT tape file 300). I wanted nice large blocks of 18432 bytes. First I tried the "easy" way of reblocking, with the DFP IEBCOPY's "COPYMOD" feature, using a MAXBLK of 18432. A "VERIFY" run under the PDS program, which gives a statistical breakdown of actual load module blocksizes, showed the maximum block length in the resulting new library as being less than 6900. Apparently, COPYMOD didn't really do the job. The MAP subcommand of the PDS program solved the problem excellently. I ran the following sequence of PDS commands: 1. VERIFY : (colon means "all members". This command makes sure there are no apparent aliases or orphaned members. It also produces the report on block sizes.) 2. IF : NOALIAS THEN(SUBLIST) (This picks the "current subgroup of members" to be ONLY those load modules that are not ALIASES.) 3. MAP * RELINK (asterisk means "the current subgroup of members". At this point it has only main members. This command generates re-linkedit JCL for the entire library. The ALIAS members will be re-generated because all of the proper ALIAS linkedit statements are included in the JCL. I ran this sequence of commands in PDS's "ISPMODE" so the output was written to the "ISPMODE LOG" that PDS has. The log can be written out to a dataset with one ISPF prompt (Option 7), and the dataset, when it is edited to remove the re-statement of the PDS subcommands, is EXECUTABLE JCL. Just adding a JOB card is enough to run it. It might also be necessary to change the name of the load library pointed to by the SYSLMOD DD statements. After I did this, the PDS VERIFY command showed a maximum blocksize of 18432, and an average blocksize of very close to that. (Note that if you don't have ISPF but if you have the TSO Session Manager, the results of the commands will be in the OUTPUT STREAM and will be accessible from there using SMCOPY to print to a dataset. "PDS" uses the TSO PUTLINE interface, so it can be run under "TSO IN BATCH", with the output sent directly to a dataset.) Case B. This one is easy. If you have a load module that has several CSECTS, use "MAP modulname RELINK" with "PDS" pointing to the original load library. This will generate the relinkedit JCL. Save the resulting JCL on a dataset (as above). Then DELINK each CSECT using the DELINK0 program. Put the resulting OBJECT DECKS in a PDS using member names equal to each CSECT's name. Then run the relinkedit JCL, pointing the SYSLIB DD statement to that object library. Whew... It didn't take long to knock that one off. See Example 3 for an illustration. Case C. IBM used to give out its software for free (in the old MVT days). The PL1 F Compiler and Library is now a public-domain product which can be found on older CBT tapes and on the SPLA MVS tape (Share Program Library Agency, TUCC, Research Triangle Park, NC 27709, or from DAN SQUILLACE of the SAS Institute, Cary, NC). The load modules were all linkedited "downward compatible" or "DC", which places a restriction on their block sizes. I wanted to do two things: First, to add a unique SSI (System Status Indicator) to all of these load modules, for identification. Second, to remove the "DC" attribute so the relinkedited modules could have a larger block size. To do these two things, I used the "PDS" program and entered the following commands: 1. ATTRIB : NODC (this removed the "DC" attribute from all 779 load modules. The computer cranked for about a minute.) 2. ATTRIB : SSI(CB272454) (give an SSI of CB272454 to all 779 load modules. This tells me that they came from the CBT tape version 272, file 454. The computer cranked for a bit over two minutes.) Then I did the three steps above and relinkedited all the modules. Including the editing of the job stream and computer execution time, the whole thing took less than an hour, start to finish. This is pretty heady stuff, and it shows some of the enormous power of the "PDS" product, as well as of DELINK0. It's time for me to sign off now, and leave it to you clever people to get creative. Good luck. * * * * * * * * * * * * * * * * * * * EXAMPLE 1. BACKING OFF AN "ACCEPTED" PTF. ++APAR (AY19870) /* 5665-27501-HAF1220- //AY19870 JOB 5665-31933-0,27501,MSGLEVEL=(1,1),CLASS=A */ . ++ VER (Z038) FMID(HAF1220) PRE (UY31933) /* PROBLEM DESCRIPTION(S): OY19870 - **************************************************************** * USERS AFFECTED: NEWSWEEK, INCORPORATED. Mtn. Lakes, N.J. * **************************************************************** * PROBLEM DESCRIPTION: This is a backoff of UY31933 back to * * HAF1220 base level of mod APSQDEQ. * **************************************************************** COMMENTS: NEWSWEEK FIX AS PER SUPPORT CENTER - PROBLEM #2X903 - 01/13/89. */. ++ MOD (APSQDEQ ) DISTLIB(AAPSMOD0) LEPARM (LET,LIST,NCAL,RENT,XREF) . (Object deck goes here) IDENTIFY APSQDEQ('HAF1220 AY19870') SETSSI FAA19870 * * * * * * * * * * * * * * * * * * * EXAMPLE 2. REINSTALLING AN SVC WITH SMP. ++ USERMOD (NSVC243) . ++ VER(Z038) FMID(NWUSER1) /* DOCUMENTATION. THIS USERMOD PUTS SVC 243, WHICH IS USED BY JES2 EXIT1, INTO THE NUCLEUS. THIS SVC ENABLES THE CLOSE OF THE VIRTUAL PRINTER. THIS IS A REINSTALL OF AN SVC THAT IS ALREADY ON THE SYSTEM. INSTALLED: S.GOLOB 11/26/85 84.330 NEWSWEEK, INC. */ . ++MOD(IGC243) DISTLIB(NWDLIB01) LMOD(IEANUC01) . (Object deck goes here.) SETSSI E2D70132 IDENTIFY IGC243('NSVC243 11/26/85') * * * * * * * * * * * * * * * * * * * EXAMPLE 3. DELINK OF A LOAD MODULE AND ITS RE-LINKEDIT. //TST2PP2T JOB (TS,2322),'TECH.SUPPORT',CLASS=M,NOTIFY=TSTBSSG, // MSGLEVEL=(1,1),MSGCLASS=T TYPRUN=HOLD //* //DELINK EXEC PGM=DELINK,REGION=2000K //STEPLIB DD DISP=SHR,DSN=TST.TSO.CMDLIB //SYSPRINT DD SYSOUT=* //SYSLIB DD DISP=SHR,DSN=TSTBSSG.LOAD //SYSPUNCH DD DISP=SHR,DSN=TSTBSSG.A.OBJ(EXTRACT) //SYSIN DD * EXTRACT EXTRACT //* //DELINK EXEC PGM=DELINK,REGION=2000K //STEPLIB DD DISP=SHR,DSN=TST.TSO.CMDLIB //SYSPRINT DD SYSOUT=* //SYSLIB DD DISP=SHR,DSN=TSTBSSG.LOAD //SYSPUNCH DD DISP=SHR,DSN=TSTBSSG.A.OBJ(RCON) //SYSIN DD * EXTRACT RCON //* //DELINK EXEC PGM=DELINK,REGION=2000K //STEPLIB DD DISP=SHR,DSN=TST.TSO.CMDLIB //SYSPRINT DD SYSOUT=* //SYSLIB DD DISP=SHR,DSN=TSTBSSG.LOAD //SYSPUNCH DD DISP=SHR,DSN=TSTBSSG.A.OBJ(CONVRT) //SYSIN DD * EXTRACT CONVRT //* //DELINK EXEC PGM=DELINK,REGION=2000K //STEPLIB DD DISP=SHR,DSN=TST.TSO.CMDLIB //SYSPRINT DD SYSOUT=* //SYSLIB DD DISP=SHR,DSN=TSTBSSG.LOAD //SYSPUNCH DD DISP=SHR,DSN=TSTBSSG.A.OBJ(SYNTAX) //SYSIN DD * EXTRACT SYNTAX //* //LKED EXEC PGM=IEWL, // PARM='NCAL,MAP,LIST,LET' //SYSUT1 DD UNIT=SYSDA,SPACE=(1024,(200,20)) //SYSPRINT DD SYSOUT=* //SYSLIB DD DISP=SHR,DSN=TSTBSSG.A.OBJ //SYSLMOD DD DISP=SHR,DSN=TSTBSSG.LOAD //SYSLIN DD * INCLUDE SYSLIB(EXTRACT) INCLUDE SYSLIB(RCON) INCLUDE SYSLIB(CONVRT) INCLUDE SYSLIB(SYNTAX) ORDER EXTRACT,RCON,CONVRT,SYNTAX SETSSI ABB88308 ENTRY EXTRACT NAME EXTRACTZ(R) * * * * * * * * * * * * * * * * * * * EXAMPLE 4. ILLUSTRATION OF "PDS" MAP WITH RELINK. *** LOG TABLE OUTPUT *** 12.17.18 PM FRIDAY FEB 3, 1989 - DSN=TSTBSSG.LOAD,VOL=SER=TSO001 MEM=UPPER >map upper relink ** MAP UPPER //LKED EXEC PGM=IEWL, // PARM='NCAL,MAP,LIST,LET' //SYSUT1 DD UNIT=SYSDA,SPACE=(1024,(200,20)) //SYSPRINT DD SYSOUT=* //SYSLIB DD DISP=SHR,DSN=TSTBSSG.LOAD //SYSLMOD DD DISP=SHR,DSN=TSTBSSG.LOAD //SYSLIN DD * INCLUDE SYSLIB(UPPER) ORDER UPPER ENTRY UPPER NAME UPPER(R)