diff --git a/configure.ac b/configure.ac index 5de5c76..d3e31c3 100644 --- a/configure.ac +++ b/configure.ac @@ -130,4 +130,12 @@ AC_ARG_ENABLE(tests, [enable_tests=yes]) AM_CONDITIONAL(BUILD_TESTS, [test $enable_tests != no]) +# GCC tries to be "helpful" and only issue a warning for unrecognized +# attributes. So we compile the test with Werror, so that if the +# attribute is not recognized the compilation fails +AC_LANG(C) +AC_LANG_WERROR +AC_COMPILE_IFELSE([AC_LANG_SOURCE([[__attribute__ ((symver ("foo@foo_1"))) void frob (void) { }]])], + [AC_DEFINE([HAVE_ATTRIBUTE_SYMVER], [1], [Checking for symver attribute])], []) + AC_OUTPUT diff --git a/src/lib/connectx.c b/src/lib/connectx.c index 5f4552b..2a21e3a 100644 --- a/src/lib/connectx.c +++ b/src/lib/connectx.c @@ -26,6 +26,18 @@ #include #include #include +#include "config.h" + +#define __SYMPFX(pfx, sym) #pfx sym +#define _SYMPFX(pfx, sym) __SYMPFX(pfx, sym) +#define SYMPFX(sym) _SYMPFX(__USER_LABEL_PREFIX__, #sym) + +#if HAVE_ATTRIBUTE_SYMVER +#define SYMVER(name, name2) __attribute__ ((symver (SYMPFX(name2)))) +#else +#define SYMVER(name, name2) __asm__(".symver " SYMPFX(name) "," SYMPFX(name2)); +#endif + /* Support the sctp_connectx() interface. * @@ -64,6 +76,7 @@ static int __connectx_addrsize(const struct sockaddr *addrs, } +SYMVER(__sctp_connectx, sctp_connectx@) int __sctp_connectx(int fd, struct sockaddr *addrs, int addrcnt) { int addrs_size = __connectx_addrsize(addrs, addrcnt); @@ -75,6 +88,7 @@ int __sctp_connectx(int fd, struct sockaddr *addrs, int addrcnt) addrs_size); } +SYMVER(sctp_connectx_orig, sctp_connectx@VERS_1) extern int sctp_connectx_orig (int) __attribute ((alias ("__sctp_connectx"))); @@ -114,6 +128,7 @@ static int __connectx(int fd, struct sockaddr *addrs, socklen_t addrs_size, addrs, addrs_size); } +SYMVER(sctp_connectx2, sctp_connectx@VERS_2) int sctp_connectx2(int fd, struct sockaddr *addrs, int addrcnt, sctp_assoc_t *id) { @@ -125,6 +140,7 @@ int sctp_connectx2(int fd, struct sockaddr *addrs, int addrcnt, return __connectx(fd, addrs, addrs_size, id); } +SYMVER(sctp_connectx3, sctp_connectx@@VERS_3) int sctp_connectx3(int fd, struct sockaddr *addrs, int addrcnt, sctp_assoc_t *id) { @@ -179,12 +195,3 @@ int sctp_connectx3(int fd, struct sockaddr *addrs, int addrcnt, return __connectx(fd, addrs, addrs_size, id); } -#define __SYMPFX(pfx, sym) #pfx sym -#define _SYMPFX(pfx, sym) __SYMPFX(pfx, sym) -#define SYMPFX(sym) _SYMPFX(__USER_LABEL_PREFIX__, #sym) -#define SYMVER(name, name2) __asm__(".symver " SYMPFX(name) "," SYMPFX(name2)) - -SYMVER(__sctp_connectx, sctp_connectx@); -SYMVER(sctp_connectx_orig, sctp_connectx@VERS_1); -SYMVER(sctp_connectx2, sctp_connectx@VERS_2); -SYMVER(sctp_connectx3, sctp_connectx@@VERS_3);