From patchwork Fri Feb 14 16:10:51 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Paul E. Murphy" X-Patchwork-Id: 1238155 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-109745-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.vnet.ibm.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.a=rsa-sha1 header.s=default header.b=AsXcOWnh; dkim-atps=neutral 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 48Jz0g5QRyz9sV4 for ; Sat, 15 Feb 2020 03:12:03 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; q=dns; s= default; b=pMsS7RbC4R3vk1c+WrirLk7rB943hBjB2jjzeV6+WVy9ell7hc01r rhvYqQBibDsU2G1WaGfU9GbKsTY5Pc8rygRBdVzqouUbpuMjeigN3gRrzWfO7AnD 0Hd8VM2ICexmcvFiZXGGRRBXcbvm7YIolCW34oOAOdEllopkXTkTMI= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; s=default; bh=BCLmfEuiI69BAQGqbUvYupiZN6M=; b=AsXcOWnh6Fjr0E8iyuowZSxsf6dE yrPuuAneYWEFNfTNGImTWIaZNnE263OuaKR+zD4gahk19gSe/KKwqTOgSNgEgW1q dwEtG777Gz6Lo01LqsGvRPg/Olspxmfd1PIo9PDg6/VXxBtKi0ApFKTmAwGVXOxp aJSTqoPlEbQsxR8= Received: (qmail 63317 invoked by alias); 14 Feb 2020 16:11:07 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 63210 invoked by uid 89); 14 Feb 2020 16:11:07 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.4 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.1 spammy=pf, bridge, sk:__gi___, sk:__GI___ X-HELO: mx0a-001b2d01.pphosted.com From: "Paul E. Murphy" To: libc-alpha@sourceware.org Subject: [PATCH 7/7] RFC: ldbl-128ibm-compat: PLT redirects for using ldbl redirects internally Date: Fri, 14 Feb 2020 10:10:51 -0600 Message-Id: <20200214161051.32579-8-murphyp@linux.vnet.ibm.com> In-Reply-To: <20200214161051.32579-1-murphyp@linux.vnet.ibm.com> References: <20200214161051.32579-1-murphyp@linux.vnet.ibm.com> MIME-Version: 1.0 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 asprintf 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 --- include/err.h | 12 ++--- include/stdio.h | 51 +++++++++++++------ include/sys/cdefs.h | 23 +++++++++ include/sys/syslog.h | 2 +- include/wchar.h | 2 +- .../ldbl-128ibm-compat/ieee128-asprintf.c | 5 +- .../ldbl-128ibm-compat/ieee128-dprintf.c | 1 + .../ieee754/ldbl-128ibm-compat/ieee128-err.c | 7 +++ .../ldbl-128ibm-compat/ieee128-fprintf.c | 1 + .../ieee128-isoc99_sscanf.c | 1 + .../ieee128-isoc99_vfscanf.c | 2 + .../ieee128-isoc99_vsscanf.c | 1 + .../ldbl-128ibm-compat/ieee128-sprintf.c | 1 + .../ldbl-128ibm-compat/ieee128-syslog.c | 1 + .../ldbl-128ibm-compat/ieee128-vfprintf.c | 1 + .../ldbl-128ibm/include/bits/iscanonical.h | 2 +- 16 files changed, 87 insertions(+), 26 deletions(-) diff --git a/include/err.h b/include/err.h index 7c05cd1dbb..b9b7516287 100644 --- a/include/err.h +++ b/include/err.h @@ -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 */ diff --git a/include/stdio.h b/include/stdio.h index dffa7765dd..ab3d375ec7 100644 --- a/include/stdio.h +++ b/include/stdio.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) diff --git a/include/sys/cdefs.h b/include/sys/cdefs.h index 524fe57a25..ae5802e744 100644 --- a/include/sys/cdefs.h +++ b/include/sys/cdefs.h @@ -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 diff --git a/include/sys/syslog.h b/include/sys/syslog.h index 89d3479ebc..44422eab13 100644 --- a/include/sys/syslog.h +++ b/include/sys/syslog.h @@ -3,7 +3,7 @@ #include #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. */ diff --git a/include/wchar.h b/include/wchar.h index c792b38943..617906eb14 100644 --- a/include/wchar.h +++ b/include/wchar.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) diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-asprintf.c b/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-asprintf.c index 68cafbb2fa..2a6ed2f813 100644 --- a/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-asprintf.c +++ b/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-asprintf.c @@ -20,7 +20,7 @@ #include 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) diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-dprintf.c b/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-dprintf.c index 9dc65309bd..87440c9850 100644 --- a/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-dprintf.c +++ b/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-dprintf.c @@ -32,3 +32,4 @@ ___ieee128_dprintf (int d, const char *format, ...) return done; } strong_alias (___ieee128_dprintf, __dprintfieee128) +hidden_def (___ieee128_dprintf); diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-err.c b/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-err.c index eae071b9c4..f81d3edcbf 100644 --- a/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-err.c +++ b/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-err.c @@ -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) diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-fprintf.c b/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-fprintf.c index e1c989643e..b05e6f1bc6 100644 --- a/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-fprintf.c +++ b/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-fprintf.c @@ -32,3 +32,4 @@ ___ieee128_fprintf (FILE *fp, const char *format, ...) return done; } strong_alias (___ieee128_fprintf, __fprintfieee128) +hidden_def (___ieee128_fprintf) diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_sscanf.c b/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_sscanf.c index bfc7270a78..cd1c9fa333 100644 --- a/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_sscanf.c +++ b/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_sscanf.c @@ -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) diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_vfscanf.c b/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_vfscanf.c index b561fa3044..2a11f49ea6 100644 --- a/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_vfscanf.c +++ b/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_vfscanf.c @@ -17,6 +17,7 @@ . */ #include +#include 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) diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_vsscanf.c b/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_vsscanf.c index bef6ebcce0..d976cdbe1f 100644 --- a/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_vsscanf.c +++ b/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-isoc99_vsscanf.c @@ -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) diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-sprintf.c b/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-sprintf.c index 52088cd576..690dc3abf1 100644 --- a/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-sprintf.c +++ b/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-sprintf.c @@ -33,3 +33,4 @@ ___ieee128_sprintf (char *s, const char *format, ...) return done; } strong_alias (___ieee128_sprintf, __sprintfieee128) +hidden_def (___ieee128_sprintf) diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-syslog.c b/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-syslog.c index 914f24aebd..4af546326c 100644 --- a/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-syslog.c +++ b/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-syslog.c @@ -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) diff --git a/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-vfprintf.c b/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-vfprintf.c index 234cd9de8d..b407eae969 100644 --- a/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-vfprintf.c +++ b/sysdeps/ieee754/ldbl-128ibm-compat/ieee128-vfprintf.c @@ -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) diff --git a/sysdeps/ieee754/ldbl-128ibm/include/bits/iscanonical.h b/sysdeps/ieee754/ldbl-128ibm/include/bits/iscanonical.h index bee080bd29..8cbd6f74bf 100644 --- a/sysdeps/ieee754/ldbl-128ibm/include/bits/iscanonical.h +++ b/sysdeps/ieee754/ldbl-128ibm/include/bits/iscanonical.h @@ -1,5 +1,5 @@ #include_next -#ifndef _ISOMAC +#if !defined _ISOMAC && (__LONG_DOUBLE_USES_FLOAT128 == 0) libm_hidden_proto (__iscanonicall) #endif