diff options
author | Will Dietz <w@wdtz.org> | 2018-09-24 23:40:08 -0500 |
---|---|---|
committer | Will Dietz <w@wdtz.org> | 2018-09-24 23:59:02 -0500 |
commit | f38218a7568296eb19eed65b745d310a33f43297 (patch) | |
tree | 1120b2d9c3a89cc5bace0ea939682af3a7aea08f /pkgs/os-specific | |
parent | dcd5e4558fb38c202c69f588e3a5fa99c73ea09b (diff) | |
download | nixpkgs-f38218a7568296eb19eed65b745d310a33f43297.tar nixpkgs-f38218a7568296eb19eed65b745d310a33f43297.tar.gz nixpkgs-f38218a7568296eb19eed65b745d310a33f43297.tar.bz2 nixpkgs-f38218a7568296eb19eed65b745d310a33f43297.tar.lz nixpkgs-f38218a7568296eb19eed65b745d310a33f43297.tar.xz nixpkgs-f38218a7568296eb19eed65b745d310a33f43297.tar.zst nixpkgs-f38218a7568296eb19eed65b745d310a33f43297.zip |
musl: pick stacksize-related improvements, increase default size
Also supports setting default thread stack size via linker, making it possible to fix programs without modifying source.
Diffstat (limited to 'pkgs/os-specific')
-rw-r--r-- | pkgs/os-specific/linux/musl/default.nix | 5 | ||||
-rw-r--r-- | pkgs/os-specific/linux/musl/stacksize-0001.patch | 56 | ||||
-rw-r--r-- | pkgs/os-specific/linux/musl/stacksize-0002.patch | 86 | ||||
-rw-r--r-- | pkgs/os-specific/linux/musl/stacksize-0003.patch | 36 | ||||
-rw-r--r-- | pkgs/os-specific/linux/musl/stacksize-0004.patch | 81 |
5 files changed, 264 insertions, 0 deletions
diff --git a/pkgs/os-specific/linux/musl/default.nix b/pkgs/os-specific/linux/musl/default.nix index e28b6316486..ba634c5d161 100644 --- a/pkgs/os-specific/linux/musl/default.nix +++ b/pkgs/os-specific/linux/musl/default.nix @@ -72,6 +72,11 @@ stdenv.mkDerivation rec { # name_to_handle_at ./name-to-handle-at.patch ./max-handle-sz-for-name-to-handle-at.patch + # Upstream improvements regarding stack size, incl size increase + ./stacksize-0001.patch + ./stacksize-0002.patch + ./stacksize-0003.patch + ./stacksize-0004.patch ]; preConfigure = '' configureFlagsArray+=("--syslibdir=$out/lib") diff --git a/pkgs/os-specific/linux/musl/stacksize-0001.patch b/pkgs/os-specific/linux/musl/stacksize-0001.patch new file mode 100644 index 00000000000..5c4a6b3e9bd --- /dev/null +++ b/pkgs/os-specific/linux/musl/stacksize-0001.patch @@ -0,0 +1,56 @@ +From c7ed3e909a69d34a7821f7db644c2fa590a1a690 Mon Sep 17 00:00:00 2001 +From: Rich Felker <dalias@aerifal.cx> +Date: Tue, 18 Sep 2018 19:43:52 -0400 +Subject: [PATCH 1/4] remove redundant declarations of __default_stacksize, + __default_guardsize + +these are now declared in pthread_impl.h. +--- + src/thread/pthread_attr_init.c | 3 --- + src/thread/pthread_create.c | 2 -- + src/thread/pthread_setattr_default_np.c | 3 --- + 3 files changed, 8 deletions(-) + +diff --git a/src/thread/pthread_attr_init.c b/src/thread/pthread_attr_init.c +index 398990d1..463a8d20 100644 +--- a/src/thread/pthread_attr_init.c ++++ b/src/thread/pthread_attr_init.c +@@ -1,8 +1,5 @@ + #include "pthread_impl.h" + +-extern size_t __default_stacksize; +-extern size_t __default_guardsize; +- + int pthread_attr_init(pthread_attr_t *a) + { + *a = (pthread_attr_t){0}; +diff --git a/src/thread/pthread_create.c b/src/thread/pthread_create.c +index 3293dcd5..3da7db14 100644 +--- a/src/thread/pthread_create.c ++++ b/src/thread/pthread_create.c +@@ -162,8 +162,6 @@ static void *dummy_tsd[1] = { 0 }; + weak_alias(dummy_tsd, __pthread_tsd_main); + + volatile int __block_new_threads = 0; +-extern size_t __default_stacksize; +-extern size_t __default_guardsize; + + static FILE *volatile dummy_file = 0; + weak_alias(dummy_file, __stdin_used); +diff --git a/src/thread/pthread_setattr_default_np.c b/src/thread/pthread_setattr_default_np.c +index 88503e34..256f0685 100644 +--- a/src/thread/pthread_setattr_default_np.c ++++ b/src/thread/pthread_setattr_default_np.c +@@ -2,9 +2,6 @@ + #include "pthread_impl.h" + #include <string.h> + +-extern size_t __default_stacksize; +-extern size_t __default_guardsize; +- + int pthread_setattr_default_np(const pthread_attr_t *attrp) + { + /* Reject anything in the attr object other than stack/guard size. */ +-- +2.19.0 + diff --git a/pkgs/os-specific/linux/musl/stacksize-0002.patch b/pkgs/os-specific/linux/musl/stacksize-0002.patch new file mode 100644 index 00000000000..1191452d669 --- /dev/null +++ b/pkgs/os-specific/linux/musl/stacksize-0002.patch @@ -0,0 +1,86 @@ +From 792f32772e64a32527cd455ebfa087ef434a6f4f Mon Sep 17 00:00:00 2001 +From: Rich Felker <dalias@aerifal.cx> +Date: Tue, 18 Sep 2018 23:06:50 -0400 +Subject: [PATCH 2/4] limit the configurable default stack/guard size for + threads + +limit to 8MB/1MB, repectively. since the defaults cannot be reduced +once increased, excessively large settings would lead to an +unrecoverably broken state. this change is in preparation to allow +defaults to be increased via program headers at the linker level. + +creation of threads that really need larger sizes needs to be done +with an explicit attribute. +--- + src/internal/pthread_impl.h | 7 +++++-- + src/thread/default_attr.c | 4 ++-- + src/thread/pthread_setattr_default_np.c | 12 ++++++++---- + 3 files changed, 15 insertions(+), 8 deletions(-) + +diff --git a/src/internal/pthread_impl.h b/src/internal/pthread_impl.h +index 26e6e1df..e73a251f 100644 +--- a/src/internal/pthread_impl.h ++++ b/src/internal/pthread_impl.h +@@ -182,12 +182,15 @@ hidden void __acquire_ptc(void); + hidden void __release_ptc(void); + hidden void __inhibit_ptc(void); + +-extern hidden size_t __default_stacksize; +-extern hidden size_t __default_guardsize; ++extern hidden unsigned __default_stacksize; ++extern hidden unsigned __default_guardsize; + + #define DEFAULT_STACK_SIZE 81920 + #define DEFAULT_GUARD_SIZE 4096 + ++#define DEFAULT_STACK_MAX (8<<20) ++#define DEFAULT_GUARD_MAX (1<<20) ++ + #define __ATTRP_C11_THREAD ((void*)(uintptr_t)-1) + + #endif +diff --git a/src/thread/default_attr.c b/src/thread/default_attr.c +index 46fe98ee..dce96409 100644 +--- a/src/thread/default_attr.c ++++ b/src/thread/default_attr.c +@@ -1,4 +1,4 @@ + #include "pthread_impl.h" + +-size_t __default_stacksize = DEFAULT_STACK_SIZE; +-size_t __default_guardsize = DEFAULT_GUARD_SIZE; ++unsigned __default_stacksize = DEFAULT_STACK_SIZE; ++unsigned __default_guardsize = DEFAULT_GUARD_SIZE; +diff --git a/src/thread/pthread_setattr_default_np.c b/src/thread/pthread_setattr_default_np.c +index 256f0685..58486220 100644 +--- a/src/thread/pthread_setattr_default_np.c ++++ b/src/thread/pthread_setattr_default_np.c +@@ -2,6 +2,9 @@ + #include "pthread_impl.h" + #include <string.h> + ++#define MIN(a,b) ((a)<(b) ? (a) : (b)) ++#define MAX(a,b) ((a)>(b) ? (a) : (b)) ++ + int pthread_setattr_default_np(const pthread_attr_t *attrp) + { + /* Reject anything in the attr object other than stack/guard size. */ +@@ -11,11 +14,12 @@ int pthread_setattr_default_np(const pthread_attr_t *attrp) + if (memcmp(&tmp, &zero, sizeof tmp)) + return EINVAL; + ++ unsigned stack = MIN(attrp->_a_stacksize, DEFAULT_STACK_MAX); ++ unsigned guard = MIN(attrp->_a_guardsize, DEFAULT_GUARD_MAX); ++ + __inhibit_ptc(); +- if (attrp->_a_stacksize >= __default_stacksize) +- __default_stacksize = attrp->_a_stacksize; +- if (attrp->_a_guardsize >= __default_guardsize) +- __default_guardsize = attrp->_a_guardsize; ++ __default_stacksize = MAX(__default_stacksize, stack); ++ __default_guardsize = MAX(__default_guardsize, guard); + __release_ptc(); + + return 0; +-- +2.19.0 + diff --git a/pkgs/os-specific/linux/musl/stacksize-0003.patch b/pkgs/os-specific/linux/musl/stacksize-0003.patch new file mode 100644 index 00000000000..fb5373005cb --- /dev/null +++ b/pkgs/os-specific/linux/musl/stacksize-0003.patch @@ -0,0 +1,36 @@ +From c0058ab465e950c2c3302d2b62e21cc0b494224b Mon Sep 17 00:00:00 2001 +From: Rich Felker <dalias@aerifal.cx> +Date: Tue, 18 Sep 2018 23:11:49 -0400 +Subject: [PATCH 3/4] increase default thread stack/guard size + +stack size default is increased from 80k to 128k. this coincides with +Linux's hard-coded default stack for the main thread (128k is +initially committed; growth beyond that up to ulimit is contingent on +additional allocation succeeding) and GNU ld's default PT_GNU_STACK +size for FDPIC, at least on sh. + +guard size default is increased from 4k to 8k to reduce the risk of +guard page jumping on overflow, since use of just over 4k of stack is +common (PATH_MAX buffers, etc.). +--- + src/internal/pthread_impl.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/internal/pthread_impl.h b/src/internal/pthread_impl.h +index e73a251f..d491f975 100644 +--- a/src/internal/pthread_impl.h ++++ b/src/internal/pthread_impl.h +@@ -185,8 +185,8 @@ hidden void __inhibit_ptc(void); + extern hidden unsigned __default_stacksize; + extern hidden unsigned __default_guardsize; + +-#define DEFAULT_STACK_SIZE 81920 +-#define DEFAULT_GUARD_SIZE 4096 ++#define DEFAULT_STACK_SIZE 131072 ++#define DEFAULT_GUARD_SIZE 8192 + + #define DEFAULT_STACK_MAX (8<<20) + #define DEFAULT_GUARD_MAX (1<<20) +-- +2.19.0 + diff --git a/pkgs/os-specific/linux/musl/stacksize-0004.patch b/pkgs/os-specific/linux/musl/stacksize-0004.patch new file mode 100644 index 00000000000..7a6f9792de5 --- /dev/null +++ b/pkgs/os-specific/linux/musl/stacksize-0004.patch @@ -0,0 +1,81 @@ +From 7b3348a98c139b4b4238384e52d4b0eb237e4833 Mon Sep 17 00:00:00 2001 +From: Rich Felker <dalias@aerifal.cx> +Date: Tue, 18 Sep 2018 23:54:18 -0400 +Subject: [PATCH 4/4] support setting of default thread stack size via + PT_GNU_STACK header + +this facilitates building software that assumes a large default stack +size without any patching to call pthread_setattr_default_np or +pthread_attr_setstacksize at each thread creation site, using just +LDFLAGS. + +normally the PT_GNU_STACK header is used only to reflect whether +executable stack is desired, but with GNU ld at least, passing +-Wl,-z,stack-size=N will set a size on the program header. with this +patch, that size will be incorporated into the default stack size +(subject to increase-only rule and DEFAULT_STACK_MAX limit). + +both static and dynamic linking honor the program header. for dynamic +linking, all libraries loaded at program start, including preloaded +ones, are considered. dlopened libraries are not considered, for +several reasons. extra logic would be needed to defer processing until +the load of the new library is commited, synchronization woud be +needed since other threads may be running concurrently, and the +effectiveness woud be limited since the larger size would not apply to +threads that already existed at the time of dlopen. programs that will +dlopen code expecting a large stack need to declare the requirement +themselves, or pthread_setattr_default_np can be used. +--- + ldso/dynlink.c | 12 ++++++++++++ + src/env/__init_tls.c | 5 +++++ + 2 files changed, 17 insertions(+) + +diff --git a/ldso/dynlink.c b/ldso/dynlink.c +index e4829c3a..3ecbddfa 100644 +--- a/ldso/dynlink.c ++++ b/ldso/dynlink.c +@@ -609,6 +609,12 @@ static void *map_library(int fd, struct dso *dso) + } else if (ph->p_type == PT_GNU_RELRO) { + dso->relro_start = ph->p_vaddr & -PAGE_SIZE; + dso->relro_end = (ph->p_vaddr + ph->p_memsz) & -PAGE_SIZE; ++ } else if (ph->p_type == PT_GNU_STACK) { ++ if (!runtime && ph->p_memsz > __default_stacksize) { ++ __default_stacksize = ++ ph->p_memsz < DEFAULT_STACK_MAX ? ++ ph->p_memsz : DEFAULT_STACK_MAX; ++ } + } + if (ph->p_type != PT_LOAD) continue; + nsegs++; +@@ -1238,6 +1244,12 @@ static void kernel_mapped_dso(struct dso *p) + } else if (ph->p_type == PT_GNU_RELRO) { + p->relro_start = ph->p_vaddr & -PAGE_SIZE; + p->relro_end = (ph->p_vaddr + ph->p_memsz) & -PAGE_SIZE; ++ } else if (ph->p_type == PT_GNU_STACK) { ++ if (!runtime && ph->p_memsz > __default_stacksize) { ++ __default_stacksize = ++ ph->p_memsz < DEFAULT_STACK_MAX ? ++ ph->p_memsz : DEFAULT_STACK_MAX; ++ } + } + if (ph->p_type != PT_LOAD) continue; + if (ph->p_vaddr < min_addr) +diff --git a/src/env/__init_tls.c b/src/env/__init_tls.c +index e0224243..96d0e284 100644 +--- a/src/env/__init_tls.c ++++ b/src/env/__init_tls.c +@@ -90,6 +90,11 @@ static void static_init_tls(size_t *aux) + base = (size_t)_DYNAMIC - phdr->p_vaddr; + if (phdr->p_type == PT_TLS) + tls_phdr = phdr; ++ if (phdr->p_type == PT_GNU_STACK && ++ phdr->p_memsz > __default_stacksize) ++ __default_stacksize = ++ phdr->p_memsz < DEFAULT_STACK_MAX ? ++ phdr->p_memsz : DEFAULT_STACK_MAX; + } + + if (tls_phdr) { +-- +2.19.0 + |