This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Global Constructors and Shared Libraries


> 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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]