This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Global Constructors and Shared Libraries
- To: mklein at dis dot com
- Subject: Re: Global Constructors and Shared Libraries
- From: "Martin v. Loewis" <martin at loewis dot home dot cs dot tu-berlin dot de>
- Date: Mon, 26 Jun 2000 00:26:04 +0200
- CC: gcc at gcc dot gnu dot org
- References: <4.2.0.58.20000625123437.00bb6600@garfield.dis.com>
> Would someone please take a brief moment and explain to me how
> shared libraries and linking is done on Unix boxes?
I'll try. As a first note, there is no "on Unix", in this respect.
Shared libraries work all different on different systems, unless the
follow System V in this respect and use the ELF binary format.
> My problem now is due to the late binding feature, I need
> to figure out how to make programs be able to invoke the
> global constructors in the shared library. I see in the
> collect2 code some stuff meant to do that, but it appears
> that this requires the program be linked and reference the
> shared library in order to scan it for these references.
> (Is that true whenever a shared library is replaced?)
There is a number of different schemes, and only some require collect2
at all:
1. On an ELF system, each object file contributes a small piece to a
section called .ctors, namely a function pointer. The linker
combines all .ctors sections, starting with the one crtbegin.o
(which gives the starting address of an array __CTORS__) and ending
with crtend.o (which contributes a terminating 0). crtbegin.o also
contains a .init section, which has code to invoke all the function
pointers. This .init section in turn is invoked automatically at
run-time by the dynamic linker.
2. On systems without arbitrarily-named sections, the compiler emits
_GLOBAL_.I.<unique name> symbols, which are the functions mentioned
above. collect2 combines them all into an array which is linked into
the shared library.
2a) On systems with an automatic init section, this array is again
arranged to be executed automatically.
2b) On systems without such a section, collecting is deferred to the
time when main executable is linked. At that time, a function
__main is constructed, which invokes all the functions. In turn,
when the compiler encounters main, it adds an implicit call to
__main. I believe __main will have only a single initializer
function per shared library, so that recollection is not needed
when a shared library changes - only when it changes so much that
it needs initialization now, but didn't before.
> Collect2 runs something called "ldd" that doesn't exist on
> MPE. Since I don't know how this works on other platforms,
> I'm a bit at a loss to emulate it on MPE.
On some systems (SunOS 4), you had to collect initializer routines
recursively: Linking libfoo.so means not only to add an initializer
call for libfoo, but also for every library implicitly loaded by
libfoo.so; ldd is the tool that produces this dependency list.
If MPE is capable of a scheme similar to the ELF one, I strongly
recommend to use such a mechanism, instead of relying on collect2.
collect2 will still be used for the template repository, but that is a
different story.
Regards,
Martin