This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [PATCH] Support -z initfirst for multiple shared libraries
- From: Carlos O'Donell <carlos at redhat dot com>
- To: d wk <dwksrc at gmail dot com>, libc-alpha at sourceware dot org
- Date: Thu, 28 Apr 2016 10:12:12 -0400
- Subject: Re: [PATCH] Support -z initfirst for multiple shared libraries
- Authentication-results: sourceware.org; auth=none
- References: <CAPESumqMqVem6VvaKXf_ko1zpM9_wOXixp1O7WGtS0RnvhMSpg at mail dot gmail dot com>
On 04/26/2016 04:58 PM, d wk wrote:
> In a project of mine, I needed to run some code before any constructors
> from any system libraries (such as libc or libpthread). The linker/loader
> -z initfirst feature is perfect for this, but it only supports one shared
> library. Unfortunately libpthread also uses this feature (I assume the
> feature exists because pthread needed it), so my project was incompatible
> with libpthread.
>
> So, I wrote a small patch which changes the single dl_initfirst variable
> into a linked list. This patch does not change the size of any data
> structures (it's ABI compatible), just turns dl_initfirst into a list. The
> list is not freed (the allocator wouldn't free it anyway), and insertion
> into the list is quadratic, but I expect there will never be more than
> a handful of initfirst libraries!
>
> This patch records initfirst libraries in load order, so LD_PRELOAD
> libraries will have their constructors called before libpthread. If the
> opposite behaviour is desired, the LD_PRELOAD'd library can always declare
> a dependency on libpthread. Normally LD_PRELOAD constructors are run last,
> which is very inconvenient when trying to inject new functionality, and
> I expect anyone using -z initfirst with LD_PRELOAD to really want to run
> first. The patch is written against latest glibc 2.23 (I also tested on
> glibc 2.21, and it's not quite compatible with 2.17 since the other data
> structures changed).
>
> I was not the first person to run into this problem,
> someone wanted the same thing on stack overflow two years
> ago. You can see my answer there with a complete test case.
> http://stackoverflow.com/questions/19796383/linux-ld-preload-z-initfirst/36143861
>
> Hope you will accept this patch. Comments welcome. Thanks,
(1) High level review: I like the idea.
At a high level I like the idea.
We have one open bug for this here:
Bug 14379 - shared object constructors are called in the wrong order
https://sourceware.org/bugzilla/show_bug.cgi?id=14379
It is true that LD_PRELOAD'd libraries are loaded last, but only because
of a quirk in the processing mechanics. The library is first in the scope
search order (so the symbols interpose) which means it's initialized last,
and finalized first after the application.
To be honest I think this is a bug and LD_PRELOAD'd libraries should be
initialized and finalized based on their dependencies.
(2) DF_1_INITFIRST
Implementing DF_1_INITFIRST is going to be complicated. It is complicated
by the fact that dlopen could result in N libraries being loaded, and if
M of those is DF_1_INITFIRST, then M must be initialized first. This
is my interpretation of the Solaris implementation and the reason for
the wording "at the same time."
I can't look at your patch to review this though (copyright issues).
(3) Finalization of DF_1_INITFIRST and initfirst libraries.
Ignore DF_1_INITFIRST.
Finalization for initfirst libraries has to happen after the
finalization of all other libraries. This makes the behaviour
deterministic and symmetric.
(4) Copyright status?
Please clarify your copyright status with the project:
https://sourceware.org/glibc/wiki/Contribution%20checklist#FSF_copyright_Assignment
I don't see your name on the copyright assignment documents
from the FSF.
The easiest form is:
http://git.savannah.gnu.org/cgit/gnulib.git/plain/doc/Copyright/request-assign.future
It assigns all current and future contributions to glibc to the FSF and
allows us to accept them immediately.
Cheers,
Carlos.