CEEPCALL COBTEST,MF=(E,) expands to:
DS 0H
01-CEEPCALL
CEE0007F ALIAS C'COBTEST'
01-CEEPCALL
EXTRN CEE0007F
01-CEEPCALL
CEE0007F XATTR SCOPE(IMPORT),REFERENCE(INDIRECT),REFERENCE(CODE)
01-CEEPCALL
CNOP 0,4
01-CEEPCALL
J CEE0007J BRANCH AROUND QCON
01-CEEPCALL
CEE0007Q DC Q(CEE0007F) OFFSET TO DESCRIPTOR
01-CEEPCALL
CEE0007J DS 0H
01-CEEPCALL
L 15,500(,12) LOAD 15 WITH CEECAACRENT
01-CEEPCALL
A 15,CEE0007Q ADD OFFSET TO FUNC DESC @P0C
01-CEEPCALL
BASR 14,15 BRANCH TO ENTRY POINT
01-CEEPCALL
For the invocations that work, the CEE0007Q variable (in this example) resolves
(correctly) to 0, which is the offset of the "descriptor". If there were two
CEEPCALL invocations (of two different programs) the CEE00xxQ variable resolves
to 20, which is the offset of the descriptor for this routine. I specifically
refer to the following from the binder step:
---------------
CLASS C_WSA LENGTH = 40 ATTRIBUTES = MRG, DEFER , RMODE=ANY
OFFSET = 0 IN SEGMENT 002 ALIGN = DBLWORD
---------------
CLASS
OFFSET NAME TYPE LENGTH SECTION
0 COBTEST DESCRIPTOR 20
20 DLLTEST DESCRIPTOR 20
It's interesting to note that when COBTEST is compiled with COBOL V6.3, there's
an additional item in the C_WSA class:
CLASS
OFFSET NAME TYPE LENGTH SECTION
0 COBTEST DESCRIPTOR 20
20 DLLTEST DESCRIPTOR 20
40 COBTEST#S PART 84 COBTEST
Not sure what that represents, but I imagine it might have something to do with
the issue.
As for how any of this works to actually invoke the desired module, I don't
really know. The macro code generated for both static and DLL calls is
identical and indeed the assembler has no idea which linkage will be used. So
my guess is that the BASR 14,15 doesn't branch directly to the routine, but
rather to some special code that does the DLL load, if required, and then
branches to the routine from there. No DLL load for static linkage, of course.
I can change the CEEPCALL to invoke a CSECT that simply does an abend (see
below).
ABENDER CSECT ,
ABENDER RMODE ANY
ABEND 2001,DUMP
END ABENDER
Then I see the following.
From the LE dump:
Information for enclave CALLER
Information for thread 8000000000000000
Traceback:
DSA Entry E Offset Statement Load Mod Program Unit
Service Status
1 CEEHDSP +00004A4C CEEPLPKA CEEHDSP
HLE77B0 Call
2 CEEPGTFN +0855FCCC CEEPLPKA
Exception
3 CALLER +0000008C CALLER CALLER
Call
DSA DSA Addr E Addr PU Addr PU Offset Comp Date Compile
Attributes
1 00014170 076C0EC8 076C0EC8 +00004A4C 20170307 CEL
2 000140B0 077A1080 077A11F0 +0855FB5C 20170307 LIBRARY
3 00014030 0FD00000 0FD00000 +0000008C 20210816 ASM
IBM Fault Analyzer shows this:
Event Fail Module Program EP
# Type Point Name Name Name Event Location (*) Description
-- ------------ ----- -------- -------- -------- ------------------
--------------------------------------------
1 Call ***** CALLER CALLER CALLER E+8C From
DVFJS.APPLIB.LOAD
2 BALR CEEPLPKA n/a CEEPGTFN E+64 CEL Get
Function and swap WSA; From LPA
3 Abend U2001 CALLER ABENDER n/a P+E From
DVFJS.APPLIB.LOAD
So the CEEPGTFN routine in CEEPLPKA must be the "magic" routine that does (or
doesn't do) the DLL load and then calls the actual routine. I imagine it does
whatever WSA magic needs to be done as well.
Frank
On Mon, 16 Aug 2021 21:16:14 +0200, Bernd Oppolzer <[email protected]>
wrote:
>I cannot comment on the specific situations, but
>
>- register 12 normally contains the address of the CEECAA control block,
>when running under LE control
>
>- at position 500 of the CEECAA, the address of the current active WSA
>(writeable static area) is stored;
>the WSA is related to the module to be called (or just having been
>called), and it contains all its
>static (but modifyable) variables. The WSA is built if the module is
>compiled with the RENT option;
>if not, there is no WSA.
>
>It would be interesting to look at the expansion of the complete
>CEEPCALL macro,
>because: the CEEPCALL must do some action first to load COBTEST, to
>setup and
>initialize the WSA (which is specific to COBTEST), and to store its
>address into 500(R12) ...
>which seems not to work in some of the scenarios. (This is why we did
>CEEFETCH
>in the situation mentioned some mails before, when we had to call a PL/1
>module
>which was compiled using the RENT compiler option).
>
>HTH,
>kind regards
>
>Bernd
>
>
>
>Am 16.08.2021 um 20:46 schrieb Frank Swarbrick:
>> I have a very simple LE-enabled assembler program:
>> SYSSTATE ARCHLVL=2
>> CALLER CEEENTRY MAIN=YES,RMODE=ANY
>> CEEPCALL COBTEST,MF=(E,)
>> CEETERM
>> PPA CEEPPA ,
>> CEEDSA ,
>> CEECAA ,
>> END CALLER
>>
>> This works under the following conditions:
>> - COBTEST is a COBOL V6.3 DLL and is "DLL linked" with CALLER.
>> - COBTEST is a COBOL V4.2 non-DLL and is static linked with CALLER.
>>
>> However, if COBTEST is a COBOL V6.3 non-DLL and is static linked with
>> CALLER, it abends with an S0C1.
>> It appears that when a COBOL V6.3 program is static linked with an
>> LE-assembler main program it's wiping our or not properly setting
>> CEECAACRENT, the address of the writable static area.
>>
>> Specifically, the CEEPCALL macro expansion has the following statement:
>> L 15,500(,12) LOAD 15 WITH CEECAACRENT
>> When working properly, this loads R15 with a valid address. But in the not
>> working scenario it's loading address 0.
>>
>> Should this be working? Is this a bug? Am I doing something wrong?
>>
>> Thanks,
>> Frank
>>
>> ----------------------------------------------------------------------
>> For IBM-MAIN subscribe / signoff / archive access instructions,
>> send email to [email protected] with the message: INFO IBM-MAIN
>
>----------------------------------------------------------------------
>For IBM-MAIN subscribe / signoff / archive access instructions,
>send email to [email protected] with the message: INFO IBM-MAIN
----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to [email protected] with the message: INFO IBM-MAIN