libc, libthr: use AT_USRSTACK{BASE,LIM} instead of sysctl("kern.usrstack") and get_rlimit(RLIMIT_STACK)

Reviewed by:	brooks, imp (previous version)
Discussed with:	markj
Sponsored by:	The FreeBSD Foundation
MFC after:	2 weeks
Differential revision:	https://reviews.freebsd.org/D36540
This commit is contained in:
Konstantin Belousov 2022-09-12 22:45:21 +03:00
parent ebf7a01594
commit e2879ece43
3 changed files with 49 additions and 29 deletions

View File

@ -29,6 +29,7 @@
*/ */
#include <sys/param.h> #include <sys/param.h>
#include <sys/auxv.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/resource.h> #include <sys/resource.h>
#include <sys/sysctl.h> #include <sys/sysctl.h>
@ -77,19 +78,23 @@ __libc_map_stacks_exec(void)
{ {
int mib[2]; int mib[2];
struct rlimit rlim; struct rlimit rlim;
u_long usrstack; u_long usrstack, stacksz;
size_t len; size_t len;
mib[0] = CTL_KERN; if (_elf_aux_info(AT_USRSTACKBASE, &usrstack, sizeof(usrstack)) != 0) {
mib[1] = KERN_USRSTACK; mib[0] = CTL_KERN;
len = sizeof(usrstack); mib[1] = KERN_USRSTACK;
if (sysctl(mib, nitems(mib), &usrstack, &len, NULL, 0) len = sizeof(usrstack);
== -1) if (sysctl(mib, nitems(mib), &usrstack, &len, NULL, 0) == -1)
return; return;
if (getrlimit(RLIMIT_STACK, &rlim) == -1) }
return; if (_elf_aux_info(AT_USRSTACKLIM, &stacksz, sizeof(stacksz)) != 0) {
mprotect((void *)(uintptr_t)(usrstack - rlim.rlim_cur), if (getrlimit(RLIMIT_STACK, &rlim) == -1)
rlim.rlim_cur, _rtld_get_stack_prot()); return;
stacksz = rlim.rlim_cur;
}
mprotect((void *)(uintptr_t)(usrstack - stacksz), stacksz,
_rtld_get_stack_prot());
} }
#pragma weak __pthread_map_stacks_exec #pragma weak __pthread_map_stacks_exec

View File

@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$");
#include "namespace.h" #include "namespace.h"
#include <sys/param.h> #include <sys/param.h>
#include <sys/auxv.h>
#include <sys/signalvar.h> #include <sys/signalvar.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/link_elf.h> #include <sys/link_elf.h>
@ -462,18 +463,26 @@ init_private(void)
if (init_once == 0) { if (init_once == 0) {
__thr_pshared_init(); __thr_pshared_init();
__thr_malloc_init(); __thr_malloc_init();
/* Find the stack top */ /* Find the stack top */
mib[0] = CTL_KERN; if (elf_aux_info(AT_USRSTACKBASE, &_usrstack,
mib[1] = KERN_USRSTACK; sizeof(_usrstack)) != 0) {
len = sizeof (_usrstack); mib[0] = CTL_KERN;
if (sysctl(mib, nitems(mib), &_usrstack, &len, NULL, 0) == -1) mib[1] = KERN_USRSTACK;
PANIC("Cannot get kern.usrstack from sysctl"); len = sizeof (_usrstack);
if (sysctl(mib, nitems(mib), &_usrstack, &len,
NULL, 0) == -1)
PANIC("Cannot get kern.usrstack from sysctl");
}
env_bigstack = getenv("LIBPTHREAD_BIGSTACK_MAIN"); env_bigstack = getenv("LIBPTHREAD_BIGSTACK_MAIN");
env_splitstack = getenv("LIBPTHREAD_SPLITSTACK_MAIN"); env_splitstack = getenv("LIBPTHREAD_SPLITSTACK_MAIN");
if (env_bigstack != NULL || env_splitstack == NULL) { if (env_bigstack != NULL || env_splitstack == NULL) {
if (getrlimit(RLIMIT_STACK, &rlim) == -1) if (elf_aux_info(AT_USRSTACKLIM, &_thr_stack_initial,
PANIC("Cannot get stack rlimit"); sizeof(_thr_stack_initial)) != 0) {
_thr_stack_initial = rlim.rlim_cur; if (getrlimit(RLIMIT_STACK, &rlim) == -1)
PANIC("Cannot get stack rlimit");
_thr_stack_initial = rlim.rlim_cur;
}
} }
_thr_is_smp = sysconf(_SC_NPROCESSORS_CONF); _thr_is_smp = sysconf(_SC_NPROCESSORS_CONF);
if (_thr_is_smp == -1) if (_thr_is_smp == -1)

View File

@ -31,6 +31,7 @@
__FBSDID("$FreeBSD$"); __FBSDID("$FreeBSD$");
#include <sys/param.h> #include <sys/param.h>
#include <sys/auxv.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/queue.h> #include <sys/queue.h>
#include <sys/resource.h> #include <sys/resource.h>
@ -149,18 +150,23 @@ singlethread_map_stacks_exec(void)
{ {
int mib[2]; int mib[2];
struct rlimit rlim; struct rlimit rlim;
u_long usrstack; u_long usrstack, stacksz;
size_t len; size_t len;
mib[0] = CTL_KERN; if (elf_aux_info(AT_USRSTACKBASE, &usrstack, sizeof(usrstack)) != 0) {
mib[1] = KERN_USRSTACK; mib[0] = CTL_KERN;
len = sizeof(usrstack); mib[1] = KERN_USRSTACK;
if (sysctl(mib, nitems(mib), &usrstack, &len, NULL, 0) == -1) len = sizeof(usrstack);
return; if (sysctl(mib, nitems(mib), &usrstack, &len, NULL, 0) == -1)
if (getrlimit(RLIMIT_STACK, &rlim) == -1) return;
return; }
mprotect((void *)(uintptr_t)(usrstack - rlim.rlim_cur), if (elf_aux_info(AT_USRSTACKLIM, &stacksz, sizeof(stacksz)) != 0) {
rlim.rlim_cur, _rtld_get_stack_prot()); if (getrlimit(RLIMIT_STACK, &rlim) == -1)
return;
stacksz = rlim.rlim_cur;
}
mprotect((void *)(uintptr_t)(usrstack - stacksz), stacksz,
_rtld_get_stack_prot());
} }
void void