Longpela Expertise logo
Longpela Expertise Consulting
Longpela Expertise
Home | Press Room | Contact Us | Site Map
FAQ


LongEx Mainframe Quarterly - February 2014
 

technical: Find Out More About Your Load Module

Often I'm at a client site trawling through load libraries, and need to know more about a load module. I'm looking for things like what the module is, how old it is, and what language it was written in. A few sites may have spreadsheets or information from source code control software. However in most cases, I'm on my own. So how can I find out more about a load module?

ISPF DSLIST

It's no secret that you can get some basic information about load modules from your normal ISPF DSLIST. Take a look at the following screen listing the members in a PDS load library.

Command ===>                                             Scroll ===> PAGE
            Name     Prompt    Alias-of    Size      TTR     AC   AM   RM
 _________ A447GG3                       00001C30   000005   00    31  ANY
 _________ MOD002                        00006718   00000A   00    31  ANY
 _________ MOD5654                       00007DC8   000008   00    31  ANY
 _________ T55G884                       00001EA0   000007   00    24   24

I can see that load module MOD002 has no aliases, is not APF authorised, and has AMODE 31, RMODE ANY. Go right (PF11) and you get a bit more:

Command ===>                                             Scroll ===> PAGE
            Name     Prompt    Alias-of   ---- Attributes ----      SSI
 _________ A447GG3                           RN RU
 _________ MOD002                            RN RU
 _________ MOD5654
 _________ T55G884

A447GG3 and MOD002 and bound as re-entrant and re-usable. The others are not. The SSI column displays the System Status Index - 8 hex characters that today are rarely used.

Unfortunately, this is all DSLIST gives you. The good news is that IBM gives more.

AMBLIST

AMBLIST is THE way to find everything you've ever wanted to know about a load module. It's a batch utility that will give you everything: a dump of the module, CSECTS included, bind date, bind options, and IDRDATA (we talk about IDRDATA shortly). You name it, it's there. The output is wordy, particularly if you're looking at every load module in a library. Some will pass AMBLIST output to something like DFSORT to just produce one line per module.

You can find out more about AMBLIST from the z/OS Diagnosis: Tools and Service Aids manual.

An interesting bit of trivia: AMBLIST and other utilities such as AMASPZAP and IEBCOPY call the z/OS Binder API to get information about each load module.

Load Module Browse

AMBLIST is great, but it's a batch utility, and produces a lot of output. Sometimes I want information quickly, or something that AMBLIST can't give me. In this case, browse is my first choice.

That's right. ISPF browse. Sure, browsing a load module gives you gobbldy-gook that looks like this:

********************************* Top of Data ****************************
.......0MODLX001........IGZCBSO ........CEESTART.......^CEEBETBL........C
.......0CEEROOTA......  CEEROOTD......  IGZEOPT ......  IGZETUN ......  
.......{CEESG004......  CEESG006......  CEESG007......  CEESG008......  CE
..........................................................................
...5695PMB01 .......k.
.:....5655S7100 ..........569623400 ....|PL/X-390  ....|.............56962
..h....|.RSI10742265....|.RSI10742130
............ ......................^...............Y.......y...-....
.00..CEE.........00.q......¶.............Ö}. .0.q.0<...............{......
.......Ö....................... ...........<.......F...-...O..............
.......Ö............æ..&...........Y.......D...............0.......Ü......
..........................................................................
******************************** Bottom of Data **************************

But there's a lot to find out here. Straight away I can see that this is an Enterprise COBOL application program that uses Language Environment, and was bound using z/OS (not OS/390 or MVS/XA). How?

The first things you'll see in a load module are the External System Directories (ESDs) for internal and external references. In the above example, these are the first three lines. Here I can see a few Language Environment modules (they're the ones starting with CEE), so this is an application program (can't be a z/OS exit). I can also see some beginning with IGZ, which indicates COBOL. So this is a COBOL application. If you browse through the module (both up and down, and left to right), you'll see a few more of these references.

These references can tell you a lot about a module. For example, if you find some beginning with DFH = CICS application, L$C=SAS/C, DSN=DB2, EDC=XL C/C++.

With a bit more digging, we can find out more about the compiler. Take a look at the sixth line down (.:....5655S7100 ..........). This includes the product code for Enterprise COBOL V4 (5655-S71), padded out with a couple of zeroes, and a space at the end. Every load module has records with information about that load module and the programs (or CSECTs) inside it. These records are called IDRDATA. The above line is a type of IDRDATA record called a Translator Record. Let's look at the hexadecimal for this line (using the ISPF HEX line command):

.:....5655S7100 ..........
870800FFFFEFFFF44013800800
0A401056552710002035F02061

The first byte ('x80') indicates that this is a CSECT identification record. The second shows the number of IDRDATA bytes in this record, and the third is x'04' (showing us that this is a subtype 4 record). If there are no more IDRDATA records, the high order bit of this third byte is set to 1, making it x'14'.

Subtype 4 records (Translator, or compiler records) show information about the compilers used for each CSECT in the module. They include the compiler identification (10 characters, padded with spaces) followed by the version and release, and finally the compile date as a Julian date (yyddd) in packed decimal. So in our example, the Enterprise COBOL version is 4.2 (42), no release (it is zero), and was compiled on the date 13358F (Day 358 in 2013: 24-Dec-2013). Longpela Expertise has a Julian date converter tool at http://www.longpelaexpertise.com.au/toolsJulian.php to make working with Julian dates easier.

Other compiler identification strings you may find include:

  • z/OS product ID (e.g. 5650ZOS, 5694A01, 5647A01) - IBM XL C/C++
  • 5655G5300- Enterprise COBOL V3
  • 5648A2500 - COBOL for OS/390 and VM V2
  • 566895801 - COBOL II
  • 5655-H31 - Enterprise PL/I V3
  • 5655-B22 - VisualAge PL/I V2
  • 569623400 - High Level Assembler
  • PL/X-390 - IBMs internal PL/X language
  • SAS/C - SAS/C

You can see a more comprehensive list at the GSF-Soft website

This sounds excellent - you can quickly find out the language used. But it's not that simple. Translator records show compilers for ALL CSECTs in the module. Most application program modules will include several other CSECTs from Language Environment, IMS, CICS, DB2 and others. So you'll see the compilers used for all of these modules as well as the original program. Fortunately, these included CSECTs are almost always assembler or PL/X, with the occasional C/C++ or SAS/C. So if you see the PL/1 product code, it's probably a PL/1 program.

You could manually decipher these records to find out the compiler for each CSECT. But that's a lot of hard work. AMBLIST is a much better option. Here's the AMBLIST for our CSECT in the above module:

           CONTROL SECTION:  MODLX001
===== IDRL =====
          TRANSLATOR   VER   MOD     DATE        TIME
          5655S7100     42    00    12/24/2013.

Let's take a look at the line before to our Translator record: ...5695PMB01 .......k.

This is an IDRDATA Subtype 2 (Binder) record. Again, we'll use the ISPF HEX command to get the hexadecimal values for this record:

...5695PMB01 .......k.
810FFFFDDCFF4011380392
05256957420101335F132F

Straight away we can see the string 5695PMB01, which is the product ID of the product that translated/bound/link-edited it. In our case, this is 5695-PMB01 (with a space at the end to pad it out to 10 characters): the z/OS Binder. Programs bound using the old link-editor will have something like 5695DF108 (DFSMS/MVS), 566529508 (DFP/370) or 566528408 (DFP/XA).

The full format of the record is:

Char 1: Record Type (x'80' = CSECT Identification Record)
Char 2: Number of bytes
Char 3: Format or subtype (x'02')
Char 4-13: Program ID of binder/link-editor/translator
Char 14 - Binder version (x'01')
Char 15 - Binder release (x'13')
Char 16-18 - Date module was bound

I often want to find out when a module was bound, so characters 16-18 are gold. These show the date in packed decimal Julian format. In our example, this is 13358F: 24-Dec-2013.

You may also see another packed decimal number in characters 19-23. This is the time the module was bound in packed decimal hhmmss (hour/minute/second) format. So in our example, it was bound at 0133922F (13:39:22 UTC). Older modules won't include this timestamp.

Again, AMBLIST provides this information as well. Here's the AMBLIST output for the above module:

THIS PROGRAM OBJECT WAS ORIGINALLY PRODUCED BY 5695PMB01 AT LEVEL 01.13 ON
12/24/2013 AT 13:39:22

You can see the format of load modules in the IBM z/OS Program Management: Advanced Facilities manual.

All this is great providing you're look at load modules in a PDS. And today, this is still most of them. However these older modules are slowly being replaced with a new type: Program Objects.

PDSE Browse

Program Objects were introduced in OS/390 1.1, and can be thought of as load modules on steroids. They get around a lot of the limitations of load modules, but are only stored in PDSEs or z/OS UNIX directories. So instantly we know that any modules in z/OS UNIX directories or PDSEs are Program Objects.

Unlike load modules, IBM has stated that it won't publish the format of Program Objects, and in fact there are already several different Program Object formats, with more undoubtedly on the way. So to find out information, we should use AMBLIST (or if from a program, the z/OS Binder API). However if we just want to quickly find information about a Program Object, we can still find it out from browsing. Below shows the browse of the same module above, but copied into a PDSE:

********************************* Top of Data ****************************
IEWPLMH ...............................................m...h..............
.00..CEE.........00.q......¶.............Ö}. .0.q.0<...............{......
K...{.K..Mw&K..\wüK..YveK..8v¨K...v.. j.k/.ük/.ÿk:.Uk:.Xk:..K...w.K..5w.K
Jyw.K..8Jym..8o.... ..s.8.....nY.....;..j-N..-sw....n1.....;2.J...o.Jt..J.
J^ &..&&J.& J. &..&&J.& J{  ..& JDP.JHJH. }}& K.K.K..dP.K.K. .J..0....&0J.
....n.B....D.0...Ý..}...}... ..m.0.........0}<.0....B4.Ý..}...}... ..m.\..
5695PMB01 ........k.......
.................SDSD.....................................................
.........................ERERL............................................
............................L..............................\S.............
******************************** Bottom of Data **************************

It looks different, but things aren't so bad. For starters, can still see our trusty Binder IDRDATA in the seventh row (without the x'801502' at the beginning):

5695PMB01 ........k.......
FFFFDDCFF40121380392004400
569574201013035F132F00A800

Same format, except this has a 4 digit year (2013358F). Browse through the module (up and down, left and right) and we can see our CEE* and IGZ* external references:

********************************* Top of Data ****************************
..........................................................................
. .......Y. .......u.{.......: .....{.. .......6. .......:...............
-n ....].9 .&{..^{..}^Ü ...KtJ.t.&.J. ...&.J^  ..& J.&.J..&}8  &.& J.&.J{ 
.K..{w?. j.k. Ik. ...j........&&...K. .wE.0  .¬n. I..]. ...&.j...  ..KtJ.t
..........................................................................
..........................................................................
.................................Ü........................................
......ERWXM...............................................................
H..MODLX001...MODLX001...IGZCBSO...CEESTART...CEEBETBL...CEELOCT...CEESG00
..........................................................................
******************************** Bottom of Data **************************

The compiler IDRDATA record is also there, but takes some finding. If we search on 5655S7100, we can see it:

********************************* Top of Data ****************************
............f0...y....................MODLX001.....{.....................
3320131224133922040200.......%..>..a..K...a. &..... .....Ý...H....    ..MO
K...w.&...&...&...K...w.&.. k...k..&&...K..-v.K.J ..j .ï...Üj....\.4o.}do 
N..-sw...o.^{.  .h& J..0[ê.^{..0.onY..... ..j-K..-w[. . s.8.. . K.J^. m.J^
J.&&J. ...&.J.&&J{ &. &&JDP.JHJHK.K..d&-K.P.K.K. .J..0....&0J. ... ... \..
&}\..}a..0......a^o.{..}...0.b.0........ \.........h....j.........a..\...0
    5655S7100 ......569623400 .....|PL/X-390  .....|569623400 ....."569623
...........................................................LDLDM..........
..........................................*.......\................ED  ...
..................... S...............................X...................
******************************** Bottom of Data **************************

Conclusion

There are several products and freeware that can also be used to find information about load modules and program objects. ISPF productivity tools such as IBM ISPF Productivity Tool, Serena Startool DA and IBM FileManager show information similar to that from AMBLIST, but without the batch job. Other products such as the Edge Portfolio Analyzer, Prince Load Analyzer and the Load Module Analyzer component of IBM Debug Tool go further, showing compiler options used.

These products are great for finding information about load modules and program objects, as is the standard IBM AMBLIST batch utility. But if you don't have them, or don't want to submit batch jobs, a simple ISPF Browse can quickly tell you a lot about a load module or program object.


Thanks to Peter Vels for spotting a typo.


David Stephens



LongEx Quarterly is a quarterly eZine produced by Longpela Expertise. It provides Mainframe articles for management and technical experts. It is published every November, February, May and August.

The opinions in this article are solely those of the author, and do not necessarily represent the opinions of any other person or organisation. All trademarks, trade names, service marks and logos referenced in these articles belong to their respective companies.

Although Longpela Expertise may be paid by organisations reprinting our articles, all articles are independent. Longpela Expertise has not been paid money by any vendor or company to write any articles appearing in our e-zine.

Inside This Month

Printer Friendly Version

Read Previous Articles


Longpela Expertise are mainframe technical experts: from coding and administration to management, problem solving and training. Contact us to get your own mainframe expert.
© Copyright 2014 Longpela Expertise  |  ABN 55 072 652 147
Legal Disclaimer | Privacy Policy Australia
Website Design: Hecate Jay