When compiling the following program ``` #undef __GNUC__ #define __GNUC__ 4 #undef __GNUC_MINOR__ #define __GNUC_MINOR__ 9 #include <string.h> char a[64]; int main () { memset (a, 64, 0); return 0; } ``` with a decent gcc version (8.3) and glibc version (2.28), I get a link error ``` gcc a.c -D_FORTIFY_SOURCE=2 -O2 In file included from /usr/include/string.h:494, from a.c:6: In function ‘memset’, inlined from ‘main’ at a.c:10:3: /usr/include/x86_64-linux-gnu/bits/string_fortified.h:67:7: warning: call to ‘__warn_memset_zero_len’ declared with attribute warning: memset used with constant zero length parameter; this could be due to transposed parameters __warn_memset_zero_len (); ^~~~~~~~~~~~~~~~~~~~~~~~~ /usr/bin/ld: /tmp/cc7RDLx1.o: in function `main': a.c:(.text.startup+0x5): undefined reference to `__warn_memset_zero_len' collect2: error: ld returned 1 exit status ``` No link error if I don't force the __GNUC__ and __GNUC_MINOR__. I've checked the source of glibc-2.30, and the problem seems related to ``` #if !__GNUC_PREREQ (5,0) __warndecl (__warn_memset_zero_len, "memset used with constant zero length parameter; this could be due to transposed parameters"); #endif ``` while `__warn_memset_zero_len` is not defined elsewhere. In addition to binding glibc to some gcc version, it is also a problem for non-gcc compilers, like clang, which set GNU C version to 3.2 by default (see for instance https://reviews.llvm.org/D71082#1822925)
debug/warning-nop.c should provide those symbols in libc.a (and libc_nonshared.a ?), but for some reason it doesn't work anymore.
When glibc is compiled with GCC >= 5 the __warndecl in <bits/string3.h> is compiled out, so debug/warning-nop.c gets empty.
Indeed, that's it. So perhaps we need: /* Pretend compilation with GCC 4.9 if compiled by GCC >= 5, so that __warndecl are not skipped. */ #if __GNUC_PREREQ (5, 0) #undef __GNUC__ #define __GNUC__ 4 #undef __GNUC_MINOR__ #define __GNUC_MINOR__ 9 #endif (or instead of __GNUC_PREREQ the longer check and do this before including the first header in warning-nop.c).
This compilation issue has been fixed[1] upstream; clang and other non-gcc compilers should now be able to build the reproducer correctly without any linker errors. There is the outstanding issue where static libraries and objects built with older compilers against the older glibc may refuse to link correctly with current glibc. The __warn_memset_zero_len symbol has been missing for a while now and nobody has complained specifically about that yet, so it appears that this issue is rare and if not, being worked around in other ways. If one needs this to be fixed in glibc by providing __warn_memset_zero_len and provide the linker warning, please file a new bug report to discuss it. [1] https://sourceware.org/pipermail/glibc-cvs/2020q4/070949.html
Fixed by: commit dc274b141666766b8ef70992d887e3c0c5e41bed Author: Siddhesh Poyarekar <siddhesh@sourceware.org> Date: Tue Nov 3 15:09:28 2020 +0530 Remove __warn_memset_zero_len [BZ #25399] Non-gcc compilers (clang and possibly other compilers that do not masquerade as gcc 5.0 or later) are unable to use __warn_memset_zero_len since the symbol is no longer available on glibc built with gcc 5.0 or later. While it was likely an oversight that caused this omission, the fact that it wasn't noticed until recently (when clang closed the gap on _FORTIFY_SUPPORT) that the symbol was missing. Given that both gcc and clang are capable of doing this check in the compiler, drop all remaining signs of __warn_memset_zero_len from glibc so that no more objects are built with this symbol in future. We should consider backports.
I am exited to all time this game follow https://freevbucksblog.com and see free vbucks codes online game all time.