summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2009-03-20 20:00:20 +0000
committerJakub Jelinek <jakub@redhat.com>2009-03-20 20:00:20 +0000
commitef860a878bf532436a469fc1f89fe3366862a949 (patch)
treec4a2666ac77cdaa00f41bd8f66a828b39e2642ff
parentd4c583b4466962a9d9d4ca54ab6108dc7b42cdcc (diff)
Updated to fedora-glibc-20090320T1944cvs/fedora-glibc-2_9_90-11
-rw-r--r--ChangeLog136
-rw-r--r--NEWS9
-rw-r--r--config.h.in3
-rw-r--r--config.make.in3
-rwxr-xr-xconfigure70
-rw-r--r--configure.in43
-rw-r--r--crypt/sha256test.c12
-rw-r--r--dirent/alphasort.c7
-rw-r--r--dirent/alphasort64.c7
-rw-r--r--dirent/dirent.h49
-rw-r--r--dirent/scandir.c7
-rw-r--r--dirent/scandir64.c5
-rw-r--r--dirent/versionsort.c7
-rw-r--r--dirent/versionsort64.c7
-rw-r--r--elf/dl-load.c3
-rw-r--r--elf/dl-open.c11
-rw-r--r--elf/dl-reloc.c8
-rw-r--r--elf/dl-runtime.c33
-rw-r--r--elf/dl-sysdep.c59
-rw-r--r--elf/do-lookup.h12
-rw-r--r--elf/elf.h1
-rw-r--r--elf/rtld.c15
-rw-r--r--fedora/branch.mk4
-rw-r--r--fedora/glibc.spec.in8
-rw-r--r--include/dirent.h8
-rw-r--r--include/libc-symbols.h14
-rw-r--r--inet/Makefile4
-rw-r--r--inet/inet6_rth.c9
-rw-r--r--inet/tst-inet6_rth.c188
-rw-r--r--locale/iso-639.def1
-rw-r--r--localedata/ChangeLog19
-rw-r--r--localedata/SUPPORTED1
-rw-r--r--localedata/locales/iso14651_t1_common16
-rw-r--r--localedata/locales/ko_KR4
-rw-r--r--localedata/locales/mt_MT4
-rw-r--r--localedata/locales/nan_TW@latin205
-rw-r--r--malloc/Makefile5
-rw-r--r--malloc/arena.c203
-rw-r--r--malloc/hooks.c15
-rw-r--r--malloc/malloc.c260
-rw-r--r--malloc/malloc.h4
-rw-r--r--nptl/ChangeLog10
-rw-r--r--nptl/init.c6
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S123
-rw-r--r--nptl_db/ChangeLog5
-rw-r--r--nptl_db/td_symbol_list.c4
-rw-r--r--nscd/connections.c17
-rw-r--r--string/Makefile4
-rw-r--r--string/strlen.c52
-rw-r--r--string/strverscmp.c61
-rw-r--r--string/tst-svc2.c62
-rw-r--r--sysdeps/generic/ldsodefs.h4
-rw-r--r--sysdeps/i386/dl-machine.h114
-rw-r--r--sysdeps/powerpc/powerpc32/power7/fpu/Implies1
-rw-r--r--sysdeps/unix/sysv/linux/i386/alphasort64.c16
-rw-r--r--sysdeps/unix/sysv/linux/i386/olddirent.h5
-rw-r--r--sysdeps/unix/sysv/linux/i386/versionsort64.c16
-rw-r--r--sysdeps/wordsize-64/alphasort.c4
-rw-r--r--sysdeps/wordsize-64/versionsort.c4
-rw-r--r--sysdeps/x86_64/cacheinfo.c32
-rw-r--r--sysdeps/x86_64/dl-machine.h114
-rw-r--r--sysdeps/x86_64/dl-runtime.c9
-rw-r--r--sysdeps/x86_64/dl-trampoline.S249
-rw-r--r--sysdeps/x86_64/multiarch/Makefile3
-rw-r--r--sysdeps/x86_64/multiarch/init-arch.c65
-rw-r--r--sysdeps/x86_64/multiarch/init-arch.h70
-rw-r--r--sysdeps/x86_64/multiarch/sched_cpucount.c42
67 files changed, 1951 insertions, 620 deletions
diff --git a/ChangeLog b/ChangeLog
index 9e9558c95d..2d5123e9de 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,139 @@
+2009-03-16 Ulrich Drepper <drepper@redhat.com>
+
+ * include/dirent.h: Yet more changes to match sort function type
+ change.
+ * sysdeps/unix/sysv/linux/i386/alphasort64.c: Likewise.
+ * sysdeps/unix/sysv/linux/i386/olddirent.h: Likewise.
+ * sysdeps/unix/sysv/linux/i386/versionsort64.c: Likewise.
+
+2009-03-16 Thomas Schwinge <tschwinge@gnu.org>
+
+ * dirent/scandir64.c (scandir64): Adjust declaration to type change.
+
+2009-03-16 Ulrich Drepper <drepper@redhat.com>
+
+ * nscd/connections.c (restart): Try to preserve the process name
+ by reading the /proc/self/exe symlink and using the return name.
+ Patch by Jeff Bastian <jbastian@redhat.com>.
+
+2009-03-15 Ulrich Drepper <drepper@redhat.com>
+
+ [BZ #9733]
+ * elf/dl-load.c (_dl_map_object_from_fd): Only call audit hooks
+ if we are not loading a new audit library.
+ * elf/dl-reloc (_dl_relocate_object): Third parameter is now a bitmask.
+ Only use profiling trampoline for auditing if we are not relocating
+ an audit library.
+ * elf/dl-open.c (dl_open_worker): Adjust _dl_relocate_object call.
+ * elf/rtld.c: Likewise.
+ * sysdeps/generic/ldsodefs.h: Adjust _dl_relocate_object prototype.
+
+ * elf/rtld.c (dl_main): Extend help message for --audit option.
+
+ [BZ #9759]
+ * dirent/dirent.h: Adjust prototypes of scandir, scandir64, alphasort,
+ alphasort64, versionsort, and versionsort64 to POSIX 2008.
+ * dirent/alphasort.c: Adjust implementation to type change.
+ * dirent/alphasort64.c: Likewise.
+ * dirent/scandir.c: Likewise.
+ * dirent/versionsort.c: Likewise.
+ * dirent/versionsort64.c: Likewise.
+ * sysdeps/wordsize-64/alphasort.c: Add hack to hide alphasort64
+ declaration.
+ * sysdeps/wordsize-64/versionsort.c: Add hack to hide versionsort64
+ declaration.
+
+ [BZ #9880]
+ * inet/inet6_rth.c (inet6_rth_reverse): Compute number of segments
+ correctly. Set segleft member in output as required.
+ Patch partly by Yang Hongyang <yanghy@cn.fujitsu.com>.
+ * inet/tst-inet6_rth.c (do_test): Add tests for inet6_rth_reverse.
+
+ [BZ #9881]
+ * inet/inet6_rth.c (inet6_rth_add): Add some error checking.
+ Patch mostly by Yang Hongyang <yanghy@cn.fujitsu.com>.
+ * inet/Makefile (tests): Add tst-inet6_rth.
+ * inet/tst-inet6_rth.c: New file.
+
+ [BZ #5807]
+ * string/strlen.c (strlen): Fix omission in the expression to test
+ for NUL bytes.
+
+2009-03-14 Ulrich Drepper <drepper@redhat.com>
+
+ * crypt/sha256test.c (main): Perform 100,000 'a' test in a second way.
+
+ * elf/dl-runtime.c (reloc_offset): Define.
+ (reloc_index): Define.
+ (_dl_fixup): Rename reloc_offset parameter to reloc_arg.
+ (_dl_fixup_profile): Likewise. Use reloc_index instead of
+ computing index from reloc_offset.
+ (_dl_call_pltexit): Likewise.
+ * sysdeps/x86_64/dl-trampoline.S (_dl_runtime_resolve): Just pass
+ the relocation index to _dl_fixup.
+ (_dl_runtime_profile): Likewise for _dl_fixup_profile and
+ _dl_call_pltexit.
+ * sysdeps/x86_64/dl-runtime.c: New file.
+
+ [BZ #9893]
+ * sysdeps/x86_64/dl-trampoline.S (_dl_runtime_profile): Fix
+ alignment of La_x86_64_regs. Store xmm parameters.
+ Patch mostly by Jiri Olsa <olsajiri@gmail.com>.
+
+ [BZ #9913]
+ * string/strverscmp.c (__strverscmp): Fix case of different digits
+ in fractional part of string.
+ Patch by Jingyu Liu <jyliu@fortinet.com>.
+ * string/Makefile (tests): Add tst-svc2.
+ * string/tst-svc2.c: New file.
+
+ * string/strverscmp.c (__strverscmp): Optimize size of tables.
+
+ * locale/iso-639.def: Add Min Nan.
+
+2009-03-11 Carlos Eduardo Seo <cseo@linux.vnet.ibm.com>
+
+ [BZ #9948]
+ * elf/dl-sysdep.c (_dl_show_auxv): Add support for AT_BASE_PLATFORM.
+
+2009-03-14 Ulrich Drepper <drepper@redhat.com>
+
+ * elf/dl-sysdep.c (auxvars): Compress data structure.
+
+ * sysdeps/i386/dl-machine.h (elf_machine_rel): Implement
+ STT_GNU_IFUNC handling.
+ (elf_machine_rela): Likewise.
+
+2009-03-13 Ulrich Drepper <drepper@redhat.com>
+
+ * config.h.in (USE_MULTIARCH): Define.
+ * configure.in: Handle --enable-multi-arch.
+ * elf/dl-runtime.c (_dl_fixup): Handle STT_GNU_IFUNC.
+ (_dl_fixup_profile): Likewise.
+ * elf/do-lookup.c (dl_lookup_x): Likewise.
+ * sysdeps/x86_64/dl-machine.h: Handle STT_GNU_IFUNC.
+ * elf/elf.h (STT_GNU_IFUNC): Define.
+ * include/libc-symbols.h (libc_ifunc): Define.
+ * sysdeps/x86_64/cacheinfo.c: If USE_MULTIARCH is defined, use the
+ framework in init-arch.h to get CPUID values.
+ * sysdeps/x86_64/multiarch/Makefile: New file.
+ * sysdeps/x86_64/multiarch/init-arch.c: New file.
+ * sysdeps/x86_64/multiarch/init-arch.h: New file.
+ * sysdeps/x86_64/multiarch/sched_cpucount.c: New file.
+
+ * config.make.in (experimental-malloc): Define.
+ * configure.in: Handle --enable-experimental-malloc.
+ * malloc/Makefile: Handle experimental-malloc flag.
+ * malloc/malloc.c: Implement PER_THREAD and ATOMIC_FASTBINS features.
+ * malloc/arena.c: Likewise.
+ * malloc/hooks.c: Likewise.
+ * malloc/malloc.h: Define M_ARENA_TEST and M_ARENA_MAX.
+
+2009-03-11 Ulrich Drepper <drepper@redhat.com>
+
+ * sysdeps/x86_64/dl-machine.h (elf_machine_rela): Add branch
+ prediction. A few size optimizations.
+
2009-03-10 Ulrich Drepper <drepper@redhat.com>
* time/tzset.c: Optimize a bit for size.
diff --git a/NEWS b/NEWS
index 2689db304e..686d5dfdc4 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,4 @@
-GNU C Library NEWS -- history of user-visible changes. 2009-3-8
+GNU C Library NEWS -- history of user-visible changes. 2009-3-14
Copyright (C) 1992-2008, 2009 Free Software Foundation, Inc.
See the end for copying conditions.
@@ -7,7 +7,7 @@ using `glibc' in the "product" field.
Version 2.10
-* New Linux interface: accept4
+* New Linux interfaces: accept4, fallocate, fallocate64.
* Correct declarations of string function when used in C++ code. This
could lead to compile error for invalid C++ code.
@@ -21,6 +21,11 @@ Version 2.10
* New ISO C++1x interfaces: quick_exit, at_quick_exit
Implemented by Ulrich Drepper.
+* Support for selecting between multiple function definitions at runtime
+ using STT_GNU_IFUNC symbols. Implemented by Ulrich Drepper.
+
+* New locale: nan_TW@latin
+
Version 2.9
diff --git a/config.h.in b/config.h.in
index b5abb10187..8dbc224a7d 100644
--- a/config.h.in
+++ b/config.h.in
@@ -189,6 +189,9 @@
/* Define if __stack_chk_guard canary should be randomized at program startup. */
#undef ENABLE_STACKGUARD_RANDOMIZE
+/* Define if multi-arch DSOs should be generated. */
+#undef USE_MULTIARCH
+
/*
*/
diff --git a/config.make.in b/config.make.in
index aa73466713..6da6362f24 100644
--- a/config.make.in
+++ b/config.make.in
@@ -70,6 +70,7 @@ versioning = @VERSIONING@
oldest-abi = @oldest_abi@
no-whole-archive = @no_whole_archive@
exceptions = @exceptions@
+multi-arch = @multi_arch@
mach-interface-list = @mach_interface_list@
@@ -78,6 +79,8 @@ have-ksh = @libc_cv_have_ksh@
sizeof-long-double = @sizeof_long_double@
+experimental-malloc = @experimental_malloc@
+
# Configuration options.
build-static = @static@
build-shared = @shared@
diff --git a/configure b/configure
index c5c6dc4789..69af8525be 100755
--- a/configure
+++ b/configure
@@ -660,6 +660,8 @@ oldest_abi
bindnow
force_install
all_warnings
+multi_arch
+experimental_malloc
build
build_cpu
build_vendor
@@ -1380,6 +1382,10 @@ Optional Features:
--enable-kernel=VERSION compile for compatibility with kernel not older than
VERSION
--enable-all-warnings enable all useful warnings gcc can issue
+ --enable-multi-arch enable single DSO with optimizations for multiple
+ architectures
+ --enable-experimental-malloc
+ enable experimental malloc features
Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
@@ -2173,6 +2179,29 @@ fi
+# Check whether --enable-multi-arch was given.
+if test "${enable_multi_arch+set}" = set; then
+ enableval=$enable_multi_arch; multi_arch=$enableval
+else
+ multi_arch=no
+fi
+
+if test x"$multi_arch" = xyes; then
+ cat >>confdefs.h <<\_ACEOF
+#define USE_MULTIARCH 1
+_ACEOF
+
+ multi_arch_d=/multiarch
+fi
+
+
+# Check whether --enable-experimental-malloc was given.
+if test "${enable_experimental_malloc+set}" = set; then
+ enableval=$enable_experimental_malloc; experimental_malloc=$enableval
+fi
+
+
+
# Make sure we can run config.sub.
$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
{ { echo "$as_me:$LINENO: error: cannot run $SHELL $ac_aux_dir/config.sub" >&5
@@ -2627,7 +2656,7 @@ for b in $base ''; do
test "$v" = / && continue
for o in /$ostry ''; do
test "$o" = / && continue
- for m in $mach ''; do
+ for m in $multi_arch_d $mach ''; do
for d in $add_ons_pfx ''; do
for a in $add_ons_sfx ''; do
if test -n "$m0$m0sub$b$v$o$m$msub"; then
@@ -5684,6 +5713,37 @@ _ACEOF
fi
+# For the multi-arch option we need support in the assembler.
+if test "$multi_arch" = yes; then
+ if test "x$libc_cv_asm_type_prefix" != xno; then
+{ echo "$as_me:$LINENO: checking for assembler gnu_indirect_function symbol type support" >&5
+echo $ECHO_N "checking for assembler gnu_indirect_function symbol type support... $ECHO_C" >&6; }
+if test "${libc_cv_asm_gnu_indirect_function+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat > conftest.s <<EOF
+.type foo,%gnu_indirect_function
+EOF
+if ${CC-cc} -c $ASFLAGS conftest.s 1>&5 2>&5;
+then
+ libc_cv_asm_gnu_indirect_function=yes
+else
+ libc_cv_asm_gnu_indirect_function=no
+fi
+rm -f conftest*
+fi
+{ echo "$as_me:$LINENO: result: $libc_cv_asm_gnu_indirect_function" >&5
+echo "${ECHO_T}$libc_cv_asm_gnu_indirect_function" >&6; }
+ else
+ libc_cv_asm_gnu_indirect_function=no
+ fi
+ if test x"$libc_cv_asm_gnu_indirect_function" != xyes; then
+ { { echo "$as_me:$LINENO: error: --enable-multi-arch support requires assembler and linker support" >&5
+echo "$as_me: error: --enable-multi-arch support requires assembler and linker support" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+fi
+
{ echo "$as_me:$LINENO: checking for .symver assembler directive" >&5
echo $ECHO_N "checking for .symver assembler directive... $ECHO_C" >&6; }
if test "${libc_cv_asm_symver_directive+set}" = set; then
@@ -9184,6 +9244,8 @@ oldest_abi!$oldest_abi$ac_delim
bindnow!$bindnow$ac_delim
force_install!$force_install$ac_delim
all_warnings!$all_warnings$ac_delim
+multi_arch!$multi_arch$ac_delim
+experimental_malloc!$experimental_malloc$ac_delim
build!$build$ac_delim
build_cpu!$build_cpu$ac_delim
build_vendor!$build_vendor$ac_delim
@@ -9235,8 +9297,6 @@ libc_cv_have_bash2!$libc_cv_have_bash2$ac_delim
KSH!$KSH$ac_delim
libc_cv_have_ksh!$libc_cv_have_ksh$ac_delim
AWK!$AWK$ac_delim
-PERL!$PERL$ac_delim
-INSTALL_INFO!$INSTALL_INFO$ac_delim
_ACEOF
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then
@@ -9278,6 +9338,8 @@ _ACEOF
ac_delim='%!_!# '
for ac_last_try in false false false false false :; do
cat >conf$$subs.sed <<_ACEOF
+PERL!$PERL$ac_delim
+INSTALL_INFO!$INSTALL_INFO$ac_delim
BISON!$BISON$ac_delim
VERSIONING!$VERSIONING$ac_delim
libc_cv_cc_with_libunwind!$libc_cv_cc_with_libunwind$ac_delim
@@ -9334,7 +9396,7 @@ LIBOBJS!$LIBOBJS$ac_delim
LTLIBOBJS!$LTLIBOBJS$ac_delim
_ACEOF
- if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 54; then
+ if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 56; then
break
elif $ac_last_try; then
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
diff --git a/configure.in b/configure.in
index d7b22f3a3b..4015722d5a 100644
--- a/configure.in
+++ b/configure.in
@@ -254,6 +254,24 @@ AC_ARG_ENABLE([all-warnings],
[])
AC_SUBST(all_warnings)
+AC_ARG_ENABLE([multi-arch],
+ AC_HELP_STRING([--enable-multi-arch],
+ [enable single DSO with optimizations for multiple architectures]),
+ [multi_arch=$enableval],
+ [multi_arch=no])
+if test x"$multi_arch" = xyes; then
+ AC_DEFINE(USE_MULTIARCH)
+ multi_arch_d=/multiarch
+fi
+AC_SUBST(multi_arch)
+
+AC_ARG_ENABLE([experimental-malloc],
+ AC_HELP_STRING([--enable-experimental-malloc],
+ [enable experimental malloc features]),
+ [experimental_malloc=$enableval],
+ [])
+AC_SUBST(experimental_malloc)
+
AC_CANONICAL_HOST
# The way shlib-versions is used to generate soversions.mk uses a
@@ -608,7 +626,7 @@ for b in $base ''; do
test "$v" = / && continue
for o in /$ostry ''; do
test "$o" = / && continue
- for m in $mach ''; do
+ for m in $multi_arch_d $mach ''; do
for d in $add_ons_pfx ''; do
for a in $add_ons_sfx ''; do
if test -n "$m0$m0sub$b$v$o$m$msub"; then
@@ -1157,6 +1175,29 @@ if test "x$libc_cv_asm_type_prefix" != xno; then
AC_DEFINE_UNQUOTED(ASM_TYPE_DIRECTIVE_PREFIX, ${libc_cv_asm_type_prefix})
fi
+# For the multi-arch option we need support in the assembler.
+if test "$multi_arch" = yes; then
+ if test "x$libc_cv_asm_type_prefix" != xno; then
+AC_CACHE_CHECK([for assembler gnu_indirect_function symbol type support],
+ libc_cv_asm_gnu_indirect_function, [dnl
+cat > conftest.s <<EOF
+.type foo,%gnu_indirect_function
+EOF
+if ${CC-cc} -c $ASFLAGS conftest.s 1>&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD;
+then
+ libc_cv_asm_gnu_indirect_function=yes
+else
+ libc_cv_asm_gnu_indirect_function=no
+fi
+rm -f conftest*])
+ else
+ libc_cv_asm_gnu_indirect_function=no
+ fi
+ if test x"$libc_cv_asm_gnu_indirect_function" != xyes; then
+ AC_MSG_ERROR([--enable-multi-arch support requires assembler and linker support])
+ fi
+fi
+
AC_CACHE_CHECK(for .symver assembler directive, libc_cv_asm_symver_directive,
[cat > conftest.s <<EOF
${libc_cv_dot_text}
diff --git a/crypt/sha256test.c b/crypt/sha256test.c
index b13a3c511e..39e80307c7 100644
--- a/crypt/sha256test.c
+++ b/crypt/sha256test.c
@@ -84,7 +84,17 @@ main (void)
"\xf1\x80\x9a\x48\xa4\x97\x20\x0e\x04\x6d\x39\xcc\xc7\x11\x2c\xd0";
if (memcmp (expected, sum, 32) != 0)
{
- printf ("test %d failed\n", cnt);
+ printf ("test %d failed\n", cnt++);
+ result = 1;
+ }
+
+ __sha256_init_ctx (&ctx);
+ for (int i = 0; i < 100000; ++i)
+ __sha256_process_bytes (buf, 10, &ctx);
+ __sha256_finish_ctx (&ctx, sum);
+ if (memcmp (expected, sum, 32) != 0)
+ {
+ printf ("test %d failed\n", cnt++);
result = 1;
}
diff --git a/dirent/alphasort.c b/dirent/alphasort.c
index b378626f6c..360b17c5a0 100644
--- a/dirent/alphasort.c
+++ b/dirent/alphasort.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1992, 1997, 1998, 2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -20,8 +20,7 @@
#include <string.h>
int
-alphasort (const void *a, const void *b)
+alphasort (const struct dirent **a, const struct dirent **b)
{
- return strcoll ((*(const struct dirent **) a)->d_name,
- (*(const struct dirent **) b)->d_name);
+ return strcoll ((*a)->d_name, (*b)->d_name);
}
diff --git a/dirent/alphasort64.c b/dirent/alphasort64.c
index fe84aec2f1..f91cba5088 100644
--- a/dirent/alphasort64.c
+++ b/dirent/alphasort64.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1997, 1998, 2000 Free Software Foundation, Inc.
+/* Copyright (C) 1992, 1997, 1998, 2000, 2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -20,8 +20,7 @@
#include <string.h>
int
-alphasort64 (const void *a, const void *b)
+alphasort64 (const struct dirent64 **a, const struct dirent64 **b)
{
- return strcoll ((*(const struct dirent64 **) a)->d_name,
- (*(const struct dirent64 **) b)->d_name);
+ return strcoll ((*a)->d_name, (*b)->d_name);
}
diff --git a/dirent/dirent.h b/dirent/dirent.h
index cb6d0bc2d5..369ccdc9ee 100644
--- a/dirent/dirent.h
+++ b/dirent/dirent.h
@@ -252,7 +252,8 @@ extern int dirfd (DIR *__dirp) __THROW __nonnull ((1));
extern int scandir (__const char *__restrict __dir,
struct dirent ***__restrict __namelist,
int (*__selector) (__const struct dirent *),
- int (*__cmp) (__const void *, __const void *))
+ int (*__cmp) (__const struct dirent **,
+ __const struct dirent **))
__nonnull ((1, 2));
# else
# ifdef __REDIRECT
@@ -260,7 +261,8 @@ extern int __REDIRECT (scandir,
(__const char *__restrict __dir,
struct dirent ***__restrict __namelist,
int (*__selector) (__const struct dirent *),
- int (*__cmp) (__const void *, __const void *)),
+ int (*__cmp) (__const struct dirent **,
+ __const struct dirent **)),
scandir64) __nonnull ((1, 2));
# else
# define scandir scandir64
@@ -273,18 +275,21 @@ extern int __REDIRECT (scandir,
extern int scandir64 (__const char *__restrict __dir,
struct dirent64 ***__restrict __namelist,
int (*__selector) (__const struct dirent64 *),
- int (*__cmp) (__const void *, __const void *))
+ int (*__cmp) (__const struct dirent64 **,
+ __const struct dirent64 **))
__nonnull ((1, 2));
# endif
/* Function to compare two `struct dirent's alphabetically. */
# ifndef __USE_FILE_OFFSET64
-extern int alphasort (__const void *__e1, __const void *__e2)
+extern int alphasort (__const struct dirent **__e1,
+ __const struct dirent **__e2)
__THROW __attribute_pure__ __nonnull ((1, 2));
# else
# ifdef __REDIRECT
extern int __REDIRECT_NTH (alphasort,
- (__const void *__e1, __const void *__e2),
+ (__const struct dirent **__e1,
+ __const struct dirent **__e2),
alphasort64) __attribute_pure__ __nonnull ((1, 2));
# else
# define alphasort alphasort64
@@ -292,51 +297,54 @@ extern int __REDIRECT_NTH (alphasort,
# endif
# if defined __USE_GNU && defined __USE_LARGEFILE64
-extern int alphasort64 (__const void *__e1, __const void *__e2)
+extern int alphasort64 (__const struct dirent64 **__e1,
+ __const struct dirent64 **__e2)
__THROW __attribute_pure__ __nonnull ((1, 2));
# endif
+#endif /* Use BSD or misc or XPG7. */
-# if defined __USE_BSD || defined __USE_MISC
+#if defined __USE_BSD || defined __USE_MISC
/* Read directory entries from FD into BUF, reading at most NBYTES.
Reading starts at offset *BASEP, and *BASEP is updated with the new
position after reading. Returns the number of bytes read; zero when at
end of directory; or -1 for errors. */
-# ifndef __USE_FILE_OFFSET64
+# ifndef __USE_FILE_OFFSET64
extern __ssize_t getdirentries (int __fd, char *__restrict __buf,
size_t __nbytes,
__off_t *__restrict __basep)
__THROW __nonnull ((2, 4));
-# else
-# ifdef __REDIRECT
+# else
+# ifdef __REDIRECT
extern __ssize_t __REDIRECT_NTH (getdirentries,
(int __fd, char *__restrict __buf,
size_t __nbytes,
__off64_t *__restrict __basep),
getdirentries64) __nonnull ((2, 4));
-# else
-# define getdirentries getdirentries64
-# endif
+# else
+# define getdirentries getdirentries64
# endif
+# endif
-# ifdef __USE_LARGEFILE64
+# ifdef __USE_LARGEFILE64
extern __ssize_t getdirentries64 (int __fd, char *__restrict __buf,
size_t __nbytes,
__off64_t *__restrict __basep)
__THROW __nonnull ((2, 4));
-# endif
-# endif /* Use BSD or misc. */
-#endif /* Use BSD or misc or XPG7. */
+# endif
+#endif /* Use BSD or misc. */
#ifdef __USE_GNU
/* Function to compare two `struct dirent's by name & version. */
# ifndef __USE_FILE_OFFSET64
-extern int versionsort (__const void *__e1, __const void *__e2)
+extern int versionsort (__const struct dirent **__e1,
+ __const struct dirent **__e2)
__THROW __attribute_pure__ __nonnull ((1, 2));
# else
# ifdef __REDIRECT
extern int __REDIRECT_NTH (versionsort,
- (__const void *__e1, __const void *__e2),
+ (__const struct dirent **__e1,
+ __const struct dirent **__e2),
versionsort64)
__attribute_pure__ __nonnull ((1, 2));
# else
@@ -345,7 +353,8 @@ extern int __REDIRECT_NTH (versionsort,
# endif
# ifdef __USE_LARGEFILE64
-extern int versionsort64 (__const void *__e1, __const void *__e2)
+extern int versionsort64 (__const struct dirent64 **__e1,
+ __const struct dirent64 **__e2)
__THROW __attribute_pure__ __nonnull ((1, 2));
# endif
#endif /* Use GNU. */
diff --git a/dirent/scandir.c b/dirent/scandir.c
index 89bd9e94fe..2e03578a3c 100644
--- a/dirent/scandir.c
+++ b/dirent/scandir.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992-1998, 2000, 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 1992-1998,2000,2002,2003,2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -57,7 +57,7 @@ SCANDIR (dir, namelist, select, cmp)
const char *dir;
DIRENT_TYPE ***namelist;
int (*select) (const DIRENT_TYPE *);
- int (*cmp) (const void *, const void *);
+ int (*cmp) (const DIRENT_TYPE **, const DIRENT_TYPE **);
{
DIR *dp = __opendir (dir);
DIRENT_TYPE **v = NULL;
@@ -134,7 +134,8 @@ SCANDIR (dir, namelist, select, cmp)
{
/* Sort the list if we have a comparison function to sort with. */
if (cmp != NULL)
- qsort (v, c.cnt, sizeof (*v), cmp);
+ qsort (v, c.cnt, sizeof (*v),
+ (int (*) (const void *, const void *)) cmp);
*namelist = v;
}
diff --git a/dirent/scandir64.c b/dirent/scandir64.c
index 68608de9a0..b7bd654658 100644
--- a/dirent/scandir64.c
+++ b/dirent/scandir64.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 Free Software Foundation, Inc.
+/* Copyright (C) 2000, 2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -25,6 +25,7 @@
int scandir64 (__const char *__restrict __dir,
struct dirent64 ***__restrict __namelist,
int (*__selector) (__const struct dirent64 *),
- int (*__cmp) (__const void *, __const void *));
+ int (*__cmp) (__const struct dirent64 **,
+ __const struct dirent64 **));
#include <dirent/scandir.c>
diff --git a/dirent/versionsort.c b/dirent/versionsort.c
index d986981bce..f7bd717848 100644
--- a/dirent/versionsort.c
+++ b/dirent/versionsort.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1992, 1997, 1998, 2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -20,8 +20,7 @@
#include <string.h>
int
-versionsort (const void *a, const void *b)
+versionsort (const struct dirent **a, const struct dirent **b)
{
- return __strverscmp ((*(const struct dirent **) a)->d_name,
- (*(const struct dirent **) b)->d_name);
+ return __strverscmp ((*a)->d_name, (*b)->d_name);
}
diff --git a/dirent/versionsort64.c b/dirent/versionsort64.c
index e471827023..5b2833111b 100644
--- a/dirent/versionsort64.c
+++ b/dirent/versionsort64.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1997, 1998, 2000 Free Software Foundation, Inc.
+/* Copyright (C) 1992, 1997, 1998, 2000, 2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -20,8 +20,7 @@
#include <string.h>
int
-versionsort64 (const void *a, const void *b)
+versionsort64 (const struct dirent64 **a, const struct dirent64 **b)
{
- return __strverscmp ((*(const struct dirent64 **) a)->d_name,
- (*(const struct dirent64 **) b)->d_name);
+ return __strverscmp ((*a)->d_name, (*b)->d_name);
}
diff --git a/elf/dl-load.c b/elf/dl-load.c
index c77c259156..0deb51e445 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -941,7 +941,8 @@ _dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp,
{
#ifdef SHARED
/* Auditing checkpoint: we are going to add new objects. */
- if (__builtin_expect (GLRO(dl_naudit) > 0, 0))
+ if ((mode & __RTLD_AUDIT) == 0
+ && __builtin_expect (GLRO(dl_naudit) > 0, 0))
{
struct link_map *head = GL(dl_ns)[nsid]._ns_loaded;
/* Do not call the functions for any auditing object. */
diff --git a/elf/dl-open.c b/elf/dl-open.c
index f825aa0437..75dc7bc406 100644
--- a/elf/dl-open.c
+++ b/elf/dl-open.c
@@ -1,5 +1,5 @@
/* Load a shared object at runtime, relocate it, and run its initializer.
- Copyright (C) 1996-2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+ Copyright (C) 1996-2007, 2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -207,7 +207,6 @@ dl_open_worker (void *a)
const char *file = args->file;
int mode = args->mode;
struct link_map *new;
- int lazy;
unsigned int i;
bool any_tls = false;
struct link_map *call_map = NULL;
@@ -366,7 +365,9 @@ dl_open_worker (void *a)
_dl_debug_state ();
/* Only do lazy relocation if `LD_BIND_NOW' is not set. */
- lazy = (mode & RTLD_BINDING_MASK) == RTLD_LAZY && GLRO(dl_lazy);
+ int reloc_mode = mode & __RTLD_AUDIT;
+ if (GLRO(dl_lazy))
+ reloc_mode |= mode & RTLD_LAZY;
/* Relocate the objects loaded. We do this in reverse order so that copy
relocs of earlier objects overwrite the data written by later objects. */
@@ -388,7 +389,7 @@ dl_open_worker (void *a)
start the profiling. */
struct link_map *old_profile_map = GL(dl_profile_map);
- _dl_relocate_object (l, l->l_scope, 1, 1);
+ _dl_relocate_object (l, l->l_scope, reloc_mode | RTLD_LAZY, 1);
if (old_profile_map == NULL && GL(dl_profile_map) != NULL)
{
@@ -401,7 +402,7 @@ dl_open_worker (void *a)
}
else
#endif
- _dl_relocate_object (l, l->l_scope, lazy, 0);
+ _dl_relocate_object (l, l->l_scope, reloc_mode, 0);
}
if (l == new)
diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c
index a303cb4ce6..28f08de3e7 100644
--- a/elf/dl-reloc.c
+++ b/elf/dl-reloc.c
@@ -1,5 +1,5 @@
/* Relocate a shared object and resolve its references to other loaded objects.
- Copyright (C) 1995-2004, 2005, 2006, 2008 Free Software Foundation, Inc.
+ Copyright (C) 1995-2006, 2008, 2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -151,7 +151,7 @@ _dl_nothread_init_static_tls (struct link_map *map)
void
_dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
- int lazy, int consider_profiling)
+ int reloc_mode, int consider_profiling)
{
struct textrels
{
@@ -162,10 +162,12 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
} *textrels = NULL;
/* Initialize it to make the compiler happy. */
const char *errstring = NULL;
+ int lazy = reloc_mode & RTLD_LAZY;
#ifdef SHARED
/* If we are auditing, install the same handlers we need for profiling. */
- consider_profiling |= GLRO(dl_audit) != NULL;
+ if ((reloc_mode & __RTLD_AUDIT) == 0)
+ consider_profiling |= GLRO(dl_audit) != NULL;
#elif defined PROF
/* Never use dynamic linker profiling for gprof profiling code. */
# define consider_profiling 0
diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c
index 968e293409..93c8f29d39 100644
--- a/elf/dl-runtime.c
+++ b/elf/dl-runtime.c
@@ -1,5 +1,5 @@
/* On-demand PLT fixup for shared objects.
- Copyright (C) 1995-2006, 2007 Free Software Foundation, Inc.
+ Copyright (C) 1995-2006, 2007, 2008, 2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -46,6 +46,12 @@
# define ARCH_FIXUP_ATTRIBUTE
#endif
+#ifndef reloc_offset
+# define reloc_offset reloc_arg
+# define reloc_index reloc_arg / sizeof (PLTREL)
+#endif
+
+
/* This function is called through a special trampoline from the PLT the
first time each PLT entry is called. We must perform the relocation
@@ -63,7 +69,7 @@ _dl_fixup (
# endif
/* GKM FIXME: Fix trampoline to pass bounds so we can do
without the `__unbounded' qualifier. */
- struct link_map *__unbounded l, ElfW(Word) reloc_offset)
+ struct link_map *__unbounded l, ElfW(Word) reloc_arg)
{
const ElfW(Sym) *const symtab
= (const void *) D_PTR (l, l_info[DT_SYMTAB]);
@@ -130,6 +136,9 @@ _dl_fixup (
/* And now perhaps the relocation addend. */
value = elf_machine_plt_value (l, reloc, value);
+ if (__builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC, 0))
+ value = ((DL_FIXUP_VALUE_TYPE (*) (void)) value) ();
+
/* Finally, fix up the plt itself. */
if (__builtin_expect (GLRO(dl_bind_not), 0))
return value;
@@ -139,22 +148,20 @@ _dl_fixup (
#endif
#if !defined PROF && !defined ELF_MACHINE_NO_PLT && !__BOUNDED_POINTERS__
-
DL_FIXUP_VALUE_TYPE
__attribute ((noinline)) ARCH_FIXUP_ATTRIBUTE
_dl_profile_fixup (
#ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS
ELF_MACHINE_RUNTIME_FIXUP_ARGS,
#endif
- struct link_map *l, ElfW(Word) reloc_offset,
+ struct link_map *l, ElfW(Word) reloc_arg,
ElfW(Addr) retaddr, void *regs, long int *framesizep)
{
void (*mcount_fct) (ElfW(Addr), ElfW(Addr)) = INTUSE(_dl_mcount);
/* This is the address in the array where we store the result of previous
relocations. */
- struct reloc_result *reloc_result
- = &l->l_reloc_result[reloc_offset / sizeof (PLTREL)];
+ struct reloc_result *reloc_result = &l->l_reloc_result[reloc_index];
DL_FIXUP_VALUE_TYPE *resultp = &reloc_result->addr;
DL_FIXUP_VALUE_TYPE value = *resultp;
@@ -215,12 +222,21 @@ _dl_profile_fixup (
defsym != NULL
? LOOKUP_VALUE_ADDRESS (result)
+ defsym->st_value : 0);
+
+ if (__builtin_expect (ELFW(ST_TYPE) (defsym->st_info)
+ == STT_GNU_IFUNC, 0))
+ value = ((DL_FIXUP_VALUE_TYPE (*) (void)) value) ();
}
else
{
/* We already found the symbol. The module (and therefore its load
address) is also known. */
value = DL_FIXUP_MAKE_VALUE (l, l->l_addr + refsym->st_value);
+
+ if (__builtin_expect (ELFW(ST_TYPE) (refsym->st_info)
+ == STT_GNU_IFUNC, 0))
+ value = ((DL_FIXUP_VALUE_TYPE (*) (void)) value) ();
+
result = l;
}
/* And now perhaps the relocation addend. */
@@ -403,7 +419,7 @@ _dl_profile_fixup (
#include <stdio.h>
void
ARCH_FIXUP_ATTRIBUTE
-_dl_call_pltexit (struct link_map *l, ElfW(Word) reloc_offset,
+_dl_call_pltexit (struct link_map *l, ElfW(Word) reloc_arg,
const void *inregs, void *outregs)
{
#ifdef SHARED
@@ -411,8 +427,7 @@ _dl_call_pltexit (struct link_map *l, ElfW(Word) reloc_offset,
relocations. */
// XXX Maybe the bound information must be stored on the stack since
// XXX with bind_not a new value could have been stored in the meantime.
- struct reloc_result *reloc_result
- = &l->l_reloc_result[reloc_offset / sizeof (PLTREL)];
+ struct reloc_result *reloc_result = &l->l_reloc_result[reloc_index];
ElfW(Sym) *defsym = ((ElfW(Sym) *) D_PTR (reloc_result->bound,
l_info[DT_SYMTAB])
+ reloc_result->boundndx);
diff --git a/elf/dl-sysdep.c b/elf/dl-sysdep.c
index a44bee7086..db1001253c 100644
--- a/elf/dl-sysdep.c
+++ b/elf/dl-sysdep.c
@@ -269,36 +269,37 @@ _dl_show_auxv (void)
{
static const struct
{
- const char label[20];
- enum { unknown = 0, dec, hex, str, ignore } form;
+ const char label[17];
+ enum { unknown = 0, dec, hex, str, ignore } form : 8;
} auxvars[] =
{
- [AT_EXECFD - 2] = { "AT_EXECFD: ", dec },
- [AT_EXECFN - 2] = { "AT_EXECFN: ", str },
- [AT_PHDR - 2] = { "AT_PHDR: 0x", hex },
- [AT_PHENT - 2] = { "AT_PHENT: ", dec },
- [AT_PHNUM - 2] = { "AT_PHNUM: ", dec },
- [AT_PAGESZ - 2] = { "AT_PAGESZ: ", dec },
- [AT_BASE - 2] = { "AT_BASE: 0x", hex },
- [AT_FLAGS - 2] = { "AT_FLAGS: 0x", hex },
- [AT_ENTRY - 2] = { "AT_ENTRY: 0x", hex },
- [AT_NOTELF - 2] = { "AT_NOTELF: ", hex },
- [AT_UID - 2] = { "AT_UID: ", dec },
- [AT_EUID - 2] = { "AT_EUID: ", dec },
- [AT_GID - 2] = { "AT_GID: ", dec },
- [AT_EGID - 2] = { "AT_EGID: ", dec },
- [AT_PLATFORM - 2] = { "AT_PLATFORM: ", str },
- [AT_HWCAP - 2] = { "AT_HWCAP: ", hex },
- [AT_CLKTCK - 2] = { "AT_CLKTCK: ", dec },
- [AT_FPUCW - 2] = { "AT_FPUCW: ", hex },
- [AT_DCACHEBSIZE - 2] = { "AT_DCACHEBSIZE: 0x", hex },
- [AT_ICACHEBSIZE - 2] = { "AT_ICACHEBSIZE: 0x", hex },
- [AT_UCACHEBSIZE - 2] = { "AT_UCACHEBSIZE: 0x", hex },
- [AT_IGNOREPPC - 2] = { "AT_IGNOREPPC", ignore },
- [AT_SECURE - 2] = { "AT_SECURE: ", dec },
- [AT_SYSINFO - 2] = { "AT_SYSINFO: 0x", hex },
- [AT_SYSINFO_EHDR - 2] = { "AT_SYSINFO_EHDR: 0x", hex },
- [AT_RANDOM - 2] = { "AT_RANDOM: 0x", hex },
+ [AT_EXECFD - 2] = { "EXECFD: ", dec },
+ [AT_EXECFN - 2] = { "EXECFN: ", str },
+ [AT_PHDR - 2] = { "PHDR: 0x", hex },
+ [AT_PHENT - 2] = { "PHENT: ", dec },
+ [AT_PHNUM - 2] = { "PHNUM: ", dec },
+ [AT_PAGESZ - 2] = { "PAGESZ: ", dec },
+ [AT_BASE - 2] = { "BASE: 0x", hex },
+ [AT_FLAGS - 2] = { "FLAGS: 0x", hex },
+ [AT_ENTRY - 2] = { "ENTRY: 0x", hex },
+ [AT_NOTELF - 2] = { "NOTELF: ", hex },
+ [AT_UID - 2] = { "UID: ", dec },
+ [AT_EUID - 2] = { "EUID: ", dec },
+ [AT_GID - 2] = { "GID: ", dec },
+ [AT_EGID - 2] = { "EGID: ", dec },
+ [AT_PLATFORM - 2] = { "PLATFORM: ", str },
+ [AT_HWCAP - 2] = { "HWCAP: ", hex },
+ [AT_CLKTCK - 2] = { "CLKTCK: ", dec },
+ [AT_FPUCW - 2] = { "FPUCW: ", hex },
+ [AT_DCACHEBSIZE - 2] = { "DCACHEBSIZE: 0x", hex },
+ [AT_ICACHEBSIZE - 2] = { "ICACHEBSIZE: 0x", hex },
+ [AT_UCACHEBSIZE - 2] = { "UCACHEBSIZE: 0x", hex },
+ [AT_IGNOREPPC - 2] = { "IGNOREPPC", ignore },
+ [AT_SECURE - 2] = { "SECURE: ", dec },
+ [AT_BASE_PLATFORM - 2] = { "BASE_PLATFORM:", str },
+ [AT_SYSINFO - 2] = { "SYSINFO: 0x", hex },
+ [AT_SYSINFO_EHDR - 2] = { "SYSINFO_EHDR: 0x", hex },
+ [AT_RANDOM - 2] = { "RANDOM: 0x", hex },
};
unsigned int idx = (unsigned int) (av->a_type - 2);
@@ -327,7 +328,7 @@ _dl_show_auxv (void)
val = _itoa ((unsigned long int) av->a_un.a_val,
buf + sizeof buf - 1, 16, 0);
- _dl_printf ("%s%s\n", auxvars[idx].label, val);
+ _dl_printf ("AT_%s%s\n", auxvars[idx].label, val);
continue;
}
diff --git a/elf/do-lookup.h b/elf/do-lookup.h
index ebb9ed5b47..41e5fc137c 100644
--- a/elf/do-lookup.h
+++ b/elf/do-lookup.h
@@ -1,5 +1,5 @@
/* Look up a symbol in the loaded objects.
- Copyright (C) 1995-2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+ Copyright (C) 1995-2007, 2008 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
@@ -88,10 +88,12 @@ do_lookup_x (const char *undef_name, uint_fast32_t new_hash,
if (__builtin_expect (ELFW(ST_TYPE) (sym->st_info) > STT_FUNC
&& ELFW(ST_TYPE) (sym->st_info) != STT_COMMON
- && ELFW(ST_TYPE) (sym->st_info) != STT_TLS, 0))
- /* Ignore all but STT_NOTYPE, STT_OBJECT, STT_FUNC, and STT_COMMON
- entries (and STT_TLS if TLS is supported) since these
- are no code/data definitions. */
+ && ELFW(ST_TYPE) (sym->st_info) != STT_TLS
+ && ELFW(ST_TYPE) (sym->st_info) != STT_GNU_IFUNC,
+ 0))
+ /* Ignore all but STT_NOTYPE, STT_OBJECT, STT_FUNC, STT_COMMON,
+ STT_TLS, and STT_GNU_IFUNC since these are no code/data
+ definitions. */
return NULL;
if (sym != ref && strcmp (strtab + sym->st_name, undef_name))
diff --git a/elf/elf.h b/elf/elf.h
index 2792820c35..cd74d510ee 100644
--- a/elf/elf.h
+++ b/elf/elf.h
@@ -459,6 +459,7 @@ typedef struct
#define STT_TLS 6 /* Symbol is thread-local data object*/
#define STT_NUM 7 /* Number of defined types. */
#define STT_LOOS 10 /* Start of OS-specific */
+#define STT_GNU_IFUNC 10 /* Symbol is indirect code object */
#define STT_HIOS 12 /* End of OS-specific */
#define STT_LOPROC 13 /* Start of processor-specific */
#define STT_HIPROC 15 /* End of processor-specific */
diff --git a/elf/rtld.c b/elf/rtld.c
index aa4c030f73..bfe9564463 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -574,7 +574,7 @@ _dl_start (void *arg)
struct relocate_args
{
struct link_map *l;
- int lazy;
+ int reloc_mode;
};
struct map_args
@@ -613,7 +613,7 @@ relocate_doit (void *a)
{
struct relocate_args *args = (struct relocate_args *) a;
- _dl_relocate_object (args->l, args->l->l_scope, args->lazy, 0);
+ _dl_relocate_object (args->l, args->l->l_scope, args->reloc_mode, 0);
}
static void
@@ -1011,7 +1011,8 @@ of this helper program; chances are you did not intend to run this program.\n\
--library-path PATH use given PATH instead of content of the environment\n\
variable LD_LIBRARY_PATH\n\
--inhibit-rpath LIST ignore RUNPATH and RPATH information in object names\n\
- in LIST\n");
+ in LIST\n\
+ --audit LIST use objects named in LIST as auditors\n");
++_dl_skip_args;
--_dl_argc;
@@ -1908,7 +1909,9 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
struct link_map *l = main_map;
/* Relocate the main executable. */
- struct relocate_args args = { .l = l, .lazy = GLRO(dl_lazy) };
+ struct relocate_args args = { .l = l,
+ .reloc_mode = (GLRO(dl_lazy)
+ ? RTLD_LAZY : 0) };
_dl_receive_error (print_unresolved, relocate_doit, &args);
/* This loop depends on the dependencies of the executable to
@@ -1985,7 +1988,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
struct relocate_args args;
struct link_map *l;
- args.lazy = GLRO(dl_lazy);
+ args.reloc_mode = GLRO(dl_lazy) ? RTLD_LAZY : 0;
l = main_map;
while (l->l_next != NULL)
@@ -2225,7 +2228,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
}
if (l != &GL(dl_rtld_map))
- _dl_relocate_object (l, l->l_scope, GLRO(dl_lazy),
+ _dl_relocate_object (l, l->l_scope, GLRO(dl_lazy) ? RTLD_LAZY : 0,
consider_profiling);
/* Add object to slot information data if necessasy. */
diff --git a/fedora/branch.mk b/fedora/branch.mk
index bb315585f2..1466977998 100644
--- a/fedora/branch.mk
+++ b/fedora/branch.mk
@@ -3,5 +3,5 @@ glibc-branch := fedora
glibc-base := HEAD
DIST_BRANCH := devel
COLLECTION := dist-f8
-fedora-sync-date := 2009-03-10 19:25 UTC
-fedora-sync-tag := fedora-glibc-20090310T1925
+fedora-sync-date := 2009-03-20 19:44 UTC
+fedora-sync-tag := fedora-glibc-20090320T1944
diff --git a/fedora/glibc.spec.in b/fedora/glibc.spec.in
index cec16002d3..4dd603da07 100644
--- a/fedora/glibc.spec.in
+++ b/fedora/glibc.spec.in
@@ -19,7 +19,7 @@
Summary: The GNU libc libraries
Name: glibc
Version: @glibcversion@
-Release: 10
+Release: 11
# GPLv2+ is used in a bunch of programs, LGPLv2+ is used for libraries.
# Things that are linked directly into dynamically linked programs
# and shared libraries (e.g. crt files, lib*_nonshared.a) have an additional
@@ -1009,6 +1009,12 @@ rm -f *.filelist*
%endif
%changelog
+* Fri Mar 20 2009 Jakub Jelinek <jakub@redhat.com> 2.9.90-11
+- update from trunk
+ - POSIX 2008 prototype adjustments for scandir{,64}, alphasort{,64} and
+ versionsort{,64}
+ - fix libthread_db (#491197)
+
* Tue Mar 10 2009 Jakub Jelinek <jakub@redhat.com> 2.9.90-10
- update from trunk
- fix atexit/__cxa_atexit
diff --git a/include/dirent.h b/include/dirent.h
index 8f23aee234..3f6c4b9ae5 100644
--- a/include/dirent.h
+++ b/include/dirent.h
@@ -17,14 +17,16 @@ extern int __readdir64_r (DIR *__dirp, struct dirent64 *__entry,
extern int __scandir64 (__const char * __dir,
struct dirent64 *** __namelist,
int (*__selector) (__const struct dirent64 *),
- int (*__cmp) (__const void *, __const void *));
+ int (*__cmp) (__const struct dirent64 **,
+ __const struct dirent64 **));
extern __ssize_t __getdents (int __fd, char *__buf, size_t __nbytes)
internal_function;
extern __ssize_t __getdents64 (int __fd, char *__buf, size_t __nbytes)
internal_function;
-extern int __alphasort64 (const void *a, const void *b)
+extern int __alphasort64 (const struct dirent64 **a, const struct dirent64 **b)
__attribute_pure__;
-extern int __versionsort64 (const void *a, const void *b)
+extern int __versionsort64 (const struct dirent64 **a,
+ const struct dirent64 **b)
__attribute_pure__;
extern DIR *__alloc_dir (int fd, bool close_fd, const struct stat64 *statp)
internal_function;
diff --git a/include/libc-symbols.h b/include/libc-symbols.h
index a2faeafb32..d53bcb9b77 100644
--- a/include/libc-symbols.h
+++ b/include/libc-symbols.h
@@ -1,7 +1,6 @@
/* Support macros for making weak and strong aliases for symbols,
and for using symbol sets and linker warnings with GNU ld.
- Copyright (C) 1995-1998,2000-2003,2004,2005,2006
- Free Software Foundation, Inc.
+ Copyright (C) 1995-1998, 2000-2006, 2008 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
@@ -835,4 +834,15 @@ for linking")
# define compat_data_section .section ".data.compat", "aw";
#endif
+/* Marker used for indirection function symbols. */
+#define libc_ifunc(name, expr) \
+ extern void *name##_ifunc (void) __asm__ (#name); \
+ void *name##_ifunc (void) \
+ { \
+ INIT_ARCH (); \
+ __typeof (name) *res = expr; \
+ return res; \
+ } \
+ __asm__ (".type " #name ", %gnu_indirect_function");
+
#endif /* libc-symbols.h */
diff --git a/inet/Makefile b/inet/Makefile
index 16b2aae683..37985940ae 100644
--- a/inet/Makefile
+++ b/inet/Makefile
@@ -1,4 +1,4 @@
-# Copyright (C) 1991-2006, 2007 Free Software Foundation, Inc.
+# Copyright (C) 1991-2006, 2007, 2009 Free Software Foundation, Inc.
# This file is part of the GNU C Library.
# The GNU C Library is free software; you can redistribute it and/or
@@ -53,7 +53,7 @@ aux := check_pf check_native ifreq
tests := htontest test_ifindex tst-ntoa tst-ether_aton tst-network \
tst-gethnm test-ifaddrs bug-if1 test-inet6_opt tst-ether_line \
- tst-getni1 tst-getni2
+ tst-getni1 tst-getni2 tst-inet6_rth
include ../Rules
diff --git a/inet/inet6_rth.c b/inet/inet6_rth.c
index 15f8240909..36269fc6a4 100644
--- a/inet/inet6_rth.c
+++ b/inet/inet6_rth.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2006, 2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2006.
@@ -93,6 +93,9 @@ inet6_rth_add (void *bp, const struct in6_addr *addr)
struct ip6_rthdr0 *rthdr0;
case IPV6_RTHDR_TYPE_0:
rthdr0 = (struct ip6_rthdr0 *) rthdr;
+ if (rthdr0->ip6r0_len * 8 / sizeof (struct in6_addr)
+ - rthdr0->ip6r0_segleft < 1)
+ return -1;
memcpy (&rthdr0->ip6r0_addr[rthdr0->ip6r0_segleft++],
addr, sizeof (struct in6_addr));
@@ -127,7 +130,7 @@ inet6_rth_reverse (const void *in, void *out)
/* Copy header, not the addresses. The memory regions can overlap. */
memmove (out_rthdr0, in_rthdr0, sizeof (struct ip6_rthdr0));
- int total = in_rthdr0->ip6r0_segleft * 8 / sizeof (struct in6_addr);
+ int total = in_rthdr0->ip6r0_len * 8 / sizeof (struct in6_addr);
for (int i = 0; i < total / 2; ++i)
{
/* Remember, IN_RTHDR0 and OUT_RTHDR0 might overlap. */
@@ -138,6 +141,8 @@ inet6_rth_reverse (const void *in, void *out)
if (total % 2 != 0 && in != out)
out_rthdr0->ip6r0_addr[total / 2] = in_rthdr0->ip6r0_addr[total / 2];
+ out_rthdr0->ip6r0_segleft = total;
+
return 0;
}
diff --git a/inet/tst-inet6_rth.c b/inet/tst-inet6_rth.c
new file mode 100644
index 0000000000..4c5c90ac01
--- /dev/null
+++ b/inet/tst-inet6_rth.c
@@ -0,0 +1,188 @@
+#include <stdio.h>
+#include <string.h>
+#include <arpa/inet.h>
+#include <netinet/ip6.h>
+
+static int
+do_test (void)
+{
+ int res = 0;
+ char buf[1000];
+ void *p = inet6_rth_init (buf, 24, IPV6_RTHDR_TYPE_0, 0);
+ if (p == NULL)
+ {
+ puts ("first inet6_rth_init failed");
+ res = 1;
+ }
+ else if (inet6_rth_add (p, &in6addr_any) == 0)
+ {
+ puts ("first inet6_rth_add succeeded");
+ res = 1;
+ }
+
+ p = inet6_rth_init (buf, 24, IPV6_RTHDR_TYPE_0, 1);
+ if (p == NULL)
+ {
+ puts ("second inet6_rth_init failed");
+ res = 1;
+ }
+ else if (inet6_rth_add (p, &in6addr_any) != 0)
+ {
+ puts ("second inet6_rth_add failed");
+ res = 1;
+ }
+
+ for (int nseg = 4; nseg < 6; ++nseg)
+ {
+ printf ("nseg = %d\n", nseg);
+
+ p = inet6_rth_init (buf, sizeof (buf), IPV6_RTHDR_TYPE_0, nseg);
+ if (p == NULL)
+ {
+ puts ("third inet6_rth_init failed");
+ res = 1;
+ }
+ else
+ {
+ struct in6_addr tmp;
+ memset (&tmp, '\0', sizeof (tmp));
+
+ for (int i = 0; i < nseg; ++i)
+ {
+ tmp.s6_addr[0] = i;
+ if (inet6_rth_add (p, &tmp) != 0)
+ {
+ printf ("call %d of third inet6_rth_add failed\n", i + 1);
+ res = 1;
+ goto out;
+ }
+ }
+ ((struct ip6_rthdr0 *) p)->ip6r0_segleft = 0;
+ if (inet6_rth_segments (p) != nseg)
+ {
+ puts ("\
+inet6_rth_segments returned wrong value after loop with third inet6_rth_add");
+ res = 1;
+ goto out;
+ }
+
+ char buf2[1000];
+ if (inet6_rth_reverse (p, buf2) != 0)
+ {
+ puts ("first inet6_rth_reverse call failed");
+ res = 1;
+ goto out;
+ }
+ if (((struct ip6_rthdr0 *) buf2)->ip6r0_segleft != nseg)
+ {
+ puts ("segleft after first inet6_rth_reverse wrong");
+ res = 1;
+ }
+
+ if (inet6_rth_segments (p) != inet6_rth_segments (buf2))
+ {
+ puts ("number of seconds after first inet6_rth_reverse differs");
+ res = 1;
+ goto out;
+ }
+
+ for (int i = 0; i < nseg; ++i)
+ {
+ struct in6_addr *addr = inet6_rth_getaddr (buf2, i);
+ if (addr == NULL)
+ {
+ printf ("call %d of first inet6_rth_getaddr failed\n",
+ i + 1);
+ res = 1;
+ }
+ else if (addr->s6_addr[0] != nseg - 1 - i
+ || memcmp (&addr->s6_addr[1], &in6addr_any.s6_addr[1],
+ sizeof (in6addr_any)
+ - sizeof (in6addr_any.s6_addr[0])) != 0)
+ {
+ char addrbuf[100];
+ inet_ntop (AF_INET6, addr, addrbuf, sizeof (addrbuf));
+ printf ("\
+address %d after first inet6_rth_reverse wrong (%s)\n",
+ i + 1, addrbuf);
+ res = 1;
+ }
+ }
+ out:
+ ;
+ }
+
+ p = inet6_rth_init (buf, sizeof (buf), IPV6_RTHDR_TYPE_0, nseg);
+ if (p == NULL)
+ {
+ puts ("fourth inet6_rth_init failed");
+ res = 1;
+ }
+ else
+ {
+ struct in6_addr tmp;
+ memset (&tmp, '\0', sizeof (tmp));
+
+ for (int i = 0; i < nseg; ++i)
+ {
+ tmp.s6_addr[0] = i;
+ if (inet6_rth_add (p, &tmp) != 0)
+ {
+ printf ("call %d of fourth inet6_rth_add failed\n", i + 1);
+ res = 1;
+ goto out2;
+ }
+ }
+ ((struct ip6_rthdr0 *) p)->ip6r0_segleft = 0;
+ if (inet6_rth_segments (p) != nseg)
+ {
+ puts ("\
+inet6_rth_segments returned wrong value after loop with fourth inet6_rth_add");
+ res = 1;
+ goto out2;
+ }
+
+ if (inet6_rth_reverse (p, p) != 0)
+ {
+ puts ("second inet6_rth_reverse call failed");
+ res = 1;
+ goto out2;
+ }
+ if (((struct ip6_rthdr0 *) p)->ip6r0_segleft != nseg)
+ {
+ puts ("segleft after second inet6_rth_reverse wrong");
+ res = 1;
+ }
+
+ for (int i = 0; i < nseg; ++i)
+ {
+ struct in6_addr *addr = inet6_rth_getaddr (p, i);
+ if (addr == NULL)
+ {
+ printf ("call %d of second inet6_rth_getaddr failed\n",
+ i + 1);
+ res = 1;
+ }
+ else if (addr->s6_addr[0] != nseg - 1 - i
+ || memcmp (&addr->s6_addr[1], &in6addr_any.s6_addr[1],
+ sizeof (in6addr_any)
+ - sizeof (in6addr_any.s6_addr[0])) != 0)
+ {
+ char addrbuf[100];
+ inet_ntop (AF_INET6, addr, addrbuf, sizeof (addrbuf));
+ printf ("\
+address %d after second inet6_rth_reverse wrong (%s)\n",
+ i + 1, addrbuf);
+ res = 1;
+ }
+ }
+ out2:
+ ;
+ }
+ }
+
+ return res;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/locale/iso-639.def b/locale/iso-639.def
index 6d88767c8a..de78aa1c0d 100644
--- a/locale/iso-639.def
+++ b/locale/iso-639.def
@@ -303,6 +303,7 @@ DEFINE_LANGUAGE_CODE3 ("Mayan languages", myn, myn)
DEFINE_LANGUAGE_CODE3 ("Mende", men, men)
DEFINE_LANGUAGE_CODE3 ("Mi'kmaq; Micmac", mic, mic)
DEFINE_LANGUAGE_CODE3 ("Minangkabau", min, min)
+DEFINE_LANGUAGE_CODE3 ("Min Nan", nan, nan)
DEFINE_LANGUAGE_CODE3 ("Mirandese", mwl, mwl)
DEFINE_LANGUAGE_CODE3 ("Miscellaneous languages", mis, mis)
DEFINE_LANGUAGE_CODE3 ("Mohawk", moh, moh)
diff --git a/localedata/ChangeLog b/localedata/ChangeLog
index 801a2a5dae..17f26f68c1 100644
--- a/localedata/ChangeLog
+++ b/localedata/ChangeLog
@@ -1,3 +1,22 @@
+2009-03-15 Ulrich Drepper <drepper@redhat.com>
+
+ [BZ #9844]
+ * locales/iso14651_t1_common: Move U0138 entry.
+
+ [BZ #9833]
+ * locales/ko_KR: Fix noexpr. Add nostr.
+
+ [BZ #9891]
+ * locales/mt_MT: Fix spelling of August (Awwissu).
+ Patch by Martin Pitt.
+
+2009-03-14 Ulrich Drepper <drepper@redhat.com>
+
+ [BZ #9916]
+ * SUPPORTED (SUPPORTED-LOCALES): Add nan_TW@latin.
+ * locales/nan_TW@latin: New file.
+ Contributed by Arne Goetje.
+
2009-02-11 Ulrich Drepper <drepper@redhat.com>
* locales/iso14651_t1_common: Add rules for sorting Malayalam.
diff --git a/localedata/SUPPORTED b/localedata/SUPPORTED
index cbf73a70c9..9a9cbd1275 100644
--- a/localedata/SUPPORTED
+++ b/localedata/SUPPORTED
@@ -290,6 +290,7 @@ ms_MY.UTF-8/UTF-8 \
ms_MY/ISO-8859-1 \
mt_MT.UTF-8/UTF-8 \
mt_MT/ISO-8859-3 \
+nan_TW@latin/UTF-8 \
nb_NO.UTF-8/UTF-8 \
nb_NO/ISO-8859-1 \
nds_DE/UTF-8 \
diff --git a/localedata/locales/iso14651_t1_common b/localedata/locales/iso14651_t1_common
index 1c9963aaf6..6bdc795f4a 100644
--- a/localedata/locales/iso14651_t1_common
+++ b/localedata/locales/iso14651_t1_common
@@ -917,7 +917,7 @@ collating-symbol <k-ai_lenght_mark>
# mlvw- denotes Malayalam vowel
# ml-visarga - dentos Malayalam Visarga
# consonant + virama is considered half of consonant or consonant without vowel part
-# so it consonant + virama should be considered as cluster and should be
+# so it consonant + virama should be considered as cluster and should be
# sorted before the consonant. All consonants are considered to have an implicit a vowel
# part associated with it.
collating-element <ml-chillu-n> from "<U0D28><U0D4D>"
@@ -2362,7 +2362,6 @@ endif
<U1E33> <k>;<BPT>;<MIN>;IGNORE # 337 ḳ
<U1E35> <k>;<BMA>;<MIN>;IGNORE # 338 ḵ
<U0199> <k>;<CRL>;<MIN>;IGNORE # 339 ƙ
-<U0138> <k>;<PCL>;<MIN>;IGNORE # 340 <kk>
<U006C> <l>;<BAS>;<MIN>;IGNORE # 341 l
<U013A> <l>;<ACA>;<MIN>;IGNORE # 342 <l'>
<U013E> <l>;<CAR>;<MIN>;IGNORE # 343 <l<>
@@ -2436,6 +2435,7 @@ endif
<U1E55> <p>;<ACA>;<MIN>;IGNORE # 411 <p'>
<U1E57> <p>;<PCT>;<MIN>;IGNORE # 412 <p.>
<U0071> <q>;<BAS>;<MIN>;IGNORE # 413 q
+<U0138> <q>;<PCL>;<MIN>;IGNORE # 340 <kk>
<U0072> <r>;<BAS>;<MIN>;IGNORE # 414 r
<U0155> <r>;<ACA>;<MIN>;IGNORE # 415 <r'>
<U0159> <r>;<CAR>;<MIN>;IGNORE # 416 <r<>
@@ -4309,7 +4309,7 @@ order_start <MALAYALAM>;forward;forward;forward;forward,position
<ml-dh> "<ml-dha><ml-virama>";<BAS>;<MIN>;IGNORE
<U0D22> "<ml-dha><ml-virama><mlvw-shorta>";<BAS>;<MIN>;IGNORE
<ml-chillu-nn> "<ml-nna><ml-virama>";<BAS>;<MIN>;IGNORE # ണ്‍ = ണ + ് + zwj
-<U0D23> "<ml-nna><ml-virama><mlvw-shorta>";<BAS>;<MIN>;IGNORE # ണ = ണ + ് + അ
+<U0D23> "<ml-nna><ml-virama><mlvw-shorta>";<BAS>;<MIN>;IGNORE # ണ = ണ + ് + അ
<ml-th> "<ml-tha><ml-virama>";<BAS>;<MIN>;IGNORE
<U0D24> "<ml-tha><ml-virama><mlvw-shorta>";<BAS>;<MIN>;IGNORE
<ml-thh> "<ml-thha><ml-virama>";<BAS>;<MIN>;IGNORE
@@ -4329,14 +4329,14 @@ order_start <MALAYALAM>;forward;forward;forward;forward,position
<ml-bh> "<ml-bha><ml-virama>";<BAS>;<MIN>;IGNORE
<U0D2D> "<ml-bha><ml-virama><mlvw-shorta>";<BAS>;<MIN>;IGNORE
<U0D02> "<ml-ma><ml-virama>";<BAS>;<MIN>;IGNORE # ം = മ + ്
-<ml-m> "<ml-ma><ml-virama>";"<BAS><ml-virama>";<MIN>;IGNORE # ം = മ + ്
-<U0D2E> "<ml-ma><ml-virama><mlvw-shorta>";<BAS>;<MIN>;IGNORE # മ = മ + ് + അ
+<ml-m> "<ml-ma><ml-virama>";"<BAS><ml-virama>";<MIN>;IGNORE # ം = മ + ്
+<U0D2E> "<ml-ma><ml-virama><mlvw-shorta>";<BAS>;<MIN>;IGNORE # മ = മ + ് + അ
<ml-y> "<ml-ya><ml-virama>";<BAS>;<MIN>;IGNORE
<U0D2F> "<ml-ya><ml-virama><mlvw-shorta>";<BAS>;<MIN>;IGNORE
<ml-chillu-r> "<ml-ra><ml-virama>";<BAS>;<MIN>;IGNORE # ര = ര + ് + zwj
-<U0D30> "<ml-ra><ml-virama><mlvw-shorta>";<BAS>;<MIN>;IGNORE # ര = ര + ് + അ
+<U0D30> "<ml-ra><ml-virama><mlvw-shorta>";<BAS>;<MIN>;IGNORE # ര = ര + ് + അ
<ml-chillu-l> <ml-la>;<BAS>;<MIN>;IGNORE # ല്‍ = ല + ് + zwj
-<U0D32> "<ml-la><ml-virama><mlvw-shorta>";<BAS>;<MIN>;IGNORE # ല = ല + ് + അ
+<U0D32> "<ml-la><ml-virama><mlvw-shorta>";<BAS>;<MIN>;IGNORE # ല = ല + ് + അ
<ml-v> "<ml-va><ml-virama>";<BAS>;<MIN>;IGNORE
<U0D35> "<ml-va><ml-virama><mlvw-shorta>";<BAS>;<MIN>;IGNORE
<ml-ss> "<ml-ssa><ml-virama>";<BAS>;<MIN>;IGNORE
@@ -4348,7 +4348,7 @@ order_start <MALAYALAM>;forward;forward;forward;forward,position
<ml-h> "<ml-ha><ml-virama>";<BAS>;<MIN>;IGNORE
<U0D39> "<ml-ha><ml-virama><mlvw-shorta>";<BAS>;<MIN>;IGNORE
<ml-chillu-ll> "<ml-lla><ml-virama>";<BAS>;<MIN>;IGNORE # ള്‍ = ള + ് + zwj
-<U0D33> "<ml-lla><ml-virama><mlvw-shorta>";<BAS>;<MIN>;IGNORE # ള = ള + ് + അ
+<U0D33> "<ml-lla><ml-virama><mlvw-shorta>";<BAS>;<MIN>;IGNORE # ള = ള + ് + അ
<ml-zh> "<ml-zha><ml-virama>";<BAS>;<MIN>;IGNORE
<U0D34> "<ml-zha><ml-virama><mlvw-shorta>";<BAS>;<MIN>;IGNORE
<ml-rr> "<ml-rra><ml-virama>";<BAS>;<MIN>;IGNORE
diff --git a/localedata/locales/ko_KR b/localedata/locales/ko_KR
index 43915c2a82..59653ad188 100644
--- a/localedata/locales/ko_KR
+++ b/localedata/locales/ko_KR
@@ -6202,7 +6202,9 @@ LC_MESSAGES
yesexpr "<U005E><U005B><U0079><U0059><UC608><U005D>"
-noexpr "<U005E><U005B><U006E><U004E><UC544><UB2C8><UC624><U005D>"
+noexpr "<U005E><U005B><U006E><U004E><UC544><U005D>"
+
+nostr "<UC544><UB2C8><UC624>"
END LC_MESSAGES
diff --git a/localedata/locales/mt_MT b/localedata/locales/mt_MT
index 81c134fde1..d6af96b1ef 100644
--- a/localedata/locales/mt_MT
+++ b/localedata/locales/mt_MT
@@ -188,7 +188,7 @@ day "<U0069><U006C><U002D><U0126><U0061><U0064><U0064>";/
abmon "<U004A><U0061><U006E>";"<U0046><U0072><U0061>";/
"<U004D><U0061><U0072>";"<U0041><U0070><U0072>";/
"<U004D><U0065><U006A>";"<U0120><U0075><U006E>";/
- "<U004C><U0075><U006C>";"<U0041><U0077><U0069>";/
+ "<U004C><U0075><U006C>";"<U0041><U0077><U0077>";/
"<U0053><U0065><U0074>";"<U004F><U0074><U0074>";/
"<U004E><U006F><U0076>";"<U0044><U0069><U010B>"
%
@@ -200,7 +200,7 @@ mon "<U004A><U0061><U006E><U006E><U0061><U0072>";/
"<U004D><U0065><U006A><U006A><U0075>";/
"<U0120><U0075><U006E><U006A><U0075>";/
"<U004C><U0075><U006C><U006A><U0075>";/
- "<U0041><U0077><U0069><U0073><U0073><U0075>";/
+ "<U0041><U0077><U0077><U0069><U0073><U0073><U0075>";/
"<U0053><U0065><U0074><U0074><U0065><U006D><U0062><U0072><U0075>";/
"<U004F><U0074><U0074><U0075><U0062><U0072><U0075>";/
"<U004E><U006F><U0076><U0065><U006D><U0062><U0072><U0075>";/
diff --git a/localedata/locales/nan_TW@latin b/localedata/locales/nan_TW@latin
new file mode 100644
index 0000000000..bf8a6cd903
--- /dev/null
+++ b/localedata/locales/nan_TW@latin
@@ -0,0 +1,205 @@
+comment_char %
+escape_char /
+%
+% Minnan Language Locale for Taiwan
+% Source:
+% Contact: Arne Goetje
+% Email: arne@ubuntu.com
+% Language: nan
+% Territory: TW
+% Revision: 0.1
+% Date: 2008-06-16
+% Users: general
+% Charset: UTF-8
+% Distribution and use is free, also
+% for commercial purposes.
+
+LC_IDENTIFICATION
+title "Minnan language locale for Taiwan"
+source ""
+address ""
+contact "Arne Goetje"
+email "arne@canonical.com"
+tel ""
+fax ""
+language "Minnan"
+territory "Taiwan"
+revision "0.1"
+date "2008-06-16"
+
+category "nan_TW@latin:2000";LC_IDENTIFICATION
+category "nan_TW@latin:2000";LC_CTYPE
+category "nan_TW@latin:2000";LC_COLLATE
+category "nan_TW@latin:2000";LC_TIME
+category "nan_TW@latin:2000";LC_NUMERIC
+category "nan_TW@latin:2000";LC_PAPER
+category "nan_TW@latin:2000";LC_TELEPHONE
+category "nan_TW@latin:2000";LC_MEASUREMENT
+category "nan_TW@latin:2000";LC_ADDRESS
+category "nan_TW@latin:2000";LC_MESSAGES
+category "nan_TW@latin:2000";LC_MONETARY
+
+END LC_IDENTIFICATION
+
+LC_CTYPE
+copy "i18n"
+
+translit_start
+
+% accents are simply omitted if they cannot be represented.
+include "translit_combining";""
+
+translit_end
+
+END LC_CTYPE
+
+LC_COLLATE
+copy "iso14651_t1"
+
+%% a b c d e f g h i j k l m n o o͘ p q r s t u v w x y z ⁿ
+
+collating-element <oo> from "<U006F><U0358>"
+collating-element <OO> from "<U004F><U0358>"
+collating-element <nn> from "<U207F>"
+
+collating-symbol <CAP-MIN>
+collating-symbol <MIN-CAP>
+
+reorder-after <MIN>
+<MIN-CAP>
+reorder-after <CAP>
+<CAP-MIN>
+
+reorder-after <U006E>
+<oo>
+reorder-after <U004E>
+<OO>
+reorder-after <U007A>
+<nn>
+reorder-after <U005A>
+<nn>
+
+reorder-end
+
+END LC_COLLATE
+
+LC_MONETARY
+copy "zh_TW"
+END LC_MONETARY
+
+LC_NUMERIC
+copy "zh_TW"
+END LC_NUMERIC
+
+LC_TIME
+abday "<U006C><U0070>";/
+ "<U0070><U0031>";/
+ "<U0070><U0032>";/
+ "<U0070><U0033>";/
+ "<U0070><U0034>";/
+ "<U0070><U0035>";/
+ "<U0070><U0036>"
+day "<U006C><U00E9><U002D><U0070><U00E0><U0069><U002D><U006A><U0069><U030D><U0074>";/
+ "<U0070><U00E0><U0069><U002D><U0069><U0074>";/
+ "<U0070><U00E0><U0069><U002D><U006A><U012B>";/
+ "<U0070><U00E0><U0069><U002D><U0073><U0061><U207F>";/
+ "<U0070><U00E0><U0069><U002D><U0073><U00EC>";/
+ "<U0070><U00E0><U0069><U002D><U0067><U014D><U0358>";/
+ "<U0070><U00E0><U0069><U002D><U006C><U0061><U030D><U006B>"
+abmon "<U0031><U0067>";/
+ "<U0032><U0067>";/
+ "<U0033><U0067>";/
+ "<U0034><U0067>";/
+ "<U0035><U0067>";/
+ "<U0036><U0067>";/
+ "<U0037><U0067>";/
+ "<U0038><U0067>";/
+ "<U0039><U0067>";/
+ "<U0031><U0030><U0067>";/
+ "<U0031><U0031><U0067>";/
+ "<U0031><U0032><U0067>"
+mon "<U0031><U0067><U006F><U0065><U030D><U0068>";/
+ "<U0032><U0067><U006F><U0065><U030D><U0068>";/
+ "<U0033><U0067><U006F><U0065><U030D><U0068>";/
+ "<U0034><U0067><U006F><U0065><U030D><U0068>";/
+ "<U0035><U0067><U006F><U0065><U030D><U0068>";/
+ "<U0036><U0067><U006F><U0065><U030D><U0068>";/
+ "<U0037><U0067><U006F><U0065><U030D><U0068>";/
+ "<U0038><U0067><U006F><U0065><U030D><U0068>";/
+ "<U0039><U0067><U006F><U0065><U030D><U0068>";/
+ "<U0031><U0030><U0067><U006F><U0065><U030D><U0068>";/
+ "<U0031><U0031><U0067><U006F><U0065><U030D><U0068>";/
+ "<U0031><U0032><U0067><U006F><U0065><U030D><U0068>"
+%
+d_t_fmt "<U0025><U0059><U0020><U0025><U0062><U0020><U0025><U0064><U0020><U0028><U0025><U0061><U0029><U0020><U0025><U0048><U003A><U0025><U004D><U003A><U0025><U0053><U0020><U0025><U005A>"
+d_fmt "<U0025><U0046>"
+t_fmt "<U0025><U0072>"
+am_pm "<U0074><U00E9><U006E><U0067><U002D><U0070><U006F><U0358>";"<U0113><U002D><U0070><U006F><U0358>"
+t_fmt_ampm "<U0025><U0049><U003A><U0025><U004D><U003A><U0025><U0053><U0020><U0025><U0070>"
+timezone "<U0054><U0053><U0054><U002D><U0038>"
+date_fmt "<U0025><U0059><U0020><U0025><U0062><U0020><U0025><U0064><U0020><U0028><U0025><U0061><U0029><U0020><U0025><U0048><U003A><U0025><U004D><U003A><U0025><U0053><U0020><U0025><U005A>"
+END LC_TIME
+
+LC_MESSAGES
+
+% "^[sS].*" for "Yes"
+yesexpr "<U005E><U005B><U0073><U0053><U005D><U002E><U002A>"
+
+% "^[mM].*" for "No"
+noexpr "<U005E><U005B><U006D><U004D><U005D><U002E><U002A>"
+
+% "Sī" for "Yes"
+yesstr "<U0053><U012B>"
+
+% "M̄-sī" for "No"
+nostr "<U004D><U0304><U002D><U0053><U012B>"
+
+END LC_MESSAGES
+
+LC_PAPER
+height 297
+width 210
+END LC_PAPER
+
+LC_MEASUREMENT
+measurement 1
+END LC_MEASUREMENT
+
+LC_NAME
+%FIXME
+name_fmt "<U0025><U0064><U0025><U0074><U0025><U0067><U0025><U0074>/
+<U0025><U006D><U0025><U0074><U0025><U0066>"
+name_miss "<U006B><U006F><U0358><U002D><U006E><U0069><U00FB>"
+name_mr "<U0073><U0069><U0061><U006E><U002D><U0073><U0069><U207F>"
+name_mrs "<U006C><U00FA><U002D><U0073><U016B>"
+name_ms "<U0073><U0069><U00F3><U002D><U0063><U0068><U0069><U00E1>"
+END LC_NAME
+
+LC_ADDRESS
+% postal_fmt: "%f%N%a%N%d%N%b%N%r %e %h %s%N%z %T%N%c%N"
+postal_fmt "<U0025><U0066><U0025><U004E><U0025><U0061><U0025><U004E>/
+<U0025><U0064><U0025><U004E><U0025><U0062><U0025><U004E><U0025><U0072>/
+<U0020><U0025><U0065><U0020><U0025><U0068><U0020><U0025><U0073><U0025>/
+<U004E><U0025><U007A><U0020><U0025><U0054><U0025>/
+<U004E><U0025><U0063><U0025><U004E>"
+% Reference: http://www.un.org/Depts/unsd/methods/m49alpha.htm
+% http://www.isbn.spk-berlin.de/html/prefix.htm
+% country_ab2: TW
+% country_ab3: TWN
+% country_isbn: 957
+country_name "<U0054><U00E2><U0069><U002D><U006F><U00E2><U006E>"
+%country_post "FIXME"
+country_ab2 "<U0054><U0057>"
+country_ab3 "<U0054><U0057><U004E>"
+country_num 158
+%country_car "FIXME"
+country_isbn "<U0039><U0035><U0037>"
+%lang_name "Bân-lâm-gú, Hō-ló-oē"
+lang_name "<U0042><U00E2><U006E><U002D><U006C><U00E2><U006D><U002D><U0067><U00FA><U002C><U0020><U0048><U014D><U002D><U006C><U00F3><U002D><U006F><U0113>"
+lang_term "<U006E><U0061><U006E>"
+lang_lib "<U006E><U0061><U006E>"
+END LC_ADDRESS
+
+LC_TELEPHONE
+copy "zh_TW"
+END LC_TELEPHONE
diff --git a/malloc/Makefile b/malloc/Makefile
index 22b14eac77..1099335fff 100644
--- a/malloc/Makefile
+++ b/malloc/Makefile
@@ -1,4 +1,4 @@
-# Copyright (C) 1991-1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007
+# Copyright (C) 1991-1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2009
# Free Software Foundation, Inc.
# This file is part of the GNU C Library.
@@ -124,6 +124,9 @@ endif
tst-mcheck-ENV = MALLOC_CHECK_=3
+ifeq ($(experimental-malloc),yes)
+CPPFLAGS-malloc.c += -DPER_THREAD -DATOMIC_FASTBINS
+endif
# Uncomment this for test releases. For public releases it is too expensive.
#CPPFLAGS-malloc.o += -DMALLOC_DEBUG=1
diff --git a/malloc/arena.c b/malloc/arena.c
index cc03dc4a5b..f280d38811 100644
--- a/malloc/arena.c
+++ b/malloc/arena.c
@@ -1,5 +1,5 @@
/* Malloc implementation for multiple threads without lock contention.
- Copyright (C) 2001,2002,2003,2004,2005,2006,2007
+ Copyright (C) 2001,2002,2003,2004,2005,2006,2007,2009
Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Wolfram Gloger <wg@malloc.de>, 2001.
@@ -78,6 +78,10 @@ extern int sanity_check_heap_info_alignment[(sizeof (heap_info)
static tsd_key_t arena_key;
static mutex_t list_lock;
+#ifdef PER_THREAD
+static size_t narenas;
+static mstate free_list;
+#endif
#if THREAD_STATS
static int stat_n_heaps;
@@ -105,13 +109,30 @@ int __malloc_initialized = -1;
in the new arena. */
#define arena_get(ptr, size) do { \
+ arena_lookup(ptr); \
+ arena_lock(ptr, size); \
+} while(0)
+
+#define arena_lookup(ptr) do { \
Void_t *vptr = NULL; \
ptr = (mstate)tsd_getspecific(arena_key, vptr); \
+} while(0)
+
+#ifdef PER_THREAD
+#define arena_lock(ptr, size) do { \
+ if(ptr) \
+ (void)mutex_lock(&ptr->mutex); \
+ else \
+ ptr = arena_get2(ptr, (size)); \
+} while(0)
+#else
+#define arena_lock(ptr, size) do { \
if(ptr && !mutex_trylock(&ptr->mutex)) { \
THREAD_STAT(++(ptr->stat_lock_direct)); \
} else \
ptr = arena_get2(ptr, (size)); \
} while(0)
+#endif
/* find the heap and corresponding arena for a given ptr */
@@ -219,6 +240,11 @@ free_atfork(Void_t* mem, const Void_t *caller)
}
#endif
+#ifdef ATOMIC_FASTBINS
+ ar_ptr = arena_for_chunk(p);
+ tsd_getspecific(arena_key, vptr);
+ _int_free(ar_ptr, p, vptr == ATFORK_ARENA_PTR);
+#else
ar_ptr = arena_for_chunk(p);
tsd_getspecific(arena_key, vptr);
if(vptr != ATFORK_ARENA_PTR)
@@ -226,6 +252,7 @@ free_atfork(Void_t* mem, const Void_t *caller)
_int_free(ar_ptr, p);
if(vptr != ATFORK_ARENA_PTR)
(void)mutex_unlock(&ar_ptr->mutex);
+#endif
}
@@ -312,8 +339,17 @@ ptmalloc_unlock_all2 (void)
__malloc_hook = save_malloc_hook;
__free_hook = save_free_hook;
#endif
+#ifdef PER_THREAD
+ free_list = NULL;
+#endif
for(ar_ptr = &main_arena;;) {
mutex_init(&ar_ptr->mutex);
+#ifdef PER_THREAD
+ if (ar_ptr != save_arena) {
+ ar_ptr->next_free = free_list;
+ free_list = ar_ptr;
+ }
+#endif
ar_ptr = ar_ptr->next;
if(ar_ptr == &main_arena) break;
}
@@ -377,6 +413,11 @@ ptmalloc_init_minimal (void)
mp_.mmap_threshold = DEFAULT_MMAP_THRESHOLD;
mp_.trim_threshold = DEFAULT_TRIM_THRESHOLD;
mp_.pagesize = malloc_getpagesize;
+#ifdef PER_THREAD
+# define NARENAS_FROM_NCORES(n) ((n) * (sizeof(long) == 4 ? 2 : 8))
+ mp_.arena_test = NARENAS_FROM_NCORES (1);
+ narenas = 1;
+#endif
}
@@ -529,9 +570,25 @@ ptmalloc_init (void)
}
break;
case 9:
- if (! secure && memcmp (envline, "MMAP_MAX_", 9) == 0)
- mALLOPt(M_MMAP_MAX, atoi(&envline[10]));
+ if (! secure)
+ {
+ if (memcmp (envline, "MMAP_MAX_", 9) == 0)
+ mALLOPt(M_MMAP_MAX, atoi(&envline[10]));
+#ifdef PER_THREAD
+ else if (memcmp (envline, "ARENA_MAX", 9) == 0)
+ mALLOPt(M_ARENA_MAX, atoi(&envline[10]));
+#endif
+ }
break;
+#ifdef PER_THREAD
+ case 10:
+ if (! secure)
+ {
+ if (memcmp (envline, "ARENA_TEST", 10) == 0)
+ mALLOPt(M_ARENA_TEST, atoi(&envline[11]));
+ }
+ break;
+#endif
case 15:
if (! secure)
{
@@ -875,9 +932,110 @@ _int_new_arena(size_t size)
top(a) = (mchunkptr)ptr;
set_head(top(a), (((char*)h + h->size) - ptr) | PREV_INUSE);
+ tsd_setspecific(arena_key, (Void_t *)a);
+ mutex_init(&a->mutex);
+ (void)mutex_lock(&a->mutex);
+
+#ifdef PER_THREAD
+ (void)mutex_lock(&list_lock);
+#endif
+
+ /* Add the new arena to the global list. */
+ a->next = main_arena.next;
+ atomic_write_barrier ();
+ main_arena.next = a;
+
+#ifdef PER_THREAD
+ ++narenas;
+
+ (void)mutex_unlock(&list_lock);
+#endif
+
+ THREAD_STAT(++(a->stat_lock_loop));
+
return a;
}
+
+#ifdef PER_THREAD
+static mstate
+get_free_list (void)
+{
+ mstate result = free_list;
+ if (result != NULL)
+ {
+ (void)mutex_lock(&list_lock);
+ result = free_list;
+ if (result != NULL)
+ free_list = result->next_free;
+ (void)mutex_unlock(&list_lock);
+
+ if (result != NULL)
+ {
+ (void)mutex_lock(&result->mutex);
+ tsd_setspecific(arena_key, (Void_t *)result);
+ THREAD_STAT(++(result->stat_lock_loop));
+ }
+ }
+
+ return result;
+}
+
+
+static mstate
+reused_arena (void)
+{
+ if (narenas <= mp_.arena_test)
+ return NULL;
+
+ static int narenas_limit;
+ if (narenas_limit == 0)
+ {
+ if (mp_.arena_max != 0)
+ narenas_limit = mp_.arena_max;
+ else
+ {
+ int n = __get_nprocs ();
+
+ if (n >= 1)
+ narenas_limit = NARENAS_FROM_NCORES (n);
+ else
+ /* We have no information about the system. Assume two
+ cores. */
+ narenas_limit = NARENAS_FROM_NCORES (2);
+ }
+ }
+
+ if (narenas < narenas_limit)
+ return NULL;
+
+ mstate result;
+ static mstate next_to_use;
+ if (next_to_use == NULL)
+ next_to_use = &main_arena;
+
+ result = next_to_use;
+ do
+ {
+ if (!mutex_trylock(&result->mutex))
+ goto out;
+
+ result = result->next;
+ }
+ while (result != next_to_use);
+
+ /* No arena available. Wait for the next in line. */
+ (void)mutex_lock(&result->mutex);
+
+ out:
+ tsd_setspecific(arena_key, (Void_t *)result);
+ THREAD_STAT(++(result->stat_lock_loop));
+ next_to_use = result->next;
+
+ return result;
+}
+#endif
+
static mstate
internal_function
#if __STD_C
@@ -888,6 +1046,12 @@ arena_get2(a_tsd, size) mstate a_tsd; size_t size;
{
mstate a;
+#ifdef PER_THREAD
+ if ((a = get_free_list ()) == NULL
+ && (a = reused_arena ()) == NULL)
+ /* Nothing immediately available, so generate a new arena. */
+ a = _int_new_arena(size);
+#else
if(!a_tsd)
a = a_tsd = &main_arena;
else {
@@ -930,24 +1094,31 @@ arena_get2(a_tsd, size) mstate a_tsd; size_t size;
/* Nothing immediately available, so generate a new arena. */
a = _int_new_arena(size);
- if(a)
- {
- tsd_setspecific(arena_key, (Void_t *)a);
- mutex_init(&a->mutex);
- mutex_lock(&a->mutex); /* remember result */
-
- /* Add the new arena to the global list. */
- a->next = main_arena.next;
- atomic_write_barrier ();
- main_arena.next = a;
-
- THREAD_STAT(++(a->stat_lock_loop));
- }
(void)mutex_unlock(&list_lock);
+#endif
return a;
}
+#ifdef PER_THREAD
+static void __attribute__ ((section ("__libc_thread_freeres_fn")))
+arena_thread_freeres (void)
+{
+ Void_t *vptr = NULL;
+ mstate a = tsd_getspecific(arena_key, vptr);
+ tsd_setspecific(arena_key, NULL);
+
+ if (a != NULL)
+ {
+ (void)mutex_lock(&list_lock);
+ a->next_free = free_list;
+ free_list = a;
+ (void)mutex_unlock(&list_lock);
+ }
+}
+text_set_element (__libc_thread_subfreeres, arena_thread_freeres);
+#endif
+
#endif /* USE_ARENAS */
/*
diff --git a/malloc/hooks.c b/malloc/hooks.c
index 9659ec5fbe..fe89db83f4 100644
--- a/malloc/hooks.c
+++ b/malloc/hooks.c
@@ -275,17 +275,13 @@ free_check(mem, caller) Void_t* mem; const Void_t *caller;
mchunkptr p;
if(!mem) return;
- (void)mutex_lock(&main_arena.mutex);
p = mem2chunk_check(mem, NULL);
if(!p) {
- (void)mutex_unlock(&main_arena.mutex);
-
malloc_printerr(check_action, "free(): invalid pointer", mem);
return;
}
#if HAVE_MMAP
if (chunk_is_mmapped(p)) {
- (void)mutex_unlock(&main_arena.mutex);
munmap_chunk(p);
return;
}
@@ -293,8 +289,13 @@ free_check(mem, caller) Void_t* mem; const Void_t *caller;
#if 0 /* Erase freed memory. */
memset(mem, 0, chunksize(p) - (SIZE_SZ+1));
#endif
+#ifdef ATOMIC_FASTBINS
+ _int_free(&main_arena, p, 0);
+#else
+ (void)mutex_lock(&main_arena.mutex);
_int_free(&main_arena, p);
(void)mutex_unlock(&main_arena.mutex);
+#endif
}
static Void_t*
@@ -472,7 +473,11 @@ free_starter(mem, caller) Void_t* mem; const Void_t *caller;
return;
}
#endif
+#ifdef ATOMIC_FASTBINS
+ _int_free(&main_arena, p, 1);
+#else
_int_free(&main_arena, p);
+#endif
}
# endif /* !defiend NO_STARTER */
@@ -584,7 +589,7 @@ public_sET_STATe(Void_t* msptr)
clear_fastchunks(&main_arena);
set_max_fast(DEFAULT_MXFAST);
for (i=0; i<NFASTBINS; ++i)
- main_arena.fastbins[i] = 0;
+ fastbin (&main_arena, i) = 0;
for (i=0; i<BINMAPSIZE; ++i)
main_arena.binmap[i] = 0;
top(&main_arena) = ms->av[2];
diff --git a/malloc/malloc.c b/malloc/malloc.c
index 12e23b0f9b..bb7ea36c80 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -208,7 +208,7 @@
Tuning options that are also dynamically changeable via mallopt:
- DEFAULT_MXFAST 64
+ DEFAULT_MXFAST 64 (for 32bit), 128 (for 64bit)
DEFAULT_TRIM_THRESHOLD 128 * 1024
DEFAULT_TOP_PAD 0
DEFAULT_MMAP_THRESHOLD 128 * 1024
@@ -254,8 +254,12 @@
#include <malloc-machine.h>
#ifdef _LIBC
+#ifdef ATOMIC_FASTBINS
+#include <atomic.h>
+#endif
#include <stdio-common/_itoa.h>
#include <bits/wordsize.h>
+#include <sys/sysinfo.h>
#endif
#ifdef __cplusplus
@@ -321,12 +325,7 @@ extern "C" {
or other mallocs available that do this.
*/
-#if MALLOC_DEBUG
#include <assert.h>
-#else
-#undef assert
-#define assert(x) ((void)0)
-#endif
/*
@@ -1308,7 +1307,7 @@ int __posix_memalign(void **, size_t, size_t);
#endif
#ifndef DEFAULT_MXFAST
-#define DEFAULT_MXFAST 64
+#define DEFAULT_MXFAST (64 * SIZE_SZ / 4)
#endif
@@ -1582,7 +1581,11 @@ typedef struct malloc_chunk* mchunkptr;
#if __STD_C
static Void_t* _int_malloc(mstate, size_t);
+#ifdef ATOMIC_FASTBINS
+static void _int_free(mstate, mchunkptr, int);
+#else
static void _int_free(mstate, mchunkptr);
+#endif
static Void_t* _int_realloc(mstate, mchunkptr, INTERNAL_SIZE_T);
static Void_t* _int_memalign(mstate, size_t, size_t);
static Void_t* _int_valloc(mstate, size_t);
@@ -2239,12 +2242,15 @@ typedef struct malloc_chunk* mbinptr;
*/
typedef struct malloc_chunk* mfastbinptr;
+#define fastbin(ar_ptr, idx) ((ar_ptr)->fastbinsY[idx])
/* offset 2 to use otherwise unindexable first 2 bins */
-#define fastbin_index(sz) ((((unsigned int)(sz)) >> 3) - 2)
+#define fastbin_index(sz) \
+ ((((unsigned int)(sz)) >> (SIZE_SZ == 8 ? 4 : 3)) - 2)
+
/* The maximum fastbin request size we support */
-#define MAX_FAST_SIZE 80
+#define MAX_FAST_SIZE (80 * SIZE_SZ / 4)
#define NFASTBINS (fastbin_index(request2size(MAX_FAST_SIZE))+1)
@@ -2279,8 +2285,13 @@ typedef struct malloc_chunk* mfastbinptr;
#define FASTCHUNKS_BIT (1U)
#define have_fastchunks(M) (((M)->flags & FASTCHUNKS_BIT) == 0)
+#ifdef ATOMIC_FASTBINS
+#define clear_fastchunks(M) catomic_or (&(M)->flags, FASTCHUNKS_BIT)
+#define set_fastchunks(M) catomic_and (&(M)->flags, ~FASTCHUNKS_BIT)
+#else
#define clear_fastchunks(M) ((M)->flags |= FASTCHUNKS_BIT)
#define set_fastchunks(M) ((M)->flags &= ~FASTCHUNKS_BIT)
+#endif
/*
NONCONTIGUOUS_BIT indicates that MORECORE does not return contiguous
@@ -2327,7 +2338,7 @@ struct malloc_state {
#endif
/* Fastbins */
- mfastbinptr fastbins[NFASTBINS];
+ mfastbinptr fastbinsY[NFASTBINS];
/* Base of the topmost chunk -- not otherwise kept in a bin */
mchunkptr top;
@@ -2344,6 +2355,11 @@ struct malloc_state {
/* Linked list */
struct malloc_state *next;
+#ifdef PER_THREAD
+ /* Linked list for free arenas. */
+ struct malloc_state *next_free;
+#endif
+
/* Memory allocated from the system in this arena. */
INTERNAL_SIZE_T system_mem;
INTERNAL_SIZE_T max_system_mem;
@@ -2354,6 +2370,10 @@ struct malloc_par {
unsigned long trim_threshold;
INTERNAL_SIZE_T top_pad;
INTERNAL_SIZE_T mmap_threshold;
+#ifdef PER_THREAD
+ INTERNAL_SIZE_T arena_test;
+ INTERNAL_SIZE_T arena_max;
+#endif
/* Memory map support */
int n_mmaps;
@@ -2391,6 +2411,13 @@ static struct malloc_state main_arena;
static struct malloc_par mp_;
+#ifdef PER_THREAD
+/* Non public mallopt parameters. */
+#define M_ARENA_TEST -7
+#define M_ARENA_MAX -8
+#endif
+
+
/* Maximum size of memory handled in fastbins. */
static INTERNAL_SIZE_T global_max_fast;
@@ -3037,8 +3064,10 @@ static Void_t* sYSMALLOc(nb, av) INTERNAL_SIZE_T nb; mstate av;
/* Precondition: not enough current space to satisfy nb request */
assert((unsigned long)(old_size) < (unsigned long)(nb + MINSIZE));
+#ifndef ATOMIC_FASTBINS
/* Precondition: all fastbins are consolidated */
assert(!have_fastchunks(av));
+#endif
if (av != &main_arena) {
@@ -3084,7 +3113,11 @@ static Void_t* sYSMALLOc(nb, av) INTERNAL_SIZE_T nb; mstate av;
set_head(chunk_at_offset(old_top, old_size), (2*SIZE_SZ)|PREV_INUSE);
set_foot(chunk_at_offset(old_top, old_size), (2*SIZE_SZ));
set_head(old_top, old_size|PREV_INUSE|NON_MAIN_ARENA);
+#ifdef ATOMIC_FASTBINS
+ _int_free(av, old_top, 1);
+#else
_int_free(av, old_top);
+#endif
} else {
set_head(old_top, (old_size + 2*SIZE_SZ)|PREV_INUSE);
set_foot(old_top, (old_size + 2*SIZE_SZ));
@@ -3323,7 +3356,11 @@ static Void_t* sYSMALLOc(nb, av) INTERNAL_SIZE_T nb; mstate av;
/* If possible, release the rest. */
if (old_size >= MINSIZE) {
+#ifdef ATOMIC_FASTBINS
+ _int_free(av, old_top, 1);
+#else
_int_free(av, old_top);
+#endif
}
}
@@ -3545,7 +3582,40 @@ public_mALLOc(size_t bytes)
if (__builtin_expect (hook != NULL, 0))
return (*hook)(bytes, RETURN_ADDRESS (0));
- arena_get(ar_ptr, bytes);
+ arena_lookup(ar_ptr);
+#if 0
+ // XXX We need double-word CAS and fastbins must be extended to also
+ // XXX hold a generation counter for each entry.
+ if (ar_ptr) {
+ INTERNAL_SIZE_T nb; /* normalized request size */
+ checked_request2size(bytes, nb);
+ if (nb <= get_max_fast ()) {
+ long int idx = fastbin_index(nb);
+ mfastbinptr* fb = &fastbin (ar_ptr, idx);
+ mchunkptr pp = *fb;
+ mchunkptr v;
+ do
+ {
+ v = pp;
+ if (v == NULL)
+ break;
+ }
+ while ((pp = catomic_compare_and_exchange_val_acq (fb, v->fd, v)) != v);
+ if (v != 0) {
+ if (__builtin_expect (fastbin_index (chunksize (v)) != idx, 0))
+ malloc_printerr (check_action, "malloc(): memory corruption (fast)",
+ chunk2mem (v));
+ check_remalloced_chunk(ar_ptr, v, nb);
+ void *p = chunk2mem(v);
+ if (__builtin_expect (perturb_byte, 0))
+ alloc_perturb (p, bytes);
+ return p;
+ }
+ }
+ }
+#endif
+
+ arena_lock(ar_ptr, bytes);
if(!ar_ptr)
return 0;
victim = _int_malloc(ar_ptr, bytes);
@@ -3612,18 +3682,22 @@ public_fREe(Void_t* mem)
#endif
ar_ptr = arena_for_chunk(p);
-#if THREAD_STATS
+#ifdef ATOMIC_FASTBINS
+ _int_free(ar_ptr, p, 0);
+#else
+# if THREAD_STATS
if(!mutex_trylock(&ar_ptr->mutex))
++(ar_ptr->stat_lock_direct);
else {
(void)mutex_lock(&ar_ptr->mutex);
++(ar_ptr->stat_lock_wait);
}
-#else
+# else
(void)mutex_lock(&ar_ptr->mutex);
-#endif
+# endif
_int_free(ar_ptr, p);
(void)mutex_unlock(&ar_ptr->mutex);
+#endif
}
#ifdef libc_hidden_def
libc_hidden_def (public_fREe)
@@ -3699,7 +3773,7 @@ public_rEALLOc(Void_t* oldmem, size_t bytes)
(void)mutex_lock(&ar_ptr->mutex);
#endif
-#ifndef NO_THREADS
+#if !defined NO_THREADS && !defined PER_THREAD
/* As in malloc(), remember this arena for the next allocation. */
tsd_setspecific(arena_key, (Void_t *)ar_ptr);
#endif
@@ -3717,18 +3791,22 @@ public_rEALLOc(Void_t* oldmem, size_t bytes)
if (newp != NULL)
{
MALLOC_COPY (newp, oldmem, oldsize - SIZE_SZ);
-#if THREAD_STATS
+#ifdef ATOMIC_FASTBINS
+ _int_free(ar_ptr, oldp, 0);
+#else
+# if THREAD_STATS
if(!mutex_trylock(&ar_ptr->mutex))
++(ar_ptr->stat_lock_direct);
else {
(void)mutex_lock(&ar_ptr->mutex);
++(ar_ptr->stat_lock_wait);
}
-#else
+# else
(void)mutex_lock(&ar_ptr->mutex);
-#endif
+# endif
_int_free(ar_ptr, oldp);
(void)mutex_unlock(&ar_ptr->mutex);
+#endif
}
}
@@ -4130,7 +4208,6 @@ _int_malloc(mstate av, size_t bytes)
INTERNAL_SIZE_T nb; /* normalized request size */
unsigned int idx; /* associated bin index */
mbinptr bin; /* associated bin */
- mfastbinptr* fb; /* associated fastbin */
mchunkptr victim; /* inspected/selected chunk */
INTERNAL_SIZE_T size; /* its size */
@@ -4164,13 +4241,28 @@ _int_malloc(mstate av, size_t bytes)
*/
if ((unsigned long)(nb) <= (unsigned long)(get_max_fast ())) {
- long int idx = fastbin_index(nb);
- fb = &(av->fastbins[idx]);
- if ( (victim = *fb) != 0) {
+ idx = fastbin_index(nb);
+ mfastbinptr* fb = &fastbin (av, idx);
+#ifdef ATOMIC_FASTBINS
+ mchunkptr pp = *fb;
+ do
+ {
+ victim = pp;
+ if (victim == NULL)
+ break;
+ }
+ while ((pp = catomic_compare_and_exchange_val_acq (fb, victim->fd, victim))
+ != victim);
+#else
+ victim = *fb;
+#endif
+ if (victim != 0) {
if (__builtin_expect (fastbin_index (chunksize (victim)) != idx, 0))
malloc_printerr (check_action, "malloc(): memory corruption (fast)",
chunk2mem (victim));
+#ifndef ATOMIC_FASTBINS
*fb = victim->fd;
+#endif
check_remalloced_chunk(av, victim, nb);
void *p = chunk2mem(victim);
if (__builtin_expect (perturb_byte, 0))
@@ -4560,6 +4652,18 @@ _int_malloc(mstate av, size_t bytes)
return p;
}
+#ifdef ATOMIC_FASTBINS
+ /* When we are using atomic ops to free fast chunks we can get
+ here for all block sizes. */
+ else if (have_fastchunks(av)) {
+ malloc_consolidate(av);
+ /* restore original bin index */
+ if (in_smallbin_range(nb))
+ idx = smallbin_index(nb);
+ else
+ idx = largebin_index(nb);
+ }
+#else
/*
If there is space available in fastbins, consolidate and retry,
to possibly avoid expanding memory. This can occur only if nb is
@@ -4571,6 +4675,7 @@ _int_malloc(mstate av, size_t bytes)
malloc_consolidate(av);
idx = smallbin_index(nb); /* restore original bin index */
}
+#endif
/*
Otherwise, relay to handle system-dependent cases
@@ -4589,7 +4694,11 @@ _int_malloc(mstate av, size_t bytes)
*/
static void
+#ifdef ATOMIC_FASTBINS
+_int_free(mstate av, mchunkptr p, int have_lock)
+#else
_int_free(mstate av, mchunkptr p)
+#endif
{
INTERNAL_SIZE_T size; /* its size */
mfastbinptr* fb; /* associated fastbin */
@@ -4601,6 +4710,9 @@ _int_free(mstate av, mchunkptr p)
mchunkptr fwd; /* misc temp for linking */
const char *errstr = NULL;
+#ifdef ATOMIC_FASTBINS
+ int locked = 0;
+#endif
size = chunksize(p);
@@ -4613,6 +4725,10 @@ _int_free(mstate av, mchunkptr p)
{
errstr = "free(): invalid pointer";
errout:
+#ifdef ATOMIC_FASTBINS
+ if (! have_lock && locked)
+ (void)mutex_unlock(&av->mutex);
+#endif
malloc_printerr (check_action, errstr, chunk2mem(p));
return;
}
@@ -4649,8 +4765,28 @@ _int_free(mstate av, mchunkptr p)
goto errout;
}
+ if (__builtin_expect (perturb_byte, 0))
+ free_perturb (chunk2mem(p), size - SIZE_SZ);
+
set_fastchunks(av);
- fb = &(av->fastbins[fastbin_index(size)]);
+ fb = &fastbin (av, fastbin_index(size));
+
+#ifdef ATOMIC_FASTBINS
+ mchunkptr fd;
+ mchunkptr old = *fb;
+ do
+ {
+ /* Another simple check: make sure the top of the bin is not the
+ record we are going to add (i.e., double free). */
+ if (__builtin_expect (old == p, 0))
+ {
+ errstr = "double free or corruption (fasttop)";
+ goto errout;
+ }
+ p->fd = fd = old;
+ }
+ while ((old = catomic_compare_and_exchange_val_acq (fb, p, fd)) != fd);
+#else
/* Another simple check: make sure the top of the bin is not the
record we are going to add (i.e., double free). */
if (__builtin_expect (*fb == p, 0))
@@ -4659,11 +4795,9 @@ _int_free(mstate av, mchunkptr p)
goto errout;
}
- if (__builtin_expect (perturb_byte, 0))
- free_perturb (chunk2mem(p), size - SIZE_SZ);
-
p->fd = *fb;
*fb = p;
+#endif
}
/*
@@ -4671,6 +4805,22 @@ _int_free(mstate av, mchunkptr p)
*/
else if (!chunk_is_mmapped(p)) {
+#ifdef ATOMIC_FASTBINS
+ if (! have_lock) {
+# if THREAD_STATS
+ if(!mutex_trylock(&av->mutex))
+ ++(av->stat_lock_direct);
+ else {
+ (void)mutex_lock(&av->mutex);
+ ++(av->stat_lock_wait);
+ }
+# else
+ (void)mutex_lock(&av->mutex);
+# endif
+ locked = 1;
+ }
+#endif
+
nextchunk = chunk_at_offset(p, size);
/* Lightweight tests: check whether the block is already the
@@ -4794,6 +4944,12 @@ _int_free(mstate av, mchunkptr p)
}
}
+#ifdef ATOMIC_FASTBINS
+ if (! have_lock) {
+ assert (locked);
+ (void)mutex_unlock(&av->mutex);
+ }
+#endif
}
/*
If the chunk was allocated via mmap, release via munmap(). Note
@@ -4869,15 +5025,21 @@ static void malloc_consolidate(av) mstate av;
because, except for the main arena, all the others might have
blocks in the high fast bins. It's not worth it anyway, just
search all bins all the time. */
- maxfb = &(av->fastbins[fastbin_index(get_max_fast ())]);
+ maxfb = &fastbin (av, fastbin_index(get_max_fast ()));
#else
- maxfb = &(av->fastbins[NFASTBINS - 1]);
+ maxfb = &fastbin (av, NFASTBINS - 1);
#endif
- fb = &(av->fastbins[0]);
+ fb = &fastbin (av, 0);
do {
- if ( (p = *fb) != 0) {
- *fb = 0;
-
+#ifdef ATOMIC_FASTBINS
+ p = atomic_exchange_acq (fb, 0);
+#else
+ p = *fb;
+#endif
+ if (p != 0) {
+#ifndef ATOMIC_FASTBINS
+ *fb = 0;
+#endif
do {
check_inuse_chunk(av, p);
nextp = p->fd;
@@ -5070,7 +5232,11 @@ _int_realloc(mstate av, mchunkptr oldp, INTERNAL_SIZE_T nb)
}
}
+#ifdef ATOMIC_FASTBINS
+ _int_free(av, oldp, 1);
+#else
_int_free(av, oldp);
+#endif
check_inuse_chunk(av, newp);
return chunk2mem(newp);
}
@@ -5094,7 +5260,11 @@ _int_realloc(mstate av, mchunkptr oldp, INTERNAL_SIZE_T nb)
(av != &main_arena ? NON_MAIN_ARENA : 0));
/* Mark remainder as inuse so free() won't complain */
set_inuse_bit_at_offset(remainder, remainder_size);
+#ifdef ATOMIC_FASTBINS
+ _int_free(av, remainder, 1);
+#else
_int_free(av, remainder);
+#endif
}
check_inuse_chunk(av, newp);
@@ -5153,7 +5323,11 @@ _int_realloc(mstate av, mchunkptr oldp, INTERNAL_SIZE_T nb)
newmem = _int_malloc(av, nb - MALLOC_ALIGN_MASK);
if (newmem != 0) {
MALLOC_COPY(newmem, chunk2mem(oldp), oldsize - 2*SIZE_SZ);
+#ifdef ATOMIC_FASTBINS
+ _int_free(av, oldp, 1);
+#else
_int_free(av, oldp);
+#endif
}
}
return newmem;
@@ -5247,7 +5421,11 @@ _int_memalign(mstate av, size_t alignment, size_t bytes)
(av != &main_arena ? NON_MAIN_ARENA : 0));
set_inuse_bit_at_offset(newp, newsize);
set_head_size(p, leadsize | (av != &main_arena ? NON_MAIN_ARENA : 0));
+#ifdef ATOMIC_FASTBINS
+ _int_free(av, p, 1);
+#else
_int_free(av, p);
+#endif
p = newp;
assert (newsize >= nb &&
@@ -5263,7 +5441,11 @@ _int_memalign(mstate av, size_t alignment, size_t bytes)
set_head(remainder, remainder_size | PREV_INUSE |
(av != &main_arena ? NON_MAIN_ARENA : 0));
set_head_size(p, nb);
+#ifdef ATOMIC_FASTBINS
+ _int_free(av, remainder, 1);
+#else
_int_free(av, remainder);
+#endif
}
}
@@ -5650,7 +5832,7 @@ struct mallinfo mALLINFo(mstate av)
fastavail = 0;
for (i = 0; i < NFASTBINS; ++i) {
- for (p = av->fastbins[i]; p != 0; p = p->fd) {
+ for (p = fastbin (av, i); p != 0; p = p->fd) {
++nfastblocks;
fastavail += chunksize(p);
}
@@ -5818,6 +6000,18 @@ int mALLOPt(param_number, value) int param_number; int value;
case M_PERTURB:
perturb_byte = value;
break;
+
+#ifdef PER_THREAD
+ case M_ARENA_TEST:
+ if (value > 0)
+ mp_.arena_test = value;
+ break;
+
+ case M_ARENA_MAX:
+ if (value > 0)
+ mp_.arena_max = value;
+ break;
+#endif
}
(void)mutex_unlock(&av->mutex);
return res;
diff --git a/malloc/malloc.h b/malloc/malloc.h
index b6d7a8afaf..2c0ee35c4e 100644
--- a/malloc/malloc.h
+++ b/malloc/malloc.h
@@ -1,5 +1,5 @@
/* Prototypes and definition for malloc implementation.
- Copyright (C) 1996, 1997, 1999, 2000, 2002-2004, 2005, 2007
+ Copyright (C) 1996, 1997, 1999, 2000, 2002-2004, 2005, 2007, 2009
Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -127,6 +127,8 @@ extern struct mallinfo mallinfo __MALLOC_P ((void));
#define M_MMAP_MAX -4
#define M_CHECK_ACTION -5
#define M_PERTURB -6
+#define M_ARENA_TEST -7
+#define M_ARENA_MAX -8
/* General SVID/XPG interface to tunable parameters. */
extern int mallopt __MALLOC_P ((int __param, int __val));
diff --git a/nptl/ChangeLog b/nptl/ChangeLog
index 7b9999860d..60adce37d9 100644
--- a/nptl/ChangeLog
+++ b/nptl/ChangeLog
@@ -1,3 +1,13 @@
+2009-03-15 Ulrich Drepper <drepper@redhat.com>
+
+ * sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
+ (__pthread_cond_timedwait): Change to use cfi directives instead of
+ hand-coded unwind sections.
+
+2009-03-10 Ulrich Drepper <drepper@redhat.com>
+
+ * init.c (nptl_freeres): Compile only for SHARED.
+
2009-03-09 Jakub Jelinek <jakub@redhat.com>
* sysdeps/unix/sysv/linux/sparc/lowlevellock.h: Define
diff --git a/nptl/init.c b/nptl/init.c
index ba3caeead8..5e9c250ff7 100644
--- a/nptl/init.c
+++ b/nptl/init.c
@@ -67,10 +67,10 @@ static const char nptl_version[] __attribute_used__ = VERSION;
extern void __libc_setup_tls (size_t tcbsize, size_t tcbalign);
#endif
+#ifdef SHARED
static void nptl_freeres (void);
-#ifdef SHARED
static const struct pthread_functions pthread_functions =
{
.ptr_pthread_attr_destroy = __pthread_attr_destroy,
@@ -138,16 +138,16 @@ static const struct pthread_functions pthread_functions =
#endif
+#ifdef SHARED
/* This function is called indirectly from the freeres code in libc. */
static void
__libc_freeres_fn_section
nptl_freeres (void)
{
-#ifdef SHARED
__unwind_freeres ();
-#endif
__free_stacks (0);
}
+#endif
/* For asynchronous cancellation we use a signal. This is the handler. */
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
index 20bc59db9c..ddcf106a6d 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2002-2005, 2007, 2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@@ -37,16 +37,19 @@
.type __pthread_cond_timedwait, @function
.align 16
__pthread_cond_timedwait:
-.LSTARTCODE:
+ cfi_startproc
pushq %r12
-.Lpush_r12:
+ cfi_adjust_cfa_offset(8)
+ cfi_rel_offset(%r12, 0)
pushq %r13
-.Lpush_r13:
+ cfi_adjust_cfa_offset(8)
+ cfi_rel_offset(%r13, 0)
pushq %r14
-.Lpush_r14:
+ cfi_adjust_cfa_offset(8)
+ cfi_rel_offset(%r14, 0)
#define FRAME_SIZE 80
subq $FRAME_SIZE, %rsp
-.Lsubq:
+ cfi_adjust_cfa_offset(FRAME_SIZE)
cmpq $1000000000, 8(%rdx)
movl $EINVAL, %eax
@@ -305,19 +308,25 @@ __pthread_cond_timedwait:
cmoveq %r14, %rax
18: addq $FRAME_SIZE, %rsp
-.Laddq:
+ cfi_adjust_cfa_offset(-FRAME_SIZE)
popq %r14
-.Lpop_r14:
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%r14)
popq %r13
-.Lpop_r13:
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%r13)
popq %r12
-.Lpop_r12:
+ cfi_adjust_cfa_offset(-8)
+ cfi_restore(%r12)
retq
/* Initial locking failed. */
1:
-.LSbl1:
+ cfi_adjust_cfa_offset(3 * 8 + FRAME_SIZE)
+ cfi_rel_offset(%r12, FRAME_SIZE + 16)
+ cfi_rel_offset(%r13, FRAME_SIZE + 8)
+ cfi_rel_offset(%r14, FRAME_SIZE)
#if cond_lock != 0
addq $cond_lock, %rdi
#endif
@@ -414,97 +423,7 @@ __pthread_cond_timedwait:
js 6b
jmp 21b
#endif
-.LENDCODE:
+ cfi_endproc
.size __pthread_cond_timedwait, .-__pthread_cond_timedwait
versioned_symbol (libpthread, __pthread_cond_timedwait, pthread_cond_timedwait,
GLIBC_2_3_2)
-
-
- .section .eh_frame,"a",@progbits
-.LSTARTFRAME:
- .long L(ENDCIE)-L(STARTCIE) # Length of the CIE.
-.LSTARTCIE:
- .long 0 # CIE ID.
- .byte 1 # Version number.
-#ifdef SHARED
- .string "zR" # NUL-terminated augmentation
- # string.
-#else
- .ascii "\0" # NUL-terminated augmentation
- # string.
-#endif
- .uleb128 1 # Code alignment factor.
- .sleb128 -8 # Data alignment factor.
- .byte 16 # Return address register
- # column.
-#ifdef SHARED
- .uleb128 1 # Augmentation value length.
- .byte 0x1b # Encoding: DW_EH_PE_pcrel
- # + DW_EH_PE_sdata4.
-#endif
- .byte 0x0c # DW_CFA_def_cfa
- .uleb128 7
- .uleb128 8
- .byte 0x90 # DW_CFA_offset, column 0x8
- .uleb128 1
- .align 8
-.LENDCIE:
-
- .long .LENDFDE-.LSTARTFDE # Length of the FDE.
-.LSTARTFDE:
- .long .LSTARTFDE-.LSTARTFRAME # CIE pointer.
-#ifdef SHARED
- .long .LSTARTCODE-. # PC-relative start address
- # of the code
-#else
- .long .LSTARTCODE # Start address of the code.
-#endif
- .long .LENDCODE-.LSTARTCODE # Length of the code.
-#ifdef SHARED
- .uleb128 0 # No augmentation data.
-#endif
- .byte 0x40+.Lpush_r12-.LSTARTCODE # DW_CFA_advance_loc+N
- .byte 14 # DW_CFA_def_cfa_offset
- .uleb128 16
- .byte 0x8c # DW_CFA_offset %r12
- .uleb128 2
- .byte 0x40+.Lpush_r13-.Lpush_r12 # DW_CFA_advance_loc+N
- .byte 14 # DW_CFA_def_cfa_offset
- .uleb128 24
- .byte 0x8d # DW_CFA_offset %r13
- .uleb128 3
- .byte 0x40+.Lpush_r14-.Lpush_r13 # DW_CFA_advance_loc+N
- .byte 14 # DW_CFA_def_cfa_offset
- .uleb128 32
- .byte 0x84 # DW_CFA_offset %r14
- .uleb128 4
- .byte 0x40+.Lsubq-.Lpush_r14 # DW_CFA_advance_loc+N
- .byte 14 # DW_CFA_def_cfa_offset
- .uleb128 32+FRAME_SIZE
- .byte 3 # DW_CFA_advance_loc2
- .2byte .Laddq-.Lsubq
- .byte 14 # DW_CFA_def_cfa_offset
- .uleb128 32
- .byte 0x40+.Lpop_r14-.Laddq # DW_CFA_advance_loc+N
- .byte 14 # DW_CFA_def_cfa_offset
- .uleb128 24
- .byte 0xce # DW_CFA_restore %r14
- .byte 0x40+.Lpop_r13-.Lpop_r14 # DW_CFA_advance_loc+N
- .byte 14 # DW_CFA_def_cfa_offset
- .uleb128 16
- .byte 0xcd # DW_CFA_restore %r13
- .byte 0x40+.Lpop_r12-.Lpop_r13 # DW_CFA_advance_loc+N
- .byte 14 # DW_CFA_def_cfa_offset
- .uleb128 8
- .byte 0xcc # DW_CFA_restore %r12
- .byte 0x40+.LSbl1-.Lpop_r12 # DW_CFA_advance_loc+N
- .byte 14 # DW_CFA_def_cfa_offset
- .uleb128 32+FRAME_SIZE
- .byte 0x8c # DW_CFA_offset %r12
- .uleb128 2
- .byte 0x8d # DW_CFA_offset %r13
- .uleb128 3
- .byte 0x84 # DW_CFA_offset %r14
- .uleb128 4
- .align 8
-.LENDFDE:
diff --git a/nptl_db/ChangeLog b/nptl_db/ChangeLog
index 610ca9dbb6..8c07d9f32f 100644
--- a/nptl_db/ChangeLog
+++ b/nptl_db/ChangeLog
@@ -1,3 +1,8 @@
+2009-03-19 Roland McGrath <roland@redhat.com>
+
+ * td_symbol_list.c (DB_LOOKUP_NAME, DB_LOOKUP_NAME_TH_UNIQUE):
+ Use STRINGIFY macro in place of #argument.
+
2009-02-27 Roland McGrath <roland@redhat.com>
* td_symbol_list.c (symbol_list_arr): Move initializer guts to ...
diff --git a/nptl_db/td_symbol_list.c b/nptl_db/td_symbol_list.c
index 79498404cb..474251d627 100644
--- a/nptl_db/td_symbol_list.c
+++ b/nptl_db/td_symbol_list.c
@@ -24,8 +24,8 @@
static const char *symbol_list_arr[] =
{
-# define DB_LOOKUP_NAME(idx, name) [idx] = #name,
-# define DB_LOOKUP_NAME_TH_UNIQUE(idx, name) [idx] = #name,
+# define DB_LOOKUP_NAME(idx, name) [idx] = STRINGIFY (name),
+# define DB_LOOKUP_NAME_TH_UNIQUE(idx, name) [idx] = STRINGIFY (name),
# include "db-symbols.h"
# undef DB_LOOKUP_NAME
# undef DB_LOOKUP_NAME_TH_UNIQUE
diff --git a/nscd/connections.c b/nscd/connections.c
index 3d0727f33b..234e289f00 100644
--- a/nscd/connections.c
+++ b/nscd/connections.c
@@ -1418,7 +1418,22 @@ cannot change to old working directory: %s; disabling paranoia mode"),
}
/* The preparations are done. */
- execv ("/proc/self/exe", argv);
+#ifdef PATH_MAX
+ char pathbuf[PATH_MAX];
+#else
+ char pathbuf[256];
+#endif
+ /* Try to exec the real nscd program so the process name (as reported
+ in /proc/PID/status) will be 'nscd', but fall back to /proc/self/exe
+ if readlink fails */
+ ssize_t n = readlink ("/proc/self/exe", pathbuf, sizeof (pathbuf) - 1);
+ if (n == -1)
+ execv ("/proc/self/exe", argv);
+ else
+ {
+ pathbuf[n] = '\0';
+ execv (pathbuf, argv);
+ }
/* If we come here, we will never be able to re-exec. */
dbg_log (_("re-exec failed: %s; disabling paranoia mode"),
diff --git a/string/Makefile b/string/Makefile
index cccd68cf45..127e25fbd9 100644
--- a/string/Makefile
+++ b/string/Makefile
@@ -1,4 +1,4 @@
-# Copyright (C) 1991-2002, 2005-2007, 2008 Free Software Foundation, Inc.
+# Copyright (C) 1991-2002, 2005-2008, 2009 Free Software Foundation, Inc.
# This file is part of the GNU C Library.
# The GNU C Library is free software; you can redistribute it and/or
@@ -54,7 +54,7 @@ tests := tester inl-tester noinl-tester testcopy test-ffs \
bug-strncat1 bug-strspn1 bug-strpbrk1 tst-bswap \
tst-strtok tst-strxfrm bug-strcoll1 tst-strfry \
bug-strtok1 $(addprefix test-,$(strop-tests)) \
- bug-envz1 tst-strxfrm2 tst-endian
+ bug-envz1 tst-strxfrm2 tst-endian tst-svc2
distribute := memcopy.h pagecopy.h tst-svc.expect test-string.h \
str-two-way.h
diff --git a/string/strlen.c b/string/strlen.c
index 9bc9db68f7..5f22ce9509 100644
--- a/string/strlen.c
+++ b/string/strlen.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1993, 1997, 2000, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 1991,1993,1997,2000,2003,2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Torbjorn Granlund (tege@sics.se),
with help from Dan Sahlin (dan@sics.se);
@@ -32,7 +32,7 @@ strlen (str)
{
const char *char_ptr;
const unsigned long int *longword_ptr;
- unsigned long int longword, magic_bits, himagic, lomagic;
+ unsigned long int longword, himagic, lomagic;
/* Handle the first few characters by reading one character at a time.
Do this until CHAR_PTR is aligned on a longword boundary. */
@@ -56,14 +56,12 @@ strlen (str)
The 1-bits make sure that carries propagate to the next 0-bit.
The 0-bits provide holes for carries to fall into. */
- magic_bits = 0x7efefeffL;
himagic = 0x80808080L;
lomagic = 0x01010101L;
if (sizeof (longword) > 4)
{
/* 64-bit version of the magic. */
/* Do the shift in two steps to avoid a warning if long has 32 bits. */
- magic_bits = ((0x7efefefeL << 16) << 16) | 0xfefefeffL;
himagic = ((himagic << 16) << 16) | himagic;
lomagic = ((lomagic << 16) << 16) | lomagic;
}
@@ -75,53 +73,9 @@ strlen (str)
if *any of the four* bytes in the longword in question are zero. */
for (;;)
{
- /* We tentatively exit the loop if adding MAGIC_BITS to
- LONGWORD fails to change any of the hole bits of LONGWORD.
-
- 1) Is this safe? Will it catch all the zero bytes?
- Suppose there is a byte with all zeros. Any carry bits
- propagating from its left will fall into the hole at its
- least significant bit and stop. Since there will be no
- carry from its most significant bit, the LSB of the
- byte to the left will be unchanged, and the zero will be
- detected.
-
- 2) Is this worthwhile? Will it ignore everything except
- zero bytes? Suppose every byte of LONGWORD has a bit set
- somewhere. There will be a carry into bit 8. If bit 8
- is set, this will carry into bit 16. If bit 8 is clear,
- one of bits 9-15 must be set, so there will be a carry
- into bit 16. Similarly, there will be a carry into bit
- 24. If one of bits 24-30 is set, there will be a carry
- into bit 31, so all of the hole bits will be changed.
-
- The one misfire occurs when bits 24-30 are clear and bit
- 31 is set; in this case, the hole at bit 31 is not
- changed. If we had access to the processor carry flag,
- we could close this loophole by putting the fourth hole
- at bit 32!
-
- So it ignores everything except 128's, when they're aligned
- properly. */
-
longword = *longword_ptr++;
- if (
-#if 0
- /* Add MAGIC_BITS to LONGWORD. */
- (((longword + magic_bits)
-
- /* Set those bits that were unchanged by the addition. */
- ^ ~longword)
-
- /* Look at only the hole bits. If any of the hole bits
- are unchanged, most likely one of the bytes was a
- zero. */
- & ~magic_bits)
-#else
- ((longword - lomagic) & himagic)
-#endif
- != 0)
+ if (((longword - lomagic) & ~longword & himagic) != 0)
{
/* Which of the bytes was the zero? If none of them were, it was
a misfire; continue the search. */
diff --git a/string/strverscmp.c b/string/strverscmp.c
index 8efac30383..2b7ebcb8a8 100644
--- a/string/strverscmp.c
+++ b/string/strverscmp.c
@@ -1,5 +1,5 @@
/* Compare strings while treating digits characters numerically.
- Copyright (C) 1997, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1997, 2002, 2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jean-Franois Bignolles <bignolle@ecoledoc.ibp.fr>, 1997.
@@ -18,15 +18,16 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
+#include <stdint.h>
#include <string.h>
#include <ctype.h>
/* states: S_N: normal, S_I: comparing integral part, S_F: comparing
fractionnal parts, S_Z: idem but with leading Zeroes only */
#define S_N 0x0
-#define S_I 0x4
-#define S_F 0x8
-#define S_Z 0xC
+#define S_I 0x3
+#define S_F 0x6
+#define S_Z 0x9
/* result_type: CMP: return diff; LEN: compare using len_diff/diff */
#define CMP 2
@@ -45,53 +46,49 @@ __strverscmp (s1, s2)
{
const unsigned char *p1 = (const unsigned char *) s1;
const unsigned char *p2 = (const unsigned char *) s2;
- unsigned char c1, c2;
- int state;
- int diff;
- /* Symbol(s) 0 [1-9] others (padding)
- Transition (10) 0 (01) d (00) x (11) - */
- static const unsigned int next_state[] =
+ /* Symbol(s) 0 [1-9] others
+ Transition (10) 0 (01) d (00) x */
+ static const uint8_t next_state[] =
{
- /* state x d 0 - */
- /* S_N */ S_N, S_I, S_Z, S_N,
- /* S_I */ S_N, S_I, S_I, S_I,
- /* S_F */ S_N, S_F, S_F, S_F,
- /* S_Z */ S_N, S_F, S_Z, S_Z
+ /* state x d 0 */
+ /* S_N */ S_N, S_I, S_Z,
+ /* S_I */ S_N, S_I, S_I,
+ /* S_F */ S_N, S_F, S_F,
+ /* S_Z */ S_N, S_F, S_Z
};
- static const int result_type[] =
+ static const int8_t result_type[] =
{
- /* state x/x x/d x/0 x/- d/x d/d d/0 d/-
- 0/x 0/d 0/0 0/- -/x -/d -/0 -/- */
-
- /* S_N */ CMP, CMP, CMP, CMP, CMP, LEN, CMP, CMP,
- CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP,
- /* S_I */ CMP, -1, -1, CMP, +1, LEN, LEN, CMP,
- +1, LEN, LEN, CMP, CMP, CMP, CMP, CMP,
- /* S_F */ CMP, CMP, CMP, CMP, CMP, LEN, CMP, CMP,
- CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP,
- /* S_Z */ CMP, +1, +1, CMP, -1, CMP, CMP, CMP,
- -1, CMP, CMP, CMP
+ /* state x/x x/d x/0 d/x d/d d/0 0/x 0/d 0/0 */
+
+ /* S_N */ CMP, CMP, CMP, CMP, LEN, CMP, CMP, CMP, CMP,
+ /* S_I */ CMP, -1, -1, +1, LEN, LEN, +1, LEN, LEN,
+ /* S_F */ CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP,
+ /* S_Z */ CMP, +1, +1, -1, CMP, CMP, -1, CMP, CMP
};
if (p1 == p2)
return 0;
- c1 = *p1++;
- c2 = *p2++;
+ unsigned char c1 = *p1++;
+ unsigned char c2 = *p2++;
/* Hint: '0' is a digit too. */
- state = S_N | ((c1 == '0') + (isdigit (c1) != 0));
+ int state = S_N | ((c1 == '0') + (isdigit (c1) != 0));
- while ((diff = c1 - c2) == 0 && c1 != '\0')
+ int diff;
+ while ((diff = c1 - c2) == 0)
{
+ if (c1 == '\0')
+ return diff;
+
state = next_state[state];
c1 = *p1++;
c2 = *p2++;
state |= (c1 == '0') + (isdigit (c1) != 0);
}
- state = result_type[state << 2 | (((c2 == '0') + (isdigit (c2) != 0)))];
+ state = result_type[state * 3 | (((c2 == '0') + (isdigit (c2) != 0)))];
switch (state)
{
diff --git a/string/tst-svc2.c b/string/tst-svc2.c
new file mode 100644
index 0000000000..12c88aa2b8
--- /dev/null
+++ b/string/tst-svc2.c
@@ -0,0 +1,62 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+static struct
+{
+ const char *str1;
+ const char *str2;
+} tests[] =
+ {
+ { "B0075022800016.gbp.corp.com", "B007502280067.gbp.corp.com" },
+ { "B0075022800016.gbp.corp.com", "B007502357019.GBP.CORP.COM" },
+ { "B007502280067.gbp.corp.com", "B007502357019.GBP.CORP.COM" }
+ };
+#define ntests (sizeof (tests) / sizeof (tests[0]))
+
+
+int
+compare (const char *str1, const char *str2, int exp)
+{
+ int c = strverscmp (str1, str2);
+ if (c != 0)
+ c /= abs (c);
+ return c != exp;
+}
+
+
+static int
+do_test (void)
+{
+ int res = 0;
+ for (int i = 0; i < ntests; ++i)
+ {
+ if (compare (tests[i].str1, tests[i].str2, -1))
+ {
+ printf ("FAIL: \"%s\" > \"%s\"\n", tests[i].str1, tests[i].str2);
+ res = 1;
+ }
+ if (compare (tests[i].str2, tests[i].str1, +1))
+ {
+ printf ("FAIL: \"%s\" > \"%s\"\n", tests[i].str2, tests[i].str1);
+ res = 1;
+ }
+ char *copy1 = strdupa (tests[i].str1);
+ if (compare (tests[i].str1, copy1, 0))
+ {
+ printf ("FAIL: \"%s\" != \"%s\"\n", tests[i].str1, copy1);
+ res = 1;
+ }
+ char *copy2 = strdupa (tests[i].str2);
+ if (compare (tests[i].str2, copy2, 0))
+ {
+ printf ("FAIL: \"%s\" != \"%s\"\n", tests[i].str2, copy2);
+ res = 1;
+ }
+ }
+ return res;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
index e00b173f49..943369bb24 100644
--- a/sysdeps/generic/ldsodefs.h
+++ b/sysdeps/generic/ldsodefs.h
@@ -882,10 +882,10 @@ extern struct link_map *_dl_new_object (char *realname, const char *libname,
/* Relocate the given object (if it hasn't already been).
SCOPE is passed to _dl_lookup_symbol in symbol lookups.
- If LAZY is nonzero, don't relocate its PLT. */
+ If RTLD_LAZY is set in RELOC-MODE, don't relocate its PLT. */
extern void _dl_relocate_object (struct link_map *map,
struct r_scope_elem *scope[],
- int lazy, int consider_profiling)
+ int reloc_mode, int consider_profiling)
attribute_hidden;
/* Protect PT_GNU_RELRO area. */
diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h
index e3342d8e12..0e15878d4e 100644
--- a/sysdeps/i386/dl-machine.h
+++ b/sysdeps/i386/dl-machine.h
@@ -1,5 +1,5 @@
/* Machine-dependent ELF dynamic relocation inline functions. i386 version.
- Copyright (C) 1995-2005, 2006 Free Software Foundation, Inc.
+ Copyright (C) 1995-2005, 2006, 2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -316,34 +316,39 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
Elf32_Addr *const reloc_addr = reloc_addr_arg;
const unsigned int r_type = ELF32_R_TYPE (reloc->r_info);
-#if !defined RTLD_BOOTSTRAP || !defined HAVE_Z_COMBRELOC
+# if !defined RTLD_BOOTSTRAP || !defined HAVE_Z_COMBRELOC
if (__builtin_expect (r_type == R_386_RELATIVE, 0))
{
-# if !defined RTLD_BOOTSTRAP && !defined HAVE_Z_COMBRELOC
+# if !defined RTLD_BOOTSTRAP && !defined HAVE_Z_COMBRELOC
/* This is defined in rtld.c, but nowhere in the static libc.a;
make the reference weak so static programs can still link.
This declaration cannot be done when compiling rtld.c
(i.e. #ifdef RTLD_BOOTSTRAP) because rtld.c contains the
common defn for _dl_rtld_map, which is incompatible with a
weak decl in the same file. */
-# ifndef SHARED
+# ifndef SHARED
weak_extern (_dl_rtld_map);
-# endif
+# endif
if (map != &GL(dl_rtld_map)) /* Already done in rtld itself. */
-# endif
+# endif
*reloc_addr += map->l_addr;
}
-# ifndef RTLD_BOOTSTRAP
+# ifndef RTLD_BOOTSTRAP
else if (__builtin_expect (r_type == R_386_NONE, 0))
return;
-# endif
+# endif
else
-#endif /* !RTLD_BOOTSTRAP and have no -z combreloc */
+# endif /* !RTLD_BOOTSTRAP and have no -z combreloc */
{
const Elf32_Sym *const refsym = sym;
struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
Elf32_Addr value = sym_map == NULL ? 0 : sym_map->l_addr + sym->st_value;
+ if (sym != NULL
+ && __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC,
+ 0))
+ value = ((Elf32_Addr (*) (void)) value) ();
+
switch (r_type)
{
case R_386_GLOB_DAT:
@@ -351,44 +356,44 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
*reloc_addr = value;
break;
-#if !defined RTLD_BOOTSTRAP || USE___THREAD
+# if !defined RTLD_BOOTSTRAP || USE___THREAD
case R_386_TLS_DTPMOD32:
-# ifdef RTLD_BOOTSTRAP
+# ifdef RTLD_BOOTSTRAP
/* During startup the dynamic linker is always the module
with index 1.
XXX If this relocation is necessary move before RESOLVE
call. */
*reloc_addr = 1;
-# else
+# else
/* Get the information from the link map returned by the
resolv function. */
if (sym_map != NULL)
*reloc_addr = sym_map->l_tls_modid;
-# endif
+# endif
break;
case R_386_TLS_DTPOFF32:
-# ifndef RTLD_BOOTSTRAP
+# ifndef RTLD_BOOTSTRAP
/* During relocation all TLS symbols are defined and used.
Therefore the offset is already correct. */
if (sym != NULL)
*reloc_addr = sym->st_value;
-# endif
+# endif
break;
case R_386_TLS_DESC:
{
struct tlsdesc volatile *td =
(struct tlsdesc volatile *)reloc_addr;
-# ifndef RTLD_BOOTSTRAP
+# ifndef RTLD_BOOTSTRAP
if (! sym)
td->entry = _dl_tlsdesc_undefweak;
else
-# endif
+# endif
{
-# ifndef RTLD_BOOTSTRAP
-# ifndef SHARED
+# ifndef RTLD_BOOTSTRAP
+# ifndef SHARED
CHECK_STATIC_TLS (map, sym_map);
-# else
+# else
if (!TRY_STATIC_TLS (map, sym_map))
{
td->arg = _dl_make_tlsdesc_dynamic
@@ -396,8 +401,8 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
td->entry = _dl_tlsdesc_dynamic;
}
else
+# endif
# endif
-# endif
{
td->arg = (void*)(sym->st_value - sym_map->l_tls_offset
+ (ElfW(Word))td->arg);
@@ -408,9 +413,9 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
}
case R_386_TLS_TPOFF32:
/* The offset is positive, backward from the thread pointer. */
-# ifdef RTLD_BOOTSTRAP
+# ifdef RTLD_BOOTSTRAP
*reloc_addr += map->l_tls_offset - sym->st_value;
-# else
+# else
/* We know the offset of object the symbol is contained in.
It is a positive value which will be subtracted from the
thread pointer. To get the variable position in the TLS
@@ -420,13 +425,13 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
CHECK_STATIC_TLS (map, sym_map);
*reloc_addr += sym_map->l_tls_offset - sym->st_value;
}
-# endif
+# endif
break;
case R_386_TLS_TPOFF:
/* The offset is negative, forward from the thread pointer. */
-# ifdef RTLD_BOOTSTRAP
+# ifdef RTLD_BOOTSTRAP
*reloc_addr += sym->st_value - map->l_tls_offset;
-# else
+# else
/* We know the offset of object the symbol is contained in.
It is a negative value which will be added to the
thread pointer. */
@@ -435,11 +440,11 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
CHECK_STATIC_TLS (map, sym_map);
*reloc_addr += sym->st_value - sym_map->l_tls_offset;
}
-# endif
+# endif
break;
-#endif /* use TLS */
+# endif /* use TLS */
-#ifndef RTLD_BOOTSTRAP
+# ifndef RTLD_BOOTSTRAP
case R_386_32:
*reloc_addr += value;
break;
@@ -469,12 +474,12 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc,
default:
_dl_reloc_bad_type (map, r_type, 0);
break;
-#endif /* !RTLD_BOOTSTRAP */
+# endif /* !RTLD_BOOTSTRAP */
}
}
}
-#ifndef RTLD_BOOTSTRAP
+# ifndef RTLD_BOOTSTRAP
auto inline void
__attribute__ ((always_inline))
elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
@@ -488,12 +493,17 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
*reloc_addr = map->l_addr + reloc->r_addend;
else if (r_type != R_386_NONE)
{
-# ifndef RESOLVE_CONFLICT_FIND_MAP
+# ifndef RESOLVE_CONFLICT_FIND_MAP
const Elf32_Sym *const refsym = sym;
-# endif
+# endif
struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
Elf32_Addr value = sym == NULL ? 0 : sym_map->l_addr + sym->st_value;
+ if (sym != NULL
+ && __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC,
+ 0))
+ value = ((Elf32_Addr (*) (void)) value) ();
+
switch (ELF32_R_TYPE (reloc->r_info))
{
case R_386_GLOB_DAT:
@@ -501,7 +511,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
case R_386_32:
*reloc_addr = value + reloc->r_addend;
break;
-# ifndef RESOLVE_CONFLICT_FIND_MAP
+# ifndef RESOLVE_CONFLICT_FIND_MAP
/* Not needed for dl-conflict.c. */
case R_386_PC32:
*reloc_addr = (value + reloc->r_addend - (Elf32_Addr) reloc_addr);
@@ -523,19 +533,19 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
struct tlsdesc volatile *td =
(struct tlsdesc volatile *)reloc_addr;
-# ifndef RTLD_BOOTSTRAP
+# ifndef RTLD_BOOTSTRAP
if (!sym)
{
td->arg = (void*)reloc->r_addend;
td->entry = _dl_tlsdesc_undefweak;
}
else
-# endif
+# endif
{
-# ifndef RTLD_BOOTSTRAP
-# ifndef SHARED
+# ifndef RTLD_BOOTSTRAP
+# ifndef SHARED
CHECK_STATIC_TLS (map, sym_map);
-# else
+# else
if (!TRY_STATIC_TLS (map, sym_map))
{
td->arg = _dl_make_tlsdesc_dynamic
@@ -543,8 +553,8 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
td->entry = _dl_tlsdesc_dynamic;
}
else
-# endif
-# endif
+# endif
+# endif
{
td->arg = (void*)(sym->st_value - sym_map->l_tls_offset
+ reloc->r_addend);
@@ -598,7 +608,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
memcpy (reloc_addr_arg, (void *) value,
MIN (sym->st_size, refsym->st_size));
break;
-# endif /* !RESOLVE_CONFLICT_FIND_MAP */
+# endif /* !RESOLVE_CONFLICT_FIND_MAP */
default:
/* We add these checks in the version to relocate ld.so only
if we are still debugging. */
@@ -607,7 +617,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
}
}
}
-#endif /* !RTLD_BOOTSTRAP */
+# endif /* !RTLD_BOOTSTRAP */
auto inline void
__attribute ((always_inline))
@@ -619,7 +629,7 @@ elf_machine_rel_relative (Elf32_Addr l_addr, const Elf32_Rel *reloc,
*reloc_addr += l_addr;
}
-#ifndef RTLD_BOOTSTRAP
+# ifndef RTLD_BOOTSTRAP
auto inline void
__attribute__ ((always_inline))
elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
@@ -628,7 +638,7 @@ elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
Elf32_Addr *const reloc_addr = reloc_addr_arg;
*reloc_addr = l_addr + reloc->r_addend;
}
-#endif /* !RTLD_BOOTSTRAP */
+# endif /* !RTLD_BOOTSTRAP */
auto inline void
__attribute__ ((always_inline))
@@ -672,12 +682,12 @@ elf_machine_lazy_rel (struct link_map *map,
const ElfW(Sym) *const symtab =
(const void *) D_PTR (map, l_info[DT_SYMTAB]);
-#ifdef RTLD_BOOTSTRAP
+# ifdef RTLD_BOOTSTRAP
/* The dynamic linker always uses versioning. */
assert (map->l_info[VERSYMIDX (DT_VERSYM)] != NULL);
-#else
+# else
if (map->l_info[VERSYMIDX (DT_VERSYM)])
-#endif
+# endif
{
const ElfW(Half) *const version =
(const void *) D_PTR (map, l_info[VERSYMIDX (DT_VERSYM)]);
@@ -686,18 +696,18 @@ elf_machine_lazy_rel (struct link_map *map,
&map->l_versions[ndx],
(void *) (l_addr + r->r_offset));
}
-#ifndef RTLD_BOOTSTRAP
+# ifndef RTLD_BOOTSTRAP
else
elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL,
(void *) (l_addr + r->r_offset));
-#endif
+# endif
}
}
else
_dl_reloc_bad_type (map, r_type, 1);
}
-#ifndef RTLD_BOOTSTRAP
+# ifndef RTLD_BOOTSTRAP
auto inline void
__attribute__ ((always_inline))
@@ -720,6 +730,6 @@ elf_machine_lazy_rela (struct link_map *map,
_dl_reloc_bad_type (map, r_type, 1);
}
-#endif /* !RTLD_BOOTSTRAP */
+# endif /* !RTLD_BOOTSTRAP */
#endif /* RESOLVE_MAP */
diff --git a/sysdeps/powerpc/powerpc32/power7/fpu/Implies b/sysdeps/powerpc/powerpc32/power7/fpu/Implies
new file mode 100644
index 0000000000..819a7d7979
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/power7/fpu/Implies
@@ -0,0 +1 @@
+powerpc/powerpc32/power5/fpu
diff --git a/sysdeps/unix/sysv/linux/i386/alphasort64.c b/sysdeps/unix/sysv/linux/i386/alphasort64.c
index 221aedc16b..33e2fcd435 100644
--- a/sysdeps/unix/sysv/linux/i386/alphasort64.c
+++ b/sysdeps/unix/sysv/linux/i386/alphasort64.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1997, 1998, 2000, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 1992, 1997,1998,2000,2004,2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -20,10 +20,9 @@
#include <string.h>
int
-__alphasort64 (const void *a, const void *b)
+__alphasort64 (const struct dirent64 **a, const struct dirent64 **b)
{
- return strcoll ((*(const struct dirent64 **) a)->d_name,
- (*(const struct dirent64 **) b)->d_name);
+ return strcoll ((*a)->d_name, (*b)->d_name);
}
#include <shlib-compat.h>
@@ -35,14 +34,15 @@ versioned_symbol (libc, __alphasort64, alphasort64, GLIBC_2_2);
#include <sysdeps/unix/sysv/linux/i386/olddirent.h>
int
-__old_alphasort64 (const void *a, const void *b);
+__old_alphasort64 (const struct __old_dirent64 **a,
+ const struct __old_dirent64 **b);
int
attribute_compat_text_section
-__old_alphasort64 (const void *a, const void *b)
+__old_alphasort64 (const struct __old_dirent64 **a,
+ const struct __old_dirent64 **b)
{
- return strcoll ((*(const struct __old_dirent64 **) a)->d_name,
- (*(const struct __old_dirent64 **) b)->d_name);
+ return strcoll ((*a)->d_name, (*b)->d_name);
}
compat_symbol (libc, __old_alphasort64, alphasort64, GLIBC_2_1);
diff --git a/sysdeps/unix/sysv/linux/i386/olddirent.h b/sysdeps/unix/sysv/linux/i386/olddirent.h
index f9a79b2352..4f73197e53 100644
--- a/sysdeps/unix/sysv/linux/i386/olddirent.h
+++ b/sysdeps/unix/sysv/linux/i386/olddirent.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 Free Software Foundation, Inc.
+/* Copyright (C) 2000, 2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -39,6 +39,7 @@ extern __ssize_t __old_getdents64 (int __fd, char *__buf, size_t __nbytes)
int __old_scandir64 (__const char * __dir,
struct __old_dirent64 *** __namelist,
int (*__selector) (__const struct __old_dirent64 *),
- int (*__cmp) (__const void *, __const void *));
+ int (*__cmp) (__const struct __old_dirent64 **,
+ __const struct __old_dirent64 **));
#endif
diff --git a/sysdeps/unix/sysv/linux/i386/versionsort64.c b/sysdeps/unix/sysv/linux/i386/versionsort64.c
index 3efce692f7..be635f918a 100644
--- a/sysdeps/unix/sysv/linux/i386/versionsort64.c
+++ b/sysdeps/unix/sysv/linux/i386/versionsort64.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1997, 1998, 2000, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 1992,1997,1998,2000,2004,2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -20,10 +20,9 @@
#include <string.h>
int
-__versionsort64 (const void *a, const void *b)
+__versionsort64 (const struct dirent64 **a, const struct dirent64 **b)
{
- return __strverscmp ((*(const struct dirent64 **) a)->d_name,
- (*(const struct dirent64 **) b)->d_name);
+ return __strverscmp ((*a)->d_name, (*b)->d_name);
}
#include <shlib-compat.h>
@@ -35,14 +34,15 @@ versioned_symbol (libc, __versionsort64, versionsort64, GLIBC_2_2);
#include <sysdeps/unix/sysv/linux/i386/olddirent.h>
int
-__old_versionsort64 (const void *a, const void *b);
+__old_versionsort64 (const struct __old_dirent64 **a,
+ const struct __old_dirent64 **b);
int
attribute_compat_text_section
-__old_versionsort64 (const void *a, const void *b)
+__old_versionsort64 (const struct __old_dirent64 **a,
+ const struct __old_dirent64 **b)
{
- return __strverscmp ((*(const struct __old_dirent64 **) a)->d_name,
- (*(const struct __old_dirent64 **) b)->d_name);
+ return __strverscmp ((*a)->d_name, (*b)->d_name);
}
compat_symbol (libc, __old_versionsort64, versionsort64, GLIBC_2_1);
diff --git a/sysdeps/wordsize-64/alphasort.c b/sysdeps/wordsize-64/alphasort.c
index 5096166625..edc410129d 100644
--- a/sysdeps/wordsize-64/alphasort.c
+++ b/sysdeps/wordsize-64/alphasort.c
@@ -1,3 +1,7 @@
+#define alphasort64 rename_alphasort64
+
#include "../../dirent/alphasort.c"
+#undef alphasort64
+
weak_alias (alphasort, alphasort64)
diff --git a/sysdeps/wordsize-64/versionsort.c b/sysdeps/wordsize-64/versionsort.c
index 90365a4b25..bb25550d3d 100644
--- a/sysdeps/wordsize-64/versionsort.c
+++ b/sysdeps/wordsize-64/versionsort.c
@@ -1,3 +1,7 @@
+#define versionsort64 rename_versionsort64
+
#include "../../dirent/versionsort.c"
+#undef versionsort64
+
weak_alias (versionsort, versionsort64)
diff --git a/sysdeps/x86_64/cacheinfo.c b/sysdeps/x86_64/cacheinfo.c
index a7e3fc7633..8769e9c966 100644
--- a/sysdeps/x86_64/cacheinfo.c
+++ b/sysdeps/x86_64/cacheinfo.c
@@ -23,6 +23,10 @@
#include <stdlib.h>
#include <unistd.h>
+#ifdef USE_MULTIARCH
+# include "multiarch/init-arch.h"
+#endif
+
static const struct intel_02_cache_info
{
unsigned int idx;
@@ -443,19 +447,32 @@ init_cacheinfo (void)
unsigned int ebx;
unsigned int ecx;
unsigned int edx;
- int max_cpuid;
int max_cpuid_ex;
long int data = -1;
long int shared = -1;
unsigned int level;
unsigned int threads = 0;
+#ifdef USE_MULTIARCH
+ if (__cpu_features.kind == arch_kind_unknown)
+ __init_cpu_features ();
+# define is_intel __cpu_features.kind == arch_kind_intel
+# define is_amd __cpu_features.kind == arch_kind_amd
+# define max_cpuid __cpu_features.max_cpuid
+#else
+ int max_cpuid;
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)
+# define is_intel \
+ ebx == 0x756e6547 && ecx == 0x6c65746e && edx == 0x49656e69
+ /* This spells out "AuthenticAMD". */
+# define is_amd \
+ ebx == 0x68747541 && ecx == 0x444d4163 && edx == 0x69746e65
+#endif
+
+ if (is_intel)
{
data = handle_intel (_SC_LEVEL1_DCACHE_SIZE, max_cpuid);
@@ -470,9 +487,16 @@ init_cacheinfo (void)
shared = handle_intel (_SC_LEVEL2_CACHE_SIZE, max_cpuid);
}
+#ifdef USE_MULTIARCH
+ eax = __cpu_features.cpuid[INTEL_CPUID_INDEX_1].eax;
+ ebx = __cpu_features.cpuid[INTEL_CPUID_INDEX_1].ebx;
+ ecx = __cpu_features.cpuid[INTEL_CPUID_INDEX_1].ecx;
+ edx = __cpu_features.cpuid[INTEL_CPUID_INDEX_1].edx;
+#else
asm volatile ("cpuid"
: "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
: "0" (1));
+#endif
/* Intel prefers SSSE3 instructions for memory/string routines
if they are avaiable. */
@@ -519,7 +543,7 @@ init_cacheinfo (void)
shared /= threads;
}
/* This spells out "AuthenticAMD". */
- else if (ebx == 0x68747541 && ecx == 0x444d4163 && edx == 0x69746e65)
+ else if (is_amd)
{
data = handle_amd (_SC_LEVEL1_DCACHE_SIZE);
long int core = handle_amd (_SC_LEVEL2_CACHE_SIZE);
diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h
index 959b1328d7..8c67b5b5f9 100644
--- a/sysdeps/x86_64/dl-machine.h
+++ b/sysdeps/x86_64/dl-machine.h
@@ -1,5 +1,5 @@
/* Machine-dependent ELF dynamic relocation inline functions. x86-64 version.
- Copyright (C) 2001-2005, 2006 Free Software Foundation, Inc.
+ Copyright (C) 2001-2005, 2006, 2008, 2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Andreas Jaeger <aj@suse.de>.
@@ -266,40 +266,45 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
Elf64_Addr *const reloc_addr = reloc_addr_arg;
const unsigned long int r_type = ELF64_R_TYPE (reloc->r_info);
-#if !defined RTLD_BOOTSTRAP || !defined HAVE_Z_COMBRELOC
+# if !defined RTLD_BOOTSTRAP || !defined HAVE_Z_COMBRELOC
if (__builtin_expect (r_type == R_X86_64_RELATIVE, 0))
{
-# if !defined RTLD_BOOTSTRAP && !defined HAVE_Z_COMBRELOC
+# if !defined RTLD_BOOTSTRAP && !defined HAVE_Z_COMBRELOC
/* This is defined in rtld.c, but nowhere in the static libc.a;
make the reference weak so static programs can still link.
This declaration cannot be done when compiling rtld.c
(i.e. #ifdef RTLD_BOOTSTRAP) because rtld.c contains the
common defn for _dl_rtld_map, which is incompatible with a
weak decl in the same file. */
-# ifndef SHARED
+# ifndef SHARED
weak_extern (GL(dl_rtld_map));
-# endif
+# endif
if (map != &GL(dl_rtld_map)) /* Already done in rtld itself. */
-# endif
+# endif
*reloc_addr = map->l_addr + reloc->r_addend;
}
else
-#endif
+# endif
if (__builtin_expect (r_type == R_X86_64_NONE, 0))
return;
else
{
-#ifndef RTLD_BOOTSTRAP
+# ifndef RTLD_BOOTSTRAP
const Elf64_Sym *const refsym = sym;
-#endif
+# endif
struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
Elf64_Addr value = (sym == NULL ? 0
: (Elf64_Addr) sym_map->l_addr + sym->st_value);
-#if defined RTLD_BOOTSTRAP && !USE___THREAD
+ if (sym != NULL
+ && __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC,
+ 0))
+ value = ((Elf64_Addr (*) (void)) value) ();
+
+# if defined RTLD_BOOTSTRAP && !USE___THREAD
assert (r_type == R_X86_64_GLOB_DAT || r_type == R_X86_64_JUMP_SLOT);
*reloc_addr = value + reloc->r_addend;
-#else
+# else
switch (r_type)
{
case R_X86_64_GLOB_DAT:
@@ -307,47 +312,47 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
*reloc_addr = value + reloc->r_addend;
break;
-#ifndef RESOLVE_CONFLICT_FIND_MAP
+# ifndef RESOLVE_CONFLICT_FIND_MAP
case R_X86_64_DTPMOD64:
-# ifdef RTLD_BOOTSTRAP
+# ifdef RTLD_BOOTSTRAP
/* During startup the dynamic linker is always the module
with index 1.
XXX If this relocation is necessary move before RESOLVE
call. */
*reloc_addr = 1;
-# else
+# else
/* Get the information from the link map returned by the
resolve function. */
if (sym_map != NULL)
*reloc_addr = sym_map->l_tls_modid;
-# endif
+# endif
break;
case R_X86_64_DTPOFF64:
-# ifndef RTLD_BOOTSTRAP
+# ifndef RTLD_BOOTSTRAP
/* During relocation all TLS symbols are defined and used.
Therefore the offset is already correct. */
if (sym != NULL)
*reloc_addr = sym->st_value + reloc->r_addend;
-# endif
+# endif
break;
case R_X86_64_TLSDESC:
{
struct tlsdesc volatile *td =
(struct tlsdesc volatile *)reloc_addr;
-# ifndef RTLD_BOOTSTRAP
+# ifndef RTLD_BOOTSTRAP
if (! sym)
{
td->arg = (void*)reloc->r_addend;
td->entry = _dl_tlsdesc_undefweak;
}
else
-# endif
+# endif
{
-# ifndef RTLD_BOOTSTRAP
-# ifndef SHARED
+# ifndef RTLD_BOOTSTRAP
+# ifndef SHARED
CHECK_STATIC_TLS (map, sym_map);
-# else
+# else
if (!TRY_STATIC_TLS (map, sym_map))
{
td->arg = _dl_make_tlsdesc_dynamic
@@ -355,8 +360,8 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
td->entry = _dl_tlsdesc_dynamic;
}
else
+# endif
# endif
-# endif
{
td->arg = (void*)(sym->st_value - sym_map->l_tls_offset
+ reloc->r_addend);
@@ -367,13 +372,13 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
}
case R_X86_64_TPOFF64:
/* The offset is negative, forward from the thread pointer. */
-# ifndef RTLD_BOOTSTRAP
+# ifndef RTLD_BOOTSTRAP
if (sym != NULL)
-# endif
+# endif
{
-# ifndef RTLD_BOOTSTRAP
+# ifndef RTLD_BOOTSTRAP
CHECK_STATIC_TLS (map, sym_map);
-# endif
+# endif
/* We know the offset of the object the symbol is contained in.
It is a negative value which will be added to the
thread pointer. */
@@ -381,42 +386,41 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
- sym_map->l_tls_offset);
}
break;
-#endif
+# endif
-#ifndef RTLD_BOOTSTRAP
+# ifndef RTLD_BOOTSTRAP
case R_X86_64_64:
*reloc_addr = value + reloc->r_addend;
break;
case R_X86_64_32:
- *(unsigned int *) reloc_addr = value + reloc->r_addend;
- if (value + reloc->r_addend > UINT_MAX)
+ value += reloc->r_addend;
+ *(unsigned int *) reloc_addr = value;
+
+ const char *fmt;
+ if (__builtin_expect (value > UINT_MAX, 0))
{
const char *strtab;
+ fmt = "\
+%s: Symbol `%s' causes overflow in R_X86_64_32 relocation\n";
+ print_err:
strtab = (const char *) D_PTR (map, l_info[DT_STRTAB]);
- _dl_error_printf ("\
-%s: Symbol `%s' causes overflow in R_X86_64_32 relocation\n",
+ _dl_error_printf (fmt,
rtld_progname ?: "<program name unknown>",
strtab + refsym->st_name);
}
break;
-# ifndef RESOLVE_CONFLICT_FIND_MAP
+# ifndef RESOLVE_CONFLICT_FIND_MAP
/* Not needed for dl-conflict.c. */
case R_X86_64_PC32:
- *(unsigned int *) reloc_addr = value + reloc->r_addend
- - (Elf64_Addr) reloc_addr;
- if (value + reloc->r_addend - (Elf64_Addr) reloc_addr
- != (int)(value + reloc->r_addend - (Elf64_Addr) reloc_addr))
+ value += reloc->r_addend - (Elf64_Addr) reloc_addr;
+ *(unsigned int *) reloc_addr = value;
+ if (__builtin_expect (value != (unsigned int) value, 0))
{
- const char *strtab;
-
- strtab = (const char *) D_PTR (map, l_info[DT_STRTAB]);
-
- _dl_error_printf ("\
-%s: Symbol `%s' causes overflow in R_X86_64_PC32 relocation\n",
- rtld_progname ?: "<program name unknown>",
- strtab + refsym->st_name);
+ fmt = "\
+%s: Symbol `%s' causes overflow in R_X86_64_PC32 relocation\n";
+ goto print_err;
}
break;
case R_X86_64_COPY:
@@ -424,26 +428,22 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc,
/* This can happen in trace mode if an object could not be
found. */
break;
+ memcpy (reloc_addr_arg, (void *) value,
+ MIN (sym->st_size, refsym->st_size));
if (__builtin_expect (sym->st_size > refsym->st_size, 0)
|| (__builtin_expect (sym->st_size < refsym->st_size, 0)
&& GLRO(dl_verbose)))
{
- const char *strtab;
-
- strtab = (const char *) D_PTR (map, l_info[DT_STRTAB]);
- _dl_error_printf ("\
-%s: Symbol `%s' has different size in shared object, consider re-linking\n",
- rtld_progname ?: "<program name unknown>",
- strtab + refsym->st_name);
+ fmt = "\
+%s: Symbol `%s' has different size in shared object, consider re-linking\n";
+ goto print_err;
}
- memcpy (reloc_addr_arg, (void *) value,
- MIN (sym->st_size, refsym->st_size));
break;
-# endif
+# endif
default:
_dl_reloc_bad_type (map, r_type, 0);
break;
-#endif
+# endif
}
#endif
}
diff --git a/sysdeps/x86_64/dl-runtime.c b/sysdeps/x86_64/dl-runtime.c
new file mode 100644
index 0000000000..b625d1e882
--- /dev/null
+++ b/sysdeps/x86_64/dl-runtime.c
@@ -0,0 +1,9 @@
+/* The ABI calls for the PLT stubs to pass the index of the relocation
+ and not its offset. In _dl_profile_fixup and _dl_call_pltexit we
+ also use the index. Therefore it is wasteful to compute the offset
+ in the trampoline just to reverse the operation immediately
+ afterwards. */
+#define reloc_offset reloc_arg * sizeof (PLTREL)
+#define reloc_index reloc_arg
+
+#include <elf/dl-runtime.c>
diff --git a/sysdeps/x86_64/dl-trampoline.S b/sysdeps/x86_64/dl-trampoline.S
index 3e2d182758..d8d9bc12a4 100644
--- a/sysdeps/x86_64/dl-trampoline.S
+++ b/sysdeps/x86_64/dl-trampoline.S
@@ -1,5 +1,5 @@
/* PLT trampolines. x86-64 version.
- Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -35,11 +35,7 @@ _dl_runtime_resolve:
movq %r8, 40(%rsp)
movq %r9, 48(%rsp)
movq 64(%rsp), %rsi # Copy args pushed by PLT in register.
- movq %rsi, %r11 # Multiply by 24
- addq %r11, %rsi
- addq %r11, %rsi
- shlq $3, %rsi
- movq 56(%rsp), %rdi # %rdi: link_map, %rsi: reloc_offset
+ movq 56(%rsp), %rdi # %rdi: link_map, %rsi: reloc_index
call _dl_fixup # Call resolver.
movq %rax, %r11 # Save return value
movq 48(%rsp), %r9 # Get register content back.
@@ -61,132 +57,165 @@ _dl_runtime_resolve:
.type _dl_runtime_profile, @function
.align 16
cfi_startproc
+
_dl_runtime_profile:
- subq $88, %rsp
- cfi_adjust_cfa_offset(104) # Incorporate PLT
- movq %rax, (%rsp) # Preserve registers otherwise clobbered.
- movq %rdx, 8(%rsp)
- movq %r8, 16(%rsp)
- movq %r9, 24(%rsp)
- movq %rcx, 32(%rsp)
- movq %rsi, 40(%rsp)
- movq %rdi, 48(%rsp)
- movq %rbp, 56(%rsp) # Information for auditors.
- leaq 104(%rsp), %rax
- movq %rax, 64(%rsp)
- leaq 8(%rsp), %rcx
- movq 104(%rsp), %rdx # Load return address if needed
- movq 96(%rsp), %rsi # Copy args pushed by PLT in register.
- movq %rsi,%r11 # Multiply by 24
- addq %r11,%rsi
- addq %r11,%rsi
- shlq $3, %rsi
- movq 88(%rsp), %rdi # %rdi: link_map, %rsi: reloc_offset
- leaq 72(%rsp), %r8
+ /* The La_x86_64_regs data structure pointed to by the
+ fourth paramater must be 16-byte aligned. This must
+ be explicitly enforced. We have the set up a dynamically
+ sized stack frame. %rbx points to the top half which
+ has a fixed size and preserves the original stack pointer. */
+
+ subq $32, %rsp # Allocate the local storage.
+ cfi_adjust_cfa_offset(48) # Incorporate PLT
+ movq %rbx, (%rsp)
+ cfi_rel_offset(%rbx, 0)
+
+ /* On the stack:
+ 56(%rbx) parameter #1
+ 48(%rbx) return address
+
+ 40(%rbx) reloc index
+ 32(%rbx) link_map
+
+ 24(%rbx) La_x86_64_regs pointer
+ 16(%rbx) framesize
+ 8(%rbx) rax
+ (%rbx) rbx
+ */
+
+ movq %rax, 8(%rsp)
+ movq %rsp, %rbx
+ cfi_def_cfa_register(%rbx)
+
+ /* Actively align the La_x86_64_regs structure. */
+ andq $0xfffffffffffffff0, %rsp
+ subq $192, %rsp # sizeof(La_x86_64_regs)
+ movq %rsp, 24(%rbx)
+
+ movq %rdx, (%rsp) # Fill the La_x86_64_regs structure.
+ movq %r8, 8(%rsp)
+ movq %r9, 16(%rsp)
+ movq %rcx, 24(%rsp)
+ movq %rsi, 32(%rsp)
+ movq %rdi, 40(%rsp)
+ movq %rbp, 48(%rsp)
+ leaq 48(%rbx), %rax
+ movq %rax, 56(%rsp)
+ movaps %xmm0, 64(%rsp)
+ movaps %xmm1, 80(%rsp)
+ movaps %xmm2, 96(%rsp)
+ movaps %xmm3, 112(%rsp)
+ movaps %xmm4, 128(%rsp)
+ movaps %xmm5, 144(%rsp)
+ movaps %xmm7, 160(%rsp)
+
+ movq %rsp, %rcx # La_x86_64_regs pointer to %rcx.
+ movq 48(%rbx), %rdx # Load return address if needed.
+ movq 40(%rbx), %rsi # Copy args pushed by PLT in register.
+ movq 32(%rbx), %rdi # %rdi: link_map, %rsi: reloc_index
+ leaq 16(%rbx), %r8
call _dl_profile_fixup # Call resolver.
- movq %rax, %r11 # Save return value
- movq 8(%rsp), %rdx # Get back register content.
- movq 16(%rsp), %r8
- movq 24(%rsp), %r9
- movq (%rsp),%rax
- movq 72(%rsp), %r10
+
+ movq %rax, %r11 # Save return value.
+
+ movq 8(%rbx), %rax # Get back register content.
+ movq (%rsp), %rdx
+ movq 8(%rsp), %r8
+ movq 16(%rsp), %r9
+ movaps 64(%rsp), %xmm0
+ movaps 80(%rsp), %xmm1
+ movaps 96(%rsp), %xmm2
+ movaps 112(%rsp), %xmm3
+ movaps 128(%rsp), %xmm4
+ movaps 144(%rsp), %xmm5
+ movaps 160(%rsp), %xmm7
+
+ movq 16(%rbx), %r10 # Anything in framesize?
testq %r10, %r10
jns 1f
- movq 32(%rsp), %rcx
- movq 40(%rsp), %rsi
- movq 48(%rsp), %rdi
- addq $104,%rsp # Adjust stack
- cfi_adjust_cfa_offset (-104)
+
+ /* There's nothing in the frame size, so there
+ will be no call to the _dl_call_pltexit. */
+
+ movq 24(%rsp), %rcx # Get back registers content.
+ movq 32(%rsp), %rsi
+ movq 40(%rsp), %rdi
+
+ movq %rbx, %rsp
+ movq (%rsp), %rbx
+ cfi_restore(rbx)
+ cfi_def_cfa_register(%rsp)
+
+ addq $48, %rsp # Adjust the stack to the return value
+ # (eats the reloc index and link_map)
+ cfi_adjust_cfa_offset(-48)
jmp *%r11 # Jump to function address.
- /*
- +104 return address
- +96 PLT2
- +88 PLT1
- +80 free
- +72 free
- +64 %rsp
- +56 %rbp
- +48 %rdi
- +40 %rsi
- +32 %rcx
- +24 %r9
- +16 %r8
- +8 %rdx
- %rsp %rax
- */
- cfi_adjust_cfa_offset (104)
-1: movq %rbx, 72(%rsp)
- cfi_rel_offset (rbx, 72)
- leaq 112(%rsp), %rsi
- movq %rsp, %rbx
- cfi_def_cfa_register (%rbx)
- movq %r10, %rcx
+1:
+ cfi_adjust_cfa_offset(48)
+ cfi_rel_offset(%rbx, 0)
+ cfi_def_cfa_register(%rbx)
+
+ /* At this point we need to prepare new stack for the function
+ which has to be called. We copy the original stack to a
+ temporary buffer of the size specified by the 'framesize'
+ returned from _dl_profile_fixup */
+
+ leaq 56(%rbx), %rsi # stack
addq $8, %r10
andq $0xfffffffffffffff0, %r10
+ movq %r10, %rcx
subq %r10, %rsp
movq %rsp, %rdi
shrq $3, %rcx
rep
movsq
- movq 32(%rbx), %rcx
- movq 40(%rbx), %rsi
- movq 48(%rbx), %rdi
+
+ movq 24(%rdi), %rcx # Get back register content.
+ movq 32(%rdi), %rsi
+ movq 40(%rdi), %rdi
+
call *%r11
- movq %rbx, %rsp
- cfi_def_cfa_register (%rsp)
- subq $72, %rsp
- cfi_adjust_cfa_offset (72)
- movq %rsp, %rcx
- movq %rax, (%rcx)
+
+ mov 24(%rbx), %rsp # Drop the copied stack content
+
+ /* Now we have to prepare the La_x86_64_retval structure for the
+ _dl_call_pltexit. The La_x86_64_regs is being pointed by rsp now,
+ so we just need to allocate the sizeof(La_x86_64_retval) space on
+ the stack, since the alignment has already been taken care of. */
+
+ subq $80, %rsp # sizeof(La_x86_64_retval)
+ movq %rsp, %rcx # La_x86_64_retval argument to %rcx.
+
+ movq %rax, (%rcx) # Fill in the La_x86_64_retval structure.
movq %rdx, 8(%rcx)
- /* Even though the stack is correctly aligned to allow using movaps
- we use movups. Some callers might provide an incorrectly aligned
- stack and we do not want to have it blow up here. */
- movups %xmm0, 16(%rcx)
- movups %xmm1, 32(%rcx)
+ movaps %xmm0, 16(%rcx)
+ movaps %xmm1, 32(%rcx)
fstpt 48(%rcx)
fstpt 64(%rcx)
- /*
- +176 return address
- +168 PLT2
- +160 PLT1
- +152 free
- +144 free
- +136 %rsp
- +128 %rbp
- +120 %rdi
- +112 %rsi
- +104 %rcx
- +96 %r9
- +88 %r8
- +80 %rdx
- +64 %st1 result
- +48 %st result
- +32 %xmm1 result
- +16 %xmm0 result
- +8 %rdx result
- %rsp %rax result
- */
- leaq 80(%rsp), %rdx
- movq 144(%rsp), %rbx
- cfi_restore (rbx)
- movq 168(%rsp), %rsi # Copy args pushed by PLT in register.
- movq %rsi,%r11 # Multiply by 24
- addq %r11,%rsi
- addq %r11,%rsi
- shlq $3, %rsi
- movq 160(%rsp), %rdi # %rdi: link_map, %rsi: reloc_offset
+
+ movq 24(%rbx), %rdx # La_x86_64_regs argument to %rdx.
+ movq 40(%rbx), %rsi # Copy args pushed by PLT in register.
+ movq 32(%rbx), %rdi # %rdi: link_map, %rsi: reloc_index
call _dl_call_pltexit
- movq (%rsp), %rax
+
+ movq (%rsp), %rax # Restore return registers.
movq 8(%rsp), %rdx
- movups 16(%rsp), %xmm0
- movups 32(%rsp), %xmm1
+ movaps 16(%rsp), %xmm0
+ movaps 32(%rsp), %xmm1
fldt 64(%rsp)
fldt 48(%rsp)
- addq $176, %rsp
- cfi_adjust_cfa_offset (-176)
+
+ movq %rbx, %rsp
+ movq (%rsp), %rbx
+ cfi_restore(rbx)
+ cfi_def_cfa_register(%rsp)
+
+ addq $48, %rsp # Adjust the stack to the return value
+ # (eats the reloc index and link_map)
+ cfi_adjust_cfa_offset(-48)
retq
+
cfi_endproc
.size _dl_runtime_profile, .-_dl_runtime_profile
#endif
diff --git a/sysdeps/x86_64/multiarch/Makefile b/sysdeps/x86_64/multiarch/Makefile
new file mode 100644
index 0000000000..2a1e910e06
--- /dev/null
+++ b/sysdeps/x86_64/multiarch/Makefile
@@ -0,0 +1,3 @@
+ifeq ($(subdir),csu)
+aux += init-arch
+endif
diff --git a/sysdeps/x86_64/multiarch/init-arch.c b/sysdeps/x86_64/multiarch/init-arch.c
new file mode 100644
index 0000000000..eb4365fe32
--- /dev/null
+++ b/sysdeps/x86_64/multiarch/init-arch.c
@@ -0,0 +1,65 @@
+/* Initialize CPU feature data.
+ This file is part of the GNU C Library.
+ Copyright (C) 2008 Free Software Foundation, Inc.
+ Contributed by Ulrich Drepper <drepper@redhat.com>.
+
+ 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 "init-arch.h"
+
+
+struct cpu_features __cpu_features attribute_hidden;
+
+
+void
+__init_cpu_features (void)
+{
+ unsigned int ebx;
+ unsigned int ecx;
+ unsigned int edx;
+
+ asm volatile ("cpuid"
+ : "=a" (__cpu_features.max_cpuid), "=b" (ebx), "=c" (ecx),
+ "=d" (edx)
+ : "0" (0));
+
+ /* This spells out "GenuineIntel". */
+ if (ebx == 0x756e6547 && ecx == 0x6c65746e && edx == 0x49656e69)
+ {
+ __cpu_features.kind = arch_kind_intel;
+
+ asm volatile ("cpuid"
+ : "=a" (__cpu_features.cpuid[INTEL_CPUID_INDEX_1].eax),
+ "=b" (__cpu_features.cpuid[INTEL_CPUID_INDEX_1].ebx),
+ "=c" (__cpu_features.cpuid[INTEL_CPUID_INDEX_1].ecx),
+ "=d" (__cpu_features.cpuid[INTEL_CPUID_INDEX_1].edx)
+ : "0" (1));
+ }
+ /* This spells out "AuthenticAMD". */
+ else if (ebx == 0x68747541 && ecx == 0x444d4163 && edx == 0x69746e65)
+ {
+ __cpu_features.kind = arch_kind_amd;
+
+ asm volatile ("cpuid"
+ : "=a" (__cpu_features.cpuid[AMD_CPUID_INDEX_1].eax),
+ "=b" (__cpu_features.cpuid[AMD_CPUID_INDEX_1].ebx),
+ "=c" (__cpu_features.cpuid[AMD_CPUID_INDEX_1].ecx),
+ "=d" (__cpu_features.cpuid[AMD_CPUID_INDEX_1].edx)
+ : "0" (1));
+ }
+ else
+ __cpu_features.kind = arch_kind_other;
+}
diff --git a/sysdeps/x86_64/multiarch/init-arch.h b/sysdeps/x86_64/multiarch/init-arch.h
new file mode 100644
index 0000000000..86cd83dc4c
--- /dev/null
+++ b/sysdeps/x86_64/multiarch/init-arch.h
@@ -0,0 +1,70 @@
+/* This file is part of the GNU C Library.
+ Copyright (C) 2008 Free Software Foundation, Inc.
+
+ 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 <sys/param.h>
+
+enum
+ {
+ INTEL_CPUID_INDEX_1 = 0,
+ /* Keep the following line at the end. */
+ INTEL_CPUID_INDEX_MAX
+ };
+
+enum
+ {
+ AMD_CPUID_INDEX_1 = 0,
+ /* Keep the following line at the end. */
+ AMD_CPUID_INDEX_MAX
+ };
+
+extern struct cpu_features
+{
+ enum
+ {
+ arch_kind_unknown = 0,
+ arch_kind_intel,
+ arch_kind_amd,
+ arch_kind_other
+ } kind;
+ int max_cpuid;
+ struct
+ {
+ unsigned int eax;
+ unsigned int ebx;
+ unsigned int ecx;
+ unsigned int edx;
+ } cpuid[MAX (INTEL_CPUID_INDEX_MAX, AMD_CPUID_INDEX_MAX)];
+} __cpu_features attribute_hidden;
+
+
+extern void __init_cpu_features (void) attribute_hidden;
+#define INIT_ARCH()\
+ do \
+ if (__cpu_features.kind == arch_kind_unknown) \
+ __init_cpu_features (); \
+ while (0)
+
+/* Following are the feature tests used throughout libc. */
+
+#define INTEL_HAS_POPCOUNT \
+ (__cpu_features.kind == arch_kind_intel \
+ && (__cpu_features.cpuid[INTEL_CPUID_INDEX_1].ecx & (1 << 23)) != 0)
+
+#define AMD_HAS_POPCOUNT \
+ (__cpu_features.kind == arch_kind_amd \
+ && (__cpu_features.cpuid[AMD_CPUID_INDEX_1].ecx & (1 << 23)) != 0)
diff --git a/sysdeps/x86_64/multiarch/sched_cpucount.c b/sysdeps/x86_64/multiarch/sched_cpucount.c
new file mode 100644
index 0000000000..dc20182df4
--- /dev/null
+++ b/sysdeps/x86_64/multiarch/sched_cpucount.c
@@ -0,0 +1,42 @@
+/* Count bits in CPU set. x86-64 multi-arch version.
+ This file is part of the GNU C Library.
+ Copyright (C) 2008 Free Software Foundation, Inc.
+ Contributed by Ulrich Drepper <drepper@redhat.com>.
+
+ 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. */
+
+#ifdef SHARED
+# include <sched.h>
+# include "init-arch.h"
+
+# define __sched_cpucount static generic_cpucount
+# include <posix/sched_cpucount.c>
+# undef __sched_cpucount
+
+# define POPCNT(l) \
+ ({ __cpu_mask r; \
+ asm ("popcntq %1, %0" : "=r" (r) : "0" (l));\
+ r; })
+# define __sched_cpucount static popcount_cpucount
+# include <posix/sched_cpucount.c>
+# undef __sched_cpucount
+
+libc_ifunc (__sched_cpucount,
+ INTEL_HAS_POPCOUNT || AMD_HAS_POPCOUNT
+ ? popcount_cpucount : generic_cpucount);
+#else
+# include_next <sched_cpucount.c>
+#endif