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++