Discussion:
Question about the z/OS Binder API
(too old to reply)
Farley, Peter x23353
2018-07-02 20:49:54 UTC
Permalink
Raw Message
The documentation for the z/OS V2.2 Binder API in the manual "z/OS MVS Program Management: Advanced Facilities" in "Appendix D. Binder API buffer formats", page 279 (PDF page count 297) has a footnote #3 for field ESD_ELEM_OFFSET which says:

3. Calculated on the ED and ER records, required input to LD.

That note says to me that if I INCLUDE an existing program (object or load module) into a Binder work space using the Binder API's, then for ED entries in the ESD obtained for that program using FUNC=GETD for TYPE=ESD I should see the element offset for the class of that section.

As it turns out, the Binder API FUNC=GETD for TYPE=ESD always returns a binary zero in that field. No matter what VERSION level of the API macros is used (I have tried all version numbers from 4 up to 7) the field ESD_ELEM_OFFSET is always a zero. This holds true for both program objects loaded form a PDSE and load modules loaded from a PDS.

For load modules loaded from a PDS, the "class" offset is actually zero (B_TEXT is the only class of a load module) so the zero value for a load module loaded form a PDS is actually accurate. However, for a complex program object (COBOL V5+ or C/C++, etc.) it is not accurate.

The other offset field in the ED entry (field ESD_CLASS_OFFSET) accurately contains the offset from the start of the containing Binder class section, but nowhere does the ED entry contain the offset of the CLASS from the start of the loaded program. It was my impression (perhaps wrongly) that the Binder API should tell me that offset in each ED entry for an ESD section.

To get to the actual start of a particular section of code in a loaded program it seems that you also have to use FUNC=GETN for NTYPE=CLASS to get all of the CLASS names and their respective offsets (field name BNL_SEGM_OFF) and add that value to the ESD_CLASS_OFFSET to find the code in storage. Which means you have to search the CLASS names table for each ED section name using the name at ESD_RES_CLASS_PTR to find the containing class name and then extract the offset from that CLASS entry.

Is this expected behavior of the Binder API, or is this a possible error/failure in the API? Should that class offset value from BNL_SEGM_OFF in the CLASS entry also be stored into the ESD_ELEM_OFFSET field automatically by the Binder API when a module is INCLUDEd into a workspace, or not?

If I am just misreading the API documentation, I would appreciate any enlightenment you can provide.

Peter


This message and any attachments are intended only for the use of the addressee and may contain information that is privileged and confidential. If the reader of the message is not the intended recipient or an authorized representative of the intended recipient, you are hereby notified that any dissemination of this communication is strictly prohibited. If you have received this communication in error, please notify us immediately by e-mail and delete the message and any attachments from your system.

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN
Barry Lichtenstein
2018-07-03 19:09:28 UTC
Permalink
Raw Message
Hi Peter,

In the description of the fields of the ESD entry buffer format it shows:

3 ESD_ELEM_OFFSET Binary 72 4 Offset within class element (LD, ER)
2 ESD_CLASS_OFFSET Binary 76 4 Offset within class segment (ED, LD, PD, ER)

The parenthetical information means these fields apply to only those ESD types. The Class offset is the offset of that item within the class, as you say. The Element offset is the offset of that item within the element.

That footnote may have been meant to say that with respect to inputs (PUTD), for an ED or ER type the binder will provide the value regardless of what you specify, but for LD you must provide one (probably it just shouldn't say ED). In the binder MODULE MAP output the corresponding heading on this column is "SECTION OFFSET" as the section name is really describing the element contributions within the defined class(es).

In "Using the binder application programming interfaces (APIs) -> Understanding binder programming concepts -> Organization of data in the program module -> Multiple-text class modules, load segments and ESD offsets", there is a description of finding the SEGMENT offset, the offset of the class within the segment (for a single segment module, the offset within the module), which is just as you described it.

It seems like a useful RFE to submit to ask for a new ESD_SEGM_OFFSET. The binder would have to go back through all the ESD records and update the ED, LD, PR, and ER records with the calculated value after it determined how it was segmented and bound.

There is one other way which is to build the module with the MODMAP option. Then the MODMAP can be read from the module and it contains a mapping of the ESDs relative to their owning segments. See the description of the MODMAP option in the Program Management: User's Guide & Reference and the description of the MODMAP structure and how to read it in the Program Management: Advanced Facilities manual in "Data areas -> Module Map".

Barry
Post by Farley, Peter x23353
3. Calculated on the ED and ER records, required input to LD.
That note says to me that if I INCLUDE an existing program (object or load module) into a Binder work space using the Binder API's, then for ED entries in the ESD obtained for that program using FUNC=GETD for TYPE=ESD I should see the element offset for the class of that section.
As it turns out, the Binder API FUNC=GETD for TYPE=ESD always returns a binary zero in that field. No matter what VERSION level of the API macros is used (I have tried all version numbers from 4 up to 7) the field ESD_ELEM_OFFSET is always a zero. This holds true for both program objects loaded form a PDSE and load modules loaded from a PDS.
For load modules loaded from a PDS, the "class" offset is actually zero (B_TEXT is the only class of a load module) so the zero value for a load module loaded form a PDS is actually accurate. However, for a complex program object (COBOL V5+ or C/C++, etc.) it is not accurate.
The other offset field in the ED entry (field ESD_CLASS_OFFSET) accurately contains the offset from the start of the containing Binder class section, but nowhere does the ED entry contain the offset of the CLASS from the start of the loaded program. It was my impression (perhaps wrongly) that the Binder API should tell me that offset in each ED entry for an ESD section.
To get to the actual start of a particular section of code in a loaded program it seems that you also have to use FUNC=GETN for NTYPE=CLASS to get all of the CLASS names and their respective offsets (field name BNL_SEGM_OFF) and add that value to the ESD_CLASS_OFFSET to find the code in storage. Which means you have to search the CLASS names table for each ED > section name using the name at ESD_RES_CLASS_PTR to find the containing class name and then extract the offset from that CLASS entry.
Is this expected behavior of the Binder API, or is this a possible error/failure in the API? Should that class offset value from BNL_SEGM_OFF in the CLASS entry also be stored into the ESD_ELEM_OFFSET field automatically by the Binder API when a module is INCLUDEd into a workspace, or not?
If I am just misreading the API documentation, I would appreciate any enlightenment you can provide.
Peter
----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN
Farley, Peter x23353
2018-07-03 20:25:41 UTC
Permalink
Raw Message
Hi Barry,

Thanks for the detailed reply. I understand a bit more about the structure now. I may be able to examine the ER data to get the information instead of scanning the class table, but if the ED table entry physically precedes the ER entry it may be tricky to coordinate within the current code structure. Scanning the class entries is already coded, and at least that works for now.

Unfortunately the application is scanning existing executables, none of which was bound (or is ever likely to be bound) using the MODMAP option. Re-binding is not an available option -- unless it could be created on-the-fly in the created in-memory workspace? Is that possible without actually rewriting the executable to the input library? How much external knowledge of the original binding parameters (entry points, AMODE/RMODE, RENT options, etc.) is necessary but not available in an INCLUDE'd existing executable program? And what may be needed if it is a really OLD executable program from decades-ago linkage?

I will consider entering an RFE, thanks for the suggestion. In the meantime, I do have at least one working alternative to collect the needed data.

Again my sincere thanks for your help, it is much appreciated.

Peter

-----Original Message-----
From: IBM Mainframe Discussion List [mailto:IBM-***@LISTSERV.UA.EDU] On Behalf Of Barry Lichtenstein
Sent: Tuesday, July 3, 2018 3:09 PM
To: IBM-***@LISTSERV.UA.EDU
Subject: Re: Question about the z/OS Binder API

EXTERNAL EMAIL

Hi Peter,

In the description of the fields of the ESD entry buffer format it shows:

3 ESD_ELEM_OFFSET Binary 72 4 Offset within class element (LD, ER)
2 ESD_CLASS_OFFSET Binary 76 4 Offset within class segment (ED, LD, PD, ER)

The parenthetical information means these fields apply to only those ESD types. The Class offset is the offset of that item within the class, as you say. The Element offset is the offset of that item within the element.

That footnote may have been meant to say that with respect to inputs (PUTD), for an ED or ER type the binder will provide the value regardless of what you specify, but for LD you must provide one (probably it just shouldn't say ED). In the binder MODULE MAP output the corresponding heading on this column is "SECTION OFFSET" as the section name is really describing the element contributions within the defined class(es).

In "Using the binder application programming interfaces (APIs) -> Understanding binder programming concepts -> Organization of data in the program module -> Multiple-text class modules, load segments and ESD offsets", there is a description of finding the SEGMENT offset, the offset of the class within the segment (for a single segment module, the offset within the module), which is just as you described it.

It seems like a useful RFE to submit to ask for a new ESD_SEGM_OFFSET. The binder would have to go back through all the ESD records and update the ED, LD, PR, and ER records with the calculated value after it determined how it was segmented and bound.

There is one other way which is to build the module with the MODMAP option. Then the MODMAP can be read from the module and it contains a mapping of the ESDs relative to their owning segments. See the description of the MODMAP option in the Program Management: User's Guide & Reference and the description of the MODMAP structure and how to read it in the Program Management: Advanced Facilities manual in "Data areas -> Module Map".

Barry
Post by Farley, Peter x23353
3. Calculated on the ED and ER records, required input to LD.
That note says to me that if I INCLUDE an existing program (object or load module) into a Binder work space using the Binder API's, then for ED entries in the ESD obtained for that program using FUNC=GETD for TYPE=ESD I should see the element offset for the class of that section.
As it turns out, the Binder API FUNC=GETD for TYPE=ESD always returns a binary zero in that field. No matter what VERSION level of the API macros is used (I have tried all version numbers from 4 up to 7) the field ESD_ELEM_OFFSET is always a zero. This holds true for both program objects loaded form a PDSE and load modules loaded from a PDS.
For load modules loaded from a PDS, the "class" offset is actually zero (B_TEXT is the only class of a load module) so the zero value for a load module loaded form a PDS is actually accurate. However, for a complex program object (COBOL V5+ or C/C++, etc.) it is not accurate.
The other offset field in the ED entry (field ESD_CLASS_OFFSET) accurately contains the offset from the start of the containing Binder class section, but nowhere does the ED entry contain the offset of the CLASS from the start of the loaded program. It was my impression (perhaps wrongly) that the Binder API should tell me that offset in each ED entry for an ESD section.
To get to the actual start of a particular section of code in a loaded program it seems that you also have to use FUNC=GETN for NTYPE=CLASS to get all of the CLASS names and their respective offsets (field name BNL_SEGM_OFF) and add that value to the ESD_CLASS_OFFSET to find the code in storage. Which means you have to search the CLASS names table for each ED > section name using the name at ESD_RES_CLASS_PTR to find the containing class name and then extract the offset from that CLASS entry.
Is this expected behavior of the Binder API, or is this a possible error/failure in the API? Should that class offset value from BNL_SEGM_OFF in the CLASS entry also be stored into the ESD_ELEM_OFFSET field automatically by the Binder API when a module is INCLUDEd into a workspace, or not?
If I am just misreading the API documentation, I would appreciate any enlightenment you can provide.
Peter
--


This message and any attachments are intended only for the use of the addressee and may contain information that is privileged and confidential. If the reader of the message is not the intended recipient or an authorized representative of the intended recipient, you are hereby notified that any dissemination of this communication is strictly prohibited. If you have received this communication in error, please notify us immediately by e-mail and delete the message and any attachments from your system.


----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN
Barry Lichtenstein
2018-07-05 15:41:18 UTC
Permalink
Raw Message
Hi Peter,

The documentation for GETE warns: "Note: Processing of the ESD records returned by a GETE call should not make assumptions about the order of the returned ESD records..." The expectation was that there would never be a very large number of classes, so that a simple class lookup (as it sounds like you've done) would be acceptable.

Yeah that's been the problem with MODMAP. In general for this sort of thing you should be creating the workmod (CREATEW) with INTENT=ACCESS and doing the INCLUDE with ATTRIB=Y to preserve things. That is what is done for both IEBCOPY (between PDS & PDSE) and UNIX cp/mv (from UNIX filesystem to dataset). I presume you are doing that, otherwise you would need to rebind (BINDW) prior to using GETE.

Unfortunately that's the problem, the use of MODMAP changes the module structure, and using INTENT=BIND, thus requiring a BINDW call before doing GETE, can potentially change the module organization (i.e. change locations of items).

Barry
Post by Farley, Peter x23353
Hi Barry,
Thanks for the detailed reply. I understand a bit more about the structure now. I may be able to examine the ER data to get the information instead of scanning the class table,
but if the ED table entry physically precedes the ER entry it may be tricky to coordinate within the current code structure. Scanning the class entries is already coded, and at least that works for now.
Unfortunately the application is scanning existing executables, none of which was bound (or is ever likely to be bound) using the MODMAP option.
Re-binding is not an available option -- unless it could be created on-the-fly in the created in-memory workspace?
Is that possible without actually rewriting the executable to the input library? How much external knowledge of the original binding parameters (entry points, AMODE/RMODE, RENT options, etc.)
is necessary but not available in an INCLUDE'd existing executable program? And what may be needed if it is a really OLD executable program from decades-ago linkage?
I will consider entering an RFE, thanks for the suggestion. In the meantime, I do have at least one working alternative to collect the needed data.
Again my sincere thanks for your help, it is much appreciated.
Peter
----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN
Loading...