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