From aj@suse.de Fri Oct 1 04:33:00 2010 From: aj@suse.de (Andreas Jaeger) Date: Fri, 01 Oct 2010 04:33:00 -0000 Subject: Patch to handle cgroup and btrfs filesystems Message-ID: <201010010632.57347.aj@suse.de> Here's a patch to handle btrfs and cgroup on Linux, Andreas 2010-09-30 Andreas Jaeger * sysdeps/unix/sysv/linux_fsinfo.h (BTRFS_SUPER_MAGIC): Define. (CGROUP_SUPER_MAGIC): Define. * sysdeps/unix/sysv/linux/internal_statvfs.c (__statvfs_getflags): Handle btrfs and cgroup file systems. * sysdeps/unix/sysv/linux/pathconf.c (__statfs_filesize_max): Likewise. diff --git a/sysdeps/unix/sysv/linux/internal_statvfs.c b/sysdeps/unix/sysv/linux/internal_statvfs.c index 0169ae3..aefaf2a 100644 --- a/sysdeps/unix/sysv/linux/internal_statvfs.c +++ b/sysdeps/unix/sysv/linux/internal_statvfs.c @@ -109,6 +109,12 @@ __statvfs_getflags (const char *name, int fstype, struct stat64 *st) case LOGFS_MAGIC_U32: fsname = "logfs"; break; + case BTRFS_SUPER_MAGIC: + fsname = "btrfs"; + break; + case CGROUP_SUPER_MAGIC: + fsname = "cgroup"; + break; } FILE *mtab = __setmntent ("/proc/mounts", "r"); diff --git a/sysdeps/unix/sysv/linux/linux_fsinfo.h b/sysdeps/unix/sysv/linux/linux_fsinfo.h index b10e98b..8efbdea 100644 --- a/sysdeps/unix/sysv/linux/linux_fsinfo.h +++ b/sysdeps/unix/sysv/linux/linux_fsinfo.h @@ -23,7 +23,7 @@ /* These definitions come from the kernel headers. But we cannot include the headers here because of type clashes. If new filesystem types will become available we have to add the - appropriate definitions here.*/ + appropriate definitions here. */ /* Constant that identifies the `adfs' filesystem. */ #define ADFS_SUPER_MAGIC 0xadf5 @@ -37,6 +37,12 @@ /* Constant that identifies the `bfs' filesystem. */ #define BFS_MAGIC 0x1BADFACE +/* Constant that identifies the `btrfs' filesystem. */ +#define BTRFS_SUPER_MAGIC 0x1BADFACE + +/* Constant that identifies the `cgroup' filesystem. */ +#define CGROUP_SUPER_MAGIC 0x1BADFACE + /* Constant that identifies the `coda' filesystem. */ #define CODA_SUPER_MAGIC 0x73757245 diff --git a/sysdeps/unix/sysv/linux/pathconf.c b/sysdeps/unix/sysv/linux/pathconf.c index db03529..ae597fb 100644 --- a/sysdeps/unix/sysv/linux/pathconf.c +++ b/sysdeps/unix/sysv/linux/pathconf.c @@ -1,5 +1,5 @@ /* Get file-specific information about a file. Linux version. - Copyright (C) 1991,1995,1996,1998-2003,2008 Free Software Foundation, Inc. + Copyright (C) 1991,1995,1996,1998-2003,2008,2010 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 @@ -126,6 +126,9 @@ __statfs_filesize_max (int result, const struct statfs *fsbuf) switch (fsbuf->f_type) { + case BTRFS_SUPER_MAGIC: + return 255; + case EXT2_SUPER_MAGIC: case UFS_MAGIC: case UFS_CIGAM: @@ -136,6 +139,7 @@ __statfs_filesize_max (int result, const struct statfs *fsbuf) case UDF_SUPER_MAGIC: case JFS_SUPER_MAGIC: case VXFS_SUPER_MAGIC: + case CGROUP_SUPER_MAGIC: return 64; case MSDOS_SUPER_MAGIC: -- Andreas Jaeger, Program Manager openSUSE, aj@{novell.com,opensuse.org} Twitter: jaegerandi | Identica: jaegerandi SUSE LINUX Products GmbH, GF: Markus Rex, HRB 16746 (AG N?rnberg) Maxfeldstr. 5, 90409 N?rnberg, Germany GPG fingerprint = 93A3 365E CE47 B889 DF7F FED1 389A 563C C272 A126 -- Andreas Jaeger, Program Manager openSUSE, aj@{novell.com,opensuse.org} Twitter: jaegerandi | Identica: jaegerandi SUSE LINUX Products GmbH, GF: Markus Rex, HRB 16746 (AG N?rnberg) Maxfeldstr. 5, 90409 N?rnberg, Germany GPG fingerprint = 93A3 365E CE47 B889 DF7F FED1 389A 563C C272 A126 From schwab@redhat.com Fri Oct 1 12:57:00 2010 From: schwab@redhat.com (Andreas Schwab) Date: Fri, 01 Oct 2010 12:57:00 -0000 Subject: [PATCH] Don't discard result of decoding ACE if AI_CANONIDN Message-ID: 2010-10-01 Andreas Schwab * sysdeps/posix/getaddrinfo.c (gaih_inet): Don't discard result of decoding ACE if AI_CANONIDN. --- sysdeps/posix/getaddrinfo.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c index 126a09e..c61c72a 100644 --- a/sysdeps/posix/getaddrinfo.c +++ b/sysdeps/posix/getaddrinfo.c @@ -965,6 +965,7 @@ gaih_inet (const char *name, const struct gaih_service *service, make a copy. */ if (out == canon) goto make_copy; + canon = out; } else #endif -- 1.7.2.3 -- Andreas Schwab, schwab@redhat.com GPG Key fingerprint = D4E8 DBE3 3813 BB5D FA84 5EC7 45C6 250E 6F00 984E "And now for something completely different." From rth@twiddle.net Fri Oct 1 15:26:00 2010 From: rth@twiddle.net (Richard Henderson) Date: Fri, 01 Oct 2010 15:26:00 -0000 Subject: Patch to handle cgroup and btrfs filesystems In-Reply-To: <201010010632.57347.aj@suse.de> References: <201010010632.57347.aj@suse.de> Message-ID: <4CA5FDA4.2060705@twiddle.net> On 09/30/2010 09:32 PM, Andreas Jaeger wrote: > /* Constant that identifies the `bfs' filesystem. */ > #define BFS_MAGIC 0x1BADFACE > > +/* Constant that identifies the `btrfs' filesystem. */ > +#define BTRFS_SUPER_MAGIC 0x1BADFACE > + > +/* Constant that identifies the `cgroup' filesystem. */ > +#define CGROUP_SUPER_MAGIC 0x1BADFACE 3 identical magic's can't be put into the same switch statements. How did this compile for you? r~ From aj@suse.de Fri Oct 1 19:49:00 2010 From: aj@suse.de (Andreas Jaeger) Date: Fri, 01 Oct 2010 19:49:00 -0000 Subject: Patch to handle cgroup and btrfs filesystems In-Reply-To: <4CA5FDA4.2060705@twiddle.net> References: <201010010632.57347.aj@suse.de> <4CA5FDA4.2060705@twiddle.net> Message-ID: <201010012149.16162.aj@suse.de> On Friday 01 October 2010 17:26:28 Richard Henderson wrote: > On 09/30/2010 09:32 PM, Andreas Jaeger wrote: > > /* Constant that identifies the `bfs' filesystem. */ > > #define BFS_MAGIC 0x1BADFACE > > > > +/* Constant that identifies the `btrfs' filesystem. */ > > +#define BTRFS_SUPER_MAGIC 0x1BADFACE > > + > > +/* Constant that identifies the `cgroup' filesystem. */ > > +#define CGROUP_SUPER_MAGIC 0x1BADFACE > > 3 identical magic's can't be put into the same switch > statements. How did this compile for you? I tested the wrong tree, not sure how emacs tricked me, I copied the values ;-( thanks for noticing, here's the fix. This time tested with the right tree, Andreas 2010-10-01 Andreas Jaeger * sysdeps/unix/sysv/linux/linux_fsinfo.h (BTRFS_SUPER_MAGIC): Fix value. (CGROUP_SUPER_MAGIC): Likewise. diff --git a/sysdeps/unix/sysv/linux/linux_fsinfo.h b/sysdeps/unix/sysv/linux/linux_fsinfo.h index 8efbdea..b671d2c 100644 --- a/sysdeps/unix/sysv/linux/linux_fsinfo.h +++ b/sysdeps/unix/sysv/linux/linux_fsinfo.h @@ -38,10 +38,10 @@ #define BFS_MAGIC 0x1BADFACE /* Constant that identifies the `btrfs' filesystem. */ -#define BTRFS_SUPER_MAGIC 0x1BADFACE +#define BTRFS_SUPER_MAGIC 0x9123683E /* Constant that identifies the `cgroup' filesystem. */ -#define CGROUP_SUPER_MAGIC 0x1BADFACE +#define CGROUP_SUPER_MAGIC 0x27e0eb /* Constant that identifies the `coda' filesystem. */ #define CODA_SUPER_MAGIC 0x73757245 -- Andreas Jaeger, Program Manager openSUSE, aj@{novell.com,opensuse.org} Twitter: jaegerandi | Identica: jaegerandi SUSE LINUX Products GmbH, GF: Markus Rex, HRB 16746 (AG N?rnberg) Maxfeldstr. 5, 90409 N?rnberg, Germany GPG fingerprint = 93A3 365E CE47 B889 DF7F FED1 389A 563C C272 A126 From schwab@redhat.com Fri Oct 15 08:30:00 2010 From: schwab@redhat.com (Andreas Schwab) Date: Fri, 15 Oct 2010 08:30:00 -0000 Subject: [PATCH] Expect PLT call to _Unwind_Find_FDE on s390*-linux Message-ID: 2010-10-15 Andreas Schwab * scripts/data/localplt-s390-linux-gnu.data: New file. * scripts/data/localplt-s390x-linux-gnu.data: New file. --- scripts/data/localplt-s390-linux-gnu.data | 7 +++++++ scripts/data/localplt-s390x-linux-gnu.data | 7 +++++++ 2 files changed, 14 insertions(+), 0 deletions(-) create mode 100644 scripts/data/localplt-s390-linux-gnu.data create mode 100644 scripts/data/localplt-s390x-linux-gnu.data diff --git a/scripts/data/localplt-s390-linux-gnu.data b/scripts/data/localplt-s390-linux-gnu.data new file mode 100644 index 0000000..8fb56b6 --- /dev/null +++ b/scripts/data/localplt-s390-linux-gnu.data @@ -0,0 +1,7 @@ +libc.so: _Unwind_Find_FDE +libc.so: calloc +libc.so: free +libc.so: malloc +libc.so: memalign +libc.so: realloc +libm.so: matherr diff --git a/scripts/data/localplt-s390x-linux-gnu.data b/scripts/data/localplt-s390x-linux-gnu.data new file mode 100644 index 0000000..8fb56b6 --- /dev/null +++ b/scripts/data/localplt-s390x-linux-gnu.data @@ -0,0 +1,7 @@ +libc.so: _Unwind_Find_FDE +libc.so: calloc +libc.so: free +libc.so: malloc +libc.so: memalign +libc.so: realloc +libm.so: matherr -- 1.7.2.3 -- Andreas Schwab, schwab@redhat.com GPG Key fingerprint = D4E8 DBE3 3813 BB5D FA84 5EC7 45C6 250E 6F00 984E "And now for something completely different." From jakub@redhat.com Fri Oct 15 19:08:00 2010 From: jakub@redhat.com (Jakub Jelinek) Date: Fri, 15 Oct 2010 19:08:00 -0000 Subject: [PATCH] Implement fmal, some fma bugfixes Message-ID: <20101015190744.GA21391@sunsite.ms.mff.cuni.cz> Hi! This patch on top of http://sources.redhat.com/ml/libc-alpha/2010-10/msg00022.html implements extended long double and IEEE quad long double fmal and fixes some bugs in fma, in particular fma (DBL_MAX, DBL_MAX, -__builtin_inf ()) should be __builtin_inf () rather than NaN, as the computation is supposed to happen with infinite precision before rounding and thus x * y will be still finite, albeit very large. Also, unfortunately it seems two fetestexcept calls for adjust == -1 are unavoidable as shown by one of the added testcases - if result is slightly above DBL_MIN, we compute (a1 + u.d) * 0x1p106 in round to nearest, but if the inexact bit from first addition hasn't been ored into u.d, it is lost. Attached is also greatly improved mpfr testing proglet, now handles all of float (-DDO_FLT), double (-DDO_DBL) and long double (-DDO_LDBL, both extended and quad). Tested on x86_64-linux and i686-linux and slightly on s390x-linux, unfortunately I've discovered mpfr_set_ld is buggy there, so the tester is currently unusable there. 2010-10-15 Jakub Jelinek [BZ #3268] * math/libm-test.inc (fma_test): Some new testcases. * sysdeps/ieee754/ldbl-128/s_fmal.c: New file. * sysdeps/ieee754/ldbl-96/s_fma.c (__fma): Fix fma with finite x and y and infinite z. Do multiplication by C already in long double. * sysdeps/ieee754/ldbl-96/s_fmal.c: New file. * sysdeps/ieee754/dbl-64/s_fma.c (__fma): Fix fma with finite x and y and infinite z. Do bitwise or of inexact bit into u.d. * sysdeps/ieee754/ldbl-64-128/s_fmal.c: New file. * sysdeps/i386/fpu/s_fmaf.S: Removed. * sysdeps/i386/fpu/s_fma.S: Removed. * sysdeps/i386/fpu/s_fmal.S: Removed. --- libc/math/libm-test.inc.jj 2010-10-14 20:21:24.000000000 +0200 +++ libc/math/libm-test.inc 2010-10-15 17:51:16.000000000 +0200 @@ -2787,8 +2787,24 @@ fma_test (void) TEST_fff_f (fma, minus_infty, plus_infty, plus_infty, nan_value, INVALID_EXCEPTION); TEST_fff_f (fma, plus_infty, minus_infty, plus_infty, nan_value, INVALID_EXCEPTION); TEST_fff_f (fma, minus_infty, minus_infty, minus_infty, nan_value, INVALID_EXCEPTION); + TEST_fff_f (fma, plus_infty, 3.5L, minus_infty, nan_value, INVALID_EXCEPTION); + TEST_fff_f (fma, minus_infty, -7.5L, minus_infty, nan_value, INVALID_EXCEPTION); + TEST_fff_f (fma, -13.5L, plus_infty, plus_infty, nan_value, INVALID_EXCEPTION); + TEST_fff_f (fma, minus_infty, 7.5L, plus_infty, nan_value, INVALID_EXCEPTION); TEST_fff_f (fma, 1.25L, 0.75L, 0.0625L, 1.0L); + + FLOAT fltmax = CHOOSE (LDBL_MAX, DBL_MAX, FLT_MAX, + LDBL_MAX, DBL_MAX, FLT_MAX); + TEST_fff_f (fma, -fltmax, -fltmax, minus_infty, minus_infty); + TEST_fff_f (fma, fltmax / 2, fltmax / 2, minus_infty, minus_infty); + TEST_fff_f (fma, -fltmax, fltmax, plus_infty, plus_infty); + TEST_fff_f (fma, fltmax / 2, -fltmax / 4, plus_infty, plus_infty); + TEST_fff_f (fma, plus_infty, 4, plus_infty, plus_infty); + TEST_fff_f (fma, 2, minus_infty, minus_infty, minus_infty); + TEST_fff_f (fma, minus_infty, minus_infty, plus_infty, plus_infty); + TEST_fff_f (fma, plus_infty, minus_infty, minus_infty, minus_infty); + #if defined (TEST_FLOAT) && FLT_MANT_DIG == 24 TEST_fff_f (fma, 0x1.7ff8p+13, 0x1.000002p+0, 0x1.ffffp-24, 0x1.7ff802p+13); TEST_fff_f (fma, 0x1.fffp+0, 0x1.00001p+0, -0x1.fffp+0, 0x1.fffp-20); @@ -2818,6 +2834,15 @@ fma_test (void) TEST_fff_f (fma, -0x1.19cab66d73e17p-959, 0x1.c7108a8c5ff51p-107, -0x0.80b0ad65d9b64p-1022, -0x0.80b0ad65d9d59p-1022); TEST_fff_f (fma, -0x1.d2eaed6e8e9d3p-979, -0x1.4e066c62ac9ddp-63, -0x0.9245e6b003454p-1022, -0x0.9245c09c5fb5dp-1022); TEST_fff_f (fma, 0x1.153d650bb9f06p-907, 0x1.2d01230d48407p-125, -0x0.b278d5acfc3cp-1022, -0x0.b22757123bbe9p-1022); + TEST_fff_f (fma, -0x1.fffffffffffffp-711, 0x1.fffffffffffffp-275, 0x1.fffffe00007ffp-983, 0x1.7ffffe00007ffp-983); +#endif +#if defined (TEST_LDOUBLE) && LDBL_MANT_DIG == 64 + TEST_fff_f (fma, -0x8.03fcp+3696L, 0xf.fffffffffffffffp-6140L, 0x8.3ffffffffffffffp-2450L, -0x8.01ecp-2440L); + TEST_fff_f (fma, 0x9.fcp+2033L, -0x8.000e1f000ff800fp-3613L, -0xf.fffffffffffc0ffp-1579L, -0xd.fc119fb093ed092p-1577L); + TEST_fff_f (fma, 0xc.7fc000003ffffffp-1194L, 0x8.1e0003fffffffffp+15327L, -0x8.fffep+14072L, 0xc.ae9f164020effffp+14136L); + TEST_fff_f (fma, -0x8.0001fc000000003p+1798L, 0xcp-2230L, 0x8.f7e000000000007p-468L, -0xc.0002f9ffee10404p-429L); + TEST_fff_f (fma, 0xc.0000000000007ffp+10130L, -0x8.000000000000001p+4430L, 0xc.07000000001ffffp+14513L, -0xb.fffffffffffd7e4p+14563L); + TEST_fff_f (fma, 0xb.ffffp-4777L, 0x8.000000fffffffffp-11612L, -0x0.3800fff8p-16385L, 0x5.c7fe80c7ffeffffp-16385L); #endif END (fma); --- libc/sysdeps/ieee754/ldbl-128/s_fmal.c.jj 2010-10-15 18:03:31.000000000 +0200 +++ libc/sysdeps/ieee754/ldbl-128/s_fmal.c 2010-10-15 18:08:43.000000000 +0200 @@ -0,0 +1,221 @@ +/* Compute x * y + z as ternary operation. + Copyright (C) 2010 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek , 2010. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include +#include +#include + +/* This implementation uses rounding to odd to avoid problems with + double rounding. See a paper by Boldo and Melquiond: + http://www.lri.fr/~melquion/doc/08-tc.pdf */ + +long double +__fmal (long double x, long double y, long double z) +{ + union ieee854_long_double u, v, w; + int adjust = 0; + u.d = x; + v.d = y; + w.d = z; + if (__builtin_expect (u.ieee.exponent + v.ieee.exponent + >= 0x7fff + IEEE854_LONG_DOUBLE_BIAS + - LDBL_MANT_DIG, 0) + || __builtin_expect (u.ieee.exponent >= 0x7fff - LDBL_MANT_DIG, 0) + || __builtin_expect (v.ieee.exponent >= 0x7fff - LDBL_MANT_DIG, 0) + || __builtin_expect (w.ieee.exponent >= 0x7fff - LDBL_MANT_DIG, 0) + || __builtin_expect (u.ieee.exponent + v.ieee.exponent + <= IEEE854_LONG_DOUBLE_BIAS + LDBL_MANT_DIG, 0)) + { + /* If z is Inf, but x and y are finite, the result should be + z rather than NaN. */ + if (w.ieee.exponent == 0x7fff + && u.ieee.exponent != 0x7fff + && v.ieee.exponent != 0x7fff) + return (z + x) + y; + /* If x or y or z is Inf/NaN, or if fma will certainly overflow, + or if x * y is less than half of LDBL_DENORM_MIN, + compute as x * y + z. */ + if (u.ieee.exponent == 0x7fff + || v.ieee.exponent == 0x7fff + || w.ieee.exponent == 0x7fff + || u.ieee.exponent + v.ieee.exponent + > 0x7fff + IEEE854_LONG_DOUBLE_BIAS + || u.ieee.exponent + v.ieee.exponent + < IEEE854_LONG_DOUBLE_BIAS - LDBL_MANT_DIG - 2) + return x * y + z; + if (u.ieee.exponent + v.ieee.exponent + >= 0x7fff + IEEE854_LONG_DOUBLE_BIAS - LDBL_MANT_DIG) + { + /* Compute 1p-113 times smaller result and multiply + at the end. */ + if (u.ieee.exponent > v.ieee.exponent) + u.ieee.exponent -= LDBL_MANT_DIG; + else + v.ieee.exponent -= LDBL_MANT_DIG; + /* If x + y exponent is very large and z exponent is very small, + it doesn't matter if we don't adjust it. */ + if (w.ieee.exponent > LDBL_MANT_DIG) + w.ieee.exponent -= LDBL_MANT_DIG; + adjust = 1; + } + else if (w.ieee.exponent >= 0x7fff - LDBL_MANT_DIG) + { + /* Similarly. + If z exponent is very large and x and y exponents are + very small, it doesn't matter if we don't adjust it. */ + if (u.ieee.exponent > v.ieee.exponent) + { + if (u.ieee.exponent > LDBL_MANT_DIG) + u.ieee.exponent -= LDBL_MANT_DIG; + } + else if (v.ieee.exponent > LDBL_MANT_DIG) + v.ieee.exponent -= LDBL_MANT_DIG; + w.ieee.exponent -= LDBL_MANT_DIG; + adjust = 1; + } + else if (u.ieee.exponent >= 0x7fff - LDBL_MANT_DIG) + { + u.ieee.exponent -= LDBL_MANT_DIG; + if (v.ieee.exponent) + v.ieee.exponent += LDBL_MANT_DIG; + else + v.d *= 0x1p113L; + } + else if (v.ieee.exponent >= 0x7fff - LDBL_MANT_DIG) + { + v.ieee.exponent -= LDBL_MANT_DIG; + if (u.ieee.exponent) + u.ieee.exponent += LDBL_MANT_DIG; + else + u.d *= 0x1p113L; + } + else /* if (u.ieee.exponent + v.ieee.exponent + <= IEEE854_LONG_DOUBLE_BIAS + LDBL_MANT_DIG) */ + { + if (u.ieee.exponent > v.ieee.exponent) + u.ieee.exponent += 2 * LDBL_MANT_DIG; + else + v.ieee.exponent += 2 * LDBL_MANT_DIG; + if (w.ieee.exponent <= 4 * LDBL_MANT_DIG + 4) + { + if (w.ieee.exponent) + w.ieee.exponent += 2 * LDBL_MANT_DIG; + else + w.d *= 0x1p226L; + adjust = -1; + } + /* Otherwise x * y should just affect inexact + and nothing else. */ + } + x = u.d; + y = v.d; + z = w.d; + } + /* Multiplication m1 + m2 = x * y using Dekker's algorithm. */ +#define C ((1LL << (LDBL_MANT_DIG + 1) / 2) + 1) + long double x1 = x * C; + long double y1 = y * C; + long double m1 = x * y; + x1 = (x - x1) + x1; + y1 = (y - y1) + y1; + long double x2 = x - x1; + long double y2 = y - y1; + long double m2 = (((x1 * y1 - m1) + x1 * y2) + x2 * y1) + x2 * y2; + + /* Addition a1 + a2 = z + m1 using Knuth's algorithm. */ + long double a1 = z + m1; + long double t1 = a1 - z; + long double t2 = a1 - t1; + t1 = m1 - t1; + t2 = z - t2; + long double a2 = t1 + t2; + + fenv_t env; + feholdexcept (&env); + fesetround (FE_TOWARDZERO); + /* Perform m2 + a2 addition with round to odd. */ + u.d = a2 + m2; + + if (__builtin_expect (adjust == 0, 1)) + { + if ((u.ieee.mantissa3 & 1) == 0 && u.ieee.exponent != 0x7fff) + u.ieee.mantissa3 |= fetestexcept (FE_INEXACT) != 0; + feupdateenv (&env); + /* Result is a1 + u.d. */ + return a1 + u.d; + } + else if (__builtin_expect (adjust > 0, 1)) + { + if ((u.ieee.mantissa3 & 1) == 0 && u.ieee.exponent != 0x7fff) + u.ieee.mantissa3 |= fetestexcept (FE_INEXACT) != 0; + feupdateenv (&env); + /* Result is a1 + u.d, scaled up. */ + return (a1 + u.d) * 0x1p113L; + } + else + { + if ((u.ieee.mantissa3 & 1) == 0) + u.ieee.mantissa3 |= fetestexcept (FE_INEXACT) != 0; + v.d = a1 + u.d; + int j = fetestexcept (FE_INEXACT) != 0; + feupdateenv (&env); + /* Ensure the following computations are performed in default rounding + mode instead of just reusing the round to zero computation. */ + asm volatile ("" : "=m" (u) : "m" (u)); + /* If a1 + u.d is exact, the only rounding happens during + scaling down. */ + if (j == 0) + return v.d * 0x1p-226L; + /* If result rounded to zero is not subnormal, no double + rounding will occur. */ + if (v.ieee.exponent > 226) + return (a1 + u.d) * 0x1p-226L; + /* If v.d * 0x1p-226L with round to zero is a subnormal above + or equal to LDBL_MIN / 2, then v.d * 0x1p-226L shifts mantissa + down just by 1 bit, which means v.ieee.mantissa3 |= j would + change the round bit, not sticky or guard bit. + v.d * 0x1p-226L never normalizes by shifting up, + so round bit plus sticky bit should be already enough + for proper rounding. */ + if (v.ieee.exponent == 226) + { + /* v.ieee.mantissa3 & 2 is LSB bit of the result before rounding, + v.ieee.mantissa3 & 1 is the round bit and j is our sticky + bit. In round-to-nearest 001 rounds down like 00, + 011 rounds up, even though 01 rounds down (thus we need + to adjust), 101 rounds down like 10 and 111 rounds up + like 11. */ + if ((v.ieee.mantissa3 & 3) == 1) + { + v.d *= 0x1p-226L; + if (v.ieee.negative) + return v.d - 0x1p-16493L /* __LDBL_DENORM_MIN__ */; + else + return v.d + 0x1p-16493L /* __LDBL_DENORM_MIN__ */; + } + else + return v.d * 0x1p-226L; + } + v.ieee.mantissa3 |= j; + return v.d * 0x1p-226L; + } +} +weak_alias (__fmal, fmal) --- libc/sysdeps/ieee754/ldbl-96/s_fma.c.jj 2010-10-14 09:08:58.000000000 +0200 +++ libc/sysdeps/ieee754/ldbl-96/s_fma.c 2010-10-15 13:41:15.000000000 +0200 @@ -30,11 +30,20 @@ double __fma (double x, double y, double z) { + if (__builtin_expect (isinf (z), 0)) + { + /* If z is Inf, but x and y are finite, the result should be + z rather than NaN. */ + if (finite (x) && finite (y)) + return (z + x) + y; + return (x * y) + z; + } + /* Multiplication m1 + m2 = x * y using Dekker's algorithm. */ #define C ((1ULL << (LDBL_MANT_DIG + 1) / 2) + 1) - long double x1 = x * C; - long double y1 = y * C; - long double m1 = x * y; + long double x1 = (long double) x * C; + long double y1 = (long double) y * C; + long double m1 = (long double) x * y; x1 = (x - x1) + x1; y1 = (y - y1) + y1; long double x2 = x - x1; --- libc/sysdeps/ieee754/ldbl-96/s_fmal.c.jj 2010-10-14 22:39:23.000000000 +0200 +++ libc/sysdeps/ieee754/ldbl-96/s_fmal.c 2010-10-15 17:51:46.000000000 +0200 @@ -0,0 +1,221 @@ +/* Compute x * y + z as ternary operation. + Copyright (C) 2010 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek , 2010. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include +#include +#include + +/* This implementation uses rounding to odd to avoid problems with + double rounding. See a paper by Boldo and Melquiond: + http://www.lri.fr/~melquion/doc/08-tc.pdf */ + +long double +__fmal (long double x, long double y, long double z) +{ + union ieee854_long_double u, v, w; + int adjust = 0; + u.d = x; + v.d = y; + w.d = z; + if (__builtin_expect (u.ieee.exponent + v.ieee.exponent + >= 0x7fff + IEEE854_LONG_DOUBLE_BIAS + - LDBL_MANT_DIG, 0) + || __builtin_expect (u.ieee.exponent >= 0x7fff - LDBL_MANT_DIG, 0) + || __builtin_expect (v.ieee.exponent >= 0x7fff - LDBL_MANT_DIG, 0) + || __builtin_expect (w.ieee.exponent >= 0x7fff - LDBL_MANT_DIG, 0) + || __builtin_expect (u.ieee.exponent + v.ieee.exponent + <= IEEE854_LONG_DOUBLE_BIAS + LDBL_MANT_DIG, 0)) + { + /* If z is Inf, but x and y are finite, the result should be + z rather than NaN. */ + if (w.ieee.exponent == 0x7fff + && u.ieee.exponent != 0x7fff + && v.ieee.exponent != 0x7fff) + return (z + x) + y; + /* If x or y or z is Inf/NaN, or if fma will certainly overflow, + or if x * y is less than half of LDBL_DENORM_MIN, + compute as x * y + z. */ + if (u.ieee.exponent == 0x7fff + || v.ieee.exponent == 0x7fff + || w.ieee.exponent == 0x7fff + || u.ieee.exponent + v.ieee.exponent + > 0x7fff + IEEE854_LONG_DOUBLE_BIAS + || u.ieee.exponent + v.ieee.exponent + < IEEE854_LONG_DOUBLE_BIAS - LDBL_MANT_DIG - 2) + return x * y + z; + if (u.ieee.exponent + v.ieee.exponent + >= 0x7fff + IEEE854_LONG_DOUBLE_BIAS - LDBL_MANT_DIG) + { + /* Compute 1p-64 times smaller result and multiply + at the end. */ + if (u.ieee.exponent > v.ieee.exponent) + u.ieee.exponent -= LDBL_MANT_DIG; + else + v.ieee.exponent -= LDBL_MANT_DIG; + /* If x + y exponent is very large and z exponent is very small, + it doesn't matter if we don't adjust it. */ + if (w.ieee.exponent > LDBL_MANT_DIG) + w.ieee.exponent -= LDBL_MANT_DIG; + adjust = 1; + } + else if (w.ieee.exponent >= 0x7fff - LDBL_MANT_DIG) + { + /* Similarly. + If z exponent is very large and x and y exponents are + very small, it doesn't matter if we don't adjust it. */ + if (u.ieee.exponent > v.ieee.exponent) + { + if (u.ieee.exponent > LDBL_MANT_DIG) + u.ieee.exponent -= LDBL_MANT_DIG; + } + else if (v.ieee.exponent > LDBL_MANT_DIG) + v.ieee.exponent -= LDBL_MANT_DIG; + w.ieee.exponent -= LDBL_MANT_DIG; + adjust = 1; + } + else if (u.ieee.exponent >= 0x7fff - LDBL_MANT_DIG) + { + u.ieee.exponent -= LDBL_MANT_DIG; + if (v.ieee.exponent) + v.ieee.exponent += LDBL_MANT_DIG; + else + v.d *= 0x1p64L; + } + else if (v.ieee.exponent >= 0x7fff - LDBL_MANT_DIG) + { + v.ieee.exponent -= LDBL_MANT_DIG; + if (u.ieee.exponent) + u.ieee.exponent += LDBL_MANT_DIG; + else + u.d *= 0x1p64L; + } + else /* if (u.ieee.exponent + v.ieee.exponent + <= IEEE854_LONG_DOUBLE_BIAS + LDBL_MANT_DIG) */ + { + if (u.ieee.exponent > v.ieee.exponent) + u.ieee.exponent += 2 * LDBL_MANT_DIG; + else + v.ieee.exponent += 2 * LDBL_MANT_DIG; + if (w.ieee.exponent <= 4 * LDBL_MANT_DIG + 4) + { + if (w.ieee.exponent) + w.ieee.exponent += 2 * LDBL_MANT_DIG; + else + w.d *= 0x1p128L; + adjust = -1; + } + /* Otherwise x * y should just affect inexact + and nothing else. */ + } + x = u.d; + y = v.d; + z = w.d; + } + /* Multiplication m1 + m2 = x * y using Dekker's algorithm. */ +#define C ((1LL << (LDBL_MANT_DIG + 1) / 2) + 1) + long double x1 = x * C; + long double y1 = y * C; + long double m1 = x * y; + x1 = (x - x1) + x1; + y1 = (y - y1) + y1; + long double x2 = x - x1; + long double y2 = y - y1; + long double m2 = (((x1 * y1 - m1) + x1 * y2) + x2 * y1) + x2 * y2; + + /* Addition a1 + a2 = z + m1 using Knuth's algorithm. */ + long double a1 = z + m1; + long double t1 = a1 - z; + long double t2 = a1 - t1; + t1 = m1 - t1; + t2 = z - t2; + long double a2 = t1 + t2; + + fenv_t env; + feholdexcept (&env); + fesetround (FE_TOWARDZERO); + /* Perform m2 + a2 addition with round to odd. */ + u.d = a2 + m2; + + if (__builtin_expect (adjust == 0, 1)) + { + if ((u.ieee.mantissa1 & 1) == 0 && u.ieee.exponent != 0x7fff) + u.ieee.mantissa1 |= fetestexcept (FE_INEXACT) != 0; + feupdateenv (&env); + /* Result is a1 + u.d. */ + return a1 + u.d; + } + else if (__builtin_expect (adjust > 0, 1)) + { + if ((u.ieee.mantissa1 & 1) == 0 && u.ieee.exponent != 0x7fff) + u.ieee.mantissa1 |= fetestexcept (FE_INEXACT) != 0; + feupdateenv (&env); + /* Result is a1 + u.d, scaled up. */ + return (a1 + u.d) * 0x1p64L; + } + else + { + if ((u.ieee.mantissa1 & 1) == 0) + u.ieee.mantissa1 |= fetestexcept (FE_INEXACT) != 0; + v.d = a1 + u.d; + int j = fetestexcept (FE_INEXACT) != 0; + feupdateenv (&env); + /* Ensure the following computations are performed in default rounding + mode instead of just reusing the round to zero computation. */ + asm volatile ("" : "=m" (u) : "m" (u)); + /* If a1 + u.d is exact, the only rounding happens during + scaling down. */ + if (j == 0) + return v.d * 0x1p-128L; + /* If result rounded to zero is not subnormal, no double + rounding will occur. */ + if (v.ieee.exponent > 128) + return (a1 + u.d) * 0x1p-128L; + /* If v.d * 0x1p-128L with round to zero is a subnormal above + or equal to LDBL_MIN / 2, then v.d * 0x1p-128L shifts mantissa + down just by 1 bit, which means v.ieee.mantissa1 |= j would + change the round bit, not sticky or guard bit. + v.d * 0x1p-128L never normalizes by shifting up, + so round bit plus sticky bit should be already enough + for proper rounding. */ + if (v.ieee.exponent == 128) + { + /* v.ieee.mantissa1 & 2 is LSB bit of the result before rounding, + v.ieee.mantissa1 & 1 is the round bit and j is our sticky + bit. In round-to-nearest 001 rounds down like 00, + 011 rounds up, even though 01 rounds down (thus we need + to adjust), 101 rounds down like 10 and 111 rounds up + like 11. */ + if ((v.ieee.mantissa1 & 3) == 1) + { + v.d *= 0x1p-128L; + if (v.ieee.negative) + return v.d - 0x1p-16445L /* __LDBL_DENORM_MIN__ */; + else + return v.d + 0x1p-16445L /* __LDBL_DENORM_MIN__ */; + } + else + return v.d * 0x1p-128L; + } + v.ieee.mantissa1 |= j; + return v.d * 0x1p-128L; + } +} +weak_alias (__fmal, fmal) --- libc/sysdeps/ieee754/dbl-64/s_fma.c.jj 2010-10-14 20:26:05.000000000 +0200 +++ libc/sysdeps/ieee754/dbl-64/s_fma.c 2010-10-15 17:56:30.000000000 +0200 @@ -43,6 +43,12 @@ __fma (double x, double y, double z) || __builtin_expect (u.ieee.exponent + v.ieee.exponent <= IEEE754_DOUBLE_BIAS + DBL_MANT_DIG, 0)) { + /* If z is Inf, but x and y are finite, the result should be + z rather than NaN. */ + if (w.ieee.exponent == 0x7ff + && u.ieee.exponent != 0x7ff + && v.ieee.exponent != 0x7ff) + return (z + x) + y; /* If x or y or z is Inf/NaN, or if fma will certainly overflow, or if x * y is less than half of DBL_DENORM_MIN, compute as x * y + z. */ @@ -165,6 +171,8 @@ __fma (double x, double y, double z) } else { + if ((u.ieee.mantissa1 & 1) == 0) + u.ieee.mantissa1 |= fetestexcept (FE_INEXACT) != 0; v.d = a1 + u.d; int j = fetestexcept (FE_INEXACT) != 0; feupdateenv (&env); --- libc/sysdeps/ieee754/ldbl-64-128/s_fmal.c.jj 2010-10-15 18:05:04.000000000 +0200 +++ libc/sysdeps/ieee754/ldbl-64-128/s_fmal.c 2010-10-15 18:05:17.000000000 +0200 @@ -0,0 +1,5 @@ +#include +#undef weak_alias +#define weak_alias(n,a) +#include +long_double_symbol (libm, __fmal, fmal); --- libc/sysdeps/i386/fpu/s_fmaf.S.jj 2009-05-16 19:23:38.000000000 +0200 +++ libc/sysdeps/i386/fpu/s_fmaf.S 2010-09-14 11:29:01.831482015 +0200 @@ -1,31 +0,0 @@ -/* Compute (X * Y) + Z as ternary operation. - Copyright (C) 1997 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper , 1997. - - 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, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include - - .text -ENTRY(__fmaf) - flds 4(%esp) // x - fmuls 8(%esp) // x * y - flds 12(%esp) // z : x * y - faddp // (x * y) + z - ret -END(__fmaf) -weak_alias (__fmaf, fmaf) --- libc/sysdeps/i386/fpu/s_fma.S.jj 2009-05-16 19:23:38.000000000 +0200 +++ libc/sysdeps/i386/fpu/s_fma.S 2010-09-14 11:29:01.831482015 +0200 @@ -1,31 +0,0 @@ -/* Compute (X * Y) + Z as ternary operation. - Copyright (C) 1997, 1998 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper , 1997. - - 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, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include - - .text -ENTRY(__fma) - fldl 4(%esp) // x - fmull 12(%esp) // x * y - fldl 20(%esp) // z : x * y - faddp // (x * y) + z - ret -END(__fma) -weak_alias (__fma, fma) --- libc/sysdeps/i386/fpu/s_fmal.S.jj 2009-05-16 19:23:38.000000000 +0200 +++ libc/sysdeps/i386/fpu/s_fmal.S 2010-09-14 11:29:01.831482015 +0200 @@ -1,32 +0,0 @@ -/* Compute (X * Y) + Z as ternary operation. - Copyright (C) 1997 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper , 1997. - - 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, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include - - .text -ENTRY(__fmal) - fldt 4(%esp) // x - fldt 16(%esp) // x : y - fmulp // x * y - fldt 28(%esp) // z : x * y - faddp // (x * y) + z - ret -END(__fmal) -weak_alias (__fmal, fmal) Jakub -------------- next part -------------- #define _GNU_SOURCE #include #include #include #include #include #ifdef DO_FLT #define MANT_DIG __FLT_MANT_DIG__ #define MAX_EXP __FLT_MAX_EXP__ #define union_type union ieee754_float #define suff(x) x##d #define fma_suff fmaf #define BIAS 0x7f #define FMT "%a" #define fltfield f #elif defined DO_DBL #define MANT_DIG __DBL_MANT_DIG__ #define MAX_EXP __DBL_MAX_EXP__ #define union_type union ieee754_double #define suff(x) x##d #define fma_suff fma #define BIAS 0x3ff #define FMT "%a" #define fltfield d #elif defined DO_LDBL #define MANT_DIG __LDBL_MANT_DIG__ #define MAX_EXP __LDBL_MAX_EXP__ #define union_type union ieee854_long_double #define suff(x) x##ld #define fma_suff fmal #define BIAS 0x3fff #if MANT_DIG == 64 #define FMT "%La" #else #define FMT "%.40La" #endif #define fltfield d #else #error Define DO_FLT, DO_DBL or DO_LDBL #endif unsigned int randbits (int count) { static unsigned int val, bits; unsigned int ret = 0; if (count > bits) { if (count == 32 && bits == 0) { ret = ((unsigned int) random ()) << 1; count -= 31; } else { ret = val << (count - bits); count -= bits; } val = (random () & 0x7fffffffU); bits = 31; } ret |= val & ((1U << count) - 1); val >>= count; bits -= count; return ret; } void randflt (int mode, union_type *p, unsigned int exp) { if (mode == 1 || (mode >= 2 && randbits (4) == 0)) { unsigned int mantissa[4] = { 0, 0, 0, 0 }; unsigned int bits = 0, cur = randbits (1); do { unsigned int curbits = randbits (8) % (MANT_DIG - bits + 6); if (curbits > MANT_DIG - bits) curbits = MANT_DIG - bits; if (cur && curbits) { do { unsigned int thisbits = 32 - (bits & 31); if (curbits < thisbits) thisbits = curbits; mantissa[bits / 32] |= (~0U << (32 - thisbits)) >> (32 - thisbits - (bits & 31)); bits += thisbits; curbits -= thisbits; } while (curbits); } else bits += curbits; cur ^= 1; } while (bits < MANT_DIG); #ifdef DO_FLT p->ieee.mantissa = mantissa[0]; #elif defined DO_DBL p->ieee.mantissa1 = mantissa[0]; p->ieee.mantissa0 = mantissa[1]; #elif defined DO_LDBL #if MANT_DIG == 64 p->ieee.mantissa1 = mantissa[0]; p->ieee.mantissa0 = mantissa[1] & 0x7fffffffU; #elif MANT_DIG == 113 p->ieee.mantissa3 = mantissa[0]; p->ieee.mantissa2 = mantissa[1]; p->ieee.mantissa1 = mantissa[2]; p->ieee.mantissa0 = mantissa[3]; #endif #endif } else { #ifdef DO_FLT p->ieee.mantissa = randbits (23); #elif defined DO_DBL p->ieee.mantissa1 = randbits (32); p->ieee.mantissa0 = randbits (20); #elif defined DO_LDBL #if MANT_DIG == 64 p->ieee.mantissa1 = randbits (32); p->ieee.mantissa0 = randbits (31); #elif MANT_DIG == 113 p->ieee.mantissa3 = randbits (32); p->ieee.mantissa2 = randbits (32); p->ieee.mantissa1 = randbits (32); p->ieee.mantissa0 = randbits (16); #endif #endif } p->ieee.negative = randbits (1); p->ieee.exponent = exp; #if defined (DO_LDBL) && MANT_DIG == 64 p->ieee.empty = 0; if (exp != 0) p->ieee.mantissa0 |= 0x80000000; #endif } int main (int argc, const char **argv) { long int i, count = 100; if (argc >= 2) count = strtoul (argv[1], NULL, 0); mpfr_set_default_prec (MANT_DIG); mpfr_set_emin (-MAX_EXP-MANT_DIG+4); mpfr_set_emax (MAX_EXP); for (i = 0; i < count; i++) { union_type u, v, w, x, y; int mode = randbits (2); randflt (mode, &u, randbits (15)); randflt (mode, &v, randbits (15)); if (randbits (4)) randflt (mode, &w, ((int) u.ieee.exponent + (int) v.ieee.exponent) - BIAS - MANT_DIG + randbits (18) % (2 * MANT_DIG)); else randflt (mode, &w, randbits (15)); mpfr_t xx, xy, xz; suff (mpfr_init_set_) (xx, u.fltfield, GMP_RNDN); suff (mpfr_init_set_) (xy, v.fltfield, GMP_RNDN); suff (mpfr_init_set_) (xz, w.fltfield, GMP_RNDN); int i = mpfr_fma (xx, xx, xy, xz, GMP_RNDN); mpfr_subnormalize (xx, i, GMP_RNDN); x.fltfield = suff (mpfr_get_) (xx, GMP_RNDN); mpfr_clear (xx); mpfr_clear (xy); mpfr_clear (xz); y.fltfield = fma_suff (u.fltfield, v.fltfield, w.fltfield); if (x.fltfield != y.fltfield && !(isnan (x.fltfield) && isnan (y.fltfield))) printf ("fma ("FMT", "FMT", "FMT") = "FMT" mpfr_fma "FMT"\n", u.fltfield, v.fltfield, w.fltfield, y.fltfield, x.fltfield); } return 0; } From jakub@redhat.com Mon Oct 18 10:17:00 2010 From: jakub@redhat.com (Jakub Jelinek) Date: Mon, 18 Oct 2010 10:17:00 -0000 Subject: [PATCH] IEEE quad fmal fixes Message-ID: <20101018101703.GB21391@sunsite.ms.mff.cuni.cz> Hi! I've used wrong value for denorm minimum and gcc on s390x scheduled the TFmode addition after the fetestexcept call. This patch fixes it both and adds some tests, with this (and fixed mpfr_set_ld) the tester passed 10billion tests even on s390x. OT, there 28 failures out of 10billion tests in x86_64 fmal testing, but at least the first one turned out to be a mpfr_sub1 bug: https://gforge.inria.fr/tracker/index.php?func=detail&aid=11301&group_id=136&atid=619 so I'm waiting for that bug to be fixed now. If all those 28 failures are the same bug, then glibc fma{f,,l} should be fine now. 2010-10-16 Jakub Jelinek [BZ #3268] * math/libm-test.inc (fma_test): Add IEEE quad long double fmal tests. * sysdeps/ieee754/ldbl-128/s_fmal.c (__fmal): Ensure a1 + u.d computation is not scheduled after fetestexcept. Fix value of minimum denormal long double. --- libc/math/libm-test.inc.jj 2010-10-15 17:51:16.000000000 +0200 +++ libc/math/libm-test.inc 2010-10-16 17:35:05.000000000 +0200 @@ -2844,6 +2844,21 @@ fma_test (void) TEST_fff_f (fma, 0xc.0000000000007ffp+10130L, -0x8.000000000000001p+4430L, 0xc.07000000001ffffp+14513L, -0xb.fffffffffffd7e4p+14563L); TEST_fff_f (fma, 0xb.ffffp-4777L, 0x8.000000fffffffffp-11612L, -0x0.3800fff8p-16385L, 0x5.c7fe80c7ffeffffp-16385L); #endif +#if defined (TEST_LDOUBLE) && LDBL_MANT_DIG == 113 + TEST_fff_f (fma, 0x1.bb2de33e02ccbbfa6e245a7c1f71p-2584L, -0x1.6b500daf0580d987f1bc0cadfcddp-13777L, 0x1.613cd91d9fed34b33820e5ab9d8dp-16378L, -0x1.3a79fb50eb9ce887cffa0f09bd9fp-16360L); + TEST_fff_f (fma, -0x1.f949b880cacb0f0c61540105321dp-5954L, -0x1.3876cec84b4140f3bd6198731b7ep-10525L, -0x0.a5dc1c6cfbc498c54fb0b504bf19p-16382L, -0x0.a5dc1c6cfbc498c54fb0b5038abbp-16382L); + TEST_fff_f (fma, -0x1.0000fffffffffp-16221L, 0x1.0000001fffff8007fep-239L, 0x0.ff87ffffffffffffe000003fffffp-16382L, 0x0.ff87ffffffffffffdffc003bff7fp-16382L); + TEST_fff_f (fma, -0x1.ac79c9376ef447f3827c9e9de008p-2228L, -0x1.5ba830022b6139e21fbe7270cad8p-6314L, 0x1.e8282b6a26bb6a9daf5c8e73e9f9p-8616L, 0x1.22f14a0253878a730cd1aee373adp-8541L); + TEST_fff_f (fma, -0x1.c69749ec574caaa2ab8e97ddb9f3p+2652L, 0x1.f34235ff9d095449c29b4831b62dp+3311L, 0x1.fbe4302df23354dbd0c4d3cfe606p+5879L, -0x1.bb473bfdfb7a6e18886ce6e57eafp+5964L); + TEST_fff_f (fma, -0x1.ca8835fc6ecfb5398625fc891be5p-1686L, 0x1.621e1972bbe2180e5be9dd7d8df5p-7671L, -0x1.7d2d21b73b52cf20dec2a83902a4p-9395L, -0x1.3d2322191c9c88bc68a62ab8042cp-9356L); + TEST_fff_f (fma, -0x1.55cff679ec49c2541fab41fc843ep-11819L, 0x1.e60e9f464f9e8df0509647c7c971p+12325L, 0x1.eaa2a7649d765c2f564f7a5beca7p+454L, -0x1.447e29fa7e406a285f4e350fcf86p+507L); + TEST_fff_f (fma, 0x1.f0e7b1454908576f2537d863cf9bp+11432L, 0x1.cdce52f09d4ca76e68706f34b5d5p-1417L, -0x1.2e986187c70f146235ea2066e486p+9979L, 0x1.c030dad3cc5643f3dd0f5619f661p+10016L); + TEST_fff_f (fma, 0x1.f102f7da4a57a3a4aab620e29452p-3098L, -0x1.cc06a4ff40248f9e2dcc4b6afd84p-11727L, 0x1.d512a11126b5ac8ed8973b8580c8p-14849L, -0x1.be8f1cf737ab4d1c31c54f5ec23bp-14824L); + TEST_fff_f (fma, -0x1.fc47ac7434b993cd8dcb2b431f25p-3816L, 0x1.fbc9750da8468852d84558e1db6dp-5773L, -0x1.00a98abf783f75c40fe5b7a37d86p-9607L, -0x1.f81917b166f45e763cfcc057e2adp-9588L); + TEST_fff_f (fma, 0x1.00000000000007ffffffffffffffp-9045L, -0x1.ffffffffffff80000001ffffffffp+4773L, -0x1.f8p-4316L, -0x1.00000000000f88000000fffffdffp-4271L); + TEST_fff_f (fma, 0x1.4e922764c90701d4a2f21d01893dp-8683L, -0x1.955a12e2d7c9447c27fa022fc865p+212L, -0x1.e9634462eaef96528b90b6944578p-8521L, -0x1.08e1783184a371943d3598e10865p-8470L); + TEST_fff_f (fma, 0x1.801181509c03bdbef10d6165588cp-15131L, 0x1.ad86f8e57d3d40bfa8007780af63p-368L, -0x1.6e9df0dab1c9f1d7a6043c390741p-15507L, 0x1.417c9b2b15e2ad57dc9e0e920844p-15498L); +#endif END (fma); } --- libc/sysdeps/ieee754/ldbl-128/s_fmal.c.jj 2010-10-15 18:08:43.000000000 +0200 +++ libc/sysdeps/ieee754/ldbl-128/s_fmal.c 2010-10-16 17:17:15.000000000 +0200 @@ -175,6 +175,8 @@ __fmal (long double x, long double y, lo if ((u.ieee.mantissa3 & 1) == 0) u.ieee.mantissa3 |= fetestexcept (FE_INEXACT) != 0; v.d = a1 + u.d; + /* Ensure the addition is not scheduled after fetestexcept call. */ + asm volatile ("" : "m" (v)); int j = fetestexcept (FE_INEXACT) != 0; feupdateenv (&env); /* Ensure the following computations are performed in default rounding @@ -207,9 +209,9 @@ __fmal (long double x, long double y, lo { v.d *= 0x1p-226L; if (v.ieee.negative) - return v.d - 0x1p-16493L /* __LDBL_DENORM_MIN__ */; + return v.d - 0x1p-16494L /* __LDBL_DENORM_MIN__ */; else - return v.d + 0x1p-16493L /* __LDBL_DENORM_MIN__ */; + return v.d + 0x1p-16494L /* __LDBL_DENORM_MIN__ */; } else return v.d * 0x1p-226L; Jakub From schwab@redhat.com Mon Oct 18 13:12:00 2010 From: schwab@redhat.com (Andreas Schwab) Date: Mon, 18 Oct 2010 13:12:00 -0000 Subject: [PATCH] Never expand $ORIGIN in privileged programs Message-ID: Path elements containing $ORIGIN should always be ignored in privileged programs. Andreas. 2010-10-18 Andreas Schwab * elf/dl-load.c (is_dst): Remove last parameter. (_dl_dst_count): Ignore $ORIGIN in privileged programs. (_dl_dst_substitute): Likewise. --- elf/dl-load.c | 30 +++++++++++++----------------- 1 files changed, 13 insertions(+), 17 deletions(-) diff --git a/elf/dl-load.c b/elf/dl-load.c index a7162eb..776f7e4 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -169,8 +169,7 @@ local_strdup (const char *s) static size_t -is_dst (const char *start, const char *name, const char *str, - int is_path, int secure) +is_dst (const char *start, const char *name, const char *str, int is_path) { size_t len; bool is_curly = false; @@ -199,11 +198,6 @@ is_dst (const char *start, const char *name, const char *str, && (!is_path || name[len] != ':')) return 0; - if (__builtin_expect (secure, 0) - && ((name[len] != '\0' && (!is_path || name[len] != ':')) - || (name != start + 1 && (!is_path || name[-2] != ':')))) - return 0; - return len; } @@ -218,13 +212,12 @@ _dl_dst_count (const char *name, int is_path) { size_t len; - /* $ORIGIN is not expanded for SUID/GUID programs (except if it - is $ORIGIN alone) and it must always appear first in path. */ + /* $ORIGIN is not expanded for SUID/GUID programs. */ ++name; - if ((len = is_dst (start, name, "ORIGIN", is_path, - INTUSE(__libc_enable_secure))) != 0 - || (len = is_dst (start, name, "PLATFORM", is_path, 0)) != 0 - || (len = is_dst (start, name, "LIB", is_path, 0)) != 0) + if (((len = is_dst (start, name, "ORIGIN", is_path)) != 0 + && !INTUSE(__libc_enable_secure)) + || (len = is_dst (start, name, "PLATFORM", is_path)) != 0 + || (len = is_dst (start, name, "LIB", is_path)) != 0) ++cnt; name = strchr (name + len, '$'); @@ -256,9 +249,12 @@ _dl_dst_substitute (struct link_map *l, const char *name, char *result, size_t len; ++name; - if ((len = is_dst (start, name, "ORIGIN", is_path, - INTUSE(__libc_enable_secure))) != 0) + if ((len = is_dst (start, name, "ORIGIN", is_path)) != 0) { + /* Ignore this path element in SUID/SGID programs. */ + if (INTUSE(__libc_enable_secure)) + repl = (const char *) -1; + else #ifndef SHARED if (l == NULL) repl = _dl_get_origin (); @@ -266,9 +262,9 @@ _dl_dst_substitute (struct link_map *l, const char *name, char *result, #endif repl = l->l_origin; } - else if ((len = is_dst (start, name, "PLATFORM", is_path, 0)) != 0) + else if ((len = is_dst (start, name, "PLATFORM", is_path)) != 0) repl = GLRO(dl_platform); - else if ((len = is_dst (start, name, "LIB", is_path, 0)) != 0) + else if ((len = is_dst (start, name, "LIB", is_path)) != 0) repl = DL_DST_LIB; if (repl != NULL && repl != (const char *) -1) -- 1.7.2.3 -- Andreas Schwab, schwab@redhat.com GPG Key fingerprint = D4E8 DBE3 3813 BB5D FA84 5EC7 45C6 250E 6F00 984E "And now for something completely different." From schwab@redhat.com Mon Oct 18 13:28:00 2010 From: schwab@redhat.com (Andreas Schwab) Date: Mon, 18 Oct 2010 13:28:00 -0000 Subject: [PATCH] Don't expand DST twice in dl_open Message-ID: _dl_map_object already expands DST elements, no point in doing it twice. Andreas. 2010-10-18 Andreas Schwab * elf/dl-open.c (dl_open_worker): Don't expand DST here, let _dl_map_object do it. --- elf/dl-open.c | 29 ----------------------------- 1 files changed, 0 insertions(+), 29 deletions(-) diff --git a/elf/dl-open.c b/elf/dl-open.c index 754a263..c394b3f 100644 --- a/elf/dl-open.c +++ b/elf/dl-open.c @@ -221,35 +221,6 @@ dl_open_worker (void *a) assert (_dl_debug_initialize (0, args->nsid)->r_state == RT_CONSISTENT); - /* Maybe we have to expand a DST. */ - if (__builtin_expect (dst != NULL, 0)) - { - size_t len = strlen (file); - - /* Determine how much space we need. We have to allocate the - memory locally. */ - size_t required = DL_DST_REQUIRED (call_map, file, len, - _dl_dst_count (dst, 0)); - - /* Get space for the new file name. */ - char *new_file = (char *) alloca (required + 1); - - /* Generate the new file name. */ - _dl_dst_substitute (call_map, file, new_file, 0); - - /* If the substitution failed don't try to load. */ - if (*new_file == '\0') - _dl_signal_error (0, "dlopen", NULL, - N_("empty dynamic string token substitution")); - - /* Now we have a new file name. */ - file = new_file; - - /* It does not matter whether call_map is set even if we - computed it only because of the DST. Since the path contains - a slash the value is not used. See dl-load.c. */ - } - /* Load the named object. */ struct link_map *new; args->map = new = _dl_map_object (call_map, file, 0, lt_loaded, 0, -- 1.7.2.3 -- Andreas Schwab, schwab@redhat.com GPG Key fingerprint = D4E8 DBE3 3813 BB5D FA84 5EC7 45C6 250E 6F00 984E "And now for something completely different." From jakub@redhat.com Wed Oct 20 11:30:00 2010 From: jakub@redhat.com (Jakub Jelinek) Date: Wed, 20 Oct 2010 11:30:00 -0000 Subject: [PATCH] bits/mathdef.h changes for s390 and ia64, ldbl-128 fmal fix Message-ID: <20101020112957.GD21391@sunsite.ms.mff.cuni.cz> Hi! This provides FP_FAST* definitions for ia64 and s390{,x} and fixes a buglet in ldbl-128 fmal. 2010-10-20 Jakub Jelinek * sysdeps/ia64/bits/mathdef.h (FP_FAST_FMA, FP_FAST_FMAF, FP_FAST_FMAL): Define. * sysdeps/s390/bits/mathdef.h (FP_FAST_FMA, FP_FAST_FMAF): Likewise. * sysdeps/ieee754/ldbl-128/s_fmal.c (__fmal): Fix up inline asm. --- libc/sysdeps/ia64/bits/mathdef.h +++ libc/sysdeps/ia64/bits/mathdef.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2000, 2001, 2004 Free Software Foundation, Inc. +/* Copyright (C) 2000, 2001, 2004, 2010 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 @@ -34,4 +34,9 @@ typedef double double_t; /* `double' expressions are evaluated as # define FP_ILOGB0 (-2147483647 - 1) # define FP_ILOGBNAN 2147483647 +/* The IA-64 architecture has fused multiply/add instructions. */ +# define FP_FAST_FMA 1 +# define FP_FAST_FMAF 1 +# define FP_FAST_FMAL 1 + #endif /* ISO C99 */ --- libc/sysdeps/ieee754/ldbl-128/s_fmal.c +++ libc/sysdeps/ieee754/ldbl-128/s_fmal.c @@ -176,7 +176,7 @@ __fmal (long double x, long double y, long double z) u.ieee.mantissa3 |= fetestexcept (FE_INEXACT) != 0; v.d = a1 + u.d; /* Ensure the addition is not scheduled after fetestexcept call. */ - asm volatile ("" : "m" (v)); + asm volatile ("" : : "m" (v)); int j = fetestexcept (FE_INEXACT) != 0; feupdateenv (&env); /* Ensure the following computations are performed in default rounding --- libc/sysdeps/s390/bits/mathdef.h +++ libc/sysdeps/s390/bits/mathdef.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1997, 1998, 1999, 2000, 2004, 2006 +/* Copyright (C) 1997, 1998, 1999, 2000, 2004, 2006, 2010 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -35,4 +35,8 @@ typedef double double_t; /* `double' expressions are evaluated as # define FP_ILOGB0 (-2147483647) # define FP_ILOGBNAN 2147483647 +/* The S/390 architecture has fused multiply/add instructions. */ +# define FP_FAST_FMA 1 +# define FP_FAST_FMAF 1 + #endif /* ISO C99 */ Jakub From schwab@redhat.com Fri Oct 22 17:17:00 2010 From: schwab@redhat.com (Andreas Schwab) Date: Fri, 22 Oct 2010 17:17:00 -0000 Subject: [PATCH] Require suid bit on audit objects in privileged programs Message-ID: 2010-10-22 Andreas Schwab * include/dlfcn.h (__RTLD_SECURE): Define. * elf/dl-load.c (_dl_map_object): Remove preloaded parameter. Use mode & __RTLD_SECURE instead. (open_path): Rename preloaded parameter to secure. * sysdeps/generic/ldsodefs.h (_dl_map_object): Adjust declaration. * elf/dl-open.c (dl_open_worker): Adjust call to _dl_map_object. * elf/dl-deps.c (openaux): Likewise. * elf/rtld.c (struct map_args): Remove is_preloaded. (map_doit): Don't use it. (dl_main): Likewise. (do_preload): Use __RTLD_SECURE instead of is_preloaded. (dlmopen_doit): Add __RTLD_SECURE to mode bits. --- elf/dl-deps.c | 2 +- elf/dl-load.c | 20 +++++++++++--------- elf/dl-open.c | 2 +- elf/rtld.c | 16 +++++++--------- include/dlfcn.h | 1 + sysdeps/generic/ldsodefs.h | 6 ++---- 6 files changed, 23 insertions(+), 24 deletions(-) diff --git a/elf/dl-deps.c b/elf/dl-deps.c index e5b9cdf..1cab2d1 100644 --- a/elf/dl-deps.c +++ b/elf/dl-deps.c @@ -62,7 +62,7 @@ openaux (void *a) { struct openaux_args *args = (struct openaux_args *) a; - args->aux = _dl_map_object (args->map, args->name, 0, + args->aux = _dl_map_object (args->map, args->name, (args->map->l_type == lt_executable ? lt_library : args->map->l_type), args->trace_mode, args->open_mode, diff --git a/elf/dl-load.c b/elf/dl-load.c index 776f7e4..9ab3520 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -1808,7 +1808,7 @@ open_verify (const char *name, struct filebuf *fbp, struct link_map *loader, if MAY_FREE_DIRS is true. */ static int -open_path (const char *name, size_t namelen, int preloaded, +open_path (const char *name, size_t namelen, int secure, struct r_search_path_struct *sps, char **realname, struct filebuf *fbp, struct link_map *loader, int whatcode, bool *found_other_class) @@ -1890,7 +1890,7 @@ open_path (const char *name, size_t namelen, int preloaded, /* Remember whether we found any existing directory. */ here_any |= this_dir->status[cnt] != nonexisting; - if (fd != -1 && __builtin_expect (preloaded, 0) + if (fd != -1 && __builtin_expect (secure, 0) && INTUSE(__libc_enable_secure)) { /* This is an extra security effort to make sure nobody can @@ -1959,7 +1959,7 @@ open_path (const char *name, size_t namelen, int preloaded, struct link_map * internal_function -_dl_map_object (struct link_map *loader, const char *name, int preloaded, +_dl_map_object (struct link_map *loader, const char *name, int type, int trace_mode, int mode, Lmid_t nsid) { int fd; @@ -2063,7 +2063,8 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded, for (l = loader; l; l = l->l_loader) if (cache_rpath (l, &l->l_rpath_dirs, DT_RPATH, "RPATH")) { - fd = open_path (name, namelen, preloaded, &l->l_rpath_dirs, + fd = open_path (name, namelen, mode & __RTLD_SECURE, + &l->l_rpath_dirs, &realname, &fb, loader, LA_SER_RUNPATH, &found_other_class); if (fd != -1) @@ -2078,14 +2079,15 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded, && main_map != NULL && main_map->l_type != lt_loaded && cache_rpath (main_map, &main_map->l_rpath_dirs, DT_RPATH, "RPATH")) - fd = open_path (name, namelen, preloaded, &main_map->l_rpath_dirs, + fd = open_path (name, namelen, mode & __RTLD_SECURE, + &main_map->l_rpath_dirs, &realname, &fb, loader ?: main_map, LA_SER_RUNPATH, &found_other_class); } /* Try the LD_LIBRARY_PATH environment variable. */ if (fd == -1 && env_path_list.dirs != (void *) -1) - fd = open_path (name, namelen, preloaded, &env_path_list, + fd = open_path (name, namelen, mode & __RTLD_SECURE, &env_path_list, &realname, &fb, loader ?: GL(dl_ns)[LM_ID_BASE]._ns_loaded, LA_SER_LIBPATH, &found_other_class); @@ -2094,12 +2096,12 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded, if (fd == -1 && loader != NULL && cache_rpath (loader, &loader->l_runpath_dirs, DT_RUNPATH, "RUNPATH")) - fd = open_path (name, namelen, preloaded, + fd = open_path (name, namelen, mode & __RTLD_SECURE, &loader->l_runpath_dirs, &realname, &fb, loader, LA_SER_RUNPATH, &found_other_class); if (fd == -1 - && (__builtin_expect (! preloaded, 1) + && (__builtin_expect (! (mode & __RTLD_SECURE), 1) || ! INTUSE(__libc_enable_secure))) { /* Check the list of libraries in the file /etc/ld.so.cache, @@ -2165,7 +2167,7 @@ _dl_map_object (struct link_map *loader, const char *name, int preloaded, && ((l = loader ?: GL(dl_ns)[nsid]._ns_loaded) == NULL || __builtin_expect (!(l->l_flags_1 & DF_1_NODEFLIB), 1)) && rtld_search_dirs.dirs != (void *) -1) - fd = open_path (name, namelen, preloaded, &rtld_search_dirs, + fd = open_path (name, namelen, mode & __RTLD_SECURE, &rtld_search_dirs, &realname, &fb, l, LA_SER_DEFAULT, &found_other_class); /* Add another newline when we are tracing the library loading. */ diff --git a/elf/dl-open.c b/elf/dl-open.c index c394b3f..cf8e8cc 100644 --- a/elf/dl-open.c +++ b/elf/dl-open.c @@ -223,7 +223,7 @@ dl_open_worker (void *a) /* Load the named object. */ struct link_map *new; - args->map = new = _dl_map_object (call_map, file, 0, lt_loaded, 0, + args->map = new = _dl_map_object (call_map, file, lt_loaded, 0, mode | __RTLD_CALLMAP, args->nsid); /* If the pointer returned is NULL this means the RTLD_NOLOAD flag is diff --git a/elf/rtld.c b/elf/rtld.c index 201c9cf..4a8cee8 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -587,7 +587,6 @@ struct map_args /* Argument to map_doit. */ char *str; struct link_map *loader; - int is_preloaded; int mode; /* Return value of map_doit. */ struct link_map *map; @@ -625,16 +624,17 @@ static void map_doit (void *a) { struct map_args *args = (struct map_args *) a; - args->map = _dl_map_object (args->loader, args->str, - args->is_preloaded, lt_library, 0, args->mode, - LM_ID_BASE); + args->map = _dl_map_object (args->loader, args->str, lt_library, 0, + args->mode, LM_ID_BASE); } static void dlmopen_doit (void *a) { struct dlmopen_args *args = (struct dlmopen_args *) a; - args->map = _dl_open (args->fname, RTLD_LAZY | __RTLD_DLOPEN | __RTLD_AUDIT, + args->map = _dl_open (args->fname, + (RTLD_LAZY | __RTLD_DLOPEN | __RTLD_AUDIT + | __RTLD_SECURE), dl_main, LM_ID_NEWLM, _dl_argc, INTUSE(_dl_argv), __environ); } @@ -804,8 +804,7 @@ do_preload (char *fname, struct link_map *main_map, const char *where) args.str = fname; args.loader = main_map; - args.is_preloaded = 1; - args.mode = 0; + args.mode = __RTLD_SECURE; unsigned int old_nloaded = GL(dl_ns)[LM_ID_BASE]._ns_nloaded; @@ -1050,7 +1049,6 @@ of this helper program; chances are you did not intend to run this program.\n\ args.str = rtld_progname; args.loader = NULL; - args.is_preloaded = 0; args.mode = __RTLD_OPENEXEC; (void) _dl_catch_error (&objname, &err_str, &malloced, map_doit, &args); @@ -1062,7 +1060,7 @@ of this helper program; chances are you did not intend to run this program.\n\ else { HP_TIMING_NOW (start); - _dl_map_object (NULL, rtld_progname, 0, lt_library, 0, + _dl_map_object (NULL, rtld_progname, lt_library, 0, __RTLD_OPENEXEC, LM_ID_BASE); HP_TIMING_NOW (stop); diff --git a/include/dlfcn.h b/include/dlfcn.h index a67426d..af92483 100644 --- a/include/dlfcn.h +++ b/include/dlfcn.h @@ -9,6 +9,7 @@ #define __RTLD_OPENEXEC 0x20000000 #define __RTLD_CALLMAP 0x10000000 #define __RTLD_AUDIT 0x08000000 +#define __RTLD_SECURE 0x04000000 /* Apply additional security checks. */ #define __LM_ID_CALLER -2 diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index fcc943b..fa4b6b2 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -824,11 +824,9 @@ extern void _dl_receive_error (receiver_fct fct, void (*operate) (void *), /* Open the shared object NAME and map in its segments. LOADER's DT_RPATH is used in searching for NAME. - If the object is already opened, returns its existing map. - For preloaded shared objects PRELOADED is set to a non-zero - value to allow additional security checks. */ + If the object is already opened, returns its existing map. */ extern struct link_map *_dl_map_object (struct link_map *loader, - const char *name, int preloaded, + const char *name, int type, int trace_mode, int mode, Lmid_t nsid) internal_function attribute_hidden; -- 1.7.2.3 -- Andreas Schwab, schwab@redhat.com GPG Key fingerprint = D4E8 DBE3 3813 BB5D FA84 5EC7 45C6 250E 6F00 984E "And now for something completely different." From roland@redhat.com Fri Oct 22 17:38:00 2010 From: roland@redhat.com (Roland McGrath) Date: Fri, 22 Oct 2010 17:38:00 -0000 Subject: [PATCH] Require suid bit on audit objects in privileged programs In-Reply-To: Andreas Schwab's message of Friday, 22 October 2010 19:17:20 +0200 References: Message-ID: <20101022173806.2D8ABC9E37@blackie.sf.frob.com> AIUI this makes the treatment of LD_AUDIT match the treatment of LD_PRELOAD. That seems very sensible to me. Thanks, Roland From drepper@gmail.com Fri Oct 22 17:40:00 2010 From: drepper@gmail.com (Ulrich Drepper) Date: Fri, 22 Oct 2010 17:40:00 -0000 Subject: [PATCH] Require suid bit on audit objects in privileged programs In-Reply-To: <20101022173806.2D8ABC9E37@blackie.sf.frob.com> References: <20101022173806.2D8ABC9E37@blackie.sf.frob.com> Message-ID: On Fri, Oct 22, 2010 at 13:38, Roland McGrath wrote: > AIUI this makes the treatment of LD_AUDIT match the treatment of LD_PRELOAD. > That seems very sensible to me. I agree, but want to go over all the pending changes in detail. Will do all that over the weekend. From schwab@redhat.com Tue Oct 26 09:19:00 2010 From: schwab@redhat.com (Andreas Schwab) Date: Tue, 26 Oct 2010 09:19:00 -0000 Subject: [PATCH] Remove false assertion Message-ID: 2010-10-26 Andreas Schwab * elf/rtld.c (dl_main): Remove false assertion. --- elf/rtld.c | 1 - 1 files changed, 0 insertions(+), 1 deletions(-) diff --git a/elf/rtld.c b/elf/rtld.c index eebd8af..9be149d 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -1104,7 +1104,6 @@ of this helper program; chances are you did not intend to run this program.\n\ main_map = _dl_new_object ((char *) "", "", lt_executable, NULL, __RTLD_OPENEXEC, LM_ID_BASE); assert (main_map != NULL); - assert (main_map == GL(dl_ns)[LM_ID_BASE]._ns_loaded); main_map->l_phdr = phdr; main_map->l_phnum = phnum; main_map->l_entry = *user_entry; -- 1.7.2.3 -- Andreas Schwab, schwab@redhat.com GPG Key fingerprint = D4E8 DBE3 3813 BB5D FA84 5EC7 45C6 250E 6F00 984E "And now for something completely different." From schwab@redhat.com Tue Oct 26 12:53:00 2010 From: schwab@redhat.com (Andreas Schwab) Date: Tue, 26 Oct 2010 12:53:00 -0000 Subject: [PATCH] Don't require DNS labels to be host names Message-ID: 2010-10-26 Andreas Schwab [BZ #12154] * resolv/nss_dns/dns-host.c (getanswer_r): Don't require DNS labels to be host names. (gaih_getanswer_slice): Likewise. --- resolv/nss_dns/dns-host.c | 42 ++++++++++++++++++++++++++++-------------- 1 files changed, 28 insertions(+), 14 deletions(-) diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c index 8592183..19f6dab 100644 --- a/resolv/nss_dns/dns-host.c +++ b/resolv/nss_dns/dns-host.c @@ -716,7 +716,7 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype, n = -1; } - if (__builtin_expect (n < 0 || (*name_ok) (bp) == 0, 0)) + if (__builtin_expect (n < 0 || res_dnok (bp) == 0, 0)) { ++had_error; continue; @@ -746,25 +746,29 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype, if ((qtype == T_A || qtype == T_AAAA) && type == T_CNAME) { - if (ap >= &host_data->aliases[MAX_NR_ALIASES - 1]) - continue; n = dn_expand (answer->buf, end_of_message, cp, tbuf, sizeof tbuf); - if (__builtin_expect (n < 0 || (*name_ok) (tbuf) == 0, 0)) + if (__builtin_expect (n < 0 || res_dnok (tbuf) == 0, 0)) { ++had_error; continue; } cp += n; - /* Store alias. */ - *ap++ = bp; - n = strlen (bp) + 1; /* For the \0. */ - if (__builtin_expect (n, 0) >= MAXHOSTNAMELEN) + /* Ignore aliases that are not valid host names. */ + if (res_hnok (bp)) { - ++had_error; - continue; + if (ap >= &host_data->aliases[MAX_NR_ALIASES - 1]) + continue; + /* Store alias. */ + *ap++ = bp; + n = strlen (bp) + 1; /* For the \0. */ + if (__builtin_expect (n, 0) >= MAXHOSTNAMELEN) + { + ++had_error; + continue; + } + bp += n; + linebuflen -= n; } - bp += n; - linebuflen -= n; /* Get canonical name. */ n = strlen (tbuf) + 1; /* For the \0. */ if (__builtin_expect (n > linebuflen, 0)) @@ -892,6 +896,11 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype, #endif case T_A: case T_AAAA: + if (res_hnok (bp) == 0) + { + had_error++; + break; + } if (__builtin_expect (strcasecmp (result->h_name, bp), 0) != 0) { syslog (LOG_NOTICE | LOG_AUTH, AskedForGot, result->h_name, bp); @@ -1045,7 +1054,7 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname, n = -1; } - if (__builtin_expect (n < 0 || res_hnok (buffer) == 0, 0)) + if (__builtin_expect (n < 0 || res_dnok (buffer) == 0, 0)) { ++had_error; continue; @@ -1084,7 +1093,7 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname, { char tbuf[MAXDNAME]; n = dn_expand (answer->buf, end_of_message, cp, tbuf, sizeof tbuf); - if (__builtin_expect (n < 0 || res_hnok (tbuf) == 0, 0)) + if (__builtin_expect (n < 0 || res_dnok (tbuf) == 0, 0)) { ++had_error; continue; @@ -1163,6 +1172,11 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname, if (*firstp) { + if (res_hnok (canon ?: h_name) == 0) + { + ++had_error; + continue; + } if (ttl != 0 && ttlp != NULL) *ttlp = ttl; -- 1.7.2.3 -- Andreas Schwab, schwab@redhat.com GPG Key fingerprint = D4E8 DBE3 3813 BB5D FA84 5EC7 45C6 250E 6F00 984E "And now for something completely different." From drepper@gmail.com Tue Oct 26 14:06:00 2010 From: drepper@gmail.com (Ulrich Drepper) Date: Tue, 26 Oct 2010 14:06:00 -0000 Subject: [PATCH] Don't require DNS labels to be host names In-Reply-To: References: Message-ID: Is this what more recent versions of libresolv do or where does this come from? From schwab@redhat.com Tue Oct 26 15:20:00 2010 From: schwab@redhat.com (Andreas Schwab) Date: Tue, 26 Oct 2010 15:20:00 -0000 Subject: [PATCH] Don't require DNS labels to be host names In-Reply-To: (Ulrich Drepper's message of "Tue, 26 Oct 2010 10:05:46 -0400") References: Message-ID: Ulrich Drepper writes: > Is this what more recent versions of libresolv do or What do you mean with "more recent versions of libresolv"? > where does this come from? Read the bug report. Andreas. -- Andreas Schwab, schwab@redhat.com GPG Key fingerprint = D4E8 DBE3 3813 BB5D FA84 5EC7 45C6 250E 6F00 984E "And now for something completely different." From drepper@gmail.com Tue Oct 26 15:25:00 2010 From: drepper@gmail.com (Ulrich Drepper) Date: Tue, 26 Oct 2010 15:25:00 -0000 Subject: [PATCH] Don't require DNS labels to be host names In-Reply-To: References: Message-ID: On Tue, Oct 26, 2010 at 11:20, Andreas Schwab wrote: > What do you mean with "more recent versions of libresolv"? bind releases still have libresolv. > Read the bug report. I did and I am not at all convinced that anything done is valid. The code is as it is forever. Invalid extensions by msft or others are still invalid and don't warrant support. Therefore the question: how did you come up with the patch? There are a lot of changes and there is no detailed explanation. From schwab@redhat.com Tue Oct 26 15:42:00 2010 From: schwab@redhat.com (Andreas Schwab) Date: Tue, 26 Oct 2010 15:42:00 -0000 Subject: [PATCH] Don't require DNS labels to be host names In-Reply-To: (Ulrich Drepper's message of "Tue, 26 Oct 2010 11:24:43 -0400") References: Message-ID: Ulrich Drepper writes: > Invalid extensions by msft What does this have to do with msft? > Therefore the question: how did you come up with the patch? By fixing the bug described in the bug report. Andreas. -- Andreas Schwab, schwab@redhat.com GPG Key fingerprint = D4E8 DBE3 3813 BB5D FA84 5EC7 45C6 250E 6F00 984E "And now for something completely different."