MVS TOOLS AND TRICKS OF THE TRADE Exploiting Partitioned Data Set Directory Fields: Part I By Sam Golob Sam Golob is a senior systems programmer in New Jersey. This monthly column is for discussing tips and techniques for the MVS community. Suggestions for future discussions are invited. Please send them to me in care of Technical Support magazine. This month, I'd like to talk about utilizing information contained in partitioned data set directory entries. The fields and bits in the directory, especially in the directory entries of a load module library, contain crucial information that is used by the MVS operating system. Knowing about these fields can help you in some startling ways. It may not have occurred to you to look in such a place for help in problem situations. That's why I thought it appropriate to mention the subject here rather than in a separate tutorial article. We try to point out some cases where information from directory entry fields will make a great impact on our work. As is well known, source-type partitioned data sets have very different directory entries than load libraries have, which contain executable load modules as their members. We therefore discuss these different types of partitioned data sets separately, concentrating in areas where the most gain by manipulation is to be had. We discuss source-type PDS members that have ISPF statistics in their directory entries as opposed to membersthat don't have stats. This subject is continued next month. Fundamentals: The Structure of Partitioned Data Set Directories The partitioned data set directory is located at the beginning of the first disk extent for a partitioned data set. Although the DCB attributes of the DATA in a partitioned data set will vary, the external physical structure of the DIRECTORY does not vary. The directory of a PDS consists of directory blocks and directory entries. The directory blocks of a PDS may be conceptualized as the physical part of the PDS directory. Considered as raw data, each directory block is of fixed length, and is 255 bytes long with a 9-byte key -- 264 bytes in all. The size of a directory block is fixed by the architecture of partitioned data sets and is not subject to user software control for all practical purposes. Each directory block contains a number of directory entries of variable length. The directory entries, in contrast to the directory blocks, may be pictured conceptually as the logical part of the directory data. We say logical because the contents of the directory entries are variable and are subject to much more software control. Our discussion is concerned with directory entries, which contain information that is useful for our needs as programmers. There is exactly one directory entry for each member of a PDS. Each directory entry defines an area of data in the physical PDS data extents as belonging to one member. A pointer field in the PDS directory entry points to the start of each member, while an EOF marker in the data itself defines the end of that member. Some fields of each directory entry are required by PDS design. These fields constitute the first 12 bytes of any directory entry. An example of a required field is the TTR pointer in the directory entry that points to the start of that member's data. The TTR is the relative track and record number for a data record, starting from the beginning of the data set. Another required field is the 8-byte member name in the directory entry. Every PDS directory has to contain a member name and a TTR pointer to the beginning of that member's data. The last required field in a directory entry is a flag byte. Descriptions of the required flag byte will be found in the figures. The required fields may, or may not, be followed by user-defined directory entry fields of variable length to a maximum of 62 bytes. User fields, while not required by general PDS structure, are created by an MVS component that uses the PDS structure as a base for its own requirements. The most notable example of MVS component use of user fields is the load library whose data consists of executable programs or load modules. PDS directory entries for load library members contain far more required user fields than do most other PDS directory entries. The MVS component called program fetch utilizes those extra load library directory entry fields to affect program execution of the load module. In this article, we learn how to take advantage of the accessibility of these directory entry fields. We may be able to fix load modules, for example, without having to relinkedit them. Merely flipping one or more directory entry bits could accomplish the fix that we need. Quick Examples Let's whet your appetite by showing a few examples. Load module linkedit attributes are all reflected in the directory entry user fields.If you were linkediting a module, and you forgot to mention RENT in the linkedit parms, you need only go to the re-entrancy and reusability bits of the module's directory entry and turn those bits on. That will have the same effect as if the linkage editor turned them on when it was creating the member. Similarly, if a module had to be authorized and you forgot to say SETCODE AC(1) in the linkage editor control statements, you need only go to the directory entry of the module and turn the proper auth bit on. In all of these cases, you do not have to relinkedit the module. Similar considerations apply if those attributes needed to be turned off. Knowing these facts can save you a lot of work. Learning About Directory Entry Fields The macro IHAPDS (in SYS1.AMODGEN) describes many (but not all) types of PDS directory entry fields. You can find a description of many directory entry fields in the IBM manual SPL Debugging Handbook under entries PDS and PDS2. In MVS/ESA, the equivalent manuals are MVS/ESA Diagnosis: Data Areas. Because in many cases directory entry fields are user-defined or application-defined, a single IBM descriptive macro cannot cover all the ground. In particular, ISPF directory entry field descriptions are not too readily available (see Figure 3). I am providing some descriptions of directory entry fields. See Figures 1 through 3. These descriptions were taken from the source member of the PDS product Version 8.4, on the CBT MVS Utilities Tape, File 182. It is hoped that these descriptions will be sufficient to help the reader learn this material. Let's begin by learning about the required directory entry fields. These comprise 12 bytes. In other words, a single directory entry has to be at least 12 bytes long. The first eight bytes of a directory entry consist of the member name, left justified. It is necessary that all directory entries be sorted ascendingly in member name order. Therefore, some directory entries need to be rearranged each time a new member is added. This is an overhead-consuming process. The next 3-byte field is a relative TTR pointer to the beginning of that member's data. Finally, there is a 1-byte field officially consisting of binary flags. This flag byte is crucial to the rest of the directory entry so we need to study this byte in more detail. Look at Figure 2. The high-order bit, X'10000000' of the flag byte, is turned on to mark the member as an alias member. Strictly speaking, although the purpose of an alias member is to provide an alternate name for a main member, any PDS member can theoretically be flagged as an alias if this bit is on. For load modules, the alias bit on will be accompanied by a user field (the real member name field) containing the name of a main member, filled in by the linkage editor at the time of alias creation. The next two bits, X'01100000', are relevant to load module directory entries. All load modules contain one extra TTR location, which is the TTR of the first TEXT record, needed by MVS program fetch. For certain load modules such as OVERLAY modules and SCATTER LOADED modules, extra control records must be available to ensure their proper functioning. Notelist tables (for OVERLAY) and scatter tables (for SCATTER) may be imbedded among the load module text data. To be found, these tables need an extra TTR pointer in user fields of the module's directory entry. The second bit of the flag byte, turned on, denotes that two extra TTR pointers need to be constantly updated for the load module member. The third bit being on denotes that only one extra TTR pointer needs to be continually kept track of for that member. The last five bits in the flag byte denote a binary quantity that varies from 0 through 31. That denotes the number of halfwords of user data that will be appended to the required 12 bytes of the directory entry. This is clear enough. As many as 62 bytes of user data may be added to the minimum 12 bytes. ISPF Stats in a Source-Type Member A PDS member that was edited by the ISPF editor receives ISPF statistics in its directory entry when the member is saved. The statistics consist of 28 extra bytes of user data appended to the first 12 bytes. When ISPF statistics are present, required flag bits X'00001111' might be turned on; also bits X'01110000' should be turned off. This should be a fairly accurate test for the presence of ISPF statistics. (Hint is courtesy of Steve Smith). These statistics (or most of them) are displayed during an ISPF member listing for non-load type members and are familiar to many of us. A DSECT-type description of the ISPF user directory fields is at the bottom of Figure 3. It will become apparent how to change any of the statistics in the directory. We must somehow be able to display them in their native format, and then zap the changes in. ISPF Option 3.5, which changes the contents of some of these directory fields, actually does this zapping for us. Source-type PDS members that don't have ISPF stats usually have just 12-byte directory entries with the lower five bits of the required flag byte set to zeros. It is apparent that the process of adding ISPF statistics to a member that didn't have them is not trivial. A re-creation of the directory entry, possibly through the use of the STOW macro, becomes necessary. Directory space consumed for the same number of members will have to increase noticeably. Next month, I'll go into more detail about the STOW macro, ISPF statisticsalteration and load module directory user fields. Good luck. /* Was this article of value to you? If so, please let us know by circling Reader Service No. 00. Figure 1: DSECT Descriptions of Partitioned Data Set Directory Entries The required portion of the directory entry (first 12 bytes) is shown here. This description was mostly taken from source code for the PDS Program Product, Version 8.4, which can be found on File 182 of the CBT MVS Utilities Tape, member. You can refer to the macro IHAPDS in SYS1.AMODGEN for IBM official field names. DIRLINK DS 0F *** DIRECTORY AREA MAPPING *** * DIRNAME DS CL8 Member Name DIRTTR DS XL3 TTR of beginning of the Member DIRFLAG DS X Contains 3 flags in high-order bits. * Low-order 5 bits contain number of * halfwords in user-defined fields to * follow this point (62 bytes maximum). * DIRALIAS EQU X'80' This member is an alias. DIR2TTR EQU X'40' Two TTR's to update DIR1TTR EQU X'20' One TTR to update * DIRUSER DS XL62 Maximum length of directory entry * user fields. Actual length depends on * the number of halfwords indicated by * the 5 low-order bits of DIRFLAG * (the 12th byte of the directory entry). * * * * * * * * * * * * * * * * * * * * * * Figure 2: A DSECT Description of Partitioned Data Set Directory Entries for Load Modules Load modules use the user fields of the directory entry in a special way that is defined by the linkage editor and the MVS program fetch component. Labels in this illustration are from source code in the PDS Version 8.4 product, module. This source code is on the CBT Tape, File 182. For more standard names, see macro IHAPDS on SYS1.AMODGEN. DIRLINK DS 0F *** DIRECTORY AREA MAPPING *** * DIRNAME DS CL8 Member Name DIRTTR DS XL3 TTR of beginning of the Member DIRFLAG DS X Flags for required direntry fields. * DIRCALIS EQU B'10000000' This member is an alias. DIRCTTRN EQU B'01100000' There is more than 1 TTR to update DIRCUDHW EQU B'00011111' Halfword count bits. Size of user bytes. * DIRUSER DS XL62 Directory USER Fields * ORG DIRUSER FOLLOWING FOR LOAD MODULES DIRSTART DS XL4 TTR of first Text block DIRNOTE DS XL3 TTR of Notelist DIRNOTE# DS X Number of Notelist entries DIRATTR DS XL2 Member Attributes * EQUATES for First Byte ORG DIRATTR DIRAT1ST DS X DIRRENT EQU B'10000000' Reentrant DIRREUS EQU B'01000000' Reusable DIROVLY EQU B'00100000' Overlay Module DIRTEST EQU B'00010000' Test DIRLOAD EQU B'00001000' Only Loadable DIRSCTR EQU B'00000100' Scatter Load DIREXEC EQU B'00000010' Executable DIRF1 EQU B'00000001' * EQUATES for Second Byte ORG DIRATTR+1 DIRAT2ND DS X DIRNODC EQU B'10000000' Not DC (Downward Compatible) DIRF2 EQU B'01000000' DIRF3 EQU B'00100000' DIRF4 EQU B'00010000' DIRNOED EQU B'00001000' Not Editable DIRF5 EQU B'00000100' DIRLKEDF EQU B'00000010' F Level Linkage Editor DIRREFR EQU B'00000001' Refreshable * DIRSTORE DS XL3 Size of Load Module DIRTEXTL DS XL2 Length of 1st Text Record DIREPA DS XL3 Entry Point Address * DIRATTR2 DS X ADDITIONAL ATTRIBUTE BYTES: DIRAOSLE EQU B'10000000' VS Linkage Editor created this module DIR2PAGA EQU B'00100000' Page Alignment is required DIR2SSI EQU B'00010000' SSI Information present for module DIRAPFLG EQU B'00001000' APF Information for this module is valid * DIRATTR3 DS X ADDITIONAL ATTRIBUTE BYTES: DIRRMANY EQU B'00010000' RMODE=ANY DIRAA31 EQU B'00001000' AMODE=31 (Alias entry) DIRAA24 EQU B'00000100' AMODE=24 (Alias entry) DIRAM31 EQU B'00000010' AMODE=31 (Main entry) DIRAM24 EQU B'00000001' AMODE=24 (Main entry) * DIRATTR4 DS X Count of RLD Entries after first Text * DIRAPF DS 0XL2 APF (If not SCATTER, SSI or ALIAS) DIREP DS XL3 Entry Point of Main Member DIRREAL DS CL8 Real Name of Member DIRAPF2 DS XL2 APF Information (ALIAS, no SCAT or SSI) DIREND2 EQU * End of ALIAS Section * ORG DIRAPF FOLLOWING IS FOR SCATTER LOADED MODULES. DIRSCLL DS XL2 Length of Scatter List DIRSCTL DS XL2 Length of Translate Table DIRSCET DS XL2 ESDID of First Text Record DIRSCEP DS XL2 ESDID of Entry Point DIRAPF3 DS 0XL2 APF Info (If SCATTER, no SSI and no ALIAS) DIREPSC DS XL3 Entry Point (Main Membewr) DIRREALS DS CL8 Real Name of Member DIRAPF4 DS XL2 APF Info (SCATTER, no SSI and ALIAS) DIREND3 EQU * End of SCATTER, ALIAS Section Figure 3: DSECT Description of Partitioned Data Set Directory Entries These are for source-type members that have ISPF statistics. ISPF statistics are merely a special use of partitioned data set directory user fields. DIRLINK DS 0F *** DIRECTORY AREA MAPPING *** * DIRNAME DS CL8 Member Name DIRTTR DS XL3 TTR of beginning of the Member DIRFLAG DS X Contains 3 flags in high-order bits. * Low-order 5 bits contain number of * halfwords in user-defined fields to * follow this point (62 bytes maximum). * DIRALIAS EQU X'80' This member is an alias. DIR2TTR EQU X'40' Two TTR's to update DIR1TTR EQU X'20' One TTR to update DIRSPFOF EQU B'01110000' BITS ARE OFF IN ISPF STATS. DIRSPFON EQU B'00001111' BITS ARE ON IN ISPF STATS. * DIRUSER DS XL62 Directory Entry User Fields. 62 bytes max. (28 Bytes are used by ISPF Stats) * ORG DIRUSER FOLLOWING FOR MODULES SAVED BY ISPF EDIT. DIRSPFV DS XL1 Version Number in Binary DIRSPFR DS XL1 Revision Number in Binary DIRSPFZ DS XL2 Not currently used DIRSPFCR DS XL4 Creation Date in format 00YYDDDF DIRSPFCD DS XL4 Last Change Date in format 00YYDDDF DIRSPFCT DS XL2 Last Change Time in format HHMM DIRSPFSI DS XL2 Current Size in Binary (max 65535) DIRSPFIN DS XL2 Initial Size in Binary DIRSPFMD DS XL2 Modified Lines in Binary DIRSPFID DS CL8 ID of Last Person to Update