|
Message-ID: <20220823202926.GK7074@brightrain.aerifal.cx> Date: Tue, 23 Aug 2022 16:29:27 -0400 From: Rich Felker <dalias@...c.org> To: Ben Noordhuis <info@...ordhuis.nl>, musl@...ts.openwall.com Subject: Re: [PATCH] ldso: add basic ifunc support On Tue, Aug 23, 2022 at 10:03:32PM +0200, Szabolcs Nagy wrote: > * Ben Noordhuis <info@...ordhuis.nl> [2022-08-23 20:41:57 +0200]: > > Not perfect yet because it doesn't handle resolver functions that need > > relocations themselves but basic functionality works. That is, this > > works: > > > > typedef void (*Func)(void); > > void f(void) __attribute__((ifunc("g"))); > > Func g(void) { return h; } > > void h(void) { abort(); } > > > > But returning an extern function does not: > > > > typedef void (*Func)(void); > > void f(void) __attribute__((ifunc("g"))); > > Func g(void) { return abort; } // segfaults > > there are a lot more problems than that. > > the patch only works if f is hidden or binds locally in some other > way (e.g. in an executable) otherwise references to f will generate > symbolic relocations not IRELATIVE. > > resolving symbolic relocation for ifunc symbols requires the ldso > to look at the symbol type (STT_GNU_IFUNC) and do the indirect call > based on that. > > the main issue is that code is executed before the module is fully > relocated (in fact it may execute code in other libs before those are > relocated because symbol lookup can process not yet relcated libs) > which is problematic if the resolver function itself depends on > relocations (e.g. return h only works if constructing the address > of h does not require dynamic relocs or those relocs happen to get > resolved before the IRELATIVE, glibc tries a bit to shuffle ifunc > relocs to the end of reloc processing, it was never fixed completely > iirc because copy relocs and circular deps made things complicated). > > and of course static linking is not addressed (where there are > further ordering issues since it is target dependent if ifunc has > to be resolved before or after TLS is set up). Yes, there are multiple reasons ifunc is not just a missing feature but rejected as an anti-feature. It has issues with the order relocations take place in and exposes that as a contract with the application, especially if (like musl) you do not do lazy binding, which slightly relaxes the ordering requirement. It does not have a well-defined or definable contract for what you can actually do from the resovler functions, isn't compatible with static linking, etc. Everything that can be done badly with ifunc can be done just as well, fully portably, with function pointers initialized to a generic version of the function replaced by ctors, or to a self-initializing version of the function that replaces itself on first call (modulo some technicalities about how you do the atomics, but this is basically solvable with relaxed-mode atomics or call_once). In a normal dynamic-linked context, this is just as fast as an ifunc call too -- you just load the function pointer from a PC-relative address outside the GOT rather than a PC-relative address in the GOT (and you get to bypass the PLT thunk too). Rich
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.