X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ldso%2Fdynlink.c;h=5b9c8be42160c1730424226c1d29e05a6964a86e;hb=55b727d7ad6c3c8ac147622c441e2995e553e91d;hp=af983692b764132556f35cc38f4ccc872c31d3dd;hpb=50716702d41d5f6f31c1075a1734b9f759477f0d;p=musl diff --git a/ldso/dynlink.c b/ldso/dynlink.c index af983692..5b9c8be4 100644 --- a/ldso/dynlink.c +++ b/ldso/dynlink.c @@ -1,6 +1,5 @@ #define _GNU_SOURCE #define SYSCALL_NO_TLS 1 -#include #include #include #include @@ -21,9 +20,15 @@ #include #include #include "pthread_impl.h" +#include "fork_impl.h" #include "libc.h" #include "dynlink.h" +#define malloc __libc_malloc +#define calloc __libc_calloc +#define realloc __libc_realloc +#define free __libc_free + static void error(const char *, ...); #define MAXP2(a,b) (-(-(a)&-(b))) @@ -556,10 +561,25 @@ static void reclaim_gaps(struct dso *dso) } } +static ssize_t read_loop(int fd, void *p, size_t n) +{ + for (size_t i=0; i=0) { + size_t n = 0; + if (!fstat(fd, &st)) n = st.st_size; + if ((sys_path = malloc(n+1))) + sys_path[n] = 0; + if (!sys_path || read_loop(fd, sys_path, n)<0) { free(sys_path); sys_path = ""; } - fclose(f); + close(fd); } else if (errno != ENOENT) { sys_path = ""; } @@ -1404,6 +1428,17 @@ void __libc_exit_fini() } } +void __ldso_atfork(int who) +{ + if (who<0) { + pthread_rwlock_wrlock(&lock); + pthread_mutex_lock(&init_fini_lock); + } else { + pthread_mutex_unlock(&init_fini_lock); + pthread_rwlock_unlock(&lock); + } +} + static struct dso **queue_ctors(struct dso *dso) { size_t cnt, qpos, spos, i; @@ -1462,6 +1497,13 @@ static struct dso **queue_ctors(struct dso *dso) } queue[qpos] = 0; for (i=0; imark = 0; + for (i=0; ictor_visitor && queue[i]->ctor_visitor->tid < 0) { + error("State of %s is inconsistent due to multithreaded fork\n", + queue[i]->name); + free(queue); + if (runtime) longjmp(*rtld_fail, 1); + } return queue; } @@ -1789,7 +1831,7 @@ void __dls3(size_t *sp, size_t *auxv) dprintf(2, "%s: cannot load %s: %s\n", ldname, argv[0], strerror(errno)); _exit(1); } - Ehdr *ehdr = (void *)map_library(fd, &app); + Ehdr *ehdr = map_library(fd, &app); if (!ehdr) { dprintf(2, "%s: %s: Not a valid dynamic program\n", ldname, argv[0]); _exit(1); @@ -1947,7 +1989,7 @@ void __dls3(size_t *sp, size_t *auxv) debug.bp = dl_debug_state; debug.head = head; debug.base = ldso.base; - debug.state = 0; + debug.state = RT_CONSISTENT; _dl_debug_state(); if (replace_argv0) argv[0] = replace_argv0; @@ -1996,6 +2038,9 @@ void *dlopen(const char *file, int mode) pthread_rwlock_wrlock(&lock); __inhibit_ptc(); + debug.state = RT_ADD; + _dl_debug_state(); + p = 0; if (shutting_down) { error("Cannot dlopen while program is exiting."); @@ -2089,9 +2134,10 @@ void *dlopen(const char *file, int mode) update_tls_size(); if (tls_cnt != orig_tls_cnt) install_new_tls(); - _dl_debug_state(); orig_tail = tail; end: + debug.state = RT_CONSISTENT; + _dl_debug_state(); __release_ptc(); if (p) gencnt++; pthread_rwlock_unlock(&lock); @@ -2285,7 +2331,8 @@ int dl_iterate_phdr(int(*callback)(struct dl_phdr_info *info, size_t size, void info.dlpi_adds = gencnt; info.dlpi_subs = 0; info.dlpi_tls_modid = current->tls_id; - info.dlpi_tls_data = current->tls.image; + info.dlpi_tls_data = !current->tls_id ? 0 : + __tls_get_addr((tls_mod_off_t[]){current->tls_id,0}); ret = (callback)(&info, sizeof (info), data);