https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119414

--- Comment #11 from rdubner at symas dot com ---
COBOL comes from long ago, and far away.  And the vast bulk of code that I 
never forget is where my boss, paying my salary, hopes to someday actually 
make some money as we support migration and conversion, is mainframe code. 
And mainframe code operates on different assumptions than those expected by 
people who are steeped in Unix-like platforms.

(I am not a mainframe guy.  But I don't think that the customs of the Unix 
tribe constitute natural law, either.)

Here is the test program that first alerted me to the problem that I tracked 
down to -rdynamic.


       IDENTIFICATION   DIVISION.
       PROGRAM-ID.      caller.
       PROCEDURE        DIVISION.
           CALL "callee1" ON EXCEPTION
              CALL "callee2" ON EXCEPTION
                  DISPLAY "neither callee1 nor callee2 found"
              END-CALL
           END-CALL
           GOBACK.
       END PROGRAM caller.
       IDENTIFICATION   DIVISION.
       PROGRAM-ID.      callee2.
       PROCEDURE        DIVISION.
           DISPLAY "this is callee2" NO ADVANCING
           GOBACK.
       END PROGRAM callee2.

The instruction CALL "callee1" ON EXCEPTION means that if "callee1" can't be 
found, then execute the code following "ON EXCEPTION" until the enclosing 
END-CALL is encountered.

There is no callee1 to be found; there are no DSOs involved.  As you can see 
callee2 is part of the source code module.

When compiled with "gcobol playpen.cbl", the result is a static linking 
error:

/usr/bin/ld: /tmp/ccqZ2tzw.o: in function 
`_para._implicit_paragraph_5._initialize_program.caller.0.67':
playpen.cbl:(.text+0x399): undefined reference to `callee1'

When compiled with "gcobol 
playpen.cbl -fno-static-call -Wl,-rpath=/usr/local/lib64"

the resulting a.out executable reports:

     neither callee1 nor callee2 found

That's the erroneous response:  "callee2" is there, but dlopen/dlsym can't 
find it. because it is never explicitly referenced in the source code.

When compiled with "gcobol 
playpen.cbl -fno-static-call -rdynamic -Wl,-rpath=/usr/local/lib64"

the executable properly reports

     this is callee2

Speaking to the larger issue of finding an entry point in a DSO in a 
mainframe-like environment:  Apparently, in the mainframe world, it is 
ordinary procedure to have each of hundreds of program-id entry point in 
their own equivalent of a DSO.  Apparently it is routine to have a "main" 
program call "this-program-id" and "that-program-id".  The behavior of that 
main program is then changeable by specifying different versions of those 
.so files for different purposes.

GnuCOBOL has an internal specification:  If you want to CALL "abc", then the 
entry point abc has to live in a file named "abc.so".

I have used more of a sledeghammer approach:

When -fno-static-call is operative, the libgcobol function 
__gg__function_handle_from_cobpath() becomes operative.  I use dlopen(NULL, 
RTLD_LAZY) and dlsym to first search for the routine in the main program

I then, rather expensively, check every .so file to be found in the 
directories specified by the environment variable COBPATH, and failing that, 
every .so file specified by LD_LIBRARY_PATH. In weak defense of that method, 
I do cache the results, so the search isn't done every time for a given 
entry-point name.

With regard to the debugger...  My memory is fuzzy.  But I do create 
variables that the debugger needs that are not automatically exported.  One, 
for example, contains the source-code file name and line number where the 
initial temporary break point needs to be set when the gdb "start" command 
is issued.  It's a static variable, with a constructor, that nobody in the 
executable references.  But GDB needs to be able to find it.  Hence 
the -rdynamic.

> -----Original Message-----
> From: iains at gcc dot gnu.org <gcc-bugzi...@gcc.gnu.org>
> Sent: Wednesday, April 9, 2025 10:25
> To: rdub...@gcc.gnu.org
> Subject: [Bug cobol/119414] cobol driver unconditionally adds platform-
> specific command line options.
>
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119414
>
> --- Comment #8 from Iain Sandoe <iains at gcc dot gnu.org> ---
> (In reply to Robert Dubner from comment #7)
> > The commit has the comment, "...the options had been added during
> development
> >     to handle specific cases, they are no longer needed..."
>
> > That turns out not to be the case, and I am sorry I wasn't tracking it
> more
> > closely at the time.
>
> Apologies, that was my understanding from the discussion here.
>
> OK this is probably going to take a little time to figure out ... taking
> one
> point at a time,
>
> > The patch eliminated the "-rdynamic" that I was adding to the command
> line
> > switches.
>
> > 1) -rdynamic
>
> a) this is a pretty big hammer (it's a blanket export everything)
> b) it is not available on all platforms, so there might need to be
> alternate
> arrangements made in some cases.
> c) ... however sometimes the big hammer is needed ..
>
> Trying to understand the underlying requirement in order to suggest
> possible
> alternates...
>
> > COBOL provides for the instruction "CALL "xyz" ON EXCEPTION...",
> > where the executable code in the ON EXCEPTION clause is executed when
> the
> > program-id "xyz" can't be found.
>
> So "xyz" is a symbol in a separate DSO? (or is it the name of the DSO?).
>
> Most platforms provide mechanisms for exporting specific symbols so that
> one
> can avoid the blanket mechanism.
>
> > When doing static linking, a missing "xyz" will cause a static linking
> error.
>
> On some platforms this is also the default for DSOs (and can be a policy
> on
> Linux too).
>
> But this ^ is about allowing undefined symbols at link-time..
>
> > So, GCOBOL provides the -fno-static-call
> > switch, which internally results in the use of dlopen/dlsym to find
> other
> > programs.
>
> "other programs" meaning executables or symbols in other DSOs?
>
> > The "-rdynamic" is needed so that dlsym() can find the named
> > function.
>
> so you DSO (A) dlopen() a DSO (B), then call an exported symbol that then
> needs
> to be able to refer to symbols in the current DSO (A)?
>
> Can you not explicitly export those symbols?
>
> > Also, if memory serves, the -rdynamic is needed so that the GDB-COBOL
> > version of GDB can behave sensibly.
>
> It would help to know what aspect is needed.
>
> > So, I would like to insert that switch when compiling for the x86_64 and
> > aarch64 architectures.  What conditional compilation variables should be
> > used for that?
>
> It's more a case of whether a platform supports it or not - e.g x86_64
> Linux
> and Darwin do .. but AFAIR x86_64 Windows does not..
>
> There might be some dance we can do with specs - but first to make sure
> that
> the requirement is understood.
>
> --
> You are receiving this mail because:
> You are on the CC list for the bug.

Reply via email to