RFC: Add pagesize to __ifunc_arg_t
Hey!
I am working on HWASan where we have some initialization logic in ifunc resolvers. For non-4K page size systems, it would be nice to know the page size (because we call mmap via our own implementation of syscall). __ifunc_arg_t solves this for HWCAP (and HWCAP2), so it seems natural to also add the page size. I would be happy to do the change in glibc and Android Bionic.
What do you think?
Thanks for creating the issue.
I expect the place to document this would be in https://github.com/ARM-software/abi-aa/blob/main/sysvabi64/sysvabi64.rst#941gnu-c-library-ifunc-interface
I think @nsz-arm would likely be the best person to discuss this and the implementation choices. Although it may be best to do that on the glibc/bionic mailing lists as I see this as a GNU/Linux platform decision that I'd certainly be happy to document the outcome if __ifunc_arg_t changed.
Some thoughts, I'm mostly a linker person so I've not got too much expertise in this area:
- Page size wouldn't normally be within the scope of hwcaps (based on https://docs.kernel.org/arch/arm64/elf_hwcaps.html). Is adding page-size within the spirit of ifunc resolvers, or is it anything that can be used.
- How do we describe the page size? There could be another entry, or given that there are only likely to be a few entries do we use a small number of bits, potentially (ab)using HWCAP bits.
- Would we need to have a way of testing that page size is available? Or could it be implied from the size field?
Another idea would be to put a pointer to the auxval array there, that would let people extract pagesize but also other information they might need.
we will have to extend ifunc arg with hwcap3 soon so it is a good time to discuss extensions.
i think pagesize is ok to add, pointer to auxv may be.
for the record, the constraints are that an ifunc resolver
- may be called multiple times (for every dynamic reloc referencing it in the same or different module).
- must return the same result during the lifetime of a process and thus its argument must not change either between calls.
- must not access global data or call functions in other modules including the libc, so relevant parameters must be passed in the arguments or available via id registers (though the latter is trap-and-emulate so has linux entry overhead).
- may access local data and local functions but only if this does not depend on dynamic relocations (which may be processed later than the ifunc reloc).
- must not access tls (this is arch specific constraint on targets where it runs before tls setup with static linking).
- must be async-signal- and thread-safe (in case ld.so supports lazy binding).
- must not fail (may run late when crash/abort is unacceptable).
if auxv is user modifiable (according to interface contracts, not according to page protection) then a libc would need to make a copy to pass it to ifunc resolvers (unbounded memory) even then it would be fine to pass an unspecified subset to resolvers in auxv format, however it is ugly to parse auxv in a resolver when all you need is hwcap flags. (i think argv and env are owned by the user application, but auxv is owned by the libc, so probably fine to pass.)
it's hard to find out the pagesize so that's a valid request (i believe one could do it with a raw mprotect syscall, with some handwaving, but i would not recommend using raw syscalls).
fyi, glibc (and bionic) are adding _hwcap3 and _hwcap4 to __ifunc_arg_t.
Thanks for letting me know.
I've found https://inbox.sourceware.org/libc-alpha/[email protected]/ (upstream review) for glibc.
If there's a public bionic link that would be great.
I can update the description in the sysvabi when this lands.
Thanks for letting me know.
I've found https://inbox.sourceware.org/libc-alpha/[email protected]/ (upstream review) for glibc.
If there's a public bionic link that would be great.
sadly we're a week too late for that kind of thing --- https://source.android.com/docs/setup/about/faqs#android-latest-release
but i wasn't planning on merging until either glibc or the psabi is updated, since the whole point is source compatibility :-)