From patchwork Mon Oct 29 12:16:43 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Gabriel F. T. Gomes" X-Patchwork-Id: 990165 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-96794-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=inconstante.eti.br Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="lQVmOHqj"; 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 42kDB76cD3z9s7T for ; Mon, 29 Oct 2018 23:17:19 +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-type; q=dns; s=default; b=Omsgf wo956wTexk4PCYuziiajNfPcBGGHN/s7CUoqL/byn7ojCfiQ6gOxm6KPGbL2327y rpms4yqq0Z00UMNcIgEy4LXg23SCa+9xi2SAvt7Zi8K3qj9SYacOfoA0SXIX02AJ 5OtK+/9l9+UaZxdAgeDRikcs3yuvVKBqlzTA+k= 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-type; s=default; bh=R9rK2rusFPP OY8/CTztHw2gYZPQ=; b=lQVmOHqjLmmKF1WyT13JbckU6IcHwJ2TdIILLCvpl70 1PcL9HW+ijMIuCfwsZiwXexEsdxDjeWLF4n0C0YwK9jMeeciD4Z7FfDLlTKxiXlF KPSfWsVgwumJafs07kkycT2Fu/S7jgPXQIJAoeLRKOqT5PBxvPlBCdy8lqRCrVTg = Received: (qmail 17215 invoked by alias); 29 Oct 2018 12:17:13 -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 17125 invoked by uid 89); 29 Oct 2018 12:17:12 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-23.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_LAZY_DOMAIN_SECURITY, RCVD_IN_DNSWL_NONE, UNSUBSCRIBE_BODY autolearn=ham version=3.3.2 spammy=contradicts, eight, mflr, switched X-HELO: mo20.mail-out.ovh.net From: "Gabriel F. T. Gomes" To: Subject: [PATCH v2 1/8] Use STRFMON_LDBL_IS_DBL instead of __ldbl_is_dbl. Date: Mon, 29 Oct 2018 09:16:43 -0300 Message-ID: <20181029121650.24544-2-gabriel@inconstante.eti.br> In-Reply-To: <20181029121650.24544-1-gabriel@inconstante.eti.br> References: <20181029121650.24544-1-gabriel@inconstante.eti.br> MIME-Version: 1.0 X-Ovh-Tracer-Id: 18033257337046748867 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: 0 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedtkedrheekgdefjecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemucehtddtnecu From: Zack Weinberg Changed since v1: - Added attribute hidden to __vstrfmon_l_internal. On powerpc, code in the call sites changed: From: $ objdump -d --reloc VISIBLE-glibc/libc.so.6 | grep __nldbl___vstrfmon_l -A 13 001502a0 <__nldbl___vstrfmon_l>: 1502a0: 94 21 ff f0 stwu r1,-16(r1) 1502a4: 39 00 00 01 li r8,1 1502a8: 7c 08 02 a6 mflr r0 1502ac: 42 9f 00 05 bcl 20,4*cr7+so,1502b0 <__nldbl___vstrfmon_l+0x10> 1502b0: 93 c1 00 08 stw r30,8(r1) 1502b4: 90 01 00 14 stw r0,20(r1) 1502b8: 7f c8 02 a6 mflr r30 1502bc: 3f de 00 05 addis r30,r30,5 1502c0: 3b de fd 44 addi r30,r30,-700 1502c4: 4b ef b6 5d bl 4b920 <__vstrfmon_l_internal> 1502c8: 80 01 00 14 lwz r0,20(r1) 1502cc: 83 c1 00 08 lwz r30,8(r1) 1502d0: 38 21 00 10 addi r1,r1,16 1502d4: 7c 08 03 a6 mtlr r0 1502d8: 4e 80 00 20 blr 1502dc: 60 00 00 00 nop To: $ objdump -d --reloc HIDDEN-glibc/libc.so.6 | grep __nldbl___vstrfmon_l -A 5 00150260 <__nldbl___vstrfmon_l>: 150260: 39 00 00 01 li r8,1 150264: 4b ef b6 bc b 4b920 <__vstrfmon_l_internal> 150268: 60 00 00 00 nop 15026c: 60 00 00 00 nop - Replaced blocks of eight spaces with tabs. - Added signed-off-by field with Zack's and mine names. - Extended commit message and comments. -- 8< -- On platforms where long double used to have the same format as double, but later switched to a different format (alpha, s390, sparc, and powerpc), accessing the older behavior is possible and it happens via __nldbl_* functions (not on the API, but accessible from header redirection and from compat symbols). These functions write to the global flag __ldbl_is_dbl, which tells other functions that long double variables should be handled as double. This patch takes the first step towards removing this global flag and creates __vstrfmon_l_internal, which takes an explicit flags parameter. This change arguably makes the generated code slightly worse on architectures where __ldbl_is_dbl is never true; right now, on those architectures, it's a compile-time constant; after this change, the compiler could theoretically prove that __vstrfmon_l_internal was never called with a nonzero flags argument, but it would probably need LTO to do it. This is not performance critical code and I tend to think that the maintainability benefits of removing action at a distance are worth it. However, we _could_ wrap the runtime flag check with a macro that was defined to ignore its argument and always return false on architectures where __ldbl_is_dbl is never true, if people think the codegen benefits are important. Tested for powerpc and powerpc64le. 2018-10-11 Zack Weinberg Gabriel F. T. Gomes * include/monetary.h (STRFMON_LDBL_IS_DBL): New constant. (__vstrfmon_l): Rename to __vstrfmon_l_internal and add flags argument. * stdlib/strfmon_l.c (__vstrfmon_l): Rename to __vstrfmon_l_internal and add flags argument. Check flags instead of __ldbl_is_dbl when deciding whether to set is_long_double. (__strfmon_l): Call __vstrfmon_l_internal instead of __vstrfmon_l, passing zero for flags argument. * stdlib/strfmon.c (strfmon): Same change as made to __strfmon_l. * sysdeps/ieee754/ldbl-opt/nldbl-compat.c (__nldbl___vstrfmon, __nldbl___vstrfmon_l) (__nldbl_strfmon, __nldbl___strfmon_l): Call __vstrfmon_l_internal directly, passing STRFMON_LDBL_IS_DBL for flags argument. Normalize variable names. Remove libc_hidden_def/libc_hidden_proto from __nldbl___vstrfmon and __nldbl___vstrfmon_l, because they are no longer called from within the library. * sysdeps/ieee754/ldbl-opt/nldbl-compat.h: Don't use NLDBL_DECL for __nldbl___vstrfmon_l, declare it explicitly. * manual/locale.texi: Update a reference to vstrfmon_l in comments. Signed-off-by: Zack Weinberg Signed-off-by: Gabriel F. T. Gomes --- include/monetary.h | 12 +++++++++--- manual/locale.texi | 9 +++++---- stdlib/strfmon.c | 3 ++- stdlib/strfmon_l.c | 8 ++++---- sysdeps/ieee754/ldbl-opt/nldbl-compat.c | 34 ++++++++++++--------------------- sysdeps/ieee754/ldbl-opt/nldbl-compat.h | 8 +++++--- 6 files changed, 37 insertions(+), 37 deletions(-) diff --git a/include/monetary.h b/include/monetary.h index c130ed56a3..a226305adf 100644 --- a/include/monetary.h +++ b/include/monetary.h @@ -2,7 +2,13 @@ #ifndef _ISOMAC #include -extern ssize_t __vstrfmon_l (char *s, size_t maxsize, locale_t loc, - const char *format, va_list ap) - attribute_hidden; +extern ssize_t +__vstrfmon_l_internal (char *s, size_t maxsize, locale_t loc, + const char *format, va_list ap, + unsigned int flags) + attribute_hidden; + +/* Flags for __vstrfmon_l_internal. */ +#define STRFMON_LDBL_IS_DBL 0x0001 + #endif diff --git a/manual/locale.texi b/manual/locale.texi index dabb959f9e..720e0ca952 100644 --- a/manual/locale.texi +++ b/manual/locale.texi @@ -1209,10 +1209,11 @@ numbers according to these rules. @deftypefun ssize_t strfmon (char *@var{s}, size_t @var{maxsize}, const char *@var{format}, @dots{}) @safety{@prelim{}@mtsafe{@mtslocale{}}@asunsafe{@ascuheap{}}@acunsafe{@acsmem{}}} -@c It (and strfmon_l) both call vstrfmon_l, which, besides accessing the -@c locale object passed to it, accesses the active locale through -@c isdigit (but to_digit assumes ASCII digits only). It may call -@c __printf_fp (@mtslocale @ascuheap @acsmem) and guess_grouping (safe). +@c It (and strfmon_l) both call __vstrfmon_l_internal, which, besides +@c accessing the locale object passed to it, accesses the active +@c locale through isdigit (but to_digit assumes ASCII digits only). +@c It may call __printf_fp (@mtslocale @ascuheap @acsmem) and +@c guess_grouping (safe). The @code{strfmon} function is similar to the @code{strftime} function in that it takes a buffer, its size, a format string, and values to write into the buffer as text in a form specified diff --git a/stdlib/strfmon.c b/stdlib/strfmon.c index 01980d3e15..3058b3eed1 100644 --- a/stdlib/strfmon.c +++ b/stdlib/strfmon.c @@ -30,7 +30,8 @@ __strfmon (char *s, size_t maxsize, const char *format, ...) va_start (ap, format); - ssize_t res = __vstrfmon_l (s, maxsize, _NL_CURRENT_LOCALE, format, ap); + ssize_t res = __vstrfmon_l_internal (s, maxsize, _NL_CURRENT_LOCALE, + format, ap, 0); va_end (ap); diff --git a/stdlib/strfmon_l.c b/stdlib/strfmon_l.c index cd3796ced9..5293104400 100644 --- a/stdlib/strfmon_l.c +++ b/stdlib/strfmon_l.c @@ -76,8 +76,8 @@ too. Some of the information contradicts the information which can be specified in format string. */ ssize_t -__vstrfmon_l (char *s, size_t maxsize, locale_t loc, const char *format, - va_list ap) +__vstrfmon_l_internal (char *s, size_t maxsize, locale_t loc, + const char *format, va_list ap, unsigned int flags) { struct __locale_data *current = loc->__locales[LC_MONETARY]; _IO_strfile f; @@ -268,7 +268,7 @@ __vstrfmon_l (char *s, size_t maxsize, locale_t loc, const char *format, if (*fmt == 'L') { ++fmt; - if (!__ldbl_is_dbl) + if (__glibc_likely ((flags & STRFMON_LDBL_IS_DBL) == 0)) is_long_double = 1; } @@ -608,7 +608,7 @@ ___strfmon_l (char *s, size_t maxsize, locale_t loc, const char *format, ...) va_start (ap, format); - ssize_t res = __vstrfmon_l (s, maxsize, loc, format, ap); + ssize_t res = __vstrfmon_l_internal (s, maxsize, loc, format, ap, 0); va_end (ap); diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-compat.c b/sysdeps/ieee754/ldbl-opt/nldbl-compat.c index ffb5fabebe..7a1e89c1a3 100644 --- a/sysdeps/ieee754/ldbl-opt/nldbl-compat.c +++ b/sysdeps/ieee754/ldbl-opt/nldbl-compat.c @@ -51,8 +51,6 @@ libc_hidden_proto (__nldbl___vswprintf_chk) libc_hidden_proto (__nldbl___vasprintf_chk) libc_hidden_proto (__nldbl___vdprintf_chk) libc_hidden_proto (__nldbl___obstack_vprintf_chk) -libc_hidden_proto (__nldbl___vstrfmon) -libc_hidden_proto (__nldbl___vstrfmon_l) libc_hidden_proto (__nldbl___isoc99_vsscanf) libc_hidden_proto (__nldbl___isoc99_vfscanf) libc_hidden_proto (__nldbl___isoc99_vswscanf) @@ -780,12 +778,13 @@ attribute_compat_text_section __nldbl_strfmon (char *s, size_t maxsize, const char *format, ...) { va_list ap; - ssize_t res; + ssize_t ret; va_start (ap, format); - res = __nldbl___vstrfmon (s, maxsize, format, ap); + ret = __vstrfmon_l_internal (s, maxsize, _NL_CURRENT_LOCALE, format, ap, + STRFMON_LDBL_IS_DBL); va_end (ap); - return res; + return ret; } ssize_t @@ -794,12 +793,13 @@ __nldbl___strfmon_l (char *s, size_t maxsize, locale_t loc, const char *format, ...) { va_list ap; - ssize_t res; + ssize_t ret; va_start (ap, format); - res = __nldbl___vstrfmon_l (s, maxsize, loc, format, ap); + ret = __vstrfmon_l_internal (s, maxsize, loc, format, ap, + STRFMON_LDBL_IS_DBL); va_end (ap); - return res; + return ret; } weak_alias (__nldbl___strfmon_l, __nldbl_strfmon_l) @@ -807,28 +807,18 @@ ssize_t attribute_compat_text_section __nldbl___vstrfmon (char *s, size_t maxsize, const char *format, va_list ap) { - ssize_t res; - __no_long_double = 1; - res = __vstrfmon_l (s, maxsize, _NL_CURRENT_LOCALE, format, ap); - __no_long_double = 0; - va_end (ap); - return res; + return __vstrfmon_l_internal (s, maxsize, _NL_CURRENT_LOCALE, format, ap, + STRFMON_LDBL_IS_DBL); } -libc_hidden_def (__nldbl___vstrfmon) ssize_t attribute_compat_text_section __nldbl___vstrfmon_l (char *s, size_t maxsize, locale_t loc, const char *format, va_list ap) { - ssize_t res; - __no_long_double = 1; - res = __vstrfmon_l (s, maxsize, loc, format, ap); - __no_long_double = 0; - va_end (ap); - return res; + return __vstrfmon_l_internal (s, maxsize, loc, format, ap, + STRFMON_LDBL_IS_DBL); } -libc_hidden_def (__nldbl___vstrfmon_l) void attribute_compat_text_section diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-compat.h b/sysdeps/ieee754/ldbl-opt/nldbl-compat.h index b7e938f785..b7606c3c2d 100644 --- a/sysdeps/ieee754/ldbl-opt/nldbl-compat.h +++ b/sysdeps/ieee754/ldbl-opt/nldbl-compat.h @@ -64,7 +64,6 @@ NLDBL_DECL (vsyslog); NLDBL_DECL (qecvt); NLDBL_DECL (qfcvt); NLDBL_DECL (qgcvt); -NLDBL_DECL (__vstrfmon_l); NLDBL_DECL (__isoc99_scanf); NLDBL_DECL (__isoc99_fscanf); NLDBL_DECL (__isoc99_sscanf); @@ -78,10 +77,13 @@ NLDBL_DECL (__isoc99_vwscanf); NLDBL_DECL (__isoc99_vfwscanf); NLDBL_DECL (__isoc99_vswscanf); -/* This one does not exist in the normal interface, only - __nldbl___vstrfmon really exists. */ +/* These do not exist in the normal interface, but must exist in the + __nldbl interface so that they can be called from libnldbl. */ extern ssize_t __nldbl___vstrfmon (char *, size_t, const char *, va_list) __THROW; +extern ssize_t __nldbl___vstrfmon_l (char *, size_t, locale_t, const char *, + va_list) + __THROW; /* These don't use __typeof because they were not declared by the headers, since we don't compile with _FORTIFY_SOURCE. */ From patchwork Mon Oct 29 12:16:44 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Gabriel F. T. Gomes" X-Patchwork-Id: 990167 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-96796-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=inconstante.eti.br Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="yELvB63l"; 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 42kDBf6JqGz9s7T for ; Mon, 29 Oct 2018 23:17:46 +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-type; q=dns; s=default; b=LjFIJ FLyTCiGfleo4mNCNMX3EJYJi1k3M5J6NZrCHcCgQP7DkwfSbfkZlBVpoSKU5/tnK 5rqwZMf2oZWGi4/acLIJgQBy+EOqI0wTdzaAildEaJyDvBb5vEW+spsaIn11gSQt kJ6lTCJBm7qsrL4qc2yaQMTSMGJsK8J+Msx3x0= 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-type; s=default; bh=E8msB1GH3EJ 6ykdugfprFoH0saE=; b=yELvB63lLg8fSVMEEZA9zLcFKvV7bo+mfG79MuyoSbP ajsfg7N5ngO6l7B2tEEsZG6Kok+PqEeen6rr0bjEP1VfZ2nLca+xF7Lp2VqeIdJD oYUCLR5tiBWISHr9CUUN4x8woon/m2rCLPAPfCghz5/nh8YvocUVw6qBKCpN9JFQ = Received: (qmail 22678 invoked by alias); 29 Oct 2018 12:17:30 -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 17832 invoked by uid 89); 29 Oct 2018 12:17:18 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-25.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_LAZY_DOMAIN_SECURITY, KAM_SHORT, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.2 spammy=GROUP, temporarily, carefully, exposed X-HELO: mo20.mail-out.ovh.net From: "Gabriel F. T. Gomes" To: Subject: [PATCH v2 2/8] Add __vfscanf_internal and __vfwscanf_internal with flags arguments. Date: Mon, 29 Oct 2018 09:16:44 -0300 Message-ID: <20181029121650.24544-3-gabriel@inconstante.eti.br> In-Reply-To: <20181029121650.24544-1-gabriel@inconstante.eti.br> References: <20181029121650.24544-1-gabriel@inconstante.eti.br> MIME-Version: 1.0 X-Ovh-Tracer-Id: 18033820285211889347 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: 0 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedtkedrheekgdefjecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemucehtddtnecu From: Zack Weinberg Changed since v1: - Added one line comment to new files. - In nldbl-compat.c, added explanation for the need to use '#if SHLIB_COMPAT' within 'if LONG_DOUBLE_COMPAT'. Also moved the block further down, for stylistic reasons [1]. - Added attribute_hidden to the internal (libioP.h) declarations of __vfscanf_internal and __vfwscanf_internal [2]. - Added comment explaining the reason for the use of SHLIB_COMPAT on stdio-common/iovfscanf.c and stdio-common/iovfwscanf.c. - Converted the definition of ldbl_compat_symbol from an expansion of compat_symbol to '...', because ldbl_compat_symbol is also not supposed to be used outside of '#if SHLIB_COMPAT' statements. In my opinion, it's better to make this clear in the definition of ldbl_compat_symbol itself, rather than having to go to the definition of compat_symbol to learn this (if people think that this is not the best option, I can revert this change (In that case, the definition of ldbl_compat_symbol could be moved outside the '#if SHARED' block). Added a comment with this explanation. - Added signed-off-by statements. - Replaced 2.28 with 2.29 to adjust for the next release. Not changed since v1: - Florian suggested that the need for ldbl_compat_symbol is questionable, because we could define LONG_DOUBLE_COMPAT_VERSION to GLIBC_2_0 by default (pretending that the long double transition happened for all other platforms), then use it in compat_symbol calls, which would create the compat symbols for _IO_vfscanf and _IO_vfwscanf with that version. That would work, because all the functions that will use ldbl_compat_symbol after this patch set were actually introduced before GLIBC_2_0. However, for newer functions, such as swscanf, that wouldn't work, if we ever need to do something similar. Additional note for review: - Reviewing the changes from vfscanf.c to vfscanf-internal.c in the original patch would be vey hard, because git doesn't detect the filename change. To make review a little easier, I did as Zack did and manually edited the diff. I'll reply to this thread and attach the original patch if someone wants to apply it. (ping me if I forget it) [1] https://sourceware.org/ml/libc-alpha/2018-03/msg00309.html [2] As a result, internal calls to __vfscanf_internal, on powerpc, do not use the PLT, the following blocks show the difference: Without __attribute__ (hidden): $ objdump -d --reloc VFSCANF-VISIBLE-glibc/libc.so | grep "<__nldbl___vfscanf>" -A 17 0014ea00 <__nldbl___vfscanf>: 14ea00: 94 21 ff f0 stwu r1,-16(r1) 14ea04: 38 c0 00 01 li r6,1 14ea08: 7c 08 02 a6 mflr r0 14ea0c: 42 9f 00 05 bcl 20,4*cr7+so,14ea10 <__nldbl___vfscanf+0x10> 14ea10: 93 c1 00 08 stw r30,8(r1) 14ea14: 90 01 00 14 stw r0,20(r1) 14ea18: 7f c8 02 a6 mflr r30 14ea1c: 3f de 00 05 addis r30,r30,5 14ea20: 3b de 15 e4 addi r30,r30,5604 14ea24: 4b f0 b8 0d bl 5a230 <__vfscanf_internal> 14ea28: 80 01 00 14 lwz r0,20(r1) 14ea2c: 83 c1 00 08 lwz r30,8(r1) 14ea30: 38 21 00 10 addi r1,r1,16 14ea34: 7c 08 03 a6 mtlr r0 14ea38: 4e 80 00 20 blr 14ea3c: 60 00 00 00 nop With __attribute__ (hidden): $ objdump -d --reloc VFSCANF-HIDDEN-glibc/libc.so | grep "<__nldbl___vfscanf>" -A 5 0014e8b0 <__nldbl___vfscanf>: 14e8b0: 38 c0 00 01 li r6,1 14e8b4: 4b f0 b8 bc b 5a170 <__vfscanf_internal> 14e8b8: 60 00 00 00 nop 14e8bc: 60 00 00 00 nop -- 8< -- There are two flags currently defined: SCANF_LDBL_IS_DBL is the mode used by __nldbl_ scanf variants, and SCANF_ISOC99_A is the mode used by __isoc99_ scanf variants. In this patch, the new functions honor these flag bits if they're set, but they still also look at the corresponding bits of environmental state, and callers all pass zero. The new functions do *not* have the "errp" argument possessed by _IO_vfscanf and _IO_vfwscanf. All internal callers passed NULL for that argument. External callers could theoretically exist, so I preserved wrappers, but they are flagged as compat symbols and they don't preserve the three-way distinction among types of errors that was formerly exposed. These functions probably should have been in the list of deprecated _IO_ symbols in 2.27 NEWS -- they're not just aliases for vfscanf and vfwscanf. (It was necessary to introduce ldbl_compat_symbol for _IO_vfscanf. Please check that part of the patch very carefully, I am still not confident I understand all of the details of ldbl-opt.) This patch also introduces helper inlines in libio/strfile.h that encapsulate the process of initializing an _IO_strfile object for reading. This allows us to call __vfscanf_internal directly from sscanf, and __vfwscanf_internal directly from swscanf, without duplicating the initialization code. (Previously, they called their v-counterparts, but that won't work if we want to control *both* C99 mode and ldbl-is-dbl mode using the flags argument to__vfscanf_internal.) It's still a little awkward, especially for wide strfiles, but it's much better than what we had. Tested for powerpc and powerpc64le. 2018-10-16 Zack Weinberg Gabriel F. T. Gomes * libio/libioP.h (SCANF_LDBL_IS_DBL, SCANF_ISOC99_A): New constants. (__vfscanf_internal, __vfwscanf_internal): New function prototypes. * libio/libio.h: Remove libc_hidden_proto for _IO_vfscanf. * libio/strfile.h: Add multiple inclusion guard. (_IO_strfile_read, _IO_strfile_readw): New inline functions. * sysdeps/generic/math_ldbl_opt.h: Include shlib-compat.h, for consistency with the other version of this file. (ldbl_compat_symbol): New macro. * sysdeps/ieee754/ldbl-opt/math_ldbl_opt.h (ldbl_compat_symbol): New macro. * stdio-common/vfscanf-internal.c: Rename from vfscanf.c. Define __vfscanf_internal or __vfwscanf_internal, depending on COMPILE_WSCANF; don't define any other public symbols. Remove errval and code to set errp. Temporarily check __ldbl_is_dbl and _IO_FLAGS2_SCANF_STD as well as the mode_flags argument. (encode_error, conv_error, input_error): Don't set errval. * stdio-common/vfwscanf-internal.c: Rename from vfwscanf.c. Include vfscanf-internal.c. * stdio-common/vfscanf.c: New file defining the public entry point vfscanf, which calls __vfscanf_internal. * stdio-common/vfwscanf.c: New file defining the public entry point vfwscanf, which calls __vfwscanf_internal. * stdio-common/iovfscanf.c: New file. * stdio-common/iovfwscanf.c: Likewise. * stdio-common/Makefile (routines): Add vfscanf-internal, vfwscanf-internal, iovfscanf, iovfwscanf. * stdio-common/Versions: Mention GLIBC_2.29, so that it can be used in SHLIB_COMPAT expressions. * sysdeps/ieee754/ldbl-opt/nldbl-compat.c (__nldbl__IO_vfscanf): Wrap definition and compat_symbol line in #if SHLIB_COMPAT. Call __vfscanf_internal, instead of _IO_vfscanf. (__nldbl___vfscanf): Call __vfscanf_internal, instead of _IO_vfscanf. (__nldbl_vfwscanf): Call __vfwscanf_internal, instead of _IO_vfwscanf. * libio/iovsscanf.c: Clean up includes, when possible. Use _IO_strfile_read or _IO_strfile_readw, when needed. Call __vfscanf_internal or __vfwscanf_internal directly. * libio/iovswscanf.c: Likewise. * libio/swscanf.c: Likewise. * libio/vscanf.c: Likewise. * libio/vwscanf.c: Likewise. * libio/wscanf.c: Likewise. * stdio-common/isoc99_fscanf.c: Likewise. * stdio-common/isoc99_scanf.c: Likewise. * stdio-common/isoc99_sscanf.c: Likewise. * stdio-common/isoc99_vfscanf.c: Likewise. * stdio-common/isoc99_vscanf.c: Likewise. * stdio-common/isoc99_vsscanf.c: Likewise. * stdio-common/scanf.c: Likewise. * stdio-common/sscanf.c: Likewise. * wcsmbs/isoc99_fwscanf.c: Likewise. * wcsmbs/isoc99_swscanf.c: Likewise. * wcsmbs/isoc99_vfwscanf.c: Likewise. * wcsmbs/isoc99_vswscanf.c: Likewise. * wcsmbs/isoc99_vwscanf.c: Likewise. * wcsmbs/isoc99_wscanf.c: Likewise. Signed-off-by: Zack Weinberg Signed-off-by: Gabriel F. T. Gomes Signed-off-by: Zack Weinberg Signed-off-by: Gabriel F. T. Gomes --- libio/iovsscanf.c | 12 +- libio/iovswscanf.c | 14 +- libio/libio.h | 1 - libio/libioP.h | 11 + libio/strfile.h | 33 +- libio/swscanf.c | 10 +- libio/vscanf.c | 2 +- libio/vwscanf.c | 2 +- libio/wscanf.c | 2 +- stdio-common/Makefile | 3 +- stdio-common/Versions | 3 + stdio-common/iovfscanf.c | 38 + stdio-common/iovfwscanf.c | 38 + stdio-common/isoc99_fscanf.c | 2 +- stdio-common/isoc99_scanf.c | 2 +- stdio-common/isoc99_sscanf.c | 9 +- stdio-common/isoc99_vfscanf.c | 2 +- stdio-common/isoc99_vscanf.c | 2 +- stdio-common/isoc99_vsscanf.c | 17 +- stdio-common/scanf.c | 2 +- stdio-common/sscanf.c | 12 +- stdio-common/vfscanf-internal.c | 3050 ++++++++++++++++++++++++++++++ stdio-common/vfscanf.c | 3042 +---------------------------- stdio-common/vfwscanf-internal.c | 2 + stdio-common/vfwscanf.c | 28 +- sysdeps/generic/math_ldbl_opt.h | 4 + sysdeps/ieee754/ldbl-opt/math_ldbl_opt.h | 5 + sysdeps/ieee754/ldbl-opt/nldbl-compat.c | 17 +- wcsmbs/isoc99_fwscanf.c | 2 +- wcsmbs/isoc99_swscanf.c | 12 +- wcsmbs/isoc99_vfwscanf.c | 2 +- wcsmbs/isoc99_vswscanf.c | 16 +- wcsmbs/isoc99_vwscanf.c | 2 +- wcsmbs/isoc99_wscanf.c | 2 +- 34 files changed, 3273 insertions(+), 3128 deletions(-) create mode 100644 stdio-common/iovfscanf.c create mode 100644 stdio-common/iovfwscanf.c create mode 100644 stdio-common/vfscanf-internal.c create mode 100644 stdio-common/vfwscanf-internal.c diff --git a/libio/iovsscanf.c b/libio/iovsscanf.c index e56ab8bd7d..ee6a99ec6a 100644 --- a/libio/iovsscanf.c +++ b/libio/iovsscanf.c @@ -24,22 +24,14 @@ This exception applies to code released by its copyright holders in files containing the exception. */ -#include "libioP.h" #include "strfile.h" int _IO_vsscanf (const char *string, const char *format, va_list args) { - int ret; _IO_strfile sf; -#ifdef _IO_MTSAFE_IO - sf._sbf._f._lock = NULL; -#endif - _IO_no_init (&sf._sbf._f, _IO_USER_LOCK, -1, NULL, NULL); - _IO_JUMPS (&sf._sbf) = &_IO_str_jumps; - _IO_str_init_static_internal (&sf, (char*)string, 0, NULL); - ret = _IO_vfscanf (&sf._sbf._f, format, args, NULL); - return ret; + FILE *f = _IO_strfile_read (&sf, string); + return __vfscanf_internal (f, format, args, 0); } ldbl_weak_alias (_IO_vsscanf, __vsscanf) ldbl_weak_alias (_IO_vsscanf, vsscanf) diff --git a/libio/iovswscanf.c b/libio/iovswscanf.c index 5bd1c88412..cb9cbe15cc 100644 --- a/libio/iovswscanf.c +++ b/libio/iovswscanf.c @@ -24,24 +24,16 @@ This exception applies to code released by its copyright holders in files containing the exception. */ -#include "libioP.h" -#include "strfile.h" #include +#include "strfile.h" int __vswscanf (const wchar_t *string, const wchar_t *format, va_list args) { - int ret; _IO_strfile sf; struct _IO_wide_data wd; -#ifdef _IO_MTSAFE_IO - sf._sbf._f._lock = NULL; -#endif - _IO_no_init (&sf._sbf._f, _IO_USER_LOCK, 0, &wd, &_IO_wstr_jumps); - _IO_fwide (&sf._sbf._f, 1); - _IO_wstr_init_static (&sf._sbf._f, (wchar_t *)string, 0, NULL); - ret = _IO_vfwscanf ((FILE *) &sf._sbf, format, args, NULL); - return ret; + FILE *f = _IO_strfile_readw (&sf, &wd, string); + return __vfwscanf_internal (f, format, args, 0); } libc_hidden_def (__vswscanf) ldbl_hidden_def (__vswscanf, vswscanf) diff --git a/libio/libio.h b/libio/libio.h index 00f9169613..d4eba2df54 100644 --- a/libio/libio.h +++ b/libio/libio.h @@ -321,7 +321,6 @@ libc_hidden_proto (_IO_padn) libc_hidden_proto (_IO_putc) libc_hidden_proto (_IO_sgetn) libc_hidden_proto (_IO_vfprintf) -libc_hidden_proto (_IO_vfscanf) #ifdef _IO_MTSAFE_IO # undef _IO_peekc diff --git a/libio/libioP.h b/libio/libioP.h index df2633d858..fa34a628fe 100644 --- a/libio/libioP.h +++ b/libio/libioP.h @@ -704,6 +704,17 @@ extern off64_t _IO_seekpos_unlocked (FILE *, off64_t, int) #endif /* _G_HAVE_MMAP */ +/* Flags for __vfscanf_internal and __vfwscanf_internal. */ +#define SCANF_LDBL_IS_DBL 0x0001 +#define SCANF_ISOC99_A 0x0002 + +extern int __vfscanf_internal (FILE *fp, const char *format, va_list argp, + unsigned int flags) + attribute_hidden; +extern int __vfwscanf_internal (FILE *fp, const wchar_t *format, va_list argp, + unsigned int flags) + attribute_hidden; + extern int _IO_vscanf (const char *, va_list) __THROW; #ifdef _IO_MTSAFE_IO diff --git a/libio/strfile.h b/libio/strfile.h index 75caac2af5..62900a7128 100644 --- a/libio/strfile.h +++ b/libio/strfile.h @@ -24,7 +24,9 @@ This exception applies to code released by its copyright holders in files containing the exception. */ -#include +#ifndef STRFILE_H_ +#define STRFILE_H_ + #include "libioP.h" typedef void *(*_IO_alloc_type) (size_t); @@ -80,3 +82,32 @@ typedef struct } _IO_wstrnfile; extern const struct _IO_jump_t _IO_wstrn_jumps attribute_hidden; + +/* Initialize an _IO_strfile SF to read from narrow string STRING, and + return the corresponding FILE object. It is not necessary to fclose + the FILE when it is no longer needed. */ +static inline FILE * +_IO_strfile_read (_IO_strfile *sf, const char *string) +{ + sf->_sbf._f._lock = NULL; + _IO_no_init (&sf->_sbf._f, _IO_USER_LOCK, -1, NULL, NULL); + _IO_JUMPS (&sf->_sbf) = &_IO_str_jumps; + _IO_str_init_static_internal (sf, (char*)string, 0, NULL); + return &sf->_sbf._f; +} + +/* Initialize an _IO_strfile SF and _IO_wide_data WD to read from wide + string STRING, and return the corresponding FILE object. It is not + necessary to fclose the FILE when it is no longer needed. */ +static inline FILE * +_IO_strfile_readw (_IO_strfile *sf, struct _IO_wide_data *wd, + const wchar_t *string) +{ + sf->_sbf._f._lock = NULL; + _IO_no_init (&sf->_sbf._f, _IO_USER_LOCK, 0, wd, &_IO_wstr_jumps); + _IO_fwide (&sf->_sbf._f, 1); + _IO_wstr_init_static (&sf->_sbf._f, (wchar_t *)string, 0, NULL); + return &sf->_sbf._f; +} + +#endif /* strfile.h. */ diff --git a/libio/swscanf.c b/libio/swscanf.c index c8686bcbaf..90f721cc51 100644 --- a/libio/swscanf.c +++ b/libio/swscanf.c @@ -15,20 +15,22 @@ License along with the GNU C Library; if not, see . */ -#include #include -#include +#include "strfile.h" /* Read formatted input from S, according to the format string FORMAT. */ -/* VARARGS2 */ + int __swscanf (const wchar_t *s, const wchar_t *format, ...) { va_list arg; int done; + _IO_strfile sf; + struct _IO_wide_data wd; + FILE *f = _IO_strfile_readw (&sf, &wd, s); va_start (arg, format); - done = __vswscanf (s, format, arg); + done = __vfwscanf_internal (f, format, arg, 0); va_end (arg); return done; diff --git a/libio/vscanf.c b/libio/vscanf.c index 9c27122c27..a3e2dd43f2 100644 --- a/libio/vscanf.c +++ b/libio/vscanf.c @@ -32,6 +32,6 @@ int _IO_vscanf (const char *format, va_list args) { - return _IO_vfscanf (_IO_stdin, format, args, NULL); + return __vfscanf_internal (_IO_stdin, format, args, 0); } ldbl_weak_alias (_IO_vscanf, vscanf) diff --git a/libio/vwscanf.c b/libio/vwscanf.c index 0d5f558758..7af770c8c3 100644 --- a/libio/vwscanf.c +++ b/libio/vwscanf.c @@ -30,6 +30,6 @@ int __vwscanf (const wchar_t *format, va_list args) { - return _IO_vfwscanf (_IO_stdin, format, args, NULL); + return __vfwscanf_internal (_IO_stdin, format, args, 0); } ldbl_strong_alias (__vwscanf, vwscanf) diff --git a/libio/wscanf.c b/libio/wscanf.c index c8cdad0acd..fe27ff6fa6 100644 --- a/libio/wscanf.c +++ b/libio/wscanf.c @@ -30,7 +30,7 @@ __wscanf (const wchar_t *format, ...) int done; va_start (arg, format); - done = _IO_vfwscanf (stdin, format, arg, NULL); + done = __vfwscanf_internal (stdin, format, arg, 0); va_end (arg); return done; diff --git a/stdio-common/Makefile b/stdio-common/Makefile index a10f12ab3c..f3b3ceddbd 100644 --- a/stdio-common/Makefile +++ b/stdio-common/Makefile @@ -39,7 +39,8 @@ routines := \ flockfile ftrylockfile funlockfile \ isoc99_scanf isoc99_vscanf isoc99_fscanf isoc99_vfscanf isoc99_sscanf \ isoc99_vsscanf \ - psiginfo gentempfd + psiginfo gentempfd \ + vfscanf-internal vfwscanf-internal iovfscanf iovfwscanf aux := errlist siglist printf-parsemb printf-parsewc fxprintf diff --git a/stdio-common/Versions b/stdio-common/Versions index b8217578c8..522f302198 100644 --- a/stdio-common/Versions +++ b/stdio-common/Versions @@ -60,6 +60,9 @@ libc { GLIBC_2.28 { renameat2; } + GLIBC_2.29 { + # SHLIB_COMPAT(GLIBC_2_0, GLIBC_2_29) used in iovfscanf.c etc. + } GLIBC_PRIVATE { # global variables _itoa_lower_digits; diff --git a/stdio-common/iovfscanf.c b/stdio-common/iovfscanf.c new file mode 100644 index 0000000000..77e698f665 --- /dev/null +++ b/stdio-common/iovfscanf.c @@ -0,0 +1,38 @@ +/* Implementation and symbols for _IO_vfscanf. + Copyright (C) 2018 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 + . */ + +#include +#include + +/* This function is provided for ports older than GLIBC 2.29 because + external callers could theoretically exist. Newer ports do not need, + since it is not part of the API. */ +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_29) + +int +attribute_compat_text_section +__IO_vfscanf (FILE *fp, const char *format, va_list ap, int *errp) +{ + int rv = __vfscanf_internal (fp, format, ap, 0); + if (__glibc_unlikely (errp != 0)) + *errp = (rv == -1); + return rv; +} +ldbl_compat_symbol (libc, __IO_vfscanf, _IO_vfscanf, GLIBC_2_0); + +#endif diff --git a/stdio-common/iovfwscanf.c b/stdio-common/iovfwscanf.c new file mode 100644 index 0000000000..26a57788cb --- /dev/null +++ b/stdio-common/iovfwscanf.c @@ -0,0 +1,38 @@ +/* Implementation and symbols for _IO_vfwscanf. + Copyright (C) 1991-2018 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 + . */ + +#include +#include + +/* This function is provided for ports older than GLIBC 2.29 because + external callers could theoretically exist. Newer ports do not need, + since it is not part of the API. */ +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_29) + +int +attribute_compat_text_section +__IO_vfwscanf (FILE *fp, const wchar_t *format, va_list ap, int *errp) +{ + int rv = __vfwscanf_internal (fp, format, ap, 0); + if (__glibc_unlikely (errp != 0)) + *errp = (rv == -1); + return rv; +} +compat_symbol (libc, __IO_vfwscanf, _IO_vfwscanf, GLIBC_2_0); + +#endif diff --git a/stdio-common/isoc99_fscanf.c b/stdio-common/isoc99_fscanf.c index 9cdf85e679..4210d11f2b 100644 --- a/stdio-common/isoc99_fscanf.c +++ b/stdio-common/isoc99_fscanf.c @@ -31,7 +31,7 @@ __isoc99_fscanf (FILE *stream, const char *format, ...) stream->_flags2 |= _IO_FLAGS2_SCANF_STD; va_start (arg, format); - done = _IO_vfscanf (stream, format, arg, NULL); + done = __vfscanf_internal (stream, format, arg, 0); va_end (arg); _IO_release_lock (stream); diff --git a/stdio-common/isoc99_scanf.c b/stdio-common/isoc99_scanf.c index bf7dbe86bb..64c873eed9 100644 --- a/stdio-common/isoc99_scanf.c +++ b/stdio-common/isoc99_scanf.c @@ -34,7 +34,7 @@ __isoc99_scanf (const char *format, ...) stdin->_flags2 |= _IO_FLAGS2_SCANF_STD; va_start (arg, format); - done = _IO_vfscanf (stdin, format, arg, NULL); + done = __vfscanf_internal (stdin, format, arg, 0); va_end (arg); #ifdef _IO_MTSAFE_IO diff --git a/stdio-common/isoc99_sscanf.c b/stdio-common/isoc99_sscanf.c index 56a60a2c05..2c89a03fe9 100644 --- a/stdio-common/isoc99_sscanf.c +++ b/stdio-common/isoc99_sscanf.c @@ -16,19 +16,20 @@ . */ #include -#include -#include +#include /* Read formatted input from S, according to the format string FORMAT. */ -/* VARARGS2 */ int __isoc99_sscanf (const char *s, const char *format, ...) { va_list arg; int done; + _IO_strfile sf; + FILE *f = _IO_strfile_read (&sf, s); + f->_flags2 |= _IO_FLAGS2_SCANF_STD; va_start (arg, format); - done = __isoc99_vsscanf (s, format, arg); + done = __vfscanf_internal (f, format, arg, 0); va_end (arg); return done; diff --git a/stdio-common/isoc99_vfscanf.c b/stdio-common/isoc99_vfscanf.c index b80e05f8db..c96ca831ae 100644 --- a/stdio-common/isoc99_vfscanf.c +++ b/stdio-common/isoc99_vfscanf.c @@ -27,7 +27,7 @@ __isoc99_vfscanf (FILE *stream, const char *format, va_list args) _IO_acquire_lock_clear_flags2 (stream); stream->_flags2 |= _IO_FLAGS2_SCANF_STD; - done = _IO_vfscanf (stream, format, args, NULL); + done = __vfscanf_internal (stream, format, args, 0); _IO_release_lock (stream); return done; } diff --git a/stdio-common/isoc99_vscanf.c b/stdio-common/isoc99_vscanf.c index 0b747f85ba..72ae72ddee 100644 --- a/stdio-common/isoc99_vscanf.c +++ b/stdio-common/isoc99_vscanf.c @@ -27,7 +27,7 @@ __isoc99_vscanf (const char *format, va_list args) _IO_acquire_lock_clear_flags2 (stdin); stdin->_flags2 |= _IO_FLAGS2_SCANF_STD; - done = _IO_vfscanf (stdin, format, args, NULL); + done = __vfscanf_internal (stdin, format, args, 0); _IO_release_lock (stdin); return done; } diff --git a/stdio-common/isoc99_vsscanf.c b/stdio-common/isoc99_vsscanf.c index ac85ef2d0d..02bc0f50e6 100644 --- a/stdio-common/isoc99_vsscanf.c +++ b/stdio-common/isoc99_vsscanf.c @@ -24,23 +24,14 @@ This exception applies to code released by its copyright holders in files containing the exception. */ -#include -#include -#include "../libio/strfile.h" +#include int __isoc99_vsscanf (const char *string, const char *format, va_list args) { - int ret; _IO_strfile sf; -#ifdef _IO_MTSAFE_IO - sf._sbf._f._lock = NULL; -#endif - _IO_no_init (&sf._sbf._f, _IO_USER_LOCK, -1, NULL, NULL); - _IO_JUMPS (&sf._sbf) = &_IO_str_jumps; - _IO_str_init_static_internal (&sf, (char*)string, 0, NULL); - sf._sbf._f._flags2 |= _IO_FLAGS2_SCANF_STD; - ret = _IO_vfscanf (&sf._sbf._f, format, args, NULL); - return ret; + FILE *f = _IO_strfile_read (&sf, string); + f->_flags2 |= _IO_FLAGS2_SCANF_STD; + return __vfscanf_internal (f, format, args, 0); } libc_hidden_def (__isoc99_vsscanf) diff --git a/stdio-common/scanf.c b/stdio-common/scanf.c index e61b5f1ad3..de38d70353 100644 --- a/stdio-common/scanf.c +++ b/stdio-common/scanf.c @@ -30,7 +30,7 @@ __scanf (const char *format, ...) int done; va_start (arg, format); - done = _IO_vfscanf (stdin, format, arg, NULL); + done = __vfscanf_internal (stdin, format, arg, 0); va_end (arg); return done; diff --git a/stdio-common/sscanf.c b/stdio-common/sscanf.c index 88cd641798..e25e9c27a5 100644 --- a/stdio-common/sscanf.c +++ b/stdio-common/sscanf.c @@ -16,26 +16,24 @@ . */ #include -#include -#include -#define __vsscanf(s, f, a) _IO_vsscanf (s, f, a) +#include /* Read formatted input from S, according to the format string FORMAT. */ -/* VARARGS2 */ + int __sscanf (const char *s, const char *format, ...) { va_list arg; int done; + _IO_strfile sf; + FILE *f = _IO_strfile_read (&sf, s); va_start (arg, format); - done = __vsscanf (s, format, arg); + done = __vfscanf_internal (f, format, arg, 0); va_end (arg); return done; } ldbl_hidden_def (__sscanf, sscanf) ldbl_strong_alias (__sscanf, sscanf) -#undef _IO_sscanf -/* This is for libg++. */ ldbl_strong_alias (__sscanf, _IO_sscanf) diff -u stdio-common/vfscanf.c.old stdio-common/vfscanf-internal.c.new --- stdio-common/vfscanf.c.old 2018-10-25 17:21:09.232711752 -0300 +++ stdio-common/vfscanf-internal.c.new 2018-10-25 17:21:24.143739981 -0300 @@ -1,4 +1,5 @@ -/* Copyright (C) 1991-2018 Free Software Foundation, Inc. +/* Internal functions for the *scanf* implementation. + Copyright (C) 1991-2018 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 @@ -132,16 +133,13 @@ #include "printf-parse.h" /* Use read_int. */ #define encode_error() do { \ - errval = 4; \ __set_errno (EILSEQ); \ goto errout; \ } while (0) #define conv_error() do { \ - errval = 2; \ goto errout; \ } while (0) #define input_error() do { \ - errval = 1; \ if (done == 0) done = EOF; \ goto errout; \ } while (0) @@ -267,12 +265,12 @@ Return the number of assignments made, or -1 for an input error. */ #ifdef COMPILE_WSCANF int -_IO_vfwscanf (FILE *s, const wchar_t *format, va_list argptr, - int *errp) +__vfwscanf_internal (FILE *s, const wchar_t *format, va_list argptr, + unsigned int mode_flags) #else int -_IO_vfscanf_internal (FILE *s, const char *format, va_list argptr, - int *errp) +__vfscanf_internal (FILE *s, const char *format, va_list argptr, + unsigned int mode_flags) #endif { va_list arg; @@ -283,7 +281,6 @@ WINT_T c = 0; /* Last char read. */ int width; /* Maximum field width. */ int flags; /* Modifiers for current format element. */ - int errval = 0; #ifndef COMPILE_WSCANF locale_t loc = _NL_CURRENT_LOCALE; struct __locale_data *const curctype = loc->__locales[LC_CTYPE]; @@ -335,6 +332,14 @@ struct char_buffer charbuf; scratch_buffer_init (&charbuf.scratch); +#define LDBL_DISTINCT (__glibc_likely ((mode_flags & SCANF_LDBL_IS_DBL) == 0)) +#define USE_ISOC99_A (__glibc_likely (mode_flags & SCANF_ISOC99_A)) + /* Temporarily honor the environmental mode bits. */ + if (__ldbl_is_dbl) + mode_flags |= SCANF_LDBL_IS_DBL; + if (s->_flags2 & _IO_FLAGS2_SCANF_STD) + mode_flags |= SCANF_ISOC99_A; + #ifdef __va_copy __va_copy (arg, argptr); #else @@ -566,7 +571,7 @@ } /* In __isoc99_*scanf %as, %aS and %a[ extension is not supported at all. */ - if (s->_flags2 & _IO_FLAGS2_SCANF_STD) + if (USE_ISOC99_A) { --f; break; @@ -2423,7 +2428,7 @@ done = EOF; goto errout; } - if ((flags & LONGDBL) && !__ldbl_is_dbl) + if ((flags & LONGDBL) && LDBL_DISTINCT) { long double d = __strtold_internal (char_buffer_start (&charbuf), &tw, flags & GROUP); @@ -3018,8 +3023,6 @@ UNLOCK_STREAM (s); scratch_buffer_free (&charbuf.scratch); - if (errp != NULL) - *errp |= errval; if (__glibc_unlikely (done == EOF)) { @@ -3045,23 +3048,3 @@ } return done; } - -#ifdef COMPILE_WSCANF -int -__vfwscanf (FILE *s, const wchar_t *format, va_list argptr) -{ - return _IO_vfwscanf (s, format, argptr, NULL); -} -ldbl_weak_alias (__vfwscanf, vfwscanf) -#else -int -___vfscanf (FILE *s, const char *format, va_list argptr) -{ - return _IO_vfscanf_internal (s, format, argptr, NULL); -} -ldbl_strong_alias (_IO_vfscanf_internal, _IO_vfscanf) -ldbl_hidden_def (_IO_vfscanf_internal, _IO_vfscanf) -ldbl_strong_alias (___vfscanf, __vfscanf) -ldbl_hidden_def (___vfscanf, __vfscanf) -ldbl_weak_alias (___vfscanf, vfscanf) -#endif diff -u /dev/null stdio-common/vfscanf.c.new --- /dev/null 2018-10-15 19:30:16.914999855 -0300 +++ stdio-common/vfscanf.c.new 2018-10-25 17:21:39.355768779 -0300 @@ -0,0 +1,27 @@ +/* Copyright (C) 1991-2018 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 + . */ + +#include + +int +___vfscanf (FILE *s, const char *format, va_list argptr) +{ + return __vfscanf_internal (s, format, argptr, 0); +} +ldbl_strong_alias (___vfscanf, __vfscanf) +ldbl_hidden_def (___vfscanf, __vfscanf) +ldbl_weak_alias (___vfscanf, vfscanf) diff --git a/stdio-common/vfwscanf-internal.c b/stdio-common/vfwscanf-internal.c new file mode 100644 index 0000000000..26c89270b7 --- /dev/null +++ b/stdio-common/vfwscanf-internal.c @@ -0,0 +1,2 @@ +#define COMPILE_WSCANF 1 +#include "vfscanf-internal.c" diff --git a/stdio-common/vfwscanf.c b/stdio-common/vfwscanf.c index 26b1a66608..f1c70ad6b3 100644 --- a/stdio-common/vfwscanf.c +++ b/stdio-common/vfwscanf.c @@ -1,2 +1,26 @@ -#define COMPILE_WSCANF 1 -#include "vfscanf.c" +/* Implementation and symbols for vfwscanf. + Copyright (C) 1991-2018 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 + . */ + +#include + +int +__vfwscanf (FILE *s, const wchar_t *format, va_list argptr) +{ + return __vfwscanf_internal (s, format, argptr, 0); +} +ldbl_weak_alias (__vfwscanf, vfwscanf) diff --git a/sysdeps/generic/math_ldbl_opt.h b/sysdeps/generic/math_ldbl_opt.h index 8a5d8ba107..92f670dff7 100644 --- a/sysdeps/generic/math_ldbl_opt.h +++ b/sysdeps/generic/math_ldbl_opt.h @@ -6,9 +6,13 @@ for platforms where compatibility symbols are required for a previous ABI that defined long double functions as aliases for the double code. */ +#include + #define LONG_DOUBLE_COMPAT(lib, introduced) 0 #define long_double_symbol(lib, local, symbol) #define ldbl_hidden_def(local, name) libc_hidden_def (name) #define ldbl_strong_alias(name, aliasname) strong_alias (name, aliasname) #define ldbl_weak_alias(name, aliasname) weak_alias (name, aliasname) +#define ldbl_compat_symbol(lib, local, symbol, version) \ + compat_symbol (lib, local, symbol, version) #define __ldbl_is_dbl 0 diff --git a/sysdeps/ieee754/ldbl-opt/math_ldbl_opt.h b/sysdeps/ieee754/ldbl-opt/math_ldbl_opt.h index 61ba784f86..4d2f3c7be2 100644 --- a/sysdeps/ieee754/ldbl-opt/math_ldbl_opt.h +++ b/sysdeps/ieee754/ldbl-opt/math_ldbl_opt.h @@ -20,10 +20,15 @@ long_double_symbol (libc, __GL_##name##_##aliasname, aliasname); # define long_double_symbol_1(lib, local, symbol, version) \ versioned_symbol (lib, local, symbol, version) +# define ldbl_compat_symbol(lib, local, symbol, version) \ + compat_symbol (lib, local, symbol, LONG_DOUBLE_COMPAT_VERSION) #else # define ldbl_hidden_def(local, name) libc_hidden_def (name) # define ldbl_strong_alias(name, aliasname) strong_alias (name, aliasname) # define ldbl_weak_alias(name, aliasname) weak_alias (name, aliasname) +/* Same as compat_symbol, ldbl_compat_symbol is not to be used outside + '#if SHLIB_COMPAT' statement and should fail if it is. */ +# define ldbl_compat_symbol(lib, local, symbol, version) ... # ifndef __ASSEMBLER__ /* Note that weak_alias cannot be used - it is defined to nothing in most of the C files. */ diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-compat.c b/sysdeps/ieee754/ldbl-opt/nldbl-compat.c index 7a1e89c1a3..91ea27a423 100644 --- a/sysdeps/ieee754/ldbl-opt/nldbl-compat.c +++ b/sysdeps/ieee754/ldbl-opt/nldbl-compat.c @@ -330,16 +330,20 @@ __nldbl_wprintf (const wchar_t *fmt, ...) return done; } +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_29) int attribute_compat_text_section __nldbl__IO_vfscanf (FILE *s, const char *fmt, va_list ap, int *errp) { int res; set_no_long_double (); - res = _IO_vfscanf (s, fmt, ap, errp); + res = __vfscanf_internal (s, fmt, ap, 0); clear_no_long_double (); + if (__glibc_unlikely (errp != 0)) + *errp = (res == -1); return res; } +#endif int attribute_compat_text_section @@ -347,7 +351,7 @@ __nldbl___vfscanf (FILE *s, const char *fmt, va_list ap) { int res; set_no_long_double (); - res = _IO_vfscanf (s, fmt, ap, NULL); + res = __vfscanf_internal (s, fmt, ap, 0); clear_no_long_double (); return res; } @@ -423,7 +427,7 @@ __nldbl_vfwscanf (FILE *s, const wchar_t *fmt, va_list ap) { int res; set_no_long_double (); - res = _IO_vfwscanf (s, fmt, ap, NULL); + res = __vfwscanf_internal (s, fmt, ap, 0); clear_no_long_double (); return res; } @@ -1027,7 +1031,6 @@ compat_symbol (libc, __nldbl_vdprintf, vdprintf, GLIBC_2_0); compat_symbol (libc, __nldbl_vsnprintf, vsnprintf, GLIBC_2_0); compat_symbol (libc, __nldbl_vsprintf, vsprintf, GLIBC_2_0); compat_symbol (libc, __nldbl__IO_sscanf, _IO_sscanf, GLIBC_2_0); -compat_symbol (libc, __nldbl__IO_vfscanf, _IO_vfscanf, GLIBC_2_0); compat_symbol (libc, __nldbl___vfscanf, __vfscanf, GLIBC_2_0); compat_symbol (libc, __nldbl___vsscanf, __vsscanf, GLIBC_2_0); compat_symbol (libc, __nldbl_fscanf, fscanf, GLIBC_2_0); @@ -1040,6 +1043,12 @@ compat_symbol (libc, __nldbl___printf_fp, __printf_fp, GLIBC_2_0); compat_symbol (libc, __nldbl_strfmon, strfmon, GLIBC_2_0); compat_symbol (libc, __nldbl_syslog, syslog, GLIBC_2_0); compat_symbol (libc, __nldbl_vsyslog, vsyslog, GLIBC_2_0); +/* This function is not in public headers, but was exported until + version 2.29. For platforms that are newer than that, there's no + need to expose the symbol. */ +# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_29) +compat_symbol (libc, __nldbl__IO_vfscanf, _IO_vfscanf, GLIBC_2_0); +# endif #endif #if LONG_DOUBLE_COMPAT(libc, GLIBC_2_1) compat_symbol (libc, __nldbl___asprintf, __asprintf, GLIBC_2_1); diff --git a/wcsmbs/isoc99_fwscanf.c b/wcsmbs/isoc99_fwscanf.c index 0c6a2c47ac..00b07dd48e 100644 --- a/wcsmbs/isoc99_fwscanf.c +++ b/wcsmbs/isoc99_fwscanf.c @@ -32,7 +32,7 @@ __isoc99_fwscanf (FILE *stream, const wchar_t *format, ...) stream->_flags2 |= _IO_FLAGS2_SCANF_STD; va_start (arg, format); - done = _IO_vfwscanf (stream, format, arg, NULL); + done = __vfwscanf_internal (stream, format, arg, 0); va_end (arg); _IO_release_lock (stream); diff --git a/wcsmbs/isoc99_swscanf.c b/wcsmbs/isoc99_swscanf.c index ff523db706..40401d0aa1 100644 --- a/wcsmbs/isoc99_swscanf.c +++ b/wcsmbs/isoc99_swscanf.c @@ -16,20 +16,22 @@ . */ #include -#include -#include -#include +#include /* Read formatted input from S, according to the format string FORMAT. */ -/* VARARGS2 */ + int __isoc99_swscanf (const wchar_t *s, const wchar_t *format, ...) { va_list arg; int done; + _IO_strfile sf; + struct _IO_wide_data wd; + FILE *f = _IO_strfile_readw (&sf, &wd, s); + f->_flags2 |= _IO_FLAGS2_SCANF_STD; va_start (arg, format); - done = __isoc99_vswscanf (s, format, arg); + done = __vfwscanf_internal (f, format, arg, 0); va_end (arg); return done; diff --git a/wcsmbs/isoc99_vfwscanf.c b/wcsmbs/isoc99_vfwscanf.c index 7beb45b4d3..f70c6b596d 100644 --- a/wcsmbs/isoc99_vfwscanf.c +++ b/wcsmbs/isoc99_vfwscanf.c @@ -28,7 +28,7 @@ __isoc99_vfwscanf (FILE *stream, const wchar_t *format, va_list args) _IO_acquire_lock_clear_flags2 (stream); stream->_flags2 |= _IO_FLAGS2_SCANF_STD; - done = _IO_vfwscanf (stream, format, args, NULL); + done = __vfwscanf_internal (stream, format, args, 0); _IO_release_lock (stream); return done; } diff --git a/wcsmbs/isoc99_vswscanf.c b/wcsmbs/isoc99_vswscanf.c index 130769154d..b91eb651a3 100644 --- a/wcsmbs/isoc99_vswscanf.c +++ b/wcsmbs/isoc99_vswscanf.c @@ -24,24 +24,16 @@ This exception applies to code released by its copyright holders in files containing the exception. */ -#include #include -#include "../libio/strfile.h" +#include int __isoc99_vswscanf (const wchar_t *string, const wchar_t *format, va_list args) { - int ret; _IO_strfile sf; struct _IO_wide_data wd; -#ifdef _IO_MTSAFE_IO - sf._sbf._f._lock = NULL; -#endif - _IO_no_init (&sf._sbf._f, _IO_USER_LOCK, 0, &wd, &_IO_wstr_jumps); - _IO_fwide (&sf._sbf._f, 1); - _IO_wstr_init_static (&sf._sbf._f, (wchar_t *)string, 0, NULL); - sf._sbf._f._flags2 |= _IO_FLAGS2_SCANF_STD; - ret = _IO_vfwscanf ((FILE *) &sf._sbf, format, args, NULL); - return ret; + FILE *f = _IO_strfile_readw (&sf, &wd, string); + f->_flags2 |= _IO_FLAGS2_SCANF_STD; + return __vfwscanf_internal (f, format, args, 0); } libc_hidden_def (__isoc99_vswscanf) diff --git a/wcsmbs/isoc99_vwscanf.c b/wcsmbs/isoc99_vwscanf.c index 049521b964..eb22c8acae 100644 --- a/wcsmbs/isoc99_vwscanf.c +++ b/wcsmbs/isoc99_vwscanf.c @@ -28,7 +28,7 @@ __isoc99_vwscanf (const wchar_t *format, va_list args) _IO_acquire_lock_clear_flags2 (stdin); stdin->_flags2 |= _IO_FLAGS2_SCANF_STD; - done = _IO_vfwscanf (stdin, format, args, NULL); + done = __vfwscanf_internal (stdin, format, args, 0); _IO_release_lock (stdin); return done; } diff --git a/wcsmbs/isoc99_wscanf.c b/wcsmbs/isoc99_wscanf.c index abfbd50c11..59f80d78fb 100644 --- a/wcsmbs/isoc99_wscanf.c +++ b/wcsmbs/isoc99_wscanf.c @@ -33,7 +33,7 @@ __isoc99_wscanf (const wchar_t *format, ...) stdin->_flags2 |= _IO_FLAGS2_SCANF_STD; va_start (arg, format); - done = _IO_vfwscanf (stdin, format, arg, NULL); + done = __vfwscanf_internal (stdin, format, arg, 0); va_end (arg); _IO_release_lock (stdin); From patchwork Mon Oct 29 12:16:45 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Gabriel F. T. Gomes" X-Patchwork-Id: 990166 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-96795-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=inconstante.eti.br Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="EeAQtVC8"; 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 42kDBS28jbz9s7T for ; Mon, 29 Oct 2018 23:17:36 +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-type; q=dns; s=default; b=XXMLZ JS119Z5yjQpJgazvrQLypgIZGfvgH4cw9gle/DCIskJOY+1fBr6LP8T6tb9jnY4S Urw8ciw2xcCyvbdg9h2uBdmRLw4ZPAGA9DTpyIOdqkGuZWy05T5c9G22UA7A/fnR 7+4G/JnO5FIRvNaD0XQLHtVXGwZ6NMMjlBNSek= 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-type; s=default; bh=dG4sjR7188/ e8D7KPKjUuN8OiXk=; b=EeAQtVC8uoiCZNVOa2pK33o7H4zAXFCiqteUVo3rhzW LHtPOKw7kH8mLR3jVO2mhcVv0sgWrexoCAx3wZyehZgAWwf5bt9EreDBYmdg3pZq gzImZW7DVDxKE+I1jVB3i2xis9Cj2kZAKmAWClNuaNfceQDYcDaeOn7MCmh8X/fk = Received: (qmail 22386 invoked by alias); 29 Oct 2018 12:17:29 -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 18093 invoked by uid 89); 29 Oct 2018 12:17:21 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-25.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_LAZY_DOMAIN_SECURITY, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.2 spammy=temporarily, 2016, 2020, environmental X-HELO: mo20.mail-out.ovh.net From: "Gabriel F. T. Gomes" To: Subject: [PATCH v2 3/8] Use SCANF_ISOC99_A instead of _IO_FLAGS2_SCANF_STD. Date: Mon, 29 Oct 2018 09:16:45 -0300 Message-ID: <20181029121650.24544-4-gabriel@inconstante.eti.br> In-Reply-To: <20181029121650.24544-1-gabriel@inconstante.eti.br> References: <20181029121650.24544-1-gabriel@inconstante.eti.br> MIME-Version: 1.0 X-Ovh-Tracer-Id: 18035227658156035779 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: 0 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedtkedrheekgdefjecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemucehtddtnecu From: Zack Weinberg Changes since v1: - Cleared VARGARSn comments. - Added signed-off-by statements. -- 8< -- Change the callers of __vfscanf_internal and __vfwscanf_internal that want C99-compliant behavior to communicate this via the new flags argument, rather than setting bits on the FILE object. This also means these functions do not need to do their own locking. Tested for powerpc and powerpc64le. 2018-10-16 Zack Weinberg Gabriel F. T. Gomes * stdio-common/isoc99_scanf.c * stdio-common/isoc99_fscanf.c * stdio-common/isoc99_sscanf.c * stdio-common/isoc99_vscanf.c * stdio-common/isoc99_vfscanf.c * stdio-common/isoc99_vsscanf.c * wcsmbs/isoc99_wscanf.c * wcsmbs/isoc99_fwscanf.c * wcsmbs/isoc99_swscanf.c * wcsmbs/isoc99_vwscanf.c * wcsmbs/isoc99_vfwscanf.c * wcsmbs/isoc99_vswscanf.c: Pass SCANF_ISOC99_A to __vfscanf_internal and/or __vfwscanf_internal. Do not set _IO_FLAGS2_SCANF_STD on the FILE passed to that function. No need to lock and unlock the FILE passed to that function. * stdio-common/vfscanf-internal.c (__vfscanf_internal, __vfwscanf_internal): Don't look at _IO_FLAGS2_SCANF_STD. * libio/libioP.h (_IO_acquire_lock_clear_flags2_fct) (_IO_release_lock): Don't clear _IO_FLAGS2_SCANF_STD. * libio/libio.h (_IO_FLAGS2_SCANF_STD): Delete. Signed-off-by: Zack Weinberg Signed-off-by: Gabriel F. T. Gomes --- libio/libio.h | 1 - libio/libioP.h | 5 ++--- stdio-common/isoc99_fscanf.c | 7 +------ stdio-common/isoc99_scanf.c | 12 +----------- stdio-common/isoc99_sscanf.c | 3 +-- stdio-common/isoc99_vfscanf.c | 9 +-------- stdio-common/isoc99_vscanf.c | 9 +-------- stdio-common/isoc99_vsscanf.c | 3 +-- stdio-common/vfscanf-internal.c | 2 -- wcsmbs/isoc99_fwscanf.c | 7 +------ wcsmbs/isoc99_swscanf.c | 3 +-- wcsmbs/isoc99_vfwscanf.c | 9 +-------- wcsmbs/isoc99_vswscanf.c | 3 +-- wcsmbs/isoc99_vwscanf.c | 9 +-------- wcsmbs/isoc99_wscanf.c | 7 +------ 15 files changed, 14 insertions(+), 75 deletions(-) diff --git a/libio/libio.h b/libio/libio.h index d4eba2df54..30cb7d784f 100644 --- a/libio/libio.h +++ b/libio/libio.h @@ -92,7 +92,6 @@ typedef union #define _IO_FLAGS2_NOTCANCEL 2 #define _IO_FLAGS2_FORTIFY 4 #define _IO_FLAGS2_USER_WBUF 8 -#define _IO_FLAGS2_SCANF_STD 16 #define _IO_FLAGS2_NOCLOSE 32 #define _IO_FLAGS2_CLOEXEC 64 #define _IO_FLAGS2_NEED_LOCK 128 diff --git a/libio/libioP.h b/libio/libioP.h index fa34a628fe..f90fb2c050 100644 --- a/libio/libioP.h +++ b/libio/libioP.h @@ -775,7 +775,7 @@ __attribute__ ((__always_inline__)) _IO_acquire_lock_clear_flags2_fct (FILE **p) { FILE *fp = *p; - fp->_flags2 &= ~(_IO_FLAGS2_FORTIFY | _IO_FLAGS2_SCANF_STD); + fp->_flags2 &= ~(_IO_FLAGS2_FORTIFY); if ((fp->_flags & _IO_USER_LOCK) == 0) _IO_funlockfile (fp); } @@ -789,8 +789,7 @@ _IO_acquire_lock_clear_flags2_fct (FILE **p) FILE *_IO_acquire_lock_file = (_fp) # define _IO_release_lock(_fp) \ if (_IO_acquire_lock_file != NULL) \ - _IO_acquire_lock_file->_flags2 &= ~(_IO_FLAGS2_FORTIFY \ - | _IO_FLAGS2_SCANF_STD); \ + _IO_acquire_lock_file->_flags2 &= ~(_IO_FLAGS2_FORTIFY); \ } while (0) #endif diff --git a/stdio-common/isoc99_fscanf.c b/stdio-common/isoc99_fscanf.c index 4210d11f2b..d7b5993f3e 100644 --- a/stdio-common/isoc99_fscanf.c +++ b/stdio-common/isoc99_fscanf.c @@ -20,20 +20,15 @@ #include /* Read formatted input from STREAM according to the format string FORMAT. */ -/* VARARGS2 */ int __isoc99_fscanf (FILE *stream, const char *format, ...) { va_list arg; int done; - _IO_acquire_lock_clear_flags2 (stream); - stream->_flags2 |= _IO_FLAGS2_SCANF_STD; - va_start (arg, format); - done = __vfscanf_internal (stream, format, arg, 0); + done = __vfscanf_internal (stream, format, arg, SCANF_ISOC99_A); va_end (arg); - _IO_release_lock (stream); return done; } diff --git a/stdio-common/isoc99_scanf.c b/stdio-common/isoc99_scanf.c index 64c873eed9..3998322ea1 100644 --- a/stdio-common/isoc99_scanf.c +++ b/stdio-common/isoc99_scanf.c @@ -19,26 +19,16 @@ #include #include - /* Read formatted input from stdin according to the format string FORMAT. */ -/* VARARGS1 */ int __isoc99_scanf (const char *format, ...) { va_list arg; int done; -#ifdef _IO_MTSAFE_IO - _IO_acquire_lock_clear_flags2 (stdin); -#endif - stdin->_flags2 |= _IO_FLAGS2_SCANF_STD; - va_start (arg, format); - done = __vfscanf_internal (stdin, format, arg, 0); + done = __vfscanf_internal (stdin, format, arg, SCANF_ISOC99_A); va_end (arg); -#ifdef _IO_MTSAFE_IO - _IO_release_lock (stdin); -#endif return done; } diff --git a/stdio-common/isoc99_sscanf.c b/stdio-common/isoc99_sscanf.c index 2c89a03fe9..c9e5103b81 100644 --- a/stdio-common/isoc99_sscanf.c +++ b/stdio-common/isoc99_sscanf.c @@ -26,10 +26,9 @@ __isoc99_sscanf (const char *s, const char *format, ...) int done; _IO_strfile sf; FILE *f = _IO_strfile_read (&sf, s); - f->_flags2 |= _IO_FLAGS2_SCANF_STD; va_start (arg, format); - done = __vfscanf_internal (f, format, arg, 0); + done = __vfscanf_internal (f, format, arg, SCANF_ISOC99_A); va_end (arg); return done; diff --git a/stdio-common/isoc99_vfscanf.c b/stdio-common/isoc99_vfscanf.c index c96ca831ae..3c59c60b3e 100644 --- a/stdio-common/isoc99_vfscanf.c +++ b/stdio-common/isoc99_vfscanf.c @@ -19,16 +19,9 @@ #include /* Read formatted input from STREAM according to the format string FORMAT. */ -/* VARARGS2 */ int __isoc99_vfscanf (FILE *stream, const char *format, va_list args) { - int done; - - _IO_acquire_lock_clear_flags2 (stream); - stream->_flags2 |= _IO_FLAGS2_SCANF_STD; - done = __vfscanf_internal (stream, format, args, 0); - _IO_release_lock (stream); - return done; + return __vfscanf_internal (stream, format, args, SCANF_ISOC99_A); } libc_hidden_def (__isoc99_vfscanf) diff --git a/stdio-common/isoc99_vscanf.c b/stdio-common/isoc99_vscanf.c index 72ae72ddee..fc5d609ae7 100644 --- a/stdio-common/isoc99_vscanf.c +++ b/stdio-common/isoc99_vscanf.c @@ -19,15 +19,8 @@ #include /* Read formatted input from STDIN according to the format string FORMAT. */ -/* VARARGS2 */ int __isoc99_vscanf (const char *format, va_list args) { - int done; - - _IO_acquire_lock_clear_flags2 (stdin); - stdin->_flags2 |= _IO_FLAGS2_SCANF_STD; - done = __vfscanf_internal (stdin, format, args, 0); - _IO_release_lock (stdin); - return done; + return __vfscanf_internal (stdin, format, args, SCANF_ISOC99_A); } diff --git a/stdio-common/isoc99_vsscanf.c b/stdio-common/isoc99_vsscanf.c index 02bc0f50e6..dfc394bb51 100644 --- a/stdio-common/isoc99_vsscanf.c +++ b/stdio-common/isoc99_vsscanf.c @@ -31,7 +31,6 @@ __isoc99_vsscanf (const char *string, const char *format, va_list args) { _IO_strfile sf; FILE *f = _IO_strfile_read (&sf, string); - f->_flags2 |= _IO_FLAGS2_SCANF_STD; - return __vfscanf_internal (f, format, args, 0); + return __vfscanf_internal (f, format, args, SCANF_ISOC99_A); } libc_hidden_def (__isoc99_vsscanf) diff --git a/stdio-common/vfscanf-internal.c b/stdio-common/vfscanf-internal.c index 1ae37a2a11..dc341b0b1f 100644 --- a/stdio-common/vfscanf-internal.c +++ b/stdio-common/vfscanf-internal.c @@ -337,8 +337,6 @@ __vfscanf_internal (FILE *s, const char *format, va_list argptr, /* Temporarily honor the environmental mode bits. */ if (__ldbl_is_dbl) mode_flags |= SCANF_LDBL_IS_DBL; - if (s->_flags2 & _IO_FLAGS2_SCANF_STD) - mode_flags |= SCANF_ISOC99_A; #ifdef __va_copy __va_copy (arg, argptr); diff --git a/wcsmbs/isoc99_fwscanf.c b/wcsmbs/isoc99_fwscanf.c index 00b07dd48e..5829607916 100644 --- a/wcsmbs/isoc99_fwscanf.c +++ b/wcsmbs/isoc99_fwscanf.c @@ -21,20 +21,15 @@ #include /* Read formatted input from STREAM according to the format string FORMAT. */ -/* VARARGS2 */ int __isoc99_fwscanf (FILE *stream, const wchar_t *format, ...) { va_list arg; int done; - _IO_acquire_lock_clear_flags2 (stream); - stream->_flags2 |= _IO_FLAGS2_SCANF_STD; - va_start (arg, format); - done = __vfwscanf_internal (stream, format, arg, 0); + done = __vfwscanf_internal (stream, format, arg, SCANF_ISOC99_A); va_end (arg); - _IO_release_lock (stream); return done; } diff --git a/wcsmbs/isoc99_swscanf.c b/wcsmbs/isoc99_swscanf.c index 40401d0aa1..f90e56d97f 100644 --- a/wcsmbs/isoc99_swscanf.c +++ b/wcsmbs/isoc99_swscanf.c @@ -28,10 +28,9 @@ __isoc99_swscanf (const wchar_t *s, const wchar_t *format, ...) _IO_strfile sf; struct _IO_wide_data wd; FILE *f = _IO_strfile_readw (&sf, &wd, s); - f->_flags2 |= _IO_FLAGS2_SCANF_STD; va_start (arg, format); - done = __vfwscanf_internal (f, format, arg, 0); + done = __vfwscanf_internal (f, format, arg, SCANF_ISOC99_A); va_end (arg); return done; diff --git a/wcsmbs/isoc99_vfwscanf.c b/wcsmbs/isoc99_vfwscanf.c index f70c6b596d..715d354b5a 100644 --- a/wcsmbs/isoc99_vfwscanf.c +++ b/wcsmbs/isoc99_vfwscanf.c @@ -20,16 +20,9 @@ #include /* Read formatted input from STREAM according to the format string FORMAT. */ -/* VARARGS2 */ int __isoc99_vfwscanf (FILE *stream, const wchar_t *format, va_list args) { - int done; - - _IO_acquire_lock_clear_flags2 (stream); - stream->_flags2 |= _IO_FLAGS2_SCANF_STD; - done = __vfwscanf_internal (stream, format, args, 0); - _IO_release_lock (stream); - return done; + return __vfwscanf_internal (stream, format, args, SCANF_ISOC99_A); } libc_hidden_def (__isoc99_vfwscanf) diff --git a/wcsmbs/isoc99_vswscanf.c b/wcsmbs/isoc99_vswscanf.c index b91eb651a3..0d8ef7611a 100644 --- a/wcsmbs/isoc99_vswscanf.c +++ b/wcsmbs/isoc99_vswscanf.c @@ -33,7 +33,6 @@ __isoc99_vswscanf (const wchar_t *string, const wchar_t *format, va_list args) _IO_strfile sf; struct _IO_wide_data wd; FILE *f = _IO_strfile_readw (&sf, &wd, string); - f->_flags2 |= _IO_FLAGS2_SCANF_STD; - return __vfwscanf_internal (f, format, args, 0); + return __vfwscanf_internal (f, format, args, SCANF_ISOC99_A); } libc_hidden_def (__isoc99_vswscanf) diff --git a/wcsmbs/isoc99_vwscanf.c b/wcsmbs/isoc99_vwscanf.c index eb22c8acae..3ac3182608 100644 --- a/wcsmbs/isoc99_vwscanf.c +++ b/wcsmbs/isoc99_vwscanf.c @@ -20,15 +20,8 @@ #include /* Read formatted input from STDIN according to the format string FORMAT. */ -/* VARARGS2 */ int __isoc99_vwscanf (const wchar_t *format, va_list args) { - int done; - - _IO_acquire_lock_clear_flags2 (stdin); - stdin->_flags2 |= _IO_FLAGS2_SCANF_STD; - done = __vfwscanf_internal (stdin, format, args, 0); - _IO_release_lock (stdin); - return done; + return __vfwscanf_internal (stdin, format, args, SCANF_ISOC99_A); } diff --git a/wcsmbs/isoc99_wscanf.c b/wcsmbs/isoc99_wscanf.c index 59f80d78fb..b9418f7912 100644 --- a/wcsmbs/isoc99_wscanf.c +++ b/wcsmbs/isoc99_wscanf.c @@ -22,20 +22,15 @@ /* Read formatted input from stdin according to the format string FORMAT. */ -/* VARARGS1 */ int __isoc99_wscanf (const wchar_t *format, ...) { va_list arg; int done; - _IO_acquire_lock_clear_flags2 (stdin); - stdin->_flags2 |= _IO_FLAGS2_SCANF_STD; - va_start (arg, format); - done = __vfwscanf_internal (stdin, format, arg, 0); + done = __vfwscanf_internal (stdin, format, arg, SCANF_ISOC99_A); va_end (arg); - _IO_release_lock (stdin); return done; } From patchwork Mon Oct 29 12:16:46 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Gabriel F. T. Gomes" X-Patchwork-Id: 990168 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-96797-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=inconstante.eti.br Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="quLoEEns"; 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 42kDBt09Bmz9s9J for ; Mon, 29 Oct 2018 23:17:57 +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-type; q=dns; s=default; b=hq7us w3ondgFXCMYblH5iL9Wb9qpR6oJl26OFrLRdNn4SKu9KwHCcbGcoBtw3fV05mkjv OFj16zypq/rX5dCjBr/SjPRJ4jRiY97N198WhjhuEkeeYQDLjlIrh3CzSa8ZSC8h IBZN+saIhjgYbW8bX3oZsA7Oe1gj7ePtgwbqzw= 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-type; s=default; bh=di86UkbRgPQ qOXm2kVTg3DyZR+c=; b=quLoEEnswU8Jy0WFKdF1m6wp/LxJ4Sc4UNi5M46RGK+ zIQIv4nyAODkmbIJMscd6/q6YEg8p8z3WOIoxO+tEzjheH8v4Ub3XJKV12l/ebNR 8h9NbajaoKmC2TN5VnZCBV+hFocvqHwv+OEd+CzFmHrLSQ6Q6Xx0hwkJ+ThYIK6Q = Received: (qmail 22761 invoked by alias); 29 Oct 2018 12:17:30 -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 20581 invoked by uid 89); 29 Oct 2018 12:17:26 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-25.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_LAZY_DOMAIN_SECURITY, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.2 spammy=39046 X-HELO: mo19.mail-out.ovh.net From: "Gabriel F. T. Gomes" To: Subject: [PATCH v2 4/8] Use SCANF_LDBL_IS_DBL instead of __ldbl_is_dbl. Date: Mon, 29 Oct 2018 09:16:46 -0300 Message-ID: <20181029121650.24544-5-gabriel@inconstante.eti.br> In-Reply-To: <20181029121650.24544-1-gabriel@inconstante.eti.br> References: <20181029121650.24544-1-gabriel@inconstante.eti.br> MIME-Version: 1.0 X-Ovh-Tracer-Id: 18036916510541795011 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: 0 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedtkedrheekgdefjecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemucehtddtnecu From: Zack Weinberg Changed since v1: - In __nldbl___isoc99_vwscanf, called __vfwscanf_internal directly (missing (accidentally?) from the previous version). - Broke long lines. - Changed name of variable (from rv to ret), since the rationale for making these changes to variables names is consistency. - Added signed-off-by statements. -- 8< -- Change the callers of __vfscanf_internal and __vfwscanf_internal that want to treat 'long double' as another name for 'double' (all of which happen to be in sysdeps/ieee754/ldbl-opt/nldbl-compat.c) to communicate this via the new flags argument, instead of the per-thread variable __no_long_double and its __ldbl_is_dbl wrapper macro. Tested for powerpc and powerpc64le. 2018-10-16 Zack Weinberg Gabriel F. T. Gomes * stdio-common/vfscanf-internal.c: Don't look at __ldbl_is_dbl. * sysdeps/ieee754/ldbl-opt/ndlbl-compat.c: Include libio/strfile.h instead of libioP.h. (__nldbl_IO_vfscanf, __ndlbl___vfscanf, __nldbl_sscanf) (__nldbl___vsscanf, __nldbl_vscanf, __nldbl_fscanf) (__nldbl_scanf, __nldbl_vfwscanf, __nldbl_swscanf) (__nldbl_vswscanf, __nldbl_vwscanf, __nldbl_fwscanf) (__nldbl_wscanf): Call __vfscanf_internal / __vfwscanf_internal directly, passing SCANF_LDBL_IS_DBL. Set up a strfile if necessary. Do not set __no_long_double. Normalize variable names. (__nldbl___isoc99_vfscanf, __nldbl___isoc99_sscanf) (__nldbl___isoc99_vsscanf, __nldbl___isoc99_vscanf) (__nldbl___isoc99_fscanf, __nldbl___isoc99_scanf) (__nldbl___isoc99_vfwscanf, __nldbl___isoc99_swscanf) (__nldbl___isoc99_vswscanf, __nldbl___isoc99_vwscanf) (__nldbl___isoc99_fwscanf, __nldbl___isoc99_wscanf): Call __vfscanf_internal / __vfwscanf_internal directly, passing SCANF_LDBL_IS_DBL | SCANF_ISOC99_A. Set up a strfile if necessary. Do not set __no_long_double. Normalize variable names. Signed-off-by: Zack Weinberg Signed-off-by: Gabriel F. T. Gomes --- stdio-common/vfscanf-internal.c | 3 - sysdeps/ieee754/ldbl-opt/nldbl-compat.c | 251 +++++++++++++++----------------- 2 files changed, 121 insertions(+), 133 deletions(-) diff --git a/stdio-common/vfscanf-internal.c b/stdio-common/vfscanf-internal.c index dc341b0b1f..f989f8dc07 100644 --- a/stdio-common/vfscanf-internal.c +++ b/stdio-common/vfscanf-internal.c @@ -334,9 +334,6 @@ __vfscanf_internal (FILE *s, const char *format, va_list argptr, #define LDBL_DISTINCT (__glibc_likely ((mode_flags & SCANF_LDBL_IS_DBL) == 0)) #define USE_ISOC99_A (__glibc_likely (mode_flags & SCANF_ISOC99_A)) - /* Temporarily honor the environmental mode bits. */ - if (__ldbl_is_dbl) - mode_flags |= SCANF_LDBL_IS_DBL; #ifdef __va_copy __va_copy (arg, argptr); diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-compat.c b/sysdeps/ieee754/ldbl-opt/nldbl-compat.c index 91ea27a423..468e23dec4 100644 --- a/sysdeps/ieee754/ldbl-opt/nldbl-compat.c +++ b/sysdeps/ieee754/ldbl-opt/nldbl-compat.c @@ -19,7 +19,7 @@ #include #include -#include +#include #include #include #include @@ -335,13 +335,10 @@ int attribute_compat_text_section __nldbl__IO_vfscanf (FILE *s, const char *fmt, va_list ap, int *errp) { - int res; - set_no_long_double (); - res = __vfscanf_internal (s, fmt, ap, 0); - clear_no_long_double (); + int ret = __vfscanf_internal (s, fmt, ap, SCANF_LDBL_IS_DBL); if (__glibc_unlikely (errp != 0)) - *errp = (res == -1); - return res; + *errp = (ret == -1); + return ret; } #endif @@ -349,11 +346,7 @@ int attribute_compat_text_section __nldbl___vfscanf (FILE *s, const char *fmt, va_list ap) { - int res; - set_no_long_double (); - res = __vfscanf_internal (s, fmt, ap, 0); - clear_no_long_double (); - return res; + return __vfscanf_internal (s, fmt, ap, SCANF_LDBL_IS_DBL); } weak_alias (__nldbl___vfscanf, __nldbl_vfscanf) libc_hidden_def (__nldbl_vfscanf) @@ -362,26 +355,26 @@ int attribute_compat_text_section __nldbl_sscanf (const char *s, const char *fmt, ...) { - va_list arg; - int done; + _IO_strfile sf; + FILE *f = _IO_strfile_read (&sf, s); + va_list ap; + int ret; - va_start (arg, fmt); - done = __nldbl_vsscanf (s, fmt, arg); - va_end (arg); + va_start (ap, fmt); + ret = __vfscanf_internal (f, fmt, ap, SCANF_LDBL_IS_DBL); + va_end (ap); - return done; + return ret; } strong_alias (__nldbl_sscanf, __nldbl__IO_sscanf) int attribute_compat_text_section -__nldbl___vsscanf (const char *string, const char *fmt, va_list ap) +__nldbl___vsscanf (const char *s, const char *fmt, va_list ap) { - int res; - __no_long_double = 1; - res = _IO_vsscanf (string, fmt, ap); - __no_long_double = 0; - return res; + _IO_strfile sf; + FILE *f = _IO_strfile_read (&sf, s); + return __vfscanf_internal (f, fmt, ap, SCANF_LDBL_IS_DBL); } weak_alias (__nldbl___vsscanf, __nldbl_vsscanf) libc_hidden_def (__nldbl_vsscanf) @@ -390,46 +383,42 @@ int attribute_compat_text_section weak_function __nldbl_vscanf (const char *fmt, va_list ap) { - return __nldbl_vfscanf (stdin, fmt, ap); + return __vfscanf_internal (stdin, fmt, ap, SCANF_LDBL_IS_DBL); } int attribute_compat_text_section __nldbl_fscanf (FILE *stream, const char *fmt, ...) { - va_list arg; - int done; + va_list ap; + int ret; - va_start (arg, fmt); - done = __nldbl_vfscanf (stream, fmt, arg); - va_end (arg); + va_start (ap, fmt); + ret = __vfscanf_internal (stream, fmt, ap, SCANF_LDBL_IS_DBL); + va_end (ap); - return done; + return ret; } int attribute_compat_text_section __nldbl_scanf (const char *fmt, ...) { - va_list arg; - int done; + va_list ap; + int ret; - va_start (arg, fmt); - done = __nldbl_vfscanf (stdin, fmt, arg); - va_end (arg); + va_start (ap, fmt); + ret = __vfscanf_internal (stdin, fmt, ap, SCANF_LDBL_IS_DBL); + va_end (ap); - return done; + return ret; } int attribute_compat_text_section __nldbl_vfwscanf (FILE *s, const wchar_t *fmt, va_list ap) { - int res; - set_no_long_double (); - res = __vfwscanf_internal (s, fmt, ap, 0); - clear_no_long_double (); - return res; + return __vfwscanf_internal (s, fmt, ap, SCANF_LDBL_IS_DBL); } libc_hidden_def (__nldbl_vfwscanf) @@ -437,25 +426,28 @@ int attribute_compat_text_section __nldbl_swscanf (const wchar_t *s, const wchar_t *fmt, ...) { - va_list arg; - int done; + _IO_strfile sf; + struct _IO_wide_data wd; + FILE *f = _IO_strfile_readw (&sf, &wd, s); + va_list ap; + int ret; - va_start (arg, fmt); - done = __nldbl_vswscanf (s, fmt, arg); - va_end (arg); + va_start (ap, fmt); + ret = __vfwscanf_internal (f, fmt, ap, SCANF_LDBL_IS_DBL); + va_end (ap); - return done; + return ret; } int attribute_compat_text_section -__nldbl_vswscanf (const wchar_t *string, const wchar_t *fmt, va_list ap) +__nldbl_vswscanf (const wchar_t *s, const wchar_t *fmt, va_list ap) { - int res; - __no_long_double = 1; - res = vswscanf (string, fmt, ap); - __no_long_double = 0; - return res; + _IO_strfile sf; + struct _IO_wide_data wd; + FILE *f = _IO_strfile_readw (&sf, &wd, s); + + return __vfwscanf_internal (f, fmt, ap, SCANF_LDBL_IS_DBL); } libc_hidden_def (__nldbl_vswscanf) @@ -463,35 +455,35 @@ int attribute_compat_text_section weak_function __nldbl_vwscanf (const wchar_t *fmt, va_list ap) { - return __nldbl_vfwscanf (stdin, fmt, ap); + return __vfwscanf_internal (stdin, fmt, ap, SCANF_LDBL_IS_DBL); } int attribute_compat_text_section __nldbl_fwscanf (FILE *stream, const wchar_t *fmt, ...) { - va_list arg; - int done; + va_list ap; + int ret; - va_start (arg, fmt); - done = __nldbl_vfwscanf (stream, fmt, arg); - va_end (arg); + va_start (ap, fmt); + ret = __vfwscanf_internal (stream, fmt, ap, SCANF_LDBL_IS_DBL); + va_end (ap); - return done; + return ret; } int attribute_compat_text_section __nldbl_wscanf (const wchar_t *fmt, ...) { - va_list arg; - int done; + va_list ap; + int ret; - va_start (arg, fmt); - done = __nldbl_vfwscanf (stdin, fmt, arg); - va_end (arg); + va_start (ap, fmt); + ret = __vfwscanf_internal (stdin, fmt, ap, SCANF_LDBL_IS_DBL); + va_end (ap); - return done; + return ret; } int @@ -866,11 +858,7 @@ int attribute_compat_text_section __nldbl___isoc99_vfscanf (FILE *s, const char *fmt, va_list ap) { - int res; - set_no_long_double (); - res = __isoc99_vfscanf (s, fmt, ap); - clear_no_long_double (); - return res; + return __vfscanf_internal (s, fmt, ap, SCANF_LDBL_IS_DBL | SCANF_ISOC99_A); } libc_hidden_def (__nldbl___isoc99_vfscanf) @@ -878,25 +866,26 @@ int attribute_compat_text_section __nldbl___isoc99_sscanf (const char *s, const char *fmt, ...) { - va_list arg; - int done; + _IO_strfile sf; + FILE *f = _IO_strfile_read (&sf, s); + va_list ap; + int ret; - va_start (arg, fmt); - done = __nldbl___isoc99_vsscanf (s, fmt, arg); - va_end (arg); + va_start (ap, fmt); + ret = __vfscanf_internal (f, fmt, ap, SCANF_LDBL_IS_DBL | SCANF_ISOC99_A); + va_end (ap); - return done; + return ret; } int attribute_compat_text_section -__nldbl___isoc99_vsscanf (const char *string, const char *fmt, va_list ap) +__nldbl___isoc99_vsscanf (const char *s, const char *fmt, va_list ap) { - int res; - __no_long_double = 1; - res = __isoc99_vsscanf (string, fmt, ap); - __no_long_double = 0; - return res; + _IO_strfile sf; + FILE *f = _IO_strfile_read (&sf, s); + + return __vfscanf_internal (f, fmt, ap, SCANF_LDBL_IS_DBL | SCANF_ISOC99_A); } libc_hidden_def (__nldbl___isoc99_vsscanf) @@ -904,46 +893,44 @@ int attribute_compat_text_section __nldbl___isoc99_vscanf (const char *fmt, va_list ap) { - return __nldbl___isoc99_vfscanf (stdin, fmt, ap); + return __vfscanf_internal (stdin, fmt, ap, + SCANF_LDBL_IS_DBL | SCANF_ISOC99_A); } int attribute_compat_text_section -__nldbl___isoc99_fscanf (FILE *stream, const char *fmt, ...) +__nldbl___isoc99_fscanf (FILE *s, const char *fmt, ...) { - va_list arg; - int done; + va_list ap; + int ret; - va_start (arg, fmt); - done = __nldbl___isoc99_vfscanf (stream, fmt, arg); - va_end (arg); + va_start (ap, fmt); + ret = __vfscanf_internal (s, fmt, ap, SCANF_LDBL_IS_DBL | SCANF_ISOC99_A); + va_end (ap); - return done; + return ret; } int attribute_compat_text_section __nldbl___isoc99_scanf (const char *fmt, ...) { - va_list arg; - int done; + va_list ap; + int ret; - va_start (arg, fmt); - done = __nldbl___isoc99_vfscanf (stdin, fmt, arg); - va_end (arg); + va_start (ap, fmt); + ret = __vfscanf_internal (stdin, fmt, ap, + SCANF_LDBL_IS_DBL | SCANF_ISOC99_A); + va_end (ap); - return done; + return ret; } int attribute_compat_text_section __nldbl___isoc99_vfwscanf (FILE *s, const wchar_t *fmt, va_list ap) { - int res; - set_no_long_double (); - res = __isoc99_vfwscanf (s, fmt, ap); - clear_no_long_double (); - return res; + return __vfwscanf_internal (s, fmt, ap, SCANF_LDBL_IS_DBL | SCANF_ISOC99_A); } libc_hidden_def (__nldbl___isoc99_vfwscanf) @@ -951,26 +938,28 @@ int attribute_compat_text_section __nldbl___isoc99_swscanf (const wchar_t *s, const wchar_t *fmt, ...) { - va_list arg; - int done; + _IO_strfile sf; + struct _IO_wide_data wd; + FILE *f = _IO_strfile_readw (&sf, &wd, s); + va_list ap; + int ret; - va_start (arg, fmt); - done = __nldbl___isoc99_vswscanf (s, fmt, arg); - va_end (arg); + va_start (ap, fmt); + ret = __vfwscanf_internal (f, fmt, ap, SCANF_LDBL_IS_DBL | SCANF_ISOC99_A); + va_end (ap); - return done; + return ret; } int attribute_compat_text_section -__nldbl___isoc99_vswscanf (const wchar_t *string, const wchar_t *fmt, - va_list ap) +__nldbl___isoc99_vswscanf (const wchar_t *s, const wchar_t *fmt, va_list ap) { - int res; - __no_long_double = 1; - res = __isoc99_vswscanf (string, fmt, ap); - __no_long_double = 0; - return res; + _IO_strfile sf; + struct _IO_wide_data wd; + FILE *f = _IO_strfile_readw (&sf, &wd, s); + + return __vfwscanf_internal (f, fmt, ap, SCANF_LDBL_IS_DBL | SCANF_ISOC99_A); } libc_hidden_def (__nldbl___isoc99_vswscanf) @@ -978,35 +967,37 @@ int attribute_compat_text_section __nldbl___isoc99_vwscanf (const wchar_t *fmt, va_list ap) { - return __nldbl___isoc99_vfwscanf (stdin, fmt, ap); + return __vfwscanf_internal (stdin, fmt, ap, + SCANF_LDBL_IS_DBL | SCANF_ISOC99_A); } int attribute_compat_text_section -__nldbl___isoc99_fwscanf (FILE *stream, const wchar_t *fmt, ...) +__nldbl___isoc99_fwscanf (FILE *s, const wchar_t *fmt, ...) { - va_list arg; - int done; + va_list ap; + int ret; - va_start (arg, fmt); - done = __nldbl___isoc99_vfwscanf (stream, fmt, arg); - va_end (arg); + va_start (ap, fmt); + ret = __vfwscanf_internal (s, fmt, ap, SCANF_LDBL_IS_DBL | SCANF_ISOC99_A); + va_end (ap); - return done; + return ret; } int attribute_compat_text_section __nldbl___isoc99_wscanf (const wchar_t *fmt, ...) { - va_list arg; - int done; + va_list ap; + int ret; - va_start (arg, fmt); - done = __nldbl___isoc99_vfwscanf (stdin, fmt, arg); - va_end (arg); + va_start (ap, fmt); + ret = __vfwscanf_internal (stdin, fmt, ap, + SCANF_LDBL_IS_DBL | SCANF_ISOC99_A); + va_end (ap); - return done; + return ret; } #if LONG_DOUBLE_COMPAT(libc, GLIBC_2_0) From patchwork Mon Oct 29 12:16:47 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Gabriel F. T. Gomes" X-Patchwork-Id: 990170 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-96799-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=inconstante.eti.br Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="kHU+caou"; 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 42kDCL5mgLz9s9m for ; Mon, 29 Oct 2018 23:18:22 +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-type; q=dns; s=default; b=AV2VY gIxU6SbF8dK8LtYdHX8nW89ElM5MuKErwSevzVETXRd43kIuP99p2ZRx09PIpjdE 09RsfFhcO78yHnoABxt5G0173VOArZsuXjn2qDp5N01NtRYfnZDQXgmP0+4UlSO3 rsM/HMpVOu+foF8RDWqrt9pkSiAF1TbzWr8lKQ= 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-type; s=default; bh=7QgcT11yaI/ V+H/buUvIZx18zns=; b=kHU+caouvCIMAU+Ezl/IRcjfJAE5RGd64BVTdrROs8q hSV04G6vS2nvJJ8VjLOPdAUJdbzLwfZ/whmo5EqyW27QCB8jPzHDHULxHrrQ/oMD FmIIkFvQB19jxJMHRTfU8gu7uejfCdHxiOU0WLRo5mIP91DTVKI57gCBumDpkFWI = Received: (qmail 23748 invoked by alias); 29 Oct 2018 12:17:37 -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 23591 invoked by uid 89); 29 Oct 2018 12:17:36 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-25.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_LAZY_DOMAIN_SECURITY, KAM_SHORT, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.2 spammy=planning, shrink, Shrink X-HELO: mo19.mail-out.ovh.net From: "Gabriel F. T. Gomes" To: Subject: [PATCH v2 5/8] Add __v*printf_internal with flags arguments. Date: Mon, 29 Oct 2018 09:16:47 -0300 Message-ID: <20181029121650.24544-6-gabriel@inconstante.eti.br> In-Reply-To: <20181029121650.24544-1-gabriel@inconstante.eti.br> References: <20181029121650.24544-1-gabriel@inconstante.eti.br> MIME-Version: 1.0 X-Ovh-Tracer-Id: 18038605360613609155 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: 0 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedtkedrheekgdefjecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemucehtddtnecu From: Zack Weinberg Changes since v1: - Fixed white-space errors. - In argp_fmtstream_printf, do not call __vsnprintf, instead call __vsnprintf_internal passing 0 to mode_flags. With this change, there's no need to use libc_hidden_{proto,def} for __vsnprintf (because it doesn't have other internal callers). Also, it is no longer necessary to '#undef __vsnprintf' and '#define __vsnprintf vsnprintf' in argp-namefrob.h. - In __argp_error and __argp_failure call __vasprintf_internal directly, passing 0 (zero) to mode_flags, since these functions do not currently have support for long double with the same format as double (a subsequent patch in my personal branch provides that and adjusts the call accordingly). With this change, there's no need to use libc_hidden_{proto,def} for __vasprintf. It is also no longer required to '#undef __vasprintf' and '#define __vasprintf vasprintf' in argp-namefrob.h. - Declarations of _IO_vfprintf, _IO_vsprintf, __vfwprintf, and __vswprintf removed from the internal headers: libio.h, iolibio.h, and include/wchar.h, since they are no longer called from within glibc. - Added attribute_hidden to all new internal functions, since they are all called from within libc. Here are the objdumps of one such calls, before and after this change, on a 32-bits powerpc machine: Without attribute_hidden: $ objdump -d --reloc INTERNAL-VISIBLE-glibc/libc.so | grep ":" -A 21 000523a0 : 523a0: 94 21 ff f0 stwu r1,-16(r1) 523a4: 7c 85 23 78 mr r5,r4 523a8: 7c 08 02 a6 mflr r0 523ac: 42 9f 00 05 bcl 20,4*cr7+so,523b0 523b0: 7c 64 1b 78 mr r4,r3 523b4: 38 c0 00 00 li r6,0 523b8: 93 c1 00 08 stw r30,8(r1) 523bc: 90 01 00 14 stw r0,20(r1) 523c0: 7f c8 02 a6 mflr r30 523c4: 3f de 00 15 addis r30,r30,21 523c8: 3b de dc 44 addi r30,r30,-9148 523cc: 81 3e fe 80 lwz r9,-384(r30) 523d0: 80 69 00 00 lwz r3,0(r9) 523d4: 48 01 52 bd bl 67690 <__vfprintf_internal> 523d8: 80 01 00 14 lwz r0,20(r1) 523dc: 83 c1 00 08 lwz r30,8(r1) 523e0: 38 21 00 10 addi r1,r1,16 523e4: 7c 08 03 a6 mtlr r0 523e8: 4e 80 00 20 blr With attribute_hidden: $ objdump -d --reloc INTERNAL-HIDDEN-glibc/libc.so | grep ":" -A 18 00052370 : 52370: 94 21 ff f0 stwu r1,-16(r1) 52374: 7c 85 23 78 mr r5,r4 52378: 7d 88 02 a6 mflr r12 5237c: 42 9f 00 05 bcl 20,4*cr7+so,52380 52380: 7c 64 1b 78 mr r4,r3 52384: 38 c0 00 00 li r6,0 52388: 93 c1 00 08 stw r30,8(r1) 5238c: 7f c8 02 a6 mflr r30 52390: 7d 88 03 a6 mtlr r12 52394: 3f de 00 15 addis r30,r30,21 52398: 3b de dc 74 addi r30,r30,-9100 5239c: 81 3e fe 80 lwz r9,-384(r30) 523a0: 83 c1 00 08 lwz r30,8(r1) 523a4: 80 69 00 00 lwz r3,0(r9) 523a8: 38 21 00 10 addi r1,r1,16 523ac: 48 01 52 24 b 675d0 <__vfprintf_internal> The branch-and-link instruction is gone. Additional note for review: - Reviewing the changes from vfprintf.c to vfprintf-internal.c in the original patch would be vey hard, because git doesn't detect the filename change. To make review a little easier, I did as Zack did and manually edited the diff. I'll reply to this thread and attach the original patch if someone wants to apply it. (ping me if I forget it) -- 8< -- There are a lot more printf variants than there are scanf variants, and the code for setting up and tearing down their custom FILE variants around the call to __vf(w)printf is more complicated and variable. Therefore, I have added _internal versions of all the v*printf variants, rather than introducing helper routines so that they can all directly call __vf(w)printf_internal, as was done with scanf. As with the scanf changes, in this patch the _internal functions still look at the environmental mode bits and all callers pass 0 for the flags parameter. Several of the affected public functions had _IO_ name aliases that were not exported (but, in one case, appeared in libio.h anyway); I was originally planning to leave them as aliases to avoid having to touch internal callers, but it turns out ldbl_*_alias only work for exported symbols, so they've all been removed instead. It also turns out there were hardly any internal callers. _IO_vsprintf and _IO_vfprintf *are* exported, so those two stick around. Summary for the changes to each of the affected symbols: _IO_vfprintf, _IO_vsprintf: All internal calls removed, thus the internal declarations, as well as uses of libc_hidden_proto and libc_hidden_def, were also removed. The external symbol is now exposed via uses of ldbl_strong_alias to __vfprintf_internal and __vsprintf_internal, respectively. _IO_vasprintf, _IO_vdprintf, _IO_vsnprintf, _IO_vfwprintf, _IO_vswprintf, _IO_obstack_vprintf, _IO_obstack_printf: All internal calls removed, thus declaration in internal headers were also removed. They were never exported, so there are no aliases tying them to the internal functions. I.e.: entirely gone. __vsnprintf: Internal calls were always preceded by macros such as #define __vsnprintf _IO_vsnprintf, and #define __vsnprintf vsnprintf The macros were removed and their uses replaced with calls to the new internal function __vsnprintf_internal. Since there were no internal calls, the internal declaration was also removed. The external symbol is preserved with ldbl_weak_alias to ___vsnprintf. __vfwprintf: All internal calls converted into calls to __vfwprintf_internal, thus the internal declaration was removed. The function is now a wrapper that calls __vfwprintf_internal. The external symbol is preserved. __vswprintf: Similarly, but no external symbol. __vasprintf, __vdprintf, __vfprintf, __vsprintf: New internal wrappers. Not exported. vasprintf, vdprintf, vfprintf, vsprintf, vsnprintf, vfwprintf, vswprintf, obstack_vprintf, obstack_printf: These functions used to be aliases to the respective _IO_* function, they are now aliases to their respective __* functions. Tested for powerpc and powerpc64le. 2018-10-16 Zack Weinberg Gabriel F. T. Gomes * libio/libioP.h (__vfprintf_internal, __vfwprintf_internal) (__vasprintf_internal, __vdprintf_internal, __obstack_vprintf_internal) (__vsprintf_internal, __vsnprintf_internal, __vswprintf_internal): New functions. (PRINTF_LDBL_IS_DBL, PRINTF_FORTIFY): New constants. (_IO_vasprintf, _IO_vdprintf, _IO_vsnprintf): Remove prototypes. * stdio-common/vfprintf-internal.c: Rename from vfprintf.c. Include wctype.h here if COMPILE_WPRINTF is defined. Define __vfprintf_internal or __vfwprintf_internal, depending on COMPILE_WPRINTF. Temporarily, on entry to this function, update mode_flags according to the environmental settings corresponding to PRINTF_LDBL_IS_DBL and PRINTF_FORTIFY. (LDBL_IS_DBL, DO_FORTIFY): New macros. Throughout, use LDBL_IS_DBL instead of __ldbl_is_dbl, and DO_FORTIFY instead of checking _IO_FLAGS2_FORTIFY on the destination FILE. * stdio-common/vfwprintf-internal.c: Rename from vfwprintf.c. Include vfprintf-internal.c. Don't include wctype.h. * stdio-common/vfprintf.c: New file. Just define __vfprintf as a wrapper around __vfprintf_internal, with aliases _IO_vfprintf and vfprintf. * stdio-common/vfwprintf.c: New file. Just define __vfwprintf as a wrapper around __vfwprintf_internal, with aliases _IO_vfwprintf and vfwprintf. * stdio-common/Makefile: Add vfprintf-internal and vfwprintf-internal. * libio/iovdprintf.c (_IO_vdprintf): Rename to __vdprintf_internal and add mode_flags argument; use __vfprintf_internal. (__vdprintf): New function. Alias vdprintf to this. * libio/iovsprintf.c (_IO_vsprintf, __vsprintf): Similarly. * libio/vasprintf.c (_IO_vasprintf, __vasprintf): Similarly. * libio/obprintf.c (_IO_obstack_vprintf, __obstack_vprintf): Similarly. (__obstack_printf): Use __obstack_printf_internal. * libio/vsnprintf.c (_IO_vsnprintf, ___vsnprintf): Similarly, with public aliases __vsnprintf and vsnprintf. Remove use of ldbl_hidden_def, since __vsnprintf is no longer called internally. * libio/vswprintf (_IO_vswprintf, __vswprintf): Similarly, with public aliases _IO_vsprintf and vsprintf. * libio/swprintf.c (__swprintf): Use __vswprintf_internal. * stdio-common/asprintf.c (__asprintf): Use __vasprintf_internal. * stdio-common/dprintf.c (__dprintf): Use __vdprintf_internal. * stdio-common/snprintf.c (__snprintf): Use __vsprintf_internal. * stdio-common/sprintf.c (__sprintf): Use __vsprintf_internal. * debug/obprintf_chk.c, debug/vasprintf_chk.c, debug/vdprintf_chk.c * debug/vsnprintf_chk.c, debug/vsprintf_chk.c, hurd/vpprintf.c * stdio-common/fprintf.c, stdio-common/fxprintf.c * stdio-common/printf.c: Use __vfprintf_internal. * debug/fwprintf_chk.c, debug/vfwprintf_chk.c, debug/vswprintf_chk.c * debug/vwprintf_chk.c, debug/wprintf_chk.c, libio/fwprintf.c * libio/vwprintf.c, libio/wprintf.c: Use __vfwprintf_internal. * sysdeps/ieee754/ldbl-opt/nldbl-compat.c: Use __vsprintf_internal, __obstack_vprintf_internal, __vasprintf_internal, __vdprintf_internal, __vsnprintf_internal, __vswprintf_internal, __vfprintf_internal, and __vfwprintf_internal. * libio/libio.h: Remove libc_hidden_proto and declaration for _IO_vfprintf. Remove declaration of _IO_vfwprintf. * libio/iolibio.h: Remove libc_hidden_proto and declaration for _IO_vsprintf. Remove declarations of _IO_vswprintf, _IO_obstack_printf, and _IO_obstack_printf. * include/stdio.h: Add prototype for __vasprintf. (__vsnprintf): Remove declaration, because there are no more internal calls. * include/wchar.h (__vfwprintf, __vswprintf): Remove declaration, because there are no more internal calls. * argp/argp-fmtstream.c (__argp_fmtstream_printf): Use __vsnprintf_internal, instead of _IO_vsnprintf. * argp/argp-help.c (__argp_error, __argp_failure): Use __vasprintf_internal, instead of _IO_vasprintf. * argp/argp-namefrob.h (__vsnprintf): Do not undefined then redefine, because there are no more internal calls. Signed-off-by: Zack Weinberg Signed-off-by: Gabriel F. T. Gomes Signed-off-by: Zack Weinberg Signed-off-by: Gabriel F. T. Gomes --- argp/argp-fmtstream.c | 3 +- argp/argp-help.c | 4 +- argp/argp-namefrob.h | 2 - debug/fwprintf_chk.c | 2 +- debug/obprintf_chk.c | 2 +- debug/vasprintf_chk.c | 2 +- debug/vdprintf_chk.c | 2 +- debug/vfwprintf_chk.c | 2 +- debug/vsnprintf_chk.c | 2 +- debug/vsprintf_chk.c | 2 +- debug/vswprintf_chk.c | 2 +- debug/vwprintf_chk.c | 2 +- debug/wprintf_chk.c | 2 +- hurd/vpprintf.c | 2 +- include/stdio.h | 3 - include/wchar.h | 10 - libio/fwprintf.c | 2 +- libio/iolibio.h | 8 - libio/iovdprintf.c | 13 +- libio/iovsprintf.c | 16 +- libio/libio.h | 5 - libio/libioP.h | 40 +- libio/obprintf.c | 19 +- libio/swprintf.c | 2 +- libio/vasprintf.c | 20 +- libio/vsnprintf.c | 16 +- libio/vswprintf.c | 16 +- libio/vwprintf.c | 2 +- libio/wprintf.c | 2 +- stdio-common/Makefile | 3 +- stdio-common/asprintf.c | 6 +- stdio-common/dprintf.c | 5 +- stdio-common/fprintf.c | 2 +- stdio-common/fxprintf.c | 4 +- stdio-common/printf.c | 3 +- stdio-common/snprintf.c | 4 +- stdio-common/sprintf.c | 4 +- stdio-common/vfprintf-internal.c | 2366 +++++++++++++++++++++++++++++++ stdio-common/vfprintf.c | 2351 +----------------------------- stdio-common/vfwprintf-internal.c | 2 + stdio-common/vfwprintf.c | 28 +- stdio-common/vprintf.c | 4 +- stdlib/strfrom-skeleton.c | 2 +- sysdeps/ieee754/ldbl-opt/nldbl-compat.c | 21 +- 44 files changed, 2544 insertions(+), 2466 deletions(-) create mode 100644 stdio-common/vfprintf-internal.c create mode 100644 stdio-common/vfwprintf-internal.c diff --git a/argp/argp-fmtstream.c b/argp/argp-fmtstream.c index e43a0c7cf1..b9dcb2c9c7 100644 --- a/argp/argp-fmtstream.c +++ b/argp/argp-fmtstream.c @@ -42,7 +42,6 @@ #ifdef _LIBC # include # include -# define __vsnprintf(s, l, f, a) _IO_vsnprintf (s, l, f, a) #endif #define INIT_BUF_SIZE 200 @@ -409,7 +408,7 @@ __argp_fmtstream_printf (struct argp_fmtstream *fs, const char *fmt, ...) va_start (args, fmt); avail = fs->end - fs->p; - out = __vsnprintf (fs->p, avail, fmt, args); + out = __vsnprintf_internal (fs->p, avail, fmt, args, 0); va_end (args); if ((size_t) out >= avail) size_guess = out + 1; diff --git a/argp/argp-help.c b/argp/argp-help.c index 2b6b0775d6..6857391ce2 100644 --- a/argp/argp-help.c +++ b/argp/argp-help.c @@ -1769,7 +1769,7 @@ __argp_error (const struct argp_state *state, const char *fmt, ...) #ifdef _LIBC char *buf; - if (_IO_vasprintf (&buf, fmt, ap) < 0) + if (__vasprintf_internal (&buf, fmt, ap, 0) < 0) buf = NULL; __fxprintf (stream, "%s: %s\n", @@ -1839,7 +1839,7 @@ __argp_failure (const struct argp_state *state, int status, int errnum, #ifdef _LIBC char *buf; - if (_IO_vasprintf (&buf, fmt, ap) < 0) + if (__vasprintf_internal (&buf, fmt, ap, 0) < 0) buf = NULL; __fxprintf (stream, ": %s", buf); diff --git a/argp/argp-namefrob.h b/argp/argp-namefrob.h index 5588fe172a..5e48b5940d 100644 --- a/argp/argp-namefrob.h +++ b/argp/argp-namefrob.h @@ -98,8 +98,6 @@ #define __strerror_r strerror_r #undef __strndup #define __strndup strndup -#undef __vsnprintf -#define __vsnprintf vsnprintf #if defined(HAVE_DECL_CLEARERR_UNLOCKED) && !HAVE_DECL_CLEARERR_UNLOCKED # define clearerr_unlocked(x) clearerr (x) diff --git a/debug/fwprintf_chk.c b/debug/fwprintf_chk.c index aeb83077da..63167c1839 100644 --- a/debug/fwprintf_chk.c +++ b/debug/fwprintf_chk.c @@ -32,7 +32,7 @@ __fwprintf_chk (FILE *fp, int flag, const wchar_t *format, ...) fp->_flags2 |= _IO_FLAGS2_FORTIFY; va_start (ap, format); - done = _IO_vfwprintf (fp, format, ap); + done = __vfwprintf_internal (fp, format, ap, 0); va_end (ap); if (flag > 0) diff --git a/debug/obprintf_chk.c b/debug/obprintf_chk.c index 3ac5a3cd4f..41dd481c34 100644 --- a/debug/obprintf_chk.c +++ b/debug/obprintf_chk.c @@ -91,7 +91,7 @@ __obstack_vprintf_chk (struct obstack *obstack, int flags, const char *format, if (flags > 0) new_f.ofile.file.file._flags2 |= _IO_FLAGS2_FORTIFY; - result = _IO_vfprintf (&new_f.ofile.file.file, format, args); + result = __vfprintf_internal (&new_f.ofile.file.file, format, args, 0); /* Shrink the buffer to the space we really currently need. */ obstack_blank_fast (obstack, (new_f.ofile.file.file._IO_write_ptr diff --git a/debug/vasprintf_chk.c b/debug/vasprintf_chk.c index 48b4741651..dbfebff83f 100644 --- a/debug/vasprintf_chk.c +++ b/debug/vasprintf_chk.c @@ -63,7 +63,7 @@ __vasprintf_chk (char **result_ptr, int flags, const char *format, if (flags > 0) sf._sbf._f._flags2 |= _IO_FLAGS2_FORTIFY; - ret = _IO_vfprintf (&sf._sbf._f, format, args); + ret = __vfprintf_internal (&sf._sbf._f, format, args, 0); if (ret < 0) { free (sf._sbf._f._IO_buf_base); diff --git a/debug/vdprintf_chk.c b/debug/vdprintf_chk.c index bc713b4962..4386127cfe 100644 --- a/debug/vdprintf_chk.c +++ b/debug/vdprintf_chk.c @@ -55,7 +55,7 @@ __vdprintf_chk (int d, int flags, const char *format, va_list arg) if (flags > 0) tmpfil.file._flags2 |= _IO_FLAGS2_FORTIFY; - done = _IO_vfprintf (&tmpfil.file, format, arg); + done = __vfprintf_internal (&tmpfil.file, format, arg, 0); _IO_FINISH (&tmpfil.file); diff --git a/debug/vfwprintf_chk.c b/debug/vfwprintf_chk.c index 1ffd18cbd2..abf2bd6517 100644 --- a/debug/vfwprintf_chk.c +++ b/debug/vfwprintf_chk.c @@ -30,7 +30,7 @@ __vfwprintf_chk (FILE *fp, int flag, const wchar_t *format, va_list ap) if (flag > 0) fp->_flags2 |= _IO_FLAGS2_FORTIFY; - done = _IO_vfwprintf (fp, format, ap); + done = __vfwprintf_internal (fp, format, ap, 0); if (flag > 0) fp->_flags2 &= ~_IO_FLAGS2_FORTIFY; diff --git a/debug/vsnprintf_chk.c b/debug/vsnprintf_chk.c index d20d0fbd93..95d286f416 100644 --- a/debug/vsnprintf_chk.c +++ b/debug/vsnprintf_chk.c @@ -60,7 +60,7 @@ ___vsnprintf_chk (char *s, size_t maxlen, int flags, size_t slen, sf.f._sbf._f._flags2 |= _IO_FLAGS2_FORTIFY; _IO_str_init_static_internal (&sf.f, s, maxlen - 1, s); - ret = _IO_vfprintf (&sf.f._sbf._f, format, args); + ret = __vfprintf_internal (&sf.f._sbf._f, format, args, 0); if (sf.f._sbf._f._IO_buf_base != sf.overflow_buf) *sf.f._sbf._f._IO_write_ptr = '\0'; diff --git a/debug/vsprintf_chk.c b/debug/vsprintf_chk.c index 9a443bb699..53f07236ae 100644 --- a/debug/vsprintf_chk.c +++ b/debug/vsprintf_chk.c @@ -80,7 +80,7 @@ ___vsprintf_chk (char *s, int flags, size_t slen, const char *format, if (flags > 0) f._sbf._f._flags2 |= _IO_FLAGS2_FORTIFY; - ret = _IO_vfprintf (&f._sbf._f, format, args); + ret = __vfprintf_internal (&f._sbf._f, format, args, 0); *f._sbf._f._IO_write_ptr = '\0'; return ret; diff --git a/debug/vswprintf_chk.c b/debug/vswprintf_chk.c index c6a7edcacd..4d616f8835 100644 --- a/debug/vswprintf_chk.c +++ b/debug/vswprintf_chk.c @@ -59,7 +59,7 @@ __vswprintf_chk (wchar_t *s, size_t maxlen, int flags, size_t slen, sf.f._sbf._f._flags2 |= _IO_FLAGS2_FORTIFY; _IO_wstr_init_static (&sf.f._sbf._f, s, maxlen - 1, s); - ret = _IO_vfwprintf ((FILE *) &sf.f._sbf, format, args); + ret = __vfwprintf_internal ((FILE *) &sf.f._sbf, format, args, 0); if (sf.f._sbf._f._wide_data->_IO_buf_base == sf.overflow_buf) /* ISO C99 requires swprintf/vswprintf to return an error if the diff --git a/debug/vwprintf_chk.c b/debug/vwprintf_chk.c index 51b67c159d..fedc7a46bf 100644 --- a/debug/vwprintf_chk.c +++ b/debug/vwprintf_chk.c @@ -31,7 +31,7 @@ __vwprintf_chk (int flag, const wchar_t *format, va_list ap) if (flag > 0) stdout->_flags2 |= _IO_FLAGS2_FORTIFY; - done = _IO_vfwprintf (stdout, format, ap); + done = __vfwprintf_internal (stdout, format, ap, 0); if (flag > 0) stdout->_flags2 &= ~_IO_FLAGS2_FORTIFY; diff --git a/debug/wprintf_chk.c b/debug/wprintf_chk.c index 17023b6bb4..819050e5af 100644 --- a/debug/wprintf_chk.c +++ b/debug/wprintf_chk.c @@ -33,7 +33,7 @@ __wprintf_chk (int flag, const wchar_t *format, ...) stdout->_flags2 |= _IO_FLAGS2_FORTIFY; va_start (ap, format); - done = _IO_vfwprintf (stdout, format, ap); + done = __vfwprintf_internal (stdout, format, ap, 0); va_end (ap); if (flag > 0) diff --git a/hurd/vpprintf.c b/hurd/vpprintf.c index 76cd31f922..b9634afc2b 100644 --- a/hurd/vpprintf.c +++ b/hurd/vpprintf.c @@ -53,7 +53,7 @@ vpprintf (io_t port, const char *format, va_list arg) _IO_cookie_init (&temp_f.cfile, _IO_NO_READS, (void *) port, (cookie_io_functions_t) { write: do_write }); - done = _IO_vfprintf (&temp_f.cfile.__fp.file, format, arg); + done = __vfprintf_internal (&temp_f.cfile.__fp.file, format, arg, 0); return done; } diff --git a/include/stdio.h b/include/stdio.h index 51ada4a4c4..0856d729d9 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -14,9 +14,6 @@ extern int __snprintf (char *__restrict __s, size_t __maxlen, const char *__restrict __format, ...) __attribute__ ((__format__ (__printf__, 3, 4))); libc_hidden_proto (__snprintf) -extern int __vsnprintf (char *__restrict __s, size_t __maxlen, - const char *__restrict __format, __gnuc_va_list __arg) - __attribute__ ((__format__ (__printf__, 3, 0))); extern int __vfscanf (FILE *__restrict __s, const char *__restrict __format, __gnuc_va_list __arg) diff --git a/include/wchar.h b/include/wchar.h index 1db0ac8278..d0fe45c3a6 100644 --- a/include/wchar.h +++ b/include/wchar.h @@ -203,20 +203,10 @@ extern int __vfwscanf (__FILE *__restrict __s, __gnuc_va_list __arg) attribute_hidden /* __attribute__ ((__format__ (__wscanf__, 2, 0)) */; -extern int __vswprintf (wchar_t *__restrict __s, size_t __n, - const wchar_t *__restrict __format, - __gnuc_va_list __arg) - attribute_hidden - /* __attribute__ ((__format__ (__wprintf__, 3, 0))) */; extern int __fwprintf (__FILE *__restrict __s, const wchar_t *__restrict __format, ...) attribute_hidden /* __attribute__ ((__format__ (__wprintf__, 2, 3))) */; -extern int __vfwprintf (__FILE *__restrict __s, - const wchar_t *__restrict __format, - __gnuc_va_list __arg) - attribute_hidden - /* __attribute__ ((__format__ (__wprintf__, 2, 0))) */; extern int __vfwprintf_chk (FILE *__restrict __s, int __flag, const wchar_t *__restrict __format, __gnuc_va_list __arg) diff --git a/libio/fwprintf.c b/libio/fwprintf.c index fab63a8716..9903f1f342 100644 --- a/libio/fwprintf.c +++ b/libio/fwprintf.c @@ -30,7 +30,7 @@ __fwprintf (FILE *stream, const wchar_t *format, ...) int done; va_start (arg, format); - done = __vfwprintf (stream, format, arg); + done = __vfwprintf_internal (stream, format, arg, 0); va_end (arg); return done; diff --git a/libio/iolibio.h b/libio/iolibio.h index 6c94fe6d62..2642d71e4f 100644 --- a/libio/iolibio.h +++ b/libio/iolibio.h @@ -51,15 +51,7 @@ extern int _IO_sscanf (const char*, const char*, ...) __THROW; extern int _IO_sprintf (char *, const char*, ...) __THROW; extern int _IO_ungetc (int, FILE*) __THROW; extern int _IO_vsscanf (const char *, const char *, __gnuc_va_list) __THROW; -extern int _IO_vsprintf (char*, const char*, __gnuc_va_list) __THROW; -libc_hidden_proto (_IO_vsprintf) -extern int _IO_vswprintf (wchar_t*, size_t, const wchar_t*, __gnuc_va_list) - __THROW; -struct obstack; -extern int _IO_obstack_vprintf (struct obstack *, const char *, __gnuc_va_list) - __THROW; -extern int _IO_obstack_printf (struct obstack *, const char *, ...) __THROW; #define _IO_clearerr(FP) ((FP)->_flags &= ~(_IO_ERR_SEEN|_IO_EOF_SEEN)) #define _IO_fseek(__fp, __offset, __whence) \ (_IO_seekoff_unlocked (__fp, __offset, __whence, _IOS_INPUT|_IOS_OUTPUT) \ diff --git a/libio/iovdprintf.c b/libio/iovdprintf.c index 78a3a2bd15..1d2ed0f9e7 100644 --- a/libio/iovdprintf.c +++ b/libio/iovdprintf.c @@ -28,7 +28,8 @@ #include int -_IO_vdprintf (int d, const char *format, va_list arg) +__vdprintf_internal (int d, const char *format, va_list arg, + unsigned int mode_flags) { struct _IO_FILE_plus tmpfil; struct _IO_wide_data wd; @@ -50,7 +51,7 @@ _IO_vdprintf (int d, const char *format, va_list arg) _IO_mask_flags (&tmpfil.file, _IO_NO_READS, _IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING); - done = _IO_vfprintf (&tmpfil.file, format, arg); + done = __vfprintf_internal (&tmpfil.file, format, arg, mode_flags); if (done != EOF && _IO_do_flush (&tmpfil.file) == EOF) done = EOF; @@ -59,4 +60,10 @@ _IO_vdprintf (int d, const char *format, va_list arg) return done; } -ldbl_weak_alias (_IO_vdprintf, vdprintf) + +int +__vdprintf (int d, const char *format, va_list arg) +{ + return __vdprintf_internal (d, format, arg, 0); +} +ldbl_weak_alias (__vdprintf, vdprintf) diff --git a/libio/iovsprintf.c b/libio/iovsprintf.c index 4def251701..3b1e8292b5 100644 --- a/libio/iovsprintf.c +++ b/libio/iovsprintf.c @@ -28,7 +28,8 @@ #include "strfile.h" int -__IO_vsprintf (char *string, const char *format, va_list args) +__vsprintf_internal (char *string, const char *format, va_list args, + unsigned int mode_flags) { _IO_strfile sf; int ret; @@ -39,11 +40,16 @@ __IO_vsprintf (char *string, const char *format, va_list args) _IO_no_init (&sf._sbf._f, _IO_USER_LOCK, -1, NULL, NULL); _IO_JUMPS (&sf._sbf) = &_IO_str_jumps; _IO_str_init_static_internal (&sf, string, -1, string); - ret = _IO_vfprintf (&sf._sbf._f, format, args); + ret = __vfprintf_internal (&sf._sbf._f, format, args, mode_flags); _IO_putc_unlocked ('\0', &sf._sbf._f); return ret; } -ldbl_hidden_def (__IO_vsprintf, _IO_vsprintf) -ldbl_strong_alias (__IO_vsprintf, _IO_vsprintf) -ldbl_weak_alias (__IO_vsprintf, vsprintf) +int +__vsprintf (char *string, const char *format, va_list args) +{ + return __vsprintf_internal (string, format, args, 0); +} + +ldbl_strong_alias (__vsprintf, _IO_vsprintf) +ldbl_weak_alias (__vsprintf, vsprintf) diff --git a/libio/libio.h b/libio/libio.h index 30cb7d784f..c188814ccc 100644 --- a/libio/libio.h +++ b/libio/libio.h @@ -255,8 +255,6 @@ extern int _IO_ftrylockfile (FILE *) __THROW; extern int _IO_vfscanf (FILE * __restrict, const char * __restrict, __gnuc_va_list, int *__restrict); -extern int _IO_vfprintf (FILE *__restrict, const char *__restrict, - __gnuc_va_list); extern __ssize_t _IO_padn (FILE *, int, __ssize_t); extern size_t _IO_sgetn (FILE *, void *, size_t); @@ -298,8 +296,6 @@ weak_extern (_IO_stdin_used); extern int _IO_vfwscanf (FILE * __restrict, const wchar_t * __restrict, __gnuc_va_list, int *__restrict); -extern int _IO_vfwprintf (FILE *__restrict, const wchar_t *__restrict, - __gnuc_va_list); extern __ssize_t _IO_wpadn (FILE *, wint_t, __ssize_t); extern void _IO_free_wbackup_area (FILE *) __THROW; @@ -319,7 +315,6 @@ libc_hidden_proto (_IO_free_wbackup_area) libc_hidden_proto (_IO_padn) libc_hidden_proto (_IO_putc) libc_hidden_proto (_IO_sgetn) -libc_hidden_proto (_IO_vfprintf) #ifdef _IO_MTSAFE_IO # undef _IO_peekc diff --git a/libio/libioP.h b/libio/libioP.h index f90fb2c050..c762cf9b67 100644 --- a/libio/libioP.h +++ b/libio/libioP.h @@ -658,12 +658,40 @@ extern off64_t _IO_wstr_seekoff (FILE *, off64_t, int, int) extern wint_t _IO_wstr_pbackfail (FILE *, wint_t) __THROW; extern void _IO_wstr_finish (FILE *, int) __THROW; -extern int _IO_vasprintf (char **result_ptr, const char *format, - va_list args) __THROW; -extern int _IO_vdprintf (int d, const char *format, va_list arg); -extern int _IO_vsnprintf (char *string, size_t maxlen, - const char *format, va_list args) __THROW; - +/* Internal versions of v*printf that take an additional flags + parameter. */ +extern int __vfprintf_internal (FILE *fp, const char *format, va_list ap, + unsigned int mode_flags) + attribute_hidden; +extern int __vfwprintf_internal (FILE *fp, const wchar_t *format, va_list ap, + unsigned int mode_flags) + attribute_hidden; + +extern int __vasprintf_internal (char **result_ptr, const char *format, + va_list ap, unsigned int mode_flags) + attribute_hidden; +extern int __vdprintf_internal (int d, const char *format, va_list ap, + unsigned int mode_flags) + attribute_hidden; +extern int __obstack_vprintf_internal (struct obstack *ob, const char *fmt, + va_list ap, unsigned int mode_flags) + attribute_hidden; + +extern int __vsprintf_internal (char *string, const char *format, va_list ap, + unsigned int mode_flags) + attribute_hidden; +extern int __vsnprintf_internal (char *string, size_t maxlen, + const char *format, va_list ap, + unsigned int mode_flags) + attribute_hidden; +extern int __vswprintf_internal (wchar_t *string, size_t maxlen, + const wchar_t *format, va_list ap, + unsigned int mode_flags) + attribute_hidden; + +/* Flags for __v*printf_internal. */ +#define PRINTF_LDBL_IS_DBL 0x0001 +#define PRINTF_FORTIFY 0x0002 extern size_t _IO_getline (FILE *,char *, size_t, int, int); libc_hidden_proto (_IO_getline) diff --git a/libio/obprintf.c b/libio/obprintf.c index a74f9467a2..10a4b5c10c 100644 --- a/libio/obprintf.c +++ b/libio/obprintf.c @@ -117,7 +117,8 @@ const struct _IO_jump_t _IO_obstack_jumps libio_vtable attribute_hidden = int -_IO_obstack_vprintf (struct obstack *obstack, const char *format, va_list args) +__obstack_vprintf_internal (struct obstack *obstack, const char *format, + va_list args, unsigned int mode_flags) { struct obstack_FILE { @@ -164,7 +165,8 @@ _IO_obstack_vprintf (struct obstack *obstack, const char *format, va_list args) new_f.ofile.obstack = obstack; - result = _IO_vfprintf (&new_f.ofile.file.file, format, args); + result = __vfprintf_internal (&new_f.ofile.file.file, format, args, + mode_flags); /* Shrink the buffer to the space we really currently need. */ obstack_blank_fast (obstack, (new_f.ofile.file.file._IO_write_ptr @@ -172,17 +174,22 @@ _IO_obstack_vprintf (struct obstack *obstack, const char *format, va_list args) return result; } -ldbl_weak_alias (_IO_obstack_vprintf, obstack_vprintf) +int +__obstack_vprintf (struct obstack *obstack, const char *format, va_list ap) +{ + return __obstack_vprintf_internal (obstack, format, ap, 0); +} +ldbl_weak_alias (__obstack_vprintf, obstack_vprintf) int -_IO_obstack_printf (struct obstack *obstack, const char *format, ...) +__obstack_printf (struct obstack *obstack, const char *format, ...) { int result; va_list ap; va_start (ap, format); - result = _IO_obstack_vprintf (obstack, format, ap); + result = __obstack_vprintf_internal (obstack, format, ap, 0); va_end (ap); return result; } -ldbl_weak_alias (_IO_obstack_printf, obstack_printf) +ldbl_weak_alias (__obstack_printf, obstack_printf) diff --git a/libio/swprintf.c b/libio/swprintf.c index 10f722d035..19b3f33198 100644 --- a/libio/swprintf.c +++ b/libio/swprintf.c @@ -28,7 +28,7 @@ __swprintf (wchar_t *s, size_t n, const wchar_t *format, ...) int done; va_start (arg, format); - done = __vswprintf (s, n, format, arg); + done = __vswprintf_internal (s, n, format, arg, 0); va_end (arg); return done; diff --git a/libio/vasprintf.c b/libio/vasprintf.c index 6c35d2b108..fabd84f403 100644 --- a/libio/vasprintf.c +++ b/libio/vasprintf.c @@ -24,15 +24,13 @@ This exception applies to code released by its copyright holders in files containing the exception. */ -#include #include -#include "libioP.h" -#include "stdio.h" -#include -#include "strfile.h" +#include +#include int -_IO_vasprintf (char **result_ptr, const char *format, va_list args) +__vasprintf_internal (char **result_ptr, const char *format, va_list args, + unsigned int mode_flags) { /* Initial size of the buffer to be used. Will be doubled each time an overflow occurs. */ @@ -56,7 +54,7 @@ _IO_vasprintf (char **result_ptr, const char *format, va_list args) sf._sbf._f._flags &= ~_IO_USER_BUF; sf._s._allocate_buffer_unused = (_IO_alloc_type) malloc; sf._s._free_buffer_unused = (_IO_free_type) free; - ret = _IO_vfprintf (&sf._sbf._f, format, args); + ret = __vfprintf_internal (&sf._sbf._f, format, args, mode_flags); if (ret < 0) { free (sf._sbf._f._IO_buf_base); @@ -85,4 +83,10 @@ _IO_vasprintf (char **result_ptr, const char *format, va_list args) (*result_ptr)[needed - 1] = '\0'; return ret; } -ldbl_weak_alias (_IO_vasprintf, vasprintf) + +int +__vasprintf (char **result_ptr, const char *format, va_list args) +{ + return __vasprintf_internal (result_ptr, format, args, 0); +} +ldbl_weak_alias (__vasprintf, vasprintf) diff --git a/libio/vsnprintf.c b/libio/vsnprintf.c index 39b5500528..35b267abf8 100644 --- a/libio/vsnprintf.c +++ b/libio/vsnprintf.c @@ -90,8 +90,8 @@ const struct _IO_jump_t _IO_strn_jumps libio_vtable attribute_hidden = int -_IO_vsnprintf (char *string, size_t maxlen, const char *format, - va_list args) +__vsnprintf_internal (char *string, size_t maxlen, const char *format, + va_list args, unsigned int mode_flags) { _IO_strnfile sf; int ret; @@ -111,11 +111,17 @@ _IO_vsnprintf (char *string, size_t maxlen, const char *format, _IO_JUMPS (&sf.f._sbf) = &_IO_strn_jumps; string[0] = '\0'; _IO_str_init_static_internal (&sf.f, string, maxlen - 1, string); - ret = _IO_vfprintf (&sf.f._sbf._f, format, args); + ret = __vfprintf_internal (&sf.f._sbf._f, format, args, mode_flags); if (sf.f._sbf._f._IO_buf_base != sf.overflow_buf) *sf.f._sbf._f._IO_write_ptr = '\0'; return ret; } -ldbl_weak_alias (_IO_vsnprintf, __vsnprintf) -ldbl_weak_alias (_IO_vsnprintf, vsnprintf) + +int +___vsnprintf (char *string, size_t maxlen, const char *format, va_list args) +{ + return __vsnprintf_internal (string, maxlen, format, args, 0); +} +ldbl_weak_alias (___vsnprintf, __vsnprintf) +ldbl_weak_alias (___vsnprintf, vsnprintf) diff --git a/libio/vswprintf.c b/libio/vswprintf.c index bcc473d115..e415e39fc9 100644 --- a/libio/vswprintf.c +++ b/libio/vswprintf.c @@ -89,8 +89,8 @@ const struct _IO_jump_t _IO_wstrn_jumps libio_vtable attribute_hidden = int -_IO_vswprintf (wchar_t *string, size_t maxlen, const wchar_t *format, - va_list args) +__vswprintf_internal (wchar_t *string, size_t maxlen, const wchar_t *format, + va_list args, unsigned int mode_flags) { _IO_wstrnfile sf; int ret; @@ -108,7 +108,7 @@ _IO_vswprintf (wchar_t *string, size_t maxlen, const wchar_t *format, _IO_fwide (&sf.f._sbf._f, 1); string[0] = L'\0'; _IO_wstr_init_static (&sf.f._sbf._f, string, maxlen - 1, string); - ret = _IO_vfwprintf ((FILE *) &sf.f._sbf, format, args); + ret = __vfwprintf_internal ((FILE *) &sf.f._sbf, format, args, mode_flags); if (sf.f._sbf._f._wide_data->_IO_buf_base == sf.overflow_buf) /* ISO C99 requires swprintf/vswprintf to return an error if the @@ -120,5 +120,11 @@ _IO_vswprintf (wchar_t *string, size_t maxlen, const wchar_t *format, return ret; } -weak_alias (_IO_vswprintf, __vswprintf) -ldbl_weak_alias (_IO_vswprintf, vswprintf) + +int +__vswprintf (wchar_t *string, size_t maxlen, const wchar_t *format, + va_list args) +{ + return __vswprintf_internal (string, maxlen, format, args, 0); +} +ldbl_weak_alias (__vswprintf, vswprintf) diff --git a/libio/vwprintf.c b/libio/vwprintf.c index 72ebfec92d..e8a529afff 100644 --- a/libio/vwprintf.c +++ b/libio/vwprintf.c @@ -25,6 +25,6 @@ int __vwprintf (const wchar_t *format, __gnuc_va_list arg) { - return __vfwprintf (stdout, format, arg); + return __vfwprintf_internal (stdout, format, arg, 0); } ldbl_strong_alias (__vwprintf, vwprintf) diff --git a/libio/wprintf.c b/libio/wprintf.c index 5945f651fc..361cd40a1b 100644 --- a/libio/wprintf.c +++ b/libio/wprintf.c @@ -29,7 +29,7 @@ __wprintf (const wchar_t *format, ...) int done; va_start (arg, format); - done = __vfwprintf (stdout, format, arg); + done = __vfwprintf_internal (stdout, format, arg, 0); va_end (arg); return done; diff --git a/stdio-common/Makefile b/stdio-common/Makefile index f3b3ceddbd..84bad1fafe 100644 --- a/stdio-common/Makefile +++ b/stdio-common/Makefile @@ -40,7 +40,8 @@ routines := \ isoc99_scanf isoc99_vscanf isoc99_fscanf isoc99_vfscanf isoc99_sscanf \ isoc99_vsscanf \ psiginfo gentempfd \ - vfscanf-internal vfwscanf-internal iovfscanf iovfwscanf + vfscanf-internal vfwscanf-internal iovfscanf iovfwscanf \ + vfprintf-internal vfwprintf-internal aux := errlist siglist printf-parsemb printf-parsewc fxprintf diff --git a/stdio-common/asprintf.c b/stdio-common/asprintf.c index bff858e657..8943ffcae1 100644 --- a/stdio-common/asprintf.c +++ b/stdio-common/asprintf.c @@ -16,11 +16,7 @@ . */ #include -#include - #include -#define vasprintf(s, f, a) _IO_vasprintf (s, f, a) -#undef __asprintf /* Write formatted output from FORMAT to a string which is allocated with malloc and stored in *STRING_PTR. */ @@ -32,7 +28,7 @@ ___asprintf (char **string_ptr, const char *format, ...) int done; va_start (arg, format); - done = vasprintf (string_ptr, format, arg); + done = __vasprintf_internal (string_ptr, format, arg, 0); va_end (arg); return done; diff --git a/stdio-common/dprintf.c b/stdio-common/dprintf.c index 11bd12b838..9adc8ae4c7 100644 --- a/stdio-common/dprintf.c +++ b/stdio-common/dprintf.c @@ -16,10 +16,7 @@ . */ #include -#include - #include -#define vdprintf(d, f, a) _IO_vdprintf (d, f, a) /* Write formatted output to D, according to the format string FORMAT. */ /* VARARGS2 */ @@ -30,7 +27,7 @@ __dprintf (int d, const char *format, ...) int done; va_start (arg, format); - done = vdprintf (d, format, arg); + done = __vdprintf_internal (d, format, arg, 0); va_end (arg); return done; diff --git a/stdio-common/fprintf.c b/stdio-common/fprintf.c index 2bbf14bf5d..c8f8ac4faf 100644 --- a/stdio-common/fprintf.c +++ b/stdio-common/fprintf.c @@ -29,7 +29,7 @@ __fprintf (FILE *stream, const char *format, ...) int done; va_start (arg, format); - done = vfprintf (stream, format, arg); + done = __vfprintf_internal (stream, format, arg, 0); va_end (arg); return done; diff --git a/stdio-common/fxprintf.c b/stdio-common/fxprintf.c index 8d02b71f91..a028e8edd5 100644 --- a/stdio-common/fxprintf.c +++ b/stdio-common/fxprintf.c @@ -27,7 +27,7 @@ static int locked_vfxprintf (FILE *fp, const char *fmt, va_list ap) { if (_IO_fwide (fp, 0) <= 0) - return _IO_vfprintf (fp, fmt, ap); + return __vfprintf_internal (fp, fmt, ap, 0); /* We must convert the narrow format string to a wide one. Each byte can produce at most one wide character. */ @@ -53,7 +53,7 @@ locked_vfxprintf (FILE *fp, const char *fmt, va_list ap) res = __mbsrtowcs (wfmt, &fmt, len, &mbstate); if (res != -1) - res = _IO_vfwprintf (fp, wfmt, ap); + res = __vfwprintf_internal (fp, wfmt, ap, 0); if (used_malloc) free (wfmt); diff --git a/stdio-common/printf.c b/stdio-common/printf.c index 205b5e42df..ea41dd557c 100644 --- a/stdio-common/printf.c +++ b/stdio-common/printf.c @@ -30,7 +30,7 @@ __printf (const char *format, ...) int done; va_start (arg, format); - done = vfprintf (stdout, format, arg); + done = __vfprintf_internal (stdout, format, arg, 0); va_end (arg); return done; @@ -38,5 +38,4 @@ __printf (const char *format, ...) #undef _IO_printf ldbl_strong_alias (__printf, printf); -/* This is for libg++. */ ldbl_strong_alias (__printf, _IO_printf); diff --git a/stdio-common/snprintf.c b/stdio-common/snprintf.c index 29a169b08b..b75e160ea3 100644 --- a/stdio-common/snprintf.c +++ b/stdio-common/snprintf.c @@ -16,9 +16,7 @@ . */ #include -#include #include -#define __vsnprintf(s, l, f, a) _IO_vsnprintf (s, l, f, a) /* Write formatted output into S, according to the format string FORMAT, writing no more than MAXLEN characters. */ @@ -30,7 +28,7 @@ __snprintf (char *s, size_t maxlen, const char *format, ...) int done; va_start (arg, format); - done = __vsnprintf (s, maxlen, format, arg); + done = __vsnprintf_internal (s, maxlen, format, arg, 0); va_end (arg); return done; diff --git a/stdio-common/sprintf.c b/stdio-common/sprintf.c index bf5671dde9..77423b292f 100644 --- a/stdio-common/sprintf.c +++ b/stdio-common/sprintf.c @@ -16,9 +16,7 @@ . */ #include -#include #include -#define vsprintf(s, f, a) _IO_vsprintf (s, f, a) /* Write formatted output into S, according to the format string FORMAT. */ /* VARARGS2 */ @@ -29,7 +27,7 @@ __sprintf (char *s, const char *format, ...) int done; va_start (arg, format); - done = vsprintf (s, format, arg); + done = __vsprintf_internal (s, format, arg, 0); va_end (arg); return done; diff -u stdio-common/vfprintf.c.old stdio-common/vfprintf-internal.c.new --- stdio-common/vfprintf.c.old 2018-10-26 11:09:08.538713613 -0300 +++ stdio-common/vfprintf-internal.c.new 2018-10-26 11:08:45.130667960 -0300 @@ -41,6 +41,10 @@ #include +#ifdef COMPILE_WPRINTF +#include +#endif + /* In some cases we need extra space for all the output which is not counted in the width of the string. We assume 32 characters is enough. */ @@ -63,6 +67,8 @@ } \ } while (0) #define UNBUFFERED_P(S) ((S)->_flags & _IO_UNBUFFERED) +#define LDBL_IS_DBL (__glibc_unlikely ((mode_flags & PRINTF_LDBL_IS_DBL) != 0)) +#define DO_FORTIFY ((mode_flags & PRINTF_FORTIFY) != 0) #define done_add(val) \ do { \ @@ -78,7 +84,7 @@ } while (0) #ifndef COMPILE_WPRINTF -# define vfprintf _IO_vfprintf_internal +# define vfprintf __vfprintf_internal # define CHAR_T char # define UCHAR_T unsigned char # define INT_T int @@ -105,7 +111,7 @@ # define ORIENT if (_IO_vtable_offset (s) == 0 && _IO_fwide (s, -1) != -1)\ return -1 #else -# define vfprintf _IO_vfwprintf +# define vfprintf __vfwprintf_internal # define CHAR_T wchar_t /* This is a hack!!! There should be a type uwchar_t. */ # define UCHAR_T unsigned int /* uwchar_t */ @@ -747,7 +753,7 @@ \ if (fspec == NULL) \ { \ - if (__ldbl_is_dbl) \ + if (LDBL_IS_DBL) \ is_long_double = 0; \ \ struct printf_info info = { .prec = prec, \ @@ -778,7 +784,7 @@ else \ { \ ptr = (const void *) &args_value[fspec->data_arg]; \ - if (__ldbl_is_dbl) \ + if (LDBL_IS_DBL) \ { \ fspec->data_arg_type = PA_DOUBLE; \ fspec->info.is_long_double = 0; \ @@ -808,7 +814,7 @@ \ if (fspec == NULL) \ { \ - if (__ldbl_is_dbl) \ + if (LDBL_IS_DBL) \ is_long_double = 0; \ \ struct printf_info info = { .prec = prec, \ @@ -838,7 +844,7 @@ else \ { \ ptr = (const void *) &args_value[fspec->data_arg]; \ - if (__ldbl_is_dbl) \ + if (LDBL_IS_DBL) \ fspec->info.is_long_double = 0; \ /* Not supported by *printf functions. */ \ fspec->info.is_binary128 = 0; \ @@ -891,7 +897,7 @@ /* NOTREACHED */ \ \ LABEL (form_number): \ - if (s->_flags2 & _IO_FLAGS2_FORTIFY) \ + if (DO_FORTIFY) \ { \ if (! readonly_format) \ { \ @@ -1214,7 +1220,8 @@ #endif /* Helper function to provide temporary buffering for unbuffered streams. */ -static int buffered_vfprintf (FILE *stream, const CHAR_T *fmt, va_list) +static int buffered_vfprintf (FILE *stream, const CHAR_T *fmt, va_list, + unsigned int) __THROW __attribute__ ((noinline)); /* Handle positional format specifiers. */ @@ -1223,7 +1230,9 @@ va_list ap, va_list *ap_savep, int done, int nspecs_done, const UCHAR_T *lead_str_end, CHAR_T *work_buffer, int save_errno, - const char *grouping, THOUSANDS_SEP_T); + const char *grouping, + THOUSANDS_SEP_T thousands_sep, + unsigned int mode_flags); /* Handle unknown format specifier. */ static int printf_unknown (FILE *, const struct printf_info *, @@ -1235,7 +1244,7 @@ /* The function itself. */ int -vfprintf (FILE *s, const CHAR_T *format, va_list ap) +vfprintf (FILE *s, const CHAR_T *format, va_list ap, unsigned int mode_flags) { /* The character used as thousands separator. */ THOUSANDS_SEP_T thousands_sep = 0; @@ -1273,6 +1282,12 @@ 0 if unknown. */ int readonly_format = 0; + /* Temporarily honor environmental settings. */ + if (__ldbl_is_dbl) + mode_flags |= PRINTF_LDBL_IS_DBL; + if (s->_flags2 & _IO_FLAGS2_FORTIFY) + mode_flags |= PRINTF_FORTIFY; + /* Orient the stream. */ #ifdef ORIENT ORIENT; @@ -1293,7 +1308,7 @@ if (UNBUFFERED_P (s)) /* Use a helper function which will allocate a local temporary buffer for the stream and then call us again. */ - return buffered_vfprintf (s, format, ap); + return buffered_vfprintf (s, format, ap, mode_flags); /* Initialize local variables. */ done = 0; @@ -1682,7 +1697,7 @@ } done = printf_positional (s, format, readonly_format, ap, &ap_save, done, nspecs_done, lead_str_end, work_buffer, - save_errno, grouping, thousands_sep); + save_errno, grouping, thousands_sep, mode_flags); all_done: if (__glibc_unlikely (workstart != NULL)) @@ -1699,7 +1714,8 @@ va_list ap, va_list *ap_savep, int done, int nspecs_done, const UCHAR_T *lead_str_end, CHAR_T *work_buffer, int save_errno, - const char *grouping, THOUSANDS_SEP_T thousands_sep) + const char *grouping, THOUSANDS_SEP_T thousands_sep, + unsigned int mode_flags) { /* For positional argument handling. */ struct scratch_buffer specsbuf; @@ -1789,7 +1805,7 @@ now. */ args_size = &args_value[nargs].pa_int; args_type = &args_size[nargs]; - memset (args_type, s->_flags2 & _IO_FLAGS2_FORTIFY ? '\xff' : '\0', + memset (args_type, DO_FORTIFY ? '\xff' : '\0', nargs * sizeof (*args_type)); } @@ -1856,7 +1872,7 @@ case PA_FLOAT: /* Promoted. */ T (PA_DOUBLE, pa_double, double); case PA_DOUBLE|PA_FLAG_LONG_DOUBLE: - if (__ldbl_is_dbl) + if (LDBL_IS_DBL) { args_value[cnt].pa_double = va_arg (*ap_savep, double); args_type[cnt] &= ~PA_FLAG_LONG_DOUBLE; @@ -1884,7 +1900,7 @@ case -1: /* Error case. Not all parameters appear in N$ format strings. We have no way to determine their type. */ - assert (s->_flags2 & _IO_FLAGS2_FORTIFY); + assert (DO_FORTIFY); __libc_fatal ("*** invalid %N$ use detected ***\n"); } @@ -2285,7 +2301,8 @@ #endif static int -buffered_vfprintf (FILE *s, const CHAR_T *format, va_list args) +buffered_vfprintf (FILE *s, const CHAR_T *format, va_list args, + unsigned int mode_flags) { CHAR_T buf[BUFSIZ]; struct helper_file helper; @@ -2318,11 +2335,7 @@ _IO_JUMPS (&helper._f) = (struct _IO_jump_t *) &_IO_helper_jumps; /* Now print to helper instead. */ -#ifndef COMPILE_WPRINTF - result = _IO_vfprintf (hp, format, args); -#else - result = vfprintf (hp, format, args); -#endif + result = vfprintf (hp, format, args, mode_flags); /* Lock stream. */ __libc_cleanup_region_start (1, (void (*) (void *)) &_IO_funlockfile, s); @@ -2351,14 +2364,3 @@ return result; } - -#undef vfprintf -#ifdef COMPILE_WPRINTF -strong_alias (_IO_vfwprintf, __vfwprintf); -ldbl_weak_alias (_IO_vfwprintf, vfwprintf); -#else -ldbl_strong_alias (_IO_vfprintf_internal, vfprintf); -ldbl_hidden_def (_IO_vfprintf_internal, vfprintf) -ldbl_strong_alias (_IO_vfprintf_internal, _IO_vfprintf); -ldbl_hidden_def (_IO_vfprintf_internal, _IO_vfprintf) -#endif diff -u /dev/null stdio-common/vfprintf.c.new --- /dev/null 2018-10-15 19:30:16.914999855 -0300 +++ stdio-common/vfprintf.c.new 2018-10-26 11:08:58.758694540 -0300 @@ -0,0 +1,27 @@ +/* Copyright (C) 1991-2018 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 + . */ + +#include + +extern int +__vfprintf (FILE *fp, const char *format, va_list ap) +{ + return __vfprintf_internal (fp, format, ap, 0); +} +ldbl_strong_alias (__vfprintf, _IO_vfprintf); +ldbl_strong_alias (__vfprintf, vfprintf); +ldbl_hidden_def (__vfprintf, vfprintf) diff --git a/stdio-common/vfwprintf-internal.c b/stdio-common/vfwprintf-internal.c new file mode 100644 index 0000000000..cefaf2fafe --- /dev/null +++ b/stdio-common/vfwprintf-internal.c @@ -0,0 +1,2 @@ +#define COMPILE_WPRINTF 1 +#include "vfprintf-internal.c" diff --git a/stdio-common/vfwprintf.c b/stdio-common/vfwprintf.c index 2c3cd06fad..5d65eb7697 100644 --- a/stdio-common/vfwprintf.c +++ b/stdio-common/vfwprintf.c @@ -1,3 +1,25 @@ -#include -#define COMPILE_WPRINTF 1 -#include "vfprintf.c" +/* Copyright (C) 1991-2018 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 + . */ + +#include + +extern int +__vfwprintf (FILE *fp, const wchar_t *format, va_list ap) +{ + return __vfwprintf_internal (fp, format, ap, 0); +} +ldbl_weak_alias (__vfwprintf, vfwprintf); diff --git a/stdio-common/vprintf.c b/stdio-common/vprintf.c index d459642dc8..0da8ba761e 100644 --- a/stdio-common/vprintf.c +++ b/stdio-common/vprintf.c @@ -25,9 +25,9 @@ /* Write formatted output to stdout according to the format string FORMAT, using the argument list in ARG. */ int -__vprintf (const char *format, __gnuc_va_list arg) +__vprintf (const char *format, va_list ap) { - return vfprintf (stdout, format, arg); + return __vfprintf_internal (stdout, format, ap, 0); } ldbl_strong_alias (__vprintf, vprintf) diff --git a/stdlib/strfrom-skeleton.c b/stdlib/strfrom-skeleton.c index 2840512cae..5b33604427 100644 --- a/stdlib/strfrom-skeleton.c +++ b/stdlib/strfrom-skeleton.c @@ -106,7 +106,7 @@ STRFROM (char *dest, size_t size, const char *format, FLOAT f) } /* The following code to prepare the virtual file has been adapted from the - function _IO_vsnprintf from libio. */ + function __vsnprintf_internal from libio. */ if (size == 0) { diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-compat.c b/sysdeps/ieee754/ldbl-opt/nldbl-compat.c index 468e23dec4..bda84af0bb 100644 --- a/sysdeps/ieee754/ldbl-opt/nldbl-compat.c +++ b/sysdeps/ieee754/ldbl-opt/nldbl-compat.c @@ -166,7 +166,7 @@ __nldbl_vfprintf (FILE *s, const char *fmt, va_list ap) { int done; set_no_long_double (); - done = _IO_vfprintf (s, fmt, ap); + done = __vfprintf_internal (s, fmt, ap, 0); clear_no_long_double (); return done; } @@ -175,15 +175,16 @@ strong_alias (__nldbl_vfprintf, __nldbl__IO_vfprintf) int attribute_compat_text_section -__nldbl__IO_vsprintf (char *string, const char *fmt, va_list ap) +__nldbl___vsprintf (char *string, const char *fmt, va_list ap) { int done; __no_long_double = 1; - done = _IO_vsprintf (string, fmt, ap); + done = __vsprintf_internal (string, fmt, ap, 0); __no_long_double = 0; return done; } -weak_alias (__nldbl__IO_vsprintf, __nldbl_vsprintf) +strong_alias (__nldbl___vsprintf, __nldbl__IO_vsprintf) +weak_alias (__nldbl___vsprintf, __nldbl_vsprintf) libc_hidden_def (__nldbl_vsprintf) int @@ -193,7 +194,7 @@ __nldbl_obstack_vprintf (struct obstack *obstack, const char *fmt, { int done; __no_long_double = 1; - done = _IO_obstack_vprintf (obstack, fmt, ap); + done = __obstack_vprintf_internal (obstack, fmt, ap, 0); __no_long_double = 0; return done; } @@ -245,7 +246,7 @@ __nldbl_vasprintf (char **result_ptr, const char *fmt, va_list ap) { int res; __no_long_double = 1; - res = _IO_vasprintf (result_ptr, fmt, ap); + res = __vasprintf_internal (result_ptr, fmt, ap, 0); __no_long_double = 0; return res; } @@ -257,7 +258,7 @@ __nldbl_vdprintf (int d, const char *fmt, va_list arg) { int res; set_no_long_double (); - res = _IO_vdprintf (d, fmt, arg); + res = __vdprintf_internal (d, fmt, arg, 0); clear_no_long_double (); return res; } @@ -269,7 +270,7 @@ __nldbl_vfwprintf (FILE *s, const wchar_t *fmt, va_list ap) { int res; set_no_long_double (); - res = _IO_vfwprintf (s, fmt, ap); + res = __vfwprintf_internal (s, fmt, ap, 0); clear_no_long_double (); return res; } @@ -289,7 +290,7 @@ __nldbl_vsnprintf (char *string, size_t maxlen, const char *fmt, { int res; __no_long_double = 1; - res = _IO_vsnprintf (string, maxlen, fmt, ap); + res = __vsnprintf_internal (string, maxlen, fmt, ap, 0); __no_long_double = 0; return res; } @@ -303,7 +304,7 @@ __nldbl_vswprintf (wchar_t *string, size_t maxlen, const wchar_t *fmt, { int res; __no_long_double = 1; - res = _IO_vswprintf (string, maxlen, fmt, ap); + res = __vswprintf_internal (string, maxlen, fmt, ap, 0); __no_long_double = 0; return res; } From patchwork Mon Oct 29 12:16:48 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Gabriel F. T. Gomes" X-Patchwork-Id: 990169 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-96798-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=inconstante.eti.br Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="oWMzwTFy"; 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 42kDC61m6vz9s9J for ; Mon, 29 Oct 2018 23:18:10 +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-type; q=dns; s=default; b=AbfZV RNYTAYchzQKdQavtvO4qIeGrPLgpivDV0j2maYofXRk4EEsDBegDphHRYLgy24wG 8bGoGGGO8CY4WsgJ571n03nB/YH1RykIRBG8N4blgKFIIO6Sw1t4/yt2+PJUL+a+ omk+HMFpqZpUPClT+6K3RgSv+4M6JbkQx+IGfA= 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-type; s=default; bh=7LNs9GvLBy4 zW0/iCnU7Wo8H+vA=; b=oWMzwTFyAaK+vajqU75Uge1l+l6bAMmO+3t6G78VDgj BkHlxYkelgs/HPN/L9sceZ+gkey6VWS6qQJMzotCxJ1wU+QDLktAb2g9yARWbVtu grjRk7Mpbs7bVXY6cSXfxX4sX4qTc5wCfAPu1CUfFXr6nOsMpTRNWqXkWKD1qUEY = Received: (qmail 23664 invoked by alias); 29 Oct 2018 12:17:37 -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 23542 invoked by uid 89); 29 Oct 2018 12:17:36 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-25.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_LAZY_DOMAIN_SECURITY, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.2 spammy=84, Close, former, internally X-HELO: mo19.mail-out.ovh.net From: "Gabriel F. T. Gomes" To: Subject: [PATCH v2 6/8] Add __vsyslog_internal, with same flags as __v*printf_internal. Date: Mon, 29 Oct 2018 09:16:48 -0300 Message-ID: <20181029121650.24544-7-gabriel@inconstante.eti.br> In-Reply-To: <20181029121650.24544-1-gabriel@inconstante.eti.br> References: <20181029121650.24544-1-gabriel@inconstante.eti.br> MIME-Version: 1.0 X-Ovh-Tracer-Id: 18040012733683125955 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: 0 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedtkedrheekgdefjecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemucehtddtnecu From: Zack Weinberg Changed since v1: - Fixed white-space errors. - Removed internal declaration of __vsyslog_chk, because it's no longer called from within libc. There's a call to it in the inline definition of vsyslog in bits/syslog.h, but that definition is only inlined in user code with: #if __USE_FORTIFY_LEVEL > 0 && defined __fortify_function - Removed libc_hidden_def and libc_hidden_proto for vsyslog, as it is never called internally (it never was). - Added attribute_hidden to the internal declaration of __vsyslog_internal. Here are the objdumps of one internal call, before and after this change, on a 32-bits powerpc machine: Without attribute_hidden: $ objdump -d --reloc SYSLOG-PRISTINE-glibc/libc.so | grep ":" -A 17 000fc790 : fc790: 94 21 ff f0 stwu r1,-16(r1) fc794: 38 c0 00 00 li r6,0 fc798: 7c 08 02 a6 mflr r0 fc79c: 42 9f 00 05 bcl 20,4*cr7+so,fc7a0 fc7a0: 93 c1 00 08 stw r30,8(r1) fc7a4: 90 01 00 14 stw r0,20(r1) fc7a8: 7f c8 02 a6 mflr r30 fc7ac: 3f de 00 0a addis r30,r30,10 fc7b0: 3b de 38 54 addi r30,r30,14420 fc7b4: 4b ff f9 9d bl fc150 <__vsyslog_internal> fc7b8: 80 01 00 14 lwz r0,20(r1) fc7bc: 83 c1 00 08 lwz r30,8(r1) fc7c0: 38 21 00 10 addi r1,r1,16 fc7c4: 7c 08 03 a6 mtlr r0 fc7c8: 4e 80 00 20 blr fc7cc: 60 00 00 00 nop With attribute_hidden: $ objdump -d --reloc SYSLOG-PATCHED-glibc/libc.so | grep ":" -A 5 000fc780 : fc780: 38 c0 00 00 li r6,0 fc784: 4b ff f9 cc b fc150 <__vsyslog_internal> fc788: 60 00 00 00 nop fc78c: 60 00 00 00 nop -- 8< -- __nldbl___vsyslog_chk will ultimately want to pass PRINTF_LDBL_IS_DBL down to __vfprintf_internal *as well as* possibly setting PRINTF_FORTIFY. To make that possible, we need a __vsyslog_internal that takes the same flags as printf. The code in misc/syslog.c does also get a little simpler. Tested for powerpc and powerpc64le. 2018-10-16 Zack Weinberg Gabriel F. T. Gomes * misc/syslog.c: Include libioP.h, not iolibio.h. (__vsyslog_internal): New function with the former body of __vsyslog_chk; takes mode_flags argument same as __v*printf_internal. Call __vfprintf_internal directly. (__vsyslog_chk): Now a wrapper around __vsyslog_internal. Remove libc_hidden_def. (__syslog, __syslog_chk): Use __vsyslog_internal. (__vsyslog): Move to just below __syslog. Use __vsyslog_internal. * include/sys/syslog.h: Add multiple inclusion guard. Add prototype for __vsyslog_internal. Remove declaration and libc_hidden_proto for __vsyslog_chk. * sysdeps/ieee754/ldbl-opt/nldbl-compat.c (__nldbl___vsyslog_chk): Use __vsyslog_internal. Signed-off-by: Zack Weinberg Signed-off-by: Gabriel F. T. Gomes --- include/sys/syslog.h | 19 ++++++++++------- misc/syslog.c | 36 +++++++++++++++++---------------- sysdeps/ieee754/ldbl-opt/nldbl-compat.c | 2 +- 3 files changed, 32 insertions(+), 25 deletions(-) diff --git a/include/sys/syslog.h b/include/sys/syslog.h index 3be3189ed1..89d3479ebc 100644 --- a/include/sys/syslog.h +++ b/include/sys/syslog.h @@ -1,11 +1,16 @@ +#ifndef _LIBC_SYS_SYSLOG_H +#define _LIBC_SYS_SYSLOG_H 1 #include - #ifndef _ISOMAC + libc_hidden_proto (syslog) -libc_hidden_proto (vsyslog) -extern void __vsyslog_chk (int __pri, int __flag, const char *__fmt, - __gnuc_va_list __ap) - __attribute__ ((__format__ (__printf__, 3, 0))); -libc_hidden_proto (__vsyslog_chk) -#endif +/* __vsyslog_internal uses the same mode_flags bits as + __v*printf_internal; see libio/libioP.h. */ +extern void __vsyslog_internal (int pri, const char *fmt, __gnuc_va_list ap, + unsigned int mode_flags) + attribute_hidden + __attribute__ ((__format__ (__printf__, 2, 0))); + +#endif /* _ISOMAC */ +#endif /* syslog.h */ diff --git a/misc/syslog.c b/misc/syslog.c index 644dbe80ec..3a15da41ce 100644 --- a/misc/syslog.c +++ b/misc/syslog.c @@ -53,7 +53,7 @@ static char sccsid[] = "@(#)syslog.c 8.4 (Berkeley) 3/18/94"; #include -#include +#include #include #include @@ -114,24 +114,38 @@ __syslog(int pri, const char *fmt, ...) va_list ap; va_start(ap, fmt); - __vsyslog_chk(pri, -1, fmt, ap); + __vsyslog_internal(pri, fmt, ap, 0); va_end(ap); } ldbl_hidden_def (__syslog, syslog) ldbl_strong_alias (__syslog, syslog) +void +__vsyslog(int pri, const char *fmt, va_list ap) +{ + __vsyslog_internal(pri, fmt, ap, 0); +} +ldbl_weak_alias (__vsyslog, vsyslog) + void __syslog_chk(int pri, int flag, const char *fmt, ...) { va_list ap; va_start(ap, fmt); - __vsyslog_chk(pri, flag, fmt, ap); + __vsyslog_internal(pri, fmt, ap, (flag > 0) ? PRINTF_FORTIFY : 0); va_end(ap); } void __vsyslog_chk(int pri, int flag, const char *fmt, va_list ap) +{ + __vsyslog_internal(pri, fmt, ap, (flag > 0) ? PRINTF_FORTIFY : 0); +} + +void +__vsyslog_internal(int pri, const char *fmt, va_list ap, + unsigned int mode_flags) { struct tm now_tm; time_t now; @@ -215,11 +229,8 @@ __vsyslog_chk(int pri, int flag, const char *fmt, va_list ap) __set_errno (saved_errno); /* We have the header. Print the user's format into the - buffer. */ - if (flag == -1) - vfprintf (f, fmt, ap); - else - __vfprintf_chk (f, flag, fmt, ap); + buffer. */ + __vfprintf_internal (f, fmt, ap, mode_flags); /* Close the memory stream; this will finalize the data into a malloc'd buffer in BUF. */ @@ -316,15 +327,6 @@ __vsyslog_chk(int pri, int flag, const char *fmt, va_list ap) if (buf != failbuf) free (buf); } -libc_hidden_def (__vsyslog_chk) - -void -__vsyslog(int pri, const char *fmt, va_list ap) -{ - __vsyslog_chk (pri, -1, fmt, ap); -} -ldbl_hidden_def (__vsyslog, vsyslog) -ldbl_weak_alias (__vsyslog, vsyslog) static struct sockaddr_un SyslogAddr; /* AF_UNIX address of local logger */ diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-compat.c b/sysdeps/ieee754/ldbl-opt/nldbl-compat.c index bda84af0bb..958bbc1834 100644 --- a/sysdeps/ieee754/ldbl-opt/nldbl-compat.c +++ b/sysdeps/ieee754/ldbl-opt/nldbl-compat.c @@ -843,7 +843,7 @@ attribute_compat_text_section __nldbl___vsyslog_chk (int pri, int flag, const char *fmt, va_list ap) { set_no_long_double (); - __vsyslog_chk (pri, flag, fmt, ap); + __vsyslog_internal (pri, fmt, ap, (flag > 0) ? PRINTF_FORTIFY : 0); clear_no_long_double (); } libc_hidden_def (__nldbl___vsyslog_chk) From patchwork Mon Oct 29 12:16:49 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Gabriel F. T. Gomes" X-Patchwork-Id: 990171 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-96800-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=inconstante.eti.br Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="TQfJDi1f"; 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 42kDCc1y89z9s7T for ; Mon, 29 Oct 2018 23:18:36 +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-type; q=dns; s=default; b=kjusx mVsbaNOOvH37BHBxylg6P84UqMFMBBQuPM/h4SGbB0NnmubxEJYXVLtBCppFgsa8 96wEw0rwAgl+YwBOxl9nh6dYS/bcwAJxwVvfKJNdC0a9d6nw9VpUylVWH5lZ61wx 98l+tdfKPZvgNs9yrSqzDtGvUY1pfzzbkwQTW8= 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-type; s=default; bh=sJe4CdSU48C n+c+g+brpQ7dBB1I=; b=TQfJDi1fPaD2da9bPv6kh9pYdowIUDT5qxMwjIBTumw WcIuyzWoQXeCLlEOvE3RGj/k9IRfXLVvJbbbywUjxazCkp1MpRzc7KaB1vG1S/bZ JWWpg/UaUIXjS7uuGngtvbvzYj/MLseBxDRaYIaDqQW8S9OmQD2ak5O0ldbadH4w = Received: (qmail 25458 invoked by alias); 29 Oct 2018 12:17:52 -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 25330 invoked by uid 89); 29 Oct 2018 12:17:51 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-25.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_LAZY_DOMAIN_SECURITY, KAM_SHORT, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.2 spammy=filled, upfront, Though X-HELO: mo19.mail-out.ovh.net From: "Gabriel F. T. Gomes" To: Subject: [PATCH v2 7/8] Use PRINTF_FORTIFY instead of _IO_FLAGS2_FORTIFY. Date: Mon, 29 Oct 2018 09:16:49 -0300 Message-ID: <20181029121650.24544-8-gabriel@inconstante.eti.br> In-Reply-To: <20181029121650.24544-1-gabriel@inconstante.eti.br> References: <20181029121650.24544-1-gabriel@inconstante.eti.br> MIME-Version: 1.0 X-Ovh-Tracer-Id: 18041983059418336963 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: 0 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedtkedrheekgdefjecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemucehtddtnecu From: Zack Weinberg Changes since v1: - Fixed white-space errors. - Updated commit message. - In the declaration of __vsnprintf_internal, in libio/libioP.h, mention that passing -1 to the maxlen argument is the behavior of ordinary (v)sprintf function (this was already described in the commit message, but seems relevant to the code itself). -- 8< -- The _chk variants of all of the printf functions become much simpler. This is the last thing that we needed _IO_acquire_lock_clear_flags2 for, so it can go as well. I took the opportunity to make the headers included and the names of all local variables consistent across all the affected files. Since we ultimately want to get rid of __no_long_double as well, it must be possible to get all of the nontrivial effects of the _chk functions by calling the _internal functions with appropriate flags. For most of the __(v)xprintf_chk functions, this is covered by PRINTF_FORTIFY plus some up-front argument checks that can be duplicated. However, __(v)sprintf_chk installs a custom jump table so that it can crash instead of overflowing the output buffer. This functionality is moved to __vsprintf_internal, which now has a 'maxlen' argument like __vsnprintf_internal; to get the unsafe behavior of ordinary (v)sprintf, pass -1 for that argument. obstack_printf_chk and obstack_vprintf_chk are no longer in the same file. Tested for powerpc and powerpc64le. 2018-10-24 Zack Weinberg Gabriel F. T. Gomes * libio/iovsprintf.c (_IO_str_chk_overflow, libio_vtable): Moved here from debug/vsprintf_chk.c. (__vsprintf_internal): Add 'maxlen' argument. Change the setup and completion logic for the strfile to match exactly what __vsprintf_chk used to do, except, when maxlen is -1, pass -1 to _IO_str_init_static_internal instead of maxlen-1. (__vsprintf): Pass -1 as maxlen to __vsprintf_internal. * stdio-common/sprintf.c (__sprintf): Pass -1 as maxlen to __vsprintf_internal. * debug/vsprintf_chk.c (__vsprintf_chk) * debug/sprintf_chk.c (__sprintf_chk): Directly call __vsprintf_internal, passing PRINTF_FORTIFY if 'flags' argument is positive, and slen as maxlen. No need to lock the FILE and/or construct a temporary FILE. Minimize and normalize header inclusions and variable names. Do not libc_hidden_def anything. * debug/asprintf_chk.c (__asprintf_chk) * debug/dprintf_chk.c (__dprintf_chk) * debug/fprintf_chk.c (__fprintf_chk) * debug/fwprintf_chk.c (__fwprintf_chk) * debug/printf_chk.c (__printf_chk) * debug/snprintf_chk.c (__snprintf_chk) * debug/swprintf_chk.c (__swprintf_chk) * debug/vasprintf_chk.c (__vasprintf_chk) * debug/vdprintf_chk.c (__vdprintf_chk) * debug/vfprintf_chk.c (__vfprintf_chk) * debug/vfwprintf_chk.c (__vfwprintf_chk) * debug/vprintf_chk.c (__vprintf_chk) * debug/vsnprintf_chk.c (__vsnprintf_chk) * debug/vswprintf_chk.c (__vswprintf_chk) * debug/vwprintf_chk.c (__vwprintf_chk) * debug/wprintf_chk.c (__wprintf_chk): Directly call the corresponding vxxprintf_internal function, passing PRINTF_FORTIFY if 'flag' argument is positive. No need to lock the FILE and/or construct a temporary FILE. Minimize and normalize header inclusions and variable names. Do not libc_hidden_def anything. * debug/obprintf_chk.c (__obstack_printf_chk): Directly call __obstack_vprintf_internal. (__obstack_vprintf_chk): Convert into a wrapper that calls __obstack_vprintf_internal (these two functions already had the same code) and move to new file... * debug/vobprintf_chk.c (__obstack_vprintf_chk): ... here. New file. * debug/obprintf.c (__obstack_vprintf_internal): Remove the checking of the flags argument and the setting of _IO_FLAGS2_FORTIFY. * debug/Makefile (routines): Add vobprintf_chk. * sysdeps/ieee754/ldbl-opt/nldbl-compat.c (__nldbl___vsprintf): Pass -1 as maxlen to __vsprintf_internal. (__nldbl___vfprintf_chk, __nldbl___vsnprintf_chk) (__nldbl___vsprintf_chk, __nldbl___vswprintf_chk) (__nldbl___vasprintf_chk, __nldbl___vdprintf_chk) (__nldbl___obstack_vfprintf_chk): Directly call the corresponding vxxprintf_internal function, passing PRINTF_FORTIFY if 'flag' argument is positive. If necessary, duplicate comparison of slen with 0 or maxlen from the corresponding non-__nldbl function. * include/stdio.h (__vsnprintf_chk, __vfprintf_chk, __vasprintf_chk) (__vdprintf_chk, __obstack_vfprintf_chk): Remove libc_hidden_proto. * include/wchar.h (__vfwprintf_chk, __vswprintf_chk): Remove libc_hidden_proto. * stdio-common/vfprintf-internal.c (__vfprintf_internal, __vfwprintf_internal): Do not check _IO_FLAGS2_FORTIFY. * libio/libio.h (_IO_FLAGS2_FORTIFY): Remove. * libio/libioP.h: Update prototype of __vsprintf_internal and add a comment explaining why it has the maxlen argument. (_IO_acquire_lock_clear_flags2_fct): Remove. (_IO_acquire_lock_clear_flags2): Remove. (_IO_release_lock): Remove conditional statement which will now never execute. (_IO_acquire_lock): Remove variable which is now unused. * sysdeps/generic/stdio-lock.h (_IO_acquire_lock_clear_flags2): Remove. * sysdeps/nptl/stdio-lock.h (_IO_acquire_lock_clear_flags2): Remove. Signed-off-by: Zack Weinberg Signed-off-by: Gabriel F. T. Gomes --- debug/Makefile | 2 +- debug/asprintf_chk.c | 20 +++---- debug/dprintf_chk.c | 20 +++---- debug/fprintf_chk.c | 20 +++---- debug/fwprintf_chk.c | 20 +++---- debug/obprintf_chk.c | 96 ++++----------------------------- debug/printf_chk.c | 20 +++---- debug/snprintf_chk.c | 24 +++++---- debug/sprintf_chk.c | 25 +++++---- debug/swprintf_chk.c | 27 ++++++---- debug/vasprintf_chk.c | 68 ++--------------------- debug/vdprintf_chk.c | 37 ++----------- debug/vfprintf_chk.c | 21 ++------ debug/vfwprintf_chk.c | 21 ++------ debug/vobprintf_chk.c | 32 +++++++++++ debug/vprintf_chk.c | 20 ++----- debug/vsnprintf_chk.c | 46 +++------------- debug/vsprintf_chk.c | 69 +++--------------------- debug/vswprintf_chk.c | 51 +++--------------- debug/vwprintf_chk.c | 21 ++------ debug/wprintf_chk.c | 21 +++----- include/stdio.h | 5 -- include/wchar.h | 2 - libio/iovsprintf.c | 54 +++++++++++++++++-- libio/libio.h | 1 - libio/libioP.h | 27 ++++------ stdio-common/sprintf.c | 2 +- stdio-common/vfprintf-internal.c | 2 - sysdeps/generic/stdio-lock.h | 7 --- sysdeps/ieee754/ldbl-opt/nldbl-compat.c | 32 +++++++---- sysdeps/nptl/stdio-lock.h | 7 --- 31 files changed, 270 insertions(+), 550 deletions(-) create mode 100644 debug/vobprintf_chk.c diff --git a/debug/Makefile b/debug/Makefile index 506cebc3c4..2ef08cf23b 100644 --- a/debug/Makefile +++ b/debug/Makefile @@ -45,7 +45,7 @@ routines = backtrace backtracesyms backtracesymsfd noophooks \ gethostname_chk getdomainname_chk wcrtomb_chk mbsnrtowcs_chk \ wcsnrtombs_chk mbsrtowcs_chk wcsrtombs_chk mbstowcs_chk \ wcstombs_chk asprintf_chk vasprintf_chk dprintf_chk \ - vdprintf_chk obprintf_chk \ + vdprintf_chk obprintf_chk vobprintf_chk \ longjmp_chk ____longjmp_chk \ fdelt_chk poll_chk ppoll_chk \ explicit_bzero_chk \ diff --git a/debug/asprintf_chk.c b/debug/asprintf_chk.c index 9cd4143f2e..eb885c35ca 100644 --- a/debug/asprintf_chk.c +++ b/debug/asprintf_chk.c @@ -15,22 +15,24 @@ License along with the GNU C Library; if not, see . */ -#include #include -#include +#include /* Write formatted output from FORMAT to a string which is allocated with malloc and stored in *STRING_PTR. */ int -__asprintf_chk (char **result_ptr, int flags, const char *format, ...) +__asprintf_chk (char **result_ptr, int flag, const char *format, ...) { - va_list arg; - int done; + /* For flag > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n + can only come from read-only format strings. */ + unsigned int mode = (flag > 0) ? PRINTF_FORTIFY : 0; + va_list ap; + int ret; - va_start (arg, format); - done = __vasprintf_chk (result_ptr, flags, format, arg); - va_end (arg); + va_start (ap, format); + ret = __vasprintf_internal (result_ptr, format, ap, mode); + va_end (ap); - return done; + return ret; } diff --git a/debug/dprintf_chk.c b/debug/dprintf_chk.c index df3867c61c..b5c62827c0 100644 --- a/debug/dprintf_chk.c +++ b/debug/dprintf_chk.c @@ -15,21 +15,23 @@ License along with the GNU C Library; if not, see . */ -#include #include -#include +#include /* Write formatted output to D, according to the format string FORMAT. */ int -__dprintf_chk (int d, int flags, const char *format, ...) +__dprintf_chk (int d, int flag, const char *format, ...) { - va_list arg; - int done; + /* For flag > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n + can only come from read-only format strings. */ + unsigned int mode = (flag > 0) ? PRINTF_FORTIFY : 0; + va_list ap; + int ret; - va_start (arg, format); - done = __vdprintf_chk (d, flags, format, arg); - va_end (arg); + va_start (ap, format); + ret = __vdprintf_internal (d, format, ap, mode); + va_end (ap); - return done; + return ret; } diff --git a/debug/fprintf_chk.c b/debug/fprintf_chk.c index cff4438afb..14afc073b2 100644 --- a/debug/fprintf_chk.c +++ b/debug/fprintf_chk.c @@ -16,29 +16,23 @@ . */ #include -#include -#include "../libio/libioP.h" +#include /* Write formatted output to FP from the format string FORMAT. */ int ___fprintf_chk (FILE *fp, int flag, const char *format, ...) { + /* For flag > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n + can only come from read-only format strings. */ + unsigned int mode = (flag > 0) ? PRINTF_FORTIFY : 0; va_list ap; - int done; - - _IO_acquire_lock_clear_flags2 (fp); - if (flag > 0) - fp->_flags2 |= _IO_FLAGS2_FORTIFY; + int ret; va_start (ap, format); - done = vfprintf (fp, format, ap); + ret = __vfprintf_internal (fp, format, ap, mode); va_end (ap); - if (flag > 0) - fp->_flags2 &= ~_IO_FLAGS2_FORTIFY; - _IO_release_lock (fp); - - return done; + return ret; } ldbl_strong_alias (___fprintf_chk, __fprintf_chk) diff --git a/debug/fwprintf_chk.c b/debug/fwprintf_chk.c index 63167c1839..10d84ce98b 100644 --- a/debug/fwprintf_chk.c +++ b/debug/fwprintf_chk.c @@ -16,28 +16,22 @@ . */ #include -#include -#include "../libio/libioP.h" +#include /* Write formatted output to FP from the format string FORMAT. */ int __fwprintf_chk (FILE *fp, int flag, const wchar_t *format, ...) { + /* For flag > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n + can only come from read-only format strings. */ + unsigned int mode = (flag > 0) ? PRINTF_FORTIFY : 0; va_list ap; - int done; - - _IO_acquire_lock_clear_flags2 (fp); - if (flag > 0) - fp->_flags2 |= _IO_FLAGS2_FORTIFY; + int ret; va_start (ap, format); - done = __vfwprintf_internal (fp, format, ap, 0); + ret = __vfwprintf_internal (fp, format, ap, mode); va_end (ap); - if (flag > 0) - fp->_flags2 &= ~_IO_FLAGS2_FORTIFY; - _IO_release_lock (fp); - - return done; + return ret; } diff --git a/debug/obprintf_chk.c b/debug/obprintf_chk.c index 41dd481c34..c1a8f9e9a9 100644 --- a/debug/obprintf_chk.c +++ b/debug/obprintf_chk.c @@ -17,99 +17,23 @@ License along with the GNU C Library; if not, see . */ - -#include -#include -#include "../libio/strfile.h" -#include -#include -#include -#include +#include #include -#include - - -struct _IO_obstack_file -{ - struct _IO_FILE_plus file; - struct obstack *obstack; -}; - -extern const struct _IO_jump_t _IO_obstack_jumps libio_vtable attribute_hidden; - -int -__obstack_vprintf_chk (struct obstack *obstack, int flags, const char *format, - va_list args) -{ - struct obstack_FILE - { - struct _IO_obstack_file ofile; - } new_f; - int result; - int size; - int room; - -#ifdef _IO_MTSAFE_IO - new_f.ofile.file.file._lock = NULL; -#endif - - _IO_no_init (&new_f.ofile.file.file, _IO_USER_LOCK, -1, NULL, NULL); - _IO_JUMPS (&new_f.ofile.file) = &_IO_obstack_jumps; - room = obstack_room (obstack); - size = obstack_object_size (obstack) + room; - if (size == 0) - { - /* We have to handle the allocation a bit different since the - `_IO_str_init_static' function would handle a size of zero - different from what we expect. */ - - /* Get more memory. */ - obstack_make_room (obstack, 64); - - /* Recompute how much room we have. */ - room = obstack_room (obstack); - size = room; - - assert (size != 0); - } - - _IO_str_init_static_internal ((struct _IO_strfile_ *) &new_f.ofile, - obstack_base (obstack), - size, obstack_next_free (obstack)); - /* Now allocate the rest of the current chunk. */ - assert (size == (new_f.ofile.file.file._IO_write_end - - new_f.ofile.file.file._IO_write_base)); - assert (new_f.ofile.file.file._IO_write_ptr - == (new_f.ofile.file.file._IO_write_base - + obstack_object_size (obstack))); - obstack_blank_fast (obstack, room); - - new_f.ofile.obstack = obstack; - - /* For flags > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n - can only come from read-only format strings. */ - if (flags > 0) - new_f.ofile.file.file._flags2 |= _IO_FLAGS2_FORTIFY; - - result = __vfprintf_internal (&new_f.ofile.file.file, format, args, 0); - - /* Shrink the buffer to the space we really currently need. */ - obstack_blank_fast (obstack, (new_f.ofile.file.file._IO_write_ptr - - new_f.ofile.file.file._IO_write_end)); - - return result; -} -libc_hidden_def (__obstack_vprintf_chk) int -__obstack_printf_chk (struct obstack *obstack, int flags, const char *format, +__obstack_printf_chk (struct obstack *obstack, int flag, const char *format, ...) { - int result; + /* For flag > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n + can only come from read-only format strings. */ + unsigned int mode = (flag > 0) ? PRINTF_FORTIFY : 0; va_list ap; + int ret; + va_start (ap, format); - result = __obstack_vprintf_chk (obstack, flags, format, ap); + ret = __obstack_vprintf_internal (obstack, format, ap, mode); va_end (ap); - return result; + + return ret; } diff --git a/debug/printf_chk.c b/debug/printf_chk.c index 426dc78386..e035b42590 100644 --- a/debug/printf_chk.c +++ b/debug/printf_chk.c @@ -16,29 +16,23 @@ . */ #include -#include -#include "../libio/libioP.h" +#include /* Write formatted output to stdout from the format string FORMAT. */ int ___printf_chk (int flag, const char *format, ...) { + /* For flag > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n + can only come from read-only format strings. */ + unsigned int mode = (flag > 0) ? PRINTF_FORTIFY : 0; va_list ap; - int done; - - _IO_acquire_lock_clear_flags2 (stdout); - if (flag > 0) - stdout->_flags2 |= _IO_FLAGS2_FORTIFY; + int ret; va_start (ap, format); - done = vfprintf (stdout, format, ap); + ret = __vfprintf_internal (stdout, format, ap, mode); va_end (ap); - if (flag > 0) - stdout->_flags2 &= ~_IO_FLAGS2_FORTIFY; - _IO_release_lock (stdout); - - return done; + return ret; } ldbl_strong_alias (___printf_chk, __printf_chk) diff --git a/debug/snprintf_chk.c b/debug/snprintf_chk.c index cddba37109..984b5e8932 100644 --- a/debug/snprintf_chk.c +++ b/debug/snprintf_chk.c @@ -15,25 +15,29 @@ License along with the GNU C Library; if not, see . */ -#include #include -#include +#include /* Write formatted output into S, according to the format string FORMAT, writing no more than MAXLEN characters. */ -/* VARARGS5 */ int -___snprintf_chk (char *s, size_t maxlen, int flags, size_t slen, +___snprintf_chk (char *s, size_t maxlen, int flag, size_t slen, const char *format, ...) { - va_list arg; - int done; + if (__glibc_unlikely (slen < maxlen)) + __chk_fail (); - va_start (arg, format); - done = __vsnprintf_chk (s, maxlen, flags, slen, format, arg); - va_end (arg); + /* For flag > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n + can only come from read-only format strings. */ + unsigned int mode = (flag > 0) ? PRINTF_FORTIFY : 0; + va_list ap; + int ret; - return done; + va_start (ap, format); + ret = __vsnprintf_internal (s, maxlen, format, ap, mode); + va_end (ap); + + return ret; } ldbl_strong_alias (___snprintf_chk, __snprintf_chk) diff --git a/debug/sprintf_chk.c b/debug/sprintf_chk.c index 78214563dd..649e8ab4d5 100644 --- a/debug/sprintf_chk.c +++ b/debug/sprintf_chk.c @@ -15,22 +15,27 @@ License along with the GNU C Library; if not, see . */ -#include #include -#include +#include + /* Write formatted output into S, according to the format string FORMAT. */ -/* VARARGS4 */ int -___sprintf_chk (char *s, int flags, size_t slen, const char *format, ...) +___sprintf_chk (char *s, int flag, size_t slen, const char *format, ...) { - va_list arg; - int done; + /* For flag > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n + can only come from read-only format strings. */ + unsigned int mode = (flag > 0) ? PRINTF_FORTIFY : 0; + va_list ap; + int ret; + + if (slen == 0) + __chk_fail (); - va_start (arg, format); - done = __vsprintf_chk (s, flags, slen, format, arg); - va_end (arg); + va_start (ap, format); + ret = __vsprintf_internal (s, slen, format, ap, mode); + va_end (ap); - return done; + return ret; } ldbl_strong_alias (___sprintf_chk, __sprintf_chk) diff --git a/debug/swprintf_chk.c b/debug/swprintf_chk.c index 35887e48e2..186c17751c 100644 --- a/debug/swprintf_chk.c +++ b/debug/swprintf_chk.c @@ -16,20 +16,27 @@ . */ #include -#include +#include -/* Write formatted output into S, according to the format string FORMAT. */ -/* VARARGS5 */ + +/* Write formatted output into S, according to the format string FORMAT, + writing no more than MAXLEN characters. */ int -__swprintf_chk (wchar_t *s, size_t n, int flag, size_t s_len, +__swprintf_chk (wchar_t *s, size_t maxlen, int flag, size_t slen, const wchar_t *format, ...) { - va_list arg; - int done; + if (__glibc_unlikely (slen < maxlen)) + __chk_fail (); + + /* For flag > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n + can only come from read-only format strings. */ + unsigned int mode = (flag > 0) ? PRINTF_FORTIFY : 0; + va_list ap; + int ret; - va_start (arg, format); - done = __vswprintf_chk (s, n, flag, s_len, format, arg); - va_end (arg); + va_start (ap, format); + ret = __vswprintf_internal (s, maxlen, format, ap, mode); + va_end (ap); - return done; + return ret; } diff --git a/debug/vasprintf_chk.c b/debug/vasprintf_chk.c index dbfebff83f..f5975ea02a 100644 --- a/debug/vasprintf_chk.c +++ b/debug/vasprintf_chk.c @@ -24,72 +24,14 @@ This exception applies to code released by its copyright holders in files containing the exception. */ -#include -#include -#include -#include -#include "../libio/libioP.h" -#include "../libio/strfile.h" +#include int -__vasprintf_chk (char **result_ptr, int flags, const char *format, - va_list args) +__vasprintf_chk (char **result_ptr, int flag, const char *format, va_list ap) { - /* Initial size of the buffer to be used. Will be doubled each time an - overflow occurs. */ - const size_t init_string_size = 100; - char *string; - _IO_strfile sf; - int ret; - size_t needed; - size_t allocated; - /* No need to clear the memory here (unlike for open_memstream) since - we know we will never seek on the stream. */ - string = (char *) malloc (init_string_size); - if (string == NULL) - return -1; -#ifdef _IO_MTSAFE_IO - sf._sbf._f._lock = NULL; -#endif - _IO_no_init (&sf._sbf._f, _IO_USER_LOCK, -1, NULL, NULL); - _IO_JUMPS (&sf._sbf) = &_IO_str_jumps; - _IO_str_init_static_internal (&sf, string, init_string_size, string); - sf._sbf._f._flags &= ~_IO_USER_BUF; - sf._s._allocate_buffer_unused = (_IO_alloc_type) malloc; - sf._s._free_buffer_unused = (_IO_free_type) free; - - /* For flags > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n + /* For flag > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n can only come from read-only format strings. */ - if (flags > 0) - sf._sbf._f._flags2 |= _IO_FLAGS2_FORTIFY; + unsigned int mode = (flag > 0) ? PRINTF_FORTIFY : 0; - ret = __vfprintf_internal (&sf._sbf._f, format, args, 0); - if (ret < 0) - { - free (sf._sbf._f._IO_buf_base); - return ret; - } - /* Only use realloc if the size we need is of the same (binary) - order of magnitude then the memory we allocated. */ - needed = sf._sbf._f._IO_write_ptr - sf._sbf._f._IO_write_base + 1; - allocated = sf._sbf._f._IO_write_end - sf._sbf._f._IO_write_base; - if ((allocated >> 1) <= needed) - *result_ptr = (char *) realloc (sf._sbf._f._IO_buf_base, needed); - else - { - *result_ptr = (char *) malloc (needed); - if (*result_ptr != NULL) - { - memcpy (*result_ptr, sf._sbf._f._IO_buf_base, needed - 1); - free (sf._sbf._f._IO_buf_base); - } - else - /* We have no choice, use the buffer we already have. */ - *result_ptr = (char *) realloc (sf._sbf._f._IO_buf_base, needed); - } - if (*result_ptr == NULL) - *result_ptr = sf._sbf._f._IO_buf_base; - (*result_ptr)[needed - 1] = '\0'; - return ret; + return __vasprintf_internal (result_ptr, format, ap, mode); } -libc_hidden_def (__vasprintf_chk) diff --git a/debug/vdprintf_chk.c b/debug/vdprintf_chk.c index 4386127cfe..e04514e355 100644 --- a/debug/vdprintf_chk.c +++ b/debug/vdprintf_chk.c @@ -24,41 +24,14 @@ This exception applies to code released by its copyright holders in files containing the exception. */ -#include -#include +#include int -__vdprintf_chk (int d, int flags, const char *format, va_list arg) +__vdprintf_chk (int d, int flag, const char *format, va_list ap) { - struct _IO_FILE_plus tmpfil; - struct _IO_wide_data wd; - int done; - -#ifdef _IO_MTSAFE_IO - tmpfil.file._lock = NULL; -#endif - _IO_no_init (&tmpfil.file, _IO_USER_LOCK, 0, &wd, &_IO_wfile_jumps); - _IO_JUMPS (&tmpfil) = &_IO_file_jumps; - _IO_new_file_init_internal (&tmpfil); - if (_IO_file_attach (&tmpfil.file, d) == NULL) - { - _IO_un_link (&tmpfil); - return EOF; - } - tmpfil.file._flags |= _IO_DELETE_DONT_CLOSE; - - _IO_mask_flags (&tmpfil.file, _IO_NO_READS, - _IO_NO_READS+_IO_NO_WRITES+_IO_IS_APPENDING); - - /* For flags > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n + /* For flag > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n can only come from read-only format strings. */ - if (flags > 0) - tmpfil.file._flags2 |= _IO_FLAGS2_FORTIFY; - - done = __vfprintf_internal (&tmpfil.file, format, arg, 0); - - _IO_FINISH (&tmpfil.file); + unsigned int mode = (flag > 0) ? PRINTF_FORTIFY : 0; - return done; + return __vdprintf_internal (d, format, ap, mode); } -libc_hidden_def (__vdprintf_chk) diff --git a/debug/vfprintf_chk.c b/debug/vfprintf_chk.c index 5babbf611e..44426e14fd 100644 --- a/debug/vfprintf_chk.c +++ b/debug/vfprintf_chk.c @@ -15,28 +15,17 @@ License along with the GNU C Library; if not, see . */ -#include -#include -#include "../libio/libioP.h" +#include /* Write formatted output to FP from the format string FORMAT. */ int ___vfprintf_chk (FILE *fp, int flag, const char *format, va_list ap) { - int done; + /* For flag > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n + can only come from read-only format strings. */ + unsigned int mode = (flag > 0) ? PRINTF_FORTIFY : 0; - _IO_acquire_lock_clear_flags2 (fp); - if (flag > 0) - fp->_flags2 |= _IO_FLAGS2_FORTIFY; - - done = vfprintf (fp, format, ap); - - if (flag > 0) - fp->_flags2 &= ~_IO_FLAGS2_FORTIFY; - _IO_release_lock (fp); - - return done; + return __vfprintf_internal (fp, format, ap, mode); } -ldbl_hidden_def (___vfprintf_chk, __vfprintf_chk) ldbl_strong_alias (___vfprintf_chk, __vfprintf_chk) diff --git a/debug/vfwprintf_chk.c b/debug/vfwprintf_chk.c index abf2bd6517..3aed308156 100644 --- a/debug/vfwprintf_chk.c +++ b/debug/vfwprintf_chk.c @@ -15,27 +15,16 @@ License along with the GNU C Library; if not, see . */ -#include -#include -#include "../libio/libioP.h" +#include /* Write formatted output to FP from the format string FORMAT. */ int __vfwprintf_chk (FILE *fp, int flag, const wchar_t *format, va_list ap) { - int done; + /* For flag > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n + can only come from read-only format strings. */ + unsigned int mode = (flag > 0) ? PRINTF_FORTIFY : 0; - _IO_acquire_lock_clear_flags2 (fp); - if (flag > 0) - fp->_flags2 |= _IO_FLAGS2_FORTIFY; - - done = __vfwprintf_internal (fp, format, ap, 0); - - if (flag > 0) - fp->_flags2 &= ~_IO_FLAGS2_FORTIFY; - _IO_release_lock (fp); - - return done; + return __vfwprintf_internal (fp, format, ap, mode); } -libc_hidden_def (__vfwprintf_chk) diff --git a/debug/vobprintf_chk.c b/debug/vobprintf_chk.c new file mode 100644 index 0000000000..edfbe8f00a --- /dev/null +++ b/debug/vobprintf_chk.c @@ -0,0 +1,32 @@ +/* Print output of stream to given obstack. + Copyright (C) 1996-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1996. + + 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 + . */ + +#include + + +int +__obstack_vprintf_chk (struct obstack *obstack, int flag, const char *format, + va_list ap) +{ + /* For flag > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n + can only come from read-only format strings. */ + unsigned int mode = (flag > 0) ? PRINTF_FORTIFY : 0; + + return __obstack_vprintf_internal (obstack, format, ap, mode); +} diff --git a/debug/vprintf_chk.c b/debug/vprintf_chk.c index b3b2c53df2..69fcb721ac 100644 --- a/debug/vprintf_chk.c +++ b/debug/vprintf_chk.c @@ -15,27 +15,17 @@ License along with the GNU C Library; if not, see . */ -#include -#include -#include "../libio/libioP.h" +#include /* Write formatted output to stdout from the format string FORMAT. */ int ___vprintf_chk (int flag, const char *format, va_list ap) { - int done; + /* For flag > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n + can only come from read-only format strings. */ + unsigned int mode = (flag > 0) ? PRINTF_FORTIFY : 0; - _IO_acquire_lock_clear_flags2 (stdout); - if (flag > 0) - stdout->_flags2 |= _IO_FLAGS2_FORTIFY; - - done = vfprintf (stdout, format, ap); - - if (flag > 0) - stdout->_flags2 &= ~_IO_FLAGS2_FORTIFY; - _IO_release_lock (stdout); - - return done; + return __vfprintf_internal (stdout, format, ap, mode); } ldbl_strong_alias (___vprintf_chk, __vprintf_chk) diff --git a/debug/vsnprintf_chk.c b/debug/vsnprintf_chk.c index 95d286f416..666a83b701 100644 --- a/debug/vsnprintf_chk.c +++ b/debug/vsnprintf_chk.c @@ -15,56 +15,22 @@ License along with the GNU C Library; if not, see . */ -#include -#include -#include "../libio/libioP.h" -#include "../libio/strfile.h" +#include -extern const struct _IO_jump_t _IO_strn_jumps libio_vtable attribute_hidden; /* Write formatted output into S, according to the format string FORMAT, writing no more than MAXLEN characters. */ -/* VARARGS5 */ int -___vsnprintf_chk (char *s, size_t maxlen, int flags, size_t slen, - const char *format, va_list args) +___vsnprintf_chk (char *s, size_t maxlen, int flag, size_t slen, + const char *format, va_list ap) { - /* XXX Maybe for less strict version do not fail immediately. - Though, maxlen is supposed to be the size of buffer pointed - to by s, so a conforming program can't pass such maxlen - to *snprintf. */ if (__glibc_unlikely (slen < maxlen)) __chk_fail (); - _IO_strnfile sf; - int ret; -#ifdef _IO_MTSAFE_IO - sf.f._sbf._f._lock = NULL; -#endif - - /* We need to handle the special case where MAXLEN is 0. Use the - overflow buffer right from the start. */ - if (maxlen == 0) - { - s = sf.overflow_buf; - maxlen = sizeof (sf.overflow_buf); - } - - _IO_no_init (&sf.f._sbf._f, _IO_USER_LOCK, -1, NULL, NULL); - _IO_JUMPS (&sf.f._sbf) = &_IO_strn_jumps; - s[0] = '\0'; - - /* For flags > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n + /* For flag > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n can only come from read-only format strings. */ - if (flags > 0) - sf.f._sbf._f._flags2 |= _IO_FLAGS2_FORTIFY; - - _IO_str_init_static_internal (&sf.f, s, maxlen - 1, s); - ret = __vfprintf_internal (&sf.f._sbf._f, format, args, 0); + unsigned int mode = (flag > 0) ? PRINTF_FORTIFY : 0; - if (sf.f._sbf._f._IO_buf_base != sf.overflow_buf) - *sf.f._sbf._f._IO_write_ptr = '\0'; - return ret; + return __vsnprintf_internal (s, maxlen, format, ap, mode); } -ldbl_hidden_def (___vsnprintf_chk, __vsnprintf_chk) ldbl_strong_alias (___vsnprintf_chk, __vsnprintf_chk) diff --git a/debug/vsprintf_chk.c b/debug/vsprintf_chk.c index 53f07236ae..c1b1a8da4f 100644 --- a/debug/vsprintf_chk.c +++ b/debug/vsprintf_chk.c @@ -15,75 +15,20 @@ License along with the GNU C Library; if not, see . */ -#include -#include -#include "../libio/libioP.h" -#include "../libio/strfile.h" - - -static int _IO_str_chk_overflow (FILE *fp, int c) __THROW; - -static int -_IO_str_chk_overflow (FILE *fp, int c) -{ - /* When we come to here this means the user supplied buffer is - filled. */ - __chk_fail (); -} - - -static const struct _IO_jump_t _IO_str_chk_jumps libio_vtable = -{ - JUMP_INIT_DUMMY, - JUMP_INIT(finish, _IO_str_finish), - JUMP_INIT(overflow, _IO_str_chk_overflow), - JUMP_INIT(underflow, _IO_str_underflow), - JUMP_INIT(uflow, _IO_default_uflow), - JUMP_INIT(pbackfail, _IO_str_pbackfail), - JUMP_INIT(xsputn, _IO_default_xsputn), - JUMP_INIT(xsgetn, _IO_default_xsgetn), - JUMP_INIT(seekoff, _IO_str_seekoff), - JUMP_INIT(seekpos, _IO_default_seekpos), - JUMP_INIT(setbuf, _IO_default_setbuf), - JUMP_INIT(sync, _IO_default_sync), - JUMP_INIT(doallocate, _IO_default_doallocate), - JUMP_INIT(read, _IO_default_read), - JUMP_INIT(write, _IO_default_write), - JUMP_INIT(seek, _IO_default_seek), - JUMP_INIT(close, _IO_default_close), - JUMP_INIT(stat, _IO_default_stat), - JUMP_INIT(showmanyc, _IO_default_showmanyc), - JUMP_INIT(imbue, _IO_default_imbue) -}; - +#include int -___vsprintf_chk (char *s, int flags, size_t slen, const char *format, - va_list args) +___vsprintf_chk (char *s, int flag, size_t slen, const char *format, + va_list ap) { - _IO_strfile f; - int ret; -#ifdef _IO_MTSAFE_IO - f._sbf._f._lock = NULL; -#endif + /* For flag > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n + can only come from read-only format strings. */ + unsigned int mode = (flag > 0) ? PRINTF_FORTIFY : 0; if (slen == 0) __chk_fail (); - _IO_no_init (&f._sbf._f, _IO_USER_LOCK, -1, NULL, NULL); - _IO_JUMPS (&f._sbf) = &_IO_str_chk_jumps; - s[0] = '\0'; - _IO_str_init_static_internal (&f, s, slen - 1, s); - - /* For flags > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n - can only come from read-only format strings. */ - if (flags > 0) - f._sbf._f._flags2 |= _IO_FLAGS2_FORTIFY; - - ret = __vfprintf_internal (&f._sbf._f, format, args, 0); - - *f._sbf._f._IO_write_ptr = '\0'; - return ret; + return __vsprintf_internal (s, slen, format, ap, mode); } ldbl_hidden_def (___vsprintf_chk, __vsprintf_chk) ldbl_strong_alias (___vsprintf_chk, __vsprintf_chk) diff --git a/debug/vswprintf_chk.c b/debug/vswprintf_chk.c index 4d616f8835..2c6fadd463 100644 --- a/debug/vswprintf_chk.c +++ b/debug/vswprintf_chk.c @@ -15,60 +15,21 @@ License along with the GNU C Library; if not, see . */ -#include -#include -#include "../libio/libioP.h" -#include "../libio/strfile.h" +#include /* Write formatted output into S, according to the format string FORMAT, writing no more than MAXLEN characters. */ -/* VARARGS5 */ int -__vswprintf_chk (wchar_t *s, size_t maxlen, int flags, size_t slen, - const wchar_t *format, va_list args) +__vswprintf_chk (wchar_t *s, size_t maxlen, int flag, size_t slen, + const wchar_t *format, va_list ap) { - /* XXX Maybe for less strict version do not fail immediately. - Though, maxlen is supposed to be the size of buffer pointed - to by s, so a conforming program can't pass such maxlen - to *snprintf. */ if (__glibc_unlikely (slen < maxlen)) __chk_fail (); - _IO_wstrnfile sf; - struct _IO_wide_data wd; - int ret; -#ifdef _IO_MTSAFE_IO - sf.f._sbf._f._lock = NULL; -#endif - - /* We need to handle the special case where MAXLEN is 0. Use the - overflow buffer right from the start. */ - if (__glibc_unlikely (maxlen == 0)) - /* Since we have to write at least the terminating L'\0' a buffer - length of zero always makes the function fail. */ - return -1; - - _IO_no_init (&sf.f._sbf._f, _IO_USER_LOCK, 0, &wd, &_IO_wstrn_jumps); - _IO_fwide (&sf.f._sbf._f, 1); - s[0] = L'\0'; - - /* For flags > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n + /* For flag > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n can only come from read-only format strings. */ - if (flags > 0) - sf.f._sbf._f._flags2 |= _IO_FLAGS2_FORTIFY; - - _IO_wstr_init_static (&sf.f._sbf._f, s, maxlen - 1, s); - ret = __vfwprintf_internal ((FILE *) &sf.f._sbf, format, args, 0); - - if (sf.f._sbf._f._wide_data->_IO_buf_base == sf.overflow_buf) - /* ISO C99 requires swprintf/vswprintf to return an error if the - output does not fit int he provided buffer. */ - return -1; - - /* Terminate the string. */ - *sf.f._sbf._f._wide_data->_IO_write_ptr = '\0'; + unsigned int mode = (flag > 0) ? PRINTF_FORTIFY : 0; - return ret; + return __vswprintf_internal (s, maxlen, format, ap, mode); } -libc_hidden_def (__vswprintf_chk) diff --git a/debug/vwprintf_chk.c b/debug/vwprintf_chk.c index fedc7a46bf..f1e8878a54 100644 --- a/debug/vwprintf_chk.c +++ b/debug/vwprintf_chk.c @@ -15,27 +15,16 @@ License along with the GNU C Library; if not, see . */ -#include -#include -#include -#include "../libio/libioP.h" +#include /* Write formatted output to stdout from the format string FORMAT. */ int __vwprintf_chk (int flag, const wchar_t *format, va_list ap) { - int done; + /* For flag > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n + can only come from read-only format strings. */ + unsigned int mode = (flag > 0) ? PRINTF_FORTIFY : 0; - _IO_acquire_lock_clear_flags2 (stdout); - if (flag > 0) - stdout->_flags2 |= _IO_FLAGS2_FORTIFY; - - done = __vfwprintf_internal (stdout, format, ap, 0); - - if (flag > 0) - stdout->_flags2 &= ~_IO_FLAGS2_FORTIFY; - _IO_release_lock (stdout); - - return done; + return __vfwprintf_internal (stdout, format, ap, mode); } diff --git a/debug/wprintf_chk.c b/debug/wprintf_chk.c index 819050e5af..9f406e95f8 100644 --- a/debug/wprintf_chk.c +++ b/debug/wprintf_chk.c @@ -16,29 +16,22 @@ . */ #include -#include -#include -#include "../libio/libioP.h" +#include /* Write formatted output to stdout from the format string FORMAT. */ int __wprintf_chk (int flag, const wchar_t *format, ...) { + /* For flag > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n + can only come from read-only format strings. */ + unsigned int mode = (flag > 0) ? PRINTF_FORTIFY : 0; va_list ap; - int done; - - _IO_acquire_lock_clear_flags2 (stdout); - if (flag > 0) - stdout->_flags2 |= _IO_FLAGS2_FORTIFY; + int ret; va_start (ap, format); - done = __vfwprintf_internal (stdout, format, ap, 0); + ret = __vfwprintf_internal (stdout, format, ap, mode); va_end (ap); - if (flag > 0) - stdout->_flags2 &= ~_IO_FLAGS2_FORTIFY; - _IO_release_lock (stdout); - - return done; + return ret; } diff --git a/include/stdio.h b/include/stdio.h index 0856d729d9..1b7da0f74d 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -216,11 +216,6 @@ libc_hidden_proto (__open_memstream) libc_hidden_proto (__libc_fatal) rtld_hidden_proto (__libc_fatal) libc_hidden_proto (__vsprintf_chk) -libc_hidden_proto (__vsnprintf_chk) -libc_hidden_proto (__vfprintf_chk) -libc_hidden_proto (__vasprintf_chk) -libc_hidden_proto (__vdprintf_chk) -libc_hidden_proto (__obstack_vprintf_chk) extern FILE * __fmemopen (void *buf, size_t len, const char *mode); libc_hidden_proto (__fmemopen) diff --git a/include/wchar.h b/include/wchar.h index d0fe45c3a6..86506d28e9 100644 --- a/include/wchar.h +++ b/include/wchar.h @@ -216,8 +216,6 @@ extern int __vswprintf_chk (wchar_t *__restrict __s, size_t __n, const wchar_t *__restrict __format, __gnuc_va_list __arg) /* __attribute__ ((__format__ (__wprintf__, 5, 0))) */; -libc_hidden_proto (__vfwprintf_chk) -libc_hidden_proto (__vswprintf_chk) extern int __isoc99_fwscanf (__FILE *__restrict __stream, const wchar_t *__restrict __format, ...); diff --git a/libio/iovsprintf.c b/libio/iovsprintf.c index 3b1e8292b5..08e4002625 100644 --- a/libio/iovsprintf.c +++ b/libio/iovsprintf.c @@ -27,8 +27,47 @@ #include "libioP.h" #include "strfile.h" +static int __THROW +_IO_str_chk_overflow (FILE *fp, int c) +{ + /* If we get here, the user-supplied buffer would be overrun by + further output. */ + __chk_fail (); +} + +static const struct _IO_jump_t _IO_str_chk_jumps libio_vtable = +{ + JUMP_INIT_DUMMY, + JUMP_INIT(finish, _IO_str_finish), + JUMP_INIT(overflow, _IO_str_chk_overflow), + JUMP_INIT(underflow, _IO_str_underflow), + JUMP_INIT(uflow, _IO_default_uflow), + JUMP_INIT(pbackfail, _IO_str_pbackfail), + JUMP_INIT(xsputn, _IO_default_xsputn), + JUMP_INIT(xsgetn, _IO_default_xsgetn), + JUMP_INIT(seekoff, _IO_str_seekoff), + JUMP_INIT(seekpos, _IO_default_seekpos), + JUMP_INIT(setbuf, _IO_default_setbuf), + JUMP_INIT(sync, _IO_default_sync), + JUMP_INIT(doallocate, _IO_default_doallocate), + JUMP_INIT(read, _IO_default_read), + JUMP_INIT(write, _IO_default_write), + JUMP_INIT(seek, _IO_default_seek), + JUMP_INIT(close, _IO_default_close), + JUMP_INIT(stat, _IO_default_stat), + JUMP_INIT(showmanyc, _IO_default_showmanyc), + JUMP_INIT(imbue, _IO_default_imbue) +}; + +/* This function is called by regular vsprintf with maxlen set to -1, + and by vsprintf_chk with maxlen set to the size of the output + string. In the former case, _IO_str_chk_overflow will never be + called; in the latter case it will crash the program if the buffer + overflows. */ + int -__vsprintf_internal (char *string, const char *format, va_list args, +__vsprintf_internal (char *string, size_t maxlen, + const char *format, va_list args, unsigned int mode_flags) { _IO_strfile sf; @@ -38,17 +77,22 @@ __vsprintf_internal (char *string, const char *format, va_list args, sf._sbf._f._lock = NULL; #endif _IO_no_init (&sf._sbf._f, _IO_USER_LOCK, -1, NULL, NULL); - _IO_JUMPS (&sf._sbf) = &_IO_str_jumps; - _IO_str_init_static_internal (&sf, string, -1, string); + _IO_JUMPS (&sf._sbf) = &_IO_str_chk_jumps; + string[0] = '\0'; + _IO_str_init_static_internal (&sf, string, + (maxlen == -1) ? -1 : maxlen - 1, + string); + ret = __vfprintf_internal (&sf._sbf._f, format, args, mode_flags); - _IO_putc_unlocked ('\0', &sf._sbf._f); + + *sf._sbf._f._IO_write_ptr = '\0'; return ret; } int __vsprintf (char *string, const char *format, va_list args) { - return __vsprintf_internal (string, format, args, 0); + return __vsprintf_internal (string, -1, format, args, 0); } ldbl_strong_alias (__vsprintf, _IO_vsprintf) diff --git a/libio/libio.h b/libio/libio.h index c188814ccc..3a93807efc 100644 --- a/libio/libio.h +++ b/libio/libio.h @@ -90,7 +90,6 @@ typedef union /* Bits for the _flags2 field. */ #define _IO_FLAGS2_MMAP 1 #define _IO_FLAGS2_NOTCANCEL 2 -#define _IO_FLAGS2_FORTIFY 4 #define _IO_FLAGS2_USER_WBUF 8 #define _IO_FLAGS2_NOCLOSE 32 #define _IO_FLAGS2_CLOEXEC 64 diff --git a/libio/libioP.h b/libio/libioP.h index c762cf9b67..17270b126f 100644 --- a/libio/libioP.h +++ b/libio/libioP.h @@ -677,9 +677,16 @@ extern int __obstack_vprintf_internal (struct obstack *ob, const char *fmt, va_list ap, unsigned int mode_flags) attribute_hidden; -extern int __vsprintf_internal (char *string, const char *format, va_list ap, +/* Note: __vsprintf_internal, unlike vsprintf, does take a maxlen argument, + because it's called by both vsprintf and vsprintf_chk. If maxlen is + not set to -1, overrunning the buffer will cause a prompt crash. + This is the behavior of ordinary (v)sprintf functions, thus they call + __vsprintf_internal with that argument set to -1. */ +extern int __vsprintf_internal (char *string, size_t maxlen, + const char *format, va_list ap, unsigned int mode_flags) attribute_hidden; + extern int __vsnprintf_internal (char *string, size_t maxlen, const char *format, va_list ap, unsigned int mode_flags) @@ -798,26 +805,10 @@ _IO_acquire_lock_fct (FILE **p) _IO_funlockfile (fp); } -static inline void -__attribute__ ((__always_inline__)) -_IO_acquire_lock_clear_flags2_fct (FILE **p) -{ - FILE *fp = *p; - fp->_flags2 &= ~(_IO_FLAGS2_FORTIFY); - if ((fp->_flags & _IO_USER_LOCK) == 0) - _IO_funlockfile (fp); -} - #if !defined _IO_MTSAFE_IO && IS_IN (libc) # define _IO_acquire_lock(_fp) \ - do { \ - FILE *_IO_acquire_lock_file = NULL -# define _IO_acquire_lock_clear_flags2(_fp) \ - do { \ - FILE *_IO_acquire_lock_file = (_fp) + do { # define _IO_release_lock(_fp) \ - if (_IO_acquire_lock_file != NULL) \ - _IO_acquire_lock_file->_flags2 &= ~(_IO_FLAGS2_FORTIFY); \ } while (0) #endif diff --git a/stdio-common/sprintf.c b/stdio-common/sprintf.c index 77423b292f..447faa4e25 100644 --- a/stdio-common/sprintf.c +++ b/stdio-common/sprintf.c @@ -27,7 +27,7 @@ __sprintf (char *s, const char *format, ...) int done; va_start (arg, format); - done = __vsprintf_internal (s, format, arg, 0); + done = __vsprintf_internal (s, -1, format, arg, 0); va_end (arg); return done; diff --git a/stdio-common/vfprintf-internal.c b/stdio-common/vfprintf-internal.c index 7752ad5b68..b5ae868371 100644 --- a/stdio-common/vfprintf-internal.c +++ b/stdio-common/vfprintf-internal.c @@ -1285,8 +1285,6 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap, unsigned int mode_flags) /* Temporarily honor environmental settings. */ if (__ldbl_is_dbl) mode_flags |= PRINTF_LDBL_IS_DBL; - if (s->_flags2 & _IO_FLAGS2_FORTIFY) - mode_flags |= PRINTF_FORTIFY; /* Orient the stream. */ #ifdef ORIENT diff --git a/sysdeps/generic/stdio-lock.h b/sysdeps/generic/stdio-lock.h index 4a40618545..25ccd07f29 100644 --- a/sysdeps/generic/stdio-lock.h +++ b/sysdeps/generic/stdio-lock.h @@ -54,15 +54,8 @@ __libc_lock_define_recursive (typedef, _IO_lock_t) __attribute__((cleanup (_IO_acquire_lock_fct))) \ = (_fp); \ _IO_flockfile (_IO_acquire_lock_file); -# define _IO_acquire_lock_clear_flags2(_fp) \ - do { \ - FILE *_IO_acquire_lock_file \ - __attribute__((cleanup (_IO_acquire_lock_clear_flags2_fct))) \ - = (_fp); \ - _IO_flockfile (_IO_acquire_lock_file); # else # define _IO_acquire_lock(_fp) _IO_acquire_lock_needs_exceptions_enabled -# define _IO_acquire_lock_clear_flags2(_fp) _IO_acquire_lock (_fp) # endif # define _IO_release_lock(_fp) ; } while (0) diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-compat.c b/sysdeps/ieee754/ldbl-opt/nldbl-compat.c index 958bbc1834..59b2c9fcdd 100644 --- a/sysdeps/ieee754/ldbl-opt/nldbl-compat.c +++ b/sysdeps/ieee754/ldbl-opt/nldbl-compat.c @@ -179,7 +179,7 @@ __nldbl___vsprintf (char *string, const char *fmt, va_list ap) { int done; __no_long_double = 1; - done = __vsprintf_internal (string, fmt, ap, 0); + done = __vsprintf_internal (string, -1, fmt, ap, 0); __no_long_double = 0; return done; } @@ -579,7 +579,7 @@ __nldbl___vfprintf_chk (FILE *s, int flag, const char *fmt, va_list ap) { int res; set_no_long_double (); - res = __vfprintf_chk (s, flag, fmt, ap); + res = __vfprintf_internal (s, fmt, ap, (flag > 0) ? PRINTF_FORTIFY : 0); clear_no_long_double (); return res; } @@ -591,7 +591,7 @@ __nldbl___vfwprintf_chk (FILE *s, int flag, const wchar_t *fmt, va_list ap) { int res; set_no_long_double (); - res = __vfwprintf_chk (s, flag, fmt, ap); + res = __vfwprintf_internal (s, fmt, ap, (flag > 0) ? PRINTF_FORTIFY : 0); clear_no_long_double (); return res; } @@ -609,9 +609,13 @@ attribute_compat_text_section __nldbl___vsnprintf_chk (char *string, size_t maxlen, int flag, size_t slen, const char *fmt, va_list ap) { + if (__glibc_unlikely (slen < maxlen)) + __chk_fail (); + int res; __no_long_double = 1; - res = __vsnprintf_chk (string, maxlen, flag, slen, fmt, ap); + res = __vsnprintf_internal (string, maxlen, fmt, ap, + (flag > 0) ? PRINTF_FORTIFY : 0); __no_long_double = 0; return res; } @@ -622,9 +626,13 @@ attribute_compat_text_section __nldbl___vsprintf_chk (char *string, int flag, size_t slen, const char *fmt, va_list ap) { + if (slen == 0) + __chk_fail (); + int res; __no_long_double = 1; - res = __vsprintf_chk (string, flag, slen, fmt, ap); + res = __vsprintf_internal (string, slen, fmt, ap, + (flag > 0) ? PRINTF_FORTIFY : 0); __no_long_double = 0; return res; } @@ -635,9 +643,13 @@ attribute_compat_text_section __nldbl___vswprintf_chk (wchar_t *string, size_t maxlen, int flag, size_t slen, const wchar_t *fmt, va_list ap) { + if (__glibc_unlikely (slen < maxlen)) + __chk_fail (); + int res; __no_long_double = 1; - res = __vswprintf_chk (string, maxlen, flag, slen, fmt, ap); + res = __vswprintf_internal (string, maxlen, fmt, ap, + (flag > 0) ? PRINTF_FORTIFY : 0); __no_long_double = 0; return res; } @@ -670,7 +682,8 @@ __nldbl___vasprintf_chk (char **ptr, int flag, const char *fmt, va_list arg) { int res; __no_long_double = 1; - res = __vasprintf_chk (ptr, flag, fmt, arg); + res = __vasprintf_internal (ptr, fmt, arg, + (flag > 0) ? PRINTF_FORTIFY : 0); __no_long_double = 0; return res; } @@ -696,7 +709,7 @@ __nldbl___vdprintf_chk (int d, int flag, const char *fmt, va_list arg) { int res; set_no_long_double (); - res = __vdprintf_chk (d, flag, fmt, arg); + res = __vdprintf_internal (d, fmt, arg, (flag > 0) ? PRINTF_FORTIFY : 0); clear_no_long_double (); return res; } @@ -723,7 +736,8 @@ __nldbl___obstack_vprintf_chk (struct obstack *obstack, int flag, { int res; __no_long_double = 1; - res = __obstack_vprintf_chk (obstack, flag, fmt, arg); + res = __obstack_vprintf_internal (obstack, fmt, arg, + (flag > 0) ? PRINTF_FORTIFY : 0); __no_long_double = 0; return res; } diff --git a/sysdeps/nptl/stdio-lock.h b/sysdeps/nptl/stdio-lock.h index 5b9782452f..1d6a81c5bf 100644 --- a/sysdeps/nptl/stdio-lock.h +++ b/sysdeps/nptl/stdio-lock.h @@ -94,15 +94,8 @@ typedef struct { int lock; int cnt; void *owner; } _IO_lock_t; __attribute__((cleanup (_IO_acquire_lock_fct))) \ = (_fp); \ _IO_flockfile (_IO_acquire_lock_file); -# define _IO_acquire_lock_clear_flags2(_fp) \ - do { \ - FILE *_IO_acquire_lock_file \ - __attribute__((cleanup (_IO_acquire_lock_clear_flags2_fct))) \ - = (_fp); \ - _IO_flockfile (_IO_acquire_lock_file); # else # define _IO_acquire_lock(_fp) _IO_acquire_lock_needs_exceptions_enabled -# define _IO_acquire_lock_clear_flags2(_fp) _IO_acquire_lock (_fp) # endif # define _IO_release_lock(_fp) ; } while (0) From patchwork Mon Oct 29 12:16:50 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Gabriel F. T. Gomes" X-Patchwork-Id: 990172 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-96801-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=inconstante.eti.br Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="aeKsEZNb"; 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 42kDCq5kK1z9s7T for ; Mon, 29 Oct 2018 23:18:47 +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-type; q=dns; s=default; b=ssKam 9Ok1Of8mJHVqImCNEgZHrBy7fnX/FOKr7nF+iU9vv25muxQGfQPvm8zvk5MWKAmd hOJev6QpcrIQte35FmZdFvJ9c6WV+TOPsrofshiVPhZg3+WDN7EllxxeJoiBzeWk YyOX1D5SnAkxalfyvVgOwWqqL3kGFipC9Hh59k= 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-type; s=default; bh=8qyUa6VAhaB sKL2qLVJT7wyAHrI=; b=aeKsEZNbzy13/i/eywY+oUNDdF0awOraCpBG6mlDzu5 +gnPy5wKkXaawes4imFECqZQ0k0Ymu8EBbO+inrU2WmKTNqDfblwWprZe1DCH9U7 BvRYeslty/CbkeqYIaaE2Lj3wmhDvm1FYAO92y47sEM3AqdyGQxieGzFUWse0Lkw = Received: (qmail 25525 invoked by alias); 29 Oct 2018 12:17:52 -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 25394 invoked by uid 89); 29 Oct 2018 12:17:51 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-25.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_LAZY_DOMAIN_SECURITY, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.2 spammy=87, Directly, prep X-HELO: mo19.mail-out.ovh.net From: "Gabriel F. T. Gomes" To: Subject: [PATCH v2 8/8] Use PRINTF_LDBL_IS_DBL instead of __ldbl_is_dbl. Date: Mon, 29 Oct 2018 09:16:50 -0300 Message-ID: <20181029121650.24544-9-gabriel@inconstante.eti.br> In-Reply-To: <20181029121650.24544-1-gabriel@inconstante.eti.br> References: <20181029121650.24544-1-gabriel@inconstante.eti.br> MIME-Version: 1.0 X-Ovh-Tracer-Id: 18043671911015304899 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: 0 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedtkedrheekgdefjecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemucehtddtnecu From: Zack Weinberg Changed since v1: - Removed libc_hidden_def and libc_hidden_proto from all of the __nldbl_*printf* function, since they are no longer called from within glibc, only from nldbl-*printf*.c files (libnldbl_nonshared.a) -- 8< -- After all that prep work, nldbl-compat.c can now use PRINTF_LDBL_IS_DBL instead of __no_long_double to control the behavior of printf-like functions; this is the last thing we needed __no_long_double for, so it can go away entirely. Tested for powerpc and powerpc64le. 2018-10-25 Zack Weinberg Gabriel F. T. Gomes * stdio-common/vfprintf-internal.c (__vfprintf_internal, __vfwprintf_internal): Don't use __ldbl_is_dbl. * sysdeps/generic/math_ldbl_opt.h: Remove __ldbl_is_dbl. * sysdeps/ieee754/ldbl-opt/math_ldbl_opt.h: Remove __ldbl_is_dbl and __no_long_double. * sysdeps/ieee754/ldbl-opt/math_ldbl_opt.c: Remove file. * sysdeps/ieee754/ldbl-opt/Makefile (routines): Remove math_ldbl_opt. * sysdeps/ieee754/ldbl-opt/nldbl-compat.c: Remove libc_hidden_proto and libc_hidden_def from all __nldbl_*printf* and __nldbl_*syslog* functions. (__nldbl_cleanup, set_no_long_double, clear_no_long_double): Remove. (__nldbl___asprintf, __nldbl_dprintf, __nldbl_fprintf) (__nldbl_fwprintf, __nldbl_printf, __nldbl_sprintf) (__nldbl_vfprintf, __nldbl___vsprintf, __nldbl_obstack_vprintf) (__ndlbl_obstack_printf, __nldbl_snprintf, __nldbl_swprintf) (__nldbl_vasprintf, __nldbl_vdprintf, __nldbl_vfwprintf) (__nldbl_vprintf, __nldbl_vsnprintf, __ndlbl_vswprintf) (__nldbl_vwprintf, __nldbl_wprintf): Directly call the appropriate __v*printf_internal routine, passing PRINTF_LDBL_IS_DBL. Do not mess with __no_long_double. Normalize variable names. (__nldbl___fprintf_chk, __nldbl___fwprintf_chk) (__nldbl___printf_chk, __nldbl___snprintf_chk) (__nldbl___sprintf_chk, __nldbl___swprintf_chk) (__nldbl___vfprintf_chk, __nldbl___vfwprintf_chk) (__nldbl___vprintf_chk, __nldbl___vsnprintf_chk) (__nldbl___vsprintf_chk, __nldbl___vswprintf_chk) (__nldbl___vwprintf_chk, __nldbl___wprintf_chk) (__nldbl___vasprintf_chk, __nldbl___asprintf_chk) (__nldbl___vdprintf_chk, __nldbl___dprintf_chk) (__nldbl___obstack_vprintf_chk, __nldbl___obstack_printf_chk): Likewise, and also pass PRINTF_FORTIFY when appropriate. (__nldbl_syslog, __nldbl_vsyslog): Directly call __vsyslog_internal, passing PRINTF_LDBL_IS_DBL. (__nldbl_syslog_chk): Likewise, and also pass PRINTF_FORTIFY when appropriate. (__nldbl_vsyslog_chk): Likewise, and also pass PRINTF_FORTIFY when appropriate. Signed-off-by: Zack Weinberg Signed-off-by: Gabriel F. T. Gomes --- stdio-common/vfprintf-internal.c | 4 - sysdeps/generic/math_ldbl_opt.h | 1 - sysdeps/ieee754/ldbl-opt/Makefile | 2 +- sysdeps/ieee754/ldbl-opt/math_ldbl_opt.h | 4 - sysdeps/ieee754/ldbl-opt/nldbl-compat.c | 504 +++++++++++++++---------------- 5 files changed, 238 insertions(+), 277 deletions(-) diff --git a/stdio-common/vfprintf-internal.c b/stdio-common/vfprintf-internal.c index b5ae868371..cf7e858e35 100644 --- a/stdio-common/vfprintf-internal.c +++ b/stdio-common/vfprintf-internal.c @@ -1282,10 +1282,6 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap, unsigned int mode_flags) 0 if unknown. */ int readonly_format = 0; - /* Temporarily honor environmental settings. */ - if (__ldbl_is_dbl) - mode_flags |= PRINTF_LDBL_IS_DBL; - /* Orient the stream. */ #ifdef ORIENT ORIENT; diff --git a/sysdeps/generic/math_ldbl_opt.h b/sysdeps/generic/math_ldbl_opt.h index 92f670dff7..fbd2c82e2f 100644 --- a/sysdeps/generic/math_ldbl_opt.h +++ b/sysdeps/generic/math_ldbl_opt.h @@ -15,4 +15,3 @@ #define ldbl_weak_alias(name, aliasname) weak_alias (name, aliasname) #define ldbl_compat_symbol(lib, local, symbol, version) \ compat_symbol (lib, local, symbol, version) -#define __ldbl_is_dbl 0 diff --git a/sysdeps/ieee754/ldbl-opt/Makefile b/sysdeps/ieee754/ldbl-opt/Makefile index 6854413fa3..64fdb8cb9e 100644 --- a/sysdeps/ieee754/ldbl-opt/Makefile +++ b/sysdeps/ieee754/ldbl-opt/Makefile @@ -8,7 +8,7 @@ endif ifeq ($(subdir),math) libm-routines += s_nexttowardfd -routines += math_ldbl_opt nldbl-compat +routines += nldbl-compat extra-libs += libnldbl libnldbl-calls = asprintf dprintf fprintf fscanf fwprintf fwscanf iovfscanf \ diff --git a/sysdeps/ieee754/ldbl-opt/math_ldbl_opt.h b/sysdeps/ieee754/ldbl-opt/math_ldbl_opt.h index 4d2f3c7be2..dbd52d6d22 100644 --- a/sysdeps/ieee754/ldbl-opt/math_ldbl_opt.h +++ b/sysdeps/ieee754/ldbl-opt/math_ldbl_opt.h @@ -41,8 +41,4 @@ #endif #ifndef __ASSEMBLER__ -/* Set temporarily to non-zero if long double should be considered - the same as double. */ -extern __thread int __no_long_double attribute_tls_model_ie attribute_hidden; -# define __ldbl_is_dbl __builtin_expect (__no_long_double, 0) #endif diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-compat.c b/sysdeps/ieee754/ldbl-opt/nldbl-compat.c index 59b2c9fcdd..f6dd81759d 100644 --- a/sysdeps/ieee754/ldbl-opt/nldbl-compat.c +++ b/sysdeps/ieee754/ldbl-opt/nldbl-compat.c @@ -30,43 +30,15 @@ #include "nldbl-compat.h" -libc_hidden_proto (__nldbl_vfprintf) libc_hidden_proto (__nldbl_vsscanf) -libc_hidden_proto (__nldbl_vsprintf) libc_hidden_proto (__nldbl_vfscanf) libc_hidden_proto (__nldbl_vfwscanf) -libc_hidden_proto (__nldbl_vdprintf) libc_hidden_proto (__nldbl_vswscanf) -libc_hidden_proto (__nldbl_vfwprintf) -libc_hidden_proto (__nldbl_vswprintf) -libc_hidden_proto (__nldbl_vsnprintf) -libc_hidden_proto (__nldbl_vasprintf) -libc_hidden_proto (__nldbl_obstack_vprintf) -libc_hidden_proto (__nldbl___vfwprintf_chk) -libc_hidden_proto (__nldbl___vsnprintf_chk) -libc_hidden_proto (__nldbl___vfprintf_chk) -libc_hidden_proto (__nldbl___vsyslog_chk) -libc_hidden_proto (__nldbl___vsprintf_chk) -libc_hidden_proto (__nldbl___vswprintf_chk) -libc_hidden_proto (__nldbl___vasprintf_chk) -libc_hidden_proto (__nldbl___vdprintf_chk) -libc_hidden_proto (__nldbl___obstack_vprintf_chk) libc_hidden_proto (__nldbl___isoc99_vsscanf) libc_hidden_proto (__nldbl___isoc99_vfscanf) libc_hidden_proto (__nldbl___isoc99_vswscanf) libc_hidden_proto (__nldbl___isoc99_vfwscanf) -static void -__nldbl_cleanup (void *arg) -{ - __no_long_double = 0; -} - -#define set_no_long_double() \ - __libc_cleanup_push (__nldbl_cleanup, NULL); __no_long_double = 1 -#define clear_no_long_double() \ - __no_long_double = 0; __libc_cleanup_pop (0) - /* Compatibility with IEEE double as long double. IEEE quad long double is used by default for most programs, so we don't need to split this into one file per function for the @@ -76,14 +48,14 @@ int attribute_compat_text_section __nldbl___asprintf (char **string_ptr, const char *fmt, ...) { - va_list arg; - int done; + va_list ap; + int ret; - va_start (arg, fmt); - done = __nldbl_vasprintf (string_ptr, fmt, arg); - va_end (arg); + va_start (ap, fmt); + ret = __vasprintf_internal (string_ptr, fmt, ap, PRINTF_LDBL_IS_DBL); + va_end (ap); - return done; + return ret; } weak_alias (__nldbl___asprintf, __nldbl_asprintf) @@ -91,28 +63,28 @@ int attribute_compat_text_section __nldbl_dprintf (int d, const char *fmt, ...) { - va_list arg; - int done; + va_list ap; + int ret; - va_start (arg, fmt); - done = __nldbl_vdprintf (d, fmt, arg); - va_end (arg); + va_start (ap, fmt); + ret = __vdprintf_internal (d, fmt, ap, PRINTF_LDBL_IS_DBL); + va_end (ap); - return done; + return ret; } int attribute_compat_text_section __nldbl_fprintf (FILE *stream, const char *fmt, ...) { - va_list arg; - int done; + va_list ap; + int ret; - va_start (arg, fmt); - done = __nldbl_vfprintf (stream, fmt, arg); - va_end (arg); + va_start (ap, fmt); + ret = __vfprintf_internal (stream, fmt, ap, PRINTF_LDBL_IS_DBL); + va_end (ap); - return done; + return ret; } weak_alias (__nldbl_fprintf, __nldbl__IO_fprintf) @@ -120,28 +92,28 @@ int attribute_compat_text_section weak_function __nldbl_fwprintf (FILE *stream, const wchar_t *fmt, ...) { - va_list arg; - int done; + va_list ap; + int ret; - va_start (arg, fmt); - done = __nldbl_vfwprintf (stream, fmt, arg); - va_end (arg); + va_start (ap, fmt); + ret = __vfwprintf_internal (stream, fmt, ap, PRINTF_LDBL_IS_DBL); + va_end (ap); - return done; + return ret; } int attribute_compat_text_section __nldbl_printf (const char *fmt, ...) { - va_list arg; - int done; + va_list ap; + int ret; - va_start (arg, fmt); - done = __nldbl_vfprintf (stdout, fmt, arg); - va_end (arg); + va_start (ap, fmt); + ret = __vfprintf_internal (stdout, fmt, ap, PRINTF_LDBL_IS_DBL); + va_end (ap); - return done; + return ret; } strong_alias (__nldbl_printf, __nldbl__IO_printf) @@ -149,14 +121,14 @@ int attribute_compat_text_section __nldbl_sprintf (char *s, const char *fmt, ...) { - va_list arg; - int done; + va_list ap; + int ret; - va_start (arg, fmt); - done = __nldbl_vsprintf (s, fmt, arg); - va_end (arg); + va_start (ap, fmt); + ret = __vsprintf_internal (s, -1, fmt, ap, PRINTF_LDBL_IS_DBL); + va_end (ap); - return done; + return ret; } strong_alias (__nldbl_sprintf, __nldbl__IO_sprintf) @@ -164,123 +136,93 @@ int attribute_compat_text_section __nldbl_vfprintf (FILE *s, const char *fmt, va_list ap) { - int done; - set_no_long_double (); - done = __vfprintf_internal (s, fmt, ap, 0); - clear_no_long_double (); - return done; + return __vfprintf_internal (s, fmt, ap, PRINTF_LDBL_IS_DBL); } -libc_hidden_def (__nldbl_vfprintf) strong_alias (__nldbl_vfprintf, __nldbl__IO_vfprintf) int attribute_compat_text_section __nldbl___vsprintf (char *string, const char *fmt, va_list ap) { - int done; - __no_long_double = 1; - done = __vsprintf_internal (string, -1, fmt, ap, 0); - __no_long_double = 0; - return done; + return __vsprintf_internal (string, -1, fmt, ap, PRINTF_LDBL_IS_DBL); } strong_alias (__nldbl___vsprintf, __nldbl__IO_vsprintf) weak_alias (__nldbl___vsprintf, __nldbl_vsprintf) -libc_hidden_def (__nldbl_vsprintf) int attribute_compat_text_section __nldbl_obstack_vprintf (struct obstack *obstack, const char *fmt, va_list ap) { - int done; - __no_long_double = 1; - done = __obstack_vprintf_internal (obstack, fmt, ap, 0); - __no_long_double = 0; - return done; + return __obstack_vprintf_internal (obstack, fmt, ap, PRINTF_LDBL_IS_DBL); } -libc_hidden_def (__nldbl_obstack_vprintf) int attribute_compat_text_section __nldbl_obstack_printf (struct obstack *obstack, const char *fmt, ...) { - int result; + int ret; va_list ap; va_start (ap, fmt); - result = __nldbl_obstack_vprintf (obstack, fmt, ap); + ret = __obstack_vprintf_internal (obstack, fmt, ap, PRINTF_LDBL_IS_DBL); va_end (ap); - return result; + return ret; } int attribute_compat_text_section weak_function __nldbl_snprintf (char *s, size_t maxlen, const char *fmt, ...) { - va_list arg; - int done; + va_list ap; + int ret; - va_start (arg, fmt); - done = __nldbl_vsnprintf (s, maxlen, fmt, arg); - va_end (arg); + va_start (ap, fmt); + ret = __vsnprintf_internal (s, maxlen, fmt, ap, PRINTF_LDBL_IS_DBL); + va_end (ap); - return done; + return ret; } int attribute_compat_text_section __nldbl_swprintf (wchar_t *s, size_t n, const wchar_t *fmt, ...) { - va_list arg; - int done; + va_list ap; + int ret; - va_start (arg, fmt); - done = __nldbl_vswprintf (s, n, fmt, arg); - va_end (arg); + va_start (ap, fmt); + ret = __vswprintf_internal (s, n, fmt, ap, PRINTF_LDBL_IS_DBL); + va_end (ap); - return done; + return ret; } int attribute_compat_text_section weak_function __nldbl_vasprintf (char **result_ptr, const char *fmt, va_list ap) { - int res; - __no_long_double = 1; - res = __vasprintf_internal (result_ptr, fmt, ap, 0); - __no_long_double = 0; - return res; + return __vasprintf_internal (result_ptr, fmt, ap, PRINTF_LDBL_IS_DBL); } -libc_hidden_def (__nldbl_vasprintf) int attribute_compat_text_section -__nldbl_vdprintf (int d, const char *fmt, va_list arg) +__nldbl_vdprintf (int d, const char *fmt, va_list ap) { - int res; - set_no_long_double (); - res = __vdprintf_internal (d, fmt, arg, 0); - clear_no_long_double (); - return res; + return __vdprintf_internal (d, fmt, ap, PRINTF_LDBL_IS_DBL); } -libc_hidden_def (__nldbl_vdprintf) int attribute_compat_text_section weak_function __nldbl_vfwprintf (FILE *s, const wchar_t *fmt, va_list ap) { - int res; - set_no_long_double (); - res = __vfwprintf_internal (s, fmt, ap, 0); - clear_no_long_double (); - return res; + return __vfwprintf_internal (s, fmt, ap, PRINTF_LDBL_IS_DBL); } -libc_hidden_def (__nldbl_vfwprintf) int attribute_compat_text_section __nldbl_vprintf (const char *fmt, va_list ap) { - return __nldbl_vfprintf (stdout, fmt, ap); + return __vfprintf_internal (stdout, fmt, ap, PRINTF_LDBL_IS_DBL); } int @@ -288,13 +230,8 @@ attribute_compat_text_section __nldbl_vsnprintf (char *string, size_t maxlen, const char *fmt, va_list ap) { - int res; - __no_long_double = 1; - res = __vsnprintf_internal (string, maxlen, fmt, ap, 0); - __no_long_double = 0; - return res; + return __vsnprintf_internal (string, maxlen, fmt, ap, PRINTF_LDBL_IS_DBL); } -libc_hidden_def (__nldbl_vsnprintf) weak_alias (__nldbl_vsnprintf, __nldbl___vsnprintf) int @@ -302,33 +239,28 @@ attribute_compat_text_section weak_function __nldbl_vswprintf (wchar_t *string, size_t maxlen, const wchar_t *fmt, va_list ap) { - int res; - __no_long_double = 1; - res = __vswprintf_internal (string, maxlen, fmt, ap, 0); - __no_long_double = 0; - return res; + return __vswprintf_internal (string, maxlen, fmt, ap, PRINTF_LDBL_IS_DBL); } -libc_hidden_def (__nldbl_vswprintf) int attribute_compat_text_section __nldbl_vwprintf (const wchar_t *fmt, va_list ap) { - return __nldbl_vfwprintf (stdout, fmt, ap); + return __vfwprintf_internal (stdout, fmt, ap, PRINTF_LDBL_IS_DBL); } int attribute_compat_text_section __nldbl_wprintf (const wchar_t *fmt, ...) { - va_list arg; - int done; + va_list ap; + int ret; - va_start (arg, fmt); - done = __nldbl_vfwprintf (stdout, fmt, arg); - va_end (arg); + va_start (ap, fmt); + ret = __vfwprintf_internal (stdout, fmt, ap, PRINTF_LDBL_IS_DBL); + va_end (ap); - return done; + return ret; } #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_29) @@ -491,42 +423,51 @@ int attribute_compat_text_section __nldbl___fprintf_chk (FILE *stream, int flag, const char *fmt, ...) { - va_list arg; - int done; + va_list ap; + int ret; + unsigned int mode = PRINTF_LDBL_IS_DBL; + if (flag > 0) + mode |= PRINTF_FORTIFY; - va_start (arg, fmt); - done = __nldbl___vfprintf_chk (stream, flag, fmt, arg); - va_end (arg); + va_start (ap, fmt); + ret = __vfprintf_internal (stream, fmt, ap, mode); + va_end (ap); - return done; + return ret; } int attribute_compat_text_section __nldbl___fwprintf_chk (FILE *stream, int flag, const wchar_t *fmt, ...) { - va_list arg; - int done; + va_list ap; + int ret; + unsigned int mode = PRINTF_LDBL_IS_DBL; + if (flag > 0) + mode |= PRINTF_FORTIFY; - va_start (arg, fmt); - done = __nldbl___vfwprintf_chk (stream, flag, fmt, arg); - va_end (arg); + va_start (ap, fmt); + ret = __vfwprintf_internal (stream, fmt, ap, mode); + va_end (ap); - return done; + return ret; } int attribute_compat_text_section __nldbl___printf_chk (int flag, const char *fmt, ...) { - va_list arg; - int done; + va_list ap; + int ret; + unsigned int mode = PRINTF_LDBL_IS_DBL; + if (flag > 0) + mode |= PRINTF_FORTIFY; - va_start (arg, fmt); - done = __nldbl___vfprintf_chk (stdout, flag, fmt, arg); - va_end (arg); + va_start (ap, fmt); + ret = __vfprintf_internal (stdout, fmt, ap, mode); + va_end (ap); - return done; + return ret; } int @@ -534,74 +475,94 @@ attribute_compat_text_section __nldbl___snprintf_chk (char *s, size_t maxlen, int flag, size_t slen, const char *fmt, ...) { - va_list arg; - int done; + if (__glibc_unlikely (slen < maxlen)) + __chk_fail (); - va_start (arg, fmt); - done = __nldbl___vsnprintf_chk (s, maxlen, flag, slen, fmt, arg); - va_end (arg); + va_list ap; + int ret; + unsigned int mode = PRINTF_LDBL_IS_DBL; + if (flag > 0) + mode |= PRINTF_FORTIFY; - return done; + va_start (ap, fmt); + ret = __vsnprintf_internal (s, maxlen, fmt, ap, mode); + va_end (ap); + + return ret; } int attribute_compat_text_section __nldbl___sprintf_chk (char *s, int flag, size_t slen, const char *fmt, ...) { - va_list arg; - int done; + if (slen == 0) + __chk_fail (); + + va_list ap; + int ret; + unsigned int mode = PRINTF_LDBL_IS_DBL; + if (flag > 0) + mode |= PRINTF_FORTIFY; - va_start (arg, fmt); - done = __nldbl___vsprintf_chk (s, flag, slen, fmt, arg); - va_end (arg); + va_start (ap, fmt); + ret = __vsprintf_internal (s, slen, fmt, ap, mode); + va_end (ap); - return done; + return ret; } int attribute_compat_text_section -__nldbl___swprintf_chk (wchar_t *s, size_t n, int flag, size_t slen, +__nldbl___swprintf_chk (wchar_t *s, size_t maxlen, int flag, size_t slen, const wchar_t *fmt, ...) { - va_list arg; - int done; + if (__glibc_unlikely (slen < maxlen)) + __chk_fail (); + + va_list ap; + int ret; + unsigned int mode = PRINTF_LDBL_IS_DBL; + if (flag > 0) + mode |= PRINTF_FORTIFY; - va_start (arg, fmt); - done = __nldbl___vswprintf_chk (s, n, flag, slen, fmt, arg); - va_end (arg); + va_start (ap, fmt); + ret = __vswprintf_internal (s, maxlen, fmt, ap, mode); + va_end (ap); - return done; + return ret; } int attribute_compat_text_section __nldbl___vfprintf_chk (FILE *s, int flag, const char *fmt, va_list ap) { - int res; - set_no_long_double (); - res = __vfprintf_internal (s, fmt, ap, (flag > 0) ? PRINTF_FORTIFY : 0); - clear_no_long_double (); - return res; + unsigned int mode = PRINTF_LDBL_IS_DBL; + if (flag > 0) + mode |= PRINTF_FORTIFY; + + return __vfprintf_internal (s, fmt, ap, mode); } -libc_hidden_def (__nldbl___vfprintf_chk) int attribute_compat_text_section __nldbl___vfwprintf_chk (FILE *s, int flag, const wchar_t *fmt, va_list ap) { - int res; - set_no_long_double (); - res = __vfwprintf_internal (s, fmt, ap, (flag > 0) ? PRINTF_FORTIFY : 0); - clear_no_long_double (); - return res; + unsigned int mode = PRINTF_LDBL_IS_DBL; + if (flag > 0) + mode |= PRINTF_FORTIFY; + + return __vfwprintf_internal (s, fmt, ap, mode); } -libc_hidden_def (__nldbl___vfwprintf_chk) int attribute_compat_text_section __nldbl___vprintf_chk (int flag, const char *fmt, va_list ap) { - return __nldbl___vfprintf_chk (stdout, flag, fmt, ap); + unsigned int mode = PRINTF_LDBL_IS_DBL; + if (flag > 0) + mode |= PRINTF_FORTIFY; + + return __vfprintf_internal (stdout, fmt, ap, mode); } int @@ -612,14 +573,12 @@ __nldbl___vsnprintf_chk (char *string, size_t maxlen, int flag, size_t slen, if (__glibc_unlikely (slen < maxlen)) __chk_fail (); - int res; - __no_long_double = 1; - res = __vsnprintf_internal (string, maxlen, fmt, ap, - (flag > 0) ? PRINTF_FORTIFY : 0); - __no_long_double = 0; - return res; + unsigned int mode = PRINTF_LDBL_IS_DBL; + if (flag > 0) + mode |= PRINTF_FORTIFY; + + return __vsnprintf_internal (string, maxlen, fmt, ap, mode); } -libc_hidden_def (__nldbl___vsnprintf_chk) int attribute_compat_text_section @@ -629,14 +588,12 @@ __nldbl___vsprintf_chk (char *string, int flag, size_t slen, const char *fmt, if (slen == 0) __chk_fail (); - int res; - __no_long_double = 1; - res = __vsprintf_internal (string, slen, fmt, ap, - (flag > 0) ? PRINTF_FORTIFY : 0); - __no_long_double = 0; - return res; + unsigned int mode = PRINTF_LDBL_IS_DBL; + if (flag > 0) + mode |= PRINTF_FORTIFY; + + return __vsprintf_internal (string, slen, fmt, ap, mode); } -libc_hidden_def (__nldbl___vsprintf_chk) int attribute_compat_text_section @@ -646,116 +603,125 @@ __nldbl___vswprintf_chk (wchar_t *string, size_t maxlen, int flag, size_t slen, if (__glibc_unlikely (slen < maxlen)) __chk_fail (); - int res; - __no_long_double = 1; - res = __vswprintf_internal (string, maxlen, fmt, ap, - (flag > 0) ? PRINTF_FORTIFY : 0); - __no_long_double = 0; - return res; + unsigned int mode = PRINTF_LDBL_IS_DBL; + if (flag > 0) + mode |= PRINTF_FORTIFY; + + return __vswprintf_internal (string, maxlen, fmt, ap, mode); } -libc_hidden_def (__nldbl___vswprintf_chk) int attribute_compat_text_section __nldbl___vwprintf_chk (int flag, const wchar_t *fmt, va_list ap) { - return __nldbl___vfwprintf_chk (stdout, flag, fmt, ap); + unsigned int mode = PRINTF_LDBL_IS_DBL; + if (flag > 0) + mode |= PRINTF_FORTIFY; + + return __vfwprintf_internal (stdout, fmt, ap, mode); } int attribute_compat_text_section __nldbl___wprintf_chk (int flag, const wchar_t *fmt, ...) { - va_list arg; - int done; + va_list ap; + int ret; + unsigned int mode = PRINTF_LDBL_IS_DBL; + if (flag > 0) + mode |= PRINTF_FORTIFY; - va_start (arg, fmt); - done = __nldbl___vfwprintf_chk (stdout, flag, fmt, arg); - va_end (arg); + va_start (ap, fmt); + ret = __vfwprintf_internal (stdout, fmt, ap, mode); + va_end (ap); - return done; + return ret; } int attribute_compat_text_section -__nldbl___vasprintf_chk (char **ptr, int flag, const char *fmt, va_list arg) +__nldbl___vasprintf_chk (char **ptr, int flag, const char *fmt, va_list ap) { - int res; - __no_long_double = 1; - res = __vasprintf_internal (ptr, fmt, arg, - (flag > 0) ? PRINTF_FORTIFY : 0); - __no_long_double = 0; - return res; + unsigned int mode = PRINTF_LDBL_IS_DBL; + if (flag > 0) + mode |= PRINTF_FORTIFY; + + return __vasprintf_internal (ptr, fmt, ap, mode); } -libc_hidden_def (__nldbl___vasprintf_chk) int attribute_compat_text_section __nldbl___asprintf_chk (char **ptr, int flag, const char *fmt, ...) { - va_list arg; - int done; + va_list ap; + int ret; + unsigned int mode = PRINTF_LDBL_IS_DBL; + if (flag > 0) + mode |= PRINTF_FORTIFY; - va_start (arg, fmt); - done = __nldbl___vasprintf_chk (ptr, flag, fmt, arg); - va_end (arg); + va_start (ap, fmt); + ret = __vasprintf_internal (ptr, fmt, ap, mode); + va_end (ap); - return done; + return ret; } int attribute_compat_text_section -__nldbl___vdprintf_chk (int d, int flag, const char *fmt, va_list arg) +__nldbl___vdprintf_chk (int d, int flag, const char *fmt, va_list ap) { - int res; - set_no_long_double (); - res = __vdprintf_internal (d, fmt, arg, (flag > 0) ? PRINTF_FORTIFY : 0); - clear_no_long_double (); - return res; + unsigned int mode = PRINTF_LDBL_IS_DBL; + if (flag > 0) + mode |= PRINTF_FORTIFY; + + return __vdprintf_internal (d, fmt, ap, mode); } -libc_hidden_def (__nldbl___vdprintf_chk) int attribute_compat_text_section __nldbl___dprintf_chk (int d, int flag, const char *fmt, ...) { - va_list arg; - int done; + va_list ap; + int ret; + unsigned int mode = PRINTF_LDBL_IS_DBL; + if (flag > 0) + mode |= PRINTF_FORTIFY; - va_start (arg, fmt); - done = __nldbl___vdprintf_chk (d, flag, fmt, arg); - va_end (arg); + va_start (ap, fmt); + ret = __vdprintf_internal (d, fmt, ap, mode); + va_end (ap); - return done; + return ret; } int attribute_compat_text_section __nldbl___obstack_vprintf_chk (struct obstack *obstack, int flag, - const char *fmt, va_list arg) + const char *fmt, va_list ap) { - int res; - __no_long_double = 1; - res = __obstack_vprintf_internal (obstack, fmt, arg, - (flag > 0) ? PRINTF_FORTIFY : 0); - __no_long_double = 0; - return res; + unsigned int mode = PRINTF_LDBL_IS_DBL; + if (flag > 0) + mode |= PRINTF_FORTIFY; + + return __obstack_vprintf_internal (obstack, fmt, ap, mode); } -libc_hidden_def (__nldbl___obstack_vprintf_chk) int attribute_compat_text_section __nldbl___obstack_printf_chk (struct obstack *obstack, int flag, const char *fmt, ...) { - va_list arg; - int done; + va_list ap; + int ret; + unsigned int mode = PRINTF_LDBL_IS_DBL; + if (flag > 0) + mode |= PRINTF_FORTIFY; - va_start (arg, fmt); - done = __nldbl___obstack_vprintf_chk (obstack, flag, fmt, arg); - va_end (arg); + va_start (ap, fmt); + ret = __obstack_vprintf_internal (obstack, fmt, ap, mode); + va_end (ap); - return done; + return ret; } extern __typeof (printf_size) __printf_size; @@ -837,18 +803,28 @@ __nldbl_syslog (int pri, const char *fmt, ...) { va_list ap; va_start (ap, fmt); - __nldbl___vsyslog_chk (pri, -1, fmt, ap); + __vsyslog_internal (pri, fmt, ap, PRINTF_LDBL_IS_DBL); va_end (ap); } +void +attribute_compat_text_section +__nldbl_vsyslog (int pri, const char *fmt, va_list ap) +{ + __vsyslog_internal (pri, fmt, ap, PRINTF_LDBL_IS_DBL); +} + void attribute_compat_text_section __nldbl___syslog_chk (int pri, int flag, const char *fmt, ...) { va_list ap; + unsigned int mode = PRINTF_LDBL_IS_DBL; + if (flag > 0) + mode |= PRINTF_FORTIFY; va_start (ap, fmt); - __nldbl___vsyslog_chk (pri, flag, fmt, ap); + __vsyslog_internal (pri, fmt, ap, mode); va_end(ap); } @@ -856,17 +832,11 @@ void attribute_compat_text_section __nldbl___vsyslog_chk (int pri, int flag, const char *fmt, va_list ap) { - set_no_long_double (); - __vsyslog_internal (pri, fmt, ap, (flag > 0) ? PRINTF_FORTIFY : 0); - clear_no_long_double (); -} -libc_hidden_def (__nldbl___vsyslog_chk) + unsigned int mode = PRINTF_LDBL_IS_DBL; + if (flag > 0) + mode |= PRINTF_FORTIFY; -void -attribute_compat_text_section -__nldbl_vsyslog (int pri, const char *fmt, va_list ap) -{ - __nldbl___vsyslog_chk (pri, -1, fmt, ap); + __vsyslog_internal (pri, fmt, ap, mode); } int