* _FORTIFY_SOURCE has no effect for C++ due to usage of #define
@ 2018-03-06 13:39 Christian Franke
0 siblings, 0 replies; only message in thread
From: Christian Franke @ 2018-03-06 13:39 UTC (permalink / raw)
To: cygwin
Cygport now sets _FORTIFY_SOURCE=2 for C and C++ but this has no effect
for C++. In <sys/features.h> __SSP_FORTIFY_LEVEL is always set to 0 if
__cplusplus is defined. This is needed because <ssp/string.h> ... use
#defines to replace the functions.
Testcase:
$ cat copy.c
#include <string.h>
char sbuf[42], *dbuf;
void to_sbuf(const char *p)
{
strcpy(sbuf, p);
}
void to_dbuf(const char *p)
{
strcpy(dbuf, p);
}
Examine preprocessed code:
$ gcc -D_FORTIFY_SOURCE=2 -O2 -E copy.c > copy2.c
$ vim copy2.c # Remove unnecessary code && pretty-print
$ cat copy2.c
typedef unsigned int size_t;
char *__strcpy_chk(char *, const char *, size_t);
extern __inline__ __attribute__((__always_inline__, __gnu_inline__)) char *
__strcpy_ichk(char * restrict dst, const char * restrict src)
{
return __builtin___strcpy_chk(dst, src, __builtin_object_size(dst, 0));
}
char sbuf[42], *dbuf;
void to_sbuf(const char *p)
{
((__builtin_object_size(sbuf, 0) != (size_t)-1)
? __builtin___strcpy_chk(sbuf, p, __builtin_object_size(sbuf, 0))
: __strcpy_ichk(sbuf, p));
}
void to_dbuf(const char *p)
{
((__builtin_object_size(dbuf, 0) != (size_t)-1)
? __builtin___strcpy_chk(dbuf, p, __builtin_object_size(dbuf, 0))
: __strcpy_ichk(dbuf, p));
}
Why are these (a ? b : c) expanded from the "#define strcpy" needed?
Both branches lead to the same __builtin___strcpy_chk() call. Is this
possibly needed for (very) old compiler versions with weaker optimization?
According to "gcc -O2 -S" outputs, the generated code is identical for
this source:
$ cat copy3.c
typedef unsigned int size_t;
char *strcpy (char *restrict, const char *restrict);
char *__strcpy_chk(char *, const char *, size_t);
char sbuf[42], *dbuf;
void to_sbuf(const char *p)
{
__strcpy_chk(sbuf, p, 42);
}
void to_dbuf(const char *p)
{
strcpy(dbuf, p);
}
The same code is generated if strcpy() is replaced itself without a
"#define strcpy":
$ cat copy4.c
typedef unsigned int size_t;
char *strcpy (char *restrict, const char *restrict);
// #if __SSP_FORTIFY_LEVEL > 0
extern __inline__ __attribute__((__always_inline__, __gnu_inline__)) char *
strcpy(char * restrict dst, const char * restrict src)
{
return __builtin___strcpy_chk(dst, src, __builtin_object_size(dst, 0));
}
// #endif
char sbuf[42], *dbuf;
void to_sbuf(const char *p)
{
strcpy(sbuf, p); // changed to __strcpy_chk(sbuf, p, 42);
}
void to_dbuf(const char *p)
{
strcpy(dbuf, p); // unchanged
}
This variant would be also compatible with C++. Same results with CLang(++).
Christian
PS: There is an outdated "#define __restrict" section in <sys/cdefs.h>
which checks for GCC version 2.95 only.
--
Problem reports: http://cygwin.com/problems.html
FAQ: http://cygwin.com/faq/
Documentation: http://cygwin.com/docs.html
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2018-03-06 12:05 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-03-06 13:39 _FORTIFY_SOURCE has no effect for C++ due to usage of #define Christian Franke
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).