Browse Source

nptl: Replace sbrk with mmap

Replace sbrk with mmap since this commit disables sbrk area
for FDPIC MMU-less platform:
fs/binfmt_elf_fdpic.c: fix brk area overlap with stack on NOMMU
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/fs/binfmt_elf_fdpic.c?id=4ac313111018cb44ecc250445de5ccb93026a980

	* libpthread/nptl/sysdeps/generic/libc-tls.c (__libc_setup_tls):
	Handle __FDPIC__.

Signed-off-by: Mickaël Guêné <mickael.guene@st.com>
Signed-off-by: Christophe Lyon <christophe.lyon@st.com>
Christophe Lyon 5 years ago
parent
commit
0f4ddec32e
1 changed files with 16 additions and 1 deletions
  1. 16 1
      libpthread/nptl/sysdeps/generic/libc-tls.c

+ 16 - 1
libpthread/nptl/sysdeps/generic/libc-tls.c

@@ -26,7 +26,7 @@
 #include <link.h>
 #include <string.h>
 #include <stdlib.h>
-
+#include <sys/mman.h>
 
 #ifdef SHARED
  #error makefile bug, this file is for static only
@@ -155,13 +155,28 @@ __libc_setup_tls (size_t tcbsize, size_t tcbalign)
      The initialized value of _dl_tls_static_size is provided by dl-open.c
      to request some surplus that permits dynamic loading of modules with
      IE-model TLS.  */
+  /* Use mmap instead of sbrk since this commit disables sbrk area
+     for FDPIC MMU-less platforms:
+     fs/binfmt_elf_fdpic.c: fix brk area overlap with stack on NOMMU
+     https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/fs/binfmt_elf_fdpic.c?id=4ac313111018cb44ecc250445de5ccb93026a980
+   */
 # if defined(TLS_TCB_AT_TP)
   tcb_offset = roundup (memsz + GL(dl_tls_static_size), tcbalign);
+#  if defined(__FDPIC__)
+  tlsblock = mmap (NULL, tcb_offset + tcbsize + max_align,
+                   PROT_READ|PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+#  else
   tlsblock = sbrk (tcb_offset + tcbsize + max_align);
+#  endif
 # elif defined(TLS_DTV_AT_TP)
   tcb_offset = roundup (tcbsize, align ?: 1);
+#  if defined(__FDPIC__)
+  tlsblock = mmap (NULL, tcb_offset + memsz + max_align + TLS_PRE_TCB_SIZE + GL(dl_tls_static_size),
+                   PROT_READ|PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+#  else
   tlsblock = sbrk (tcb_offset + memsz + max_align
 		     + TLS_PRE_TCB_SIZE + GL(dl_tls_static_size));
+#  endif
   memset(tlsblock, '\0', tcb_offset + memsz + max_align + TLS_PRE_TCB_SIZE + GL(dl_tls_static_size));
   tlsblock += TLS_PRE_TCB_SIZE;
 # else