On Fri, Jul 08, 2011 at 11:36:30AM -0700, Richard Henderson wrote:
On 07/08/2011 09:55 AM, Dave Martin wrote:
Talking to Will Deacon about this, it sounds like there may be little appetite for VDSO-ifying the vectors page unless there's a real, concrete benefit.
Making the libc startup's job slightly easier probably doesn't count as such a benefit, but if it renders possible something which is otherwise impossible to do from userspace than that would be more compelling.
I don't consider it anything to do with "making libc's job easier", but of providing a standard mechanism for version control of the ABI.
All you're going to do by using a different mechanism is re-invent the wheel.
There's limited support for dlopen within statically linked programs as well. The userland side can provide a static interface which defers to the kernel implementation.
But you don't dlopen the VDSO, it's just mapped by the kernel on process startup. To find it, on other architectures something in the C library needs to grab the base address passed by the kernel in the aux vector.
Of course. Did you think I didn't know that? And so does the dynamic linker, and the dynamic linker stub in libc.a. The point is to get a handle that you can pass into the other functions like dlsym.
I guess I misunderstood the point you were making when you referred to being able to call dlopen from statically-linked programs...
See also _dl_vdso_vsym in libc/sysdeps/unix/sysv/linux/dl-vdso.c, and the uses in libc/sysdeps/unix/sysv/linux/*/init-first.c.
Can individual IFUNCs be set to resolve at startup?
No. They're kinda sorta a special type of PLT entry. So they're resolved either when called, or at startup. See also LD_BIND_NOW for the entire program and DT_BIND_NOW (-Wl,-z,now) for individual libraries and executables.
The key problem that we have is not how to direct the 64-bit atomics to the correct function, but rather what to do about it when there is no suitable target function at all.
I really think we have to detect that on process startup -- detecting that and destroying the program just when it first tries to do a cmpxchg64 is unacceptable IMHO. (*)
I don't think that a constructor function solves this in a maintainable way, because there is no metadata allowing us to determine when this check should be done relative to the other constructors. Simply putting it first raises the question of what order to do things in if we also have another contructor which much be called first.
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.
We could modify the libc startup objects to do the check, but that feels a bit unclean.
That brings us back to VDSO -- am I right in thinking that the symbol versioning checks allow the program to be killed on startup of the VDSO ABI is tool old? If so, maybe that's the right approach after all.
This doesn't replace the existing interface, and the few non-libc based programs can still interact directly with the vectors page to do the same check if they need to.
Cheers ---Dave