diff --git a/glibc-fedora.patch b/glibc-fedora.patch index 87f58a6..dc760d1 100644 --- a/glibc-fedora.patch +++ b/glibc-fedora.patch @@ -1,11 +1,184 @@ --- glibc-20070515T2025/ChangeLog 15 May 2007 20:24:57 -0000 1.10641 -+++ glibc-20070515T2025-fedora/ChangeLog 24 May 2007 10:33:00 -0000 1.8782.2.246 -@@ -1,3 +1,64 @@ -+2007-01-15 Jakub Jelinek ++++ glibc-20070515T2025-fedora/ChangeLog 8 Jul 2007 10:08:23 -0000 1.8782.2.258 +@@ -1,3 +1,237 @@ ++2007-07-07 Ulrich Drepper ++ ++ [BZ #4745] ++ * stdio-common/vfscanf.c (_IO_vfscanf): Add additional test for EOF ++ in loop to look for conversion specifier to avoid testing of ++ wrong errno value. ++ * stdio-common/Makefile (tests): Add bug18, bug18a, bug19, bug19a. ++ * stdio-common/bug18.c: New file. ++ * stdio-common/bug18a.c: New file. ++ * stdio-common/bug19.c: New file. ++ * stdio-common/bug19a.c: New file. ++ ++2007-06-06 Jakub Jelinek ++ ++ [BZ #4586] ++ * sysdeps/i386/ldbl2mpn.c (__mpn_extract_long_double): Treat ++ pseudo-zeros as zero. ++ * sysdeps/x86_64/ldbl2mpn.c: New file. ++ * sysdeps/ia64/ldbl2mpn.c: New file. ++ ++2007-07-01 Jakub Jelinek ++ ++ * elf/dl-sysdep.c (_dl_important_hwcaps): Add integer overflow check. ++ * elf/dl-minimal.c (__libc_memalign): Likewise. Handle malloc (0). ++ Return NULL if mmap failed instead of asserting it does not. ++ (calloc): Check for integer overflow. ++ ++ * elf/dl-minimal.c (__strtoul_internal): Fix parsing of numbers bigger ++ than LONG_MAX / 10. ++ ++2007-07-03 Jakub Jelinek ++ ++ [BZ #4702] ++ * nis/nss-default.c: Include errno.h. ++ (init): Preserve errno. ++ ++2007-06-19 Ulrich Drepper ++ ++ * sysdeps/generic/ldsodefs.h (rtld_global): Reorder some elements ++ to fill in holes ++ (rtld_global_ro): Likewise. ++ ++2007-06-18 Jakub Jelinek ++ ++ * elf/dl-addr.c (_dl_addr): Skip PT_LOAD checking if l_contiguous. ++ Move PT_LOAD checking to... ++ (_dl_addr_inside_object): ... here, new function. ++ * elf/dl-sym.c (do_sym): If not l_contiguous, ++ call _dl_addr_inside_object. ++ * elf/dl-iteratephdr.c (__dl_iterate_phdr): Likewise. ++ * dlfcn/dlinfo.c (dlinfo_doit): Likewise. ++ * elf/dl-open.c (dl_open_worker): Likewise. ++ (_dl_addr_inside_object): New function if IS_IN_rtld. ++ * elf/dl-load.c (_dl_map_object_from_fd): Set l_contiguous if no ++ holes are present or are PROT_NONE protected. ++ * include/link.h (struct link_map): Add l_contiguous field. ++ * sysdeps/generic/ldsodefs.h (_dl_addr_inside_object): New prototype. ++ ++2007-06-18 Jakub Jelinek ++ ++ * elf/rtld.c (dl_main): Don't call init_tls more than once. ++ ++2007-06-19 Ulrich Drepper ++ ++ * elf/dl-close.c (free_mem): Free _dl_scope_free_list. ++ ++2007-06-13 Jakub Jelinek ++ ++ * include/link.h: Don't include rtld-lowlevel.h. ++ (struct link_map): Remove l_scope_lock. ++ * sysdeps/generic/ldsodefs.h: Don't include rtld-lowlevel.h. ++ (_dl_scope_free_list): New field (variable) in _rtld_global. ++ (DL_LOOKUP_SCOPE_LOCK): Remove. ++ (_dl_scope_free): New prototype. ++ * elf/dl-runtime.c (_dl_fixup): Don't use __rtld_mrlock_*lock. ++ Don't pass DL_LOOKUP_SCOPE_LOCK to _dl_lookup_symbol_x. ++ (_dl_profile_fixup): Likewise. ++ * elf/dl-sym.c (do_sym): Likewise. Use wrapped _dl_lookup_symbol_x ++ whenever !RTLD_SINGLE_THREAD_P, use THREAD_GSCOPE_SET_FLAG and ++ THREAD_GSCOPE_RESET_FLAG around it. ++ * elf/dl-close.c (_dl_close_worker): Don't use ++ __rtld_mrlock_{change,done}. Call _dl_scope_free on the old ++ scope. Make sure THREAD_GSCOPE_WAIT () happens if any old ++ scopes were queued or if l_scope_mem has been abandoned. ++ * elf/dl-open.c (_dl_scope_free): New function. ++ (dl_open_worker): Use it. Don't use __rtld_mrlock_{change,done}. ++ * elf/dl-support.c (_dl_scope_free_list): New variable. ++ * elf/dl-lookup.c (add_dependency): Remove flags argument. ++ Remove DL_LOOKUP_SCOPE_LOCK handling. ++ (_dl_lookup_symbol_x): Adjust caller. Remove DL_LOOKUP_SCOPE_LOCK ++ handling. ++ * elf/dl-object.c (_dl_new_object): Don't use ++ __rtld_mrlock_initialize. ++ ++2007-06-09 Ulrich Drepper ++ ++ * elf/do-lookup.h (do_lookup_x): Read r_nlist before r_list and ++ make sure gcc doesn't mess around with this. ++ ++2007-06-08 Ulrich Drepper ++ ++ * elf/dl-lookup.c (_dl_lookup_symbol_x): Remove use of r_nlist. ++ ++2007-06-08 Jakub Jelinek ++ ++ * elf/dl-close.c (_dl_close_worker): Remove all to be removed ++ libraries from the global scope at once and call THREAD_GSCOPE_WAIT + -+ * elf/dl-open.c (add_to_global): If the main searchlist is 256 -+ entries or more, on each reallocation at least double the size -+ of the search list rather than growing it linearly. ++2007-05-18 Ulrich Drepper ++ ++ * elf/dl-close.c (_dl_close_worker): When removing object from ++ global scope, wait for all lookups to finish afterwards. ++ * elf/dl-open.c (add_to_global): When global scope array must ++ grow, allocate a new one and free old array only after all ++ lookups finish. ++ * elf/dl-runtime.c (_dl_fixup): Protect using global scope. ++ (_dl_lookup_symbol_x): Likewise. ++ * elf/dl-support.c: Define _dl_wait_lookup_done. ++ * sysdeps/generic/ldsodefs.h (struct rtld_global): Add ++ _dl_wait_lookup_done. ++ ++2007-06-05 Jakub Jelinek ++ ++ * sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c ++ (__mpn_construct_long_double): Fix conversion where result ought ++ to be smaller than __LDBL_MIN__, or the low double should be ++ denormal. Fix decision where to negate low double - honor round ++ to even rules. ++ * stdio-common/tst-sprintf2.c: Include string.h. ++ (COMPARE_LDBL): Define. ++ (TEST): Also test whether a string hexadecimal float representation ++ can be parsed back to the number. ++ (main): Add a couple of further tests. ++ ++2007-06-04 Jakub Jelinek ++ ++ * sysdeps/ieee754/ldbl-128ibm/printf_fphex.c ++ (PRINT_FPHEX_LONG_DOUBLE): Fix printing numbers where lower double ++ is non-zero, but smaller than 2 * __DBL_MIN__. ++ * stdio-common/tst-sprintf2.c: New test. ++ * stdio-common/Makefile (tests): Add tst-sprintf2. ++ ++2007-06-04 Jakub Jelinek ++ ++ * sysdeps/ieee754/ldbl-128ibm/s_nextafterl.c (nextafterl): Remove ++ unused ily variable. Fix nextafterl on +-__LDBL_MAX__ and +-Inf. ++ Remove unreachable code at the end. ++ ++2007-06-01 Steven Munroe ++ ++ * sysdeps/ieee754/ldbl-128ibm/s_fpclassifyl.c: Correct description of ++ ldbl-128ibm in comment. ++ (fpclassifyl): Correct classification of denormals. ++ * sysdeps/ieee754/ldbl-128ibm/s_nextafterl.c (nextafterl): Correct ++ return value for MIN denormal. Rewrite using long double math too ++ correctly handle denormals and canonicalize the results. ++ ++2007-05-29 Ulrich Drepper ++ ++ * nscd/nscd_helper.c (get_mapping): Handle short replies instead ++ of crashing. When this is the case or if the reply is malformed, ++ don't try to close the new file descriptor since it does not ++ exist. ++ Patch in part by Guillaume Chazarain . ++ ++2007-05-21 Ulrich Drepper ++ ++ * sysdeps/x86_64/cacheinfo.c (init_cacheinfo): Pass correct value ++ as second parameter to handle_intel. ++ ++ * sysdeps/unix/sysv/linux/x86_64/sysconf.c: Move cache information ++ handling to ... ++ * sysdeps/x86_64/cacheinfo.c: ... here. New file. ++ * sysdeps/x86_64/Makefile [subdir=string] (sysdep_routines): Add ++ cacheinfo. ++ * sysdeps/x86_64/memcpy.S: Complete rewrite. ++ * sysdeps/x86_64/mempcpy.S: Adjust appropriately. ++ Patch by Evandro Menezes . + +2007-05-21 Ulrich Drepper + @@ -65,7 +238,7 @@ 2007-05-14 Ulrich Drepper * version.h (VERSION): Define to 6. -@@ -71,6 +132,13 @@ +@@ -71,6 +305,13 @@ * include/sys/cdefs.h: Redefine __nonnull so that test for incorrect parameters in the libc code itself are not omitted. @@ -79,7 +252,7 @@ 2007-05-09 Jakub Jelinek * sysdeps/ia64/fpu/fraiseexcpt.c (feraiseexcept): Don't raise overflow -@@ -366,6 +434,10 @@ +@@ -366,6 +607,10 @@ [BZ #4368] * stdlib/stdlib.h: Remove obsolete part of comment for realpath. @@ -90,7 +263,7 @@ 2007-04-16 Ulrich Drepper [BZ #4364] -@@ -1623,6 +1695,15 @@ +@@ -1623,6 +1868,15 @@ separators also if no non-zero digits found. * stdlib/Makefile (tests): Add tst-strtod3. @@ -414,30 +587,733 @@ # define O 0 #else # define O 1 +--- glibc-20070515T2025/dlfcn/dlinfo.c 27 Oct 2006 23:11:41 -0000 1.7 ++++ glibc-20070515T2025-fedora/dlfcn/dlinfo.c 7 Jul 2007 21:28:54 -0000 1.2.2.7 +@@ -1,5 +1,5 @@ + /* dlinfo -- Get information from the dynamic linker. +- 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. + + The GNU C Library is free software; you can redistribute it and/or +@@ -56,9 +56,8 @@ dlinfo_doit (void *argsblock) + /* Find the highest-addressed object that CALLER is not below. */ + for (nsid = 0; nsid < DL_NNS; ++nsid) + for (l = GL(dl_ns)[nsid]._ns_loaded; l != NULL; l = l->l_next) +- if (caller >= l->l_map_start && caller < l->l_map_end) +- /* There must be exactly one DSO for the range of the virtual +- memory. Otherwise something is really broken. */ ++ if (caller >= l->l_map_start && caller < l->l_map_end ++ && (l->l_contiguous || _dl_addr_inside_object (l, caller))) + break; + + if (l == NULL) +--- glibc-20070515T2025/elf/dl-addr.c 6 May 2007 21:00:04 -0000 1.33 ++++ glibc-20070515T2025-fedora/elf/dl-addr.c 7 Jul 2007 17:31:45 -0000 1.21.2.13 +@@ -134,22 +134,12 @@ _dl_addr (const void *address, Dl_info * + /* Find the highest-addressed object that ADDRESS is not below. */ + for (Lmid_t ns = 0; ns < DL_NNS; ++ns) + for (struct link_map *l = GL(dl_ns)[ns]._ns_loaded; l; l = l->l_next) +- if (addr >= l->l_map_start && addr < l->l_map_end) ++ if (addr >= l->l_map_start && addr < l->l_map_end ++ && (l->l_contiguous || _dl_addr_inside_object (l, addr))) + { +- /* Make sure it lies within one of L's segments. */ +- int n = l->l_phnum; +- const ElfW(Addr) reladdr = addr - l->l_addr; +- while (--n >= 0) +- if (l->l_phdr[n].p_type == PT_LOAD) +- { +- if (reladdr - l->l_phdr[n].p_vaddr >= 0 +- && reladdr - l->l_phdr[n].p_vaddr < l->l_phdr[n].p_memsz) +- { +- determine_info (addr, l, info, mapp, symbolp); +- result = 1; +- goto out; +- } +- } ++ determine_info (addr, l, info, mapp, symbolp); ++ result = 1; ++ goto out; + } + + out: +@@ -158,3 +148,19 @@ _dl_addr (const void *address, Dl_info * + return result; + } + libc_hidden_def (_dl_addr) ++ ++/* Return non-zero if ADDR lies within one of L's segments. */ ++int ++internal_function ++_dl_addr_inside_object (struct link_map *l, const ElfW(Addr) addr) ++{ ++ int n = l->l_phnum; ++ const ElfW(Addr) reladdr = addr - l->l_addr; ++ ++ while (--n >= 0) ++ if (l->l_phdr[n].p_type == PT_LOAD ++ && reladdr - l->l_phdr[n].p_vaddr >= 0 ++ && reladdr - l->l_phdr[n].p_vaddr < l->l_phdr[n].p_memsz) ++ return 1; ++ return 0; ++} +--- glibc-20070515T2025/elf/dl-close.c 11 May 2007 18:46:34 -0000 1.126 ++++ glibc-20070515T2025-fedora/elf/dl-close.c 7 Jul 2007 17:19:40 -0000 1.104.2.13 +@@ -31,6 +31,7 @@ + #include + #include + #include ++#include + + + /* Type of the constructor functions. */ +@@ -228,6 +229,8 @@ _dl_close_worker (struct link_map *map) + bool do_audit = GLRO(dl_naudit) > 0 && !ns->_ns_loaded->l_auditing; + #endif + bool unload_any = false; ++ bool scope_mem_left = false; ++ unsigned int unload_global = 0; + unsigned int first_loaded = ~0; + for (unsigned int i = 0; i < nloaded; ++i) + { +@@ -292,6 +295,9 @@ _dl_close_worker (struct link_map *map) + /* We indeed have an object to remove. */ + unload_any = true; + ++ if (imap->l_global) ++ ++unload_global; ++ + /* Remember where the first dynamically loaded object is. */ + if (i < first_loaded) + first_loaded = i; +@@ -400,18 +406,18 @@ _dl_close_worker (struct link_map *map) + + struct r_scope_elem **old = imap->l_scope; + +- if (RTLD_SINGLE_THREAD_P) +- imap->l_scope = newp; +- else +- { +- __rtld_mrlock_change (imap->l_scope_lock); +- imap->l_scope = newp; +- __rtld_mrlock_done (imap->l_scope_lock); +- } ++ imap->l_scope = newp; + + /* No user anymore, we can free it now. */ + if (old != imap->l_scope_mem) +- free (old); ++ { ++ if (_dl_scope_free (old)) ++ /* If _dl_scope_free used THREAD_GSCOPE_WAIT (), ++ no need to repeat it. */ ++ scope_mem_left = false; ++ } ++ else ++ scope_mem_left = true; + + imap->l_scope_max = new_size; + } +@@ -457,6 +463,46 @@ _dl_close_worker (struct link_map *map) + r->r_state = RT_DELETE; + _dl_debug_state (); + ++ if (unload_global) ++ { ++ /* Some objects are in the global scope list. Remove them. */ ++ struct r_scope_elem *ns_msl = ns->_ns_main_searchlist; ++ unsigned int i; ++ unsigned int j = 0; ++ unsigned int cnt = ns_msl->r_nlist; ++ ++ while (cnt > 0 && ns_msl->r_list[cnt - 1]->l_removed) ++ --cnt; ++ ++ if (cnt + unload_global == ns_msl->r_nlist) ++ /* Speed up removing most recently added objects. */ ++ j = cnt; ++ else ++ for (i = 0; i < cnt; i++) ++ if (ns_msl->r_list[i]->l_removed == 0) ++ { ++ if (i != j) ++ ns_msl->r_list[j] = ns_msl->r_list[i]; ++ j++; ++ } ++ ns_msl->r_nlist = j; ++ } ++ ++ if (!RTLD_SINGLE_THREAD_P ++ && (unload_global ++ || scope_mem_left ++ || (GL(dl_scope_free_list) != NULL ++ && GL(dl_scope_free_list)->count))) ++ { ++ struct dl_scope_free_list *fsl; ++ ++ THREAD_GSCOPE_WAIT (); ++ /* Now we can free any queued old scopes. */ ++ if ((fsl = GL(dl_scope_free_list)) != NULL) ++ while (fsl->count > 0) ++ free (fsl->list[--fsl->count]); ++ } ++ + size_t tls_free_start; + size_t tls_free_end; + tls_free_start = tls_free_end = NO_TLS_OFFSET; +@@ -472,22 +518,6 @@ _dl_close_worker (struct link_map *map) + + /* That was the last reference, and this was a dlopen-loaded + object. We can unmap it. */ +- if (__builtin_expect (imap->l_global, 0)) +- { +- /* This object is in the global scope list. Remove it. */ +- struct r_scope_elem *ns_msl = ns->_ns_main_searchlist; +- unsigned int cnt = ns_msl->r_nlist; +- +- do +- --cnt; +- while (ns_msl->r_list[cnt] != imap); +- +- /* The object was already correctly registered. */ +- while (++cnt < ns_msl->r_nlist) +- ns_msl->r_list[cnt - 1] = ns_msl->r_list[cnt]; +- +- --ns_msl->r_nlist; +- } + + /* Remove the object from the dtv slotinfo array if it uses TLS. */ + if (__builtin_expect (imap->l_tls_blocksize > 0, 0)) +@@ -769,4 +799,8 @@ libc_freeres_fn (free_mem) + malloc), and in the static library it's in .bss space. */ + free_slotinfo (&GL(dl_tls_dtv_slotinfo_list)->next); + } ++ ++ void *scope_free_list = GL(dl_scope_free_list); ++ GL(dl_scope_free_list) = NULL; ++ free (scope_free_list); + } +--- glibc-20070515T2025/elf/dl-iteratephdr.c 27 Oct 2006 23:11:41 -0000 1.14 ++++ glibc-20070515T2025-fedora/elf/dl-iteratephdr.c 7 Jul 2007 21:28:54 -0000 1.11.2.5 +@@ -1,5 +1,5 @@ + /* Get loaded objects program headers. +- Copyright (C) 2001,2002,2003,2004,2006 Free Software Foundation, Inc. ++ Copyright (C) 2001,2002,2003,2004,2006,2007 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek , 2001. + +@@ -54,9 +54,9 @@ __dl_iterate_phdr (int (*callback) (stru + nloaded += GL(dl_ns)[cnt]._ns_nloaded; + + if (caller >= (const void *) l->l_map_start +- && caller < (const void *) l->l_map_end) +- /* There must be exactly one DSO for the range of the virtual +- memory. Otherwise something is really broken. */ ++ && caller < (const void *) l->l_map_end ++ && (l->l_contiguous ++ || _dl_addr_inside_object (l, (ElfW(Addr)) caller))) + ns = cnt; + } + +--- glibc-20070515T2025/elf/dl-load.c 9 Nov 2006 16:08:30 -0000 1.284 ++++ glibc-20070515T2025-fedora/elf/dl-load.c 7 Jul 2007 21:28:54 -0000 1.249.2.28 +@@ -1,5 +1,5 @@ + /* Map in a shared object's segments from the file. +- Copyright (C) 1995-2005, 2006 Free Software Foundation, Inc. ++ Copyright (C) 1995-2005, 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 +@@ -1223,6 +1223,8 @@ cannot allocate TLS data structures for + loadcmds[nloadcmds - 1].mapstart - c->mapend, + PROT_NONE); + ++ l->l_contiguous = 1; ++ + goto postmap; + } + +@@ -1242,6 +1244,7 @@ cannot allocate TLS data structures for + /* Remember which part of the address space this object uses. */ + l->l_map_start = c->mapstart + l->l_addr; + l->l_map_end = l->l_map_start + maplength; ++ l->l_contiguous = !has_holes; + + while (c < &loadcmds[nloadcmds]) + { +--- glibc-20070515T2025/elf/dl-lookup.c 15 Jan 2007 20:45:53 -0000 1.126 ++++ glibc-20070515T2025-fedora/elf/dl-lookup.c 7 Jul 2007 17:19:40 -0000 1.116.2.11 +@@ -86,7 +86,7 @@ dl_new_hash (const char *s) + /* Add extra dependency on MAP to UNDEF_MAP. */ + static int + internal_function +-add_dependency (struct link_map *undef_map, struct link_map *map, int flags) ++add_dependency (struct link_map *undef_map, struct link_map *map) + { + struct link_map **list; + struct link_map *runp; +@@ -99,18 +99,8 @@ add_dependency (struct link_map *undef_m + if (undef_map == map) + return 0; + +- /* Make sure nobody can unload the object while we are at it. +- If we hold a scope lock drop it now to avoid ABBA locking problems. */ +- if ((flags & DL_LOOKUP_SCOPE_LOCK) != 0 && !RTLD_SINGLE_THREAD_P) +- { +- __rtld_mrlock_unlock (undef_map->l_scope_lock); +- +- __rtld_lock_lock_recursive (GL(dl_load_lock)); +- +- __rtld_mrlock_lock (undef_map->l_scope_lock); +- } +- else +- __rtld_lock_lock_recursive (GL(dl_load_lock)); ++ /* Make sure nobody can unload the object while we are at it. */ ++ __rtld_lock_lock_recursive (GL(dl_load_lock)); + + /* Avoid references to objects which cannot be unloaded anyway. */ + if (map->l_type != lt_loaded +@@ -237,20 +227,15 @@ _dl_lookup_symbol_x (const char *undef_n + + bump_num_relocations (); + +- /* No other flag than DL_LOOKUP_ADD_DEPENDENCY and DL_LOOKUP_SCOPE_LOCK +- is allowed if we look up a versioned symbol. */ +- assert (version == NULL || (flags & ~(DL_LOOKUP_ADD_DEPENDENCY +- | DL_LOOKUP_SCOPE_LOCK)) == 0); ++ /* No other flag than DL_LOOKUP_ADD_DEPENDENCY is allowed if we look ++ up a versioned symbol. */ ++ assert (version == NULL || (flags & ~(DL_LOOKUP_ADD_DEPENDENCY)) == 0); + + size_t i = 0; + if (__builtin_expect (skip_map != NULL, 0)) +- { +- /* Search the relevant loaded objects for a definition. */ +- while ((*scope)->r_list[i] != skip_map) +- ++i; +- +- assert (i < (*scope)->r_nlist); +- } ++ /* Search the relevant loaded objects for a definition. */ ++ while ((*scope)->r_list[i] != skip_map) ++ ++i; + + /* Search the relevant loaded objects for a definition. */ + for (size_t start = i; *scope != NULL; start = 0, ++scope) +@@ -350,13 +335,11 @@ _dl_lookup_symbol_x (const char *undef_n + runtime lookups. */ + && (flags & DL_LOOKUP_ADD_DEPENDENCY) != 0 + /* Add UNDEF_MAP to the dependencies. */ +- && add_dependency (undef_map, current_value.m, flags) < 0) ++ && add_dependency (undef_map, current_value.m) < 0) + /* Something went wrong. Perhaps the object we tried to reference + was just removed. Try finding another definition. */ +- return _dl_lookup_symbol_x (undef_name, undef_map, ref, +- (flags & DL_LOOKUP_SCOPE_LOCK) == 0 +- ? symbol_scope : undef_map->l_scope, version, +- type_class, flags, skip_map); ++ return _dl_lookup_symbol_x (undef_name, undef_map, ref, symbol_scope, ++ version, type_class, flags, skip_map); + + /* The object is used. */ + current_value.m->l_used = 1; +--- glibc-20070515T2025/elf/dl-minimal.c 25 Jan 2007 17:10:40 -0000 1.53 ++++ glibc-20070515T2025-fedora/elf/dl-minimal.c 7 Jul 2007 17:37:06 -0000 1.48.2.5 +@@ -75,14 +75,21 @@ __libc_memalign (size_t align, size_t n) + alloc_ptr = (void *) 0 + (((alloc_ptr - (void *) 0) + align - 1) + & ~(align - 1)); + +- if (alloc_ptr + n >= alloc_end) ++ if (alloc_ptr + n >= alloc_end || n >= -(uintptr_t) alloc_ptr) + { + /* Insufficient space left; allocate another page. */ + caddr_t page; + size_t nup = (n + GLRO(dl_pagesize) - 1) & ~(GLRO(dl_pagesize) - 1); ++ if (__builtin_expect (nup == 0, 0)) ++ { ++ if (n) ++ return NULL; ++ nup = GLRO(dl_pagesize); ++ } + page = __mmap (0, nup, PROT_READ|PROT_WRITE, + MAP_ANON|MAP_PRIVATE, _dl_zerofd, 0); +- assert (page != MAP_FAILED); ++ if (page == MAP_FAILED) ++ return NULL; + if (page != alloc_end) + alloc_ptr = page; + alloc_end = page + nup; +@@ -108,7 +115,14 @@ calloc (size_t nmemb, size_t size) + /* New memory from the trivial malloc above is always already cleared. + (We make sure that's true in the rare occasion it might not be, + by clearing memory in free, below.) */ +- return malloc (nmemb * size); ++ size_t bytes = nmemb * size; ++ ++#define HALF_SIZE_T (((size_t) 1) << (8 * sizeof (size_t) / 2)) ++ if (__builtin_expect ((nmemb | size) >= HALF_SIZE_T, 0) ++ && size != 0 && bytes / size != nmemb) ++ return NULL; ++ ++ return malloc (bytes); + } + + /* This will rarely be called. */ +@@ -264,7 +278,7 @@ __strtoul_internal (const char *nptr, ch + while (*nptr >= '0' && *nptr <= '9') + { + unsigned long int digval = *nptr - '0'; +- if (result > LONG_MAX / 10 ++ if (result > ULONG_MAX / 10 + || (result == ULONG_MAX / 10 && digval > ULONG_MAX % 10)) + { + errno = ERANGE; +--- glibc-20070515T2025/elf/dl-object.c 27 Oct 2006 23:11:41 -0000 1.43 ++++ glibc-20070515T2025-fedora/elf/dl-object.c 7 Jul 2007 21:28:55 -0000 1.37.2.8 +@@ -1,5 +1,5 @@ + /* Storage management for the chain of loaded shared objects. +- Copyright (C) 1995-2002, 2004, 2006 Free Software Foundation, Inc. ++ Copyright (C) 1995-2002, 2004, 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 +@@ -85,11 +85,6 @@ _dl_new_object (char *realname, const ch + new->l_scope = new->l_scope_mem; + new->l_scope_max = sizeof (new->l_scope_mem) / sizeof (new->l_scope_mem[0]); + +- /* No need to initialize the scope lock if the initializer is zero. */ +-#if _RTLD_MRLOCK_INITIALIZER != 0 +- __rtld_mrlock_initialize (new->l_scope_lock); +-#endif +- + /* Counter for the scopes we have to handle. */ + idx = 0; + --- glibc-20070515T2025/elf/dl-open.c 11 May 2007 21:34:32 -0000 1.139 -+++ glibc-20070515T2025-fedora/elf/dl-open.c 24 May 2007 10:33:02 -0000 1.111.2.18 -@@ -125,14 +125,18 @@ add_to_global (struct link_map *new) ++++ glibc-20070515T2025-fedora/elf/dl-open.c 7 Jul 2007 17:31:45 -0000 1.111.2.21 +@@ -32,6 +32,7 @@ + #include + #include + #include ++#include + + #include + +@@ -125,15 +126,25 @@ add_to_global (struct link_map *new) { /* We have to extend the existing array of link maps in the main map. */ -+ size_t new_size = ns->_ns_global_scope_alloc; -+ if (new_size >= 256 && new_size > to_add + 8) -+ new_size *= 2; -+ else -+ new_size += to_add + 8; ++ struct link_map **old_global ++ = GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_list; ++ size_t new_nalloc = ((ns->_ns_global_scope_alloc + to_add) * 2); ++ new_global = (struct link_map **) - realloc (ns->_ns_main_searchlist->r_list, +- realloc (ns->_ns_main_searchlist->r_list, - ((ns->_ns_global_scope_alloc + to_add + 8) - * sizeof (struct link_map *))); -+ new_size * sizeof (struct link_map *)); ++ malloc (new_nalloc * sizeof (struct link_map *)); if (new_global == NULL) goto nomem; - ns->_ns_global_scope_alloc += to_add + 8; -+ ns->_ns_global_scope_alloc = new_size; ++ memcpy (new_global, old_global, ++ ns->_ns_global_scope_alloc * sizeof (struct link_map *)); ++ ++ ns->_ns_global_scope_alloc = new_nalloc; ns->_ns_main_searchlist->r_list = new_global; ++ ++ if (!RTLD_SINGLE_THREAD_P) ++ THREAD_GSCOPE_WAIT (); ++ ++ free (old_global); + } + + /* Now add the new entries. */ +@@ -154,6 +165,40 @@ add_to_global (struct link_map *new) + return 0; + } + ++int ++_dl_scope_free (struct r_scope_elem **old) ++{ ++ struct dl_scope_free_list *fsl; ++#define DL_SCOPE_FREE_LIST_SIZE (sizeof (fsl->list) / sizeof (fsl->list[0])) ++ ++ if (RTLD_SINGLE_THREAD_P) ++ free (old); ++ else if ((fsl = GL(dl_scope_free_list)) == NULL) ++ { ++ GL(dl_scope_free_list) = fsl = malloc (sizeof (*fsl)); ++ if (fsl == NULL) ++ { ++ THREAD_GSCOPE_WAIT (); ++ free (old); ++ return 1; ++ } ++ else ++ { ++ fsl->list[0] = old; ++ fsl->count = 1; ++ } ++ } ++ else if (fsl->count < DL_SCOPE_FREE_LIST_SIZE) ++ fsl->list[fsl->count++] = old; ++ else ++ { ++ THREAD_GSCOPE_WAIT (); ++ while (fsl->count > 0) ++ free (fsl->list[--fsl->count]); ++ return 1; ++ } ++ return 0; ++} + + static void + dl_open_worker (void *a) +@@ -190,10 +235,10 @@ dl_open_worker (void *a) + for (Lmid_t ns = 0; ns < DL_NNS; ++ns) + for (l = GL(dl_ns)[ns]._ns_loaded; l != NULL; l = l->l_next) + if (caller_dlopen >= (const void *) l->l_map_start +- && caller_dlopen < (const void *) l->l_map_end) ++ && caller_dlopen < (const void *) l->l_map_end ++ && (l->l_contiguous ++ || _dl_addr_inside_object (l, (ElfW(Addr)) caller_dlopen))) + { +- /* There must be exactly one DSO for the range of the virtual +- memory. Otherwise something is really broken. */ + assert (ns == l->l_ns); + call_map = l; + goto found_caller; +@@ -418,17 +463,10 @@ dl_open_worker (void *a) + memcpy (newp, imap->l_scope, cnt * sizeof (imap->l_scope[0])); + struct r_scope_elem **old = imap->l_scope; + +- if (RTLD_SINGLE_THREAD_P) +- imap->l_scope = newp; +- else +- { +- __rtld_mrlock_change (imap->l_scope_lock); +- imap->l_scope = newp; +- __rtld_mrlock_done (imap->l_scope_lock); +- } ++ imap->l_scope = newp; + + if (old != imap->l_scope_mem) +- free (old); ++ _dl_scope_free (old); + + imap->l_scope_max = new_size; + } +@@ -651,3 +689,21 @@ show_scope (struct link_map *new) + } + } + #endif ++ ++#ifdef IS_IN_rtld ++/* Return non-zero if ADDR lies within one of L's segments. */ ++int ++internal_function ++_dl_addr_inside_object (struct link_map *l, const ElfW(Addr) addr) ++{ ++ int n = l->l_phnum; ++ const ElfW(Addr) reladdr = addr - l->l_addr; ++ ++ while (--n >= 0) ++ if (l->l_phdr[n].p_type == PT_LOAD ++ && reladdr - l->l_phdr[n].p_vaddr >= 0 ++ && reladdr - l->l_phdr[n].p_vaddr < l->l_phdr[n].p_memsz) ++ return 1; ++ return 0; ++} ++#endif +--- glibc-20070515T2025/elf/dl-runtime.c 15 Jan 2007 20:46:54 -0000 1.75 ++++ glibc-20070515T2025-fedora/elf/dl-runtime.c 7 Jul 2007 17:19:40 -0000 1.65.2.7 +@@ -26,6 +26,8 @@ + #include + #include + #include "dynamic-link.h" ++#include ++ + + #if (!defined ELF_MACHINE_NO_RELA && !defined ELF_MACHINE_PLT_REL) \ + || ELF_MACHINE_NO_REL +@@ -97,17 +99,15 @@ _dl_fixup ( + not necessary for objects which cannot be unloaded or when + we are not using any threads (yet). */ + int flags = DL_LOOKUP_ADD_DEPENDENCY; +- if (l->l_type == lt_loaded && !RTLD_SINGLE_THREAD_P) +- { +- __rtld_mrlock_lock (l->l_scope_lock); +- flags |= DL_LOOKUP_SCOPE_LOCK; +- } ++ if (!RTLD_SINGLE_THREAD_P) ++ THREAD_GSCOPE_SET_FLAG (); + + result = _dl_lookup_symbol_x (strtab + sym->st_name, l, &sym, l->l_scope, + version, ELF_RTYPE_CLASS_PLT, flags, NULL); + +- if ((flags & DL_LOOKUP_SCOPE_LOCK) != 0) +- __rtld_mrlock_unlock (l->l_scope_lock); ++ /* We are done with the global scope. */ ++ if (!RTLD_SINGLE_THREAD_P) ++ THREAD_GSCOPE_RESET_FLAG (); + + /* Currently result contains the base load address (or link map) + of the object that defines sym. Now add in the symbol +@@ -191,18 +191,16 @@ _dl_profile_fixup ( + not necessary for objects which cannot be unloaded or when + we are not using any threads (yet). */ + int flags = DL_LOOKUP_ADD_DEPENDENCY; +- if (l->l_type == lt_loaded && !RTLD_SINGLE_THREAD_P) +- { +- __rtld_mrlock_lock (l->l_scope_lock); +- flags |= DL_LOOKUP_SCOPE_LOCK; +- } ++ if (!RTLD_SINGLE_THREAD_P) ++ THREAD_GSCOPE_SET_FLAG (); + + result = _dl_lookup_symbol_x (strtab + refsym->st_name, l, + &defsym, l->l_scope, version, + ELF_RTYPE_CLASS_PLT, flags, NULL); + +- if ((flags & DL_LOOKUP_SCOPE_LOCK) != 0) +- __rtld_mrlock_unlock (l->l_scope_lock); ++ /* We are done with the global scope. */ ++ if (!RTLD_SINGLE_THREAD_P) ++ THREAD_GSCOPE_RESET_FLAG (); + + /* Currently result contains the base load address (or link map) + of the object that defines sym. Now add in the symbol +--- glibc-20070515T2025/elf/dl-support.c 13 Mar 2007 21:25:15 -0000 1.92 ++++ glibc-20070515T2025-fedora/elf/dl-support.c 7 Jul 2007 17:19:40 -0000 1.84.2.12 +@@ -1,5 +1,5 @@ + /* Support for dynamic linking code in static libc. +- Copyright (C) 1996-2005, 2006 Free Software Foundation, Inc. ++ Copyright (C) 1996-2005, 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 +@@ -132,6 +132,11 @@ int (*_dl_make_stack_executable_hook) (v + = _dl_make_stack_executable; + + ++/* Function in libpthread to wait for termination of lookups. */ ++void (*_dl_wait_lookup_done) (void); ++ ++struct dl_scope_free_list *_dl_scope_free_list; ++ + #ifdef NEED_DL_SYSINFO + /* Needed for improved syscall handling on at least x86/Linux. */ + uintptr_t _dl_sysinfo = DL_SYSINFO_DEFAULT; +--- glibc-20070515T2025/elf/dl-sym.c 15 Jan 2007 20:47:44 -0000 1.34 ++++ glibc-20070515T2025-fedora/elf/dl-sym.c 7 Jul 2007 17:31:45 -0000 1.22.2.10 +@@ -98,10 +98,9 @@ do_sym (void *handle, const char *name, + for (Lmid_t ns = 0; ns < DL_NNS; ++ns) + for (struct link_map *l = GL(dl_ns)[ns]._ns_loaded; l != NULL; + l = l->l_next) +- if (caller >= l->l_map_start && caller < l->l_map_end) ++ if (caller >= l->l_map_start && caller < l->l_map_end ++ && (l->l_contiguous || _dl_addr_inside_object (l, caller))) + { +- /* There must be exactly one DSO for the range of the virtual +- memory. Otherwise something is really broken. */ + match = l; + break; + } +@@ -113,29 +112,29 @@ do_sym (void *handle, const char *name, + the initial binary. And then the more complex part + where the object is dynamically loaded and the scope + array can change. */ +- if (match->l_type != lt_loaded || RTLD_SINGLE_THREAD_P) ++ if (RTLD_SINGLE_THREAD_P) + result = GLRO(dl_lookup_symbol_x) (name, match, &ref, + match->l_scope, vers, 0, + flags | DL_LOOKUP_ADD_DEPENDENCY, + NULL); + else + { +- __rtld_mrlock_lock (match->l_scope_lock); +- + struct call_dl_lookup_args args; + args.name = name; + args.map = match; + args.vers = vers; +- args.flags = flags | DL_LOOKUP_ADD_DEPENDENCY | DL_LOOKUP_SCOPE_LOCK; ++ args.flags = flags | DL_LOOKUP_ADD_DEPENDENCY; + args.refp = &ref; + ++ THREAD_GSCOPE_SET_FLAG (); ++ + const char *objname; + const char *errstring = NULL; + bool malloced; + int err = GLRO(dl_catch_error) (&objname, &errstring, &malloced, + call_dl_lookup, &args); + +- __rtld_mrlock_unlock (match->l_scope_lock); ++ THREAD_GSCOPE_RESET_FLAG (); + + if (__builtin_expect (errstring != NULL, 0)) + { +--- glibc-20070515T2025/elf/dl-sysdep.c 27 Oct 2006 23:11:42 -0000 1.2 ++++ glibc-20070515T2025-fedora/elf/dl-sysdep.c 7 Jul 2007 21:28:55 -0000 1.1.2.4 +@@ -1,5 +1,5 @@ + /* Operating system support for run-time dynamic linker. Generic Unix version. +- Copyright (C) 1995-1998, 2000-2005, 2006 Free Software Foundation, Inc. ++ Copyright (C) 1995-1998, 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 +@@ -460,9 +460,21 @@ _dl_important_hwcaps (const char *platfo + total = temp[0].len + 1; + else + { +- total = (1UL << (cnt - 2)) * (temp[0].len + temp[cnt - 1].len + 2); +- for (n = 1; n + 1 < cnt; ++n) +- total += (1UL << (cnt - 3)) * (temp[n].len + 1); ++ total = temp[0].len + temp[cnt - 1].len + 2; ++ if (cnt > 2) ++ { ++ total <<= 1; ++ for (n = 1; n + 1 < cnt; ++n) ++ total += temp[n].len + 1; ++ if (cnt > 3 ++ && (cnt >= sizeof (size_t) * 8 ++ || total + (sizeof (*result) << 3) ++ >= (1UL << (sizeof (size_t) * 8 - cnt + 3)))) ++ _dl_signal_error (ENOMEM, NULL, NULL, ++ N_("cannot create capability list")); ++ ++ total <<= cnt - 3; ++ } } + /* The result structure: we use a very compressed way to store the +--- glibc-20070515T2025/elf/do-lookup.h 4 Sep 2006 20:40:11 -0000 1.36 ++++ glibc-20070515T2025-fedora/elf/do-lookup.h 7 Jul 2007 17:15:06 -0000 1.29.2.6 +@@ -1,5 +1,5 @@ + /* Look up a symbol in the loaded objects. +- Copyright (C) 1995-2004, 2005, 2006 Free Software Foundation, Inc. ++ Copyright (C) 1995-2004, 2005, 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 +@@ -29,8 +29,13 @@ do_lookup_x (const char *undef_name, uin + const struct r_found_version *const version, int flags, + struct link_map *skip, int type_class) + { +- struct link_map **list = scope->r_list; + size_t n = scope->r_nlist; ++ /* Make sure we read the value before proceeding. Otherwise we ++ might use r_list pointing to the initial scope and r_nlist being ++ the value after a resize. That is the only path in dl-open.c not ++ protected by GSCOPE. A read barrier here might be to expensive. */ ++ __asm volatile ("" : "+r" (n), "+m" (scope->r_list)); ++ struct link_map **list = scope->r_list; + + do + { --- glibc-20070515T2025/elf/ldconfig.c 13 Apr 2007 19:53:20 -0000 1.59 +++ glibc-20070515T2025-fedora/elf/ldconfig.c 16 Apr 2007 23:59:03 -0000 1.47.2.14 @@ -965,17 +965,19 @@ search_dirs (void) @@ -521,6 +1397,32 @@ } search_dirs (); +--- glibc-20070515T2025/elf/rtld.c 12 Feb 2007 15:17:21 -0000 1.370 ++++ glibc-20070515T2025-fedora/elf/rtld.c 7 Jul 2007 17:21:49 -0000 1.330.2.35 +@@ -1400,6 +1400,11 @@ of this helper program; chances are you + /* Iterate over all entries in the list. The order is important. */ + struct audit_ifaces *last_audit = NULL; + struct audit_list *al = audit_list->next; ++ ++ /* Since we start using the auditing DSOs right away we need to ++ initialize the data structures now. */ ++ tcbp = init_tls (); ++ + do + { + int tls_idx = GL(dl_tls_max_dtv_idx); +@@ -1409,11 +1414,6 @@ of this helper program; chances are you + always allocate the static block, we never defer it even if + no DF_STATIC_TLS bit is set. The reason is that we know + glibc will use the static model. */ +- +- /* Since we start using the auditing DSOs right away we need to +- initialize the data structures now. */ +- tcbp = init_tls (); +- + struct dlmopen_args dlmargs; + dlmargs.fname = al->name; + dlmargs.map = NULL; --- glibc-20070515T2025/elf/tst-stackguard1.c 26 Jun 2005 18:08:36 -0000 1.1 +++ glibc-20070515T2025-fedora/elf/tst-stackguard1.c 8 Aug 2005 21:24:27 -0000 1.1.2.3 @@ -160,17 +160,21 @@ do_test (void) @@ -642,6 +1544,35 @@ # if _FORTIFY_SOURCE > 1 # define __USE_FORTIFY_LEVEL 2 # else +--- glibc-20070515T2025/include/link.h 11 May 2007 06:38:05 -0000 1.44 ++++ glibc-20070515T2025-fedora/include/link.h 7 Jul 2007 17:31:45 -0000 1.32.2.12 +@@ -44,7 +44,6 @@ extern unsigned int la_objopen (struct l + #include + #include + #include +-#include + + + /* Some internal data structures of the dynamic linker used in the +@@ -187,6 +186,9 @@ struct link_map + is interested in the PLT interception.*/ + unsigned int l_removed:1; /* Nozero if the object cannot be used anymore + since it is removed. */ ++ unsigned int l_contiguous:1; /* Nonzero if inter-segment holes are ++ mprotected or if no holes are present at ++ all. */ + + /* Collected information about own RPATH directories. */ + struct r_search_path_struct l_rpath_dirs; +@@ -220,8 +222,6 @@ struct link_map + /* This is an array defining the lookup scope for this link map. + There are initially at most three different scope lists. */ + struct r_scope_elem **l_scope; +- /* We need to protect using the SCOPEREC. */ +- __rtld_mrlock_define (, l_scope_lock) + + /* A similar array, this time only with the local scope. This is + used occasionally. */ --- glibc-20070515T2025/include/bits/stdlib-ldbl.h 1 Jan 1970 00:00:00 -0000 +++ glibc-20070515T2025-fedora/include/bits/stdlib-ldbl.h 1 Feb 2006 09:30:43 -0000 1.1.2.1 @@ -0,0 +1 @@ @@ -1400,14 +2331,148 @@ # the next entry. -#SETENT_BATCH_READ=TRUE +SETENT_BATCH_READ=TRUE +--- glibc-20070515T2025/nis/nss-default.c 28 Apr 2006 21:03:17 -0000 1.3 ++++ glibc-20070515T2025-fedora/nis/nss-default.c 7 Jul 2007 21:28:55 -0000 1.1.2.4 +@@ -1,4 +1,4 @@ +-/* Copyright (C) 1996, 2001, 2004, 2006 Free Software Foundation, Inc. ++/* Copyright (C) 1996, 2001, 2004, 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 +@@ -17,6 +17,7 @@ + 02111-1307 USA. */ + + #include ++#include + #include + #include + #include +@@ -54,6 +55,7 @@ static const struct + static void + init (void) + { ++ int saved_errno = errno; + FILE *fp = fopen (default_nss, "rc"); + if (fp != NULL) + { +@@ -111,6 +113,7 @@ init (void) + + fclose (fp); + } ++ __set_errno (saved_errno); + } + + --- glibc-20070515T2025/nptl/ChangeLog 15 May 2007 06:32:02 -0000 1.970 -+++ glibc-20070515T2025-fedora/nptl/ChangeLog 24 May 2007 10:33:02 -0000 1.706.2.126 -@@ -1,3 +1,22 @@ -+2007-01-15 Jakub Jelinek ++++ glibc-20070515T2025-fedora/nptl/ChangeLog 7 Jul 2007 17:32:36 -0000 1.706.2.130 +@@ -1,3 +1,124 @@ ++2007-06-22 Jakub Jelinek ++ ++ * pthread_getattr_np.c (pthread_getattr_np): Clear cpuset and ++ cpusetsize if pthread_getaffinity_np failed with ENOSYS. ++ ++2007-05-28 Jakub Jelinek ++ ++ * sysdeps/i386/tls.h (THREAD_GSCOPE_RESET_FLAG): Use explicit ++ insn suffix. ++ (THREAD_GSCOPE_GET_FLAG): Remove. ++ * sysdeps/x86_64/tls.h (THREAD_GSCOPE_GET_FLAG): Remove. ++ * allocatestack.c (__wait_lookup_done): Revert 2007-05-24 ++ changes. ++ * sysdeps/powerpc/tls.h (tcbhead_t): Remove gscope_flag. ++ (THREAD_GSCOPE_GET_FLAG): Remove. ++ (THREAD_GSCOPE_RESET_FLAG): Use THREAD_SELF->header.gscope_flag ++ instead of THREAD_GSCOPE_GET_FLAG. ++ (THREAD_GSCOPE_SET_FLAG): Likewise. Add atomic_write_barrier after ++ it. ++ * sysdeps/s390/tls.h (THREAD_GSCOPE_FLAG_UNUSED, ++ THREAD_GSCOPE_FLAG_USED, THREAD_GSCOPE_FLAG_WAIT, ++ THREAD_GSCOPE_RESET_FLAG, THREAD_GSCOPE_SET_FLAG, ++ THREAD_GSCOPE_WAIT): Define. ++ * sysdeps/sparc/tls.h (THREAD_GSCOPE_FLAG_UNUSED, ++ THREAD_GSCOPE_FLAG_USED, THREAD_GSCOPE_FLAG_WAIT, ++ THREAD_GSCOPE_RESET_FLAG, THREAD_GSCOPE_SET_FLAG, ++ THREAD_GSCOPE_WAIT): Define. ++ * sysdeps/sh/tls.h (THREAD_GSCOPE_FLAG_UNUSED, ++ THREAD_GSCOPE_FLAG_USED, THREAD_GSCOPE_FLAG_WAIT, ++ THREAD_GSCOPE_RESET_FLAG, THREAD_GSCOPE_SET_FLAG, ++ THREAD_GSCOPE_WAIT): Define. ++ * sysdeps/ia64/tls.h (THREAD_GSCOPE_FLAG_UNUSED, ++ THREAD_GSCOPE_FLAG_USED, THREAD_GSCOPE_FLAG_WAIT, ++ THREAD_GSCOPE_RESET_FLAG, THREAD_GSCOPE_SET_FLAG, ++ THREAD_GSCOPE_WAIT): Define. ++ ++2007-05-24 Richard Henderson ++ ++ * descr.h (struct pthread): Add header.gscope_flag. ++ * sysdeps/alpha/tls.h (THREAD_GSCOPE_FLAG_UNUSED, ++ THREAD_GSCOPE_FLAG_USED, THREAD_GSCOPE_FLAG_WAIT, ++ THREAD_GSCOPE_RESET_FLAG, THREAD_GSCOPE_SET_FLAG, ++ THREAD_GSCOPE_WAIT): Define. ++ ++2007-05-26 Ulrich Drepper ++ ++ * allocatestack.c: Revert last change. ++ * init.c: Likewise. ++ * sysdeps/i386/tls.h: Likewise. ++ * sysdeps/x86_64/tls.h: Likewise. ++ ++2007-05-24 Jakub Jelinek ++ ++ * sysdeps/powerpc/tls.h (tcbhead_t): Add gscope_flag. ++ (THREAD_GSCOPE_FLAG_UNUSED, THREAD_GSCOPE_FLAG_USED, ++ THREAD_GSCOPE_FLAG_WAIT): Define. ++ (THREAD_GSCOPE_GET_FLAG, THREAD_GSCOPE_SET_FLAG, ++ THREAD_GSCOPE_RESET_FLAG, THREAD_GSCOPE_WAIT): Define. ++ * sysdeps/i386/tls.h (THREAD_GSCOPE_WAIT): Don't use ++ PTR_DEMANGLE. ++ (THREAD_GSCOPE_GET_FLAG): Define. ++ * sysdeps/x86_64/tls.h (THREAD_GSCOPE_GET_FLAG): Define. ++ * allocatestack.c (__wait_lookup_done): Use THREAD_GSCOPE_GET_FLAG ++ instead of ->header.gscope_flag directly. ++ ++2007-05-21 Ulrich Drepper + -+ * pthread_create.c (__pthread_create_2_1): On the first pthread_create -+ in a process make sure main search list can store at least 256 -+ entries. ++ * sysdeps/pthread/pthread-functions.h (struct pthread_functions): ++ Remove ptr_wait_lookup_done again. ++ * init.c (pthread_functions): Don't add .ptr_wait_lookup_done here. ++ (__pthread_initialize_minimal_internal): Initialize ++ _dl_wait_lookup_done pointer in _rtld_global directly. ++ * sysdeps/unix/sysv/linux/libc_pthread_init.c (__libc_pthread_init): ++ Remove code to code _dl_wait_lookup_done. ++ * sysdeps/x86_64/tls.h (THREAD_GSCOPE_WAIT): The pointer is not ++ encrypted for now. ++ ++2007-05-19 Ulrich Drepper ++ ++ * allocatestack.c (__wait_lookup_done): New function. ++ * sysdeps/pthread/pthread-functions.h (struct pthread_functions): ++ Add ptr_wait_lookup_done. ++ * init.c (pthread_functions): Initialize .ptr_wait_lookup_done. ++ * pthreadP.h: Declare __wait_lookup_done. ++ * sysdeps/i386/tls.h (tcbhead_t): Add gscope_flag. ++ Define macros to implement reference handling of global scope. ++ * sysdeps/x86_64/tls.h: Likewise. ++ * sysdeps/unix/sysv/linux/libc_pthread_init.c (__libc_pthread_init): ++ Initialize GL(dl_wait_lookup_done). ++ ++2007-05-25 Ulrich Drepper ++ ++ * Makefile (tests): Add tst-sem10. ++ * tst-sem10.c: New file. ++ ++2007-05-25 Ulrich Drepper ++ Jakub Jelinek ++ ++ * sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S (sem_timedwait): ++ Move __pthread_enable_asynccancel right before futex syscall. ++ * sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S (sem_timedwait): ++ Likewise. ++ ++2007-05-21 Jakub Jelinek ++ ++ * tst-robust9.c (do_test): Don't fail if ENABLE_PI and ++ pthread_mutex_init failed with ENOTSUP. + +2007-05-17 Ulrich Drepper + @@ -1425,7 +2490,7 @@ 2007-05-14 Ulrich Drepper * sysdeps/unix/sysv/linux/x86_64/sem_wait.S: Remove unnecessary -@@ -1474,6 +1493,15 @@ +@@ -1474,6 +1595,15 @@ Use __sigfillset. Document that sigfillset does the right thing wrt to SIGSETXID. @@ -1441,7 +2506,7 @@ 2005-07-11 Jakub Jelinek [BZ #1102] -@@ -2210,6 +2238,11 @@ +@@ -2210,6 +2340,11 @@ Move definition inside libpthread, libc, librt check. Provide definition for rtld. @@ -1453,7 +2518,7 @@ 2004-09-02 Ulrich Drepper * sysdeps/alpha/jmpbuf-unwind.h: Define __libc_unwind_longjmp. -@@ -4284,6 +4317,11 @@ +@@ -4284,6 +4419,11 @@ * Makefile [$(build-shared) = yes] (tests): Depend on $(test-modules). @@ -1466,14 +2531,14 @@ * tst-cancel17.c (do_test): Check if aio_cancel failed. --- glibc-20070515T2025/nptl/Makefile 8 Sep 2006 10:40:49 -0000 1.188 -+++ glibc-20070515T2025-fedora/nptl/Makefile 21 May 2007 20:01:10 -0000 1.157.2.30 ++++ glibc-20070515T2025-fedora/nptl/Makefile 7 Jul 2007 16:11:40 -0000 1.157.2.31 @@ -1,4 +1,4 @@ -# 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. # The GNU C Library is free software; you can redistribute it and/or -@@ -209,9 +209,9 @@ tests = tst-typesizes \ +@@ -209,16 +209,16 @@ tests = tst-typesizes \ tst-cond14 tst-cond15 tst-cond16 tst-cond17 tst-cond18 tst-cond19 \ tst-cond20 tst-cond21 tst-cond22 \ tst-robust1 tst-robust2 tst-robust3 tst-robust4 tst-robust5 \ @@ -1486,6 +2551,14 @@ tst-rwlock1 tst-rwlock2 tst-rwlock3 tst-rwlock4 tst-rwlock5 \ tst-rwlock6 tst-rwlock7 tst-rwlock8 tst-rwlock9 tst-rwlock10 \ tst-rwlock11 tst-rwlock12 tst-rwlock13 tst-rwlock14 \ + tst-once1 tst-once2 tst-once3 tst-once4 \ + tst-key1 tst-key2 tst-key3 tst-key4 \ + tst-sem1 tst-sem2 tst-sem3 tst-sem4 tst-sem5 tst-sem6 tst-sem7 \ +- tst-sem8 tst-sem9 \ ++ tst-sem8 tst-sem9 tst-sem10 \ + tst-barrier1 tst-barrier2 tst-barrier3 tst-barrier4 \ + tst-align tst-align2 tst-align3 \ + tst-basic1 tst-basic2 tst-basic3 tst-basic4 tst-basic5 tst-basic6 \ @@ -340,7 +340,8 @@ endif extra-objs += $(crti-objs) $(crtn-objs) omit-deps += crti crtn @@ -1518,39 +2591,136 @@ else $(addprefix $(objpfx),$(tests) $(test-srcs)): $(objpfx)libpthread.a endif ---- glibc-20070515T2025/nptl/pthread_create.c 5 Sep 2006 17:12:15 -0000 1.54 -+++ glibc-20070515T2025-fedora/nptl/pthread_create.c 24 May 2007 10:33:02 -0000 1.34.2.18 -@@ -462,6 +462,30 @@ __pthread_create_2_1 (newthread, attr, s - pd->flags = ((iattr->flags & ~(ATTR_FLAG_SCHED_SET | ATTR_FLAG_POLICY_SET)) - | (self->flags & (ATTR_FLAG_SCHED_SET | ATTR_FLAG_POLICY_SET))); - -+ /* Hack: realloc the main search list on the first pthread_create call -+ to minimize the number of global search scope reallocations. -+ Wastes at most 1KB on 32-bit and 2KB on 64-bit per process -+ which calls pthread_create. */ -+ if (__builtin_expect (self->header.multiple_threads == 0, 0) -+ && GL(dl_ns)[0]._ns_main_searchlist -+ && GL(dl_ns)[0]._ns_main_searchlist->r_nlist < 256 -+ && GL(dl_ns)[0]._ns_global_scope_alloc < 256) +--- glibc-20070515T2025/nptl/allocatestack.c 7 May 2007 22:02:37 -0000 1.65 ++++ glibc-20070515T2025-fedora/nptl/allocatestack.c 7 Jul 2007 17:15:06 -0000 1.51.2.14 +@@ -996,3 +996,60 @@ __pthread_init_static_tls (struct link_m + + lll_unlock (stack_cache_lock); + } ++ ++ ++void ++attribute_hidden ++__wait_lookup_done (void) ++{ ++ lll_lock (stack_cache_lock); ++ ++ struct pthread *self = THREAD_SELF; ++ ++ /* Iterate over the list with system-allocated threads first. */ ++ list_t *runp; ++ list_for_each (runp, &stack_used) + { -+ struct link_map **new_global = (struct link_map **) -+ realloc (GL(dl_ns)[0]._ns_global_scope_alloc == 0 -+ ? NULL : GL(dl_ns)[0]._ns_main_searchlist->r_list, -+ 256 * sizeof (struct link_map *)); -+ if (new_global != NULL) -+ { -+ if (GL(dl_ns)[0]._ns_global_scope_alloc == 0) -+ memcpy (new_global, GL(dl_ns)[0]._ns_main_searchlist->r_list, -+ GL(dl_ns)[0]._ns_main_searchlist->r_nlist -+ * sizeof (struct link_map *)); -+ GL(dl_ns)[0]._ns_global_scope_alloc = 256; -+ GL(dl_ns)[0]._ns_main_searchlist->r_list = new_global; -+ } ++ struct pthread *t = list_entry (runp, struct pthread, list); ++ if (t == self || t->header.gscope_flag == THREAD_GSCOPE_FLAG_UNUSED) ++ continue; ++ ++ int *const gscope_flagp = &t->header.gscope_flag; ++ ++ /* We have to wait until this thread is done with the global ++ scope. First tell the thread that we are waiting and ++ possibly have to be woken. */ ++ if (atomic_compare_and_exchange_bool_acq (gscope_flagp, ++ THREAD_GSCOPE_FLAG_WAIT, ++ THREAD_GSCOPE_FLAG_USED)) ++ continue; ++ ++ do ++ lll_futex_wait (gscope_flagp, THREAD_GSCOPE_FLAG_WAIT); ++ while (*gscope_flagp == THREAD_GSCOPE_FLAG_WAIT); ++ } ++ ++ /* Now the list with threads using user-allocated stacks. */ ++ list_for_each (runp, &__stack_user) ++ { ++ struct pthread *t = list_entry (runp, struct pthread, list); ++ if (t == self || t->header.gscope_flag == THREAD_GSCOPE_FLAG_UNUSED) ++ continue; ++ ++ int *const gscope_flagp = &t->header.gscope_flag; ++ ++ /* We have to wait until this thread is done with the global ++ scope. First tell the thread that we are waiting and ++ possibly have to be woken. */ ++ if (atomic_compare_and_exchange_bool_acq (gscope_flagp, ++ THREAD_GSCOPE_FLAG_WAIT, ++ THREAD_GSCOPE_FLAG_USED)) ++ continue; ++ ++ do ++ lll_futex_wait (gscope_flagp, THREAD_GSCOPE_FLAG_WAIT); ++ while (*gscope_flagp == THREAD_GSCOPE_FLAG_WAIT); + } + - /* Initialize the field for the ID of the thread which is waiting - for us. This is a self-reference in case the thread is created - detached. */ ++ lll_unlock (stack_cache_lock); ++} +--- glibc-20070515T2025/nptl/descr.h 11 May 2007 06:11:48 -0000 1.39 ++++ glibc-20070515T2025-fedora/nptl/descr.h 7 Jul 2007 17:15:06 -0000 1.23.2.19 +@@ -131,6 +131,7 @@ struct pthread + struct + { + int multiple_threads; ++ int gscope_flag; + } header; + #endif + +--- glibc-20070515T2025/nptl/init.c 27 Oct 2006 23:11:43 -0000 1.60 ++++ glibc-20070515T2025-fedora/nptl/init.c 7 Jul 2007 21:28:55 -0000 1.49.2.13 +@@ -1,4 +1,4 @@ +-/* 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. + +@@ -386,6 +386,8 @@ __pthread_initialize_minimal_internal (v + + GL(dl_init_static_tls) = &__pthread_init_static_tls; + ++ GL(dl_wait_lookup_done) = &__wait_lookup_done; ++ + /* Register the fork generation counter with the libc. */ + #ifndef TLS_MULTIPLE_THREADS_IN_TCB + __libc_multiple_threads_ptr = +--- glibc-20070515T2025/nptl/pthreadP.h 23 Aug 2006 17:42:52 -0000 1.64 ++++ glibc-20070515T2025-fedora/nptl/pthreadP.h 7 Jul 2007 21:28:55 -0000 1.54.2.12 +@@ -1,4 +1,4 @@ +-/* 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. + +@@ -545,6 +545,8 @@ extern int __nptl_setxid (struct xid_com + + extern void __free_stack_cache (void) attribute_hidden; + ++extern void __wait_lookup_done (void) attribute_hidden; ++ + #ifdef SHARED + # define PTHREAD_STATIC_FN_REQUIRE(name) + #else +--- glibc-20070515T2025/nptl/pthread_getattr_np.c 7 Apr 2006 04:26:42 -0000 1.12 ++++ glibc-20070515T2025-fedora/nptl/pthread_getattr_np.c 7 Jul 2007 21:28:55 -0000 1.11.2.3 +@@ -1,4 +1,4 @@ +-/* Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc. ++/* Copyright (C) 2002, 2003, 2004, 2006, 2007 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 2002. + +@@ -168,8 +168,12 @@ pthread_getattr_np (thread_id, attr) + { + free (cpuset); + if (ret == ENOSYS) +- /* There is no such functionality. */ +- ret = 0; ++ { ++ /* There is no such functionality. */ ++ ret = 0; ++ iattr->cpuset = NULL; ++ iattr->cpusetsize = 0; ++ } + } + } + --- glibc-20070515T2025/nptl/pthread_mutex_lock.c 14 Aug 2006 23:01:26 -0000 1.15 +++ glibc-20070515T2025-fedora/nptl/pthread_mutex_lock.c 21 May 2007 20:01:11 -0000 1.8.2.7 @@ -1,4 +1,4 @@ @@ -1607,8 +2777,8 @@ if (newval != oldval) { --- glibc-20070515T2025/nptl/tst-robust9.c 1 Jan 1970 00:00:00 -0000 -+++ glibc-20070515T2025-fedora/nptl/tst-robust9.c 21 May 2007 20:01:11 -0000 1.1.2.1 -@@ -0,0 +1,87 @@ ++++ glibc-20070515T2025-fedora/nptl/tst-robust9.c 7 Jul 2007 16:03:57 -0000 1.1.2.2 +@@ -0,0 +1,94 @@ +#include +#include +#include @@ -1665,6 +2835,13 @@ + } +#endif + err = pthread_mutex_init (&m, &ma); ++#ifdef ENABLE_PI ++ if (err == ENOTSUP) ++ { ++ puts ("PI robust mutexes not supported"); ++ return 0; ++ } ++#endif + if (err) + { + puts ("pthread_mutex_init"); @@ -1701,46 +2878,515 @@ @@ -0,0 +1,2 @@ +#define ENABLE_PI 1 +#include "tst-robust9.c" ---- glibc-20070515T2025/nptl/tst-stackguard1.c 26 Jun 2005 17:44:14 -0000 1.1 -+++ glibc-20070515T2025-fedora/nptl/tst-stackguard1.c 8 Aug 2005 21:24:28 -0000 1.1.2.3 -@@ -190,17 +190,21 @@ do_test (void) - the 16 runs, something is very wrong. */ - int ndifferences = 0; - int ndefaults = 0; -+ int npartlyrandomized = 0; - for (i = 0; i < N; ++i) - { - if (child_stack_chk_guards[i] != child_stack_chk_guards[i+1]) - ndifferences++; - else if (child_stack_chk_guards[i] == default_guard) - ndefaults++; -+ else if (*(char *) &child_stack_chk_guards[i] == 0) -+ npartlyrandomized++; - } - -- printf ("differences %d defaults %d\n", ndifferences, ndefaults); -+ printf ("differences %d defaults %d partly randomized %d\n", -+ ndifferences, ndefaults, npartlyrandomized); - -- if (ndifferences < N / 2 && ndefaults < N / 2) -+ if ((ndifferences + ndefaults + npartlyrandomized) < 3 * N / 4) - { - puts ("stack guard canaries are not randomized enough"); - puts ("nor equal to the default canary value"); ---- glibc-20070515T2025/nptl/sysdeps/unix/sysv/linux/kernel-features.h 1 Jan 1970 00:00:00 -0000 -+++ glibc-20070515T2025-fedora/nptl/sysdeps/unix/sysv/linux/kernel-features.h 22 Sep 2004 21:21:02 -0000 1.1.2.1 -@@ -0,0 +1,6 @@ -+#include_next +--- glibc-20070515T2025/nptl/tst-sem10.c 1 Jan 1970 00:00:00 -0000 ++++ glibc-20070515T2025-fedora/nptl/tst-sem10.c 7 Jul 2007 16:11:40 -0000 1.1.2.1 +@@ -0,0 +1,88 @@ ++/* Copyright (C) 2007 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Jakub Jelinek , 2007. + -+/* NPTL can always assume all clone thread flags work. */ -+#ifndef __ASSUME_CLONE_THREAD_FLAGS -+# define __ASSUME_CLONE_THREAD_FLAGS 1 -+#endif ---- glibc-20070515T2025/nscd/connections.c 1 Feb 2007 16:05:31 -0000 1.98 -+++ glibc-20070515T2025-fedora/nscd/connections.c 10 May 2007 17:07:30 -0000 1.55.2.29 -@@ -68,6 +68,7 @@ static gid_t *server_groups; - # define NGROUPS 32 - #endif ++ 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) ++{ ++ sem_t s; ++ if (sem_init (&s, 0, 0) == -1) ++ { ++ puts ("sem_init failed"); ++ return 1; ++ } ++ ++ struct timeval tv; ++ if (gettimeofday (&tv, NULL) != 0) ++ { ++ puts ("gettimeofday failed"); ++ return 1; ++ } ++ ++ struct timespec ts; ++ TIMEVAL_TO_TIMESPEC (&tv, &ts); ++ ++ /* Set ts to yesterday. */ ++ ts.tv_sec -= 86400; ++ ++ int type_before; ++ if (pthread_setcanceltype (PTHREAD_CANCEL_DEFERRED, &type_before) != 0) ++ { ++ puts ("first pthread_setcanceltype failed"); ++ return 1; ++ } ++ ++ errno = 0; ++ if (TEMP_FAILURE_RETRY (sem_timedwait (&s, &ts)) != -1) ++ { ++ puts ("sem_timedwait succeeded"); ++ return 1; ++ } ++ if (errno != ETIMEDOUT) ++ { ++ printf ("sem_timedwait return errno = %d instead of ETIMEDOUT\n", ++ errno); ++ return 1; ++ } ++ ++ int type_after; ++ if (pthread_setcanceltype (PTHREAD_CANCEL_DEFERRED, &type_after) != 0) ++ { ++ puts ("second pthread_setcanceltype failed"); ++ return 1; ++ } ++ if (type_after != PTHREAD_CANCEL_DEFERRED) ++ { ++ puts ("sem_timedwait changed cancellation type"); ++ return 1; ++ } ++ ++ return 0; ++} ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +--- glibc-20070515T2025/nptl/tst-stackguard1.c 26 Jun 2005 17:44:14 -0000 1.1 ++++ glibc-20070515T2025-fedora/nptl/tst-stackguard1.c 8 Aug 2005 21:24:28 -0000 1.1.2.3 +@@ -190,17 +190,21 @@ do_test (void) + the 16 runs, something is very wrong. */ + int ndifferences = 0; + int ndefaults = 0; ++ int npartlyrandomized = 0; + for (i = 0; i < N; ++i) + { + if (child_stack_chk_guards[i] != child_stack_chk_guards[i+1]) + ndifferences++; + else if (child_stack_chk_guards[i] == default_guard) + ndefaults++; ++ else if (*(char *) &child_stack_chk_guards[i] == 0) ++ npartlyrandomized++; + } + +- printf ("differences %d defaults %d\n", ndifferences, ndefaults); ++ printf ("differences %d defaults %d partly randomized %d\n", ++ ndifferences, ndefaults, npartlyrandomized); + +- if (ndifferences < N / 2 && ndefaults < N / 2) ++ if ((ndifferences + ndefaults + npartlyrandomized) < 3 * N / 4) + { + puts ("stack guard canaries are not randomized enough"); + puts ("nor equal to the default canary value"); +--- glibc-20070515T2025/nptl/sysdeps/alpha/tls.h 27 Oct 2006 23:11:43 -0000 1.7 ++++ glibc-20070515T2025-fedora/nptl/sysdeps/alpha/tls.h 7 Jul 2007 21:28:55 -0000 1.4.2.5 +@@ -1,5 +1,5 @@ + /* Definition for thread-local data handling. NPTL/Alpha version. +- Copyright (C) 2003, 2005, 2006 Free Software Foundation, Inc. ++ Copyright (C) 2003, 2005, 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 +@@ -121,6 +121,29 @@ typedef struct + #define THREAD_SETMEM_NC(descr, member, idx, value) \ + descr->member[idx] = (value) + ++/* Get and set the global scope generation counter in struct pthread. */ ++#define THREAD_GSCOPE_FLAG_UNUSED 0 ++#define THREAD_GSCOPE_FLAG_USED 1 ++#define THREAD_GSCOPE_FLAG_WAIT 2 ++#define THREAD_GSCOPE_RESET_FLAG() \ ++ do \ ++ { int __res \ ++ = atomic_exchange_rel (&THREAD_SELF->header.gscope_flag, \ ++ THREAD_GSCOPE_FLAG_UNUSED); \ ++ if (__res == THREAD_GSCOPE_FLAG_WAIT) \ ++ lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1); \ ++ } \ ++ while (0) ++#define THREAD_GSCOPE_SET_FLAG() \ ++ do \ ++ { \ ++ THREAD_SELF->header.gscope_flag = THREAD_GSCOPE_FLAG_USED; \ ++ atomic_write_barrier (); \ ++ } \ ++ while (0) ++#define THREAD_GSCOPE_WAIT() \ ++ GL(dl_wait_lookup_done) () ++ + #endif /* __ASSEMBLER__ */ + + #endif /* tls.h */ +--- glibc-20070515T2025/nptl/sysdeps/i386/tls.h 27 Oct 2006 23:11:43 -0000 1.33 ++++ glibc-20070515T2025-fedora/nptl/sysdeps/i386/tls.h 7 Jul 2007 21:28:55 -0000 1.26.2.9 +@@ -1,5 +1,5 @@ + /* Definition for thread-local data handling. nptl/i386 version. +- 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. + + The GNU C Library is free software; you can redistribute it and/or +@@ -51,6 +51,7 @@ typedef struct + uintptr_t sysinfo; + uintptr_t stack_guard; + uintptr_t pointer_guard; ++ int gscope_flag; + } tcbhead_t; + + # define TLS_MULTIPLE_THREADS_IN_TCB 1 +@@ -431,6 +432,26 @@ union user_desc_init + = THREAD_GETMEM (THREAD_SELF, header.pointer_guard)) + + ++/* Get and set the global scope generation counter in the TCB head. */ ++#define THREAD_GSCOPE_FLAG_UNUSED 0 ++#define THREAD_GSCOPE_FLAG_USED 1 ++#define THREAD_GSCOPE_FLAG_WAIT 2 ++#define THREAD_GSCOPE_RESET_FLAG() \ ++ do \ ++ { int __res; \ ++ asm volatile ("xchgl %0, %%gs:%P1" \ ++ : "=r" (__res) \ ++ : "i" (offsetof (struct pthread, header.gscope_flag)), \ ++ "0" (THREAD_GSCOPE_FLAG_UNUSED)); \ ++ if (__res == THREAD_GSCOPE_FLAG_WAIT) \ ++ lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1); \ ++ } \ ++ while (0) ++#define THREAD_GSCOPE_SET_FLAG() \ ++ THREAD_SETMEM (THREAD_SELF, header.gscope_flag, THREAD_GSCOPE_FLAG_USED) ++#define THREAD_GSCOPE_WAIT() \ ++ GL(dl_wait_lookup_done) () ++ + #endif /* __ASSEMBLER__ */ + + #endif /* tls.h */ +--- glibc-20070515T2025/nptl/sysdeps/ia64/tls.h 27 Oct 2006 23:11:43 -0000 1.12 ++++ glibc-20070515T2025-fedora/nptl/sysdeps/ia64/tls.h 7 Jul 2007 21:28:55 -0000 1.7.2.7 +@@ -1,5 +1,5 @@ + /* Definition for thread-local data handling. nptl/IA-64 version. +- Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. ++ Copyright (C) 2003, 2004, 2005, 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 +@@ -163,6 +163,29 @@ register struct pthread *__thread_self _ + (((uintptr_t *) ((char *) (descr) + TLS_PRE_TCB_SIZE))[-2] \ + = THREAD_GET_POINTER_GUARD ()) + ++/* Get and set the global scope generation counter in struct pthread. */ ++#define THREAD_GSCOPE_FLAG_UNUSED 0 ++#define THREAD_GSCOPE_FLAG_USED 1 ++#define THREAD_GSCOPE_FLAG_WAIT 2 ++#define THREAD_GSCOPE_RESET_FLAG() \ ++ do \ ++ { int __res \ ++ = atomic_exchange_rel (&THREAD_SELF->header.gscope_flag, \ ++ THREAD_GSCOPE_FLAG_UNUSED); \ ++ if (__res == THREAD_GSCOPE_FLAG_WAIT) \ ++ lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1); \ ++ } \ ++ while (0) ++#define THREAD_GSCOPE_SET_FLAG() \ ++ do \ ++ { \ ++ THREAD_SELF->header.gscope_flag = THREAD_GSCOPE_FLAG_USED; \ ++ atomic_write_barrier (); \ ++ } \ ++ while (0) ++#define THREAD_GSCOPE_WAIT() \ ++ GL(dl_wait_lookup_done) () ++ + #endif /* __ASSEMBLER__ */ + + #endif /* tls.h */ +--- glibc-20070515T2025/nptl/sysdeps/powerpc/tls.h 27 Oct 2006 23:11:43 -0000 1.12 ++++ glibc-20070515T2025-fedora/nptl/sysdeps/powerpc/tls.h 7 Jul 2007 21:28:55 -0000 1.8.2.6 +@@ -1,5 +1,5 @@ + /* Definition for thread-local data handling. NPTL/PowerPC version. +- Copyright (C) 2003, 2005, 2006 Free Software Foundation, Inc. ++ Copyright (C) 2003, 2005, 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 +@@ -180,6 +180,29 @@ register void *__thread_register __asm__ + different value to mean unset l_tls_offset. */ + # define NO_TLS_OFFSET -1 + ++/* Get and set the global scope generation counter in struct pthread. */ ++#define THREAD_GSCOPE_FLAG_UNUSED 0 ++#define THREAD_GSCOPE_FLAG_USED 1 ++#define THREAD_GSCOPE_FLAG_WAIT 2 ++#define THREAD_GSCOPE_RESET_FLAG() \ ++ do \ ++ { int __res \ ++ = atomic_exchange_rel (&THREAD_SELF->header.gscope_flag, \ ++ THREAD_GSCOPE_FLAG_UNUSED); \ ++ if (__res == THREAD_GSCOPE_FLAG_WAIT) \ ++ lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1); \ ++ } \ ++ while (0) ++#define THREAD_GSCOPE_SET_FLAG() \ ++ do \ ++ { \ ++ THREAD_SELF->header.gscope_flag = THREAD_GSCOPE_FLAG_USED; \ ++ atomic_write_barrier (); \ ++ } \ ++ while (0) ++#define THREAD_GSCOPE_WAIT() \ ++ GL(dl_wait_lookup_done) () ++ + #endif /* __ASSEMBLER__ */ + + #endif /* tls.h */ +--- glibc-20070515T2025/nptl/sysdeps/s390/tls.h 27 Oct 2006 23:11:44 -0000 1.15 ++++ glibc-20070515T2025-fedora/nptl/sysdeps/s390/tls.h 7 Jul 2007 21:28:55 -0000 1.10.2.7 +@@ -1,5 +1,5 @@ + /* Definition for thread-local data handling. NPTL/s390 version. +- Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. ++ Copyright (C) 2003, 2004, 2005, 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 +@@ -50,6 +50,7 @@ typedef struct + int multiple_threads; + uintptr_t sysinfo; + uintptr_t stack_guard; ++ int gscope_flag; + } tcbhead_t; + + # ifndef __s390x__ +@@ -168,6 +169,29 @@ typedef struct + #define THREAD_SET_POINTER_GUARD(value) + #define THREAD_COPY_POINTER_GUARD(descr) + ++/* Get and set the global scope generation counter in struct pthread. */ ++#define THREAD_GSCOPE_FLAG_UNUSED 0 ++#define THREAD_GSCOPE_FLAG_USED 1 ++#define THREAD_GSCOPE_FLAG_WAIT 2 ++#define THREAD_GSCOPE_RESET_FLAG() \ ++ do \ ++ { int __res \ ++ = atomic_exchange_rel (&THREAD_SELF->header.gscope_flag, \ ++ THREAD_GSCOPE_FLAG_UNUSED); \ ++ if (__res == THREAD_GSCOPE_FLAG_WAIT) \ ++ lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1); \ ++ } \ ++ while (0) ++#define THREAD_GSCOPE_SET_FLAG() \ ++ do \ ++ { \ ++ THREAD_SELF->header.gscope_flag = THREAD_GSCOPE_FLAG_USED; \ ++ atomic_write_barrier (); \ ++ } \ ++ while (0) ++#define THREAD_GSCOPE_WAIT() \ ++ GL(dl_wait_lookup_done) () ++ + #endif /* __ASSEMBLER__ */ + + #endif /* tls.h */ +--- glibc-20070515T2025/nptl/sysdeps/sh/tls.h 27 Oct 2006 23:11:44 -0000 1.11 ++++ glibc-20070515T2025-fedora/nptl/sysdeps/sh/tls.h 7 Jul 2007 21:28:55 -0000 1.7.2.6 +@@ -1,5 +1,5 @@ + /* Definition for thread-local data handling. NPTL/SH version. +- Copyright (C) 2003, 2005, 2006 Free Software Foundation, Inc. ++ Copyright (C) 2003, 2005, 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 +@@ -150,6 +150,29 @@ typedef struct + __asm __volatile ("stc gbr,%0" : "=r" (__tcbp)); \ + ((tcbhead_t *) (descr + 1))->pointer_guard = __tcbp->pointer_guard;}) + ++/* Get and set the global scope generation counter in struct pthread. */ ++#define THREAD_GSCOPE_FLAG_UNUSED 0 ++#define THREAD_GSCOPE_FLAG_USED 1 ++#define THREAD_GSCOPE_FLAG_WAIT 2 ++#define THREAD_GSCOPE_RESET_FLAG() \ ++ do \ ++ { int __res \ ++ = atomic_exchange_rel (&THREAD_SELF->header.gscope_flag, \ ++ THREAD_GSCOPE_FLAG_UNUSED); \ ++ if (__res == THREAD_GSCOPE_FLAG_WAIT) \ ++ lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1); \ ++ } \ ++ while (0) ++#define THREAD_GSCOPE_SET_FLAG() \ ++ do \ ++ { \ ++ THREAD_SELF->header.gscope_flag = THREAD_GSCOPE_FLAG_USED; \ ++ atomic_write_barrier (); \ ++ } \ ++ while (0) ++#define THREAD_GSCOPE_WAIT() \ ++ GL(dl_wait_lookup_done) () ++ + #endif /* __ASSEMBLER__ */ + + #endif /* tls.h */ +--- glibc-20070515T2025/nptl/sysdeps/sparc/tls.h 27 Oct 2006 23:11:44 -0000 1.8 ++++ glibc-20070515T2025-fedora/nptl/sysdeps/sparc/tls.h 7 Jul 2007 21:28:56 -0000 1.3.2.7 +@@ -1,5 +1,5 @@ + /* Definitions for thread-local data handling. NPTL/sparc version. +- Copyright (C) 2003, 2005, 2006 Free Software Foundation, Inc. ++ Copyright (C) 2003, 2005, 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 +@@ -141,6 +141,29 @@ register struct pthread *__thread_self _ + # define THREAD_COPY_POINTER_GUARD(descr) \ + ((descr)->header.pointer_guard = THREAD_GET_POINTER_GUARD ()) + ++/* Get and set the global scope generation counter in struct pthread. */ ++#define THREAD_GSCOPE_FLAG_UNUSED 0 ++#define THREAD_GSCOPE_FLAG_USED 1 ++#define THREAD_GSCOPE_FLAG_WAIT 2 ++#define THREAD_GSCOPE_RESET_FLAG() \ ++ do \ ++ { int __res \ ++ = atomic_exchange_rel (&THREAD_SELF->header.gscope_flag, \ ++ THREAD_GSCOPE_FLAG_UNUSED); \ ++ if (__res == THREAD_GSCOPE_FLAG_WAIT) \ ++ lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1); \ ++ } \ ++ while (0) ++#define THREAD_GSCOPE_SET_FLAG() \ ++ do \ ++ { \ ++ THREAD_SELF->header.gscope_flag = THREAD_GSCOPE_FLAG_USED; \ ++ atomic_write_barrier (); \ ++ } \ ++ while (0) ++#define THREAD_GSCOPE_WAIT() \ ++ GL(dl_wait_lookup_done) () ++ + #endif /* !ASSEMBLER */ + + #endif /* tls.h */ +--- glibc-20070515T2025/nptl/sysdeps/unix/sysv/linux/kernel-features.h 1 Jan 1970 00:00:00 -0000 ++++ glibc-20070515T2025-fedora/nptl/sysdeps/unix/sysv/linux/kernel-features.h 22 Sep 2004 21:21:02 -0000 1.1.2.1 +@@ -0,0 +1,6 @@ ++#include_next ++ ++/* NPTL can always assume all clone thread flags work. */ ++#ifndef __ASSUME_CLONE_THREAD_FLAGS ++# define __ASSUME_CLONE_THREAD_FLAGS 1 ++#endif +--- glibc-20070515T2025/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S 9 Apr 2006 02:42:29 -0000 1.8 ++++ glibc-20070515T2025-fedora/nptl/sysdeps/unix/sysv/linux/i386/i486/sem_timedwait.S 7 Jul 2007 21:28:56 -0000 1.6.2.4 +@@ -1,4 +1,4 @@ +-/* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. ++/* Copyright (C) 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 2002. + +@@ -79,10 +79,7 @@ sem_timedwait: + jae 6f + + cfi_offset(3, -16) /* %ebx */ +-7: call __pthread_enable_asynccancel +- movl %eax, 8(%esp) +- +- xorl %ecx, %ecx ++7: xorl %ecx, %ecx + movl %esp, %ebx + movl %ecx, %edx + movl $SYS_gettimeofday, %eax +@@ -105,6 +102,10 @@ sem_timedwait: + + movl %ecx, (%esp) /* Store relative timeout. */ + movl %edx, 4(%esp) ++ ++ call __pthread_enable_asynccancel ++ movl %eax, 8(%esp) ++ + movl 28(%esp), %ebx + xorl %ecx, %ecx + movl %esp, %esi +--- glibc-20070515T2025/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S 15 May 2007 06:24:23 -0000 1.11 ++++ glibc-20070515T2025-fedora/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S 7 Jul 2007 16:11:40 -0000 1.9.2.3 +@@ -73,10 +73,7 @@ sem_timedwait: + cfi_offset(14, -24) /* %r14 */ + jae 6f + +-7: call __pthread_enable_asynccancel +- movl %eax, 16(%rsp) +- +- xorl %esi, %esi ++7: xorl %esi, %esi + movq %rsp, %rdi + movq $VSYSCALL_ADDR_vgettimeofday, %rax + callq *%rax +@@ -99,6 +96,9 @@ sem_timedwait: + movq %rdi, (%rsp) /* Store relative timeout. */ + movq %rsi, 8(%rsp) + ++ call __pthread_enable_asynccancel ++ movl %eax, 16(%rsp) ++ + movq %rsp, %r10 + movq %r12, %rdi + xorl %esi, %esi +--- glibc-20070515T2025/nptl/sysdeps/x86_64/tls.h 26 Apr 2007 04:44:47 -0000 1.28 ++++ glibc-20070515T2025-fedora/nptl/sysdeps/x86_64/tls.h 7 Jul 2007 17:15:07 -0000 1.21.2.8 +@@ -47,6 +47,7 @@ typedef struct + dtv_t *dtv; + void *self; /* Pointer to the thread descriptor. */ + int multiple_threads; ++ int gscope_flag; + uintptr_t sysinfo; + uintptr_t stack_guard; + uintptr_t pointer_guard; +@@ -337,6 +338,26 @@ typedef struct + = THREAD_GETMEM (THREAD_SELF, header.pointer_guard)) + + ++/* Get and set the global scope generation counter in the TCB head. */ ++#define THREAD_GSCOPE_FLAG_UNUSED 0 ++#define THREAD_GSCOPE_FLAG_USED 1 ++#define THREAD_GSCOPE_FLAG_WAIT 2 ++#define THREAD_GSCOPE_RESET_FLAG() \ ++ do \ ++ { int __res; \ ++ asm volatile ("xchgl %0, %%fs:%P1" \ ++ : "=r" (__res) \ ++ : "i" (offsetof (struct pthread, header.gscope_flag)), \ ++ "0" (THREAD_GSCOPE_FLAG_UNUSED)); \ ++ if (__res == THREAD_GSCOPE_FLAG_WAIT) \ ++ lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1); \ ++ } \ ++ while (0) ++#define THREAD_GSCOPE_SET_FLAG() \ ++ THREAD_SETMEM (THREAD_SELF, header.gscope_flag, THREAD_GSCOPE_FLAG_USED) ++#define THREAD_GSCOPE_WAIT() \ ++ GL(dl_wait_lookup_done) () ++ + #endif /* __ASSEMBLER__ */ + + #endif /* tls.h */ +--- glibc-20070515T2025/nscd/connections.c 1 Feb 2007 16:05:31 -0000 1.98 ++++ glibc-20070515T2025-fedora/nscd/connections.c 10 May 2007 17:07:30 -0000 1.55.2.29 +@@ -68,6 +68,7 @@ static gid_t *server_groups; + # define NGROUPS 32 + #endif static int server_ngroups; +static volatile int sighup_pending; @@ -1878,6 +3524,25 @@ RETVAL=$? echo [ $RETVAL -eq 0 ] && touch /var/lock/subsys/nscd +--- glibc-20070515T2025/nscd/nscd_helper.c 16 Feb 2007 06:34:19 -0000 1.22 ++++ glibc-20070515T2025-fedora/nscd/nscd_helper.c 7 Jul 2007 16:15:16 -0000 1.6.2.14 +@@ -269,11 +269,12 @@ get_mapping (request_type type, const ch + != keylen, 0)) + goto out_close2; + +- mapfd = *(int *) CMSG_DATA (cmsg); ++ if (__builtin_expect (CMSG_FIRSTHDR (&msg) == NULL ++ || (CMSG_FIRSTHDR (&msg)->cmsg_len ++ != CMSG_LEN (sizeof (int))), 0)) ++ goto out_close2; + +- if (__builtin_expect (CMSG_FIRSTHDR (&msg)->cmsg_len +- != CMSG_LEN (sizeof (int)), 0)) +- goto out_close; ++ mapfd = *(int *) CMSG_DATA (cmsg); + + struct stat64 st; + if (__builtin_expect (strcmp (resdata, key) != 0, 0) --- glibc-20070515T2025/posix/Makefile 3 Apr 2007 23:28:20 -0000 1.197 +++ glibc-20070515T2025-fedora/posix/Makefile 16 Apr 2007 23:59:05 -0000 1.171.2.24 @@ -110,7 +110,7 @@ generated := $(addprefix wordexp-test-re @@ -1980,6 +3645,149 @@ /* Spawn to processes which will do the work. */ pid1 = fork (); +--- glibc-20070515T2025/stdio-common/Makefile 18 Feb 2007 08:25:39 -0000 1.100 ++++ glibc-20070515T2025-fedora/stdio-common/Makefile 8 Jul 2007 10:08:25 -0000 1.90.2.11 +@@ -54,7 +54,8 @@ tests := tstscanf test_rdwr test-popen t + tst-swprintf tst-fseek tst-fmemopen test-vfprintf tst-gets \ + tst-perror tst-sprintf tst-rndseek tst-fdopen tst-fphex bug14 bug15 \ + tst-popen tst-unlockedio tst-fmemopen2 tst-put-error tst-fgets \ +- tst-fwrite bug16 bug17 tst-swscanf ++ tst-fwrite bug16 bug17 tst-swscanf tst-sprintf2 bug18 bug18a \ ++ bug19 bug19a + + test-srcs = tst-unbputc tst-printf + +--- glibc-20070515T2025/stdio-common/bug18.c 1 Jan 1970 00:00:00 -0000 ++++ glibc-20070515T2025-fedora/stdio-common/bug18.c 8 Jul 2007 10:08:25 -0000 1.2.2.1 +@@ -0,0 +1,48 @@ ++#include ++#include ++#include ++ ++#ifndef CHAR ++# define CHAR char ++# define L(str) str ++# define SSCANF sscanf ++#endif ++ ++ ++static int ++do_test (void) ++{ ++ printf("setting errno to EINTR\n"); ++ errno = EINTR; ++ ++ printf("checking sscanf\n"); ++ ++ CHAR str[] = L("7-11"); ++ int i, j, n; ++ ++ i = j = n = 0; ++ SSCANF (str, L(" %i - %i %n"), &i, &j, &n); ++ printf ("found %i-%i (length=%i)\n", i, j, n); ++ ++ int result = 0; ++ if (i != 7) ++ { ++ printf ("i is %d, expected 7\n", i); ++ result = 1; ++ } ++ if (j != 11) ++ { ++ printf ("j is %d, expected 11\n", j); ++ result = 1; ++ } ++ if (n != 4) ++ { ++ printf ("n is %d, expected 4\n", j); ++ result = 1; ++ } ++ ++ return result; ++} ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +--- glibc-20070515T2025/stdio-common/bug18a.c 1 Jan 1970 00:00:00 -0000 ++++ glibc-20070515T2025-fedora/stdio-common/bug18a.c 8 Jul 2007 10:08:25 -0000 1.1.2.1 +@@ -0,0 +1,6 @@ ++#include ++#define CHAR wchar_t ++#define L(str) L##str ++#define SSCANF swscanf ++ ++#include "bug18.c" +--- glibc-20070515T2025/stdio-common/bug19.c 1 Jan 1970 00:00:00 -0000 ++++ glibc-20070515T2025-fedora/stdio-common/bug19.c 8 Jul 2007 10:08:25 -0000 1.1.2.1 +@@ -0,0 +1,58 @@ ++#include ++#include ++#include ++ ++#ifndef CHAR ++# define CHAR char ++# define L(str) str ++# define FPUTS fputs ++# define FSCANF fscanf ++#endif ++ ++ ++static int ++do_test (void) ++{ ++ FILE *fp = tmpfile (); ++ if (fp == NULL) ++ { ++ puts ("cannot open file"); ++ return 1; ++ } ++ ++ FPUTS (L("7-11"), fp); ++ rewind (fp); ++ ++ printf("setting errno to EINTR\n"); ++ errno = EINTR; ++ ++ printf("checking sscanf\n"); ++ ++ int i, j, n; ++ ++ i = j = n = 0; ++ FSCANF (fp, L(" %i - %i %n"), &i, &j, &n); ++ printf ("found %i-%i (length=%i)\n", i, j, n); ++ ++ int result = 0; ++ if (i != 7) ++ { ++ printf ("i is %d, expected 7\n", i); ++ result = 1; ++ } ++ if (j != 11) ++ { ++ printf ("j is %d, expected 11\n", j); ++ result = 1; ++ } ++ if (n != 4) ++ { ++ printf ("n is %d, expected 4\n", j); ++ result = 1; ++ } ++ ++ return result; ++} ++ ++#define TEST_FUNCTION do_test () ++#include "../test-skeleton.c" +--- glibc-20070515T2025/stdio-common/bug19a.c 1 Jan 1970 00:00:00 -0000 ++++ glibc-20070515T2025-fedora/stdio-common/bug19a.c 8 Jul 2007 10:08:25 -0000 1.1.2.1 +@@ -0,0 +1,7 @@ ++#include ++#define CHAR wchar_t ++#define L(str) L##str ++#define FPUTS fputws ++#define FSCANF fwscanf ++ ++#include "bug19.c" --- glibc-20070515T2025/stdio-common/tst-sprintf.c 25 Jun 2003 11:04:49 -0000 1.3 +++ glibc-20070515T2025-fedora/stdio-common/tst-sprintf.c 21 May 2007 20:01:11 -0000 1.3.2.1 @@ -37,5 +37,26 @@ main (void) @@ -2009,6 +3817,91 @@ + return result; } +--- glibc-20070515T2025/stdio-common/tst-sprintf2.c 1 Jan 1970 00:00:00 -0000 ++++ glibc-20070515T2025-fedora/stdio-common/tst-sprintf2.c 7 Jul 2007 16:19:21 -0000 1.2.2.1 +@@ -0,0 +1,82 @@ ++#include ++#include ++#include ++#include ++ ++int ++main (void) ++{ ++ volatile union { long double l; long long x[2]; } u, v; ++ char buf[64]; ++ int result = 0; ++ ++#if LDBL_MANT_DIG == 106 || LDBL_MANT_DIG == 113 ++# define COMPARE_LDBL(u, v) \ ++ ((u).l == (v).l && (u).x[0] == (v).x[0] && (u).x[1] == (v).x[1]) ++#else ++# define COMPARE_LDBL(u, v) ((u).l == (v).l) ++#endif ++ ++#define TEST(val) \ ++ do \ ++ { \ ++ u.l = (val); \ ++ snprintf (buf, sizeof buf, "%LaL", u.l); \ ++ if (strcmp (buf, #val) != 0) \ ++ { \ ++ printf ("Error on line %d: %s != %s\n", __LINE__, buf, #val); \ ++ result = 1; \ ++ } \ ++ if (sscanf (#val, "%La", &v.l) != 1 || !COMPARE_LDBL (u, v)) \ ++ { \ ++ printf ("Error sscanf on line %d: %La != %La\n", __LINE__, \ ++ u.l, v.l); \ ++ result = 1; \ ++ } \ ++ /* printf ("%s %La %016Lx %016Lx\n", #val, u.l, u.x[0], u.x[1]); */ \ ++ } \ ++ while (0) ++ ++#if LDBL_MANT_DIG >= 106 ++# if LDBL_MANT_DIG == 106 ++ TEST (0x0.ffffffffffffp-1022L); ++ TEST (0x0.ffffffffffff1p-1022L); ++ TEST (0x0.fffffffffffffp-1022L); ++# endif ++ TEST (0x1p-1022L); ++ TEST (0x1.0000000000001p-1022L); ++ TEST (0x1.00000000001e7p-1022L); ++ TEST (0x1.fffffffffffffp-1022L); ++ TEST (0x1p-1021L); ++ TEST (0x1.00000000000008p-1021L); ++ TEST (0x1.0000000000001p-1021L); ++ TEST (0x1.00000000000018p-1021L); ++ TEST (0x1.0000000000000f8p-1017L); ++ TEST (0x1.0000000000001p-1017L); ++ TEST (0x1.000000000000108p-1017L); ++ TEST (0x1.000000000000dcf8p-1013L); ++ TEST (0x1.000000000000ddp-1013L); ++ TEST (0x1.000000000000dd08p-1013L); ++ TEST (0x1.ffffffffffffffffffffffffffp-1L); ++ TEST (0x1.ffffffffffffffffffffffffff8p-1L); ++ TEST (0x1p+0L); ++ TEST (0x1.000000000000000000000000008p+0L); ++ TEST (0x1.00000000000000000000000001p+0L); ++ TEST (0x1.000000000000000000000000018p+0L); ++ TEST (0x1.23456789abcdef123456789abc8p+0L); ++ TEST (0x1.23456789abcde7123456789abc8p+0L); ++ TEST (0x1.23456789abcdef123456789abc8p+64L); ++ TEST (0x1.23456789abcde7123456789abc8p+64L); ++ TEST (0x1.123456789abcdef123456789p-969L); ++# if LDBL_MANT_DIG == 106 ++ TEST (-0x1.2d71957cc1263bbbeb1d365f1e8p-969L); ++ TEST (0x1.23456789abcdef0123456789abp-970L); ++ TEST (0x1.579bde02468acp-1001L); ++ TEST (0x0.abcdef0123456p-1022L); ++ TEST (0x1.abcdef0123456p-1022L); ++ TEST (0x1.abcdef012345678p-1014L); ++ TEST (0x1.abcdef0123456f8p-1014L); ++# endif ++#endif ++ return result; ++} --- glibc-20070515T2025/stdio-common/vfprintf.c 7 May 2007 03:43:55 -0000 1.139 +++ glibc-20070515T2025-fedora/stdio-common/vfprintf.c 21 May 2007 20:01:11 -0000 1.128.2.9 @@ -1627,6 +1627,8 @@ do_positional: @@ -2050,6 +3943,29 @@ CHAR_T *const workend = &work_buffer[sizeof (work_buffer) / sizeof (CHAR_T)]; register CHAR_T *w; +--- glibc-20070515T2025/stdio-common/vfscanf.c 27 Apr 2007 19:28:32 -0000 1.123 ++++ glibc-20070515T2025-fedora/stdio-common/vfscanf.c 8 Jul 2007 10:08:25 -0000 1.110.2.7 +@@ -530,12 +530,17 @@ _IO_vfscanf_internal (_IO_FILE *s, const + { + /* Eat whitespace. */ + int save_errno = errno; +- errno = 0; ++ __set_errno (0); + do +- if (__builtin_expect (inchar () == EOF && errno == EINTR, 0)) ++ /* We add the additional test for EOF here since otherwise ++ inchar will restore the old errno value which might be ++ EINTR but does not indicate an interrupt since nothing ++ was read at this time. */ ++ if (__builtin_expect ((c == EOF || inchar () == EOF) ++ && errno == EINTR, 0)) + input_error (); + while (ISSPACE (c)); +- errno = save_errno; ++ __set_errno (save_errno); + ungetc (c, s); + skip_space = 0; + } --- glibc-20070515T2025/sysdeps/generic/dl-cache.h 25 Jun 2003 08:01:22 -0000 1.13 +++ glibc-20070515T2025-fedora/sysdeps/generic/dl-cache.h 22 Sep 2004 21:21:07 -0000 1.13.2.1 @@ -36,6 +36,14 @@ @@ -2067,6 +3983,126 @@ #define CACHEMAGIC "ld.so-1.7.0" /* libc5 and glibc 2.0/2.1 use the same format. For glibc 2.2 another +--- glibc-20070515T2025/sysdeps/generic/ldsodefs.h 15 Jan 2007 20:48:43 -0000 1.134 ++++ glibc-20070515T2025-fedora/sysdeps/generic/ldsodefs.h 7 Jul 2007 17:31:45 -0000 1.102.2.23 +@@ -38,7 +38,6 @@ + #include + #include + #include +-#include + + __BEGIN_DECLS + +@@ -439,18 +438,18 @@ struct rtld_global + EXTERN void (*_dl_rtld_unlock_recursive) (void *); + #endif + +- /* Prevailing state of the stack, PF_X indicating it's executable. */ +- EXTERN ElfW(Word) _dl_stack_flags; +- + /* If loading a shared object requires that we make the stack executable + when it was not, we do it by calling this function. + It returns an errno code or zero on success. */ + EXTERN int (*_dl_make_stack_executable_hook) (void **) internal_function; + +- /* Highest dtv index currently needed. */ +- EXTERN size_t _dl_tls_max_dtv_idx; ++ /* Prevailing state of the stack, PF_X indicating it's executable. */ ++ EXTERN ElfW(Word) _dl_stack_flags; ++ + /* Flag signalling whether there are gaps in the module ID allocation. */ + EXTERN bool _dl_tls_dtv_gaps; ++ /* Highest dtv index currently needed. */ ++ EXTERN size_t _dl_tls_max_dtv_idx; + /* Information about the dtv slots. */ + EXTERN struct dtv_slotinfo_list + { +@@ -486,6 +485,14 @@ struct rtld_global + + EXTERN void (*_dl_init_static_tls) (struct link_map *); + ++ EXTERN void (*_dl_wait_lookup_done) (void); ++ ++ /* Scopes to free after next THREAD_GSCOPE_WAIT (). */ ++ EXTERN struct dl_scope_free_list ++ { ++ size_t count; ++ struct r_scope_elem **list[50]; ++ } *_dl_scope_free_list; + #ifdef SHARED + }; + # define __rtld_global_attribute__ +@@ -532,15 +539,15 @@ struct rtld_global_ro + #define DL_DEBUG_HELP (1 << 9) + #define DL_DEBUG_PRELINK (1 << 10) + +- /* Cached value of `getpagesize ()'. */ +- EXTERN size_t _dl_pagesize; +- + /* OS version. */ + EXTERN unsigned int _dl_osversion; + /* Platform name. */ + EXTERN const char *_dl_platform; + EXTERN size_t _dl_platformlen; + ++ /* Cached value of `getpagesize ()'. */ ++ EXTERN size_t _dl_pagesize; ++ + /* Copy of the content of `_dl_main_searchlist' at startup time. */ + EXTERN struct r_scope_elem _dl_initial_searchlist; + +@@ -569,9 +576,6 @@ struct rtld_global_ro + /* Expected cache ID. */ + EXTERN int _dl_correct_cache_id; + +- /* 0 if internal pointer values should not be guarded, 1 if they should. */ +- EXTERN int _dl_pointer_guard; +- + /* Mask for hardware capabilities that are available. */ + EXTERN uint64_t _dl_hwcap; + +@@ -655,6 +659,9 @@ struct rtld_global_ro + /* List of auditing interfaces. */ + struct audit_ifaces *_dl_audit; + unsigned int _dl_naudit; ++ ++ /* 0 if internal pointer values should not be guarded, 1 if they should. */ ++ EXTERN int _dl_pointer_guard; + }; + # define __rtld_global_attribute__ + # ifdef IS_IN_rtld +@@ -838,9 +845,7 @@ enum + DL_LOOKUP_ADD_DEPENDENCY = 1, + /* Return most recent version instead of default version for + unversioned lookup. */ +- DL_LOOKUP_RETURN_NEWEST = 2, +- /* Set if the scopr lock in the UNDEF_MAP is taken. */ +- DL_LOOKUP_SCOPE_LOCK = 4 ++ DL_LOOKUP_RETURN_NEWEST = 2 + }; + + /* Lookup versioned symbol. */ +@@ -1048,6 +1053,11 @@ extern void *_dl_open (const char *name, + Lmid_t nsid, int argc, char *argv[], char *env[]) + attribute_hidden; + ++/* Free or queue for freeing scope OLD. If other threads might be ++ in the middle of _dl_fixup, _dl_profile_fixup or dl*sym using the ++ old scope, OLD can't be freed until no thread is using it. */ ++extern int _dl_scope_free (struct r_scope_elem **old) attribute_hidden; ++ + /* Add module to slot information data. */ + extern void _dl_add_to_slotinfo (struct link_map *l) attribute_hidden; + +@@ -1059,6 +1069,8 @@ extern struct link_map *_dl_update_sloti + but never touch anything. Return null if it's not allocated yet. */ + extern void *_dl_tls_get_addr_soft (struct link_map *l) internal_function; + ++extern int _dl_addr_inside_object (struct link_map *l, const ElfW(Addr) addr) ++ internal_function attribute_hidden; + + __END_DECLS + --- glibc-20070515T2025/sysdeps/i386/Makefile 6 Mar 2005 00:18:16 -0000 1.20 +++ glibc-20070515T2025-fedora/sysdeps/i386/Makefile 30 Jun 2006 09:16:34 -0000 1.16.2.4 @@ -64,4 +64,12 @@ endif @@ -2082,6 +4118,46 @@ +CPPFLAGS-.oS += -DNO_TLS_DIRECT_SEG_REFS +CFLAGS-.oS += -mno-tls-direct-seg-refs endif +--- glibc-20070515T2025/sysdeps/i386/ldbl2mpn.c 6 Jul 2001 04:55:52 -0000 1.4 ++++ glibc-20070515T2025-fedora/sysdeps/i386/ldbl2mpn.c 7 Jul 2007 21:28:56 -0000 1.4.4.2 +@@ -1,4 +1,4 @@ +-/* Copyright (C) 1995, 1996, 1997, 2000 Free Software Foundation, Inc. ++/* Copyright (C) 1995, 1996, 1997, 2000, 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 +@@ -19,7 +19,7 @@ + #include "gmp.h" + #include "gmp-impl.h" + #include "longlong.h" +-#include "ieee754.h" ++#include + #include + #include + +@@ -46,7 +46,7 @@ __mpn_extract_long_double (mp_ptr res_pt + #elif BITS_PER_MP_LIMB == 64 + /* Hopefully the compiler will combine the two bitfield extracts + and this composition into just the original quadword extract. */ +- res_ptr[0] = ((unsigned long int) u.ieee.mantissa0 << 32) | u.ieee.mantissa1; ++ res_ptr[0] = ((mp_limb_t) u.ieee.mantissa0 << 32) | u.ieee.mantissa1; + #define N 1 + #else + #error "mp_limb size " BITS_PER_MP_LIMB "not accounted for" +@@ -109,6 +109,13 @@ __mpn_extract_long_double (mp_ptr res_pt + } + } + } ++ else if (u.ieee.exponent < 0x7fff ++#if N == 2 ++ && res_ptr[0] == 0 ++#endif ++ && res_ptr[N - 1] == 0) ++ /* Pseudo zero. */ ++ *expt = 0; + + return N; + } --- glibc-20070515T2025/sysdeps/ia64/Makefile 16 Aug 2004 06:46:14 -0000 1.10 +++ glibc-20070515T2025-fedora/sysdeps/ia64/Makefile 22 Sep 2004 21:21:07 -0000 1.10.2.1 @@ -12,8 +12,8 @@ elide-routines.os += hp-timing @@ -2448,6 +4524,10 @@ - .symver ___multi3, __multi3@GLIBC_2.2 - -#endif +--- glibc-20070515T2025/sysdeps/ia64/ldbl2mpn.c 1 Jan 1970 00:00:00 -0000 ++++ glibc-20070515T2025-fedora/sysdeps/ia64/ldbl2mpn.c 7 Jul 2007 19:59:56 -0000 1.1.2.1 +@@ -0,0 +1 @@ ++#include "../i386/ldbl2mpn.c" --- glibc-20070515T2025/sysdeps/ia64/libgcc-compat.c 1 Jan 1970 00:00:00 -0000 +++ glibc-20070515T2025-fedora/sysdeps/ia64/libgcc-compat.c 22 Sep 2004 21:21:08 -0000 1.1.2.1 @@ -0,0 +1,84 @@ @@ -2535,20 +4615,387 @@ +symbol_version (INTUSE (__multi3), __multi3, GLIBC_2.2); + +#endif ---- glibc-20070515T2025/sysdeps/powerpc/powerpc64/Makefile 2 Feb 2006 08:23:44 -0000 1.8 -+++ glibc-20070515T2025-fedora/sysdeps/powerpc/powerpc64/Makefile 30 Nov 2006 17:07:38 -0000 1.4.2.5 -@@ -30,6 +30,7 @@ ifneq ($(elf),no) - # we use -fpic instead which is much better. - CFLAGS-initfini.s += -fpic -O1 - endif -+CFLAGS-libc-start.c += -fno-asynchronous-unwind-tables - endif +--- glibc-20070515T2025/sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c 28 Jan 2006 00:07:25 -0000 1.1 ++++ glibc-20070515T2025-fedora/sysdeps/ieee754/ldbl-128ibm/mpn2ldbl.c 7 Jul 2007 21:28:56 -0000 1.1.2.3 +@@ -1,4 +1,4 @@ +-/* Copyright (C) 1995, 1996, 1997, 1998, 1999, 2002, 2003, 2004, 2006 ++/* Copyright (C) 1995, 1996, 1997, 1998, 1999, 2002, 2003, 2004, 2006, 2007 + Free Software Foundation, Inc. + This file is part of the GNU C Library. - ifeq ($(subdir),elf) ---- glibc-20070515T2025/sysdeps/unix/nice.c 15 Aug 2006 05:24:45 -0000 1.7 -+++ glibc-20070515T2025-fedora/sysdeps/unix/nice.c 15 Aug 2006 05:53:50 -0000 1.6.2.2 -@@ -42,7 +42,12 @@ nice (int incr) - __set_errno (save); +@@ -31,19 +31,20 @@ long double + __mpn_construct_long_double (mp_srcptr frac_ptr, int expt, int sign) + { + union ibm_extended_long_double u; +- unsigned long hidden2, lzcount; ++ unsigned long lzcount; + unsigned long long hi, lo; ++ int exponent2; + + u.ieee.negative = sign; + u.ieee.negative2 = sign; + u.ieee.exponent = expt + IBM_EXTENDED_LONG_DOUBLE_BIAS; +- u.ieee.exponent2 = expt - 53 + IBM_EXTENDED_LONG_DOUBLE_BIAS; ++ u.ieee.exponent2 = 0; ++ exponent2 = expt - 53 + IBM_EXTENDED_LONG_DOUBLE_BIAS; + + #if BITS_PER_MP_LIMB == 32 + /* The low order 53 bits (52 + hidden) go into the lower double */ + lo = frac_ptr[0]; + lo |= (frac_ptr[1] & ((1LL << (53 - 32)) - 1)) << 32; +- hidden2 = (frac_ptr[1] >> (52 - 32)) & ((mp_limb_t) 1); + /* The high order 53 bits (52 + hidden) go into the upper double */ + hi = (frac_ptr[1] >> (53 - 32)) & ((1 << 11) - 1); + hi |= ((unsigned long long) frac_ptr[2]) << 11; +@@ -51,7 +52,6 @@ __mpn_construct_long_double (mp_srcptr f + #elif BITS_PER_MP_LIMB == 64 + /* The low order 53 bits (52 + hidden) go into the lower double */ + lo = frac_ptr[0] & (((mp_limb_t) 1 << 53) - 1); +- hidden2 = (frac_ptr[0] >> 52) & ((mp_limb_t) 1); + /* The high order 53 bits (52 + hidden) go into the upper double */ + hi = (frac_ptr[0] >> 53) & (((mp_limb_t) 1 << 11) - 1); + hi |= (frac_ptr[1] << 11); +@@ -59,14 +59,62 @@ __mpn_construct_long_double (mp_srcptr f + #error "mp_limb size " BITS_PER_MP_LIMB "not accounted for" + #endif + ++ if ((hi & (1LL << 52)) == 0 && (hi | lo) != 0) ++ { ++ /* denormal number */ ++ unsigned long long val = hi ? hi : lo; ++ ++ if (sizeof (val) == sizeof (long)) ++ lzcount = __builtin_clzl (val); ++ else if ((val >> 32) != 0) ++ lzcount = __builtin_clzl ((long) (val >> 32)); ++ else ++ lzcount = __builtin_clzl ((long) val) + 32; ++ if (hi) ++ lzcount = lzcount - 11; ++ else ++ lzcount = lzcount + 42; ++ ++ if (lzcount > u.ieee.exponent) ++ { ++ lzcount = u.ieee.exponent; ++ u.ieee.exponent = 0; ++ exponent2 -= lzcount; ++ } ++ else ++ { ++ u.ieee.exponent -= (lzcount - 1); ++ exponent2 -= (lzcount - 1); ++ } ++ ++ if (lzcount <= 53) ++ { ++ hi = (hi << lzcount) | (lo >> (53 - lzcount)); ++ lo = (lo << lzcount) & ((1LL << 53) - 1); ++ } ++ else ++ { ++ hi = lo << (lzcount - 53); ++ lo = 0; ++ } ++ } ++ + if (lo != 0L) + { + /* hidden2 bit of low double controls rounding of the high double. +- If hidden2 is '1' then round up hi and adjust lo (2nd mantissa) ++ If hidden2 is '1' and either the explicit mantissa is non-zero ++ or hi is odd, then round up hi and adjust lo (2nd mantissa) + plus change the sign of the low double to compensate. */ +- if (hidden2) ++ if ((lo & (1LL << 52)) != 0 ++ && ((hi & 1) != 0 || (lo & ((1LL << 52) - 1)))) + { + hi++; ++ if ((hi & ((1LL << 52) - 1)) == 0) ++ { ++ if ((hi & (1LL << 53)) != 0) ++ hi -= 1LL << 52; ++ u.ieee.exponent++; ++ } + u.ieee.negative2 = !sign; + lo = (1LL << 53) - lo; + } +@@ -85,17 +133,18 @@ __mpn_construct_long_double (mp_srcptr f + if (lzcount > 0) + { + lo = lo << lzcount; +- u.ieee.exponent2 = u.ieee.exponent2 - lzcount; ++ exponent2 = exponent2 - lzcount; + } ++ if (exponent2 > 0) ++ u.ieee.exponent2 = exponent2; ++ else ++ lo >>= 1 - exponent2; + } + else +- { +- u.ieee.negative2 = 0; +- u.ieee.exponent2 = 0; +- } ++ u.ieee.negative2 = 0; + + u.ieee.mantissa3 = lo & 0xffffffffLL; +- u.ieee.mantissa2 = (lo >> 32) & 0xffffff; ++ u.ieee.mantissa2 = (lo >> 32) & 0xfffff; + u.ieee.mantissa1 = hi & 0xffffffffLL; + u.ieee.mantissa0 = (hi >> 32) & ((1LL << (LDBL_MANT_DIG - 86)) - 1); + +--- glibc-20070515T2025/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c 28 Jan 2006 00:07:25 -0000 1.1 ++++ glibc-20070515T2025-fedora/sysdeps/ieee754/ldbl-128ibm/printf_fphex.c 7 Jul 2007 21:28:56 -0000 1.1.2.3 +@@ -1,5 +1,5 @@ + /* Print floating point number in hexadecimal notation according to ISO C99. +- Copyright (C) 1997,1998,1999,2000,2001,2002,2004,2006 ++ Copyright (C) 1997,1998,1999,2000,2001,2002,2004,2006,2007 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1997. +@@ -35,21 +35,24 @@ do { \ + \ + lo = ((long long)eldbl.ieee.mantissa2 << 32) | eldbl.ieee.mantissa3; \ + hi = ((long long)eldbl.ieee.mantissa0 << 32) | eldbl.ieee.mantissa1; \ +- /* If the lower double is not a denomal or zero then set the hidden \ +- 53rd bit. */ \ +- if (eldbl.ieee.exponent2 > 0x001) \ +- { \ +- lo |= (1ULL << 52); \ +- lo = lo << 7; /* pre-shift lo to match ieee854. */ \ +- /* The lower double is normalized separately from the upper. We \ +- may need to adjust the lower manitissa to reflect this. */ \ +- ediff = eldbl.ieee.exponent - eldbl.ieee.exponent2; \ +- if (ediff > 53) \ +- lo = lo >> (ediff-53); \ +- } \ +- \ +- if ((eldbl.ieee.negative != eldbl.ieee.negative2) \ +- && ((eldbl.ieee.exponent2 != 0) && (lo != 0L))) \ ++ lo <<= 7; /* pre-shift lo to match ieee854. */ \ ++ /* If the lower double is not a denomal or zero then set the hidden \ ++ 53rd bit. */ \ ++ if (eldbl.ieee.exponent2 != 0) \ ++ lo |= (1ULL << (52 + 7)); \ ++ else \ ++ lo <<= 1; \ ++ /* The lower double is normalized separately from the upper. We \ ++ may need to adjust the lower manitissa to reflect this. */ \ ++ ediff = eldbl.ieee.exponent - eldbl.ieee.exponent2; \ ++ if (ediff > 53 + 63) \ ++ lo = 0; \ ++ else if (ediff > 53) \ ++ lo = lo >> (ediff - 53); \ ++ else if (eldbl.ieee.exponent2 == 0 && ediff < 53) \ ++ lo = lo << (53 - ediff); \ ++ if (eldbl.ieee.negative != eldbl.ieee.negative2 \ ++ && (eldbl.ieee.exponent2 != 0 || lo != 0L)) \ + { \ + lo = (1ULL << 60) - lo; \ + if (hi == 0L) \ +--- glibc-20070515T2025/sysdeps/ieee754/ldbl-128ibm/s_fpclassifyl.c 28 Jan 2006 00:07:25 -0000 1.1 ++++ glibc-20070515T2025-fedora/sysdeps/ieee754/ldbl-128ibm/s_fpclassifyl.c 7 Jul 2007 21:28:56 -0000 1.1.2.3 +@@ -1,5 +1,5 @@ + /* Return classification value corresponding to argument. +- Copyright (C) 1997,1999,2002,2004,2006 Free Software Foundation, Inc. ++ Copyright (C) 1997,1999,2002,2004,2006,2007 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1997 and + Jakub Jelinek , 1999. +@@ -30,14 +30,16 @@ + * -NaN fffn nnnn nnnn nnnn xxxx xxxx xxxx xxxx + * +Inf 7ff0 0000 0000 0000 xxxx xxxx xxxx xxxx + * -Inf fff0 0000 0000 0000 xxxx xxxx xxxx xxxx +- * +0 0000 0000 0000 0000 +- * -0 8000 0000 0000 0000 +- * +normal 001n nnnn nnnn nnnn (smallest) +- * -normal 801n nnnn nnnn nnnn (smallest) +- * +normal 7fen nnnn nnnn nnnn (largest) +- * -normal ffen nnnn nnnn nnnn (largest) +- * +denorm 000n nnnn nnnn nnnn +- * -denorm 800n nnnn nnnn nnnn ++ * +0 0000 0000 0000 0000 xxxx xxxx xxxx xxxx ++ * -0 8000 0000 0000 0000 xxxx xxxx xxxx xxxx ++ * +normal 0360 0000 0000 0000 0000 0000 0000 0000 (smallest) ++ * -normal 8360 0000 0000 0000 0000 0000 0000 0000 (smallest) ++ * +normal 7fef ffff ffff ffff 7c8f ffff ffff fffe (largest) ++ * +normal ffef ffff ffff ffff fc8f ffff ffff fffe (largest) ++ * +denorm 0360 0000 0000 0000 8000 0000 0000 0001 (largest) ++ * -denorm 8360 0000 0000 0000 0000 0000 0000 0001 (largest) ++ * +denorm 000n nnnn nnnn nnnn xxxx xxxx xxxx xxxx ++ * -denorm 800n nnnn nnnn nnnn xxxx xxxx xxxx xxxx + */ + + int +@@ -59,12 +61,23 @@ ___fpclassifyl (long double x) + /* +/-zero or +/- normal or +/- denormal */ + if (hx & 0x7fffffffffffffffULL) { + /* +/- normal or +/- denormal */ +- if ((hx & 0x7ff0000000000000ULL) >= 0x0360000000000000ULL) { ++ if ((hx & 0x7ff0000000000000ULL) > 0x0360000000000000ULL) { + /* +/- normal */ + retval = FP_NORMAL; + } else { +- /* +/- denormal */ +- retval = FP_SUBNORMAL; ++ if ((hx & 0x7ff0000000000000ULL) == 0x0360000000000000ULL) { ++ if ((lx & 0x7fffffffffffffff) /* lower is non-zero */ ++ && ((lx^hx) & 0x8000000000000000ULL)) { /* and sign differs */ ++ /* +/- denormal */ ++ retval = FP_SUBNORMAL; ++ } else { ++ /* +/- normal */ ++ retval = FP_NORMAL; ++ } ++ } else { ++ /* +/- denormal */ ++ retval = FP_SUBNORMAL; ++ } + } + } else { + /* +/- zero */ +--- glibc-20070515T2025/sysdeps/ieee754/ldbl-128ibm/s_nextafterl.c 16 Apr 2007 20:42:16 -0000 1.2 ++++ glibc-20070515T2025-fedora/sysdeps/ieee754/ldbl-128ibm/s_nextafterl.c 7 Jul 2007 16:16:55 -0000 1.1.2.3 +@@ -35,7 +35,7 @@ static char rcsid[] = "$NetBSD: $"; + long double x,y; + #endif + { +- int64_t hx,hy,ihx,ihy,ilx,ily; ++ int64_t hx,hy,ihx,ihy,ilx; + u_int64_t lx,ly; + + GET_LDOUBLE_WORDS64(hx,lx,x); +@@ -43,7 +43,6 @@ static char rcsid[] = "$NetBSD: $"; + ihx = hx&0x7fffffffffffffffLL; /* |hx| */ + ilx = lx&0x7fffffffffffffffLL; /* |lx| */ + ihy = hy&0x7fffffffffffffffLL; /* |hy| */ +- ily = ly&0x7fffffffffffffffLL; /* |ly| */ + + if((((ihx&0x7ff0000000000000LL)==0x7ff0000000000000LL)&& + ((ihx&0x000fffffffffffffLL)!=0)) || /* x is nan */ +@@ -54,54 +53,66 @@ static char rcsid[] = "$NetBSD: $"; + return y; /* x=y, return y */ + if(ihx == 0 && ilx == 0) { /* x == 0 */ + long double u; +- SET_LDOUBLE_WORDS64(x,hy&0x8000000000000000ULL,1);/* return +-minsubnormal */ +- u = math_opt_barrier (u); ++ hy = (hy & 0x8000000000000000ULL) | 1; ++ SET_LDOUBLE_WORDS64(x,hy,0ULL);/* return +-minsubnormal */ ++ u = math_opt_barrier (x); + u = u * u; + math_force_eval (u); /* raise underflow flag */ + return x; + } +- if(ihx>=0) { /* x > 0 */ +- if(ihx>ihy||((ihx==ihy)&&(ilx>ily))) { /* x > y, x -= ulp */ +- +- if(ilx==0) +- hx--; +- else +- lx--; +- } else { /* x < y, x += ulp */ +- if((hx==0x7fefffffffffffffLL)&&(lx==0x7c8ffffffffffffeLL)) +- { +- SET_LDOUBLE_WORDS64(x,0x7ff0000000000000,0x8000000000000000); +- return x; +- } +- else if((hx==0xffefffffffffffffLL)&&(lx==0xfc8ffffffffffffeLL)) +- { +- SET_LDOUBLE_WORDS64(x,0xfff0000000000000,0x8000000000000000); +- return x; +- } +- else if((lx&0x7fffffffffffffff)==0) hx++; +- else +- lx++; ++ ++ long double u; ++ if(x > y) { /* x > y, x -= ulp */ ++ if((hx==0xffefffffffffffffLL)&&(lx==0xfc8ffffffffffffeLL)) ++ return x+x; /* overflow, return -inf */ ++ if (hx >= 0x7ff0000000000000LL) { ++ SET_LDOUBLE_WORDS64(u,0x7fefffffffffffffLL,0x7c8ffffffffffffeLL); ++ return u; + } +- } else { /* x < 0 */ +- if(ihy>=0||ihx>ihy||((ihx==ihy)&&(ilx>ily))){/* x < y, x -= ulp */ +- if((lx&0x7fffffffffffffff)==0) +- hx--; +- else +- lx--; +- } else { /* x > y, x += ulp */ +- if((lx&0x7fffffffffffffff)==0) hx++; +- else +- lx++; ++ if(ihx <= 0x0360000000000000LL) { /* x <= LDBL_MIN */ ++ u = math_opt_barrier (x); ++ x -= __LDBL_DENORM_MIN__; ++ if (ihx < 0x0360000000000000LL ++ || (hx > 0 && (int64_t) lx <= 0) ++ || (hx < 0 && (int64_t) lx > 1)) { ++ u = u * u; ++ math_force_eval (u); /* raise underflow flag */ ++ } ++ return x; + } ++ if (ihx < 0x06a0000000000000LL) { /* ulp will denormal */ ++ SET_LDOUBLE_WORDS64(u,(hx&0x7ff0000000000000LL),0ULL); ++ u *= 0x1.0000000000000p-105L; ++ } else ++ SET_LDOUBLE_WORDS64(u,(hx&0x7ff0000000000000LL)-0x0690000000000000LL,0ULL); ++ return x - u; ++ } else { /* x < y, x += ulp */ ++ if((hx==0x7fefffffffffffffLL)&&(lx==0x7c8ffffffffffffeLL)) ++ return x+x; /* overflow, return +inf */ ++ if ((u_int64_t) hx >= 0xfff0000000000000ULL) { ++ SET_LDOUBLE_WORDS64(u,0xffefffffffffffffLL,0xfc8ffffffffffffeLL); ++ return u; ++ } ++ if(ihx <= 0x0360000000000000LL) { /* x <= LDBL_MIN */ ++ u = math_opt_barrier (x); ++ x += __LDBL_DENORM_MIN__; ++ if (ihx < 0x0360000000000000LL ++ || (hx > 0 && (int64_t) lx < 0 && lx != 0x8000000000000001LL) ++ || (hx < 0 && (int64_t) lx >= 0)) { ++ u = u * u; ++ math_force_eval (u); /* raise underflow flag */ ++ } ++ if (x == 0.0L) /* handle negative __LDBL_DENORM_MIN__ case */ ++ x = -0.0L; ++ return x; ++ } ++ if (ihx < 0x06a0000000000000LL) { /* ulp will denormal */ ++ SET_LDOUBLE_WORDS64(u,(hx&0x7ff0000000000000LL),0ULL); ++ u *= 0x1.0000000000000p-105L; ++ } else ++ SET_LDOUBLE_WORDS64(u,(hx&0x7ff0000000000000LL)-0x0690000000000000LL,0ULL); ++ return x + u; + } +- hy = hx&0x7ff0000000000000LL; +- if(hy==0x7ff0000000000000LL) return x+x;/* overflow */ +- if(hy==0) { +- long double u = x * x; /* underflow */ +- math_force_eval (u); /* raise underflow flag */ +- } +- SET_LDOUBLE_WORDS64(x,hx,lx); +- return x; + } + strong_alias (__nextafterl, __nexttowardl) + long_double_symbol (libm, __nextafterl, nextafterl); +--- glibc-20070515T2025/sysdeps/powerpc/powerpc64/Makefile 2 Feb 2006 08:23:44 -0000 1.8 ++++ glibc-20070515T2025-fedora/sysdeps/powerpc/powerpc64/Makefile 30 Nov 2006 17:07:38 -0000 1.4.2.5 +@@ -30,6 +30,7 @@ ifneq ($(elf),no) + # we use -fpic instead which is much better. + CFLAGS-initfini.s += -fpic -O1 + endif ++CFLAGS-libc-start.c += -fno-asynchronous-unwind-tables + endif + + ifeq ($(subdir),elf) +--- glibc-20070515T2025/sysdeps/unix/nice.c 15 Aug 2006 05:24:45 -0000 1.7 ++++ glibc-20070515T2025-fedora/sysdeps/unix/nice.c 15 Aug 2006 05:53:50 -0000 1.6.2.2 +@@ -42,7 +42,12 @@ nice (int incr) + __set_errno (save); } - result = setpriority (PRIO_PROCESS, 0, prio + incr); @@ -3111,6 +5558,348 @@ cfi_startproc; PSEUDO_END (BP_SYM (__clone)) +--- glibc-20070515T2025/sysdeps/unix/sysv/linux/x86_64/sysconf.c 10 Nov 2006 07:31:55 -0000 1.7 ++++ glibc-20070515T2025-fedora/sysdeps/unix/sysv/linux/x86_64/sysconf.c 7 Jul 2007 21:28:56 -0000 1.2.2.7 +@@ -1,5 +1,5 @@ + /* Get file-specific information about a file. Linux version. +- 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. + + The GNU C Library is free software; you can redistribute it and/or +@@ -24,328 +24,17 @@ + + + static long int linux_sysconf (int name); +- +- +-static const struct intel_02_cache_info +-{ +- unsigned int idx; +- int name; +- long int size; +- long int assoc; +- long int linesize; +-} intel_02_known[] = +- { +- { 0x06, _SC_LEVEL1_ICACHE_SIZE, 8192, 4, 32 }, +- { 0x08, _SC_LEVEL1_ICACHE_SIZE, 16384, 4, 32 }, +- { 0x0a, _SC_LEVEL1_DCACHE_SIZE, 8192, 2, 32 }, +- { 0x0c, _SC_LEVEL1_DCACHE_SIZE, 16384, 4, 32 }, +- { 0x22, _SC_LEVEL3_CACHE_SIZE, 524288, 4, 64 }, +- { 0x23, _SC_LEVEL3_CACHE_SIZE, 1048576, 8, 64 }, +- { 0x25, _SC_LEVEL3_CACHE_SIZE, 2097152, 8, 64 }, +- { 0x29, _SC_LEVEL3_CACHE_SIZE, 4194304, 8, 64 }, +- { 0x2c, _SC_LEVEL1_DCACHE_SIZE, 32768, 8, 64 }, +- { 0x30, _SC_LEVEL1_ICACHE_SIZE, 32768, 8, 64 }, +- { 0x39, _SC_LEVEL2_CACHE_SIZE, 131072, 4, 64 }, +- { 0x3a, _SC_LEVEL2_CACHE_SIZE, 196608, 6, 64 }, +- { 0x3b, _SC_LEVEL2_CACHE_SIZE, 131072, 2, 64 }, +- { 0x3c, _SC_LEVEL2_CACHE_SIZE, 262144, 4, 64 }, +- { 0x3d, _SC_LEVEL2_CACHE_SIZE, 393216, 6, 64 }, +- { 0x3e, _SC_LEVEL2_CACHE_SIZE, 524288, 4, 64 }, +- { 0x41, _SC_LEVEL2_CACHE_SIZE, 131072, 4, 32 }, +- { 0x42, _SC_LEVEL2_CACHE_SIZE, 262144, 4, 32 }, +- { 0x43, _SC_LEVEL2_CACHE_SIZE, 524288, 4, 32 }, +- { 0x44, _SC_LEVEL2_CACHE_SIZE, 1048576, 4, 32 }, +- { 0x45, _SC_LEVEL2_CACHE_SIZE, 2097152, 4, 32 }, +- { 0x46, _SC_LEVEL3_CACHE_SIZE, 4194304, 4, 64 }, +- { 0x47, _SC_LEVEL3_CACHE_SIZE, 8388608, 8, 64 }, +- { 0x49, _SC_LEVEL2_CACHE_SIZE, 4194304, 16, 64 }, +- { 0x4a, _SC_LEVEL3_CACHE_SIZE, 6291456, 12, 64 }, +- { 0x4b, _SC_LEVEL3_CACHE_SIZE, 8388608, 16, 64 }, +- { 0x4c, _SC_LEVEL3_CACHE_SIZE, 12582912, 12, 64 }, +- { 0x4d, _SC_LEVEL3_CACHE_SIZE, 16777216, 16, 64 }, +- { 0x60, _SC_LEVEL1_DCACHE_SIZE, 16384, 8, 64 }, +- { 0x66, _SC_LEVEL1_DCACHE_SIZE, 8192, 4, 64 }, +- { 0x67, _SC_LEVEL1_DCACHE_SIZE, 16384, 4, 64 }, +- { 0x68, _SC_LEVEL1_DCACHE_SIZE, 32768, 4, 64 }, +- { 0x78, _SC_LEVEL2_CACHE_SIZE, 1048576, 8, 64 }, +- { 0x79, _SC_LEVEL2_CACHE_SIZE, 131072, 8, 64 }, +- { 0x7a, _SC_LEVEL2_CACHE_SIZE, 262144, 8, 64 }, +- { 0x7b, _SC_LEVEL2_CACHE_SIZE, 524288, 8, 64 }, +- { 0x7c, _SC_LEVEL2_CACHE_SIZE, 1048576, 8, 64 }, +- { 0x7d, _SC_LEVEL2_CACHE_SIZE, 2097152, 8, 64 }, +- { 0x7f, _SC_LEVEL2_CACHE_SIZE, 524288, 2, 64 }, +- { 0x82, _SC_LEVEL2_CACHE_SIZE, 262144, 8, 32 }, +- { 0x83, _SC_LEVEL2_CACHE_SIZE, 524288, 8, 32 }, +- { 0x84, _SC_LEVEL2_CACHE_SIZE, 1048576, 8, 32 }, +- { 0x85, _SC_LEVEL2_CACHE_SIZE, 2097152, 8, 32 }, +- { 0x86, _SC_LEVEL2_CACHE_SIZE, 524288, 4, 64 }, +- { 0x87, _SC_LEVEL2_CACHE_SIZE, 1048576, 8, 64 }, +- }; +-#define nintel_02_known (sizeof (intel_02_known) / sizeof (intel_02_known[0])) +- +- +-static int +-intel_02_known_compare (const void *p1, const void *p2) +-{ +- const struct intel_02_cache_info *i1; +- const struct intel_02_cache_info *i2; +- +- i1 = (const struct intel_02_cache_info *) p1; +- i2 = (const struct intel_02_cache_info *) p2; +- +- if (i1->idx == i2->idx) +- return 0; +- +- return i1->idx < i2->idx ? -1 : 1; +-} +- +- +-static long int +-__attribute__ ((noinline)) +-intel_check_word (int name, unsigned int value, bool *has_level_2, +- bool *no_level_2_or_3) +-{ +- if ((value & 0x80000000) != 0) +- /* The register value is reserved. */ +- return 0; +- +- /* Fold the name. The _SC_ constants are always in the order SIZE, +- ASSOC, LINESIZE. */ +- int folded_name = (_SC_LEVEL1_ICACHE_SIZE +- + ((name - _SC_LEVEL1_ICACHE_SIZE) / 3) * 3); +- +- while (value != 0) +- { +- unsigned int byte = value & 0xff; +- +- if (byte == 0x40) +- { +- *no_level_2_or_3 = true; +- +- if (folded_name == _SC_LEVEL3_CACHE_SIZE) +- /* No need to look further. */ +- break; +- } +- else +- { +- if (byte == 0x49 && folded_name == _SC_LEVEL3_CACHE_SIZE) +- { +- /* Intel reused this value. For family 15, model 6 it +- specifies the 3rd level cache. Otherwise the 2nd +- level cache. */ +- unsigned int eax; +- unsigned int ebx; +- unsigned int ecx; +- unsigned int edx; +- asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1" +- : "=a" (eax), "=r" (ebx), "=c" (ecx), "=d" (edx) +- : "0" (1)); +- +- unsigned int family = ((eax >> 20) & 0xff) + ((eax >> 8) & 0xf); +- unsigned int model = ((((eax >>16) & 0xf) << 4) +- + ((eax >> 4) & 0xf)); +- if (family == 15 && model == 6) +- { +- /* The level 3 cache is encoded for this model like +- the level 2 cache is for other models. Pretend +- the caller asked for the level 2 cache. */ +- name = (_SC_LEVEL2_CACHE_SIZE +- + (name - _SC_LEVEL3_CACHE_SIZE)); +- folded_name = _SC_LEVEL3_CACHE_SIZE; +- } +- } +- +- struct intel_02_cache_info *found; +- struct intel_02_cache_info search; +- +- search.idx = byte; +- found = bsearch (&search, intel_02_known, nintel_02_known, +- sizeof (intel_02_known[0]), intel_02_known_compare); +- if (found != NULL) +- { +- if (found->name == folded_name) +- { +- unsigned int offset = name - folded_name; +- +- if (offset == 0) +- /* Cache size. */ +- return found->size; +- if (offset == 1) +- return found->assoc; +- +- assert (offset == 2); +- return found->linesize; +- } +- +- if (found->name == _SC_LEVEL2_CACHE_SIZE) +- *has_level_2 = true; +- } +- } +- +- /* Next byte for the next round. */ +- value >>= 8; +- } +- +- /* Nothing found. */ +- return 0; +-} +- +- +-static long int __attribute__ ((noinline)) +-handle_intel (int name, unsigned int maxidx) +-{ +- assert (maxidx >= 2); +- +- /* OK, we can use the CPUID instruction to get all info about the +- caches. */ +- unsigned int cnt = 0; +- unsigned int max = 1; +- long int result = 0; +- bool no_level_2_or_3 = false; +- bool has_level_2 = false; +- while (cnt++ < max) +- { +- unsigned int eax; +- unsigned int ebx; +- unsigned int ecx; +- unsigned int edx; +- asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1" +- : "=a" (eax), "=r" (ebx), "=c" (ecx), "=d" (edx) +- : "0" (2)); +- +- /* 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 +- doing. */ +- if (cnt == 1) +- { +- max = eax & 0xff; +- eax &= 0xffffff00; +- } +- +- /* Process the individual registers' value. */ +- result = intel_check_word (name, eax, &has_level_2, &no_level_2_or_3); +- if (result != 0) +- return result; +- +- result = intel_check_word (name, ebx, &has_level_2, &no_level_2_or_3); +- if (result != 0) +- return result; +- +- result = intel_check_word (name, ecx, &has_level_2, &no_level_2_or_3); +- if (result != 0) +- return result; +- +- result = intel_check_word (name, edx, &has_level_2, &no_level_2_or_3); +- if (result != 0) +- return result; +- } +- +- if (name >= _SC_LEVEL2_CACHE_SIZE && name <= _SC_LEVEL3_CACHE_LINESIZE +- && no_level_2_or_3) +- return -1; +- +- return 0; +-} +- +- +-static long int __attribute__ ((noinline)) +-handle_amd (int name) +-{ +- unsigned int eax; +- unsigned int ebx; +- unsigned int ecx; +- unsigned int edx; +- asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1" +- : "=a" (eax), "=r" (ebx), "=c" (ecx), "=d" (edx) +- : "0" (0x80000000)); +- +- if (name >= _SC_LEVEL3_CACHE_SIZE) +- return 0; +- +- unsigned int fn = 0x80000005 + (name >= _SC_LEVEL2_CACHE_SIZE); +- if (eax < fn) +- return 0; +- +- asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1" +- : "=a" (eax), "=r" (ebx), "=c" (ecx), "=d" (edx) +- : "0" (fn)); +- +- if (name < _SC_LEVEL1_DCACHE_SIZE) +- { +- name += _SC_LEVEL1_DCACHE_SIZE - _SC_LEVEL1_ICACHE_SIZE; +- ecx = edx; +- } +- +- switch (name) +- { +- case _SC_LEVEL1_DCACHE_SIZE: +- return (ecx >> 14) & 0x3fc00; +- case _SC_LEVEL1_DCACHE_ASSOC: +- ecx >>= 16; +- if ((ecx & 0xff) == 0xff) +- /* Fully associative. */ +- return (ecx << 2) & 0x3fc00; +- return ecx & 0xff; +- case _SC_LEVEL1_DCACHE_LINESIZE: +- return ecx & 0xff; +- case _SC_LEVEL2_CACHE_SIZE: +- return (ecx & 0xf000) == 0 ? 0 : (ecx >> 6) & 0x3fffc00; +- case _SC_LEVEL2_CACHE_ASSOC: +- ecx >>= 12; +- switch (ecx & 0xf) +- { +- case 0: +- case 1: +- case 2: +- case 4: +- return ecx & 0xf; +- case 6: +- return 8; +- case 8: +- return 16; +- case 0xf: +- return (ecx << 6) & 0x3fffc00; +- default: +- return 0; +- } +- case _SC_LEVEL2_CACHE_LINESIZE: +- return (ecx & 0xf000) == 0 ? 0 : ecx & 0xff; +- default: +- assert (! "cannot happen"); +- } +- return -1; +-} ++extern long int __cache_sysconf (int) attribute_hidden; + + + /* Get the value of the system variable NAME. */ + long int + __sysconf (int name) + { +- /* We only handle the cache information here (for now). */ +- if (name < _SC_LEVEL1_ICACHE_SIZE || name > _SC_LEVEL4_CACHE_LINESIZE) +- return linux_sysconf (name); +- +- /* Find out what brand of processor. */ +- unsigned int eax; +- unsigned int ebx; +- unsigned int ecx; +- unsigned int edx; +- asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1" +- : "=a" (eax), "=r" (ebx), "=c" (ecx), "=d" (edx) +- : "0" (0)); +- +- /* This spells out "GenuineIntel". */ +- if (ebx == 0x756e6547 && ecx == 0x6c65746e && edx == 0x49656e69) +- return handle_intel (name, eax); +- +- /* This spells out "AuthenticAMD". */ +- if (ebx == 0x68747541 && ecx == 0x444d4163 && edx == 0x69746e65) +- return handle_amd (name); +- +- // XXX Fill in more vendors. ++ if (name >= _SC_LEVEL1_ICACHE_SIZE && name <= _SC_LEVEL4_CACHE_LINESIZE) ++ return __cache_sysconf (name); + +- /* CPU not known, we have no information. */ +- return 0; ++ return linux_sysconf (name); + } + + /* Now the generic Linux version. */ --- glibc-20070515T2025/sysdeps/unix/sysv/linux/x86_64/sys/epoll.h 22 Feb 2006 05:48:50 -0000 1.3 +++ glibc-20070515T2025-fedora/sysdeps/unix/sysv/linux/x86_64/sys/epoll.h 21 May 2007 20:01:11 -0000 1.2.2.2 @@ -1,4 +1,4 @@ @@ -3151,6 +5940,1100 @@ __END_DECLS #endif /* sys/epoll.h */ +--- glibc-20070515T2025/sysdeps/x86_64/Makefile 16 Aug 2004 06:46:14 -0000 1.4 ++++ glibc-20070515T2025-fedora/sysdeps/x86_64/Makefile 7 Jul 2007 16:06:42 -0000 1.4.2.1 +@@ -9,3 +9,7 @@ endif + ifeq ($(subdir),gmon) + sysdep_routines += _mcount + endif ++ ++ifeq ($(subdir),string) ++sysdep_routines += cacheinfo ++endif +--- glibc-20070515T2025/sysdeps/x86_64/cacheinfo.c 1 Jan 1970 00:00:00 -0000 ++++ glibc-20070515T2025-fedora/sysdeps/x86_64/cacheinfo.c 7 Jul 2007 16:06:42 -0000 1.2.2.1 +@@ -0,0 +1,451 @@ ++/* x86_64 cache info. ++ Copyright (C) 2003, 2004, 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 ++ 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 ++ ++static const struct intel_02_cache_info ++{ ++ unsigned int idx; ++ int name; ++ long int size; ++ long int assoc; ++ long int linesize; ++} intel_02_known [] = ++ { ++ { 0x06, _SC_LEVEL1_ICACHE_SIZE, 8192, 4, 32 }, ++ { 0x08, _SC_LEVEL1_ICACHE_SIZE, 16384, 4, 32 }, ++ { 0x0a, _SC_LEVEL1_DCACHE_SIZE, 8192, 2, 32 }, ++ { 0x0c, _SC_LEVEL1_DCACHE_SIZE, 16384, 4, 32 }, ++ { 0x22, _SC_LEVEL3_CACHE_SIZE, 524288, 4, 64 }, ++ { 0x23, _SC_LEVEL3_CACHE_SIZE, 1048576, 8, 64 }, ++ { 0x25, _SC_LEVEL3_CACHE_SIZE, 2097152, 8, 64 }, ++ { 0x29, _SC_LEVEL3_CACHE_SIZE, 4194304, 8, 64 }, ++ { 0x2c, _SC_LEVEL1_DCACHE_SIZE, 32768, 8, 64 }, ++ { 0x30, _SC_LEVEL1_ICACHE_SIZE, 32768, 8, 64 }, ++ { 0x39, _SC_LEVEL2_CACHE_SIZE, 131072, 4, 64 }, ++ { 0x3a, _SC_LEVEL2_CACHE_SIZE, 196608, 6, 64 }, ++ { 0x3b, _SC_LEVEL2_CACHE_SIZE, 131072, 2, 64 }, ++ { 0x3c, _SC_LEVEL2_CACHE_SIZE, 262144, 4, 64 }, ++ { 0x3d, _SC_LEVEL2_CACHE_SIZE, 393216, 6, 64 }, ++ { 0x3e, _SC_LEVEL2_CACHE_SIZE, 524288, 4, 64 }, ++ { 0x41, _SC_LEVEL2_CACHE_SIZE, 131072, 4, 32 }, ++ { 0x42, _SC_LEVEL2_CACHE_SIZE, 262144, 4, 32 }, ++ { 0x43, _SC_LEVEL2_CACHE_SIZE, 524288, 4, 32 }, ++ { 0x44, _SC_LEVEL2_CACHE_SIZE, 1048576, 4, 32 }, ++ { 0x45, _SC_LEVEL2_CACHE_SIZE, 2097152, 4, 32 }, ++ { 0x46, _SC_LEVEL3_CACHE_SIZE, 4194304, 4, 64 }, ++ { 0x47, _SC_LEVEL3_CACHE_SIZE, 8388608, 8, 64 }, ++ { 0x49, _SC_LEVEL2_CACHE_SIZE, 4194304, 16, 64 }, ++ { 0x4a, _SC_LEVEL3_CACHE_SIZE, 6291456, 12, 64 }, ++ { 0x4b, _SC_LEVEL3_CACHE_SIZE, 8388608, 16, 64 }, ++ { 0x4c, _SC_LEVEL3_CACHE_SIZE, 12582912, 12, 64 }, ++ { 0x4d, _SC_LEVEL3_CACHE_SIZE, 16777216, 16, 64 }, ++ { 0x60, _SC_LEVEL1_DCACHE_SIZE, 16384, 8, 64 }, ++ { 0x66, _SC_LEVEL1_DCACHE_SIZE, 8192, 4, 64 }, ++ { 0x67, _SC_LEVEL1_DCACHE_SIZE, 16384, 4, 64 }, ++ { 0x68, _SC_LEVEL1_DCACHE_SIZE, 32768, 4, 64 }, ++ { 0x78, _SC_LEVEL2_CACHE_SIZE, 1048576, 8, 64 }, ++ { 0x79, _SC_LEVEL2_CACHE_SIZE, 131072, 8, 64 }, ++ { 0x7a, _SC_LEVEL2_CACHE_SIZE, 262144, 8, 64 }, ++ { 0x7b, _SC_LEVEL2_CACHE_SIZE, 524288, 8, 64 }, ++ { 0x7c, _SC_LEVEL2_CACHE_SIZE, 1048576, 8, 64 }, ++ { 0x7d, _SC_LEVEL2_CACHE_SIZE, 2097152, 8, 64 }, ++ { 0x7f, _SC_LEVEL2_CACHE_SIZE, 524288, 2, 64 }, ++ { 0x82, _SC_LEVEL2_CACHE_SIZE, 262144, 8, 32 }, ++ { 0x83, _SC_LEVEL2_CACHE_SIZE, 524288, 8, 32 }, ++ { 0x84, _SC_LEVEL2_CACHE_SIZE, 1048576, 8, 32 }, ++ { 0x85, _SC_LEVEL2_CACHE_SIZE, 2097152, 8, 32 }, ++ { 0x86, _SC_LEVEL2_CACHE_SIZE, 524288, 4, 64 }, ++ { 0x87, _SC_LEVEL2_CACHE_SIZE, 1048576, 8, 64 }, ++ }; ++ ++#define nintel_02_known (sizeof (intel_02_known) / sizeof (intel_02_known [0])) ++ ++static int ++intel_02_known_compare (const void *p1, const void *p2) ++{ ++ const struct intel_02_cache_info *i1; ++ const struct intel_02_cache_info *i2; ++ ++ i1 = (const struct intel_02_cache_info *) p1; ++ i2 = (const struct intel_02_cache_info *) p2; ++ ++ if (i1->idx == i2->idx) ++ return 0; ++ ++ return i1->idx < i2->idx ? -1 : 1; ++} ++ ++ ++static long int ++__attribute__ ((noinline)) ++intel_check_word (int name, unsigned int value, bool *has_level_2, ++ bool *no_level_2_or_3) ++{ ++ if ((value & 0x80000000) != 0) ++ /* The register value is reserved. */ ++ return 0; ++ ++ /* Fold the name. The _SC_ constants are always in the order SIZE, ++ ASSOC, LINESIZE. */ ++ int folded_name = (_SC_LEVEL1_ICACHE_SIZE ++ + ((name - _SC_LEVEL1_ICACHE_SIZE) / 3) * 3); ++ ++ while (value != 0) ++ { ++ unsigned int byte = value & 0xff; ++ ++ if (byte == 0x40) ++ { ++ *no_level_2_or_3 = true; ++ ++ if (folded_name == _SC_LEVEL3_CACHE_SIZE) ++ /* No need to look further. */ ++ break; ++ } ++ else ++ { ++ if (byte == 0x49 && folded_name == _SC_LEVEL3_CACHE_SIZE) ++ { ++ /* Intel reused this value. For family 15, model 6 it ++ specifies the 3rd level cache. Otherwise the 2nd ++ level cache. */ ++ unsigned int eax; ++ unsigned int ebx; ++ unsigned int ecx; ++ unsigned int edx; ++ asm volatile ("cpuid" ++ : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) ++ : "0" (1)); ++ ++ unsigned int family = ((eax >> 20) & 0xff) + ((eax >> 8) & 0xf); ++ unsigned int model = ((((eax >>16) & 0xf) << 4) ++ + ((eax >> 4) & 0xf)); ++ if (family == 15 && model == 6) ++ { ++ /* The level 3 cache is encoded for this model like ++ the level 2 cache is for other models. Pretend ++ the caller asked for the level 2 cache. */ ++ name = (_SC_LEVEL2_CACHE_SIZE ++ + (name - _SC_LEVEL3_CACHE_SIZE)); ++ folded_name = _SC_LEVEL3_CACHE_SIZE; ++ } ++ } ++ ++ struct intel_02_cache_info *found; ++ struct intel_02_cache_info search; ++ ++ search.idx = byte; ++ found = bsearch (&search, intel_02_known, nintel_02_known, ++ sizeof (intel_02_known[0]), intel_02_known_compare); ++ if (found != NULL) ++ { ++ if (found->name == folded_name) ++ { ++ unsigned int offset = name - folded_name; ++ ++ if (offset == 0) ++ /* Cache size. */ ++ return found->size; ++ if (offset == 1) ++ return found->assoc; ++ ++ assert (offset == 2); ++ return found->linesize; ++ } ++ ++ if (found->name == _SC_LEVEL2_CACHE_SIZE) ++ *has_level_2 = true; ++ } ++ } ++ ++ /* Next byte for the next round. */ ++ value >>= 8; ++ } ++ ++ /* Nothing found. */ ++ return 0; ++} ++ ++ ++static long int __attribute__ ((noinline)) ++handle_intel (int name, unsigned int maxidx) ++{ ++ assert (maxidx >= 2); ++ ++ /* OK, we can use the CPUID instruction to get all info about the ++ caches. */ ++ unsigned int cnt = 0; ++ unsigned int max = 1; ++ long int result = 0; ++ bool no_level_2_or_3 = false; ++ bool has_level_2 = false; ++ ++ while (cnt++ < max) ++ { ++ unsigned int eax; ++ unsigned int ebx; ++ unsigned int ecx; ++ unsigned int edx; ++ asm volatile ("cpuid" ++ : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) ++ : "0" (2)); ++ ++ /* 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 ++ doing. */ ++ if (cnt == 1) ++ { ++ max = eax & 0xff; ++ eax &= 0xffffff00; ++ } ++ ++ /* Process the individual registers' value. */ ++ result = intel_check_word (name, eax, &has_level_2, &no_level_2_or_3); ++ if (result != 0) ++ return result; ++ ++ result = intel_check_word (name, ebx, &has_level_2, &no_level_2_or_3); ++ if (result != 0) ++ return result; ++ ++ result = intel_check_word (name, ecx, &has_level_2, &no_level_2_or_3); ++ if (result != 0) ++ return result; ++ ++ result = intel_check_word (name, edx, &has_level_2, &no_level_2_or_3); ++ if (result != 0) ++ return result; ++ } ++ ++ if (name >= _SC_LEVEL2_CACHE_SIZE && name <= _SC_LEVEL3_CACHE_LINESIZE ++ && no_level_2_or_3) ++ return -1; ++ ++ return 0; ++} ++ ++ ++static long int __attribute__ ((noinline)) ++handle_amd (int name) ++{ ++ unsigned int eax; ++ unsigned int ebx; ++ unsigned int ecx; ++ unsigned int edx; ++ asm volatile ("cpuid" ++ : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) ++ : "0" (0x80000000)); ++ ++ if (name >= _SC_LEVEL3_CACHE_SIZE) ++ return 0; ++ ++ unsigned int fn = 0x80000005 + (name >= _SC_LEVEL2_CACHE_SIZE); ++ if (eax < fn) ++ return 0; ++ ++ asm volatile ("cpuid" ++ : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) ++ : "0" (fn)); ++ ++ if (name < _SC_LEVEL1_DCACHE_SIZE) ++ { ++ name += _SC_LEVEL1_DCACHE_SIZE - _SC_LEVEL1_ICACHE_SIZE; ++ ecx = edx; ++ } ++ ++ switch (name) ++ { ++ case _SC_LEVEL1_DCACHE_SIZE: ++ return (ecx >> 14) & 0x3fc00; ++ case _SC_LEVEL1_DCACHE_ASSOC: ++ ecx >>= 16; ++ if ((ecx & 0xff) == 0xff) ++ /* Fully associative. */ ++ return (ecx << 2) & 0x3fc00; ++ return ecx & 0xff; ++ case _SC_LEVEL1_DCACHE_LINESIZE: ++ return ecx & 0xff; ++ case _SC_LEVEL2_CACHE_SIZE: ++ return (ecx & 0xf000) == 0 ? 0 : (ecx >> 6) & 0x3fffc00; ++ case _SC_LEVEL2_CACHE_ASSOC: ++ ecx >>= 12; ++ switch (ecx & 0xf) ++ { ++ case 0: ++ case 1: ++ case 2: ++ case 4: ++ return ecx & 0xf; ++ case 6: ++ return 8; ++ case 8: ++ return 16; ++ case 0xf: ++ return (ecx << 6) & 0x3fffc00; ++ default: ++ return 0; ++ } ++ case _SC_LEVEL2_CACHE_LINESIZE: ++ return (ecx & 0xf000) == 0 ? 0 : ecx & 0xff; ++ default: ++ assert (! "cannot happen"); ++ } ++ return -1; ++} ++ ++ ++/* Get the value of the system variable NAME. */ ++long int ++attribute_hidden ++__cache_sysconf (int name) ++{ ++ /* Find out what brand of processor. */ ++ unsigned int eax; ++ unsigned int ebx; ++ unsigned int ecx; ++ unsigned int edx; ++ asm volatile ("cpuid" ++ : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) ++ : "0" (0)); ++ ++ /* This spells out "GenuineIntel". */ ++ if (ebx == 0x756e6547 && ecx == 0x6c65746e && edx == 0x49656e69) ++ return handle_intel (name, eax); ++ ++ /* This spells out "AuthenticAMD". */ ++ if (ebx == 0x68747541 && ecx == 0x444d4163 && edx == 0x69746e65) ++ return handle_amd (name); ++ ++ // XXX Fill in more vendors. ++ ++ /* CPU not known, we have no information. */ ++ return 0; ++} ++ ++ ++/* Half the core cache size for use in memory and string routines, typically ++ L1 size. */ ++long int __x86_64_core_cache_size_half attribute_hidden = 32 * 1024 / 2; ++/* Shared cache size for use in memory and string routines, typically ++ L2 or L3 size. */ ++long int __x86_64_shared_cache_size_half attribute_hidden = 1024 * 1024 / 2; ++/* PREFETCHW support flag for use in memory and string routines. */ ++int __x86_64_prefetchw attribute_hidden; ++ ++ ++static void ++__attribute__((constructor)) ++init_cacheinfo (void) ++{ ++ /* Find out what brand of processor. */ ++ unsigned int eax; ++ unsigned int ebx; ++ unsigned int ecx; ++ unsigned int edx; ++ int max_cpuid; ++ int max_cpuid_ex; ++ long int core = -1; ++ long int shared = -1; ++ unsigned int level; ++ unsigned int threads = 0; ++ ++ asm volatile ("cpuid" ++ : "=a" (max_cpuid), "=b" (ebx), "=c" (ecx), "=d" (edx) ++ : "0" (0)); ++ ++ /* This spells out "GenuineIntel". */ ++ if (ebx == 0x756e6547 && ecx == 0x6c65746e && edx == 0x49656e69) ++ { ++ core = handle_intel (_SC_LEVEL1_DCACHE_SIZE, max_cpuid); ++ ++ /* Try L3 first. */ ++ level = 3; ++ shared = handle_intel (_SC_LEVEL3_CACHE_SIZE, max_cpuid); ++ ++ if (shared <= 0) ++ { ++ /* Try L2 otherwise. */ ++ level = 2; ++ shared = handle_intel (_SC_LEVEL2_CACHE_SIZE, max_cpuid); ++ } ++ ++ /* Figure out the number of logical threads that share the ++ highest cache level. */ ++ if (max_cpuid >= 4) ++ { ++ int i = 0; ++ ++ /* Query until desired cache level is enumerated. */ ++ do ++ { ++ asm volatile ("cpuid" ++ : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) ++ : "0" (4), "2" (i++)); ++ } ++ while (((eax >> 5) & 0x7) != level); ++ ++ threads = ((eax >> 14) & 0x3ff) + 1; ++ } ++ else ++ { ++ /* Assume that all logical threads share the highest cache level. */ ++ asm volatile ("cpuid" ++ : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) ++ : "0" (1)); ++ ++ threads = (ebx >> 16) & 0xff; ++ } ++ ++ /* Cap usage of highest cache level to the number of supported ++ threads. */ ++ if (shared > 0 && threads > 0) ++ shared /= threads; ++ } ++ /* This spells out "AuthenticAMD". */ ++ else if (ebx == 0x68747541 && ecx == 0x444d4163 && edx == 0x69746e65) ++ { ++ core = handle_amd (_SC_LEVEL1_DCACHE_SIZE); ++ shared = handle_amd (_SC_LEVEL2_CACHE_SIZE); ++ ++ asm volatile ("cpuid" ++ : "=a" (max_cpuid_ex), "=b" (ebx), "=c" (ecx), "=d" (edx) ++ : "0" (0x80000000)); ++ ++ if (max_cpuid_ex >= 0x80000001) ++ { ++ asm volatile ("cpuid" ++ : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) ++ : "0" (0x80000001)); ++ /* PREFETCHW || 3DNow! */ ++ if ((ecx & 0x100) || (edx & 0x80000000)) ++ __x86_64_prefetchw = -1; ++ } ++ } ++ ++ if (core > 0) ++ __x86_64_core_cache_size_half = core / 2; ++ ++ if (shared > 0) ++ __x86_64_shared_cache_size_half = shared / 2; ++} +--- glibc-20070515T2025/sysdeps/x86_64/ldbl2mpn.c 1 Jan 1970 00:00:00 -0000 ++++ glibc-20070515T2025-fedora/sysdeps/x86_64/ldbl2mpn.c 7 Jul 2007 19:59:56 -0000 1.1.2.1 +@@ -0,0 +1 @@ ++#include "../i386/ldbl2mpn.c" +--- glibc-20070515T2025/sysdeps/x86_64/memcpy.S 18 Oct 2004 04:17:08 -0000 1.5 ++++ glibc-20070515T2025-fedora/sysdeps/x86_64/memcpy.S 7 Jul 2007 16:06:42 -0000 1.4.2.2 +@@ -1,7 +1,10 @@ +-/* Highly optimized version for x86-64. +- Copyright (C) 1997, 2000, 2002, 2003, 2004 Free Software Foundation, Inc. ++/* ++ Optimized memcpy for x86-64. ++ ++ Copyright (C) 2007 Free Software Foundation, Inc. ++ Contributed by Evandro Menezes , 2007. ++ + This file is part of the GNU C Library. +- Based on i586 version contributed by Ulrich Drepper , 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public +@@ -16,86 +19,556 @@ + 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. */ ++ 02111-1307 USA. ++*/ + + #include + #include "asm-syntax.h" +-#include "bp-sym.h" +-#include "bp-asm.h" + +-/* BEWARE: `#ifdef memcpy' means that memcpy is redefined as `mempcpy', +- and the return value is the byte after the last one copied in +- the destination. */ +-#define MEMPCPY_P (defined memcpy) ++/* Stack slots in the red-zone. */ ++ ++#ifdef USE_AS_MEMPCPY ++# define RETVAL (0) ++#else ++# define RETVAL (-8) ++#endif ++#define SAVE0 (RETVAL - 8) ++#define SAVE1 (SAVE0 - 8) ++#define SAVE2 (SAVE1 - 8) ++#define SAVE3 (SAVE2 - 8) + + .text ++ + #if defined PIC && !defined NOT_IN_libc + ENTRY (__memcpy_chk) ++ + cmpq %rdx, %rcx + jb HIDDEN_JUMPTARGET (__chk_fail) ++ + END (__memcpy_chk) + #endif +-ENTRY (BP_SYM (memcpy)) +- /* Cutoff for the big loop is a size of 32 bytes since otherwise +- the loop will never be entered. */ ++ ++ENTRY(memcpy) /* (void *, const void*, size_t) */ ++ ++/* Handle tiny blocks. */ ++ ++L(1try): /* up to 32B */ + cmpq $32, %rdx +- movq %rdx, %rcx +-#if !MEMPCPY_P +- movq %rdi, %r10 /* Save value. */ ++#ifndef USE_AS_MEMPCPY ++ movq %rdi, %rax /* save return value */ + #endif ++ jae L(1after) + +- /* We need this in any case. */ +- cld ++L(1): /* 1-byte once */ ++ testb $1, %dl ++ jz L(1a) + +- jbe 1f ++ movzbl (%rsi), %ecx ++ movb %cl, (%rdi) + +- /* Align destination. */ +- movq %rdi, %rax +- negq %rax +- andq $7, %rax +- subq %rax, %rcx +- xchgq %rax, %rcx ++ incq %rsi ++ incq %rdi ++ ++ .p2align 4,, 4 ++ ++L(1a): /* 2-byte once */ ++ testb $2, %dl ++ jz L(1b) ++ ++ movzwl (%rsi), %ecx ++ movw %cx, (%rdi) + +- rep; movsb ++ addq $2, %rsi ++ addq $2, %rdi + +- movq %rax, %rcx +- subq $32, %rcx +- js 2f ++ .p2align 4,, 4 ++ ++L(1b): /* 4-byte once */ ++ testb $4, %dl ++ jz L(1c) ++ ++ movl (%rsi), %ecx ++ movl %ecx, (%rdi) ++ ++ addq $4, %rsi ++ addq $4, %rdi ++ ++ .p2align 4,, 4 ++ ++L(1c): /* 8-byte once */ ++ testb $8, %dl ++ jz L(1d) ++ ++ movq (%rsi), %rcx ++ movq %rcx, (%rdi) ++ ++ addq $8, %rsi ++ addq $8, %rdi ++ ++ .p2align 4,, 4 ++ ++L(1d): /* 16-byte loop */ ++ andl $0xf0, %edx ++ jz L(exit) + + .p2align 4 +-3: + +- /* Now correct the loop counter. Please note that in the following +- code the flags are not changed anymore. */ +- subq $32, %rcx ++L(1loop): ++ movq (%rsi), %rcx ++ movq 8 (%rsi), %r8 ++ movq %rcx, (%rdi) ++ movq %r8, 8 (%rdi) ++ ++ subl $16, %edx ++ ++ leaq 16 (%rsi), %rsi ++ leaq 16 (%rdi), %rdi ++ ++ jnz L(1loop) ++ ++ .p2align 4,, 4 ++ ++L(exit): /* exit */ ++#ifdef USE_AS_MEMPCPY ++ movq %rdi, %rax /* return value */ ++#else ++ rep ++#endif ++ retq ++ ++ .p2align 4 ++ ++L(1after): ++#ifndef USE_AS_MEMPCPY ++ movq %rax, RETVAL (%rsp) /* save return value */ ++#endif ++ ++/* Align to the natural word size. */ ++ ++L(aligntry): ++ movl %esi, %ecx /* align by destination */ ++ ++ andl $7, %ecx ++ jz L(alignafter) /* already aligned */ ++ ++L(align): /* align */ ++ leaq -8 (%rcx, %rdx), %rdx /* calculate remaining bytes */ ++ subl $8, %ecx ++ ++ .p2align 4 ++ ++L(alignloop): /* 1-byte alignment loop */ ++ movzbl (%rsi), %eax ++ movb %al, (%rdi) ++ ++ incl %ecx ++ ++ leaq 1 (%rsi), %rsi ++ leaq 1 (%rdi), %rdi ++ ++ jnz L(alignloop) ++ ++ .p2align 4 ++ ++L(alignafter): ++ ++/* Loop to handle mid-sized blocks. */ ++ ++L(32try): /* up to 1KB */ ++ cmpq $1024, %rdx ++ ja L(32after) ++ ++L(32): /* 32-byte loop */ ++ movl %edx, %ecx ++ shrl $5, %ecx ++ jz L(32skip) ++ ++ .p2align 4 ++ ++L(32loop): ++ decl %ecx + + movq (%rsi), %rax +- movq 8(%rsi), %rdx +- movq 16(%rsi), %r8 +- movq 24(%rsi), %r9 ++ movq 8 (%rsi), %r8 ++ movq 16 (%rsi), %r9 ++ movq 24 (%rsi), %r10 ++ + movq %rax, (%rdi) +- movq %rdx, 8(%rdi) +- movq %r8, 16(%rdi) +- movq %r9, 24(%rdi) ++ movq %r8, 8 (%rdi) ++ movq %r9, 16 (%rdi) ++ movq %r10, 24 (%rdi) + + leaq 32(%rsi), %rsi + leaq 32(%rdi), %rdi + +- jns 3b ++ jz L(32skip) /* help out smaller blocks */ ++ ++ decl %ecx ++ ++ movq (%rsi), %rax ++ movq 8 (%rsi), %r8 ++ movq 16 (%rsi), %r9 ++ movq 24 (%rsi), %r10 ++ ++ movq %rax, (%rdi) ++ movq %r8, 8 (%rdi) ++ movq %r9, 16 (%rdi) ++ movq %r10, 24 (%rdi) ++ ++ leaq 32 (%rsi), %rsi ++ leaq 32 (%rdi), %rdi ++ ++ jnz L(32loop) ++ ++ .p2align 4 + +- /* Correct extra loop counter modification. */ +-2: addq $32, %rcx +-1: rep; movsb ++L(32skip): ++ andl $31, %edx /* check for left overs */ ++#ifdef USE_AS_MEMPCPY ++ jnz L(1) + +-#if MEMPCPY_P +- movq %rdi, %rax /* Set return value. */ ++ movq %rdi, %rax + #else +- movq %r10, %rax /* Set return value. */ ++ movq RETVAL (%rsp), %rax ++ jnz L(1) + ++ rep ++#endif ++ retq /* exit */ ++ ++ .p2align 4 ++ ++L(32after): ++ ++/* ++ In order to minimize code-size in RTLD, algorithms specific for ++ larger blocks are excluded when building for RTLD. ++*/ ++ ++/* Handle large blocks smaller than 1/2 L1. */ ++ ++L(fasttry): /* first 1/2 L1 */ ++#ifndef NOT_IN_libc /* only up to this algorithm outside of libc.so */ ++ movq __x86_64_core_cache_size_half (%rip), %r11 ++ cmpq %rdx, %r11 /* calculate the smaller of */ ++ cmovaq %rdx, %r11 /* remaining bytes and 1/2 L1 */ ++#endif ++ ++L(fast): /* good ol' MOVS */ ++#ifndef NOT_IN_libc ++ movq %r11, %rcx ++ andq $-8, %r11 ++#else ++ movq %rdx, %rcx ++#endif ++ shrq $3, %rcx ++ jz L(fastskip) ++ ++ rep ++ movsq ++ ++ .p2align 4,, 4 ++ ++L(fastskip): ++#ifndef NOT_IN_libc ++ subq %r11, %rdx /* check for more */ ++ testq $-8, %rdx ++ jnz L(fastafter) + #endif +- ret + +-END (BP_SYM (memcpy)) +-#if !MEMPCPY_P ++ andl $7, %edx /* check for left overs */ ++#ifdef USE_AS_MEMPCPY ++ jnz L(1) ++ ++ movq %rdi, %rax ++#else ++ movq RETVAL (%rsp), %rax ++ jnz L(1) ++ ++ rep ++#endif ++ retq /* exit */ ++ ++#ifndef NOT_IN_libc /* none of the algorithms below for RTLD */ ++ ++ .p2align 4 ++ ++L(fastafter): ++ ++/* Handle large blocks smaller than 1/2 L2. */ ++ ++L(pretry): /* first 1/2 L2 */ ++ movq __x86_64_shared_cache_size_half (%rip), %r8 ++ cmpq %rdx, %r8 /* calculate the lesser of */ ++ cmovaq %rdx, %r8 /* remaining bytes and 1/2 L2 */ ++ ++L(pre): /* 64-byte with prefetching */ ++ movq %r8, %rcx ++ andq $-64, %r8 ++ shrq $6, %rcx ++ jz L(preskip) ++ ++ movq %r14, SAVE0 (%rsp) ++ cfi_rel_offset (%r14, SAVE0) ++ movq %r13, SAVE1 (%rsp) ++ cfi_rel_offset (%r13, SAVE1) ++ movq %r12, SAVE2 (%rsp) ++ cfi_rel_offset (%r12, SAVE2) ++ movq %rbx, SAVE3 (%rsp) ++ cfi_rel_offset (%rbx, SAVE3) ++ ++ cmpl $0, __x86_64_prefetchw (%rip) ++ jz L(preloop) /* check if PREFETCHW OK */ ++ ++ .p2align 4 ++ ++/* ... when PREFETCHW is available (less cache-probe traffic in MP systems). */ ++ ++L(prewloop): /* cache-line in state M */ ++ decq %rcx ++ ++ movq (%rsi), %rax ++ movq 8 (%rsi), %rbx ++ movq 16 (%rsi), %r9 ++ movq 24 (%rsi), %r10 ++ movq 32 (%rsi), %r11 ++ movq 40 (%rsi), %r12 ++ movq 48 (%rsi), %r13 ++ movq 56 (%rsi), %r14 ++ ++ prefetcht0 0 + 896 (%rsi) ++ prefetcht0 64 + 896 (%rsi) ++ ++ movq %rax, (%rdi) ++ movq %rbx, 8 (%rdi) ++ movq %r9, 16 (%rdi) ++ movq %r10, 24 (%rdi) ++ movq %r11, 32 (%rdi) ++ movq %r12, 40 (%rdi) ++ movq %r13, 48 (%rdi) ++ movq %r14, 56 (%rdi) ++ ++ leaq 64 (%rsi), %rsi ++ leaq 64 (%rdi), %rdi ++ ++ jz L(prebail) ++ ++ decq %rcx ++ ++ movq (%rsi), %rax ++ movq 8 (%rsi), %rbx ++ movq 16 (%rsi), %r9 ++ movq 24 (%rsi), %r10 ++ movq 32 (%rsi), %r11 ++ movq 40 (%rsi), %r12 ++ movq 48 (%rsi), %r13 ++ movq 56 (%rsi), %r14 ++ ++ movq %rax, (%rdi) ++ movq %rbx, 8 (%rdi) ++ movq %r9, 16 (%rdi) ++ movq %r10, 24 (%rdi) ++ movq %r11, 32 (%rdi) ++ movq %r12, 40 (%rdi) ++ movq %r13, 48 (%rdi) ++ movq %r14, 56 (%rdi) ++ ++ prefetchw 896 - 64 (%rdi) ++ prefetchw 896 - 0 (%rdi) ++ ++ leaq 64 (%rsi), %rsi ++ leaq 64 (%rdi), %rdi ++ ++ jnz L(prewloop) ++ jmp L(prebail) ++ ++ .p2align 4 ++ ++/* ... when PREFETCHW is not available. */ ++ ++L(preloop): /* cache-line in state E */ ++ decq %rcx ++ ++ movq (%rsi), %rax ++ movq 8 (%rsi), %rbx ++ movq 16 (%rsi), %r9 ++ movq 24 (%rsi), %r10 ++ movq 32 (%rsi), %r11 ++ movq 40 (%rsi), %r12 ++ movq 48 (%rsi), %r13 ++ movq 56 (%rsi), %r14 ++ ++ prefetcht0 896 + 0 (%rsi) ++ prefetcht0 896 + 64 (%rsi) ++ ++ movq %rax, (%rdi) ++ movq %rbx, 8 (%rdi) ++ movq %r9, 16 (%rdi) ++ movq %r10, 24 (%rdi) ++ movq %r11, 32 (%rdi) ++ movq %r12, 40 (%rdi) ++ movq %r13, 48 (%rdi) ++ movq %r14, 56 (%rdi) ++ ++ leaq 64 (%rsi), %rsi ++ leaq 64 (%rdi), %rdi ++ ++ jz L(prebail) ++ ++ decq %rcx ++ ++ movq (%rsi), %rax ++ movq 8 (%rsi), %rbx ++ movq 16 (%rsi), %r9 ++ movq 24 (%rsi), %r10 ++ movq 32 (%rsi), %r11 ++ movq 40 (%rsi), %r12 ++ movq 48 (%rsi), %r13 ++ movq 56 (%rsi), %r14 ++ ++ prefetcht0 896 - 64 (%rdi) ++ prefetcht0 896 - 0 (%rdi) ++ ++ movq %rax, (%rdi) ++ movq %rbx, 8 (%rdi) ++ movq %r9, 16 (%rdi) ++ movq %r10, 24 (%rdi) ++ movq %r11, 32 (%rdi) ++ movq %r12, 40 (%rdi) ++ movq %r13, 48 (%rdi) ++ movq %r14, 56 (%rdi) ++ ++ leaq 64 (%rsi), %rsi ++ leaq 64 (%rdi), %rdi ++ ++ jnz L(preloop) ++ ++L(prebail): ++ movq SAVE3 (%rsp), %rbx ++ cfi_restore (%rbx) ++ movq SAVE2 (%rsp), %r12 ++ cfi_restore (%r12) ++ movq SAVE1 (%rsp), %r13 ++ cfi_restore (%r13) ++ movq SAVE0 (%rsp), %r14 ++ cfi_restore (%r14) ++ ++/* .p2align 4 */ ++ ++L(preskip): ++ subq %r8, %rdx /* check for more */ ++ testq $-64, %rdx ++ jnz L(preafter) ++ ++ andl $63, %edx /* check for left overs */ ++#ifdef USE_AS_MEMPCPY ++ jnz L(1) ++ ++ movq %rdi, %rax ++#else ++ movq RETVAL (%rsp), %rax ++ jnz L(1) ++ ++ rep ++#endif ++ retq /* exit */ ++ ++ .p2align 4 ++ ++L(preafter): ++ ++/* Loop to handle huge blocks. */ ++ ++L(NTtry): ++ ++L(NT): /* non-temporal 128-byte */ ++ movq %rdx, %rcx ++ shrq $7, %rcx ++ jz L(NTskip) ++ ++ movq %r14, SAVE0 (%rsp) ++ cfi_rel_offset (%r14, SAVE0) ++ movq %r13, SAVE1 (%rsp) ++ cfi_rel_offset (%r13, SAVE1) ++ movq %r12, SAVE2 (%rsp) ++ cfi_rel_offset (%r12, SAVE2) ++ ++ .p2align 4 ++ ++L(NTloop): ++ prefetchnta 768 (%rsi) ++ prefetchnta 832 (%rsi) ++ ++ decq %rcx ++ ++ movq (%rsi), %rax ++ movq 8 (%rsi), %r8 ++ movq 16 (%rsi), %r9 ++ movq 24 (%rsi), %r10 ++ movq 32 (%rsi), %r11 ++ movq 40 (%rsi), %r12 ++ movq 48 (%rsi), %r13 ++ movq 56 (%rsi), %r14 ++ ++ movntiq %rax, (%rdi) ++ movntiq %r8, 8 (%rdi) ++ movntiq %r9, 16 (%rdi) ++ movntiq %r10, 24 (%rdi) ++ movntiq %r11, 32 (%rdi) ++ movntiq %r12, 40 (%rdi) ++ movntiq %r13, 48 (%rdi) ++ movntiq %r14, 56 (%rdi) ++ ++ movq 64 (%rsi), %rax ++ movq 72 (%rsi), %r8 ++ movq 80 (%rsi), %r9 ++ movq 88 (%rsi), %r10 ++ movq 96 (%rsi), %r11 ++ movq 104 (%rsi), %r12 ++ movq 112 (%rsi), %r13 ++ movq 120 (%rsi), %r14 ++ ++ movntiq %rax, 64 (%rdi) ++ movntiq %r8, 72 (%rdi) ++ movntiq %r9, 80 (%rdi) ++ movntiq %r10, 88 (%rdi) ++ movntiq %r11, 96 (%rdi) ++ movntiq %r12, 104 (%rdi) ++ movntiq %r13, 112 (%rdi) ++ movntiq %r14, 120 (%rdi) ++ ++ leaq 128 (%rsi), %rsi ++ leaq 128 (%rdi), %rdi ++ ++ jnz L(NTloop) ++ ++ sfence /* serialize memory stores */ ++ ++ movq SAVE2 (%rsp), %r12 ++ cfi_restore (%r12) ++ movq SAVE1 (%rsp), %r13 ++ cfi_restore (%r13) ++ movq SAVE0 (%rsp), %r14 ++ cfi_restore (%r14) ++ ++L(NTskip): ++ andl $127, %edx /* check for left overs */ ++#ifdef USE_AS_MEMPCPY ++ jnz L(1) ++ ++ movq %rdi, %rax ++#else ++ movq RETVAL (%rsp), %rax ++ jnz L(1) ++ ++ rep ++#endif ++ retq /* exit */ ++ ++#endif /* !NOT_IN_libc */ ++ ++END(memcpy) ++ ++#ifndef USE_AS_MEMPCPY + libc_hidden_builtin_def (memcpy) + #endif +--- glibc-20070515T2025/sysdeps/x86_64/mempcpy.S 18 Oct 2004 04:17:08 -0000 1.3 ++++ glibc-20070515T2025-fedora/sysdeps/x86_64/mempcpy.S 7 Jul 2007 16:06:42 -0000 1.2.2.2 +@@ -1,3 +1,4 @@ ++#define USE_AS_MEMPCPY + #define memcpy __mempcpy + #define __memcpy_chk __mempcpy_chk + #include --- glibc-20070515T2025/sysdeps/x86_64/fpu/k_cosl.c 1 Jan 1970 00:00:00 -0000 +++ glibc-20070515T2025-fedora/sysdeps/x86_64/fpu/k_cosl.c 21 May 2007 20:01:15 -0000 1.1.2.1 @@ -0,0 +1 @@ diff --git a/glibc.spec b/glibc.spec index c386fa0..1219dcb 100644 --- a/glibc.spec +++ b/glibc.spec @@ -3,7 +3,7 @@ %define glibcsrcdir glibc-20070515T2025 %define glibc_release_tarballs 0 %define glibcversion 2.6 -%define glibcrelease 3 +%define glibcrelease 4 %define auxarches i586 i686 athlon sparcv9 alphaev6 %define xenarches i686 athlon %ifarch %{xenarches} @@ -1334,8 +1334,8 @@ for f in `find $RPM_BUILD_ROOT/%{_lib} -type l`; do done echo Sorting source file lists. Might take a while... -xargs -0 -n 1 echo < $sf | LC_ALL=C grep -v '/$\|\.gperf$' | LC_ALL=C sort -u > $sf.sorted -xargs -0 -n 1 echo < $csf | LC_ALL=C grep -v '/$\|\.gperf$' | LC_ALL=C sort -u > $csf.sorted +xargs -0 -n 1 echo < $sf | LC_ALL=C grep -v '/$\|$\|\.gperf$' | LC_ALL=C sort -u > $sf.sorted +xargs -0 -n 1 echo < $csf | LC_ALL=C grep -v '/$\|$\|\.gperf$' | LC_ALL=C sort -u > $csf.sorted mkdir -p $RPM_BUILD_ROOT/usr/src/debug cat $sf.sorted $csf.sorted \ | (cd $RPM_BUILD_DIR; LC_ALL=C sort -u | cpio -pdm ${RPM_BUILD_ROOT}/usr/src/debug) @@ -1566,6 +1566,25 @@ rm -f *.filelist* %endif %changelog +* Sun Jul 8 2007 Jakub Jelinek 2.6-4 +- filter pseudo-files from debuginfo source lists (#245714) +- fix sscanf when errno is EINTR before the call (BZ#4745) +- save/restore errno around reading /etc/default/nss (BZ#4702) +- fix LD_HWCAP_MASK handling +- disable workaround for #210748, instead backport + ld.so locking fixes from the trunk (#235026) +- new x86_64 memcpy +- don't write uninitialized padding bytes to nscd socket +- fix dl{,v}sym, dl_iterate_phdr and dlopen if some library is + mapped into ld.so's inter-segment hole on x86_64 (#245035, #244545) +- fix LD_AUDIT=a:b program (#180432) +- don't crash on pseudo-zero long double values passed to + *printf on i?86/x86_64/ia64 (BZ#4586) +- fix *printf %La and strtold with some hexadecimal floating point + constants on ppc/ppc64 +- fix nextafterl on ppc/ppc64 +- fix sem_timedwait on i?86 and x86_64 + * Thu May 24 2007 Jakub Jelinek 2.6-3 - don't use %%config(missingok) for locale-archive.tmpl, instead of removing it altogether truncate it to zero diff --git a/sources b/sources index ebed5a1..4365019 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ 9e33d4d525c8317685e925972f0f145b glibc-20070515T2025.tar.bz2 -ad50ecf4f3e877558e03d1df1259c4d0 glibc-fedora-20070515T2025.tar.bz2 +bf7a2ab1d2217c8d41e72702f63bbd6f glibc-fedora-20070515T2025.tar.bz2