This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Support -z initfirst for multiple shared libraries


On Thu, Apr 28, 2016 at 12:58 PM, Yury Gribov <y.gribov@samsung.com> wrote:
> On 04/28/2016 06:54 PM, Szabolcs Nagy wrote:
>>
>> On 28/04/16 16:27, Carlos O'Donell wrote:
>>>
>>> On 04/27/2016 01:22 PM, Yury Gribov wrote:
>>>>
>>>> Yeah. It seems that initfirst is a crude hack which bypasses all
>>>> dependency tracking. I wonder if there's a place for another,
>>>> hopefully saner, dependency-respecting flag.
>>>
>>>
>>> What use cases do you need to support?
>>>
>>> How would a dependency-respecting initfirst-like flag work given the
>>> conflicting requirements to initialize in dependency order and yet
>>> not initialize in dependency order?
>>>
>>
>> may be use a topological sort order where the
>> flagged module comes earliest possible?
>
>
> That was my expectation as well.

It seems like we have found two use cases for initfirst:
1) Changing the behaviour of libraries loaded later (pthread tells libc
it needs to support multithreading before libc is initialized). This is
for tightly coupled libraries and dependency order does not matter here
assuming you're just setting flags.

2) Getting a very early hook into the program for profiling,
etc. Dependency ordering is necessary only to ease the implementation
of this hook. Any dependencies are not going to be handled by this hook
(i.e. you can't profile libdl if you depend on it).

There are other ways of implementing hook dependencies. For example,
hook-safe libraries like libdl could check if they have been initialized,
and if not, initialize before processing the user's request (dlsym). Or,
a constructor could have the option to run other constructors by library
name (via ld.so's call_init). I think a tool that needs serious control
over the loading process will simply reimplement its dependencies as I did
to make sure it really knows what's going on. The ordering at load-time
is already complicated enough as it is...

Would it be possible to just statically link libdl into the tool? Or design
libdl so that it doesn't need initializing? Then anyone can call dlopen,
dlsym, and do what they need to do.


>
>
>>> Today we have:
>>>
>>> - Library initializers and finalizers (Run in dep order)
>>> - Library constructors and destructors (Run in dep order)
>>> - Prioritized constructors and destructors (Run in dep order, and #
>>> order)
>>> - LD_PRELOAD initializer run last before the application is initialized.
>>> - Non-zero initialized data from .data in the ELF image.
>>>
>>> Dependency ordering also include symbol dependencies and relocation
>>> dependencies, sorting all objects into a linear list and breaking
>>
>>
>> if that was done correctly then i think LD_PRELOAD
>> libs would come before the modules using the interposed
>> symbols.
>>
>>> cycles where appropriate at deterministic points (though we need
>>> a better ldd to show these problems).
>>>
>>> It might be better if we had some kind of invariant assertions like
>>> "abort if I'm not initialized before library SONAME" that then allowed
>>> developers to realize their invariant is wrong and restructure the
>>> application. Alternatively if we had some better tooling that might
>>> help also (I'm working on an alternate eu-ldd and deterministic
>>> cycle breaking in ld.so, but it's a long way off).
>>>
>>
>> depending on elf ctor ordering sounds broken to me.
>> (incompatible with static linking)
>>
>> depending on deterministic ordering in the presence
>> of cycles sounds even more nonsensical.
>> (the dynamic linker shouldn't try to solve np hard
>> problems.)
>>
>>
>>
>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]