> Date: Wed, 17 Aug 2016 12:50:54 -0700
> From: Philip Guenther <guent...@gmail.com>
> 
> On Wed, 17 Aug 2016, Mark Kettenis wrote:
> ...
> > Functions listed by DT_PREINIT_ARRAY get run immediately after ld.so has 
> > finished loading and relocating all shared objects. This happens only 
> > for the main executable.
> 
> The _dl_call_init() invocation in dlopen() needs to change too, or 
> dlopen() will call preinit functions in the requested object, no?

Hmm, yes.  Our linker doesn't actually allow you to create a
DT_PREINIT_ARRAY in something that isn't an executable, but the
standard is quite explicit:

  DT_PREINIT_ARRAY

    This element holds the address of the array of pointers to
    pre-initialization functions, discussed in ``Initialization and
    Termination Functions'' below. The DT_PREINIT_ARRAY table is
    processed only in an executable file; it is ignored if contained
    in a shared object.

I'll fix that.

> > There is a functional change here.  Our current ld.so doesn't run 
> > DT_INIT and DT_FINI for the main executable.  The ELF standard is a bit 
> > ambiguous about this, but Linux does run tose for the main executable.  
> > And Solaris allegedly does as well.  So my diff changes that.
> 
> ld.so doesn't run them because __start() in csu does!  Note that csu needs 
> to run them for static executables, and we use the same crt0.o for both 
> static and dynamic executables.  I think you're double executing them with 
> this.

We're not double executing because we don't create a DT_INIT entry for
them.

> (There are _some_ regress tests for this, but we'll want to add more for 
> the {init,fini,preinit}array additions.)

Yeah, I need to convert my testing code into a proper regress test.

Reply via email to