From jakub@redhat.com Wed Jan 3 13:15:00 2007 From: jakub@redhat.com (Jakub Jelinek) Date: Wed, 03 Jan 2007 13:15:00 -0000 Subject: [PATCH] Use alloca in execvp if possible Message-ID: <20070103131738.GR3819@sunsite.mff.cuni.cz> Hi! If execvp is used after vfork (which should be possible as execvp is one of the exec* family functions and POSIX allows them to be called after vfork), it leaks memory in the parent process (as the memory is only freed if execve fails and the address space is shared with the parent). The following patch tries to use alloca when possible (should cover most usual cases), alternatively we could say add a __thread vfork_mem pointer and wrappers around malloc/free/realloc which execvp/execl* etc. could use. The wrappers would allocate extra pointer at the beginning of the memory blocks and chain all such allocations together. When vfork returns in parent, it would walk this chain and free all the buffers mentioned there. vfork is not async signal safe, so it ought to be possible, but probably overkill. 2007-01-03 Jakub Jelinek * posix/execvp.c: Include alloca.h. (allocate_scripts_argv): Renamed to... (scripts_argv): ... this. Don't allocate buffer here nor count arguments. (execvp): Use alloca if possible. * posix/Makefile: Add rules to build and run tst-vfork3 test. * posix/tst-vfork3.c: New test. --- libc/posix/execvp.c.jj 2005-07-24 23:38:43.000000000 +0200 +++ libc/posix/execvp.c 2007-01-03 13:49:28.000000000 +0100 @@ -1,4 +1,5 @@ -/* Copyright (C) 1991,92,1995-99,2002,2004,2005 Free Software Foundation, Inc. +/* Copyright (C) 1991,92, 1995-99, 2002, 2004, 2005, 2007 + 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 @@ -16,6 +17,7 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#include #include #include #include @@ -27,29 +29,18 @@ /* The file is accessible but it is not an executable file. Invoke the shell to interpret it as a script. */ -static char ** +static void internal_function -allocate_scripts_argv (const char *file, char *const argv[]) +scripts_argv (const char *file, char *const argv[], int argc, char **new_argv) { - /* Count the arguments. */ - int argc = 0; - while (argv[argc++]) - ; - /* Construct an argument list for the shell. */ - char **new_argv = (char **) malloc ((argc + 1) * sizeof (char *)); - if (new_argv != NULL) + new_argv[0] = (char *) _PATH_BSHELL; + new_argv[1] = (char *) file; + while (argc > 1) { - new_argv[0] = (char *) _PATH_BSHELL; - new_argv[1] = (char *) file; - while (argc > 1) - { - new_argv[argc] = argv[argc - 1]; - --argc; - } + new_argv[argc] = argv[argc - 1]; + --argc; } - - return new_argv; } @@ -67,8 +58,6 @@ execvp (file, argv) return -1; } - char **script_argv = NULL; - if (strchr (file, '/') != NULL) { /* Don't search when it contains a slash. */ @@ -76,46 +65,71 @@ execvp (file, argv) if (errno == ENOEXEC) { - script_argv = allocate_scripts_argv (file, argv); + /* Count the arguments. */ + int argc = 0; + while (argv[argc++]) + ; + size_t len = (argc + 1) * sizeof (char *); + char **script_argv; + void *ptr = NULL; + if (__libc_use_alloca (len)) + script_argv = alloca (len); + else + script_argv = ptr = malloc (len); + if (script_argv != NULL) { + scripts_argv (file, argv, argc, script_argv); __execve (script_argv[0], script_argv, __environ); - free (script_argv); + free (ptr); } } } else { + size_t pathlen; + size_t alloclen = 0; char *path = getenv ("PATH"); - char *path_malloc = NULL; + if (path == NULL) + { + pathlen = confstr (_CS_PATH, (char *) NULL, 0); + alloclen = pathlen + 1; + } + else + pathlen = strlen (path); + + size_t len = strlen (file) + 1; + alloclen += pathlen + len + 1; + + char *name; + char *path_malloc = NULL; + if (__libc_use_alloca (alloclen)) + name = alloca (alloclen); + else + { + path_malloc = name = malloc (alloclen); + if (name == NULL) + return -1; + } + if (path == NULL) { /* There is no `PATH' in the environment. The default search path is the current directory followed by the path `confstr' returns for `_CS_PATH'. */ - size_t len = confstr (_CS_PATH, (char *) NULL, 0); - path = (char *) malloc (1 + len); - if (path == NULL) - return -1; + path = name + pathlen + len + 1; path[0] = ':'; - (void) confstr (_CS_PATH, path + 1, len); - path_malloc = path; + (void) confstr (_CS_PATH, path + 1, pathlen); } - size_t len = strlen (file) + 1; - size_t pathlen = strlen (path); - char *name = malloc (pathlen + len + 1); - if (name == NULL) - { - free (path_malloc); - return -1; - } /* Copy the file name at the top. */ name = (char *) memcpy (name + pathlen + 1, file, len); /* And add the slash. */ *--name = '/'; + char **script_argv = NULL; + void *script_argv_malloc = NULL; bool got_eacces = false; char *p = path; do @@ -139,7 +153,15 @@ execvp (file, argv) { if (script_argv == NULL) { - script_argv = allocate_scripts_argv (startp, argv); + /* Count the arguments. */ + int argc = 0; + while (argv[argc++]) + ; + size_t arglen = (argc + 1) * sizeof (char *); + if (__libc_use_alloca (alloclen + arglen)) + script_argv = alloca (arglen); + else + script_argv = script_argv_malloc = malloc (arglen); if (script_argv == NULL) { /* A possible EACCES error is not as important as @@ -147,6 +169,7 @@ execvp (file, argv) got_eacces = false; break; } + scripts_argv (startp, argv, argc, script_argv); } __execve (script_argv[0], script_argv, __environ); @@ -184,11 +207,10 @@ execvp (file, argv) /* We tried every element and none of them worked. */ if (got_eacces) /* At least one failure was due to permissions, so report that - error. */ + error. */ __set_errno (EACCES); - free (script_argv); - free (name - pathlen); + free (script_argv_malloc); free (path_malloc); } --- libc/posix/Makefile.jj 2006-09-07 15:50:05.000000000 +0200 +++ libc/posix/Makefile 2007-01-03 12:25:12.000000000 +0100 @@ -1,4 +1,4 @@ -# Copyright (C) 1991-1999, 2000-2005, 2006 Free Software Foundation, Inc. +# Copyright (C) 1991-1999, 2000-2006, 2007 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 @@ -83,7 +83,7 @@ tests := tstgetopt testfnm runtests run bug-regex21 bug-regex22 bug-regex23 bug-regex24 \ bug-regex25 bug-regex26 tst-nice tst-nanosleep tst-regex2 \ transbug tst-rxspencer tst-pcre tst-boost \ - bug-ga1 tst-vfork1 tst-vfork2 tst-waitid \ + bug-ga1 tst-vfork1 tst-vfork2 tst-vfork3 tst-waitid \ tst-getaddrinfo2 bug-glob1 bug-glob2 tst-sysconf \ tst-execvp1 tst-execvp2 tst-execlp1 tst-execlp2 \ tst-execv1 tst-execv2 tst-execl1 tst-execl2 \ @@ -108,7 +108,8 @@ generated := $(addprefix wordexp-test-re bug-regex21-mem bug-regex21.mtrace \ tst-rxspencer-mem tst-rxspencer.mtrace tst-getconf.out \ tst-pcre-mem tst-pcre.mtrace tst-boost-mem tst-boost.mtrace \ - bug-ga2.mtrace bug-ga2-mem bug-glob2.mtrace bug-glob2-mem + bug-ga2.mtrace bug-ga2-mem bug-glob2.mtrace bug-glob2-mem \ + tst-vfork3-mem tst-vfork3.mtrace include ../Rules @@ -218,7 +219,7 @@ ifeq (no,$(cross-compiling)) tests: $(objpfx)bug-regex2-mem $(objpfx)bug-regex14-mem \ $(objpfx)bug-regex21-mem $(objpfx)tst-rxspencer-mem \ $(objpfx)tst-pcre-mem $(objpfx)tst-boost-mem $(objpfx)tst-getconf.out \ - $(objpfx)bug-glob2-mem + $(objpfx)bug-glob2-mem $(objpfx)tst-vfork3-mem xtests: $(objpfx)bug-ga2-mem endif @@ -245,6 +246,11 @@ bug-regex21-ENV = MALLOC_TRACE=$(objpfx) $(objpfx)bug-regex21-mem: $(objpfx)bug-regex21.out $(common-objpfx)malloc/mtrace $(objpfx)bug-regex21.mtrace > $@ +tst-vfork3-ENV = MALLOC_TRACE=$(objpfx)tst-vfork3.mtrace + +$(objpfx)tst-vfork3-mem: $(objpfx)tst-vfork3.out + $(common-objpfx)malloc/mtrace $(objpfx)tst-vfork3.mtrace > $@ + # tst-rxspencer.mtrace is generated only when run without --utf8 # option, since otherwise the file has almost 100M and takes very long # time to process. --- libc/posix/tst-vfork3.c.jj 2007-01-03 11:19:07.000000000 +0100 +++ libc/posix/tst-vfork3.c 2007-01-03 12:18:12.000000000 +0100 @@ -0,0 +1,219 @@ +/* Test for vfork functions. + Copyright (C) 2007 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek , 2007. + + 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 + +static int do_test (void); +static void do_prepare (void); +char *tmpdirname; + +#define TEST_FUNCTION do_test () +#define PREPARE(argc, argv) do_prepare () +#include "../test-skeleton.c" + +static int +do_test (void) +{ + mtrace (); + + char *path = getenv ("PATH"); + if (path == NULL) + path = "/bin"; + char pathbuf [strlen (tmpdirname) + 1 + strlen (path) + 1]; + strcpy (stpcpy (stpcpy (pathbuf, tmpdirname), ":"), path); + if (setenv ("PATH", pathbuf, 1) < 0) + { + puts ("setenv failed"); + return 1; + } + + size_t i; + char *argv[3] = { "script1.sh", "1", NULL }; + for (i = 0; i < 5; i++) + { + pid_t pid = vfork (); + if (pid < 0) + { + printf ("vfork failed: %m\n"); + return 1; + } + else if (pid == 0) + { + execvp ("script1.sh", argv); + _exit (errno); + } + int status; + if (TEMP_FAILURE_RETRY (waitpid (pid, &status, 0)) != pid) + { + puts ("waitpid failed"); + return 1; + } + else if (status != 0) + { + printf ("script1.sh failed with status %d\n", status); + return 1; + } + } + + argv[0] = "script2.sh"; + argv[1] = "2"; + for (i = 0; i < 5; i++) + { + pid_t pid = vfork (); + if (pid < 0) + { + printf ("vfork failed: %m\n"); + return 1; + } + else if (pid == 0) + { + execvp ("script2.sh", argv); + _exit (errno); + } + int status; + if (TEMP_FAILURE_RETRY (waitpid (pid, &status, 0)) != pid) + { + puts ("waitpid failed"); + return 1; + } + else if (status != 0) + { + printf ("script2.sh failed with status %d\n", status); + return 1; + } + } + + for (i = 0; i < 5; i++) + { + pid_t pid = vfork (); + if (pid < 0) + { + printf ("vfork failed: %m\n"); + return 1; + } + else if (pid == 0) + { + execlp ("script2.sh", "script2.sh", "3", NULL); + _exit (errno); + } + int status; + if (TEMP_FAILURE_RETRY (waitpid (pid, &status, 0)) != pid) + { + puts ("waitpid failed"); + return 1; + } + else if (status != 0) + { + printf ("script2.sh failed with status %d\n", status); + return 1; + } + } + + unsetenv ("PATH"); + argv[0] = "echo"; + argv[1] = "script 4"; + for (i = 0; i < 5; i++) + { + pid_t pid = vfork (); + if (pid < 0) + { + printf ("vfork failed: %m\n"); + return 1; + } + else if (pid == 0) + { + execvp ("echo", argv); + _exit (errno); + } + int status; + if (TEMP_FAILURE_RETRY (waitpid (pid, &status, 0)) != pid) + { + puts ("waitpid failed"); + return 1; + } + else if (status != 0) + { + printf ("echo failed with status %d\n", status); + return 1; + } + } + + return 0; +} + +static void +do_prepare (void) +{ + size_t len = strlen (test_dir) + sizeof ("/tst-vfork3.XXXXXX"); + tmpdirname = malloc (len); + char *script1 = malloc (len + sizeof "/script1.sh"); + char *script2 = malloc (len + sizeof "/script2.sh"); + if (tmpdirname == NULL || script1 == NULL || script2 == NULL) + { + puts ("out of memory"); + exit (1); + } + strcpy (stpcpy (tmpdirname, test_dir), "/tst-vfork3.XXXXXX"); + + tmpdirname = mkdtemp (tmpdirname); + if (tmpdirname == NULL) + { + puts ("could not create temporary directory"); + exit (1); + } + + strcpy (stpcpy (script1, tmpdirname), "/script1.sh"); + strcpy (stpcpy (script2, tmpdirname), "/script2.sh"); + + /* Need to make sure tmpdirname is at the end of the linked list. */ + add_temp_file (script1); + add_temp_file (tmpdirname); + add_temp_file (script2); + + const char content1[] = "#!/bin/sh\necho script $1\n"; + int fd = open (script1, O_WRONLY | O_CREAT, 0700); + if (fd < 0 + || TEMP_FAILURE_RETRY (write (fd, content1, sizeof content1)) + != sizeof content1 + || fchmod (fd, S_IRUSR | S_IXUSR) < 0) + { + printf ("Could not write %s\n", script1); + exit (1); + } + close (fd); + + const char content2[] = "echo script $1\n"; + fd = open (script2, O_WRONLY | O_CREAT, 0700); + if (fd < 0 + || TEMP_FAILURE_RETRY (write (fd, content2, sizeof content2)) + != sizeof content2 + || fchmod (fd, S_IRUSR | S_IXUSR) < 0) + { + printf ("Could not write %s\n", script2); + exit (1); + } + close (fd); +} Jakub From drepper@redhat.com Wed Jan 3 23:03:00 2007 From: drepper@redhat.com (Ulrich Drepper) Date: Wed, 03 Jan 2007 23:03:00 -0000 Subject: [PATCH] Use alloca in execvp if possible In-Reply-To: <20070103131738.GR3819@sunsite.mff.cuni.cz> References: <20070103131738.GR3819@sunsite.mff.cuni.cz> Message-ID: <459C362B.8030707@redhat.com> Applied after adding some changes to remove warnings and to avoid depending on files in /tmp being executable. -- ? Ulrich Drepper ? Red Hat, Inc. ? 444 Castro St ? Mountain View, CA ? -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 251 bytes Desc: OpenPGP digital signature URL: From jakub@redhat.com Wed Jan 10 19:28:00 2007 From: jakub@redhat.com (Jakub Jelinek) Date: Wed, 10 Jan 2007 19:28:00 -0000 Subject: [PATCH] Fix sparcv9 build Message-ID: <20070110193048.GZ3819@sunsite.mff.cuni.cz> Hi! nptl/sysdeps/pthread/pthread_barrier_wait.c has been moved to nptl/pthread_barrier_wait.c recently. 2007-01-10 Jakub Jelinek * sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/pthread_barrier_wait.c: Adjust include path for pthread_barrier_wait.c move. --- libc/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/pthread_barrier_wait.c.jj 2006-01-03 18:59:56.000000000 -0500 +++ libc/nptl/sysdeps/unix/sysv/linux/sparc/sparc32/sparcv9/pthread_barrier_wait.c 2007-01-10 08:52:52.000000000 -0500 @@ -1 +1 @@ -#include "../../../../../../pthread/pthread_barrier_wait.c" +#include "../../../../../../../pthread_barrier_wait.c" Jakub From jakub@redhat.com Wed Jan 10 19:31:00 2007 From: jakub@redhat.com (Jakub Jelinek) Date: Wed, 10 Jan 2007 19:31:00 -0000 Subject: [PATCH] Fix x86_64 __FP_CLZ Message-ID: <20070110193335.GA3819@sunsite.mff.cuni.cz> Hi! bsrq %rdx, %eax ins not a valid instruction. While we could tweak these macros to store result in the same sized variable as input and only then copy to r and furthermore handle the various sizeof (x) cases, GCC 3.4+ contains __builtin_clz{,l,ll} and the generic soft-fp.h definition already handles that all (plus __builtin_clz expands to bsrl on i?86/x86_64 and __builtin_clzl on x86_64 to bsrq). 2007-01-10 Jakub Jelinek * sysdeps/i386/soft-fp/sfp-machine.h (__FP_CLZ): Remove. * sysdeps/x86_64/soft-fp/sfp-machine.h (__FP_CLZ): Likewise. --- libc/sysdeps/i386/soft-fp/sfp-machine.h.jj 2002-11-01 22:49:28.000000000 +0100 +++ libc/sysdeps/i386/soft-fp/sfp-machine.h 2007-01-10 12:15:01.000000000 +0100 @@ -27,12 +27,6 @@ : "0"(xh), "1"(xl), "g"(yh), "g"(yl) \ : "cc") -#define __FP_CLZ(r, x) \ - do { \ - __asm__("bsrl %1,%0" : "=r"(r) : "g"(x) : "cc"); \ - r ^= 31; \ - } while (0) - #define _i386_mul_32_64(rh, rl, x, y) \ __asm__("mull %2" : "=d"(rh), "=a"(rl) : "%g"(x), "1"(y) : "cc") --- libc/sysdeps/x86_64/soft-fp/sfp-machine.h.jj 2002-11-01 22:49:29.000000000 +0100 +++ libc/sysdeps/x86_64/soft-fp/sfp-machine.h 2007-01-10 12:13:31.000000000 +0100 @@ -3,12 +3,6 @@ #define _FP_WS_TYPE signed long #define _FP_I_TYPE long -#define __FP_CLZ(r, x) \ - do { \ - __asm__("bsrq %1,%0" : "=r"(r) : "g"(x) : "cc"); \ - r ^= 63; \ - } while (0) - #define _FP_NANFRAC_S _FP_QNANBIT_S #define _FP_NANFRAC_D _FP_QNANBIT_D, 0 #define _FP_NANFRAC_Q _FP_QNANBIT_Q, 0, 0, 0 Jakub From jakub@redhat.com Thu Jan 11 16:27:00 2007 From: jakub@redhat.com (Jakub Jelinek) Date: Thu, 11 Jan 2007 16:27:00 -0000 Subject: [PATCH] Fix strtod on 0x. [BZ #3855] Message-ID: <20070111163020.GB3819@sunsite.mff.cuni.cz> Hi! 0x needs to be followed by non-empty sequence of hex digits optionally containing the radix character to form a valid hexadecimal number for strtod, similarly how a valid decimal float number needs to start with non-empty sequence of decimal digits optionally containing the radix character. So, 0x.X should be parsed just accept just the initial 0. For base != 16 this is handled early: /* Return 0.0 if no legal string is found. No character is used even if a sign was found. */ #ifdef USE_WIDE_CHAR if (c == (wint_t) decimal && (wint_t) cp[1] >= L'0' && (wint_t) cp[1] <= L'9') { /* We accept it. This funny construct is here only to indent the code directly. */ } #else for (cnt = 0; decimal[cnt] != '\0'; ++cnt) if (cp[cnt] != decimal[cnt]) break; if (decimal[cnt] == '\0' && cp[cnt] >= '0' && cp[cnt] <= '9') { /* We accept it. This funny construct is here only to indent the code directly. */ } #endif Either we can handle this early too for 0x (in the if which sets base == 16), or IMHO better just to extend the check later on, as done in this patch. 2007-01-11 Jakub Jelinek [BZ #3855] * stdlib/strtod_l.c (____STRTOF_INTERNAL): 0x. not followed by hexadecimal digit should accept just the initial 0. * stdlib/tst-strtod2.c (tests): New variable. (do_test): Run several tests rather than just one. --- libc/stdlib/strtod_l.c.jj 2007-01-11 15:43:07.000000000 +0100 +++ libc/stdlib/strtod_l.c 2007-01-11 17:10:27.000000000 +0100 @@ -1,5 +1,6 @@ /* Convert string representing a number to float value, using given locale. - Copyright (C) 1997,1998,2002,2004,2005,2006 Free Software Foundation, Inc. + Copyright (C) 1997,1998,2002,2004,2005,2006,2007 + Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1997. @@ -665,14 +666,23 @@ ____STRTOF_INTERNAL (nptr, endptr, group if (!((c >= L_('0') && c <= L_('9')) || (base == 16 && ((CHAR_TYPE) TOLOWER (c) >= L_('a') && (CHAR_TYPE) TOLOWER (c) <= L_('f'))) + || ( #ifdef USE_WIDE_CHAR - || c == (wint_t) decimal + c == (wint_t) decimal #else - || ({ for (cnt = 0; decimal[cnt] != '\0'; ++cnt) - if (decimal[cnt] != cp[cnt]) - break; - decimal[cnt] == '\0'; }) -#endif + ({ for (cnt = 0; decimal[cnt] != '\0'; ++cnt) + if (decimal[cnt] != cp[cnt]) + break; + decimal[cnt] == '\0'; }) +#endif + /* '0x.' alone is not a valid hexadecimal number. + '.' alone is not valid either, but that has been checked + already earlier. */ + && (base != 16 + || cp != start_of_digits + || (cp[decimal_len] >= L_('0') && cp[decimal_len] <= L_('9')) + || ((CHAR_TYPE) TOLOWER (cp[decimal_len]) >= L_('a') + && (CHAR_TYPE) TOLOWER (cp[decimal_len]) <= L_('f')))) || (base == 16 && (cp != start_of_digits && (CHAR_TYPE) TOLOWER (c) == L_('p'))) || (base != 16 && (CHAR_TYPE) TOLOWER (c) == L_('e')))) --- libc/stdlib/tst-strtod2.c.jj 2007-01-03 10:59:42.000000000 +0100 +++ libc/stdlib/tst-strtod2.c 2007-01-11 14:57:13.000000000 +0100 @@ -1,22 +1,41 @@ #include #include +struct test +{ + const char *str; + double result; + size_t offset; +} tests[] = +{ + { "0xy", 0.0, 1 }, + { "0x.y", 0.0, 1 }, + { "0x0.y", 0.0, 4 }, + { "0x.0y", 0.0, 4 }, + { ".y", 0.0, 0 }, + { "0.y", 0.0, 2 }, + { ".0y", 0.0, 2 } +}; + static int do_test (void) { int status = 0; - const char s[] = "0x"; - char *ep; - double r = strtod (s, &ep); - if (r != 0) - { - printf ("r = %g, expect 0\n", r); - status = 1; - } - if (ep != s + 1) + for (size_t i = 0; i < sizeof (tests) / sizeof (tests[0]); ++i) { - printf ("strtod parsed %ju characters, expected 1\n", ep - s); - status = 1; + char *ep; + double r = strtod (tests[i].str, &ep); + if (r != tests[i].result) + { + printf ("test %zu r = %g, expect %g\n", i, r, tests[i].result); + status = 1; + } + if (ep != tests[i].str + tests[i].offset) + { + printf ("test %zu strtod parsed %ju characters, expected %zu\n", + i, ep - tests[i].str, tests[i].offset); + status = 1; + } } return status; } Jakub From jakub@redhat.com Thu Jan 11 16:29:00 2007 From: jakub@redhat.com (Jakub Jelinek) Date: Thu, 11 Jan 2007 16:29:00 -0000 Subject: [PATCH] Fix strtod handling of multi-byte thousands separator Message-ID: <20070111163149.GC3819@sunsite.mff.cuni.cz> Hi! While looking at BZ#3855 I noticed that non-wide thousands separators can't work properly if they are longer than one byte (as shown in the attached testcase). Fixed thusly: 2007-01-11 Jakub Jelinek * stdlib/strtod_l.c (____STRTOF_INTERNAL): Fix handling of multi-byte thousands separators. * stdlib/Makefile: Add rules to build and run tst-strtod4. * stdlib/tst-strtod4.c: New test. --- libc/stdlib/strtod_l.c.jj 2007-01-11 17:10:27.000000000 +0100 +++ libc/stdlib/strtod_l.c 2007-01-11 17:10:16.000000000 +0100 @@ -651,10 +651,11 @@ ____STRTOF_INTERNAL (nptr, endptr, group if (c != '0') { for (cnt = 0; thousands[cnt] != '\0'; ++cnt) - if (c != thousands[cnt]) + if (thousands[cnt] != cp[cnt]) break; if (thousands[cnt] != '\0') break; + cp += cnt - 1; } c = *++cp; } @@ -725,6 +726,7 @@ ____STRTOF_INTERNAL (nptr, endptr, group break; if (thousands[cnt] != '\0') break; + cp += cnt - 1; } #endif } --- libc/stdlib/Makefile.jj 2007-01-10 17:04:12.000000000 +0100 +++ libc/stdlib/Makefile 2007-01-11 17:11:01.000000000 +0100 @@ -68,7 +68,7 @@ tests := tst-strtol tst-strtod testmb t tst-limits tst-rand48 bug-strtod tst-setcontext \ test-a64l tst-qsort tst-system testmb2 bug-strtod2 \ tst-atof1 tst-atof2 tst-strtod2 tst-strtod3 tst-rand48-2 \ - tst-makecontext + tst-makecontext tst-strtod4 include ../Makeconfig @@ -114,6 +114,7 @@ test-canon-ARGS = --test-dir=${common-ob tst-strtod-ENV = LOCPATH=$(common-objpfx)localedata tst-strtod3-ENV = LOCPATH=$(common-objpfx)localedata +tst-strtod4-ENV = LOCPATH=$(common-objpfx)localedata testmb2-ENV = LOCPATH=$(common-objpfx)localedata # Run a test on the header files we use. --- libc/stdlib/tst-strtod4.c.jj 2007-01-11 16:52:17.000000000 +0100 +++ libc/stdlib/tst-strtod4.c 2007-01-11 17:01:26.000000000 +0100 @@ -0,0 +1,56 @@ +#include +#include +#include +#include + +#define NBSP "\xc2\xa0" + +static const struct +{ + const char *in; + const char *out; + double expected; +} tests[] = + { + { "000"NBSP"000"NBSP"000", "", 0.0 }, + { "1"NBSP"000"NBSP"000,5x", "x", 1000000.5 } + }; +#define NTESTS (sizeof (tests) / sizeof (tests[0])) + + +static int +do_test (void) +{ + if (setlocale (LC_ALL, "cs_CZ.UTF-8") == NULL) + { + puts ("could not set locale"); + return 1; + } + + int status = 0; + + for (int i = 0; i < NTESTS; ++i) + { + char *ep; + double r = __strtod_internal (tests[i].in, &ep, 1); + + if (strcmp (ep, tests[i].out) != 0) + { + printf ("%d: got rest string \"%s\", expected \"%s\"\n", + i, ep, tests[i].out); + status = 1; + } + + if (r != tests[i].expected) + { + printf ("%d: got wrong results %g, expected %g\n", + i, r, tests[i].expected); + status = 1; + } + } + + return status; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" Jakub From drepper@redhat.com Thu Jan 11 17:38:00 2007 From: drepper@redhat.com (Ulrich Drepper) Date: Thu, 11 Jan 2007 17:38:00 -0000 Subject: [PATCH] Fix strtod handling of multi-byte thousands separator In-Reply-To: <20070111163149.GC3819@sunsite.mff.cuni.cz> References: <20070111163149.GC3819@sunsite.mff.cuni.cz> Message-ID: <45A675F6.5040705@redhat.com> I applied both strtod patches. -- ? Ulrich Drepper ? Red Hat, Inc. ? 444 Castro St ? Mountain View, CA ? -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 251 bytes Desc: OpenPGP digital signature URL: From jakub@redhat.com Tue Jan 16 15:58:00 2007 From: jakub@redhat.com (Jakub Jelinek) Date: Tue, 16 Jan 2007 15:58:00 -0000 Subject: [PATCH] Speed up pthread_cleanup_{push,pop} inside of libpthread Message-ID: <20070116160109.GE3819@sunsite.mff.cuni.cz> Hi! While looking at pthread_cond_*wait, I noticed it was calling __pthread_cleanup_push/pop, which is the old (and slower) way of registering a cleanup handler. Except for pthread_once which really needs to use that way (because it is calling a callback function, which might not have unwind info - see e.g. tst-once3). Tested on ppc32. TODO things I have noticed, but didn't change: i386 pthread_once.S shouldn't use sigsetjmp etc., but __pthread_cleanup_{push,pop} x86_64 pthread_cond_*wait.S shouldn't use __pthread_cleanup_* but attribute cleanup handler x86_64 lll_timedwait_tid should have unwind info 2007-01-16 Jakub Jelinek * Makefile (CFLAGS-lowlevellock.c): Compile with -fa-u-t. * pthreadP.h (pthread_cleanup_push, pthread_cleanup_pop): Don't redefine if _EXCEPTIONS is defined. * pthread_cond_wait.c (__pthread_cond_wait): Use pthread_cleanup_{push,pop} instead of __pthread_cleanup_{push,pop}. * pthread_cond_timedwait.c (__pthread_cond_timedwait): Likewise. * sysdeps/unix/sysv/linux/alpha/pthread_once.c (__pthread_once): Use explicitly __pthread_cond_{push,pop}. * sysdeps/unix/sysv/linux/s390/pthread_once.c (__pthread_once): Likewise. * sysdeps/unix/sysv/linux/powerpc/pthread_once.c (__pthread_once): Likewise. * sysdeps/unix/sysv/linux/sparc/pthread_once.c (__pthread_once): Likewise. * sysdeps/unix/sysv/linux/ia64/pthread_once.c (__pthread_once): Likewise. --- libc/nptl/Makefile.jj 2006-09-08 13:57:49.000000000 +0200 +++ libc/nptl/Makefile 2007-01-16 15:56:05.000000000 +0100 @@ -175,6 +175,7 @@ CFLAGS-pthread_cond_wait.c = -fexception CFLAGS-pthread_cond_timedwait.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-sem_wait.c = -fexceptions -fasynchronous-unwind-tables CFLAGS-sem_timedwait.c = -fexceptions -fasynchronous-unwind-tables +CFLAGS-lowlevellock.c = -fasynchronous-unwind-tables # These are the function wrappers we have to duplicate here. CFLAGS-fcntl.c = -fexceptions -fasynchronous-unwind-tables --- libc/nptl/sysdeps/unix/sysv/linux/alpha/pthread_once.c.jj 2004-09-08 18:56:46.000000000 +0200 +++ libc/nptl/sysdeps/unix/sysv/linux/alpha/pthread_once.c 2007-01-16 15:23:56.000000000 +0100 @@ -1,4 +1,4 @@ -/* Copyright (C) 2003, 2004 Free Software Foundation, Inc. +/* Copyright (C) 2003, 2004, 2007 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 @@ -77,12 +77,16 @@ __pthread_once (pthread_once_t *once_con /* This thread is the first here. Do the initialization. Register a cleanup handler so that in case the thread gets - interrupted the initialization can be restarted. */ - pthread_cleanup_push (clear_once_control, once_control); + interrupted the initialization can be restarted. + This uses __pthread_cleanup_{push,pop} explicitly, because + init_routine or something it calls might not have unwind + information. */ + struct _pthread_cleanup_buffer buffer; + __pthread_cleanup_push (&buffer, clear_once_control, once_control); init_routine (); - pthread_cleanup_pop (0); + __pthread_cleanup_pop (&buffer, 0); /* Add one to *once_control to take the bottom 2 bits from 01 to 10. */ atomic_increment (once_control); --- libc/nptl/sysdeps/unix/sysv/linux/s390/pthread_once.c.jj 2003-02-05 10:29:49.000000000 +0100 +++ libc/nptl/sysdeps/unix/sysv/linux/s390/pthread_once.c 2007-01-16 15:25:56.000000000 +0100 @@ -1,4 +1,4 @@ -/* Copyright (C) 2003 Free Software Foundation, Inc. +/* Copyright (C) 2003, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Martin Schwidefsky , 2003. @@ -83,12 +83,16 @@ __pthread_once (once_control, init_routi /* This thread is the first here. Do the initialization. Register a cleanup handler so that in case the thread gets - interrupted the initialization can be restarted. */ - pthread_cleanup_push (clear_once_control, once_control); + interrupted the initialization can be restarted. + This uses __pthread_cleanup_{push,pop} explicitly, because + init_routine or something it calls might not have unwind + information. */ + struct _pthread_cleanup_buffer buffer; + __pthread_cleanup_push (&buffer, clear_once_control, once_control); init_routine (); - pthread_cleanup_pop (0); + __pthread_cleanup_pop (&buffer, 0); /* Add one to *once_control. */ --- libc/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c.jj 2004-09-08 18:56:46.000000000 +0200 +++ libc/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_once.c 2007-01-16 15:22:45.000000000 +0100 @@ -1,4 +1,4 @@ -/* Copyright (C) 2003, 2004 Free Software Foundation, Inc. +/* Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Paul Mackerras , 2003. @@ -80,12 +80,16 @@ __pthread_once (pthread_once_t *once_con /* This thread is the first here. Do the initialization. Register a cleanup handler so that in case the thread gets - interrupted the initialization can be restarted. */ - pthread_cleanup_push (clear_once_control, once_control); + interrupted the initialization can be restarted. + This uses __pthread_cleanup_{push,pop} explicitly, because + init_routine or something it calls might not have unwind + information. */ + struct _pthread_cleanup_buffer buffer; + __pthread_cleanup_push (&buffer, clear_once_control, once_control); init_routine (); - pthread_cleanup_pop (0); + __pthread_cleanup_pop (&buffer, 0); /* Add one to *once_control to take the bottom 2 bits from 01 to 10. */ --- libc/nptl/sysdeps/unix/sysv/linux/sparc/pthread_once.c.jj 2004-09-08 18:56:46.000000000 +0200 +++ libc/nptl/sysdeps/unix/sysv/linux/sparc/pthread_once.c 2007-01-16 15:27:19.000000000 +0100 @@ -1,4 +1,4 @@ -/* Copyright (C) 2003, 2004 Free Software Foundation, Inc. +/* Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Jakub Jelinek , 2003. @@ -72,12 +72,16 @@ __pthread_once (once_control, init_routi /* This thread is the first here. Do the initialization. Register a cleanup handler so that in case the thread gets - interrupted the initialization can be restarted. */ - pthread_cleanup_push (clear_once_control, once_control); + interrupted the initialization can be restarted. + This uses __pthread_cleanup_{push,pop} explicitly, because + init_routine or something it calls might not have unwind + information. */ + struct _pthread_cleanup_buffer buffer; + __pthread_cleanup_push (&buffer, clear_once_control, once_control); init_routine (); - pthread_cleanup_pop (0); + __pthread_cleanup_pop (&buffer, 0); /* Add one to *once_control. */ --- libc/nptl/sysdeps/unix/sysv/linux/ia64/pthread_once.c.jj 2004-09-08 18:56:46.000000000 +0200 +++ libc/nptl/sysdeps/unix/sysv/linux/ia64/pthread_once.c 2007-01-16 15:28:18.000000000 +0100 @@ -1,4 +1,4 @@ -/* Copyright (C) 2003, 2004 Free Software Foundation, Inc. +/* Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Jakub Jelinek , 2003. @@ -72,12 +72,16 @@ __pthread_once (once_control, init_routi /* This thread is the first here. Do the initialization. Register a cleanup handler so that in case the thread gets - interrupted the initialization can be restarted. */ - pthread_cleanup_push (clear_once_control, once_control); + interrupted the initialization can be restarted. + This uses __pthread_cleanup_{push,pop} explicitly, because + init_routine or something it calls might not have unwind + information. */ + struct _pthread_cleanup_buffer buffer; + __pthread_cleanup_push (&buffer, clear_once_control, once_control); init_routine (); - pthread_cleanup_pop (0); + __pthread_cleanup_pop (&buffer, 0); /* Add one to *once_control. */ --- libc/nptl/pthreadP.h.jj 2006-08-25 11:01:24.000000000 +0200 +++ libc/nptl/pthreadP.h 2007-01-16 15:23:18.000000000 +0100 @@ -1,4 +1,5 @@ -/* Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +/* Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 + Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 2002. @@ -512,16 +513,20 @@ extern void __librt_disable_asynccancel extern void __pthread_cleanup_push (struct _pthread_cleanup_buffer *buffer, void (*routine) (void *), void *arg) attribute_hidden; -# undef pthread_cleanup_push -# define pthread_cleanup_push(routine,arg) \ +# ifndef __EXCEPTIONS +# undef pthread_cleanup_push +# define pthread_cleanup_push(routine,arg) \ { struct _pthread_cleanup_buffer _buffer; \ __pthread_cleanup_push (&_buffer, (routine), (arg)); +# endif extern void __pthread_cleanup_pop (struct _pthread_cleanup_buffer *buffer, int execute) attribute_hidden; -# undef pthread_cleanup_pop -# define pthread_cleanup_pop(execute) \ +# ifndef __EXCEPTIONS +# undef pthread_cleanup_pop +# define pthread_cleanup_pop(execute) \ __pthread_cleanup_pop (&_buffer, (execute)); } +# endif #endif extern void __pthread_cleanup_push_defer (struct _pthread_cleanup_buffer *buffer, --- libc/nptl/pthread_cond_wait.c.jj 2006-10-28 07:08:47.000000000 +0200 +++ libc/nptl/pthread_cond_wait.c 2007-01-16 15:23:31.000000000 +0100 @@ -1,4 +1,4 @@ -/* Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc. +/* Copyright (C) 2003, 2004, 2006, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Martin Schwidefsky , 2003. @@ -93,7 +93,6 @@ __pthread_cond_wait (cond, mutex) pthread_cond_t *cond; pthread_mutex_t *mutex; { - struct _pthread_cleanup_buffer buffer; struct _condvar_cleanup_buffer cbuffer; int err; @@ -125,7 +124,7 @@ __pthread_cond_wait (cond, mutex) /* Before we block we enable cancellation. Therefore we have to install a cancellation handler. */ - __pthread_cleanup_push (&buffer, __condvar_cleanup, &cbuffer); + pthread_cleanup_push (__condvar_cleanup, &cbuffer); /* The current values of the wakeup counter. The "woken" counter must exceed this value. */ @@ -181,7 +180,7 @@ __pthread_cond_wait (cond, mutex) lll_mutex_unlock (cond->__data.__lock); /* The cancellation handling is back to normal, remove the handler. */ - __pthread_cleanup_pop (&buffer, 0); + pthread_cleanup_pop (0); /* Get the mutex before returning. */ return __pthread_mutex_cond_lock (mutex); --- libc/nptl/pthread_cond_timedwait.c.jj 2006-10-28 07:08:17.000000000 +0200 +++ libc/nptl/pthread_cond_timedwait.c 2007-01-16 15:23:40.000000000 +0100 @@ -1,4 +1,4 @@ -/* Copyright (C) 2003, 2004 Free Software Foundation, Inc. +/* Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Martin Schwidefsky , 2003. @@ -45,7 +45,6 @@ __pthread_cond_timedwait (cond, mutex, a pthread_mutex_t *mutex; const struct timespec *abstime; { - struct _pthread_cleanup_buffer buffer; struct _condvar_cleanup_buffer cbuffer; int result = 0; @@ -81,7 +80,7 @@ __pthread_cond_timedwait (cond, mutex, a /* Before we block we enable cancellation. Therefore we have to install a cancellation handler. */ - __pthread_cleanup_push (&buffer, __condvar_cleanup, &cbuffer); + pthread_cleanup_push (__condvar_cleanup, &cbuffer); /* The current values of the wakeup counter. The "woken" counter must exceed this value. */ @@ -202,7 +201,7 @@ __pthread_cond_timedwait (cond, mutex, a lll_mutex_unlock (cond->__data.__lock); /* The cancellation handling is back to normal, remove the handler. */ - __pthread_cleanup_pop (&buffer, 0); + pthread_cleanup_pop (0); /* Get the mutex before returning. */ err = __pthread_mutex_cond_lock (mutex); Jakub From jakub@redhat.com Mon Jan 22 16:06:00 2007 From: jakub@redhat.com (Jakub Jelinek) Date: Mon, 22 Jan 2007 16:06:00 -0000 Subject: [PATCH] Fix _itoa (0LL, ...) for bases other than 8 and 16 [BZ #3902] Message-ID: <20070122160948.GL3819@sunsite.mff.cuni.cz> Hi! While _itoa_word for 0L as first argument always adds 0 into the buffer for all bases (all the loops are do ... while (value != 0);) and so does the RUN_2N macro in _itoa as well (i.e. _itoa (0LL, bufend, 8, 0) or _itoa (0LL, bufend, 16, 0) both return "0"), _itoa (0LL, bufend, x, 0) for x != 8 && x != 16 returns "". stdio-common/vfprintf.c IMHO correctly relies on the 0 being added, as shown on the following testcase. Fixed by making sure 0 is added for value == 0 for all bases. 2007-01-22 Jakub Jelinek [BZ #3902] * stdio-common/_itoa.c (_itoa): If value is 0, always add 0 into the buffer. * stdio-common/tst-sprintf.c (main): Add test for %0lld with 0LL. --- libc/stdio-common/_itoa.c.jj 2004-06-06 08:02:14.000000000 +0200 +++ libc/stdio-common/_itoa.c 2007-01-22 16:46:39.000000000 +0100 @@ -1,5 +1,5 @@ /* Internal function for converting integers to ASCII. - Copyright (C) 1994, 1995, 1996, 1999, 2000, 2002, 2003, 2004 + Copyright (C) 1994, 1995, 1996, 1999, 2000, 2002, 2003, 2004, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Torbjorn Granlund @@ -272,7 +272,7 @@ _itoa (value, buflim, base, upper_case) #if BITS_PER_MP_LIMB == 64 mp_limb_t base_multiplier = brec->base_multiplier; if (brec->flag) - while (value != 0) + do { mp_limb_t quo, rem, x, dummy; @@ -282,8 +282,9 @@ _itoa (value, buflim, base, upper_case) *--buflim = digits[rem]; value = quo; } + while (value != 0); else - while (value != 0) + do { mp_limb_t quo, rem, x, dummy; @@ -293,6 +294,7 @@ _itoa (value, buflim, base, upper_case) *--buflim = digits[rem]; value = quo; } + while (value != 0); #endif #if BITS_PER_MP_LIMB == 32 mp_limb_t t[3]; @@ -394,6 +396,11 @@ _itoa (value, buflim, base, upper_case) n = 2; } } + else if (value == 0) + { + *--buflim = '0'; + return buflim; + } else { t[0] = value; --- libc/stdio-common/tst-sprintf.c.jj 2003-06-25 13:04:49.000000000 +0200 +++ libc/stdio-common/tst-sprintf.c 2007-01-22 16:51:33.000000000 +0100 @@ -37,5 +37,13 @@ main (void) free (dst); } + if (sprintf (buf, "%0d %0ld %0lld", 0, 0L, 0LL) != 5 + || strcmp (buf, "0 0 0") != 0) + { + printf ("sprintf (buf, \"%%0d %%0ld %%0lld\", 0, 0L, 0LL) produced \"%s\"\n", + buf); + result = 1; + } + return result; } Jakub From aj@suse.de Wed Jan 24 09:11:00 2007 From: aj@suse.de (Andreas Jaeger) Date: Wed, 24 Jan 2007 09:11:00 -0000 Subject: Add some more values to personality.h Message-ID: linux/personality.h has some more values now - and a fix. I synced the header with current Linux 2.6.20. Ok to commit? Andreas 2007-01-24 Andreas Jaeger * sysdeps/unix/sysv/linux/sys/personality.h (ADDR_NO_RANDOMIZE, FDPIC_FUNCPTRS, ADDR_LIMIT_3GB, PER_LINUX_32BIT, PER_LINUX32_3GB): Add. Correct values of PER_HPUX and PER_OSF4. ============================================================ Index: sysdeps/unix/sysv/linux/sys/personality.h --- sysdeps/unix/sysv/linux/sys/personality.h 28 Aug 2002 09:33:13 -0000 1.2 +++ sysdeps/unix/sysv/linux/sys/personality.h 24 Jan 2007 09:10:35 -0000 @@ -1,4 +1,4 @@ -/* Copyright (C) 2002 Free Software Foundation, Inc. +/* Copyright (C) 2002, 2007 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 @@ -16,7 +16,7 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -/* Taken verbatim from Linux 2.4 (include/linux/personality.h). */ +/* Taken verbatim from Linux 2.6 (include/linux/personality.h). */ #ifndef _SYS_PERSONALITY_H #define _SYS_PERSONALITY_H 1 @@ -27,11 +27,14 @@ These occupy the top three bytes. */ enum { + ADDR_NO_RANDOMIZE = 0x0040000, + FDPIC_FUNCPTRS = 0x0080000, MMAP_PAGE_ZERO = 0x0100000, ADDR_LIMIT_32BIT = 0x0800000, SHORT_INODE = 0x1000000, WHOLE_SECONDS = 0x2000000, STICKY_TIMEOUTS = 0x4000000, + ADDR_LIMIT_3GB = 0x8000000 }; /* Personality types. @@ -42,6 +45,7 @@ enum { PER_LINUX = 0x0000, PER_LINUX_32BIT = 0x0000 | ADDR_LIMIT_32BIT, + PER_LINUX_FDPIC = 0x0000 | FDPIC_FUNCPTRS, PER_SVR4 = 0x0001 | STICKY_TIMEOUTS | MMAP_PAGE_ZERO, PER_SVR3 = 0x0002 | STICKY_TIMEOUTS | SHORT_INODE, PER_SCOSVR3 = 0x0003 | STICKY_TIMEOUTS | WHOLE_SECONDS | SHORT_INODE, @@ -52,14 +56,15 @@ enum PER_SUNOS = 0x0006 | STICKY_TIMEOUTS, PER_XENIX = 0x0007 | STICKY_TIMEOUTS | SHORT_INODE, PER_LINUX32 = 0x0008, + PER_LINUX32_3GB = 0x0008 | ADDR_LIMIT_3GB, PER_IRIX32 = 0x0009 | STICKY_TIMEOUTS, /* IRIX5 32-bit */ PER_IRIXN32 = 0x000a | STICKY_TIMEOUTS, /* IRIX6 new 32-bit */ PER_IRIX64 = 0x000b | STICKY_TIMEOUTS, /* IRIX6 64-bit */ PER_RISCOS = 0x000c, PER_SOLARIS = 0x000d | STICKY_TIMEOUTS, PER_UW7 = 0x000e | STICKY_TIMEOUTS | MMAP_PAGE_ZERO, - PER_HPUX = 0x000f, - PER_OSF4 = 0x0010, + PER_OSF4 = 0x000f, + PER_HPUX = 0x0010, PER_MASK = 0x00ff, }; -- Andreas Jaeger, aj@suse.de, http://www.suse.de/~aj/ SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 N?rnberg, Germany GPG fingerprint = 93A3 365E CE47 B889 DF7F FED1 389A 563C C272 A126 -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 188 bytes Desc: not available URL: From jakub@redhat.com Wed Jan 24 21:51:00 2007 From: jakub@redhat.com (Jakub Jelinek) Date: Wed, 24 Jan 2007 21:51:00 -0000 Subject: [PATCH] Re: bswap on prescott In-Reply-To: <4354d3270701241326v596084d5m2341d6ce2cfa201f@mail.gmail.com> References: <4354d3270701241326v596084d5m2341d6ce2cfa201f@mail.gmail.com> Message-ID: <20070124215414.GM3819@sunsite.mff.cuni.cz> On Wed, Jan 24, 2007 at 11:26:44PM +0200, T?r?k Edvin wrote: > If I compile a program using ntohl with '-march=prescott -O2', I get 3 > ror instr., however if I compile it with '-march=pentium4 -O2', I get > the bswap instr. > > Looking at bits/byteswap.h, it seems that prescott is missing from the list: > > # if __WORDSIZE == 64 || (defined __i486__ || defined __pentium__ > \ > || defined __pentiumpro__ || defined __pentium4__ > \ > || defined __k8__ || defined __athlon__ > \ > || defined __k6__) > [...] > __asm__ ("bswap %0",... > > Is this intended behaviour? Which is faster on prescott: bswap, or the > 3 rotations? No, byteswap.h just didn't keep with the speed of new -march macro additions in GCC. This adds what has been added recently: 2007-01-24 Jakub Jelinek * sysdeps/i386/bits/byteswap.h (__bswap_32): Add __nocona__, __core2__ and __geode__ to the list of i486+ CPUs. * sysdeps/x86_64/bits/byteswap.h (__bswap_32): Likewise. --- libc/sysdeps/i386/bits/byteswap.h.jj 2006-08-24 09:02:16.000000000 +0200 +++ libc/sysdeps/i386/bits/byteswap.h 2007-01-24 22:34:45.000000000 +0100 @@ -1,5 +1,6 @@ /* Macros to swap the order of bytes in integer values. - Copyright (C) 1997,1998,2000,2002,2003,2006 Free Software Foundation, Inc. + Copyright (C) 1997, 1998, 2000, 2002, 2003, 2006, 2007 + 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 @@ -66,7 +67,8 @@ __bswap_16 (unsigned short int __bsx) `bswap' opcode. On i386 we have to use three instructions. */ # if !defined __i486__ && !defined __pentium__ && !defined __pentiumpro__ \ && !defined __pentium4__ && !defined __k8__ && !defined __athlon__ \ - && !defined __k6__ + && !defined __k6__ && !defined __nocona__ && !defined __core2__ \ + && !defined __geode__ # define __bswap_32(x) \ (__extension__ \ ({ register unsigned int __v, __x = (x); \ --- libc/sysdeps/x86_64/bits/byteswap.h.jj 2003-08-17 08:32:00.000000000 +0200 +++ libc/sysdeps/x86_64/bits/byteswap.h 2007-01-24 22:35:36.000000000 +0100 @@ -1,5 +1,6 @@ /* Macros to swap the order of bytes in integer values. - Copyright (C) 1997, 1998, 2000, 2002, 2003 Free Software Foundation, Inc. + Copyright (C) 1997, 1998, 2000, 2002, 2003, 2007 + 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 @@ -59,7 +60,8 @@ # if __WORDSIZE == 64 || (defined __i486__ || defined __pentium__ \ || defined __pentiumpro__ || defined __pentium4__ \ || defined __k8__ || defined __athlon__ \ - || defined __k6__) + || defined __k6__ || defined __nocona__ \ + || defined __core2__ || defined __geode__) /* To swap the bytes in a word the i486 processors and up provide the `bswap' opcode. On i386 we have to use three instructions. */ # define __bswap_32(x) \ Jakub From roland@redhat.com Thu Jan 25 01:23:00 2007 From: roland@redhat.com (Roland McGrath) Date: Thu, 25 Jan 2007 01:23:00 -0000 Subject: [PATCH] Re: bswap on prescott In-Reply-To: Jakub Jelinek's message of Wednesday, 24 January 2007 22:54:14 +0100 <20070124215414.GM3819@sunsite.mff.cuni.cz> Message-ID: <20070125012253.998341800E9@magilla.sf.frob.com> It really would be more reasonable if GCC defined some things meaning "this or later" or "has these features", so that things like this don't have to change every year to still mean ">= i486". From drepper@redhat.com Fri Jan 26 01:29:00 2007 From: drepper@redhat.com (Ulrich Drepper) Date: Fri, 26 Jan 2007 01:29:00 -0000 Subject: Add some more values to personality.h In-Reply-To: References: Message-ID: <45B95979.5070104@redhat.com> Andreas Jaeger wrote: > + PER_LINUX_FDPIC = 0x0000 | FDPIC_FUNCPTRS, There is no need for this. The rest is OK. -- ? Ulrich Drepper ? Red Hat, Inc. ? 444 Castro St ? Mountain View, CA ? -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 251 bytes Desc: OpenPGP digital signature URL: