public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Re: dlopen() does not call static constructors on HP-UX
@ 2002-12-06 21:27 John David Anglin
  2002-12-12 12:07 ` Harri Pasanen
  0 siblings, 1 reply; 7+ messages in thread
From: John David Anglin @ 2002-12-06 21:27 UTC (permalink / raw)
  To: gcc; +Cc: harri

> > Looks like on HP-UX 11.00,  using g++ 3.2, when I link against a shared 
> > library containing static objects, their constructors are called.  But 
> > if I do dlopen(), or shl_load() for the shared library, the static 
> > objects are not initialized.
> 
> I have an impression that DT_INIT_ARRAY/DT_FINI_ARRAY may work with
> HP-UX if ELF is used.

The 32-bit port uses collect to collect constructors and these are all
run just after main is entered.  There is no way this will work with
a dlopened library.  As H. J. noted, you can use +init/+fini switches,
I think with both the 32 and 64-bit HP linkers.  On the 32-bit port,
you would have to manually build the constructor/destructor lists
along the lines as is done by collect.

You might have better luck with the 64-bit port and the HP linker.
Read the comment near the end of pa64-hpux.h.  Get the current cvs
source and enable the LD_INIT_SWITCH/LD_FINI_SWITCH macros.  This
still uses collect but in this case the code to run the init/fini
routines are in the libraries as well as the main executable, so
they should run when a library is dlopened.

I believe that DT_INIT/DT_FINI are not supported by the HP dynamic
64-bit loader and that's why using -init/-fini doesn't work with
the GNU linker.  It needs some work.

With some experimentation, it might be possible to use +init/+fini
on the 32-bit port on 10.X and 11.X.  You would have to remove
LDD_SUFFIX and PARSE_LDD_OUTPUT, and define LD_INIT_SWITCH/LD_FINI_SWITCH.
If that works, it would be a useful improvement.  There is only
one linker to worry about in this case and you wouldn't need any
special tricks to change switches as in the 64-bit case.  If you
try it and it works, let me know.

Dave
-- 
J. David Anglin                                  dave.anglin@nrc.ca
National Research Council of Canada              (613) 990-0752 (FAX: 952-6605)

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: dlopen() does not call static constructors on HP-UX
  2002-12-06 21:27 dlopen() does not call static constructors on HP-UX John David Anglin
@ 2002-12-12 12:07 ` Harri Pasanen
  2002-12-12 12:26   ` David Edelsohn
                     ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Harri Pasanen @ 2002-12-12 12:07 UTC (permalink / raw)
  To: John David Anglin, gcc

On Saturday 07 December 2002 06:09, John David Anglin wrote:
> > > Looks like on HP-UX 11.00,  using g++ 3.2, when I link against a
> > > shared library containing static objects, their constructors are
> > > called.  But if I do dlopen(), or shl_load() for the shared
> > > library, the static objects are not initialized.
> >
> > I have an impression that DT_INIT_ARRAY/DT_FINI_ARRAY may work with
> > HP-UX if ELF is used.
>
> The 32-bit port uses collect to collect constructors and these are
> all run just after main is entered.  There is no way this will work
> with a dlopened library.  As H. J. noted, you can use +init/+fini
> switches, I think with both the 32 and 64-bit HP linkers.  On the
> 32-bit port, you would have to manually build the
> constructor/destructor lists along the lines as is done by collect.
>

I've currently been only experimenting with 32 bit port, apparently the 
64 bit port seems to be broken, both 3.2 and the CVS version.

Looking at what is happening when shared library is linked with 
-Wl,+debug, I noticed that each shared lib appears to have just one 
function that calls the constructors.   That function appears to be 
smart enough, so that if it is called more than once, it will still 
only construct the objects once.

So if I have a C++ built shared library called foo.sl, the function 
resposible called the constructors is called _GLOBAL__FI_foo_sl.
By passing -Wl,+I -Wl,_GLOBAL__FI_foo_sl to the linker when linking the 
shared lib, the loader will call _GLOBAL__FI_foo_sl and all the 
constructors are called.  This works also when dlopen/shl_load is used, 
and appears to do no harm if it is linked with directly.

I have not bothered about calling the destructors, as I'm not unloading 
any libs.

It is possible to make the above process fully automatic, but it 
requires first building the shared lib, looking if the _GLOBAL__FI_* 
symbol is present and then rebuilding it.

So all this is done without any modifications to gcc itself.   Can you 
see any pitfalls with my approach?   I'll let you know if I run into 
any problems.

-Harri

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: dlopen() does not call static constructors on HP-UX
  2002-12-12 12:07 ` Harri Pasanen
@ 2002-12-12 12:26   ` David Edelsohn
  2002-12-12 13:02   ` John David Anglin
  2002-12-12 14:29   ` John David Anglin
  2 siblings, 0 replies; 7+ messages in thread
From: David Edelsohn @ 2002-12-12 12:26 UTC (permalink / raw)
  To: Harri Pasanen; +Cc: John David Anglin, gcc

>>>>> Harri Pasanen writes:

Harri> It is possible to make the above process fully automatic, but it 
Harri> requires first building the shared lib, looking if the _GLOBAL__FI_* 
Harri> symbol is present and then rebuilding it.

Harri> So all this is done without any modifications to gcc itself.   Can you 
Harri> see any pitfalls with my approach?   I'll let you know if I run into 
Harri> any problems.

	You do not need to build the library twice.  GCC's collect2 knows
the name of the function.  I would suggest looking at how I enabled
something similar in collect2.c for AIX.  Look for LD_INIT_SWITCH.

David

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: dlopen() does not call static constructors on HP-UX
  2002-12-12 12:07 ` Harri Pasanen
  2002-12-12 12:26   ` David Edelsohn
@ 2002-12-12 13:02   ` John David Anglin
  2002-12-12 14:29   ` John David Anglin
  2 siblings, 0 replies; 7+ messages in thread
From: John David Anglin @ 2002-12-12 13:02 UTC (permalink / raw)
  To: Harri Pasanen; +Cc: gcc

> I've currently been only experimenting with 32 bit port, apparently the 
> 64 bit port seems to be broken, both 3.2 and the CVS version.

Did you try what I suggested using the HP linker and enabling the
LD_INIT_SWITCH and LD_FINI_SWITCH macros in pa64-hpux.h?  Constructors
are not being called in shared libraries currently because the technique
used in the 32-bit SOM port doesn't work.

If you are having other difficulties with the 64-bit port, please
provide specifics.

> Looking at what is happening when shared library is linked with 
> -Wl,+debug, I noticed that each shared lib appears to have just one 
> function that calls the constructors.   That function appears to be 
> smart enough, so that if it is called more than once, it will still 
> only construct the objects once.

Yes.

> So all this is done without any modifications to gcc itself.   Can you 
> see any pitfalls with my approach?   I'll let you know if I run into 
> any problems.

The LD_INIT_SWITCH is a much much simpler approach.  As I indicated, I
believe that the HP linker has supported +init/+fini switches since at
least HPUX 10.  Collect will build the init/fini global constructors
for you and the dynamic loader will arrange to call the init/fini
routines for you when the library is loaded/unloaded.

The GNU linker needs to be fixed to use this approach or init/fini
sections.  I believe that it currently sets DT_INIT/DT_FINI.  These
aren't supported by HPUX.  It needs to set DT_INIT_ARRAY/DT_FINI_ARRAY.
The LD_INIT_SWITCH/LD_FINI_SWITCH macros are not enabled because they
cause problems with the GNU linker (i.e., GCC will not build).

Dave
-- 
J. David Anglin                                  dave.anglin@nrc.ca
National Research Council of Canada              (613) 990-0752 (FAX: 952-6605)

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: dlopen() does not call static constructors on HP-UX
  2002-12-12 12:07 ` Harri Pasanen
  2002-12-12 12:26   ` David Edelsohn
  2002-12-12 13:02   ` John David Anglin
@ 2002-12-12 14:29   ` John David Anglin
  2 siblings, 0 replies; 7+ messages in thread
From: John David Anglin @ 2002-12-12 14:29 UTC (permalink / raw)
  To: Harri Pasanen; +Cc: gcc

> So if I have a C++ built shared library called foo.sl, the function 
> resposible called the constructors is called _GLOBAL__FI_foo_sl.
> By passing -Wl,+I -Wl,_GLOBAL__FI_foo_sl to the linker when linking the 
> shared lib, the loader will call _GLOBAL__FI_foo_sl and all the 
> constructors are called.  This works also when dlopen/shl_load is used, 
> and appears to do no harm if it is linked with directly.

This is what the LD_INIT_SWITCH and LD_FINI_SWITCH defines do for you.
In looking at HPUX 10, I see that only the "+I" option is available
for running initializers.  There isn't an option for finalizers.
HPUX 11 ld has +init/+fini as well.

Thus, I can see using LD_INIT_SWITCH/LD_FINI_SWITCH for the HPUX 11
32-bit port but I am not sure there is a good argument to do this
for HPUX 10 as it seems to lack a switch to automatically call
destructors.

You might also be able to explicitly call the initializer and finalizer
routines when using dlopen/shl_load.

> I have not bothered about calling the destructors, as I'm not unloading 
> any libs.
> 
> It is possible to make the above process fully automatic, but it 
> requires first building the shared lib, looking if the _GLOBAL__FI_* 
> symbol is present and then rebuilding it.

I believe it is collect2 that creates the _GLOBAL__FI_* initializer for
each shared library.

Dave
-- 
J. David Anglin                                  dave.anglin@nrc.ca
National Research Council of Canada              (613) 990-0752 (FAX: 952-6605)

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: dlopen() does not call static constructors on HP-UX
  2002-12-05 23:24 Harri Pasanen
@ 2002-12-06  0:44 ` H. J. Lu
  0 siblings, 0 replies; 7+ messages in thread
From: H. J. Lu @ 2002-12-06  0:44 UTC (permalink / raw)
  To: harri.pasanen; +Cc: gcc

On Fri, Dec 06, 2002 at 08:06:14AM +0100, Harri Pasanen wrote:
> I suppose this is an old can of worms, but after multiple searches 
> through the mailing list I'm still not enlightened in my specific 
> problem, so here I go.
> 
> Looks like on HP-UX 11.00,  using g++ 3.2, when I link against a shared 
> library containing static objects, their constructors are called.  But 
> if I do dlopen(), or shl_load() for the shared library, the static 
> objects are not initialized.
> 
> Now seems like a HP-UX specific bug, and searching gnats it indeed looks 
> like the same one 
> as PR 8360. 
> http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=8360
> 
> Having full control of the dlopen(), which happens in my C++ source, I'm 
> looking for a way to manually circumvent this bug.  Examining my shared 
> library symbols, looks like there is something called 
> __static_initialization_and_destruction, which I guess arranges for the 
> constructors and destructors to be called.   Is there a way I can 
> arrange my code to call this function after I've done the dlopen()?

I have an impression that DT_INIT_ARRAY/DT_FINI_ARRAY may work with
HP-UX if ELF is used.


H.J.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* dlopen() does not call static constructors on HP-UX
@ 2002-12-05 23:24 Harri Pasanen
  2002-12-06  0:44 ` H. J. Lu
  0 siblings, 1 reply; 7+ messages in thread
From: Harri Pasanen @ 2002-12-05 23:24 UTC (permalink / raw)
  To: gcc

I suppose this is an old can of worms, but after multiple searches 
through the mailing list I'm still not enlightened in my specific 
problem, so here I go.

Looks like on HP-UX 11.00,  using g++ 3.2, when I link against a shared 
library containing static objects, their constructors are called.  But 
if I do dlopen(), or shl_load() for the shared library, the static 
objects are not initialized.

Now seems like a HP-UX specific bug, and searching gnats it indeed looks 
like the same one 
as PR 8360. 
http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=8360

Having full control of the dlopen(), which happens in my C++ source, I'm 
looking for a way to manually circumvent this bug.  Examining my shared 
library symbols, looks like there is something called 
__static_initialization_and_destruction, which I guess arranges for the 
constructors and destructors to be called.   Is there a way I can 
arrange my code to call this function after I've done the dlopen()?

Regards,

Harri

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2002-12-12 21:59 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-12-06 21:27 dlopen() does not call static constructors on HP-UX John David Anglin
2002-12-12 12:07 ` Harri Pasanen
2002-12-12 12:26   ` David Edelsohn
2002-12-12 13:02   ` John David Anglin
2002-12-12 14:29   ` John David Anglin
  -- strict thread matches above, loose matches on Subject: below --
2002-12-05 23:24 Harri Pasanen
2002-12-06  0:44 ` H. J. Lu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).