Do not redirect calls to __GI_* symbols, when redirecting to *ieee128

On platforms where long double has IEEE binary128 format as a third
option (initially, only powerpc64le), many exported functions are
redirected to their __*ieee128 equivalents.  This redirection is
provided by installed headers such as stdio-ldbl.h, and is supposed to
work correctly with user code.

However, during the build of glibc, similar redirections are employed,
in internal headers, such as include/stdio.h, in order to avoid extra
PLT entries.  These redirections conflict with the redirections to
__*ieee128, and must be avoided during the build.  This patch protects
the second redirections with a test for __LONG_DOUBLE_USES_FLOAT128, a
new macro that is defined to 1 when functions that deal with long double
typed values reuses the _Float128 implementation (this is currently only
true for powerpc64le).

Tested for powerpc64le, x86_64, and with build-many-glibcs.py.

Co-authored-by: Gabriel F. T. Gomes <gabrielftg@linux.ibm.com>
Reviewed-by: Florian Weimer <fweimer@redhat.com>
This commit is contained in:
Tulio Magno Quites Machado Filho 2019-10-20 16:00:30 -05:00 committed by Gabriel F. T. Gomes
parent 863d775c48
commit 1ef9b6e0bf
10 changed files with 48 additions and 2 deletions

View File

@ -37,3 +37,4 @@
#ifndef __NO_LONG_DOUBLE_MATH
# define __NO_LONG_DOUBLE_MATH 1
#endif
#define __LONG_DOUBLE_USES_FLOAT128 0

View File

@ -13,7 +13,9 @@ extern int __fcloseall (void) attribute_hidden;
extern int __snprintf (char *__restrict __s, size_t __maxlen,
const char *__restrict __format, ...)
__attribute__ ((__format__ (__printf__, 3, 4)));
# if __LONG_DOUBLE_USES_FLOAT128 == 0
libc_hidden_proto (__snprintf)
# endif
extern int __vfscanf (FILE *__restrict __s,
const char *__restrict __format,
__gnuc_va_list __arg)
@ -72,7 +74,8 @@ libc_hidden_proto (__isoc99_vfscanf)
Unfortunately, symbol redirection is not transitive, so the
__REDIRECT in the public header does not link up with the above
libc_hidden_proto. Bridge the gap with a macro. */
# if !__GLIBC_USE (DEPRECATED_SCANF)
# if !__GLIBC_USE (DEPRECATED_SCANF) \
&& __LONG_DOUBLE_USES_FLOAT128 == 0
# undef sscanf
# define sscanf __isoc99_sscanf
# endif
@ -150,7 +153,9 @@ libc_hidden_proto (__libc_readline_unlocked);
extern const char *const _sys_errlist_internal[] attribute_hidden;
extern int _sys_nerr_internal attribute_hidden;
#if __LONG_DOUBLE_USES_FLOAT128 == 0
libc_hidden_proto (__asprintf)
#endif
# if IS_IN (libc)
extern FILE *_IO_new_fopen (const char*, const char*);
# define fopen(fname, mode) _IO_new_fopen (fname, mode)
@ -171,13 +176,15 @@ extern int _IO_new_fgetpos (FILE *, __fpos_t *);
# define fgetpos(fp, posp) _IO_new_fgetpos (fp, posp)
# endif
libc_hidden_proto (dprintf)
extern __typeof (dprintf) __dprintf
__attribute__ ((__format__ (__printf__, 2, 3)));
libc_hidden_proto (__dprintf)
#if __LONG_DOUBLE_USES_FLOAT128 == 0
libc_hidden_proto (dprintf)
libc_hidden_proto (fprintf)
libc_hidden_proto (vfprintf)
libc_hidden_proto (sprintf)
#endif
libc_hidden_proto (fwrite)
libc_hidden_proto (perror)
libc_hidden_proto (remove)

View File

@ -202,9 +202,12 @@ libc_hidden_proto (____strtoll_l_internal)
libc_hidden_proto (____strtoul_l_internal)
libc_hidden_proto (____strtoull_l_internal)
#include <bits/floatn.h>
libc_hidden_proto (strtof)
libc_hidden_proto (strtod)
#if __LONG_DOUBLE_USES_FLOAT128 == 0
libc_hidden_proto (strtold)
#endif
libc_hidden_proto (strtol)
libc_hidden_proto (strtoll)
libc_hidden_proto (strtoul)

View File

@ -18,3 +18,4 @@
/* long double is distinct from double, so there is nothing to
define here. */
#define __LONG_DOUBLE_USES_FLOAT128 0

View File

@ -0,0 +1,29 @@
/* Properties of long double type. ldbl-opt version.
Copyright (C) 2019 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 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 __NO_LONG_DOUBLE_MATH
# define __LONG_DOUBLE_MATH_OPTIONAL 1
# ifndef __LONG_DOUBLE_128__
# define __NO_LONG_DOUBLE_MATH 1
# endif
#endif
/* On platforms that reuse the _Float128 implementation for IEEE long
double, access to the correct long double functions is selected based
on the long double mode being used during the compilation. On
powerpc64le, this is true when -mabi=ieeelongdouble is in use. */
#define __LONG_DOUBLE_USES_FLOAT128 (__LDBL_MANT_DIG__ == 113)

View File

@ -18,3 +18,4 @@
/* long double is distinct from double, so there is nothing to
define here. */
#define __LONG_DOUBLE_USES_FLOAT128 0

View File

@ -22,3 +22,4 @@
# define __NO_LONG_DOUBLE_MATH 1
# endif
#endif
#define __LONG_DOUBLE_USES_FLOAT128 0

View File

@ -21,3 +21,4 @@
#if !defined __NO_LONG_DOUBLE_MATH && _MIPS_SIM == _ABIO32
# define __NO_LONG_DOUBLE_MATH 1
#endif
#define __LONG_DOUBLE_USES_FLOAT128 0

View File

@ -24,3 +24,4 @@
# define __NO_LONG_DOUBLE_MATH 1
# endif
#endif
#define __LONG_DOUBLE_USES_FLOAT128 0

View File

@ -24,3 +24,4 @@
# define __NO_LONG_DOUBLE_MATH 1
# endif
#endif
#define __LONG_DOUBLE_USES_FLOAT128 0