X-Git-Url: http://nsz.repo.hu/git/?p=musl;a=blobdiff_plain;f=src%2Fldso%2Fdynlink.c;h=ac4b669f178bdb94d5d674e1a6fbea196c3b0c19;hp=b1a4409dc17c1066e6774d7e045e7b2c5d576b06;hb=509b50eda8ea7d4a28f738e4cf8ea98d25959f00;hpb=4d07e5521ea811278f00f434fe2b8345ea1d8832 diff --git a/src/ldso/dynlink.c b/src/ldso/dynlink.c index b1a4409d..ac4b669f 100644 --- a/src/ldso/dynlink.c +++ b/src/ldso/dynlink.c @@ -403,16 +403,16 @@ error: return 0; } -static int path_open(const char *name, const char *search, char *buf, size_t buf_size) +static int path_open(const char *name, const char *s, char *buf, size_t buf_size) { - const char *s=search, *z; - int l, fd; + size_t l; + int fd; for (;;) { - while (*s==':') s++; - if (!*s) return -1; - z = strchr(s, ':'); - l = z ? z-s : strlen(s); - snprintf(buf, buf_size, "%.*s/%s", l, s, name); + s += strspn(s, ":\n"); + l = strcspn(s, ":\n"); + if (l-1 >= INT_MAX) return -1; + if (snprintf(buf, buf_size, "%.*s/%s", (int)l, s, name) >= buf_size) + continue; if ((fd = open(buf, O_RDONLY|O_CLOEXEC))>=0) return fd; s += l; } @@ -435,7 +435,6 @@ static struct dso *load_library(const char *name) char buf[2*NAME_MAX+2]; const char *pathname; unsigned char *map; - size_t map_len; struct dso *p, temp_dso = {0}; int fd; struct stat st; @@ -479,10 +478,9 @@ static struct dso *load_library(const char *name) if (!sys_path) { FILE *f = fopen(ETC_LDSO_PATH, "rbe"); if (f) { - if (getline(&sys_path, (size_t[1]){0}, f) > 0) { - size_t l = strlen(sys_path); - if (l && sys_path[l-1]=='\n') - sys_path[l-1] = 0; + if (getdelim(&sys_path, (size_t[1]){0}, 0, f) <= 0) { + free(sys_path); + sys_path = ""; } fclose(f); } @@ -528,7 +526,7 @@ static struct dso *load_library(const char *name) } p = calloc(1, alloc_size); if (!p) { - munmap(map, map_len); + munmap(map, temp_dso.map_len); return 0; } memcpy(p, &temp_dso, sizeof temp_dso); @@ -542,8 +540,8 @@ static struct dso *load_library(const char *name) if (pathname != name) p->shortname = strrchr(p->name, '/')+1; if (p->tls_image) { if (runtime && !__pthread_self_init()) { + munmap(map, p->map_len); free(p); - munmap(map, map_len); return 0; } p->tls_id = ++tls_cnt; @@ -694,6 +692,10 @@ static void do_init_fini(struct dso *p) } if (dyn[0] & (1<base + dyn[DT_INIT]))(); + if (!need_locking && libc.threads_minus_1) { + need_locking = 1; + pthread_mutex_lock(&init_fini_lock); + } } if (need_locking) pthread_mutex_unlock(&init_fini_lock); } @@ -741,13 +743,13 @@ void *__copy_tls(unsigned char *mem) void *__tls_get_addr(size_t *v) { pthread_t self = __pthread_self(); - if (self->dtv && v[0]<=(size_t)self->dtv[0] && self->dtv[v[0]]) + if (v[0]<=(size_t)self->dtv[0] && self->dtv[v[0]]) return (char *)self->dtv[v[0]]+v[1]; /* Block signals to make accessing new TLS async-signal-safe */ sigset_t set; pthread_sigmask(SIG_BLOCK, SIGALL_SET, &set); - if (self->dtv && v[0]<=(size_t)self->dtv[0] && self->dtv[v[0]]) { + if (v[0]<=(size_t)self->dtv[0] && self->dtv[v[0]]) { pthread_sigmask(SIG_SETMASK, &set, 0); return (char *)self->dtv[v[0]]+v[1]; } @@ -760,10 +762,10 @@ void *__tls_get_addr(size_t *v) for (p=head; p->tls_id != v[0]; p=p->next); /* Get new DTV space from new DSO if needed */ - if (!self->dtv || v[0] > (size_t)self->dtv[0]) { + if (v[0] > (size_t)self->dtv[0]) { void **newdtv = p->new_dtv + (v[0]+1)*sizeof(void *)*a_fetch_add(&p->new_dtv_idx,1); - if (self->dtv) memcpy(newdtv, self->dtv, + memcpy(newdtv, self->dtv, ((size_t)self->dtv[0]+1) * sizeof(void *)); newdtv[0] = (void *)v[0]; self->dtv = newdtv;