rtld - Use kern.tls_extra * Use kern.tls_extra, if available, to calculate the extra tls space to allocate for late library loads. * If not available, default to 6144 bytes instead of 1280 bytes to support greater use of static tls sections in late-loaded libraries (read: mesa 19.3). Reported-by: ftigeot
libc - Implement sigblockall() and sigunblockall() * Signal safety is becoming a defacto requirement for most of libc and pthreads. In particular, the memory allocator. Given the chances of teaching tens of thousands of programmers about signal safety, and just making it work in libc and pthreads, only one of these two possibilities is actually realizable. In particular, high-level languages have become so complex, and some applications (chrome, firefox, etc) have become so complex, that the code is regularly tripping over signal safety issues. However, implementing signal safety with current mechanisms is extremely expensive due to the need for multiple system calls. To whit, DragonFlyBSD now has a mechanism that does not require system calls in the critical path. * Implement sigblockall() and sigunblockall(). These functions leverage the new /dev/lpmap per-thread shared page mechanism to provide a way to temporary block the dispatch of all maskable signals without having to make any system calls. These are extremely fast routines. - Reentrant / Recursable - Temporarily blocks any dispatch of a maskable asynchronous signal to the calling thread. Other threads are not affected... this is a per-thread mechanism. - The last sigunblockall() will immediately dispatch any blocked signals. - The normal signal mask is not affected by these routines. - Does not block signals caused by synchronous traps. - The current recursion count is retained on [v]fork() to ease coding and to also allow signals to be temporarily blocked across a fork until the child process is ready to deal with them, if desired. * Implement signal safety for most of pthreads. All temporary internal mutexes are now wrapped with sigblockall() and sigunblockall(). * Implement signal safety for the malloc subsystem. All functions are wrawpped with sigblockall() and sigunblockall(). These implementations make lang/mono and lang/rust far more reliable than they were before. Where 9 out of 10 builds used to fail, now they succeed.
rtld - Support static TLS bindings for late-loaded shared libraries * Allow late (manual) dlopen()s to load shared libraries which use static TLS variables, as long as there is space. Do proper late-binding and initialize the area for all threads. * rtld will cache a symbol lookup on first-need for: "_pthread_distribute_static_tls" and then call it as needed to initialize late-bound static TLS space. This symbol is weakly bounded to __libc_distribute_static_tls in libc, and strongly overridden by _libthread_distribute_static_tls in libthread_xu. * Fixes mesa glx-tls and others. * Test code from FreeBSD. Also tested with other combinations including a pthread_create() and -static compilation. https://github.com/dumbbell/test-tls-initial-exec
rtld-elf - Notify thread state to optimize relocations * Add shims to allow libthread_xu to notify rtld when threading is being used. * Requires weak symbols in libc which are overriden by rtld-elf. * Implement the feature in rtld-elf and use it to avoid making calls to lwp_gettid(). When threaded, use tls_get_tcb() (which does not require a system call) instead of lwp_gettid(). When not threaded, just use a constant. NOTE: We cannot use tls_get_tcb() unconditionally because the tcb is not setup during early relocations. So do this whack-a-mole to make it work. * This leaves just the sigprocmask wrappers around rtld-elf (which are needed to prevent stacked relocations from signal handlers). Poked-by: mjg
rtld-elf - Allow dynamic (late) relocations to relro section * Normally the relro section is mprotect()ed to read-only after normal load relocations. * It appears that some programs can issue dynamic relocations at run-time to such sections. * If the relro mprotect has been done on an object, temporarily mprotect the object back to RW to execute the relocation, then mprotect it back to RO. Reported-by: marino
rtld - Fix ifunc relocations * ifunc relocations had a bug that caused an immediate seg-fault. Apparently this type of relocation is not used very much, we've never encountered it before. But the qemu port uses it. * Fix the bug. Basically missing lockstate and the top level in rtld was expected to hold the bind lock.
rtld: Add a postinit debugger hook FreeBSD's dtrace(1) uses this hook to halt the "victim" process before its entry point is called, at which point probes and DOF data are registered with the kernel. The r_debg_state hook cannot be used for this purpose, as it is called before the program's init routines are invoked and in particular before ODF is registered. It may or may not be useful for DragonFly by itself, but if dtrace every comes in, rtld will be ready. Taken from: FreeBSD svn 265456 (6 May 2014) FreeBSD svn 265578 (7 May 2014)
rtld: Handle IFUNC symbols at non-PLT relocations An example of this is initializing a global variable with a pointer to ifunc. This adds a symble type check and call resolver for STT_GNU_IFNC symbol types whien processing non-PLT relocations, but only after non-IFUNC relocations are done. The two-phase processing is required since resolvers may reference other symbols which most be ready to use when resolver calls are done. This restructures reloc_non_plt() to call find_symdef() and handle IFUNC in a single place. Taken from: FreeBSD svn 270798 (29 Aug 2014) FreeBSD svn 270802 (29 Aug 2014)
rtld: Add support for LD_LIBRARY_PATH_FDS env variable This variable allows loading of shared libraries via directory descriptors rather than via library paths. if LD_LIBRARY_PATH_FDS=3:4:12, the directories represented by file descriptors 3, 4, and 12 will be searched for shared libraries before the normal path-based mechanisms are used. This allows the execution of unpriviledge binaries from within a Capsicum sandbox even if they require shared libraries. Note that Capsicum is not available on DragonFly yet. While here, adjust whitespace and rearrange a bit to minimize differences with FreeBSD rtld. Taken from: FreeBSD svn 267678 (20 June 2014)
rtld: Allows return pathname in dl_iterate_phdr dlpi_name This is the behavior of Linux and also of FreeBSD since October 2014. Until this point, dlpi_name returned the short name of the object unless it wasn't defined, so the fallback was to return the pathname. Returning the pathname in all cases is considered more useful and matches the definition of Linux. Taken from: FreeBSD svn 272842 (9 Oct 2014)