To allow for a dynamic page size on arm64 have the runtime linker
query the kernel for the currentl page size.
Details
Same rtld binary runs on a kernel built with 4k and 16k pages on arm64
Diff Detail
- Repository
- rS FreeBSD src repository - subversion
- Lint
Lint Passed - Unit
No Test Coverage - Build Status
Buildable 45043 Build 41931: arc lint + arc unit
Event Timeline
Rtld already has to cope with pagesizes. In particular, look at init_pagesizes() and RTLD_INIT_PAGESIZES_EARLY. The later is actually a remnant of ia64 which might be exactly what you need. This should allow to eliminate all getpagesize() calls from your patch and use pagesizes[0].
It might be best to remove RTLD_INIT_PAGESIZES_EARLY and just do it early unconditionally.
RTLD_INIT_PAGESIZES_EARLY doesn't seem to be needed as the call to init_pagesizes() is before the first call to getpagesize(), even if I use it in place of all users of pagesize[0].
Is there a reason to prefer pageisze[0] over pagesizes()? I have a version of pagesizes() with the sysctl removed as it's never needed that still works.
sysctl(3) call in the rtld_libc.c version of getpagesize() is for compat case, since in principle almost all auxv entries (except base for relocation) are optional, and allocator does need to know the page size.
Using pagesizes[0] (or better, just pagesize global) avoids function call.
Doesn't in-kernel image activator require some related fixes?
libexec/rtld-elf/map_object.c | ||
---|---|---|
136 | I must admit this changes ABI. | |
215 | This would cause similar ABI issue, since binary built for 4k page with corresponding alignment would be not runnable. |
Initially there will be no compatability for userspace and the kernel built with a different PAGE_SIZE value. I'm working towards userspace having any knowledge of it and would like the arm64 ABI in 14 to not include any hard coded knowledge of the page size. The only place that this will be difficult is jemalloc.
I don't expect a kernel built with 16k PAGE_SIZE will be able to run pre-14 binaries, however this will be a non-default option that the user will need to opt in to with knowledge on what they are doing.
What fixes would you expect?
libexec/rtld-elf/map_object.c | ||
---|---|---|
136 | That is expected. Userspace from <= 13 is not expected to run on a kernel built with 16k PAGE_SIZE. It will be a non-default option that the user has to enable with the understanding it will break the ABI. I would like to make the alignment 64k here on arm64 for 14+. It should be safe as the linker should already use 64k alignment, however I'd expect to keep 4k for older binaries. |
I prefer to not use asserts in rtld, at least not in the early parts. They are very hard to debug.
WRT imgact_elf.c of the page size use, it was a question, not the statement.
libexec/rtld-elf/rtld_malloc.c | ||
---|---|---|
123 ↗ | (On Diff #104627) | This file is also used by libthr, and I do not think that page_size is defined there. Look at libthr/thread/thr_malloc.c. |
The page size imgact_elf.c uses will be PAGE_SIZE, i.e. 4k or 16k depending on which was used when building the kernel. For AT_PAGESIZES we only initialise the pagesizes kernel array used to populate it with the values the hardware supports, i.e. L3 page size, L2 block size, and if supported the L1 block size.
libexec/rtld-elf/rtld-libc/rtld_libc.c | ||
---|---|---|
103 | I would add a note there referencing init_pagesizes(). |