RE: GCC harm in ARM

2025-06-19 Thread Bob Dubner



> -Original Message-
> From: Basile Starynkevitch 
> Sent: Thursday, June 19, 2025 11:51
> To: Bob Dubner 
> Cc: gcc@gcc.gnu.org
> Subject: GCC harm in ARM
> 
> HEllo,
> 
> 
> Bob Dubner wrote on gcc@
> >
> > Thus, the statement
> >
> > CALL "foo"
> >
> > might be the equivalent, implemented in C, of
> >
> > extern  foo(...); //External reference
> > foo();
> >
> > or
> >
> > static  foo(...); // Forward reference to a static
> > function
> > foo();
> >
> > At the point of the CALL, we don't know which it's going to be.
> >
> > This is further complicated by COBOL being able to do something that C
> can't:
> >
> > CALL call_me
> >
> > If C could do it, it would look like this:
> >
> > char call_me[] = "foo";
> > call_me();  // I told you C can't do it.
> >
> 
> 
> If you restrict the GCC compiler and the compiled program to run on a
> Linux (or
> POSIX) operating system, the dlsym(3) function is doing that (on global
> functions only): fetching a function pointer from the string name of that
> global
> function.
> https://man7.org/linux/man-pages/man3/dlsym.3.html
> https://man7.org/linux/man-pages/man3/dlopen.3.html
> 
> (you might consider generating unique C identifiers with some random
> generator)
> 
> Of course, dlsym(3) is computationally costly, you may want to cache the
> result.

Thank you.  I am using dlopen/dlsym to handle cases where the called function's 
name is a variable.  And I am cacheing the dlsym results.

One point I was attempting to make is that for COBOL, the capability is in the 
language specification.  For C/C++ the capability is not part of the language.

> 
> And Cobol GCC experts (I am not one) could of course consider either
> generating
> code with libgccjit (it is now inside GCC) or perhaps use GNU lightning to
> generate machine code.
> https://www.gnu.org/software/lightning/
> 
> Experimentally dlopen can be used many thousands of times (and with enough
> RAM
> perhaps hundred thousands of times). See
> https://github.com/bstarynk/misc-basile/blob/master/manydl.c
> 
> 
> Regards
> --
> Basile STARYNKEVITCH
> 8 rue de la Faïencerie
> http://starynkevitch.net/Basile/
> 92340 Bourg-la-Reine https://github.com/bstarynk
> France
> https://github.com/RefPerSys/RefPerSys



RE: harm in ARM

2025-06-18 Thread Bob Dubner



> -Original Message-
> From: Richard Biener 
> Sent: Wednesday, June 18, 2025 09:28
> To: James K. Lowden 
> Cc: gcc@gcc.gnu.org; Bob Dubner 
> Subject: Re: harm in ARM
> 
> On Tue, Jun 17, 2025 at 7:51 PM James K. Lowden
>  wrote:
> >
> > The COBOL FE emits code for a recent ARM VM that is definitely not what
> > the user or, ahem, the FE author intended.  The observed behavior is
> > that the program enters an infinite loop calling the main entry point,
> > eventually exhausting the stack. The observed assembler code does or
> > does not refer to the GOT and ends up not going where it should.
> >
> > We think either we're not using GENERIC as intended, or what we're
> > doing is tripping up the code generator.  Possibly both.
> >
> > The working VM is
> >
> > hostname = gcc-cobol
> > uname -m = aarch64
> > uname -r = 5.15.0-122-generic
> > uname -s = Linux
> > uname -v = #132-Ubuntu SMP Thu Aug 29 13:45:17 UTC 2024
> >
> > The broken VM is
> >
> > hostname = potato
> > uname -m = aarch64
> > uname -r = 6.8.0-60-generic
> > uname -s = Linux
> > uname -v = #63-Ubuntu SMP PREEMPT_DYNAMIC Tue Apr 15 18:51:58 UTC 2025
> >
> > The COBOL is
> >
> > IDENTIFICATION DIVISION.
> > PROGRAM-ID. prog.
> > PROCEDURE DIVISION.
> > PROG-MAIN.
> > DISPLAY "I am prog"
> > CALL "prog2"
> > STOP RUN.
> >
> > IDENTIFICATION DIVISION.
> > PROGRAM-ID. prog2.
> > PROCEDURE DIVISION.
> > PROG-PROG2.
> > DISPLAY "I am prog2".
> > END PROGRAM prog2.
> >
> > END PROGRAM prog.
> >
> > The problem is a forward reference to a function without external
> > linkage, namely prog2.
> >
> > In COBOL parlance, prog2 is a "contained program".  The containing
> > program, prog1, can call contained programs but not vice-versa.  There
> > is no requirement for a function prototype denoting a forward
> > reference.
> >
> > A COBOL program (top-level) is a function with external linkage and C
> > semantics. A contained program is function with "internal linkage" if
> > there is such a thing.  In C terms, the above might be represented as
> >
> > void prog() { puts("I am prog"); prog2(); }
> > static void prog2() { puts("I am prog2"); }
> >
> > Names with external linkage are published verbatim.  Names with
> > internal linkage get an internal name unique to the translation unit, in
> > this case, "prog2.62". It is the compiler's job, I think obviously, to
> > find prog2; the linker is not involved.
> >
> > Because a contained program always appears after the containing program,
> > the compiler does not know when it encounters CALL whether "prog2"
> > names a contained program or is a reference to another module to be
> > linked in later.  We begin by assuming it's an external reference.  At
> > EOF we review the CALLs and, for string constants that name contained
> > programs, substitute the name of the function representing the contained
> > program.  For your reference, that touch-up work is done by
> > parser_call_target_update().
> 
> I'm just looking there where you do
> 
> for( auto func : p->second )
>   {
>   func.convention = cbl_call_verbatim_e;
>   DECL_NAME(func.node) = get_identifier(mangled_name);
> 
> but GCC, when matching a CALL_EXPR and a destination _definition_,
> requires the actual FUNCTION_DECL trees to match up, not just
> their name.  That is, while GCC builds up a symbol table it does that
> based on _decls_, not based on decl names.
> 
> That means, the adjustment should end up unifying the FUNCTION_DECL
> used for all calls.

  Richard, you hit the nail right on the head.I have been 
trying to convey to Jim my growing conviction that CALL_EXPR expressions to 
static functions have to take a FUNCTION_DECL.  And I have told him that the 
fact that our CALL code is working is more-or-less accidental.

I will be revisiting this very soon.

One of the reasons I haven't yet fixed it is because, well, it's COBOL.  CALLs 
had to be implemented very early, back when I was young and foolish and I 
didn't know anything about GENERIC.

And because it's COBOL, there are no function prototypes.  And we implemented 
the front end doing a single pass.

Thus, the statement

CALL "foo"

might be the equivale