Problem:
If an entry-point stored in .a archive is called from main COBOL program using the ON OVERFLOW or ON EXCEPTION clause, even if the program is linked with the .a archive, the call fails and the ON OVERFLOW clause is executed.
If in the same program the same entry-point is called using a simple CALL, it will succeed but the call with the ON OVERFLOW clause will still fail.
To reproduce it:
$ cat test1.cbl
PROCEDURE DIVISION.
CALL "HF-TEST02" ON OVERFLOW
DISPLAY "OVERFLOW." END-CALL.
DISPLAY "Back to the main program.".
CALL "HF-TEST02".
STOP RUN.
$ cat hf-test02.cob
IDENTIFICATION DIVISION.
PROGRAM-ID. HF-TEST02.
PROCEDURE DIVISION.
DISPLAY "HF-TEST02 is called.".
EXIT PROGRAM.
$ cob -cx hf-test02.cob
$ ar -r libtss.a hf-test02.o
ar: creating an archive file libtss.a
$ cob -x test1.cbl -L. -ltss
$ ./test1
OVERFLOW.
Back to the main program.
HF-TEST02 is called.
Resolution:
This problem is easily solved by adding the -I flag to the cob command:
$ cob -x test1.cbl -L. -ltss -IHF-TEST02
$ ./test1
HF-TEST02 is called.
Back to the main program.
HF-TEST02 is called.
The explanation for this is that when you use a CALL "myentry" ON OVERFLOW (or ON EXCEPTION) the compiler assumes that you are doing a dynamic call and then it inserts a call to the rts instead. You have to understand that when you link with an archive, you are statically linking the exact entry/function that you are directly referencing in the exact part where it is referenced. At runtime the archive is NOT available in memory and therefore none of the entry points/functions inside the archive are dynamically available.
So what is happening is that in the simple CALL, the HF-TEST02 entry point is statically linked to that exact part of the code but the HF-TEST02 symbol is not dynamically visible to other parts of the code. But in the ON OVERFLOW case, the call is assumed to be dynamic, and nothing is statically linked in that part of the code. At runtime it tries to dynamically load it, but the HF-TEST02 symbol is not loaded in memory and it tries to load HF-TEST02.so or HF-TEST02.gnt or HF-TEST.int (I am not sure if that is the right order, but it doesn't matter here) and as it can not dynamically load the entry-point, the call fails. I easily tested this by creating HF-TEST02.int and running the code (test12.cbl is copy of test1.cbl):
$ cob -x test12.cbl -L. -ltss
$ ./test12
OVERFLOW
HF-TEST02 is called.
Back to the main program.
$ cp hf-test02.int HF-TEST02.int
$ ./test12
HF-TEST02 is called.
HF-TEST02 is called.
Back to the main program.
$ rm HF-TEST02.int