On Fri, 19 Aug 2016, Mark Kettenis wrote: > > From: Philip Guenther <guent...@gmail.com> > > Date: Thu, 18 Aug 2016 21:09:10 -0700 > > > > On Thursday, August 18, 2016, Mark Kettenis <mark.kette...@xs4all.nl> wrote: > > ... > > > > > > > > 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. > > > > Hmm, is that a bug? Static and dynamic should ideally behave the same for > > all these, no? > > Ah, perhaps I wasn't clear. We don't create DT_INIT for both static > and dynamic executables.
Hmm, I'm trying to decide if that's a bug or not. > You raise an interesting question though. Traditional static > executables cannot have DT_INIT since they don't have a .dynamic > section. But static PIE executables can have DT_INIT. So should our > self-relocation code attempt to exeute it? To talk mostly at myself... It's an underdocumented part of the ELF standard how code in .init sections gets executed, and how that interacts with setting DT_INIT. The Solaris 11 linker guide says: The sections .init and .fini provide a runtime initialization and termination code block, respectively. The compiler drivers typically supply .init and .fini sections with files they add to the beginning and end of your input file list. These compiler provided files have the effect of encapsulating the .init and .fini code from your relocatable objects into individual functions. These functions are identified by the reserved symbol names _init and _fini respectively. When creating a dynamic object, the link-editor identifies these symbols with the .dynamic tags DT_INIT and DT_FINI accordingly. These tags identify the associated sections so they can be called by the runtime linker. We agree with that for shared-libraries, but for executables we don't, presumably because we can't depend on the viability of the DT_INIT hook because non-PIE, static executables don't have an dynamic section at all, so instead the .init section code ends up in a function __init(): note the extra underbar. That function is then called from __start(). So I think it's fine for you to change ld.so to execute the DT_INIT function for executables: it's won't normally be set but if code explicitly sets it then we'll be fine...as long as they aren't *depending* on doing that to disable execution of .init section code...but if someone did that they deserve to lose: if you don't want .init code, then DON'T INCLUDE IT. The same may apply to executing DT_INIT functions for static, PIE executables. ...but in the end we still need to be able to support static, non-PIE, which means that at least in some cases _start() has to execute .init code and we don't have a great way to handle that case differently in _start(). So for now we need to not handle .init section code in executables via DT_INIT, which makes calling DT_INIT of executables, whether dynamic or static PIE, mostly a moot point and subject to whatever we want to do. Philip