From jakub@redhat.com Tue Sep 1 15:54:00 2009 From: jakub@redhat.com (Jakub Jelinek) Date: Tue, 01 Sep 2009 15:54:00 -0000 Subject: [PATCH] Fix x86_64 bits/mathinline.h for -m32 compilation Message-ID: <20090901152934.GB3611@sunsite.ms.mff.cuni.cz> Hi! With the latest bits/mathinline.h, echo '#include ' | gcc -S -xc - -o - -std=c99 -O2 -m32 doesn't compile: /usr/include/bits/mathinline.h:39: error: impossible constraint in 'asm' /usr/include/bits/mathinline.h:46: error: impossible constraint in 'asm' The problem is that SSE{,2} assembly and "x" constraint is used even in 32-bit code. Here is an untested fix: 2009-09-01 Jakub Jelinek * sysdeps/x86_64/fpu/bits/mathinline.h: Include bits/wordsize.h. (__signbitf, __signbit): Only use SSE inline asm for 64-bit. diff --git a/sysdeps/x86_64/fpu/bits/mathinline.h b/sysdeps/x86_64/fpu/bits/mathinline.h index ece0f02..dc58f67 100644 --- a/sysdeps/x86_64/fpu/bits/mathinline.h +++ b/sysdeps/x86_64/fpu/bits/mathinline.h @@ -22,6 +22,8 @@ # error "Never use directly; include instead." #endif +#include + #ifndef __extern_inline # define __MATH_INLINE __inline #else @@ -35,16 +37,26 @@ __MATH_INLINE int __NTH (__signbitf (float __x)) { +#if __WORDSIZE == 32 + __extension__ union { float __f; int __i; } __u = { __f: __x }; + return __u.__i < 0; +#else int __m; __asm ("pmovmskb %1, %0" : "=r" (__m) : "x" (__x)); return __m & 0x8; +#endif } __MATH_INLINE int __NTH (__signbit (double __x)) { +#if __WORDSIZE == 32 + __extension__ union { double __d; int __i[2]; } __u = { __d: __x }; + return __u.__i[1] < 0; +#else int __m; __asm ("pmovmskb %1, %0" : "=r" (__m) : "x" (__x)); return __m & 0x80; +#endif } __MATH_INLINE int __NTH (__signbitl (long double __x)) Jakub From jakub@redhat.com Wed Sep 2 09:32:00 2009 From: jakub@redhat.com (Jakub Jelinek) Date: Wed, 02 Sep 2009 09:32:00 -0000 Subject: [PATCH] Fix strstr/strcasestr/fma/fmaf on x86_64 Message-ID: <20090902085848.GC3611@sunsite.ms.mff.cuni.cz> Hi! Without this patch e.g. strstr IFUNC looks like: 0000000000089090 : 89090: 48 83 ec 08 sub $0x8,%rsp 89094: 8b 05 86 51 2f 00 mov 0x2f5186(%rip),%eax # 37e220 <__cpu_features> 8909a: 85 c0 test %eax,%eax 8909c: 74 22 je 890c0 8909e: f6 05 8d 51 2f 00 10 testb $0x10,0x2f518d(%rip) # 37e232 <__cpu_features+0x12> 890a5: 48 8b 05 44 fd 2e 00 mov 0x2efd44(%rip),%rax # 378df0 <_DYNAMIC+0x2d0> 890ac: 48 0f 45 05 04 fe 2e cmovne 0x2efe04(%rip),%rax # 378eb8 <_DYNAMIC+0x398> 890b3: 00 890b4: 48 83 c4 08 add $0x8,%rsp 890b8: c3 retq 890b9: 0f 1f 80 00 00 00 00 nopl 0x0(%rax) 890c0: e8 2b 5e f9 ff callq 1eef0 <__init_cpu_features> 890c5: eb d7 jmp 8909e 890c7: 66 0f 1f 84 00 00 00 nopw 0x0(%rax,%rax,1) 890ce: 00 00 Note that __strstr_sse2 and __strstr_sse42 addresses are read from GOT where they have RELATIVE relocation on them. This is completely unnecessary (they are not exported from libc.so), and worse it breaks when some library has e.g. strstr relocation resolved (with LD_BIND_NOW=1) before libc.so has been relocated. Even with this patch, I still wonder how can fma/fmaf actually work with LD_BIND_NOW=1, because those IFUNC functions actually make a PLT call. If libm.so's relocation hasn't been started yet, I wonder what will happen. 2009-09-02 Jakub Jelinek * sysdeps/x86_64/multiarch/strstr-c.c (__strstr_sse42, __strstr_sse2): Add attribute_hidden. * sysdeps/x86_64/multiarch/strcasestr-c.c (__strcasestr_sse42, __strcasestr_sse2): Likewise. * sysdeps/x86_64/multiarch/s_fma.c (__fma_sse2): Add attribute_hidden. (__fma_fma): Make static. * sysdeps/x86_64/multiarch/s_fmaf.c (__fmaf_sse2): Add attribute_hidden. (__fmaf_fma): Make static. --- libc/sysdeps/x86_64/multiarch/strstr-c.c.jj 2009-07-23 08:59:29.000000000 +0200 +++ libc/sysdeps/x86_64/multiarch/strstr-c.c 2009-09-02 10:34:48.000000000 +0200 @@ -7,6 +7,7 @@ #include "string/strstr.c" -extern char *__strstr_sse42 (const char *, const char *); +extern char *__strstr_sse42 (const char *, const char *) attribute_hidden; +extern __typeof (__strstr_sse2) __strstr_sse2 attribute_hidden; libc_ifunc (strstr, HAS_SSE4_2 ? __strstr_sse42 : __strstr_sse2); --- libc/sysdeps/x86_64/multiarch/strcasestr-c.c.jj 2009-07-23 08:59:29.000000000 +0200 +++ libc/sysdeps/x86_64/multiarch/strcasestr-c.c 2009-09-02 10:36:07.000000000 +0200 @@ -7,7 +7,8 @@ #include "string/strcasestr.c" -extern char *__strcasestr_sse42 (const char *, const char *); +extern char *__strcasestr_sse42 (const char *, const char *) attribute_hidden; +extern __typeof (__strcasestr_sse2) __strcasestr_sse2 attribute_hidden; #if 1 libc_ifunc (__strcasestr, --- libc/sysdeps/x86_64/multiarch/s_fma.c.jj 2009-07-31 12:52:08.000000000 +0200 +++ libc/sysdeps/x86_64/multiarch/s_fma.c 2009-09-02 10:38:00.000000000 +0200 @@ -24,10 +24,10 @@ #ifdef HAVE_AVX_SUPPORT -extern double __fma_sse2 (double x, double y, double z); +extern double __fma_sse2 (double x, double y, double z) attribute_hidden; -double +static double __fma_fma (double x, double y, double z) { asm ("vfmadd213sd %3, %2, %0" : "=x" (x) : "0" (x), "x" (y), "xm" (z)); --- libc/sysdeps/x86_64/multiarch/s_fmaf.c.jj 2009-07-31 12:52:08.000000000 +0200 +++ libc/sysdeps/x86_64/multiarch/s_fmaf.c 2009-09-02 10:38:22.000000000 +0200 @@ -23,10 +23,10 @@ #ifdef HAVE_AVX_SUPPORT -extern float __fmaf_sse2 (float x, float y, float z); +extern float __fmaf_sse2 (float x, float y, float z) attribute_hidden; -float +static float __fmaf_fma (float x, float y, float z) { asm ("vfmadd213ss %3, %2, %0" : "=x" (x) : "0" (x), "x" (y), "xm" (z)); Jakub From schwab@linux-m68k.org Wed Sep 2 10:08:00 2009 From: schwab@linux-m68k.org (Andreas Schwab) Date: Wed, 02 Sep 2009 10:08:00 -0000 Subject: [PATCH] Fix strstr/strcasestr/fma/fmaf on x86_64 In-Reply-To: <20090902085848.GC3611@sunsite.ms.mff.cuni.cz> (Jakub Jelinek's message of "Wed, 2 Sep 2009 10:58:48 +0200") References: <20090902085848.GC3611@sunsite.ms.mff.cuni.cz> Message-ID: Jakub Jelinek writes: > --- libc/sysdeps/x86_64/multiarch/strstr-c.c.jj 2009-07-23 08:59:29.000000000 +0200 > +++ libc/sysdeps/x86_64/multiarch/strstr-c.c 2009-09-02 10:34:48.000000000 +0200 > @@ -7,6 +7,7 @@ > > #include "string/strstr.c" > > -extern char *__strstr_sse42 (const char *, const char *); > +extern char *__strstr_sse42 (const char *, const char *) attribute_hidden; > +extern __typeof (__strstr_sse2) __strstr_sse2 attribute_hidden; Shouldn't those use the libc_hidden* macros? Andreas. -- Andreas Schwab, schwab@linux-m68k.org GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 "And now for something completely different." From jakub@redhat.com Tue Sep 8 13:04:00 2009 From: jakub@redhat.com (Jakub Jelinek) Date: Tue, 08 Sep 2009 13:04:00 -0000 Subject: [PATCH] Fix __longjmp_chk on s390/s390x Message-ID: <20090908130424.GE3611@sunsite.ms.mff.cuni.cz> Hi! s390/s390x hasn't been updated to handle alternate stacks properly. The following untested patch should cure it. 2009-09-08 Jakub Jelinek * sysdeps/s390/s390-32/____longjmp_chk.c: Removed. * sysdeps/s390/s390-64/____longjmp_chk.c: Removed. * sysdeps/unix/sysv/linux/s390/s390-32/____longjmp_chk.c: New file. * sysdeps/unix/sysv/linux/s390/s390-64/____longjmp_chk.c: New file. --- libc/sysdeps/s390/s390-32/____longjmp_chk.c.jj 2009-05-29 21:50:43.000000000 +0200 +++ libc/sysdeps/s390/s390-32/____longjmp_chk.c 2009-09-08 13:52:10.000000000 +0200 @@ -1,41 +0 @@ -/* Copyright (C) 2009 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Jakub Jelinek . - - 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 -#include -#include -#include - -#define __longjmp ____longjmp_chk - -#define CHECK_SP(env, guard) \ - do \ - { \ - uintptr_t cur_sp; \ - uintptr_t new_sp = env->__gregs[9]; \ - __asm ("lr %0, %%r15" : "=r" (cur_sp)); \ - new_sp ^= guard; \ - if (new_sp < cur_sp) \ - __fortify_fail ("longjmp causes uninitialized stack frame"); \ - } while (0) - -#include "__longjmp.c" --- libc/sysdeps/s390/s390-64/____longjmp_chk.c.jj 2009-05-29 21:50:43.000000000 +0200 +++ libc/sysdeps/s390/s390-64/____longjmp_chk.c 2009-09-08 13:52:10.000000000 +0200 @@ -1,41 +0 @@ -/* Copyright (C) 2009 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Jakub Jelinek . - - 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 -#include -#include -#include - -#define __longjmp ____longjmp_chk - -#define CHECK_SP(env, guard) \ - do \ - { \ - uintptr_t cur_sp; \ - uintptr_t new_sp = env->__gregs[9]; \ - __asm ("lgr %0, %%r15" : "=r" (cur_sp)); \ - new_sp ^= guard; \ - if (new_sp < cur_sp) \ - __fortify_fail ("longjmp causes uninitialized stack frame"); \ - } while (0) - -#include "__longjmp.c" --- libc/sysdeps/unix/sysv/linux/s390/s390-32/____longjmp_chk.c.jj 2009-09-08 13:51:22.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/s390/s390-32/____longjmp_chk.c 2009-09-08 14:15:27.000000000 +0200 @@ -0,0 +1,55 @@ +/* Copyright (C) 2009 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek . + + 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 +#include +#include +#include +#include +#include +#include + +#define __longjmp ____longjmp_chk + +#define CHECK_SP(env, guard) \ + do \ + { \ + uintptr_t cur_sp; \ + uintptr_t new_sp = env->__gregs[9]; \ + __asm ("lr %0, %%r15" : "=r" (cur_sp)); \ + new_sp ^= guard; \ + if (new_sp < cur_sp) \ + { \ + stack_t oss; \ + INTERNAL_SYSCALL_DECL (err); \ + int res = INTERNAL_SYSCALL (sigaltstack, err, 2, NULL, &oss); \ + if (!INTERNAL_SYSCALL_ERROR_P (res, err)) \ + { \ + if ((oss.ss_flags & SS_ONSTACK) == 0 \ + || ((uintptr_t) (oss.ss_sp + oss.ss_size) - new_sp \ + >= oss.ss_size)) \ + __fortify_fail ("longjmp causes uninitialized stack frame");\ + } \ + } \ + } while (0) + +#include "__longjmp.c" --- libc/sysdeps/unix/sysv/linux/s390/s390-64/____longjmp_chk.c.jj 2009-09-08 13:51:22.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/s390/s390-64/____longjmp_chk.c 2009-09-08 14:15:14.000000000 +0200 @@ -0,0 +1,55 @@ +/* Copyright (C) 2009 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek . + + 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 +#include +#include +#include +#include +#include +#include + +#define __longjmp ____longjmp_chk + +#define CHECK_SP(env, guard) \ + do \ + { \ + uintptr_t cur_sp; \ + uintptr_t new_sp = env->__gregs[9]; \ + __asm ("lgr %0, %%r15" : "=r" (cur_sp)); \ + new_sp ^= guard; \ + if (new_sp < cur_sp) \ + { \ + stack_t oss; \ + INTERNAL_SYSCALL_DECL (err); \ + int res = INTERNAL_SYSCALL (sigaltstack, err, 2, NULL, &oss); \ + if (!INTERNAL_SYSCALL_ERROR_P (res, err)) \ + { \ + if ((oss.ss_flags & SS_ONSTACK) == 0 \ + || ((uintptr_t) (oss.ss_sp + oss.ss_size) - new_sp \ + >= oss.ss_size)) \ + __fortify_fail ("longjmp causes uninitialized stack frame");\ + } \ + } \ + } while (0) + +#include "__longjmp.c" Jakub