This commit is contained in:
Jakub Jelinek 2007-07-31 13:33:18 +00:00
parent d6220e9ee3
commit 32c075e1f0
448 changed files with 13841 additions and 10982 deletions

1903
ChangeLog

File diff suppressed because it is too large Load Diff

View File

@ -407,9 +407,11 @@ LDFLAGS.so += $(combreloc-LDFLAGS)
LDFLAGS-rtld += $(combreloc-LDFLAGS) LDFLAGS-rtld += $(combreloc-LDFLAGS)
endif endif
ifeq (yes,$(have-z-relro))
relro-LDFLAGS = -Wl,-z,relro relro-LDFLAGS = -Wl,-z,relro
LDFLAGS.so += $(relro-LDFLAGS) LDFLAGS.so += $(relro-LDFLAGS)
LDFLAGS-rtld += $(relro-LDFLAGS) LDFLAGS-rtld += $(relro-LDFLAGS)
endif
ifeq (yes,$(have-hash-style)) ifeq (yes,$(have-hash-style))
# For the time being we unconditionally use 'both'. At some time we # For the time being we unconditionally use 'both'. At some time we

View File

@ -1233,7 +1233,10 @@ endif
ifeq ($(firstword $(sysd-sorted-done) f)$(firstword $(generating) f),tf) ifeq ($(firstword $(sysd-sorted-done) f)$(firstword $(generating) f),tf)
-include $(common-objpfx)tls.make -include $(common-objpfx)tls.make
config-tls := notls
ifeq ($(use-tls),yes)
config-tls := tls config-tls := tls
endif
ifeq ($(use-thread),yes) ifeq ($(use-thread),yes)
config-tls := thread config-tls := thread
endif endif

14
NEWS
View File

@ -1,13 +1,21 @@
GNU C Library NEWS -- history of user-visible changes. 2006-10-11 GNU C Library NEWS -- history of user-visible changes. 2006-09-29
Copyright (C) 1992-2002,2003,2004,2005,2006 Free Software Foundation, Inc. Copyright (C) 1992-2002,2003,2004,2005,2006 Free Software Foundation, Inc.
See the end for copying conditions. See the end for copying conditions.
Please send GNU C library bug reports via <http://sources.redhat.com/bugzilla/> Please send GNU C library bug reports via <http://sources.redhat.com/bugzilla/>
using `glibc' in the "product" field. using `glibc' in the "product" field.
Version 2.6 Version 2.5.1
* New Linux interfaces: epoll_pwait. * The following bugs are resolved with this release:
2337, 2749, 3213, 3291, 3306, 3320, 3322, 3334, 3348, 3352, 3369, 3429,
3451, 3458, 3559, 3632, 3664, 3673, 3674, 3747, 3842, 3851, 3855, 3884,
3902, 3919, 3944, 3954, 3955, 3957, 3995, 4069, 4070, 4074, 4076, 4101,
4102, 4130, 4131, 4181, 4342, 4344, 4364, 4368, 4381, 4405, 4406, 4411,
4438, 4439, 4465, 4512, 4514, 4586, 4702, 4858
Visit <http://sources.redhat.com/bugzilla/> for the details of each bug.
Version 2.5 Version 2.5

4
README
View File

@ -1,4 +1,4 @@
This directory contains the version 2.5 release of the GNU C Library. This directory contains the version 2.5.1 release of the GNU C Library.
The GNU C Library is the standard system C library for all GNU systems, The GNU C Library is the standard system C library for all GNU systems,
and is an important part of what makes up a GNU system. It provides the and is an important part of what makes up a GNU system. It provides the
@ -52,7 +52,7 @@ The GNU C Library supports these configurations for using Linux kernels:
The code for other CPU configurations supported by volunteers outside of The code for other CPU configurations supported by volunteers outside of
the core glibc maintenance effort is contained in the separate `ports' the core glibc maintenance effort is contained in the separate `ports'
add-on. You can find glibc-ports-2.5 distributed separately in the add-on. You can find glibc-ports-2.5.1 distributed separately in the
same place where you got the main glibc distribution files. same place where you got the main glibc distribution files.
Currently these configurations are known to work using the `ports' add-on: Currently these configurations are known to work using the `ports' add-on:

View File

@ -22,7 +22,6 @@ libc {
GLIBC_2.3.4 GLIBC_2.3.4
GLIBC_2.4 GLIBC_2.4
GLIBC_2.5 GLIBC_2.5
GLIBC_2.6
%ifdef USE_IN_LIBIO %ifdef USE_IN_LIBIO
HURD_CTHREADS_0.3 HURD_CTHREADS_0.3
%endif %endif
@ -83,7 +82,6 @@ libpthread {
GLIBC_2.3.3 GLIBC_2.3.3
GLIBC_2.3.4 GLIBC_2.3.4
GLIBC_2.4 GLIBC_2.4
GLIBC_2.6
GLIBC_PRIVATE GLIBC_PRIVATE
} }
libresolv { libresolv {

View File

@ -1,4 +1,4 @@
# Copyright (C) 1997, 2002, 2003, 2006 Free Software Foundation, Inc. # Copyright (C) 1997, 2002, 2003, 2006, 2007 Free Software Foundation, Inc.
# This file is part of the GNU C Library. # This file is part of the GNU C Library.
# The GNU C Library is free software; you can redistribute it and/or # The GNU C Library is free software; you can redistribute it and/or
@ -26,7 +26,7 @@ distribute = argp-fmtstream.h argp-namefrob.h
routines = $(addprefix argp-, ba fmtstream fs-xinl help parse pv \ routines = $(addprefix argp-, ba fmtstream fs-xinl help parse pv \
pvh xinl eexst) pvh xinl eexst)
tests = argp-test tst-argp1 bug-argp1 tests = argp-test tst-argp1 bug-argp1 tst-argp2
CFLAGS-argp-help.c = $(uses-callbacks) -fexceptions CFLAGS-argp-help.c = $(uses-callbacks) -fexceptions
CFLAGS-argp-parse.c = $(uses-callbacks) CFLAGS-argp-parse.c = $(uses-callbacks)

View File

@ -1,5 +1,6 @@
/* Hierarchial argument parsing help output /* Hierarchial argument parsing help output
Copyright (C) 1995-2003, 2004, 2005, 2006 Free Software Foundation, Inc. Copyright (C) 1995-2003, 2004, 2005, 2006, 2007
Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Written by Miles Bader <miles@gnu.ai.mit.edu>. Written by Miles Bader <miles@gnu.ai.mit.edu>.
@ -672,9 +673,9 @@ hol_cluster_cmp (const struct hol_cluster *cl1, const struct hol_cluster *cl2)
{ {
/* If one cluster is deeper than the other, use its ancestor at the same /* If one cluster is deeper than the other, use its ancestor at the same
level, so that finding the common ancestor is straightforward. */ level, so that finding the common ancestor is straightforward. */
while (cl1->depth < cl2->depth) while (cl1->depth > cl2->depth)
cl1 = cl1->parent; cl1 = cl1->parent;
while (cl2->depth < cl1->depth) while (cl2->depth > cl1->depth)
cl2 = cl2->parent; cl2 = cl2->parent;
/* Now reduce both clusters to their ancestors at the point where both have /* Now reduce both clusters to their ancestors at the point where both have
@ -987,7 +988,7 @@ static const char *
filter_doc (const char *doc, int key, const struct argp *argp, filter_doc (const char *doc, int key, const struct argp *argp,
const struct argp_state *state) const struct argp_state *state)
{ {
if (argp->help_filter) if (argp && argp->help_filter)
/* We must apply a user filter to this output. */ /* We must apply a user filter to this output. */
{ {
void *input = __argp_input (argp, state); void *input = __argp_input (argp, state);

101
argp/tst-argp2.c Normal file
View File

@ -0,0 +1,101 @@
/* Copyright (C) 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2007.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <argp.h>
static const struct argp_option opt1[] =
{
{ "opt1", '1', "NUMBER", 0, "Option 1" },
{ NULL, 0, NULL, 0, NULL }
};
static const struct argp_option opt2[] =
{
{ "opt2", '2', "NUMBER", 0, "Option 2" },
{ NULL, 0, NULL, 0, NULL }
};
static const struct argp_option opt3[] =
{
{ "opt3", '3', "NUMBER", 0, "Option 3" },
{ NULL, 0, NULL, 0, NULL }
};
static const struct argp_option opt4[] =
{
{ "opt4", '4', "NUMBER", 0, "Option 4" },
{ NULL, 0, NULL, 0, NULL }
};
static const struct argp_option opt5[] =
{
{ "opt5", '5', "NUMBER", 0, "Option 5" },
{ NULL, 0, NULL, 0, NULL }
};
static struct argp argp5 =
{
opt5, NULL, "args doc5", "doc5", NULL, NULL, NULL
};
static struct argp argp4 =
{
opt4, NULL, "args doc4", "doc4", NULL, NULL, NULL
};
static struct argp argp3 =
{
opt3, NULL, "args doc3", "doc3", NULL, NULL, NULL
};
static struct argp_child children2[] =
{
{ &argp4, 0, "child3", 3 },
{ &argp5, 0, "child4", 4 },
{ NULL, 0, NULL, 0 }
};
static struct argp argp2 =
{
opt2, NULL, "args doc2", "doc2", children2, NULL, NULL
};
static struct argp_child children1[] =
{
{ &argp2, 0, "child1", 1 },
{ &argp3, 0, "child2", 2 },
{ NULL, 0, NULL, 0 }
};
static struct argp argp1 =
{
opt1, NULL, "args doc1", "doc1", children1, NULL, NULL
};
static int
do_test (void)
{
argp_help (&argp1, stdout, ARGP_HELP_LONG, (char *) "tst-argp2");
return 0;
}
#define TEST_FUNCTION do_test ()
#include "../test-skeleton.c"

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1996-2005, 2006, 2007 Free Software Foundation, Inc. /* Copyright (C) 1996-2005, 2006 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 1996. Contributed by Ulrich Drepper <drepper@redhat.com>, 1996.
@ -246,7 +246,7 @@ print_version (FILE *stream, struct argp_state *state)
Copyright (C) %s Free Software Foundation, Inc.\n\ Copyright (C) %s Free Software Foundation, Inc.\n\
This is free software; see the source for copying conditions. There is NO\n\ This is free software; see the source for copying conditions. There is NO\n\
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
"), "2007"); "), "2006");
fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper"); fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper");
} }

View File

@ -19,6 +19,9 @@
/* Defined if building with SELinux support & audit libs are detected. */ /* Defined if building with SELinux support & audit libs are detected. */
#undef HAVE_LIBAUDIT #undef HAVE_LIBAUDIT
/* Defined if building with SELinux support & libcap libs are detected. */
#undef HAVE_LIBCAP
/* Define if using XCOFF. Set by --with-xcoff. */ /* Define if using XCOFF. Set by --with-xcoff. */
#undef HAVE_XCOFF #undef HAVE_XCOFF
@ -120,6 +123,23 @@
/* Define if the linker supports the -z combreloc option. */ /* Define if the linker supports the -z combreloc option. */
#undef HAVE_Z_COMBRELOC #undef HAVE_Z_COMBRELOC
/* Define if the assembler supported .protected. */
#undef HAVE_PROTECTED
/* Define if the assembler supported .hidden. */
#undef HAVE_HIDDEN
/* Define if the compiler supports __attribute__ ((visibility (...))). */
#undef HAVE_VISIBILITY_ATTRIBUTE
/* Define if the compiler doesn't support __attribute__ ((visibility (...)))
together with __asm__ redirection properly. */
#undef HAVE_BROKEN_VISIBILITY_ATTRIBUTE
/* Define if the compiler doesn't support __attribute__ ((alias (...)))
together with __asm__ redirection properly. */
#undef HAVE_BROKEN_ALIAS_ATTRIBUTE
/* Define if _rtld_local structure should be forced into .sdata section. */ /* Define if _rtld_local structure should be forced into .sdata section. */
#undef HAVE_SDATA_SECTION #undef HAVE_SDATA_SECTION
@ -171,6 +191,9 @@
/* Defined if forced unwind support is available. */ /* Defined if forced unwind support is available. */
#undef HAVE_FORCED_UNWIND #undef HAVE_FORCED_UNWIND
/* Defined if the linker supports the -z relro option. */
#undef HAVE_Z_RELRO
/* Defined of libidn is available. */ /* Defined of libidn is available. */
#undef HAVE_LIBIDN #undef HAVE_LIBIDN

View File

@ -38,9 +38,14 @@ c++-sysincludes = @CXX_SYSINCLUDES@
all-warnings = @all_warnings@ all-warnings = @all_warnings@
elf = @elf@ elf = @elf@
have-protected = @libc_cv_asm_protected_directive@
have-z-nodelete = @libc_cv_z_nodelete@
have-z-nodlopen = @libc_cv_z_nodlopen@
have-z-initfirst = @libc_cv_z_initfirst@
have-z-combreloc = @libc_cv_z_combreloc@ have-z-combreloc = @libc_cv_z_combreloc@
have-z-execstack = @libc_cv_z_execstack@ have-z-execstack = @libc_cv_z_execstack@
have-initfini = @libc_cv_have_initfini@ have-initfini = @libc_cv_have_initfini@
have-z-relro = @libc_cv_z_relro@
have-Bgroup = @libc_cv_Bgroup@ have-Bgroup = @libc_cv_Bgroup@
have-as-needed = @libc_cv_as_needed@ have-as-needed = @libc_cv_as_needed@
libgcc_s_suffix = @libc_cv_libgcc_s_suffix@ libgcc_s_suffix = @libc_cv_libgcc_s_suffix@

81
configure vendored
View File

@ -313,7 +313,7 @@ ac_includes_default="\
# include <unistd.h> # include <unistd.h>
#endif" #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 with_fp with_cvs enable_check_abi oldest_abi bindnow force_install all_warnings 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 CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC OBJEXT BUILD_CC cross_compiling CPP CXX CXXFLAGS ac_ct_CXX AR OBJDUMP RANLIB ac_ct_RANLIB MIG AS LD PWD_P MAKE MSGFMT MAKEINFO SED AUTOCONF SYSINCLUDES CXX_SYSINCLUDES libc_cv_gcc_static_libgcc BASH 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_have_initfini no_whole_archive exceptions 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 use_ldconfig ldd_rewrite_script elf xcoff static shared 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 with_fp with_cvs enable_check_abi oldest_abi bindnow force_install all_warnings 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 CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC OBJEXT BUILD_CC cross_compiling CPP CXX CXXFLAGS ac_ct_CXX AR OBJDUMP RANLIB ac_ct_RANLIB MIG AS LD PWD_P MAKE MSGFMT MAKEINFO SED AUTOCONF SYSINCLUDES CXX_SYSINCLUDES libc_cv_gcc_static_libgcc BASH libc_cv_have_bash2 KSH libc_cv_have_ksh AWK PERL INSTALL_INFO BISON VERSIONING libc_cv_asm_protected_directive libc_cv_cc_with_libunwind libc_cv_z_nodelete libc_cv_z_nodlopen libc_cv_z_initfirst libc_cv_z_relro 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_have_initfini no_whole_archive exceptions 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 use_ldconfig ldd_rewrite_script elf xcoff static shared pic_default profile omitfp bounded static_nss nopic_initfini DEFINES mach_interface_list VERSION RELEASE LIBOBJS LTLIBOBJS'
ac_subst_files='' ac_subst_files=''
# Initialize some variables set by options. # Initialize some variables set by options.
@ -864,7 +864,7 @@ Optional Features:
[default=no] [default=no]
--enable-shared build shared library [default=yes if GNU ld & --enable-shared build shared library [default=yes if GNU ld &
ELF] ELF]
--enable-profile build profiled library [default=no] --enable-profile build profiled library [default=yes]
--enable-omitfp build undebuggable optimized library --enable-omitfp build undebuggable optimized library
[default=no] [default=no]
--enable-bounded build with runtime bounds checking --enable-bounded build with runtime bounds checking
@ -1543,7 +1543,7 @@ if test "${enable_profile+set}" = set; then
enableval="$enable_profile" enableval="$enable_profile"
profile=$enableval profile=$enableval
else else
profile=no profile=yes
fi; fi;
# Check whether --enable-omitfp or --disable-omitfp was given. # Check whether --enable-omitfp or --disable-omitfp was given.
if test "${enable_omitfp+set}" = set; then if test "${enable_omitfp+set}" = set; then
@ -5339,15 +5339,22 @@ EOF
(exit $ac_status); }; }; then (exit $ac_status); }; }; then
libc_cv_asm_protected_directive=yes libc_cv_asm_protected_directive=yes
else else
{ { echo "$as_me:$LINENO: error: assembler support for symbol visibility is required" >&5 libc_cv_asm_protected_directive=no
echo "$as_me: error: assembler support for symbol visibility is required" >&2;}
{ (exit 1); exit 1; }; }
fi fi
rm -f conftest* rm -f conftest*
fi fi
echo "$as_me:$LINENO: result: $libc_cv_asm_protected_directive" >&5 echo "$as_me:$LINENO: result: $libc_cv_asm_protected_directive" >&5
echo "${ECHO_T}$libc_cv_asm_protected_directive" >&6 echo "${ECHO_T}$libc_cv_asm_protected_directive" >&6
cat >>confdefs.h <<\_ACEOF
#define HAVE_PROTECTED 1
_ACEOF
cat >>confdefs.h <<\_ACEOF
#define HAVE_HIDDEN 1
_ACEOF
if test $libc_cv_asm_protected_directive = yes; then if test $libc_cv_asm_protected_directive = yes; then
echo "$as_me:$LINENO: checking whether __attribute__((visibility())) is supported" >&5 echo "$as_me:$LINENO: checking whether __attribute__((visibility())) is supported" >&5
echo $ECHO_N "checking whether __attribute__((visibility())) is supported... $ECHO_C" >&6 echo $ECHO_N "checking whether __attribute__((visibility())) is supported... $ECHO_C" >&6
@ -5376,10 +5383,11 @@ EOF
fi fi
echo "$as_me:$LINENO: result: $libc_cv_visibility_attribute" >&5 echo "$as_me:$LINENO: result: $libc_cv_visibility_attribute" >&5
echo "${ECHO_T}$libc_cv_visibility_attribute" >&6 echo "${ECHO_T}$libc_cv_visibility_attribute" >&6
if test $libc_cv_visibility_attribute != yes; then if test $libc_cv_visibility_attribute = yes; then
{ { echo "$as_me:$LINENO: error: compiler support for visibility attribute is required" >&5 cat >>confdefs.h <<\_ACEOF
echo "$as_me: error: compiler support for visibility attribute is required" >&2;} #define HAVE_VISIBILITY_ATTRIBUTE 1
{ (exit 1); exit 1; }; } _ACEOF
fi fi
fi fi
@ -5411,9 +5419,10 @@ fi
echo "$as_me:$LINENO: result: $libc_cv_broken_visibility_attribute" >&5 echo "$as_me:$LINENO: result: $libc_cv_broken_visibility_attribute" >&5
echo "${ECHO_T}$libc_cv_broken_visibility_attribute" >&6 echo "${ECHO_T}$libc_cv_broken_visibility_attribute" >&6
if test $libc_cv_broken_visibility_attribute = yes; then if test $libc_cv_broken_visibility_attribute = yes; then
{ { echo "$as_me:$LINENO: error: working compiler support for visibility attribute is required" >&5 cat >>confdefs.h <<\_ACEOF
echo "$as_me: error: working compiler support for visibility attribute is required" >&2;} #define HAVE_BROKEN_VISIBILITY_ATTRIBUTE 1
{ (exit 1); exit 1; }; } _ACEOF
fi fi
fi fi
@ -5448,9 +5457,10 @@ fi
echo "$as_me:$LINENO: result: $libc_cv_broken_alias_attribute" >&5 echo "$as_me:$LINENO: result: $libc_cv_broken_alias_attribute" >&5
echo "${ECHO_T}$libc_cv_broken_alias_attribute" >&6 echo "${ECHO_T}$libc_cv_broken_alias_attribute" >&6
if test $libc_cv_broken_alias_attribute = yes; then if test $libc_cv_broken_alias_attribute = yes; then
{ { echo "$as_me:$LINENO: error: working alias attribute support required" >&5 cat >>confdefs.h <<\_ACEOF
echo "$as_me: error: working alias attribute support required" >&2;} #define HAVE_BROKEN_ALIAS_ATTRIBUTE 1
{ (exit 1); exit 1; }; } _ACEOF
fi fi
if test $libc_cv_visibility_attribute = yes; then if test $libc_cv_visibility_attribute = yes; then
@ -5562,15 +5572,14 @@ EOF
then then
libc_cv_z_nodelete=yes libc_cv_z_nodelete=yes
else else
{ { echo "$as_me:$LINENO: error: linker with -z nodelete support required" >&5 libc_cv_z_nodelete=no
echo "$as_me: error: linker with -z nodelete support required" >&2;}
{ (exit 1); exit 1; }; }
fi fi
rm -f conftest* rm -f conftest*
fi fi
echo "$as_me:$LINENO: result: $libc_cv_z_nodelete" >&5 echo "$as_me:$LINENO: result: $libc_cv_z_nodelete" >&5
echo "${ECHO_T}$libc_cv_z_nodelete" >&6 echo "${ECHO_T}$libc_cv_z_nodelete" >&6
echo "$as_me:$LINENO: checking for -z nodlopen option" >&5 echo "$as_me:$LINENO: checking for -z nodlopen option" >&5
echo $ECHO_N "checking for -z nodlopen option... $ECHO_C" >&6 echo $ECHO_N "checking for -z nodlopen option... $ECHO_C" >&6
if test "${libc_cv_z_nodlopen+set}" = set; then if test "${libc_cv_z_nodlopen+set}" = set; then
@ -5591,15 +5600,14 @@ EOF
then then
libc_cv_z_nodlopen=yes libc_cv_z_nodlopen=yes
else else
{ { echo "$as_me:$LINENO: error: linker with -z nodlopen support required" >&5 libc_cv_z_nodlopen=no
echo "$as_me: error: linker with -z nodlopen support required" >&2;}
{ (exit 1); exit 1; }; }
fi fi
rm -f conftest* rm -f conftest*
fi fi
echo "$as_me:$LINENO: result: $libc_cv_z_nodlopen" >&5 echo "$as_me:$LINENO: result: $libc_cv_z_nodlopen" >&5
echo "${ECHO_T}$libc_cv_z_nodlopen" >&6 echo "${ECHO_T}$libc_cv_z_nodlopen" >&6
echo "$as_me:$LINENO: checking for -z initfirst option" >&5 echo "$as_me:$LINENO: checking for -z initfirst option" >&5
echo $ECHO_N "checking for -z initfirst option... $ECHO_C" >&6 echo $ECHO_N "checking for -z initfirst option... $ECHO_C" >&6
if test "${libc_cv_z_initfirst+set}" = set; then if test "${libc_cv_z_initfirst+set}" = set; then
@ -5620,18 +5628,15 @@ EOF
then then
libc_cv_z_initfirst=yes libc_cv_z_initfirst=yes
else else
{ { echo "$as_me:$LINENO: error: linker with -z initfirst support required" >&5 libc_cv_z_initfirst=no
echo "$as_me: error: linker with -z initfirst support required" >&2;}
{ (exit 1); exit 1; }; }
fi fi
rm -f conftest* rm -f conftest*
fi fi
echo "$as_me:$LINENO: result: $libc_cv_z_initfirst" >&5 echo "$as_me:$LINENO: result: $libc_cv_z_initfirst" >&5
echo "${ECHO_T}$libc_cv_z_initfirst" >&6 echo "${ECHO_T}$libc_cv_z_initfirst" >&6
case "$base_machine" in
i[34567]86 | x86_64 | powerpc* | s390* | sparc* | alpha*) echo "$as_me:$LINENO: checking for -z relro option" >&5
echo "$as_me:$LINENO: checking for -z relro option" >&5
echo $ECHO_N "checking for -z relro option... $ECHO_C" >&6 echo $ECHO_N "checking for -z relro option... $ECHO_C" >&6
if test "${libc_cv_z_relro+set}" = set; then if test "${libc_cv_z_relro+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6 echo $ECHO_N "(cached) $ECHO_C" >&6
@ -5657,14 +5662,13 @@ else
fi fi
echo "$as_me:$LINENO: result: $libc_cv_z_relro" >&5 echo "$as_me:$LINENO: result: $libc_cv_z_relro" >&5
echo "${ECHO_T}$libc_cv_z_relro" >&6 echo "${ECHO_T}$libc_cv_z_relro" >&6
if test "$libc_cv_z_relro" = no; then
{ { echo "$as_me:$LINENO: error: linker with -z relro support required" >&5 if test $libc_cv_z_relro = yes; then
echo "$as_me: error: linker with -z relro support required" >&2;} cat >>confdefs.h <<\_ACEOF
{ (exit 1); exit 1; }; } #define HAVE_Z_RELRO 1
fi _ACEOF
;;
*) ;; fi
esac
echo "$as_me:$LINENO: checking for -Bgroup option" >&5 echo "$as_me:$LINENO: checking for -Bgroup option" >&5
echo $ECHO_N "checking for -Bgroup option... $ECHO_C" >&6 echo $ECHO_N "checking for -Bgroup option... $ECHO_C" >&6
@ -8506,7 +8510,12 @@ s,@PERL@,$PERL,;t t
s,@INSTALL_INFO@,$INSTALL_INFO,;t t s,@INSTALL_INFO@,$INSTALL_INFO,;t t
s,@BISON@,$BISON,;t t s,@BISON@,$BISON,;t t
s,@VERSIONING@,$VERSIONING,;t t s,@VERSIONING@,$VERSIONING,;t t
s,@libc_cv_asm_protected_directive@,$libc_cv_asm_protected_directive,;t t
s,@libc_cv_cc_with_libunwind@,$libc_cv_cc_with_libunwind,;t t s,@libc_cv_cc_with_libunwind@,$libc_cv_cc_with_libunwind,;t t
s,@libc_cv_z_nodelete@,$libc_cv_z_nodelete,;t t
s,@libc_cv_z_nodlopen@,$libc_cv_z_nodlopen,;t t
s,@libc_cv_z_initfirst@,$libc_cv_z_initfirst,;t t
s,@libc_cv_z_relro@,$libc_cv_z_relro,;t t
s,@libc_cv_Bgroup@,$libc_cv_Bgroup,;t t s,@libc_cv_Bgroup@,$libc_cv_Bgroup,;t t
s,@libc_cv_libgcc_s_suffix@,$libc_cv_libgcc_s_suffix,;t t s,@libc_cv_libgcc_s_suffix@,$libc_cv_libgcc_s_suffix,;t t
s,@libc_cv_as_needed@,$libc_cv_as_needed,;t t s,@libc_cv_as_needed@,$libc_cv_as_needed,;t t

View File

@ -131,9 +131,9 @@ AC_ARG_ENABLE([shared],
[shared=default]) [shared=default])
AC_ARG_ENABLE([profile], AC_ARG_ENABLE([profile],
AC_HELP_STRING([--enable-profile], AC_HELP_STRING([--enable-profile],
[build profiled library @<:@default=no@:>@]), [build profiled library @<:@default=yes@:>@]),
[profile=$enableval], [profile=$enableval],
[profile=no]) [profile=yes])
AC_ARG_ENABLE([omitfp], AC_ARG_ENABLE([omitfp],
AC_HELP_STRING([--enable-omitfp], AC_HELP_STRING([--enable-omitfp],
[build undebuggable optimized library @<:@default=no@:>@]), [build undebuggable optimized library @<:@default=no@:>@]),
@ -1259,9 +1259,12 @@ EOF
if AC_TRY_COMMAND(${CC-cc} -c $ASFLAGS conftest.s 1>&AS_MESSAGE_LOG_FD); then if AC_TRY_COMMAND(${CC-cc} -c $ASFLAGS conftest.s 1>&AS_MESSAGE_LOG_FD); then
libc_cv_asm_protected_directive=yes libc_cv_asm_protected_directive=yes
else else
AC_MSG_ERROR(assembler support for symbol visibility is required) libc_cv_asm_protected_directive=no
fi fi
rm -f conftest*]) rm -f conftest*])
AC_SUBST(libc_cv_asm_protected_directive)
AC_DEFINE(HAVE_PROTECTED)
AC_DEFINE(HAVE_HIDDEN)
if test $libc_cv_asm_protected_directive = yes; then if test $libc_cv_asm_protected_directive = yes; then
AC_CACHE_CHECK(whether __attribute__((visibility())) is supported, AC_CACHE_CHECK(whether __attribute__((visibility())) is supported,
@ -1280,8 +1283,8 @@ EOF
fi fi
rm -f conftest.[cs] rm -f conftest.[cs]
]) ])
if test $libc_cv_visibility_attribute != yes; then if test $libc_cv_visibility_attribute = yes; then
AC_MSG_ERROR(compiler support for visibility attribute is required) AC_DEFINE(HAVE_VISIBILITY_ATTRIBUTE)
fi fi
fi fi
@ -1304,7 +1307,7 @@ changequote([,])dnl
rm -f conftest.c conftest.s rm -f conftest.c conftest.s
]) ])
if test $libc_cv_broken_visibility_attribute = yes; then if test $libc_cv_broken_visibility_attribute = yes; then
AC_MSG_ERROR(working compiler support for visibility attribute is required) AC_DEFINE(HAVE_BROKEN_VISIBILITY_ATTRIBUTE)
fi fi
fi fi
@ -1328,7 +1331,7 @@ EOF
rm -f conftest.c conftest.s rm -f conftest.c conftest.s
]) ])
if test $libc_cv_broken_alias_attribute = yes; then if test $libc_cv_broken_alias_attribute = yes; then
AC_MSG_ERROR(working alias attribute support required) AC_DEFINE(HAVE_BROKEN_ALIAS_ATTRIBUTE)
fi fi
if test $libc_cv_visibility_attribute = yes; then if test $libc_cv_visibility_attribute = yes; then
@ -1400,9 +1403,10 @@ EOF
then then
libc_cv_z_nodelete=yes libc_cv_z_nodelete=yes
else else
AC_MSG_ERROR(linker with -z nodelete support required) libc_cv_z_nodelete=no
fi fi
rm -f conftest*]) rm -f conftest*])
AC_SUBST(libc_cv_z_nodelete)
AC_CACHE_CHECK(for -z nodlopen option, AC_CACHE_CHECK(for -z nodlopen option,
libc_cv_z_nodlopen, [dnl libc_cv_z_nodlopen, [dnl
@ -1416,9 +1420,10 @@ EOF
then then
libc_cv_z_nodlopen=yes libc_cv_z_nodlopen=yes
else else
AC_MSG_ERROR(linker with -z nodlopen support required) libc_cv_z_nodlopen=no
fi fi
rm -f conftest*]) rm -f conftest*])
AC_SUBST(libc_cv_z_nodlopen)
AC_CACHE_CHECK(for -z initfirst option, AC_CACHE_CHECK(for -z initfirst option,
libc_cv_z_initfirst, [dnl libc_cv_z_initfirst, [dnl
@ -1432,16 +1437,13 @@ EOF
then then
libc_cv_z_initfirst=yes libc_cv_z_initfirst=yes
else else
AC_MSG_ERROR(linker with -z initfirst support required) libc_cv_z_initfirst=no
fi fi
rm -f conftest*]) rm -f conftest*])
AC_SUBST(libc_cv_z_initfirst)
case "$base_machine" in AC_CACHE_CHECK(for -z relro option,
changequote(,)dnl libc_cv_z_relro, [dnl
i[34567]86 | x86_64 | powerpc* | s390* | sparc* | alpha*)
changequote([,])dnl
AC_CACHE_CHECK(for -z relro option,
libc_cv_z_relro, [dnl
libc_cv_z_relro=no libc_cv_z_relro=no
if AC_TRY_COMMAND([${CC-cc} -v --help 2>&1|grep "z relro" 1>&AS_MESSAGE_LOG_FD]) if AC_TRY_COMMAND([${CC-cc} -v --help 2>&1|grep "z relro" 1>&AS_MESSAGE_LOG_FD])
then then
@ -1450,12 +1452,10 @@ changequote([,])dnl
libc_cv_z_relro=yes libc_cv_z_relro=yes
fi fi
fi]) fi])
if test "$libc_cv_z_relro" = no; then AC_SUBST(libc_cv_z_relro)
AC_MSG_ERROR(linker with -z relro support required) if test $libc_cv_z_relro = yes; then
fi AC_DEFINE(HAVE_Z_RELRO)
;; fi
*) ;;
esac
AC_CACHE_CHECK(for -Bgroup option, AC_CACHE_CHECK(for -Bgroup option,
libc_cv_Bgroup, [dnl libc_cv_Bgroup, [dnl

View File

@ -5,7 +5,7 @@ libc {
# helper functions # helper functions
__libc_init_first; __libc_start_main; __libc_init_first; __libc_start_main;
%if !HAVE___THREAD %if !(USE_TLS && HAVE___THREAD)
# global variables # global variables
_errno; _errno;
@ -18,7 +18,7 @@ libc {
gnu_get_libc_release; gnu_get_libc_version; gnu_get_libc_release; gnu_get_libc_version;
} }
GLIBC_PRIVATE { GLIBC_PRIVATE {
%if HAVE___THREAD %if USE_TLS && HAVE___THREAD
# This version is for the TLS symbol, GLIBC_2.0 is the old object symbol. # This version is for the TLS symbol, GLIBC_2.0 is the old object symbol.
errno; errno;
%endif %endif

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1998-2003, 2004, 2005, 2006 Free Software Foundation, Inc. /* Copyright (C) 1998-2003, 2004, 2005 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -30,7 +30,11 @@ extern int __libc_multiple_libcs;
#include <tls.h> #include <tls.h>
#ifndef SHARED #ifndef SHARED
# include <dl-osinfo.h> # include <dl-osinfo.h>
extern void __pthread_initialize_minimal (void); extern void __pthread_initialize_minimal (void)
# if !(USE_TLS - 0) && !defined NONTLS_INIT_TP
__attribute__ ((weak))
# endif
;
# ifndef THREAD_SET_STACK_GUARD # ifndef THREAD_SET_STACK_GUARD
/* Only exported for architectures that don't store the stack guard canary /* Only exported for architectures that don't store the stack guard canary
in thread local area. */ in thread local area. */
@ -136,8 +140,13 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
/* Initialize the thread library at least a bit since the libgcc /* Initialize the thread library at least a bit since the libgcc
functions are using thread functions if these are available and functions are using thread functions if these are available and
we need to setup errno. */ we need to setup errno. If there is no thread library and we
__pthread_initialize_minimal (); handle TLS the function is defined in the libc to initialized the
TLS handling. */
# if !(USE_TLS - 0) && !defined NONTLS_INIT_TP
if (__pthread_initialize_minimal)
# endif
__pthread_initialize_minimal ();
#endif #endif
# ifndef SHARED # ifndef SHARED

View File

@ -1,5 +1,5 @@
/* Initialization code for TLS in statically linked application. /* Initialization code for TLS in statically linked application.
Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -29,6 +29,7 @@
#error makefile bug, this file is for static only #error makefile bug, this file is for static only
#endif #endif
#ifdef USE_TLS
extern ElfW(Phdr) *_dl_phdr; extern ElfW(Phdr) *_dl_phdr;
extern size_t _dl_phnum; extern size_t _dl_phnum;
@ -142,19 +143,19 @@ __libc_setup_tls (size_t tcbsize, size_t tcbalign)
The initialized value of _dl_tls_static_size is provided by dl-open.c The initialized value of _dl_tls_static_size is provided by dl-open.c
to request some surplus that permits dynamic loading of modules with to request some surplus that permits dynamic loading of modules with
IE-model TLS. */ IE-model TLS. */
#if TLS_TCB_AT_TP # if TLS_TCB_AT_TP
tcb_offset = roundup (memsz + GL(dl_tls_static_size), tcbalign); tcb_offset = roundup (memsz + GL(dl_tls_static_size), tcbalign);
tlsblock = __sbrk (tcb_offset + tcbsize + max_align); tlsblock = __sbrk (tcb_offset + tcbsize + max_align);
#elif TLS_DTV_AT_TP # elif TLS_DTV_AT_TP
tcb_offset = roundup (tcbsize, align ?: 1); tcb_offset = roundup (tcbsize, align ?: 1);
tlsblock = __sbrk (tcb_offset + memsz + max_align tlsblock = __sbrk (tcb_offset + memsz + max_align
+ TLS_PRE_TCB_SIZE + GL(dl_tls_static_size)); + TLS_PRE_TCB_SIZE + GL(dl_tls_static_size));
tlsblock += TLS_PRE_TCB_SIZE; tlsblock += TLS_PRE_TCB_SIZE;
#else # else
/* In case a model with a different layout for the TCB and DTV /* In case a model with a different layout for the TCB and DTV
is defined add another #elif here and in the following #ifs. */ is defined add another #elif here and in the following #ifs. */
# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined" # error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
#endif # endif
/* Align the TLS block. */ /* Align the TLS block. */
tlsblock = (void *) (((uintptr_t) tlsblock + max_align - 1) tlsblock = (void *) (((uintptr_t) tlsblock + max_align - 1)
@ -165,16 +166,16 @@ __libc_setup_tls (size_t tcbsize, size_t tcbalign)
// static_dtv[1].counter = 0; would be needed if not already done // static_dtv[1].counter = 0; would be needed if not already done
/* Initialize the TLS block. */ /* Initialize the TLS block. */
#if TLS_TCB_AT_TP # if TLS_TCB_AT_TP
static_dtv[2].pointer.val = ((char *) tlsblock + tcb_offset static_dtv[2].pointer.val = ((char *) tlsblock + tcb_offset
- roundup (memsz, align ?: 1)); - roundup (memsz, align ?: 1));
static_map.l_tls_offset = roundup (memsz, align ?: 1); static_map.l_tls_offset = roundup (memsz, align ?: 1);
#elif TLS_DTV_AT_TP # elif TLS_DTV_AT_TP
static_dtv[2].pointer.val = (char *) tlsblock + tcb_offset; static_dtv[2].pointer.val = (char *) tlsblock + tcb_offset;
static_map.l_tls_offset = tcb_offset; static_map.l_tls_offset = tcb_offset;
#else # else
# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined" # error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
#endif # endif
static_dtv[2].pointer.is_static = true; static_dtv[2].pointer.is_static = true;
/* sbrk gives us zero'd memory, so we don't need to clear the remainder. */ /* sbrk gives us zero'd memory, so we don't need to clear the remainder. */
memcpy (static_dtv[2].pointer.val, initimage, filesz); memcpy (static_dtv[2].pointer.val, initimage, filesz);
@ -182,16 +183,16 @@ __libc_setup_tls (size_t tcbsize, size_t tcbalign)
/* Install the pointer to the dtv. */ /* Install the pointer to the dtv. */
/* Initialize the thread pointer. */ /* Initialize the thread pointer. */
#if TLS_TCB_AT_TP # if TLS_TCB_AT_TP
INSTALL_DTV ((char *) tlsblock + tcb_offset, static_dtv); INSTALL_DTV ((char *) tlsblock + tcb_offset, static_dtv);
const char *lossage = TLS_INIT_TP ((char *) tlsblock + tcb_offset, 0); const char *lossage = TLS_INIT_TP ((char *) tlsblock + tcb_offset, 0);
#elif TLS_DTV_AT_TP # elif TLS_DTV_AT_TP
INSTALL_DTV (tlsblock, static_dtv); INSTALL_DTV (tlsblock, static_dtv);
const char *lossage = TLS_INIT_TP (tlsblock, 0); const char *lossage = TLS_INIT_TP (tlsblock, 0);
#else # else
# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined" # error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
#endif # endif
if (__builtin_expect (lossage != NULL, 0)) if (__builtin_expect (lossage != NULL, 0))
__libc_fatal (lossage); __libc_fatal (lossage);
@ -211,11 +212,11 @@ __libc_setup_tls (size_t tcbsize, size_t tcbalign)
memsz = roundup (memsz, align ?: 1); memsz = roundup (memsz, align ?: 1);
#if TLS_TCB_AT_TP # if TLS_TCB_AT_TP
memsz += tcbsize; memsz += tcbsize;
#elif TLS_DTV_AT_TP # elif TLS_DTV_AT_TP
memsz += tcb_offset; memsz += tcb_offset;
#endif # endif
init_static_tls (memsz, MAX (TLS_TCB_ALIGN, max_align)); init_static_tls (memsz, MAX (TLS_TCB_ALIGN, max_align));
} }
@ -229,11 +230,11 @@ _dl_tls_setup (void)
{ {
init_slotinfo (); init_slotinfo ();
init_static_tls ( init_static_tls (
#if TLS_TCB_AT_TP # if TLS_TCB_AT_TP
TLS_TCB_SIZE, TLS_TCB_SIZE,
#else # else
0, 0,
#endif # endif
TLS_TCB_ALIGN); TLS_TCB_ALIGN);
return 0; return 0;
} }
@ -247,3 +248,16 @@ __pthread_initialize_minimal (void)
{ {
__libc_setup_tls (TLS_INIT_TCB_SIZE, TLS_INIT_TCB_ALIGN); __libc_setup_tls (TLS_INIT_TCB_SIZE, TLS_INIT_TCB_ALIGN);
} }
#elif defined NONTLS_INIT_TP
/* This is the minimal initialization function used when libpthread is
not used. */
void
__attribute__ ((weak))
__pthread_initialize_minimal (void)
{
NONTLS_INIT_TP;
}
#endif

View File

@ -1,5 +1,5 @@
/* Tests for atomic.h macros. /* Tests for atomic.h macros.
Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc. Copyright (C) 2003, 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2003. Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
@ -379,117 +379,6 @@ do_test (void)
} }
#endif #endif
#ifdef catomic_compare_and_exchange_val_acq
mem = 24;
if (catomic_compare_and_exchange_val_acq (&mem, 35, 24) != 24
|| mem != 35)
{
puts ("catomic_compare_and_exchange_val_acq test 1 failed");
ret = 1;
}
mem = 12;
if (catomic_compare_and_exchange_val_acq (&mem, 10, 15) != 12
|| mem != 12)
{
puts ("catomic_compare_and_exchange_val_acq test 2 failed");
ret = 1;
}
mem = -15;
if (catomic_compare_and_exchange_val_acq (&mem, -56, -15) != -15
|| mem != -56)
{
puts ("catomic_compare_and_exchange_val_acq test 3 failed");
ret = 1;
}
mem = -1;
if (catomic_compare_and_exchange_val_acq (&mem, 17, 0) != -1
|| mem != -1)
{
puts ("catomic_compare_and_exchange_val_acq test 4 failed");
ret = 1;
}
#endif
mem = 24;
if (catomic_compare_and_exchange_bool_acq (&mem, 35, 24)
|| mem != 35)
{
puts ("catomic_compare_and_exchange_bool_acq test 1 failed");
ret = 1;
}
mem = 12;
if (! catomic_compare_and_exchange_bool_acq (&mem, 10, 15)
|| mem != 12)
{
puts ("catomic_compare_and_exchange_bool_acq test 2 failed");
ret = 1;
}
mem = -15;
if (catomic_compare_and_exchange_bool_acq (&mem, -56, -15)
|| mem != -56)
{
puts ("catomic_compare_and_exchange_bool_acq test 3 failed");
ret = 1;
}
mem = -1;
if (! catomic_compare_and_exchange_bool_acq (&mem, 17, 0)
|| mem != -1)
{
puts ("catomic_compare_and_exchange_bool_acq test 4 failed");
ret = 1;
}
mem = 2;
if (catomic_exchange_and_add (&mem, 11) != 2
|| mem != 13)
{
puts ("catomic_exchange_and_add test failed");
ret = 1;
}
mem = -21;
catomic_add (&mem, 22);
if (mem != 1)
{
puts ("catomic_add test failed");
ret = 1;
}
mem = -1;
catomic_increment (&mem);
if (mem != 0)
{
puts ("catomic_increment test failed");
ret = 1;
}
mem = 2;
if (catomic_increment_val (&mem) != 3)
{
puts ("catomic_increment_val test failed");
ret = 1;
}
mem = 17;
catomic_decrement (&mem);
if (mem != 16)
{
puts ("catomic_decrement test failed");
ret = 1;
}
if (catomic_decrement_val (&mem) != 15)
{
puts ("catomic_decrement_val test failed");
ret = 1;
}
return ret; return ret;
} }

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1992-2006, 2007 Free Software Foundation, Inc. /* Copyright (C) 1992-2002, 2003, 2004, 2006 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -25,7 +25,7 @@ static const char __libc_version[] = VERSION;
static const char banner[] = static const char banner[] =
"GNU C Library "RELEASE" release version "VERSION", by Roland McGrath et al.\n\ "GNU C Library "RELEASE" release version "VERSION", by Roland McGrath et al.\n\
Copyright (C) 2007 Free Software Foundation, Inc.\n\ Copyright (C) 2006 Free Software Foundation, Inc.\n\
This is free software; see the source for copying conditions.\n\ This is free software; see the source for copying conditions.\n\
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A\n\ There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A\n\
PARTICULAR PURPOSE.\n\ PARTICULAR PURPOSE.\n\
@ -34,6 +34,9 @@ Compiled by GNU CC version "__VERSION__".\n"
#ifdef GLIBC_OLDEST_ABI #ifdef GLIBC_OLDEST_ABI
"The oldest ABI supported: " GLIBC_OLDEST_ABI ".\n" "The oldest ABI supported: " GLIBC_OLDEST_ABI ".\n"
#endif #endif
#ifdef USE_TLS
"Thread-local storage support included.\n"
#endif
"For bug reporting instructions, please see:\n\ "For bug reporting instructions, please see:\n\
<http://www.gnu.org/software/libc/bugs.html>.\n"; <http://www.gnu.org/software/libc/bugs.html>.\n";

View File

@ -1,6 +1,5 @@
#! /bin/sh #! /bin/sh
# Copyright (C) 1998,1999,2001,2003,2004,2006,2007 # Copyright (C) 1998,1999,2001,2003,2004,2006 Free Software Foundation, Inc.
# Free Software Foundation, Inc.
# This file is part of the GNU C Library. # This file is part of the GNU C Library.
# Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998. # Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
@ -40,7 +39,7 @@ if test $# -eq 0; then
;; ;;
--v | --ve | --ver | --vers | --versi | --versio | --version) --v | --ve | --ver | --vers | --versi | --versio | --version)
echo 'catchsegv (GNU libc) @VERSION@' echo 'catchsegv (GNU libc) @VERSION@'
echo 'Copyright (C) 2007 Free Software Foundation, Inc. echo 'Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Written by Ulrich Drepper.' Written by Ulrich Drepper.'

View File

@ -64,7 +64,7 @@ do_version() {
printf $"Copyright (C) %s Free Software Foundation, Inc. printf $"Copyright (C) %s Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
" "2007" " "2006"
printf $"Written by %s. printf $"Written by %s.
" "Ulrich Drepper" " "Ulrich Drepper"
exit 0 exit 0
@ -161,32 +161,32 @@ if test -n "$data"; then
while read fct; do while read fct; do
read file read file
if test "$fct" != '??' -a "$file" != '??:0'; then if test "$fct" != '??' -a "$file" != '??:0'; then
format_line $fct $file format_line "$fct" "$file"
fi fi
done done
else else
fifo=$(mktemp -u ${TMPDIR:-/tmp}/xtrace.XXXXXX) fifo=$(mktemp -ut xtrace.XXXXXX) || exit
trap 'rm -f "$fifo"; exit 1' HUP INT QUIT TERM PIPE
mkfifo -m 0600 $fifo || exit 1 mkfifo -m 0600 $fifo || exit 1
trap 'rm $fifo; exit 1' SIGINT SIGTERM SIGPIPE
# Now start the program and let it write to the FIFO. # Now start the program and let it write to the FIFO.
$TERMINAL_PROG -T "xtrace - $program $*" -e /bin/sh -c "LD_PRELOAD=$pcprofileso PCPROFILE_OUTPUT=$fifo $program $*; read < $fifo" & $TERMINAL_PROG -T "xtrace - $program $*" -e /bin/sh -c "LD_PRELOAD=$pcprofileso PCPROFILE_OUTPUT=$fifo $program $*; read < $fifo" &
termpid=$! termpid=$!
$pcprofiledump -u $fifo | $pcprofiledump -u "$fifo" |
while read line; do while read line; do
echo $line | echo "$line" |
sed 's/this = \([^,]*\).*/\1/' | sed 's/this = \([^,]*\).*/\1/' |
addr2line -fC -e $program addr2line -fC -e "$program"
done | done |
while read fct; do while read fct; do
read file read file
if test "$fct" != '??' -a "$file" != '??:0'; then if test "$fct" != '??' -a "$file" != '??:0'; then
format_line $fct $file format_line "$fct" "$file"
fi fi
done done
read -p "Press return here to close $TERMINAL_PROG($program)." read -p "Press return here to close $TERMINAL_PROG($program)."
echo > $fifo echo > "$fifo"
rm $fifo rm "$fifo"
fi fi
exit 0 exit 0

View File

@ -41,7 +41,10 @@ endif
ifeq (yes,$(build-shared)) ifeq (yes,$(build-shared))
tests = glrefmain failtest tst-dladdr default errmsg1 tstcxaatexit \ tests = glrefmain failtest tst-dladdr default errmsg1 tstcxaatexit \
bug-dlopen1 bug-dlsym1 tst-dlinfo bug-atexit1 bug-atexit2 \ bug-dlopen1 bug-dlsym1 tst-dlinfo bug-atexit1 bug-atexit2 \
bug-atexit3 tstatexit bug-atexit3
ifeq (yes,$(have-protected))
tests += tstatexit
endif
endif endif
modules-names = glreflib1 glreflib2 failtestmod defaultmod1 defaultmod2 \ modules-names = glreflib1 glreflib2 failtestmod defaultmod1 defaultmod2 \
errmsg1mod modatexit modcxaatexit \ errmsg1mod modatexit modcxaatexit \

View File

@ -1,5 +1,5 @@
/* dlinfo -- Get information from the dynamic linker. /* dlinfo -- Get information from the dynamic linker.
Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc. Copyright (C) 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -32,7 +32,9 @@ dlinfo (void *handle, int request, void *arg)
#else #else
# include <dl-tls.h> # ifdef USE_TLS
# include <dl-tls.h>
# endif
struct dlinfo_args struct dlinfo_args
{ {
@ -56,9 +58,8 @@ dlinfo_doit (void *argsblock)
/* Find the highest-addressed object that CALLER is not below. */ /* Find the highest-addressed object that CALLER is not below. */
for (nsid = 0; nsid < DL_NNS; ++nsid) for (nsid = 0; nsid < DL_NNS; ++nsid)
for (l = GL(dl_ns)[nsid]._ns_loaded; l != NULL; l = l->l_next) for (l = GL(dl_ns)[nsid]._ns_loaded; l != NULL; l = l->l_next)
if (caller >= l->l_map_start && caller < l->l_map_end) if (caller >= l->l_map_start && caller < l->l_map_end
/* There must be exactly one DSO for the range of the virtual && (l->l_contiguous || _dl_addr_inside_object (l, caller)))
memory. Otherwise something is really broken. */
break; break;
if (l == NULL) if (l == NULL)
@ -95,14 +96,18 @@ RTLD_SELF used in code not dynamically loaded"));
case RTLD_DI_TLS_MODID: case RTLD_DI_TLS_MODID:
*(size_t *) args->arg = 0; *(size_t *) args->arg = 0;
#ifdef USE_TLS
*(size_t *) args->arg = l->l_tls_modid; *(size_t *) args->arg = l->l_tls_modid;
#endif
break; break;
case RTLD_DI_TLS_DATA: case RTLD_DI_TLS_DATA:
{ {
void *data = NULL; void *data = NULL;
#ifdef USE_TLS
if (l->l_tls_modid != 0) if (l->l_tls_modid != 0)
data = _dl_tls_get_addr_soft (l); data = _dl_tls_get_addr_soft (l);
#endif
*(void **) args->arg = data; *(void **) args->arg = data;
break; break;
} }

View File

@ -159,8 +159,8 @@ endif
ifeq (yes,$(build-shared)) ifeq (yes,$(build-shared))
tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \ tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \
constload1 order $(tests-vis-$(have-protected)) noload filter unload \ constload1 order $(tests-vis-$(have-protected)) noload filter unload \
reldep reldep2 reldep3 reldep4 nodelete nodelete2 \ reldep reldep2 reldep3 reldep4 $(tests-nodelete-$(have-z-nodelete)) \
nodlopen nodlopen2 neededtest neededtest2 \ $(tests-nodlopen-$(have-z-nodlopen)) neededtest neededtest2 \
neededtest3 neededtest4 unload2 lateglobal initfirst global \ neededtest3 neededtest4 unload2 lateglobal initfirst global \
restest2 next dblload dblunload reldep5 reldep6 reldep7 reldep8 \ restest2 next dblload dblunload reldep5 reldep6 reldep7 reldep8 \
circleload1 tst-tls3 tst-tls4 tst-tls5 tst-tls6 tst-tls7 tst-tls8 \ circleload1 tst-tls3 tst-tls4 tst-tls5 tst-tls6 tst-tls7 tst-tls8 \
@ -175,6 +175,8 @@ tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \
# reldep9 # reldep9
test-srcs = tst-pathopt test-srcs = tst-pathopt
tests-vis-yes = vismain tests-vis-yes = vismain
tests-nodelete-yes = nodelete nodelete2
tests-nodlopen-yes = nodlopen nodlopen2
tests-execstack-yes = tst-execstack tst-execstack-needed tst-execstack-prog tests-execstack-yes = tst-execstack tst-execstack-needed tst-execstack-prog
endif endif
ifeq (yesyes,$(have-fpie)$(build-shared)) ifeq (yesyes,$(have-fpie)$(build-shared))
@ -184,9 +186,8 @@ tests: $(objpfx)tst-leaks1-mem
modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
testobj1_1 failobj constload2 constload3 unloadmod \ testobj1_1 failobj constload2 constload3 unloadmod \
dep1 dep2 dep3 dep4 $(modules-vis-$(have-protected)) \ dep1 dep2 dep3 dep4 $(modules-vis-$(have-protected)) \
nodelmod1 nodelmod2 nodelmod3 nodelmod4 \ $(modules-nodelete-$(have-z-nodelete)) \
nodel2mod1 nodel2mod2 nodel2mod3 \ $(modules-nodlopen-$(have-z-nodlopen)) filtmod1 filtmod2 \
nodlopenmod nodlopenmod2 filtmod1 filtmod2 \
reldepmod1 reldepmod2 reldepmod3 reldepmod4 nextmod1 nextmod2 \ reldepmod1 reldepmod2 reldepmod3 reldepmod4 nextmod1 nextmod2 \
reldep4mod1 reldep4mod2 reldep4mod3 reldep4mod4 \ reldep4mod1 reldep4mod2 reldep4mod3 reldep4mod4 \
neededobj1 neededobj2 neededobj3 neededobj4 \ neededobj1 neededobj2 neededobj3 neededobj4 \
@ -220,6 +221,9 @@ ifeq (yesyes,$(have-fpie)$(build-shared))
modules-names += tst-piemod1 modules-names += tst-piemod1
endif endif
modules-vis-yes = vismod1 vismod2 vismod3 modules-vis-yes = vismod1 vismod2 vismod3
modules-nodelete-yes = nodelmod1 nodelmod2 nodelmod3 nodelmod4 \
nodel2mod1 nodel2mod2 nodel2mod3
modules-nodlopen-yes = nodlopenmod nodlopenmod2
modules-execstack-yes = tst-execstack-mod modules-execstack-yes = tst-execstack-mod
extra-test-objs += $(addsuffix .os,$(strip $(modules-names))) extra-test-objs += $(addsuffix .os,$(strip $(modules-names)))
# We need this variable to be sure the test modules get the right CPPFLAGS. # We need this variable to be sure the test modules get the right CPPFLAGS.

View File

@ -439,7 +439,7 @@ save_cache (const char *cache_name)
} }
if (write (fd, strings, total_strlen) != (ssize_t) total_strlen) if (write (fd, strings, total_strlen) != (ssize_t) total_strlen)
error (EXIT_FAILURE, errno, _("Writing of cache data failed")); error (EXIT_FAILURE, errno, _("Writing of cache data failed."));
close (fd); close (fd);

View File

@ -1,5 +1,5 @@
/* Locate the shared object symbol nearest a given address. /* Locate the shared object symbol nearest a given address.
Copyright (C) 1996-2004, 2005, 2006 Free Software Foundation, Inc. Copyright (C) 1996-2004, 2005, 2006, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -22,139 +22,149 @@
#include <ldsodefs.h> #include <ldsodefs.h>
static void
__attribute ((always_inline))
determine_info (const ElfW(Addr) addr, struct link_map *match, Dl_info *info,
struct link_map **mapp, const ElfW(Sym) **symbolp)
{
/* Now we know what object the address lies in. */
info->dli_fname = match->l_name;
info->dli_fbase = (void *) match->l_map_start;
/* If this is the main program the information is incomplete. */
if (__builtin_expect (match->l_name[0], 'a') == '\0'
&& match->l_type == lt_executable)
info->dli_fname = _dl_argv[0];
const ElfW(Sym) *symtab
= (const ElfW(Sym) *) D_PTR (match, l_info[DT_SYMTAB]);
const char *strtab = (const char *) D_PTR (match, l_info[DT_STRTAB]);
ElfW(Word) strtabsize = match->l_info[DT_STRSZ]->d_un.d_val;
const ElfW(Sym) *matchsym = NULL;
if (match->l_info[DT_ADDRTAGIDX (DT_GNU_HASH) + DT_NUM + DT_THISPROCNUM
+ DT_VERSIONTAGNUM + DT_EXTRANUM + DT_VALNUM] != NULL)
{
/* We look at all symbol table entries referenced by the hash
table. */
for (Elf_Symndx bucket = 0; bucket < match->l_nbuckets; ++bucket)
{
Elf32_Word symndx = match->l_gnu_buckets[bucket];
if (symndx != 0)
{
const Elf32_Word *hasharr = &match->l_gnu_chain_zero[symndx];
do
{
/* The hash table never references local symbols so
we can omit that test here. */
if ((symtab[symndx].st_shndx != SHN_UNDEF
|| symtab[symndx].st_value != 0)
#ifdef USE_TLS
&& ELFW(ST_TYPE) (symtab[symndx].st_info) != STT_TLS
#endif
&& DL_ADDR_SYM_MATCH (match, &symtab[symndx],
matchsym, addr)
&& symtab[symndx].st_name < strtabsize)
matchsym = (ElfW(Sym) *) &symtab[symndx];
++symndx;
}
while ((*hasharr++ & 1u) == 0);
}
}
}
else
{
const ElfW(Sym) *symtabend;
if (match->l_info[DT_HASH] != NULL)
symtabend = (symtab
+ ((Elf_Symndx *) D_PTR (match, l_info[DT_HASH]))[1]);
else
/* There is no direct way to determine the number of symbols in the
dynamic symbol table and no hash table is present. The ELF
binary is ill-formed but what shall we do? Use the beginning of
the string table which generally follows the symbol table. */
symtabend = (const ElfW(Sym) *) strtab;
for (; (void *) symtab < (void *) symtabend; ++symtab)
if ((ELFW(ST_BIND) (symtab->st_info) == STB_GLOBAL
|| ELFW(ST_BIND) (symtab->st_info) == STB_WEAK)
#ifdef USE_TLS
&& ELFW(ST_TYPE) (symtab->st_info) != STT_TLS
#endif
&& (symtab->st_shndx != SHN_UNDEF
|| symtab->st_value != 0)
&& DL_ADDR_SYM_MATCH (match, symtab, matchsym, addr)
&& symtab->st_name < strtabsize)
matchsym = (ElfW(Sym) *) symtab;
}
if (mapp)
*mapp = match;
if (symbolp)
*symbolp = matchsym;
if (matchsym)
{
/* We found a symbol close by. Fill in its name and exact
address. */
lookup_t matchl = LOOKUP_VALUE (match);
info->dli_sname = strtab + matchsym->st_name;
info->dli_saddr = DL_SYMBOL_ADDRESS (matchl, matchsym);
}
else
{
/* No symbol matches. We return only the containing object. */
info->dli_sname = NULL;
info->dli_saddr = NULL;
}
}
int int
internal_function internal_function
_dl_addr (const void *address, Dl_info *info, _dl_addr (const void *address, Dl_info *info,
struct link_map **mapp, const ElfW(Sym) **symbolp) struct link_map **mapp, const ElfW(Sym) **symbolp)
{ {
const ElfW(Addr) addr = DL_LOOKUP_ADDRESS (address); const ElfW(Addr) addr = DL_LOOKUP_ADDRESS (address);
int result = 0;
/* Protect against concurrent loads and unloads. */ /* Protect against concurrent loads and unloads. */
__rtld_lock_lock_recursive (GL(dl_load_lock)); __rtld_lock_lock_recursive (GL(dl_load_lock));
/* Find the highest-addressed object that ADDRESS is not below. */ /* Find the highest-addressed object that ADDRESS is not below. */
struct link_map *match = NULL;
for (Lmid_t ns = 0; ns < DL_NNS; ++ns) for (Lmid_t ns = 0; ns < DL_NNS; ++ns)
for (struct link_map *l = GL(dl_ns)[ns]._ns_loaded; l; l = l->l_next) for (struct link_map *l = GL(dl_ns)[ns]._ns_loaded; l; l = l->l_next)
if (addr >= l->l_map_start && addr < l->l_map_end) if (addr >= l->l_map_start && addr < l->l_map_end
&& (l->l_contiguous || _dl_addr_inside_object (l, addr)))
{ {
/* We know ADDRESS lies within L if in any shared object. determine_info (addr, l, info, mapp, symbolp);
Make sure it isn't past the end of L's segments. */ result = 1;
size_t n = l->l_phnum; goto out;
if (n > 0)
{
do
--n;
while (l->l_phdr[n].p_type != PT_LOAD);
if (addr >= (l->l_addr +
l->l_phdr[n].p_vaddr + l->l_phdr[n].p_memsz))
/* Off the end of the highest-addressed shared object. */
continue;
}
match = l;
break;
} }
int result = 0; out:
if (match != NULL)
{
/* Now we know what object the address lies in. */
info->dli_fname = match->l_name;
info->dli_fbase = (void *) match->l_map_start;
/* If this is the main program the information is incomplete. */
if (__builtin_expect (match->l_name[0], 'a') == '\0'
&& match->l_type == lt_executable)
info->dli_fname = _dl_argv[0];
const ElfW(Sym) *symtab
= (const ElfW(Sym) *) D_PTR (match, l_info[DT_SYMTAB]);
const char *strtab = (const char *) D_PTR (match, l_info[DT_STRTAB]);
ElfW(Word) strtabsize = match->l_info[DT_STRSZ]->d_un.d_val;
const ElfW(Sym) *matchsym = NULL;
if (match->l_info[DT_ADDRTAGIDX (DT_GNU_HASH) + DT_NUM + DT_THISPROCNUM
+ DT_VERSIONTAGNUM + DT_EXTRANUM + DT_VALNUM] != NULL)
{
/* We look at all symbol table entries referenced by the
hash table. */
for (Elf_Symndx bucket = 0; bucket < match->l_nbuckets; ++bucket)
{
Elf32_Word symndx = match->l_gnu_buckets[bucket];
if (symndx != 0)
{
const Elf32_Word *hasharr = &match->l_gnu_chain_zero[symndx];
do
{
/* The hash table never references local symbols
so we can omit that test here. */
if ((symtab[symndx].st_shndx != SHN_UNDEF
|| symtab[symndx].st_value != 0)
&& ELFW(ST_TYPE) (symtab[symndx].st_info) != STT_TLS
&& DL_ADDR_SYM_MATCH (match, &symtab[symndx],
matchsym, addr)
&& symtab[symndx].st_name < strtabsize)
matchsym = (ElfW(Sym) *) &symtab[symndx];
++symndx;
}
while ((*hasharr++ & 1u) == 0);
}
}
}
else
{
const ElfW(Sym) *symtabend;
if (match->l_info[DT_HASH] != NULL)
symtabend = (symtab
+ ((Elf_Symndx *) D_PTR (match, l_info[DT_HASH]))[1]);
else
/* There is no direct way to determine the number of symbols in the
dynamic symbol table and no hash table is present. The ELF
binary is ill-formed but what shall we do? Use the beginning of
the string table which generally follows the symbol table. */
symtabend = (const ElfW(Sym) *) strtab;
for (; (void *) symtab < (void *) symtabend; ++symtab)
if ((ELFW(ST_BIND) (symtab->st_info) == STB_GLOBAL
|| ELFW(ST_BIND) (symtab->st_info) == STB_WEAK)
&& ELFW(ST_TYPE) (symtab->st_info) != STT_TLS
&& (symtab->st_shndx != SHN_UNDEF
|| symtab->st_value != 0)
&& DL_ADDR_SYM_MATCH (match, symtab, matchsym, addr)
&& symtab->st_name < strtabsize)
matchsym = (ElfW(Sym) *) symtab;
}
if (mapp)
*mapp = match;
if (symbolp)
*symbolp = matchsym;
if (matchsym)
{
/* We found a symbol close by. Fill in its name and exact
address. */
lookup_t matchl = LOOKUP_VALUE (match);
info->dli_sname = strtab + matchsym->st_name;
info->dli_saddr = DL_SYMBOL_ADDRESS (matchl, matchsym);
}
else
{
/* No symbol matches. We return only the containing object. */
info->dli_sname = NULL;
info->dli_saddr = NULL;
}
result = 1;
}
__rtld_lock_unlock_recursive (GL(dl_load_lock)); __rtld_lock_unlock_recursive (GL(dl_load_lock));
return result; return result;
} }
libc_hidden_def (_dl_addr) libc_hidden_def (_dl_addr)
/* Return non-zero if ADDR lies within one of L's segments. */
int
internal_function
_dl_addr_inside_object (struct link_map *l, const ElfW(Addr) addr)
{
int n = l->l_phnum;
const ElfW(Addr) reladdr = addr - l->l_addr;
while (--n >= 0)
if (l->l_phdr[n].p_type == PT_LOAD
&& reladdr - l->l_phdr[n].p_vaddr >= 0
&& reladdr - l->l_phdr[n].p_vaddr < l->l_phdr[n].p_memsz)
return 1;
return 0;
}

View File

@ -256,7 +256,11 @@ _dl_load_cache_lookup (const char *name)
platform = 1ULL << platform; platform = 1ULL << platform;
/* Only accept hwcap if it's for the right platform. */ /* Only accept hwcap if it's for the right platform. */
#define _DL_HWCAP_TLS_MASK (1LL << 63) #ifdef USE_TLS
# define _DL_HWCAP_TLS_MASK (1LL << 63)
#else
# define _DL_HWCAP_TLS_MASK 0
#endif
#define HWCAP_CHECK \ #define HWCAP_CHECK \
if (GLRO(dl_osversion) && lib->osversion > GLRO(dl_osversion)) \ if (GLRO(dl_osversion) && lib->osversion > GLRO(dl_osversion)) \
continue; \ continue; \

View File

@ -1,5 +1,5 @@
/* Close a shared object opened by `_dl_open'. /* Close a shared object opened by `_dl_open'.
Copyright (C) 1996-2005, 2006 Free Software Foundation, Inc. Copyright (C) 1996-2005, 2006, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -31,6 +31,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <sysdep-cancel.h> #include <sysdep-cancel.h>
#include <tls.h>
/* Type of the constructor functions. */ /* Type of the constructor functions. */
@ -41,6 +42,7 @@ typedef void (*fini_t) (void);
#define IDX_STILL_USED -1 #define IDX_STILL_USED -1
#ifdef USE_TLS
/* Returns true we an non-empty was found. */ /* Returns true we an non-empty was found. */
static bool static bool
remove_slotinfo (size_t idx, struct dtv_slotinfo_list *listp, size_t disp, remove_slotinfo (size_t idx, struct dtv_slotinfo_list *listp, size_t disp,
@ -102,13 +104,12 @@ remove_slotinfo (size_t idx, struct dtv_slotinfo_list *listp, size_t disp,
/* No non-entry in this list element. */ /* No non-entry in this list element. */
return false; return false;
} }
#endif
void void
_dl_close_worker (struct link_map *map) _dl_close_worker (struct link_map *map)
{ {
Lmid_t ns = map->l_ns;
/* One less direct use. */ /* One less direct use. */
--map->l_direct_opencount; --map->l_direct_opencount;
@ -131,11 +132,16 @@ _dl_close_worker (struct link_map *map)
return; return;
} }
Lmid_t nsid = map->l_ns;
struct link_namespaces *ns = &GL(dl_ns)[nsid];
retry: retry:
dl_close_state = pending; dl_close_state = pending;
#ifdef USE_TLS
bool any_tls = false; bool any_tls = false;
const unsigned int nloaded = GL(dl_ns)[ns]._ns_nloaded; #endif
const unsigned int nloaded = ns->_ns_nloaded;
char used[nloaded]; char used[nloaded];
char done[nloaded]; char done[nloaded];
struct link_map *maps[nloaded]; struct link_map *maps[nloaded];
@ -143,7 +149,7 @@ _dl_close_worker (struct link_map *map)
/* Run over the list and assign indexes to the link maps and enter /* Run over the list and assign indexes to the link maps and enter
them into the MAPS array. */ them into the MAPS array. */
int idx = 0; int idx = 0;
for (struct link_map *l = GL(dl_ns)[ns]._ns_loaded; l != NULL; l = l->l_next) for (struct link_map *l = ns->_ns_loaded; l != NULL; l = l->l_next)
{ {
l->l_idx = idx; l->l_idx = idx;
maps[idx] = l; maps[idx] = l;
@ -220,20 +226,22 @@ _dl_close_worker (struct link_map *map)
} }
/* Sort the entries. */ /* Sort the entries. */
_dl_sort_fini (GL(dl_ns)[ns]._ns_loaded, maps, nloaded, used, ns); _dl_sort_fini (ns->_ns_loaded, maps, nloaded, used, nsid);
/* Call all termination functions at once. */ /* Call all termination functions at once. */
#ifdef SHARED #ifdef SHARED
bool do_audit = GLRO(dl_naudit) > 0 && !GL(dl_ns)[ns]._ns_loaded->l_auditing; bool do_audit = GLRO(dl_naudit) > 0 && !ns->_ns_loaded->l_auditing;
#endif #endif
bool unload_any = false; bool unload_any = false;
bool scope_mem_left = false;
unsigned int unload_global = 0;
unsigned int first_loaded = ~0; unsigned int first_loaded = ~0;
for (unsigned int i = 0; i < nloaded; ++i) for (unsigned int i = 0; i < nloaded; ++i)
{ {
struct link_map *imap = maps[i]; struct link_map *imap = maps[i];
/* All elements must be in the same namespace. */ /* All elements must be in the same namespace. */
assert (imap->l_ns == ns); assert (imap->l_ns == nsid);
if (!used[i]) if (!used[i])
{ {
@ -248,7 +256,7 @@ _dl_close_worker (struct link_map *map)
if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS, if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS,
0)) 0))
_dl_debug_printf ("\ncalling fini: %s [%lu]\n\n", _dl_debug_printf ("\ncalling fini: %s [%lu]\n\n",
imap->l_name, ns); imap->l_name, nsid);
if (imap->l_info[DT_FINI_ARRAY] != NULL) if (imap->l_info[DT_FINI_ARRAY] != NULL)
{ {
@ -291,6 +299,9 @@ _dl_close_worker (struct link_map *map)
/* We indeed have an object to remove. */ /* We indeed have an object to remove. */
unload_any = true; unload_any = true;
if (imap->l_global)
++unload_global;
/* Remember where the first dynamically loaded object is. */ /* Remember where the first dynamically loaded object is. */
if (i < first_loaded) if (i < first_loaded)
first_loaded = i; first_loaded = i;
@ -334,7 +345,7 @@ _dl_close_worker (struct link_map *map)
struct link_map *tmap = (struct link_map *) struct link_map *tmap = (struct link_map *)
((char *) imap->l_scope[cnt] ((char *) imap->l_scope[cnt]
- offsetof (struct link_map, l_searchlist)); - offsetof (struct link_map, l_searchlist));
assert (tmap->l_ns == ns); assert (tmap->l_ns == nsid);
if (tmap->l_idx == IDX_STILL_USED) if (tmap->l_idx == IDX_STILL_USED)
++remain; ++remain;
else else
@ -399,18 +410,18 @@ _dl_close_worker (struct link_map *map)
struct r_scope_elem **old = imap->l_scope; struct r_scope_elem **old = imap->l_scope;
if (RTLD_SINGLE_THREAD_P) imap->l_scope = newp;
imap->l_scope = newp;
else
{
__rtld_mrlock_change (imap->l_scope_lock);
imap->l_scope = newp;
__rtld_mrlock_done (imap->l_scope_lock);
}
/* No user anymore, we can free it now. */ /* No user anymore, we can free it now. */
if (old != imap->l_scope_mem) if (old != imap->l_scope_mem)
free (old); {
if (_dl_scope_free (old))
/* If _dl_scope_free used THREAD_GSCOPE_WAIT (),
no need to repeat it. */
scope_mem_left = false;
}
else
scope_mem_left = true;
imap->l_scope_max = new_size; imap->l_scope_max = new_size;
} }
@ -435,7 +446,7 @@ _dl_close_worker (struct link_map *map)
/* Auditing checkpoint: we will start deleting objects. */ /* Auditing checkpoint: we will start deleting objects. */
if (__builtin_expect (do_audit, 0)) if (__builtin_expect (do_audit, 0))
{ {
struct link_map *head = GL(dl_ns)[ns]._ns_loaded; struct link_map *head = ns->_ns_loaded;
struct audit_ifaces *afct = GLRO(dl_audit); struct audit_ifaces *afct = GLRO(dl_audit);
/* Do not call the functions for any auditing object. */ /* Do not call the functions for any auditing object. */
if (head->l_auditing == 0) if (head->l_auditing == 0)
@ -452,13 +463,55 @@ _dl_close_worker (struct link_map *map)
#endif #endif
/* Notify the debugger we are about to remove some loaded objects. */ /* Notify the debugger we are about to remove some loaded objects. */
struct r_debug *r = _dl_debug_initialize (0, ns); struct r_debug *r = _dl_debug_initialize (0, nsid);
r->r_state = RT_DELETE; r->r_state = RT_DELETE;
_dl_debug_state (); _dl_debug_state ();
if (unload_global)
{
/* Some objects are in the global scope list. Remove them. */
struct r_scope_elem *ns_msl = ns->_ns_main_searchlist;
unsigned int i;
unsigned int j = 0;
unsigned int cnt = ns_msl->r_nlist;
while (cnt > 0 && ns_msl->r_list[cnt - 1]->l_removed)
--cnt;
if (cnt + unload_global == ns_msl->r_nlist)
/* Speed up removing most recently added objects. */
j = cnt;
else
for (i = 0; i < cnt; i++)
if (ns_msl->r_list[i]->l_removed == 0)
{
if (i != j)
ns_msl->r_list[j] = ns_msl->r_list[i];
j++;
}
ns_msl->r_nlist = j;
}
if (!RTLD_SINGLE_THREAD_P
&& (unload_global
|| scope_mem_left
|| (GL(dl_scope_free_list) != NULL
&& GL(dl_scope_free_list)->count)))
{
struct dl_scope_free_list *fsl;
THREAD_GSCOPE_WAIT ();
/* Now we can free any queued old scopes. */
if ((fsl = GL(dl_scope_free_list)) != NULL)
while (fsl->count > 0)
free (fsl->list[--fsl->count]);
}
#ifdef USE_TLS
size_t tls_free_start; size_t tls_free_start;
size_t tls_free_end; size_t tls_free_end;
tls_free_start = tls_free_end = NO_TLS_OFFSET; tls_free_start = tls_free_end = NO_TLS_OFFSET;
#endif
/* Check each element of the search list to see if all references to /* Check each element of the search list to see if all references to
it are gone. */ it are gone. */
@ -471,24 +524,8 @@ _dl_close_worker (struct link_map *map)
/* That was the last reference, and this was a dlopen-loaded /* That was the last reference, and this was a dlopen-loaded
object. We can unmap it. */ object. We can unmap it. */
if (__builtin_expect (imap->l_global, 0))
{
/* This object is in the global scope list. Remove it. */
unsigned int cnt = GL(dl_ns)[ns]._ns_main_searchlist->r_nlist;
do
--cnt;
while (GL(dl_ns)[ns]._ns_main_searchlist->r_list[cnt] != imap);
/* The object was already correctly registered. */
while (++cnt
< GL(dl_ns)[ns]._ns_main_searchlist->r_nlist)
GL(dl_ns)[ns]._ns_main_searchlist->r_list[cnt - 1]
= GL(dl_ns)[ns]._ns_main_searchlist->r_list[cnt];
--GL(dl_ns)[ns]._ns_main_searchlist->r_nlist;
}
#ifdef USE_TLS
/* Remove the object from the dtv slotinfo array if it uses TLS. */ /* Remove the object from the dtv slotinfo array if it uses TLS. */
if (__builtin_expect (imap->l_tls_blocksize > 0, 0)) if (__builtin_expect (imap->l_tls_blocksize > 0, 0))
{ {
@ -507,7 +544,7 @@ _dl_close_worker (struct link_map *map)
this search list, going in either direction. When the this search list, going in either direction. When the
whole chunk is at the end of the used area then we can whole chunk is at the end of the used area then we can
reclaim it. */ reclaim it. */
#if TLS_TCB_AT_TP # if TLS_TCB_AT_TP
if (tls_free_start == NO_TLS_OFFSET if (tls_free_start == NO_TLS_OFFSET
|| (size_t) imap->l_tls_offset == tls_free_start) || (size_t) imap->l_tls_offset == tls_free_start)
{ {
@ -547,7 +584,7 @@ _dl_close_worker (struct link_map *map)
= tls_free_end - imap->l_tls_blocksize; = tls_free_end - imap->l_tls_blocksize;
} }
} }
#elif TLS_DTV_AT_TP # elif TLS_DTV_AT_TP
if ((size_t) imap->l_tls_offset == tls_free_end) if ((size_t) imap->l_tls_offset == tls_free_end)
/* Extend the contiguous chunk being reclaimed. */ /* Extend the contiguous chunk being reclaimed. */
tls_free_end -= imap->l_tls_blocksize; tls_free_end -= imap->l_tls_blocksize;
@ -564,11 +601,12 @@ _dl_close_worker (struct link_map *map)
tls_free_start = imap->l_tls_offset; tls_free_start = imap->l_tls_offset;
tls_free_end = tls_free_start + imap->l_tls_blocksize; tls_free_end = tls_free_start + imap->l_tls_blocksize;
} }
#else # else
# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined" # error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
#endif # endif
} }
} }
#endif
/* We can unmap all the maps at once. We determined the /* We can unmap all the maps at once. We determined the
start address and length when we loaded the object and start address and length when we loaded the object and
@ -581,12 +619,12 @@ _dl_close_worker (struct link_map *map)
else else
{ {
#ifdef SHARED #ifdef SHARED
assert (ns != LM_ID_BASE); assert (nsid != LM_ID_BASE);
#endif #endif
GL(dl_ns)[ns]._ns_loaded = imap->l_next; ns->_ns_loaded = imap->l_next;
} }
--GL(dl_ns)[ns]._ns_nloaded; --ns->_ns_nloaded;
if (imap->l_next != NULL) if (imap->l_next != NULL)
imap->l_next->l_prev = imap->l_prev; imap->l_next->l_prev = imap->l_prev;
@ -634,6 +672,7 @@ _dl_close_worker (struct link_map *map)
} }
} }
#ifdef USE_TLS
/* If we removed any object which uses TLS bump the generation counter. */ /* If we removed any object which uses TLS bump the generation counter. */
if (any_tls) if (any_tls)
{ {
@ -643,12 +682,13 @@ _dl_close_worker (struct link_map *map)
if (tls_free_end == GL(dl_tls_static_used)) if (tls_free_end == GL(dl_tls_static_used))
GL(dl_tls_static_used) = tls_free_start; GL(dl_tls_static_used) = tls_free_start;
} }
#endif
#ifdef SHARED #ifdef SHARED
/* Auditing checkpoint: we have deleted all objects. */ /* Auditing checkpoint: we have deleted all objects. */
if (__builtin_expect (do_audit, 0)) if (__builtin_expect (do_audit, 0))
{ {
struct link_map *head = GL(dl_ns)[ns]._ns_loaded; struct link_map *head = ns->_ns_loaded;
/* Do not call the functions for any auditing object. */ /* Do not call the functions for any auditing object. */
if (head->l_auditing == 0) if (head->l_auditing == 0)
{ {
@ -702,6 +742,7 @@ _dl_close (void *_map)
} }
#ifdef USE_TLS
static bool __libc_freeres_fn_section static bool __libc_freeres_fn_section
free_slotinfo (struct dtv_slotinfo_list **elemp) free_slotinfo (struct dtv_slotinfo_list **elemp)
{ {
@ -728,45 +769,52 @@ free_slotinfo (struct dtv_slotinfo_list **elemp)
return true; return true;
} }
#endif
libc_freeres_fn (free_mem) libc_freeres_fn (free_mem)
{ {
for (Lmid_t ns = 0; ns < DL_NNS; ++ns) for (Lmid_t nsid = 0; nsid < DL_NNS; ++nsid)
if (__builtin_expect (GL(dl_ns)[ns]._ns_global_scope_alloc, 0) != 0 if (__builtin_expect (GL(dl_ns)[nsid]._ns_global_scope_alloc, 0) != 0
&& (GL(dl_ns)[ns]._ns_main_searchlist->r_nlist && (GL(dl_ns)[nsid]._ns_main_searchlist->r_nlist
// XXX Check whether we need NS-specific initial_searchlist // XXX Check whether we need NS-specific initial_searchlist
== GLRO(dl_initial_searchlist).r_nlist)) == GLRO(dl_initial_searchlist).r_nlist))
{ {
/* All object dynamically loaded by the program are unloaded. Free /* All object dynamically loaded by the program are unloaded. Free
the memory allocated for the global scope variable. */ the memory allocated for the global scope variable. */
struct link_map **old = GL(dl_ns)[ns]._ns_main_searchlist->r_list; struct link_map **old = GL(dl_ns)[nsid]._ns_main_searchlist->r_list;
/* Put the old map in. */ /* Put the old map in. */
GL(dl_ns)[ns]._ns_main_searchlist->r_list GL(dl_ns)[nsid]._ns_main_searchlist->r_list
// XXX Check whether we need NS-specific initial_searchlist // XXX Check whether we need NS-specific initial_searchlist
= GLRO(dl_initial_searchlist).r_list; = GLRO(dl_initial_searchlist).r_list;
/* Signal that the original map is used. */ /* Signal that the original map is used. */
GL(dl_ns)[ns]._ns_global_scope_alloc = 0; GL(dl_ns)[nsid]._ns_global_scope_alloc = 0;
/* Now free the old map. */ /* Now free the old map. */
free (old); free (old);
} }
#ifdef USE_TLS
if (USE___THREAD || GL(dl_tls_dtv_slotinfo_list) != NULL) if (USE___THREAD || GL(dl_tls_dtv_slotinfo_list) != NULL)
{ {
/* Free the memory allocated for the dtv slotinfo array. We can do /* Free the memory allocated for the dtv slotinfo array. We can do
this only if all modules which used this memory are unloaded. */ this only if all modules which used this memory are unloaded. */
#ifdef SHARED # ifdef SHARED
if (GL(dl_initial_dtv) == NULL) if (GL(dl_initial_dtv) == NULL)
/* There was no initial TLS setup, it was set up later when /* There was no initial TLS setup, it was set up later when
it used the normal malloc. */ it used the normal malloc. */
free_slotinfo (&GL(dl_tls_dtv_slotinfo_list)); free_slotinfo (&GL(dl_tls_dtv_slotinfo_list));
else else
#endif # endif
/* The first element of the list does not have to be deallocated. /* The first element of the list does not have to be deallocated.
It was allocated in the dynamic linker (i.e., with a different It was allocated in the dynamic linker (i.e., with a different
malloc), and in the static library it's in .bss space. */ malloc), and in the static library it's in .bss space. */
free_slotinfo (&GL(dl_tls_dtv_slotinfo_list)->next); free_slotinfo (&GL(dl_tls_dtv_slotinfo_list)->next);
} }
#endif
void *scope_free_list = GL(dl_scope_free_list);
GL(dl_scope_free_list) = NULL;
free (scope_free_list);
} }

View File

@ -123,7 +123,7 @@ DST not allowed in SUID/SGID programs")); \
processed. */ \ processed. */ \
if (fatal) \ if (fatal) \
_dl_signal_error (0, __str, NULL, N_("\ _dl_signal_error (0, __str, NULL, N_("\
empty dynamic string token substitution")); \ empty dynamics string token substitution")); \
else \ else \
{ \ { \
/* This is for DT_AUXILIARY. */ \ /* This is for DT_AUXILIARY. */ \

View File

@ -1,5 +1,6 @@
/* Handling of dynamic sring tokens. /* Handling of dynamic sring tokens.
Copyright (C) 1999,2001,2002,2003,2004,2006 Free Software Foundation, Inc. Copyright (C) 1999,2001,2002,2003,2004,2006,2007
Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -50,7 +51,7 @@
\ \
First get the origin string if it is not available yet. \ First get the origin string if it is not available yet. \
This can only happen for the map of the executable. */ \ This can only happen for the map of the executable. */ \
DL_DST_REQ_STATIC \ DL_DST_REQ_STATIC (l) \
if ((l)->l_origin == NULL) \ if ((l)->l_origin == NULL) \
{ \ { \
assert ((l)->l_name[0] == '\0'); \ assert ((l)->l_name[0] == '\0'); \
@ -68,9 +69,9 @@
__len; }) __len; })
#ifdef SHARED #ifdef SHARED
# define DL_DST_REQ_STATIC /* nothing */ # define DL_DST_REQ_STATIC(l) /* nothing */
#else #else
# define DL_DST_REQ_STATIC \ # define DL_DST_REQ_STATIC(l) \
if ((l) == NULL) \ if ((l) == NULL) \
{ \ { \
const char *origin = _dl_get_origin (); \ const char *origin = _dl_get_origin (); \

View File

@ -1,5 +1,5 @@
/* Manage function descriptors. Generic version. /* Manage function descriptors. Generic version.
Copyright (C) 1999-2004, 2006 Free Software Foundation, Inc. Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -40,7 +40,7 @@
#ifndef COMPARE_AND_SWAP #ifndef COMPARE_AND_SWAP
# define COMPARE_AND_SWAP(ptr, old, new) \ # define COMPARE_AND_SWAP(ptr, old, new) \
(catomic_compare_and_exchange_bool_acq (ptr, new, old) == 0) (atomic_compare_and_exchange_bool_acq (ptr, new, old) == 0)
#endif #endif
ElfW(Addr) _dl_boot_fptr_table [ELF_MACHINE_BOOT_FPTR_TABLE_LEN]; ElfW(Addr) _dl_boot_fptr_table [ELF_MACHINE_BOOT_FPTR_TABLE_LEN];

View File

@ -1,5 +1,5 @@
/* Get loaded objects program headers. /* Get loaded objects program headers.
Copyright (C) 2001,2002,2003,2004,2006 Free Software Foundation, Inc. Copyright (C) 2001,2002,2003,2004,2006,2007 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2001. Contributed by Jakub Jelinek <jakub@redhat.com>, 2001.
@ -54,9 +54,9 @@ __dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info,
nloaded += GL(dl_ns)[cnt]._ns_nloaded; nloaded += GL(dl_ns)[cnt]._ns_nloaded;
if (caller >= (const void *) l->l_map_start if (caller >= (const void *) l->l_map_start
&& caller < (const void *) l->l_map_end) && caller < (const void *) l->l_map_end
/* There must be exactly one DSO for the range of the virtual && (l->l_contiguous
memory. Otherwise something is really broken. */ || _dl_addr_inside_object (l, (ElfW(Addr)) caller)))
ns = cnt; ns = cnt;
} }
@ -70,9 +70,11 @@ __dl_iterate_phdr (int (*callback) (struct dl_phdr_info *info,
info.dlpi_subs = GL(dl_load_adds) - nloaded; info.dlpi_subs = GL(dl_load_adds) - nloaded;
info.dlpi_tls_modid = 0; info.dlpi_tls_modid = 0;
info.dlpi_tls_data = NULL; info.dlpi_tls_data = NULL;
#ifdef USE_TLS
info.dlpi_tls_modid = l->l_tls_modid; info.dlpi_tls_modid = l->l_tls_modid;
if (info.dlpi_tls_modid != 0) if (info.dlpi_tls_modid != 0)
info.dlpi_tls_data = _dl_tls_get_addr_soft (l); info.dlpi_tls_data = _dl_tls_get_addr_soft (l);
#endif
ret = callback (&info, sizeof (struct dl_phdr_info), data); ret = callback (&info, sizeof (struct dl_phdr_info), data);
if (ret) if (ret)
break; break;

View File

@ -1,5 +1,5 @@
/* Handle loading and unloading shared objects for internal libc purposes. /* Handle loading and unloading shared objects for internal libc purposes.
Copyright (C) 1999-2002,2004,2005,2006 Free Software Foundation, Inc. Copyright (C) 1999,2000,2001,2002,2004,2005 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Contributed by Zack Weinberg <zack@rabi.columbia.edu>, 1999. Contributed by Zack Weinberg <zack@rabi.columbia.edu>, 1999.

View File

@ -1,5 +1,5 @@
/* Map in a shared object's segments from the file. /* Map in a shared object's segments from the file.
Copyright (C) 1995-2005, 2006 Free Software Foundation, Inc. Copyright (C) 1995-2005, 2006, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -1078,6 +1078,7 @@ _dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp,
break; break;
case PT_TLS: case PT_TLS:
#ifdef USE_TLS
if (ph->p_memsz == 0) if (ph->p_memsz == 0)
/* Nothing to do for an empty segment. */ /* Nothing to do for an empty segment. */
break; break;
@ -1105,7 +1106,7 @@ _dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp,
break; break;
} }
#ifdef SHARED # ifdef SHARED
if (l->l_prev == NULL || (mode & __RTLD_AUDIT) != 0) if (l->l_prev == NULL || (mode & __RTLD_AUDIT) != 0)
/* We are loading the executable itself when the dynamic linker /* We are loading the executable itself when the dynamic linker
was executed directly. The setup will happen later. */ was executed directly. The setup will happen later. */
@ -1114,7 +1115,7 @@ _dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp,
/* In a static binary there is no way to tell if we dynamically /* In a static binary there is no way to tell if we dynamically
loaded libpthread. */ loaded libpthread. */
if (GL(dl_error_catch_tsd) == &_dl_initial_error_catch_tsd) if (GL(dl_error_catch_tsd) == &_dl_initial_error_catch_tsd)
#endif # endif
{ {
/* We have not yet loaded libpthread. /* We have not yet loaded libpthread.
We can do the TLS setup right now! */ We can do the TLS setup right now! */
@ -1147,6 +1148,7 @@ cannot allocate TLS data structures for initial thread");
_dl_deallocate_tls (tcb, 1); _dl_deallocate_tls (tcb, 1);
goto call_lose; goto call_lose;
} }
#endif
/* Uh-oh, the binary expects TLS support but we cannot /* Uh-oh, the binary expects TLS support but we cannot
provide it. */ provide it. */
@ -1223,6 +1225,8 @@ cannot allocate TLS data structures for initial thread");
loadcmds[nloadcmds - 1].mapstart - c->mapend, loadcmds[nloadcmds - 1].mapstart - c->mapend,
PROT_NONE); PROT_NONE);
l->l_contiguous = 1;
goto postmap; goto postmap;
} }
@ -1242,6 +1246,7 @@ cannot allocate TLS data structures for initial thread");
/* Remember which part of the address space this object uses. */ /* Remember which part of the address space this object uses. */
l->l_map_start = c->mapstart + l->l_addr; l->l_map_start = c->mapstart + l->l_addr;
l->l_map_end = l->l_map_start + maplength; l->l_map_end = l->l_map_start + maplength;
l->l_contiguous = !has_holes;
while (c < &loadcmds[nloadcmds]) while (c < &loadcmds[nloadcmds])
{ {
@ -1385,7 +1390,7 @@ cannot allocate TLS data structures for initial thread");
requires that it be executable. We must change the requires that it be executable. We must change the
protection of the variable which contains the flags used in protection of the variable which contains the flags used in
the mprotect calls. */ the mprotect calls. */
#ifdef SHARED #if defined HAVE_Z_RELRO && defined SHARED
if ((mode & (__RTLD_DLOPEN | __RTLD_AUDIT)) == __RTLD_DLOPEN) if ((mode & (__RTLD_DLOPEN | __RTLD_AUDIT)) == __RTLD_DLOPEN)
{ {
const uintptr_t p = (uintptr_t) &__stack_prot & -GLRO(dl_pagesize); const uintptr_t p = (uintptr_t) &__stack_prot & -GLRO(dl_pagesize);
@ -1422,9 +1427,11 @@ cannot enable executable stack as shared object requires");
} }
} }
#ifdef USE_TLS
/* Adjust the address of the TLS initialization image. */ /* Adjust the address of the TLS initialization image. */
if (l->l_tls_initimage != NULL) if (l->l_tls_initimage != NULL)
l->l_tls_initimage = (char *) l->l_tls_initimage + l->l_addr; l->l_tls_initimage = (char *) l->l_tls_initimage + l->l_addr;
#endif
/* We are done mapping in the file. We no longer need the descriptor. */ /* We are done mapping in the file. We no longer need the descriptor. */
if (__builtin_expect (__close (fd) != 0, 0)) if (__builtin_expect (__close (fd) != 0, 0))
@ -1928,10 +1935,11 @@ open_path (const char *name, size_t namelen, int preloaded,
must not be freed using the general free() in libc. */ must not be freed using the general free() in libc. */
if (sps->malloced) if (sps->malloced)
free (sps->dirs); free (sps->dirs);
#ifdef HAVE_Z_RELRO
/* rtld_search_dirs is attribute_relro, therefore avoid writing /* rtld_search_dirs is attribute_relro, therefore avoid writing
into it. */ into it. */
if (sps != &rtld_search_dirs) if (sps != &rtld_search_dirs)
#endif
sps->dirs = (void *) -1; sps->dirs = (void *) -1;
} }

View File

@ -1,5 +1,5 @@
/* Look up a symbol in the loaded objects. /* Look up a symbol in the loaded objects.
Copyright (C) 1995-2005, 2006 Free Software Foundation, Inc. Copyright (C) 1995-2005, 2006, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -25,6 +25,7 @@
#include <ldsodefs.h> #include <ldsodefs.h>
#include <dl-hash.h> #include <dl-hash.h>
#include <dl-machine.h> #include <dl-machine.h>
#include <sysdep-cancel.h>
#include <bits/libc-lock.h> #include <bits/libc-lock.h>
#include <tls.h> #include <tls.h>
@ -228,17 +229,13 @@ _dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map,
/* No other flag than DL_LOOKUP_ADD_DEPENDENCY is allowed if we look /* No other flag than DL_LOOKUP_ADD_DEPENDENCY is allowed if we look
up a versioned symbol. */ up a versioned symbol. */
assert (version == NULL || flags == 0 || flags == DL_LOOKUP_ADD_DEPENDENCY); assert (version == NULL || (flags & ~(DL_LOOKUP_ADD_DEPENDENCY)) == 0);
size_t i = 0; size_t i = 0;
if (__builtin_expect (skip_map != NULL, 0)) if (__builtin_expect (skip_map != NULL, 0))
{ /* Search the relevant loaded objects for a definition. */
/* Search the relevant loaded objects for a definition. */ while ((*scope)->r_list[i] != skip_map)
while ((*scope)->r_list[i] != skip_map) ++i;
++i;
assert (i < (*scope)->r_nlist);
}
/* Search the relevant loaded objects for a definition. */ /* Search the relevant loaded objects for a definition. */
for (size_t start = i; *scope != NULL; start = 0, ++scope) for (size_t start = i; *scope != NULL; start = 0, ++scope)
@ -341,9 +338,8 @@ _dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map,
&& add_dependency (undef_map, current_value.m) < 0) && add_dependency (undef_map, current_value.m) < 0)
/* Something went wrong. Perhaps the object we tried to reference /* Something went wrong. Perhaps the object we tried to reference
was just removed. Try finding another definition. */ was just removed. Try finding another definition. */
return _dl_lookup_symbol_x (undef_name, undef_map, ref, return _dl_lookup_symbol_x (undef_name, undef_map, ref, symbol_scope,
symbol_scope, version, type_class, version, type_class, flags, skip_map);
flags, skip_map);
/* The object is used. */ /* The object is used. */
current_value.m->l_used = 1; current_value.m->l_used = 1;
@ -449,10 +445,12 @@ _dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
conflict = 1; conflict = 1;
} }
# ifdef USE_TLS
if (value->s if (value->s
&& (__builtin_expect (ELFW(ST_TYPE) (value->s->st_info) && (__builtin_expect (ELFW(ST_TYPE) (value->s->st_info)
== STT_TLS, 0))) == STT_TLS, 0)))
type_class = 4; type_class = 4;
# endif
if (conflict if (conflict
|| GLRO(dl_trace_prelink_map) == undef_map || GLRO(dl_trace_prelink_map) == undef_map

View File

@ -1,5 +1,5 @@
/* Minimal replacements for basic facilities used in the dynamic linker. /* Minimal replacements for basic facilities used in the dynamic linker.
Copyright (C) 1995-1998,2000-2002,2004,2005,2006 Copyright (C) 1995-1998,2000-2002,2004-2006,2007
Free Software Foundation, Inc. Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
@ -75,14 +75,21 @@ __libc_memalign (size_t align, size_t n)
alloc_ptr = (void *) 0 + (((alloc_ptr - (void *) 0) + align - 1) alloc_ptr = (void *) 0 + (((alloc_ptr - (void *) 0) + align - 1)
& ~(align - 1)); & ~(align - 1));
if (alloc_ptr + n >= alloc_end) if (alloc_ptr + n >= alloc_end || n >= -(uintptr_t) alloc_ptr)
{ {
/* Insufficient space left; allocate another page. */ /* Insufficient space left; allocate another page. */
caddr_t page; caddr_t page;
size_t nup = (n + GLRO(dl_pagesize) - 1) & ~(GLRO(dl_pagesize) - 1); size_t nup = (n + GLRO(dl_pagesize) - 1) & ~(GLRO(dl_pagesize) - 1);
if (__builtin_expect (nup == 0, 0))
{
if (n)
return NULL;
nup = GLRO(dl_pagesize);
}
page = __mmap (0, nup, PROT_READ|PROT_WRITE, page = __mmap (0, nup, PROT_READ|PROT_WRITE,
MAP_ANON|MAP_PRIVATE, _dl_zerofd, 0); MAP_ANON|MAP_PRIVATE, _dl_zerofd, 0);
assert (page != MAP_FAILED); if (page == MAP_FAILED)
return NULL;
if (page != alloc_end) if (page != alloc_end)
alloc_ptr = page; alloc_ptr = page;
alloc_end = page + nup; alloc_end = page + nup;
@ -108,7 +115,14 @@ calloc (size_t nmemb, size_t size)
/* New memory from the trivial malloc above is always already cleared. /* New memory from the trivial malloc above is always already cleared.
(We make sure that's true in the rare occasion it might not be, (We make sure that's true in the rare occasion it might not be,
by clearing memory in free, below.) */ by clearing memory in free, below.) */
return malloc (nmemb * size); size_t bytes = nmemb * size;
#define HALF_SIZE_T (((size_t) 1) << (8 * sizeof (size_t) / 2))
if (__builtin_expect ((nmemb | size) >= HALF_SIZE_T, 0)
&& size != 0 && bytes / size != nmemb)
return NULL;
return malloc (bytes);
} }
/* This will rarely be called. */ /* This will rarely be called. */
@ -264,7 +278,7 @@ __strtoul_internal (const char *nptr, char **endptr, int base, int group)
while (*nptr >= '0' && *nptr <= '9') while (*nptr >= '0' && *nptr <= '9')
{ {
unsigned long int digval = *nptr - '0'; unsigned long int digval = *nptr - '0';
if (result > LONG_MAX / 10 if (result > ULONG_MAX / 10
|| (result == ULONG_MAX / 10 && digval > ULONG_MAX % 10)) || (result == ULONG_MAX / 10 && digval > ULONG_MAX % 10))
{ {
errno = ERANGE; errno = ERANGE;

View File

@ -1,5 +1,5 @@
/* Storage management for the chain of loaded shared objects. /* Storage management for the chain of loaded shared objects.
Copyright (C) 1995-2002, 2004, 2006 Free Software Foundation, Inc. Copyright (C) 1995-2002, 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -64,7 +64,7 @@ _dl_new_object (char *realname, const char *libname, int type,
new->l_name = realname; new->l_name = realname;
new->l_type = type; new->l_type = type;
new->l_loader = loader; new->l_loader = loader;
#if NO_TLS_OFFSET != 0 #if defined USE_TLS && NO_TLS_OFFSET != 0
new->l_tls_offset = NO_TLS_OFFSET; new->l_tls_offset = NO_TLS_OFFSET;
#endif #endif
new->l_ns = nsid; new->l_ns = nsid;
@ -85,11 +85,6 @@ _dl_new_object (char *realname, const char *libname, int type,
new->l_scope = new->l_scope_mem; new->l_scope = new->l_scope_mem;
new->l_scope_max = sizeof (new->l_scope_mem) / sizeof (new->l_scope_mem[0]); new->l_scope_max = sizeof (new->l_scope_mem) / sizeof (new->l_scope_mem[0]);
/* No need to initialize the scope lock if the initializer is zero. */
#if _RTLD_MRLOCK_INITIALIZER != 0
__rtld_mrlock_initialize (new->l_scope_lock);
#endif
/* Counter for the scopes we have to handle. */ /* Counter for the scopes we have to handle. */
idx = 0; idx = 0;

View File

@ -1,5 +1,5 @@
/* Load a shared object at runtime, relocate it, and run its initializer. /* Load a shared object at runtime, relocate it, and run its initializer.
Copyright (C) 1996-2004, 2005, 2006 Free Software Foundation, Inc. Copyright (C) 1996-2004, 2005, 2006, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -32,6 +32,7 @@
#include <bp-sym.h> #include <bp-sym.h>
#include <caller.h> #include <caller.h>
#include <sysdep-cancel.h> #include <sysdep-cancel.h>
#include <tls.h>
#include <dl-dst.h> #include <dl-dst.h>
@ -97,17 +98,17 @@ add_to_global (struct link_map *new)
in an realloc() call. Therefore we allocate a completely new in an realloc() call. Therefore we allocate a completely new
array the first time we have to add something to the locale scope. */ array the first time we have to add something to the locale scope. */
if (GL(dl_ns)[new->l_ns]._ns_global_scope_alloc == 0) struct link_namespaces *ns = &GL(dl_ns)[new->l_ns];
if (ns->_ns_global_scope_alloc == 0)
{ {
/* This is the first dynamic object given global scope. */ /* This is the first dynamic object given global scope. */
GL(dl_ns)[new->l_ns]._ns_global_scope_alloc ns->_ns_global_scope_alloc
= GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_nlist + to_add + 8; = ns->_ns_main_searchlist->r_nlist + to_add + 8;
new_global = (struct link_map **) new_global = (struct link_map **)
malloc (GL(dl_ns)[new->l_ns]._ns_global_scope_alloc malloc (ns->_ns_global_scope_alloc * sizeof (struct link_map *));
* sizeof (struct link_map *));
if (new_global == NULL) if (new_global == NULL)
{ {
GL(dl_ns)[new->l_ns]._ns_global_scope_alloc = 0; ns->_ns_global_scope_alloc = 0;
nomem: nomem:
_dl_signal_error (ENOMEM, new->l_libname->name, NULL, _dl_signal_error (ENOMEM, new->l_libname->name, NULL,
N_("cannot extend global scope")); N_("cannot extend global scope"));
@ -115,29 +116,39 @@ add_to_global (struct link_map *new)
} }
/* Copy over the old entries. */ /* Copy over the old entries. */
GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_list ns->_ns_main_searchlist->r_list
= memcpy (new_global, = memcpy (new_global, ns->_ns_main_searchlist->r_list,
GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_list, (ns->_ns_main_searchlist->r_nlist
(GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_nlist
* sizeof (struct link_map *))); * sizeof (struct link_map *)));
} }
else if (GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_nlist + to_add else if (ns->_ns_main_searchlist->r_nlist + to_add
> GL(dl_ns)[new->l_ns]._ns_global_scope_alloc) > ns->_ns_global_scope_alloc)
{ {
/* We have to extend the existing array of link maps in the /* We have to extend the existing array of link maps in the
main map. */ main map. */
struct link_map **old_global
= GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_list;
size_t new_nalloc = ((ns->_ns_global_scope_alloc + to_add) * 2);
new_global = (struct link_map **) new_global = (struct link_map **)
realloc (GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_list, malloc (new_nalloc * sizeof (struct link_map *));
((GL(dl_ns)[new->l_ns]._ns_global_scope_alloc + to_add + 8)
* sizeof (struct link_map *)));
if (new_global == NULL) if (new_global == NULL)
goto nomem; goto nomem;
GL(dl_ns)[new->l_ns]._ns_global_scope_alloc += to_add + 8; memcpy (new_global, old_global,
GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_list = new_global; ns->_ns_global_scope_alloc * sizeof (struct link_map *));
ns->_ns_global_scope_alloc = new_nalloc;
ns->_ns_main_searchlist->r_list = new_global;
if (!RTLD_SINGLE_THREAD_P)
THREAD_GSCOPE_WAIT ();
free (old_global);
} }
/* Now add the new entries. */ /* Now add the new entries. */
unsigned int new_nlist = ns->_ns_main_searchlist->r_nlist;
for (cnt = 0; cnt < new->l_searchlist.r_nlist; ++cnt) for (cnt = 0; cnt < new->l_searchlist.r_nlist; ++cnt)
{ {
struct link_map *map = new->l_searchlist.r_list[cnt]; struct link_map *map = new->l_searchlist.r_list[cnt];
@ -145,15 +156,49 @@ add_to_global (struct link_map *new)
if (map->l_global == 0) if (map->l_global == 0)
{ {
map->l_global = 1; map->l_global = 1;
GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_list[GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_nlist] ns->_ns_main_searchlist->r_list[new_nlist++] = map;
= map;
++GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_nlist;
} }
} }
atomic_write_barrier ();
ns->_ns_main_searchlist->r_nlist = new_nlist;
return 0; return 0;
} }
int
_dl_scope_free (struct r_scope_elem **old)
{
struct dl_scope_free_list *fsl;
#define DL_SCOPE_FREE_LIST_SIZE (sizeof (fsl->list) / sizeof (fsl->list[0]))
if (RTLD_SINGLE_THREAD_P)
free (old);
else if ((fsl = GL(dl_scope_free_list)) == NULL)
{
GL(dl_scope_free_list) = fsl = malloc (sizeof (*fsl));
if (fsl == NULL)
{
THREAD_GSCOPE_WAIT ();
free (old);
return 1;
}
else
{
fsl->list[0] = old;
fsl->count = 1;
}
}
else if (fsl->count < DL_SCOPE_FREE_LIST_SIZE)
fsl->list[fsl->count++] = old;
else
{
THREAD_GSCOPE_WAIT ();
while (fsl->count > 0)
free (fsl->list[--fsl->count]);
return 1;
}
return 0;
}
static void static void
dl_open_worker (void *a) dl_open_worker (void *a)
@ -161,10 +206,12 @@ dl_open_worker (void *a)
struct dl_open_args *args = a; struct dl_open_args *args = a;
const char *file = args->file; const char *file = args->file;
int mode = args->mode; int mode = args->mode;
struct link_map *new, *l; struct link_map *new;
int lazy; int lazy;
unsigned int i; unsigned int i;
#ifdef USE_TLS
bool any_tls = false; bool any_tls = false;
#endif
struct link_map *call_map = NULL; struct link_map *call_map = NULL;
/* Check whether _dl_open() has been called from a valid DSO. */ /* Check whether _dl_open() has been called from a valid DSO. */
@ -186,13 +233,14 @@ dl_open_worker (void *a)
By default we assume this is the main application. */ By default we assume this is the main application. */
call_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded; call_map = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
struct link_map *l;
for (Lmid_t ns = 0; ns < DL_NNS; ++ns) for (Lmid_t ns = 0; ns < DL_NNS; ++ns)
for (l = GL(dl_ns)[ns]._ns_loaded; l != NULL; l = l->l_next) for (l = GL(dl_ns)[ns]._ns_loaded; l != NULL; l = l->l_next)
if (caller_dlopen >= (const void *) l->l_map_start if (caller_dlopen >= (const void *) l->l_map_start
&& caller_dlopen < (const void *) l->l_map_end) && caller_dlopen < (const void *) l->l_map_end
&& (l->l_contiguous
|| _dl_addr_inside_object (l, (ElfW(Addr)) caller_dlopen)))
{ {
/* There must be exactly one DSO for the range of the virtual
memory. Otherwise something is really broken. */
assert (ns == l->l_ns); assert (ns == l->l_ns);
call_map = l; call_map = l;
goto found_caller; goto found_caller;
@ -325,7 +373,7 @@ dl_open_worker (void *a)
/* Relocate the objects loaded. We do this in reverse order so that copy /* Relocate the objects loaded. We do this in reverse order so that copy
relocs of earlier objects overwrite the data written by later objects. */ relocs of earlier objects overwrite the data written by later objects. */
l = new; struct link_map *l = new;
while (l->l_next) while (l->l_next)
l = l->l_next; l = l->l_next;
while (1) while (1)
@ -417,17 +465,10 @@ dl_open_worker (void *a)
memcpy (newp, imap->l_scope, cnt * sizeof (imap->l_scope[0])); memcpy (newp, imap->l_scope, cnt * sizeof (imap->l_scope[0]));
struct r_scope_elem **old = imap->l_scope; struct r_scope_elem **old = imap->l_scope;
if (RTLD_SINGLE_THREAD_P) imap->l_scope = newp;
imap->l_scope = newp;
else
{
__rtld_mrlock_change (imap->l_scope_lock);
imap->l_scope = newp;
__rtld_mrlock_done (imap->l_scope_lock);
}
if (old != imap->l_scope_mem) if (old != imap->l_scope_mem)
free (old); _dl_scope_free (old);
imap->l_scope_max = new_size; imap->l_scope_max = new_size;
} }
@ -439,6 +480,7 @@ dl_open_worker (void *a)
atomic_write_barrier (); atomic_write_barrier ();
imap->l_scope[cnt] = &new->l_searchlist; imap->l_scope[cnt] = &new->l_searchlist;
} }
#if USE_TLS
/* Only add TLS memory if this object is loaded now and /* Only add TLS memory if this object is loaded now and
therefore is not yet initialized. */ therefore is not yet initialized. */
else if (! imap->l_init_called else if (! imap->l_init_called
@ -453,11 +495,11 @@ dl_open_worker (void *a)
if (imap->l_need_tls_init) if (imap->l_need_tls_init)
{ {
imap->l_need_tls_init = 0; imap->l_need_tls_init = 0;
#ifdef SHARED # ifdef SHARED
/* Update the slot information data for at least the /* Update the slot information data for at least the
generation of the DSO we are allocating data for. */ generation of the DSO we are allocating data for. */
_dl_update_slotinfo (imap->l_tls_modid); _dl_update_slotinfo (imap->l_tls_modid);
#endif # endif
GL(dl_init_static_tls) (imap); GL(dl_init_static_tls) (imap);
assert (imap->l_need_tls_init == 0); assert (imap->l_need_tls_init == 0);
@ -466,12 +508,15 @@ dl_open_worker (void *a)
/* We have to bump the generation counter. */ /* We have to bump the generation counter. */
any_tls = true; any_tls = true;
} }
#endif
} }
#if USE_TLS
/* Bump the generation number if necessary. */ /* Bump the generation number if necessary. */
if (any_tls && __builtin_expect (++GL(dl_tls_generation) == 0, 0)) if (any_tls && __builtin_expect (++GL(dl_tls_generation) == 0, 0))
_dl_fatal_printf (N_("\ _dl_fatal_printf (N_("\
TLS generation counter wrapped! Please report this.")); TLS generation counter wrapped! Please report this."));
#endif
/* Run the initializer functions of new objects. */ /* Run the initializer functions of new objects. */
_dl_init (new, args->argc, args->argv, args->env); _dl_init (new, args->argc, args->argv, args->env);
@ -568,6 +613,7 @@ no more namespaces available for dlmopen()"));
state if relocation failed, for example. */ state if relocation failed, for example. */
if (args.map) if (args.map)
{ {
#ifdef USE_TLS
/* Maybe some of the modules which were loaded use TLS. /* Maybe some of the modules which were loaded use TLS.
Since it will be removed in the following _dl_close call Since it will be removed in the following _dl_close call
we have to mark the dtv array as having gaps to fill the we have to mark the dtv array as having gaps to fill the
@ -577,6 +623,7 @@ no more namespaces available for dlmopen()"));
up. */ up. */
if ((mode & __RTLD_AUDIT) == 0) if ((mode & __RTLD_AUDIT) == 0)
GL(dl_tls_dtv_gaps) = true; GL(dl_tls_dtv_gaps) = true;
#endif
_dl_close_worker (args.map); _dl_close_worker (args.map);
} }
@ -650,3 +697,21 @@ show_scope (struct link_map *new)
} }
} }
#endif #endif
#ifdef IS_IN_rtld
/* Return non-zero if ADDR lies within one of L's segments. */
int
internal_function
_dl_addr_inside_object (struct link_map *l, const ElfW(Addr) addr)
{
int n = l->l_phnum;
const ElfW(Addr) reladdr = addr - l->l_addr;
while (--n >= 0)
if (l->l_phdr[n].p_type == PT_LOAD
&& reladdr - l->l_phdr[n].p_vaddr >= 0
&& reladdr - l->l_phdr[n].p_vaddr < l->l_phdr[n].p_memsz)
return 1;
return 0;
}
#endif

View File

@ -1,5 +1,5 @@
/* Profiling of shared libraries. /* Profiling of shared libraries.
Copyright (C) 1997-2002, 2003, 2004, 2006 Free Software Foundation, Inc. Copyright (C) 1997-2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
Based on the BSD mcount implementation. Based on the BSD mcount implementation.
@ -509,24 +509,24 @@ _dl_mcount (ElfW(Addr) frompc, ElfW(Addr) selfpc)
size_t newfromidx; size_t newfromidx;
to_index = (data[narcs].self_pc to_index = (data[narcs].self_pc
/ (HASHFRACTION * sizeof (*tos))); / (HASHFRACTION * sizeof (*tos)));
newfromidx = catomic_exchange_and_add (&fromidx, 1) + 1; newfromidx = atomic_exchange_and_add (&fromidx, 1) + 1;
froms[newfromidx].here = &data[narcs]; froms[newfromidx].here = &data[narcs];
froms[newfromidx].link = tos[to_index]; froms[newfromidx].link = tos[to_index];
tos[to_index] = newfromidx; tos[to_index] = newfromidx;
catomic_increment (&narcs); atomic_increment (&narcs);
} }
/* If we still have no entry stop searching and insert. */ /* If we still have no entry stop searching and insert. */
if (*topcindex == 0) if (*topcindex == 0)
{ {
uint_fast32_t newarc = catomic_exchange_and_add (narcsp, 1); uint_fast32_t newarc = atomic_exchange_and_add (narcsp, 1);
/* In rare cases it could happen that all entries in FROMS are /* In rare cases it could happen that all entries in FROMS are
occupied. So we cannot count this anymore. */ occupied. So we cannot count this anymore. */
if (newarc >= fromlimit) if (newarc >= fromlimit)
goto done; goto done;
*topcindex = catomic_exchange_and_add (&fromidx, 1) + 1; *topcindex = atomic_exchange_and_add (&fromidx, 1) + 1;
fromp = &froms[*topcindex]; fromp = &froms[*topcindex];
fromp->here = &data[newarc]; fromp->here = &data[newarc];
@ -534,7 +534,7 @@ _dl_mcount (ElfW(Addr) frompc, ElfW(Addr) selfpc)
data[newarc].self_pc = selfpc; data[newarc].self_pc = selfpc;
data[newarc].count = 0; data[newarc].count = 0;
fromp->link = 0; fromp->link = 0;
catomic_increment (&narcs); atomic_increment (&narcs);
break; break;
} }
@ -547,7 +547,7 @@ _dl_mcount (ElfW(Addr) frompc, ElfW(Addr) selfpc)
} }
/* Increment the counter. */ /* Increment the counter. */
catomic_increment (&fromp->here->count); atomic_increment (&fromp->here->count);
done: done:
; ;

View File

@ -1,5 +1,5 @@
/* Relocate a shared object and resolve its references to other loaded objects. /* Relocate a shared object and resolve its references to other loaded objects.
Copyright (C) 1995-2004, 2005, 2006 Free Software Foundation, Inc. Copyright (C) 1995-2004, 2005 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -35,6 +35,7 @@
#endif #endif
#ifdef USE_TLS
/* We are trying to perform a static TLS relocation in MAP, but it was /* We are trying to perform a static TLS relocation in MAP, but it was
dynamically loaded. This can only work if there is enough surplus in dynamically loaded. This can only work if there is enough surplus in
the static TLS area already allocated for each running thread. If this the static TLS area already allocated for each running thread. If this
@ -55,7 +56,7 @@ _dl_allocate_static_tls (struct link_map *map)
cannot allocate memory in static TLS block")); cannot allocate memory in static TLS block"));
} }
#if TLS_TCB_AT_TP # if TLS_TCB_AT_TP
size_t freebytes; size_t freebytes;
size_t n; size_t n;
size_t blsize; size_t blsize;
@ -72,7 +73,7 @@ cannot allocate memory in static TLS block"));
- map->l_tls_firstbyte_offset); - map->l_tls_firstbyte_offset);
map->l_tls_offset = GL(dl_tls_static_used) = offset; map->l_tls_offset = GL(dl_tls_static_used) = offset;
#elif TLS_DTV_AT_TP # elif TLS_DTV_AT_TP
size_t used; size_t used;
size_t check; size_t check;
@ -86,9 +87,9 @@ cannot allocate memory in static TLS block"));
map->l_tls_offset = offset; map->l_tls_offset = offset;
GL(dl_tls_static_used) = used; GL(dl_tls_static_used) = used;
#else # else
# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined" # error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
#endif # endif
/* If the object is not yet relocated we cannot initialize the /* If the object is not yet relocated we cannot initialize the
static TLS region. Delay it. */ static TLS region. Delay it. */
@ -114,13 +115,13 @@ cannot allocate memory in static TLS block"));
void void
_dl_nothread_init_static_tls (struct link_map *map) _dl_nothread_init_static_tls (struct link_map *map)
{ {
#if TLS_TCB_AT_TP # if TLS_TCB_AT_TP
void *dest = (char *) THREAD_SELF - map->l_tls_offset; void *dest = (char *) THREAD_SELF - map->l_tls_offset;
#elif TLS_DTV_AT_TP # elif TLS_DTV_AT_TP
void *dest = (char *) THREAD_SELF + map->l_tls_offset + TLS_PRE_TCB_SIZE; void *dest = (char *) THREAD_SELF + map->l_tls_offset + TLS_PRE_TCB_SIZE;
#else # else
# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined" # error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
#endif # endif
/* Fill in the DTV slot so that a later LD/GD access will find it. */ /* Fill in the DTV slot so that a later LD/GD access will find it. */
dtv_t *dtv = THREAD_DTV (); dtv_t *dtv = THREAD_DTV ();
@ -132,6 +133,7 @@ _dl_nothread_init_static_tls (struct link_map *map)
memset (__mempcpy (dest, map->l_tls_initimage, map->l_tls_initimage_size), memset (__mempcpy (dest, map->l_tls_initimage, map->l_tls_initimage_size),
'\0', map->l_tls_blocksize - map->l_tls_initimage_size); '\0', map->l_tls_blocksize - map->l_tls_initimage_size);
} }
#endif
void void

View File

@ -1,5 +1,5 @@
/* On-demand PLT fixup for shared objects. /* On-demand PLT fixup for shared objects.
Copyright (C) 1995-2002,2003,2004,2005,2006 Free Software Foundation, Inc. Copyright (C) 1995-2006, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -26,6 +26,8 @@
#include <ldsodefs.h> #include <ldsodefs.h>
#include <sysdep-cancel.h> #include <sysdep-cancel.h>
#include "dynamic-link.h" #include "dynamic-link.h"
#include <tls.h>
#if (!defined ELF_MACHINE_NO_RELA && !defined ELF_MACHINE_PLT_REL) \ #if (!defined ELF_MACHINE_NO_RELA && !defined ELF_MACHINE_PLT_REL) \
|| ELF_MACHINE_NO_REL || ELF_MACHINE_NO_REL
@ -93,15 +95,19 @@ _dl_fixup (
version = NULL; version = NULL;
} }
if (l->l_type == lt_loaded && !RTLD_SINGLE_THREAD_P) /* We need to keep the scope around so do some locking. This is
__rtld_mrlock_lock (l->l_scope_lock); not necessary for objects which cannot be unloaded or when
we are not using any threads (yet). */
int flags = DL_LOOKUP_ADD_DEPENDENCY;
if (!RTLD_SINGLE_THREAD_P)
THREAD_GSCOPE_SET_FLAG ();
result = _dl_lookup_symbol_x (strtab + sym->st_name, l, &sym, result = _dl_lookup_symbol_x (strtab + sym->st_name, l, &sym, l->l_scope,
l->l_scope, version, ELF_RTYPE_CLASS_PLT, version, ELF_RTYPE_CLASS_PLT, flags, NULL);
DL_LOOKUP_ADD_DEPENDENCY, NULL);
if (l->l_type == lt_loaded && !RTLD_SINGLE_THREAD_P) /* We are done with the global scope. */
__rtld_mrlock_unlock (l->l_scope_lock); if (!RTLD_SINGLE_THREAD_P)
THREAD_GSCOPE_RESET_FLAG ();
/* Currently result contains the base load address (or link map) /* Currently result contains the base load address (or link map)
of the object that defines sym. Now add in the symbol of the object that defines sym. Now add in the symbol
@ -181,16 +187,20 @@ _dl_profile_fixup (
version = NULL; version = NULL;
} }
if (l->l_type == lt_loaded && !RTLD_SINGLE_THREAD_P) /* We need to keep the scope around so do some locking. This is
__rtld_mrlock_lock (l->l_scope_lock); not necessary for objects which cannot be unloaded or when
we are not using any threads (yet). */
int flags = DL_LOOKUP_ADD_DEPENDENCY;
if (!RTLD_SINGLE_THREAD_P)
THREAD_GSCOPE_SET_FLAG ();
result = _dl_lookup_symbol_x (strtab + refsym->st_name, l, &defsym, result = _dl_lookup_symbol_x (strtab + refsym->st_name, l,
l->l_scope, version, &defsym, l->l_scope, version,
ELF_RTYPE_CLASS_PLT, ELF_RTYPE_CLASS_PLT, flags, NULL);
DL_LOOKUP_ADD_DEPENDENCY, NULL);
if (l->l_type == lt_loaded && !RTLD_SINGLE_THREAD_P) /* We are done with the global scope. */
__rtld_mrlock_unlock (l->l_scope_lock); if (!RTLD_SINGLE_THREAD_P)
THREAD_GSCOPE_RESET_FLAG ();
/* Currently result contains the base load address (or link map) /* Currently result contains the base load address (or link map)
of the object that defines sym. Now add in the symbol of the object that defines sym. Now add in the symbol

View File

@ -1,5 +1,5 @@
/* Support for dynamic linking code in static libc. /* Support for dynamic linking code in static libc.
Copyright (C) 1996-2005, 2006 Free Software Foundation, Inc. Copyright (C) 1996-2005, 2006, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -98,7 +98,9 @@ int _dl_starting_up = 1;
hp_timing_t _dl_cpuclock_offset; hp_timing_t _dl_cpuclock_offset;
#endif #endif
#ifdef USE_TLS
void (*_dl_init_static_tls) (struct link_map *) = &_dl_nothread_init_static_tls; void (*_dl_init_static_tls) (struct link_map *) = &_dl_nothread_init_static_tls;
#endif
size_t _dl_pagesize; size_t _dl_pagesize;
@ -132,6 +134,11 @@ int (*_dl_make_stack_executable_hook) (void **) internal_function
= _dl_make_stack_executable; = _dl_make_stack_executable;
/* Function in libpthread to wait for termination of lookups. */
void (*_dl_wait_lookup_done) (void);
struct dl_scope_free_list *_dl_scope_free_list;
#ifdef NEED_DL_SYSINFO #ifdef NEED_DL_SYSINFO
/* Needed for improved syscall handling on at least x86/Linux. */ /* Needed for improved syscall handling on at least x86/Linux. */
uintptr_t _dl_sysinfo = DL_SYSINFO_DEFAULT; uintptr_t _dl_sysinfo = DL_SYSINFO_DEFAULT;

View File

@ -1,5 +1,5 @@
/* Look up a symbol in a shared object loaded by `dlopen'. /* Look up a symbol in a shared object loaded by `dlopen'.
Copyright (C) 1999,2000,2001,2002,2004,2006 Free Software Foundation, Inc. Copyright (C) 1999-2002,2004,2006,2007 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -26,10 +26,12 @@
#include <ldsodefs.h> #include <ldsodefs.h>
#include <dl-hash.h> #include <dl-hash.h>
#include <sysdep-cancel.h> #include <sysdep-cancel.h>
#include <dl-tls.h> #ifdef USE_TLS
# include <dl-tls.h>
#endif
#ifdef SHARED #if defined USE_TLS && defined SHARED
/* Systems which do not have tls_index also probably have to define /* Systems which do not have tls_index also probably have to define
DONT_USE_TLS_INDEX. */ DONT_USE_TLS_INDEX. */
@ -98,10 +100,9 @@ do_sym (void *handle, const char *name, void *who,
for (Lmid_t ns = 0; ns < DL_NNS; ++ns) for (Lmid_t ns = 0; ns < DL_NNS; ++ns)
for (struct link_map *l = GL(dl_ns)[ns]._ns_loaded; l != NULL; for (struct link_map *l = GL(dl_ns)[ns]._ns_loaded; l != NULL;
l = l->l_next) l = l->l_next)
if (caller >= l->l_map_start && caller < l->l_map_end) if (caller >= l->l_map_start && caller < l->l_map_end
&& (l->l_contiguous || _dl_addr_inside_object (l, caller)))
{ {
/* There must be exactly one DSO for the range of the virtual
memory. Otherwise something is really broken. */
match = l; match = l;
break; break;
} }
@ -113,15 +114,13 @@ do_sym (void *handle, const char *name, void *who,
the initial binary. And then the more complex part the initial binary. And then the more complex part
where the object is dynamically loaded and the scope where the object is dynamically loaded and the scope
array can change. */ array can change. */
if (match->l_type != lt_loaded || RTLD_SINGLE_THREAD_P) if (RTLD_SINGLE_THREAD_P)
result = GLRO(dl_lookup_symbol_x) (name, match, &ref, result = GLRO(dl_lookup_symbol_x) (name, match, &ref,
match->l_scope, vers, 0, match->l_scope, vers, 0,
flags | DL_LOOKUP_ADD_DEPENDENCY, flags | DL_LOOKUP_ADD_DEPENDENCY,
NULL); NULL);
else else
{ {
__rtld_mrlock_lock (match->l_scope_lock);
struct call_dl_lookup_args args; struct call_dl_lookup_args args;
args.name = name; args.name = name;
args.map = match; args.map = match;
@ -129,13 +128,15 @@ do_sym (void *handle, const char *name, void *who,
args.flags = flags | DL_LOOKUP_ADD_DEPENDENCY; args.flags = flags | DL_LOOKUP_ADD_DEPENDENCY;
args.refp = &ref; args.refp = &ref;
THREAD_GSCOPE_SET_FLAG ();
const char *objname; const char *objname;
const char *errstring = NULL; const char *errstring = NULL;
bool malloced; bool malloced;
int err = GLRO(dl_catch_error) (&objname, &errstring, &malloced, int err = GLRO(dl_catch_error) (&objname, &errstring, &malloced,
call_dl_lookup, &args); call_dl_lookup, &args);
__rtld_mrlock_unlock (match->l_scope_lock); THREAD_GSCOPE_RESET_FLAG ();
if (__builtin_expect (errstring != NULL, 0)) if (__builtin_expect (errstring != NULL, 0))
{ {
@ -182,7 +183,7 @@ RTLD_NEXT used in code not dynamically loaded"));
{ {
void *value; void *value;
#ifdef SHARED #if defined USE_TLS && defined SHARED
if (ELFW(ST_TYPE) (ref->st_info) == STT_TLS) if (ELFW(ST_TYPE) (ref->st_info) == STT_TLS)
/* The found symbol is a thread-local storage variable. /* The found symbol is a thread-local storage variable.
Return the address for to the current thread. */ Return the address for to the current thread. */

View File

@ -1,5 +1,5 @@
/* Operating system support for run-time dynamic linker. Generic Unix version. /* Operating system support for run-time dynamic linker. Generic Unix version.
Copyright (C) 1995-1998, 2000-2005, 2006 Free Software Foundation, Inc. Copyright (C) 1995-1998, 2000-2005, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -405,8 +405,25 @@ _dl_important_hwcaps (const char *platform, size_t platform_len, size_t *sz,
} }
#endif #endif
#ifdef USE_TLS
/* For TLS enabled builds always add 'tls'. */ /* For TLS enabled builds always add 'tls'. */
++cnt; ++cnt;
#else
if (cnt == 0)
{
/* If we no have platform name and no important capability we only
have the base directory to search. */
result = (struct r_strlenpair *) malloc (sizeof (*result));
if (result == NULL)
goto no_memory;
result[0].str = (char *) result; /* Does not really matter. */
result[0].len = 0;
*sz = 1;
return result;
}
#endif
/* Create temporary data structure to generate result table. */ /* Create temporary data structure to generate result table. */
temp = (struct r_strlenpair *) alloca (cnt * sizeof (*temp)); temp = (struct r_strlenpair *) alloca (cnt * sizeof (*temp));
@ -448,11 +465,11 @@ _dl_important_hwcaps (const char *platform, size_t platform_len, size_t *sz,
temp[m].len = platform_len; temp[m].len = platform_len;
++m; ++m;
} }
#ifdef USE_TLS
temp[m].str = "tls"; temp[m].str = "tls";
temp[m].len = 3; temp[m].len = 3;
++m; ++m;
#endif
assert (m == cnt); assert (m == cnt);
/* Determine the total size of all strings together. */ /* Determine the total size of all strings together. */
@ -460,9 +477,21 @@ _dl_important_hwcaps (const char *platform, size_t platform_len, size_t *sz,
total = temp[0].len + 1; total = temp[0].len + 1;
else else
{ {
total = (1UL << (cnt - 2)) * (temp[0].len + temp[cnt - 1].len + 2); total = temp[0].len + temp[cnt - 1].len + 2;
for (n = 1; n + 1 < cnt; ++n) if (cnt > 2)
total += (1UL << (cnt - 3)) * (temp[n].len + 1); {
total <<= 1;
for (n = 1; n + 1 < cnt; ++n)
total += temp[n].len + 1;
if (cnt > 3
&& (cnt >= sizeof (size_t) * 8
|| total + (sizeof (*result) << 3)
>= (1UL << (sizeof (size_t) * 8 - cnt + 3))))
_dl_signal_error (ENOMEM, NULL, NULL,
N_("cannot create capability list"));
total <<= cnt - 3;
}
} }
/* The result structure: we use a very compressed way to store the /* The result structure: we use a very compressed way to store the
@ -470,8 +499,13 @@ _dl_important_hwcaps (const char *platform, size_t platform_len, size_t *sz,
*sz = 1 << cnt; *sz = 1 << cnt;
result = (struct r_strlenpair *) malloc (*sz * sizeof (*result) + total); result = (struct r_strlenpair *) malloc (*sz * sizeof (*result) + total);
if (result == NULL) if (result == NULL)
_dl_signal_error (ENOMEM, NULL, NULL, {
N_("cannot create capability list")); #ifndef USE_TLS
no_memory:
#endif
_dl_signal_error (ENOMEM, NULL, NULL,
N_("cannot create capability list"));
}
if (cnt == 1) if (cnt == 1)
{ {

View File

@ -26,26 +26,30 @@
#include <sys/param.h> #include <sys/param.h>
#include <tls.h> #include <tls.h>
#include <dl-tls.h>
#include <ldsodefs.h> /* We don't need any of this if TLS is not supported. */
#ifdef USE_TLS
# include <dl-tls.h>
# include <ldsodefs.h>
/* Amount of excess space to allocate in the static TLS area /* Amount of excess space to allocate in the static TLS area
to allow dynamic loading of modules defining IE-model TLS data. */ to allow dynamic loading of modules defining IE-model TLS data. */
#define TLS_STATIC_SURPLUS 64 + DL_NNS * 100 # define TLS_STATIC_SURPLUS 64 + DL_NNS * 100
/* Value used for dtv entries for which the allocation is delayed. */ /* Value used for dtv entries for which the allocation is delayed. */
#define TLS_DTV_UNALLOCATED ((void *) -1l) # define TLS_DTV_UNALLOCATED ((void *) -1l)
/* Out-of-memory handler. */ /* Out-of-memory handler. */
#ifdef SHARED # ifdef SHARED
static void static void
__attribute__ ((__noreturn__)) __attribute__ ((__noreturn__))
oom (void) oom (void)
{ {
_dl_fatal_printf ("cannot allocate memory for thread-local data: ABORT\n"); _dl_fatal_printf ("cannot allocate memory for thread-local data: ABORT\n");
} }
#endif # endif
size_t size_t
@ -109,7 +113,7 @@ _dl_next_tls_modid (void)
} }
#ifdef SHARED # ifdef SHARED
void void
internal_function internal_function
_dl_determine_tlsoffset (void) _dl_determine_tlsoffset (void)
@ -154,7 +158,7 @@ _dl_determine_tlsoffset (void)
memory requirement for the next TLS block is smaller than the memory requirement for the next TLS block is smaller than the
gap. */ gap. */
#if TLS_TCB_AT_TP # if TLS_TCB_AT_TP
/* We simply start with zero. */ /* We simply start with zero. */
size_t offset = 0; size_t offset = 0;
@ -201,7 +205,7 @@ _dl_determine_tlsoffset (void)
GL(dl_tls_static_used) = offset; GL(dl_tls_static_used) = offset;
GL(dl_tls_static_size) = (roundup (offset + TLS_STATIC_SURPLUS, max_align) GL(dl_tls_static_size) = (roundup (offset + TLS_STATIC_SURPLUS, max_align)
+ TLS_TCB_SIZE); + TLS_TCB_SIZE);
#elif TLS_DTV_AT_TP # elif TLS_DTV_AT_TP
/* The TLS blocks start right after the TCB. */ /* The TLS blocks start right after the TCB. */
size_t offset = TLS_TCB_SIZE; size_t offset = TLS_TCB_SIZE;
@ -245,9 +249,9 @@ _dl_determine_tlsoffset (void)
GL(dl_tls_static_used) = offset; GL(dl_tls_static_used) = offset;
GL(dl_tls_static_size) = roundup (offset + TLS_STATIC_SURPLUS, GL(dl_tls_static_size) = roundup (offset + TLS_STATIC_SURPLUS,
TLS_TCB_ALIGN); TLS_TCB_ALIGN);
#else # else
# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined" # error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
#endif # endif
/* The alignment requirement for the static TLS block. */ /* The alignment requirement for the static TLS block. */
GL(dl_tls_static_align) = max_align; GL(dl_tls_static_align) = max_align;
@ -284,7 +288,7 @@ _dl_tls_setup (void)
return 0; return 0;
} }
rtld_hidden_def (_dl_tls_setup) rtld_hidden_def (_dl_tls_setup)
#endif # endif
static void * static void *
internal_function internal_function
@ -333,13 +337,13 @@ _dl_allocate_tls_storage (void)
void *result; void *result;
size_t size = GL(dl_tls_static_size); size_t size = GL(dl_tls_static_size);
#if TLS_DTV_AT_TP # if TLS_DTV_AT_TP
/* Memory layout is: /* Memory layout is:
[ TLS_PRE_TCB_SIZE ] [ TLS_TCB_SIZE ] [ TLS blocks ] [ TLS_PRE_TCB_SIZE ] [ TLS_TCB_SIZE ] [ TLS blocks ]
^ This should be returned. */ ^ This should be returned. */
size += (TLS_PRE_TCB_SIZE + GL(dl_tls_static_align) - 1) size += (TLS_PRE_TCB_SIZE + GL(dl_tls_static_align) - 1)
& ~(GL(dl_tls_static_align) - 1); & ~(GL(dl_tls_static_align) - 1);
#endif # endif
/* Allocate a correctly aligned chunk of memory. */ /* Allocate a correctly aligned chunk of memory. */
result = __libc_memalign (GL(dl_tls_static_align), size); result = __libc_memalign (GL(dl_tls_static_align), size);
@ -348,14 +352,14 @@ _dl_allocate_tls_storage (void)
/* Allocate the DTV. */ /* Allocate the DTV. */
void *allocated = result; void *allocated = result;
#if TLS_TCB_AT_TP # if TLS_TCB_AT_TP
/* The TCB follows the TLS blocks. */ /* The TCB follows the TLS blocks. */
result = (char *) result + size - TLS_TCB_SIZE; result = (char *) result + size - TLS_TCB_SIZE;
/* Clear the TCB data structure. We can't ask the caller (i.e. /* Clear the TCB data structure. We can't ask the caller (i.e.
libpthread) to do it, because we will initialize the DTV et al. */ libpthread) to do it, because we will initialize the DTV et al. */
memset (result, '\0', TLS_TCB_SIZE); memset (result, '\0', TLS_TCB_SIZE);
#elif TLS_DTV_AT_TP # elif TLS_DTV_AT_TP
result = (char *) result + size - GL(dl_tls_static_size); result = (char *) result + size - GL(dl_tls_static_size);
/* Clear the TCB data structure and TLS_PRE_TCB_SIZE bytes before it. /* Clear the TCB data structure and TLS_PRE_TCB_SIZE bytes before it.
@ -363,7 +367,7 @@ _dl_allocate_tls_storage (void)
initialize the DTV et al. */ initialize the DTV et al. */
memset ((char *) result - TLS_PRE_TCB_SIZE, '\0', memset ((char *) result - TLS_PRE_TCB_SIZE, '\0',
TLS_PRE_TCB_SIZE + TLS_TCB_SIZE); TLS_PRE_TCB_SIZE + TLS_TCB_SIZE);
#endif # endif
result = allocate_dtv (result); result = allocate_dtv (result);
if (result == NULL) if (result == NULL)
@ -424,14 +428,14 @@ _dl_allocate_tls_init (void *result)
assert (map->l_tls_modid == cnt); assert (map->l_tls_modid == cnt);
assert (map->l_tls_blocksize >= map->l_tls_initimage_size); assert (map->l_tls_blocksize >= map->l_tls_initimage_size);
#if TLS_TCB_AT_TP # if TLS_TCB_AT_TP
assert ((size_t) map->l_tls_offset >= map->l_tls_blocksize); assert ((size_t) map->l_tls_offset >= map->l_tls_blocksize);
dest = (char *) result - map->l_tls_offset; dest = (char *) result - map->l_tls_offset;
#elif TLS_DTV_AT_TP # elif TLS_DTV_AT_TP
dest = (char *) result + map->l_tls_offset; dest = (char *) result + map->l_tls_offset;
#else # else
# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined" # error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
#endif # endif
/* Copy the initialization image and clear the BSS part. */ /* Copy the initialization image and clear the BSS part. */
dtv[map->l_tls_modid].pointer.val = dest; dtv[map->l_tls_modid].pointer.val = dest;
@ -487,21 +491,21 @@ _dl_deallocate_tls (void *tcb, bool dealloc_tcb)
if (dealloc_tcb) if (dealloc_tcb)
{ {
#if TLS_TCB_AT_TP # if TLS_TCB_AT_TP
/* The TCB follows the TLS blocks. Back up to free the whole block. */ /* The TCB follows the TLS blocks. Back up to free the whole block. */
tcb -= GL(dl_tls_static_size) - TLS_TCB_SIZE; tcb -= GL(dl_tls_static_size) - TLS_TCB_SIZE;
#elif TLS_DTV_AT_TP # elif TLS_DTV_AT_TP
/* Back up the TLS_PRE_TCB_SIZE bytes. */ /* Back up the TLS_PRE_TCB_SIZE bytes. */
tcb -= (TLS_PRE_TCB_SIZE + GL(dl_tls_static_align) - 1) tcb -= (TLS_PRE_TCB_SIZE + GL(dl_tls_static_align) - 1)
& ~(GL(dl_tls_static_align) - 1); & ~(GL(dl_tls_static_align) - 1);
#endif # endif
free (tcb); free (tcb);
} }
} }
rtld_hidden_def (_dl_deallocate_tls) rtld_hidden_def (_dl_deallocate_tls)
#ifdef SHARED # ifdef SHARED
/* The __tls_get_addr function has two basic forms which differ in the /* The __tls_get_addr function has two basic forms which differ in the
arguments. The IA-64 form takes two parameters, the module ID and arguments. The IA-64 form takes two parameters, the module ID and
offset. The form used, among others, on IA-32 takes a reference to offset. The form used, among others, on IA-32 takes a reference to
@ -509,15 +513,15 @@ rtld_hidden_def (_dl_deallocate_tls)
form seems to be more often used (in the moment) so we default to form seems to be more often used (in the moment) so we default to
it. Users of the IA-64 form have to provide adequate definitions it. Users of the IA-64 form have to provide adequate definitions
of the following macros. */ of the following macros. */
# ifndef GET_ADDR_ARGS # ifndef GET_ADDR_ARGS
# define GET_ADDR_ARGS tls_index *ti # define GET_ADDR_ARGS tls_index *ti
# endif # endif
# ifndef GET_ADDR_MODULE # ifndef GET_ADDR_MODULE
# define GET_ADDR_MODULE ti->ti_module # define GET_ADDR_MODULE ti->ti_module
# endif # endif
# ifndef GET_ADDR_OFFSET # ifndef GET_ADDR_OFFSET
# define GET_ADDR_OFFSET ti->ti_offset # define GET_ADDR_OFFSET ti->ti_offset
# endif # endif
static void * static void *
@ -728,7 +732,7 @@ __tls_get_addr (GET_ADDR_ARGS)
return (char *) p + GET_ADDR_OFFSET; return (char *) p + GET_ADDR_OFFSET;
} }
#endif # endif
/* Look up the module's TLS block as for __tls_get_addr, /* Look up the module's TLS block as for __tls_get_addr,
@ -836,3 +840,4 @@ cannot create TLS data structures"));
listp->slotinfo[idx].map = l; listp->slotinfo[idx].map = l;
listp->slotinfo[idx].gen = GL(dl_tls_generation) + 1; listp->slotinfo[idx].gen = GL(dl_tls_generation) + 1;
} }
#endif /* use TLS */

View File

@ -1,5 +1,5 @@
/* Look up a symbol in the loaded objects. /* Look up a symbol in the loaded objects.
Copyright (C) 1995-2004, 2005, 2006 Free Software Foundation, Inc. Copyright (C) 1995-2004, 2005, 2006, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -29,8 +29,13 @@ do_lookup_x (const char *undef_name, uint_fast32_t new_hash,
const struct r_found_version *const version, int flags, const struct r_found_version *const version, int flags,
struct link_map *skip, int type_class) struct link_map *skip, int type_class)
{ {
struct link_map **list = scope->r_list;
size_t n = scope->r_nlist; size_t n = scope->r_nlist;
/* Make sure we read the value before proceeding. Otherwise we
might use r_list pointing to the initial scope and r_nlist being
the value after a resize. That is the only path in dl-open.c not
protected by GSCOPE. A read barrier here might be to expensive. */
__asm volatile ("" : "+r" (n), "+m" (scope->r_list));
struct link_map **list = scope->r_list;
do do
{ {

View File

@ -1,5 +1,5 @@
/* This file defines standard ELF types, structures, and macros. /* This file defines standard ELF types, structures, and macros.
Copyright (C) 1995-2003,2004,2005,2006,2007 Free Software Foundation, Inc. Copyright (C) 1995-2003,2004,2005,2006 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -1511,9 +1511,8 @@ typedef struct
#define R_MIPS_TLS_TPREL64 48 /* TP-relative offset, 64 bit */ #define R_MIPS_TLS_TPREL64 48 /* TP-relative offset, 64 bit */
#define R_MIPS_TLS_TPREL_HI16 49 /* TP-relative offset, high 16 bits */ #define R_MIPS_TLS_TPREL_HI16 49 /* TP-relative offset, high 16 bits */
#define R_MIPS_TLS_TPREL_LO16 50 /* TP-relative offset, low 16 bits */ #define R_MIPS_TLS_TPREL_LO16 50 /* TP-relative offset, low 16 bits */
#define R_MIPS_GLOB_DAT 51
/* Keep this the last entry. */ /* Keep this the last entry. */
#define R_MIPS_NUM 52 #define R_MIPS_NUM 51
/* Legal values for p_type field of Elf32_Phdr. */ /* Legal values for p_type field of Elf32_Phdr. */

View File

@ -24,7 +24,6 @@
#include <errno.h> #include <errno.h>
#include <inttypes.h> #include <inttypes.h>
#include <libintl.h> #include <libintl.h>
#include <locale.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include <stdio_ext.h> #include <stdio_ext.h>
@ -287,7 +286,7 @@ print_version (FILE *stream, struct argp_state *state)
Copyright (C) %s Free Software Foundation, Inc.\n\ Copyright (C) %s Free Software Foundation, Inc.\n\
This is free software; see the source for copying conditions. There is NO\n\ This is free software; see the source for copying conditions. There is NO\n\
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
"), "2007"); "), "2006");
fprintf (stream, gettext ("Written by %s.\n"), fprintf (stream, gettext ("Written by %s.\n"),
"Andreas Jaeger"); "Andreas Jaeger");
} }
@ -559,7 +558,7 @@ manual_link (char *library)
/* Do some sanity checks first. */ /* Do some sanity checks first. */
if (lstat64 (real_library, &stat_buf)) if (lstat64 (real_library, &stat_buf))
{ {
error (0, errno, _("Cannot lstat %s"), library); error (0, errno, _("Can't lstat %s"), library);
free (path); free (path);
return; return;
} }
@ -707,10 +706,10 @@ search_dir (const struct dir_entry *entry)
+ 1, ".#prelink#.", sizeof (".#prelink#.") - 1) == 0) + 1, ".#prelink#.", sizeof (".#prelink#.") - 1) == 0)
continue; continue;
} }
len += strlen (entry->path); len += strlen (entry->path) + 2;
if (len > file_name_len) if (len > file_name_len)
{ {
file_name_len = len + 1; file_name_len = len;
file_name = alloca (file_name_len); file_name = alloca (file_name_len);
if (!opt_chroot) if (!opt_chroot)
real_file_name = file_name; real_file_name = file_name;
@ -718,10 +717,10 @@ search_dir (const struct dir_entry *entry)
sprintf (file_name, "%s/%s", entry->path, direntry->d_name); sprintf (file_name, "%s/%s", entry->path, direntry->d_name);
if (opt_chroot) if (opt_chroot)
{ {
len = strlen (dir_name) + strlen (direntry->d_name); len = strlen (dir_name) + strlen (direntry->d_name) + 2;
if (len > real_file_name_len) if (len > real_file_name_len)
{ {
real_file_name_len = len + 1; real_file_name_len = len;
real_file_name = alloca (real_file_name_len); real_file_name = alloca (real_file_name_len);
} }
sprintf (real_file_name, "%s/%s", dir_name, direntry->d_name); sprintf (real_file_name, "%s/%s", dir_name, direntry->d_name);
@ -1167,14 +1166,9 @@ set_hwcap (void)
int int
main (int argc, char **argv) main (int argc, char **argv)
{ {
/* Set locale via LC_ALL. */ int remaining;
setlocale (LC_ALL, "");
/* Set the text message domain. */
textdomain (_libc_intl_domainname);
/* Parse and process arguments. */ /* Parse and process arguments. */
int remaining;
argp_parse (&argp, argc, argv, 0, &remaining, NULL); argp_parse (&argp, argc, argv, 0, &remaining, NULL);
/* Remaining arguments are additional directories if opt_manual_link /* Remaining arguments are additional directories if opt_manual_link
@ -1191,7 +1185,9 @@ main (int argc, char **argv)
add_dir (argv[i]); add_dir (argv[i]);
} }
#ifdef USE_TLS
hwcap_extra[63 - _DL_FIRST_EXTRA] = "tls"; hwcap_extra[63 - _DL_FIRST_EXTRA] = "tls";
#endif
set_hwcap (); set_hwcap ();

View File

@ -1,5 +1,5 @@
#! @BASH@ #! @BASH@
# Copyright (C) 1996-2004, 2005, 2006, 2007 Free Software Foundation, Inc. # Copyright (C) 1996-2004, 2005, 2006 Free Software Foundation, Inc.
# This file is part of the GNU C Library. # This file is part of the GNU C Library.
# The GNU C Library is free software; you can redistribute it and/or # The GNU C Library is free software; you can redistribute it and/or
@ -39,7 +39,7 @@ while test $# -gt 0; do
printf $"Copyright (C) %s Free Software Foundation, Inc. printf $"Copyright (C) %s Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
" "2007" " "2006"
printf $"Written by %s and %s. printf $"Written by %s and %s.
" "Roland McGrath" "Ulrich Drepper" " "Roland McGrath" "Ulrich Drepper"
exit 0 exit 0

View File

@ -1,5 +1,5 @@
/* Run time dynamic linker. /* Run time dynamic linker.
Copyright (C) 1995-2002,2003,2004,2005,2006 Free Software Foundation, Inc. Copyright (C) 1995-2006, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -207,7 +207,8 @@ DL_SYSINFO_IMPLEMENTATION
is fine, too. The latter is important here. We can avoid setting is fine, too. The latter is important here. We can avoid setting
up a temporary link map for ld.so if we can mark _rtld_global as up a temporary link map for ld.so if we can mark _rtld_global as
hidden. */ hidden. */
#ifdef PI_STATIC_AND_HIDDEN #if defined PI_STATIC_AND_HIDDEN && defined HAVE_HIDDEN \
&& defined HAVE_VISIBILITY_ATTRIBUTE
# define DONT_USE_BOOTSTRAP_MAP 1 # define DONT_USE_BOOTSTRAP_MAP 1
#endif #endif
@ -291,7 +292,7 @@ _dl_start_final (void *arg, struct dl_start_final_info *info)
GL(dl_rtld_map).l_map_end = (ElfW(Addr)) _end; GL(dl_rtld_map).l_map_end = (ElfW(Addr)) _end;
GL(dl_rtld_map).l_text_end = (ElfW(Addr)) _etext; GL(dl_rtld_map).l_text_end = (ElfW(Addr)) _etext;
/* Copy the TLS related data if necessary. */ /* Copy the TLS related data if necessary. */
#ifndef DONT_USE_BOOTSTRAP_MAP #if USE_TLS && !defined DONT_USE_BOOTSTRAP_MAP
# if USE___THREAD # if USE___THREAD
assert (info->l.l_tls_modid != 0); assert (info->l.l_tls_modid != 0);
GL(dl_rtld_map).l_tls_blocksize = info->l.l_tls_blocksize; GL(dl_rtld_map).l_tls_blocksize = info->l.l_tls_blocksize;
@ -399,7 +400,7 @@ _dl_start (void *arg)
bootstrap_map.l_ld = (void *) bootstrap_map.l_addr + elf_machine_dynamic (); bootstrap_map.l_ld = (void *) bootstrap_map.l_addr + elf_machine_dynamic ();
elf_get_dynamic_info (&bootstrap_map, NULL); elf_get_dynamic_info (&bootstrap_map, NULL);
#if NO_TLS_OFFSET != 0 #if defined USE_TLS && NO_TLS_OFFSET != 0
bootstrap_map.l_tls_offset = NO_TLS_OFFSET; bootstrap_map.l_tls_offset = NO_TLS_OFFSET;
#endif #endif
@ -700,6 +701,7 @@ match_version (const char *string, struct link_map *map)
return 0; return 0;
} }
#ifdef USE_TLS
static bool tls_init_tp_called; static bool tls_init_tp_called;
static void * static void *
@ -771,6 +773,7 @@ cannot allocate TLS data structures for initial thread");
return tcbp; return tcbp;
} }
#endif
#ifdef _LIBC_REENTRANT #ifdef _LIBC_REENTRANT
/* _dl_error_catch_tsd points to this for the single-threaded case. /* _dl_error_catch_tsd points to this for the single-threaded case.
@ -858,14 +861,18 @@ dl_main (const ElfW(Phdr) *phdr,
hp_timing_t stop; hp_timing_t stop;
hp_timing_t diff; hp_timing_t diff;
#endif #endif
#ifdef USE_TLS
void *tcbp = NULL; void *tcbp = NULL;
#endif
#ifdef _LIBC_REENTRANT #ifdef _LIBC_REENTRANT
/* Explicit initialization since the reloc would just be more work. */ /* Explicit initialization since the reloc would just be more work. */
GL(dl_error_catch_tsd) = &_dl_initial_error_catch_tsd; GL(dl_error_catch_tsd) = &_dl_initial_error_catch_tsd;
#endif #endif
#ifdef USE_TLS
GL(dl_init_static_tls) = &_dl_nothread_init_static_tls; GL(dl_init_static_tls) = &_dl_nothread_init_static_tls;
#endif
#if defined SHARED && defined _LIBC_REENTRANT \ #if defined SHARED && defined _LIBC_REENTRANT \
&& defined __rtld_lock_default_lock_recursive && defined __rtld_lock_default_lock_recursive
@ -1150,6 +1157,7 @@ of this helper program; chances are you did not intend to run this program.\n\
break; break;
case PT_TLS: case PT_TLS:
#ifdef USE_TLS
if (ph->p_memsz > 0) if (ph->p_memsz > 0)
{ {
/* Note that in the case the dynamic linker we duplicate work /* Note that in the case the dynamic linker we duplicate work
@ -1169,6 +1177,10 @@ of this helper program; chances are you did not intend to run this program.\n\
/* This image gets the ID one. */ /* This image gets the ID one. */
GL(dl_tls_max_dtv_idx) = main_map->l_tls_modid = 1; GL(dl_tls_max_dtv_idx) = main_map->l_tls_modid = 1;
} }
#else
_dl_fatal_printf ("\
ld.so does not support TLS, but program uses it!\n");
#endif
break; break;
case PT_GNU_STACK: case PT_GNU_STACK:
@ -1180,12 +1192,13 @@ of this helper program; chances are you did not intend to run this program.\n\
main_map->l_relro_size = ph->p_memsz; main_map->l_relro_size = ph->p_memsz;
break; break;
} }
#ifdef USE_TLS
/* Adjust the address of the TLS initialization image in case /* Adjust the address of the TLS initialization image in case
the executable is actually an ET_DYN object. */ the executable is actually an ET_DYN object. */
if (main_map->l_tls_initimage != NULL) if (main_map->l_tls_initimage != NULL)
main_map->l_tls_initimage main_map->l_tls_initimage
= (char *) main_map->l_tls_initimage + main_map->l_addr; = (char *) main_map->l_tls_initimage + main_map->l_addr;
#endif
if (! main_map->l_map_end) if (! main_map->l_map_end)
main_map->l_map_end = ~0; main_map->l_map_end = ~0;
if (! main_map->l_text_end) if (! main_map->l_text_end)
@ -1388,10 +1401,12 @@ of this helper program; chances are you did not intend to run this program.\n\
break; break;
} }
#ifdef USE_TLS
/* Add the dynamic linker to the TLS list if it also uses TLS. */ /* Add the dynamic linker to the TLS list if it also uses TLS. */
if (GL(dl_rtld_map).l_tls_blocksize != 0) if (GL(dl_rtld_map).l_tls_blocksize != 0)
/* Assign a module ID. Do this before loading any audit modules. */ /* Assign a module ID. Do this before loading any audit modules. */
GL(dl_rtld_map).l_tls_modid = _dl_next_tls_modid (); GL(dl_rtld_map).l_tls_modid = _dl_next_tls_modid ();
#endif
/* If we have auditing DSOs to load, do it now. */ /* If we have auditing DSOs to load, do it now. */
if (__builtin_expect (audit_list != NULL, 0)) if (__builtin_expect (audit_list != NULL, 0))
@ -1399,8 +1414,15 @@ of this helper program; chances are you did not intend to run this program.\n\
/* Iterate over all entries in the list. The order is important. */ /* Iterate over all entries in the list. The order is important. */
struct audit_ifaces *last_audit = NULL; struct audit_ifaces *last_audit = NULL;
struct audit_list *al = audit_list->next; struct audit_list *al = audit_list->next;
#ifdef USE_TLS
/* Since we start using the auditing DSOs right away we need to
initialize the data structures now. */
tcbp = init_tls ();
#endif
do do
{ {
#ifdef USE_TLS
int tls_idx = GL(dl_tls_max_dtv_idx); int tls_idx = GL(dl_tls_max_dtv_idx);
/* Now it is time to determine the layout of the static TLS /* Now it is time to determine the layout of the static TLS
@ -1408,11 +1430,7 @@ of this helper program; chances are you did not intend to run this program.\n\
always allocate the static block, we never defer it even if always allocate the static block, we never defer it even if
no DF_STATIC_TLS bit is set. The reason is that we know no DF_STATIC_TLS bit is set. The reason is that we know
glibc will use the static model. */ glibc will use the static model. */
#endif
/* Since we start using the auditing DSOs right away we need to
initialize the data structures now. */
tcbp = init_tls ();
struct dlmopen_args dlmargs; struct dlmopen_args dlmargs;
dlmargs.fname = al->name; dlmargs.fname = al->name;
dlmargs.map = NULL; dlmargs.map = NULL;
@ -1527,7 +1545,9 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
assert (GL(dl_ns)[ns]._ns_loaded == NULL); assert (GL(dl_ns)[ns]._ns_loaded == NULL);
assert (GL(dl_ns)[ns]._ns_nloaded == 0); assert (GL(dl_ns)[ns]._ns_nloaded == 0);
#ifdef USE_TLS
GL(dl_tls_max_dtv_idx) = tls_idx; GL(dl_tls_max_dtv_idx) = tls_idx;
#endif
goto not_loaded; goto not_loaded;
} }
} }
@ -1803,6 +1823,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
_dl_receive_error (print_missing_version, version_check_doit, &args); _dl_receive_error (print_missing_version, version_check_doit, &args);
} }
#ifdef USE_TLS
/* We do not initialize any of the TLS functionality unless any of the /* We do not initialize any of the TLS functionality unless any of the
initial modules uses TLS. This makes dynamic loading of modules with initial modules uses TLS. This makes dynamic loading of modules with
TLS impossible, but to support it requires either eagerly doing setup TLS impossible, but to support it requires either eagerly doing setup
@ -1813,6 +1834,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
bool was_tls_init_tp_called = tls_init_tp_called; bool was_tls_init_tp_called = tls_init_tp_called;
if (tcbp == NULL) if (tcbp == NULL)
tcbp = init_tls (); tcbp = init_tls ();
#endif
/* Set up the stack checker's canary. */ /* Set up the stack checker's canary. */
uintptr_t stack_chk_guard = _dl_setup_stack_chk_guard (); uintptr_t stack_chk_guard = _dl_setup_stack_chk_guard ();
@ -1869,12 +1891,13 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
(size_t) l->l_map_start, (size_t) l->l_map_start,
(int) sizeof l->l_addr * 2, (int) sizeof l->l_addr * 2,
(size_t) l->l_addr); (size_t) l->l_addr);
#ifdef USE_TLS
if (l->l_tls_modid) if (l->l_tls_modid)
_dl_printf (" TLS(0x%Zx, 0x%0*Zx)\n", l->l_tls_modid, _dl_printf (" TLS(0x%Zx, 0x%0*Zx)\n", l->l_tls_modid,
(int) sizeof l->l_tls_offset * 2, (int) sizeof l->l_tls_offset * 2,
(size_t) l->l_tls_offset); (size_t) l->l_tls_offset);
else else
#endif
_dl_printf ("\n"); _dl_printf ("\n");
} }
} }
@ -1942,8 +1965,8 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
lookup_t result; lookup_t result;
result = _dl_lookup_symbol_x (INTUSE(_dl_argv)[i], main_map, result = _dl_lookup_symbol_x (INTUSE(_dl_argv)[i], main_map,
&ref, main_map->l_scope, &ref, main_map->l_scope, NULL,
NULL, ELF_RTYPE_CLASS_PLT, ELF_RTYPE_CLASS_PLT,
DL_LOOKUP_ADD_DEPENDENCY, NULL); DL_LOOKUP_ADD_DEPENDENCY, NULL);
loadbase = LOOKUP_VALUE_ADDRESS (result); loadbase = LOOKUP_VALUE_ADDRESS (result);
@ -1985,8 +2008,8 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
{ {
/* Mark the link map as not yet relocated again. */ /* Mark the link map as not yet relocated again. */
GL(dl_rtld_map).l_relocated = 0; GL(dl_rtld_map).l_relocated = 0;
_dl_relocate_object (&GL(dl_rtld_map), _dl_relocate_object (&GL(dl_rtld_map), main_map->l_scope,
main_map->l_scope, 0, 0); 0, 0);
} }
} }
#define VERNEEDTAG (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (DT_VERNEED)) #define VERNEEDTAG (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (DT_VERNEED))
@ -2157,9 +2180,11 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
if (l->l_relro_size) if (l->l_relro_size)
_dl_protect_relro (l); _dl_protect_relro (l);
#ifdef USE_TLS
/* Add object to slot information data if necessasy. */ /* Add object to slot information data if necessasy. */
if (l->l_tls_blocksize != 0 && tls_init_tp_called) if (l->l_tls_blocksize != 0 && tls_init_tp_called)
_dl_add_to_slotinfo (l); _dl_add_to_slotinfo (l);
#endif
} }
_dl_sysdep_start_cleanup (); _dl_sysdep_start_cleanup ();
@ -2206,9 +2231,11 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
_dl_relocate_object (l, l->l_scope, GLRO(dl_lazy), _dl_relocate_object (l, l->l_scope, GLRO(dl_lazy),
consider_profiling); consider_profiling);
#ifdef USE_TLS
/* Add object to slot information data if necessasy. */ /* Add object to slot information data if necessasy. */
if (l->l_tls_blocksize != 0 && tls_init_tp_called) if (l->l_tls_blocksize != 0 && tls_init_tp_called)
_dl_add_to_slotinfo (l); _dl_add_to_slotinfo (l);
#endif
l = l->l_prev; l = l->l_prev;
} }
@ -2237,6 +2264,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
# define NONTLS_INIT_TP do { } while (0) # define NONTLS_INIT_TP do { } while (0)
#endif #endif
#ifdef USE_TLS
if (!was_tls_init_tp_called && GL(dl_tls_max_dtv_idx) > 0) if (!was_tls_init_tp_called && GL(dl_tls_max_dtv_idx) > 0)
++GL(dl_tls_generation); ++GL(dl_tls_generation);
@ -2254,6 +2282,9 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
_dl_fatal_printf ("cannot set up thread-local storage: %s\n", _dl_fatal_printf ("cannot set up thread-local storage: %s\n",
lossage); lossage);
} }
#else
NONTLS_INIT_TP;
#endif
if (! prelinked && rtld_multiple_ref) if (! prelinked && rtld_multiple_ref)
{ {

View File

@ -1,5 +1,5 @@
/* Read and display shared object profiling data. /* Read and display shared object profiling data.
Copyright (C) 1997-2004, 2005, 2006, 2007 Free Software Foundation, Inc. Copyright (C) 1997-2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@ -357,7 +357,7 @@ Copyright (C) %s Free Software Foundation, Inc.\n\
This is free software; see the source for copying conditions. There is NO\n\ This is free software; see the source for copying conditions. There is NO\n\
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
"), "),
"2007"); "2006");
fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper"); fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper");
} }

View File

@ -27,9 +27,8 @@ tf (void *arg)
return NULL; return NULL;
} }
int
static int main (void)
do_test (void)
{ {
#define N 10 #define N 10
pthread_t th[N]; pthread_t th[N];
@ -54,6 +53,3 @@ do_test (void)
} }
return 0; return 0;
} }
#define TEST_FUNCTION do_test ()
#include "../test-skeleton.c"

View File

@ -9,6 +9,7 @@
static int static int
do_test (void) do_test (void)
{ {
#ifdef USE_TLS
static const char modname[] = "tst-tlsmod2.so"; static const char modname[] = "tst-tlsmod2.so";
int result = 0; int result = 0;
int *foop; int *foop;
@ -82,6 +83,9 @@ do_test (void)
dlclose (h); dlclose (h);
return result; return result;
#else
return 0;
#endif
} }

View File

@ -3,18 +3,21 @@
#include <tls.h> #include <tls.h>
#include "tls-macros.h" #ifdef USE_TLS
# include "tls-macros.h"
/* Two common 'int' variables in TLS. */ /* Two common 'int' variables in TLS. */
COMMON_INT_DEF(foo); COMMON_INT_DEF(foo);
COMMON_INT_DEF(bar); COMMON_INT_DEF(bar);
#endif
#define TEST_FUNCTION do_test () #define TEST_FUNCTION do_test ()
static int static int
do_test (void) do_test (void)
{ {
#ifdef USE_TLS
int result = 0; int result = 0;
int *ap, *bp; int *ap, *bp;
@ -79,6 +82,9 @@ do_test (void)
} }
return result; return result;
#else
return 0;
#endif
} }

View File

@ -1,7 +1,8 @@
#include <tls.h> #include <tls.h>
#include <stdlib.h> #include <stdlib.h>
#if defined HAVE___THREAD && defined HAVE_TLS_MODEL_ATTRIBUTE #if defined USE_TLS && defined HAVE___THREAD \
&& defined HAVE_TLS_MODEL_ATTRIBUTE
# define USE_TLS__THREAD # define USE_TLS__THREAD
struct A struct A

View File

@ -6,9 +6,9 @@
#include <tls.h> #include <tls.h>
#if HAVE___THREAD #if USE_TLS && HAVE___THREAD
# define AL 4096 #define AL 4096
struct foo struct foo
{ {
int i; int i;
@ -55,11 +55,11 @@ do_test (void)
return result; return result;
} }
# define TEST_FUNCTION do_test () #define TEST_FUNCTION do_test ()
#else #else
# define TEST_FUNCTION 0 #define TEST_FUNCTION 0
#endif #endif

View File

@ -3,18 +3,21 @@
#include <tls.h> #include <tls.h>
#include "tls-macros.h" #ifdef USE_TLS
# include "tls-macros.h"
/* Two 'int' variables in TLS. */ /* Two 'int' variables in TLS. */
VAR_INT_DEF(foo); VAR_INT_DEF(foo);
VAR_INT_DEF(bar); VAR_INT_DEF(bar);
#endif
#define TEST_FUNCTION do_test () #define TEST_FUNCTION do_test ()
static int static int
do_test (void) do_test (void)
{ {
#ifdef USE_TLS
int result = 0; int result = 0;
int *ap, *bp; int *ap, *bp;
@ -79,6 +82,9 @@ do_test (void)
} }
return result; return result;
#else
return 0;
#endif
} }

View File

@ -3,13 +3,15 @@
#include <tls.h> #include <tls.h>
#include "tls-macros.h" #ifdef USE_TLS
# include "tls-macros.h"
/* One define int variable, two externs. */ /* One define int variable, two externs. */
COMMON_INT_DECL(foo); COMMON_INT_DECL(foo);
VAR_INT_DECL(bar); VAR_INT_DECL(bar);
VAR_INT_DEF(baz); VAR_INT_DEF(baz);
#endif
extern int in_dso (void); extern int in_dso (void);
@ -19,6 +21,7 @@ extern int in_dso (void);
static int static int
do_test (void) do_test (void)
{ {
#ifdef USE_TLS
int result = 0; int result = 0;
int *ap, *bp, *cp; int *ap, *bp, *cp;
@ -64,6 +67,9 @@ do_test (void)
result |= in_dso (); result |= in_dso ();
return result; return result;
#else
return 0;
#endif
} }

View File

@ -9,6 +9,7 @@
static int static int
do_test (void) do_test (void)
{ {
#ifdef USE_TLS
static const char modname[] = "tst-tlsmod2.so"; static const char modname[] = "tst-tlsmod2.so";
int result = 0; int result = 0;
int *foop; int *foop;
@ -46,6 +47,9 @@ do_test (void)
dlclose (h); dlclose (h);
return result; return result;
#else
return 0;
#endif
} }

View File

@ -9,6 +9,7 @@
static int static int
do_test (void) do_test (void)
{ {
#ifdef USE_TLS
static const char modname[] = "tst-tlsmod2.so"; static const char modname[] = "tst-tlsmod2.so";
int result = 0; int result = 0;
int *foop; int *foop;
@ -62,6 +63,9 @@ do_test (void)
dlclose (h); dlclose (h);
return result; return result;
#else
return 0;
#endif
} }

View File

@ -10,6 +10,7 @@
static int static int
do_test (void) do_test (void)
{ {
#ifdef USE_TLS
static const char modname[] = "tst-tlsmod2.so"; static const char modname[] = "tst-tlsmod2.so";
int result = 0; int result = 0;
int *foop; int *foop;
@ -80,6 +81,9 @@ do_test (void)
} }
return result; return result;
#else
return 0;
#endif
} }

View File

@ -10,6 +10,7 @@
static int static int
do_test (void) do_test (void)
{ {
#ifdef USE_TLS
static const char modname[] = "tst-tlsmod3.so"; static const char modname[] = "tst-tlsmod3.so";
int result = 0; int result = 0;
int (*fp) (void); int (*fp) (void);
@ -51,6 +52,9 @@ do_test (void)
} }
return result; return result;
#else
return 0;
#endif
} }

View File

@ -10,6 +10,7 @@
static int static int
do_test (void) do_test (void)
{ {
#ifdef USE_TLS
static const char modname1[] = "$ORIGIN/tst-tlsmod3.so"; static const char modname1[] = "$ORIGIN/tst-tlsmod3.so";
static const char modname2[] = "$ORIGIN/tst-tlsmod4.so"; static const char modname2[] = "$ORIGIN/tst-tlsmod4.so";
int result = 0; int result = 0;
@ -164,6 +165,9 @@ do_test (void)
} }
return result; return result;
#else
return 0;
#endif
} }

View File

@ -9,6 +9,7 @@
static int static int
do_test (void) do_test (void)
{ {
#ifdef USE_TLS
static const char modname1[] = "tst-tlsmod5.so"; static const char modname1[] = "tst-tlsmod5.so";
static const char modname2[] = "tst-tlsmod6.so"; static const char modname2[] = "tst-tlsmod6.so";
int result = 0; int result = 0;
@ -32,6 +33,9 @@ do_test (void)
dlclose (h2); dlclose (h2);
return result; return result;
#else
return 0;
#endif
} }

View File

@ -2,6 +2,7 @@
#include <tls.h> #include <tls.h>
#ifdef USE_TLS
#include "tls-macros.h" #include "tls-macros.h"
@ -9,6 +10,7 @@
COMMON_INT_DEF(foo); COMMON_INT_DEF(foo);
VAR_INT_DEF(bar); VAR_INT_DEF(bar);
VAR_INT_DECL(baz); VAR_INT_DECL(baz);
#endif
extern int in_dso (void); extern int in_dso (void);
@ -16,6 +18,7 @@ int
in_dso (void) in_dso (void)
{ {
int result = 0; int result = 0;
#ifdef USE_TLS
int *ap, *bp, *cp; int *ap, *bp, *cp;
/* Get variables using initial exec model. */ /* Get variables using initial exec model. */
@ -59,6 +62,7 @@ in_dso (void)
printf ("baz = %d\n", *cp); printf ("baz = %d\n", *cp);
result = 1; result = 1;
} }
#endif
return result; return result;
} }

View File

@ -1,6 +1,7 @@
#include <tls.h> #include <tls.h>
#if defined HAVE___THREAD && defined HAVE_TLS_MODEL_ATTRIBUTE #if defined USE_TLS && defined HAVE___THREAD \
&& defined HAVE_TLS_MODEL_ATTRIBUTE
__thread int a[2] __attribute__ ((tls_model ("initial-exec"))); __thread int a[2] __attribute__ ((tls_model ("initial-exec")));
#else #else
int a[2]; int a[2];

View File

@ -1,6 +1,7 @@
#include <tls.h> #include <tls.h>
#if defined HAVE___THREAD && defined HAVE_TLS_MODEL_ATTRIBUTE #if defined USE_TLS && defined HAVE___THREAD \
&& defined HAVE_TLS_MODEL_ATTRIBUTE
__thread int b[2] __attribute__ ((tls_model ("initial-exec"))); __thread int b[2] __attribute__ ((tls_model ("initial-exec")));
#else #else
int b[2]; int b[2];

View File

@ -3,9 +3,9 @@
#include <tls.h> #include <tls.h>
#if HAVE___THREAD #if USE_TLS && HAVE___THREAD
# define AL 4096 #define AL 4096
struct foo struct foo
{ {
int i; int i;
@ -15,9 +15,9 @@ static __thread struct foo f;
static struct foo g; static struct foo g;
# ifndef FCT #ifndef FCT
# define FCT in_dso1 # define FCT in_dso1
# endif #endif
int int

View File

@ -2,6 +2,7 @@
#include <tls.h> #include <tls.h>
#ifdef USE_TLS
#include "tls-macros.h" #include "tls-macros.h"
@ -34,3 +35,4 @@ in_dso (int n, int *caller_foop)
return result; return result;
} }
#endif

View File

@ -2,7 +2,8 @@
#include <tls.h> #include <tls.h>
#include "tls-macros.h" #ifdef USE_TLS
# include "tls-macros.h"
extern int in_dso (int n, int *caller_foop); extern int in_dso (int n, int *caller_foop);
@ -37,3 +38,4 @@ in_dso2 (void)
return result; return result;
} }
#endif

View File

@ -2,7 +2,8 @@
#include <tls.h> #include <tls.h>
#include "tls-macros.h" #ifdef USE_TLS
# include "tls-macros.h"
COMMON_INT_DEF(baz); COMMON_INT_DEF(baz);
@ -34,3 +35,4 @@ in_dso (int n, int *caller_bazp)
return result; return result;
} }
#endif

View File

@ -1,5 +1,7 @@
#include <tls.h> #include <tls.h>
#ifdef USE_TLS
#include "tls-macros.h" #include "tls-macros.h"
COMMON_INT_DEF(foo); COMMON_INT_DEF(foo);
#endif

View File

@ -1,5 +1,7 @@
#include <tls.h> #include <tls.h>
#ifdef USE_TLS
#include "tls-macros.h" #include "tls-macros.h"
COMMON_INT_DEF(bar); COMMON_INT_DEF(bar);
#endif

View File

@ -69,8 +69,8 @@ _MCOUNT_DECL(frompc, selfpc) /* _mcount; may be static, inline, etc */
* check that we are profiling * check that we are profiling
* and that we aren't recursively invoked. * and that we aren't recursively invoked.
*/ */
if (catomic_compare_and_exchange_bool_acq (&p->state, GMON_PROF_BUSY, if (atomic_compare_and_exchange_bool_acq (&p->state, GMON_PROF_BUSY,
GMON_PROF_ON)) GMON_PROF_ON))
return; return;
/* /*

View File

@ -1,5 +1,5 @@
/* Charset name normalization. /* Charset name normalization.
Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. Copyright (C) 2001,2002,2003,2004,2005,2007 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 2001. Contributed by Ulrich Drepper <drepper@cygnus.com>, 2001.
@ -30,7 +30,7 @@ strip (char *wp, const char *s)
while (*s != '\0') while (*s != '\0')
{ {
if (__isalnum_l (*s, _nl_C_locobj_ptr) if (__isalnum_l (*s, _nl_C_locobj_ptr)
|| *s == '_' || *s == '-' || *s == '.' || *s == ',') || *s == '_' || *s == '-' || *s == '.' || *s == ',' || *s == ':')
*wp++ = __toupper_l (*s, _nl_C_locobj_ptr); *wp++ = __toupper_l (*s, _nl_C_locobj_ptr);
else if (*s == '/') else if (*s == '/')
{ {

View File

@ -1,5 +1,5 @@
/* Get descriptor for character set conversion. /* Get descriptor for character set conversion.
Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. Copyright (C) 1997,1998,1999,2000,2001,2007 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@ -38,7 +38,7 @@ iconv_open (const char *tocode, const char *fromcode)
int res; int res;
/* Normalize the name. We remove all characters beside alpha-numeric, /* Normalize the name. We remove all characters beside alpha-numeric,
'_', '-', '/', and '.'. */ '_', '-', '/', '.', and ':'. */
tocode_len = strlen (tocode); tocode_len = strlen (tocode);
tocode_conv = (char *) alloca (tocode_len + 3); tocode_conv = (char *) alloca (tocode_len + 3);
strip (tocode_conv, tocode); strip (tocode_conv, tocode);

View File

@ -1,5 +1,5 @@
/* Convert text in given files from the specified from-set to the to-set. /* Convert text in given files from the specified from-set to the to-set.
Copyright (C) 1998-2004, 2005, 2006, 2007 Free Software Foundation, Inc. Copyright (C) 1998-2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
@ -426,7 +426,7 @@ print_version (FILE *stream, struct argp_state *state)
Copyright (C) %s Free Software Foundation, Inc.\n\ Copyright (C) %s Free Software Foundation, Inc.\n\
This is free software; see the source for copying conditions. There is NO\n\ This is free software; see the source for copying conditions. There is NO\n\
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
"), "2007"); "), "2006");
fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper"); fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper");
} }

View File

@ -1,5 +1,5 @@
/* Generate fastloading iconv module configuration files. /* Generate fastloading iconv module configuration files.
Copyright (C) 2000-2004, 2005, 2006, 2007 Free Software Foundation, Inc. Copyright (C) 2000-2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2000. Contributed by Ulrich Drepper <drepper@redhat.com>, 2000.
@ -395,7 +395,7 @@ print_version (FILE *stream, struct argp_state *state)
Copyright (C) %s Free Software Foundation, Inc.\n\ Copyright (C) %s Free Software Foundation, Inc.\n\
This is free software; see the source for copying conditions. There is NO\n\ This is free software; see the source for copying conditions. There is NO\n\
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
"), "2007"); "), "2006");
fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper"); fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper");
} }

View File

@ -1,5 +1,5 @@
# GNU libc iconv configuration. # GNU libc iconv configuration.
# Copyright (C) 1997-2004, 2005 Free Software Foundation, Inc. # Copyright (C) 1997-2004, 2005, 2007 Free Software Foundation, Inc.
# This file is part of the GNU C Library. # This file is part of the GNU C Library.
# The GNU C Library is free software; you can redistribute it and/or # The GNU C Library is free software; you can redistribute it and/or
@ -1376,7 +1376,7 @@ module INTERNAL INIS-CYRILLIC// INIS-CYRILLIC 1
# from to module cost # from to module cost
alias ISO-IR-98// ISO_2033// alias ISO-IR-98// ISO_2033//
alias ISO_2033-1983// ISO_2033// alias ISO_2033-1983// ISO_2033//
alias E13B/ ISO_2033// alias E13B// ISO_2033//
alias CSISO2033// ISO_2033// alias CSISO2033// ISO_2033//
module ISO_2033// INTERNAL ISO_2033 1 module ISO_2033// INTERNAL ISO_2033 1
module INTERNAL ISO_2033// ISO_2033 1 module INTERNAL ISO_2033// ISO_2033 1

View File

@ -1,5 +1,5 @@
/* Mapping tables for JOHAB handling. /* Mapping tables for JOHAB handling.
Copyright (C) 1998, 1999, 2000-2002 Free Software Foundation, Inc. Copyright (C) 1998, 1999, 2000-2002, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Contributed by Jungshik Shin <jshin@pantheon.yale.edu> Contributed by Jungshik Shin <jshin@pantheon.yale.edu>
and Ulrich Drepper <drepper@cygnus.com>, 1998. and Ulrich Drepper <drepper@cygnus.com>, 1998.
@ -239,7 +239,7 @@ johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2)
if (__builtin_expect (ch2 < 0x31, 0) \ if (__builtin_expect (ch2 < 0x31, 0) \
|| (__builtin_expect (ch2 > 0x7e, 0) && ch2 < 0x91) \ || (__builtin_expect (ch2 > 0x7e, 0) && ch2 < 0x91) \
|| __builtin_expect (ch2, 0) == 0xff \ || __builtin_expect (ch2, 0) == 0xff \
|| (__builtin_expect (ch, 0) == 0xd9 && ch2 > 0xe5) \ || (__builtin_expect (ch, 0) == 0xd9 && ch2 > 0xe8) \
|| (__builtin_expect (ch, 0) == 0xda \ || (__builtin_expect (ch, 0) == 0xda \
&& ch2 > 0xa0 && ch2 < 0xd4) \ && ch2 > 0xa0 && ch2 < 0xd4) \
|| (__builtin_expect (ch, 0) == 0xde && ch2 > 0xf1)) \ || (__builtin_expect (ch, 0) == 0xde && ch2 > 0xf1)) \
@ -386,7 +386,7 @@ johab_sym_hanja_to_ucs (uint_fast32_t idx, uint_fast32_t c1, uint_fast32_t c2)
break; \ break; \
} \ } \
if (__builtin_expect (written == __UNKNOWN_10646_CHAR, 0) \ if (__builtin_expect (written == __UNKNOWN_10646_CHAR, 0) \
|| (outptr[0] == 0x22 && outptr[1] > 0x65)) \ || (outptr[0] == 0x22 && outptr[1] > 0x68)) \
{ \ { \
UNICODE_TAG_HANDLER (ch, 4); \ UNICODE_TAG_HANDLER (ch, 4); \
STANDARD_TO_LOOP_ERR_HANDLER (4); \ STANDARD_TO_LOOP_ERR_HANDLER (4); \

View File

@ -1,5 +1,5 @@
/* Conversion tables for KS C 5601-1992 based encoding conversion. /* Conversion tables for KS C 5601-1992 based encoding conversion.
Copyright (C) 1998, 2000 Free Software Foundation, Inc. Copyright (C) 1998, 2000, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Contributed by Jungshik Shin <jshin@pantheon.yale.edu>, 1998. Contributed by Jungshik Shin <jshin@pantheon.yale.edu>, 1998.
@ -412,7 +412,8 @@ const uint16_t __ksc5601_sym_to_ucs[] =
[0x0098] = 0x2669, [0x0099] = 0x266a, [0x009a] = 0x266c, [0x009b] = 0x327f, [0x0098] = 0x2669, [0x0099] = 0x266a, [0x009a] = 0x266c, [0x009b] = 0x327f,
[0x009c] = 0x321c, [0x009d] = 0x2116, [0x009e] = 0x33c7, [0x009f] = 0x2122, [0x009c] = 0x321c, [0x009d] = 0x2116, [0x009e] = 0x33c7, [0x009f] = 0x2122,
[0x00a0] = 0x33c2, [0x00a1] = 0x33d8, [0x00a2] = 0x2121, [0x00a3] = 0x20ac, [0x00a0] = 0x33c2, [0x00a1] = 0x33d8, [0x00a2] = 0x2121, [0x00a3] = 0x20ac,
[0x00a4] = 0x00ae, [0x00bc] = 0xff01, [0x00bd] = 0xff02, [0x00be] = 0xff03, [0x00a4] = 0x00ae, [0x00a5] = 0x327e,
[0x00bc] = 0xff01, [0x00bd] = 0xff02, [0x00be] = 0xff03,
[0x00bf] = 0xff04, [0x00c0] = 0xff05, [0x00c1] = 0xff06, [0x00c2] = 0xff07, [0x00bf] = 0xff04, [0x00c0] = 0xff05, [0x00c1] = 0xff06, [0x00c2] = 0xff07,
[0x00c3] = 0xff08, [0x00c4] = 0xff09, [0x00c5] = 0xff0a, [0x00c6] = 0xff0b, [0x00c3] = 0xff08, [0x00c4] = 0xff09, [0x00c5] = 0xff0a, [0x00c6] = 0xff0b,
[0x00c7] = 0xff0c, [0x00c8] = 0xff0d, [0x00c9] = 0xff0e, [0x00ca] = 0xff0f, [0x00c7] = 0xff0c, [0x00c8] = 0xff0d, [0x00c9] = 0xff0e, [0x00ca] = 0xff0f,
@ -917,6 +918,7 @@ const struct map __ksc5601_sym_from_ucs[KSC5601_SYMBOL] =
{0x3273, "\x28\x44"}, {0x3274, "\x28\x45"}, {0x3275, "\x28\x46"}, {0x3273, "\x28\x44"}, {0x3274, "\x28\x45"}, {0x3275, "\x28\x46"},
{0x3276, "\x28\x47"}, {0x3277, "\x28\x48"}, {0x3278, "\x28\x49"}, {0x3276, "\x28\x47"}, {0x3277, "\x28\x48"}, {0x3278, "\x28\x49"},
{0x3279, "\x28\x4a"}, {0x327a, "\x28\x4b"}, {0x327b, "\x28\x4c"}, {0x3279, "\x28\x4a"}, {0x327a, "\x28\x4b"}, {0x327b, "\x28\x4c"},
{0x327e, "\x22\x68"},
{0x327f, "\x22\x5e"}, {0x3380, "\x27\x49"}, {0x3381, "\x27\x4a"}, {0x327f, "\x22\x5e"}, {0x3380, "\x27\x49"}, {0x3381, "\x27\x4a"},
{0x3382, "\x27\x4b"}, {0x3383, "\x27\x4c"}, {0x3384, "\x27\x4d"}, {0x3382, "\x27\x4b"}, {0x3383, "\x27\x4c"}, {0x3384, "\x27\x4d"},
{0x3388, "\x27\x3a"}, {0x3389, "\x27\x3b"}, {0x338a, "\x27\x5c"}, {0x3388, "\x27\x3a"}, {0x3389, "\x27\x3b"}, {0x338a, "\x27\x5c"},

View File

@ -1,5 +1,5 @@
/* Access functions for KS C 5601-1992 based encoding conversion. /* Access functions for KS C 5601-1992 based encoding conversion.
Copyright (C) 1998, 1999, 2000, 2003 Free Software Foundation, Inc. Copyright (C) 1998, 1999, 2000, 2003, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -22,7 +22,7 @@
#define KSC5601_HANGUL 2350 #define KSC5601_HANGUL 2350
#define KSC5601_HANJA 4888 #define KSC5601_HANJA 4888
#define KSC5601_SYMBOL 988 #define KSC5601_SYMBOL 989
#include <gconv.h> #include <gconv.h>
#include <stdint.h> #include <stdint.h>

View File

@ -1,5 +1,5 @@
/* Mapping tables for UHC handling. /* Mapping tables for UHC handling.
Copyright (C) 1998, 1999, 2000-2002 Free Software Foundation, Inc. Copyright (C) 1998, 1999, 2000-2002, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Contributed by Jungshik Shin <jshin@pantheon.yale.edu>, 1998. Contributed by Jungshik Shin <jshin@pantheon.yale.edu>, 1998.
@ -3135,7 +3135,8 @@ static const char uhc_hangul_from_ucs[11172][2] =
else \ else \
{ \ { \
ch = ksc5601_to_ucs4 (&inptr, 2, 0x80); \ ch = ksc5601_to_ucs4 (&inptr, 2, 0x80); \
if (__builtin_expect (ch == __UNKNOWN_10646_CHAR, 0)) \ if (__builtin_expect (ch == __UNKNOWN_10646_CHAR, 0) \
|| __builtin_expect (ch == 0x327e, 0)) \
{ \ { \
/* Illegal. */ \ /* Illegal. */ \
STANDARD_FROM_LOOP_ERR_HANDLER (2); \ STANDARD_FROM_LOOP_ERR_HANDLER (2); \
@ -3207,15 +3208,16 @@ static const char uhc_hangul_from_ucs[11172][2] =
{ \ { \
size_t written = ucs4_to_ksc5601_sym (ch, outptr, outend - outptr); \ size_t written = ucs4_to_ksc5601_sym (ch, outptr, outend - outptr); \
\ \
if (__builtin_expect (ch == 0x327e, 0) \
|| __builtin_expect (written == __UNKNOWN_10646_CHAR, 0)) \
{ \
UNICODE_TAG_HANDLER (ch, 4); \
STANDARD_TO_LOOP_ERR_HANDLER (4); \
} \
if (__builtin_expect (written == 0, 0)) \ if (__builtin_expect (written == 0, 0)) \
{ \ { \
result = __GCONV_FULL_OUTPUT; \ result = __GCONV_FULL_OUTPUT; \
break; \ break; \
} \
if (__builtin_expect (written == __UNKNOWN_10646_CHAR, 0)) \
{ \
UNICODE_TAG_HANDLER (ch, 4); \
STANDARD_TO_LOOP_ERR_HANDLER (4); \
} \ } \
\ \
*outptr++ |= 0x80; \ *outptr++ |= 0x80; \

View File

@ -21,31 +21,6 @@
#ifndef _ATOMIC_H #ifndef _ATOMIC_H
#define _ATOMIC_H 1 #define _ATOMIC_H 1
/* This header defines three types of macros:
- atomic arithmetic and logic operation on memory. They all
have the prefix "atomic_".
- conditionally atomic operations of the same kinds. These
always behave identical but can be faster when atomicity
is not really needed since only one thread has access to
the memory location. In that case the code is slower in
the multi-thread case. The interfaces have the prefix
"catomic_".
- support functions like barriers. They also have the preifx
"atomic_".
Architectures must provide a few lowlevel macros (the compare
and exchange definitions). All others are optional. They
should only be provided if the architecture has specific
support for the operation.
As <atomic.h> macros are usually heavily nested and often use local
variables to make sure side-effects are evaluated properly, use for
macro local variables a per-macro unique prefix. This file uses
__atgN_ prefix where N is different in each macro. */
#include <stdlib.h> #include <stdlib.h>
#include <bits/atomic.h> #include <bits/atomic.h>
@ -55,33 +30,33 @@
and following args. */ and following args. */
#define __atomic_val_bysize(pre, post, mem, ...) \ #define __atomic_val_bysize(pre, post, mem, ...) \
({ \ ({ \
__typeof (*mem) __atg1_result; \ __typeof (*mem) __result; \
if (sizeof (*mem) == 1) \ if (sizeof (*mem) == 1) \
__atg1_result = pre##_8_##post (mem, __VA_ARGS__); \ __result = pre##_8_##post (mem, __VA_ARGS__); \
else if (sizeof (*mem) == 2) \ else if (sizeof (*mem) == 2) \
__atg1_result = pre##_16_##post (mem, __VA_ARGS__); \ __result = pre##_16_##post (mem, __VA_ARGS__); \
else if (sizeof (*mem) == 4) \ else if (sizeof (*mem) == 4) \
__atg1_result = pre##_32_##post (mem, __VA_ARGS__); \ __result = pre##_32_##post (mem, __VA_ARGS__); \
else if (sizeof (*mem) == 8) \ else if (sizeof (*mem) == 8) \
__atg1_result = pre##_64_##post (mem, __VA_ARGS__); \ __result = pre##_64_##post (mem, __VA_ARGS__); \
else \ else \
abort (); \ abort (); \
__atg1_result; \ __result; \
}) })
#define __atomic_bool_bysize(pre, post, mem, ...) \ #define __atomic_bool_bysize(pre, post, mem, ...) \
({ \ ({ \
int __atg2_result; \ int __result; \
if (sizeof (*mem) == 1) \ if (sizeof (*mem) == 1) \
__atg2_result = pre##_8_##post (mem, __VA_ARGS__); \ __result = pre##_8_##post (mem, __VA_ARGS__); \
else if (sizeof (*mem) == 2) \ else if (sizeof (*mem) == 2) \
__atg2_result = pre##_16_##post (mem, __VA_ARGS__); \ __result = pre##_16_##post (mem, __VA_ARGS__); \
else if (sizeof (*mem) == 4) \ else if (sizeof (*mem) == 4) \
__atg2_result = pre##_32_##post (mem, __VA_ARGS__); \ __result = pre##_32_##post (mem, __VA_ARGS__); \
else if (sizeof (*mem) == 8) \ else if (sizeof (*mem) == 8) \
__atg2_result = pre##_64_##post (mem, __VA_ARGS__); \ __result = pre##_64_##post (mem, __VA_ARGS__); \
else \ else \
abort (); \ abort (); \
__atg2_result; \ __result; \
}) })
@ -95,29 +70,12 @@
#endif #endif
#if !defined catomic_compare_and_exchange_val_acq \
&& defined __arch_c_compare_and_exchange_val_32_acq
# define catomic_compare_and_exchange_val_acq(mem, newval, oldval) \
__atomic_val_bysize (__arch_c_compare_and_exchange_val,acq, \
mem, newval, oldval)
#else
# define catomic_compare_and_exchange_val_acq(mem, newval, oldval) \
atomic_compare_and_exchange_val_acq (mem, newval, oldval)
#endif
#ifndef atomic_compare_and_exchange_val_rel #ifndef atomic_compare_and_exchange_val_rel
# define atomic_compare_and_exchange_val_rel(mem, newval, oldval) \ # define atomic_compare_and_exchange_val_rel(mem, newval, oldval) \
atomic_compare_and_exchange_val_acq (mem, newval, oldval) atomic_compare_and_exchange_val_acq (mem, newval, oldval)
#endif #endif
#ifndef catomic_compare_and_exchange_val_rel
# define catomic_compare_and_exchange_val_rel(mem, newval, oldval) \
atomic_compare_and_exchange_val_acq (mem, newval, oldval)
#endif
/* Atomically store NEWVAL in *MEM if *MEM is equal to OLDVAL. /* Atomically store NEWVAL in *MEM if *MEM is equal to OLDVAL.
Return zero if *MEM was changed or non-zero if no exchange happened. */ Return zero if *MEM was changed or non-zero if no exchange happened. */
#ifndef atomic_compare_and_exchange_bool_acq #ifndef atomic_compare_and_exchange_bool_acq
@ -129,26 +87,8 @@
# define atomic_compare_and_exchange_bool_acq(mem, newval, oldval) \ # define atomic_compare_and_exchange_bool_acq(mem, newval, oldval) \
({ /* Cannot use __oldval here, because macros later in this file might \ ({ /* Cannot use __oldval here, because macros later in this file might \
call this macro with __oldval argument. */ \ call this macro with __oldval argument. */ \
__typeof (oldval) __atg3_old = (oldval); \ __typeof (oldval) __old = (oldval); \
atomic_compare_and_exchange_val_acq (mem, newval, __atg3_old) \ atomic_compare_and_exchange_val_acq (mem, newval, __old) != __old; \
!= __atg3_old; \
})
# endif
#endif
#ifndef catomic_compare_and_exchange_bool_acq
# ifdef __arch_c_compare_and_exchange_bool_32_acq
# define catomic_compare_and_exchange_bool_acq(mem, newval, oldval) \
__atomic_bool_bysize (__arch_c_compare_and_exchange_bool,acq, \
mem, newval, oldval)
# else
# define catomic_compare_and_exchange_bool_acq(mem, newval, oldval) \
({ /* Cannot use __oldval here, because macros later in this file might \
call this macro with __oldval argument. */ \
__typeof (oldval) __atg4_old = (oldval); \
catomic_compare_and_exchange_val_acq (mem, newval, __atg4_old) \
!= __atg4_old; \
}) })
# endif # endif
#endif #endif
@ -160,26 +100,21 @@
#endif #endif
#ifndef catomic_compare_and_exchange_bool_rel
# define catomic_compare_and_exchange_bool_rel(mem, newval, oldval) \
catomic_compare_and_exchange_bool_acq (mem, newval, oldval)
#endif
/* Store NEWVALUE in *MEM and return the old value. */ /* Store NEWVALUE in *MEM and return the old value. */
#ifndef atomic_exchange_acq #ifndef atomic_exchange_acq
# define atomic_exchange_acq(mem, newvalue) \ # define atomic_exchange_acq(mem, newvalue) \
({ __typeof (*(mem)) __atg5_oldval; \ ({ __typeof (*(mem)) __oldval; \
__typeof (mem) __atg5_memp = (mem); \ __typeof (mem) __memp = (mem); \
__typeof (*(mem)) __atg5_value = (newvalue); \ __typeof (*(mem)) __value = (newvalue); \
\ \
do \ do \
__atg5_oldval = *__atg5_memp; \ __oldval = *__memp; \
while (__builtin_expect \ while (__builtin_expect (atomic_compare_and_exchange_bool_acq (__memp, \
(atomic_compare_and_exchange_bool_acq (__atg5_memp, __atg5_value, \ __value, \
__atg5_oldval), 0)); \ __oldval),\
0)); \
\ \
__atg5_oldval; }) __oldval; })
#endif #endif
#ifndef atomic_exchange_rel #ifndef atomic_exchange_rel
@ -190,124 +125,72 @@
/* Add VALUE to *MEM and return the old value of *MEM. */ /* Add VALUE to *MEM and return the old value of *MEM. */
#ifndef atomic_exchange_and_add #ifndef atomic_exchange_and_add
# define atomic_exchange_and_add(mem, value) \ # define atomic_exchange_and_add(mem, value) \
({ __typeof (*(mem)) __atg6_oldval; \ ({ __typeof (*(mem)) __oldval; \
__typeof (mem) __atg6_memp = (mem); \ __typeof (mem) __memp = (mem); \
__typeof (*(mem)) __atg6_value = (value); \ __typeof (*(mem)) __value = (value); \
\ \
do \ do \
__atg6_oldval = *__atg6_memp; \ __oldval = *__memp; \
while (__builtin_expect \ while (__builtin_expect (atomic_compare_and_exchange_bool_acq (__memp, \
(atomic_compare_and_exchange_bool_acq (__atg6_memp, \ __oldval \
__atg6_oldval \ + __value,\
+ __atg6_value, \ __oldval),\
__atg6_oldval), 0)); \ 0)); \
\ \
__atg6_oldval; }) __oldval; })
#endif #endif
#ifndef catomic_exchange_and_add
# define catomic_exchange_and_add(mem, value) \
({ __typeof (*(mem)) __atg7_oldv; \
__typeof (mem) __atg7_memp = (mem); \
__typeof (*(mem)) __atg7_value = (value); \
\
do \
__atg7_oldv = *__atg7_memp; \
while (__builtin_expect \
(catomic_compare_and_exchange_bool_acq (__atg7_memp, \
__atg7_oldv \
+ __atg7_value, \
__atg7_oldv), 0)); \
\
__atg7_oldv; })
#endif
#ifndef atomic_max #ifndef atomic_max
# define atomic_max(mem, value) \ # define atomic_max(mem, value) \
do { \ do { \
__typeof (*(mem)) __atg8_oldval; \ __typeof (*(mem)) __oldval; \
__typeof (mem) __atg8_memp = (mem); \ __typeof (mem) __memp = (mem); \
__typeof (*(mem)) __atg8_value = (value); \ __typeof (*(mem)) __value = (value); \
do { \ do { \
__atg8_oldval = *__atg8_memp; \ __oldval = *__memp; \
if (__atg8_oldval >= __atg8_value) \ if (__oldval >= __value) \
break; \ break; \
} while (__builtin_expect \ } while (__builtin_expect (atomic_compare_and_exchange_bool_acq (__memp, \
(atomic_compare_and_exchange_bool_acq (__atg8_memp, __atg8_value,\ __value, \
__atg8_oldval), 0)); \ __oldval),\
0)); \
} while (0) } while (0)
#endif #endif
#ifndef catomic_max
# define catomic_max(mem, value) \
do { \
__typeof (*(mem)) __atg9_oldv; \
__typeof (mem) __atg9_memp = (mem); \
__typeof (*(mem)) __atg9_value = (value); \
do { \
__atg9_oldv = *__atg9_memp; \
if (__atg9_oldv >= __atg9_value) \
break; \
} while (__builtin_expect \
(catomic_compare_and_exchange_bool_acq (__atg9_memp, \
__atg9_value, \
__atg9_oldv), 0)); \
} while (0)
#endif
#ifndef atomic_min #ifndef atomic_min
# define atomic_min(mem, value) \ # define atomic_min(mem, value) \
do { \ do { \
__typeof (*(mem)) __atg10_oldval; \ __typeof (*(mem)) __oldval; \
__typeof (mem) __atg10_memp = (mem); \ __typeof (mem) __memp = (mem); \
__typeof (*(mem)) __atg10_value = (value); \ __typeof (*(mem)) __value = (value); \
do { \ do { \
__atg10_oldval = *__atg10_memp; \ __oldval = *__memp; \
if (__atg10_oldval <= __atg10_value) \ if (__oldval <= __value) \
break; \ break; \
} while (__builtin_expect \ } while (__builtin_expect (atomic_compare_and_exchange_bool_acq (__memp, \
(atomic_compare_and_exchange_bool_acq (__atg10_memp, \ __value, \
__atg10_value, \ __oldval),\
__atg10_oldval), 0)); \ 0)); \
} while (0) } while (0)
#endif #endif
#ifndef atomic_add #ifndef atomic_add
# define atomic_add(mem, value) (void) atomic_exchange_and_add ((mem), (value)) # define atomic_add(mem, value) (void) atomic_exchange_and_add ((mem), (value))
#endif #endif
#ifndef catomic_add
# define catomic_add(mem, value) \
(void) catomic_exchange_and_add ((mem), (value))
#endif
#ifndef atomic_increment #ifndef atomic_increment
# define atomic_increment(mem) atomic_add ((mem), 1) # define atomic_increment(mem) atomic_add ((mem), 1)
#endif #endif
#ifndef catomic_increment
# define catomic_increment(mem) catomic_add ((mem), 1)
#endif
#ifndef atomic_increment_val #ifndef atomic_increment_val
# define atomic_increment_val(mem) (atomic_exchange_and_add ((mem), 1) + 1) # define atomic_increment_val(mem) (atomic_exchange_and_add ((mem), 1) + 1)
#endif #endif
#ifndef catomic_increment_val
# define catomic_increment_val(mem) (catomic_exchange_and_add ((mem), 1) + 1)
#endif
/* Add one to *MEM and return true iff it's now zero. */ /* Add one to *MEM and return true iff it's now zero. */
#ifndef atomic_increment_and_test #ifndef atomic_increment_and_test
# define atomic_increment_and_test(mem) \ # define atomic_increment_and_test(mem) \
@ -320,21 +203,11 @@
#endif #endif
#ifndef catomic_decrement
# define catomic_decrement(mem) catomic_add ((mem), -1)
#endif
#ifndef atomic_decrement_val #ifndef atomic_decrement_val
# define atomic_decrement_val(mem) (atomic_exchange_and_add ((mem), -1) - 1) # define atomic_decrement_val(mem) (atomic_exchange_and_add ((mem), -1) - 1)
#endif #endif
#ifndef catomic_decrement_val
# define catomic_decrement_val(mem) (catomic_exchange_and_add ((mem), -1) - 1)
#endif
/* Subtract 1 from *MEM and return true iff it's now zero. */ /* Subtract 1 from *MEM and return true iff it's now zero. */
#ifndef atomic_decrement_and_test #ifndef atomic_decrement_and_test
# define atomic_decrement_and_test(mem) \ # define atomic_decrement_and_test(mem) \
@ -345,34 +218,35 @@
/* Decrement *MEM if it is > 0, and return the old value. */ /* Decrement *MEM if it is > 0, and return the old value. */
#ifndef atomic_decrement_if_positive #ifndef atomic_decrement_if_positive
# define atomic_decrement_if_positive(mem) \ # define atomic_decrement_if_positive(mem) \
({ __typeof (*(mem)) __atg11_oldval; \ ({ __typeof (*(mem)) __oldval; \
__typeof (mem) __atg11_memp = (mem); \ __typeof (mem) __memp = (mem); \
\ \
do \ do \
{ \ { \
__atg11_oldval = *__atg11_memp; \ __oldval = *__memp; \
if (__builtin_expect (__atg11_oldval <= 0, 0)) \ if (__builtin_expect (__oldval <= 0, 0)) \
break; \ break; \
} \ } \
while (__builtin_expect \ while (__builtin_expect (atomic_compare_and_exchange_bool_acq (__memp, \
(atomic_compare_and_exchange_bool_acq (__atg11_memp, \ __oldval \
__atg11_oldval - 1, \ - 1, \
__atg11_oldval), 0)); \ __oldval),\
__atg11_oldval; }) 0));\
__oldval; })
#endif #endif
#ifndef atomic_add_negative #ifndef atomic_add_negative
# define atomic_add_negative(mem, value) \ # define atomic_add_negative(mem, value) \
({ __typeof (value) __atg12_value = (value); \ ({ __typeof (value) __aan_value = (value); \
atomic_exchange_and_add (mem, __atg12_value) < -__atg12_value; }) atomic_exchange_and_add (mem, __aan_value) < -__aan_value; })
#endif #endif
#ifndef atomic_add_zero #ifndef atomic_add_zero
# define atomic_add_zero(mem, value) \ # define atomic_add_zero(mem, value) \
({ __typeof (value) __atg13_value = (value); \ ({ __typeof (value) __aaz_value = (value); \
atomic_exchange_and_add (mem, __atg13_value) == -__atg13_value; }) atomic_exchange_and_add (mem, __aaz_value) == -__aaz_value; })
#endif #endif
@ -384,102 +258,55 @@
#ifndef atomic_bit_test_set #ifndef atomic_bit_test_set
# define atomic_bit_test_set(mem, bit) \ # define atomic_bit_test_set(mem, bit) \
({ __typeof (*(mem)) __atg14_old; \ ({ __typeof (*(mem)) __oldval; \
__typeof (mem) __atg14_memp = (mem); \ __typeof (mem) __memp = (mem); \
__typeof (*(mem)) __atg14_mask = ((__typeof (*(mem))) 1 << (bit)); \ __typeof (*(mem)) __mask = ((__typeof (*(mem))) 1 << (bit)); \
\ \
do \ do \
__atg14_old = (*__atg14_memp); \ __oldval = (*__memp); \
while (__builtin_expect \ while (__builtin_expect (atomic_compare_and_exchange_bool_acq (__memp, \
(atomic_compare_and_exchange_bool_acq (__atg14_memp, \ __oldval \
__atg14_old | __atg14_mask,\ | __mask, \
__atg14_old), 0)); \ __oldval),\
0)); \
\ \
__atg14_old & __atg14_mask; }) __oldval & __mask; })
#endif
/* Atomically *mem &= mask. */
#ifndef atomic_and
# define atomic_and(mem, mask) \
do { \
__typeof (*(mem)) __atg15_old; \
__typeof (mem) __atg15_memp = (mem); \
__typeof (*(mem)) __atg15_mask = (mask); \
\
do \
__atg15_old = (*__atg15_memp); \
while (__builtin_expect \
(atomic_compare_and_exchange_bool_acq (__atg15_memp, \
__atg15_old & __atg15_mask, \
__atg15_old), 0)); \
} while (0)
#endif #endif
/* Atomically *mem &= mask and return the old value of *mem. */ /* Atomically *mem &= mask and return the old value of *mem. */
#ifndef atomic_and_val #ifndef atomic_and
# define atomic_and_val(mem, mask) \ # define atomic_and(mem, mask) \
({ __typeof (*(mem)) __atg16_old; \ ({ __typeof (*(mem)) __oldval; \
__typeof (mem) __atg16_memp = (mem); \ __typeof (mem) __memp = (mem); \
__typeof (*(mem)) __atg16_mask = (mask); \ __typeof (*(mem)) __mask = (mask); \
\ \
do \ do \
__atg16_old = (*__atg16_memp); \ __oldval = (*__memp); \
while (__builtin_expect \ while (__builtin_expect (atomic_compare_and_exchange_bool_acq (__memp, \
(atomic_compare_and_exchange_bool_acq (__atg16_memp, \ __oldval \
__atg16_old & __atg16_mask,\ & __mask, \
__atg16_old), 0)); \ __oldval),\
0)); \
\ \
__atg16_old; }) __oldval; })
#endif #endif
/* Atomically *mem |= mask and return the old value of *mem. */ /* Atomically *mem |= mask and return the old value of *mem. */
#ifndef atomic_or #ifndef atomic_or
# define atomic_or(mem, mask) \ # define atomic_or(mem, mask) \
do { \ ({ __typeof (*(mem)) __oldval; \
__typeof (*(mem)) __atg17_old; \ __typeof (mem) __memp = (mem); \
__typeof (mem) __atg17_memp = (mem); \ __typeof (*(mem)) __mask = (mask); \
__typeof (*(mem)) __atg17_mask = (mask); \
\
do \
__atg17_old = (*__atg17_memp); \
while (__builtin_expect \
(atomic_compare_and_exchange_bool_acq (__atg17_memp, \
__atg17_old | __atg17_mask, \
__atg17_old), 0)); \
} while (0)
#endif
#ifndef catomic_or
# define catomic_or(mem, mask) \
do { \
__typeof (*(mem)) __atg18_old; \
__typeof (mem) __atg18_memp = (mem); \
__typeof (*(mem)) __atg18_mask = (mask); \
\
do \
__atg18_old = (*__atg18_memp); \
while (__builtin_expect \
(catomic_compare_and_exchange_bool_acq (__atg18_memp, \
__atg18_old | __atg18_mask,\
__atg18_old), 0)); \
} while (0)
#endif
/* Atomically *mem |= mask and return the old value of *mem. */
#ifndef atomic_or_val
# define atomic_or_val(mem, mask) \
({ __typeof (*(mem)) __atg19_old; \
__typeof (mem) __atg19_memp = (mem); \
__typeof (*(mem)) __atg19_mask = (mask); \
\ \
do \ do \
__atg19_old = (*__atg19_memp); \ __oldval = (*__memp); \
while (__builtin_expect \ while (__builtin_expect (atomic_compare_and_exchange_bool_acq (__memp, \
(atomic_compare_and_exchange_bool_acq (__atg19_memp, \ __oldval \
__atg19_old | __atg19_mask,\ | __mask, \
__atg19_old), 0)); \ __oldval),\
0)); \
\ \
__atg19_old; }) __oldval; })
#endif #endif
#ifndef atomic_full_barrier #ifndef atomic_full_barrier

View File

@ -47,9 +47,6 @@ libc_hidden_proto (_dl_addr)
/* Close an object previously opened by _dl_open. */ /* Close an object previously opened by _dl_open. */
extern void _dl_close (void *map) attribute_hidden; extern void _dl_close (void *map) attribute_hidden;
/* Same as above, but without locking and safety checks for user
provided map arguments. */
extern void _dl_close_worker (struct link_map *map) attribute_hidden;
/* Look up NAME in shared object HANDLE (which may be RTLD_DEFAULT or /* Look up NAME in shared object HANDLE (which may be RTLD_DEFAULT or
RTLD_NEXT). WHO is the calling function, for RTLD_NEXT. Returns RTLD_NEXT). WHO is the calling function, for RTLD_NEXT. Returns

View File

@ -19,7 +19,7 @@ extern int rtld_errno attribute_hidden;
# else # else
# include <tls.h> # include <tls.h> /* Defines USE_TLS. */
# if USE___THREAD # if USE___THREAD
# undef errno # undef errno

View File

@ -114,13 +114,6 @@
# define _weak_alias(name, aliasname) \ # define _weak_alias(name, aliasname) \
extern __typeof (name) aliasname __attribute__ ((weak, alias (#name))); extern __typeof (name) aliasname __attribute__ ((weak, alias (#name)));
/* Same as WEAK_ALIAS, but mark symbol as hidden. */
# define weak_hidden_alias(name, aliasname) \
_weak_hidden_alias (name, aliasname)
# define _weak_hidden_alias(name, aliasname) \
extern __typeof (name) aliasname \
__attribute__ ((weak, alias (#name), __visibility__ ("hidden")));
/* Declare SYMBOL as weak undefined symbol (resolved to 0 if not defined). */ /* Declare SYMBOL as weak undefined symbol (resolved to 0 if not defined). */
# define weak_extern(symbol) _weak_extern (weak symbol) # define weak_extern(symbol) _weak_extern (weak symbol)
# define _weak_extern(expr) _Pragma (#expr) # define _weak_extern(expr) _Pragma (#expr)
@ -128,7 +121,6 @@
# else # else
# define weak_alias(name, aliasname) strong_alias(name, aliasname) # define weak_alias(name, aliasname) strong_alias(name, aliasname)
# define weak_hidden_alias(name, aliasname) strong_alias(name, aliasname)
# define weak_extern(symbol) /* Nothing. */ # define weak_extern(symbol) /* Nothing. */
# endif # endif
@ -294,42 +286,27 @@ requires at runtime the shared libraries from the glibc version used \
for linking") for linking")
#endif #endif
/* Declare SYMBOL to be TYPE (`function' or `object') of SIZE bytes /* Declare SYMBOL to be TYPE (`function' or `object') and of SIZE bytes,
alias to ORIGINAL, when the assembler supports such declarations when the assembler supports such declarations (such as in ELF).
(such as in ELF).
This is only necessary when defining something in assembly, or playing This is only necessary when defining something in assembly, or playing
funny alias games where the size should be other than what the compiler funny alias games where the size should be other than what the compiler
thinks it is. */ thinks it is. */
#define declare_symbol_alias(symbol, original, type, size) \ #define declare_symbol(symbol, type, size) \
declare_symbol_alias_1 (symbol, original, type, size) declare_symbol_1 (symbol, type, size)
#ifdef ASM_TYPE_DIRECTIVE_PREFIX #ifdef ASM_TYPE_DIRECTIVE_PREFIX
# ifdef __ASSEMBLER__ # ifdef __ASSEMBLER__
# define declare_symbol_alias_1(symbol, original, type, size) \ # define declare_symbol_1(symbol, type, size) \
strong_alias (original, symbol); \
.type C_SYMBOL_NAME (symbol), \ .type C_SYMBOL_NAME (symbol), \
declare_symbol_alias_1_paste (ASM_TYPE_DIRECTIVE_PREFIX, type); \ declare_symbol_1_paste (ASM_TYPE_DIRECTIVE_PREFIX, type), size
.size C_SYMBOL_NAME (symbol), size # define declare_symbol_1_paste(a, b) declare_symbol_1_paste_1 (a,b)
# define declare_symbol_alias_1_paste(a, b) \ # define declare_symbol_1_paste_1(a,b) a##b
declare_symbol_alias_1_paste_1 (a,b)
# define declare_symbol_alias_1_paste_1(a,b) a##b
# else /* Not __ASSEMBLER__. */ # else /* Not __ASSEMBLER__. */
# define declare_symbol_alias_1(symbol, original, type, size) \ # define declare_symbol_1(symbol, type, size) \
asm (declare_symbol_alias_1_stringify (ASM_GLOBAL_DIRECTIVE) \ asm (".type " __SYMBOL_PREFIX #symbol ", " \
" " __SYMBOL_PREFIX #symbol \ declare_symbol_1_stringify (ASM_TYPE_DIRECTIVE_PREFIX) #type \
"\n\t" declare_symbol_alias_1_alias (symbol, original) \
"\n\t.type " __SYMBOL_PREFIX #symbol ", " \
declare_symbol_alias_1_stringify (ASM_TYPE_DIRECTIVE_PREFIX) #type \
"\n\t.size " __SYMBOL_PREFIX #symbol ", " #size); "\n\t.size " __SYMBOL_PREFIX #symbol ", " #size);
# define declare_symbol_alias_1_stringify(x) \ # define declare_symbol_1_stringify(x) declare_symbol_1_stringify_1 (x)
declare_symbol_alias_1_stringify_1 (x) # define declare_symbol_1_stringify_1(x) #x
# define declare_symbol_alias_1_stringify_1(x) #x
# ifdef HAVE_ASM_SET_DIRECTIVE
# define declare_symbol_alias_1_alias(symbol, original) \
".set " __SYMBOL_PREFIX #symbol ", " __SYMBOL_PREFIX #original
# else
# define declare_symbol_alias_1_alias(symbol, original) \
__SYMBOL_PREFIX #symbol " = " __SYMBOL_PREFIX #original
# endif /* HAVE_ASM_SET_DIRECTIVE */
# endif /* __ASSEMBLER__ */ # endif /* __ASSEMBLER__ */
#else #else
# define declare_symbol_1(symbol, type, size) /* Nothing. */ # define declare_symbol_1(symbol, type, size) /* Nothing. */
@ -454,7 +431,8 @@ for linking")
strong_alias(real, name) strong_alias(real, name)
#endif #endif
#if defined SHARED || defined LIBC_NONSHARED #if defined HAVE_VISIBILITY_ATTRIBUTE \
&& (defined SHARED || defined LIBC_NONSHARED)
# define attribute_hidden __attribute__ ((visibility ("hidden"))) # define attribute_hidden __attribute__ ((visibility ("hidden")))
#else #else
# define attribute_hidden # define attribute_hidden
@ -466,7 +444,11 @@ for linking")
# define attribute_tls_model_ie # define attribute_tls_model_ie
#endif #endif
#define attribute_relro __attribute__ ((section (".data.rel.ro"))) #ifdef HAVE_Z_RELRO
# define attribute_relro __attribute__ ((section (".data.rel.ro")))
#else
# define attribute_relro
#endif
/* Handling on non-exported internal names. We have to do this only /* Handling on non-exported internal names. We have to do this only
for shared code. */ for shared code. */
@ -475,9 +457,14 @@ for linking")
# define INTDEF(name) strong_alias (name, name##_internal) # define INTDEF(name) strong_alias (name, name##_internal)
# define INTVARDEF(name) \ # define INTVARDEF(name) \
_INTVARDEF (name, name##_internal) _INTVARDEF (name, name##_internal)
# define _INTVARDEF(name, aliasname) \ # if defined HAVE_VISIBILITY_ATTRIBUTE
# define _INTVARDEF(name, aliasname) \
extern __typeof (name) aliasname __attribute__ ((alias (#name), \ extern __typeof (name) aliasname __attribute__ ((alias (#name), \
visibility ("hidden"))); visibility ("hidden")));
# else
# define _INTVARDEF(name, aliasname) \
extern __typeof (name) aliasname __attribute__ ((alias (#name)));
# endif
# define INTDEF2(name, newname) strong_alias (name, newname##_internal) # define INTDEF2(name, newname) strong_alias (name, newname##_internal)
# define INTVARDEF2(name, newname) _INTVARDEF (name, newname##_internal) # define INTVARDEF2(name, newname) _INTVARDEF (name, newname##_internal)
#else #else
@ -562,10 +549,16 @@ for linking")
versioned_symbol (libc, __real_foo, foo, GLIBC_2_1); versioned_symbol (libc, __real_foo, foo, GLIBC_2_1);
libc_hidden_ver (__real_foo, foo) */ libc_hidden_ver (__real_foo, foo) */
#if defined SHARED && defined DO_VERSIONING && !defined NO_HIDDEN #if defined SHARED && defined DO_VERSIONING \
&& !defined HAVE_BROKEN_ALIAS_ATTRIBUTE && !defined NO_HIDDEN
# ifndef __ASSEMBLER__ # ifndef __ASSEMBLER__
# define __hidden_proto_hiddenattr(attrs...) \ # if !defined HAVE_VISIBILITY_ATTRIBUTE \
|| defined HAVE_BROKEN_VISIBILITY_ATTRIBUTE
# define __hidden_proto_hiddenattr(attrs...)
# else
# define __hidden_proto_hiddenattr(attrs...) \
__attribute__ ((visibility ("hidden"), ##attrs)) __attribute__ ((visibility ("hidden"), ##attrs))
# endif
# define hidden_proto(name, attrs...) \ # define hidden_proto(name, attrs...) \
__hidden_proto (name, __GI_##name, ##attrs) __hidden_proto (name, __GI_##name, ##attrs)
# define __hidden_proto(name, internal, attrs...) \ # define __hidden_proto(name, internal, attrs...) \

View File

@ -1,6 +1,6 @@
/* Data structure for communication from the run-time dynamic linker for /* Data structure for communication from the run-time dynamic linker for
loaded ELF shared objects. loaded ELF shared objects.
Copyright (C) 1995-2002,2003,2004,2005,2006 Free Software Foundation, Inc. Copyright (C) 1995-2006, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -44,7 +44,6 @@ extern unsigned int la_objopen (struct link_map *__map, Lmid_t __lmid,
#include <dl-lookupcfg.h> #include <dl-lookupcfg.h>
#include <tls.h> #include <tls.h>
#include <bits/libc-lock.h> #include <bits/libc-lock.h>
#include <rtld-lowlevel.h>
/* Some internal data structures of the dynamic linker used in the /* Some internal data structures of the dynamic linker used in the
@ -122,7 +121,7 @@ struct link_map
are indexed by DT_ADDRTAGIDX(tagvalue), see <elf.h>. */ are indexed by DT_ADDRTAGIDX(tagvalue), see <elf.h>. */
ElfW(Dyn) *l_info[DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM ElfW(Dyn) *l_info[DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM
+ DT_EXTRANUM + DT_VALNUM + DT_ADDRNUM]; + DT_EXTRANUM + DT_VALNUM + DT_ADDRNUM];
const ElfW(Phdr) *l_phdr; /* Pointer to program header table in core. */ const ElfW(Phdr) *l_phdr; /* Pointer to program header table in core. */
ElfW(Addr) l_entry; /* Entry point location. */ ElfW(Addr) l_entry; /* Entry point location. */
ElfW(Half) l_phnum; /* Number of program header entries. */ ElfW(Half) l_phnum; /* Number of program header entries. */
@ -183,6 +182,9 @@ struct link_map
is interested in the PLT interception.*/ is interested in the PLT interception.*/
unsigned int l_removed:1; /* Nozero if the object cannot be used anymore unsigned int l_removed:1; /* Nozero if the object cannot be used anymore
since it is removed. */ since it is removed. */
unsigned int l_contiguous:1; /* Nonzero if inter-segment holes are
mprotected or if no holes are present at
all. */
/* Array with version names. */ /* Array with version names. */
unsigned int l_nversions; unsigned int l_nversions;
@ -220,8 +222,6 @@ struct link_map
/* This is an array defining the lookup scope for this link map. /* This is an array defining the lookup scope for this link map.
There are initially at most three different scope lists. */ There are initially at most three different scope lists. */
struct r_scope_elem **l_scope; struct r_scope_elem **l_scope;
/* We need to protect using the SCOPEREC. */
__rtld_mrlock_define (, l_scope_lock)
/* A similar array, this time only with the local scope. This is /* A similar array, this time only with the local scope. This is
used occasionally. */ used occasionally. */
@ -261,6 +261,7 @@ struct link_map
const ElfW(Sym) *ret; const ElfW(Sym) *ret;
} l_lookup_cache; } l_lookup_cache;
#ifdef USE_TLS
/* Thread-local storage related info. */ /* Thread-local storage related info. */
/* Start of the initialization image. */ /* Start of the initialization image. */
@ -273,13 +274,14 @@ struct link_map
size_t l_tls_align; size_t l_tls_align;
/* Offset of first byte module alignment. */ /* Offset of first byte module alignment. */
size_t l_tls_firstbyte_offset; size_t l_tls_firstbyte_offset;
#ifndef NO_TLS_OFFSET # ifndef NO_TLS_OFFSET
# define NO_TLS_OFFSET 0 # define NO_TLS_OFFSET 0
#endif # endif
/* For objects present at startup time: offset in the static TLS block. */ /* For objects present at startup time: offset in the static TLS block. */
ptrdiff_t l_tls_offset; ptrdiff_t l_tls_offset;
/* Index of the module in the dtv array. */ /* Index of the module in the dtv array. */
size_t l_tls_modid; size_t l_tls_modid;
#endif
/* Information used to change permission after the relocations are /* Information used to change permission after the relocations are
done. */ done. */

View File

@ -42,4 +42,6 @@ libnsl_hidden_proto (__nis_default_group)
libnsl_hidden_proto (__nis_default_access) libnsl_hidden_proto (__nis_default_access)
libnsl_hidden_proto (nis_clone_object) libnsl_hidden_proto (nis_clone_object)
extern const_nis_name __nis_domain_of (const_nis_name) __THROW;
#endif #endif

View File

@ -1,5 +1,5 @@
/* Macros for managing ABI-compatibility definitions using ELF symbol versions. /* Macros for managing ABI-compatibility definitions using ELF symbol versions.
Copyright (C) 2000, 2002, 2006 Free Software Foundation, Inc. Copyright (C) 2000, 2002 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -44,8 +44,6 @@
in the GLIBC_2.0 version and obsoleted in the GLIBC_2.2 version. */ in the GLIBC_2.0 version and obsoleted in the GLIBC_2.2 version. */
# define SHLIB_COMPAT(lib, introduced, obsoleted) \ # define SHLIB_COMPAT(lib, introduced, obsoleted) \
_SHLIB_COMPAT (lib, introduced, obsoleted)
# define _SHLIB_COMPAT(lib, introduced, obsoleted) \
((IS_IN_##lib - 0) \ ((IS_IN_##lib - 0) \
&& (!(ABI_##lib##_##obsoleted - 0) \ && (!(ABI_##lib##_##obsoleted - 0) \
|| ((ABI_##lib##_##introduced - 0) < (ABI_##lib##_##obsoleted - 0)))) || ((ABI_##lib##_##introduced - 0) < (ABI_##lib##_##obsoleted - 0))))
@ -64,17 +62,13 @@
shlib-versions if that is newer. */ shlib-versions if that is newer. */
# define versioned_symbol(lib, local, symbol, version) \ # define versioned_symbol(lib, local, symbol, version) \
versioned_symbol_1 (lib, local, symbol, version) versioned_symbol_1 (local, symbol, VERSION_##lib##_##version)
# define versioned_symbol_1(lib, local, symbol, version) \ # define versioned_symbol_1(local, symbol, name) \
versioned_symbol_2 (local, symbol, VERSION_##lib##_##version)
# define versioned_symbol_2(local, symbol, name) \
default_symbol_version (local, symbol, name) default_symbol_version (local, symbol, name)
# define compat_symbol(lib, local, symbol, version) \ # define compat_symbol(lib, local, symbol, version) \
compat_symbol_1 (lib, local, symbol, version) compat_symbol_1 (local, symbol, VERSION_##lib##_##version)
# define compat_symbol_1(lib, local, symbol, version) \ # define compat_symbol_1(local, symbol, name) \
compat_symbol_2 (local, symbol, VERSION_##lib##_##version)
# define compat_symbol_2(local, symbol, name) \
symbol_version (local, symbol, name) symbol_version (local, symbol, name)
#else #else

View File

@ -131,6 +131,7 @@ libc_hidden_proto (__vsnprintf_chk)
libc_hidden_proto (__vfprintf_chk) libc_hidden_proto (__vfprintf_chk)
# if !defined NOT_IN_libc && defined SHARED && defined DO_VERSIONING \ # if !defined NOT_IN_libc && defined SHARED && defined DO_VERSIONING \
&& defined HAVE_VISIBILITY_ATTRIBUTE && !defined HAVE_BROKEN_ALIAS_ATTRIBUTE\
&& !defined NO_HIDDEN && !defined NO_HIDDEN
/* Special gcc builtins. */ /* Special gcc builtins. */
extern size_t __builtin_fwrite (const void *, size_t, size_t, void *) extern size_t __builtin_fwrite (const void *, size_t, size_t, void *)

View File

@ -2,6 +2,12 @@
#include <misc/sys/cdefs.h> #include <misc/sys/cdefs.h>
/* The compiler will optimize based on the knowledge the parameter is
not NULL. This will omit tests. A robust implementation cannot allow
this so when compiling glibc itself we ignore this attribute. */
#undef __nonnull
#define __nonnull(params)
extern void __chk_fail (void) __attribute__ ((__noreturn__)); extern void __chk_fail (void) __attribute__ ((__noreturn__));
libc_hidden_proto (__chk_fail) libc_hidden_proto (__chk_fail)
rtld_hidden_proto (__chk_fail) rtld_hidden_proto (__chk_fail)

View File

@ -12,4 +12,7 @@ extern int __mprotect (void *__addr, size_t __len, int __prot);
/* This one is Linux specific. */ /* This one is Linux specific. */
extern void *__mremap (void *__addr, size_t __old_len, extern void *__mremap (void *__addr, size_t __old_len,
size_t __new_len, int __flags, ...); size_t __new_len, int __flags, ...);
libc_hidden_proto (madvise);
#endif #endif

View File

@ -5,7 +5,8 @@
#include_next <tls.h> #include_next <tls.h>
#if HAVE___THREAD && (!defined NOT_IN_libc || defined IS_IN_libpthread) #if USE_TLS && HAVE___THREAD \
&& (!defined NOT_IN_libc || defined IS_IN_libpthread)
# define USE___THREAD 1 # define USE___THREAD 1

View File

@ -1,4 +1,4 @@
# Copyright (C) 1991-2002, 2003, 2004, 2006 Free Software Foundation, Inc. # Copyright (C) 1991-2006, 2007 Free Software Foundation, Inc.
# This file is part of the GNU C Library. # This file is part of the GNU C Library.
# The GNU C Library is free software; you can redistribute it and/or # The GNU C Library is free software; you can redistribute it and/or
@ -52,7 +52,7 @@ routines := htonl htons \
aux := check_pf ifreq aux := check_pf ifreq
tests := htontest test_ifindex tst-ntoa tst-ether_aton tst-network \ tests := htontest test_ifindex tst-ntoa tst-ether_aton tst-network \
tst-gethnm test-ifaddrs bug-if1 tst-gethnm test-ifaddrs bug-if1 test-inet6_opt
include ../Rules include ../Rules

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2006 Free Software Foundation, Inc. /* Copyright (C) 2006, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2006. Contributed by Ulrich Drepper <drepper@redhat.com>, 2006.
@ -51,7 +51,7 @@ add_padding (uint8_t *extbuf, int offset, int npad)
{ {
if (npad == 1) if (npad == 1)
extbuf[offset] = IP6OPT_PAD1; extbuf[offset] = IP6OPT_PAD1;
else else if (npad > 0)
{ {
struct ip6_opt *pad_opt = (struct ip6_opt *) (extbuf + offset); struct ip6_opt *pad_opt = (struct ip6_opt *) (extbuf + offset);
@ -102,21 +102,17 @@ inet6_opt_append (void *extbuf, socklen_t extlen, int offset, uint8_t type,
int data_offset = offset + sizeof (struct ip6_opt); int data_offset = offset + sizeof (struct ip6_opt);
int npad = (align - data_offset % align) & (align - 1); int npad = (align - data_offset % align) & (align - 1);
/* Now we can check whether the buffer is large enough. */
if (data_offset + npad + len > extlen)
return -1;
if (npad != 0)
{
if (extbuf != NULL)
add_padding (extbuf, offset, npad);
offset += npad;
}
/* Now prepare the option itself. */
if (extbuf != NULL) if (extbuf != NULL)
{ {
/* Now we can check whether the buffer is large enough. */
if (data_offset + npad + len > extlen)
return -1;
add_padding (extbuf, offset, npad);
offset += npad;
/* Now prepare the option itself. */
struct ip6_opt *opt = (struct ip6_opt *) ((uint8_t *) extbuf + offset); struct ip6_opt *opt = (struct ip6_opt *) ((uint8_t *) extbuf + offset);
opt->ip6o_type = type; opt->ip6o_type = type;
@ -124,6 +120,8 @@ inet6_opt_append (void *extbuf, socklen_t extlen, int offset, uint8_t type,
*databufp = opt + 1; *databufp = opt + 1;
} }
else
offset += npad;
return offset + sizeof (struct ip6_opt) + len; return offset + sizeof (struct ip6_opt) + len;
} }
@ -145,12 +143,14 @@ inet6_opt_finish (void *extbuf, socklen_t extlen, int offset)
/* Required padding at the end. */ /* Required padding at the end. */
int npad = (8 - (offset & 7)) & 7; int npad = (8 - (offset & 7)) & 7;
/* Make sure the buffer is large enough. */
if (offset + npad > extlen)
return -1;
if (extbuf != NULL) if (extbuf != NULL)
add_padding (extbuf, offset, npad); {
/* Make sure the buffer is large enough. */
if (offset + npad > extlen)
return -1;
add_padding (extbuf, offset, npad);
}
return offset + npad; return offset + npad;
} }

207
inet/test-inet6_opt.c Normal file
View File

@ -0,0 +1,207 @@
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define OPT_X 42
#define OPT_Y 43
#define OPT_Z 44
static void *
encode_inet6_opt (socklen_t *elp)
{
void *eb = NULL;
socklen_t el;
int cl;
void *db;
int offset;
uint8_t val1;
uint16_t val2;
uint32_t val4;
uint64_t val8;
*elp = 0;
#define CHECK() \
if (cl == -1) \
{ \
printf ("cl == -1 on line %d\n", __LINE__); \
free (eb); \
return NULL; \
}
/* Estimate the length */
cl = inet6_opt_init (NULL, 0);
CHECK ();
cl = inet6_opt_append (NULL, 0, cl, OPT_X, 12, 8, NULL);
CHECK ();
cl = inet6_opt_append (NULL, 0, cl, OPT_Y, 7, 4, NULL);
CHECK ();
cl = inet6_opt_append (NULL, 0, cl, OPT_Z, 7, 1, NULL);
CHECK ();
cl = inet6_opt_finish (NULL, 0, cl);
CHECK ();
el = cl;
eb = malloc (el + 8);
if (eb == NULL)
{
puts ("malloc failed");
return NULL;
}
/* Canary. */
memcpy (eb + el, "deadbeef", 8);
cl = inet6_opt_init (eb, el);
CHECK ();
cl = inet6_opt_append (eb, el, cl, OPT_X, 12, 8, &db);
CHECK ();
val4 = 0x12345678;
offset = inet6_opt_set_val (db, 0, &val4, sizeof (val4));
val8 = 0x0102030405060708LL;
inet6_opt_set_val (db, offset, &val8, sizeof (val8));
cl = inet6_opt_append (eb, el, cl, OPT_Y, 7, 4, &db);
CHECK ();
val1 = 0x01;
offset = inet6_opt_set_val (db, 0, &val1, sizeof (val1));
val2 = 0x1331;
offset = inet6_opt_set_val (db, offset, &val2, sizeof (val2));
val4 = 0x01020304;
inet6_opt_set_val (db, offset, &val4, sizeof (val4));
cl = inet6_opt_append (eb, el, cl, OPT_Z, 7, 1, &db);
CHECK ();
inet6_opt_set_val (db, 0, (void *) "abcdefg", 7);
cl = inet6_opt_finish (eb, el, cl);
CHECK ();
if (memcmp (eb + el, "deadbeef", 8) != 0)
{
puts ("Canary corrupted");
free (eb);
return NULL;
}
*elp = el;
return eb;
}
int
decode_inet6_opt (void *eb, socklen_t el)
{
int ret = 0;
int seq = 0;
int cl = 0;
int offset;
uint8_t type;
socklen_t len;
uint8_t val1;
uint16_t val2;
uint32_t val4;
uint64_t val8;
void *db;
char buf[8];
while ((cl = inet6_opt_next (eb, el, cl, &type, &len, &db)) != -1)
switch (type)
{
case OPT_X:
if (seq++ != 0)
{
puts ("OPT_X is not first");
ret = 1;
}
if (len != 12)
{
printf ("OPT_X's length %d != 12\n", len);
ret = 1;
}
offset = inet6_opt_get_val (db, 0, &val4, sizeof (val4));
if (val4 != 0x12345678)
{
printf ("OPT_X's val4 %x != 0x12345678\n", val4);
ret = 1;
}
offset = inet6_opt_get_val (db, offset, &val8, sizeof (val8));
if (offset != len || val8 != 0x0102030405060708LL)
{
printf ("OPT_X's val8 %llx != 0x0102030405060708\n",
(long long) val8);
ret = 1;
}
break;
case OPT_Y:
if (seq++ != 1)
{
puts ("OPT_Y is not second");
ret = 1;
}
if (len != 7)
{
printf ("OPT_Y's length %d != 7\n", len);
ret = 1;
}
offset = inet6_opt_get_val (db, 0, &val1, sizeof (val1));
if (val1 != 0x01)
{
printf ("OPT_Y's val1 %x != 0x01\n", val1);
ret = 1;
}
offset = inet6_opt_get_val (db, offset, &val2, sizeof (val2));
if (val2 != 0x1331)
{
printf ("OPT_Y's val2 %x != 0x1331\n", val2);
ret = 1;
}
offset = inet6_opt_get_val (db, offset, &val4, sizeof (val4));
if (offset != len || val4 != 0x01020304)
{
printf ("OPT_Y's val4 %x != 0x01020304\n", val4);
ret = 1;
}
break;
case OPT_Z:
if (seq++ != 2)
{
puts ("OPT_Z is not third");
ret = 1;
}
if (len != 7)
{
printf ("OPT_Z's length %d != 7\n", len);
ret = 1;
}
offset = inet6_opt_get_val (db, 0, buf, 7);
if (offset != len || memcmp (buf, "abcdefg", 7) != 0)
{
buf[7] = '\0';
printf ("OPT_Z's buf \"%s\" != \"abcdefg\"\n", buf);
ret = 1;
}
break;
default:
printf ("Unknown option %d\n", type);
ret = 1;
break;
}
if (seq != 3)
{
puts ("Didn't see all of OPT_X, OPT_Y and OPT_Z");
ret = 1;
}
return ret;
}
int
main (void)
{
void *eb;
socklen_t el;
eb = encode_inet6_opt (&el);
if (eb == NULL)
return 1;
if (decode_inet6_opt (eb, el))
return 1;
return 0;
}

View File

@ -1,4 +1,4 @@
# Copyright (C) 1992-2002,2003,2005,2006 Free Software Foundation, Inc. # Copyright (C) 1992-2002,2003,2005,2006, 2007 Free Software Foundation, Inc.
# This file is part of the GNU C Library. # This file is part of the GNU C Library.
# The GNU C Library is free software; you can redistribute it and/or # The GNU C Library is free software; you can redistribute it and/or
@ -66,7 +66,7 @@ tests := test-utime test-stat test-stat2 test-lfs tst-getcwd \
tst-openat tst-unlinkat tst-fstatat tst-futimesat \ tst-openat tst-unlinkat tst-fstatat tst-futimesat \
tst-renameat tst-fchownat tst-fchmodat tst-faccessat \ tst-renameat tst-fchownat tst-fchmodat tst-faccessat \
tst-symlinkat tst-linkat tst-readlinkat tst-mkdirat \ tst-symlinkat tst-linkat tst-readlinkat tst-mkdirat \
tst-mknodat tst-mkfifoat tst-ttyname_r tst-mknodat tst-mkfifoat tst-ttyname_r bug-ftw5
distribute := ftwtest-sh distribute := ftwtest-sh
@ -90,6 +90,19 @@ CFLAGS-posix_fallocate64.c = -fexceptions
CFLAGS-test-stat.c = -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE CFLAGS-test-stat.c = -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE
CFLAGS-test-lfs.c = -D_LARGEFILE64_SOURCE CFLAGS-test-lfs.c = -D_LARGEFILE64_SOURCE
ifeq (yes,$(have-protected))
CFLAGS-stat.c = -DHAVE_DOT_HIDDEN
CFLAGS-fstat.c = -DHAVE_DOT_HIDDEN
CFLAGS-lstat.c = -DHAVE_DOT_HIDDEN
CFLAGS-mknod.c = -DHAVE_DOT_HIDDEN
CFLAGS-stat64.c = -DHAVE_DOT_HIDDEN
CFLAGS-fstat64.c = -DHAVE_DOT_HIDDEN
CFLAGS-lstat64.c = -DHAVE_DOT_HIDDEN
CFLAGS-fstatat.c = -DHAVE_DOT_HIDDEN
CFLAGS-fstatat64.c = -DHAVE_DOT_HIDDEN
CFLAGS-mknodat.c = -DHAVE_DOT_HIDDEN
endif
test-stat2-ARGS = Makefile . $(objpfx)test-stat2 test-stat2-ARGS = Makefile . $(objpfx)test-stat2
tst-statvfs-ARGS = $(objpfx)tst-statvfs tst-statvfs.c /tmp tst-statvfs-ARGS = $(objpfx)tst-statvfs tst-statvfs.c /tmp

25
io/bug-ftw5.c Normal file
View File

@ -0,0 +1,25 @@
#include <errno.h>
#include <ftw.h>
#include <stdio.h>
static int
fn (const char *file, const struct stat *sb, int flag, struct FTW *s)
{
puts (file);
return FTW_STOP;
}
static int
do_test (void)
{
if (nftw ("/", fn, 0, FTW_CHDIR | FTW_ACTIONRETVAL) < 0)
{
printf ("nftw / FTW_CHDIR: %m\n");
return 1;
}
return 0;
}
#define TEST_FUNCTION do_test ()
#include "../test-skeleton.c"

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1996, 1997, 1998, 2001, 2006 Free Software Foundation, Inc. /* Copyright (C) 1996, 1997, 1998, 2001 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or The GNU C Library is free software; you can redistribute it and/or
@ -47,10 +47,16 @@
#undef fstat #undef fstat
#undef __fstat #undef __fstat
int int
attribute_hidden
__fstat (int fd, struct stat *buf) __fstat (int fd, struct stat *buf)
{ {
return __fxstat (_STAT_VER, fd, buf); return __fxstat (_STAT_VER, fd, buf);
} }
weak_hidden_alias (__fstat, fstat) weak_alias (__fstat, fstat)
/* Hide the symbol so that no definition but the one locally in the
executable or DSO is used. */
#ifdef HAVE_DOT_HIDDEN
asm (".hidden\tfstat");
asm (".hidden\t__fstat");
#endif

Some files were not shown because too many files have changed in this diff Show More