X-Git-Url: https://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Faltstack%2Faltstack.c;h=67f457bce3b90dd6cdf406b33e0ec4ffd8de0834;hp=6faf38f5d31d8870e82db4d96ea2e657944f59bd;hb=141e582ead507103a5f8860a3ec8c0f237d2690a;hpb=9a8344b2cd849a5506ca5e93bfc30665fb35acab;ds=sidebyside diff --git a/ccan/altstack/altstack.c b/ccan/altstack/altstack.c index 6faf38f5..67f457bc 100644 --- a/ccan/altstack/altstack.c +++ b/ccan/altstack/altstack.c @@ -8,6 +8,7 @@ #include #include #include +#include #include static __thread char ebuf[ALTSTACK_ERR_MAXLEN]; @@ -37,6 +38,11 @@ static void segvjmp(int signum) } static __thread void *rsp_save_[2]; +static __thread rlim_t max_; + +rlim_t altstack_max(void) { + return max_; +} static ptrdiff_t rsp_save(unsigned i) { assert(i < 2); @@ -57,6 +63,7 @@ static __thread void *arg_, *out_; int altstack(rlim_t max, void *(*fn)(void *), void *arg, void **out) { + long pgsz = sysconf(_SC_PAGESIZE); int ret = -1, undo = 0; char *m; struct rlimit rl_save; @@ -69,11 +76,16 @@ int altstack(rlim_t max, void *(*fn)(void *), void *arg, void **out) fn_ = fn; arg_ = arg; out_ = 0; + max_ = max; ebuf[elen = 0] = '\0'; if (out) *out = 0; + // if the first page below the mapping is in use, we get max-pgsz usable bytes + // add pgsz to max to guarantee at least max usable bytes + max += pgsz; + ok(getrlimit(RLIMIT_STACK, &rl_save), 1); - ok(setrlimit(RLIMIT_STACK, &(struct rlimit) { max, rl_save.rlim_max }), 1); + ok(setrlimit(RLIMIT_STACK, &(struct rlimit) { max_, rl_save.rlim_max }), 1); undo++; ok(m = mmap(0, max, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_GROWSDOWN|MAP_NORESERVE, -1, 0), 1); @@ -91,8 +103,12 @@ int altstack(rlim_t max, void *(*fn)(void *), void *arg, void **out) ok(sigaction(SIGSEGV, &sa, &sa_save), 1); undo++; - asm volatile ("movq %%rsp, %%r10\nmov %0, %%rsp\npush %%r10" : : "g" (m + max) : "r10"); - rsp_save(0); + asm volatile ( + "mov %%rsp, %%r10\n\t" + "mov %1, %%rsp\n\t" + "sub $8, %%rsp\n\t" + "push %%r10" + : "=r" (rsp_save_[0]) : "0" (m + max) : "r10"); out_ = fn_(arg_); asm volatile ("pop %rsp"); ret = 0;