Discussion:
How are Program Object sections with Defer attribute loaded?
(too old to reply)
Peter Hunkeler
2017-05-10 17:02:00 UTC
Permalink
Raw Message
I understand that Cobol V5 and newer is marking the Working Storage sections (C_WSA) with the "deferred load" attribute. I further understand that "deferred load" sections are not loaded automatically when the load module is brought into storage.

How does one request that "deferred load" section be loaded now? I probably was looking for the wrong thing at the wrong place, since I could not find it.

From looking at a dump, I see the CDE does not seem to represent the "deferred load" section of a program object, only the non-deferred part. How do I find such a section in a dump?




--
Peter Hunkeler

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN
Lizette Koehler
2017-05-10 17:14:41 UTC
Permalink
Raw Message
Trust in the COBOL young Luke.. You do not need to understand the COBOL, It
knows what you need.


Sorry - not even Friday.

I am not sure it is controllable by the user. But I will do some further
research

Lizette
-----Original Message-----
Behalf Of Peter Hunkeler
Sent: Wednesday, May 10, 2017 10:03 AM
Subject: How are Program Object sections with Defer attribute loaded?
I understand that Cobol V5 and newer is marking the Working Storage sections
(C_WSA) with the "deferred load" attribute. I further understand that
"deferred load" sections are not loaded automatically when the load module is
brought into storage.
How does one request that "deferred load" section be loaded now? I probably
was looking for the wrong thing at the wrong place, since I could not find
it.
From looking at a dump, I see the CDE does not seem to represent the
"deferred load" section of a program object, only the non-deferred part. How
do I find such a section in a dump?
--
Peter Hunkeler
----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN
Paul Gilmartin
2017-05-10 17:31:36 UTC
Permalink
Raw Message
Post by Peter Hunkeler
I understand that Cobol V5 and newer is marking the Working Storage sections (C_WSA) with the "deferred load" attribute. I further understand that "deferred load" sections are not loaded automatically when the load module is brought into storage.
How does one request that "deferred load" section be loaded now? I probably was looking for the wrong thing at the wrong place, since I could not find it.
I believe they're loaded on demand. If you need them, they' re there;
if they're not there, you didn't need them.
Post by Peter Hunkeler
From looking at a dump, I see the CDE does not seem to represent the "deferred load" section of a program object, only the non-deferred part. How do I find such a section in a dump?
-- gil

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN
Peter Hunkeler
2017-05-10 18:09:25 UTC
Permalink
Raw Message
Post by Paul Gilmartin
Post by Peter Hunkeler
How does one request that "deferred load" section be loaded now? I probably was looking for the wrong thing at the wrong place, since I could not find it.
I believe they're loaded on demand. If you need them, they' re there;
if they're not there, you didn't need them.



This is a function offered by the MVS Binder and the MVS Loader in some way. It is being used by LE, which is the component loading Cobol, well MVS, load modules.


In previous versions of Cobol, the Working Storage section was part of the load module, and it was easier to locate Working Storage variables in dump. Now, they are disconnected from the code section, thus it all looks different in a dump. This is how I became aware of "deferred load" sections.


I'm a curious MVS guy, and I'm curious to understand this. I'm looking at this from a pure MVS point of view.




--
Peter Hunkeler






----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN
Clark Morris
2017-05-10 20:50:49 UTC
Permalink
Raw Message
[Default] On 10 May 2017 11:09:25 -0700, in bit.listserv.ibm-main
Post by Paul Gilmartin
Post by Paul Gilmartin
Post by Peter Hunkeler
How does one request that "deferred load" section be loaded now? I probably was looking for the wrong thing at the wrong place, since I could not find it.
I believe they're loaded on demand. If you need them, they' re there;
if they're not there, you didn't need them.
This is a function offered by the MVS Binder and the MVS Loader in some way. It is being used by LE, which is the component loading Cobol, well MVS, load modules.
In previous versions of Cobol, the Working Storage section was part of the load module, and it was easier to locate Working Storage variables in dump. Now, they are disconnected from the code section, thus it all looks different in a dump. This is how I became aware of "deferred load" sections.
Since VS COBOL II release 1.4 with the RENT option, WORKING-STORAGE
has not been in the load module.

Clark Morris
Post by Paul Gilmartin
I'm a curious MVS guy, and I'm curious to understand this. I'm looking at this from a pure MVS point of view.
----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN
Allan Kielstra
2017-05-10 18:02:38 UTC
Permalink
Raw Message
That's actually a trickier question than you might imagine! There are a number of cases: the case where your module consists of COBOL, PL/I and assembler only and all other cases. All other cases include cases where the COBOL run time support is implemented in a language other than the above. These cases include OO COBOL, XML support and a few others.

In the second case (not pure COBOL), the C_WSA is loaded in exactly the same way as it is for a C program. Basically, first the program is loaded and then the C run time gets control. It determines that you want to start new instance of this program (C_WSA is only used for RENT.) So it calls CEEPPOS which is the actual routine that gets a WSA and initializes it. This all happens before main is run. (Or, in the case of C++, before any file scope statics are constructed.)

In the first case, your program starts and the COBOL bootstrap routine gets control. That routine is called at the start of every PROGRAM. In most cases, it checks a few things and returns. But for the first program in the run unit, it does some work including ensuring that LE is up. Part of that work is getting storage for the WSA. All of this happens before the first user statement in the PROCEDURE DIVISION is executed.

So, no matter how the C_WSA is loaded (by and LE routine or by the COBOL run time) it is present before the first user written statement in the program is executed. Which means that unless you're getting some sort of a trap during the COBOL start up, you should always see the C_WSA somewhere in your storage.

By the way, WORKING STORAGE is another area of complexity. In the case of NOWSOPT (the default for V5) W-S items are directly in the C_WSA. In the case of WSOPT (V6) W-S is separately allocated and the WSA contains a pointer to that allocation. (Again, this is all done before the first user statement is executed.)

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN
Peter Hunkeler
2017-05-10 18:38:38 UTC
Permalink
Raw Message
Post by Allan Kielstra
That's actually a trickier question than you might imagine!
I imagine it is! In my current job, I'm getting involved when standard application debugging techniques don't help anymore. I usually work with IPCS, so SYSMDUMPs and SVCDUMPs. We moved to Cobol V5.2 earlier this year, but I still need to find the content of Cobol variables in those dumps. The changes to how Working Storage is implemented, and the fact that this is mostly undocumented, makes it difficult. This is the real reason I'm trying to understand all this.


Your comments are most welcome!
Post by Allan Kielstra
There are a number of cases: the case where your module consists of COBOL, PL/I and assembler only and all other cases. All other cases include cases where the COBOL run time support is implemented in a language other than the above. These cases include OO COBOL, XML support and a few others.
In the second case (not pure COBOL), the C_WSA is loaded in exactly the same way as it is for a C program. Basically, first the program is loaded and then the C run time gets control. It determines that you want to start new instance of this program (C_WSA is only used for RENT.) So it calls CEEPPOS which is the actual routine that gets a WSA and initializes it.
This all happens before main is run. (Or, in the case of C++, before any file scope statics are constructed.)
Yes, this is well understood.
Post by Allan Kielstra
In the first case, your program starts and the COBOL bootstrap routine gets control. That routine is called at the start of every PROGRAM. In most cases, it checks a few things and returns. But for the first program in the run unit, it does some work including ensuring that LE is up. Part of that work is getting storage for the WSA.
All of this happens before the first user statement in the PROCEDURE DIVISION is executed.
So, no matter how the C_WSA is loaded (by and LE routine or by the COBOL run time) it is present before the first user written statement in the program is executed.
Yes, again well understood.
Post by Allan Kielstra
Which means that unless you're getting some sort of a trap during the COBOL start up, you should always see the C_WSA somewhere in your storage.
Yep, somewhere. But somewhere is not specific enough if you need to find the value of a variable at the time of the dump.
Post by Allan Kielstra
By the way, WORKING STORAGE is another area of complexity. In the case of NOWSOPT (the default for V5) W-S items are directly in the C_WSA. In the case of WSOPT (V6) W-S is separately allocated and the WSA contains a pointer to that allocation. (Again, this is all done before the first user statement is executed.)
I really which there was a document describing all the variants in detail and how to find variables in a dump in each case. Lack of that document, I'm trying to find out step by step.


You would seem to be able to be of great help for me on this quest.


--
Peter Hunkeler




----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN
Peter Hunkeler
2017-05-10 19:01:46 UTC
Permalink
Raw Message
Reposting under a different subject, since the topic has changed
Post by Allan Kielstra
That's actually a trickier question than you might imagine!
I imagine it is! In my current job, I'm getting involved when standard application debugging techniques don't help anymore. I usually work with IPCS, so SYSMDUMPs and SVCDUMPs. We moved to Cobol V5.2 earlier this year, but I still need to find the content of Cobol variables in those dumps. The changes to how Working Storage is implemented, and the fact that this is mostly undocumented, makes it difficult. This is the real reason I'm trying to understand all this.


Your comments are most welcome!
Post by Allan Kielstra
There are a number of cases: the case where your module consists of COBOL, PL/I and assembler only and all other cases. All other cases include cases where the COBOL run time support is implemented in a language other than the above. These cases include OO COBOL, XML support and a few others.
In the second case (not pure COBOL), the C_WSA is loaded in exactly the same way as it is for a C program. Basically, first the program is loaded and then the C run time gets control. It determines that you want to start new instance of this program (C_WSA is only used for RENT.) So it calls CEEPPOS which is the actual routine that gets a WSA and initializes it.
This all happens before main is run. (Or, in the case of C++, before any file scope statics are constructed.)
Yes, this is well understood.
Post by Allan Kielstra
In the first case, your program starts and the COBOL bootstrap routine gets control. That routine is called at the start of every PROGRAM. In most cases, it checks a few things and returns. But for the first program in the run unit, it does some work including ensuring that LE is up. Part of that work is getting storage for the WSA.
All of this happens before the first user statement in the PROCEDURE DIVISION is executed.
So, no matter how the C_WSA is loaded (by and LE routine or by the COBOL run time) it is present before the first user written statement in the program is executed.
Yes, again well understood.
Post by Allan Kielstra
Which means that unless you're getting some sort of a trap during the COBOL start up, you should always see the C_WSA somewhere in your storage.
Yep, somewhere. But somewhere is not specific enough if you need to find the value of a variable at the time of the dump.
Post by Allan Kielstra
By the way, WORKING STORAGE is another area of complexity. In the case of NOWSOPT (the default for V5) W-S items are directly in the C_WSA. In the case of WSOPT (V6) W-S is separately allocated and the WSA contains a pointer to that allocation. (Again, this is all done before the first user statement is executed.)
I really which there was a document describing all the variants in detail and how to find variables in a dump in each case. Lack of that document, I'm trying to find out step by step.


You would seem to be able to be of great help for me on this quest.
--
Peter Hunkeler




----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN


----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN
Bernd Oppolzer
2017-05-10 19:24:50 UTC
Permalink
Raw Message
I guess that this is the same case as finding C and PL/1 static variables
when the C and PL/1 procedures or functions are compiled using the RENT
compiler switch.

Because:

a) auto variables are always part of the "stack" which is addressed by
register 13
(aka save area aka dynamic save area aka dynamic save area)

b) in the NORENT case the STATIC variables are part of the STATIC CSECT,
which is located inside the load module ... this is, what classical
COBOL did,
and which is still present in C and PL/1 in the NORENT case ... NORENT is
recommended by IBM for PL/1, today :-)

So, let's go:

the static variables in the RENT case are part of the WSA. To locate
them in
the dump (SYSUDUMP, CEEDUMP, ...), you have several choices:

a) when you are inside the function where the variable is defined,
CEECSA+500 (X'1F4) should point to the WSA, so you have the base
address of the WSA. From the prelinker listing, you can see where the
static section of your particular function starts (Q(@STATIC)), add this
to the
base address, and then add the offset of the variable from the compiler
listing ..
voila the address of the variable

b) to speed up the addressing of the variables at run time, a certain
register
is loaded just after the function prologue with the value CEECSA+500 +
Q(@STATIC).
Look for this register (may be R4, R5, R6, R7, ...). Then add the offset
of the
variable to that register.

Sorry, no easier way. In prior releases, the base register of the static
area
always was register 3 (in PL/1).

The compiler builders could make the jobs of dump readers easier, if they
want, but they normally don't have dump readers in mind.

I'm trying to do it differently with my Stanford Pascal compiler:
http://bernd-oppolzer.de/job9.htm

HTH,
have a nice day

Bernd
Post by Peter Hunkeler
Reposting under a different subject, since the topic has changed
Post by Allan Kielstra
That's actually a trickier question than you might imagine!
I imagine it is! In my current job, I'm getting involved when standard application debugging techniques don't help anymore. I usually work with IPCS, so SYSMDUMPs and SVCDUMPs. We moved to Cobol V5.2 earlier this year, but I still need to find the content of Cobol variables in those dumps. The changes to how Working Storage is implemented, and the fact that this is mostly undocumented, makes it difficult. This is the real reason I'm trying to understand all this.
Your comments are most welcome!
Post by Allan Kielstra
There are a number of cases: the case where your module consists of COBOL, PL/I and assembler only and all other cases. All other cases include cases where the COBOL run time support is implemented in a language other than the above. These cases include OO COBOL, XML support and a few others.
In the second case (not pure COBOL), the C_WSA is loaded in exactly the same way as it is for a C program. Basically, first the program is loaded and then the C run time gets control. It determines that you want to start new instance of this program (C_WSA is only used for RENT.) So it calls CEEPPOS which is the actual routine that gets a WSA and initializes it.
This all happens before main is run. (Or, in the case of C++, before any file scope statics are constructed.)
Yes, this is well understood.
Post by Allan Kielstra
In the first case, your program starts and the COBOL bootstrap routine gets control. That routine is called at the start of every PROGRAM. In most cases, it checks a few things and returns. But for the first program in the run unit, it does some work including ensuring that LE is up. Part of that work is getting storage for the WSA.
All of this happens before the first user statement in the PROCEDURE DIVISION is executed.
So, no matter how the C_WSA is loaded (by and LE routine or by the COBOL run time) it is present before the first user written statement in the program is executed.
Yes, again well understood.
Post by Allan Kielstra
Which means that unless you're getting some sort of a trap during the COBOL start up, you should always see the C_WSA somewhere in your storage.
Yep, somewhere. But somewhere is not specific enough if you need to find the value of a variable at the time of the dump.
Post by Allan Kielstra
By the way, WORKING STORAGE is another area of complexity. In the case of NOWSOPT (the default for V5) W-S items are directly in the C_WSA. In the case of WSOPT (V6) W-S is separately allocated and the WSA contains a pointer to that allocation. (Again, this is all done before the first user statement is executed.)
I really which there was a document describing all the variants in detail and how to find variables in a dump in each case. Lack of that document, I'm trying to find out step by step.
You would seem to be able to be of great help for me on this quest.
----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN
Bernd Oppolzer
2017-05-10 19:28:48 UTC
Permalink
Raw Message
Two minor errors below:

"addressed by register 13 (aka save area aka dynamic save area aka
dynamic save area)"

should read

"addressed by register 13 (aka save area aka dynamic save area aka
dynamic STORAGE area)"

And I forgot to mention:

CEECSA is always address by reg 12, while inside a LE module.

So you get:

reg 12 + 500 = address of the WSA
take this address
add @(Static) from the compiler or prelinker listing
= address of your static section (which should be in some register ...)
add offset of the desired variable
now you have the address

Kind regards

Bernd
Post by Bernd Oppolzer
I guess that this is the same case as finding C and PL/1 static variables
when the C and PL/1 procedures or functions are compiled using the RENT
compiler switch.
a) auto variables are always part of the "stack" which is addressed by
register 13
(aka save area aka dynamic save area aka dynamic save area)
b) in the NORENT case the STATIC variables are part of the STATIC CSECT,
which is located inside the load module ... this is, what classical
COBOL did,
and which is still present in C and PL/1 in the NORENT case ... NORENT is
recommended by IBM for PL/1, today :-)
the static variables in the RENT case are part of the WSA. To locate
them in
a) when you are inside the function where the variable is defined,
CEECSA+500 (X'1F4) should point to the WSA, so you have the base
address of the WSA. From the prelinker listing, you can see where the
this to the
base address, and then add the offset of the variable from the
compiler listing ..
voila the address of the variable
b) to speed up the addressing of the variables at run time, a certain
register
is loaded just after the function prologue with the value CEECSA+500 +
Look for this register (may be R4, R5, R6, R7, ...). Then add the
offset of the
variable to that register.
Sorry, no easier way. In prior releases, the base register of the
static area
always was register 3 (in PL/1).
The compiler builders could make the jobs of dump readers easier, if they
want, but they normally don't have dump readers in mind.
http://bernd-oppolzer.de/job9.htm
HTH,
have a nice day
Bernd
Post by Peter Hunkeler
Reposting under a different subject, since the topic has changed
Post by Allan Kielstra
That's actually a trickier question than you might imagine!
I imagine it is! In my current job, I'm getting involved when
standard application debugging techniques don't help anymore. I
usually work with IPCS, so SYSMDUMPs and SVCDUMPs. We moved to Cobol
V5.2 earlier this year, but I still need to find the content of Cobol
variables in those dumps. The changes to how Working Storage is
implemented, and the fact that this is mostly undocumented, makes it
difficult. This is the real reason I'm trying to understand all this.
Your comments are most welcome!
Post by Allan Kielstra
There are a number of cases: the case where your module consists of
COBOL, PL/I and assembler only and all other cases. All other cases
include cases where the COBOL run time support is implemented in a
language other than the above. These cases include OO COBOL, XML
support and a few others.
In the second case (not pure COBOL), the C_WSA is loaded in
exactly the same way as it is for a C program. Basically, first the
program is loaded and then the C run time gets control. It
determines that you want to start new instance of this program
(C_WSA is only used for RENT.) So it calls CEEPPOS which is the
actual routine that gets a WSA and initializes it.
This all happens before main is run. (Or, in the case of C++, before
any file scope statics are constructed.)
Yes, this is well understood.
Post by Allan Kielstra
In the first case, your program starts and the COBOL bootstrap
routine gets control. That routine is called at the start of every
PROGRAM. In most cases, it checks a few things and returns. But
for the first program in the run unit, it does some work including
ensuring that LE is up. Part of that work is getting storage for
the WSA.
All of this happens before the first user statement in the PROCEDURE
DIVISION is executed.
So, no matter how the C_WSA is loaded (by and LE routine or by the
COBOL run time) it is present before the first user written
statement in the program is executed.
Yes, again well understood.
Post by Allan Kielstra
Which means that unless you're getting some sort of a trap during
the COBOL start up, you should always see the C_WSA somewhere in
your storage.
Yep, somewhere. But somewhere is not specific enough if you need
to find the value of a variable at the time of the dump.
Post by Allan Kielstra
By the way, WORKING STORAGE is another area of complexity. In the
case of NOWSOPT (the default for V5) W-S items are directly in the
C_WSA. In the case of WSOPT (V6) W-S is separately allocated and
the WSA contains a pointer to that allocation. (Again, this is all
done before the first user statement is executed.)
I really which there was a document describing all the
variants in detail and how to find variables in a dump in each case.
Lack of that document, I'm trying to find out step by step.
You would seem to be able to be of great help for me on this quest.
----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN
Thomas Dunlap
2017-05-10 20:13:43 UTC
Permalink
Raw Message
Bernd and Peter,

What Bernd shows you is the way I have found it in COBOL V5.1.1. I am
putting up V6 next month and will revisit it again. I also did the ASM
map in V5.1.1 and discovered that Working Storage seems to be based on
Reg. 8. I do not have V5.2, but I would imagine it would be the same.

Cheers,
Tom
Post by Bernd Oppolzer
"addressed by register 13 (aka save area aka dynamic save area aka
dynamic save area)"
should read
"addressed by register 13 (aka save area aka dynamic save area aka
dynamic STORAGE area)"
CEECSA is always address by reg 12, while inside a LE module.
reg 12 + 500 = address of the WSA
take this address
= address of your static section (which should be in some register ...)
add offset of the desired variable
now you have the address
Kind regards
Bernd
Post by Bernd Oppolzer
I guess that this is the same case as finding C and PL/1 static variables
when the C and PL/1 procedures or functions are compiled using the RENT
compiler switch.
a) auto variables are always part of the "stack" which is addressed
by register 13
(aka save area aka dynamic save area aka dynamic save area)
b) in the NORENT case the STATIC variables are part of the STATIC CSECT,
which is located inside the load module ... this is, what classical
COBOL did,
and which is still present in C and PL/1 in the NORENT case ... NORENT is
recommended by IBM for PL/1, today :-)
the static variables in the RENT case are part of the WSA. To locate
them in
a) when you are inside the function where the variable is defined,
CEECSA+500 (X'1F4) should point to the WSA, so you have the base
address of the WSA. From the prelinker listing, you can see where the
this to the
base address, and then add the offset of the variable from the
compiler listing ..
voila the address of the variable
b) to speed up the addressing of the variables at run time, a certain
register
is loaded just after the function prologue with the value CEECSA+500
Look for this register (may be R4, R5, R6, R7, ...). Then add the
offset of the
variable to that register.
Sorry, no easier way. In prior releases, the base register of the
static area
always was register 3 (in PL/1).
The compiler builders could make the jobs of dump readers easier, if they
want, but they normally don't have dump readers in mind.
http://bernd-oppolzer.de/job9.htm
HTH,
have a nice day
Bernd
Post by Peter Hunkeler
Reposting under a different subject, since the topic has changed
Post by Allan Kielstra
That's actually a trickier question than you might imagine!
I imagine it is! In my current job, I'm getting involved when
standard application debugging techniques don't help anymore. I
usually work with IPCS, so SYSMDUMPs and SVCDUMPs. We moved to Cobol
V5.2 earlier this year, but I still need to find the content of
Cobol variables in those dumps. The changes to how Working Storage
is implemented, and the fact that this is mostly undocumented, makes
it difficult. This is the real reason I'm trying to understand all
this.
Your comments are most welcome!
Post by Allan Kielstra
There are a number of cases: the case where your module consists
of COBOL, PL/I and assembler only and all other cases. All other
cases include cases where the COBOL run time support is implemented
in a language other than the above. These cases include OO COBOL,
XML support and a few others.
In the second case (not pure COBOL), the C_WSA is loaded in
exactly the same way as it is for a C program. Basically, first the
program is loaded and then the C run time gets control. It
determines that you want to start new instance of this program
(C_WSA is only used for RENT.) So it calls CEEPPOS which is the
actual routine that gets a WSA and initializes it.
This all happens before main is run. (Or, in the case of C++,
before any file scope statics are constructed.)
Yes, this is well understood.
Post by Allan Kielstra
In the first case, your program starts and the COBOL bootstrap
routine gets control. That routine is called at the start of every
PROGRAM. In most cases, it checks a few things and returns. But
for the first program in the run unit, it does some work including
ensuring that LE is up. Part of that work is getting storage for
the WSA.
All of this happens before the first user statement in the
PROCEDURE DIVISION is executed.
So, no matter how the C_WSA is loaded (by and LE routine or by the
COBOL run time) it is present before the first user written
statement in the program is executed.
Yes, again well understood.
Post by Allan Kielstra
Which means that unless you're getting some sort of a trap during
the COBOL start up, you should always see the C_WSA somewhere in
your storage.
Yep, somewhere. But somewhere is not specific enough if you
need to find the value of a variable at the time of the dump.
Post by Allan Kielstra
By the way, WORKING STORAGE is another area of complexity. In the
case of NOWSOPT (the default for V5) W-S items are directly in the
C_WSA. In the case of WSOPT (V6) W-S is separately allocated and
the WSA contains a pointer to that allocation. (Again, this is all
done before the first user statement is executed.)
I really which there was a document describing all the
variants in detail and how to find variables in a dump in each case.
Lack of that document, I'm trying to find out step by step.
You would seem to be able to be of great help for me on this quest.
----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
--
Regards,
Thomas Dunlap Chief Technology Officer ***@themisinc.com
Themis, Inc. http://www.themisinc.com 908 400-6485

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN
Peter Hunkeler
2017-05-11 19:27:17 UTC
Permalink
Raw Message
Post by Bernd Oppolzer
CEECSA is always address by reg 12, while inside a LE module.
... and I forgot to thank you as well, Bernd


--
Peter Hunkeler



----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN
Allan Kielstra
2017-05-10 20:47:21 UTC
Permalink
Raw Message
Bernd has already started the reply, but I would like to add a little bit.

(First, I should say that most of this stuff IS documented in the PG and MG, but...)

To find a specific W-S variable, you will need a listing.

If you start with a dump, you will find a stack frame for your COBOL program and in its register save area, you will find the CAA Anchor in GPR12. Think of the CAA anchor as a thread specific piece of data. Fortunately, most non OO COBOL programs are single threaded so you don't have to worry about that subtlety.

Also, if you start with a dump, you'll find the entry point for the COBOL program. From this, you can find the PPA1 (there is one for every sub routine in a compilation unit -- using C terminology):

000000 000002 PROC PGG1
000000 47F0 F014 000002 BC R15,20(,R15) # Skip over constant area
000004 01C3 C5C5 000002 DC X'01C3C5C5' # Eyecatcher: CEE
000008 0000 0200 000002 DC X'00000200' # Stack Size
00000C 0000 0690 000002 DC X'00000690' # Offset to PPA1 <<------
000010 47F0 F001 000002 BC R15,1(,R15) # Wrong Entry Point: cause exception

from the PPA1, you can find the PPA2 (there is one for the entire compilation unit -- again C terminology):
PPA1: Entry Point Constants
000690 1CCEA506 =F'483304710' Flags
000694 00000850 =A(PPA2-PGG1) <<--------
000698 000007C0 =A(PPA3-PGG1)

from the PPA2, you can find the PPA4 (again only one):
PPA2: Entry Point Constants
000850 04002203 =F'67117571' Flags
000854 FFFFF7B0 =A(CEESTART-PPA2)
000858 00000058 =F'88' A(PPA4-PPA2) <<-------
00085C FFFFFFB0 =A(TIMESTMP-PPA2)
000860 FFFFF7B0 =A(PrimaryEntryPoint-PPA2)
000864 02200000 =F'35651584' Flags

The C_WSA is actually the combined writeable static area for all of the programs bound into your module (or DLL). To find the entire C_WSA for the module, you need to get the CEECRENT pointer out of the CEE Anchor. That means, getting 500(GPR12). Now you need to find the bit of the C_WSA for this particular program (compilation unit in C terminology). You can get that from the PPA4:
PPA4: Entry Point Constants
0008A8 08000000 =F'134217728' Flags 1
0008AC 00020100 =F'131328' Flags 2
0008B0 00000000 =F'0' A(NORENTstatic)
0008B4 00000000 =F'0' Q(RENTstatic) <<-----

Add that QCON to the CEECRENT -- 500(GPR12) -- and you have the start of the section of the WSA for your program.

Now you need to know if WSOPT was used or not. For that you need to go back to the PPA2 and find the timestamp:
000844 FFFFFFB0 =A(TIMESTMP-PPA2)

The time stamp is a fixed length and immediately following it is :
Compiler Options and Program Information Section
000814 0034 =X'0034' Size of Compiler Options and Prog Info Section
000816 (+00) 0474 =X'0474' UNSIGNED BINARY CODE PAGE CCSID VALUE
000818 (+02) 07 =X'07' ARCHITECTURE LEVEL
000819 (+03) 00 =X'00' OPTIMIZATION LEVEL
00081A (+04) 1406 =X'1406' INFO. BYTES 28-29
00081C (+06) 0000 =X'0000' INFO. BYTES 30-31
00081E (+08) A0C8754C2000 =X'A0C8754C2000' INFO. BYTES 1-6
000824 (+14) 001000084001 =X'001000084001' INFO. BYTES 7-12

The bit you're looking for is bit 3 of byte 15. Compare the output above to the same program with NOWSOPT
00080C (+14) 000000084001 =X'000000084001' INFO. BYTES 7-12

If you are using NOWSOPT (which is the default for V4) your W-S data items are all in your piece of the module's WSA. To find a specific item, you need to consult the listing looking for this section:
* * * * * S T A T I C M A P * * * * *

OFFSET (HEX) LENGTH (HEX) NAME

If you are using WSOPT (which is the default in V6), there will be a pointer in the WSA that points to the working storage for your program. That can also be found in the PPA4:
0008B8 0000006C =F'108' A(DATA31_address_cell-RENTstatic)

So you find the WSA and go to (in this case) offset x'6C' and you will find a pointer to your working storage. In this case, to find a specific data item, you need to consult the listing looking for this section:
* * * * * W O R K I N G - S T O R A G E M A P * * * * *

OFFSET (HEX) LENGTH (HEX) NAME

In both cases (WSOPT and NOWSOPT) the storage that you find (either C_WSA or the target of the pointer in C_WSA) will have both some compiler artifacts and actual working storage. These artifacts also appear in the * * M A P * * sections mentioned above. Working Storage is always contiguous. If you don't have a listing file and you have gone through the procedure described above and you really want to identify only working storage (and not compiler artifacts) and you have V6.1 and you get the PTF that was shipped on May 8, there is a new addition to the end of PPA4:
000880 002A =X'2A' A(CUName-PPA4)
000888 00000098 =X'98' Offset UsrWrkStrg <<-----
00088C 0000003B =X'3B' Length UsrWrkStrg <<-----
000890 00 =X'0' Has Externals

These tell you exactly where in the storage that you found by following the process above user working storage starts and how much working storage there is.

Hmmm... looking back over this, it really couldn't be simpler. :-)

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN
Peter Hunkeler
2017-05-11 11:22:25 UTC
Permalink
Raw Message
Many thanks for the details. Much appreciated. This information might be in the manuals, but it is a bit scattered.

-- Peter Hunkeler



----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN
Peter Relson
2017-05-11 11:58:37 UTC
Permalink
Raw Message
Post by Peter Hunkeler
How does one request that "deferred load" section be
loaded now?
"One" does not. LE does, using an internal interface. LE is responsible
for making sure that both the "immediate load" and "deferred load"
sections are in place.

As to finding it in a dump, perhaps that would be based on knowing the
address of the WSA, or perhaps some LE-based diagnostics.

Peter Relson
z/OS Core Technology Design


----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN
Peter Hunkeler
2017-05-11 13:06:34 UTC
Permalink
Raw Message
Post by Peter Relson
Post by Peter Hunkeler
How does one request that "deferred load" section be
loaded now?
"One" does not. LE does, using an internal interface. LE is responsible
for making sure that both the "immediate load" and "deferred load"
sections are in place.


I understand LE is using it, but since "deferred load" is mentioned in the Binder manual, I thought it might be a public interface. Ok, it is not. Curiosity satisfied,
Post by Peter Relson
As to finding it in a dump, perhaps that would be based on knowing the
address of the WSA, or perhaps some LE-based diagnostics.


So, although part of a load module in a PDSE, "deferred load" sections, when loaded, are not represented by any of the structures that represent load modules (CDE, etc).
Are they loaded into a specific subpool defined by MVS, or the loading piece of software responsible to do an appropriate STORAGE OBTAIN before using that internal interface? Sorry, here it is again, the curiosity :-)
--
Peter Hunkeler







----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN
Steve Smith
2017-05-11 13:11:15 UTC
Permalink
Raw Message
It appears to me that deferred-load sections are merely an enhanced
external dummy section (aka pseudo-register) facility. The binder updates
Q-cons for them, and it's up to the program to implement the actual
in-memory version, and provide a method for finding it. LE and its HLL
ancestors have always done that.

sas
Post by Peter Relson
Post by Peter Hunkeler
How does one request that "deferred load" section be
loaded now?
"One" does not. LE does, using an internal interface. LE is responsible
for making sure that both the "immediate load" and "deferred load"
sections are in place.
As to finding it in a dump, perhaps that would be based on knowing the
address of the WSA, or perhaps some LE-based diagnostics.
Peter Relson
z/OS Core Technology Design
----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
--
sas

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN
Jesse 1 Robinson
2017-05-11 15:20:01 UTC
Permalink
Raw Message
The very first program I ever wrote for pay--when I graduated from street walking to hall walking--contained a huge number of full-word counters. It was, if I may say, a superb program, but a colleague wondered why I needed three base registers. Turns out that my computer-school assembler class had never got around to GETMAIN and DSECTs. All my thousands of counters were coded as DC F'0'. (I was later told that my program was used by sysprog staff to benchmark new CPUs!)

Now of course I write large or necessarily reentrant programs with 'deferred load' of 'working storage' areas. How smart I is now.

.
.
J.O.Skip Robinson
Southern California Edison Company
Electric Dragon Team Paddler
SHARE MVS Program Co-Manager
323-715-0595 Mobile
626-543-6132 Office ⇐=== NEW
***@sce.com


-----Original Message-----
From: IBM Mainframe Discussion List [mailto:IBM-***@LISTSERV.UA.EDU] On Behalf Of Steve Smith
Sent: Thursday, May 11, 2017 6:12 AM
To: IBM-***@LISTSERV.UA.EDU
Subject: (External):Re: How are Program Object sections with Defer attribute loaded?

It appears to me that deferred-load sections are merely an enhanced external dummy section (aka pseudo-register) facility. The binder updates Q-cons for them, and it's up to the program to implement the actual in-memory version, and provide a method for finding it. LE and its HLL ancestors have always done that.

sas
Post by Peter Relson
Post by Peter Hunkeler
How does one request that "deferred load" section be loaded now?
"One" does not. LE does, using an internal interface. LE is
responsible for making sure that both the "immediate load" and "deferred load"
sections are in place.
As to finding it in a dump, perhaps that would be based on knowing the
address of the WSA, or perhaps some LE-based diagnostics.
Peter Relson
z/OS Core Technology Design
----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN
Allan Kielstra
2017-05-11 20:26:43 UTC
Permalink
Raw Message
Post by Bernd Oppolzer
CEECSA is always address by reg 12, while inside a LE module.
is not strictly true. GPR12 is only required to point to CEECSA on entry to and exit from a procedure. Compilers are free to use GPR12 for whatever other purpose they chose at other program points.

That means that if you get a crash in the middle of a procedure (COBOL PROGRAM) you should not look at the current value of GPR12. You should go back to the register save area and find what GPR12 was on entry to the procedure.

(I mention this because with COBOL V5/6, GPR12 actually is often reused inside COBOL programs.)

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN
Bernd Oppolzer
2017-05-11 20:41:26 UTC
Permalink
Raw Message
oh oh ...

I did not take this into account ...

I wrote a C program to get the HPCB addresses for Belowheap and Anyheap,
and to get them, I needed the CEECAA, and I did this by looking at reg
12 using
an ASSEMBLER subprogram:

memset (rbuffer, 0x00, sizeof (rbuffer));
MDV9970 (rbuffer);

#if 0
for (i = 0; i < 16; i ++)
{
printf ("Register %d = %p\n", i, rbuffer [i]);
}
#endif

ceecaa = rbuffer [12];
ceeedb = *((char **) (ceecaa + 0x2f0));
if (memcmp (ceeedb, "CEEEDB ", 8) != 0)
return;

anyp = *((char **) (ceeedb + 0x20));
if (memcmp (anyp, "HPCB", 4) != 0)
return;

belowp = *((char **) (ceeedb + 0x24));
if (memcmp (belowp, "HPCB", 4) != 0)
return;

worked without problems, but maybe lucky :-)

is there a LE function to get the address of the CEECAA?

or will I have to go back to the prior save area using reg 13?

the program, BTW, checks all the heap control blocks and does some
sort of book keeping at different points in time ... and then it prints the
differences ... looking for memory leaks. This helped us a lot to find
memory leaks in PL/1 programs ... but it works for every programming
language which uses LE.

Contact me offline, if you are interested about the details.

Thank you,
kind regards

Bernd
Post by Allan Kielstra
Post by Bernd Oppolzer
CEECSA is always address by reg 12, while inside a LE module.
is not strictly true. GPR12 is only required to point to CEECSA on entry to and exit from a procedure. Compilers are free to use GPR12 for whatever other purpose they chose at other program points.
That means that if you get a crash in the middle of a procedure (COBOL PROGRAM) you should not look at the current value of GPR12. You should go back to the register save area and find what GPR12 was on entry to the procedure.
(I mention this because with COBOL V5/6, GPR12 actually is often reused inside COBOL programs.)
----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN
Tom Marchant
2017-05-11 21:06:25 UTC
Permalink
Raw Message
Post by Allan Kielstra
Post by Bernd Oppolzer
CEECSA is always address by reg 12, while inside a LE module.
is not strictly true. GPR12 is only required to point to CEECSA on entry to and exit from a procedure. Compilers are free to use GPR12 for whatever other purpose they chose at other program points.
That means that if you get a crash in the middle of a procedure (COBOL PROGRAM) you should not look at the current value of GPR12. You should go back to the register save area and find what GPR12 was on entry to the procedure.
(I mention this because with COBOL V5/6, GPR12 actually is often reused inside COBOL programs.)
I think you both mean CEECAA, the Common Anchor Area.
--
Tom Marchant

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN
Bernd Oppolzer
2017-05-11 21:55:06 UTC
Permalink
Raw Message
Yes, of course. I detected the error when I looked at
my piece of software from last year which examined the different LE heaps.

and: thank you, Allan Kielstra, for the clarification regarding Reg 12;
so my call to the ASSEMBLER function to get the address of the CEECAA
will work?

Here is the ASSEMBLER program which returns the registers (especially
reg 12)
to the C program:

MDV9970 CSECT
MDV9970 AMODE 31
MDV9970 RMODE ANY
*
***************************************************************
* UNTERPROGRAMM ZUR ERMITTLUNG DER
* AKTUELLEN REGISTERSTAENDE UND ABLAGE
* IN EINEN C-BUFFER (DER ALS PARAMETER
* UEBERGEBEN WIRD). ZWECK DER UEBUNG:
* ZUGRIFF AUF CEECAA (COMMON ANCHOR AREA VOM LE)
* UND DAMIT AUF ANYHEAP UND BELOWHEAP
* BERND OPPOLZER / AUGUST 2016
***************************************************************
*
R0 EQU 0
R1 EQU 1
R2 EQU 2
R3 EQU 3
R4 EQU 4
R5 EQU 5
R6 EQU 6
R7 EQU 7
R8 EQU 8
R9 EQU 9
RA EQU 10
RB EQU 11
RC EQU 12
RD EQU 13
RE EQU 14
RF EQU 15
*
STM RE,RC,12(RD) REGISTER SICHERN
USING MDV9970,RF ADRESSIERUNG HERSTELLEN
L R3,0(R1) ADRESSE VOM BUFFER = 1. PARAMETER
MVC 0(52,R3),20(RD) REGISTER 0 BIS 12 AUS SA UEBERTR.
ST RD,52(R3) REGISTER 13 ABSPEICHERN
MVC 56(8,R3),12(RD) REGISTER 14 UND 15 AUS SA UEBERTR.
LM RE,RC,12(RD) REGISTER ZURUECKLADEN
BR RE UND RUECKSPRUNG
*
END MDV9970

Kind regards

Bernd
Post by Tom Marchant
Post by Allan Kielstra
Post by Bernd Oppolzer
CEECSA is always address by reg 12, while inside a LE module.
is not strictly true. GPR12 is only required to point to CEECSA on entry to and exit from a procedure. Compilers are free to use GPR12 for whatever other purpose they chose at other program points.
That means that if you get a crash in the middle of a procedure (COBOL PROGRAM) you should not look at the current value of GPR12. You should go back to the register save area and find what GPR12 was on entry to the procedure.
(I mention this because with COBOL V5/6, GPR12 actually is often reused inside COBOL programs.)
I think you both mean CEECAA, the Common Anchor Area.
----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN
John McKown
2017-05-11 22:07:48 UTC
Permalink
Raw Message
Post by Bernd Oppolzer
Yes, of course. I detected the error when I looked at
my piece of software from last year which examined the different LE heaps.
and: thank you, Allan Kielstra, for the clarification regarding Reg 12;
so my call to the ASSEMBLER function to get the address of the CEECAA will
work?
Here is the ASSEMBLER program which returns the registers (especially reg
12)
MDV9970 CSECT
MDV9970 AMODE 31
MDV9970 RMODE ANY
*
***************************************************************
* UNTERPROGRAMM ZUR ERMITTLUNG DER
* AKTUELLEN REGISTERSTAENDE UND ABLAGE
* IN EINEN C-BUFFER (DER ALS PARAMETER
* ZUGRIFF AUF CEECAA (COMMON ANCHOR AREA VOM LE)
* UND DAMIT AUF ANYHEAP UND BELOWHEAP
* BERND OPPOLZER / AUGUST 2016
***************************************************************
*
R0 EQU 0
R1 EQU 1
R2 EQU 2
R3 EQU 3
R4 EQU 4
R5 EQU 5
R6 EQU 6
R7 EQU 7
R8 EQU 8
R9 EQU 9
RA EQU 10
RB EQU 11
RC EQU 12
RD EQU 13
RE EQU 14
RF EQU 15
*
STM RE,RC,12(RD) REGISTER SICHERN
USING MDV9970,RF ADRESSIERUNG HERSTELLEN
L R3,0(R1) ADRESSE VOM BUFFER = 1. PARAMETER
MVC 0(52,R3),20(RD) REGISTER 0 BIS 12 AUS SA UEBERTR.
ST RD,52(R3) REGISTER 13 ABSPEICHERN
MVC 56(8,R3),12(RD) REGISTER 14 UND 15 AUS SA UEBERTR.
LM RE,RC,12(RD) REGISTER ZURUECKLADEN
BR RE UND RUECKSPRUNG
*
END MDV9970
​Looks fairly good to me. For returning the 32 bit registers, that is. But
it seems to be "overkill" to me. The "guts" of the routine could be just:

STM R0,RF,12(RD) SAVE ALL REGS.
L R3,0(,R1) POINT TO RETURN AREA
​MVC 0(64,R3),12(RD) MOVE REGS AT ENTRY
SLR RF,RF
BR RE

This does not use standard linkage, but is that really necessary? The only
possible abend would be on the MVC, if the routine is not called properly.
I included the SLR just to "zero" the return code. If the C code is
declared as returning "void" (e.g. "void MDV9970(regs) ;" where regs is
defined as "uint regs[16];" ) then R15 on exit is ignored.
Post by Bernd Oppolzer
Kind regards
Bernd
--
Advertising is a valuable economic factor because it is the cheapest way of
selling goods, particularly if the goods are worthless. -- Sinclair Lewis


Maranatha! <><
John McKown

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN
Bernd Oppolzer
2017-05-11 22:22:54 UTC
Permalink
Raw Message
Post by John McKown
Post by Bernd Oppolzer
Yes, of course. I detected the error when I looked at
my piece of software from last year which examined the different LE heaps.
and: thank you, Allan Kielstra, for the clarification regarding Reg 12;
so my call to the ASSEMBLER function to get the address of the CEECAA will
work?
Here is the ASSEMBLER program which returns the registers (especially reg
12)
MDV9970 CSECT
MDV9970 AMODE 31
MDV9970 RMODE ANY
*
***************************************************************
* UNTERPROGRAMM ZUR ERMITTLUNG DER
* AKTUELLEN REGISTERSTAENDE UND ABLAGE
* IN EINEN C-BUFFER (DER ALS PARAMETER
* ZUGRIFF AUF CEECAA (COMMON ANCHOR AREA VOM LE)
* UND DAMIT AUF ANYHEAP UND BELOWHEAP
* BERND OPPOLZER / AUGUST 2016
***************************************************************
*
R0 EQU 0
R1 EQU 1
R2 EQU 2
R3 EQU 3
R4 EQU 4
R5 EQU 5
R6 EQU 6
R7 EQU 7
R8 EQU 8
R9 EQU 9
RA EQU 10
RB EQU 11
RC EQU 12
RD EQU 13
RE EQU 14
RF EQU 15
*
STM RE,RC,12(RD) REGISTER SICHERN
USING MDV9970,RF ADRESSIERUNG HERSTELLEN
L R3,0(R1) ADRESSE VOM BUFFER = 1. PARAMETER
MVC 0(52,R3),20(RD) REGISTER 0 BIS 12 AUS SA UEBERTR.
ST RD,52(R3) REGISTER 13 ABSPEICHERN
MVC 56(8,R3),12(RD) REGISTER 14 UND 15 AUS SA UEBERTR.
LM RE,RC,12(RD) REGISTER ZURUECKLADEN
BR RE UND RUECKSPRUNG
*
END MDV9970
​Looks fairly good to me. For returning the 32 bit registers, that is. But
STM R0,RF,12(RD) SAVE ALL REGS.
L R3,0(,R1) POINT TO RETURN AREA
​MVC 0(64,R3),12(RD) MOVE REGS AT ENTRY
SLR RF,RF
BR RE
This does not use standard linkage, but is that really necessary? The only
possible abend would be on the MVC, if the routine is not called properly.
I included the SLR just to "zero" the return code. If the C code is
declared as returning "void" (e.g. "void MDV9970(regs) ;" where regs is
defined as "uint regs[16];" ) then R15 on exit is ignored.
But you should add a LM instruction to restore the registers,
for example R3. The original program is called inside a C function,
and I thought that the registers should be restored on exit in a (sort of)
standard way. This is expected by the surrounding C routine, IMO.

What I find most interesting:

if I set RF (or any other register) to zero, I always would code

XR RF,RF

you use

SLR RF,RF

it's a matter of style, or maybe what you learned first. I know of people
using SR RF,RF - but I never saw SLR RF,RF up until now. Nice :-)

There was once a discussion that you can tell the author of a piece of
software
from such style attributes ... not only with ASSEMBLER, but with other
languages (even C etc.), too. With other languages, it's maybe more the
style of writing, layout etc.

Kind regards

Bernd

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN
Charles Mills
2017-05-11 23:34:29 UTC
Permalink
Raw Message
I know of people using SR RF,RF - but I never saw SLR RF,RF up until now
This issue has been beat to death here but on recent processors SR, SLR and XR to clear a register are all equally fast. Use whichever one you find most aesthetic. At one time LHI r,0 was generally faster because SR/SLR/XR r,r tied up a fixed point arithmetic unit (albeit LHI uses 2 additional bytes of i-cache). Modern processors all recognize SR/SLR/XR r,r and treat it as a non-arithmetic "slam a zero into r." LHI may still have a slight advantage in some situations because it does not set the condition code, possibly making things easier on the branch prediction logic. That aspect is also advantageous for compilers which now do things like a compare, followed by a bunch of unrelated instructions, followed by a branch on the results of the compare -- to take advantage of pipelining.

Charles


-----Original Message-----
From: IBM Mainframe Discussion List [mailto:IBM-***@LISTSERV.UA.EDU] On Behalf Of Bernd Oppolzer
Sent: Thursday, May 11, 2017 3:24 PM
To: IBM-***@LISTSERV.UA.EDU
Subject: Re: How to find Cobol (and C) Working Storage variables in an SVCDUMP
On Thu, May 11, 2017 at 4:55 PM, Bernd Oppolzer
Yes, of course. I detected the error when I looked at my piece of
software from last year which examined the different LE heaps.
and: thank you, Allan Kielstra, for the clarification regarding Reg
12; so my call to the ASSEMBLER function to get the address of the
CEECAA will work?
Here is the ASSEMBLER program which returns the registers (especially reg
12)
MDV9970 CSECT
MDV9970 AMODE 31
MDV9970 RMODE ANY
*
***************************************************************
* UNTERPROGRAMM ZUR ERMITTLUNG DER
* AKTUELLEN REGISTERSTAENDE UND ABLAGE
* IN EINEN C-BUFFER (DER ALS PARAMETER
* ZUGRIFF AUF CEECAA (COMMON ANCHOR AREA VOM LE)
* UND DAMIT AUF ANYHEAP UND BELOWHEAP
* BERND OPPOLZER / AUGUST 2016
***************************************************************
*
R0 EQU 0
R1 EQU 1
R2 EQU 2
R3 EQU 3
R4 EQU 4
R5 EQU 5
R6 EQU 6
R7 EQU 7
R8 EQU 8
R9 EQU 9
RA EQU 10
RB EQU 11
RC EQU 12
RD EQU 13
RE EQU 14
RF EQU 15
*
STM RE,RC,12(RD) REGISTER SICHERN
USING MDV9970,RF ADRESSIERUNG HERSTELLEN
L R3,0(R1) ADRESSE VOM BUFFER = 1. PARAMETER
MVC 0(52,R3),20(RD) REGISTER 0 BIS 12 AUS SA UEBERTR.
ST RD,52(R3) REGISTER 13 ABSPEICHERN
MVC 56(8,R3),12(RD) REGISTER 14 UND 15 AUS SA UEBERTR.
LM RE,RC,12(RD) REGISTER ZURUECKLADEN
BR RE UND RUECKSPRUNG
*
END MDV9970
​Looks fairly good to me. For returning the 32 bit registers, that is.
STM R0,RF,12(RD) SAVE ALL REGS.
L R3,0(,R1) POINT TO RETURN AREA
​MVC 0(64,R3),12(RD) MOVE REGS AT ENTRY
SLR RF,RF
BR RE
This does not use standard linkage, but is that really necessary? The
only possible abend would be on the MVC, if the routine is not called properly.
I included the SLR just to "zero" the return code. If the C code is
declared as returning "void" (e.g. "void MDV9970(regs) ;" where regs
is defined as "uint regs[16];" ) then R15 on exit is ignored.
But you should add a LM instruction to restore the registers, for example R3. The original program is called inside a C function, and I thought that the registers should be restored on exit in a (sort of) standard way. This is expected by the surrounding C routine, IMO.

What I find most interesting:

if I set RF (or any other register) to zero, I always would code

XR RF,RF

you use

SLR RF,RF

it's a matter of style, or maybe what you learned first. I know of people using SR RF,RF - but I never saw SLR RF,RF up until now. Nice :-)

There was once a discussion that you can tell the author of a piece of software from such style attributes ... not only with ASSEMBLER, but with other languages (even C etc.), too. With other languages, it's maybe more the style of writing, layout etc.

Kind regards

Bernd

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions, send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN
Allan Kielstra
2017-05-11 21:37:10 UTC
Permalink
Raw Message
If a C or PL/I or COBOL (or any LE high level language) program calls an assembler program, it will have set GPR12 to the CEE Anchor correctly before making the call. Assuming that you are completely lost in space in LE and you need the CEE anchor, there is a service called CEEARLU. It is documented here: https://www.ibm.com/support/knowledgecenter/en/SSLTBW_2.1.0/com.ibm.zos.v2r1.ceev100/ceearlu.htm

The compilers don't like using this because it is known to be not very fast.

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN
Allan Kielstra
2017-05-11 23:36:10 UTC
Permalink
Raw Message
Bernd's assembler technique will work.

I have no idea why I can't find a description of this (taken from /usr/include/stdio.h)
#ifndef __gtca
#define __gtca() _gtca()
#ifdef __cplusplus
extern "builtin"
#else
#pragma linkage(_gtca,builtin)
#endif
const void *_gtca(void);
#endif
online. It is mentioned in the XL C/C++ Runtime Library Reference

Since it's not really described, I'm not sure you are allowed to count on it existing in the future. But in the past, that is the function that I have used (in 31-bit anyway) to get the CAA directly in C++.

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN
Charles Mills
2017-05-12 00:34:35 UTC
Permalink
Raw Message
Interesting. A reference to _gtca() also in LE Vendor Interfaces. Hints here and there in the C/C++ docs.

Charles


-----Original Message-----
From: IBM Mainframe Discussion List [mailto:IBM-***@LISTSERV.UA.EDU] On Behalf Of Allan Kielstra
Sent: Thursday, May 11, 2017 4:37 PM
To: IBM-***@LISTSERV.UA.EDU
Subject: Re: How to find Cobol (and C) Working Storage variables in an SVCDUMP

Bernd's assembler technique will work.

I have no idea why I can't find a description of this (taken from /usr/include/stdio.h)
#ifndef __gtca
#define __gtca() _gtca()
#ifdef __cplusplus
extern "builtin"
#else
#pragma linkage(_gtca,builtin)
#endif
const void *_gtca(void);
#endif
online. It is mentioned in the XL C/C++ Runtime Library Reference

Since it's not really described, I'm not sure you are allowed to count on it existing in the future. But in the past, that is the function that I have used (in 31-bit anyway) to get the CAA directly in C++.

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN
Peter Hunkeler
2017-05-12 05:09:18 UTC
Permalink
Raw Message
Post by Charles Mills
Interesting. A reference to _gtca() also in LE Vendor Interfaces. Hints here and there in the C/C++ docs.
I suspect _gtca() does something similar to what is described in "Chapter 14. Anchor support" in the LE Vendor Interfaces manual.


--
Peter Hunkeler



----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN
Tom Marchant
2017-05-12 13:45:22 UTC
Permalink
Raw Message
Post by John McKown
STM R0,RF,12(RD) SAVE ALL REGS.
L R3,0(,R1) POINT TO RETURN AREA
​MVC 0(64,R3),12(RD) MOVE REGS AT ENTRY
SLR RF,RF
BR RE
This does not use standard linkage, but is that really necessary?
You are going to store 16 registers (64 bytes) at offset 12 in a
72-byte save area? What is in the word that you will clobber?
--
Tom Marchant

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN
Peter Relson
2017-05-16 12:46:11 UTC
Permalink
Raw Message
<snip>
Are they loaded into a specific subpool defined by MVS, or the
loading piece of software responsible to do an appropriate
STORAGE OBTAIN before using that internal interface?
</snip>

Both are possible. The default system processing happens to use subpool 1
(but the subpool number is not to be considered an interface). But the
exploiter can provide their own storage.

Peter Relson
z/OS Core Technology Design


----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN
Peter Hunkeler
2017-05-16 14:59:54 UTC
Permalink
Raw Message
Post by Peter Relson
Post by Peter Hunkeler
Are they loaded into a specific subpool defined by MVS, or the
loading piece of software responsible to do an appropriate
STORAGE OBTAIN before using that internal interface?
Both are possible. The default system processing happens to use subpool 1
(but the subpool number is not to be considered an interface). But the
exploiter can provide their own storage.
Thank you, Sir


Cheers, Peter


--
Peter Hunkeler



----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to ***@listserv.ua.edu with the message: INFO IBM-MAIN
Loading...