diff --git a/configure.ac b/configure.ac index 6e9496d..abf891e 100644 --- a/configure.ac +++ b/configure.ac @@ -96,7 +96,7 @@ AC_CACHE_CHECK( [[ static int rc = 1; static void init(int argc) { if (argc == 1) rc = 0; } -void (*init_func)(int argc) __attribute__((__section__(".init_array"))) = init; +__attribute__ ((used)) void (*init_func)(int argc) __attribute__((__section__(".init_array"))) = init; int main() { return rc; } ]] )], @@ -183,4 +183,13 @@ AC_CONFIG_FILES([ test/Makefile ]) AC_CONFIG_HEADERS([config.h]) + +# 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/local-link.h b/src/local-link.h index 0d4351a..5f98656 100644 --- a/src/local-link.h +++ b/src/local-link.h @@ -32,16 +32,22 @@ __attribute__((__used__,__section__(".gnu.warning." #symbol))) = msg; #ifdef __ELF__ -#define libbsd_symver_default(alias, symbol, version) \ - __asm__(".symver " #symbol "," #alias "@@" #version) - -#define libbsd_symver_variant(alias, symbol, version) \ - __asm__(".symver " #symbol "," #alias "@" #version) +# if HAVE_ATTRIBUTE_SYMVER +# define libbsd_symver_default(alias, symbol, version) \ + __attribute__ ((symver (#alias "@@" #version))) +# define libbsd_symver_variant(alias, symbol, version) \ + __attribute__ ((symver (#alias "@" #version))) +# else +# define libbsd_symver_default(alias, symbol, version) \ + __asm__(".symver " #symbol "," #alias "@@" #version); +# define libbsd_symver_variant(alias, symbol, version) \ + __asm__(".symver " #symbol "," #alias "@" #version); +# endif #else -#define libbsd_symver_default(alias, symbol, version) \ +# define libbsd_symver_default(alias, symbol, version) \ extern __typeof(symbol) alias __attribute__((__alias__(#symbol))) -#define libbsd_symver_variant(alias, symbol, version) +# define libbsd_symver_variant(alias, symbol, version) #endif #endif diff --git a/src/setproctitle.c b/src/setproctitle.c index ff32aa3..f8ede26 100644 --- a/src/setproctitle.c +++ b/src/setproctitle.c @@ -222,6 +222,7 @@ setproctitle_init(int argc, char *argv[], char *envp[]) #define SPT_MAXTITLE 255 #endif +libbsd_symver_default(setproctitle, setproctitle_impl, LIBBSD_0.5) void setproctitle_impl(const char *fmt, ...) { @@ -281,7 +282,6 @@ setproctitle_impl(const char *fmt, ...) *++nul = '\0'; } } -libbsd_symver_default(setproctitle, setproctitle_impl, LIBBSD_0.5); /* The original function introduced in 0.2 was a stub, it only got implemented * in 0.5, make the implementation available in the old version as an alias @@ -289,11 +289,12 @@ libbsd_symver_default(setproctitle, setproctitle_impl, LIBBSD_0.5); * new version, so that new code depends on the implemented version. */ #ifdef HAVE_TYPEOF extern __typeof__(setproctitle_impl) +libbsd_symver_variant(setproctitle, setproctitle_stub, LIBBSD_0.2) setproctitle_stub __attribute__((__alias__("setproctitle_impl"))); #else void +libbsd_symver_variant(setproctitle, setproctitle_stub, LIBBSD_0.2) setproctitle_stub(const char *fmt, ...) __attribute__((__alias__("setproctitle_impl"))); #endif -libbsd_symver_variant(setproctitle, setproctitle_stub, LIBBSD_0.2); diff --git a/src/unvis.c b/src/unvis.c index 166421a..218ec47 100644 --- a/src/unvis.c +++ b/src/unvis.c @@ -563,16 +563,16 @@ strunvis(char *dst, const char *src) * OpenBSD, 2001: strnunvis(char *dst, const char *src, size_t dlen); * NetBSD: 2012, strnunvis(char *dst, size_t dlen, const char *src); */ +libbsd_symver_default(strnunvis, strnunvis_openbsd, LIBBSD_0.2) ssize_t strnunvis_openbsd(char *dst, const char *src, size_t dlen) { return strnunvisx(dst, dlen, src, 0); } -libbsd_symver_default(strnunvis, strnunvis_openbsd, LIBBSD_0.2); +libbsd_symver_variant(strnunvis, strnunvis_netbsd, LIBBSD_0.9.1) int strnunvis_netbsd(char *dst, size_t dlen, const char *src) { return strnunvisx(dst, dlen, src, 0); } -libbsd_symver_variant(strnunvis, strnunvis_netbsd, LIBBSD_0.9.1); diff --git a/src/vis.c b/src/vis.c index c8e5ae8..254f209 100644 --- a/src/vis.c +++ b/src/vis.c @@ -732,19 +732,19 @@ strvis(char *mbdst, const char *mbsrc, int flags) * OpenBSD, 2001: strnvis(char *dst, const char *src, size_t dlen, int flag); * NetBSD: 2012, strnvis(char *dst, size_t dlen, const char *src, int flag); */ +libbsd_symver_default(strnvis, strnvis_openbsd, LIBBSD_0.2) int strnvis_openbsd(char *mbdst, const char *mbsrc, size_t dlen, int flags) { return istrsenvisxl(mbdst, &dlen, mbsrc, flags, "", NULL); } -libbsd_symver_default(strnvis, strnvis_openbsd, LIBBSD_0.2); +libbsd_symver_variant(strnvis, strnvis_netbsd, LIBBSD_0.9.1) int strnvis_netbsd(char *mbdst, size_t dlen, const char *mbsrc, int flags) { return istrsenvisxl(mbdst, &dlen, mbsrc, flags, "", NULL); } -libbsd_symver_variant(strnvis, strnvis_netbsd, LIBBSD_0.9.1); int stravis(char **mbdstp, const char *mbsrc, int flags) diff --git a/test/nlist.c b/test/nlist.c index 82e24e9..0bfdb46 100644 --- a/test/nlist.c +++ b/test/nlist.c @@ -38,14 +38,15 @@ extern int data_pub_init; extern int data_pub_uninit[2048]; extern int *data_pub_ptr; -int *data_pub_ptr = &data_prv_init; -int data_pub_init = 10; -int data_pub_uninit[2048]; +__attribute__ ((used)) int *data_pub_ptr = &data_prv_init; +__attribute__ ((used)) int data_pub_init = 10; +__attribute__ ((used)) int data_pub_uninit[2048]; extern int func_pub(void); int +__attribute__ ((used)) func_pub(void) { return 42;