Menu

Dynamic Modules and CALL

2025-03-02
2025-03-09
  • Marco Antoniotti

    Hi

    I was experimenting with CALL and I believe I had to uncover some details that are not explicitly stated in the manuals.
    I just need confirmation and ask for advice.
    This applies to dynamic calls; static linking of modules/libraries/archives works as expected.
    I tested this on MacOS and Linux (Ubuntu).

    1. the name of a called subprogram must be the name of the module: i..e, CALL FOOBAR expects a FOOBAR.dylib in the search path.
    2. you can CALL an ENTRY only after you have CALLed the main subprogram as in case (1) above.
    3. again, you must have your PROGRAM ID equal to the name of the .so/.dylib.

    Is this correct? If so, is there some incantation that will allow you to make the manes known to the linker, as you would in Windows with .def files and in … TK4-/TK4 and friends with LKED.SYSIN and INDLUDE etc?

    Thanks

    Marco

     
    • Eugenio Di Lorenzo

      Hi Marco,
      I believe the necessary indications are already present in chapter 11.4.

      Your observations at points 1 and 3:
      1. the name of a called subprogram must be the name of the module: i..e, CALL FOOBAR expects a FOOBAR.dylib in the search path.
      3. again, you must have your PROGRAM ID equal to the name of the .so/.dylib.

      are already covered by point 2 of the PG which I report below:
      ** 2. Dynamically-loadable modules will be named xxxxxxxx.dll on a Windows system,
      xxxxxxxx.so on a Unix system or xxxxxxxx.dylib on an OSX system, where xxxxxxxx
      exactly matches, including the usage of upper- and lower-case letters, the primary
      entry-point name (PROGRAM-ID or FUNCTION-ID) or an alternate entry point name defined via the ENTRY statement (see Section 7.8.14 [ENTRY], page 319) of any one of the GnuCOBOL programs included in that module.**

      your observation at point 2
      2. you can CALL an ENTRY only after you have CALLed the main subprogram as in case (1) above.

      is already covered by point point 5 of the PG which I report below:
      5. Once the dynamically-loadable module has been successfully loaded, any of the entry-points contained within it are now available for reference.

      Do you agree?

       
      • Marco Antoniotti

        Hi Eugenio

        I kind of agree, but examples would clarify the issues. Yet, I do have
        other problems that I have shown in my latest posts regarding failed
        pre-loading of modules. Also, ENTRY's are not corresponding to modules'
        names, and it should (should it?) be possible to call an ENTRY without
        calling the "module".

        In any case, I attach my code for your amusement; I welcome any feedback.
        Two things: (1) I know I am trying to put a square peg in a round hole and
        (2) I am trying to code against the ancient MVT COBOL running on MVS3.8
        TK4-/5; hence no END- clauses and no inline PERFORM.

        You can use the Makefile to produce .dylib's on Mac OS (or change them to
        .so's on Linux), or try cobc at the command line, like in my previous email.

        All the best

        Marco

        On Fri, Mar 7, 2025 at 3:43 AM Eugenio Di Lorenzo dilodilo@users.sourceforge.net wrote:

        Hi Marco,
        I believe the necessary indications are already present in chapter 11.4.

        Your observations at points 1 and 3:

        1. the name of a called subprogram must be the name of the module: i..e,
        CALL FOOBAR expects a FOOBAR.dylib in the search path. 3. again, you must
        have your PROGRAM ID equal to the name of the .so/.dylib.

        are already covered by point 2 of the PG which I report below:
        ** 2. Dynamically-loadable modules will be named xxxxxxxx.dll on a Windows
        system,
        xxxxxxxx.so on a Unix system or xxxxxxxx.dylib on an OSX system, where
        xxxxxxxx
        exactly matches, including the usage of upper- and lower-case letters, the
        primary
        entry-point name (PROGRAM-ID or FUNCTION-ID) or an alternate entry point
        name defined via the ENTRY statement (see Section 7.8.14 [ENTRY], page
        319) of any one of the GnuCOBOL programs included in that module.**

        your observation at point 2
        2. you can CALL an ENTRY only after you have CALLed the main subprogram
        as in case (1) above.

        is already covered by point point 5 of the PG which I report below:
        5. Once the dynamically-loadable module has been successfully loaded, any
        of the entry-points contained within it are now available for reference.

        Do you agree?

        Dynamic Modules and CALL
        https://sourceforge.net/p/gnucobol/discussion/help/thread/7dbeb38b77/?limit=50#687c/5400


        Sent from sourceforge.net because you indicated interest in
        https://sourceforge.net/p/gnucobol/discussion/help/

        To unsubscribe from further messages, please visit
        https://sourceforge.net/auth/subscriptions/

        --
        Marco Antoniotti, Professor, Director tel. +39 - 02 64 48 79 01
        DISCo, University of Milan-Bicocca U14 2043 http://dcb.disco.unimib.it
        Viale Sarca 336
        I-20126 Milan (MI) ITALY

        CSCE 2025 - csce.lakecomoschool.org

         
        • Ralph Linkletter

          Humor me.
          Insert a 77 level into the LINE-READER-MODULE
          77 FIRST-TIME PIC X(01) VALUE '1'.
          ADD THESE LINES DIRECTLY AFTER THE PROCEDURE DIVISION
          IF FIRST-TIME = '1'
          MOVE '0' TO FIRST-TIME
          GOBACK
          END-IF
          I cannot determine how you would invoke this code if the module were compiled as a main.
          If the module is compiled as a main LINE-READER-MODULE will not work as you expect.
          Is LINE-READER-MODULE compile with -x or -m ?
          READ-FILE.
          ENTRY 'LR-READ-FILE'
          USING LS-RECORDS LS-REC-NO LS-LINE LS-EOF

          Unlike MVT, MVS, zOS it is required to indicate to GnuCOBOL whether a program is a
          main or a subroutine.

          Unlike MVT, MVS, zOS there is no External Symbol Directory (ESD) in the link process of GC. Thus the GC linker precludes exposing the Entry points in LINE-READER-MODULE.

          Ralph

           
          • Marco Antoniotti

            Thank you.

            Adding the code you suggest does not make any difference. The PROCEDURE
            DIVISION is not called directly in my code. Only the ENTRY's.

            Now, I believe I solved my problem. The issue is that I forgot about the
            env command in bash. If I export the COB_PRE_LOAD variable, everything
            works as expected as in the following (note that I also updated bash)

            bash-5.2$ cobc -m LINE-READER-MODULE.cob
            bash-5.2$ cobc -std=mvs -x line-reader.cob
            bash-5.2$ export COB_PRE_LOAD=LINE-READER-MODULE
            bash-5.2$ *./line-reader *

            • Reading a file line by line, char by char.

            • REC: 00000: "123456,foo bar baz" of length 018

            • REC: 99999: "101010,gnao" of length 011
            • REC: 00000: "424242,the_answer" of length 017
            • REC: 00001: "424242,the_answer again" of length 023
            • LR-DISPLAY-RECORDS...
            • [+000000001] (018) "123456,foo bar baz"
            • [+000000002] (011) "101010,gnao"

            • Input file closed.

            • Done.

            Thank you again for your patience.

            After this I can say that GnuCOBOL does recognize the "main" and the "sub"
            programs, AND that ENTRY's are exported as expected.

            Having said that, how would you achieve the same result in z/OS with JCL?

            Thanks

            Marco

            On Sat, Mar 8, 2025 at 2:49 PM Ralph Linkletter zosralph@users.sourceforge.net wrote:

            Humor me.
            Insert a 77 level into the LINE-READER-MODULE
            77 FIRST-TIME PIC X(01) VALUE '1'.
            ADD THESE LINES DIRECTLY AFTER THE PROCEDURE DIVISION
            IF FIRST-TIME = '1'
            MOVE '0' TO FIRST-TIME
            GOBACK
            END-IF
            I cannot determine how you would invoke this code if the module were
            compiled as a main.
            If the module is compiled as a main LINE-READER-MODULE will not work as
            you expect.
            Is LINE-READER-MODULE compile with -x or -m ?
            READ-FILE.
            ENTRY 'LR-READ-FILE'
            USING LS-RECORDS LS-REC-NO LS-LINE LS-EOF

            Unlike MVT, MVS, zOS it is required to indicate to GnuCOBOL whether a
            program is a
            main or a subroutine.

            Unlike MVT, MVS, zOS there is no External Symbol Directory (ESD) in the
            link process of GC. Thus the GC linker precludes exposing the Entry points
            in LINE-READER-MODULE.

            Ralph

            Dynamic Modules and CALL
            https://sourceforge.net/p/gnucobol/discussion/help/thread/7dbeb38b77/?limit=25#687c/5400/aa94/2332


            Sent from sourceforge.net because you indicated interest in
            https://sourceforge.net/p/gnucobol/discussion/help/

            To unsubscribe from further messages, please visit
            https://sourceforge.net/auth/subscriptions/

            --
            Marco Antoniotti, Professor, Director tel. +39 - 02 64 48 79 01
            DISCo, University of Milan-Bicocca U14 2043 http://dcb.disco.unimib.it
            Viale Sarca 336
            I-20126 Milan (MI) ITALY

            CSCE 2025 - csce.lakecomoschool.org

             
  • Simon Sobisch

    Simon Sobisch - 2025-03-02

    Where do you suggest to have this information in the manual?

    In any case, your findings are nearly correct.
    1 - you can have upper/lower-case variants of the program-id if you compile with -ffold-call.
    1-3 - you can use COB_PRE_LOAD to have modules loaded before the first program is even called (or do it automatically with cobcrun -M yourmodule -M anothermodule program (pre-loading is specified without the extension, but the files must be available with the right extension in COB_LIBRARY_PATH)

    Static calls need link-time awareness, dynamic libraries don't.
    And for libraries you need to let the runtime find the entry points, either by pre-loading modules or by letting the runtime find those by an exact match of the program-id.

     
    • Marco Antoniotti

      Thank you for your response.

      I believe this information should go in section 11 of the manual. Also the .info files.

      The reference to cobcrun -M m1 -M m2 ... -M mk progname was the key example that explained everything.
      However, I found it is a bit confusing that compiling an executable with cobc -x main.cob then forces you to use COB_PRE_LOAD. I would suggest adding an option to cobcrun that allows one to pass in an executable to run; something like cobcrun -M m1 ... -M mk -x main.

      Just saying...

      All the best

      Marco

       

      Last edit: Simon Sobisch 2025-03-03
      • Simon Sobisch

        Simon Sobisch - 2025-03-03

        cobcrun is the module runner - but I see your point of everything that it provides, running executables as well seems reasonable, as well as the -x option to say "execute <program> as executable".</program>

        On GNU we likely could use execvp() and, if that function is not available (check during configure) fall back to a sub-process using system(). That's at least definitely an idea, and I think that didn't came up before.

         
        • Marco Antoniotti

          Thanks.

          I will leave the coding to you guys. Meanwhile just adding some information in Section 11 would help.

          All the best

          Marco

           

          Last edit: Simon Sobisch 2025-03-05
          • Marco Antoniotti

            HI

            One more thing. This is on Mac OS Sequoia

            bash-3.2$ *make*
            cobc -m LINE-READER-MODULE.cob
            ld: warning: -undefined suppress is deprecated
            ld: warning: -undefined suppress is deprecated
            bash-3.2$
            

            Just to let you guys know.

            Marco

             

            Last edit: Simon Sobisch 2025-03-05
            • Simon Sobisch

              Simon Sobisch - 2025-03-05

              What the output of

              cobc --info
              cobc -v LINE-READER-MODULE.cob
              

              ?

               
              • Marco Antoniotti

                Hi,

                here they are.

                bash-3.2$ cobc --info
                cobc (GnuCOBOL) 3.2.0
                Copyright (C) 2023 Free Software Foundation, Inc.
                License GPLv3+: GNU GPL version 3 or later <
                https://gnu.org/licenses/gpl.html>
                This is free software; see the source for copying conditions. There is NO
                warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
                Written by Keisuke Nishida, Roger While, Ron Norman, Simon Sobisch, Edward
                Hart
                Built Jul 28 2023 18:42:18
                Packaged Jul 28 2023 17:02:56 UTC
                C version "Apple LLVM 15.0.0 (clang-1500.0.40.1)"

                build information
                build environment : x86_64-apple-darwin23.0.0
                CC : clang
                C version : "Apple LLVM 15.0.0 (clang-1500.0.40.1)"
                CPPFLAGS : -I/usr/local/Cellar/gmp/6.3.0/include
                CFLAGS : -O2 -pipe
                LD :
                /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld
                LDFLAGS :

                GnuCOBOL information
                COB_CC : clang
                COB_CFLAGS : -pipe -I/usr/local/Cellar/gmp/6.3.0/include
                -I/usr/local/Cellar/gnucobol/3.2/include
                -Wno-unused -fsigned-char -Wno-pointer-sign
                -Qunused-arguments
                -Wno-deprecated-non-prototype
                COB_DEBUG_FLAGS : -ggdb3 -fasynchronous-unwind-tables
                COB_LDFLAGS :
                COB_LIBS : -L/usr/local/Cellar/gnucobol/3.2/lib -lcob
                COB_CONFIG_DIR :
                /usr/local/Cellar/gnucobol/3.2/share/gnucobol/config
                COB_COPY_DIR :
                /usr/local/Cellar/gnucobol/3.2/share/gnucobol/copy
                COB_MSG_FORMAT : GCC
                COB_OBJECT_EXT : o
                COB_MODULE_EXT : dylib
                COB_EXE_EXT :
                64bit-mode : yes
                BINARY-C-LONG : 8 bytes
                endianness : little-endian
                native EBCDIC : no
                extended screen I/O : ncurses
                variable file format : 0
                sequential file handler : built-in
                indexed file handler : BDB
                mathematical library : GMP
                XML library : libxml2
                JSON library : json-c

                ... and

                bash-3.2$ *cobc -v LINE-READER-MODULE.cob *
                cobc (GnuCOBOL) 3.2.0
                Built Jul 28 2023 18:42:18 Packaged Jul 28 2023 17:02:56 UTC
                C version "Apple LLVM 15.0.0 (clang-1500.0.40.1)"
                loading standard configuration file 'default.conf'
                command line: cobc -v LINE-READER-MODULE.cob
                preprocessing: LINE-READER-MODULE.cob ->
                /var/folders/l4/b71hhwhj3f375fqgpw1r_f8c0000gp/T/cob26793_0.cob
                return status: 0
                parsing: /var/folders/l4/b71hhwhj3f375fqgpw1r_f8c0000gp/T/cob26793_0.cob
                (LINE-READER-MODULE.cob)
                return status: 0
                translating:
                /var/folders/l4/b71hhwhj3f375fqgpw1r_f8c0000gp/T/cob26793_0.cob ->
                /var/folders/l4/b71hhwhj3f375fqgpw1r_f8c0000gp/T/cob26793_0.c
                (LINE-READER-MODULE.cob)
                executing: clang -pipe -I/usr/local/Cellar/gmp/6.3.0/include
                -I/usr/local/Cellar/gnucobol/3.2/include -Wno-unused
                -fsigned-char -Wno-pointer-sign -Qunused-arguments
                -Wno-deprecated-non-prototype -bundle -flat_namespace
                -undefined suppress -fno-common -DPIC -o
                "LINE-READER-MODULE.dylib"
                "/var/folders/l4/b71hhwhj3f375fqgpw1r_f8c0000gp/T/cob26793_0.c"
                -L/usr/local/Cellar/gnucobol/3.2/lib -lcob
                ld: warning: -undefined suppress is deprecated
                ld: warning: -undefined suppress is deprecated
                return status: 0

                And the -undefined suppress is there.

                All the best

                Marco

                On Wed, Mar 5, 2025 at 6:28 PM Simon Sobisch sf-mensch@users.sourceforge.net wrote:

                What the output of

                cobc --info
                cobc -v LINE-READER-MODULE.cob

                ?

                Dynamic Modules and CALL
                https://sourceforge.net/p/gnucobol/discussion/help/thread/7dbeb38b77/?limit=50#d3ac/2519/1e92/dbc1/88f9/bd69


                Sent from sourceforge.net because you indicated interest in
                https://sourceforge.net/p/gnucobol/discussion/help/

                To unsubscribe from further messages, please visit
                https://sourceforge.net/auth/subscriptions/

                --
                Marco Antoniotti, Professor, Director tel. +39 - 02 64 48 79 01
                DISCo, University of Milan-Bicocca U14 2043 http://dcb.disco.unimib.it
                Viale Sarca 336
                I-20126 Milan (MI) ITALY

                CSCE 2025 - csce.lakecomoschool.org

                 
                • Marco Antoniotti

                  Hi

                  another thing.

                  I have code that works fine using cobcrun. However, if I try to have the main program compiled with cobc -x and have the other module in COB_PRE_LOAD
                  I get the following error:

                  bash-3.2$ *export COB_PRE_LOAD=LINE_READER_MODULE*
                  bash-3.2$ *./line-reader *
                  libcob: warning: preloading of 'LINE_READER_MODULE' failed
                  
                  * Reading a file line by line, char by char.
                  
                  libcob: error: module 'LR-READ-FILE' not found
                  

                  Any way to figure out what the error could be? (Everything is in the same directory).

                  Thanks

                  MA

                  PS. I am very naughty with my program :) :) :)

                   

                  Last edit: Simon Sobisch 2025-03-06
                  • Simon Sobisch

                    Simon Sobisch - 2025-03-06

                    I haven't seen your setup...

                    COB_PRE_LOAD=LINE_READER_MODULE asks libcob (either directly or when started via cobcrun) to search for a file LINE_READER_MODULE + shared-object-extension in COB_LIBRARY_PATH (which defaults to the install dir + current directory), so I conclude that there is no binary named LINE_READER_MODULE.dylib in the current directory (or an ldd to it shows unresolved entry points), so the preload failes (and output a nice warning), then the program-id LR_READ_FILE cannot be resolved from whatever module is loaded and cannot be found as separate .dylib.

                     
                    • Marco Antoniotti

                      Hi

                      I do have a LINE_READER_MODULE.dylib in the directory. Changing to

                      export COB_PRE_LOAD=LINE_READER_MODULE.dylib

                      does not change the result.

                      The LR-READ-FILE is an ENTRY in the dylib. Since the loading failed, it
                      cannot find it.

                      Note the following:

                      bash-3.2$ ls -l
                      total 56
                      -rw-r--r-- 1 marcoxa staff 5007 Mar 6 10:53 LINE-READER-MODULE.cob
                      -rw-r--r-- 1 marcoxa staff 325 Mar 6 10:53 LR-FILE-CONTROL.cpy
                      -rw-r--r-- 1 marcoxa staff 257 Mar 6 10:52 LR-FILE-FD.cpy
                      -rw-r--r-- 1 marcoxa staff 485 Mar 6 10:56 Makefile
                      -rw-r--r-- 1 marcoxa staff 2063 Mar 5 18:55 line-reader.cob
                      -rw-r--r-- 1 marcoxa staff 73 Mar 5 18:47 test.csv

                      bash-3.2$ cobc -x line-reader.cob *
                      bash-3.2$
                      cobc -m LINE-READER-MODULE.cob *
                      ld: warning: -undefined suppress is deprecated
                      ld: warning: -undefined suppress is deprecated

                      bash-3.2$ ls -l
                      total 136
                      -rw-r--r-- 1 marcoxa staff 5007 Mar 6 10:53 LINE-READER-MODULE.cob
                      -rwxr-xr-x 1 marcoxa staff 19768 Mar 6 11:49 LINE-READER-MODULE.dylib
                      -rw-r--r-- 1 marcoxa staff 325 Mar 6 10:53 LR-FILE-CONTROL.cpy
                      -rw-r--r-- 1 marcoxa staff 257 Mar 6 10:52 LR-FILE-FD.cpy
                      -rw-r--r-- 1 marcoxa staff 485 Mar 6 10:56 Makefile
                      -rwxr-xr-x 1 marcoxa staff 18720 Mar 6 11:48 line-reader
                      -rw-r--r-- 1 marcoxa staff 2063 Mar 5 18:55 line-reader.cob
                      -rw-r--r-- 1 marcoxa staff 73 Mar 5 18:47 test.csv

                      bash-3.2$ export COB_PRE_LOAD=LINE_READER_MODULE.dylib
                      bash-3.2$ *./line-reader *
                      libcob: warning: preloading of 'LINE_READER_MODULE.dylib' failed

                      • Reading a file line by line, char by char.

                      libcob: error: module 'LR-READ-FILE' not found

                      If I generate the two .dylib's and run cobcrun everything is fine.

                      Marco

                      On Thu, Mar 6, 2025 at 11:41 AM Simon Sobisch sf-mensch@users.sourceforge.net wrote:

                      I haven't seen your setup...

                      COB_PRE_LOAD=LINE_READER_MODULE asks libcob (either directly or when
                      started via cobcrun) to search for a file LINE_READER_MODULE +
                      shared-object-extension in COB_LIBRARY_PATH (which defaults to the
                      install dir + current directory), so I conclude that there is no binary
                      named LINE_READER_MODULE.dylib in the current directory (or an ldd to it
                      shows unresolved entry points), so the preload failes (and output a nice
                      warning), then the program-id LR_READ_FILE cannot be resolved from whatever
                      module is loaded and cannot be found as separate .dylib.


                      Dynamic Modules and CALL
                      https://sourceforge.net/p/gnucobol/discussion/help/thread/7dbeb38b77/?limit=50#d3ac/2519/1e92/dbc1/88f9/bd69/91c0/5872/2248


                      Sent from sourceforge.net because you indicated interest in
                      https://sourceforge.net/p/gnucobol/discussion/help/

                      To unsubscribe from further messages, please visit
                      https://sourceforge.net/auth/subscriptions/

                      --
                      Marco Antoniotti, Professor, Director tel. +39 - 02 64 48 79 01
                      DISCo, University of Milan-Bicocca U14 2043 http://dcb.disco.unimib.it
                      Viale Sarca 336
                      I-20126 Milan (MI) ITALY

                      CSCE 2025 - csce.lakecomoschool.org

                       
                      • Mickey White

                        Mickey White - 2025-03-06

                        Marco, not sure if this is what you are trying to do, but I use dynamic for my subroutines.
                        I compile as objects, the collect all the objects into an .SO using the -b option.
                        And this .so is the library that is in my preload...
                        COB_PRE_LOAD=/home/mickeyw/lib/mwoc.so

                         

                        Last edit: Mickey White 2025-03-06
  • Ralph Linkletter

    Marco
    I resolve this by having the PROGRAM-NAME (Ralph in this instance) call do nothing more than a goback.

    Program-Id. Ralph.
    Proc Div.
    goback.

    Entry Simon using ...

    Call Simon will now be resolved.

    Ralph

     

Anonymous
Anonymous

Add attachments
Cancel





Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.