Hi Tom,
Happy to help if I can. It's been a while since I wrote an exit using __4kmalc
, so this is doing a little brain archaeology!
Looking at your module map in the attached file, I can see the EDCXMEM map does contain the entry for __4kmalc - it's entry point name is @@4KMALC because the IBM z/OS XL C/C++ compiler automatically maps all underscores and lowercase letters in external identifiers in source code to '@' characters and uppercase characters in the object deck[ref].
SECTION CLASS ------- SOURCE --------
OFFSET OFFSET NAME TYPE LENGTH DDNAME SEQ MEMBER
300 EDCXMEM CSECT 508 SYSLIB 01 EDCXMEM
0 300 @@24MALC LABEL
48 348 MALLOC LABEL
F0 3F0 @@4KMALC LABEL
1E0 4E0 FREE LABEL
2F8 5F8 CALLOC LABEL
3C0 6C0 REALLOC LABEL
And yet, the bind step fails with this error:
IEW2456E 9207 SYMBOL __4kmalc UNRESOLVED. MEMBER COULD NOT BE INCLUDED FROM THE DESIGNATED CALL LIBRARY.
It seems like something might be stopping the above mentioned mapping of lowercase letters.
Looking at your invocation parameters:
IEW2278I B352 INVOCATION PARAMETERS - AMODE=31,MAP,RENT,DYNAM=DLL,CASE=MIXED,AMODE=31,MAP,XREF,DYNAM=NO
I wonder if it might be the CASE=MIXED
parameter.
The description of this binder option is thus:-
CASE: Case control option
You can control the binder's sensitivity to case by coding the CASE option as follows:
CASE={UPPER| MIXED}
The case can be either
UPPER
or
MIXED
. When
CASE=MIXED
is specified,
- The binder distinguishes between upper and lower case letters, treating two strings as different if their cases do not match exactly.
- The binder does not convert any lowercase letters in names encountered in input modules, control statements, and binder options.
Binder keywords are always converted to upper case.
CASE=UPPER
is the default value, causing conversion of all lower case letters to upper case during binder processing.
However, it is highly likely that you are using this option for a good reason. So perhaps instead of changing that, you can directly map the function name to the external symbol with something like this:
#pragma map (__4kmalc, "@@4KMALC")
In case it doesn't like @@
I've seen some code do this as follows, which I assume is because the compiler doesn't like the codepage your C part is in and messes up the @ symbols, but I don't actually understand exactly how this works because 174 is not the value in any EBCDIC codepage for the @ symbol. I include it just in case.
#pragma map (__4kmalc, "\174\1744KMALC")
Anyway, hope some of this helps.
Cheers,
Morag
------------------------------
Morag Hughson
MQ Technical Education Specialist
MQGem Software Limited
Website:
https://www.mqgem.com------------------------------
Original Message:
Sent: Mon March 01, 2021 04:03 PM
From: Tom Kane
Subject: how to call 4kmalc() from security exit on ZOS
Hi Morag,
Thanks for replying!
Tom
I've oversimplified. I'm trying to replace BLOCKIPM with __4kmalc(). It looks like I did find EDCXMEM in the link.
And yes, there is cleanup in MQXR_TERM. thanks for the reminder.
Attached is the binder output. I'm wondering if I have all the needed #pragmas
Here's what I've got in that area:
#include <cmqc.h> #include <cmqxc.h> #if (MQAT_DEFAULT == MQAT_WINDOWS_NT ) /* Windows specific definitions */ #pragma optimize("", off) #include <windows.h> #define ENV "WIN" #define MCAUSERID_LENGTH 64 #elif (MQAT_DEFAULT == MQAT_UNIX ) #define ENV "UNIX" #define MCAUSERID_LENGTH 12 #include <syslog.h> #elif (MQAT_DEFAULT == MQAT_MVS ) #define ENV "MVS" #pragma csect(code, "SSLMAPC") #pragma csect(static,"SSLAUTWS") #pragma csect(test, "SSLMAPT") #pragma runopts(trap(off),PLIST(MVS)) #pragma environment(SSLMAP) #pragma linkage (BLOCKIPW,OS) #define MCAUSERID_LENGTH MQ_USER_ID_LENGTH #define _XOPEN_SOURCE_EXTENDED 1 #define _OPEN_SYS_SOCK_IPV6 #include <spc.h> #include <sys/time.h> #endif #ifdef __MVS__ #include <spc.h> #else #include <malloc.h> #include <stdlib.h> #endif #include <stdio.h> #include <string.h> #include <ctype.h> #include <time.h> #include <assert.h>
------------------------------
Tom Kane
Senior Technical Team Lead
AT&T
Kansas City
Original Message:
Sent: Mon March 01, 2021 03:33 PM
From: Morag Hughson
Subject: how to call 4kmalc() from security exit on ZOS
If you're replacing malloc() with __4kmalc() then I'd imagine you'd already had EDCXMEM in the link? Can you show a bit more of your link step output. Did it find EDCXMEM for example? Were there any other errors in the link at all?
You need other #pragmas for the exit, but I don't remember any specific ones for __4kmalc(). You'll already have the #pragma environment statements if it was working before I assume?
You're doing this switch, I assume, to ensure the obtained storage stays around for each invocation of the exit. Have you remembered to free it in the MQXR_TERM call?
Cheers,
Morag
------------------------------
Morag Hughson
MQ Technical Education Specialist
MQGem Software Limited
Website: https://www.mqgem.com
Original Message:
Sent: Mon March 01, 2021 02:09 PM
From: Tom Kane
Subject: how to call 4kmalc() from security exit on ZOS
I've got our legacy security exit on multiple platforms that I'm trying to rebuild. Right now I'm interested in moving from the BLOCKIPM storage allocation routine to 4kmalc() but finding no doc about how to actually do it.
Are there #pragma or other compiler directives needed?
I'm trying to:
include the spc.h
I use __4kmalc() instead of malloc()
and I link in EDCXMEM.
I get:
Thanks in advance.
Tom
------------------------------
Tom Kane
Senior Technical Team Lead
AT&T
Kansas City
------------------------------