X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ldso%2Fdynlink.c;h=5b9c8be42160c1730424226c1d29e05a6964a86e;hb=3aba2150d0efc80df30d7fc6c22d6041e14d445e;hp=f9ac0100c51d2c7ffa18f0f0d56a5516bbca010b;hpb=ccba23459ebacc8bc6e5eeef7454c91ceb61b5b0;p=musl diff --git a/ldso/dynlink.c b/ldso/dynlink.c index f9ac0100..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); @@ -2289,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);