"I'd be perfectly happy for someone to tell me I missed some obvious
compiler option or did something else really stupid."

Found this on another website ...

The issue was with the search order. Although I did
search(/usr/metal/include) from with in my JCL I didn't proceed it with a
nosearch option, so string.h was getting picked up from the standard system
libraries instead of the version included with Metal C. I've pasted my
optfile dataset I passed to the CPARM below for reference.

//OPTIONS DD *
 SO
 LIST
 LONG
 NOXREF
 CSECT
 METAL
 LP64
 NOSEARCH
 search(/usr/include/metal/)

Joe

On Mon, Jan 11, 2021 at 12:39 PM Dennis Fitzpatrick <den...@dcfitz.com>
wrote:

> I'm a developer working with a client to develop Metal C functions for
> their products. Up until recently I've defined __METAL_STATIC and linked
> with SCCR3BND. I decided recently to play with the dynamic library in
> LPALIB so I removed that #define. What I'm getting is compile errors on the
> substitution macros from metal.h. That is the first problem. I decided to
> try and circumvent the compile errors and I think I found a bug in the
> memcmp library function. That is the second problem. I'm really hoping
> someone will tell me I missed something really obvious or missed some
> maintenance.
>
> I created a trivial sample program to demonstrate:
>
> /*
>   Sample for Metal C
> */
>
> #include <stdio.h>
> #include <stdlib.h>
>
> int main(int argc, char** argv)
> {
>   char* xarg = "abcd";
>   void *mem = malloc(64);
>   memset(mem, 0x0f, 64);
>   memcpy(mem, xarg, sizeof(xarg));
>   int mcmp = memcmp(mem, xarg, sizeof(xarg));
>   free(mem);
> }
> Of course, this compiles and runs just fine on Visual Studio where I do my
> initial development. On z/OS XLC though I get errors like the following:
>
>     12       |  memset(mem, 0x0f, 64);
>                                       |     12
>     12       +  ((___MEMSET * ) ( (*(struct __cvt_s * __ptr32 *
> __ptr32)16) -> __cvtecvt -> __ecvtsdc -> __sdca\+     12
> ===========>
> ....b...........a.................................................................................
> *=ERROR===========> a - CCN3275 Unexpected text ')' encountered.
> *=ERROR===========> b - CCN3045 Undeclared identifier ___MEMSET.
>     12       +libv31 -> __libfunc[33] ))(mem, 0x0f, 64);
>                                       +     12
> ===========>
> .........................................c........................................................
> *=ERROR===========> c - CCN3277 Syntax error: possible missing ')' or ','?
>
> The header file include list is exactly what I expect:
>
>                         1   /usr/include/metal/stdio.h
>                         2   /usr/include/metal/metal.h
>                         3   /usr/include/metal/stddef.h
>                         4   /usr/include/metal/stdlib.h
>                         5   /usr/include/metal/builtins.h
>
> Looking through all of the layers in the metal.h header started me looking
> for aspirin. I decided to push forward as an exercise by defining my own
> structures to use the Metal C function vector. I already had many of the
> standard z/OS structures mapped and added my own mapping of sys_libv31_s
> with real function prototypes:
>
> struct sys_libv31_s
> {
>   void (*_em_0)();
>   int (*_em_abs)(int,int); // 1
>   int (*_em_atoi)(char*); // 2
>   long (*_em_atol)(char*); // 3
>   long long (*_em_atoll)(char*); // 4
>   void* (*_em_calloc)(size_t); // 5
>
> And my own substitution macros to remove the metal.h definition and put in
> my own EMCALL reference:
>
> #define EMCALL(_t, _n)
> (##_t)(*(CVTPTR->CVTECVT->ECVTSDC->sdcalibv31->_em_##_n))
> #define em_0  EMCALL(void, em_0)
> #undef abs // 1
> #define abs EMCALL(int, abs)
> #undef atoi // 2
> #define atoi EMCALL(int atoi)
> #undef atol // 3
> #define atol EMCALL(long, atol)
> #undef atoll // 4
> #define atoll EMCALL(long long, atoll)
> #undef calloc // 5
> #define calloc EMCALL(void *, calloc)
>
> I can't give you the whole thing as it is too much to extract from client
> proprietary material. Hopefully, this is enough to get the gist.
>
> Now this is where I believe I found a bug in the memcmp function returning
> an invalid result and also a potential S0C4. With getting all of my code to
> compile I found things taking some weird code paths. I tracked it down to a
> memcmp and setup the code in the sample above to test it. I found the
> memcmp above returns an invalid result, 0x0f, even though the memory is
> equal. I went into TEST and disassembled the code and got this:
>
>
> 1F24CD78.    STM     R14,R3,12(R13)
>
> 1F24CD7C.    LR      R15,R13
>
> 1F24CD7E.    L       R13,8(,R13)
>
> 1F24CD82.    ST      R15,4(,R13)
>
> 1F24CD86.    STMH    R14,R3,80(R13)
>
> 1F24CD8C.    L       R14,0(,R1)
>
> 1F24CD90.    L       R2,4(,R1)
>
> 1F24CD94.    ICM     R0,15,8(R1)
>
> 1F24CD98.    BRC     8,*+52
>
> 1F24CD9C.    LR      R1,R0
>
> 1F24CD9E.    LLGC    R15,0(,R14)
>
> 1F24CDA4.    LLGC    R3,0(,R2)
>
> 1F24CDAA.    LA      R14,1(,R14)
>
> 1F24CDAE.    LA      R2,1(,R2)
>
> 1F24CDB2.    CR      R15,R3
>
> 1F24CDB4.    BRC     7,*+36
>
> 1F24CDB8.    LLGC    R15,0(,R14)
>
> 1F24CDBE.    LLGC    R3,0(,R2)
>
> 1F24CDC4.    BRCT    R1,*-26
>
> 1F24CDC8.    BRC     15,*+16
>
> 1F24CDCC.    LLGC    R15,0(,R14)
>
> 1F24CDD2.    LLGC    R3,0(,R2)
>
> 1F24CDD8.    SLR     R15,R3
>
> 1F24CDDA.    LMH     R14,R3,80(R13)
>
> 1F24CDE0.    L       R13,4(,R13)
>
> 1F24CDE4.    L       R14,12(,R13)
>
> 1F24CDE8.    LM      R1,R3,24(R13)
>
> 1F24CDEC.    BCR     15,R14
>
> The important thing is that the loop uses R14 & R2 as the character
> pointers and R1 as the count. The loop at D9E loads the first bytes of each
> memory area. Then it increments the pointers, does the compare, and if NE
> branches to *+36 (DCC). It then reloads R15 & R3 but the pointers have
> already been incremented. It calculates the difference of the two bytes as
> the return value. This gets the two random bytes after the memory area to
> compute the result which is an incorrout and a possible S0C4. Similarly, it
> uses those same next bytes if the result is BRC NE falls through giving
> random results and/or S0C4 if the strings are equal.
>
> I thought I was totally delusional at this point since how could any code
> work if the memcmp library function was bad. Then I further found that
> metal/builtin.h overrides the library call and causes a fair number of
> these critical library functions to be inlined by the compiler which of
> course generates good code. I also verified that none of my old links with
> SCCR3BND pull in any of the library memory functions (memcmp, memcpy, etc.)
> along with a bunch of other stdlib functions which builtin.h overrides.
>
> I'd be perfectly happy for someone to tell me I missed some obvious
> compiler option or did something else really stupid.
>
>
> Dennis C. Fitzpatrick
> den...@dcfitz.com<mailto:den...@dcfitz.com>
> H: 630.325.6184
> W: 630.325.6137
> M: 630.660.8040
>
>
> ----------------------------------------------------------------------
> 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

Reply via email to