summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog15
-rw-r--r--elf/dl-sym.c5
-rw-r--r--include/math.h3
-rw-r--r--sysdeps/i386/fpu/s_expm1.S6
-rw-r--r--sysdeps/i386/fpu/s_expm1f.S6
-rw-r--r--sysdeps/i386/fpu/s_expm1l.S3
-rw-r--r--sysdeps/ieee754/dbl-64/w_exp.c1
-rw-r--r--sysdeps/ieee754/flt-32/w_expf.c1
-rw-r--r--sysdeps/ieee754/ldbl-96/w_expl.c1
9 files changed, 40 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index 700e346981..ccbb625461 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2009-10-21  Andreas Schwab  <schwab@redhat.com>
+
+	* elf/dl-sym.c (do_sym): Resolve STT_GNU_IFUNC symbols.
+
+2009-10-19  Andreas Schwab  <schwab@redhat.com>
+
+	* include/math.h: Add hidden protos for __exp/__expf/__expl.
+	* sysdeps/ieee754/dbl-64/w_exp.c: Add hidden alias.
+	* sysdeps/ieee754/flt-32/w_expf.c: Likewise.
+	* sysdeps/ieee754/ldbl-96/w_expl.c: Likewise.
+	* sysdeps/i386/fpu/s_expm1.S: Call __exp to handle overflow.
+	* sysdeps/i386/fpu/s_expm1f.S: Call __expf to handle overflow.
+	* sysdeps/i386/fpu/s_expm1l.S: Call __expl instead of
+	__ieee751_expl to handle overflow.
+
 2009-10-14  David S. Miller  <davem@davemloft.net>
 
 	* sysdeps/unix/sysv/linux/sparc/sparc32/____longjmp_chk.S: New file.
diff --git a/elf/dl-sym.c b/elf/dl-sym.c
index 740bb9a892..459729f0f2 100644
--- a/elf/dl-sym.c
+++ b/elf/dl-sym.c
@@ -191,6 +191,11 @@ RTLD_NEXT used in code not dynamically loaded"));
 #endif
 	value = DL_SYMBOL_ADDRESS (result, ref);
 
+      /* Resolve indirect function address.  */
+      if (__builtin_expect (ELFW(ST_TYPE) (ref->st_info) == STT_GNU_IFUNC, 0))
+	value
+	  = ((DL_FIXUP_VALUE_TYPE (*) (void)) DL_FIXUP_VALUE_ADDR (value)) ();
+
 #ifdef SHARED
       /* Auditing checkpoint: we have a new binding.  Provide the
 	 auditing libraries the possibility to change the value and
diff --git a/include/math.h b/include/math.h
index 1005804273..eb29ef1a56 100644
--- a/include/math.h
+++ b/include/math.h
@@ -22,9 +22,12 @@ hidden_proto (__isnanl)
 
 libm_hidden_proto (__fpclassify)
 libm_hidden_proto (__fpclassifyf)
+libm_hidden_proto (__exp)
+libm_hidden_proto (__expf)
 
 # ifndef __NO_LONG_DOUBLE_MATH
 libm_hidden_proto (__fpclassifyl)
+libm_hidden_proto (__expl)
 libm_hidden_proto (__expm1l)
 # endif
 
diff --git a/sysdeps/i386/fpu/s_expm1.S b/sysdeps/i386/fpu/s_expm1.S
index e761183639..c690a458f8 100644
--- a/sysdeps/i386/fpu/s_expm1.S
+++ b/sysdeps/i386/fpu/s_expm1.S
@@ -22,6 +22,7 @@
 
 	/* Using: e^x - 1 = 2^(x * log2(e)) - 1 */
 
+#include <sysdep.h>
 #include <machine/asm.h>
 
 #ifdef __ELF__
@@ -48,6 +49,11 @@ l2e:	.tfloat 1.442695040888963407359924681002
 
 	.text
 ENTRY(__expm1)
+	movzwl	4+6(%esp), %eax
+	xorb	$0x80, %ah	// invert sign bit (now 1 is "positive")
+	cmpl	$0xc086, %eax	// is num >= 704?
+	jae	HIDDEN_JUMPTARGET (__exp)
+
 	fldl	4(%esp)		// x
 	fxam			// Is NaN or +-Inf?
 	fstsw	%ax
diff --git a/sysdeps/i386/fpu/s_expm1f.S b/sysdeps/i386/fpu/s_expm1f.S
index 88adb75b86..8645107274 100644
--- a/sysdeps/i386/fpu/s_expm1f.S
+++ b/sysdeps/i386/fpu/s_expm1f.S
@@ -22,6 +22,7 @@
 
 	/* Using: e^x - 1 = 2^(x * log2(e)) - 1 */
 
+#include <sysdep.h>
 #include <machine/asm.h>
 
 #ifdef __ELF__
@@ -48,6 +49,11 @@ l2e:	.tfloat 1.442695040888963407359924681002
 
 	.text
 ENTRY(__expm1f)
+	movzwl	4+2(%esp), %eax
+	xorb	$0x80, %ah	// invert sign bit (now 1 is "positive")
+	cmpl	$0xc2b1, %eax	// is num >= 88.5?
+	jae	HIDDEN_JUMPTARGET (__expf)
+
 	flds	4(%esp)		// x
 	fxam			// Is NaN or +-Inf?
 	fstsw	%ax
diff --git a/sysdeps/i386/fpu/s_expm1l.S b/sysdeps/i386/fpu/s_expm1l.S
index b69b22bc62..60b5b82e20 100644
--- a/sysdeps/i386/fpu/s_expm1l.S
+++ b/sysdeps/i386/fpu/s_expm1l.S
@@ -22,6 +22,7 @@
 
 	/* Using: e^x - 1 = 2^(x * log2(e)) - 1 */
 
+#include <sysdep.h>
 #include <machine/asm.h>
 
 #ifdef __ELF__
@@ -51,7 +52,7 @@ ENTRY(__expm1l)
 	movzwl	4+8(%esp), %eax	// load sign bit and 15-bit exponent
 	xorb	$0x80, %ah	// invert sign bit (now 1 is "positive")
 	cmpl	$0xc006, %eax	// is num positive and exp >= 6 (number is >= 128.0)?
-	jae     __ieee754_expl	// (if num is denormal, it is at least >= 64.0)
+	jae	HIDDEN_JUMPTARGET (__expl) // (if num is denormal, it is at least >= 64.0)
 
 	fldt	4(%esp)		// x
 	fxam			// Is NaN or +-Inf?
diff --git a/sysdeps/ieee754/dbl-64/w_exp.c b/sysdeps/ieee754/dbl-64/w_exp.c
index 445c5788d2..1216492090 100644
--- a/sysdeps/ieee754/dbl-64/w_exp.c
+++ b/sysdeps/ieee754/dbl-64/w_exp.c
@@ -51,6 +51,7 @@ u_threshold= -7.45133219101941108420e+02;  /* 0xc0874910, 0xD52D3051 */
 	return z;
 #endif
 }
+hidden_def (__exp)
 weak_alias (__exp, exp)
 #ifdef NO_LONG_DOUBLE
 strong_alias (__exp, __expl)
diff --git a/sysdeps/ieee754/flt-32/w_expf.c b/sysdeps/ieee754/flt-32/w_expf.c
index 4ba21c7c42..83b268f570 100644
--- a/sysdeps/ieee754/flt-32/w_expf.c
+++ b/sysdeps/ieee754/flt-32/w_expf.c
@@ -56,4 +56,5 @@ u_threshold= -1.0397208405e+02;  /* 0xc2cff1b5 */
 	return z;
 #endif
 }
+hidden_def (__expf)
 weak_alias (__expf, expf)
diff --git a/sysdeps/ieee754/ldbl-96/w_expl.c b/sysdeps/ieee754/ldbl-96/w_expl.c
index b8152cea65..53bb143734 100644
--- a/sysdeps/ieee754/ldbl-96/w_expl.c
+++ b/sysdeps/ieee754/ldbl-96/w_expl.c
@@ -57,4 +57,5 @@ u_threshold= -1.140019167866942050398521670162263001513e4;
 	return z;
 #endif
 }
+hidden_def (__expl)
 weak_alias (__expl, expl)