X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;ds=sidebyside;f=src%2Fldso%2Fdynlink.c;h=e0013ec0eecfe698dd717135e79cb55b44214e78;hb=a9e85c0a5c690086c652f3a8ae9a109389f671a3;hp=eda0046e9e0ac4646972292a60071bab16be6dea;hpb=700a8156adc5bfb3ddf9c92dab4ffd516df31958;p=musl diff --git a/src/ldso/dynlink.c b/src/ldso/dynlink.c index eda0046e..e0013ec0 100644 --- a/src/ldso/dynlink.c +++ b/src/ldso/dynlink.c @@ -1,4 +1,3 @@ -#ifdef __PIC__ #include #include #include @@ -18,6 +17,10 @@ #include #include +static int errflag; + +#ifdef __PIC__ + #include "reloc.h" #if ULONG_MAX == 0xffffffff @@ -610,9 +613,11 @@ void *dlopen(const char *file, int mode) { struct dso *volatile p, *orig_tail = tail, *next; size_t i; + int cs; if (!file) return head; + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); pthread_rwlock_wrlock(&lock); if (setjmp(rtld_fail)) { @@ -628,12 +633,13 @@ void *dlopen(const char *file, int mode) } tail = orig_tail; tail->next = 0; - pthread_rwlock_unlock(&lock); - return 0; - } + p = 0; + } else p = load_library(file); - p = load_library(file); - if (!p) goto end; + if (!p) { + errflag = 1; + goto end; + } /* First load handling */ if (!p->deps) { @@ -658,6 +664,7 @@ void *dlopen(const char *file, int mode) do_init_fini(tail); end: pthread_rwlock_unlock(&lock); + pthread_setcancelstate(cs, 0); return p; } @@ -671,8 +678,11 @@ static void *do_dlsym(struct dso *p, const char *s, void *ra) if (!p) p=head; p=p->next; } - if (p == head || p == RTLD_DEFAULT) - return find_sym(head, s, 0); + if (p == head || p == RTLD_DEFAULT) { + void *res = find_sym(head, s, 0); + if (!res) errflag = 1; + return res; + } h = hash(s); sym = lookup(s, h, p->syms, p->hashtab, p->strings); if (sym && sym->st_value && (1<<(sym->st_info&0xf) & OK_TYPES)) @@ -683,6 +693,7 @@ static void *do_dlsym(struct dso *p, const char *s, void *ra) if (sym && sym->st_value && (1<<(sym->st_info&0xf) & OK_TYPES)) return p->deps[i]->base + sym->st_value; } + errflag = 1; return 0; } @@ -707,6 +718,8 @@ void *__dlsym(void *p, const char *s, void *ra) char *dlerror() { + if (!errflag) return 0; + errflag = 0; return "unknown error"; }