[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Commits] r21029 - in /fsf/trunk/libc: ./ elf/ math/ nptl/ nptl/sysdeps/unix/sysv/linux/i386/i486/ nptl/sysdeps/unix/sysv/linux/x86_64...
- To: commits@xxxxxxxxxx
- Subject: [Commits] r21029 - in /fsf/trunk/libc: ./ elf/ math/ nptl/ nptl/sysdeps/unix/sysv/linux/i386/i486/ nptl/sysdeps/unix/sysv/linux/x86_64...
- From: eglibc@xxxxxxxxxx
- Date: Sat, 06 Oct 2012 00:01:48 -0000
Author: eglibc
Date: Sat Oct 6 00:01:47 2012
New Revision: 21029
Log:
Import glibc-mainline for 2012-10-06
Added:
fsf/trunk/libc/elf/dl-hwcaps.c
fsf/trunk/libc/elf/get-dynamic-info.h
fsf/trunk/libc/elf/setup-vdso.h
fsf/trunk/libc/nptl/tst-cancel24-static.cc
fsf/trunk/libc/nptl/tst-cond24.c
fsf/trunk/libc/nptl/tst-cond8-static.c
fsf/trunk/libc/nptl/tst-mutex8-static.c
fsf/trunk/libc/nptl/tst-mutexpi8-static.c
fsf/trunk/libc/nptl/tst-sem11-static.c
fsf/trunk/libc/nptl/tst-sem12-static.c
Removed:
fsf/trunk/libc/string/bug-strcasestr1.c
fsf/trunk/libc/string/bug-strchr1.c
fsf/trunk/libc/string/bug-strstr1.c
Modified:
fsf/trunk/libc/ChangeLog
fsf/trunk/libc/NEWS
fsf/trunk/libc/elf/Makefile
fsf/trunk/libc/elf/dl-support.c
fsf/trunk/libc/elf/dl-sysdep.c
fsf/trunk/libc/elf/dynamic-link.h
fsf/trunk/libc/elf/rtld.c
fsf/trunk/libc/math/libm-test.inc
fsf/trunk/libc/nptl/ChangeLog
fsf/trunk/libc/nptl/Makefile
fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
fsf/trunk/libc/ports/ChangeLog.arm
fsf/trunk/libc/ports/sysdeps/arm/dl-machine.h
fsf/trunk/libc/scripts/config.guess
fsf/trunk/libc/scripts/config.sub
fsf/trunk/libc/string/Makefile
fsf/trunk/libc/string/test-strcasestr.c
fsf/trunk/libc/string/test-strchr.c
fsf/trunk/libc/string/test-strstr.c
fsf/trunk/libc/sysdeps/mach/hurd/dl-sysdep.c
fsf/trunk/libc/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h
Modified: fsf/trunk/libc/ChangeLog
==============================================================================
--- fsf/trunk/libc/ChangeLog (original)
+++ fsf/trunk/libc/ChangeLog Sat Oct 6 00:01:47 2012
@@ -1,3 +1,69 @@
+2012-10-05 H.J. Lu <hongjiu.lu@xxxxxxxxx>
+
+ [BZ #14602]
+ * string/test-strstr.c (check2): New function.
+ (test_main): Call check2.
+
+ * string/Makefile (tests): Remove bug-strstr1, bug-strcasestr1
+ and bug-strchr1.
+ * string/bug-strcasestr1.c (do_test): Moved to ...
+ * string/test-strcasestr.c (check1): Here. New function.
+ (do_one_test): Break out result checking code into ...
+ (check_result): This. New function.
+ (do_one_test): Call check_result.
+ (test_main): Call check1.
+ * string/bug-strchr1.c (do_test): Moved to ...
+ * string/test-strchr.c (check1): Here. New function.
+ (do_one_test): Break out result checking code into ...
+ (check_result): This. New function.
+ (do_one_test): Call check_result.
+ (test_main): Call check1.
+ * string/bug-strstr1.c (main): Moved to ...
+ * string/test-strchr.c (check1): Here. New function.
+ (do_one_test): Break out result checking code into ...
+ (check_result): This. New function.
+ (do_one_test): Call check_result.
+ (test_main): Call check1.
+ * string/bug-strcasestr1.c: Removed.
+ * string/bug-strchr1.c: Likewise.
+ * string/bug-strstr1.c: Likewise.
+
+ * elf/Makefile (dl-routines): Add hwcaps.
+ * elf/dl-support.c (_dl_important_hwcaps): Removed.
+ * elf/dl-sysdep.c (_DL_FIRST_EXTRA): Likewise.
+ (_dl_important_hwcaps): Moved to ...
+ * elf/dl-hwcaps.c: Here. New file.
+ * sysdeps/mach/hurd/dl-sysdep.c (_dl_important_hwcaps): Removed.
+
+ [BZ #14557]
+ * elf/setup-vdso.h (setup_vdso): Set GL(dl_nns) to 1 for vDSO
+ if IS_IN_rtld isn't defined.
+
+ * elf/dl-support.c (_dl_sysinfo_map): New.
+ Include "get-dynamic-info.h" and "setup-vdso.h".
+ (_dl_non_dynamic_init): Call setup_vdso.
+ * elf/dynamic-link.h: Don't include <assert.h>.
+ (elf_get_dynamic_info): Moved to ...
+ * elf/get-dynamic-info.h: Here. New file.
+ * elf/dynamic-link.h: Include "get-dynamic-info.h".
+ * elf/rtld.c (dl_main): Break out vDSO setup code into ...
+ * elf/setup-vdso.h: Here. New file.
+ * elf/rtld.c: Include "setup-vdso.h".
+ (dl_main): Call setup_vdso.
+
+2012-10-05 Joseph Myers <joseph@xxxxxxxxxxxxxxxx>
+
+ * math/libm-test.inc: List nexttoward, cimag, clog10, conf and
+ creal in comment listing functions tested. List finite, isinf,
+ isnan, isless, islessequal, isgreater, isgreaterequal,
+ islessgreater, isunordered, lgamma_r and pow10 as functions and
+ macros not tested. Mention which functions not tested are aliases
+ for other functions. Fix typo. Note that signs of NaNs are not
+ tested.
+
+ * scripts/config.guess: Update from config.git.
+ * scripts/config.sub: Likewise.
+
2012-10-04 Roland McGrath <roland@xxxxxxxxxxxxx>
* misc/Versions (GLIBC_PRIVATE): New set, add __madvise.
Modified: fsf/trunk/libc/NEWS
==============================================================================
--- fsf/trunk/libc/NEWS (original)
+++ fsf/trunk/libc/NEWS Sat Oct 6 00:01:47 2012
@@ -12,10 +12,11 @@
1349, 3479, 5044, 5298, 5400, 6530, 6778, 6808, 9685, 9914, 10014,
10038, 10631, 11438, 11607, 13412, 13542, 13629, 13679, 13696, 13717,
13741, 13939, 13966, 14042, 14090, 14150, 14151, 14154, 14157, 14166,
- 14173, 14195, 14237, 14252, 14283, 14298, 14303, 14307, 14328, 14331,
- 14336, 14337, 14347, 14349, 14376, 14459, 14476, 14477, 14505, 14510,
- 14516, 14518, 14519, 14530, 14532, 14538, 14543, 14544, 14545, 14562,
- 14576, 14579, 14583, 14587, 14621, 14638, 14645, 14648.
+ 14173, 14195, 14237, 14251, 14252, 14283, 14298, 14303, 14307, 14328,
+ 14331, 14336, 14337, 14347, 14349, 14376, 14417, 14459, 14476, 14477,
+ 14505, 14510, 14516, 14518, 14519, 14530, 14532, 14538, 14543, 14544,
+ 14545, 14557, 14562, 14576, 14579, 14583, 14587, 14621, 14638, 14645,
+ 14648.
* Support for STT_GNU_IFUNC symbols added for s390 and s390x.
Optimized versions of memcpy, memset, and memcmp added for System z10 and
Modified: fsf/trunk/libc/elf/Makefile
==============================================================================
--- fsf/trunk/libc/elf/Makefile (original)
+++ fsf/trunk/libc/elf/Makefile Sat Oct 6 00:01:47 2012
@@ -28,7 +28,7 @@
# The core dynamic linking functions are in libc for the static and
# profiled libraries.
-dl-routines = $(addprefix dl-,load lookup object reloc deps \
+dl-routines = $(addprefix dl-,load lookup object reloc deps hwcaps \
runtime error init fini debug misc \
version profile conflict tls origin scope \
execstack caller open close trampoline)
Added: fsf/trunk/libc/elf/dl-hwcaps.c
==============================================================================
--- fsf/trunk/libc/elf/dl-hwcaps.c (added)
+++ fsf/trunk/libc/elf/dl-hwcaps.c Sat Oct 6 00:01:47 2012
@@ -1,0 +1,279 @@
+/* Hardware capability support for run-time dynamic loader.
+ Copyright (C) 2012 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <assert.h>
+#include <elf.h>
+#include <errno.h>
+#include <libintl.h>
+#include <unistd.h>
+#include <ldsodefs.h>
+
+#include <dl-procinfo.h>
+
+#ifdef _DL_FIRST_PLATFORM
+# define _DL_FIRST_EXTRA (_DL_FIRST_PLATFORM + _DL_PLATFORMS_COUNT)
+#else
+# define _DL_FIRST_EXTRA _DL_HWCAP_COUNT
+#endif
+
+/* Return an array of useful/necessary hardware capability names. */
+const struct r_strlenpair *
+internal_function
+_dl_important_hwcaps (const char *platform, size_t platform_len, size_t *sz,
+ size_t *max_capstrlen)
+{
+ /* Determine how many important bits are set. */
+ uint64_t masked = GLRO(dl_hwcap) & GLRO(dl_hwcap_mask);
+ size_t cnt = platform != NULL;
+ size_t n, m;
+ size_t total;
+ struct r_strlenpair *temp;
+ struct r_strlenpair *result;
+ struct r_strlenpair *rp;
+ char *cp;
+
+ /* Count the number of bits set in the masked value. */
+ for (n = 0; (~((1ULL << n) - 1) & masked) != 0; ++n)
+ if ((masked & (1ULL << n)) != 0)
+ ++cnt;
+
+#if defined NEED_DL_SYSINFO || defined NEED_DL_SYSINFO_DSO
+ /* The system-supplied DSO can contain a note of type 2, vendor "GNU".
+ This gives us a list of names to treat as fake hwcap bits. */
+
+ const char *dsocaps = NULL;
+ size_t dsocapslen = 0;
+ if (GLRO(dl_sysinfo_map) != NULL)
+ {
+ const ElfW(Phdr) *const phdr = GLRO(dl_sysinfo_map)->l_phdr;
+ const ElfW(Word) phnum = GLRO(dl_sysinfo_map)->l_phnum;
+ for (uint_fast16_t i = 0; i < phnum; ++i)
+ if (phdr[i].p_type == PT_NOTE)
+ {
+ const ElfW(Addr) start = (phdr[i].p_vaddr
+ + GLRO(dl_sysinfo_map)->l_addr);
+ const struct
+ {
+ ElfW(Word) vendorlen;
+ ElfW(Word) datalen;
+ ElfW(Word) type;
+ } *note = (const void *) start;
+ while ((ElfW(Addr)) (note + 1) - start < phdr[i].p_memsz)
+ {
+#define ROUND(len) (((len) + sizeof (ElfW(Word)) - 1) & -sizeof (ElfW(Word)))
+ if (note->type == NT_GNU_HWCAP
+ && note->vendorlen == sizeof "GNU"
+ && !memcmp ((note + 1), "GNU", sizeof "GNU")
+ && note->datalen > 2 * sizeof (ElfW(Word)) + 2)
+ {
+ const ElfW(Word) *p = ((const void *) (note + 1)
+ + ROUND (sizeof "GNU"));
+ cnt += *p++;
+ ++p; /* Skip mask word. */
+ dsocaps = (const char *) p;
+ dsocapslen = note->datalen - sizeof *p * 2;
+ break;
+ }
+ note = ((const void *) (note + 1)
+ + ROUND (note->vendorlen) + ROUND (note->datalen));
+#undef ROUND
+ }
+ if (dsocaps != NULL)
+ break;
+ }
+ }
+#endif
+
+ /* For TLS enabled builds always add 'tls'. */
+ ++cnt;
+
+ /* Create temporary data structure to generate result table. */
+ temp = (struct r_strlenpair *) alloca (cnt * sizeof (*temp));
+ m = 0;
+#if defined NEED_DL_SYSINFO || defined NEED_DL_SYSINFO_DSO
+ if (dsocaps != NULL)
+ {
+ const ElfW(Word) mask = ((const ElfW(Word) *) dsocaps)[-1];
+ GLRO(dl_hwcap) |= (uint64_t) mask << _DL_FIRST_EXTRA;
+ /* Note that we add the dsocaps to the set already chosen by the
+ LD_HWCAP_MASK environment variable (or default HWCAP_IMPORTANT).
+ So there is no way to request ignoring an OS-supplied dsocap
+ string and bit like you can ignore an OS-supplied HWCAP bit. */
+ GLRO(dl_hwcap_mask) |= (uint64_t) mask << _DL_FIRST_EXTRA;
+ size_t len;
+ for (const char *p = dsocaps; p < dsocaps + dsocapslen; p += len + 1)
+ {
+ uint_fast8_t bit = *p++;
+ len = strlen (p);
+
+ /* Skip entries that are not enabled in the mask word. */
+ if (__builtin_expect (mask & ((ElfW(Word)) 1 << bit), 1))
+ {
+ temp[m].str = p;
+ temp[m].len = len;
+ ++m;
+ }
+ else
+ --cnt;
+ }
+ }
+#endif
+ for (n = 0; masked != 0; ++n)
+ if ((masked & (1ULL << n)) != 0)
+ {
+ temp[m].str = _dl_hwcap_string (n);
+ temp[m].len = strlen (temp[m].str);
+ masked ^= 1ULL << n;
+ ++m;
+ }
+ if (platform != NULL)
+ {
+ temp[m].str = platform;
+ temp[m].len = platform_len;
+ ++m;
+ }
+
+ temp[m].str = "tls";
+ temp[m].len = 3;
+ ++m;
+
+ assert (m == cnt);
+
+ /* Determine the total size of all strings together. */
+ if (cnt == 1)
+ total = temp[0].len + 1;
+ else
+ {
+ 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
+ various combinations of capability names. */
+ *sz = 1 << cnt;
+ result = (struct r_strlenpair *) malloc (*sz * sizeof (*result) + total);
+ if (result == NULL)
+ _dl_signal_error (ENOMEM, NULL, NULL,
+ N_("cannot create capability list"));
+
+ if (cnt == 1)
+ {
+ result[0].str = (char *) (result + *sz);
+ result[0].len = temp[0].len + 1;
+ result[1].str = (char *) (result + *sz);
+ result[1].len = 0;
+ cp = __mempcpy ((char *) (result + *sz), temp[0].str, temp[0].len);
+ *cp = '/';
+ *sz = 2;
+ *max_capstrlen = result[0].len;
+
+ return result;
+ }
+
+ /* Fill in the information. This follows the following scheme
+ (indeces from TEMP for four strings):
+ entry #0: 0, 1, 2, 3 binary: 1111
+ #1: 0, 1, 3 1101
+ #2: 0, 2, 3 1011
+ #3: 0, 3 1001
+ This allows the representation of all possible combinations of
+ capability names in the string. First generate the strings. */
+ result[1].str = result[0].str = cp = (char *) (result + *sz);
+#define add(idx) \
+ cp = __mempcpy (__mempcpy (cp, temp[idx].str, temp[idx].len), "/", 1);
+ if (cnt == 2)
+ {
+ add (1);
+ add (0);
+ }
+ else
+ {
+ n = 1 << (cnt - 1);
+ do
+ {
+ n -= 2;
+
+ /* We always add the last string. */
+ add (cnt - 1);
+
+ /* Add the strings which have the bit set in N. */
+ for (m = cnt - 2; m > 0; --m)
+ if ((n & (1 << m)) != 0)
+ add (m);
+
+ /* Always add the first string. */
+ add (0);
+ }
+ while (n != 0);
+ }
+#undef add
+
+ /* Now we are ready to install the string pointers and length. */
+ for (n = 0; n < (1UL << cnt); ++n)
+ result[n].len = 0;
+ n = cnt;
+ do
+ {
+ size_t mask = 1 << --n;
+
+ rp = result;
+ for (m = 1 << cnt; m > 0; ++rp)
+ if ((--m & mask) != 0)
+ rp->len += temp[n].len + 1;
+ }
+ while (n != 0);
+
+ /* The first half of the strings all include the first string. */
+ n = (1 << cnt) - 2;
+ rp = &result[2];
+ while (n != (1UL << (cnt - 1)))
+ {
+ if ((--n & 1) != 0)
+ rp[0].str = rp[-2].str + rp[-2].len;
+ else
+ rp[0].str = rp[-1].str;
+ ++rp;
+ }
+
+ /* The second half starts right after the first part of the string of
+ the corresponding entry in the first half. */
+ do
+ {
+ rp[0].str = rp[-(1 << (cnt - 1))].str + temp[cnt - 1].len + 1;
+ ++rp;
+ }
+ while (--n != 0);
+
+ /* The maximum string length. */
+ *max_capstrlen = result[0].len;
+
+ return result;
+}
Modified: fsf/trunk/libc/elf/dl-support.c
==============================================================================
--- fsf/trunk/libc/elf/dl-support.c (original)
+++ fsf/trunk/libc/elf/dl-support.c Sat Oct 6 00:01:47 2012
@@ -161,6 +161,11 @@
#if defined NEED_DL_SYSINFO || defined NEED_DL_SYSINFO_DSO
/* Address of the ELF headers in the vsyscall page. */
const ElfW(Ehdr) *_dl_sysinfo_dso;
+
+struct link_map *_dl_sysinfo_map;
+
+# include "get-dynamic-info.h"
+# include "setup-vdso.h"
#endif
/* During the program run we must not modify the global data of
@@ -266,6 +271,10 @@
_dl_verbose = *(getenv ("LD_WARN") ?: "") == '\0' ? 0 : 1;
+ /* Set up the data structures for the system-supplied DSO early,
+ so they can influence _dl_init_paths. */
+ setup_vdso (NULL, NULL);
+
/* Initialize the data structures for the search paths for shared
objects. */
_dl_init_paths (getenv ("LD_LIBRARY_PATH"));
@@ -326,23 +335,6 @@
}
}
-
-const struct r_strlenpair *
-internal_function
-_dl_important_hwcaps (const char *platform, size_t platform_len, size_t *sz,
- size_t *max_capstrlen)
-{
- static struct r_strlenpair result;
- static char buf[1];
-
- result.str = buf; /* Does not really matter. */
- result.len = 0;
-
- *sz = 1;
- return &result;
-}
-
-
#ifdef DL_SYSINFO_IMPLEMENTATION
DL_SYSINFO_IMPLEMENTATION
#endif
Modified: fsf/trunk/libc/elf/dl-sysdep.c
==============================================================================
--- fsf/trunk/libc/elf/dl-sysdep.c (original)
+++ fsf/trunk/libc/elf/dl-sysdep.c Sat Oct 6 00:01:47 2012
@@ -43,12 +43,6 @@
#include <dl-osinfo.h>
#include <hp-timing.h>
#include <tls.h>
-
-#ifdef _DL_FIRST_PLATFORM
-# define _DL_FIRST_EXTRA (_DL_FIRST_PLATFORM + _DL_PLATFORMS_COUNT)
-#else
-# define _DL_FIRST_EXTRA _DL_HWCAP_COUNT
-#endif
extern char **_environ attribute_hidden;
extern char _end[] attribute_hidden;
@@ -350,252 +344,4 @@
}
}
-
-/* Return an array of useful/necessary hardware capability names. */
-const struct r_strlenpair *
-internal_function
-_dl_important_hwcaps (const char *platform, size_t platform_len, size_t *sz,
- size_t *max_capstrlen)
-{
- /* Determine how many important bits are set. */
- uint64_t masked = GLRO(dl_hwcap) & GLRO(dl_hwcap_mask);
- size_t cnt = platform != NULL;
- size_t n, m;
- size_t total;
- struct r_strlenpair *temp;
- struct r_strlenpair *result;
- struct r_strlenpair *rp;
- char *cp;
-
- /* Count the number of bits set in the masked value. */
- for (n = 0; (~((1ULL << n) - 1) & masked) != 0; ++n)
- if ((masked & (1ULL << n)) != 0)
- ++cnt;
-
-#if (defined NEED_DL_SYSINFO || defined NEED_DL_SYSINFO_DSO) && defined SHARED
- /* The system-supplied DSO can contain a note of type 2, vendor "GNU".
- This gives us a list of names to treat as fake hwcap bits. */
-
- const char *dsocaps = NULL;
- size_t dsocapslen = 0;
- if (GLRO(dl_sysinfo_map) != NULL)
- {
- const ElfW(Phdr) *const phdr = GLRO(dl_sysinfo_map)->l_phdr;
- const ElfW(Word) phnum = GLRO(dl_sysinfo_map)->l_phnum;
- for (uint_fast16_t i = 0; i < phnum; ++i)
- if (phdr[i].p_type == PT_NOTE)
- {
- const ElfW(Addr) start = (phdr[i].p_vaddr
- + GLRO(dl_sysinfo_map)->l_addr);
- const struct
- {
- ElfW(Word) vendorlen;
- ElfW(Word) datalen;
- ElfW(Word) type;
- } *note = (const void *) start;
- while ((ElfW(Addr)) (note + 1) - start < phdr[i].p_memsz)
- {
-#define ROUND(len) (((len) + sizeof (ElfW(Word)) - 1) & -sizeof (ElfW(Word)))
- if (note->type == NT_GNU_HWCAP
- && note->vendorlen == sizeof "GNU"
- && !memcmp ((note + 1), "GNU", sizeof "GNU")
- && note->datalen > 2 * sizeof (ElfW(Word)) + 2)
- {
- const ElfW(Word) *p = ((const void *) (note + 1)
- + ROUND (sizeof "GNU"));
- cnt += *p++;
- ++p; /* Skip mask word. */
- dsocaps = (const char *) p;
- dsocapslen = note->datalen - sizeof *p * 2;
- break;
- }
- note = ((const void *) (note + 1)
- + ROUND (note->vendorlen) + ROUND (note->datalen));
-#undef ROUND
- }
- if (dsocaps != NULL)
- break;
- }
- }
-#endif
-
- /* For TLS enabled builds always add 'tls'. */
- ++cnt;
-
- /* Create temporary data structure to generate result table. */
- temp = (struct r_strlenpair *) alloca (cnt * sizeof (*temp));
- m = 0;
-#if (defined NEED_DL_SYSINFO || defined NEED_DL_SYSINFO_DSO) && defined SHARED
- if (dsocaps != NULL)
- {
- const ElfW(Word) mask = ((const ElfW(Word) *) dsocaps)[-1];
- GLRO(dl_hwcap) |= (uint64_t) mask << _DL_FIRST_EXTRA;
- /* Note that we add the dsocaps to the set already chosen by the
- LD_HWCAP_MASK environment variable (or default HWCAP_IMPORTANT).
- So there is no way to request ignoring an OS-supplied dsocap
- string and bit like you can ignore an OS-supplied HWCAP bit. */
- GLRO(dl_hwcap_mask) |= (uint64_t) mask << _DL_FIRST_EXTRA;
- size_t len;
- for (const char *p = dsocaps; p < dsocaps + dsocapslen; p += len + 1)
- {
- uint_fast8_t bit = *p++;
- len = strlen (p);
-
- /* Skip entries that are not enabled in the mask word. */
- if (__builtin_expect (mask & ((ElfW(Word)) 1 << bit), 1))
- {
- temp[m].str = p;
- temp[m].len = len;
- ++m;
- }
- else
- --cnt;
- }
- }
-#endif
- for (n = 0; masked != 0; ++n)
- if ((masked & (1ULL << n)) != 0)
- {
- temp[m].str = _dl_hwcap_string (n);
- temp[m].len = strlen (temp[m].str);
- masked ^= 1ULL << n;
- ++m;
- }
- if (platform != NULL)
- {
- temp[m].str = platform;
- temp[m].len = platform_len;
- ++m;
- }
-
- temp[m].str = "tls";
- temp[m].len = 3;
- ++m;
-
- assert (m == cnt);
-
- /* Determine the total size of all strings together. */
- if (cnt == 1)
- total = temp[0].len + 1;
- else
- {
- 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
- various combinations of capability names. */
- *sz = 1 << cnt;
- result = (struct r_strlenpair *) malloc (*sz * sizeof (*result) + total);
- if (result == NULL)
- _dl_signal_error (ENOMEM, NULL, NULL,
- N_("cannot create capability list"));
-
- if (cnt == 1)
- {
- result[0].str = (char *) (result + *sz);
- result[0].len = temp[0].len + 1;
- result[1].str = (char *) (result + *sz);
- result[1].len = 0;
- cp = __mempcpy ((char *) (result + *sz), temp[0].str, temp[0].len);
- *cp = '/';
- *sz = 2;
- *max_capstrlen = result[0].len;
-
- return result;
- }
-
- /* Fill in the information. This follows the following scheme
- (indeces from TEMP for four strings):
- entry #0: 0, 1, 2, 3 binary: 1111
- #1: 0, 1, 3 1101
- #2: 0, 2, 3 1011
- #3: 0, 3 1001
- This allows the representation of all possible combinations of
- capability names in the string. First generate the strings. */
- result[1].str = result[0].str = cp = (char *) (result + *sz);
-#define add(idx) \
- cp = __mempcpy (__mempcpy (cp, temp[idx].str, temp[idx].len), "/", 1);
- if (cnt == 2)
- {
- add (1);
- add (0);
- }
- else
- {
- n = 1 << (cnt - 1);
- do
- {
- n -= 2;
-
- /* We always add the last string. */
- add (cnt - 1);
-
- /* Add the strings which have the bit set in N. */
- for (m = cnt - 2; m > 0; --m)
- if ((n & (1 << m)) != 0)
- add (m);
-
- /* Always add the first string. */
- add (0);
- }
- while (n != 0);
- }
-#undef add
-
- /* Now we are ready to install the string pointers and length. */
- for (n = 0; n < (1UL << cnt); ++n)
- result[n].len = 0;
- n = cnt;
- do
- {
- size_t mask = 1 << --n;
-
- rp = result;
- for (m = 1 << cnt; m > 0; ++rp)
- if ((--m & mask) != 0)
- rp->len += temp[n].len + 1;
- }
- while (n != 0);
-
- /* The first half of the strings all include the first string. */
- n = (1 << cnt) - 2;
- rp = &result[2];
- while (n != (1UL << (cnt - 1)))
- {
- if ((--n & 1) != 0)
- rp[0].str = rp[-2].str + rp[-2].len;
- else
- rp[0].str = rp[-1].str;
- ++rp;
- }
-
- /* The second half starts right after the first part of the string of
- the corresponding entry in the first half. */
- do
- {
- rp[0].str = rp[-(1 << (cnt - 1))].str + temp[cnt - 1].len + 1;
- ++rp;
- }
- while (--n != 0);
-
- /* The maximum string length. */
- *max_capstrlen = result[0].len;
-
- return result;
-}
-
-#endif
+#endif
Modified: fsf/trunk/libc/elf/dynamic-link.h
==============================================================================
--- fsf/trunk/libc/elf/dynamic-link.h (original)
+++ fsf/trunk/libc/elf/dynamic-link.h Sat Oct 6 00:01:47 2012
@@ -42,7 +42,6 @@
int internal_function _dl_try_allocate_static_tls (struct link_map *map);
#include <elf.h>
-#include <assert.h>
#ifdef RESOLVE_MAP
/* We pass reloc_addr as a pointer to void, as opposed to a pointer to
@@ -88,149 +87,7 @@
#include <dl-machine.h>
-
-/* Read the dynamic section at DYN and fill in INFO with indices DT_*. */
-#ifndef RESOLVE_MAP
-static
-#else
-auto
-#endif
-inline void __attribute__ ((unused, always_inline))
-elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
-{
- ElfW(Dyn) *dyn = l->l_ld;
- ElfW(Dyn) **info;
-#if __ELF_NATIVE_CLASS == 32
- typedef Elf32_Word d_tag_utype;
-#elif __ELF_NATIVE_CLASS == 64
- typedef Elf64_Xword d_tag_utype;
-#endif
-
-#ifndef RTLD_BOOTSTRAP
- if (dyn == NULL)
- return;
-#endif
-
- info = l->l_info;
-
- while (dyn->d_tag != DT_NULL)
- {
- if ((d_tag_utype) dyn->d_tag < DT_NUM)
- info[dyn->d_tag] = dyn;
- else if (dyn->d_tag >= DT_LOPROC &&
- dyn->d_tag < DT_LOPROC + DT_THISPROCNUM)
- info[dyn->d_tag - DT_LOPROC + DT_NUM] = dyn;
- else if ((d_tag_utype) DT_VERSIONTAGIDX (dyn->d_tag) < DT_VERSIONTAGNUM)
- info[VERSYMIDX (dyn->d_tag)] = dyn;
- else if ((d_tag_utype) DT_EXTRATAGIDX (dyn->d_tag) < DT_EXTRANUM)
- info[DT_EXTRATAGIDX (dyn->d_tag) + DT_NUM + DT_THISPROCNUM
- + DT_VERSIONTAGNUM] = dyn;
- else if ((d_tag_utype) DT_VALTAGIDX (dyn->d_tag) < DT_VALNUM)
- info[DT_VALTAGIDX (dyn->d_tag) + DT_NUM + DT_THISPROCNUM
- + DT_VERSIONTAGNUM + DT_EXTRANUM] = dyn;
- else if ((d_tag_utype) DT_ADDRTAGIDX (dyn->d_tag) < DT_ADDRNUM)
- info[DT_ADDRTAGIDX (dyn->d_tag) + DT_NUM + DT_THISPROCNUM
- + DT_VERSIONTAGNUM + DT_EXTRANUM + DT_VALNUM] = dyn;
- ++dyn;
- }
-
-#define DL_RO_DYN_TEMP_CNT 8
-
-#ifndef DL_RO_DYN_SECTION
- /* Don't adjust .dynamic unnecessarily. */
- if (l->l_addr != 0)
- {
- ElfW(Addr) l_addr = l->l_addr;
- int cnt = 0;
-
-# define ADJUST_DYN_INFO(tag) \
- do \
- if (info[tag] != NULL) \
- { \
- if (temp) \
- { \
- temp[cnt].d_tag = info[tag]->d_tag; \
- temp[cnt].d_un.d_ptr = info[tag]->d_un.d_ptr + l_addr; \
- info[tag] = temp + cnt++; \
- } \
- else \
- info[tag]->d_un.d_ptr += l_addr; \
- } \
- while (0)
-
- ADJUST_DYN_INFO (DT_HASH);
- ADJUST_DYN_INFO (DT_PLTGOT);
- ADJUST_DYN_INFO (DT_STRTAB);
- ADJUST_DYN_INFO (DT_SYMTAB);
-# if ! ELF_MACHINE_NO_RELA
- ADJUST_DYN_INFO (DT_RELA);
-# endif
-# if ! ELF_MACHINE_NO_REL
- ADJUST_DYN_INFO (DT_REL);
-# endif
- ADJUST_DYN_INFO (DT_JMPREL);
- ADJUST_DYN_INFO (VERSYMIDX (DT_VERSYM));
- ADJUST_DYN_INFO (DT_ADDRTAGIDX (DT_GNU_HASH) + DT_NUM + DT_THISPROCNUM
- + DT_VERSIONTAGNUM + DT_EXTRANUM + DT_VALNUM);
-# undef ADJUST_DYN_INFO
- assert (cnt <= DL_RO_DYN_TEMP_CNT);
- }
-#endif
- if (info[DT_PLTREL] != NULL)
- {
-#if ELF_MACHINE_NO_RELA
- assert (info[DT_PLTREL]->d_un.d_val == DT_REL);
-#elif ELF_MACHINE_NO_REL
- assert (info[DT_PLTREL]->d_un.d_val == DT_RELA);
-#else
- assert (info[DT_PLTREL]->d_un.d_val == DT_REL
- || info[DT_PLTREL]->d_un.d_val == DT_RELA);
-#endif
- }
-#if ! ELF_MACHINE_NO_RELA
- if (info[DT_RELA] != NULL)
- assert (info[DT_RELAENT]->d_un.d_val == sizeof (ElfW(Rela)));
-# endif
-# if ! ELF_MACHINE_NO_REL
- if (info[DT_REL] != NULL)
- assert (info[DT_RELENT]->d_un.d_val == sizeof (ElfW(Rel)));
-#endif
-#ifdef RTLD_BOOTSTRAP
- /* Only the bind now flags are allowed. */
- assert (info[VERSYMIDX (DT_FLAGS_1)] == NULL
- || (info[VERSYMIDX (DT_FLAGS_1)]->d_un.d_val & ~DF_1_NOW) == 0);
- assert (info[DT_FLAGS] == NULL
- || (info[DT_FLAGS]->d_un.d_val & ~DF_BIND_NOW) == 0);
- /* Flags must not be set for ld.so. */
- assert (info[DT_RUNPATH] == NULL);
- assert (info[DT_RPATH] == NULL);
-#else
- if (info[DT_FLAGS] != NULL)
- {
- /* Flags are used. Translate to the old form where available.
- Since these l_info entries are only tested for NULL pointers it
- is ok if they point to the DT_FLAGS entry. */
- l->l_flags = info[DT_FLAGS]->d_un.d_val;
-
- if (l->l_flags & DF_SYMBOLIC)
- info[DT_SYMBOLIC] = info[DT_FLAGS];
- if (l->l_flags & DF_TEXTREL)
- info[DT_TEXTREL] = info[DT_FLAGS];
- if (l->l_flags & DF_BIND_NOW)
- info[DT_BIND_NOW] = info[DT_FLAGS];
- }
- if (info[VERSYMIDX (DT_FLAGS_1)] != NULL)
- {
- l->l_flags_1 = info[VERSYMIDX (DT_FLAGS_1)]->d_un.d_val;
-
- if (l->l_flags_1 & DF_1_NOW)
- info[DT_BIND_NOW] = info[VERSYMIDX (DT_FLAGS_1)];
- }
- if (info[DT_RUNPATH] != NULL)
- /* If both RUNPATH and RPATH are given, the latter is ignored. */
- info[DT_RPATH] = NULL;
-#endif
-}
+#include "get-dynamic-info.h"
#ifdef RESOLVE_MAP
Added: fsf/trunk/libc/elf/get-dynamic-info.h
==============================================================================
--- fsf/trunk/libc/elf/get-dynamic-info.h (added)
+++ fsf/trunk/libc/elf/get-dynamic-info.h Sat Oct 6 00:01:47 2012
@@ -1,0 +1,161 @@
+/* Read the dynamic section at DYN and fill in INFO with indices DT_*.
+ Copyright (C) 2012 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <assert.h>
+
+#ifndef RESOLVE_MAP
+static
+#else
+auto
+#endif
+inline void __attribute__ ((unused, always_inline))
+elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
+{
+ ElfW(Dyn) *dyn = l->l_ld;
+ ElfW(Dyn) **info;
+#if __ELF_NATIVE_CLASS == 32
+ typedef Elf32_Word d_tag_utype;
+#elif __ELF_NATIVE_CLASS == 64
+ typedef Elf64_Xword d_tag_utype;
+#endif
+
+#ifndef RTLD_BOOTSTRAP
+ if (dyn == NULL)
+ return;
+#endif
+
+ info = l->l_info;
+
+ while (dyn->d_tag != DT_NULL)
+ {
+ if ((d_tag_utype) dyn->d_tag < DT_NUM)
+ info[dyn->d_tag] = dyn;
+ else if (dyn->d_tag >= DT_LOPROC &&
+ dyn->d_tag < DT_LOPROC + DT_THISPROCNUM)
+ info[dyn->d_tag - DT_LOPROC + DT_NUM] = dyn;
+ else if ((d_tag_utype) DT_VERSIONTAGIDX (dyn->d_tag) < DT_VERSIONTAGNUM)
+ info[VERSYMIDX (dyn->d_tag)] = dyn;
+ else if ((d_tag_utype) DT_EXTRATAGIDX (dyn->d_tag) < DT_EXTRANUM)
+ info[DT_EXTRATAGIDX (dyn->d_tag) + DT_NUM + DT_THISPROCNUM
+ + DT_VERSIONTAGNUM] = dyn;
+ else if ((d_tag_utype) DT_VALTAGIDX (dyn->d_tag) < DT_VALNUM)
+ info[DT_VALTAGIDX (dyn->d_tag) + DT_NUM + DT_THISPROCNUM
+ + DT_VERSIONTAGNUM + DT_EXTRANUM] = dyn;
+ else if ((d_tag_utype) DT_ADDRTAGIDX (dyn->d_tag) < DT_ADDRNUM)
+ info[DT_ADDRTAGIDX (dyn->d_tag) + DT_NUM + DT_THISPROCNUM
+ + DT_VERSIONTAGNUM + DT_EXTRANUM + DT_VALNUM] = dyn;
+ ++dyn;
+ }
+
+#define DL_RO_DYN_TEMP_CNT 8
+
+#ifndef DL_RO_DYN_SECTION
+ /* Don't adjust .dynamic unnecessarily. */
+ if (l->l_addr != 0)
+ {
+ ElfW(Addr) l_addr = l->l_addr;
+ int cnt = 0;
+
+# define ADJUST_DYN_INFO(tag) \
+ do \
+ if (info[tag] != NULL) \
+ { \
+ if (temp) \
+ { \
+ temp[cnt].d_tag = info[tag]->d_tag; \
+ temp[cnt].d_un.d_ptr = info[tag]->d_un.d_ptr + l_addr; \
+ info[tag] = temp + cnt++; \
+ } \
+ else \
+ info[tag]->d_un.d_ptr += l_addr; \
+ } \
+ while (0)
+
+ ADJUST_DYN_INFO (DT_HASH);
+ ADJUST_DYN_INFO (DT_PLTGOT);
+ ADJUST_DYN_INFO (DT_STRTAB);
+ ADJUST_DYN_INFO (DT_SYMTAB);
+# if ! ELF_MACHINE_NO_RELA
+ ADJUST_DYN_INFO (DT_RELA);
+# endif
+# if ! ELF_MACHINE_NO_REL
+ ADJUST_DYN_INFO (DT_REL);
+# endif
+ ADJUST_DYN_INFO (DT_JMPREL);
+ ADJUST_DYN_INFO (VERSYMIDX (DT_VERSYM));
+ ADJUST_DYN_INFO (DT_ADDRTAGIDX (DT_GNU_HASH) + DT_NUM + DT_THISPROCNUM
+ + DT_VERSIONTAGNUM + DT_EXTRANUM + DT_VALNUM);
+# undef ADJUST_DYN_INFO
+ assert (cnt <= DL_RO_DYN_TEMP_CNT);
+ }
+#endif
+ if (info[DT_PLTREL] != NULL)
+ {
+#if ELF_MACHINE_NO_RELA
+ assert (info[DT_PLTREL]->d_un.d_val == DT_REL);
+#elif ELF_MACHINE_NO_REL
+ assert (info[DT_PLTREL]->d_un.d_val == DT_RELA);
+#else
+ assert (info[DT_PLTREL]->d_un.d_val == DT_REL
+ || info[DT_PLTREL]->d_un.d_val == DT_RELA);
+#endif
+ }
+#if ! ELF_MACHINE_NO_RELA
+ if (info[DT_RELA] != NULL)
+ assert (info[DT_RELAENT]->d_un.d_val == sizeof (ElfW(Rela)));
+# endif
+# if ! ELF_MACHINE_NO_REL
+ if (info[DT_REL] != NULL)
+ assert (info[DT_RELENT]->d_un.d_val == sizeof (ElfW(Rel)));
+#endif
+#ifdef RTLD_BOOTSTRAP
+ /* Only the bind now flags are allowed. */
+ assert (info[VERSYMIDX (DT_FLAGS_1)] == NULL
+ || (info[VERSYMIDX (DT_FLAGS_1)]->d_un.d_val & ~DF_1_NOW) == 0);
+ assert (info[DT_FLAGS] == NULL
+ || (info[DT_FLAGS]->d_un.d_val & ~DF_BIND_NOW) == 0);
+ /* Flags must not be set for ld.so. */
+ assert (info[DT_RUNPATH] == NULL);
+ assert (info[DT_RPATH] == NULL);
+#else
+ if (info[DT_FLAGS] != NULL)
+ {
+ /* Flags are used. Translate to the old form where available.
+ Since these l_info entries are only tested for NULL pointers it
+ is ok if they point to the DT_FLAGS entry. */
+ l->l_flags = info[DT_FLAGS]->d_un.d_val;
+
+ if (l->l_flags & DF_SYMBOLIC)
+ info[DT_SYMBOLIC] = info[DT_FLAGS];
+ if (l->l_flags & DF_TEXTREL)
+ info[DT_TEXTREL] = info[DT_FLAGS];
+ if (l->l_flags & DF_BIND_NOW)
+ info[DT_BIND_NOW] = info[DT_FLAGS];
+ }
+ if (info[VERSYMIDX (DT_FLAGS_1)] != NULL)
+ {
+ l->l_flags_1 = info[VERSYMIDX (DT_FLAGS_1)]->d_un.d_val;
+
+ if (l->l_flags_1 & DF_1_NOW)
+ info[DT_BIND_NOW] = info[VERSYMIDX (DT_FLAGS_1)];
+ }
+ if (info[DT_RUNPATH] != NULL)
+ /* If both RUNPATH and RPATH are given, the latter is ignored. */
+ info[DT_RPATH] = NULL;
+#endif
+}
Modified: fsf/trunk/libc/elf/rtld.c
==============================================================================
--- fsf/trunk/libc/elf/rtld.c (original)
+++ fsf/trunk/libc/elf/rtld.c Sat Oct 6 00:01:47 2012
@@ -873,6 +873,7 @@
_dl_random = NULL;
}
+#include "setup-vdso.h"
/* The library search path. */
static const char *library_path attribute_relro;
@@ -1329,102 +1330,9 @@
}
struct link_map **first_preload = &GL(dl_rtld_map).l_next;
-#if defined NEED_DL_SYSINFO || defined NEED_DL_SYSINFO_DSO
/* Set up the data structures for the system-supplied DSO early,
so they can influence _dl_init_paths. */
- if (GLRO(dl_sysinfo_dso) != NULL)
- {
- /* Do an abridged version of the work _dl_map_object_from_fd would do
- to map in the object. It's already mapped and prelinked (and
- better be, since it's read-only and so we couldn't relocate it).
- We just want our data structures to describe it as if we had just
- mapped and relocated it normally. */
- struct link_map *l = _dl_new_object ((char *) "", "", lt_library, NULL,
- 0, LM_ID_BASE);
- if (__builtin_expect (l != NULL, 1))
- {
- static ElfW(Dyn) dyn_temp[DL_RO_DYN_TEMP_CNT] attribute_relro;
-
- l->l_phdr = ((const void *) GLRO(dl_sysinfo_dso)
- + GLRO(dl_sysinfo_dso)->e_phoff);
- l->l_phnum = GLRO(dl_sysinfo_dso)->e_phnum;
- for (uint_fast16_t i = 0; i < l->l_phnum; ++i)
- {
- const ElfW(Phdr) *const ph = &l->l_phdr[i];
- if (ph->p_type == PT_DYNAMIC)
- {
- l->l_ld = (void *) ph->p_vaddr;
- l->l_ldnum = ph->p_memsz / sizeof (ElfW(Dyn));
- }
- else if (ph->p_type == PT_LOAD)
- {
- if (! l->l_addr)
- l->l_addr = ph->p_vaddr;
- if (ph->p_vaddr + ph->p_memsz >= l->l_map_end)
- l->l_map_end = ph->p_vaddr + ph->p_memsz;
- if ((ph->p_flags & PF_X)
- && ph->p_vaddr + ph->p_memsz >= l->l_text_end)
- l->l_text_end = ph->p_vaddr + ph->p_memsz;
- }
- else
- /* There must be no TLS segment. */
- assert (ph->p_type != PT_TLS);
- }
- l->l_map_start = (ElfW(Addr)) GLRO(dl_sysinfo_dso);
- l->l_addr = l->l_map_start - l->l_addr;
- l->l_map_end += l->l_addr;
- l->l_text_end += l->l_addr;
- l->l_ld = (void *) ((ElfW(Addr)) l->l_ld + l->l_addr);
- elf_get_dynamic_info (l, dyn_temp);
- _dl_setup_hash (l);
- l->l_relocated = 1;
-
- /* The vDSO is always used. */
- l->l_used = 1;
-
- /* Initialize l_local_scope to contain just this map. This allows
- the use of dl_lookup_symbol_x to resolve symbols within the vdso.
- So we create a single entry list pointing to l_real as its only
- element */
- l->l_local_scope[0]->r_nlist = 1;
- l->l_local_scope[0]->r_list = &l->l_real;
-
- /* Now that we have the info handy, use the DSO image's soname
- so this object can be looked up by name. Note that we do not
- set l_name here. That field gives the file name of the DSO,
- and this DSO is not associated with any file. */
- if (l->l_info[DT_SONAME] != NULL)
- {
- /* Work around a kernel problem. The kernel cannot handle
- addresses in the vsyscall DSO pages in writev() calls. */
- const char *dsoname = ((char *) D_PTR (l, l_info[DT_STRTAB])
- + l->l_info[DT_SONAME]->d_un.d_val);
- size_t len = strlen (dsoname);
- char *copy = malloc (len);
- if (copy == NULL)
- _dl_fatal_printf ("out of memory\n");
- l->l_libname->name = l->l_name = memcpy (copy, dsoname, len);
- }
-
- /* Add the vDSO to the object list. */
- _dl_add_to_namespace_list (l, LM_ID_BASE);
-
- /* Rearrange the list so this DSO appears after rtld_map. */
- assert (l->l_next == NULL);
- assert (l->l_prev == main_map);
- GL(dl_rtld_map).l_next = l;
- l->l_prev = &GL(dl_rtld_map);
- first_preload = &l->l_next;
-
- /* We have a prelinked DSO preloaded by the system. */
- GLRO(dl_sysinfo_map) = l;
-# ifdef NEED_DL_SYSINFO
- if (GLRO(dl_sysinfo) == DL_SYSINFO_DEFAULT)
- GLRO(dl_sysinfo) = GLRO(dl_sysinfo_dso)->e_entry + l->l_addr;
-# endif
- }
- }
-#endif
+ setup_vdso (main_map, &first_preload);
#ifdef DL_SYSDEP_OSCHECK
DL_SYSDEP_OSCHECK (_dl_fatal_printf);
Added: fsf/trunk/libc/elf/setup-vdso.h
==============================================================================
--- fsf/trunk/libc/elf/setup-vdso.h (added)
+++ fsf/trunk/libc/elf/setup-vdso.h Sat Oct 6 00:01:47 2012
@@ -1,0 +1,121 @@
+/* Set up the data structures for the system-supplied DSO.
+ Copyright (C) 2012 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, see
+ <http://www.gnu.org/licenses/>. */
+
+static inline void __attribute__ ((always_inline))
+setup_vdso (struct link_map *main_map __attribute__ ((unused)),
+ struct link_map ***first_preload __attribute__ ((unused)))
+{
+#if defined NEED_DL_SYSINFO || defined NEED_DL_SYSINFO_DSO
+ if (GLRO(dl_sysinfo_dso) == NULL)
+ return;
+
+ /* Do an abridged version of the work _dl_map_object_from_fd would do
+ to map in the object. It's already mapped and prelinked (and
+ better be, since it's read-only and so we couldn't relocate it).
+ We just want our data structures to describe it as if we had just
+ mapped and relocated it normally. */
+ struct link_map *l = _dl_new_object ((char *) "", "", lt_library, NULL,
+ 0, LM_ID_BASE);
+ if (__builtin_expect (l != NULL, 1))
+ {
+ static ElfW(Dyn) dyn_temp[DL_RO_DYN_TEMP_CNT] attribute_relro;
+
+ l->l_phdr = ((const void *) GLRO(dl_sysinfo_dso)
+ + GLRO(dl_sysinfo_dso)->e_phoff);
+ l->l_phnum = GLRO(dl_sysinfo_dso)->e_phnum;
+ for (uint_fast16_t i = 0; i < l->l_phnum; ++i)
+ {
+ const ElfW(Phdr) *const ph = &l->l_phdr[i];
+ if (ph->p_type == PT_DYNAMIC)
+ {
+ l->l_ld = (void *) ph->p_vaddr;
+ l->l_ldnum = ph->p_memsz / sizeof (ElfW(Dyn));
+ }
+ else if (ph->p_type == PT_LOAD)
+ {
+ if (! l->l_addr)
+ l->l_addr = ph->p_vaddr;
+ if (ph->p_vaddr + ph->p_memsz >= l->l_map_end)
+ l->l_map_end = ph->p_vaddr + ph->p_memsz;
+ if ((ph->p_flags & PF_X)
+ && ph->p_vaddr + ph->p_memsz >= l->l_text_end)
+ l->l_text_end = ph->p_vaddr + ph->p_memsz;
+ }
+ else
+ /* There must be no TLS segment. */
+ assert (ph->p_type != PT_TLS);
+ }
+ l->l_map_start = (ElfW(Addr)) GLRO(dl_sysinfo_dso);
+ l->l_addr = l->l_map_start - l->l_addr;
+ l->l_map_end += l->l_addr;
+ l->l_text_end += l->l_addr;
+ l->l_ld = (void *) ((ElfW(Addr)) l->l_ld + l->l_addr);
+ elf_get_dynamic_info (l, dyn_temp);
+ _dl_setup_hash (l);
+ l->l_relocated = 1;
+
+ /* The vDSO is always used. */
+ l->l_used = 1;
+
+ /* Initialize l_local_scope to contain just this map. This allows
+ the use of dl_lookup_symbol_x to resolve symbols within the vdso.
+ So we create a single entry list pointing to l_real as its only
+ element */
+ l->l_local_scope[0]->r_nlist = 1;
+ l->l_local_scope[0]->r_list = &l->l_real;
+
+ /* Now that we have the info handy, use the DSO image's soname
+ so this object can be looked up by name. Note that we do not
+ set l_name here. That field gives the file name of the DSO,
+ and this DSO is not associated with any file. */
+ if (l->l_info[DT_SONAME] != NULL)
+ {
+ /* Work around a kernel problem. The kernel cannot handle
+ addresses in the vsyscall DSO pages in writev() calls. */
+ const char *dsoname = ((char *) D_PTR (l, l_info[DT_STRTAB])
+ + l->l_info[DT_SONAME]->d_un.d_val);
+ size_t len = strlen (dsoname);
+ char *copy = malloc (len);
+ if (copy == NULL)
+ _dl_fatal_printf ("out of memory\n");
+ l->l_libname->name = l->l_name = memcpy (copy, dsoname, len);
+ }
+
+ /* Add the vDSO to the object list. */
+ _dl_add_to_namespace_list (l, LM_ID_BASE);
+
+# ifdef IS_IN_rtld
+ /* Rearrange the list so this DSO appears after rtld_map. */
+ assert (l->l_next == NULL);
+ assert (l->l_prev == main_map);
+ GL(dl_rtld_map).l_next = l;
+ l->l_prev = &GL(dl_rtld_map);
+ *first_preload = &l->l_next;
+# else
+ GL(dl_nns) = 1;
+# endif
+
+ /* We have a prelinked DSO preloaded by the system. */
+ GLRO(dl_sysinfo_map) = l;
+# ifdef NEED_DL_SYSINFO
+ if (GLRO(dl_sysinfo) == DL_SYSINFO_DEFAULT)
+ GLRO(dl_sysinfo) = GLRO(dl_sysinfo_dso)->e_entry + l->l_addr;
+# endif
+ }
+#endif
+}
Modified: fsf/trunk/libc/math/libm-test.inc
==============================================================================
--- fsf/trunk/libc/math/libm-test.inc (original)
+++ fsf/trunk/libc/math/libm-test.inc Sat Oct 6 00:01:47 2012
@@ -42,11 +42,10 @@
cbrt, ceil, copysign, cos, cosh, erf, erfc, exp, exp10, exp2, expm1,
fabs, fdim, floor, fma, fmax, fmin, fmod, fpclassify,
frexp, gamma, hypot,
- ilogb, isfinite, isinf, isnan, isnormal,
- isless, islessequal, isgreater, isgreaterequal, islessgreater, isunordered,
+ ilogb, isfinite, isnormal,
j0, j1, jn,
ldexp, lgamma, log, log10, log1p, log2, logb,
- modf, nearbyint, nextafter,
+ modf, nearbyint, nextafter, nexttoward,
pow, remainder, remquo, rint, lrint, llrint,
round, lround, llround,
scalb, scalbn, scalbln, signbit, sin, sincos, sinh, sqrt, tan, tanh, tgamma, trunc,
@@ -54,10 +53,17 @@
and for the following complex math functions:
cabs, cacos, cacosh, carg, casin, casinh, catan, catanh,
- ccos, ccosh, cexp, clog, cpow, cproj, csin, csinh, csqrt, ctan, ctanh.
-
- At the moment the following functions aren't tested:
- drem, nan
+ ccos, ccosh, cexp, cimag, clog, clog10, conj, cpow, cproj, creal,
+ csin, csinh, csqrt, ctan, ctanh.
+
+ At the moment the following functions and macros aren't tested:
+ drem (alias for remainder),
+ finite (functions equivalent to isfinite macro),
+ isinf, isnan,
+ isless, islessequal, isgreater, isgreaterequal, islessgreater, isunordered,
+ lgamma_r,
+ nan,
+ pow10 (alias for exp10).
Parameter handling is primitive in the moment:
--verbose=[0..3] for different levels of output:
@@ -83,8 +89,9 @@
aren't checked at the moment.
NaN values: There exist signalling and quiet NaNs. This implementation
- only uses quiet NaN as parameter but does not differenciate
- between the two kinds of NaNs as result.
+ only uses quiet NaN as parameter but does not differentiate
+ between the two kinds of NaNs as result. Where the sign of a NaN is
+ significant, this is not tested.
Inline functions: Inlining functions should give an improvement in
speed - but not in precission. The inlined functions return
Modified: fsf/trunk/libc/nptl/ChangeLog
==============================================================================
--- fsf/trunk/libc/nptl/ChangeLog (original)
+++ fsf/trunk/libc/nptl/ChangeLog Sat Oct 6 00:01:47 2012
@@ -1,3 +1,37 @@
+2012-10-05 H.J. Lu <hongjiu.lu@xxxxxxxxx>
+
+ [BZ #14557]
+ * Makefile (tests-static): Add tst-cancel24-static,
+ tst-cond8-static tst-mutex8-static, tst-mutexpi8-static,
+ tst-sem11-static and tst-sem12-static.
+ (tests): Likewise.
+ (LDLIBS-tst-cancel24-static): New macro.
+ * tst-cancel24-static.cc: New file.
+ * tst-cond8-static.c: Likewise.
+ * tst-mutex8-static.c: Likewise.
+ * tst-mutexpi8-static.c: Likewise.
+ * tst-sem11-static.c: Likewise.
+ * tst-sem12-static.c: Likewise.
+
+2012-10-05 Siddhesh Poyarekar <siddhesh@xxxxxxxxxx>
+
+ [BZ #14417]
+ * Makefile (tests): New test case tst-cond24.
+ (LDFLAGS-tst-cond24): Link tst-cond24 against librt.
+ * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
+ (__pthread_cond_timedwait): Unlock mutex before going back to
+ wait in PI case.
+ * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
+ (__pthread_cond_wait): Likewise. Revert handling of EAGAIN
+ return from futex_wait.
+ * sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
+ (__pthread_cond_timedwait): Unlock mutex before going back to
+ wait in PI case. Set requeue_pi flag only if wait returned 0.
+ * sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
+ (__pthread_cond_wait): Likewise. Revert handling of EAGAIN
+ return from futex_wait.
+ * tst-cond24.c: New test case.
+
2012-10-04 Roland McGrath <roland@xxxxxxxxxxxxx>
* pthread_create.c (start_thread): Use __madvise, not madvise.
Modified: fsf/trunk/libc/nptl/Makefile
==============================================================================
--- fsf/trunk/libc/nptl/Makefile (original)
+++ fsf/trunk/libc/nptl/Makefile Sat Oct 6 00:01:47 2012
@@ -206,7 +206,8 @@
tst-cond1 tst-cond2 tst-cond3 tst-cond4 tst-cond5 tst-cond6 tst-cond7 \
tst-cond8 tst-cond9 tst-cond10 tst-cond11 tst-cond12 tst-cond13 \
tst-cond14 tst-cond15 tst-cond16 tst-cond17 tst-cond18 tst-cond19 \
- tst-cond20 tst-cond21 tst-cond22 tst-cond23 tst-cond-except \
+ tst-cond20 tst-cond21 tst-cond22 tst-cond23 tst-cond24 \
+ tst-cond-except \
tst-robust1 tst-robust2 tst-robust3 tst-robust4 tst-robust5 \
tst-robust6 tst-robust7 tst-robust8 tst-robust9 \
tst-robustpi1 tst-robustpi2 tst-robustpi3 tst-robustpi4 tst-robustpi5 \
@@ -274,6 +275,7 @@
LDFLAGS-pthread.so = -Wl,--enable-new-dtags,-z,nodelete,-z,initfirst
+LDFLAGS-tst-cond24 = -lrt
include ../Makeconfig
@@ -349,8 +351,12 @@
$(common-objpfx)libc.a
tests-static += tst-locale1 tst-locale2 tst-stackguard1-static \
- tst-cancel21-static
-tests += tst-stackguard1-static tst-cancel21-static
+ tst-cancel21-static tst-cancel24-static tst-cond8-static \
+ tst-mutex8-static tst-mutexpi8-static tst-sem11-static \
+ tst-sem12-static
+tests += tst-stackguard1-static tst-cancel21-static tst-cancel24-static \
+ tst-cond8-static tst-mutex8-static tst-mutexpi8-static \
+ tst-sem11-static tst-sem12-static
xtests-static += tst-setuid1-static
# These tests are linked with libc before libpthread
@@ -508,6 +514,7 @@
endif
LDLIBS-tst-cancel24 = $(no-as-needed) -lstdc++
+LDLIBS-tst-cancel24-static = $(LDLIBS-tst-cancel24)
extra-B-pthread.so = -B$(common-objpfx)nptl/
$(objpfx)libpthread.so: $(addprefix $(objpfx),$(crti-objs) $(crtn-objs))
Modified: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S (original)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S Sat Oct 6 00:01:47 2012
@@ -212,8 +212,23 @@
sete 24(%esp)
je 41f
- /* Normal and PI futexes dont mix. Use normal futex functions only
- if the kernel does not support the PI futex functions. */
+ /* When a futex syscall with FUTEX_WAIT_REQUEUE_PI returns
+ successfully, it has already locked the mutex for us and the
+ pi_flag (24(%esp)) is set to denote that fact. However, if another
+ thread changed the futex value before we entered the wait, the
+ syscall may return an EAGAIN and the mutex is not locked. We go
+ ahead with a success anyway since later we look at the pi_flag to
+ decide if we got the mutex or not. The sequence numbers then make
+ sure that only one of the threads actually wake up. We retry using
+ normal FUTEX_WAIT only if the kernel returned ENOSYS, since normal
+ and PI futexes don't mix.
+
+ Note that we don't check for EAGAIN specifically; we assume that the
+ only other error the futex function could return is EAGAIN (barring
+ the ETIMEOUT of course, for the timeout case in futex) since
+ anything else would mean an error in our function. It is too
+ expensive to do that check for every call (which is quite common in
+ case of a large number of threads), so it has been skipped. */
cmpl $-ENOSYS, %eax
jne 41f
xorl %ecx, %ecx
@@ -273,9 +288,24 @@
jne 9f
15: cmpl $-ETIMEDOUT, %esi
- jne 8b
-
- addl $1, wakeup_seq(%ebx)
+ je 28f
+
+ /* We need to go back to futex_wait. If we're using requeue_pi, then
+ release the mutex we had acquired and go back. */
+ movl 24(%esp), %edx
+ test %edx, %edx
+ jz 8b
+
+ /* Adjust the mutex values first and then unlock it. The unlock
+ should always succeed or else the kernel did not lock the mutex
+ correctly. */
+ movl dep_mutex(%ebx), %eax
+ call __pthread_mutex_cond_lock_adjust
+ xorl %edx, %edx
+ call __pthread_mutex_unlock_usercnt
+ jmp 8b
+
+28: addl $1, wakeup_seq(%ebx)
adcl $0, wakeup_seq+4(%ebx)
addl $1, cond_futex(%ebx)
movl $ETIMEDOUT, %esi
Modified: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S (original)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S Sat Oct 6 00:01:47 2012
@@ -136,7 +136,6 @@
cmpl $PI_BIT, %eax
jne 18f
-90:
movl $(FUTEX_WAIT_REQUEUE_PI|FUTEX_PRIVATE_FLAG), %ecx
movl %ebp, %edx
xorl %esi, %esi
@@ -152,11 +151,22 @@
sete 16(%esp)
je 19f
- cmpl $-EAGAIN, %eax
- je 91f
-
- /* Normal and PI futexes dont mix. Use normal futex functions only
- if the kernel does not support the PI futex functions. */
+ /* When a futex syscall with FUTEX_WAIT_REQUEUE_PI returns
+ successfully, it has already locked the mutex for us and the
+ pi_flag (16(%esp)) is set to denote that fact. However, if another
+ thread changed the futex value before we entered the wait, the
+ syscall may return an EAGAIN and the mutex is not locked. We go
+ ahead with a success anyway since later we look at the pi_flag to
+ decide if we got the mutex or not. The sequence numbers then make
+ sure that only one of the threads actually wake up. We retry using
+ normal FUTEX_WAIT only if the kernel returned ENOSYS, since normal
+ and PI futexes don't mix.
+
+ Note that we don't check for EAGAIN specifically; we assume that the
+ only other error the futex function could return is EAGAIN since
+ anything else would mean an error in our function. It is too
+ expensive to do that check for every call (which is quite common in
+ case of a large number of threads), so it has been skipped. */
cmpl $-ENOSYS, %eax
jne 19f
xorl %ecx, %ecx
@@ -206,12 +216,12 @@
cmpl 8(%esp), %edx
jne 7f
cmpl 4(%esp), %edi
- je 8b
+ je 22f
7: cmpl %ecx, %edx
jne 9f
cmp %eax, %edi
- je 8b
+ je 22f
9: addl $1, woken_seq(%ebx)
adcl $0, woken_seq+4(%ebx)
@@ -287,6 +297,22 @@
jmp 20b
cfi_adjust_cfa_offset(-FRAME_SIZE);
+
+ /* We need to go back to futex_wait. If we're using requeue_pi, then
+ release the mutex we had acquired and go back. */
+22: movl 16(%esp), %edx
+ test %edx, %edx
+ jz 8b
+
+ /* Adjust the mutex values first and then unlock it. The unlock
+ should always succeed or else the kernel did not lock the mutex
+ correctly. */
+ movl dep_mutex(%ebx), %eax
+ call __pthread_mutex_cond_lock_adjust
+ xorl %edx, %edx
+ call __pthread_mutex_unlock_usercnt
+ jmp 8b
+
/* Initial locking failed. */
1:
#if cond_lock == 0
@@ -399,77 +425,6 @@
#endif
call __lll_unlock_wake
jmp 11b
-
-91:
-.LcleanupSTART2:
- /* FUTEX_WAIT_REQUEUE_PI returned EAGAIN. We need to
- call it again. */
-
- /* Get internal lock. */
- movl $1, %edx
- xorl %eax, %eax
- LOCK
-#if cond_lock == 0
- cmpxchgl %edx, (%ebx)
-#else
- cmpxchgl %edx, cond_lock(%ebx)
-#endif
- jz 92f
-
-#if cond_lock == 0
- movl %ebx, %edx
-#else
- leal cond_lock(%ebx), %edx
-#endif
-#if (LLL_SHARED-LLL_PRIVATE) > 255
- xorl %ecx, %ecx
-#endif
- cmpl $-1, dep_mutex(%ebx)
- setne %cl
- subl $1, %ecx
- andl $(LLL_SHARED-LLL_PRIVATE), %ecx
-#if LLL_PRIVATE != 0
- addl $LLL_PRIVATE, %ecx
-#endif
- call __lll_lock_wait
-
-92:
- /* Increment the cond_futex value again, so it can be used as a new
- expected value. */
- addl $1, cond_futex(%ebx)
- movl cond_futex(%ebx), %ebp
-
- /* Unlock. */
- LOCK
-#if cond_lock == 0
- subl $1, (%ebx)
-#else
- subl $1, cond_lock(%ebx)
-#endif
- je 93f
-#if cond_lock == 0
- movl %ebx, %eax
-#else
- leal cond_lock(%ebx), %eax
-#endif
-#if (LLL_SHARED-LLL_PRIVATE) > 255
- xorl %ecx, %ecx
-#endif
- cmpl $-1, dep_mutex(%ebx)
- setne %cl
- subl $1, %ecx
- andl $(LLL_SHARED-LLL_PRIVATE), %ecx
-#if LLL_PRIVATE != 0
- addl $LLL_PRIVATE, %ecx
-#endif
- call __lll_unlock_wake
-
-93:
- /* Set the rest of SYS_futex args for FUTEX_WAIT_REQUEUE_PI. */
- xorl %ecx, %ecx
- movl dep_mutex(%ebx), %edi
- jmp 90b
-.LcleanupEND2:
.size __pthread_cond_wait, .-__pthread_cond_wait
versioned_symbol (libpthread, __pthread_cond_wait, pthread_cond_wait,
@@ -651,10 +606,6 @@
.long .LcleanupEND-.Lsub_cond_futex
.long __condvar_w_cleanup-.LSTARTCODE
.uleb128 0
- .long .LcleanupSTART2-.LSTARTCODE
- .long .LcleanupEND2-.LcleanupSTART2
- .long __condvar_w_cleanup-.LSTARTCODE
- .uleb128 0
.long .LcallUR-.LSTARTCODE
.long .LENDCODE-.LcallUR
.long 0
Modified: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S (original)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S Sat Oct 6 00:01:47 2012
@@ -103,7 +103,7 @@
mov %RSI_LP, dep_mutex(%rdi)
22:
- xorl %r15d, %r15d
+ xorb %r15b, %r15b
#ifndef __ASSUME_FUTEX_CLOCK_REALTIME
# ifdef PIC
@@ -190,18 +190,39 @@
movl $SYS_futex, %eax
syscall
- movl $1, %r15d
+ cmpl $0, %eax
+ sete %r15b
+
#ifdef __ASSUME_REQUEUE_PI
jmp 62f
#else
- cmpq $-4095, %rax
- jnae 62f
+ je 62f
+
+ /* When a futex syscall with FUTEX_WAIT_REQUEUE_PI returns
+ successfully, it has already locked the mutex for us and the
+ pi_flag (%r15b) is set to denote that fact. However, if another
+ thread changed the futex value before we entered the wait, the
+ syscall may return an EAGAIN and the mutex is not locked. We go
+ ahead with a success anyway since later we look at the pi_flag to
+ decide if we got the mutex or not. The sequence numbers then make
+ sure that only one of the threads actually wake up. We retry using
+ normal FUTEX_WAIT only if the kernel returned ENOSYS, since normal
+ and PI futexes don't mix.
+
+ Note that we don't check for EAGAIN specifically; we assume that the
+ only other error the futex function could return is EAGAIN (barring
+ the ETIMEOUT of course, for the timeout case in futex) since
+ anything else would mean an error in our function. It is too
+ expensive to do that check for every call (which is quite common in
+ case of a large number of threads), so it has been skipped. */
+ cmpl $-ENOSYS, %eax
+ jne 62f
subq $cond_futex, %rdi
#endif
61: movl $(FUTEX_WAIT_BITSET|FUTEX_PRIVATE_FLAG), %esi
-60: xorl %r15d, %r15d
+60: xorb %r15b, %r15b
xorl %eax, %eax
/* The following only works like this because we only support
two clocks, represented using a single bit. */
@@ -248,7 +269,23 @@
ja 39f
45: cmpq $-ETIMEDOUT, %r14
- jne 38b
+ je 99f
+
+ /* We need to go back to futex_wait. If we're using requeue_pi, then
+ release the mutex we had acquired and go back. */
+ test %r15b, %r15b
+ jz 38b
+
+ /* Adjust the mutex values first and then unlock it. The unlock
+ should always succeed or else the kernel did not lock the
+ mutex correctly. */
+ movq %r8, %rdi
+ callq __pthread_mutex_cond_lock_adjust
+ xorl %esi, %esi
+ callq __pthread_mutex_unlock_usercnt
+ /* Reload cond_var. */
+ movq 8(%rsp), %rdi
+ jmp 38b
99: incq wakeup_seq(%rdi)
incl cond_futex(%rdi)
@@ -298,7 +335,7 @@
/* If requeue_pi is used the kernel performs the locking of the
mutex. */
41: movq 16(%rsp), %rdi
- testl %r15d, %r15d
+ testb %r15b, %r15b
jnz 64f
callq __pthread_mutex_cond_lock
Modified: fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S (original)
+++ fsf/trunk/libc/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S Sat Oct 6 00:01:47 2012
@@ -136,19 +136,36 @@
cmpl $PI_BIT, %eax
jne 61f
-90:
movl $(FUTEX_WAIT_REQUEUE_PI|FUTEX_PRIVATE_FLAG), %esi
movl $SYS_futex, %eax
syscall
- movl $1, %r8d
- cmpq $-EAGAIN, %rax
- je 91f
+ cmpl $0, %eax
+ sete %r8b
+
#ifdef __ASSUME_REQUEUE_PI
jmp 62f
#else
- cmpq $-4095, %rax
- jnae 62f
+ je 62f
+
+ /* When a futex syscall with FUTEX_WAIT_REQUEUE_PI returns
+ successfully, it has already locked the mutex for us and the
+ pi_flag (%r8b) is set to denote that fact. However, if another
+ thread changed the futex value before we entered the wait, the
+ syscall may return an EAGAIN and the mutex is not locked. We go
+ ahead with a success anyway since later we look at the pi_flag to
+ decide if we got the mutex or not. The sequence numbers then make
+ sure that only one of the threads actually wake up. We retry using
+ normal FUTEX_WAIT only if the kernel returned ENOSYS, since normal
+ and PI futexes don't mix.
+
+ Note that we don't check for EAGAIN specifically; we assume that the
+ only other error the futex function could return is EAGAIN since
+ anything else would mean an error in our function. It is too
+ expensive to do that check for every call (which is quite common in
+ case of a large number of threads), so it has been skipped. */
+ cmpl $-ENOSYS, %eax
+ jne 62f
# ifndef __ASSUME_PRIVATE_FUTEX
movl $FUTEX_WAIT, %esi
@@ -161,7 +178,7 @@
#else
orl %fs:PRIVATE_FUTEX, %esi
#endif
-60: xorl %r8d, %r8d
+60: xorb %r8b, %r8b
movl $SYS_futex, %eax
syscall
@@ -191,10 +208,10 @@
jne 16f
cmpq 24(%rsp), %r9
- jbe 8b
+ jbe 19f
cmpq %rax, %r9
- jna 8b
+ jna 19f
incq woken_seq(%rdi)
@@ -236,7 +253,7 @@
/* If requeue_pi is used the kernel performs the locking of the
mutex. */
11: movq 16(%rsp), %rdi
- testl %r8d, %r8d
+ testb %r8b, %r8b
jnz 18f
callq __pthread_mutex_cond_lock
@@ -252,6 +269,23 @@
18: callq __pthread_mutex_cond_lock_adjust
xorl %eax, %eax
jmp 14b
+
+ /* We need to go back to futex_wait. If we're using requeue_pi, then
+ release the mutex we had acquired and go back. */
+19: testb %r8b, %r8b
+ jz 8b
+
+ /* Adjust the mutex values first and then unlock it. The unlock
+ should always succeed or else the kernel did not lock the mutex
+ correctly. */
+ movq 16(%rsp), %rdi
+ callq __pthread_mutex_cond_lock_adjust
+ movq %rdi, %r8
+ xorl %esi, %esi
+ callq __pthread_mutex_unlock_usercnt
+ /* Reload cond_var. */
+ movq 8(%rsp), %rdi
+ jmp 8b
/* Initial locking failed. */
1:
@@ -330,69 +364,6 @@
13: movq %r10, %rax
jmp 14b
-
-91:
-.LcleanupSTART2:
- /* FUTEX_WAIT_REQUEUE_PI returned EAGAIN. We need to
- call it again. */
- movq 8(%rsp), %rdi
-
- /* Get internal lock. */
- movl $1, %esi
- xorl %eax, %eax
- LOCK
-#if cond_lock == 0
- cmpxchgl %esi, (%rdi)
-#else
- cmpxchgl %esi, cond_lock(%rdi)
-#endif
- jz 92f
-
-#if cond_lock != 0
- addq $cond_lock, %rdi
-#endif
- LP_OP(cmp) $-1, dep_mutex-cond_lock(%rdi)
- movl $LLL_PRIVATE, %eax
- movl $LLL_SHARED, %esi
- cmovne %eax, %esi
- callq __lll_lock_wait
-#if cond_lock != 0
- subq $cond_lock, %rdi
-#endif
-92:
- /* Increment the cond_futex value again, so it can be used as a new
- expected value. */
- incl cond_futex(%rdi)
- movl cond_futex(%rdi), %edx
-
- /* Release internal lock. */
- LOCK
-#if cond_lock == 0
- decl (%rdi)
-#else
- decl cond_lock(%rdi)
-#endif
- jz 93f
-
-#if cond_lock != 0
- addq $cond_lock, %rdi
-#endif
- LP_OP(cmp) $-1, dep_mutex-cond_lock(%rdi)
- movl $LLL_PRIVATE, %eax
- movl $LLL_SHARED, %esi
- cmovne %eax, %esi
- /* The call preserves %rdx. */
- callq __lll_unlock_wake
-#if cond_lock != 0
- subq $cond_lock, %rdi
-#endif
-93:
- /* Set the rest of SYS_futex args for FUTEX_WAIT_REQUEUE_PI. */
- xorq %r10, %r10
- mov dep_mutex(%rdi), %R8_LP
- leaq cond_futex(%rdi), %rdi
- jmp 90b
-.LcleanupEND2:
.size __pthread_cond_wait, .-__pthread_cond_wait
versioned_symbol (libpthread, __pthread_cond_wait, pthread_cond_wait,
@@ -547,10 +518,6 @@
.uleb128 .LcleanupEND-.LcleanupSTART
.uleb128 __condvar_cleanup1-.LSTARTCODE
.uleb128 0
- .uleb128 .LcleanupSTART2-.LSTARTCODE
- .uleb128 .LcleanupEND2-.LcleanupSTART2
- .uleb128 __condvar_cleanup1-.LSTARTCODE
- .uleb128 0
.uleb128 .LcallUR-.LSTARTCODE
.uleb128 .LENDCODE-.LcallUR
.uleb128 0
Added: fsf/trunk/libc/nptl/tst-cancel24-static.cc
==============================================================================
--- fsf/trunk/libc/nptl/tst-cancel24-static.cc (added)
+++ fsf/trunk/libc/nptl/tst-cancel24-static.cc Sat Oct 6 00:01:47 2012
@@ -1,0 +1,1 @@
+#include "tst-cancel24.cc"
Added: fsf/trunk/libc/nptl/tst-cond24.c
==============================================================================
--- fsf/trunk/libc/nptl/tst-cond24.c (added)
+++ fsf/trunk/libc/nptl/tst-cond24.c Sat Oct 6 00:01:47 2012
@@ -1,0 +1,249 @@
+/* Verify that condition variables synchronized by PI mutexes don't hang.
+ Copyright (C) 2012 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <time.h>
+
+#define THREADS_NUM 5
+#define MAXITER 50000
+
+static pthread_mutex_t mutex;
+static pthread_mutexattr_t mutex_attr;
+static pthread_cond_t cond;
+static pthread_t threads[THREADS_NUM];
+static int pending = 0;
+
+typedef void * (*threadfunc) (void *);
+
+void *
+thread_fun_timed (void *arg)
+{
+ int *ret = arg;
+ int rv, i;
+
+ printf ("Started thread_fun_timed[%d]\n", *ret);
+
+ for (i = 0; i < MAXITER / THREADS_NUM; i++)
+ {
+ rv = pthread_mutex_lock (&mutex);
+ if (rv)
+ {
+ printf ("pthread_mutex_lock: %s(%d)\n", strerror (rv), rv);
+ *ret = 1;
+ goto out;
+ }
+
+ while (!pending)
+ {
+ struct timespec ts;
+ clock_gettime(CLOCK_REALTIME, &ts);
+ ts.tv_sec += 20;
+ rv = pthread_cond_timedwait (&cond, &mutex, &ts);
+
+ /* There should be no timeout either. */
+ if (rv)
+ {
+ printf ("pthread_cond_wait: %s(%d)\n", strerror (rv), rv);
+ *ret = 1;
+ goto out;
+ }
+ }
+
+ pending--;
+
+ rv = pthread_mutex_unlock (&mutex);
+ if (rv)
+ {
+ printf ("pthread_mutex_unlock: %s(%d)\n", strerror (rv), rv);
+ *ret = 1;
+ goto out;
+ }
+ }
+
+ *ret = 0;
+
+out:
+ return ret;
+}
+
+void *
+thread_fun (void *arg)
+{
+ int *ret = arg;
+ int rv, i;
+
+ printf ("Started thread_fun[%d]\n", *ret);
+
+ for (i = 0; i < MAXITER / THREADS_NUM; i++)
+ {
+ rv = pthread_mutex_lock (&mutex);
+ if (rv)
+ {
+ printf ("pthread_mutex_lock: %s(%d)\n", strerror (rv), rv);
+ *ret = 1;
+ goto out;
+ }
+
+ while (!pending)
+ {
+ rv = pthread_cond_wait (&cond, &mutex);
+
+ if (rv)
+ {
+ printf ("pthread_cond_wait: %s(%d)\n", strerror (rv), rv);
+ *ret = 1;
+ goto out;
+ }
+ }
+
+ pending--;
+
+ rv = pthread_mutex_unlock (&mutex);
+ if (rv)
+ {
+ printf ("pthread_mutex_unlock: %s(%d)\n", strerror (rv), rv);
+ *ret = 1;
+ goto out;
+ }
+ }
+
+ *ret = 0;
+
+out:
+ return ret;
+}
+
+static int
+do_test_wait (threadfunc f)
+{
+ int i;
+ int rv;
+ int counter = 0;
+ int retval[THREADS_NUM];
+
+ puts ("Starting test");
+
+ rv = pthread_mutexattr_init (&mutex_attr);
+ if (rv)
+ {
+ printf ("pthread_mutexattr_init: %s(%d)\n", strerror (rv), rv);
+ return 1;
+ }
+
+ rv = pthread_mutexattr_setprotocol (&mutex_attr, PTHREAD_PRIO_INHERIT);
+ if (rv)
+ {
+ printf ("pthread_mutexattr_setprotocol: %s(%d)\n", strerror (rv), rv);
+ return 1;
+ }
+
+ rv = pthread_mutex_init (&mutex, &mutex_attr);
+ if (rv)
+ {
+ printf ("pthread_mutex_init: %s(%d)\n", strerror (rv), rv);
+ return 1;
+ }
+
+ rv = pthread_cond_init (&cond, NULL);
+ if (rv)
+ {
+ printf ("pthread_cond_init: %s(%d)\n", strerror (rv), rv);
+ return 1;
+ }
+
+ for (i = 0; i < THREADS_NUM; i++)
+ {
+ retval[i] = i;
+ rv = pthread_create (&threads[i], NULL, f, &retval[i]);
+ if (rv)
+ {
+ printf ("pthread_create: %s(%d)\n", strerror (rv), rv);
+ return 1;
+ }
+ }
+
+ for (; counter < MAXITER; counter++)
+ {
+ rv = pthread_mutex_lock (&mutex);
+ if (rv)
+ {
+ printf ("pthread_mutex_lock: %s(%d)\n", strerror (rv), rv);
+ return 1;
+ }
+
+ if (!(counter % 100))
+ printf ("counter: %d\n", counter);
+ pending += 1;
+
+ rv = pthread_cond_signal (&cond);
+ if (rv)
+ {
+ printf ("pthread_cond_signal: %s(%d)\n", strerror (rv), rv);
+ return 1;
+ }
+
+ rv = pthread_mutex_unlock (&mutex);
+ if (rv)
+ {
+ printf ("pthread_mutex_unlock: %s(%d)\n", strerror (rv), rv);
+ return 1;
+ }
+ }
+
+ for (i = 0; i < THREADS_NUM; i++)
+ {
+ void *ret;
+ rv = pthread_join (threads[i], &ret);
+ if (rv)
+ {
+ printf ("pthread_join: %s(%d)\n", strerror (rv), rv);
+ return 1;
+ }
+ if (ret && *(int *)ret)
+ {
+ printf ("Thread %d returned with an error\n", i);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static int
+do_test (void)
+{
+ puts ("Testing pthread_cond_wait");
+ int ret = do_test_wait (thread_fun);
+ if (ret)
+ return ret;
+
+ puts ("Testing pthread_cond_timedwait");
+ return do_test_wait (thread_fun_timed);
+}
+
+#define TIMEOUT 10
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
Added: fsf/trunk/libc/nptl/tst-cond8-static.c
==============================================================================
--- fsf/trunk/libc/nptl/tst-cond8-static.c (added)
+++ fsf/trunk/libc/nptl/tst-cond8-static.c Sat Oct 6 00:01:47 2012
@@ -1,0 +1,1 @@
+#include "tst-cond8.c"
Added: fsf/trunk/libc/nptl/tst-mutex8-static.c
==============================================================================
--- fsf/trunk/libc/nptl/tst-mutex8-static.c (added)
+++ fsf/trunk/libc/nptl/tst-mutex8-static.c Sat Oct 6 00:01:47 2012
@@ -1,0 +1,1 @@
+#include "tst-mutex8.c"
Added: fsf/trunk/libc/nptl/tst-mutexpi8-static.c
==============================================================================
--- fsf/trunk/libc/nptl/tst-mutexpi8-static.c (added)
+++ fsf/trunk/libc/nptl/tst-mutexpi8-static.c Sat Oct 6 00:01:47 2012
@@ -1,0 +1,1 @@
+#include "tst-mutexpi8.c"
Added: fsf/trunk/libc/nptl/tst-sem11-static.c
==============================================================================
--- fsf/trunk/libc/nptl/tst-sem11-static.c (added)
+++ fsf/trunk/libc/nptl/tst-sem11-static.c Sat Oct 6 00:01:47 2012
@@ -1,0 +1,1 @@
+#include "tst-sem11.c"
Added: fsf/trunk/libc/nptl/tst-sem12-static.c
==============================================================================
--- fsf/trunk/libc/nptl/tst-sem12-static.c (added)
+++ fsf/trunk/libc/nptl/tst-sem12-static.c Sat Oct 6 00:01:47 2012
@@ -1,0 +1,1 @@
+#include "tst-sem12.c"
Modified: fsf/trunk/libc/ports/ChangeLog.arm
==============================================================================
--- fsf/trunk/libc/ports/ChangeLog.arm (original)
+++ fsf/trunk/libc/ports/ChangeLog.arm Sat Oct 6 00:01:47 2012
@@ -1,3 +1,9 @@
+2012-10-05 Roland McGrath <roland@xxxxxxxxxxxxx>
+
+ * sysdeps/arm/dl-machine.h (fix_bad_pc24): Rewritten, replaced with ...
+ (relocate_pc24): ... this new function.
+ (elf_machine_rel, elf_machine_rela): Update callers.
+
2012-10-02 Siddhesh Poyarekar <siddhesh@xxxxxxxxxx>
* sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.h: Fix clone
Modified: fsf/trunk/libc/ports/sysdeps/arm/dl-machine.h
==============================================================================
--- fsf/trunk/libc/ports/sysdeps/arm/dl-machine.h (original)
+++ fsf/trunk/libc/ports/sysdeps/arm/dl-machine.h Sat Oct 6 00:01:47 2012
@@ -302,36 +302,56 @@
#define ARCH_LA_PLTEXIT arm_gnu_pltexit
#ifdef RESOLVE_MAP
-
-/* Deal with an out-of-range PC24 reloc. */
-auto Elf32_Addr
-fix_bad_pc24 (Elf32_Addr *const reloc_addr, Elf32_Addr value)
-{
- static void *fix_page;
- static unsigned int fix_offset;
- static size_t pagesize;
- Elf32_Word *fix_address;
-
- if (! fix_page)
+/* Handle a PC24 reloc, including the out-of-range case. */
+auto void
+relocate_pc24 (struct link_map *map, Elf32_Addr value,
+ Elf32_Addr *const reloc_addr, Elf32_Sword addend)
+{
+ Elf32_Addr new_value;
+
+ /* Set NEW_VALUE based on V, and return true iff it overflows 24 bits. */
+ inline bool set_new_value (Elf32_Addr v)
+ {
+ new_value = v + addend - (Elf32_Addr) reloc_addr;
+ Elf32_Addr topbits = new_value & 0xfe000000;
+ return topbits != 0xfe000000 && topbits != 0x00000000;
+ }
+
+ if (set_new_value (value))
{
- if (! pagesize)
- pagesize = getpagesize ();
- fix_page = mmap (NULL, pagesize, PROT_READ | PROT_WRITE | PROT_EXEC,
- MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
- if (! fix_page)
- assert (! "could not map page for fixup");
- fix_offset = 0;
+ /* The PC-relative address doesn't fit in 24 bits! */
+
+ static void *fix_page;
+ static size_t fix_offset;
+ if (fix_page == NULL)
+ {
+ void *new_page = __mmap (NULL, GLRO(dl_pagesize),
+ PROT_READ | PROT_WRITE | PROT_EXEC,
+ MAP_PRIVATE | MAP_ANON, -1, 0);
+ if (new_page == MAP_FAILED)
+ _dl_signal_error (0, map->l_name, NULL,
+ "could not map page for fixup");
+ fix_page = new_page;
+ assert (fix_offset == 0);
+ }
+
+ Elf32_Word *fix_address = fix_page + fix_offset;
+ fix_address[0] = 0xe51ff004; /* ldr pc, [pc, #-4] */
+ fix_address[1] = value;
+
+ fix_offset += sizeof fix_address[0] * 2;
+ if (fix_offset >= GLRO(dl_pagesize))
+ {
+ fix_page = NULL;
+ fix_offset = 0;
+ }
+
+ if (set_new_value ((Elf32_Addr) fix_address))
+ _dl_signal_error (0, map->l_name, NULL,
+ "R_ARM_PC24 relocation out of range");
}
- fix_address = (Elf32_Word *)(fix_page + fix_offset);
- fix_address[0] = 0xe51ff004; /* ldr pc, [pc, #-4] */
- fix_address[1] = value;
-
- fix_offset += 8;
- if (fix_offset >= pagesize)
- fix_page = NULL;
-
- return (Elf32_Addr)fix_address;
+ *reloc_addr = (*reloc_addr & 0xff000000) | ((new_value >> 2) & 0x00ffffff);
}
/* Perform the relocation specified by RELOC and SYM (which is fully resolved).
@@ -473,30 +493,11 @@
}
break;
case R_ARM_PC24:
- {
- Elf32_Sword addend;
- Elf32_Addr newvalue, topbits;
-
- addend = *reloc_addr & 0x00ffffff;
- if (addend & 0x00800000) addend |= 0xff000000;
-
- newvalue = value - (Elf32_Addr)reloc_addr + (addend << 2);
- topbits = newvalue & 0xfe000000;
- if (topbits != 0xfe000000 && topbits != 0x00000000)
- {
- newvalue = fix_bad_pc24(reloc_addr, value)
- - (Elf32_Addr)reloc_addr + (addend << 2);
- topbits = newvalue & 0xfe000000;
- if (topbits != 0xfe000000 && topbits != 0x00000000)
- {
- _dl_signal_error (0, map->l_name, NULL,
- "R_ARM_PC24 relocation out of range");
- }
- }
- newvalue >>= 2;
- value = (*reloc_addr & 0xff000000) | (newvalue & 0x00ffffff);
- *reloc_addr = value;
- }
+ relocate_pc24 (map, value, reloc_addr,
+ /* Sign-extend the 24-bit addend in the
+ instruction (which counts instructions), and
+ then shift it up two so as to count bytes. */
+ (((Elf32_Sword) *reloc_addr << 8) >> 8) << 2);
break;
#if !defined RTLD_BOOTSTRAP
case R_ARM_TLS_DTPMOD32:
@@ -589,26 +590,7 @@
*reloc_addr = value + reloc->r_addend;
break;
case R_ARM_PC24:
- {
- Elf32_Addr newvalue, topbits;
-
- newvalue = value + reloc->r_addend - (Elf32_Addr)reloc_addr;
- topbits = newvalue & 0xfe000000;
- if (topbits != 0xfe000000 && topbits != 0x00000000)
- {
- newvalue = fix_bad_pc24(reloc_addr, value)
- - (Elf32_Addr)reloc_addr + (reloc->r_addend << 2);
- topbits = newvalue & 0xfe000000;
- if (topbits != 0xfe000000 && topbits != 0x00000000)
- {
- _dl_signal_error (0, map->l_name, NULL,
- "R_ARM_PC24 relocation out of range");
- }
- }
- newvalue >>= 2;
- value = (*reloc_addr & 0xff000000) | (newvalue & 0x00ffffff);
- *reloc_addr = value;
- }
+ relocate_pc24 (map, value, reloc_addr, reloc->r_addend);
break;
#if !defined RTLD_BOOTSTRAP
case R_ARM_TLS_DTPMOD32:
Modified: fsf/trunk/libc/scripts/config.guess
==============================================================================
--- fsf/trunk/libc/scripts/config.guess (original)
+++ fsf/trunk/libc/scripts/config.guess Sat Oct 6 00:01:47 2012
@@ -4,7 +4,7 @@
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
# 2011, 2012 Free Software Foundation, Inc.
-timestamp='2012-01-01'
+timestamp='2012-09-25'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -17,9 +17,7 @@
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
-# 02110-1301, USA.
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
@@ -201,6 +199,10 @@
# contains redundant information, the shorter form:
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
echo "${machine}-${os}${release}"
+ exit ;;
+ *:Bitrig:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
exit ;;
*:OpenBSD:*:*)
UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
@@ -304,7 +306,7 @@
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
echo arm-acorn-riscix${UNAME_RELEASE}
exit ;;
- arm:riscos:*:*|arm:RISCOS:*:*)
+ arm*:riscos:*:*|arm*:RISCOS:*:*)
echo arm-unknown-riscos
exit ;;
SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
@@ -803,6 +805,9 @@
i*:CYGWIN*:*)
echo ${UNAME_MACHINE}-pc-cygwin
exit ;;
+ *:MINGW64*:*)
+ echo ${UNAME_MACHINE}-pc-mingw64
+ exit ;;
*:MINGW*:*)
echo ${UNAME_MACHINE}-pc-mingw32
exit ;;
@@ -862,6 +867,13 @@
exit ;;
i*86:Minix:*:*)
echo ${UNAME_MACHINE}-pc-minix
+ exit ;;
+ aarch64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ aarch64_be:Linux:*:*)
+ UNAME_MACHINE=aarch64_be
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
alpha:Linux:*:*)
case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
@@ -1196,6 +1208,9 @@
BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
echo i586-pc-haiku
exit ;;
+ x86_64:Haiku:*:*)
+ echo x86_64-unknown-haiku
+ exit ;;
SX-4:SUPER-UX:*:*)
echo sx4-nec-superux${UNAME_RELEASE}
exit ;;
@@ -1251,7 +1266,7 @@
NEO-?:NONSTOP_KERNEL:*:*)
echo neo-tandem-nsk${UNAME_RELEASE}
exit ;;
- NSE-?:NONSTOP_KERNEL:*:*)
+ NSE-*:NONSTOP_KERNEL:*:*)
echo nse-tandem-nsk${UNAME_RELEASE}
exit ;;
NSR-?:NONSTOP_KERNEL:*:*)
@@ -1320,10 +1335,10 @@
i*86:AROS:*:*)
echo ${UNAME_MACHINE}-pc-aros
exit ;;
+ x86_64:VMkernel:*:*)
+ echo ${UNAME_MACHINE}-unknown-esx
+ exit ;;
esac
-
-#echo '(No uname command or uname output not recognized.)' 1>&2
-#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
eval $set_cc_for_build
cat >$dummy.c <<EOF
Modified: fsf/trunk/libc/scripts/config.sub
==============================================================================
--- fsf/trunk/libc/scripts/config.sub (original)
+++ fsf/trunk/libc/scripts/config.sub Sat Oct 6 00:01:47 2012
@@ -4,7 +4,7 @@
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
# 2011, 2012 Free Software Foundation, Inc.
-timestamp='2012-01-28'
+timestamp='2012-08-18'
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
@@ -21,9 +21,7 @@
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
-# 02110-1301, USA.
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
@@ -125,7 +123,7 @@
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
- linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
+ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
knetbsd*-gnu* | netbsd*-gnu* | \
kopensolaris*-gnu* | \
storm-chaos* | os2-emx* | rtmk-nova*)
@@ -227,6 +225,12 @@
-isc*)
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
+ -lynx*178)
+ os=-lynxos178
+ ;;
+ -lynx*5)
+ os=-lynxos5
+ ;;
-lynx*)
os=-lynxos
;;
@@ -251,6 +255,7 @@
# Some are omitted here because they have special meanings below.
1750a | 580 \
| a29k \
+ | aarch64 | aarch64_be \
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
| am33_2.0 \
@@ -362,6 +367,7 @@
# Recognize the basic CPU types with company name.
580-* \
| a29k-* \
+ | aarch64-* | aarch64_be-* \
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
@@ -785,6 +791,10 @@
microblaze)
basic_machine=microblaze-xilinx
;;
+ mingw64)
+ basic_machine=x86_64-pc
+ os=-mingw64
+ ;;
mingw32)
basic_machine=i386-pc
os=-mingw32
@@ -1346,15 +1356,15 @@
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
- | -openbsd* | -solidbsd* \
+ | -bitrig* | -openbsd* | -solidbsd* \
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
| -chorusos* | -chorusrdb* | -cegcc* \
| -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
- | -mingw32* | -linux-gnu* | -linux-android* \
- | -linux-newlib* | -linux-uclibc* \
+ | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
+ | -linux-newlib* | -linux-musl* | -linux-uclibc* \
| -uxpv* | -beos* | -mpeix* | -udk* \
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
@@ -1537,6 +1547,9 @@
c4x-* | tic4x-*)
os=-coff
;;
+ hexagon-*)
+ os=-elf
+ ;;
tic54x-*)
os=-coff
;;
Modified: fsf/trunk/libc/string/Makefile
==============================================================================
--- fsf/trunk/libc/string/Makefile (original)
+++ fsf/trunk/libc/string/Makefile Sat Oct 6 00:01:47 2012
@@ -56,7 +56,7 @@
tst-strtok tst-strxfrm bug-strcoll1 tst-strfry \
bug-strtok1 $(addprefix test-,$(strop-tests)) \
bug-envz1 tst-strxfrm2 tst-endian tst-svc2 \
- bug-strstr1 bug-strcasestr1 bug-strchr1 tst-strtok_r
+ tst-strtok_r
include ../Rules
Removed: fsf/trunk/libc/string/bug-strcasestr1.c
==============================================================================
--- fsf/trunk/libc/string/bug-strcasestr1.c (original)
+++ fsf/trunk/libc/string/bug-strcasestr1.c (removed)
@@ -1,39 +1,0 @@
-/* Test for non-submitted strcasestr bug.
- Copyright (C) 2012 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, see
- <http://www.gnu.org/licenses/>. */
-
-#include <stdio.h>
-#include <string.h>
-
-#define TEST_FUNCTION do_test ()
-static int
-do_test (void)
-{
- const char haystack[] = "AOKB";
- const char needle[] = "OK";
- const char *sub = strcasestr (haystack, needle);
-
- if (sub == NULL)
- {
- fprintf (stderr, "BUG: didn't find \"%s\" in \"%s\"\n", needle, haystack);
- return 1;
- }
-
- return 0;
-}
-
-#include "../test-skeleton.c"
Removed: fsf/trunk/libc/string/bug-strchr1.c
==============================================================================
--- fsf/trunk/libc/string/bug-strchr1.c (original)
+++ fsf/trunk/libc/string/bug-strchr1.c (removed)
@@ -1,14 +1,0 @@
-#include <stdio.h>
-#include <string.h>
-
-static int
-do_test (void)
-{
- char s[] __attribute__((aligned(16))) = "\xff";
- char *p = strchr (s, '\xfe');
- printf ("%p\n", p);
- return p != NULL;
-}
-
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"
Removed: fsf/trunk/libc/string/bug-strstr1.c
==============================================================================
--- fsf/trunk/libc/string/bug-strstr1.c (original)
+++ fsf/trunk/libc/string/bug-strstr1.c (removed)
@@ -1,26 +1,0 @@
-#include <stdio.h>
-#include <string.h>
-
-int main (int argc, char** argv)
-{
- const char haystack[] =
- "F_BD_CE_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD_C3_88_20_EF_BF_BD_EF_BF_BD_EF_BF_BD_C3_A7_20_EF_BF_BD";
-
- const char needle[] =
- "_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD";
-
- const char* sub = strstr (haystack, needle);
-
- if (sub != NULL)
- {
- int j;
-
- fprintf (stderr, "BUG: expected NULL, got:\n%s\n%s\n", sub, needle);
- for (j = 0; needle[j] != '\0'; ++j)
- putchar (needle[j] == sub[j] ? ' ' : '^');
- puts ("");
- return 1;
- }
-
- return 0;
-}
Modified: fsf/trunk/libc/string/test-strcasestr.c
==============================================================================
--- fsf/trunk/libc/string/test-strcasestr.c (original)
+++ fsf/trunk/libc/string/test-strcasestr.c Sat Oct 6 00:01:47 2012
@@ -57,8 +57,9 @@
IMPL (strcasestr, 1)
-static void
-do_one_test (impl_t *impl, const char *s1, const char *s2, char *exp_result)
+static int
+check_result (impl_t *impl, const char *s1, const char *s2,
+ char *exp_result)
{
char *result = CALL (impl, s1, s2);
if (result != exp_result)
@@ -66,8 +67,16 @@
error (0, 0, "Wrong result in function %s %s %s", impl->name,
result, exp_result);
ret = 1;
- return;
- }
+ return -1;
+ }
+ return 0;
+}
+
+static void
+do_one_test (impl_t *impl, const char *s1, const char *s2, char *exp_result)
+{
+ if (check_result (impl, s1, s2, exp_result) < 0)
+ return;
if (HP_TIMING_AVAIL)
{
@@ -136,11 +145,24 @@
putchar ('\n');
}
+static void
+check1 (void)
+{
+ const char s1[] = "AOKB";
+ const char s2[] = "OK";
+ char *exp_result;
+
+ exp_result = stupid_strcasestr (s1, s2);
+ FOR_EACH_IMPL (impl, 0)
+ check_result (impl, s1, s2, exp_result);
+}
static int
test_main (void)
{
test_init ();
+
+ check1 ();
printf ("%23s", "");
FOR_EACH_IMPL (impl, 0)
Modified: fsf/trunk/libc/string/test-strchr.c
==============================================================================
--- fsf/trunk/libc/string/test-strchr.c (original)
+++ fsf/trunk/libc/string/test-strchr.c Sat Oct 6 00:01:47 2012
@@ -79,8 +79,8 @@
IMPL (simple_STRCHR, 0)
IMPL (STRCHR, 1)
-static void
-do_one_test (impl_t *impl, const CHAR *s, int c, const CHAR *exp_res)
+static int
+check_result (impl_t *impl, const CHAR *s, int c, const CHAR *exp_res)
{
CHAR *res = CALL (impl, s, c);
if (res != exp_res)
@@ -88,8 +88,16 @@
error (0, 0, "Wrong result in function %s %#x %p %p", impl->name,
c, res, exp_res);
ret = 1;
- return;
- }
+ return -1;
+ }
+ return 0;
+}
+
+static void
+do_one_test (impl_t *impl, const CHAR *s, int c, const CHAR *exp_res)
+{
+ if (check_result (impl, s, c, exp_res) < 0)
+ return;
if (HP_TIMING_AVAIL)
{
@@ -224,12 +232,25 @@
}
}
+static void
+check1 (void)
+{
+ char s[] __attribute__((aligned(16))) = "\xff";
+ char c = '\xfe';
+ char *exp_result = stupid_STRCHR (s, c);
+
+ FOR_EACH_IMPL (impl, 0)
+ check_result (impl, s, c, exp_result);
+}
+
int
test_main (void)
{
size_t i;
test_init ();
+
+ check1 ();
printf ("%20s", "");
FOR_EACH_IMPL (impl, 0)
Modified: fsf/trunk/libc/string/test-strstr.c
==============================================================================
--- fsf/trunk/libc/string/test-strstr.c (original)
+++ fsf/trunk/libc/string/test-strstr.c Sat Oct 6 00:01:47 2012
@@ -55,8 +55,9 @@
IMPL (strstr, 1)
-static void
-do_one_test (impl_t *impl, const char *s1, const char *s2, char *exp_result)
+static int
+check_result (impl_t *impl, const char *s1, const char *s2,
+ char *exp_result)
{
char *result = CALL (impl, s1, s2);
if (result != exp_result)
@@ -64,8 +65,17 @@
error (0, 0, "Wrong result in function %s %s %s", impl->name,
result, exp_result);
ret = 1;
- return;
- }
+ return -1;
+ }
+
+ return 0;
+}
+
+static void
+do_one_test (impl_t *impl, const char *s1, const char *s2, char *exp_result)
+{
+ if (check_result (impl, s1, s2, exp_result) < 0)
+ return;
if (HP_TIMING_AVAIL)
{
@@ -133,11 +143,37 @@
putchar ('\n');
}
+static void
+check1 (void)
+{
+ const char s1[] =
+ "F_BD_CE_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD_C3_88_20_EF_BF_BD_EF_BF_BD_EF_BF_BD_C3_A7_20_EF_BF_BD";
+ const char s2[] = "_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD_EF_BF_BD";
+ char *exp_result;
+
+ exp_result = stupid_strstr (s1, s2);
+ FOR_EACH_IMPL (impl, 0)
+ check_result (impl, s1, s2, exp_result);
+}
+
+static void
+check2 (void)
+{
+ const char s1[] = ", enable_static, \0, enable_shared, ";
+ char *exp_result;
+
+ exp_result = stupid_strstr (s1, s1 + 18);
+ FOR_EACH_IMPL (impl, 0)
+ check_result (impl, s1, s1 + 18, exp_result);
+}
static int
test_main (void)
{
test_init ();
+
+ check1 ();
+ check2 ();
printf ("%23s", "");
FOR_EACH_IMPL (impl, 0)
Modified: fsf/trunk/libc/sysdeps/mach/hurd/dl-sysdep.c
==============================================================================
--- fsf/trunk/libc/sysdeps/mach/hurd/dl-sysdep.c (original)
+++ fsf/trunk/libc/sysdeps/mach/hurd/dl-sysdep.c Sat Oct 6 00:01:47 2012
@@ -646,26 +646,6 @@
}
-/* Return an array of useful/necessary hardware capability names. */
-const struct r_strlenpair *
-internal_function
-_dl_important_hwcaps (const char *platform, size_t platform_len, size_t *sz,
- size_t *max_capstrlen)
-{
- struct r_strlenpair *result;
-
- /* Return an empty array. Hurd has no hardware capabilities. */
- result = (struct r_strlenpair *) malloc (sizeof (*result));
- if (result == NULL)
- _dl_signal_error (ENOMEM, NULL, NULL, "cannot create capability list");
-
- result[0].str = (char *) result; /* Does not really matter. */
- result[0].len = 0;
-
- *sz = 1;
- return result;
-}
-
void weak_function
_dl_init_first (int argc, ...)
{
Modified: fsf/trunk/libc/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h
==============================================================================
--- fsf/trunk/libc/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h (original)
+++ fsf/trunk/libc/sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h Sat Oct 6 00:01:47 2012
@@ -1,5 +1,5 @@
/* O_*, F_*, FD_* bit values for Linux/PowerPC.
- Copyright (C) 1995-1998, 2000, 2003, 2004, 2006, 2007, 2009, 2010, 2011
+ Copyright (C) 1995-2012
Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -232,6 +232,19 @@
we splice from/to). */
# define SPLICE_F_MORE 4 /* Expect more data. */
# define SPLICE_F_GIFT 8 /* Pages passed in are a gift. */
+
+
+/* File handle structure. */
+struct file_handle
+{
+ unsigned int handle_bytes;
+ int handle_type;
+ /* File identifier. */
+ unsigned char f_handle[0];
+};
+
+/* Maximum handle size (for now). */
+# define MAX_HANDLE_SZ 128
#endif
__BEGIN_DECLS
@@ -278,6 +291,19 @@
__off64_t __len);
# endif
+
+/* Map file name to file handle. */
+extern int name_to_handle_at (int __dfd, const char *__name,
+ struct file_handle *__handle, int *__mnt_id,
+ int __flags) __THROW;
+
+/* Open file using the file handle.
+
+ This function is a possible cancellation point and therefore not
+ marked with __THROW. */
+extern int open_by_handle_at (int __mountdirfd, struct file_handle *__handle,
+ int __flags);
+
#endif
__END_DECLS
_______________________________________________
Commits mailing list
Commits@xxxxxxxxxx
http://eglibc.org/cgi-bin/mailman/listinfo/commits