summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--sysdeps/powerpc/powerpc64/le/Makefile27
-rw-r--r--sysdeps/powerpc/powerpc64/le/no_ldbl_gnu_attribute.c30
2 files changed, 56 insertions, 1 deletions
diff --git a/sysdeps/powerpc/powerpc64/le/Makefile b/sysdeps/powerpc/powerpc64/le/Makefile
index 96834d3e2b..6afa1228dd 100644
--- a/sysdeps/powerpc/powerpc64/le/Makefile
+++ b/sysdeps/powerpc/powerpc64/le/Makefile
@@ -10,7 +10,32 @@ ifeq ($(ibm128-fcts),yes)
 ibm128-abi-CFLAGS := -mabi=ibmlongdouble
 type-ldouble-CFLAGS += $(ibm128-abi-CFLAGS)
 no-gnu-attribute-CFLAGS = -mno-gnu-attribute
-endif
+
+# This is a very gnarly workaround to static libgcc providing a .gnu.attribute
+# in ibm128 functions.  This is not a bug in static libgcc as normal users
+# should only ever link ibm128 or ieee128 routines, never both.  We are the
+# exception which allows the decision to be deferred to user libraries or
+# applications.
+#
+# We built an object file and extract the desired .gnu.attributes section
+# to be inserted into lib{c,m}.so.
+ifeq ($(build-shared),yes)
+before-compile += $(common-objpfx)no_ldbl_gnu_attribute.bin
+
+$(common-objpfx)no_ldbl_gnu_attribute.bin: $(..)sysdeps/powerpc/powerpc64/le/no_ldbl_gnu_attribute.c
+	$(filter-out $(no-gnu-attribute-CFLAGS),$(compile.c)) -o $(basename $@).o
+	$(OBJCOPY) --dump-section=.gnu.attributes=$@.tmp $(basename $@).o
+	mv $@.tmp $@
+
+define after-link
+if [ ! -z "$(filter libm.so libc.so,$(notdir $1))" ]; then \
+  echo "Replacing .gnu.attributes in $1"; \
+  $(OBJCOPY) --update-section=.gnu.attributes=$(common-objpfx)no_ldbl_gnu_attribute.bin $1; \
+fi
+endef
+
+endif # ifeq ($(build-shared),yes)
+endif # ifeq ($(ibm128-fcts),yes)
 
 # All _Float128 files should be built assuming an ibm128 long double.
 # Likewise, this avoids some old GCC 7 compiler bugs whereby calls
diff --git a/sysdeps/powerpc/powerpc64/le/no_ldbl_gnu_attribute.c b/sysdeps/powerpc/powerpc64/le/no_ldbl_gnu_attribute.c
new file mode 100644
index 0000000000..8ffee30560
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/le/no_ldbl_gnu_attribute.c
@@ -0,0 +1,30 @@
+/* File to generate desired .gnu.attribute section
+   Copyright (C) 2020 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/>.  */
+
+/* This generates a .gnu.attributes sections with
+   the default toolchain settings and an indeterminate
+   long double format.  */
+long double _not_used;
+
+/* Some older GCC versions need a little more convincing to
+   generate .gnu.attributes.  */
+double
+foo (double d)
+{
+  return d;
+}