diff options
Diffstat (limited to 'main/musl/0001-v1.0.0-to-2b74315d.patch')
-rw-r--r-- | main/musl/0001-v1.0.0-to-2b74315d.patch | 810 |
1 files changed, 0 insertions, 810 deletions
diff --git a/main/musl/0001-v1.0.0-to-2b74315d.patch b/main/musl/0001-v1.0.0-to-2b74315d.patch deleted file mode 100644 index 57ca3e469c..0000000000 --- a/main/musl/0001-v1.0.0-to-2b74315d.patch +++ /dev/null @@ -1,810 +0,0 @@ -git diff v1.0.0...2b74315d8a31ad8fbcd369116c82e055e0ec3fb7 - -diff --git a/src/conf/confstr.c b/src/conf/confstr.c -index 4332f72..6e9c23a 100644 ---- a/src/conf/confstr.c -+++ b/src/conf/confstr.c -@@ -13,5 +13,5 @@ size_t confstr(int name, char *buf, size_t len) - } - // snprintf is overkill but avoid wasting code size to implement - // this completely useless function and its truncation semantics -- return snprintf(buf, len, "%s", s); -+ return snprintf(buf, len, "%s", s) + 1; - } -diff --git a/src/env/__init_security.c b/src/env/__init_security.c -index 6204c5e..da5ae94 100644 ---- a/src/env/__init_security.c -+++ b/src/env/__init_security.c -@@ -15,9 +15,7 @@ void __init_security(size_t *aux) - struct pollfd pfd[3] = { {.fd=0}, {.fd=1}, {.fd=2} }; - int i; - --#ifndef SHARED - __init_ssp((void *)aux[AT_RANDOM]); --#endif - - if (aux[AT_UID]==aux[AT_EUID] && aux[AT_GID]==aux[AT_EGID] - && !aux[AT_SECURE]) return; -diff --git a/src/env/__init_tls.c b/src/env/__init_tls.c -index 5c17681..8ac0036 100644 ---- a/src/env/__init_tls.c -+++ b/src/env/__init_tls.c -@@ -5,9 +5,30 @@ - #include "pthread_impl.h" - #include "libc.h" - #include "atomic.h" -+#include "syscall.h" -+ -+int __init_tp(void *p) -+{ -+ pthread_t td = p; -+ td->self = td; -+ if (__set_thread_area(TP_ADJ(p)) < 0) -+ return -1; -+ td->tid = td->pid = __syscall(SYS_set_tid_address, &td->tid); -+ td->errno_ptr = &td->errno_val; -+ /* Currently, both of these predicates depend in the same thing: -+ * successful initialization of the thread pointer. However, in -+ * the future, we may support setups where setting the thread -+ * pointer is possible but threads other than the main thread -+ * cannot work, so it's best to keep the predicates separate. */ -+ libc.has_thread_pointer = 1; -+ libc.can_do_threads = 1; -+ return 0; -+} - - #ifndef SHARED - -+static long long builtin_tls[(sizeof(struct pthread) + 64)/sizeof(long long)]; -+ - struct tls_image { - void *image; - size_t len, size, align; -@@ -61,10 +82,11 @@ typedef Elf64_Phdr Phdr; - - void __init_tls(size_t *aux) - { -- unsigned char *p, *mem; -+ unsigned char *p; - size_t n; - Phdr *phdr, *tls_phdr=0; - size_t base = 0; -+ void *mem; - - libc.tls_size = sizeof(struct pthread); - -@@ -75,21 +97,38 @@ void __init_tls(size_t *aux) - if (phdr->p_type == PT_TLS) - tls_phdr = phdr; - } -- if (!tls_phdr) return; - -- T.image = (void *)(base + tls_phdr->p_vaddr); -- T.len = tls_phdr->p_filesz; -- T.size = tls_phdr->p_memsz; -- T.align = tls_phdr->p_align; -+ if (tls_phdr) { -+ T.image = (void *)(base + tls_phdr->p_vaddr); -+ T.len = tls_phdr->p_filesz; -+ T.size = tls_phdr->p_memsz; -+ T.align = tls_phdr->p_align; -+ } - - T.size += (-T.size - (uintptr_t)T.image) & (T.align-1); - if (T.align < 4*sizeof(size_t)) T.align = 4*sizeof(size_t); - - libc.tls_size = 2*sizeof(void *)+T.size+T.align+sizeof(struct pthread); - -- mem = __mmap(0, libc.tls_size, PROT_READ|PROT_WRITE, -- MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); -- if (!__install_initial_tls(__copy_tls(mem))) a_crash(); -+ if (libc.tls_size > sizeof builtin_tls) { -+ mem = (void *)__syscall( -+#ifdef SYS_mmap2 -+ SYS_mmap2, -+#else -+ SYS_mmap, -+#endif -+ 0, libc.tls_size, PROT_READ|PROT_WRITE, -+ MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); -+ /* -4095...-1 cast to void * will crash on dereference anyway, -+ * so don't bloat the init code checking for error codes and -+ * explicitly calling a_crash(). */ -+ } else { -+ mem = builtin_tls; -+ } -+ -+ /* Failure to initialize thread pointer is fatal if TLS is used. */ -+ if (__init_tp(__copy_tls(mem)) < 0 && tls_phdr) -+ a_crash(); - } - #else - void __init_tls(size_t *auxv) { } -diff --git a/src/env/__stack_chk_fail.c b/src/env/__stack_chk_fail.c -index daa1b07..87ac473 100644 ---- a/src/env/__stack_chk_fail.c -+++ b/src/env/__stack_chk_fail.c -@@ -1,18 +1,16 @@ - #include <string.h> - #include <stdint.h> - #include "pthread_impl.h" --#include "atomic.h" - - uintptr_t __stack_chk_guard; - - void __init_ssp(void *entropy) - { -- pthread_t self = __pthread_self_init(); -- uintptr_t canary; -- if (entropy) memcpy(&canary, entropy, sizeof canary); -- else canary = (uintptr_t)&canary * 1103515245; -- a_cas_l(&__stack_chk_guard, 0, canary); -- self->canary = __stack_chk_guard; -+ if (entropy) memcpy(&__stack_chk_guard, entropy, sizeof(uintptr_t)); -+ else __stack_chk_guard = (uintptr_t)&__stack_chk_guard * 1103515245; -+ -+ if (libc.has_thread_pointer) -+ __pthread_self()->canary = __stack_chk_guard; - } - - void __stack_chk_fail(void) -diff --git a/src/errno/__errno_location.c b/src/errno/__errno_location.c -index 3e92d7c..8419107 100644 ---- a/src/errno/__errno_location.c -+++ b/src/errno/__errno_location.c -@@ -3,6 +3,6 @@ - int *__errno_location(void) - { - static int e; -- if (libc.main_thread) return __pthread_self()->errno_ptr; -+ if (libc.has_thread_pointer) return __pthread_self()->errno_ptr; - return &e; - } -diff --git a/src/internal/libc.h b/src/internal/libc.h -index d625b56..fb4d9bc 100644 ---- a/src/internal/libc.h -+++ b/src/internal/libc.h -@@ -6,12 +6,12 @@ - #include <limits.h> - - struct __libc { -- void *main_thread; -+ int has_thread_pointer; -+ int can_do_threads; - int threaded; - int secure; - size_t *auxv; - volatile int threads_minus_1; -- int canceldisable; - FILE *ofl_head; - int ofl_lock[2]; - size_t tls_size; -diff --git a/src/internal/syscall_ret.c b/src/internal/syscall_ret.c -index d99f4a5..a3f4713 100644 ---- a/src/internal/syscall_ret.c -+++ b/src/internal/syscall_ret.c -@@ -1,4 +1,5 @@ - #include <errno.h> -+#include "syscall.h" - - long __syscall_ret(unsigned long r) - { -diff --git a/src/ldso/dynlink.c b/src/ldso/dynlink.c -index a1bdf0f..1517281 100644 ---- a/src/ldso/dynlink.c -+++ b/src/ldso/dynlink.c -@@ -56,6 +56,7 @@ struct dso { - - Phdr *phdr; - int phnum; -+ size_t phentsize; - int refcnt; - Sym *syms; - uint32_t *hashtab; -@@ -74,6 +75,7 @@ struct dso { - char *rpath_orig, *rpath; - void *tls_image; - size_t tls_len, tls_size, tls_align, tls_id, tls_offset; -+ size_t relro_start, relro_end; - void **new_dtv; - unsigned char *new_tls; - int new_dtv_idx, new_tls_idx; -@@ -89,8 +91,7 @@ struct symdef { - - #include "reloc.h" - --void __init_ssp(size_t *); --void *__install_initial_tls(void *); -+int __init_tp(void *); - void __init_libc(char **, char *); - - const char *__libc_get_version(void); -@@ -98,7 +99,6 @@ const char *__libc_get_version(void); - static struct dso *head, *tail, *ldso, *fini_head; - static char *env_path, *sys_path; - static unsigned long long gencnt; --static int ssp_used; - static int runtime; - static int ldd_mode; - static int ldso_fail; -@@ -108,6 +108,7 @@ static pthread_rwlock_t lock; - static struct debug debug; - static size_t tls_cnt, tls_offset, tls_align = 4*sizeof(size_t); - static pthread_mutex_t init_fini_lock = { ._m_type = PTHREAD_MUTEX_RECURSIVE }; -+static long long builtin_tls[(sizeof(struct pthread) + 64)/sizeof(long long)]; - - struct debug *_dl_debug_addr = &debug; - -@@ -198,13 +199,6 @@ static struct symdef find_sym(struct dso *dso, const char *s, int need_def) - { - uint32_t h = 0, gh = 0; - struct symdef def = {0}; -- if (dso->ghashtab) { -- gh = gnu_hash(s); -- if (gh == 0x1f4039c9 && !strcmp(s, "__stack_chk_fail")) ssp_used = 1; -- } else { -- h = sysv_hash(s); -- if (h == 0x595a4cc && !strcmp(s, "__stack_chk_fail")) ssp_used = 1; -- } - for (; dso; dso=dso->next) { - Sym *sym; - if (!dso->global) continue; -@@ -280,27 +274,32 @@ static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stri - * and "donate" them to the heap by setting up minimal malloc - * structures and then freeing them. */ - --static void reclaim(unsigned char *base, size_t start, size_t end) -+static void reclaim(struct dso *dso, size_t start, size_t end) - { - size_t *a, *z; -+ if (start >= dso->relro_start && start < dso->relro_end) start = dso->relro_end; -+ if (end >= dso->relro_start && end < dso->relro_end) end = dso->relro_start; - start = start + 6*sizeof(size_t)-1 & -4*sizeof(size_t); - end = (end & -4*sizeof(size_t)) - 2*sizeof(size_t); - if (start>end || end-start < 4*sizeof(size_t)) return; -- a = (size_t *)(base + start); -- z = (size_t *)(base + end); -+ a = (size_t *)(dso->base + start); -+ z = (size_t *)(dso->base + end); - a[-2] = 1; - a[-1] = z[0] = end-start + 2*sizeof(size_t) | 1; - z[1] = 1; - free(a); - } - --static void reclaim_gaps(unsigned char *base, Phdr *ph, size_t phent, size_t phcnt) -+static void reclaim_gaps(struct dso *dso) - { -- for (; phcnt--; ph=(void *)((char *)ph+phent)) { -+ Phdr *ph = dso->phdr; -+ size_t phcnt = dso->phnum; -+ -+ for (; phcnt--; ph=(void *)((char *)ph+dso->phentsize)) { - if (ph->p_type!=PT_LOAD) continue; - if ((ph->p_flags&(PF_R|PF_W))!=(PF_R|PF_W)) continue; -- reclaim(base, ph->p_vaddr & -PAGE_SIZE, ph->p_vaddr); -- reclaim(base, ph->p_vaddr+ph->p_memsz, -+ reclaim(dso, ph->p_vaddr & -PAGE_SIZE, ph->p_vaddr); -+ reclaim(dso, ph->p_vaddr+ph->p_memsz, - ph->p_vaddr+ph->p_memsz+PAGE_SIZE-1 & -PAGE_SIZE); - } - } -@@ -343,13 +342,16 @@ static void *map_library(int fd, struct dso *dso) - ph = ph0 = (void *)((char *)buf + eh->e_phoff); - } - for (i=eh->e_phnum; i; i--, ph=(void *)((char *)ph+eh->e_phentsize)) { -- if (ph->p_type == PT_DYNAMIC) -+ if (ph->p_type == PT_DYNAMIC) { - dyn = ph->p_vaddr; -- if (ph->p_type == PT_TLS) { -+ } else if (ph->p_type == PT_TLS) { - tls_image = ph->p_vaddr; - dso->tls_align = ph->p_align; - dso->tls_len = ph->p_filesz; - dso->tls_size = ph->p_memsz; -+ } 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; - } - if (ph->p_type != PT_LOAD) continue; - if (ph->p_vaddr < addr_min) { -@@ -393,6 +395,7 @@ static void *map_library(int fd, struct dso *dso) - dso->phdr = (void *)(base + ph->p_vaddr - + (eh->e_phoff-ph->p_offset)); - dso->phnum = eh->e_phnum; -+ dso->phentsize = eh->e_phentsize; - } - /* Reuse the existing mapping for the lowest-address LOAD */ - if ((ph->p_vaddr & -PAGE_SIZE) == addr_min) continue; -@@ -418,12 +421,12 @@ static void *map_library(int fd, struct dso *dso) - goto error; - break; - } -- if (!runtime) reclaim_gaps(base, ph0, eh->e_phentsize, eh->e_phnum); - dso->map = map; - dso->map_len = map_len; - dso->base = base; - dso->dynv = (void *)(base+dyn); - if (dso->tls_size) dso->tls_image = (void *)(base+tls_image); -+ if (!runtime) reclaim_gaps(dso); - free(allocated_buf); - return map; - noexec: -@@ -673,9 +676,10 @@ static struct dso *load_library(const char *name, struct dso *needed_by) - /* Add a shortname only if name arg was not an explicit pathname. */ - if (pathname != name) p->shortname = strrchr(p->name, '/')+1; - if (p->tls_image) { -- if (runtime && !__pthread_self_init()) { -+ if (runtime && !libc.has_thread_pointer) { - munmap(map, p->map_len); - free(p); -+ errno = ENOSYS; - return 0; - } - p->tls_id = ++tls_cnt; -@@ -764,22 +768,32 @@ static void reloc_all(struct dso *p) - 2+(dyn[DT_PLTREL]==DT_RELA)); - do_relocs(p, (void *)(p->base+dyn[DT_REL]), dyn[DT_RELSZ], 2); - do_relocs(p, (void *)(p->base+dyn[DT_RELA]), dyn[DT_RELASZ], 3); -+ -+ if (p->relro_start != p->relro_end && -+ mprotect(p->base+p->relro_start, p->relro_end-p->relro_start, PROT_READ) < 0) { -+ snprintf(errbuf, sizeof errbuf, -+ "Error relocating %s: RELRO protection failed: %m", -+ p->name); -+ if (runtime) longjmp(*rtld_fail, 1); -+ dprintf(2, "%s\n", errbuf); -+ ldso_fail = 1; -+ } -+ - p->relocated = 1; - } - } - --static size_t find_dyn(Phdr *ph, size_t cnt, size_t stride) -+static void kernel_mapped_dso(struct dso *p) - { -- for (; cnt--; ph = (void *)((char *)ph + stride)) -- if (ph->p_type == PT_DYNAMIC) -- return ph->p_vaddr; -- return 0; --} -- --static void find_map_range(Phdr *ph, size_t cnt, size_t stride, struct dso *p) --{ -- size_t min_addr = -1, max_addr = 0; -- for (; cnt--; ph = (void *)((char *)ph + stride)) { -+ size_t min_addr = -1, max_addr = 0, cnt; -+ Phdr *ph = p->phdr; -+ for (cnt = p->phnum; cnt--; ph = (void *)((char *)ph + p->phentsize)) { -+ if (ph->p_type == PT_DYNAMIC) { -+ p->dynv = (void *)(p->base + ph->p_vaddr); -+ } 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; -+ } - if (ph->p_type != PT_LOAD) continue; - if (ph->p_vaddr < min_addr) - min_addr = ph->p_vaddr; -@@ -790,6 +804,7 @@ static void find_map_range(Phdr *ph, size_t cnt, size_t stride, struct dso *p) - max_addr = (max_addr + PAGE_SIZE-1) & -PAGE_SIZE; - p->map = p->base + min_addr; - p->map_len = max_addr - min_addr; -+ p->kernel_mapped = 1; - } - - static void do_fini() -@@ -866,10 +881,13 @@ void *__copy_tls(unsigned char *mem) - pthread_t td; - struct dso *p; - -- if (!tls_cnt) return mem; -- - void **dtv = (void *)mem; - dtv[0] = (void *)tls_cnt; -+ if (!tls_cnt) { -+ td = (void *)(dtv+1); -+ td->dtv = dtv; -+ return td; -+ } - - #ifdef TLS_ABOVE_TP - mem += sizeof(void *) * (tls_cnt+1); -@@ -962,6 +980,7 @@ void *__dynlink(int argc, char **argv) - size_t vdso_base; - size_t *auxv; - char **envp = argv+argc+1; -+ void *initial_tls; - - /* Find aux vector just past environ[] */ - for (i=argc+1; argv[i]; i++) -@@ -996,13 +1015,11 @@ void *__dynlink(int argc, char **argv) - lib->base = (void *)aux[AT_BASE]; - lib->name = lib->shortname = "libc.so"; - lib->global = 1; -- lib->kernel_mapped = 1; - ehdr = (void *)lib->base; - lib->phnum = ehdr->e_phnum; - lib->phdr = (void *)(aux[AT_BASE]+ehdr->e_phoff); -- find_map_range(lib->phdr, ehdr->e_phnum, ehdr->e_phentsize, lib); -- lib->dynv = (void *)(lib->base + find_dyn(lib->phdr, -- ehdr->e_phnum, ehdr->e_phentsize)); -+ lib->phentsize = ehdr->e_phentsize; -+ kernel_mapped_dso(lib); - decode_dyn(lib); - - if (aux[AT_PHDR]) { -@@ -1011,6 +1028,7 @@ void *__dynlink(int argc, char **argv) - /* Find load address of the main program, via AT_PHDR vs PT_PHDR. */ - app->phdr = phdr = (void *)aux[AT_PHDR]; - app->phnum = aux[AT_PHNUM]; -+ app->phentsize = aux[AT_PHENT]; - for (i=aux[AT_PHNUM]; i; i--, phdr=(void *)((char *)phdr + aux[AT_PHENT])) { - if (phdr->p_type == PT_PHDR) - app->base = (void *)(aux[AT_PHDR] - phdr->p_vaddr); -@@ -1030,11 +1048,7 @@ void *__dynlink(int argc, char **argv) - app->name = (char *)aux[AT_EXECFN]; - else - app->name = argv[0]; -- app->kernel_mapped = 1; -- app->dynv = (void *)(app->base + find_dyn( -- (void *)aux[AT_PHDR], aux[AT_PHNUM], aux[AT_PHENT])); -- find_map_range((void *)aux[AT_PHDR], -- aux[AT_PHNUM], aux[AT_PHENT], app); -+ kernel_mapped_dso(app); - } else { - int fd; - char *ldname = argv[0]; -@@ -1100,6 +1114,7 @@ void *__dynlink(int argc, char **argv) - ehdr = (void *)vdso_base; - vdso->phdr = phdr = (void *)(vdso_base + ehdr->e_phoff); - vdso->phnum = ehdr->e_phnum; -+ vdso->phentsize = ehdr->e_phentsize; - for (i=ehdr->e_phnum; i; i--, phdr=(void *)((char *)phdr + ehdr->e_phentsize)) { - if (phdr->p_type == PT_DYNAMIC) - vdso->dynv = (void *)(vdso_base + phdr->p_offset); -@@ -1127,10 +1142,8 @@ void *__dynlink(int argc, char **argv) - /* PAST THIS POINT, ALL LIBC INTERFACES ARE FULLY USABLE. */ - - /* Donate unused parts of app and library mapping to malloc */ -- reclaim_gaps(app->base, (void *)aux[AT_PHDR], aux[AT_PHENT], aux[AT_PHNUM]); -- ehdr = (void *)lib->base; -- reclaim_gaps(lib->base, (void *)(lib->base+ehdr->e_phoff), -- ehdr->e_phentsize, ehdr->e_phnum); -+ reclaim_gaps(app); -+ reclaim_gaps(lib); - - /* Load preload/needed libraries, add their symbols to the global - * namespace, and perform all remaining relocations. The main -@@ -1140,19 +1153,29 @@ void *__dynlink(int argc, char **argv) - load_deps(app); - make_global(app); - -+#ifndef DYNAMIC_IS_RO -+ for (i=0; app->dynv[i]; i+=2) -+ if (app->dynv[i]==DT_DEBUG) -+ app->dynv[i+1] = (size_t)&debug; -+#endif -+ - reloc_all(app->next); - reloc_all(app); - - update_tls_size(); -- if (tls_cnt) { -- void *mem = mmap(0, libc.tls_size, PROT_READ|PROT_WRITE, -- MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); -- if (mem==MAP_FAILED || -- !__install_initial_tls(__copy_tls(mem))) { -+ if (libc.tls_size > sizeof builtin_tls) { -+ initial_tls = calloc(libc.tls_size, 1); -+ if (!initial_tls) { - dprintf(2, "%s: Error getting %zu bytes thread-local storage: %m\n", - argv[0], libc.tls_size); - _exit(127); - } -+ } else { -+ initial_tls = builtin_tls; -+ } -+ if (__init_tp(__copy_tls(initial_tls)) < 0 && tls_cnt) { -+ dprintf(2, "%s: Thread-local storage not supported by kernel.\n", argv[0]); -+ _exit(127); - } - - if (ldso_fail) _exit(127); -@@ -1164,11 +1187,6 @@ void *__dynlink(int argc, char **argv) - * all memory used by the dynamic linker. */ - runtime = 1; - --#ifndef DYNAMIC_IS_RO -- for (i=0; app->dynv[i]; i+=2) -- if (app->dynv[i]==DT_DEBUG) -- app->dynv[i+1] = (size_t)&debug; --#endif - debug.ver = 1; - debug.bp = _dl_debug_state; - debug.head = head; -@@ -1176,7 +1194,6 @@ void *__dynlink(int argc, char **argv) - debug.state = 0; - _dl_debug_state(); - -- if (ssp_used) __init_ssp((void *)aux[AT_RANDOM]); - __init_libc(envp, argv[0]); - atexit(do_fini); - errno = 0; -@@ -1258,9 +1275,6 @@ void *dlopen(const char *file, int mode) - } - - update_tls_size(); -- -- if (ssp_used) __init_ssp(libc.auxv); -- - _dl_debug_state(); - orig_tail = tail; - end: -diff --git a/src/process/fork.c b/src/process/fork.c -index 1a82f42..864c7d7 100644 ---- a/src/process/fork.c -+++ b/src/process/fork.c -@@ -17,12 +17,11 @@ pid_t fork(void) - __fork_handler(-1); - __block_all_sigs(&set); - ret = syscall(SYS_fork); -- if (libc.main_thread && !ret) { -+ if (libc.has_thread_pointer && !ret) { - pthread_t self = __pthread_self(); -- self->tid = self->pid = syscall(SYS_getpid); -+ self->tid = self->pid = __syscall(SYS_getpid); - memset(&self->robust_list, 0, sizeof self->robust_list); - libc.threads_minus_1 = 0; -- libc.main_thread = self; - } - __restore_sigs(&set); - __fork_handler(!ret); -diff --git a/src/signal/sigaction.c b/src/signal/sigaction.c -index f7ff4a6..d5f4774 100644 ---- a/src/signal/sigaction.c -+++ b/src/signal/sigaction.c -@@ -8,9 +8,7 @@ - - void __restore(), __restore_rt(); - --static pthread_t dummy(void) { return 0; } --weak_alias(dummy, __pthread_self_def); -- -+static int unmask_done; - static unsigned long handler_set[_NSIG/(8*sizeof(long))]; - - void __get_handler_set(sigset_t *set) -@@ -29,7 +27,20 @@ int __libc_sigaction(int sig, const struct sigaction *restrict sa, struct sigact - if ((uintptr_t)sa->sa_handler > 1UL) { - a_or_l(handler_set+(sig-1)/(8*sizeof(long)), - 1UL<<(sig-1)%(8*sizeof(long))); -- __pthread_self_def(); -+ -+ /* If pthread_create has not yet been called, -+ * implementation-internal signals might not -+ * yet have been unblocked. They must be -+ * unblocked before any signal handler is -+ * installed, so that an application cannot -+ * receive an illegal sigset_t (with them -+ * blocked) as part of the ucontext_t passed -+ * to the signal handler. */ -+ if (!libc.threaded && !unmask_done) { -+ __syscall(SYS_rt_sigprocmask, SIG_UNBLOCK, -+ SIGPT_SET, 0, _NSIG/8); -+ unmask_done = 1; -+ } - } - ksa.handler = sa->sa_handler; - ksa.flags = sa->sa_flags | SA_RESTORER; -diff --git a/src/stdio/__stdio_read.c b/src/stdio/__stdio_read.c -index 05e56f9..6cd7b07 100644 ---- a/src/stdio/__stdio_read.c -+++ b/src/stdio/__stdio_read.c -@@ -16,13 +16,9 @@ size_t __stdio_read(FILE *f, unsigned char *buf, size_t len) - }; - ssize_t cnt; - -- if (libc.main_thread) { -- pthread_cleanup_push(cleanup, f); -- cnt = syscall_cp(SYS_readv, f->fd, iov, 2); -- pthread_cleanup_pop(0); -- } else { -- cnt = syscall(SYS_readv, f->fd, iov, 2); -- } -+ pthread_cleanup_push(cleanup, f); -+ cnt = syscall_cp(SYS_readv, f->fd, iov, 2); -+ pthread_cleanup_pop(0); - if (cnt <= 0) { - f->flags |= F_EOF ^ ((F_ERR^F_EOF) & cnt); - f->rpos = f->rend = 0; -diff --git a/src/stdio/__stdio_write.c b/src/stdio/__stdio_write.c -index e52e91a..8c89389 100644 ---- a/src/stdio/__stdio_write.c -+++ b/src/stdio/__stdio_write.c -@@ -19,13 +19,9 @@ size_t __stdio_write(FILE *f, const unsigned char *buf, size_t len) - int iovcnt = 2; - ssize_t cnt; - for (;;) { -- if (libc.main_thread) { -- pthread_cleanup_push(cleanup, f); -- cnt = syscall_cp(SYS_writev, f->fd, iov, iovcnt); -- pthread_cleanup_pop(0); -- } else { -- cnt = syscall(SYS_writev, f->fd, iov, iovcnt); -- } -+ pthread_cleanup_push(cleanup, f); -+ cnt = syscall_cp(SYS_writev, f->fd, iov, iovcnt); -+ pthread_cleanup_pop(0); - if (cnt == rem) { - f->wend = f->buf + f->buf_size; - f->wpos = f->wbase = f->buf; -diff --git a/src/thread/cancel_impl.c b/src/thread/cancel_impl.c -index c835813..525d290 100644 ---- a/src/thread/cancel_impl.c -+++ b/src/thread/cancel_impl.c -@@ -20,7 +20,7 @@ long (__syscall_cp)(syscall_arg_t nr, - pthread_t self; - long r; - -- if (!libc.main_thread || (self = __pthread_self())->canceldisable) -+ if (!libc.has_thread_pointer || (self = __pthread_self())->canceldisable) - return __syscall(nr, u, v, w, x, y, z); - - r = __syscall_cp_asm(&self->cancel, nr, u, v, w, x, y, z); -@@ -57,6 +57,7 @@ static void cancel_handler(int sig, siginfo_t *si, void *ctx) - - void __testcancel() - { -+ if (!libc.has_thread_pointer) return; - pthread_t self = pthread_self(); - if (self->cancel && !self->canceldisable) - __cancel(); -diff --git a/src/thread/pthread_create.c b/src/thread/pthread_create.c -index ee6c31c..e0b5ef1 100644 ---- a/src/thread/pthread_create.c -+++ b/src/thread/pthread_create.c -@@ -77,6 +77,7 @@ _Noreturn void pthread_exit(void *result) - - void __do_cleanup_push(struct __ptcb *cb) - { -+ if (!libc.has_thread_pointer) return; - struct pthread *self = pthread_self(); - cb->__next = self->cancelbuf; - self->cancelbuf = cb; -@@ -84,6 +85,7 @@ void __do_cleanup_push(struct __ptcb *cb) - - void __do_cleanup_pop(struct __ptcb *cb) - { -+ if (!libc.has_thread_pointer) return; - __pthread_self()->cancelbuf = cb->__next; - } - -@@ -110,6 +112,8 @@ static int start(void *p) - /* pthread_key_create.c overrides this */ - static const size_t dummy = 0; - weak_alias(dummy, __pthread_tsd_size); -+static void *const dummy_tsd[1] = { 0 }; -+weak_alias(dummy_tsd, __pthread_tsd_main); - - static FILE *const dummy_file = 0; - weak_alias(dummy_file, __stdin_used); -@@ -127,7 +131,7 @@ int pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict attrp - { - int ret; - size_t size, guard; -- struct pthread *self = pthread_self(), *new; -+ struct pthread *self, *new; - unsigned char *map = 0, *stack = 0, *tsd = 0, *stack_limit; - unsigned flags = CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND - | CLONE_THREAD | CLONE_SYSVSEM | CLONE_SETTLS -@@ -135,13 +139,16 @@ int pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict attrp - int do_sched = 0; - pthread_attr_t attr = {0}; - -- if (!self) return ENOSYS; -+ if (!libc.can_do_threads) return ENOSYS; -+ self = __pthread_self(); - if (!libc.threaded) { - for (FILE *f=libc.ofl_head; f; f=f->next) - init_file_lock(f); - init_file_lock(__stdin_used); - init_file_lock(__stdout_used); - init_file_lock(__stderr_used); -+ __syscall(SYS_rt_sigprocmask, SIG_UNBLOCK, SIGPT_SET, 0, _NSIG/8); -+ self->tsd = (void **)__pthread_tsd_main; - libc.threaded = 1; - } - if (attrp) attr = *attrp; -diff --git a/src/thread/pthread_key_create.c b/src/thread/pthread_key_create.c -index c29935c..ef8a755 100644 ---- a/src/thread/pthread_key_create.c -+++ b/src/thread/pthread_key_create.c -@@ -14,7 +14,13 @@ int pthread_key_create(pthread_key_t *k, void (*dtor)(void *)) - unsigned i = (uintptr_t)&k / 16 % PTHREAD_KEYS_MAX; - unsigned j = i; - -- __pthread_self_init(); -+ if (libc.has_thread_pointer) { -+ pthread_t self = __pthread_self(); -+ /* This can only happen in the main thread before -+ * pthread_create has been called. */ -+ if (!self->tsd) self->tsd = __pthread_tsd_main; -+ } -+ - if (!dtor) dtor = nodtor; - do { - if (!a_cas_p(keys+j, 0, (void *)dtor)) { -diff --git a/src/thread/pthread_self.c b/src/thread/pthread_self.c -index aed4b5f..5f9e651 100644 ---- a/src/thread/pthread_self.c -+++ b/src/thread/pthread_self.c -@@ -1,45 +1,6 @@ - #include "pthread_impl.h" - --static struct pthread *main_thread = &(struct pthread){0}; -- --/* pthread_key_create.c overrides this */ --static const void *dummy[1] = { 0 }; --weak_alias(dummy, __pthread_tsd_main); -- --static int init_main_thread() --{ -- __syscall(SYS_rt_sigprocmask, SIG_UNBLOCK, -- SIGPT_SET, 0, _NSIG/8); -- if (__set_thread_area(TP_ADJ(main_thread)) < 0) return -1; -- main_thread->canceldisable = libc.canceldisable; -- main_thread->tsd = (void **)__pthread_tsd_main; -- main_thread->errno_ptr = __errno_location(); -- main_thread->self = main_thread; -- main_thread->tid = main_thread->pid = -- __syscall(SYS_set_tid_address, &main_thread->tid); -- if (!main_thread->dtv) -- main_thread->dtv = (void *)dummy; -- libc.main_thread = main_thread; -- return 0; --} -- --pthread_t __pthread_self_def() -+pthread_t pthread_self() - { -- static int init, failed; -- if (!init) { -- if (failed) return 0; -- if (init_main_thread() < 0) failed = 1; -- if (failed) return 0; -- init = 1; -- } - return __pthread_self(); - } -- --weak_alias(__pthread_self_def, pthread_self); --weak_alias(__pthread_self_def, __pthread_self_init); -- --void *__install_initial_tls(void *p) --{ -- main_thread = p; -- return __pthread_self_def(); --} -diff --git a/src/thread/pthread_setcancelstate.c b/src/thread/pthread_setcancelstate.c -index ba2b231..060bcdc 100644 ---- a/src/thread/pthread_setcancelstate.c -+++ b/src/thread/pthread_setcancelstate.c -@@ -3,13 +3,9 @@ - int pthread_setcancelstate(int new, int *old) - { - if (new > 1U) return EINVAL; -- if (libc.main_thread) { -- struct pthread *self = __pthread_self(); -- if (old) *old = self->canceldisable; -- self->canceldisable = new; -- } else { -- if (old) *old = libc.canceldisable; -- libc.canceldisable = new; -- } -+ if (!libc.has_thread_pointer) return ENOSYS; -+ struct pthread *self = __pthread_self(); -+ if (old) *old = self->canceldisable; -+ self->canceldisable = new; - return 0; - } |