@@ -12,12 +12,12 @@ __vwarn_internal (const char *format, __gnuc_va_list ap,
# ifndef _ISOMAC
-libc_hidden_proto (warn)
-libc_hidden_proto (warnx)
-libc_hidden_proto (vwarn)
-libc_hidden_proto (vwarnx)
-libc_hidden_proto (verr)
-libc_hidden_proto (verrx)
+libc_hidden_ldbl_proto (warn)
+libc_hidden_ldbl_proto (warnx)
+libc_hidden_ldbl_proto (vwarn)
+libc_hidden_ldbl_proto (vwarnx)
+libc_hidden_ldbl_proto (verr)
+libc_hidden_ldbl_proto (verrx)
# endif /* !_ISOMAC */
#endif /* err.h */
@@ -9,13 +9,23 @@
/* Now define the internal interfaces. */
+/* Take a little more care when redirecting internal only symbols. Anything
+ internal to libc should redirect to internal function name. */
+# if __LONG_DOUBLE_USES_FLOAT128 == 1 && IS_IN (libc)
+# define stdio_hidden_ldbl_proto(p, f) \
+ extern __typeof (p ## f) p ## f __asm (__ASMNAME ("___ieee128_" #f));
+# elif __LONG_DOUBLE_USES_FLOAT128 == 1
+# define stdio_hidden_ldbl_proto(p,f) __LDBL_REDIR1_DECL (p ## f, p ## f ## ieee128)
+# else
+# define stdio_hidden_ldbl_proto(p,f) libc_hidden_proto (p ## f)
+# endif
+
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
+stdio_hidden_ldbl_proto (__, snprintf)
+
extern int __vfscanf (FILE *__restrict __s,
const char *__restrict __format,
__gnuc_va_list __arg)
@@ -66,6 +76,7 @@ extern int __isoc99_vscanf (const char *__restrict __format,
extern int __isoc99_vsscanf (const char *__restrict __s,
const char *__restrict __format,
__gnuc_va_list __arg) __THROW;
+
libc_hidden_proto (__isoc99_sscanf)
libc_hidden_proto (__isoc99_vsscanf)
libc_hidden_proto (__isoc99_vfscanf)
@@ -74,12 +85,25 @@ 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) \
- && __LONG_DOUBLE_USES_FLOAT128 == 0
+# if !__GLIBC_USE (DEPRECATED_SCANF)
# undef sscanf
# define sscanf __isoc99_sscanf
# endif
+# if __LONG_DOUBLE_USES_FLOAT128 == 1 && IS_IN (libc)
+/* These are implemented as redirects to other public API.
+ Therefore, the usual redirection fails to avoid PLT. */
+extern __typeof (__isoc99_sscanf) ___ieee128_isoc99_sscanf __THROW;
+extern __typeof (__isoc99_vsscanf) ___ieee128_isoc99_vsscanf __THROW;
+extern __typeof (__isoc99_vfscanf) ___ieee128_isoc99_vfscanf __THROW;
+libc_hidden_proto (___ieee128_isoc99_sscanf)
+libc_hidden_proto (___ieee128_isoc99_vsscanf)
+libc_hidden_proto (___ieee128_isoc99_vfscanf)
+#define __isoc99_sscanf ___ieee128_isoc99_sscanf
+#define __isoc99_vsscanf ___ieee128_isoc99_vsscanf
+#define __isoc99_vfscanf ___ieee128_isoc99_vfscanf
+# endif
+
/* Prototypes for compatibility functions. */
extern FILE *__new_tmpfile (void);
extern FILE *__old_tmpfile (void);
@@ -153,9 +177,8 @@ 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
+libc_hidden_ldbl_proto (__asprintf)
+
# if IS_IN (libc)
extern FILE *_IO_new_fopen (const char*, const char*);
# define fopen(fname, mode) _IO_new_fopen (fname, mode)
@@ -178,13 +201,11 @@ extern int _IO_new_fgetpos (FILE *, __fpos_t *);
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
+stdio_hidden_ldbl_proto (__, dprintf)
+libc_hidden_ldbl_proto (dprintf)
+libc_hidden_ldbl_proto (fprintf)
+libc_hidden_ldbl_proto (vfprintf)
+libc_hidden_ldbl_proto (sprintf)
libc_hidden_proto (fwrite)
libc_hidden_proto (perror)
libc_hidden_proto (remove)
@@ -15,4 +15,27 @@ rtld_hidden_proto (__chk_fail)
#endif
+/* If we are using redirects internally to support long double,
+ we need to tweak some macros to ensure the PLT bypass tricks
+ continue to work in libc. */
+#if __LONG_DOUBLE_USES_FLOAT128 == 1 && IS_IN (libc) && defined SHARED
+
+# undef __LDBL_REDIR_DECL
+# define __LDBL_REDIR_DECL(name)
+
+# undef __LDBL_REDIR2_DECL
+# define __LDBL_REDIR2_DECL(name)
+
+# undef __LDBL_REDIR1_DECL
+# define __LDBL_REDIR1_DECL(name, to)
+
+# define libc_hidden_ldbl_proto(func) \
+ extern __typeof(func) func __asm (__ASMNAME ("__GI____ieee128_" #func)); \
+ extern __typeof(func) ___ieee128_ ## func; \
+ libc_hidden_proto (___ieee128_ ## func);
+
+#else
+# define libc_hidden_ldbl_proto(func) libc_hidden_proto (func)
+#endif
+
#endif
@@ -3,7 +3,7 @@
#include <misc/sys/syslog.h>
#ifndef _ISOMAC
-libc_hidden_proto (syslog)
+libc_hidden_ldbl_proto (syslog)
/* __vsyslog_internal uses the same mode_flags bits as
__v*printf_internal; see libio/libioP.h. */
@@ -64,7 +64,7 @@ libc_hidden_proto (__wcstoul_internal)
libc_hidden_proto (__wcstoull_internal)
libc_hidden_proto (wcstof)
libc_hidden_proto (wcstod)
-libc_hidden_proto (wcstold)
+libc_hidden_ldbl_proto (wcstold)
libc_hidden_proto (wcstol)
libc_hidden_proto (wcstoll)
libc_hidden_proto (wcstoul)
@@ -20,7 +20,7 @@
#include <libio/libioP.h>
extern int
-___ieee128_asprintf (char **string_ptr, const char *format, ...)
+___ieee128___asprintf (char **string_ptr, const char *format, ...)
{
va_list ap;
int done;
@@ -32,4 +32,5 @@ ___ieee128_asprintf (char **string_ptr, const char *format, ...)
return done;
}
-strong_alias (___ieee128_asprintf, __asprintfieee128)
+hidden_def (___ieee128___asprintf)
+strong_alias (___ieee128___asprintf, __asprintfieee128)
@@ -32,3 +32,4 @@ ___ieee128_dprintf (int d, const char *format, ...)
return done;
}
strong_alias (___ieee128_dprintf, __dprintfieee128)
+hidden_def (___ieee128_dprintf);
@@ -91,3 +91,10 @@ IEEE128_DECL (errx) (int status, const char *format, ...)
VA (verrx (status, format, ap))
}
IEEE128_ALIAS (errx)
+
+hidden_def (___ieee128_warn)
+hidden_def (___ieee128_warnx)
+hidden_def (___ieee128_vwarn)
+hidden_def (___ieee128_vwarnx)
+hidden_def (___ieee128_verr)
+hidden_def (___ieee128_verrx)
@@ -32,3 +32,4 @@ ___ieee128_fprintf (FILE *fp, const char *format, ...)
return done;
}
strong_alias (___ieee128_fprintf, __fprintfieee128)
+hidden_def (___ieee128_fprintf)
@@ -37,3 +37,4 @@ ___ieee128_isoc99_sscanf (const char *string, const char *format, ...)
return done;
}
strong_alias (___ieee128_isoc99_sscanf, __isoc99_sscanfieee128)
+hidden_def (___ieee128_isoc99_sscanf)
@@ -17,6 +17,7 @@
<https://www.gnu.org/licenses/>. */
#include <libio/libioP.h>
+#include <stdio.h>
extern int
___ieee128_isoc99_vfscanf (FILE *fp, const char *format, va_list ap)
@@ -25,3 +26,4 @@ ___ieee128_isoc99_vfscanf (FILE *fp, const char *format, va_list ap)
return __vfscanf_internal (fp, format, ap, mode_flags);
}
strong_alias (___ieee128_isoc99_vfscanf, __isoc99_vfscanfieee128)
+hidden_def (___ieee128_isoc99_vfscanf)
@@ -28,3 +28,4 @@ ___ieee128_isoc99_vsscanf (const char *string, const char *format, va_list ap)
return __vfscanf_internal (fp, format, ap, mode_flags);
}
strong_alias (___ieee128_isoc99_vsscanf, __isoc99_vsscanfieee128)
+hidden_def (___ieee128_isoc99_vsscanf)
@@ -33,3 +33,4 @@ ___ieee128_sprintf (char *s, const char *format, ...)
return done;
}
strong_alias (___ieee128_sprintf, __sprintfieee128)
+hidden_def (___ieee128_sprintf)
@@ -30,6 +30,7 @@ ___ieee128_syslog (int pri, const char *fmt, ...)
va_end (ap);
}
strong_alias (___ieee128_syslog, __syslogieee128)
+hidden_def (___ieee128_syslog)
void
___ieee128_vsyslog (int pri, const char *fmt, va_list ap)
@@ -24,3 +24,4 @@ ___ieee128_vfprintf (FILE *fp, const char *format, va_list ap)
return __vfprintf_internal (fp, format, ap, PRINTF_LDBL_USES_FLOAT128);
}
strong_alias (___ieee128_vfprintf, __vfprintfieee128)
+hidden_def (___ieee128_vfprintf)
@@ -1,5 +1,5 @@
#include_next <bits/iscanonical.h>
-#ifndef _ISOMAC
+#if !defined _ISOMAC && (__LONG_DOUBLE_USES_FLOAT128 == 0)
libm_hidden_proto (__iscanonicall)
#endif