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: 29944 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 --- 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; }