From: Vincent Bernat Date: Wed, 23 Mar 2016 07:33:11 +0000 (+0100) Subject: lib: don't rely on constructors X-Git-Tag: 0.9.3~38 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d954509eb76a18b2a96ec826cba90b9a093d05f9;p=thirdparty%2Flldpd.git lib: don't rely on constructors Constructors do not work when compiled as a static libraries. Moreover, some dynamic linkers have still support for constructors optional (for example, uclibc). Since this can be tested only at runtime, this is not possible to detect that during configure when crosscompiling. Emulate this with our own glue code. --- diff --git a/NEWS b/NEWS index 85ad65b7..3b9570d7 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,7 @@ +lldpd (0.9.3) + * Change: + + Do not rely on support of constructors for liblldpctl. + lldpd (0.9.2) * Change: + Ability to add/remove/replace custom TLV from lldpcli. diff --git a/configure.ac b/configure.ac index f8be3b4f..b7ff5d79 100644 --- a/configure.ac +++ b/configure.ac @@ -89,7 +89,6 @@ AX_CFLAGS_GCC_OPTION([-Wno-missing-field-initializers], [LLDP_CFLAGS]) AX_CFLAGS_GCC_OPTION([-Wno-sign-compare], [LLDP_CFLAGS]) dnl Should be fixed later AX_LDFLAGS_OPTION([-Wl,-z,relro], [LLDP_LDFLAGS]) AX_LDFLAGS_OPTION([-Wl,-z,now], [LLDP_LDFLAGS]) -lldp_CHECK_CTORS # Hardening AC_ARG_ENABLE([hardening], diff --git a/m4/ctors.m4 b/m4/ctors.m4 deleted file mode 100644 index f8231693..00000000 --- a/m4/ctors.m4 +++ /dev/null @@ -1,48 +0,0 @@ -# -# lldp_CHECK_CTORS -# -AC_DEFUN([lldp_CHECK_CTORS], [ - - # Compiler support - AX_GCC_FUNC_ATTRIBUTE(constructor) - if test x"$ac_cv_have_func_attribute_constructor" = x"no"; then - AC_MSG_FAILURE([*** GCC constructor function attribute mandatory]) - fi - AX_GCC_FUNC_ATTRIBUTE(constructor_priority) - AX_GCC_FUNC_ATTRIBUTE(destructor) - if test x"$ac_cv_have_func_attribute_destructor" = x"no"; then - AC_MSG_FAILURE([*** GCC destructor function attribute mandatory]) - fi - - # Runtime support (libc) - AC_CACHE_CHECK([constructor/destructor runtime support], lldp_cv_ctor_runtime, [ - dnl We need to observe some sideeffect. When - dnl constructor/destructors are running, we may not have a working - dnl standard output. - true > conftest.1 - true > conftest.2 - AC_RUN_IFELSE([AC_LANG_PROGRAM([ - @%:@include - void ctor1(void) __attribute__((constructor)); - void ctor1() { unlink("conftest.1"); } - void ctor2(void) __attribute__((destructor)); - void ctor2() { unlink("conftest.2"); }], []) - ], [ - if test -r conftest.1 -o -r conftest.2; then - lldp_cv_ctor_runtime=no - else - lldp_cv_ctor_runtime=yes - fi - ], [ - dnl Unable to build the check - lldp_cv_ctor_runtime=no - ], [ - dnl Cross compilation - lldp_cv_ctor_runtime=yes - ]) - ]) - - if test x"$lldp_cv_ctor_runtime" = x"no"; then - AC_MSG_FAILURE([*** Constructor/destructor runtime support is missing]) - fi -]) diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index b419b551..7418513d 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -8,13 +8,56 @@ include_HEADERS = lldpctl.h noinst_LTLIBRARIES = libfixedpoint.la libfixedpoint_la_SOURCES = fixedpoint.h fixedpoint.c -liblldpctl_la_SOURCES = \ - lldpctl.h atom.h errors.c connection.c atom.c helpers.c helpers.h \ +ATOM_FILES = \ atoms/config.c atoms/dot1.c atoms/dot3.c \ atoms/interface.c atoms/med.c atoms/mgmt.c atoms/port.c \ atoms/custom.c atoms/chassis.c +NON_ATOM_FILES = \ + errors.c connection.c atom.c helpers.c +liblldpctl_la_SOURCES = \ + lldpctl.h atom.h helpers.h \ + $(NON_ATOM_FILES) \ + $(ATOM_FILES) +nodist_liblldpctl_la_SOURCES = atom-glue.h atom-glue.c liblldpctl_la_LIBADD = $(top_builddir)/src/libcommon-daemon-lib.la libfixedpoint.la +$(NON_ATOM_FILES):: atom-glue.h +atom-glue.h: $(ATOM_FILES) Makefile + $(AM_V_GEN)(cat $^ | \ + $(SED) -n 's+^ATOM_BUILDER_REGISTER(\([^,]*\), *\([0-9]*\)).*+\2 \1+p' | \ + $(AWK) '{ atoms[$$2] = 1 } \ + END { for (atom in atoms) { print "void init_atom_builder_"atom"(void);" } }' && \ + cat $^ | \ + $(SED) -n 's+^ATOM_MAP_REGISTER(\([^,]*\), *\([0-9]*\)).*+\2 \1+p' | \ + $(AWK) '{ atoms[$$2] = 1 } \ + END { for (atom in atoms) { print "void init_atom_map_"atom"(void);" } }' ) \ + > $@.tmp + @[ -s $@.tmp ] + @mv $@.tmp $@ +atom-glue.c: $(ATOM_FILES) Makefile atom-glue.h + $(AM_V_GEN)(cat $^ | \ + $(SED) -n 's+^ATOM_BUILDER_REGISTER(\([^,]*\), *\([0-9]*\)).*+\2 \1+p' | \ + sort -n | \ + $(AWK) '{ atoms[$$2] = 1 } \ + END { print "#include \"lldpctl.h\""; \ + print "#include \"atom.h\""; \ + print "void init_atom_builder() {"; \ + print " static int init = 0; if (init) return; init++;"; \ + for (atom in atoms) { print " init_atom_builder_"atom"();" } \ + print "}"; }' && \ + cat $^ | \ + $(SED) -n 's+^ATOM_MAP_REGISTER(\([^,]*\), *\([0-9]*\)).*+\2 \1+p' | \ + sort -n | \ + $(AWK) '{ atoms[$$2] = 1 } \ + END { print "void init_atom_map() {"; \ + print " static int init = 0; if (init) return; init++;"; \ + for (atom in atoms) { print " init_atom_map_"atom"();" } \ + print "}"; }' ) \ + > $@.tmp + @[ -s $@.tmp ] + @mv $@.tmp $@ +CLEANFILES = atom-glue.h atom-glue.c + # -version-info format is `current`:`revision`:`age`. For more details, see: # https://www.sourceware.org/autobook/autobook/autobook_61.html#Library-Versioning # @@ -35,6 +78,6 @@ pkgconfig_DATA = lldpctl.pc TEMPLATES = lldpctl.pc EXTRA_DIST = lldpctl.pc.in lldpctl.map -CLEANFILES = $(TEMPLATES) +CLEANFILES += $(TEMPLATES) lldpctl.pc: lldpctl.pc.in include $(top_srcdir)/edit.am diff --git a/src/lib/atom.c b/src/lib/atom.c index 70858553..718a4ad8 100644 --- a/src/lib/atom.c +++ b/src/lib/atom.c @@ -514,6 +514,7 @@ static struct atom_map atom_map_list = { lldpctl_map_t* lldpctl_key_get_map(lldpctl_key_t key) { + init_atom_map(); struct atom_map *map; for (map = atom_map_list.next; map ; map = map->next) { if (map->key == key) @@ -549,6 +550,7 @@ void atom_builder_register(struct atom_builder *builder) lldpctl_atom_t* _lldpctl_new_atom(lldpctl_conn_t *conn, atom_t type, ...) { + init_atom_builder(); struct atom_builder *builder; struct lldpctl_atom_t *atom; va_list(ap); @@ -655,4 +657,3 @@ _lldpctl_dump_in_atom(lldpctl_atom_t *atom, *(buffer + i*3 - 1) = 0; return buffer; } - diff --git a/src/lib/atom.h b/src/lib/atom.h index cf8b1679..f4503a10 100644 --- a/src/lib/atom.h +++ b/src/lib/atom.h @@ -20,6 +20,7 @@ #include "../compat/compat.h" #include "../marshal.h" #include "../ctl.h" +#include "atom-glue.h" /* connection.c */ struct lldpctl_conn_t { @@ -291,13 +292,9 @@ struct atom_map { }; void atom_map_register(struct atom_map *map); +void init_atom_map(void); -#ifdef HAVE_FUNC_ATTRIBUTE_CONSTRUCTOR_PRIORITY -# define __constructor__(PRIO) __attribute__ ((constructor (PRIO))) -#else -# define __constructor__(PRIO) __attribute__ ((constructor)) -#endif -#define ATOM_MAP_REGISTER(NAME, PRIO) __constructor__(100 + PRIO) void init_ ## NAME() { atom_map_register(& NAME ); } +#define ATOM_MAP_REGISTER(NAME, PRIO) void init_atom_map_ ## NAME() { atom_map_register(& NAME ); } struct atom_builder { atom_t type; /* Atom type */ @@ -323,6 +320,6 @@ struct atom_builder { }; void atom_builder_register(struct atom_builder *builder); +void init_atom_builder(void); -#define ATOM_BUILDER_REGISTER(NAME, PRIO) __constructor__(200 + PRIO) void init_ ## NAME() { atom_builder_register(& NAME ); } - +#define ATOM_BUILDER_REGISTER(NAME, PRIO) void init_atom_builder_ ## NAME() { atom_builder_register(& NAME ); } diff --git a/src/lib/atoms/config.c b/src/lib/atoms/config.c index 5d362349..f2b138a5 100644 --- a/src/lib/atoms/config.c +++ b/src/lib/atoms/config.c @@ -299,4 +299,3 @@ static struct atom_builder config = .set_int = _lldpctl_atom_set_int_config }; ATOM_BUILDER_REGISTER(config, 1); -