An example program invocation of CELQPIPI
This section contains a sample CELQPIPI program invocation with an AMODE 64 PreInit assembler driver program.
The assembler driver, CEEWQPIP, invokes CELQPIPI to:
- Initialize a main routine environment under Language Environment®, with service routines CEEWQLOD, CEEWQDEL, CEEWQGST, CEEWQFST, and CEEWQMSG replacing any Language Environment LOAD, DELETE, GETSTORE, FREESTORE, and MSGRTN service routines, respectively.
- Load and call CEEWQPMA, a reentrant HLL main routine written in C, which causes the replacement service routines to be run.
- Terminate the Language Environment environment.
**********************************************************************
*
*
* ======== --------------------------------------------
* CEEWQPIP - AMODE64 PreInit Driver with service routines
* ======== --------------------------------------------
*
*
* This sample PreInit driver illustrates the use of LOAD, DELETE
* GETSTORE, FREESTORE, and MSGRTN replacement routines in an
* AMODE64 driver.
*
*
* This sample driver does the following:
*
* 1) CELQPIPI INIT_MAIN request, with a single-entry PreInit table
* containing "CEEWQPMA", which is a C main() program.
*
* Service Routine Vector contains:
*
* - Count = 9
* - User Word points to a below-the-bar work area for
* the LOAD and DELETE replacement routines
* - LOAD replacement routine is "CEEWQLOD"
* - DELETE replacement routine is "CEEWQDEL"
* - GETSTORE replacement routine is "CEEWQGST"
* - FREESTORE replacement routine is "CEEWQFST"
* - MSGRTN replacement routine is "CEEWQMSG"
* - All other doublewords in the service vector are 0
*
** 2) CELQPIPI CALL_MAIN request, for the only row (0) in the
* PreInit table.
*
* - The Runtime options are "POSIX(ON)"
*
* - The parms passed to the C main() program are:
*
* argc = 3
* argv[0]= "ceewqpma"
* argv[1]= "Parm1"
* argv[2]= "Parm2"
*
*
* 3) CELQPIPI TERM request
*
*
*
*
* Note: This text deck must be bound with the following:
*
* CEEWQLOD -- LOAD replacement routine
* CEEWQDEL -- DELETE replacement routine
* CEEWQGST -- GETSTORE replacement routine
* CEEWQFST -- FREESTORE replacement routine
* CEEWQMSG -- MSGRTN replacement routine
* CELQSTRT (from SCEEBND2)
* CELQETBL (from SCEEBND2)
* CELQLLST (from SCEEBND2)
*
*
* Note: At runtime, the C main() program (CEEWQPMA) must be available
* for LOAD.
*
*
***********************************************************************
CEEWQPIP CSECT ,
CEEWQPIP AMODE 64
CEEWQPIP RMODE 31
SYSSTATE AMODE64=YES
SAM64 ,
*
*
* Standard 64-bit entry linkage
* -----------------------------
*
STMG R14,R12,SAVF4SAG64RS14-SAVF4SA(R13) Save caller regs
BASR R11,0 Set up basereg
USING *,R11 Addressabliity
GETMAIN RU,LV=DSA_L Obtain DSA
STG R13,SAVF4SAPREV-SAVF4SA(,R1) Set backchain
STG R1,SAVF4SANEXT-SAVF4SA(,R13) Set fwd chain
MVC SAVF4SAID-SAVF4SA(R4,R13),=A(SAVF4SAID_VALUE) "F4SA"
LGR R13,R1 Set up DSAreg
USING DSA,R13 Addressability
*
*
* Issue LOAD for CELQPIPI (will ABEND if LOAD fails)
* -----------------------
*
WTO 'CEEWQPIP: LOADing CELQPIPI',ROUTCDE=11
*
LOAD EP=CELQPIPI LOAD LE main module
NG R0,=X'00000000FFFFFFFE' Clear low (AMODE64) bit
STG R0,CELQPIPI_EP Save CELQPIPI E.P. Address
*
*
* Set up Service Routine Vector and parm
* --------------------------------------
*
MVC SV_DYNAMIC,SV_STATIC Copy over into DSA
LA R15,USER_AREA Point to 1000-byte user area
STG R15,SV_UWORD SV user word -> user area
LA R15,SV_DYNAMIC Address of modifiable SV
STG R15,SERVICE_RTNS Save as parm for INIT_MAIN
*
*
* Do CELQPIPI INIT_MAIN
* ---------------------
*
WTO 'CEEWQPIP: Doing CELQPIPI INIT_MAIN',ROUTCDE=11
*
LG R15,CELQPIPI_EP Address of CELQPIPI E.P.
*
CALL (15), X
(INIT_MAIN, CELQPIPI INIT_MAIN request X
CEEXPTBL_ADDR, Address of CELQPIPI table X
SERVICE_RTNS, Address of service rtn vector X
TOKEN), Token from INIT_MAIN X
MF=(E,CALL_PL)*
*
* Check results of INIT_MAIN
*
LTGR R2,R15 Check CELQPIPI R/C
BZ INIT_OK Go do CALL_MAIN, if OK
WTO 'CEEWQPIP: CELQPIPI INIT_MAIN failed',ROUTCDE=11
MVC RC_MSGD,RC_MSGC Create modifiable message text
LH R15,RC_MSGCN(R2) Get printable R/C
STH R15,RC_MSGDN Save in modifiable text
MVC WTO_PLD(WTO_PLL),WTO_PLC Create modifiable WTO plist
WTO TEXT=RC_MSGD,ROUTCDE=11,MF=(E,WTO_PLD)
B DO_TERM Bypass CALL_MAIN
INIT_OK EQU *
*
*
* Do CELQPIPI CALL_MAIN
* ---------------------
*
WTO 'CEEWQPIP: Doing CELQPIPI CALL_MAIN',ROUTCDE=11
*
LG R15,CELQPIPI_EP Address of CELQPIPI E.P.
*
CALL (15), X
(CALL_MAIN, CELQPIPI CALL_MAIN request X
CEEXPTL_INDEX, CELQPIPI table index (= 0) X
TOKEN, Token from INIT_MAIN X
RUNTIME_OPTS, Runtime Options X
PARM_PTR, Ptr to C main() parmlist X
ENCLAVE_RETURN_CODE, Enclave return code X
ENCLAVE_REASON_CODE, Enclave reason code X
APPL_FEEDBACK_CODE), Application feedback code X
MF=(E,CALL_PL)
*
*
* Check results of CALL_MAIN
*
LTR R2,R15 Check CELQPIPI R/C
BZ CALL_OK Bypass message, if OK
WTO 'CEEWQPIP: CELQPIPI CALL_MAIN failed',ROUTCDE=11
MVC RC_MSGD,RC_MSGC Create modifiable message text
LH R15,RC_MSGCN(R2) Get printable R/C
STH R15,RC_MSGDN Save in modifiable text
MVC WTO_PLD(WTO_PLL),WTO_PLC Create modifiable WTO plist
WTO TEXT=RC_MSGD,ROUTCDE=11,MF=(E,WTO_PLD)
CALL_OK EQU *
*
** Do CELQPIPI TERM
* ----------------
*
DO_TERM EQU *
WTO 'CEEWQPIP: Doing CELQPIPI TERM',ROUTCDE=11
*
LG R15,CELQPIPI_EP Address of CELQPIPI E.P.
*
CALL (15), X
(TERM, CELQPIPI TERM request X
TOKEN, Token from INIT_MAIN X
ENV_RETURN_CODE), Environment return code X
MF=(E,CALL_PL)
*
LTR R2,R15 Check CELQPIPI R/C
BZ TERM_OK Bypass message, if OK
WTO 'CEEWQPIP: CELQPIPI TERM failed',ROUTCDE=11
TERM_OK EQU *
*
*
* Return to caller with R/C=0
* ---------------------------
*
WTO 'CEEWQPIP: Returning',ROUTCDE=11
*
LGR R1,R13 Addr for FREEMAIN
LG R13,SAVF4SAPREV-SAVF4SA(,R13) Caller's DSA addr
FREEMAIN RU,A=(1),LV=1024 Get rid of DSA
LA R15,0 Set R/C = 0
LG R14,SAVF4SAG64RS14-SAVF4SA(,R13) Restore R14
LMG R0,R12,SAVF4SAG64RS0-SAVF4SA(R13) Restore R0-R12
SAM31 ,
BR R14 Return to caller
*
*
* ----------------
* Static constants
* ----------------
*
LTORG ,
*
INIT_MAIN DC F'1' Initialize for main routines
CALL_MAIN DC F'2' Call main routine
TERM DC F'5' Terminate
*
RC_MSGC DS 0CL28
DC AL2(26)
DC C' CELQPIPI R/C: nn'
RC_MSGCN DC C'00..04..08..12..16..20..24..28..32..36..'
DC C'40..44..48..52..56..60..64..68..72..76..'
*
WTO_PLC WTO TEXT=RC_MSGD,ROUTCDE=11,MF=L
*
CEEXPTBL_ADDR DC AD(CEEXPTBL) Address of PIPI table
CEEXPTL_INDEX DC AD(0) 1st row of CEEXPTBL = 0
*
RUNTIME_OPTS DC CL255'POSIX(ON)'
PARM_PTR DC AD(P_PLIST)
*
** CELQPIPI service routine vector (static copy)
*
DS 0D
SV_STATIC DS 0XL80 10 doublewords
SV_RES DC A(0) Reserved (must be 0)
SV_COUNT DC A(9) 9 entries in service vector
SV_UWORD_ DC AD(*-*) Will be filled in at runtime
SV_2 DC AD(0) Reserved (must be 0)
SV_LOAD DC AD(FD_L) Pointer to FD for LOAD routine
SV_DELETE DC AD(FD_D) Pointer to FD for DELETE routine
SV_GETSTOR DC AD(FD_G) Pointer to FD for GETSTORE routine
SV_FREESTOR DC AD(FD_F) Pointer to FD for FREESTOR routine
SV_7 DC AD(0) Reserved (must be 0)
SV_8 DC AD(0) Reserved (must be 0)
SV_MSGRTN DC AD(FD_M) Pointer to FD for MSGRTN routine
*
*
* Function Descriptor for CEEWQLOD (load replacement)
*
EXTRN CEEWQLOD
CEEWQLOD XATTR LINKAGE(XPLINK),REFERENCE(CODE)
*
DS 0D
FD_L DS 0CL16
DC RD(CEEWQLOD) PSECT Address
DC AD(CEEWQLOD) E.P. Address
*
** Function Descriptor for CEEWQDEL (delete replacement)
*
EXTRN CEEWQDEL
CEEWQDEL XATTR LINKAGE(XPLINK),REFERENCE(CODE)
*
DS 0D
FD_D DS 0CL16
DC RD(CEEWQDEL) PSECT address
DC AD(CEEWQDEL) E.P. Address
*
* Function Descriptor for CEEWQGST (getstore replacement)
*
EXTRN CEEWQGST
CEEWQGST XATTR LINKAGE(XPLINK),REFERENCE(CODE)
*
DS 0D
FD_G DS 0CL16
DC RD(CEEWQGST) PSECT address
DC AD(CEEWQGST) E.P. Address
*
* Function Descriptor for CEEWQFST (freestore replacement)
*
EXTRN CEEWQFST
CEEWQFST XATTR LINKAGE(XPLINK),REFERENCE(CODE)
*
DS 0D
FD_F DS 0CL16
DC RD(CEEWQFST) PSECT address
DC AD(CEEWQFST) E.P. Address
*
* Function Descriptor for CEEWQMSG (msgrtn replacement)
*
EXTRN CEEWQMSG
CEEWQMSG XATTR LINKAGE(XPLINK),REFERENCE(CODE)
*
DS 0D
FD_M DS 0CL16
DC RD(CEEWQMSG) PSECT address
DC AD(CEEWQMSG) E.P. Address
*
** CELQPIPI table (with 1 static entry)
*
CEEXPTBL CELQPIT , Start of CELQPIPI table
CELQPITY CEEWQPMA,0 Dynamically load CEEEQPMA
CELQPITS , End of CELQPIPI table
*
*
* Parmlist for C main()
*
DS 0D
P_PLIST DS 0XL16
P_ARGC DC FD'3' argc = 3
P_ARGV DC AD(P_ARG) pointer to argv
*
DS 0D
P_ARG DS 0XL16 argv
P_ARG0 DC AD(P_NAMEBUF) argv[0]
P_ARG1 DC AD(P_ARGBUF1) argv[1]
P_ARG2 DC AD(P_ARGBUF2) argv[2]
DC AD(0)
*
P_NAMEBUF DS 0CL9 argv[0]
DC CL8'ceewqpma' program name
DC XL1'0' NULL terminator
*
P_ARGBUF1 DS 0CL6 argv[1]
DC CL5'Parm1' 1st parm = "Parm1"
DC XL1'0' NULL terminator
*
P_ARGBUF2 DS 0CL6 argv[2]
DC CL5'Parm2' 2nd parm = "Parm2"
DC XL1'0' NULL terminator
DS 0D
*
** -----------------------------------
* DSA (below the bar, due to GETMAIN)
* -----------------------------------
*
DSA DSECT ,
DS CL(SAVF4SA_LEN) F4 savearea
DS 0D
*
CELQPIPI_EP DS AD Address of CELQPIPI E.P.
TOKEN DS AD Token (from INIT_MAIN)
SERVICE_RTNS DS AD Address of Service vector
APPL_FEEDBACK_CODE DS 2AD Fdbk code from CALL_MAIN
ENCLAVE_RETURN_CODE DS F Return code from CALL_MAIN
ENCLAVE_REASON_CODE DS F Reason code from CALL_MAIN
ENV_RETURN_CODE DS F Rtn code from CELQPIPI TERM
*
RC_MSGD DS 0CL28 Return code message for WTO
DS CL2 Text length = 26
DS CL24 ' CELQPIPI R/C: '
RC_MSGDN DS CL2 'nn'
*
DS 0D
SV_DYNAMIC DS 0XL(L'SV_STATIC) Modifiable service vector
DS AD 0000000 + count
SV_UWORD DS AD User word
DS AD doubleword 2
DS AD doubleword 3
DS AD doubleword 4
DS AD doubleword 5
DS AD doubleword 6
DS AD doubleword 6
DS AD doubleword 7
DS AD doubleword 8
DS AD doubleword 9
*
DS 0D
CALL_PL CALL ,(,,,,,,,),MF=L 8-parm CALL parmlist
*
DS 0D
WTO_PLD WTO TEXT=RC_MSGD,ROUTCDE=11,MF=L
WTO_PLL EQU *-WTO_PLD
*
DS 0D
USER_AREA DS XL1000 1000-byte below-the-bar
* workarea for LOAD and
* DELETE replacement routines
DS 0D
DSA_L EQU *-DSA Length of DSA
*
*
* --------------------------
* Control Blocks and equates
* --------------------------
*
YREGS ,
IHASAVER ,
*
END
A sample AMODE 64 Assembler LOAD replacement service routine, CEEWQLOD, can be found in SCEESAMP(CEEWQLOD).
A sample AMODE 64 Assembler DELETE replacement service routine, CEEWQDEL, can be found in SCEESAMP(CEEWQDEL).
A sample AMODE 64 Assembler GETSTORE replacement service routine, CEEWQGST, can be found in SCEESAMP(CEEWQGST).
A sample AMODE 64 Assembler FREESTORE replacement service routine, CEEWQFST, can be found in SCEESAMP(CEEWQFST).
A sample AMODE 64 Assembler MSGRTN replacement service routine, CEEWQMSG, can be found in SCEESAMP(CEEWQMSG).
The following example is a sample AMODE 64 C main routine.
/*********************************************************************
*
*
* ======== ------------------------------
* CEEWQPMA -- Sample AMODE64 PreInit program
* ======== ------------------------------
*
*
* This program is invoked with two parms (always assumed present)
* by the CEEWQPIP AMODE64 PreInit driver program.
*
*
*
* Processing is:
*
* 1) Print out POSIX(ON/OFF) state to verify POSIX(ON) runtime
* option.
*
* 2) Print out first two parms
*
* 3) Issue perror() to cause a LOAD request (and later DELETE)
*
*
*********************************************************************/
#define _XOPEN_SOURCE_EXTENDED 1
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char * argv[])
{
printf("\nCEEWQPMA: Called -- __isPosixOn()=%d\n", __isPosixOn());
printf("CEEWQPMA: main() argc = %d\n" , argc );
printf(" argv[0]= \"%s\"\n" , argv[0];
printf(" argv[1]= \"%s\"\n" , argv[1];
printf(" argv[2]= \"%s\"\n\n", argv[2];
errno = ESTALE;
perror("CEEWQPMA: Test message");
printf("\nCEEWQPMA: Returning\n");
return 0;
}