mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-23 01:33:36 +08:00
ldbl-128ibm-compat: PLT redirects for using ldbl redirects internally
Tweak the PLT bypass magic when building glibc with long double redirects. This is made more difficult by the fact we only get one chance to redirect functions. This happens via the public headers. There are roughly three classes of redirect we need to attend to today: 1. Simple redirects, redirected via cdef macro overrides and and new libc_hidden_ldbl_proto macro. 2. Internal usage of internal API, e.g __snprintf, which has no direct analogue. This is bypassed directly on case-by- case basis. 3. Double redirects, e.g sscanf and related. These require a heavier handed approach of macro renaming to existing symbols. Most simple redirects are handled via 1. Ideally, the libc_* macro would live in libc-symbols.h, but in practice the macros needed for it to do anything useful live in cdefs.h, so they are defined in the local override. Notably, the internal name of the asprintf generated for ieee ldbl redirects is renamed to work with internal prefixed usage. This resolves the local plt usage introduced when building glibc with ldbl == ieee128 on ppc64le. Reviewed-by: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
This commit is contained in:
parent
4eda036f5b
commit
45ae17dd7e
@ -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 */
|
||||
|
@ -885,6 +885,8 @@ for linking")
|
||||
#define libc_hidden_builtin_def(name) libc_hidden_def (name)
|
||||
#define libc_hidden_builtin_weak(name) libc_hidden_weak (name)
|
||||
#define libc_hidden_builtin_ver(local, name) libc_hidden_ver (local, name)
|
||||
|
||||
#define libc_hidden_ldbl_proto(name, attrs...) libc_hidden_proto (name, ##attrs)
|
||||
#ifdef __ASSEMBLER__
|
||||
# define HIDDEN_BUILTIN_JUMPTARGET(name) HIDDEN_JUMPTARGET(name)
|
||||
#endif
|
||||
|
@ -9,13 +9,24 @@
|
||||
|
||||
/* Now define the internal interfaces. */
|
||||
|
||||
/* Some libc_hidden_ldbl_proto's do not map to a unique symbol when
|
||||
redirecting ldouble to _Float128 variants. We can therefore safely
|
||||
directly alias them to their internal 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 +77,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 +86,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 +178,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 +202,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)
|
||||
|
@ -13,6 +13,26 @@ extern void __chk_fail (void) __attribute__ ((__noreturn__));
|
||||
libc_hidden_proto (__chk_fail)
|
||||
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(func) \
|
||||
extern __typeof(func) func __asm (__ASMNAME ("__GI____ieee128_" #func));
|
||||
|
||||
# undef libc_hidden_ldbl_proto
|
||||
# define libc_hidden_ldbl_proto(func, attrs...) \
|
||||
extern __typeof(func) ___ieee128_ ## func; \
|
||||
libc_hidden_proto (___ieee128_ ## func, ##attrs);
|
||||
|
||||
# undef __LDBL_REDIR2_DECL
|
||||
# define __LDBL_REDIR2_DECL(func) \
|
||||
extern __typeof(__ ## func) __ ## func __asm (__ASMNAME ("__GI____ieee128___" #func));
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* !defined _ISOMAC */
|
||||
|
||||
#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
|
||||
|
Loading…
Reference in New Issue
Block a user