🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: comp.lang.fortran
4 messages
4 total messages Started by Jeff Templon Thu, 14 May 1998 00:00
Request: help linking egcs-compiled fortran + other fortran
#6555
Author: Jeff Templon
Date: Thu, 14 May 1998 00:00
113 lines
5690 bytes

[ comp.lang.fortran people: sorry for all the specifics, but there is
  a genuine Fortran (egcs/g77) question near the bottom. ]

Hi All,

Background: running on a RedHat Linux 5.0 system (plus all errata).
Vanilla system, i.e. no more recent version of glibc or kernel; using
whatever is the latest redhat version on errata page.

I'm compiling a large code using Absoft Pro Fortran (f77 version 4.4).
I need to link to CERNLIB (a large package of scientific subroutines).
This package is available in many versions corresponding to different
compilers used to make the libraries.

Firstly, I was using the same Fortran compiler (Absoft v4.4) and
a version of CERNLIB compiled using g77, while running RedHat 4.2.
I had no problems at all with the code back then.

Now under RedHat 5.0, the exact same code, linked to the exact same
libraries, dies with a segmentation violation.  At some point in the
bowels of CERNLIB, the stack gets corrupted and a "return" statement
causes the program to land at an address 0000000.  What's weird is
that this should not happen, since this portion of the code has not
changed at all in the upgrade from redhat 4.2 to 5.0 (barring some
strange disk error!)

For those in the know, the routine where it All Goes South is
what_loop, which is a part of the KUIP command-interpreter package of
CERNLIB.  The details are expressed in an appendix below, thanks to
Absoft tech support.

Not knowing how to proceed, and suspecting that it was related to
libc5 vs glibc issues, I asked the C compiler and the linker to use
libc5 libs instead of glibc (using the -b option of ld, and other
options for gcc.  There is a Glibc2-HOWTO which tells you how to do
this.)

Problem: can't do it, since redhat only installs the old libraries but
not the old tools.  I get a "cpp not found" error since it looks for
cpp in some "libc5" part of the tree and not in the standard place.

Not being able to do this, I picked up Steve Adler's version of
CERNLIB 98a compiled using egcs/g77 under RedHat 5.0.  Surely this
should work.

Problem: egcs/g77 "libf2c" package is not really the same as the real
libf2c as distributed by AT&T.  Thus the link phase complains about
missing symbols.  So I pick up egcs-1.02 and install it so that I have
the version of libf2c which this CERNLIB expects.  Compile and link.

Problem: another difference of stock libf2c vs egcs libf2c is that the
egcs version defines the routine "main" within the library.  Thus,
when I try to link it only as a support library, and the main routine
is compiled with _another_ compiler (Absoft), I get *two* main
routines defined.  I don't know the implications of removing the
"main" routine from libf2c (does g77 I/O work if I do this) nor do I
know how to convince the loader how to do this (do I simply remove
main.o from libf2c using the 'ar' command?)

In short: I am stuck -- the only recourse I know is to downgrade to
RedHat 4.2.  Anyone who has any suggestions, ideas, or solutions
is extremely welcome to pass them on!

					JAT

appendix: details of segmentation violation when using 97a CERNLIB
package.

abs> Jeff,
abs> 
abs> First, I've got say that running X over the internet is one of
abs> the more painfull things I've done lately. When the program is
abs> ready to return from what_loop (what_loop+0x1c7), the stack
abs> pointer is off by 4 bytes.  At the entry to what_loop, the
abs> stack pointer is 0xbffff3f8. On the last instruction of
abs> what_loop (what_loop+0x01c7), the stack pointer is 0xbffff3f4.
abs> This memory location just happens to contain a zero, so
abs> executing the return instuction sets the pc to zero. 
abs> 
abs> Some annotated assembly to ponder:
abs> 
abs>     what_loo+0x0193   call        exec_cmd_string  *1
abs>     what_loo+0x0198   pushl       %ebx
abs>     what_loo+0x0199   call        _init+0x0f0c     *2
abs>  => what_loo+0x019e   addl        $24,%esp	   *3
abs>     what_loo+0x01a1   movl        $0,kc_break+0x000c
abs>     what_loo+0x01ab   cmpl        $0,kc_flags
abs>     what_loo+0x01b2   jnz         what_loop+0x01c1
abs>     what_loo+0x01b4   cmpl        $0,kc_flags+0x0004
abs>     what_loo+0x01bb   jz          what_loop+0x0040
abs>     what_loo+0x01c1   movl        $1,%eax
abs>     what_loo+0x01c6   popl        %ebx		   *4
abs>     what_loo+0x01c7   ret
abs> 
abs>     *1 - we got back from exec_cmd_string, so the stack was ok
abs>     to this point.
abs> 
abs>     *2 - this is a call into a shared library, the routine is
abs>     cfree and apparently gets one argument. Also, this function
abs>     returns ok, so the stack is still good.
abs> 
abs>     *3 - after this add of 24 bytes, the stack pointer is
abs>     0xbffff3f0.
abs> 
abs>     *4 - this adds another 4 bytes to the stack pointer, giving
abs>     0xbffff3f4.  But at entry to what_loop, the stack pointer
abs>     was 0xbffff3f8 so we can't to a ret instruction until
abs>     another 4 bytes are added to the stack pointer. Bug. 
abs> 
abs> 
abs> So who compiled the what_loop function - Absoft or gcc?
Re: Request: help linking egcs-compiled fortran + other fortran
#6556
Author: Craig Burley
Date: Fri, 15 May 1998 00:00
89 lines
4816 bytes
Jeff Templon <templon@studbolt.physast.uga.edu> writes:

> [ comp.lang.fortran people: sorry for all the specifics, but there is
>   a genuine Fortran (egcs/g77) question near the bottom. ]

I'll try to give some info from my perspective, though I can't
really answer any of your problems directly, I'm afraid.

> Now under RedHat 5.0, the exact same code, linked to the exact same
> libraries, dies with a segmentation violation.  At some point in the
> bowels of CERNLIB, the stack gets corrupted and a "return" statement
> causes the program to land at an address 0000000.  What's weird is
> that this should not happen, since this portion of the code has not
> changed at all in the upgrade from redhat 4.2 to 5.0 (barring some
> strange disk error!)

Tim Prince, IIRC, complained about some strange I/O bug(s) he
was running into with g77 built on his RH 5.0 machine.  I can't
recall being able to reproduce them on my RH 5.0 machine, though
I think I've installed most or all of the `update' packages
from RH already, which might account for the differences; not
sure I was ever able to get ahold of a complete test case to
try to reproduce it, however.

But, I think he discovered that upgrading his libc5 or something
fixed the problem.  Which is confusing, because apparently glibc2
is used by default.  I hope he sees your post and responds with
some info that's more useful than what I'm speculating about.

> Problem: egcs/g77 "libf2c" package is not really the same as the real
> libf2c as distributed by AT&T.  Thus the link phase complains about
> missing symbols.  So I pick up egcs-1.02 and install it so that I have
> the version of libf2c which this CERNLIB expects.  Compile and link.

netlib's libf2c hasn't been integrated into egcs' copy for some time.
However, there shouldn't be missing symbols, except for libU77
stuff like dtime_ and etime_, which would normally get called
by g77 as G77_dtime_0 and G77_etime_0.  It's a long story, but
if you tried, you could probably add egcs/g77's libU77 to your
netlib-libf2c tree, though it takes me a long time to do stuff
like this for g77.

> Problem: another difference of stock libf2c vs egcs libf2c is that the
> egcs version defines the routine "main" within the library.

So does stock libf2c, at least, last time I checked.

> Thus,
> when I try to link it only as a support library, and the main routine
> is compiled with _another_ compiler (Absoft), I get *two* main
> routines defined.  I don't know the implications of removing the
> "main" routine from libf2c (does g77 I/O work if I do this) nor do I
> know how to convince the loader how to do this (do I simply remove
> main.o from libf2c using the 'ar' command?)

I think g77/f2c I/O works without going through libf2c's main, but
exception handlers aren't necessarily set up as you might expect.
See libF77/main.c for what goes on.

Why there's a problem having main.o in libf2c is beyond me.  Seems
to me that as long as you link only *one* "main program unit"
(Fortran "PROGRAM"), crt0.o or crt1.o or whatever calls main_
should be linked to that, instead of the linker pulling in
libf2c/main.o.  It shouldn't matter, in this sense, whether the
main program unit is compiled by g77/f2c or Absoft, assuming
Absoft compiles main_ or MAIN__, because crt[01].o calls main_,
which is either produced by Absoft or is linked to libf2c's main_,
and the latter calls MAIN__.

Of course, if you put the .o's compiled by Absoft or g77/f2c,
and these include a main program unit, that can make for problems,
since you have to worry (more) about command-line ordering when
linking.

Isn't this fun?

> In short: I am stuck -- the only recourse I know is to downgrade to
> RedHat 4.2.  Anyone who has any suggestions, ideas, or solutions
> is extremely welcome to pass them on!

Another possibility is to wait for g77 0.5.23 to appear, grab
that, and recompile everything in sight.  That might improve
things, make things worse, etc., but it'll be a "cleaner" release
based on gcc 2.8.1.  Watch <ftp://alpha.gnu.org/g77.plan>.
-- 

"Practice random senselessness and act kind of beautiful."
James Craig Burley, Software Craftsperson    burley@gnu.org
Re: Request: help linking egcs-compiled fortran + other fortran
#6557
Author: Jeff Templon
Date: Fri, 15 May 1998 00:00
86 lines
4314 bytes
Hi,

Craig Burley <burley@tweedledumb.cygnus.com> writes:

> > Problem: another difference of stock libf2c vs egcs libf2c is that the
> > egcs version defines the routine "main" within the library.
> 
> So does stock libf2c, at least, last time I checked.

stock libf2c defines something called MAIN__ but not `main', or at
least I never had a problem with it.  The classic workaround was something
like -X defsym -X MAIN__=main on the loader command line.  Due
to the extra appearance of "main", it no longer worked with G77 libf2c.
This is not specific to redhat 5.0 either, we've had this problem
on redhat 4.2 as well whenever G77 is installed.

> Why there's a problem having main.o in libf2c is beyond me.  Seems
> to me that as long as you link only *one* "main program unit"
> (Fortran "PROGRAM"), crt0.o or crt1.o or whatever calls main_
> should be linked to that, instead of the linker pulling in
> libf2c/main.o.  It shouldn't matter, in this sense, whether the
> main program unit is compiled by g77/f2c or Absoft, assuming
> Absoft compiles main_ or MAIN__, because crt[01].o calls main_,
> which is either produced by Absoft or is linked to libf2c's main_,
> and the latter calls MAIN__.

See below, attached messages.  The real question is, why is G77
libf2c behaving differently than stock libf2c?  The fix proposed
in the messages below solved the problem, although it's a
huge hack.

					JAT

ps: have not included email addresses of the people who solved
this, since I don't want to be responsible for exposing them
to spam.  They did not use the newsgroups for reply, so I assume
they'd rather not have their email addresses posted.
The solutions below are the work of other people, not me!

--------------------------------------------------
$ Subject: Re: Request: help linking egcs-compiled fortran + other fortran
$ Date: Thu, 14 May 1998 17:32:38 BST
$ 
$ >  
$ >  > My two cents of contribution as an attempt to solve this problem.
$ >  > We have found that to avoid the two main programs that Jeff is
$ >  > reporting above, you can include the definition of the two
$ >  > following global variables in your C/C++ main program
$ >  > int xargv=0;
$ >  > int xargc=0;
$ >  >
$ >  > This works for us. We can link ROOT with CERNLIB98a.
$ >  > This is clearly a pain in the neck and more attention should have
$ >  > been given to this problem before making the release.
$ > 
$ > What if my main program is not C/C++ (it's not!)  Any ideas?
$ > 
$ 
$ Well, a quick and dirty way is to create a small c function
$ with these two statements and link it explicitely with your main.

--------------------------------------------------
* 
* Jeff Templon writes:
*  > Rene:
*  > 
*  > You are a genius!  Thanks, it worked.  I'm not sure I understand why,
*  > but that's OK.
*  > 
* 
* I think it works because there is a call to `getarg' in KUIP (kuinit.o
* I think it is). In libf2c, `getarg' gets the command line args via the
* `xargc' and `xargv' globals which are defined in libf2c's `main'. By
* pre-defining them there is no reason for the linker to pick up `main'.
* 
* I needed to do a kludge similar to Rene's to get PGF77 (v1.4 +
* gcc/libc5 system) to play nice with CERNLIB and C main()s. I fixed it
* by writing fake `getarg_' and `iargc_' functions. This, in effect,
* just blocks the linking in of the `xargc' and `xargv' globals which
* blocks the linking in of libf2c's main.
* 
* In general, I think it is not so good to call the `getarg' or `iargc'
* routines inside library code as it makes an arrogant assumption about
* which language `main' is being written in. Oh well.
* 
Re: Request: help linking egcs-compiled fortran + other fortran
#6558
Author: Craig Burley
Date: Fri, 15 May 1998 00:00
82 lines
4645 bytes
Jeff Templon <templon@studbolt.physast.uga.edu> writes:

> Hi,

Hi back, and thanks for the helpful info!  Maybe we can fix some
of these things before 0.5.23 is released.

> Craig Burley <burley@tweedledumb.cygnus.com> writes:
> 
> > > Problem: another difference of stock libf2c vs egcs libf2c is that the
> > > egcs version defines the routine "main" within the library.
> > 
> > So does stock libf2c, at least, last time I checked.
> 
> stock libf2c defines something called MAIN__ but not `main', or at
> least I never had a problem with it.  The classic workaround was something
> like -X defsym -X MAIN__=main on the loader command line.  Due
> to the extra appearance of "main", it no longer worked with G77 libf2c.
> This is not specific to redhat 5.0 either, we've had this problem
> on redhat 4.2 as well whenever G77 is installed.

Okay, this confuses me.  AFAIK, stock (netlib) libf2c does not
*define* MAIN__ (which becomes MAIN___), it defines main (which
becomes main_), and its main() calls MAIN__.

In this respect, g77 should be no different, in any release, from
the netlib libf2c.

> $ >  > My two cents of contribution as an attempt to solve this problem.
> $ >  > We have found that to avoid the two main programs that Jeff is
> $ >  > reporting above, you can include the definition of the two
> $ >  > following global variables in your C/C++ main program
> $ >  > int xargv=0;
> $ >  > int xargc=0;
[...]
> * I think it works because there is a call to `getarg' in KUIP (kuinit.o
> * I think it is). In libf2c, `getarg' gets the command line args via the
> * `xargc' and `xargv' globals which are defined in libf2c's `main'. By
> * pre-defining them there is no reason for the linker to pick up `main'.
> * 
> * I needed to do a kludge similar to Rene's to get PGF77 (v1.4 +
> * gcc/libc5 system) to play nice with CERNLIB and C main()s. I fixed it
> * by writing fake `getarg_' and `iargc_' functions. This, in effect,
> * just blocks the linking in of the `xargc' and `xargv' globals which
> * blocks the linking in of libf2c's main.
> * 
> * In general, I think it is not so good to call the `getarg' or `iargc'
> * routines inside library code as it makes an arrogant assumption about
> * which language `main' is being written in. Oh well.

It seems to me as if a simple and worthwhile solution is to have
libf2c (maybe just g77's version for now, but perhaps netlib will
pick up this change after we email it to them) put the definitions
of xargc and xargv into a separate source module, maybe named
`xarg.c', compiled and added to libf2c as `xarg.o'.  Of course its
main() routine would then `extern' these and set them as usual.

That way, if you want your own main(), you can have it and GETARG/IARGC
as well, as long as you set xargc and xargv in main().  (Though,
I don't like the names xargc/xargv, and hardly wish to publish
them further, as they could conflict with user code, e.g.
SUBROUTINE XARGC shouldn't conflict with it.)

Hmm, I think I'll try mangling the external names somewhat and
provide wrappers for them, so user-written main() routines can
simply call the wrappers instead of having to memorize names.
(In the libf2c world, all mangling requires is inserting an
underscore into the midst of a name, which keeps the current
naming convention from colliding with it.  `x_argc', for example,
can't be called by an g77/f2c-compiled program because of the
trailing underscore(s), unless special options are used, options
that mean "you're likely to break your program this way".  :)

How does that sound as a general approach to solving this particular
problem?  It might be worth holding up 0.5.23 to get this "right",
at least a couple of days.  Heck, if MS can hold up Windows 98 over
the weekend, we can hold up g77 0.5.23 for about that long, right?
-- 

"Practice random senselessness and act kind of beautiful."
James Craig Burley, Software Craftsperson    burley@gnu.org
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads