aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libgcc/ChangeLog20
-rw-r--r--libgcc/Makefile.in10
-rw-r--r--libgcc/config.host6
-rw-r--r--libgcc/config/t-softfp34
-rw-r--r--libgcc/config/t-softfp-compat1
-rw-r--r--libgcc/configure49
-rw-r--r--libgcc/configure.ac33
-rw-r--r--libgcc/find-symver.awk28
8 files changed, 171 insertions, 10 deletions
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index eb83460..073ed11 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -1,3 +1,23 @@
+2014-10-30 Joseph Myers <joseph@codesourcery.com>
+
+ * Makefile.in (libgcc.map.in): New target.
+ (libgcc.map): Use libgcc.map.in.
+ * config/t-softfp (softfp_compat): New variable to be set by
+ users.
+ [$(softfp_compat) = y] (softfp_map_dep, softfp_set_symver): New
+ variables.
+ [$(softfp_compat) = y] (softfp_file_list): Use files in the build
+ directory.
+ [$(softfp_compat) = y] ($(softfp_file_list)): Generate wrappers
+ that use compat symbols and disable all code unless [SHARED].
+ * config/t-softfp-compat: New file.
+ * find-symver.awk: New file.
+ * configure.ac (--with-glibc-version): New configure option.
+ (ppc_fp_compat): New variable set for powerpc*-*-linux*.
+ * configure: Regenerate.
+ * config.host (powerpc*-*-linux*): Use ${ppc_fp_compat} for
+ soft-float and e500.
+
2014-10-29 Joseph Myers <joseph@codesourcery.com>
* config/t-hardfp (hardfp_exclusions): Document new variable for
diff --git a/libgcc/Makefile.in b/libgcc/Makefile.in
index 4008a85..357e15c 100644
--- a/libgcc/Makefile.in
+++ b/libgcc/Makefile.in
@@ -922,12 +922,16 @@ ifeq ($(enable_shared),yes)
# Map-file generation.
ifneq ($(SHLIB_MKMAP),)
-libgcc.map: $(SHLIB_MKMAP) $(SHLIB_MAPFILES) $(libgcc-s-objects)
- { $(NM) $(SHLIB_NM_FLAGS) $(libgcc-s-objects); echo %%; \
- cat $(SHLIB_MAPFILES) \
+libgcc.map.in: $(SHLIB_MAPFILES)
+ { cat $(SHLIB_MAPFILES) \
| sed -e '/^[ ]*#/d' \
-e 's/^%\(if\|else\|elif\|endif\|define\)/#\1/' \
| $(gcc_compile_bare) -E -xassembler-with-cpp -; \
+ } > tmp-$@
+ mv tmp-$@ $@
+libgcc.map: $(SHLIB_MKMAP) libgcc.map.in $(libgcc-s-objects)
+ { $(NM) $(SHLIB_NM_FLAGS) $(libgcc-s-objects); echo %%; \
+ cat libgcc.map.in; \
} | $(AWK) -f $(SHLIB_MKMAP) $(SHLIB_MKMAP_OPTS) > tmp-$@
mv tmp-$@ $@
libgcc_s$(SHLIB_EXT): libgcc.map
diff --git a/libgcc/config.host b/libgcc/config.host
index 6d0fccd..f3cc276 100644
--- a/libgcc/config.host
+++ b/libgcc/config.host
@@ -998,13 +998,13 @@ powerpc*-*-linux*)
tmake_file="${tmake_file} t-hardfp-sfdf t-hardfp"
;;
soft)
- tmake_file="${tmake_file} t-softfp-sfdf t-softfp"
+ tmake_file="${tmake_file} t-softfp-sfdf ${ppc_fp_compat} t-softfp"
;;
e500v1)
- tmake_file="${tmake_file} rs6000/t-e500v1-fp t-softfp t-hardfp"
+ tmake_file="${tmake_file} rs6000/t-e500v1-fp ${ppc_fp_compat} t-softfp t-hardfp"
;;
e500v2)
- tmake_file="${tmake_file} t-hardfp-sfdf rs6000/t-e500v2-fp t-softfp t-hardfp"
+ tmake_file="${tmake_file} t-hardfp-sfdf rs6000/t-e500v2-fp ${ppc_fp_compat} t-softfp t-hardfp"
;;
*)
echo "Unknown ppc_fp_type $ppc_fp_type" 1>&2
diff --git a/libgcc/config/t-softfp b/libgcc/config/t-softfp
index 43e0b4d..e9fece7 100644
--- a/libgcc/config/t-softfp
+++ b/libgcc/config/t-softfp
@@ -35,6 +35,11 @@
# the above settings, also define softfp_extras as a list of those
# functions, e.g. unorddf2.
#
+# If the functions should only be built as compat symbols for shared
+# libgcc, not available for new links, also define:
+#
+# softfp_compat := y
+#
# If the libgcc2.c functions should not be replaced, also define:
#
# softfp_exclude_libgcc2 := y
@@ -52,7 +57,8 @@
# softfp_wrap_end: text to put at the end of wrapper source files,
# e.g. '#endif'
#
-# This is another temporary measure.
+# This is another temporary measure, and cannot be used together with
+# softfp_compat.
softfp_float_funcs = add$(m)3 div$(m)3 eq$(m)2 ge$(m)2 le$(m)2 mul$(m)3 \
neg$(m)2 sub$(m)3 unord$(m)2
@@ -77,16 +83,36 @@ softfp_func_list := $(filter-out floatdidf floatdisf fixunsdfsi fixunssfsi \
floatundidf floatundisf floatundixf floatunditf,$(softfp_func_list))
endif
-ifeq ($(softfp_wrap_start),)
-softfp_file_list := \
- $(addsuffix .c,$(addprefix $(srcdir)/soft-fp/,$(softfp_func_list)))
+ifeq ($(softfp_compat),y)
+softfp_file_list := $(addsuffix .c,$(softfp_func_list))
+
+ifeq ($(enable_shared),yes)
+softfp_map_dep := libgcc.map.in
else
+softfp_map_dep :=
+endif
+softfp_set_symver = echo "asm (\".symver $(1),$(1)@`$(AWK) -f $(srcdir)/find-symver.awk -v symbol=$(1) libgcc.map.in`\");" >> $@
+$(softfp_file_list): $(softfp_map_dep)
+ echo '#ifdef SHARED' > $@
+ echo '#include "soft-fp/$@"' >> $@
+ifeq ($(enable_shared),yes)
+ $(call softfp_set_symver,__$(*F))
+ if grep strong_alias $(srcdir)/soft-fp/$@ > /dev/null; then \
+ alias=`grep strong_alias $(srcdir)/soft-fp/$@ | sed -e 's/.*, *//' -e 's/).*//'`; \
+ $(call softfp_set_symver,$$alias); \
+ fi
+endif
+ echo '#endif' >> $@
+else ifneq ($(softfp_wrap_start),)
softfp_file_list := $(addsuffix .c,$(softfp_func_list))
$(softfp_file_list):
echo $(softfp_wrap_start) > $@
echo '#include "soft-fp/$@"' >> $@
echo $(softfp_wrap_end) >> $@
+else
+softfp_file_list := \
+ $(addsuffix .c,$(addprefix $(srcdir)/soft-fp/,$(softfp_func_list)))
endif
# Disable missing prototype and type limit warnings. The prototypes
diff --git a/libgcc/config/t-softfp-compat b/libgcc/config/t-softfp-compat
new file mode 100644
index 0000000..2afc948
--- /dev/null
+++ b/libgcc/config/t-softfp-compat
@@ -0,0 +1 @@
+softfp_compat := y
diff --git a/libgcc/configure b/libgcc/configure
index 7a154db..3f53aaf 100644
--- a/libgcc/configure
+++ b/libgcc/configure
@@ -666,6 +666,7 @@ enable_decimal_float
with_system_libunwind
enable_sjlj_exceptions
enable_explicit_exception_frame_registration
+with_glibc_version
enable_tls
'
ac_precious_vars='build_alias
@@ -1318,6 +1319,8 @@ Optional Packages:
--with-slibdir=DIR shared libraries in DIR LIBDIR
--with-build-libsubdir=DIR Directory where to find libraries for build system
--with-system-libunwind use installed libunwind
+ --with-glibc-version=M.N
+ assume GCC used with glibc version M.N or later
Some influential environment variables:
CC C compiler command
@@ -4376,6 +4379,38 @@ fi
$as_echo "$libgcc_cv_mips_hard_float" >&6; }
esac
+# Determine the version of glibc, if any, used on the target.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for target glibc version" >&5
+$as_echo_n "checking for target glibc version... " >&6; }
+
+# Check whether --with-glibc-version was given.
+if test "${with_glibc_version+set}" = set; then :
+ withval=$with_glibc_version;
+if echo "$with_glibc_version" | grep '^[0-9][0-9]*\.[0-9][0-9]*$'; then
+ glibc_version_major=`echo "$with_glibc_version" | sed -e 's/\..*//'`
+ glibc_version_minor=`echo "$with_glibc_version" | sed -e 's/.*\.//'`
+else
+ as_fn_error "option --with-glibc-version requires a version number M.N" "$LINENO" 5
+fi
+else
+
+if ac_fn_c_compute_int "$LINENO" "__GLIBC__" "glibc_version_major" "#include <features.h>"; then :
+
+else
+ glibc_version_major=0
+fi
+
+if ac_fn_c_compute_int "$LINENO" "__GLIBC_MINOR__" "glibc_version_minor" "#include <features.h>"; then :
+
+else
+ glibc_version_minor=0
+fi
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibc_version_major.$glibc_version_minor" >&5
+$as_echo "$glibc_version_major.$glibc_version_minor" >&6; }
+
# Determine floating-point type for powerpc*-*-linux*.
# Single-precision-only FPRs are not a supported configuration for
# this target, so are not allowed for in this test.
@@ -4396,6 +4431,20 @@ ppc_fp_type=hard
EOF
eval `${CC-cc} -E conftest.c | grep ppc_fp_type=`
rm -f conftest.c
+# glibc 2.19 and later provide all the soft-fp functions, with proper
+# interactions with <fenv.h> exception and rounding mode handling, so
+# make libgcc's versions into compat symbols if a recent enough glibc
+# version is being used.
+ppc_fp_compat=
+case ${ppc_fp_type} in
+soft|e500v1|e500v2)
+ if test $glibc_version_major -gt 2 \
+ || ( test $glibc_version_major -eq 2 \
+ && test $glibc_version_minor -ge 19 ); then
+ ppc_fp_compat="t-softfp-compat"
+ fi
+ ;;
+esac
;;
esac
diff --git a/libgcc/configure.ac b/libgcc/configure.ac
index 710f15a..79d0ea4 100644
--- a/libgcc/configure.ac
+++ b/libgcc/configure.ac
@@ -320,6 +320,25 @@ mips*-*-*)
[libgcc_cv_mips_hard_float=no])])
esac
+# Determine the version of glibc, if any, used on the target.
+AC_MSG_CHECKING([for target glibc version])
+AC_ARG_WITH([glibc-version],
+ [AS_HELP_STRING([--with-glibc-version=M.N],
+ [assume GCC used with glibc version M.N or later])], [
+if [echo "$with_glibc_version" | grep '^[0-9][0-9]*\.[0-9][0-9]*$']; then
+ glibc_version_major=`echo "$with_glibc_version" | sed -e 's/\..*//'`
+ glibc_version_minor=`echo "$with_glibc_version" | sed -e 's/.*\.//'`
+else
+ AC_MSG_ERROR([option --with-glibc-version requires a version number M.N])
+fi], [
+AC_COMPUTE_INT([glibc_version_major], [__GLIBC__],
+ [#include <features.h>],
+ [glibc_version_major=0])
+AC_COMPUTE_INT([glibc_version_minor], [__GLIBC_MINOR__],
+ [#include <features.h>],
+ [glibc_version_minor=0])])
+AC_MSG_RESULT([$glibc_version_major.$glibc_version_minor])
+
# Determine floating-point type for powerpc*-*-linux*.
# Single-precision-only FPRs are not a supported configuration for
# this target, so are not allowed for in this test.
@@ -340,6 +359,20 @@ ppc_fp_type=hard
EOF
eval `${CC-cc} -E conftest.c | grep ppc_fp_type=`
rm -f conftest.c
+# glibc 2.19 and later provide all the soft-fp functions, with proper
+# interactions with <fenv.h> exception and rounding mode handling, so
+# make libgcc's versions into compat symbols if a recent enough glibc
+# version is being used.
+ppc_fp_compat=
+case ${ppc_fp_type} in
+soft|e500v1|e500v2)
+ if test $glibc_version_major -gt 2 \
+ || ( test $glibc_version_major -eq 2 \
+ && test $glibc_version_minor -ge 19 ); then
+ ppc_fp_compat="t-softfp-compat"
+ fi
+ ;;
+esac
;;
esac
diff --git a/libgcc/find-symver.awk b/libgcc/find-symver.awk
new file mode 100644
index 0000000..adf5ba7
--- /dev/null
+++ b/libgcc/find-symver.awk
@@ -0,0 +1,28 @@
+# Extract the version of a single symbol from the version map.
+# Copyright (C) 2014 Free Software Foundation, Inc.
+#
+# This file is part of GCC.
+#
+# GCC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 3, or (at your option) any later
+# version.
+#
+# GCC 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 General Public
+# License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+/^[A-Z]/ {
+ version = $1;
+ next;
+}
+
+$1 == symbol {
+ print version
+ exit
+}