On Mon, Jul 11, 2011 at 01:00:08PM +0100, David Gilbert wrote:
> On 11 July 2011 12:30, Dave Martin <dave.mar...@linaro.org> wrote:
> > On Mon, Jul 11, 2011 at 10:42:27AM +0100, Richard Sandiford wrote:
> >> Dave Martin <dave.mar...@linaro.org> writes:
> >> > IFUNC doesn't solve the problem because either it gets resolved
> >> > lazily (violating the above principle (*)), or we have to force _all_
> >> > symbols to resolve at startup, with may have a significant impact on
> >> > startup time for large programs.
> >>
> >> IFUNCs are never resolved lazily; that's one way in which they differ
> >> from PLTs.
> >>
> >> (BTW, in response to a comment upthread, ARM does support IFUNCs now.)
> >
> > Do you know when support was merged in eglibc?
> >
> > For example, Linaro binutils 2.21.0.20110327-2ubuntu3 appears to support
> > IFUNC, but the natty version of eglibc (2.13-0ubuntu13) does not handle
> > it correctly.
> 
> That's why I didn't try and use it; I thought it was best to wait for
> it to percolate through.
> 
> Richard's patch went into glibc-ports on April 26th and looks like it
> got imported into eglibc-ports
> on 5th May (svn rev 13608); there was also a fix from Joseph Myers in that 
> area
> on 21st June.

Just for context, I had a quick play to get a feel for the feasibility of
implementing this directly, without relying either on a VDSO or on IFUNC.

It's possible to produce something which works reasonably well: see the
attachment.  The result is almost the same as what IFUNC would achieve
(although &__kernel_cmpxchg64 leaves something to be desired; macros
could potentially fix that).

[see attached]


The various helpers are checked independently at startup if they are used,
by registering the resolver functions as constructors as others have
suggested.  (Note that gcc/libc already fails to do this check for the
older kernel helper functions; it's just that you're unlikely to observe
a problem on any reasonably new kernel.)

The problem of constructor ordering is solved by pointing each indirect
function pointer at the appropriate resolver function initially.
Threading is not taken into account because no additional threads can
exist during execution of constructors (though if more libraries are
later dlopen()'d they may invoke additional constructors in the presence
of threads, so this might need fixing).

The main question is the correct way to blow the program up if a needed
helper function is not available.  Calling exit() is possibly too gentle,
whereas calling abort() may be too aggressive.  libc may have some correct
internal mechanism for doing this, but my knowledge falls short of that.

What to do in the case of recursive lookup failures isn't obvious:
currently I just call abort().  By this point the process should be
running atexit handlers or destructors, so calling exit() isn't going
to help in this situation anyway.

The other question is whether and how the program can be enabled to catch
the error and report something intelligible to the user.  If there is a
hook for catching dynamic link failures, we should maybe use the same.
If this problem is not solved for dynamic linking in general, it doesn't
make sense to require the kuser functions to solve it either (except that
if the problem is eventually solved, we want the fix to work smoothly for
both).


Of course, all of these are generic dynamic linking challenges which
ld.so likely has some policy or solution for already.


Overall, this isn't a perfect solution, but it doesn't feel catastrophically
bad either.

Any thoughts?

Cheers
---Dave

Attachment: libkuser.tar.gz
Description: Binary data

_______________________________________________
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev

Reply via email to