diff options
| author | Enji Cooper <ngie@FreeBSD.org> | 2017-11-04 07:05:21 +0000 |
|---|---|---|
| committer | Enji Cooper <ngie@FreeBSD.org> | 2017-11-04 07:05:21 +0000 |
| commit | f6e116eea97e79450fb8dcf81193f35dfc30fae1 (patch) | |
| tree | 4e01e8f42099bf865bf9819f69a967010ab4fbfe /lib | |
| parent | b9a2bf88a3354237f1b0ed4f15c8849191f6ec88 (diff) | |
| parent | ea10ca8944535335ba4f61577f1b6ad7720d95e0 (diff) | |
Notes
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/libc/gen/tls.c | 98 | ||||
| -rw-r--r-- | lib/libc/stdio/gets.c | 4 | ||||
| -rw-r--r-- | lib/libcxxrt/Version.map | 8 | ||||
| -rw-r--r-- | lib/libmt/mtlib.c | 1 | ||||
| -rw-r--r-- | lib/libpathconv/Makefile | 2 |
5 files changed, 86 insertions, 27 deletions
diff --git a/lib/libc/gen/tls.c b/lib/libc/gen/tls.c index 265e7de2d097..c2d608a43cf9 100644 --- a/lib/libc/gen/tls.c +++ b/lib/libc/gen/tls.c @@ -37,9 +37,15 @@ #include <stdlib.h> #include <string.h> #include <elf.h> +#include <unistd.h> #include "libc_private.h" +#define tls_assert(cond) ((cond) ? (void) 0 : \ + (tls_msg(#cond ": assert failed: " __FILE__ ":" \ + __XSTRING(__LINE__) "\n"), abort())) +#define tls_msg(s) write(STDOUT_FILENO, s, strlen(s)) + /* Provided by jemalloc to avoid bootstrapping issues. */ void *__je_bootstrap_malloc(size_t size); void *__je_bootstrap_calloc(size_t num, size_t size); @@ -85,6 +91,7 @@ void __libc_free_tls(void *tls, size_t tcbsize, size_t tcbalign); static size_t tls_static_space; static size_t tls_init_size; +static size_t tls_init_align; static void *tls_init; #endif @@ -109,6 +116,35 @@ __libc_tls_get_addr(void *ti __unused) #ifndef PIC +static void * +malloc_aligned(size_t size, size_t align) +{ + void *mem, *res; + + if (align < sizeof(void *)) + align = sizeof(void *); + + mem = __je_bootstrap_malloc(size + sizeof(void *) + align - 1); + res = (void *)roundup2((uintptr_t)mem + sizeof(void *), align); + *(void **)((uintptr_t)res - sizeof(void *)) = mem; + return (res); +} + +static void +free_aligned(void *ptr) +{ + void *mem; + uintptr_t x; + + if (ptr == NULL) + return; + + x = (uintptr_t)ptr; + x -= sizeof(void *); + mem = *(void **)x; + __je_bootstrap_free(mem); +} + #ifdef TLS_VARIANT_I #define TLS_TCB_SIZE (2 * sizeof(void *)) @@ -117,52 +153,63 @@ __libc_tls_get_addr(void *ti __unused) * Free Static TLS using the Variant I method. */ void -__libc_free_tls(void *tcb, size_t tcbsize, size_t tcbalign __unused) +__libc_free_tls(void *tcb, size_t tcbsize __unused, size_t tcbalign __unused) { Elf_Addr *dtv; Elf_Addr **tls; - tls = (Elf_Addr **)((Elf_Addr)tcb + tcbsize - TLS_TCB_SIZE); + tls = (Elf_Addr **)tcb; dtv = tls[0]; __je_bootstrap_free(dtv); - __je_bootstrap_free(tcb); + free_aligned(tls); } /* * Allocate Static TLS using the Variant I method. */ void * -__libc_allocate_tls(void *oldtcb, size_t tcbsize, size_t tcbalign __unused) +__libc_allocate_tls(void *oldtcb, size_t tcbsize, size_t tcbalign) { Elf_Addr *dtv; Elf_Addr **tls; - char *tcb; if (oldtcb != NULL && tcbsize == TLS_TCB_SIZE) return (oldtcb); - tcb = __je_bootstrap_calloc(1, tls_static_space + tcbsize - TLS_TCB_SIZE); - tls = (Elf_Addr **)(tcb + tcbsize - TLS_TCB_SIZE); + tls_assert(tcbalign >= TLS_TCB_ALIGN); + tls_assert(tcbsize == TLS_TCB_SIZE); + + tcbsize = roundup2(tcbsize, tcbalign); + tls = malloc_aligned(tcbsize + tls_static_space, tcbalign); + if (tls == NULL) { + tls_msg("__libc_allocate_tls: Out of memory.\n"); + abort(); + } + memset(tls, 0, tcbsize + tls_static_space); if (oldtcb != NULL) { - memcpy(tls, oldtcb, tls_static_space); + memcpy(tls, oldtcb, tcbsize + tls_static_space); __je_bootstrap_free(oldtcb); /* Adjust the DTV. */ dtv = tls[0]; - dtv[2] = (Elf_Addr)tls + TLS_TCB_SIZE; + dtv[2] = (Elf_Addr)tls + tcbsize; } else { dtv = __je_bootstrap_malloc(3 * sizeof(Elf_Addr)); + if (dtv == NULL) { + tls_msg("__libc_allocate_tls: Out of memory.\n"); + abort(); + } tls[0] = dtv; - dtv[0] = 1; - dtv[1] = 1; - dtv[2] = (Elf_Addr)tls + TLS_TCB_SIZE; + dtv[0] = 1; /* Generation. */ + dtv[1] = 1; /* Segments count. */ + dtv[2] = (Elf_Addr)tls + tcbsize; if (tls_init_size > 0) memcpy((void*)dtv[2], tls_init, tls_init_size); } - return(tcb); + return (tls); } #endif @@ -190,7 +237,7 @@ __libc_free_tls(void *tcb, size_t tcbsize __unused, size_t tcbalign) dtv = ((Elf_Addr**)tcb)[1]; tlsend = (Elf_Addr) tcb; tlsstart = tlsend - size; - __je_bootstrap_free((void*) tlsstart); + free_aligned((void*)tlsstart); __je_bootstrap_free(dtv); } @@ -209,8 +256,17 @@ __libc_allocate_tls(void *oldtls, size_t tcbsize, size_t tcbalign) if (tcbsize < 2 * sizeof(Elf_Addr)) tcbsize = 2 * sizeof(Elf_Addr); - tls = __je_bootstrap_calloc(1, size + tcbsize); + tls = malloc_aligned(size + tcbsize, tcbalign); + if (tls == NULL) { + tls_msg("__libc_allocate_tls: Out of memory.\n"); + abort(); + } + memset(tls, 0, size + tcbsize); dtv = __je_bootstrap_malloc(3 * sizeof(Elf_Addr)); + if (dtv == NULL) { + tls_msg("__libc_allocate_tls: Out of memory.\n"); + abort(); + } segbase = (Elf_Addr)(tls + size); ((Elf_Addr*)segbase)[0] = segbase; @@ -305,18 +361,14 @@ _init_tls(void) tls_static_space = roundup2(phdr[i].p_memsz, phdr[i].p_align); tls_init_size = phdr[i].p_filesz; + tls_init_align = phdr[i].p_align; tls_init = (void*) phdr[i].p_vaddr; + break; } } -#ifdef TLS_VARIANT_I - /* - * tls_static_space should include space for TLS structure - */ - tls_static_space += TLS_TCB_SIZE; -#endif - - tls = _rtld_allocate_tls(NULL, TLS_TCB_SIZE, TLS_TCB_ALIGN); + tls = _rtld_allocate_tls(NULL, TLS_TCB_SIZE, + MAX(TLS_TCB_ALIGN, tls_init_align)); _set_tp(tls); #endif diff --git a/lib/libc/stdio/gets.c b/lib/libc/stdio/gets.c index c75dcc202cc9..06e56f7f0c3b 100644 --- a/lib/libc/stdio/gets.c +++ b/lib/libc/stdio/gets.c @@ -61,13 +61,13 @@ gets(char *buf) warned = 1; } for (s = buf; (c = __sgetc(stdin)) != '\n'; ) { - if (c == EOF) + if (c == EOF) { if (s == buf) { ret = NULL; goto end; } else break; - else + } else *s++ = c; } *s = 0; diff --git a/lib/libcxxrt/Version.map b/lib/libcxxrt/Version.map index 39f98e371146..cef47b9dc6a3 100644 --- a/lib/libcxxrt/Version.map +++ b/lib/libcxxrt/Version.map @@ -377,9 +377,15 @@ GLIBCXX_3.4.9 { }; } GLIBCXX_3.4; +GLIBCXX_3.4.20 { + extern "C++" { + "std::get_new_handler()"; + }; +} GLIBCXX_3.4.9; + GLIBCXX_3.4.22 { extern "C++" { "std::uncaught_exceptions()"; }; -} GLIBCXX_3.4.9; +} GLIBCXX_3.4.20; diff --git a/lib/libmt/mtlib.c b/lib/libmt/mtlib.c index 08dce9d4a6b0..0ada983823a1 100644 --- a/lib/libmt/mtlib.c +++ b/lib/libmt/mtlib.c @@ -645,6 +645,7 @@ static struct densities { { 0x58, 15142, 384607, "LTO-5" }, { 0x5A, 15142, 384607, "LTO-6" }, { 0x5C, 19107, 485318, "LTO-7" }, + { 0x5D, 19107, 485318, "LTO-M8" }, { 0x5E, 20669, 524993, "LTO-8" }, { 0x71, 11800, 299720, "3592A1 (encrypted)" }, { 0x72, 11800, 299720, "3592A2 (encrypted)" }, diff --git a/lib/libpathconv/Makefile b/lib/libpathconv/Makefile index fd9924e686e3..5aeae6ebd988 100644 --- a/lib/libpathconv/Makefile +++ b/lib/libpathconv/Makefile @@ -14,6 +14,6 @@ SRCS= abs2rel.c rel2abs.c #SYMBOL_MAPS= ${.CURDIR}/Symbol.map HAS_TESTS= -SUBDIR.${MK_TESTS}+= tests +#SUBDIR.${MK_TESTS}+= tests .include <bsd.lib.mk> |
