> Date: Wed, 17 Aug 2016 12:50:54 -0700
> From: Philip Guenther <[email protected]>
>
> 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.