From 2dec6007d183aa51abedbbb048382973129f3935 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Thu, 30 Jul 2009 16:53:52 -0700 Subject: [PATCH 01/19] Stop backtrace when we make no more progress. --- ChangeLog | 5 +++++ sysdeps/ia64/backtrace.c | 10 ++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0d0120ccb6..9e78199bce 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2009-07-30 Ulrich Drepper + + * sysdeps/ia64/backtrace.c (backtrace_helper): Stop backtrace when + we make no more progress. + 2009-07-29 Ulrich Drepper * math/s_fma.c: Don't define alias if __fma is a macro. diff --git a/sysdeps/ia64/backtrace.c b/sysdeps/ia64/backtrace.c index 423fed80a8..5cefb86ae4 100644 --- a/sysdeps/ia64/backtrace.c +++ b/sysdeps/ia64/backtrace.c @@ -1,5 +1,5 @@ /* Return backtrace of current program state. - Copyright (C) 2003, 2004, 2005, 2007 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2005, 2007, 2009 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Jakub Jelinek , 2003. @@ -61,7 +61,13 @@ backtrace_helper (struct _Unwind_Context *ctx, void *a) /* We are first called with address in the __backtrace function. Skip it. */ if (arg->cnt != -1) - arg->array[arg->cnt] = (void *) unwind_getip (ctx); + { + arg->array[arg->cnt] = (void *) unwind_getip (ctx); + + /* Check whether we make any progress. */ + if (arg->cnt > 0 && arg->array[arg->cnt - 1] == arg->array[arg->cnt]) + return _URC_END_OF_STACK; + } if (++arg->cnt == arg->size) return _URC_END_OF_STACK; return _URC_NO_REASON; From 5ead9ce5c788e7dbb0bd01888c4bcb37a8bc2ff1 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Thu, 30 Jul 2009 17:31:48 -0700 Subject: [PATCH 02/19] Fix x86-64 ____longjmp_chk to handle signal stacks. The simple test previously used might trigger if the longjmp jumps from the signal stack to the normal stack. We now explicitly test for this case. --- ChangeLog | 5 ++ sysdeps/x86_64/____longjmp_chk.S | 107 ++++++++++++++++++++++++++++++- sysdeps/x86_64/__longjmp.S | 6 +- 3 files changed, 111 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9e78199bce..2492d49314 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2009-07-30 Ulrich Drepper + * sysdeps/x86_64/__longjmp.S: Remove CHECK_RSP handling. Fix CFI. + Remove incorrect use of BP_SYM. + * sysdeps/x86_64/____longjmp_chk.S: Rewrite. Complete implementation + here now since it is more complex than just a simple check. + * sysdeps/ia64/backtrace.c (backtrace_helper): Stop backtrace when we make no more progress. diff --git a/sysdeps/x86_64/____longjmp_chk.S b/sysdeps/x86_64/____longjmp_chk.S index 030a0dcaa7..50d2fca2c3 100644 --- a/sysdeps/x86_64/____longjmp_chk.S +++ b/sysdeps/x86_64/____longjmp_chk.S @@ -16,6 +16,10 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#include +#include +#include + .section .rodata.str1.1,"aMS",@progbits,1 .type longjmp_msg,@object longjmp_msg: @@ -23,7 +27,7 @@ longjmp_msg: .size longjmp_msg, .-longjmp_msg -#define __longjmp ____longjmp_chk +//#define __longjmp ____longjmp_chk #ifdef PIC # define CALL_FAIL leaq longjmp_msg(%rip), %rdi; \ @@ -39,4 +43,103 @@ longjmp_msg: CALL_FAIL; \ .Lok: -#include "__longjmp.S" +/* Jump to the position specified by ENV, causing the + setjmp call there to return VAL, or 1 if VAL is 0. + void __longjmp (__jmp_buf env, int val). */ + .text +ENTRY(____longjmp_chk) + /* Restore registers. */ + movq (JB_RSP*8)(%rdi),%r8 + movq (JB_RBP*8)(%rdi),%r9 + movq (JB_PC*8)(%rdi),%rdx +#ifdef PTR_DEMANGLE + PTR_DEMANGLE (%r8) + PTR_DEMANGLE (%r9) + PTR_DEMANGLE (%rdx) +#endif + + /* Save function parameters. */ + movq %rdi, %r10 + movl %esi, %ecx + + xorl %eax, %eax + cmpq %r8, %rsp + jbe .Lok + + subq $32, %rsp + cfi_adjust_cfa_offset(32) + movq %r10, 24(%rsp) + xorl %edi, %edi + movq %rsp, %rsi + movl $__NR_sigaltstack, %eax + syscall + movq 24(%rsp), %r10 + testl %eax, %eax + movl $0, %eax + jne .Lok + movl 8(%rsp), %eax + andl $1, %eax + +.Lok: + /* We add unwind information for the target here. */ + cfi_def_cfa(%r10, 0) + cfi_register(%rsp,%r8) + cfi_register(%rbp,%r9) + cfi_register(%rip,%rdx) + cfi_offset(%rbx,JB_RBX*8) + cfi_offset(%r12,JB_R12*8) + cfi_offset(%r13,JB_R13*8) + cfi_offset(%r14,JB_R14*8) + cfi_offset(%r15,JB_R15*8) + + xchgq %r8, %rsp + cfi_restore(%rsp) + xchgq %r9, %rbp + cfi_restore(%rbp) + + movq (JB_RBX*8)(%r10),%rbx + movq (JB_R12*8)(%r10),%r12 + movq (JB_R13*8)(%r10),%r13 + movq (JB_R14*8)(%r10),%r14 + movq (JB_R15*8)(%r10),%r15 + + cmpq %rsp, %r8 + jnbe .Lcheck + + /* Set return value for setjmp. */ +.Lout: movl %ecx, %eax + jmpq *%rdx + +.Lcheck: + testl %eax, %eax + je .Lfail + + subq $24, %rsp + cfi_adjust_cfa_offset(24) + xorl %edi, %edi + movq %rsp, %rsi + movl $__NR_sigaltstack, %eax + syscall + addq $24, %rsp + cfi_adjust_cfa_offset(-24) + testl $1, 8(%rsp) + je .Lout + +.Lfail: xchgq %r8, %rsp + /* We want the stack trace to show that of the caller. */ + cfi_def_cfa(%rsp, 40) + cfi_restore(%rsp) + cfi_register(%rbp, %r9) + cfi_restore(%rip) + cfi_restore(%rbx) + cfi_restore(%r12) + cfi_restore(%r13) + cfi_restore(%r14) + cfi_restore(%r15) + + xchgq %r9, %rbp + cfi_restore(%rbp) + + CALL_FAIL + hlt +END (BP_SYM (____longjmp_chk)) diff --git a/sysdeps/x86_64/__longjmp.S b/sysdeps/x86_64/__longjmp.S index 24552ece37..b045c04184 100644 --- a/sysdeps/x86_64/__longjmp.S +++ b/sysdeps/x86_64/__longjmp.S @@ -33,9 +33,6 @@ ENTRY(__longjmp) PTR_DEMANGLE (%r8) PTR_DEMANGLE (%r9) PTR_DEMANGLE (%rdx) -#endif -#ifdef CHECK_RSP - CHECK_RSP (%r8) #endif /* We add unwind information for the target here. */ cfi_def_cfa(%rdi, 0) @@ -43,7 +40,6 @@ ENTRY(__longjmp) cfi_register(%rbp,%r9) cfi_register(%rip,%rdx) cfi_offset(%rbx,JB_RBX*8) - cfi_offset(%rbp,JB_RBP*8) cfi_offset(%r12,JB_R12*8) cfi_offset(%r13,JB_R13*8) cfi_offset(%r14,JB_R14*8) @@ -58,4 +54,4 @@ ENTRY(__longjmp) movq %r8,%rsp movq %r9,%rbp jmpq *%rdx -END (BP_SYM (__longjmp)) +END (__longjmp) From a9a04420818e1ab0a49838e2eb83ebb66baaeaac Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Thu, 30 Jul 2009 17:48:58 -0700 Subject: [PATCH 03/19] Add test case for ____longjmp_chk vs signal stacks. --- ChangeLog | 3 ++ debug/Makefile | 3 +- debug/tst-longjmp_chk2.c | 114 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 debug/tst-longjmp_chk2.c diff --git a/ChangeLog b/ChangeLog index 2492d49314..db6e93d11d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2009-07-30 Ulrich Drepper + * debug/Makefile (tests): Add tst-longjmp_chk2. + * debug/tst-longjmp_chk2.c: New file. + * sysdeps/x86_64/__longjmp.S: Remove CHECK_RSP handling. Fix CFI. Remove incorrect use of BP_SYM. * sysdeps/x86_64/____longjmp_chk.S: Rewrite. Complete implementation diff --git a/debug/Makefile b/debug/Makefile index 181169b90d..99c8092074 100644 --- a/debug/Makefile +++ b/debug/Makefile @@ -118,7 +118,8 @@ LDFLAGS-tst-lfschk6 = -lstdc++ tests = backtrace-tst tst-longjmp_chk tst-chk1 tst-chk2 tst-chk3 \ tst-lfschk1 tst-lfschk2 tst-lfschk3 test-strcpy_chk test-stpcpy_chk \ - tst-chk4 tst-chk5 tst-chk6 tst-lfschk4 tst-lfschk5 tst-lfschk6 + tst-chk4 tst-chk5 tst-chk6 tst-lfschk4 tst-lfschk5 tst-lfschk6 \ + tst-longjmp_chk2 extra-libs = libSegFault libpcprofile extra-libs-others = $(extra-libs) diff --git a/debug/tst-longjmp_chk2.c b/debug/tst-longjmp_chk2.c new file mode 100644 index 0000000000..22d8bf0941 --- /dev/null +++ b/debug/tst-longjmp_chk2.c @@ -0,0 +1,114 @@ +/* Test case mostly written by Paolo Bonzini . */ +#include +#include +#include +#include +#include +#include +#include +#include + + +static jmp_buf mainloop; +static sigset_t mainsigset; +static int pass; + + +static void +stackoverflow_handler (int sig) +{ + stack_t altstack; + pass++; + sigaltstack (NULL, &altstack); + /* Using printf is not really kosher in signal handlers but we know + it will work. */ + printf ("%*sin signal handler\n", pass, ""); + if (altstack.ss_flags & SS_ONSTACK) + printf ("%*son alternate stack\n", pass, ""); + siglongjmp (mainloop, pass); +} + + +static volatile int * +recurse_1 (int n, volatile int *p) +{ + if (n >= 0) + *recurse_1 (n + 1, p) += n; + return p; +} + + +static int +recurse (int n) +{ + int sum = 0; + return *recurse_1 (n, &sum); +} + + +static int +do_test (void) +{ + char mystack[SIGSTKSZ]; + stack_t altstack; + struct sigaction action; + sigset_t emptyset; + /* Before starting the endless recursion, try to be friendly to the user's + machine. On some Linux 2.2.x systems, there is no stack limit for user + processes at all. We don't want to kill such systems. */ + struct rlimit rl; + rl.rlim_cur = rl.rlim_max = 0x100000; /* 1 MB */ + setrlimit (RLIMIT_STACK, &rl); + /* Install the alternate stack. */ + altstack.ss_sp = mystack; + altstack.ss_size = sizeof (mystack); + altstack.ss_flags = 0; /* no SS_DISABLE */ + if (sigaltstack (&altstack, NULL) < 0) + { + puts ("first sigaltstack failed"); + return 0; + } + /* Install the SIGSEGV handler. */ + sigemptyset (&action.sa_mask); + action.sa_handler = &stackoverflow_handler; + action.sa_flags = SA_ONSTACK; + sigaction (SIGSEGV, &action, (struct sigaction *) NULL); + sigaction (SIGBUS, &action, (struct sigaction *) NULL); + + /* Save the current signal mask. */ + sigemptyset (&emptyset); + sigprocmask (SIG_BLOCK, &emptyset, &mainsigset); + + /* Provoke two stack overflows in a row. */ + if (sigsetjmp (mainloop, 1) != 0) + { + assert (pass != 0); + printf ("%*sout of signal handler\n", pass, ""); + } + else + assert (pass == 0); + + sigaltstack (NULL, &altstack); + if (altstack.ss_flags & SS_ONSTACK) + printf ("%*son alternate stack\n", pass, ""); + else + printf ("%*snot on alternate stack\n", pass, ""); + + if (pass < 2) + { + recurse (0); + puts ("recurse call returned"); + return 2; + } + + altstack.ss_flags |= SS_DISABLE; + if (sigaltstack (&altstack, NULL) == -1) + printf ("disabling alternate stack failed\n"); + else + printf ("disabling alternate stack succeeded \n"); + + return 0; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" From 85d9d2f3a089f747177895b115ca2186f34b0122 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Thu, 30 Jul 2009 19:46:46 -0700 Subject: [PATCH 04/19] Add CFLAGS definition missing from last patch. --- debug/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/debug/Makefile b/debug/Makefile index 99c8092074..d7c51ca85f 100644 --- a/debug/Makefile +++ b/debug/Makefile @@ -82,6 +82,8 @@ CFLAGS-recv_chk.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-recvfrom_chk.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-tst-longjmp_chk.c = -fexceptions -fasynchronous-unwind-tables \ -D_FORTIFY_SOURCE=1 +CFLAGS-tst-longjmp_chk2.c = -fexceptions -fasynchronous-unwind-tables \ + -D_FORTIFY_SOURCE=1 # We know these tests have problems with format strings, this is what # we are testing. Disable that warning. From 07df80996944b95a238be755eb4957a83a5e4762 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Thu, 30 Jul 2009 20:09:30 -0700 Subject: [PATCH 05/19] Optimize ____longjmp_chk for x86-64 a bit. --- sysdeps/x86_64/____longjmp_chk.S | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/sysdeps/x86_64/____longjmp_chk.S b/sysdeps/x86_64/____longjmp_chk.S index 50d2fca2c3..23aa0cb775 100644 --- a/sysdeps/x86_64/____longjmp_chk.S +++ b/sysdeps/x86_64/____longjmp_chk.S @@ -66,14 +66,12 @@ ENTRY(____longjmp_chk) cmpq %r8, %rsp jbe .Lok - subq $32, %rsp - cfi_adjust_cfa_offset(32) - movq %r10, 24(%rsp) + subq $24, %rsp + cfi_adjust_cfa_offset(24) xorl %edi, %edi movq %rsp, %rsi movl $__NR_sigaltstack, %eax syscall - movq 24(%rsp), %r10 testl %eax, %eax movl $0, %eax jne .Lok @@ -127,7 +125,7 @@ ENTRY(____longjmp_chk) .Lfail: xchgq %r8, %rsp /* We want the stack trace to show that of the caller. */ - cfi_def_cfa(%rsp, 40) + cfi_def_cfa(%rsp, 32) cfi_restore(%rsp) cfi_register(%rbp, %r9) cfi_restore(%rip) From 8e80581787d2342824d9b70d238e646326776c31 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Thu, 30 Jul 2009 21:29:27 -0700 Subject: [PATCH 06/19] Change code a bit to correct CFI. --- sysdeps/x86_64/____longjmp_chk.S | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sysdeps/x86_64/____longjmp_chk.S b/sysdeps/x86_64/____longjmp_chk.S index 23aa0cb775..80e4aff36d 100644 --- a/sysdeps/x86_64/____longjmp_chk.S +++ b/sysdeps/x86_64/____longjmp_chk.S @@ -74,6 +74,8 @@ ENTRY(____longjmp_chk) syscall testl %eax, %eax movl $0, %eax + leaq 24(%rsp), %rsp + cfi_adjust_cfa_offset(-24) jne .Lok movl 8(%rsp), %eax andl $1, %eax @@ -125,7 +127,7 @@ ENTRY(____longjmp_chk) .Lfail: xchgq %r8, %rsp /* We want the stack trace to show that of the caller. */ - cfi_def_cfa(%rsp, 32) + cfi_def_cfa(%rsp, 8) cfi_restore(%rsp) cfi_register(%rbp, %r9) cfi_restore(%rip) From 98b1e6c8668259044a20a016a5a5957b226ce04b Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Thu, 30 Jul 2009 21:42:27 -0700 Subject: [PATCH 07/19] ____longjmp_chk is now OS-specific. We use sigaltstack internally which on some systems is a syscall and should be used as such. Move the x86-64 version to the Linux specific directory and create in its place a file which always causes compile errors. --- ChangeLog | 5 + .../unix/sysv/linux/x86_64/____longjmp_chk.S | 145 +++++++++++++++++ sysdeps/x86_64/____longjmp_chk.S | 146 +----------------- 3 files changed, 151 insertions(+), 145 deletions(-) create mode 100644 sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S diff --git a/ChangeLog b/ChangeLog index db6e93d11d..9e8f88371b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2009-07-30 Ulrich Drepper + * sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S: New file. Content + comes from... + * sysdeps/x86_64/____longjmp_chk.S: ...here. This is now a file + which always causes a compile error. + * debug/Makefile (tests): Add tst-longjmp_chk2. * debug/tst-longjmp_chk2.c: New file. diff --git a/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S b/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S new file mode 100644 index 0000000000..80e4aff36d --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S @@ -0,0 +1,145 @@ +/* Copyright (C) 2001,2004,2005,2006,2009 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include +#include + + .section .rodata.str1.1,"aMS",@progbits,1 + .type longjmp_msg,@object +longjmp_msg: + .string "longjmp causes uninitialized stack frame" + .size longjmp_msg, .-longjmp_msg + + +//#define __longjmp ____longjmp_chk + +#ifdef PIC +# define CALL_FAIL leaq longjmp_msg(%rip), %rdi; \ + call __GI___fortify_fail +#else +# define CALL_FAIL movq $longjmp_msg, %rdi; \ + call __fortify_fail +#endif + +#define CHECK_RSP(reg) \ + cmpq reg, %rsp; \ + jbe .Lok; \ + CALL_FAIL; \ +.Lok: + +/* Jump to the position specified by ENV, causing the + setjmp call there to return VAL, or 1 if VAL is 0. + void __longjmp (__jmp_buf env, int val). */ + .text +ENTRY(____longjmp_chk) + /* Restore registers. */ + movq (JB_RSP*8)(%rdi),%r8 + movq (JB_RBP*8)(%rdi),%r9 + movq (JB_PC*8)(%rdi),%rdx +#ifdef PTR_DEMANGLE + PTR_DEMANGLE (%r8) + PTR_DEMANGLE (%r9) + PTR_DEMANGLE (%rdx) +#endif + + /* Save function parameters. */ + movq %rdi, %r10 + movl %esi, %ecx + + xorl %eax, %eax + cmpq %r8, %rsp + jbe .Lok + + subq $24, %rsp + cfi_adjust_cfa_offset(24) + xorl %edi, %edi + movq %rsp, %rsi + movl $__NR_sigaltstack, %eax + syscall + testl %eax, %eax + movl $0, %eax + leaq 24(%rsp), %rsp + cfi_adjust_cfa_offset(-24) + jne .Lok + movl 8(%rsp), %eax + andl $1, %eax + +.Lok: + /* We add unwind information for the target here. */ + cfi_def_cfa(%r10, 0) + cfi_register(%rsp,%r8) + cfi_register(%rbp,%r9) + cfi_register(%rip,%rdx) + cfi_offset(%rbx,JB_RBX*8) + cfi_offset(%r12,JB_R12*8) + cfi_offset(%r13,JB_R13*8) + cfi_offset(%r14,JB_R14*8) + cfi_offset(%r15,JB_R15*8) + + xchgq %r8, %rsp + cfi_restore(%rsp) + xchgq %r9, %rbp + cfi_restore(%rbp) + + movq (JB_RBX*8)(%r10),%rbx + movq (JB_R12*8)(%r10),%r12 + movq (JB_R13*8)(%r10),%r13 + movq (JB_R14*8)(%r10),%r14 + movq (JB_R15*8)(%r10),%r15 + + cmpq %rsp, %r8 + jnbe .Lcheck + + /* Set return value for setjmp. */ +.Lout: movl %ecx, %eax + jmpq *%rdx + +.Lcheck: + testl %eax, %eax + je .Lfail + + subq $24, %rsp + cfi_adjust_cfa_offset(24) + xorl %edi, %edi + movq %rsp, %rsi + movl $__NR_sigaltstack, %eax + syscall + addq $24, %rsp + cfi_adjust_cfa_offset(-24) + testl $1, 8(%rsp) + je .Lout + +.Lfail: xchgq %r8, %rsp + /* We want the stack trace to show that of the caller. */ + cfi_def_cfa(%rsp, 8) + cfi_restore(%rsp) + cfi_register(%rbp, %r9) + cfi_restore(%rip) + cfi_restore(%rbx) + cfi_restore(%r12) + cfi_restore(%r13) + cfi_restore(%r14) + cfi_restore(%r15) + + xchgq %r9, %rbp + cfi_restore(%rbp) + + CALL_FAIL + hlt +END (BP_SYM (____longjmp_chk)) diff --git a/sysdeps/x86_64/____longjmp_chk.S b/sysdeps/x86_64/____longjmp_chk.S index 80e4aff36d..0910861a9d 100644 --- a/sysdeps/x86_64/____longjmp_chk.S +++ b/sysdeps/x86_64/____longjmp_chk.S @@ -1,145 +1 @@ -/* Copyright (C) 2001,2004,2005,2006,2009 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, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include -#include -#include - - .section .rodata.str1.1,"aMS",@progbits,1 - .type longjmp_msg,@object -longjmp_msg: - .string "longjmp causes uninitialized stack frame" - .size longjmp_msg, .-longjmp_msg - - -//#define __longjmp ____longjmp_chk - -#ifdef PIC -# define CALL_FAIL leaq longjmp_msg(%rip), %rdi; \ - call __GI___fortify_fail -#else -# define CALL_FAIL movq $longjmp_msg, %rdi; \ - call __fortify_fail -#endif - -#define CHECK_RSP(reg) \ - cmpq reg, %rsp; \ - jbe .Lok; \ - CALL_FAIL; \ -.Lok: - -/* Jump to the position specified by ENV, causing the - setjmp call there to return VAL, or 1 if VAL is 0. - void __longjmp (__jmp_buf env, int val). */ - .text -ENTRY(____longjmp_chk) - /* Restore registers. */ - movq (JB_RSP*8)(%rdi),%r8 - movq (JB_RBP*8)(%rdi),%r9 - movq (JB_PC*8)(%rdi),%rdx -#ifdef PTR_DEMANGLE - PTR_DEMANGLE (%r8) - PTR_DEMANGLE (%r9) - PTR_DEMANGLE (%rdx) -#endif - - /* Save function parameters. */ - movq %rdi, %r10 - movl %esi, %ecx - - xorl %eax, %eax - cmpq %r8, %rsp - jbe .Lok - - subq $24, %rsp - cfi_adjust_cfa_offset(24) - xorl %edi, %edi - movq %rsp, %rsi - movl $__NR_sigaltstack, %eax - syscall - testl %eax, %eax - movl $0, %eax - leaq 24(%rsp), %rsp - cfi_adjust_cfa_offset(-24) - jne .Lok - movl 8(%rsp), %eax - andl $1, %eax - -.Lok: - /* We add unwind information for the target here. */ - cfi_def_cfa(%r10, 0) - cfi_register(%rsp,%r8) - cfi_register(%rbp,%r9) - cfi_register(%rip,%rdx) - cfi_offset(%rbx,JB_RBX*8) - cfi_offset(%r12,JB_R12*8) - cfi_offset(%r13,JB_R13*8) - cfi_offset(%r14,JB_R14*8) - cfi_offset(%r15,JB_R15*8) - - xchgq %r8, %rsp - cfi_restore(%rsp) - xchgq %r9, %rbp - cfi_restore(%rbp) - - movq (JB_RBX*8)(%r10),%rbx - movq (JB_R12*8)(%r10),%r12 - movq (JB_R13*8)(%r10),%r13 - movq (JB_R14*8)(%r10),%r14 - movq (JB_R15*8)(%r10),%r15 - - cmpq %rsp, %r8 - jnbe .Lcheck - - /* Set return value for setjmp. */ -.Lout: movl %ecx, %eax - jmpq *%rdx - -.Lcheck: - testl %eax, %eax - je .Lfail - - subq $24, %rsp - cfi_adjust_cfa_offset(24) - xorl %edi, %edi - movq %rsp, %rsi - movl $__NR_sigaltstack, %eax - syscall - addq $24, %rsp - cfi_adjust_cfa_offset(-24) - testl $1, 8(%rsp) - je .Lout - -.Lfail: xchgq %r8, %rsp - /* We want the stack trace to show that of the caller. */ - cfi_def_cfa(%rsp, 8) - cfi_restore(%rsp) - cfi_register(%rbp, %r9) - cfi_restore(%rip) - cfi_restore(%rbx) - cfi_restore(%r12) - cfi_restore(%r13) - cfi_restore(%r14) - cfi_restore(%r15) - - xchgq %r9, %rbp - cfi_restore(%rbp) - - CALL_FAIL - hlt -END (BP_SYM (____longjmp_chk)) +#error "OS-specific version needed" From da97dfdcfa0ecbbf2d455c54a08bb9223ce1fc18 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Thu, 30 Jul 2009 21:50:14 -0700 Subject: [PATCH 08/19] Add sigstack handling to Linux ____longjmp_chk on i386. All other i386 ports need to provide their own versions. --- ChangeLog | 6 + sysdeps/i386/____longjmp_chk.S | 46 +----- sysdeps/i386/__longjmp.S | 22 +-- .../unix/sysv/linux/i386/____longjmp_chk.S | 143 ++++++++++++++++++ 4 files changed, 156 insertions(+), 61 deletions(-) create mode 100644 sysdeps/unix/sysv/linux/i386/____longjmp_chk.S diff --git a/ChangeLog b/ChangeLog index 9e8f88371b..eca461fc79 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2009-07-30 Ulrich Drepper + * sysdeps/unix/sysv/linux/i386/____longjmp_chk.S: New file. + * sysdeps/i386/____longjmp_chk.S: Remove all code. This is now a file + which always causes a compile error. + + * sysdeps/i386/__longjmp.S: Remove bound-checking pointer support. + * sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S: New file. Content comes from... * sysdeps/x86_64/____longjmp_chk.S: ...here. This is now a file diff --git a/sysdeps/i386/____longjmp_chk.S b/sysdeps/i386/____longjmp_chk.S index 6cd74968a2..0910861a9d 100644 --- a/sysdeps/i386/____longjmp_chk.S +++ b/sysdeps/i386/____longjmp_chk.S @@ -1,45 +1 @@ -/* Copyright (C) 2001,2004,2005,2006,2009 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, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - - .section .rodata.str1.1,"aMS",@progbits,1 - .type longjmp_msg,@object -longjmp_msg: - .string "longjmp causes uninitialized stack frame" - .size longjmp_msg, .-longjmp_msg - - -#define __longjmp ____longjmp_chk - -#ifdef PIC -# define CALL_FAIL movl %ebx, %ecx; \ - cfi_register(%ebx,%ecx); \ - LOAD_PIC_REG (bx); \ - leal longjmp_msg@GOTOFF(%ebx), %eax; \ - call __GI___fortify_fail@PLT -#else -# define CALL_FAIL movl $longjmp_msg, %eax; \ - call __fortify_fail -#endif - -#define CHECK_ESP(reg) \ - cmpl reg, %esp; \ - jbe .Lok; \ - CALL_FAIL; \ -.Lok: - -#include "__longjmp.S" +#error "OS-specific version needed" diff --git a/sysdeps/i386/__longjmp.S b/sysdeps/i386/__longjmp.S index 8b0732056a..f2eeeec04e 100644 --- a/sysdeps/i386/__longjmp.S +++ b/sysdeps/i386/__longjmp.S @@ -21,20 +21,11 @@ #include #include #include -#include -#include - -#define PARMS LINKAGE /* no space for saved regs */ -#define JBUF PARMS -#define VAL JBUF+PTR_SIZE .text -ENTRY (BP_SYM (__longjmp)) - ENTER - +ENTRY (__longjmp) #ifdef PTR_DEMANGLE - movl JBUF(%esp), %eax /* User's jmp_buf in %eax. */ - CHECK_BOUNDS_BOTH_WIDE (%eax, JBUF(%esp), $JB_SIZE) + movl 4(%esp), %eax /* User's jmp_buf in %eax. */ /* Save the return address now. */ movl (JB_PC*4)(%eax), %edx @@ -62,18 +53,17 @@ ENTRY (BP_SYM (__longjmp)) cfi_restore(%edi) cfi_restore(%ebp) - movl VAL(%esp), %eax /* Second argument is return value. */ + movl 8(%esp), %eax /* Second argument is return value. */ movl %ecx, %esp #else - movl JBUF(%esp), %ecx /* User's jmp_buf in %ecx. */ - CHECK_BOUNDS_BOTH_WIDE (%ecx, JBUF(%esp), $JB_SIZE) + movl 4(%esp), %ecx /* User's jmp_buf in %ecx. */ # ifdef CHECK_ESP movl (JB_SP*4)(%ecx), %eax CHECK_ESP (%eax) # endif - movl VAL(%esp), %eax /* Second argument is return value. */ + movl 8(%esp), %eax /* Second argument is return value. */ /* Save the return address now. */ movl (JB_PC*4)(%ecx), %edx /* Restore registers. */ @@ -85,4 +75,4 @@ ENTRY (BP_SYM (__longjmp)) #endif /* Jump to saved PC. */ jmp *%edx -END (BP_SYM (__longjmp)) +END (__longjmp) diff --git a/sysdeps/unix/sysv/linux/i386/____longjmp_chk.S b/sysdeps/unix/sysv/linux/i386/____longjmp_chk.S new file mode 100644 index 0000000000..02c401c236 --- /dev/null +++ b/sysdeps/unix/sysv/linux/i386/____longjmp_chk.S @@ -0,0 +1,143 @@ +/* Copyright (C) 2001,2004,2005,2006,2009 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include +#include + + + .section .rodata.str1.1,"aMS",@progbits,1 + .type longjmp_msg,@object +longjmp_msg: + .string "longjmp causes uninitialized stack frame" + .size longjmp_msg, .-longjmp_msg + + +#ifdef PIC +# define CALL_FAIL movl %ebx, %ecx; \ + cfi_register(%ebx,%ecx); \ + LOAD_PIC_REG (bx); \ + leal longjmp_msg@GOTOFF(%ebx), %eax; \ + call __GI___fortify_fail@PLT +#else +# define CALL_FAIL movl $longjmp_msg, %eax; \ + call __fortify_fail +#endif + +#define CHECK_ESP(reg) \ + cmpl reg, %esp; \ + jbe .Lok; \ + CALL_FAIL; \ +.Lok: + + + .text +ENTRY (____longjmp_chk) + movl 4(%esp), %ecx /* User's jmp_buf in %ecx. */ + + /* Save the return address now. */ + movl (JB_PC*4)(%ecx), %edx + /* Get the stack pointer. */ + movl (JB_SP*4)(%ecx), %edi + cfi_undefined(%edi) + PTR_DEMANGLE (%edx) + PTR_DEMANGLE (%edi) + + pushl $0 + cfi_adjust_cfa_offset(4) + cmpl %edi, %esp + jbe .Lok + + subl $12, %esp + cfi_adjust_cfa_offset(12) + xorl %ebx, %ebx + movl %esp, %ecx + movl $__NR_sigaltstack, %eax + ENTER_KERNEL + movl 4(%esp), %ebx + addl $12, %esp + cfi_adjust_cfa_offset(-12) + movl 8(%esp), %ecx + testl %eax, %eax + jne .Lok + andl $1, %ebx + movl %ebx, (%esp) +.Lok: + cfi_def_cfa(%ecx, 0) + cfi_register(%eip, %edx) + cfi_register(%esp, %edi) + cfi_offset(%ebx, JB_BX*4) + cfi_offset(%esi, JB_SI*4) + cfi_offset(%edi, JB_DI*4) + cfi_offset(%ebp, JB_BP*4) + + movl 12(%esp), %eax /* Second argument is return value. */ + xchgl %edi, %esp + cfi_restore(%edi) + + cmpl %esp, %edi + jnbe .Lcheck + + /* Restore registers. */ +.Lout: movl (JB_BX*4)(%ecx), %ebx + movl (JB_SI*4)(%ecx), %esi + movl (JB_DI*4)(%ecx), %edi + movl (JB_BP*4)(%ecx), %ebp + cfi_restore(%ebx) + cfi_restore(%esi) + cfi_restore(%edi) + cfi_restore(%ebp) + + /* Jump to saved PC. */ + jmp *%edx + + cfi_def_cfa(%ecx, 0) + cfi_register(%eip, %edx) + cfi_offset(%ebx, JB_BX*4) + cfi_offset(%esi, JB_SI*4) + cfi_offset(%edi, JB_DI*4) + cfi_offset(%ebp, JB_BP*4) + +.Lcheck: + cmpl $0, (%edi) + je .Lfail + + subl $12, %esp + cfi_adjust_cfa_offset(12) + xorl %ebx, %ebx + movl %esp, %ecx + movl $__NR_sigaltstack, %eax + ENTER_KERNEL + testl $1, 4(%esp) + leal 12(%esp), %esp + movl 8(%edi), %ecx + movl 12(%edi), %eax + cfi_adjust_cfa_offset(-12) + je .Lout + +.Lfail: xchgl %edi, %esp + cfi_def_cfa(%esp, 8) + cfi_restore(%esp) + cfi_restore(%ebx) + cfi_restore(%esi) + cfi_undefined(%edi) + cfi_restore(%ebp) + + CALL_FAIL + hlt +END (____longjmp_chk) From 57dbdb9f07fb20d5dd765c5dc91e31cb67d08b7e Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Thu, 30 Jul 2009 21:51:56 -0700 Subject: [PATCH 09/19] Whitespace cleanup. --- sysdeps/unix/sysv/linux/i386/____longjmp_chk.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sysdeps/unix/sysv/linux/i386/____longjmp_chk.S b/sysdeps/unix/sysv/linux/i386/____longjmp_chk.S index 02c401c236..b07e972468 100644 --- a/sysdeps/unix/sysv/linux/i386/____longjmp_chk.S +++ b/sysdeps/unix/sysv/linux/i386/____longjmp_chk.S @@ -93,7 +93,7 @@ ENTRY (____longjmp_chk) cmpl %esp, %edi jnbe .Lcheck - /* Restore registers. */ + /* Restore registers. */ .Lout: movl (JB_BX*4)(%ecx), %ebx movl (JB_SI*4)(%ecx), %esi movl (JB_DI*4)(%ecx), %edi @@ -104,7 +104,7 @@ ENTRY (____longjmp_chk) cfi_restore(%ebp) /* Jump to saved PC. */ - jmp *%edx + jmp *%edx cfi_def_cfa(%ecx, 0) cfi_register(%eip, %edx) From 5b938b2543c991be88a06fd7438f804d05358ac1 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Fri, 31 Jul 2009 07:20:45 -0700 Subject: [PATCH 10/19] Remove CHEC_ESP handling from i386 __longjmp. --- sysdeps/i386/__longjmp.S | 9 --------- 1 file changed, 9 deletions(-) diff --git a/sysdeps/i386/__longjmp.S b/sysdeps/i386/__longjmp.S index f2eeeec04e..5ff7a73cea 100644 --- a/sysdeps/i386/__longjmp.S +++ b/sysdeps/i386/__longjmp.S @@ -33,9 +33,6 @@ ENTRY (__longjmp) movl (JB_SP*4)(%eax), %ecx PTR_DEMANGLE (%edx) PTR_DEMANGLE (%ecx) -# ifdef CHECK_ESP - CHECK_ESP (%ecx) -# endif cfi_def_cfa(%eax, 0) cfi_register(%eip, %edx) cfi_register(%esp, %ecx) @@ -57,12 +54,6 @@ ENTRY (__longjmp) movl %ecx, %esp #else movl 4(%esp), %ecx /* User's jmp_buf in %ecx. */ - -# ifdef CHECK_ESP - movl (JB_SP*4)(%ecx), %eax - CHECK_ESP (%eax) -# endif - movl 8(%esp), %eax /* Second argument is return value. */ /* Save the return address now. */ movl (JB_PC*4)(%ecx), %edx From 1877ea16ca0714abd715d6ce0aa1b840c3850241 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Fri, 31 Jul 2009 07:26:36 -0700 Subject: [PATCH 11/19] Fix obstack* on i?86 obstack calls several callbacks, so on i?86 it'd better be compiled without -mpreferred-stack-boundary=2, otherwise the callbacks are called with misaligned stack. --- ChangeLog | 4 ++++ malloc/Makefile | 1 + 2 files changed, 5 insertions(+) diff --git a/ChangeLog b/ChangeLog index eca461fc79..2ff87e5335 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2009-07-31 Jakub Jelinek + + * malloc/Makefile (CFLAGS-obstack.c): Add $(uses-callbacks). + 2009-07-30 Ulrich Drepper * sysdeps/unix/sysv/linux/i386/____longjmp_chk.S: New file. diff --git a/malloc/Makefile b/malloc/Makefile index 1099335fff..e7ec1abf93 100644 --- a/malloc/Makefile +++ b/malloc/Makefile @@ -104,6 +104,7 @@ $(objpfx)memusagestat: $(memusagestat-modules:%=$(objpfx)%.o) include ../Rules CFLAGS-mcheck-init.c = $(PIC-ccflag) +CFLAGS-obstack.c = $(uses-callbacks) $(objpfx)libmcheck.a: $(objpfx)mcheck-init.o -rm -f $@ From 6f6f1215f68e5ae15ad18373234815fe7b2acc9e Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Fri, 31 Jul 2009 11:53:35 -0700 Subject: [PATCH 12/19] Support multiarch for i686. This patch adds multiarch support when configured for i686. I modified some x86-64 functions to support 32bit. I will contribute 32bit SSE string and memory functions later. --- ChangeLog | 30 +++++++ sysdeps/i386/i686/Makefile | 4 + sysdeps/i386/i686/cacheinfo.c | 8 ++ sysdeps/i386/i686/multiarch/Makefile | 4 + sysdeps/i386/i686/multiarch/ifunc-defines.sym | 17 ++++ sysdeps/i386/i686/multiarch/init-arch.c | 3 + sysdeps/i386/i686/multiarch/init-arch.h | 1 + sysdeps/i386/i686/multiarch/sched_cpucount.c | 1 + sysdeps/unix/sysv/linux/i386/i686/sysconf.c | 1 + sysdeps/x86_64/cacheinfo.c | 79 ++++++++++--------- sysdeps/x86_64/multiarch/init-arch.c | 18 ++--- sysdeps/x86_64/multiarch/init-arch.h | 6 ++ sysdeps/x86_64/multiarch/sched_cpucount.c | 2 +- 13 files changed, 125 insertions(+), 49 deletions(-) create mode 100644 sysdeps/i386/i686/cacheinfo.c create mode 100644 sysdeps/i386/i686/multiarch/Makefile create mode 100644 sysdeps/i386/i686/multiarch/ifunc-defines.sym create mode 100644 sysdeps/i386/i686/multiarch/init-arch.c create mode 100644 sysdeps/i386/i686/multiarch/init-arch.h create mode 100644 sysdeps/i386/i686/multiarch/sched_cpucount.c create mode 100644 sysdeps/unix/sysv/linux/i386/i686/sysconf.c diff --git a/ChangeLog b/ChangeLog index 2ff87e5335..8759b2c08d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,33 @@ +2009-07-31 H.J. Lu + + * sysdeps/i386/i686/Makefile (sysdep_routines): Add cacheinfo. + * sysdeps/i386/i686/cacheinfo.c: New file. + * sysdeps/i386/i686/multiarch/Makefile: New file. + * sysdeps/i386/i686/multiarch/ifunc-defines.sym: New file. + * sysdeps/i386/i686/multiarch/init-arch.c: New file. + * sysdeps/i386/i686/multiarch/init-arch.h: New file. + * sysdeps/i386/i686/multiarch/sched_cpucount.c: New file. + * sysdeps/unix/sysv/linux/i386/i686/sysconf.c: New file. + * sysdeps/x86_64/cacheinfo.c: Include . + (__cpuid_count): New. Provide the default. + (__x86_64_prefetchw): Define only if DISABLE_PREFETCHW is not defined. + (__x86_64_preferred_memory_instruction): Define only if + DISABLE_PREFERRED_MEMORY_INSTRUCTION is not defined. + (intel_check_word): Use __cpuid. + (handle_intel): Likewise. + (handle_amd): Likewise. + (__cache_sysconf): Likewise. + (init_cacheinfo): Updated. Use __cpuid and __cpuid_count. + (__cache_sysconf): Likewise. + (init_cacheinfo): Updated. Use __cpuid and __cpuid_count. + * sysdeps/x86_64/multiarch/init-arch.c: Include . + (get_common_indeces): Use __cpuid. + (__init_cpu_features): Likewise. Disable SSSE3 on Atom only + if ENABLE_SSSE3_ON_ATOM is not defined. + * sysdeps/x86_64/multiarch/init-arch.h (HAS_SSE2): Define. + * sysdeps/x86_64/multiarch/sched_cpucount.c (POPCNT): Use + popcnt instead of popcntq. + 2009-07-31 Jakub Jelinek * malloc/Makefile (CFLAGS-obstack.c): Add $(uses-callbacks). diff --git a/sysdeps/i386/i686/Makefile b/sysdeps/i386/i686/Makefile index c7378ab21e..dbcf1c33d3 100644 --- a/sysdeps/i386/i686/Makefile +++ b/sysdeps/i386/i686/Makefile @@ -5,3 +5,7 @@ endif # So that we can test __m128's alignment stack-align-test-flags += -msse + +ifeq ($(subdir),string) +sysdep_routines += cacheinfo +endif diff --git a/sysdeps/i386/i686/cacheinfo.c b/sysdeps/i386/i686/cacheinfo.c new file mode 100644 index 0000000000..82e4cd223e --- /dev/null +++ b/sysdeps/i386/i686/cacheinfo.c @@ -0,0 +1,8 @@ +#define __x86_64_data_cache_size_half __x86_data_cache_size_half +#define __x86_64_shared_cache_size __x86_shared_cache_size +#define __x86_64_shared_cache_size_half __x86_shared_cache_size_half + +#define DISABLE_PREFETCHW +#define DISABLE_PREFERRED_MEMORY_INSTRUCTION + +#include diff --git a/sysdeps/i386/i686/multiarch/Makefile b/sysdeps/i386/i686/multiarch/Makefile new file mode 100644 index 0000000000..33d98c36e6 --- /dev/null +++ b/sysdeps/i386/i686/multiarch/Makefile @@ -0,0 +1,4 @@ +ifeq ($(subdir),csu) +aux += init-arch +gen-as-const-headers += ifunc-defines.sym +endif diff --git a/sysdeps/i386/i686/multiarch/ifunc-defines.sym b/sysdeps/i386/i686/multiarch/ifunc-defines.sym new file mode 100644 index 0000000000..e2021cdf87 --- /dev/null +++ b/sysdeps/i386/i686/multiarch/ifunc-defines.sym @@ -0,0 +1,17 @@ +#include "init-arch.h" +#include + +-- + +CPU_FEATURES_SIZE sizeof (struct cpu_features) +KIND_OFFSET offsetof (struct cpu_features, kind) +CPUID_OFFSET offsetof (struct cpu_features, cpuid) +CPUID_SIZE sizeof (struct cpuid_registers) +CPUID_EAX_OFFSET offsetof (struct cpuid_registers, eax) +CPUID_EBX_OFFSET offsetof (struct cpuid_registers, ebx) +CPUID_ECX_OFFSET offsetof (struct cpuid_registers, ecx) +CPUID_EDX_OFFSET offsetof (struct cpuid_registers, edx) +FAMILY_OFFSET offsetof (struct cpu_features, family) +MODEL_OFFSET offsetof (struct cpu_features, model) + +COMMON_CPUID_INDEX_1 diff --git a/sysdeps/i386/i686/multiarch/init-arch.c b/sysdeps/i386/i686/multiarch/init-arch.c new file mode 100644 index 0000000000..b371bae1dc --- /dev/null +++ b/sysdeps/i386/i686/multiarch/init-arch.c @@ -0,0 +1,3 @@ +#define ENABLE_SSSE3_ON_ATOM + +#include diff --git a/sysdeps/i386/i686/multiarch/init-arch.h b/sysdeps/i386/i686/multiarch/init-arch.h new file mode 100644 index 0000000000..cd2d0befee --- /dev/null +++ b/sysdeps/i386/i686/multiarch/init-arch.h @@ -0,0 +1 @@ +#include diff --git a/sysdeps/i386/i686/multiarch/sched_cpucount.c b/sysdeps/i386/i686/multiarch/sched_cpucount.c new file mode 100644 index 0000000000..7db31b02f8 --- /dev/null +++ b/sysdeps/i386/i686/multiarch/sched_cpucount.c @@ -0,0 +1 @@ +#include diff --git a/sysdeps/unix/sysv/linux/i386/i686/sysconf.c b/sysdeps/unix/sysv/linux/i386/i686/sysconf.c new file mode 100644 index 0000000000..cf79750de3 --- /dev/null +++ b/sysdeps/unix/sysv/linux/i386/i686/sysconf.c @@ -0,0 +1 @@ +#include diff --git a/sysdeps/x86_64/cacheinfo.c b/sysdeps/x86_64/cacheinfo.c index 75b81958dd..f252fc2c6c 100644 --- a/sysdeps/x86_64/cacheinfo.c +++ b/sysdeps/x86_64/cacheinfo.c @@ -22,6 +22,26 @@ #include #include #include +#include + +#ifndef __cpuid_count +/* FIXME: Provide __cpuid_count if it isn't defined. Copied from gcc + 4.4.0. Remove this if gcc 4.4 is the minimum requirement. */ +# if defined(__i386__) && defined(__PIC__) +/* %ebx may be the PIC register. */ +# define __cpuid_count(level, count, a, b, c, d) \ + __asm__ ("xchg{l}\t{%%}ebx, %1\n\t" \ + "cpuid\n\t" \ + "xchg{l}\t{%%}ebx, %1\n\t" \ + : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \ + : "0" (level), "2" (count)) +# else +# define __cpuid_count(level, count, a, b, c, d) \ + __asm__ ("cpuid\n\t" \ + : "=a" (a), "=b" (b), "=c" (c), "=d" (d) \ + : "0" (level), "2" (count)) +# endif +#endif #ifdef USE_MULTIARCH # include "multiarch/init-arch.h" @@ -176,9 +196,7 @@ intel_check_word (int name, unsigned int value, bool *has_level_2, unsigned int ebx; unsigned int ecx; unsigned int edx; - asm volatile ("cpuid" - : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) - : "0" (1)); + __cpuid (1, eax, ebx, ecx, edx); family = ((eax >> 20) & 0xff) + ((eax >> 8) & 0xf); model = (((eax >>16) & 0xf) << 4) + ((eax >> 4) & 0xf); @@ -250,9 +268,7 @@ handle_intel (int name, unsigned int maxidx) unsigned int ebx; unsigned int ecx; unsigned int edx; - asm volatile ("cpuid" - : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) - : "0" (2)); + __cpuid (2, eax, ebx, ecx, edx); /* The low byte of EAX in the first round contain the number of rounds we have to make. At least one, the one we are already @@ -296,9 +312,7 @@ handle_amd (int name) unsigned int ebx; unsigned int ecx; unsigned int edx; - asm volatile ("cpuid" - : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) - : "0" (0x80000000)); + __cpuid (0x80000000, eax, ebx, ecx, edx); /* No level 4 cache (yet). */ if (name > _SC_LEVEL3_CACHE_LINESIZE) @@ -308,9 +322,7 @@ handle_amd (int name) if (eax < fn) return 0; - asm volatile ("cpuid" - : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) - : "0" (fn)); + __cpuid (fn, eax, ebx, ecx, edx); if (name < _SC_LEVEL1_DCACHE_SIZE) { @@ -424,9 +436,7 @@ __cache_sysconf (int name) unsigned int ebx; unsigned int ecx; unsigned int edx; - asm volatile ("cpuid" - : "=a" (max_cpuid), "=b" (ebx), "=c" (ecx), "=d" (edx) - : "0" (0)); + __cpuid (0, max_cpuid, ebx, ecx, edx); #endif if (is_intel) @@ -449,9 +459,13 @@ long int __x86_64_data_cache_size_half attribute_hidden = 32 * 1024 / 2; L2 or L3 size. */ long int __x86_64_shared_cache_size_half attribute_hidden = 1024 * 1024 / 2; long int __x86_64_shared_cache_size attribute_hidden = 1024 * 1024; + +#ifndef DISABLE_PREFETCHW /* PREFETCHW support flag for use in memory and string routines. */ int __x86_64_prefetchw attribute_hidden; +#endif +#ifndef DISABLE_PREFERRED_MEMORY_INSTRUCTION /* Instructions preferred for memory and string routines. 0: Regular instructions @@ -461,6 +475,7 @@ int __x86_64_prefetchw attribute_hidden; */ int __x86_64_preferred_memory_instruction attribute_hidden; +#endif static void @@ -483,9 +498,7 @@ init_cacheinfo (void) __init_cpu_features (); #else int max_cpuid; - asm volatile ("cpuid" - : "=a" (max_cpuid), "=b" (ebx), "=c" (ecx), "=d" (edx) - : "0" (0)); + __cpuid (0, max_cpuid, ebx, ecx, edx); #endif if (is_intel) @@ -509,17 +522,17 @@ init_cacheinfo (void) ecx = __cpu_features.cpuid[COMMON_CPUID_INDEX_1].ecx; edx = __cpu_features.cpuid[COMMON_CPUID_INDEX_1].edx; #else - asm volatile ("cpuid" - : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) - : "0" (1)); + __cpuid (1, eax, ebx, ecx, edx); #endif +#ifndef DISABLE_PREFERRED_MEMORY_INSTRUCTION /* Intel prefers SSSE3 instructions for memory/string routines if they are avaiable. */ if ((ecx & 0x200)) __x86_64_preferred_memory_instruction = 3; else __x86_64_preferred_memory_instruction = 2; +#endif /* Figure out the number of logical threads that share the highest cache level. */ @@ -530,9 +543,7 @@ init_cacheinfo (void) /* Query until desired cache level is enumerated. */ do { - asm volatile ("cpuid" - : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) - : "0" (4), "2" (i++)); + __cpuid_count (4, i++, eax, ebx, ecx, edx); /* There seems to be a bug in at least some Pentium Ds which sometimes fail to iterate all cache parameters. @@ -566,9 +577,7 @@ init_cacheinfo (void) shared = handle_amd (_SC_LEVEL3_CACHE_SIZE); /* Get maximum extended function. */ - asm volatile ("cpuid" - : "=a" (max_cpuid_ex), "=b" (ebx), "=c" (ecx), "=d" (edx) - : "0" (0x80000000)); + __cpuid (0x80000000, max_cpuid_ex, ebx, ecx, edx); if (shared <= 0) /* No shared L3 cache. All we have is the L2 cache. */ @@ -579,10 +588,7 @@ init_cacheinfo (void) if (max_cpuid_ex >= 0x80000008) { /* Get width of APIC ID. */ - asm volatile ("cpuid" - : "=a" (max_cpuid_ex), "=b" (ebx), "=c" (ecx), - "=d" (edx) - : "0" (0x80000008)); + __cpuid (0x80000008, max_cpuid_ex, ebx, ecx, edx); threads = 1 << ((ecx >> 12) & 0x0f); } @@ -590,10 +596,7 @@ init_cacheinfo (void) { /* If APIC ID width is not available, use logical processor count. */ - asm volatile ("cpuid" - : "=a" (max_cpuid_ex), "=b" (ebx), "=c" (ecx), - "=d" (edx) - : "0" (0x00000001)); + __cpuid (0x00000001, max_cpuid_ex, ebx, ecx, edx); if ((edx & (1 << 28)) != 0) threads = (ebx >> 16) & 0xff; @@ -608,15 +611,15 @@ init_cacheinfo (void) shared += core; } +#ifndef DISABLE_PREFETCHW if (max_cpuid_ex >= 0x80000001) { - asm volatile ("cpuid" - : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) - : "0" (0x80000001)); + __cpuid (0x80000001, eax, ebx, ecx, edx); /* PREFETCHW || 3DNow! */ if ((ecx & 0x100) || (edx & 0x80000000)) __x86_64_prefetchw = -1; } +#endif } if (data > 0) diff --git a/sysdeps/x86_64/multiarch/init-arch.c b/sysdeps/x86_64/multiarch/init-arch.c index 49b421eac8..c152ab29eb 100644 --- a/sysdeps/x86_64/multiarch/init-arch.c +++ b/sysdeps/x86_64/multiarch/init-arch.c @@ -18,6 +18,7 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#include #include "init-arch.h" @@ -27,12 +28,10 @@ struct cpu_features __cpu_features attribute_hidden; static void get_common_indeces (void) { - asm volatile ("cpuid" - : "=a" (__cpu_features.cpuid[COMMON_CPUID_INDEX_1].eax), - "=b" (__cpu_features.cpuid[COMMON_CPUID_INDEX_1].ebx), - "=c" (__cpu_features.cpuid[COMMON_CPUID_INDEX_1].ecx), - "=d" (__cpu_features.cpuid[COMMON_CPUID_INDEX_1].edx) - : "0" (1)); + __cpuid (1, __cpu_features.cpuid[COMMON_CPUID_INDEX_1].eax, + __cpu_features.cpuid[COMMON_CPUID_INDEX_1].ebx, + __cpu_features.cpuid[COMMON_CPUID_INDEX_1].ecx, + __cpu_features.cpuid[COMMON_CPUID_INDEX_1].edx); unsigned int eax = __cpu_features.cpuid[COMMON_CPUID_INDEX_1].eax; __cpu_features.family = (eax >> 8) & 0x0f; @@ -47,10 +46,7 @@ __init_cpu_features (void) unsigned int ecx; unsigned int edx; - asm volatile ("cpuid" - : "=a" (__cpu_features.max_cpuid), "=b" (ebx), "=c" (ecx), - "=d" (edx) - : "0" (0)); + __cpuid (0, __cpu_features.max_cpuid, ebx, ecx, edx); /* This spells out "GenuineIntel". */ if (ebx == 0x756e6547 && ecx == 0x6c65746e && edx == 0x49656e69) @@ -71,9 +67,11 @@ __init_cpu_features (void) { __cpu_features.model += extended_model; +#ifndef ENABLE_SSSE3_ON_ATOM if (__cpu_features.model == 0x1c) /* Avoid SSSE3 on Atom since it is slow. */ __cpu_features.cpuid[COMMON_CPUID_INDEX_1].ecx &= ~(1 << 9); +#endif } } /* This spells out "AuthenticAMD". */ diff --git a/sysdeps/x86_64/multiarch/init-arch.h b/sysdeps/x86_64/multiarch/init-arch.h index 0151e8b95b..8d9b1e8d8c 100644 --- a/sysdeps/x86_64/multiarch/init-arch.h +++ b/sysdeps/x86_64/multiarch/init-arch.h @@ -61,6 +61,9 @@ extern const struct cpu_features *__get_cpu_features (void) /* Following are the feature tests used throughout libc. */ #ifndef NOT_IN_libc +# define HAS_SSE2 \ + ((__cpu_features.cpuid[COMMON_CPUID_INDEX_1].edx & (1 << 26)) != 0) + # define HAS_POPCOUNT \ ((__cpu_features.cpuid[COMMON_CPUID_INDEX_1].ecx & (1 << 23)) != 0) @@ -70,6 +73,9 @@ extern const struct cpu_features *__get_cpu_features (void) # define HAS_FMA \ ((__cpu_features.cpuid[COMMON_CPUID_INDEX_1].ecx & (1 << 12)) != 0) #else +# define HAS_SSE2 \ + ((__get_cpu_features ()->cpuid[COMMON_CPUID_INDEX_1].edx & (1 << 26)) != 0) + # define HAS_POPCOUNT \ ((__get_cpu_features ()->cpuid[COMMON_CPUID_INDEX_1].ecx & (1 << 23)) != 0) diff --git a/sysdeps/x86_64/multiarch/sched_cpucount.c b/sysdeps/x86_64/multiarch/sched_cpucount.c index b6f425e948..fde6dcca60 100644 --- a/sysdeps/x86_64/multiarch/sched_cpucount.c +++ b/sysdeps/x86_64/multiarch/sched_cpucount.c @@ -27,7 +27,7 @@ #define POPCNT(l) \ ({ __cpu_mask r; \ - asm ("popcntq %1, %0" : "=r" (r) : "0" (l));\ + asm ("popcnt %1, %0" : "=r" (r) : "0" (l));\ r; }) #define __sched_cpucount static popcount_cpucount #include From 66ae9e50a336d87f943cc6314a0d405820fcdf8b Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Fri, 31 Jul 2009 12:57:45 -0700 Subject: [PATCH 13/19] Fix ____longjmp_chk on x86-64. After a recent change to fix CFI in ____longjmp_chk the test of the ss_flags used the wrong memory location. --- ChangeLog | 5 +++++ sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8759b2c08d..fb046fe4c4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2009-07-31 Ulrich Drepper + + * sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S (longjmp_msg): Get + ss_flags from the correct location. + 2009-07-31 H.J. Lu * sysdeps/i386/i686/Makefile (sysdep_routines): Add cacheinfo. diff --git a/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S b/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S index 80e4aff36d..4e53ea63c9 100644 --- a/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S +++ b/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S @@ -77,7 +77,7 @@ ENTRY(____longjmp_chk) leaq 24(%rsp), %rsp cfi_adjust_cfa_offset(-24) jne .Lok - movl 8(%rsp), %eax + movl -16(%rsp), %eax andl $1, %eax .Lok: @@ -122,7 +122,7 @@ ENTRY(____longjmp_chk) syscall addq $24, %rsp cfi_adjust_cfa_offset(-24) - testl $1, 8(%rsp) + testl $1, -16(%rsp) je .Lout .Lfail: xchgq %r8, %rsp From e4143e7a06455b073c41a6025fcd28fc5c134211 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Fri, 31 Jul 2009 17:27:38 -0700 Subject: [PATCH 14/19] Optimize x86 and x86-64 ____longjmp_chk for Linux. --- ChangeLog | 4 + .../unix/sysv/linux/i386/____longjmp_chk.S | 73 +++++--------- .../unix/sysv/linux/x86_64/____longjmp_chk.S | 94 ++++++------------- 3 files changed, 54 insertions(+), 117 deletions(-) diff --git a/ChangeLog b/ChangeLog index fb046fe4c4..6d2a62b48c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2009-07-31 Ulrich Drepper + * sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S (longjmp_msg): Yet + another rewrite. Much smaller and faster. + * sysdeps/unix/sysv/linux/i386/____longjmp_chk.S: Likewise. + * sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S (longjmp_msg): Get ss_flags from the correct location. diff --git a/sysdeps/unix/sysv/linux/i386/____longjmp_chk.S b/sysdeps/unix/sysv/linux/i386/____longjmp_chk.S index b07e972468..65c7bae9f2 100644 --- a/sysdeps/unix/sysv/linux/i386/____longjmp_chk.S +++ b/sysdeps/unix/sysv/linux/i386/____longjmp_chk.S @@ -58,8 +58,6 @@ ENTRY (____longjmp_chk) PTR_DEMANGLE (%edx) PTR_DEMANGLE (%edi) - pushl $0 - cfi_adjust_cfa_offset(4) cmpl %edi, %esp jbe .Lok @@ -69,15 +67,25 @@ ENTRY (____longjmp_chk) movl %esp, %ecx movl $__NR_sigaltstack, %eax ENTER_KERNEL - movl 4(%esp), %ebx - addl $12, %esp + /* Without working sigaltstack we cannot perform the test. */ + test %eax, %eax + jne .Lok2 + testl $1, 4(%esp) + jz .Lfail + + movl (%esp), %eax + addl 8(%esp), %eax + subl %edi, %eax + cmpl 8(%esp), %eax + jae .Lok2 + +.Lfail: CALL_FAIL + +.Lok2: addl $12, %esp cfi_adjust_cfa_offset(-12) - movl 8(%esp), %ecx - testl %eax, %eax - jne .Lok - andl $1, %ebx - movl %ebx, (%esp) -.Lok: + movl 4(%esp), %ecx + +.Lok: /* We add unwind information for the target here. */ cfi_def_cfa(%ecx, 0) cfi_register(%eip, %edx) cfi_register(%esp, %edi) @@ -86,15 +94,11 @@ ENTRY (____longjmp_chk) cfi_offset(%edi, JB_DI*4) cfi_offset(%ebp, JB_BP*4) - movl 12(%esp), %eax /* Second argument is return value. */ - xchgl %edi, %esp - cfi_restore(%edi) - - cmpl %esp, %edi - jnbe .Lcheck + movl 8(%esp), %eax /* Second argument is return value. */ + movl %edi, %esp /* Restore registers. */ -.Lout: movl (JB_BX*4)(%ecx), %ebx + movl (JB_BX*4)(%ecx), %ebx movl (JB_SI*4)(%ecx), %esi movl (JB_DI*4)(%ecx), %edi movl (JB_BP*4)(%ecx), %ebp @@ -105,39 +109,4 @@ ENTRY (____longjmp_chk) /* Jump to saved PC. */ jmp *%edx - - cfi_def_cfa(%ecx, 0) - cfi_register(%eip, %edx) - cfi_offset(%ebx, JB_BX*4) - cfi_offset(%esi, JB_SI*4) - cfi_offset(%edi, JB_DI*4) - cfi_offset(%ebp, JB_BP*4) - -.Lcheck: - cmpl $0, (%edi) - je .Lfail - - subl $12, %esp - cfi_adjust_cfa_offset(12) - xorl %ebx, %ebx - movl %esp, %ecx - movl $__NR_sigaltstack, %eax - ENTER_KERNEL - testl $1, 4(%esp) - leal 12(%esp), %esp - movl 8(%edi), %ecx - movl 12(%edi), %eax - cfi_adjust_cfa_offset(-12) - je .Lout - -.Lfail: xchgl %edi, %esp - cfi_def_cfa(%esp, 8) - cfi_restore(%esp) - cfi_restore(%ebx) - cfi_restore(%esi) - cfi_undefined(%edi) - cfi_restore(%ebp) - - CALL_FAIL - hlt END (____longjmp_chk) diff --git a/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S b/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S index 4e53ea63c9..87c728d03b 100644 --- a/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S +++ b/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S @@ -58,31 +58,36 @@ ENTRY(____longjmp_chk) PTR_DEMANGLE (%rdx) #endif + cmpq %r8, %rsp + jbe .Lok + /* Save function parameters. */ movq %rdi, %r10 movl %esi, %ecx - xorl %eax, %eax - cmpq %r8, %rsp - jbe .Lok - - subq $24, %rsp - cfi_adjust_cfa_offset(24) xorl %edi, %edi - movq %rsp, %rsi + leaq -24(%rsp), %rsi movl $__NR_sigaltstack, %eax syscall + /* Without working sigaltstack we cannot perform the test. */ testl %eax, %eax - movl $0, %eax - leaq 24(%rsp), %rsp - cfi_adjust_cfa_offset(-24) - jne .Lok - movl -16(%rsp), %eax - andl $1, %eax + jne .Lok2 + testl $1, -16(%rsp) + jz .Lfail -.Lok: - /* We add unwind information for the target here. */ - cfi_def_cfa(%r10, 0) + movq -24(%rsp), %rax + addq -8(%rsp), %rax + subq %r8, %rax + cmpq -8(%rsp), %rax + jae .Lok2 + +.Lfail: CALL_FAIL + +.Lok2: movq %r10, %rdi + movl %ecx, %esi + +.Lok: /* We add unwind information for the target here. */ + cfi_def_cfa(%rdi, 0) cfi_register(%rsp,%r8) cfi_register(%rbp,%r9) cfi_register(%rip,%rdx) @@ -91,55 +96,14 @@ ENTRY(____longjmp_chk) cfi_offset(%r13,JB_R13*8) cfi_offset(%r14,JB_R14*8) cfi_offset(%r15,JB_R15*8) - - xchgq %r8, %rsp - cfi_restore(%rsp) - xchgq %r9, %rbp - cfi_restore(%rbp) - - movq (JB_RBX*8)(%r10),%rbx - movq (JB_R12*8)(%r10),%r12 - movq (JB_R13*8)(%r10),%r13 - movq (JB_R14*8)(%r10),%r14 - movq (JB_R15*8)(%r10),%r15 - - cmpq %rsp, %r8 - jnbe .Lcheck - + movq (JB_RBX*8)(%rdi),%rbx + movq (JB_R12*8)(%rdi),%r12 + movq (JB_R13*8)(%rdi),%r13 + movq (JB_R14*8)(%rdi),%r14 + movq (JB_R15*8)(%rdi),%r15 /* Set return value for setjmp. */ -.Lout: movl %ecx, %eax + movl %esi, %eax + movq %r8,%rsp + movq %r9,%rbp jmpq *%rdx - -.Lcheck: - testl %eax, %eax - je .Lfail - - subq $24, %rsp - cfi_adjust_cfa_offset(24) - xorl %edi, %edi - movq %rsp, %rsi - movl $__NR_sigaltstack, %eax - syscall - addq $24, %rsp - cfi_adjust_cfa_offset(-24) - testl $1, -16(%rsp) - je .Lout - -.Lfail: xchgq %r8, %rsp - /* We want the stack trace to show that of the caller. */ - cfi_def_cfa(%rsp, 8) - cfi_restore(%rsp) - cfi_register(%rbp, %r9) - cfi_restore(%rip) - cfi_restore(%rbx) - cfi_restore(%r12) - cfi_restore(%r13) - cfi_restore(%r14) - cfi_restore(%r15) - - xchgq %r9, %rbp - cfi_restore(%rbp) - - CALL_FAIL - hlt END (BP_SYM (____longjmp_chk)) From 22d94a7bc924396108537d9f8467b0500dffe20c Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Fri, 31 Jul 2009 21:48:59 -0700 Subject: [PATCH 15/19] Regenerated. --- nptl/sysdeps/x86_64/configure | 48 +++++++++++++++++++++++++++++------ 1 file changed, 40 insertions(+), 8 deletions(-) mode change 100644 => 100755 nptl/sysdeps/x86_64/configure diff --git a/nptl/sysdeps/x86_64/configure b/nptl/sysdeps/x86_64/configure old mode 100644 new mode 100755 index b959168843..424118a0e8 --- a/nptl/sysdeps/x86_64/configure +++ b/nptl/sysdeps/x86_64/configure @@ -1,10 +1,42 @@ +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +if (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + # This file is generated from configure.in by Autoconf. DO NOT EDIT! # Local configure fragment for sysdeps/i386. -{ echo "$as_me:$LINENO: checking for .cfi_personality and .cfi_lsda pseudo-ops" >&5 -echo $ECHO_N "checking for .cfi_personality and .cfi_lsda pseudo-ops... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking for .cfi_personality and .cfi_lsda pseudo-ops" >&5 +$as_echo_n "checking for .cfi_personality and .cfi_lsda pseudo-ops... " >&6; } if test "${libc_cv_asm_cfi_personality+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + $as_echo_n "(cached) " >&6 else cat > conftest.s <&5 (eval $ac_try) 2>&5 ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then libc_cv_asm_cfi_personality=yes else @@ -27,10 +59,10 @@ EOF rm -f conftest* fi -{ echo "$as_me:$LINENO: result: $libc_cv_asm_cfi_personality" >&5 -echo "${ECHO_T}$libc_cv_asm_cfi_personality" >&6; } +{ $as_echo "$as_me:$LINENO: result: $libc_cv_asm_cfi_personality" >&5 +$as_echo "$libc_cv_asm_cfi_personality" >&6; } if test x"$libc_cv_asm_cfi_personality" != xyes; then - { { echo "$as_me:$LINENO: error: assembler too old, .cfi_personality support missing" >&5 -echo "$as_me: error: assembler too old, .cfi_personality support missing" >&2;} + { { $as_echo "$as_me:$LINENO: error: assembler too old, .cfi_personality support missing" >&5 +$as_echo "$as_me: error: assembler too old, .cfi_personality support missing" >&2;} { (exit 1); exit 1; }; } fi From bd03a1afa2445e5942e49c28ae1f7920b7f38a45 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Fri, 31 Jul 2009 22:30:30 -0700 Subject: [PATCH 16/19] Macro cleanup. Better definition of the *_NITSET macros. --- nptl/ChangeLog | 4 ++++ nptl/descr.h | 16 ++++++++-------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/nptl/ChangeLog b/nptl/ChangeLog index 20031b5ae6..3ebe841452 100644 --- a/nptl/ChangeLog +++ b/nptl/ChangeLog @@ -1,3 +1,7 @@ +2009-07-31 Ulrich Drepper + + * descr.h: Better definition of *_BITMASK macros for cancellation. + 2009-07-29 Ulrich Drepper * sysdeps/x86_64/tls.h (TLS_TCB_ALIGN): Define explicitly to 32. diff --git a/nptl/descr.h b/nptl/descr.h index 22e774ab7e..9c366e7400 100644 --- a/nptl/descr.h +++ b/nptl/descr.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2006, 2007, 2008 Free Software Foundation, Inc. +/* Copyright (C) 2002-2006, 2007, 2008, 2009 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 2002. @@ -243,25 +243,25 @@ struct pthread int cancelhandling; /* Bit set if cancellation is disabled. */ #define CANCELSTATE_BIT 0 -#define CANCELSTATE_BITMASK 0x01 +#define CANCELSTATE_BITMASK (0x01 << CANCELSTATE_BIT) /* Bit set if asynchronous cancellation mode is selected. */ #define CANCELTYPE_BIT 1 -#define CANCELTYPE_BITMASK 0x02 +#define CANCELTYPE_BITMASK (0x01 << CANCELTYPE_BIT) /* Bit set if canceling has been initiated. */ #define CANCELING_BIT 2 -#define CANCELING_BITMASK 0x04 +#define CANCELING_BITMASK (0x01 << CANCELING_BIT) /* Bit set if canceled. */ #define CANCELED_BIT 3 -#define CANCELED_BITMASK 0x08 +#define CANCELED_BITMASK (0x01 << CANCELED_BIT) /* Bit set if thread is exiting. */ #define EXITING_BIT 4 -#define EXITING_BITMASK 0x10 +#define EXITING_BITMASK (0x01 << EXITING_BIT) /* Bit set if thread terminated and TCB is freed. */ #define TERMINATED_BIT 5 -#define TERMINATED_BITMASK 0x20 +#define TERMINATED_BITMASK (0x01 << TERMINATED_BIT) /* Bit set if thread is supposed to change XID. */ #define SETXID_BIT 6 -#define SETXID_BITMASK 0x40 +#define SETXID_BITMASK (0x01 << SETXID_BIT) /* Mask for the rest. Helps the compiler to optimize. */ #define CANCEL_RESTMASK 0xffffff80 From 9663bb3e2cdbf63a187386ba5e94a6c4705c4377 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Sat, 1 Aug 2009 14:18:58 -0700 Subject: [PATCH 17/19] Remove last trace of bounded pointer handling from ____longjmp_chk on x86-64. --- sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S b/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S index 87c728d03b..5e11540fd4 100644 --- a/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S +++ b/sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S @@ -106,4 +106,4 @@ ENTRY(____longjmp_chk) movq %r8,%rsp movq %r9,%rbp jmpq *%rdx -END (BP_SYM (____longjmp_chk)) +END (____longjmp_chk) From 5192104773c6d2f0bee47fe55872ad12b77034a5 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Sun, 2 Aug 2009 10:38:44 -0700 Subject: [PATCH 18/19] x86/x86-64 now needs from gcc. --- ChangeLog | 4 ++ sysdeps/i386/configure | 100 +++++++++++++++++++++----------------- sysdeps/i386/configure.in | 7 +++ 3 files changed, 67 insertions(+), 44 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6d2a62b48c..c011f59c5c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2009-08-02 Ulrich Drepper + + * sysdeps/i386/configure.in: Add test for . + 2009-07-31 Ulrich Drepper * sysdeps/unix/sysv/linux/x86_64/____longjmp_chk.S (longjmp_msg): Yet diff --git a/sysdeps/i386/configure b/sysdeps/i386/configure index cbc8cd9206..ced0b31d0f 100755 --- a/sysdeps/i386/configure +++ b/sysdeps/i386/configure @@ -1,42 +1,54 @@ -as_nl=' -' -export as_nl -# Printing a long string crashes Solaris 7 /usr/bin/printf. -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -if (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='printf %s\n' - as_echo_n='printf %s' +# This file is generated from configure.in by Autoconf. DO NOT EDIT! + # Local configure fragment for sysdeps/i386. + + +{ echo "$as_me:$LINENO: checking if gcc provides " >&5 +echo $ECHO_N "checking if gcc provides ... $ECHO_C" >&6; } +if test "${libc_cv_gcc_cpuid+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +#include +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + libc_cv_gcc_cpuid=yes else - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' - as_echo_n='/usr/ucb/echo -n' - else - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' - as_echo_n_body='eval - arg=$1; - case $arg in - *"$as_nl"*) - expr "X$arg" : "X\\(.*\\)$as_nl"; - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" - ' - export as_echo_n_body - as_echo_n='sh -c $as_echo_n_body as_echo' - fi - export as_echo_body - as_echo='sh -c $as_echo_body as_echo' + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + libc_cv_gcc_cpuid=no fi -# This file is generated from configure.in by Autoconf. DO NOT EDIT! - # Local configure fragment for sysdeps/i386. +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $libc_cv_gcc_cpuid" >&5 +echo "${ECHO_T}$libc_cv_gcc_cpuid" >&6; } +if test $libc_cv_gcc_cpuid != yes; then + { { echo "$as_me:$LINENO: error: gcc must provide the header" >&5 +echo "$as_me: error: gcc must provide the header" >&2;} + { (exit 1); exit 1; }; } +fi -{ $as_echo "$as_me:$LINENO: checking if -g produces usable source locations for assembler-with-cpp" >&5 -$as_echo_n "checking if -g produces usable source locations for assembler-with-cpp... " >&6; } +{ echo "$as_me:$LINENO: checking if -g produces usable source locations for assembler-with-cpp" >&5 +echo $ECHO_N "checking if -g produces usable source locations for assembler-with-cpp... $ECHO_C" >&6; } if test "${libc_cv_cpp_asm_debuginfo+set}" = set; then - $as_echo_n "(cached) " >&6 + echo $ECHO_N "(cached) $ECHO_C" >&6 else cat > conftest.S <&5 (eval $ac_try) 2>&5 ac_status=$? - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } && { ac_pattern='conftest\.S' { ac_try='readelf --debug-dump=line conftest.o | @@ -67,7 +79,7 @@ if { ac_try='${CC-cc} $CPPFLAGS $ASFLAGS -g -c conftest.S 1>&5' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; } }; then libc_cv_cpp_asm_debuginfo=yes @@ -76,8 +88,8 @@ else fi rm -f conftest* fi -{ $as_echo "$as_me:$LINENO: result: $libc_cv_cpp_asm_debuginfo" >&5 -$as_echo "$libc_cv_cpp_asm_debuginfo" >&6; } +{ echo "$as_me:$LINENO: result: $libc_cv_cpp_asm_debuginfo" >&5 +echo "${ECHO_T}$libc_cv_cpp_asm_debuginfo" >&6; } if test $libc_cv_cpp_asm_debuginfo = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_CPP_ASM_DEBUGINFO 1 @@ -85,24 +97,24 @@ _ACEOF fi -{ $as_echo "$as_me:$LINENO: checking for SSE4 support" >&5 -$as_echo_n "checking for SSE4 support... " >&6; } +{ echo "$as_me:$LINENO: checking for SSE4 support" >&5 +echo $ECHO_N "checking for SSE4 support... $ECHO_C" >&6; } if test "${libc_cv_cc_sse4+set}" = set; then - $as_echo_n "(cached) " >&6 + echo $ECHO_N "(cached) $ECHO_C" >&6 else if { ac_try='${CC-cc} -msse4 -xc /dev/null -S -o /dev/null' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? - $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then libc_cv_cc_sse4=yes else libc_cv_cc_sse4=no fi fi -{ $as_echo "$as_me:$LINENO: result: $libc_cv_cc_sse4" >&5 -$as_echo "$libc_cv_cc_sse4" >&6; } +{ echo "$as_me:$LINENO: result: $libc_cv_cc_sse4" >&5 +echo "${ECHO_T}$libc_cv_cc_sse4" >&6; } if test $libc_cv_cc_sse4 = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_SSE4_SUPPORT 1 diff --git a/sysdeps/i386/configure.in b/sysdeps/i386/configure.in index 44f53a57a0..800f928fbd 100644 --- a/sysdeps/i386/configure.in +++ b/sysdeps/i386/configure.in @@ -1,6 +1,13 @@ GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory. # Local configure fragment for sysdeps/i386. +AC_CACHE_CHECK([if gcc provides ], libc_cv_gcc_cpuid, [dnl +AC_COMPILE_IFELSE([#include ], libc_cv_gcc_cpuid=yes, + libc_cv_gcc_cpuid=no)]) +if test $libc_cv_gcc_cpuid != yes; then + AC_MSG_ERROR([gcc must provide the header]) +fi + AC_CACHE_CHECK(if -g produces usable source locations for assembler-with-cpp, libc_cv_cpp_asm_debuginfo, [dnl cat > conftest.S < Date: Sun, 2 Aug 2009 21:51:37 -0700 Subject: [PATCH 19/19] Remove leftover code from Linux/x86 ____longjmp_chk. --- sysdeps/unix/sysv/linux/i386/____longjmp_chk.S | 6 ------ 1 file changed, 6 deletions(-) diff --git a/sysdeps/unix/sysv/linux/i386/____longjmp_chk.S b/sysdeps/unix/sysv/linux/i386/____longjmp_chk.S index 65c7bae9f2..a07e6c8edf 100644 --- a/sysdeps/unix/sysv/linux/i386/____longjmp_chk.S +++ b/sysdeps/unix/sysv/linux/i386/____longjmp_chk.S @@ -39,12 +39,6 @@ longjmp_msg: call __fortify_fail #endif -#define CHECK_ESP(reg) \ - cmpl reg, %esp; \ - jbe .Lok; \ - CALL_FAIL; \ -.Lok: - .text ENTRY (____longjmp_chk)