Re: How call from C++ thru function pointer to assembler?
David - THANK YOU! I was about one try this away from bailing and writing a linkage stub in assembler. I know typedef is your friend. I started out with a typedef but at some point bailed on that approach because of the extern must be at module level issue. Just in case someone is searching this thread five years from now, the typedef actually needs a void in it: extern OS { typedef void (*entryPoint_t)(const char *record); } You can now see the direct BASR 14,15 in the generated code: 000139 | *(entryPoint)(record); 4400 C1AC000139 | EX r0,HOOK..STMT 5800 D0C4000139 | Lr0,record(,r13,196) 5870 D0A8000139 | Lr7,entryPoint(,r13,168) A50A 8000000139 | OILH r0,H'-32768' 4110 D098000139 | LA r1,#MX_TEMP2(,r13,152) 5070 D098000139 | ST r7,#MX_TEMP2(,r13,152) 5000 D09C000139 | ST r0,#MX_TEMP2(,r13,156) 58F0 363A000139 | Lr15,1594(,r3) 4400 C1C0000139 | EX r0,HOOK..CALLBGN 0DEF 000139 | BASR r14,r15 THANKS AGAIN! Charles -Original Message- From: IBM Mainframe Discussion List [mailto:IBM-MAIN@LISTSERV.UA.EDU] On Behalf Of David Crayford Sent: Monday, July 16, 2012 9:57 PM To: IBM-MAIN@LISTSERV.UA.EDU Subject: Re: How call from C++ thru function pointer to assembler? On 17/07/2012 11:35 AM, Charles Mills wrote: David, thanks, will try again tomorrow. Does it perhaps want to factor differently? Perhaps something more like (*extern OS entryPoint)(const char *); or something? Otherwise aren't you saying that the pointer itself is extern? What you need is a typedef extern OS { typedef (*entryPoint_t)(const char * arg); } entryPoint_t entryPoint = (entryPoint_t)cvt-entryPoint; Don't let me confuse the issue -- it is not CSRSI that I am calling. Header for CSRSI is in SYS1.SAMPLIB somewhere but is printed in the callable services manual. They have something they call csrsi_byaddr that looks exactly like what I am trying to accomplish but it is bracketed with #ifndef __cplusplus which is what leads me to think that perhaps this linkage is not supported for C++. I understand. If you are using a function pointer to a function that has not been loaded via fetch() then DLL(CBA) is required. Every function call in C++ is essentially a DLL call, so they require an FCB (function control block). There is overhead associated with DLL(CBA) so try to localize it to the module that calls the function. -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN
How call from C++ thru function pointer to assembler?
Does anyone know the answer to this? I have an assembler function whose address I know at run-time in C++. I define and store it like this void __cdecl (*entryPoint)(const char *); entryPoint = (void (__cdecl *)(const char *))(myVoidStar); printf(entryPoint is %p\n, entryPoint); Printf prints the correct address (DFFD058, FWIW) so I am good so far. I then call it with (entryPoint)(record); and I end up S0C6ing out in the weeds at 27F5023B. Here is the pseudo-assembler from the C++ compiler. 4400 C1AC000114 | EX r0,HOOK..STMT 5870 D0C0000114 | Lr7,record(,r13,192) 5810 D0C8000114 | Lr1,#CEECAACRENT_2(, 5880 35DA000114 | Lr8,=Q(entryPoint)(, 4118 1000000114 | LA r1,=Q(entryPoint)(r 5810 1000000114 | Lr1,entryPoint(,r1,0 58F0 1008000114 | Lr15,EPA_WSA(,r1,8 5800 100C000114 | Lr0,EPA_WSA(,r1,12 5000 C1F4000114 | ST r0,_CEECAA_(,r12,50 4110 D098000114 | LA r1,#MX_TEMP2(,r13,1 5070 D098000114 | ST r7,#MX_TEMP2(,r13,1 4400 C1C0000114 | EX r0,HOOK..CALLBGN 0DEF 000114 | BASR r14,r15 4400 C1C4000114 | EX r0,HOOK..CALLRET Does anyone know what I should be declaring or doing differently? (If all else fails I will just write a stub in assembler to do this. I know how to L 15 BALR 14,15 in assembler g.) Charles -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN
Re: How call from C++ thru function pointer to assembler?
I suggest investigating the CALLBACKANY compiler option. On 17/07/2012, at 8:13 AM, Charles Mills charl...@mcn.org wrote: Does anyone know the answer to this? I have an assembler function whose address I know at run-time in C++. I define and store it like this void __cdecl (*entryPoint)(const char *); entryPoint = (void (__cdecl *)(const char *))(myVoidStar); printf(entryPoint is %p\n, entryPoint); Printf prints the correct address (DFFD058, FWIW) so I am good so far. I then call it with (entryPoint)(record); and I end up S0C6ing out in the weeds at 27F5023B. Here is the pseudo-assembler from the C++ compiler. 4400 C1AC000114 | EX r0,HOOK..STMT 5870 D0C0000114 | Lr7,record(,r13,192) 5810 D0C8000114 | Lr1,#CEECAACRENT_2(, 5880 35DA000114 | Lr8,=Q(entryPoint)(, 4118 1000000114 | LA r1,=Q(entryPoint)(r 5810 1000000114 | Lr1,entryPoint(,r1,0 58F0 1008000114 | Lr15,EPA_WSA(,r1,8 5800 100C000114 | Lr0,EPA_WSA(,r1,12 5000 C1F4000114 | ST r0,_CEECAA_(,r12,50 4110 D098000114 | LA r1,#MX_TEMP2(,r13,1 5070 D098000114 | ST r7,#MX_TEMP2(,r13,1 4400 C1C0000114 | EX r0,HOOK..CALLBGN 0DEF 000114 | BASR r14,r15 4400 C1C4000114 | EX r0,HOOK..CALLRET Does anyone know what I should be declaring or doing differently? (If all else fails I will just write a stub in assembler to do this. I know how to L 15 BALR 14,15 in assembler g.) Charles -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN
Re: How call from C++ thru function pointer to assembler?
Why the __cdecl instead of extern OS? On 17/07/2012, at 8:34 AM, Charles Mills charl...@mcn.org wrote: Wow! Fast answer, and looked very promising, but no change in behavior. Added DLL(CBA) to my options. Charles -Original Message- From: IBM Mainframe Discussion List [mailto:IBM-MAIN@LISTSERV.UA.EDU] On Behalf Of David Crayford Sent: Monday, July 16, 2012 5:19 PM To: IBM-MAIN@LISTSERV.UA.EDU Subject: Re: How call from C++ thru function pointer to assembler? I suggest investigating the CALLBACKANY compiler option. On 17/07/2012, at 8:13 AM, Charles Mills charl...@mcn.org wrote: Does anyone know the answer to this? I have an assembler function whose address I know at run-time in C++. I define and store it like this void __cdecl (*entryPoint)(const char *); entryPoint = (void (__cdecl *)(const char *))(myVoidStar); printf(entryPoint is %p\n, entryPoint); Printf prints the correct address (DFFD058, FWIW) so I am good so far. I then call it with (entryPoint)(record); and I end up S0C6ing out in the weeds at 27F5023B. Here is the pseudo-assembler from the C++ compiler. 4400 C1AC000114 | EX r0,HOOK..STMT 5870 D0C0000114 | Lr7,record(,r13,192) 5810 D0C8000114 | Lr1,#CEECAACRENT_2(, 5880 35DA000114 | Lr8,=Q(entryPoint)(, 4118 1000000114 | LA r1,=Q(entryPoint)(r 5810 1000000114 | Lr1,entryPoint(,r1,0 58F0 1008000114 | Lr15,EPA_WSA(,r1,8 5800 100C000114 | Lr0,EPA_WSA(,r1,12 5000 C1F4000114 | ST r0,_CEECAA_(,r12,50 4110 D098000114 | LA r1,#MX_TEMP2(,r13,1 5070 D098000114 | ST r7,#MX_TEMP2(,r13,1 4400 C1C0000114 | EX r0,HOOK..CALLBGN 0DEF 000114 | BASR r14,r15 4400 C1C4000114 | EX r0,HOOK..CALLRET Does anyone know what I should be declaring or doing differently? -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN
Re: How call from C++ thru function pointer to assembler?
1. If I code the declaration as extern C void (*entryPoint)(const SMFrecd *); (did not try OS but it would have the same problem I think) then that is the declaration of an external function, not the definition of a pointer, right? In any event I get unresolved extern's on entryPoint at link time. There is no such syntax, I believe, as just OS without the extern. 2. It won't allow extern C (and again, I think extern OS would be the same) in the cast. It says all linkage declarations must be at the module level or something like that. Charles -Original Message- From: IBM Mainframe Discussion List [mailto:IBM-MAIN@LISTSERV.UA.EDU] On Behalf Of David Crayford Sent: Monday, July 16, 2012 6:09 PM To: IBM-MAIN@LISTSERV.UA.EDU Subject: Re: How call from C++ thru function pointer to assembler? Why the __cdecl instead of extern OS? On 17/07/2012, at 8:34 AM, Charles Mills charl...@mcn.org wrote: Wow! Fast answer, and looked very promising, but no change in behavior. Added DLL(CBA) to my options. Charles -Original Message- From: IBM Mainframe Discussion List [mailto:IBM-MAIN@LISTSERV.UA.EDU] On Behalf Of David Crayford Sent: Monday, July 16, 2012 5:19 PM To: IBM-MAIN@LISTSERV.UA.EDU Subject: Re: How call from C++ thru function pointer to assembler? I suggest investigating the CALLBACKANY compiler option. On 17/07/2012, at 8:13 AM, Charles Mills charl...@mcn.org wrote: Does anyone know the answer to this? I have an assembler function whose address I know at run-time in C++. I define and store it like this void __cdecl (*entryPoint)(const char *); entryPoint = (void (__cdecl *)(const char *))(myVoidStar); printf(entryPoint is %p\n, entryPoint); Printf prints the correct address (DFFD058, FWIW) so I am good so far. I then call it with (entryPoint)(record); and I end up S0C6ing out in the weeds at 27F5023B. Here is the pseudo-assembler from the C++ compiler. 4400 C1AC000114 | EX r0,HOOK..STMT 5870 D0C0000114 | Lr7,record(,r13,192) 5810 D0C8000114 | Lr1,#CEECAACRENT_2(, 5880 35DA000114 | Lr8,=Q(entryPoint)(, 4118 1000000114 | LA r1,=Q(entryPoint)(r 5810 1000000114 | Lr1,entryPoint(,r1,0 58F0 1008000114 | Lr15,EPA_WSA(,r1,8 5800 100C000114 | Lr0,EPA_WSA(,r1,12 5000 C1F4000114 | ST r0,_CEECAA_(,r12,50 4110 D098000114 | LA r1,#MX_TEMP2(,r13,1 5070 D098000114 | ST r7,#MX_TEMP2(,r13,1 4400 C1C0000114 | EX r0,HOOK..CALLBGN 0DEF 000114 | BASR r14,r15 4400 C1C4000114 | EX r0,HOOK..CALLRET Does anyone know what I should be declaring or doing differently? -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN
Re: How call from C++ thru function pointer to assembler?
Another way of saying what I am trying to do is what you do if you are calling from C++ any MVS callable service or something like that using the pointer somewhere off of the CVT. Looking at the header file for CSRSI it looks like perhaps you can't do it from C++. Charles -Original Message- From: IBM Mainframe Discussion List [mailto:IBM-MAIN@LISTSERV.UA.EDU] On Behalf Of Charles Mills Sent: Monday, July 16, 2012 5:14 PM To: IBM-MAIN@LISTSERV.UA.EDU Subject: How call from C++ thru function pointer to assembler? Does anyone know the answer to this? I have an assembler function whose address I know at run-time in C++. I define and store it like this void __cdecl (*entryPoint)(const char *); entryPoint = (void (__cdecl *)(const char *))(myVoidStar); printf(entryPoint is %p\n, entryPoint); Printf prints the correct address (DFFD058, FWIW) so I am good so far. I then call it with (entryPoint)(record); and I end up S0C6ing out in the weeds at 27F5023B. Here is the pseudo-assembler from the C++ compiler. 4400 C1AC000114 | EX r0,HOOK..STMT 5870 D0C0000114 | Lr7,record(,r13,192) 5810 D0C8000114 | Lr1,#CEECAACRENT_2(, 5880 35DA000114 | Lr8,=Q(entryPoint)(, 4118 1000000114 | LA r1,=Q(entryPoint)(r 5810 1000000114 | Lr1,entryPoint(,r1,0 58F0 1008000114 | Lr15,EPA_WSA(,r1,8 5800 100C000114 | Lr0,EPA_WSA(,r1,12 5000 C1F4000114 | ST r0,_CEECAA_(,r12,50 4110 D098000114 | LA r1,#MX_TEMP2(,r13,1 5070 D098000114 | ST r7,#MX_TEMP2(,r13,1 4400 C1C0000114 | EX r0,HOOK..CALLBGN 0DEF 000114 | BASR r14,r15 4400 C1C4000114 | EX r0,HOOK..CALLRET Does anyone know what I should be declaring or doing differently? (If all else fails I will just write a stub in assembler to do this. I know how to L 15 BALR 14,15 in assembler g.) Charles -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN
Re: How call from C++ thru function pointer to assembler?
David, thanks, will try again tomorrow. Does it perhaps want to factor differently? Perhaps something more like (*extern OS entryPoint)(const char *); or something? Otherwise aren't you saying that the pointer itself is extern? Don't let me confuse the issue -- it is not CSRSI that I am calling. Header for CSRSI is in SYS1.SAMPLIB somewhere but is printed in the callable services manual. They have something they call csrsi_byaddr that looks exactly like what I am trying to accomplish but it is bracketed with #ifndef __cplusplus which is what leads me to think that perhaps this linkage is not supported for C++. No, have not taken the XPLINK leap. One of these days. Charles -Original Message- From: IBM Mainframe Discussion List [mailto:IBM-MAIN@LISTSERV.UA.EDU] On Behalf Of David Crayford Sent: Monday, July 16, 2012 7:17 PM To: IBM-MAIN@LISTSERV.UA.EDU Subject: Re: How call from C++ thru function pointer to assembler? extern OS (*entryPoint)(const char *) is the correct declaration for C++. I have called OS linkage functions from the CVT in C++ without problems. Where is the header file for CSRSI? Are you XPLINK? On 17/07/2012 10:10 AM, Charles Mills wrote: Another way of saying what I am trying to do is what you do if you are calling from C++ any MVS callable service or something like that using the pointer somewhere off of the CVT. Looking at the header file for CSRSI it looks like perhaps you can't do it from C++. Charles -Original Message- From: IBM Mainframe Discussion List [mailto:IBM-MAIN@LISTSERV.UA.EDU] On Behalf Of Charles Mills Sent: Monday, July 16, 2012 5:14 PM To: IBM-MAIN@LISTSERV.UA.EDU Subject: How call from C++ thru function pointer to assembler? Does anyone know the answer to this? I have an assembler function whose address I know at run-time in C++. I define and store it like this void __cdecl (*entryPoint)(const char *); entryPoint = (void (__cdecl *)(const char *))(myVoidStar); printf(entryPoint is %p\n, entryPoint); Printf prints the correct address (DFFD058, FWIW) so I am good so far. I then call it with (entryPoint)(record); and I end up S0C6ing out in the weeds at 27F5023B. -- For IBM-MAIN subscribe / signoff / archive access instructions, send email to lists...@listserv.ua.edu with the message: INFO IBM-MAIN