/* Define if the linker defines __ehdr_start. */
#undef HAVE_EHDR_START
+/* Define to 1 if the assembler needs intermediate aliases to define
+ multiple symbol versions for one symbol. */
+#define SYMVER_NEEDS_ALIAS 0
+
/*
\f */
$as_echo "$as_me: WARNING: linker is broken -- you should upgrade" >&2;}
fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the assembler requires one version per symbol" >&5
+$as_echo_n "checking whether the assembler requires one version per symbol... " >&6; }
+if ${libc_cv_symver_needs_alias+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat > conftest.s <<EOF
+ .text
+testfunc:
+ .globl testfunc
+ .symver testfunc, testfunc1@VERSION1
+ .symver testfunc, testfunc1@VERSION2
+EOF
+ libc_cv_symver_needs_alias=no
+ if ${CC-cc} $ASFLAGS -c conftest.s 2>&5; then
+ libc_cv_symver_needs_alias=no
+ else
+ libc_cv_symver_needs_alias=yes
+ fi
+ rm conftest.*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_symver_needs_alias" >&5
+$as_echo "$libc_cv_symver_needs_alias" >&6; }
+if test "$libc_cv_symver_needs_alias" = yes; then
+ $as_echo "#define SYMVER_NEEDS_ALIAS 1" >>confdefs.h
+
+fi
+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_trap with no external dependencies" >&5
$as_echo_n "checking for __builtin_trap with no external dependencies... " >&6; }
if ${libc_cv_builtin_trap+:} false; then :
AC_MSG_WARN([linker is broken -- you should upgrade])
fi
+dnl Starting with binutils 2.35, GAS can attach multiple symbol versions
+dnl to one symbol (PR 23840).
+AC_CACHE_CHECK(whether the assembler requires one version per symbol,
+ libc_cv_symver_needs_alias, [dnl
+ cat > conftest.s <<EOF
+ .text
+testfunc:
+ .globl testfunc
+ .symver testfunc, testfunc1@VERSION1
+ .symver testfunc, testfunc1@VERSION2
+EOF
+ libc_cv_symver_needs_alias=no
+ if ${CC-cc} $ASFLAGS -c conftest.s 2>&AS_MESSAGE_LOG_FD; then
+ libc_cv_symver_needs_alias=no
+ else
+ libc_cv_symver_needs_alias=yes
+ fi
+ rm conftest.*
+])
+if test "$libc_cv_symver_needs_alias" = yes; then
+ AC_DEFINE(SYMVER_NEEDS_ALIAS)
+fi
+
AC_CACHE_CHECK(for __builtin_trap with no external dependencies,
libc_cv_builtin_trap, [dnl
libc_cv_builtin_trap=no
symbol_version_reference(real, name, version)
# define default_symbol_version(real, name, version) \
_default_symbol_version(real, name, version)
+/* See <libc-symver.h>. */
# ifdef __ASSEMBLER__
# define _default_symbol_version(real, name, version) \
- .symver real, name##@##@##version
+ _set_symbol_version (real, name@@version)
# else
# define _default_symbol_version(real, name, version) \
- __asm__ (".symver " #real "," #name "@@" #version)
+ _set_symbol_version (real, #name "@@" #version)
# endif
/* Evalutes to a string literal for VERSION in LIB. */
i.e. either GLIBC_2.1 or the "earliest version" specified in
shlib-versions if that is newer. */
+/* versioned_symbol (LIB, LOCAL, SYMBOL, VERSION) emits a definition
+ of SYMBOL with a default (@@) VERSION appropriate for LIB. (The
+ actually emitted symbol version is adjusted according to the
+ baseline symbol version for LIB.) The address of the symbol is
+ taken from LOCAL. Properties of LOCAL are copied to the exported
+ symbol. In particular, LOCAL itself should be global. It is
+ unspecified whether SYMBOL@VERSION is associated with LOCAL, or if
+ an intermediate alias is created. If LOCAL and SYMBOL are
+ distinct, and LOCAL is also intended for export, its version should
+ be specified explicitly with versioned_symbol, too.
+
+ If LOCAL is a data symbol and does not have a non-zero initializer,
+ it should be defined with __attribute__ ((nocommon)) for
+ compatibility with GCC versions that default to -fcommon. */
# define versioned_symbol(lib, local, symbol, version) \
versioned_symbol_1 (lib, local, symbol, version)
# define versioned_symbol_1(lib, local, symbol, version) \
# define versioned_symbol_2(local, symbol, name) \
default_symbol_version (local, symbol, name)
+/* compat_symbol is like versioned_symbol, but emits a compatibility
+ version (with @ instead of @@). The same issue related to
+ intermediate aliases applies, so LOCAL should not be listed in the
+ Versions file, or otherwise it can be exported with an undesired
+ default symbol version. */
# define compat_symbol(lib, local, symbol, version) \
- compat_symbol_reference (lib, local, symbol, version)
-
-/* This is similar to compat_symbol, but allows versioning the same symbol
- to multiple version without having multiple symbol definitions. For
- instance:
-
- #if (SHLIB_COMPAT (libpthread, GLIBC_2_1_2, GLIBC_2_2))
- compat_symbol_unique (libc, old_foo, GLIBC_2_1_2)
- #endif
-
- #if (SHLIB_COMPAT (libpthread, GLIBC_2_2_6, GLIBC_2_3))
- compat_symbol_unique (libc, old_foo, GLIBC_2_2_6)
- #endif
-
- Internally it creates a unique strong alias to the input symbol and
- creates one compat_symbol on the alias. Using the above example,
- it is similar to:
-
- #if (SHLIB_COMPAT (libpthread, GLIBC_2_1_2, GLIBC_2_2))
- strong_alias (old_foo, old_foo__COUNTER__)
- compat_symbol (libc, old_foo__COUNTER__, foo, GLIBC_2_2)
- #endif.
-
- With __COUNTER__ being a monotonic number generated by the compiler. */
-
-# define __compat_symbol_unique_concat(x, y) x ## y
-# define _compat_symbol_unique_concat(x, y) \
- __compat_symbol_unique_concat (x, y)
-# define _compat_symbol_unique_alias(name) \
- _compat_symbol_unique_concat (name, __COUNTER__)
-# define _compat_symbol_unique(lib, orig_name, name, version) \
- strong_alias (orig_name, name) \
- compat_symbol (lib, name, orig_name, version)
-# define compat_symbol_unique(lib, name, version) \
- _compat_symbol_unique (lib, name, _compat_symbol_unique_alias (name), \
- version)
-
+ compat_symbol_1 (lib, local, symbol, version)
+# define compat_symbol_1(lib, local, symbol, version) \
+ compat_symbol_2 (local, symbol, VERSION_##lib##_##version)
+/* See <libc-symver.h>. */
+# ifdef __ASSEMBLER__
+#define compat_symbol_2(local, symbol, name) \
+ _set_symbol_version (local, symbol@name)
+# else
+# define compat_symbol_2(local, symbol, name) \
+ compat_symbol_3 (local, symbol, name)
+# define compat_symbol_3(local, symbol, name) \
+ _set_symbol_version (local, #symbol "@" #name)
+# endif
#else
/* Not compiling ELF shared libraries at all, so never any old versions. */
/* This should not appear outside `#if SHLIB_COMPAT (...)'. */
# define compat_symbol(lib, local, symbol, version) ...
-# define compat_symbol_unique(lib, name, version) ...
#endif
/* Use compat_symbol_reference for a reference *or* definition of a
- specific version of a symbol. Definitions are primarily used to
- ensure tests reference the exact compat symbol required, or define an
- interposing symbol of the right version e.g. __malloc_initialize_hook
- in mcheck-init.c. Use compat_symbol to define such a symbol within
- the shared libraries that are built for users. */
+ specific version of a symbol. compat_symbol_reference does not
+ create intermediate aliases. Definitions are primarily used to
+ ensure tests reference the exact compat symbol required, or define
+ an interposing symbol of the right version e.g.,
+ __malloc_initialize_hook in mcheck-init.c. Use compat_symbol to
+ define such a symbol within the shared libraries that are built for
+ users. */
#define compat_symbol_reference(lib, local, symbol, version) \
compat_symbol_reference_1 (lib, local, symbol, version)
#define compat_symbol_reference_1(lib, local, symbol, version) \
const void *caller) __THROW;
#if HAVE_MALLOC_INIT_HOOK
-void weak_variable (*__malloc_initialize_hook) (void) = NULL;
+void (*__malloc_initialize_hook) (void) __attribute__ ((nocommon));
compat_symbol (libc, __malloc_initialize_hook,
__malloc_initialize_hook, GLIBC_2_0);
#endif
#include <shlib-compat.h>
#ifdef SHARED
-static void
+void
attribute_compat_text_section
__attribute_used__
-__libpthread_version_placeholder (void)
+__libpthread_version_placeholder_1 (void)
{
}
#endif
there are plenty of other symbols which populate those later
versions. */
#if (SHLIB_COMPAT (libpthread, GLIBC_2_1_2, GLIBC_2_2))
-compat_symbol_unique (libpthread,
- __libpthread_version_placeholder, GLIBC_2_1_2);
+compat_symbol (libpthread, __libpthread_version_placeholder_1,
+ __libpthread_version_placeholder, GLIBC_2_1_2);
#endif
#if (SHLIB_COMPAT (libpthread, GLIBC_2_2_3, GLIBC_2_2_4))
-compat_symbol_unique (libpthread,
- __libpthread_version_placeholder, GLIBC_2_2_3);
+compat_symbol (libpthread, __libpthread_version_placeholder_1,
+ __libpthread_version_placeholder, GLIBC_2_2_3);
#endif
#if (SHLIB_COMPAT (libpthread, GLIBC_2_2_6, GLIBC_2_3))
-compat_symbol_unique (libpthread,
- __libpthread_version_placeholder, GLIBC_2_2_6);
+compat_symbol (libpthread, __libpthread_version_placeholder_1,
+ __libpthread_version_placeholder, GLIBC_2_2_6);
#endif
#ifndef _LIBC_SYMVER_H
#define _LIBC_SYMVER_H 1
+#include <config.h>
+
/* Use symbol_version_reference to specify the version a symbol
reference should link to. Use symbol_version or
default_symbol_version for the definition of a versioned symbol.
The difference is that the latter is a no-op in non-shared
- builds. */
+ builds.
+
+ _set_symbol_version is similar to symbol_version_reference, except
+ that this macro expects the name and symbol version as a single
+ string or token sequence, with an @ or @@ separator. (A string is
+ used in C mode and a token sequence in assembler mode.)
+ _set_symbol_version only be used for definitions because it may
+ introduce an alias symbol that would not be globally unique for
+ mere references. The _set_symbol_version macro is used to define
+ default_symbol_version and compat_symbol. */
+
#ifdef __ASSEMBLER__
# define symbol_version_reference(real, name, version) \
.symver real, name##@##version
-#else /* !__ASSEMBLER__ */
+#else
# define symbol_version_reference(real, name, version) \
__asm__ (".symver " #real "," #name "@" #version)
-#endif
+#endif /* !__ASSEMBLER__ */
+
+#if SYMVER_NEEDS_ALIAS
+/* If the assembler cannot support multiple versions for the same
+ symbol, introduce __SInnn_ aliases to which the symbol version is
+ attached. */
+# define __symbol_version_unique_concat(x, y) __SI ## x ## _ ## y
+# define _symbol_version_unique_concat(x, y) \
+ __symbol_version_unique_concat (x, y)
+# define _symbol_version_unique_alias(name) \
+ _symbol_version_unique_concat (name, __COUNTER__)
+# ifdef __ASSEMBLER__
+# define _set_symbol_version_2(real, alias, name_version) \
+ .globl alias ASM_LINE_SEP \
+ .equiv alias, real ASM_LINE_SEP \
+ .symver alias, name_version
+# else
+# define _set_symbol_version_2(real, alias, name_version) \
+ __asm__ (".globl " #alias "\n\t" \
+ ".equiv " #alias ", " #real "\n\t" \
+ ".symver " #alias "," name_version)
+# endif
+# define _set_symbol_version_1(real, alias, name_version) \
+ _set_symbol_version_2 (real, alias, name_version)
+/* REAL must be globally unique, so that the counter also produces
+ globally unique symbols. */
+# define _set_symbol_version(real, name_version) \
+ _set_symbol_version_1 (real, _symbol_version_unique_alias (real), \
+ name_version)
+# else /* !SYMVER_NEEDS_ALIAS */
+# ifdef __ASSEMBLER__
+# define _set_symbol_version(real, name_version) \
+ .symver real, name_version
+# else
+# define _set_symbol_version(real, name_version) \
+ __asm__ (".symver " #real "," name_version)
+# endif
+#endif /* !SYMVER_NEEDS_ALIAS */
+
#endif /* _LIBC_SYMVER_H */
--- /dev/null
+/* Symbol version management. ia64 version.
+ Copyright (C) 2021 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#ifndef _LIBC_SYMVER_H
+
+#include <sysdeps/generic/libc-symver.h>
+
+/* ia64 recognizes loc1 as a register name. Add the # suffix to all
+ symbol references. */
+#if !defined (__ASSEMBLER__) && SYMVER_NEEDS_ALIAS
+#undef _set_symbol_version_2
+# define _set_symbol_version_2(real, alias, name_version) \
+ __asm__ (".globl " #alias "#\n\t" \
+ ".equiv " #alias ", " #real "#\n\t" \
+ ".symver " #alias "#," name_version)
+#endif
+
+#endif /* _LIBC_SYMVER_H */
/* clock_getcpuclockid moved to libc in version 2.17;
old binaries may expect the symbol version it had in librt. */
#if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_17)
-strong_alias (__clock_getcpuclockid, __clock_getcpuclockid_2);
-compat_symbol (libc, __clock_getcpuclockid_2, clock_getcpuclockid, GLIBC_2_2);
+compat_symbol (libc, __clock_getcpuclockid, clock_getcpuclockid, GLIBC_2_2);
#endif
/* clock_getres moved to libc in version 2.17;
old binaries may expect the symbol version it had in librt. */
#if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_17)
-strong_alias (__clock_getres, __clock_getres_2);
-compat_symbol (libc, __clock_getres_2, clock_getres, GLIBC_2_2);
+compat_symbol (libc, __clock_getres, clock_getres, GLIBC_2_2);
#endif
stub_warning (clock_getres)
/* clock_gettime moved to libc in version 2.17;
old binaries may expect the symbol version it had in librt. */
#if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_17)
-strong_alias (__clock_gettime, __clock_gettime_2);
-compat_symbol (libc, __clock_gettime_2, clock_gettime, GLIBC_2_2);
+compat_symbol (libc, __clock_gettime, clock_gettime, GLIBC_2_2);
#endif
stub_warning (clock_gettime)
/* clock_nanosleep moved to libc in version 2.17;
old binaries may expect the symbol version it had in librt. */
#if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_17)
-strong_alias (__clock_nanosleep, __clock_nanosleep_2);
-compat_symbol (libc, __clock_nanosleep_2, clock_nanosleep, GLIBC_2_2);
+compat_symbol (libc, __clock_nanosleep, clock_nanosleep, GLIBC_2_2);
#endif
stub_warning (clock_nanosleep)
/* clock_settime moved to libc in version 2.17;
old binaries may expect the symbol version it had in librt. */
#if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_17)
-strong_alias (__clock_settime, __clock_settime_2);
-compat_symbol (libc, __clock_settime_2, clock_settime, GLIBC_2_2);
+compat_symbol (libc, __clock_settime, clock_settime, GLIBC_2_2);
#endif
stub_warning (clock_settime)