From a9e85c0a5c690086c652f3a8ae9a109389f671a3 Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Fri, 23 Mar 2012 00:28:20 -0400 Subject: make dlerror conform to posix the error status is required to be sticky after failure of dlopen or dlsym until cleared by dlerror. applications and especially libraries should never rely on this since it is not thread-safe and subject to race conditions, but glib does anyway. --- src/ldso/dynlink.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/ldso/dynlink.c b/src/ldso/dynlink.c index 6ff8850c..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 @@ -631,12 +634,13 @@ void *dlopen(const char *file, int mode) tail = orig_tail; tail->next = 0; p = 0; + } else p = load_library(file); + + if (!p) { + errflag = 1; goto end; } - p = load_library(file); - if (!p) goto end; - /* First load handling */ if (!p->deps) { load_deps(p); @@ -674,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)) @@ -686,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; } @@ -710,6 +718,8 @@ void *__dlsym(void *p, const char *s, void *ra) char *dlerror() { + if (!errflag) return 0; + errflag = 0; return "unknown error"; } -- cgit v1.2.1 From ad2d2b963a4bf9e2631b345c898e8715b36b459e Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Fri, 23 Mar 2012 01:52:49 -0400 Subject: asm for hypot and hypotf MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit special care is made to avoid any inexact computations when either arg is zero (in which case the exact absolute value of the other arg should be returned) and to support the special condition that hypot(±inf,nan) yields inf. hypotl is not yet implemented since avoiding overflow is nontrivial. --- src/math/i386/hypot.s | 45 +++++++++++++++++++++++++++++++++++++++++++++ src/math/i386/hypotf.s | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 src/math/i386/hypot.s create mode 100644 src/math/i386/hypotf.s diff --git a/src/math/i386/hypot.s b/src/math/i386/hypot.s new file mode 100644 index 00000000..299c2e18 --- /dev/null +++ b/src/math/i386/hypot.s @@ -0,0 +1,45 @@ +.global hypot +.type hypot,@function +hypot: + mov 8(%esp),%eax + mov 16(%esp),%ecx + add %eax,%eax + add %ecx,%ecx + and %eax,%ecx + cmp $0xffe00000,%ecx + jae 2f + or 4(%esp),%eax + jnz 1f + fldl 12(%esp) + fabs + ret +1: mov 16(%esp),%eax + add %eax,%eax + or 12(%esp),%eax + jnz 1f + fldl 4(%esp) + fabs + ret +1: fldl 4(%esp) + fld %st(0) + fmulp + fldl 12(%esp) + fld %st(0) + fmulp + faddp + fsqrt + ret +2: sub $0xffe00000,%eax + or 4(%esp),%eax + jnz 1f + fldl 4(%esp) + fabs + ret +1: mov 16(%esp),%eax + add %eax,%eax + sub $0xffe00000,%eax + or 12(%esp),%eax + fldl 12(%esp) + jnz 1f + fabs +1: ret diff --git a/src/math/i386/hypotf.s b/src/math/i386/hypotf.s new file mode 100644 index 00000000..068935e2 --- /dev/null +++ b/src/math/i386/hypotf.s @@ -0,0 +1,42 @@ +.global hypotf +.type hypotf,@function +hypotf: + mov 4(%esp),%eax + mov 8(%esp),%ecx + add %eax,%eax + add %ecx,%ecx + and %eax,%ecx + cmp $0xff000000,%ecx + jae 2f + test %eax,%eax + jnz 1f + flds 8(%esp) + fabs + ret +1: mov 8(%esp),%eax + add %eax,%eax + jnz 1f + flds 4(%esp) + fabs + ret +1: flds 4(%esp) + fld %st(0) + fmulp + flds 8(%esp) + fld %st(0) + fmulp + faddp + fsqrt + ret +2: cmp $0xff000000,%eax + jnz 1f + flds 4(%esp) + fabs + ret +1: mov 8(%esp),%eax + add %eax,%eax + cmp $0xff000000,%eax + flds 8(%esp) + jnz 1f + fabs +1: ret -- cgit v1.2.1