From 609ad6b89eee3485cfdad311d2ff9bcc86c4d3cd Mon Sep 17 00:00:00 2001 From: joseph Date: Mon, 1 Jun 2009 13:59:14 +0000 Subject: Merge changes between r8486 and r8519 from /fsf/trunk. git-svn-id: svn://svn.eglibc.org/trunk@8520 7b3dc134-2b1b-0410-93df-9e9f96275f8d --- libc/.gitignore | 5 - libc/ChangeLog | 77 ++++++++++ libc/NEWS | 5 +- libc/configure | 128 ++++++++-------- libc/configure.in | 4 +- libc/csu/elf-init.c | 30 ++++ libc/elf/elf.h | 6 +- libc/include/libc-symbols.h | 17 +++ libc/nptl_db/ChangeLog | 6 + libc/nptl_db/db-symbols.awk | 2 +- libc/sysdeps/generic/dl-irel.h | 23 +++ libc/sysdeps/i386/dl-irel.h | 44 ++++++ libc/sysdeps/i386/dl-machine.h | 24 +++ libc/sysdeps/ieee754/ldbl-128/s_cosl.c | 10 +- libc/sysdeps/ieee754/ldbl-128/s_expm1l.c | 6 +- libc/sysdeps/ieee754/ldbl-128/s_sinl.c | 10 +- libc/sysdeps/ieee754/ldbl-128/s_tanl.c | 10 +- libc/sysdeps/s390/s390-32/____longjmp_chk.c | 41 ++++++ libc/sysdeps/s390/s390-32/__longjmp.c | 7 +- libc/sysdeps/s390/s390-64/____longjmp_chk.c | 41 ++++++ libc/sysdeps/s390/s390-64/__longjmp.c | 7 +- .../unix/sysv/linux/i386/internal_accept4.S | 1 + libc/sysdeps/unix/sysv/linux/i386/sysconf.c | 156 ++++++++++---------- libc/sysdeps/x86_64/cacheinfo.c | 162 ++++++++++----------- libc/sysdeps/x86_64/dl-irel.h | 44 ++++++ libc/sysdeps/x86_64/dl-machine.h | 12 ++ libc/sysdeps/x86_64/multiarch/init-arch.c | 18 +-- libc/sysdeps/x86_64/multiarch/init-arch.h | 24 +-- libc/sysdeps/x86_64/multiarch/sched_cpucount.c | 27 ++-- 29 files changed, 662 insertions(+), 285 deletions(-) create mode 100644 libc/sysdeps/generic/dl-irel.h create mode 100644 libc/sysdeps/i386/dl-irel.h create mode 100644 libc/sysdeps/s390/s390-32/____longjmp_chk.c create mode 100644 libc/sysdeps/s390/s390-64/____longjmp_chk.c create mode 100644 libc/sysdeps/unix/sysv/linux/i386/internal_accept4.S create mode 100644 libc/sysdeps/x86_64/dl-irel.h diff --git a/libc/.gitignore b/libc/.gitignore index 3b3f0e750..d9294bec0 100644 --- a/libc/.gitignore +++ b/libc/.gitignore @@ -23,12 +23,7 @@ glibc-* configparms -sun[43]* -i[345]86* -hp300* - ieeetest -hppa-sysdeps regex gpl2lgpl.sed diff --git a/libc/ChangeLog b/libc/ChangeLog index 45be576e1..6355577d8 100644 --- a/libc/ChangeLog +++ b/libc/ChangeLog @@ -1,3 +1,80 @@ +2009-05-31 Ulrich Drepper + + * sysdeps/x86_64/multiarch/sched_cpucount.c: Also use optimized code + for !SHARED. + +2009-05-29 H.J. Lu + + * csu/elf-init.c: Include and if LIBC_NONSHARED + is not defined. + (__rela_iplt_start): New declaration. + (__rela_iplt_end): Likewise. + (__rel_iplt_start): Likewise. + (__rel_iplt_end): Likewise. + (__libc_csu_init): Process __rela_iplt_start and __rel_iplt_start. + * elf/elf.h (R_386_IRELATIVE): New macro. + (R_X86_64_IRELATIVE): New macro. + (R_386_NUM): Updated. + (R_X86_64_NUM): Likewise. + * include/libc-symbols.h (libc_ifunc_hidden_def1): New macro. + (libc_ifunc_hidden_def): New macro. + * sysdeps/generic/dl-irel.h: New file. + * sysdeps/i386/dl-irel.h: New file. + * sysdeps/x86_64/dl-irel.h: New file. + * sysdeps/i386/dl-machine.h (elf_machine_rel): Handle R_386_IRELATIVE. + (elf_machine_rela): Check SHN_UNDEF for STT_GNU_IFUNC symbol. + Handle R_386_IRELATIVE. + (elf_machine_lazy_rel): Handle R_386_IRELATIVE. + (elf_machine_lazy_rela): Likewise. + * sysdeps/x86_64/dl-machine.h (elf_machine_rela): Handle + R_X86_64_IRELATIVE. + (elf_machine_lazy_rel): Handle R_X86_64_IRELATIVE. + +2009-05-31 Ulrich Drepper + + * sysdeps/x86_64/multiarch/init-arch.h: Define COMMON_CPUID_INDEX_1 + instead of INTEL_CPUID_INDEX_1 and AMD_CPUID_INDEX_1. So far there + are no differences. If an architecture has bits in CPUID index 1 + meaning different things the values for the COMMON_CPUID_INDEX_1 + index must not be set. + (INTEL_HAS_POPCOUNT, AMD_HAS_POPCOUNT): Removed in favor of... + (HAS_POPCOUNT): ...this. New macro. + * sysdeps/x86_64/multiarch/init-arch.c: Use COMMON_CPUID_INDEX_1 + instead of INTEL_CPUID_INDEX_1 and AMD_CPUID_INDEX_1. Unify code + to set the value for Intel and AMD architectures. + * sysdeps/x86_64/cacheinfo.c: Use COMMON_CPUID_INDEX_1 instead of + INTEL_CPUID_INDEX_1. + * sysdeps/x86_64/multiarch/sched_cpucount.c: Adjust for HAS_POPCOUNT + change. + +2009-05-30 Andreas Schwab + + * configure.in: Move AC_CANONICAL_HOST before first use of $host + and $build. + +2009-05-29 Jakub Jelinek + + * sysdeps/ieee754/ldbl-128/s_expm1l.c: Include . + (__expm1l): Set errno to ERANGE on overflow. + * sysdeps/ieee754/ldbl-128/s_tanl.c: Include . + (__tanl): Set errno to EDOM for ±Inf. + * sysdeps/ieee754/ldbl-128/s_cosl.c: Include . + (__cosl): Set errno to EDOM for ±Inf. + * sysdeps/ieee754/ldbl-128/s_sinl.c: Include . + (__sinl): Set errno to EDOM for ±Inf. + + * sysdeps/s390/s390-32/__longjmp.c (__longjmp): If CHECK_SP is + defined, use it. + * sysdeps/s390/s390-64/__longjmp.c (__longjmp): Likewise. + * sysdeps/s390/s390-32/____longjmp_chk.c: New file. + * sysdeps/s390/s390-64/____longjmp_chk.c: New file. + +2009-05-29 Ulrich Drepper + + * sysdeps/x86_64/cacheinfo.c: Compact intel_02_known array. Adjust + code accessing it. + * sysdeps/unix/sysv/linux/i386/sysconf.c: Likewise. + 2009-05-22 Andreas Schwab * sysdeps/ieee754/ldbl-128ibm/s_sinl.c: Set errno for ±Inf. diff --git a/libc/NEWS b/libc/NEWS index 5393e73ee..5ca4e6058 100644 --- a/libc/NEWS +++ b/libc/NEWS @@ -1,4 +1,4 @@ -GNU C Library NEWS -- history of user-visible changes. 2009-5-15 +GNU C Library NEWS -- history of user-visible changes. 2009-5-31 Copyright (C) 1992-2008, 2009 Free Software Foundation, Inc. See the end for copying conditions. @@ -10,6 +10,9 @@ Version 2.11 * checking version of longjmp added that fails if an uninitialized stack frame would be created. Implemented by Ulrich Drepper. +* STT_GNU_IFUNC is now supported in static executables. + Implemented by H.J. Lu. + Version 2.10 diff --git a/libc/configure b/libc/configure index a8b25a30c..5d89dca03 100755 --- a/libc/configure +++ b/libc/configure @@ -313,7 +313,7 @@ ac_includes_default="\ # include #endif" -ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC OBJEXT BUILD_CC cross_compiling CPP CXX CXXFLAGS ac_ct_CXX with_fp with_cvs enable_check_abi oldest_abi bindnow force_install all_warnings PKGVERSION REPORT_BUGS_TO REPORT_BUGS_TEXI multi_arch experimental_malloc libc_cv_nss_crypt build build_cpu build_vendor build_os host host_cpu host_vendor host_os subdirs add_ons add_on_subdirs base_machine submachine sysnames sysdeps_add_ons INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LN_S AR NM OBJDUMP RANLIB ac_ct_RANLIB MIG AS LD PWD_P MAKE MSGFMT MAKEINFO SED AUTOCONF SYSINCLUDES CXX_SYSINCLUDES libc_cv_gcc_static_libgcc BASH_SHELL libc_cv_have_bash2 KSH libc_cv_have_ksh AWK PERL INSTALL_INFO BISON VERSIONING libc_cv_cc_with_libunwind libc_cv_Bgroup libc_cv_libgcc_s_suffix libc_cv_as_needed ASFLAGS_config libc_cv_z_combreloc libc_cv_z_execstack libc_cv_fpie libc_cv_hashstyle fno_unit_at_a_time libc_cv_ssp libc_cv_gnu89_inline libc_cv_have_initfini no_whole_archive exceptions libc_cv_cc_submachine LIBGD have_libaudit have_libcap have_selinux EGREP sizeof_long_double libc_cv_gcc_unwind_find_fde uname_sysname uname_release uname_version old_glibc_headers libc_cv_slibdir libc_cv_localedir libc_cv_sysconfdir libc_cv_rootsbindir libc_cv_forced_unwind libc_cv_cpp_asm_debuginfo use_ldconfig ldd_rewrite_script elf xcoff static shared libc_cv_pic_default profile omitfp bounded static_nss nopic_initfini DEFINES mach_interface_list VERSION RELEASE LIBOBJS LTLIBOBJS' +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC OBJEXT BUILD_CC cross_compiling CPP CXX CXXFLAGS ac_ct_CXX with_fp with_cvs enable_check_abi oldest_abi bindnow force_install all_warnings PKGVERSION REPORT_BUGS_TO REPORT_BUGS_TEXI multi_arch experimental_malloc libc_cv_nss_crypt subdirs add_ons add_on_subdirs base_machine submachine sysnames sysdeps_add_ons INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LN_S AR NM OBJDUMP RANLIB ac_ct_RANLIB MIG AS LD PWD_P MAKE MSGFMT MAKEINFO SED AUTOCONF SYSINCLUDES CXX_SYSINCLUDES libc_cv_gcc_static_libgcc BASH_SHELL libc_cv_have_bash2 KSH libc_cv_have_ksh AWK PERL INSTALL_INFO BISON VERSIONING libc_cv_cc_with_libunwind libc_cv_Bgroup libc_cv_libgcc_s_suffix libc_cv_as_needed ASFLAGS_config libc_cv_z_combreloc libc_cv_z_execstack libc_cv_fpie libc_cv_hashstyle fno_unit_at_a_time libc_cv_ssp libc_cv_gnu89_inline libc_cv_have_initfini no_whole_archive exceptions libc_cv_cc_submachine LIBGD have_libaudit have_libcap have_selinux EGREP sizeof_long_double libc_cv_gcc_unwind_find_fde uname_sysname uname_release uname_version old_glibc_headers libc_cv_slibdir libc_cv_localedir libc_cv_sysconfdir libc_cv_rootsbindir libc_cv_forced_unwind libc_cv_cpp_asm_debuginfo use_ldconfig ldd_rewrite_script elf xcoff static shared libc_cv_pic_default profile omitfp bounded static_nss nopic_initfini DEFINES mach_interface_list VERSION RELEASE LIBOBJS LTLIBOBJS' ac_subst_files='' # Initialize some variables set by options. @@ -1403,6 +1403,61 @@ ac_config_sub="$SHELL $ac_aux_dir/config.sub" ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. +# Make sure we can run config.sub. +$ac_config_sub sun4 >/dev/null 2>&1 || + { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5 +echo "$as_me: error: cannot run $ac_config_sub" >&2;} + { (exit 1); exit 1; }; } + +echo "$as_me:$LINENO: checking build system type" >&5 +echo $ECHO_N "checking build system type... $ECHO_C" >&6 +if test "${ac_cv_build+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_build_alias=$build_alias +test -z "$ac_cv_build_alias" && + ac_cv_build_alias=`$ac_config_guess` +test -z "$ac_cv_build_alias" && + { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 +echo "$as_me: error: cannot guess build type; you must specify one" >&2;} + { (exit 1); exit 1; }; } +ac_cv_build=`$ac_config_sub $ac_cv_build_alias` || + { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5 +echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +echo "$as_me:$LINENO: result: $ac_cv_build" >&5 +echo "${ECHO_T}$ac_cv_build" >&6 +build=$ac_cv_build +build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + + +echo "$as_me:$LINENO: checking host system type" >&5 +echo $ECHO_N "checking host system type... $ECHO_C" >&6 +if test "${ac_cv_host+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_host_alias=$host_alias +test -z "$ac_cv_host_alias" && + ac_cv_host_alias=$ac_cv_build_alias +ac_cv_host=`$ac_config_sub $ac_cv_host_alias` || + { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5 +echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +echo "$as_me:$LINENO: result: $ac_cv_host" >&5 +echo "${ECHO_T}$ac_cv_host" >&6 +host=$ac_cv_host +host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + + + ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -3314,61 +3369,6 @@ else fi -# Make sure we can run config.sub. -$ac_config_sub sun4 >/dev/null 2>&1 || - { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5 -echo "$as_me: error: cannot run $ac_config_sub" >&2;} - { (exit 1); exit 1; }; } - -echo "$as_me:$LINENO: checking build system type" >&5 -echo $ECHO_N "checking build system type... $ECHO_C" >&6 -if test "${ac_cv_build+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_build_alias=$build_alias -test -z "$ac_cv_build_alias" && - ac_cv_build_alias=`$ac_config_guess` -test -z "$ac_cv_build_alias" && - { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 -echo "$as_me: error: cannot guess build type; you must specify one" >&2;} - { (exit 1); exit 1; }; } -ac_cv_build=`$ac_config_sub $ac_cv_build_alias` || - { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5 -echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;} - { (exit 1); exit 1; }; } - -fi -echo "$as_me:$LINENO: result: $ac_cv_build" >&5 -echo "${ECHO_T}$ac_cv_build" >&6 -build=$ac_cv_build -build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` -build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` -build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` - - -echo "$as_me:$LINENO: checking host system type" >&5 -echo $ECHO_N "checking host system type... $ECHO_C" >&6 -if test "${ac_cv_host+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_host_alias=$host_alias -test -z "$ac_cv_host_alias" && - ac_cv_host_alias=$ac_cv_build_alias -ac_cv_host=`$ac_config_sub $ac_cv_host_alias` || - { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5 -echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;} - { (exit 1); exit 1; }; } - -fi -echo "$as_me:$LINENO: result: $ac_cv_host" >&5 -echo "${ECHO_T}$ac_cv_host" >&6 -host=$ac_cv_host -host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` -host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` -host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` - - - # The way shlib-versions is used to generate soversions.mk uses a # fairly simplistic model for name recognition that can't distinguish # i486-pc-linux-gnu fully from i486-pc-gnu. So we mutate a $host_os @@ -8732,6 +8732,14 @@ s,@ECHO_C@,$ECHO_C,;t t s,@ECHO_N@,$ECHO_N,;t t s,@ECHO_T@,$ECHO_T,;t t s,@LIBS@,$LIBS,;t t +s,@build@,$build,;t t +s,@build_cpu@,$build_cpu,;t t +s,@build_vendor@,$build_vendor,;t t +s,@build_os@,$build_os,;t t +s,@host@,$host,;t t +s,@host_cpu@,$host_cpu,;t t +s,@host_vendor@,$host_vendor,;t t +s,@host_os@,$host_os,;t t s,@CC@,$CC,;t t s,@CFLAGS@,$CFLAGS,;t t s,@LDFLAGS@,$LDFLAGS,;t t @@ -8757,14 +8765,6 @@ s,@REPORT_BUGS_TEXI@,$REPORT_BUGS_TEXI,;t t s,@multi_arch@,$multi_arch,;t t s,@experimental_malloc@,$experimental_malloc,;t t s,@libc_cv_nss_crypt@,$libc_cv_nss_crypt,;t t -s,@build@,$build,;t t -s,@build_cpu@,$build_cpu,;t t -s,@build_vendor@,$build_vendor,;t t -s,@build_os@,$build_os,;t t -s,@host@,$host,;t t -s,@host_cpu@,$host_cpu,;t t -s,@host_vendor@,$host_vendor,;t t -s,@host_os@,$host_os,;t t s,@subdirs@,$subdirs,;t t s,@add_ons@,$add_ons,;t t s,@add_on_subdirs@,$add_on_subdirs,;t t diff --git a/libc/configure.in b/libc/configure.in index b0ca65e9a..e2d9706b4 100644 --- a/libc/configure.in +++ b/libc/configure.in @@ -6,6 +6,8 @@ AC_CONFIG_SRCDIR([include/features.h]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_AUX_DIR([scripts]) +AC_CANONICAL_HOST + AC_PROG_CC if test $host != $build; then AC_CHECK_PROGS(BUILD_CC, gcc cc) @@ -321,8 +323,6 @@ else fi AC_SUBST(libc_cv_nss_crypt) -AC_CANONICAL_HOST - # The way shlib-versions is used to generate soversions.mk uses a # fairly simplistic model for name recognition that can't distinguish # i486-pc-linux-gnu fully from i486-pc-gnu. So we mutate a $host_os diff --git a/libc/csu/elf-init.c b/libc/csu/elf-init.c index 27eae1550..5a99a3a40 100644 --- a/libc/csu/elf-init.c +++ b/libc/csu/elf-init.c @@ -36,6 +36,20 @@ #include +#ifndef LIBC_NONSHARED +# include +# include + +# ifdef ELF_MACHINE_IRELA +extern const ElfW(Rela) __rela_iplt_start []; +extern const ElfW(Rela) __rela_iplt_end []; +# endif + +# ifdef ELF_MACHINE_IREL +extern const ElfW(Rel) __rel_iplt_start []; +extern const ElfW(Rel) __rel_iplt_end []; +# endif +#endif /* LIBC_NONSHARED */ /* These magic symbols are provided by the linker. */ extern void (*__preinit_array_start []) (int, char **, char **) @@ -67,6 +81,22 @@ __libc_csu_init (int argc, char **argv, char **envp) the dynamic linker (before initializing any shared object. */ #ifndef LIBC_NONSHARED +# ifdef ELF_MACHINE_IRELA + { + const size_t size = __rela_iplt_end - __rela_iplt_start; + for (size_t i = 0; i < size; i++) + elf_irela (&__rela_iplt_start [i]); + } +# endif + +# ifdef ELF_MACHINE_IREL + { + const size_t size = __rel_iplt_end - __rel_iplt_start; + for (size_t i = 0; i < size; i++) + elf_irel (&__rel_iplt_start [i]); + } +# endif + /* For static executables, preinit happens rights before init. */ { const size_t size = __preinit_array_end - __preinit_array_start; diff --git a/libc/elf/elf.h b/libc/elf/elf.h index 062ef00f5..8fdf74b09 100644 --- a/libc/elf/elf.h +++ b/libc/elf/elf.h @@ -1177,8 +1177,9 @@ typedef struct pointer to code and to argument, returning the TLS offset for the symbol. */ +#define R_386_IRELATIVE 42 /* Adjust indirectly by program base */ /* Keep this the last entry. */ -#define R_386_NUM 42 +#define R_386_NUM 43 /* SUN SPARC specific definitions. */ @@ -2625,8 +2626,9 @@ typedef Elf32_Addr Elf32_Conflict; #define R_X86_64_TLSDESC_CALL 35 /* Marker for call through TLS descriptor. */ #define R_X86_64_TLSDESC 36 /* TLS descriptor. */ +#define R_X86_64_IRELATIVE 37 /* Adjust indirectly by program base */ -#define R_X86_64_NUM 37 +#define R_X86_64_NUM 38 /* AM33 relocations. */ diff --git a/libc/include/libc-symbols.h b/libc/include/libc-symbols.h index d53bcb9b7..68da77c58 100644 --- a/libc/include/libc-symbols.h +++ b/libc/include/libc-symbols.h @@ -845,4 +845,21 @@ for linking") } \ __asm__ (".type " #name ", %gnu_indirect_function"); +#ifdef HAVE_ASM_SET_DIRECTIVE +# define libc_ifunc_hidden_def1(local, name) \ + __asm__ (declare_symbol_alias_1_stringify (ASM_GLOBAL_DIRECTIVE) \ + " " #local "\n\t" \ + ".hidden " #local "\n\t" \ + ".set " #local ", " #name); +#else +# define libc_ifunc_hidden_def1(local, name) \ + __asm__ (declare_symbol_alias_1_stringify (ASM_GLOBAL_DIRECTIVE) \ + " " #local "\n\t" \ + ".hidden " #local "\n\t" \ + #local " = " #name); +#endif + +#define libc_ifunc_hidden_def(name) \ + libc_ifunc_hidden_def1 (__GI_##name, name) + #endif /* libc-symbols.h */ diff --git a/libc/nptl_db/ChangeLog b/libc/nptl_db/ChangeLog index 8c07d9f32..1ade1968a 100644 --- a/libc/nptl_db/ChangeLog +++ b/libc/nptl_db/ChangeLog @@ -1,3 +1,9 @@ +2009-05-25 Aurelien Jarno + + [BZ #10200] + * db-symbols.awk: Use the last field for the symbol name instead + of the 8th one. + 2009-03-19 Roland McGrath * td_symbol_list.c (DB_LOOKUP_NAME, DB_LOOKUP_NAME_TH_UNIQUE): diff --git a/libc/nptl_db/db-symbols.awk b/libc/nptl_db/db-symbols.awk index 33272138f..f9a91b93b 100644 --- a/libc/nptl_db/db-symbols.awk +++ b/libc/nptl_db/db-symbols.awk @@ -14,7 +14,7 @@ NF == 0 { in_symtab=0; next } !in_symtab { next } -NF >= 8 && $7 != "UND" { seen[$8] = 1 } +NF >= 8 && $7 != "UND" { seen[$NF] = 1 } END { status = 0; diff --git a/libc/sysdeps/generic/dl-irel.h b/libc/sysdeps/generic/dl-irel.h new file mode 100644 index 000000000..4d7b481e8 --- /dev/null +++ b/libc/sysdeps/generic/dl-irel.h @@ -0,0 +1,23 @@ +/* Machine-dependent ELF indirect relocation inline functions. + Copyright (C) 2009 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _DL_IREL_h +#define _DL_IREL_H + +#endif /* dl-irel.h */ diff --git a/libc/sysdeps/i386/dl-irel.h b/libc/sysdeps/i386/dl-irel.h new file mode 100644 index 000000000..4acb862c6 --- /dev/null +++ b/libc/sysdeps/i386/dl-irel.h @@ -0,0 +1,44 @@ +/* Machine-dependent ELF indirect relocation inline functions. + i386 version. + Copyright (C) 2009 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _DL_IREL_H +#define _DL_IREL_H + +#include + +#define ELF_MACHINE_IREL 1 + +static inline void +__attribute ((always_inline)) +elf_irel (const Elf32_Rel *reloc) +{ + Elf32_Addr *const reloc_addr = (void *) reloc->r_offset; + const unsigned long int r_type = ELF32_R_TYPE (reloc->r_info); + + if (__builtin_expect (r_type == R_386_IRELATIVE, 1)) + { + Elf64_Addr value = ((Elf32_Addr (*) (void)) (*reloc_addr)) (); + *reloc_addr = value; + } + else + _exit (-1); +} + +#endif /* dl-irel.h */ diff --git a/libc/sysdeps/i386/dl-machine.h b/libc/sysdeps/i386/dl-machine.h index 0e15878d4..efa929e57 100644 --- a/libc/sysdeps/i386/dl-machine.h +++ b/libc/sysdeps/i386/dl-machine.h @@ -345,6 +345,7 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc, Elf32_Addr value = sym_map == NULL ? 0 : sym_map->l_addr + sym->st_value; if (sym != NULL + && __builtin_expect (sym->st_shndx != SHN_UNDEF, 1) && __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC, 0)) value = ((Elf32_Addr (*) (void)) value) (); @@ -471,6 +472,11 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc, memcpy (reloc_addr_arg, (void *) value, MIN (sym->st_size, refsym->st_size)); break; + case R_386_IRELATIVE: + value = map->l_addr + *reloc_addr; + value = ((Elf32_Addr (*) (void)) value) (); + *reloc_addr = value; + break; default: _dl_reloc_bad_type (map, r_type, 0); break; @@ -500,6 +506,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, Elf32_Addr value = sym == NULL ? 0 : sym_map->l_addr + sym->st_value; if (sym != NULL + && __builtin_expect (sym->st_shndx != SHN_UNDEF, 1) && __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC, 0)) value = ((Elf32_Addr (*) (void)) value) (); @@ -609,6 +616,11 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, MIN (sym->st_size, refsym->st_size)); break; # endif /* !RESOLVE_CONFLICT_FIND_MAP */ + case R_386_IRELATIVE: + value = map->l_addr + reloc->r_addend; + value = ((Elf32_Addr (*) (void)) value) (); + *reloc_addr = value; + break; default: /* We add these checks in the version to relocate ld.so only if we are still debugging. */ @@ -703,6 +715,12 @@ elf_machine_lazy_rel (struct link_map *map, # endif } } + else if (__builtin_expect (r_type == R_386_IRELATIVE, 0)) + { + Elf32_Addr value = map->l_addr + *reloc_addr; + value = ((Elf32_Addr (*) (void)) value) (); + *reloc_addr = value; + } else _dl_reloc_bad_type (map, r_type, 1); } @@ -726,6 +744,12 @@ elf_machine_lazy_rela (struct link_map *map, td->arg = (void*)reloc; td->entry = _dl_tlsdesc_resolve_rela; } + else if (__builtin_expect (r_type == R_386_IRELATIVE, 0)) + { + Elf32_Addr value = map->l_addr + reloc->r_addend; + value = ((Elf32_Addr (*) (void)) value) (); + *reloc_addr = value; + } else _dl_reloc_bad_type (map, r_type, 1); } diff --git a/libc/sysdeps/ieee754/ldbl-128/s_cosl.c b/libc/sysdeps/ieee754/ldbl-128/s_cosl.c index d1258b2cf..ef61c3afd 100644 --- a/libc/sysdeps/ieee754/ldbl-128/s_cosl.c +++ b/libc/sysdeps/ieee754/ldbl-128/s_cosl.c @@ -44,6 +44,7 @@ * TRIG(x) returns trig(x) nearly rounded */ +#include #include "math.h" #include "math_private.h" @@ -66,7 +67,14 @@ return __kernel_cosl(x,z); /* cos(Inf or NaN) is NaN */ - else if (ix>=0x7fff000000000000LL) return x-x; + else if (ix>=0x7fff000000000000LL) { + if (ix == 0x7fff000000000000LL) { + GET_LDOUBLE_LSW64(n,x); + if (n == 0) + __set_errno (EDOM); + } + return x-x; + } /* argument reduction needed */ else { diff --git a/libc/sysdeps/ieee754/ldbl-128/s_expm1l.c b/libc/sysdeps/ieee754/ldbl-128/s_expm1l.c index 78bbe65b5..a82489bb2 100644 --- a/libc/sysdeps/ieee754/ldbl-128/s_expm1l.c +++ b/libc/sysdeps/ieee754/ldbl-128/s_expm1l.c @@ -53,6 +53,7 @@ +#include #include "math.h" #include "math_private.h" @@ -121,7 +122,10 @@ __expm1l (long double x) /* Overflow. */ if (x > maxlog) - return (big * big); + { + __set_errno (ERANGE); + return (big * big); + } /* Minimum value. */ if (x < minarg) diff --git a/libc/sysdeps/ieee754/ldbl-128/s_sinl.c b/libc/sysdeps/ieee754/ldbl-128/s_sinl.c index 446a75f12..dc509e72e 100644 --- a/libc/sysdeps/ieee754/ldbl-128/s_sinl.c +++ b/libc/sysdeps/ieee754/ldbl-128/s_sinl.c @@ -44,6 +44,7 @@ * TRIG(x) returns trig(x) nearly rounded */ +#include #include "math.h" #include "math_private.h" @@ -66,7 +67,14 @@ return __kernel_sinl(x,z,0); /* sin(Inf or NaN) is NaN */ - else if (ix>=0x7fff000000000000LL) return x-x; + else if (ix>=0x7fff000000000000LL) { + if (ix == 0x7fff000000000000LL) { + GET_LDOUBLE_LSW64(n,x); + if (n == 0) + __set_errno (EDOM); + } + return x-x; + } /* argument reduction needed */ else { diff --git a/libc/sysdeps/ieee754/ldbl-128/s_tanl.c b/libc/sysdeps/ieee754/ldbl-128/s_tanl.c index ea9d053d9..2349da67f 100644 --- a/libc/sysdeps/ieee754/ldbl-128/s_tanl.c +++ b/libc/sysdeps/ieee754/ldbl-128/s_tanl.c @@ -44,6 +44,7 @@ * TRIG(x) returns trig(x) nearly rounded */ +#include #include "math.h" #include "math_private.h" @@ -65,7 +66,14 @@ if(ix <= 0x3ffe921fb54442d1LL) return __kernel_tanl(x,z,1); /* tanl(Inf or NaN) is NaN */ - else if (ix>=0x7fff000000000000LL) return x-x; /* NaN */ + else if (ix>=0x7fff000000000000LL) { + if (ix == 0x7fff000000000000LL) { + GET_LDOUBLE_LSW64(n,x); + if (n == 0) + __set_errno (EDOM); + } + return x-x; /* NaN */ + } /* argument reduction needed */ else { diff --git a/libc/sysdeps/s390/s390-32/____longjmp_chk.c b/libc/sysdeps/s390/s390-32/____longjmp_chk.c new file mode 100644 index 000000000..c5eb721e0 --- /dev/null +++ b/libc/sysdeps/s390/s390-32/____longjmp_chk.c @@ -0,0 +1,41 @@ +/* Copyright (C) 2009 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek . + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include +#include +#include +#include +#include +#include + +#define __longjmp ____longjmp_chk + +#define CHECK_SP(env, guard) \ + do \ + { \ + uintptr_t cur_sp; \ + uintptr_t new_sp = env->__gregs[9]; \ + __asm ("lr %0, %%r15" : "=r" (cur_sp)); \ + new_sp ^= guard; \ + if (new_sp < cur_sp) \ + __fortify_fail ("longjmp causes uninitialized stack frame"); \ + } while (0) + +#include "__longjmp.c" diff --git a/libc/sysdeps/s390/s390-32/__longjmp.c b/libc/sysdeps/s390/s390-32/__longjmp.c index c47ebbc52..4abc0ec81 100644 --- a/libc/sysdeps/s390/s390-32/__longjmp.c +++ b/libc/sysdeps/s390/s390-32/__longjmp.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000, 2001, 2005 Free Software Foundation, Inc. +/* Copyright (C) 2000, 2001, 2005, 2009 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). @@ -33,6 +33,11 @@ __longjmp (__jmp_buf env, int val) #ifdef PTR_DEMANGLE register uintptr_t r3 __asm ("%r3") = THREAD_GET_POINTER_GUARD (); register void *r1 __asm ("%r1") = (void *) env; +# ifdef CHECK_SP + CHECK_SP (env, r3); +# endif +#elif defined CHECK_SP + CHECK_SP (env, 0); #endif /* Restore registers and jump back. */ asm volatile ("ld %%f6,48(%1)\n\t" diff --git a/libc/sysdeps/s390/s390-64/____longjmp_chk.c b/libc/sysdeps/s390/s390-64/____longjmp_chk.c new file mode 100644 index 000000000..241822ce4 --- /dev/null +++ b/libc/sysdeps/s390/s390-64/____longjmp_chk.c @@ -0,0 +1,41 @@ +/* Copyright (C) 2009 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek . + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include +#include +#include +#include +#include +#include + +#define __longjmp ____longjmp_chk + +#define CHECK_SP(env, guard) \ + do \ + { \ + uintptr_t cur_sp; \ + uintptr_t new_sp = env->__gregs[9]; \ + __asm ("lgr %0, %%r15" : "=r" (cur_sp)); \ + new_sp ^= guard; \ + if (new_sp < cur_sp) \ + __fortify_fail ("longjmp causes uninitialized stack frame"); \ + } while (0) + +#include "__longjmp.c" diff --git a/libc/sysdeps/s390/s390-64/__longjmp.c b/libc/sysdeps/s390/s390-64/__longjmp.c index 030fb5b51..445bd3baf 100644 --- a/libc/sysdeps/s390/s390-64/__longjmp.c +++ b/libc/sysdeps/s390/s390-64/__longjmp.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2001, 2005 Free Software Foundation, Inc. +/* Copyright (C) 2001, 2005, 2009 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). @@ -33,6 +33,11 @@ __longjmp (__jmp_buf env, int val) #ifdef PTR_DEMANGLE register uintptr_t r3 __asm ("%r3") = THREAD_GET_POINTER_GUARD (); register void *r1 __asm ("%r1") = (void *) env; +# ifdef CHECK_SP + CHECK_SP (env, r3); +# endif +#elif defined CHECK_SP + CHECK_SP (env, 0); #endif /* Restore registers and jump back. */ asm volatile ("ld %%f7,104(%1)\n\t" diff --git a/libc/sysdeps/unix/sysv/linux/i386/internal_accept4.S b/libc/sysdeps/unix/sysv/linux/i386/internal_accept4.S new file mode 100644 index 000000000..c3f163049 --- /dev/null +++ b/libc/sysdeps/unix/sysv/linux/i386/internal_accept4.S @@ -0,0 +1 @@ +/* Not needed, accept4.S has everything. */ diff --git a/libc/sysdeps/unix/sysv/linux/i386/sysconf.c b/libc/sysdeps/unix/sysv/linux/i386/sysconf.c index f59e0c3fa..efe1a639c 100644 --- a/libc/sysdeps/unix/sysv/linux/i386/sysconf.c +++ b/libc/sysdeps/unix/sysv/linux/i386/sysconf.c @@ -1,5 +1,5 @@ /* Get file-specific information about a file. Linux version. - Copyright (C) 2003, 2004, 2006, 2007 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 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 @@ -67,76 +67,77 @@ handle_i486 (int name) static const struct intel_02_cache_info { - unsigned int idx; - int name; - long int size; - long int assoc; - long int linesize; -} intel_02_known[] = + unsigned char idx; + unsigned char assoc; + unsigned char linesize; + unsigned char rel_name; + unsigned int size; +} intel_02_known [] = { - { 0x06, _SC_LEVEL1_ICACHE_SIZE, 8192, 4, 32 }, - { 0x08, _SC_LEVEL1_ICACHE_SIZE, 16384, 4, 32 }, - { 0x09, _SC_LEVEL1_ICACHE_SIZE, 32768, 4, 32 }, - { 0x0a, _SC_LEVEL1_DCACHE_SIZE, 8192, 2, 32 }, - { 0x0c, _SC_LEVEL1_DCACHE_SIZE, 16384, 4, 32 }, - { 0x0d, _SC_LEVEL1_DCACHE_SIZE, 16384, 4, 64 }, - { 0x21, _SC_LEVEL2_CACHE_SIZE, 262144, 8, 64 }, - { 0x22, _SC_LEVEL3_CACHE_SIZE, 524288, 4, 64 }, - { 0x23, _SC_LEVEL3_CACHE_SIZE, 1048576, 8, 64 }, - { 0x25, _SC_LEVEL3_CACHE_SIZE, 2097152, 8, 64 }, - { 0x29, _SC_LEVEL3_CACHE_SIZE, 4194304, 8, 64 }, - { 0x2c, _SC_LEVEL1_DCACHE_SIZE, 32768, 8, 64 }, - { 0x30, _SC_LEVEL1_ICACHE_SIZE, 32768, 8, 64 }, - { 0x39, _SC_LEVEL2_CACHE_SIZE, 131072, 4, 64 }, - { 0x3a, _SC_LEVEL2_CACHE_SIZE, 196608, 6, 64 }, - { 0x3b, _SC_LEVEL2_CACHE_SIZE, 131072, 2, 64 }, - { 0x3c, _SC_LEVEL2_CACHE_SIZE, 262144, 4, 64 }, - { 0x3d, _SC_LEVEL2_CACHE_SIZE, 393216, 6, 64 }, - { 0x3e, _SC_LEVEL2_CACHE_SIZE, 524288, 4, 64 }, - { 0x3f, _SC_LEVEL2_CACHE_SIZE, 262144, 2, 64 }, - { 0x41, _SC_LEVEL2_CACHE_SIZE, 131072, 4, 32 }, - { 0x42, _SC_LEVEL2_CACHE_SIZE, 262144, 4, 32 }, - { 0x43, _SC_LEVEL2_CACHE_SIZE, 524288, 4, 32 }, - { 0x44, _SC_LEVEL2_CACHE_SIZE, 1048576, 4, 32 }, - { 0x45, _SC_LEVEL2_CACHE_SIZE, 2097152, 4, 32 }, - { 0x46, _SC_LEVEL3_CACHE_SIZE, 4194304, 4, 64 }, - { 0x47, _SC_LEVEL3_CACHE_SIZE, 8388608, 8, 64 }, - { 0x48, _SC_LEVEL2_CACHE_SIZE, 3145728, 12, 64 }, - { 0x49, _SC_LEVEL2_CACHE_SIZE, 4194304, 16, 64 }, - { 0x4a, _SC_LEVEL3_CACHE_SIZE, 6291456, 12, 64 }, - { 0x4b, _SC_LEVEL3_CACHE_SIZE, 8388608, 16, 64 }, - { 0x4c, _SC_LEVEL3_CACHE_SIZE, 12582912, 12, 64 }, - { 0x4d, _SC_LEVEL3_CACHE_SIZE, 16777216, 16, 64 }, - { 0x4e, _SC_LEVEL2_CACHE_SIZE, 6291456, 24, 64 }, - { 0x60, _SC_LEVEL1_DCACHE_SIZE, 16384, 8, 64 }, - { 0x66, _SC_LEVEL1_DCACHE_SIZE, 8192, 4, 64 }, - { 0x67, _SC_LEVEL1_DCACHE_SIZE, 16384, 4, 64 }, - { 0x68, _SC_LEVEL1_DCACHE_SIZE, 32768, 4, 64 }, - { 0x78, _SC_LEVEL2_CACHE_SIZE, 1048576, 8, 64 }, - { 0x79, _SC_LEVEL2_CACHE_SIZE, 131072, 8, 64 }, - { 0x7a, _SC_LEVEL2_CACHE_SIZE, 262144, 8, 64 }, - { 0x7b, _SC_LEVEL2_CACHE_SIZE, 524288, 8, 64 }, - { 0x7c, _SC_LEVEL2_CACHE_SIZE, 1048576, 8, 64 }, - { 0x7d, _SC_LEVEL2_CACHE_SIZE, 2097152, 8, 64 }, - { 0x7f, _SC_LEVEL2_CACHE_SIZE, 524288, 2, 64 }, - { 0x82, _SC_LEVEL2_CACHE_SIZE, 262144, 8, 32 }, - { 0x83, _SC_LEVEL2_CACHE_SIZE, 524288, 8, 32 }, - { 0x84, _SC_LEVEL2_CACHE_SIZE, 1048576, 8, 32 }, - { 0x85, _SC_LEVEL2_CACHE_SIZE, 2097152, 8, 32 }, - { 0x86, _SC_LEVEL2_CACHE_SIZE, 524288, 4, 64 }, - { 0x87, _SC_LEVEL2_CACHE_SIZE, 1048576, 8, 64 }, - { 0xd0, _SC_LEVEL3_CACHE_SIZE, 524288, 4, 64 }, - { 0xd1, _SC_LEVEL3_CACHE_SIZE, 1048576, 4, 64 }, - { 0xd2, _SC_LEVEL3_CACHE_SIZE, 2097152, 4, 64 }, - { 0xd6, _SC_LEVEL3_CACHE_SIZE, 1048576, 8, 64 }, - { 0xd7, _SC_LEVEL3_CACHE_SIZE, 2097152, 8, 64 }, - { 0xd8, _SC_LEVEL3_CACHE_SIZE, 4194304, 8, 64 }, - { 0xdc, _SC_LEVEL3_CACHE_SIZE, 2097152, 12, 64 }, - { 0xdd, _SC_LEVEL3_CACHE_SIZE, 4194304, 12, 64 }, - { 0xde, _SC_LEVEL3_CACHE_SIZE, 8388608, 12, 64 }, - { 0xe3, _SC_LEVEL3_CACHE_SIZE, 2097152, 16, 64 }, - { 0xe3, _SC_LEVEL3_CACHE_SIZE, 4194304, 16, 64 }, - { 0xe4, _SC_LEVEL3_CACHE_SIZE, 8388608, 16, 64 }, +#define M(sc) ((sc) - _SC_LEVEL1_ICACHE_SIZE) + { 0x06, 4, 32, M(_SC_LEVEL1_ICACHE_SIZE), 8192 }, + { 0x08, 4, 32, M(_SC_LEVEL1_ICACHE_SIZE), 16384 }, + { 0x09, 4, 32, M(_SC_LEVEL1_ICACHE_SIZE), 32768 }, + { 0x0a, 2, 32, M(_SC_LEVEL1_DCACHE_SIZE), 8192 }, + { 0x0c, 4, 32, M(_SC_LEVEL1_DCACHE_SIZE), 16384 }, + { 0x0d, 4, 64, M(_SC_LEVEL1_DCACHE_SIZE), 16384 }, + { 0x21, 8, 64, M(_SC_LEVEL2_CACHE_SIZE), 262144 }, + { 0x22, 4, 64, M(_SC_LEVEL3_CACHE_SIZE), 524288 }, + { 0x23, 8, 64, M(_SC_LEVEL3_CACHE_SIZE), 1048576 }, + { 0x25, 8, 64, M(_SC_LEVEL3_CACHE_SIZE), 2097152 }, + { 0x29, 8, 64, M(_SC_LEVEL3_CACHE_SIZE), 4194304 }, + { 0x2c, 8, 64, M(_SC_LEVEL1_DCACHE_SIZE), 32768 }, + { 0x30, 8, 64, M(_SC_LEVEL1_ICACHE_SIZE), 32768 }, + { 0x39, 4, 64, M(_SC_LEVEL2_CACHE_SIZE), 131072 }, + { 0x3a, 6, 64, M(_SC_LEVEL2_CACHE_SIZE), 196608 }, + { 0x3b, 2, 64, M(_SC_LEVEL2_CACHE_SIZE), 131072 }, + { 0x3c, 4, 64, M(_SC_LEVEL2_CACHE_SIZE), 262144 }, + { 0x3d, 6, 64, M(_SC_LEVEL2_CACHE_SIZE), 393216 }, + { 0x3e, 4, 64, M(_SC_LEVEL2_CACHE_SIZE), 524288 }, + { 0x3f, 2, 64, M(_SC_LEVEL2_CACHE_SIZE), 262144 }, + { 0x41, 4, 32, M(_SC_LEVEL2_CACHE_SIZE), 131072 }, + { 0x42, 4, 32, M(_SC_LEVEL2_CACHE_SIZE), 262144 }, + { 0x43, 4, 32, M(_SC_LEVEL2_CACHE_SIZE), 524288 }, + { 0x44, 4, 32, M(_SC_LEVEL2_CACHE_SIZE), 1048576 }, + { 0x45, 4, 32, M(_SC_LEVEL2_CACHE_SIZE), 2097152 }, + { 0x46, 4, 64, M(_SC_LEVEL3_CACHE_SIZE), 4194304 }, + { 0x47, 8, 64, M(_SC_LEVEL3_CACHE_SIZE), 8388608 }, + { 0x48, 12, 64, M(_SC_LEVEL2_CACHE_SIZE), 3145728 }, + { 0x49, 16, 64, M(_SC_LEVEL2_CACHE_SIZE), 4194304 }, + { 0x4a, 12, 64, M(_SC_LEVEL3_CACHE_SIZE), 6291456 }, + { 0x4b, 16, 64, M(_SC_LEVEL3_CACHE_SIZE), 8388608 }, + { 0x4c, 12, 64, M(_SC_LEVEL3_CACHE_SIZE), 12582912 }, + { 0x4d, 16, 64, M(_SC_LEVEL3_CACHE_SIZE), 16777216 }, + { 0x4e, 24, 64, M(_SC_LEVEL2_CACHE_SIZE), 6291456 }, + { 0x60, 8, 64, M(_SC_LEVEL1_DCACHE_SIZE), 16384 }, + { 0x66, 4, 64, M(_SC_LEVEL1_DCACHE_SIZE), 8192 }, + { 0x67, 4, 64, M(_SC_LEVEL1_DCACHE_SIZE), 16384 }, + { 0x68, 4, 64, M(_SC_LEVEL1_DCACHE_SIZE), 32768 }, + { 0x78, 8, 64, M(_SC_LEVEL2_CACHE_SIZE), 1048576 }, + { 0x79, 8, 64, M(_SC_LEVEL2_CACHE_SIZE), 131072 }, + { 0x7a, 8, 64, M(_SC_LEVEL2_CACHE_SIZE), 262144 }, + { 0x7b, 8, 64, M(_SC_LEVEL2_CACHE_SIZE), 524288 }, + { 0x7c, 8, 64, M(_SC_LEVEL2_CACHE_SIZE), 1048576 }, + { 0x7d, 8, 64, M(_SC_LEVEL2_CACHE_SIZE), 2097152 }, + { 0x7f, 2, 64, M(_SC_LEVEL2_CACHE_SIZE), 524288 }, + { 0x82, 8, 32, M(_SC_LEVEL2_CACHE_SIZE), 262144 }, + { 0x83, 8, 32, M(_SC_LEVEL2_CACHE_SIZE), 524288 }, + { 0x84, 8, 32, M(_SC_LEVEL2_CACHE_SIZE), 1048576 }, + { 0x85, 8, 32, M(_SC_LEVEL2_CACHE_SIZE), 2097152 }, + { 0x86, 4, 64, M(_SC_LEVEL2_CACHE_SIZE), 524288 }, + { 0x87, 8, 64, M(_SC_LEVEL2_CACHE_SIZE), 1048576 }, + { 0xd0, 4, 64, M(_SC_LEVEL3_CACHE_SIZE), 524288 }, + { 0xd1, 4, 64, M(_SC_LEVEL3_CACHE_SIZE), 1048576 }, + { 0xd2, 4, 64, M(_SC_LEVEL3_CACHE_SIZE), 2097152 }, + { 0xd6, 8, 64, M(_SC_LEVEL3_CACHE_SIZE), 1048576 }, + { 0xd7, 8, 64, M(_SC_LEVEL3_CACHE_SIZE), 2097152 }, + { 0xd8, 8, 64, M(_SC_LEVEL3_CACHE_SIZE), 4194304 }, + { 0xdc, 12, 64, M(_SC_LEVEL3_CACHE_SIZE), 2097152 }, + { 0xdd, 12, 64, M(_SC_LEVEL3_CACHE_SIZE), 4194304 }, + { 0xde, 12, 64, M(_SC_LEVEL3_CACHE_SIZE), 8388608 }, + { 0xe3, 16, 64, M(_SC_LEVEL3_CACHE_SIZE), 2097152 }, + { 0xe3, 16, 64, M(_SC_LEVEL3_CACHE_SIZE), 4194304 }, + { 0xe4, 16, 64, M(_SC_LEVEL3_CACHE_SIZE), 8388608 }, }; #define nintel_02_known (sizeof (intel_02_known) / sizeof (intel_02_known[0])) @@ -168,8 +169,7 @@ intel_check_word (int name, unsigned int value, bool *has_level_2, /* Fold the name. The _SC_ constants are always in the order SIZE, ASSOC, LINESIZE. */ - int folded_name = (_SC_LEVEL1_ICACHE_SIZE - + ((name - _SC_LEVEL1_ICACHE_SIZE) / 3) * 3); + int folded_rel_name = (M(name) / 3) * 3; while (value != 0) { @@ -179,13 +179,13 @@ intel_check_word (int name, unsigned int value, bool *has_level_2, { *no_level_2_or_3 = true; - if (folded_name == _SC_LEVEL3_CACHE_SIZE) + if (folded_rel_name == M(_SC_LEVEL3_CACHE_SIZE)) /* No need to look further. */ break; } else { - if (byte == 0x49 && folded_name == _SC_LEVEL3_CACHE_SIZE) + if (byte == 0x49 && folded_rel_name == M(_SC_LEVEL3_CACHE_SIZE)) { /* Intel reused this value. For family 15, model 6 it specifies the 3rd level cache. Otherwise the 2nd @@ -208,7 +208,7 @@ intel_check_word (int name, unsigned int value, bool *has_level_2, the caller asked for the level 2 cache. */ name = (_SC_LEVEL2_CACHE_SIZE + (name - _SC_LEVEL3_CACHE_SIZE)); - folded_name = _SC_LEVEL3_CACHE_SIZE; + folded_rel_name = M(_SC_LEVEL2_CACHE_SIZE); } } @@ -220,9 +220,9 @@ intel_check_word (int name, unsigned int value, bool *has_level_2, sizeof (intel_02_known[0]), intel_02_known_compare); if (found != NULL) { - if (found->name == folded_name) + if (found->rel_name == folded_rel_name) { - unsigned int offset = name - folded_name; + unsigned int offset = M(name) - folded_rel_name; if (offset == 0) /* Cache size. */ @@ -234,7 +234,7 @@ intel_check_word (int name, unsigned int value, bool *has_level_2, return found->linesize; } - if (found->name == _SC_LEVEL2_CACHE_SIZE) + if (found->rel_name == M(_SC_LEVEL2_CACHE_SIZE)) *has_level_2 = true; } } diff --git a/libc/sysdeps/x86_64/cacheinfo.c b/libc/sysdeps/x86_64/cacheinfo.c index 1ec4ca19c..362687c18 100644 --- a/libc/sysdeps/x86_64/cacheinfo.c +++ b/libc/sysdeps/x86_64/cacheinfo.c @@ -1,5 +1,5 @@ /* x86_64 cache info. - Copyright (C) 2003, 2004, 2006, 2007 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 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 @@ -29,76 +29,77 @@ static const struct intel_02_cache_info { - unsigned int idx; - int name; - long int size; - long int assoc; - long int linesize; + unsigned char idx; + unsigned char assoc; + unsigned char linesize; + unsigned char rel_name; + unsigned int size; } intel_02_known [] = { - { 0x06, _SC_LEVEL1_ICACHE_SIZE, 8192, 4, 32 }, - { 0x08, _SC_LEVEL1_ICACHE_SIZE, 16384, 4, 32 }, - { 0x09, _SC_LEVEL1_ICACHE_SIZE, 32768, 4, 32 }, - { 0x0a, _SC_LEVEL1_DCACHE_SIZE, 8192, 2, 32 }, - { 0x0c, _SC_LEVEL1_DCACHE_SIZE, 16384, 4, 32 }, - { 0x0d, _SC_LEVEL1_DCACHE_SIZE, 16384, 4, 64 }, - { 0x21, _SC_LEVEL2_CACHE_SIZE, 262144, 8, 64 }, - { 0x22, _SC_LEVEL3_CACHE_SIZE, 524288, 4, 64 }, - { 0x23, _SC_LEVEL3_CACHE_SIZE, 1048576, 8, 64 }, - { 0x25, _SC_LEVEL3_CACHE_SIZE, 2097152, 8, 64 }, - { 0x29, _SC_LEVEL3_CACHE_SIZE, 4194304, 8, 64 }, - { 0x2c, _SC_LEVEL1_DCACHE_SIZE, 32768, 8, 64 }, - { 0x30, _SC_LEVEL1_ICACHE_SIZE, 32768, 8, 64 }, - { 0x39, _SC_LEVEL2_CACHE_SIZE, 131072, 4, 64 }, - { 0x3a, _SC_LEVEL2_CACHE_SIZE, 196608, 6, 64 }, - { 0x3b, _SC_LEVEL2_CACHE_SIZE, 131072, 2, 64 }, - { 0x3c, _SC_LEVEL2_CACHE_SIZE, 262144, 4, 64 }, - { 0x3d, _SC_LEVEL2_CACHE_SIZE, 393216, 6, 64 }, - { 0x3e, _SC_LEVEL2_CACHE_SIZE, 524288, 4, 64 }, - { 0x3f, _SC_LEVEL2_CACHE_SIZE, 262144, 2, 64 }, - { 0x41, _SC_LEVEL2_CACHE_SIZE, 131072, 4, 32 }, - { 0x42, _SC_LEVEL2_CACHE_SIZE, 262144, 4, 32 }, - { 0x43, _SC_LEVEL2_CACHE_SIZE, 524288, 4, 32 }, - { 0x44, _SC_LEVEL2_CACHE_SIZE, 1048576, 4, 32 }, - { 0x45, _SC_LEVEL2_CACHE_SIZE, 2097152, 4, 32 }, - { 0x46, _SC_LEVEL3_CACHE_SIZE, 4194304, 4, 64 }, - { 0x47, _SC_LEVEL3_CACHE_SIZE, 8388608, 8, 64 }, - { 0x48, _SC_LEVEL2_CACHE_SIZE, 3145728, 12, 64 }, - { 0x49, _SC_LEVEL2_CACHE_SIZE, 4194304, 16, 64 }, - { 0x4a, _SC_LEVEL3_CACHE_SIZE, 6291456, 12, 64 }, - { 0x4b, _SC_LEVEL3_CACHE_SIZE, 8388608, 16, 64 }, - { 0x4c, _SC_LEVEL3_CACHE_SIZE, 12582912, 12, 64 }, - { 0x4d, _SC_LEVEL3_CACHE_SIZE, 16777216, 16, 64 }, - { 0x4e, _SC_LEVEL2_CACHE_SIZE, 6291456, 24, 64 }, - { 0x60, _SC_LEVEL1_DCACHE_SIZE, 16384, 8, 64 }, - { 0x66, _SC_LEVEL1_DCACHE_SIZE, 8192, 4, 64 }, - { 0x67, _SC_LEVEL1_DCACHE_SIZE, 16384, 4, 64 }, - { 0x68, _SC_LEVEL1_DCACHE_SIZE, 32768, 4, 64 }, - { 0x78, _SC_LEVEL2_CACHE_SIZE, 1048576, 8, 64 }, - { 0x79, _SC_LEVEL2_CACHE_SIZE, 131072, 8, 64 }, - { 0x7a, _SC_LEVEL2_CACHE_SIZE, 262144, 8, 64 }, - { 0x7b, _SC_LEVEL2_CACHE_SIZE, 524288, 8, 64 }, - { 0x7c, _SC_LEVEL2_CACHE_SIZE, 1048576, 8, 64 }, - { 0x7d, _SC_LEVEL2_CACHE_SIZE, 2097152, 8, 64 }, - { 0x7f, _SC_LEVEL2_CACHE_SIZE, 524288, 2, 64 }, - { 0x82, _SC_LEVEL2_CACHE_SIZE, 262144, 8, 32 }, - { 0x83, _SC_LEVEL2_CACHE_SIZE, 524288, 8, 32 }, - { 0x84, _SC_LEVEL2_CACHE_SIZE, 1048576, 8, 32 }, - { 0x85, _SC_LEVEL2_CACHE_SIZE, 2097152, 8, 32 }, - { 0x86, _SC_LEVEL2_CACHE_SIZE, 524288, 4, 64 }, - { 0x87, _SC_LEVEL2_CACHE_SIZE, 1048576, 8, 64 }, - { 0xd0, _SC_LEVEL3_CACHE_SIZE, 524288, 4, 64 }, - { 0xd1, _SC_LEVEL3_CACHE_SIZE, 1048576, 4, 64 }, - { 0xd2, _SC_LEVEL3_CACHE_SIZE, 2097152, 4, 64 }, - { 0xd6, _SC_LEVEL3_CACHE_SIZE, 1048576, 8, 64 }, - { 0xd7, _SC_LEVEL3_CACHE_SIZE, 2097152, 8, 64 }, - { 0xd8, _SC_LEVEL3_CACHE_SIZE, 4194304, 8, 64 }, - { 0xdc, _SC_LEVEL3_CACHE_SIZE, 2097152, 12, 64 }, - { 0xdd, _SC_LEVEL3_CACHE_SIZE, 4194304, 12, 64 }, - { 0xde, _SC_LEVEL3_CACHE_SIZE, 8388608, 12, 64 }, - { 0xe3, _SC_LEVEL3_CACHE_SIZE, 2097152, 16, 64 }, - { 0xe3, _SC_LEVEL3_CACHE_SIZE, 4194304, 16, 64 }, - { 0xe4, _SC_LEVEL3_CACHE_SIZE, 8388608, 16, 64 }, +#define M(sc) ((sc) - _SC_LEVEL1_ICACHE_SIZE) + { 0x06, 4, 32, M(_SC_LEVEL1_ICACHE_SIZE), 8192 }, + { 0x08, 4, 32, M(_SC_LEVEL1_ICACHE_SIZE), 16384 }, + { 0x09, 4, 32, M(_SC_LEVEL1_ICACHE_SIZE), 32768 }, + { 0x0a, 2, 32, M(_SC_LEVEL1_DCACHE_SIZE), 8192 }, + { 0x0c, 4, 32, M(_SC_LEVEL1_DCACHE_SIZE), 16384 }, + { 0x0d, 4, 64, M(_SC_LEVEL1_DCACHE_SIZE), 16384 }, + { 0x21, 8, 64, M(_SC_LEVEL2_CACHE_SIZE), 262144 }, + { 0x22, 4, 64, M(_SC_LEVEL3_CACHE_SIZE), 524288 }, + { 0x23, 8, 64, M(_SC_LEVEL3_CACHE_SIZE), 1048576 }, + { 0x25, 8, 64, M(_SC_LEVEL3_CACHE_SIZE), 2097152 }, + { 0x29, 8, 64, M(_SC_LEVEL3_CACHE_SIZE), 4194304 }, + { 0x2c, 8, 64, M(_SC_LEVEL1_DCACHE_SIZE), 32768 }, + { 0x30, 8, 64, M(_SC_LEVEL1_ICACHE_SIZE), 32768 }, + { 0x39, 4, 64, M(_SC_LEVEL2_CACHE_SIZE), 131072 }, + { 0x3a, 6, 64, M(_SC_LEVEL2_CACHE_SIZE), 196608 }, + { 0x3b, 2, 64, M(_SC_LEVEL2_CACHE_SIZE), 131072 }, + { 0x3c, 4, 64, M(_SC_LEVEL2_CACHE_SIZE), 262144 }, + { 0x3d, 6, 64, M(_SC_LEVEL2_CACHE_SIZE), 393216 }, + { 0x3e, 4, 64, M(_SC_LEVEL2_CACHE_SIZE), 524288 }, + { 0x3f, 2, 64, M(_SC_LEVEL2_CACHE_SIZE), 262144 }, + { 0x41, 4, 32, M(_SC_LEVEL2_CACHE_SIZE), 131072 }, + { 0x42, 4, 32, M(_SC_LEVEL2_CACHE_SIZE), 262144 }, + { 0x43, 4, 32, M(_SC_LEVEL2_CACHE_SIZE), 524288 }, + { 0x44, 4, 32, M(_SC_LEVEL2_CACHE_SIZE), 1048576 }, + { 0x45, 4, 32, M(_SC_LEVEL2_CACHE_SIZE), 2097152 }, + { 0x46, 4, 64, M(_SC_LEVEL3_CACHE_SIZE), 4194304 }, + { 0x47, 8, 64, M(_SC_LEVEL3_CACHE_SIZE), 8388608 }, + { 0x48, 12, 64, M(_SC_LEVEL2_CACHE_SIZE), 3145728 }, + { 0x49, 16, 64, M(_SC_LEVEL2_CACHE_SIZE), 4194304 }, + { 0x4a, 12, 64, M(_SC_LEVEL3_CACHE_SIZE), 6291456 }, + { 0x4b, 16, 64, M(_SC_LEVEL3_CACHE_SIZE), 8388608 }, + { 0x4c, 12, 64, M(_SC_LEVEL3_CACHE_SIZE), 12582912 }, + { 0x4d, 16, 64, M(_SC_LEVEL3_CACHE_SIZE), 16777216 }, + { 0x4e, 24, 64, M(_SC_LEVEL2_CACHE_SIZE), 6291456 }, + { 0x60, 8, 64, M(_SC_LEVEL1_DCACHE_SIZE), 16384 }, + { 0x66, 4, 64, M(_SC_LEVEL1_DCACHE_SIZE), 8192 }, + { 0x67, 4, 64, M(_SC_LEVEL1_DCACHE_SIZE), 16384 }, + { 0x68, 4, 64, M(_SC_LEVEL1_DCACHE_SIZE), 32768 }, + { 0x78, 8, 64, M(_SC_LEVEL2_CACHE_SIZE), 1048576 }, + { 0x79, 8, 64, M(_SC_LEVEL2_CACHE_SIZE), 131072 }, + { 0x7a, 8, 64, M(_SC_LEVEL2_CACHE_SIZE), 262144 }, + { 0x7b, 8, 64, M(_SC_LEVEL2_CACHE_SIZE), 524288 }, + { 0x7c, 8, 64, M(_SC_LEVEL2_CACHE_SIZE), 1048576 }, + { 0x7d, 8, 64, M(_SC_LEVEL2_CACHE_SIZE), 2097152 }, + { 0x7f, 2, 64, M(_SC_LEVEL2_CACHE_SIZE), 524288 }, + { 0x82, 8, 32, M(_SC_LEVEL2_CACHE_SIZE), 262144 }, + { 0x83, 8, 32, M(_SC_LEVEL2_CACHE_SIZE), 524288 }, + { 0x84, 8, 32, M(_SC_LEVEL2_CACHE_SIZE), 1048576 }, + { 0x85, 8, 32, M(_SC_LEVEL2_CACHE_SIZE), 2097152 }, + { 0x86, 4, 64, M(_SC_LEVEL2_CACHE_SIZE), 524288 }, + { 0x87, 8, 64, M(_SC_LEVEL2_CACHE_SIZE), 1048576 }, + { 0xd0, 4, 64, M(_SC_LEVEL3_CACHE_SIZE), 524288 }, + { 0xd1, 4, 64, M(_SC_LEVEL3_CACHE_SIZE), 1048576 }, + { 0xd2, 4, 64, M(_SC_LEVEL3_CACHE_SIZE), 2097152 }, + { 0xd6, 8, 64, M(_SC_LEVEL3_CACHE_SIZE), 1048576 }, + { 0xd7, 8, 64, M(_SC_LEVEL3_CACHE_SIZE), 2097152 }, + { 0xd8, 8, 64, M(_SC_LEVEL3_CACHE_SIZE), 4194304 }, + { 0xdc, 12, 64, M(_SC_LEVEL3_CACHE_SIZE), 2097152 }, + { 0xdd, 12, 64, M(_SC_LEVEL3_CACHE_SIZE), 4194304 }, + { 0xde, 12, 64, M(_SC_LEVEL3_CACHE_SIZE), 8388608 }, + { 0xe3, 16, 64, M(_SC_LEVEL3_CACHE_SIZE), 2097152 }, + { 0xe3, 16, 64, M(_SC_LEVEL3_CACHE_SIZE), 4194304 }, + { 0xe4, 16, 64, M(_SC_LEVEL3_CACHE_SIZE), 8388608 }, }; #define nintel_02_known (sizeof (intel_02_known) / sizeof (intel_02_known [0])) @@ -130,8 +131,7 @@ intel_check_word (int name, unsigned int value, bool *has_level_2, /* Fold the name. The _SC_ constants are always in the order SIZE, ASSOC, LINESIZE. */ - int folded_name = (_SC_LEVEL1_ICACHE_SIZE - + ((name - _SC_LEVEL1_ICACHE_SIZE) / 3) * 3); + int folded_rel_name = (M(name) / 3) * 3; while (value != 0) { @@ -141,13 +141,13 @@ intel_check_word (int name, unsigned int value, bool *has_level_2, { *no_level_2_or_3 = true; - if (folded_name == _SC_LEVEL3_CACHE_SIZE) + if (folded_rel_name == M(_SC_LEVEL3_CACHE_SIZE)) /* No need to look further. */ break; } else { - if (byte == 0x49 && folded_name == _SC_LEVEL3_CACHE_SIZE) + if (byte == 0x49 && folded_rel_name == M(_SC_LEVEL3_CACHE_SIZE)) { /* Intel reused this value. For family 15, model 6 it specifies the 3rd level cache. Otherwise the 2nd @@ -170,7 +170,7 @@ intel_check_word (int name, unsigned int value, bool *has_level_2, the caller asked for the level 2 cache. */ name = (_SC_LEVEL2_CACHE_SIZE + (name - _SC_LEVEL3_CACHE_SIZE)); - folded_name = _SC_LEVEL3_CACHE_SIZE; + folded_rel_name = M(_SC_LEVEL2_CACHE_SIZE); } } @@ -182,9 +182,9 @@ intel_check_word (int name, unsigned int value, bool *has_level_2, sizeof (intel_02_known[0]), intel_02_known_compare); if (found != NULL) { - if (found->name == folded_name) + if (found->rel_name == folded_rel_name) { - unsigned int offset = name - folded_name; + unsigned int offset = M(name) - folded_rel_name; if (offset == 0) /* Cache size. */ @@ -196,7 +196,7 @@ intel_check_word (int name, unsigned int value, bool *has_level_2, return found->linesize; } - if (found->name == _SC_LEVEL2_CACHE_SIZE) + if (found->rel_name == M(_SC_LEVEL2_CACHE_SIZE)) *has_level_2 = true; } } @@ -489,10 +489,10 @@ init_cacheinfo (void) } #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; + eax = __cpu_features.cpuid[COMMON_CPUID_INDEX_1].eax; + ebx = __cpu_features.cpuid[COMMON_CPUID_INDEX_1].ebx; + ecx = __cpu_features.cpuid[COMMON_CPUID_INDEX_1].ecx; + edx = __cpu_features.cpuid[COMMON_CPUID_INDEX_1].edx; #else asm volatile ("cpuid" : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) diff --git a/libc/sysdeps/x86_64/dl-irel.h b/libc/sysdeps/x86_64/dl-irel.h new file mode 100644 index 000000000..442ab71d2 --- /dev/null +++ b/libc/sysdeps/x86_64/dl-irel.h @@ -0,0 +1,44 @@ +/* Machine-dependent ELF indirect relocation inline functions. + x86-64 version. + Copyright (C) 2009 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _DL_IREL_H +#define _DL_IREL_H + +#include + +#define ELF_MACHINE_IRELA 1 + +static inline void +__attribute ((always_inline)) +elf_irela (const Elf64_Rela *reloc) +{ + Elf64_Addr *const reloc_addr = (void *) reloc->r_offset; + const unsigned long int r_type = ELF64_R_TYPE (reloc->r_info); + + if (__builtin_expect (r_type == R_X86_64_IRELATIVE, 1)) + { + Elf64_Addr value = ((Elf64_Addr (*) (void)) reloc->r_addend) (); + *reloc_addr = value; + } + else + _exit (-1); +} + +#endif /* dl-irel.h */ diff --git a/libc/sysdeps/x86_64/dl-machine.h b/libc/sysdeps/x86_64/dl-machine.h index 4444ae0a7..1b5ce8e98 100644 --- a/libc/sysdeps/x86_64/dl-machine.h +++ b/libc/sysdeps/x86_64/dl-machine.h @@ -297,6 +297,7 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc, : (Elf64_Addr) sym_map->l_addr + sym->st_value); if (sym != NULL + && __builtin_expect (sym->st_shndx != SHN_UNDEF, 1) && __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC, 0)) value = ((Elf64_Addr (*) (void)) value) (); @@ -442,6 +443,11 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc, } break; # endif + case R_X86_64_IRELATIVE: + value = map->l_addr + reloc->r_addend; + value = ((Elf64_Addr (*) (void)) value) (); + *reloc_addr = value; + break; default: _dl_reloc_bad_type (map, r_type, 0); break; @@ -488,6 +494,12 @@ elf_machine_lazy_rel (struct link_map *map, td->entry = (void*)(D_PTR (map, l_info[ADDRIDX (DT_TLSDESC_PLT)]) + map->l_addr); } + else if (__builtin_expect (r_type == R_X86_64_IRELATIVE, 0)) + { + Elf64_Addr value = map->l_addr + reloc->r_addend; + value = ((Elf64_Addr (*) (void)) value) (); + *reloc_addr = value; + } else _dl_reloc_bad_type (map, r_type, 1); } diff --git a/libc/sysdeps/x86_64/multiarch/init-arch.c b/libc/sysdeps/x86_64/multiarch/init-arch.c index eb4365fe3..ec0eb29fa 100644 --- a/libc/sysdeps/x86_64/multiarch/init-arch.c +++ b/libc/sysdeps/x86_64/multiarch/init-arch.c @@ -1,6 +1,6 @@ /* Initialize CPU feature data. This file is part of the GNU C Library. - Copyright (C) 2008 Free Software Foundation, Inc. + Copyright (C) 2008, 2009 Free Software Foundation, Inc. Contributed by Ulrich Drepper . The GNU C Library is free software; you can redistribute it and/or @@ -41,11 +41,12 @@ __init_cpu_features (void) { __cpu_features.kind = arch_kind_intel; + get_common_cpuid: 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) + : "=a" (__cpu_features.cpuid[COMMON_CPUID_INDEX_1].eax), + "=b" (__cpu_features.cpuid[COMMON_CPUID_INDEX_1].ebx), + "=c" (__cpu_features.cpuid[COMMON_CPUID_INDEX_1].ecx), + "=d" (__cpu_features.cpuid[COMMON_CPUID_INDEX_1].edx) : "0" (1)); } /* This spells out "AuthenticAMD". */ @@ -53,12 +54,7 @@ __init_cpu_features (void) { __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)); + goto get_common_cpuid; } else __cpu_features.kind = arch_kind_other; diff --git a/libc/sysdeps/x86_64/multiarch/init-arch.h b/libc/sysdeps/x86_64/multiarch/init-arch.h index 86cd83dc4..40b804571 100644 --- a/libc/sysdeps/x86_64/multiarch/init-arch.h +++ b/libc/sysdeps/x86_64/multiarch/init-arch.h @@ -1,5 +1,5 @@ /* This file is part of the GNU C Library. - Copyright (C) 2008 Free Software Foundation, Inc. + Copyright (C) 2008, 2009 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 @@ -20,16 +20,9 @@ enum { - INTEL_CPUID_INDEX_1 = 0, + COMMON_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 + COMMON_CPUID_INDEX_MAX }; extern struct cpu_features @@ -48,7 +41,7 @@ extern struct cpu_features unsigned int ebx; unsigned int ecx; unsigned int edx; - } cpuid[MAX (INTEL_CPUID_INDEX_MAX, AMD_CPUID_INDEX_MAX)]; + } cpuid[COMMON_CPUID_INDEX_MAX]; } __cpu_features attribute_hidden; @@ -61,10 +54,5 @@ extern void __init_cpu_features (void) attribute_hidden; /* 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) +#define HAS_POPCOUNT \ + ((__cpu_features.cpuid[COMMON_CPUID_INDEX_1].ecx & (1 << 23)) != 0) diff --git a/libc/sysdeps/x86_64/multiarch/sched_cpucount.c b/libc/sysdeps/x86_64/multiarch/sched_cpucount.c index dc20182df..b6f425e94 100644 --- a/libc/sysdeps/x86_64/multiarch/sched_cpucount.c +++ b/libc/sysdeps/x86_64/multiarch/sched_cpucount.c @@ -1,6 +1,6 @@ /* 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. + Copyright (C) 2008, 2009 Free Software Foundation, Inc. Contributed by Ulrich Drepper . The GNU C Library is free software; you can redistribute it and/or @@ -18,25 +18,20 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#ifdef SHARED -# include -# include "init-arch.h" +#include +#include "init-arch.h" -# define __sched_cpucount static generic_cpucount -# include -# undef __sched_cpucount +#define __sched_cpucount static generic_cpucount +#include +#undef __sched_cpucount -# define POPCNT(l) \ +#define POPCNT(l) \ ({ __cpu_mask r; \ asm ("popcntq %1, %0" : "=r" (r) : "0" (l));\ r; }) -# define __sched_cpucount static popcount_cpucount -# include -# undef __sched_cpucount +#define __sched_cpucount static popcount_cpucount +#include +#undef __sched_cpucount libc_ifunc (__sched_cpucount, - INTEL_HAS_POPCOUNT || AMD_HAS_POPCOUNT - ? popcount_cpucount : generic_cpucount); -#else -# include_next -#endif + HAS_POPCOUNT ? popcount_cpucount : generic_cpucount); -- cgit v1.2.1