* [PATCH] Further -D_FORTIFY_SOURCE={,=2} C++ support
@ 2007-09-07 22:34 Jakub Jelinek
0 siblings, 0 replies; only message in thread
From: Jakub Jelinek @ 2007-09-07 22:34 UTC (permalink / raw)
To: Ulrich Drepper; +Cc: Glibc hackers
Hi!
__builtin_va_arg_pack () has been committed to GCC SVN, so we can support
fortification even for {,v}{,s,sn,sw,w,f,fw}printf and syslog.
This patch is on top of the one I posted on Monday.
Distro note: the support is backported in latest Fedora gcc as well,
so with little tweaks of misc/sys/cdefs.h it is possible to test this even
with older gccs.
2007-09-07 Jakub Jelinek <jakub@redhat.com>
* misc/sys/cdefs.h (__va_arg_pack): Define for GCC 4.3+.
* misc/bits/syslog.h (syslog): When __va_arg_pack is defined,
implement as __extern_always_inline function.
(vsyslog): Define as __extern_always_inline function unconditionally.
* libio/bits/stdio2.h (sprintf, snprintf, printf, fprintf):
When __va_arg_pack is defined, implement as __extern_always_inline
functions.
(vsprintf, vsnprintf, vprintf, vfprintf): Define as
__extern_always_inline functions unconditionally.
* libio/bits/stdio.h (vprintf): Ifdef out the inline when
bits/stdio2.h will be included.
* wcsmbs/bits/wchar2.h (__swprintf_alias): New redirect.
(swprintf, wprintf, fwprintf): When __va_arg_pack is defined,
implement as __extern_always_inline functions.
(vswprintf, vwprintf, vfwprintf): Define as
__extern_always_inline functions unconditionally.
* debug/tst-chk1.c (do_test): Enable remaining tests for C++.
--- libc/misc/sys/cdefs.h.jj 2007-09-07 08:14:01.000000000 +0200
+++ libc/misc/sys/cdefs.h 2007-09-07 08:13:20.000000000 +0200
@@ -294,6 +294,12 @@
# endif
#endif
+/* GCC 4.3 and above allow passing all anonymous arguments of an
+ __extern_always_inline function to some other vararg function. */
+#if __GNUC_PREREQ (4,3)
+# define __va_arg_pack() __builtin_va_arg_pack ()
+#endif
+
/* It is possible to compile containing GCC extensions even if GCC is
run in pedantic mode if the uses are carefully marked using the
`__extension__' keyword. But this is not generally available before
--- libc/misc/bits/syslog.h.jj 2007-09-02 19:18:12.000000000 +0200
+++ libc/misc/bits/syslog.h 2007-09-07 08:26:51.000000000 +0200
@@ -25,8 +25,13 @@
extern void __syslog_chk (int __pri, int __flag, __const char *__fmt, ...)
__attribute__ ((__format__ (__printf__, 3, 4)));
-#ifndef __cplusplus
-/* FIXME for C++. */
+#ifdef __va_arg_pack
+__extern_always_inline void
+syslog (int __pri, int __flag, __const char *__fmt, ...)
+{
+ return __syslog_chk (__pri, __flag, __fmt, __va_arg_pack ());
+}
+#elif !defined __cplusplus
# define syslog(pri, ...) \
__syslog_chk (pri, __USE_FORTIFY_LEVEL - 1, __VA_ARGS__)
#endif
@@ -37,14 +42,9 @@ extern void __vsyslog_chk (int __pri, in
__gnuc_va_list __ap)
__attribute__ ((__format__ (__printf__, 3, 0)));
-# ifdef __cplusplus
__extern_always_inline void
vsyslog (int __pri, __const char *__fmt, __gnuc_va_list __ap)
{
return __vsyslog_chk (__pri, __USE_FORTIFY_LEVEL - 1, __fmt, __ap);
}
-# else
-# define vsyslog(pri, fmt, ap) \
- __vsyslog_chk (pri, __USE_FORTIFY_LEVEL - 1, fmt, ap)
-# endif
#endif
--- libc/libio/bits/stdio2.h.jj 2007-09-02 19:18:12.000000000 +0200
+++ libc/libio/bits/stdio2.h 2007-09-07 08:45:37.000000000 +0200
@@ -27,14 +27,19 @@ extern int __vsprintf_chk (char *__restr
__const char *__restrict __format,
_G_va_list __ap) __THROW;
-#ifndef __cplusplus
-/* FIXME for C++ */
+#ifdef __va_arg_pack
+__extern_always_inline int
+__NTH (sprintf (char *__restrict __s, __const char *__restrict __fmt, ...))
+{
+ return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1,
+ __bos (__s), __fmt, __va_arg_pack ());
+}
+#elif !defined __cplusplus
# define sprintf(str, ...) \
__builtin___sprintf_chk (str, __USE_FORTIFY_LEVEL - 1, __bos (str), \
__VA_ARGS__)
#endif
-#ifdef __cplusplus
__extern_always_inline int
__NTH (vsprintf (char *__restrict __s, __const char *__restrict __fmt,
_G_va_list __ap))
@@ -42,10 +47,6 @@ __NTH (vsprintf (char *__restrict __s, _
return __builtin___vsprintf_chk (__s, __USE_FORTIFY_LEVEL - 1,
__bos (__s), __fmt, __ap);
}
-#else
-# define vsprintf(str, fmt, ap) \
- __builtin___vsprintf_chk (str, __USE_FORTIFY_LEVEL - 1, __bos (str), fmt, ap)
-#endif
#if defined __USE_BSD || defined __USE_ISOC99 || defined __USE_UNIX98
@@ -56,14 +57,20 @@ extern int __vsnprintf_chk (char *__rest
size_t __slen, __const char *__restrict __format,
_G_va_list __ap) __THROW;
-# ifndef __cplusplus
-/* FIXME for C++ */
+# ifdef __va_arg_pack
+__extern_always_inline int
+__NTH (snprintf (char *__restrict __s, size_t __n,
+ __const char *__restrict __fmt, ...))
+{
+ return __builtin___snprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1,
+ __bos (__s), __fmt, __va_arg_pack ());
+}
+# elif !defined __cplusplus
# define snprintf(str, len, ...) \
__builtin___snprintf_chk (str, len, __USE_FORTIFY_LEVEL - 1, __bos (str), \
__VA_ARGS__)
# endif
-# ifdef __cplusplus
__extern_always_inline int
__NTH (vsnprintf (char *__restrict __s, size_t __n,
__const char *__restrict __fmt, _G_va_list __ap))
@@ -71,11 +78,6 @@ __NTH (vsnprintf (char *__restrict __s,
return __builtin___vsnprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1,
__bos (__s), __fmt, __ap);
}
-# else
-# define vsnprintf(str, len, fmt, ap) \
- __builtin___vsnprintf_chk (str, len, __USE_FORTIFY_LEVEL - 1, __bos (str), \
- fmt, ap)
-# endif
#endif
@@ -89,19 +91,34 @@ extern int __vfprintf_chk (FILE *__restr
extern int __vprintf_chk (int __flag, __const char *__restrict __format,
_G_va_list __ap);
-# ifndef __cplusplus
-/* FIXME for C++ */
+# ifdef __va_arg_pack
+__extern_always_inline int
+fprintf (FILE *__restrict __stream, __const char *__restrict __fmt, ...)
+{
+ return __fprintf_chk (__stream, __USE_FORTIFY_LEVEL - 1, __fmt,
+ __va_arg_pack ());
+}
+
+__extern_always_inline int
+printf (__const char *__restrict __fmt, ...)
+{
+ return __printf_chk (__USE_FORTIFY_LEVEL - 1, __fmt, __va_arg_pack ());
+}
+# elif !defined __cplusplus
# define printf(...) \
__printf_chk (__USE_FORTIFY_LEVEL - 1, __VA_ARGS__)
# define fprintf(stream, ...) \
__fprintf_chk (stream, __USE_FORTIFY_LEVEL - 1, __VA_ARGS__)
# endif
-# ifdef __cplusplus
__extern_always_inline int
vprintf (__const char *__restrict __fmt, _G_va_list __ap)
{
+#ifdef __USE_EXTERN_INLINES
+ return __vfprintf_chk (stdout, __USE_FORTIFY_LEVEL - 1, __fmt, __ap);
+#else
return __vprintf_chk (__USE_FORTIFY_LEVEL - 1, __fmt, __ap);
+#endif
}
__extern_always_inline int
@@ -110,12 +127,6 @@ vfprintf (FILE *__restrict __stream,
{
return __vfprintf_chk (__stream, __USE_FORTIFY_LEVEL - 1, __fmt, __ap);
}
-# else
-# define vprintf(format, ap) \
- __vprintf_chk (__USE_FORTIFY_LEVEL - 1, format, ap)
-# define vfprintf(stream, format, ap) \
- __vfprintf_chk (stream, __USE_FORTIFY_LEVEL - 1, format, ap)
-# endif
#endif
--- libc/wcsmbs/bits/wchar2.h.jj 2007-09-02 19:18:12.000000000 +0200
+++ libc/wcsmbs/bits/wchar2.h 2007-09-07 08:35:03.000000000 +0200
@@ -198,8 +198,23 @@ extern int __swprintf_chk (wchar_t *__re
__const wchar_t *__restrict __format, ...)
__THROW /* __attribute__ ((__format__ (__wprintf__, 5, 6))) */;
-#ifndef __cplusplus
-/* XXX We might want to have support in gcc for swprintf. FIXME for C++. */
+extern int __REDIRECT_NTH (__swprintf_alias,
+ (wchar_t *__restrict __s, size_t __n,
+ __const wchar_t *__restrict __fmt, ...),
+ swprintf);
+
+#ifdef __va_arg_pack
+__extern_always_inline int
+__NTH (swprintf (wchar_t *__restrict __s, size_t __n,
+ __const wchar_t *__restrict __fmt, ...))
+{
+ if (__bos (__s) != (size_t) -1 || __USE_FORTIFY_LEVEL > 1)
+ return __swprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1, __bos (__s),
+ __fmt, __va_arg_pack ());
+ return __swprintf_alias (__s, __n, __fmt, __va_arg_pack ());
+}
+#elif !defined __cplusplus
+/* XXX We might want to have support in gcc for swprintf. */
# define swprintf(s, n, ...) \
(__bos (s) != (size_t) -1 || __USE_FORTIFY_LEVEL > 1 \
? __swprintf_chk (s, n, __USE_FORTIFY_LEVEL - 1, __bos (s), __VA_ARGS__) \
@@ -212,7 +227,6 @@ extern int __vswprintf_chk (wchar_t *__r
__gnuc_va_list __arg)
__THROW /* __attribute__ ((__format__ (__wprintf__, 5, 0))) */;
-#ifdef __cplusplus
extern int __REDIRECT_NTH (__vswprintf_alias,
(wchar_t *__restrict __s, size_t __n,
__const wchar_t *__restrict __fmt,
@@ -227,12 +241,6 @@ __NTH (vswprintf (wchar_t *__restrict __
__fmt, __ap);
return __vswprintf_alias (__s, __n, __fmt, __ap);
}
-#else
-# define vswprintf(s, n, fmt, ap) \
- (__bos (s) != (size_t) -1 || __USE_FORTIFY_LEVEL > 1 \
- ? __vswprintf_chk (s, n, __USE_FORTIFY_LEVEL - 1, __bos (s), fmt, ap) \
- : vswprintf (s, n, fmt, ap))
-#endif
#if __USE_FORTIFY_LEVEL > 1
@@ -247,14 +255,26 @@ extern int __vfwprintf_chk (__FILE *__re
extern int __vwprintf_chk (int __flag, __const wchar_t *__restrict __format,
__gnuc_va_list __ap);
-# ifndef __cplusplus
-/* FIXME for C++. */
+# ifdef __va_arg_pack
+__extern_always_inline int
+wprintf (__const wchar_t *__restrict __fmt, ...)
+{
+ return __wprintf_chk (__USE_FORTIFY_LEVEL - 1, __fmt, __va_arg_pack ());
+}
+
+__extern_always_inline int
+fwprintf (__FILE *__restrict __stream, __const wchar_t *__restrict __fmt, ...)
+{
+ return __fwprintf_chk (__stream, __USE_FORTIFY_LEVEL - 1, __fmt,
+ __va_arg_pack ());
+}
+# elif !defined __cplusplus
# define wprintf(...) \
__wprintf_chk (__USE_FORTIFY_LEVEL - 1, __VA_ARGS__)
# define fwprintf(stream, ...) \
__fwprintf_chk (stream, __USE_FORTIFY_LEVEL - 1, __VA_ARGS__)
# endif
-# ifdef __cplusplus
+
__extern_always_inline int
vwprintf (__const wchar_t *__restrict __fmt, __gnuc_va_list __ap)
{
@@ -267,12 +287,6 @@ vfwprintf (__FILE *__restrict __stream,
{
return __vfwprintf_chk (__stream, __USE_FORTIFY_LEVEL - 1, __fmt, __ap);
}
-# else
-# define vwprintf(format, ap) \
- __vwprintf_chk (__USE_FORTIFY_LEVEL - 1, format, ap)
-# define vfwprintf(stream, format, ap) \
- __vfwprintf_chk (stream, __USE_FORTIFY_LEVEL - 1, format, ap)
-# endif
#endif
--- libc/debug/tst-chk1.c.jj 2007-09-03 13:14:30.000000000 +0200
+++ libc/debug/tst-chk1.c 2007-09-07 08:37:16.000000000 +0200
@@ -102,7 +102,7 @@ int num2 = 987654;
chk_fail_ok = 0; \
FAIL (); \
}
-#if __USE_FORTIFY_LEVEL >= 2 && !defined __cplusplus
+#if __USE_FORTIFY_LEVEL >= 2 && (!defined __cplusplus || defined __va_arg_pack)
#define CHK_FAIL2_START CHK_FAIL_START
#define CHK_FAIL2_END CHK_FAIL_END
#else
@@ -309,7 +309,7 @@ do_test (void)
stpncpy (buf + 6, "cd", l0 + 5);
CHK_FAIL_END
-# ifndef __cplusplus
+# if !defined __cplusplus || defined __va_arg_pack
CHK_FAIL_START
sprintf (buf + 8, "%d", num1);
CHK_FAIL_END
@@ -363,7 +363,7 @@ do_test (void)
strncpy (a.buf1 + (O + 6), "X", l0 + 4);
CHK_FAIL_END
-# ifndef __cplusplus
+# if !defined __cplusplus || defined __va_arg_pack
CHK_FAIL_START
sprintf (a.buf1 + (O + 7), "%d", num1);
CHK_FAIL_END
--- libio/bits/stdio.h.jj 2007-09-08 00:19:16.000000000 +0200
+++ libio/bits/stdio.h 2007-09-07 08:44:25.000000000 +0200
@@ -29,7 +29,9 @@
#ifdef __USE_EXTERN_INLINES
-# ifndef __cplusplus
+/* For -D_FORTIFY_SOURCE{,=2} bits/stdio2.h will define a different
+ inline. */
+# if !(__USE_FORTIFY_LEVEL > 0 && defined __extern_always_inline)
/* Write formatted output to stdout from argument list ARG. */
__STDIO_INLINE int
vprintf (__const char *__restrict __fmt, _G_va_list __arg)
Jakub
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2007-09-07 22:34 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-09-07 22:34 [PATCH] Further -D_FORTIFY_SOURCE={,=2} C++ support Jakub Jelinek
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).