about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2014-12-22 18:45:50 +0000
committerJoseph Myers <joseph@codesourcery.com>2014-12-22 18:45:50 +0000
commitf56f91245a0a5aa0facaa14b5608cfb761df7c38 (patch)
tree22f4e47bc078aa8e74c5943bcb75422fed2518a4
parent9d1fc928a4c3ab15b46945b0abdf7054a75cc010 (diff)
downloadglibc-f56f91245a0a5aa0facaa14b5608cfb761df7c38.tar.gz
glibc-f56f91245a0a5aa0facaa14b5608cfb761df7c38.tar.xz
glibc-f56f91245a0a5aa0facaa14b5608cfb761df7c38.zip
Split __kernel_standard* functions (fixes bug 17724).
Bug 17724 reports references to fesetround being brought in by
ldbl-128ibm rintl via references to __rintl from __kernel_standard_l.
Because all three __kernel_standard* functions are in the same file,
this gets brought in even though only the long double version
__kernel_standard_l needs __rintl, and the C90 functions use only
__kernel_standard.

This patch fixes this by splitting the three versions into separate
files; it's fine for long double functions to refer to fe* functions
directly, unless they get called by C90 double functions.

Tested for x86_64 (testsuite; the reordering of code means disassembly
of shared libraries can't usefully be compared).  Tested for powerpc
that the relevant issue disappears from the linknamespace test
output.

	[BZ #17724]
	* sysdeps/ieee754/k_standard.c: Don't include <float.h>.
	(__kernel_standard_f): Remove.  Moved to k_standardf.c.
	(__kernel_standard_l): Remove.  Moved to k_standardl.c with
	(char *) casts added.
	* sysdeps/ieee754/k_standardf.c: New file.
	* sysdeps/ieee754/k_standardl.c: Likewise.
	* math/Makefile (libm-support): Remove k_standard.
	(libm-calls): Add k_standard.
-rw-r--r--ChangeLog12
-rw-r--r--NEWS2
-rw-r--r--math/Makefile4
-rw-r--r--sysdeps/ieee754/k_standard.c90
-rw-r--r--sysdeps/ieee754/k_standardf.c31
-rw-r--r--sysdeps/ieee754/k_standardl.c123
6 files changed, 169 insertions, 93 deletions
diff --git a/ChangeLog b/ChangeLog
index fb4b955058..481a2bd423 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2014-12-22  Joseph Myers  <joseph@codesourcery.com>
+
+	[BZ #17724]
+	* sysdeps/ieee754/k_standard.c: Don't include <float.h>.
+	(__kernel_standard_f): Remove.  Moved to k_standardf.c.
+	(__kernel_standard_l): Remove.  Moved to k_standardl.c with
+	(char *) casts added.
+	* sysdeps/ieee754/k_standardf.c: New file.
+	* sysdeps/ieee754/k_standardl.c: Likewise.
+	* math/Makefile (libm-support): Remove k_standard.
+	(libm-calls): Add k_standard.
+
 2014-12-22  Wilco Dijkstra  <wdijkstr@arm.com>
 
 	* sysdeps/aarch64/fpu/feenablxcpt.c (feenableexcept):
diff --git a/NEWS b/NEWS
index a40deb0341..f66d1ee933 100644
--- a/NEWS
+++ b/NEWS
@@ -15,7 +15,7 @@ Version 2.21
   17522, 17555, 17570, 17571, 17572, 17573, 17574, 17581, 17582, 17583,
   17584, 17585, 17589, 17594, 17601, 17608, 17616, 17625, 17630, 17633,
   17634, 17647, 17653, 17657, 17664, 17665, 17668, 17682, 17717, 17719,
-  17722, 17725, 17733.
+  17722, 17724, 17725, 17733.
 
 * CVE-2104-7817 The wordexp function could ignore the WRDE_NOCMD flag
   under certain input conditions resulting in the execution of a shell for
diff --git a/math/Makefile b/math/Makefile
index 866bc0fe6f..276a207156 100644
--- a/math/Makefile
+++ b/math/Makefile
@@ -36,7 +36,7 @@ aux		:= setfpucw fpu_control
 extra-libs	:= libm
 extra-libs-others = $(extra-libs)
 
-libm-support = k_standard s_lib_version s_matherr s_signgam		\
+libm-support = s_lib_version s_matherr s_signgam			\
 	       fclrexcpt fgetexcptflg fraiseexcpt fsetexcptflg		\
 	       ftestexcept fegetround fesetround fegetenv feholdexcpt	\
 	       fesetenv feupdateenv t_exp fedisblxcpt feenablxcpt	\
@@ -61,7 +61,7 @@ libm-calls = e_acos e_acosh e_asin e_atan2 e_atanh e_cosh e_exp e_fmod	\
 	     s_casinh s_cacosh s_catanh s_csqrt s_cpow s_cproj s_clog10 \
 	     s_fma s_lrint s_llrint s_lround s_llround e_exp10 w_log2	\
 	     s_isinf_ns s_issignaling $(calls:s_%=m_%) x2y2m1 k_casinh	\
-	     gamma_product
+	     gamma_product k_standard
 
 dbl-only-routines := branred doasin dosincos halfulp mpa mpatan2	\
 		     mpatan mpexp mplog mpsqrt mptan sincos32 slowexp	\
diff --git a/sysdeps/ieee754/k_standard.c b/sysdeps/ieee754/k_standard.c
index 5399c6682d..7b82cd1130 100644
--- a/sysdeps/ieee754/k_standard.c
+++ b/sysdeps/ieee754/k_standard.c
@@ -16,7 +16,6 @@ static char rcsid[] = "$NetBSD: k_standard.c,v 1.6 1995/05/10 20:46:35 jtc Exp $
 
 #include <math.h>
 #include <math_private.h>
-#include <float.h>
 #include <errno.h>
 
 #include <assert.h>
@@ -997,92 +996,3 @@ __kernel_standard(double x, double y, int type)
 	}
 	return exc.retval;
 }
-
-
-float
-__kernel_standard_f(float x, float y, int type)
-{
-	return __kernel_standard(x, y, type);
-}
-
-#ifndef __NO_LONG_DOUBLE_MATH
-long double
-__kernel_standard_l (long double x, long double y, int type)
-{
-  double dx, dy;
-  struct exception exc;
-
-  if (isfinite (x))
-    {
-      long double ax = fabsl (x);
-      if (ax > DBL_MAX)
-	dx = __copysignl (DBL_MAX, x);
-      else if (ax > 0 && ax < DBL_MIN)
-	dx = __copysignl (DBL_MIN, x);
-      else
-	dx = x;
-    }
-  else
-    dx = x;
-  if (isfinite (y))
-    {
-      long double ay = fabsl (y);
-      if (ay > DBL_MAX)
-	dy = __copysignl (DBL_MAX, y);
-      else if (ay > 0 && ay < DBL_MIN)
-	dy = __copysignl (DBL_MIN, y);
-      else
-	dy = y;
-    }
-  else
-    dy = y;
-
-  switch (type)
-    {
-    case 221:
-      /* powl (x, y) overflow.  */
-      exc.arg1 = dx;
-      exc.arg2 = dy;
-      exc.type = OVERFLOW;
-      exc.name = "powl";
-      if (_LIB_VERSION == _SVID_)
-	{
-	  exc.retval = HUGE;
-	  y *= 0.5;
-	  if (x < zero && __rintl (y) != y)
-	    exc.retval = -HUGE;
-	}
-      else
-	{
-	  exc.retval = HUGE_VAL;
-	  y *= 0.5;
-	  if (x < zero && __rintl (y) != y)
-	    exc.retval = -HUGE_VAL;
-	}
-      if (_LIB_VERSION == _POSIX_)
-	__set_errno (ERANGE);
-      else if (!matherr (&exc))
-	__set_errno (ERANGE);
-      return exc.retval;
-
-    case 222:
-      /* powl (x, y) underflow.  */
-      exc.arg1 = dx;
-      exc.arg2 = dy;
-      exc.type = UNDERFLOW;
-      exc.name = "powl";
-      exc.retval = zero;
-      y *= 0.5;
-      if (x < zero && __rintl (y) != y)
-	exc.retval = -zero;
-      if (_LIB_VERSION == _POSIX_)
-	__set_errno (ERANGE);
-      else if (!matherr (&exc))
-	__set_errno (ERANGE);
-      return exc.retval;
-
-    default:
-      return __kernel_standard (dx, dy, type);
-    }
-}
-#endif
diff --git a/sysdeps/ieee754/k_standardf.c b/sysdeps/ieee754/k_standardf.c
new file mode 100644
index 0000000000..b4aeadf72e
--- /dev/null
+++ b/sysdeps/ieee754/k_standardf.c
@@ -0,0 +1,31 @@
+/* Implement __kernel_standard_f.
+   Copyright (C) 2011-2014 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <math_private.h>
+
+
+/* Handle errors for a libm function as specified by TYPE (see
+   comments in k_standard.c for details), with arguments X and Y,
+   returning the appropriate return value for that function.  */
+
+float
+__kernel_standard_f (float x, float y, int type)
+{
+  return __kernel_standard (x, y, type);
+}
diff --git a/sysdeps/ieee754/k_standardl.c b/sysdeps/ieee754/k_standardl.c
new file mode 100644
index 0000000000..3c0a447f5b
--- /dev/null
+++ b/sysdeps/ieee754/k_standardl.c
@@ -0,0 +1,123 @@
+/* Implement __kernel_standard_l.
+   Copyright (C) 2012-2014 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.
+
+   Parts based on k_standard.c from fdlibm: */
+
+/* @(#)k_standard.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#include <math.h>
+#include <math_private.h>
+#include <float.h>
+#include <errno.h>
+
+
+static double zero = 0.0;
+
+/* Handle errors for a libm function as specified by TYPE (see
+   comments in k_standard.c for details), with arguments X and Y,
+   returning the appropriate return value for that function.  */
+
+long double
+__kernel_standard_l (long double x, long double y, int type)
+{
+  double dx, dy;
+  struct exception exc;
+
+  if (isfinite (x))
+    {
+      long double ax = fabsl (x);
+      if (ax > DBL_MAX)
+	dx = __copysignl (DBL_MAX, x);
+      else if (ax > 0 && ax < DBL_MIN)
+	dx = __copysignl (DBL_MIN, x);
+      else
+	dx = x;
+    }
+  else
+    dx = x;
+  if (isfinite (y))
+    {
+      long double ay = fabsl (y);
+      if (ay > DBL_MAX)
+	dy = __copysignl (DBL_MAX, y);
+      else if (ay > 0 && ay < DBL_MIN)
+	dy = __copysignl (DBL_MIN, y);
+      else
+	dy = y;
+    }
+  else
+    dy = y;
+
+  switch (type)
+    {
+    case 221:
+      /* powl (x, y) overflow.  */
+      exc.arg1 = dx;
+      exc.arg2 = dy;
+      exc.type = OVERFLOW;
+      exc.name = (char *) "powl";
+      if (_LIB_VERSION == _SVID_)
+	{
+	  exc.retval = HUGE;
+	  y *= 0.5;
+	  if (x < zero && __rintl (y) != y)
+	    exc.retval = -HUGE;
+	}
+      else
+	{
+	  exc.retval = HUGE_VAL;
+	  y *= 0.5;
+	  if (x < zero && __rintl (y) != y)
+	    exc.retval = -HUGE_VAL;
+	}
+      if (_LIB_VERSION == _POSIX_)
+	__set_errno (ERANGE);
+      else if (!matherr (&exc))
+	__set_errno (ERANGE);
+      return exc.retval;
+
+    case 222:
+      /* powl (x, y) underflow.  */
+      exc.arg1 = dx;
+      exc.arg2 = dy;
+      exc.type = UNDERFLOW;
+      exc.name = (char *) "powl";
+      exc.retval = zero;
+      y *= 0.5;
+      if (x < zero && __rintl (y) != y)
+	exc.retval = -zero;
+      if (_LIB_VERSION == _POSIX_)
+	__set_errno (ERANGE);
+      else if (!matherr (&exc))
+	__set_errno (ERANGE);
+      return exc.retval;
+
+    default:
+      return __kernel_standard (dx, dy, type);
+    }
+}