Topic
  • No replies
Visda
Visda
29 Posts

Pinned topic zOS: How to combine regular C/C++ objects with Metal C generated HLASM source assembled into object?

‏2013-05-17T14:20:18Z |

Following the documents, I am able to create a separate HLASM file and object, but I'm still not clear how to combine my regular C/C++ objects and HLASM objects together. Here is my sample program:

In foo.c, I have a function Foo written in inline assembly.
In main.cpp, function main() calls Foo.

According to the document, I must run "xlc -qMETAL -S foo.c" to get foo.s, and then run "as foo.s" to get foo.o.
For main.cpp, I generate main.o with "xlc++ -c main.cpp".
The problem is that how to mix maim.o and foo.o to generate the final binary? I tried a few options, all say "SYMBOL foo UNRESOLVED". Do you know how to do it?

 

  • Visda
    Visda
    29 Posts
    ACCEPTED ANSWER

    Re: zOS: How to combine regular C/C++ objects with Metal C generated HLASM source assembled into object?

    ‏2013-05-17T14:26:19Z  

    The message ""SYMBOL foo UNRESOLVED" is due to the mis-match of LONGNAME/NOLONGNAME compiler option.  NOLONGNAME truncates the external names to 8-characters only and makes them capital.  

    METAL by default is NOLONGNAME; and z/OS USS compile the default is LONGNAME.  This mis-match will result in foo being FOO in METAL compile and foo in the non-METAL.  As a result the binder cannot resolve foo properly.

    Adding -qLONGNMAE to the METAL -C compile command will resolve this problem. Keep in mind when names are longer than 8-characters in length you need to specify the option GOFF to the assembler.

    In addition to the above, you need to keep in mind the following points when mixing METAL-C with non-METAL-C

    • METAL-C only acquires dynamic storage area, DSA, for main.  So, you need to acquire dynamic storage area for foo where foo is defined.  If you add the following: #pragma prolog(foo,main) and #pragma epilog(foo,main) to where foo is defined the compiler will treat foo as main and acquire and release storage on your behalf.
    • Don't clobber r12 in non-XPLINK and r5 if in XPLINK mode.  These two registers are used by the Language Environment, the z/OS run-time.
    • Pass all parameters to foo by reference.


    Here is a simple METAL-C non-METAL-C mixed test case:
    >cat m.c
    #pragma prolog(foo,main)
    #pragma epilog(foo,main)
    int foo() {

      __asm("*This is a comment.");
      return 5;
    }

    >cat x.cpp

    extern "C" int foo();
    int main() {

      return foo();
    }

    Commands:
    xlc -qMETAL -S -qlongname m.c
    as -mgoff m.s
    xlc++ -c x.cpp
    xlc++ m.o x.o
    a.out
    echo $?
    5

  • Visda
    Visda
    29 Posts

    Re: zOS: How to combine regular C/C++ objects with Metal C generated HLASM source assembled into object?

    ‏2013-05-17T14:26:19Z  

    The message ""SYMBOL foo UNRESOLVED" is due to the mis-match of LONGNAME/NOLONGNAME compiler option.  NOLONGNAME truncates the external names to 8-characters only and makes them capital.  

    METAL by default is NOLONGNAME; and z/OS USS compile the default is LONGNAME.  This mis-match will result in foo being FOO in METAL compile and foo in the non-METAL.  As a result the binder cannot resolve foo properly.

    Adding -qLONGNMAE to the METAL -C compile command will resolve this problem. Keep in mind when names are longer than 8-characters in length you need to specify the option GOFF to the assembler.

    In addition to the above, you need to keep in mind the following points when mixing METAL-C with non-METAL-C

    • METAL-C only acquires dynamic storage area, DSA, for main.  So, you need to acquire dynamic storage area for foo where foo is defined.  If you add the following: #pragma prolog(foo,main) and #pragma epilog(foo,main) to where foo is defined the compiler will treat foo as main and acquire and release storage on your behalf.
    • Don't clobber r12 in non-XPLINK and r5 if in XPLINK mode.  These two registers are used by the Language Environment, the z/OS run-time.
    • Pass all parameters to foo by reference.


    Here is a simple METAL-C non-METAL-C mixed test case:
    >cat m.c
    #pragma prolog(foo,main)
    #pragma epilog(foo,main)
    int foo() {

      __asm("*This is a comment.");
      return 5;
    }

    >cat x.cpp

    extern "C" int foo();
    int main() {

      return foo();
    }

    Commands:
    xlc -qMETAL -S -qlongname m.c
    as -mgoff m.s
    xlc++ -c x.cpp
    xlc++ m.o x.o
    a.out
    echo $?
    5