Subject: Re: Getting Mozilla to run under NetBSD
To: Tom Ivar Helbekkmo <tih@nhh.no>
From: Dave Huang <khym@bga.com>
List: port-i386
Date: 12/07/1998 01:36:01
On 7 Dec 1998, Tom Ivar Helbekkmo wrote:
> Little things I've picked up here and there lead me to believe that
> certain initializations are supposed to take place automatically with
> C++, and so I'm wondering whether the statement
> 
> 	static ImageManagerInit imageManagerInit;
> 
> should actually cause the constructor (that's what they're called,
> right?) inside the given struct definition for ImageManagerInit to be

I asked about this on tech-toolchain a day or so ago... haven't heard
anything back yet though. I think that the above statement should call
the constructor, and in fact, it does if it's not in a shared library.
The g++FAQ.texi file in the egcs distribution says:

	If your shared library contains global or static objects with
     constructors, then make sure to use `gcc -shared', not `ld', to
     create the shared library.  This will make sure that any
     processor-specific magic needed to execute the constructors is
     included.

	In theory, constructors for objects in your shared library
     should be called when the library is opened (by dlopen or
     equivalent).  This does not work on some platforms (e.g. SunOS4;
     it does work on Solaris and ELF systems such as Linux): on the
     broken platforms, the constructors are not called correctly.

	David Nilsen has suggested the following workaround:

	The thing to realize is that if you link your dynamic module
     with the `-shared' flag, the collect program nicely groups all
     the static ctors/dtors for you into a list and sets up a function
     that will call them (Note: this means that this trick won't work
     if you use the GNU linker without collect (*note use GNU
     linker?::.).

	The magic is knowing these function names.  Currently, they're
     called:

	  _GLOBAL__DI <-- calls all module constructors
	  _GLOBAL__DD <-- calls all module destructors

	[ possibly the leading underscore will differ between
     platforms: jbuck ]

	Therefore, if you make a wrapper around dlopen that looks up
     the symbol `_GLOBAL__DI' (or `__GLOBAL__DI' on SunOS4 machines),
     and calls it, you'll simulate getting the constructors called.

	You also need to set up the destructors to be called as well,
     so you need to put a wrapper around dlclose, which will call the
     `_GLOBAL__DD' function in the module when/if it's unloaded.

	Lastly, to get things 100% correct, you need to set up the
     destructors to also be called if the module is not unloaded, but
     the main program exits.  I do this by registering a single
     function with `atexit()' that calls all the destructors left in
     dynamically loaded modules.

	Check the file `README.SHLIB' from the libg++ distribution for
     more about making and using shared libraries.

I don't know if the requirement to use "gcc -shared" instead of "ld" to
make the shared libraries is correct for NetBSD, and if it is, I don't
know how to do it. There's no README.SHLIB on my system...
-- 
Name: Dave Huang     |   Mammal, mammal / their names are called /
INet: khym@bga.com   |   they raise a paw / the bat, the cat /
FurryMUCK: Dahan     |   dolphin and dog / koala bear and hog -- TMBG
Dahan: Hani G Y+C 23 Y++ L+++ W- C++ T++ A+ E+ S++ V++ F- Q+++ P+ B+ PA+ PL++