From patchwork Thu Oct 30 15:13:35 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joseph Myers X-Patchwork-Id: 405072 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id D97AF14009D for ; Fri, 31 Oct 2014 02:13:55 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:mime-version:content-type; q=dns; s=default; b=aL//wvW1dqqcylhepnQsccvs0HeY5MkDK6SWnJ4hXu2cvara+9 xHxPBkv+e6UOR+4iR9GxKhVntyO2hdaXPKOSt1FlqxsXqMwe1unnM8YbY/GuzBVA QtCI9julNzDPYwxCP5ovN2ZElFSQtsJ8gEzI44A9wdHr0ReVewfMxJ9TU= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:mime-version:content-type; s= default; bh=zM8MXz8wcH/j1XSqwlPCtASji9I=; b=Nm/VxTrtIu2AHt+JSdtG QShliowXaa42pOciJp/01VnP3uAk0SMVrc6bc9in19l7JBkUDlhGz7QOT2gDd2lG bjgD9vNz+3/hiM6uMa3JjNT30+bfqs1YFdl7Z0f+1pOgQo3Oy2bVTz+Da8+HOJr2 V4o7hT2AsU6iC7bdimOa9wI= Received: (qmail 2178 invoked by alias); 30 Oct 2014 15:13:48 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 2160 invoked by uid 89); 30 Oct 2014 15:13:47 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.2 X-HELO: relay1.mentorg.com Received: from relay1.mentorg.com (HELO relay1.mentorg.com) (192.94.38.131) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 30 Oct 2014 15:13:42 +0000 Received: from nat-ies.mentorg.com ([192.94.31.2] helo=SVR-IES-FEM-01.mgc.mentorg.com) by relay1.mentorg.com with esmtp id 1XjrPu-0005Wh-Dp from joseph_myers@mentor.com ; Thu, 30 Oct 2014 08:13:38 -0700 Received: from digraph.polyomino.org.uk (137.202.0.76) by SVR-IES-FEM-01.mgc.mentorg.com (137.202.0.104) with Microsoft SMTP Server id 14.3.181.6; Thu, 30 Oct 2014 15:13:36 +0000 Received: from jsm28 (helo=localhost) by digraph.polyomino.org.uk with local-esmtp (Exim 4.82) (envelope-from ) id 1XjrPr-00087h-9f; Thu, 30 Oct 2014 15:13:35 +0000 Date: Thu, 30 Oct 2014 15:13:35 +0000 From: "Joseph S. Myers" To: CC: Subject: Make soft-fp symbols into compat symbols for powerpc*-*-linux* Message-ID: MIME-Version: 1.0 Continuing preparations for implementing TARGET_ATOMIC_ASSIGN_EXPAND_FENV for powerpc*-*-linux* soft-float and e500, this patch makes soft-fp symbols used for those targets into compat symbols when building with glibc >= 2.19, so that they are only in shared libgcc for existing binaries requiring them, not in static libgcc and not available for new links using shared libgcc. Instead, new links will get the symbols from libc, which has exported all of them since 2.19. (Actually all the symbols were exported from glibc since 2.4, but some of them were exported by glibc as compat symbols only - because of a confusion between deliberately present soft-fp symbols and old accidental reexports of libgcc functions from glibc 2.0 - until 2.19.) This allows user floating-point arithmetic to interoperate properly with the state handled by functions, whether software state (for soft-float; TLS variables that don't form a public part of glibc's ABI, so can only be accessed directly by functions within glibc) or hardware state (for e500 - the copies of the soft-fp functions in glibc being built to interoperate with the hardware state whereas those in libgcc aren't). Previously only glibc's own functions, and those operations done in hardware on e500, properly worked with that state, not direct floating-point arithmetic operations that were implemented in software. The intended next step is the actual TARGET_ATOMIC_ASSIGN_EXPAND_FENV implementation. The test of glibc >= 2.19 uses the same --with-glibc-version configure option as in the gcc/ directory (but differently implemented; in gcc/ the fallback is to examine headers to find the version, while in libgcc/ we can use compile for the target and so use AC_COMPUTE_INT). The TARGET_ATOMIC_ASSIGN_EXPAND_FENV implementation will also only do anything for glibc >= 2.19, as it will depend on generating calls to functions __atomic_feholdexcept __atomic_feclearexcept __atomic_feupdateenv that were added in 2.19 for that purpose (even for e500, inline code is not readily possible because of the need to make prctl syscalls from the implementation of these functions). In order to make symbols compat symbols, the soft-fp files need wrapping with generated wrappers including asm .symver directives, which need to name the symbol version in question. This is extracted by an awk script from an intermediate stage of generating the .map file for linking libgcc (that .map itself depends on the objects that go into the library, so can't be used for this purpose as that would mean a circular dependency); the extraction is not fully general regarding the features available in .map generation, but suffices for the present purpose. It would make sense for hardfp.c symbols to be compat symbols as well (in the cases where hardfp.c gets used, the functions in question should not be used for new links), but this isn't required for the present purpose, which is only concerned with ensuring that where functions that should be affected by rounding modes or exceptions get used, those functions are actually affected by those rounding modes or exceptions. Tested with no regressions with cross to powerpc-linux-gnu (soft-float); c11-atomic-exec-5.c moves from UNSUPPORTED to FAIL, as expected, now that floating-point arithmetic in user programs uses the same state as functions, so the fenv_exceptions test passes, but TARGET_ATOMIC_ASSIGN_EXPAND_FENV isn't yet implemented. (For e500, c11-atomic-exec-5.c was already FAILing, as enough operations worked with the hardware state for the fenv_exceptions effective target test to pass.) Also verified that the exported symbols and versions are unchanged, with the expected symbols becoming compat symbols at the same versions, and that with --with-glibc-version=2.18 the symbols remain normal rather than compat symbols. OK to commit? 2014-10-30 Joseph Myers * 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. Index: libgcc/Makefile.in =================================================================== --- libgcc/Makefile.in (revision 216835) +++ libgcc/Makefile.in (working copy) @@ -922,12 +922,16 @@ # 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 Index: libgcc/config/t-softfp =================================================================== --- libgcc/config/t-softfp (revision 216835) +++ libgcc/config/t-softfp (working copy) @@ -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,10 +83,27 @@ 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): @@ -87,6 +110,9 @@ 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 Index: libgcc/config/t-softfp-compat =================================================================== --- libgcc/config/t-softfp-compat (revision 0) +++ libgcc/config/t-softfp-compat (working copy) @@ -0,0 +1 @@ +softfp_compat := y Index: libgcc/config.host =================================================================== --- libgcc/config.host (revision 216835) +++ libgcc/config.host (working copy) @@ -998,13 +998,13 @@ 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 Index: libgcc/configure =================================================================== --- libgcc/configure (revision 216835) +++ libgcc/configure (working copy) @@ -666,6 +666,7 @@ 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 @@ --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 @@ $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 "; then : + +else + glibc_version_major=0 +fi + +if ac_fn_c_compute_int "$LINENO" "__GLIBC_MINOR__" "glibc_version_minor" "#include "; 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 @@ 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 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 Index: libgcc/configure.ac =================================================================== --- libgcc/configure.ac (revision 216835) +++ libgcc/configure.ac (working copy) @@ -320,6 +320,25 @@ [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 ], + [glibc_version_major=0]) +AC_COMPUTE_INT([glibc_version_minor], [__GLIBC_MINOR__], + [#include ], + [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 @@ 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 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 Index: libgcc/find-symver.awk =================================================================== --- libgcc/find-symver.awk (revision 0) +++ libgcc/find-symver.awk (working copy) @@ -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 +# . + +/^[A-Z]/ { + version = $1; + next; +} + +$1 == symbol { + print version + exit +}