summary refs log tree commit diff
path: root/pkgs/os-specific
diff options
context:
space:
mode:
authorWill Dietz <w@wdtz.org>2018-09-24 23:40:08 -0500
committerWill Dietz <w@wdtz.org>2018-09-24 23:59:02 -0500
commitf38218a7568296eb19eed65b745d310a33f43297 (patch)
tree1120b2d9c3a89cc5bace0ea939682af3a7aea08f /pkgs/os-specific
parentdcd5e4558fb38c202c69f588e3a5fa99c73ea09b (diff)
downloadnixpkgs-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.nix5
-rw-r--r--pkgs/os-specific/linux/musl/stacksize-0001.patch56
-rw-r--r--pkgs/os-specific/linux/musl/stacksize-0002.patch86
-rw-r--r--pkgs/os-specific/linux/musl/stacksize-0003.patch36
-rw-r--r--pkgs/os-specific/linux/musl/stacksize-0004.patch81
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
+