]> git.ipfire.org Git - thirdparty/lldpd.git/commitdiff
lib: don't rely on constructors
authorVincent Bernat <vincent@bernat.im>
Wed, 23 Mar 2016 07:33:11 +0000 (08:33 +0100)
committerVincent Bernat <vincent@bernat.im>
Wed, 23 Mar 2016 19:47:12 +0000 (20:47 +0100)
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.

NEWS
configure.ac
m4/ctors.m4 [deleted file]
src/lib/Makefile.am
src/lib/atom.c
src/lib/atom.h
src/lib/atoms/config.c

diff --git a/NEWS b/NEWS
index 85ad65b7ec44ea3edb45b124a8b2073873ace6a7..3b9570d712cabe29a717f373c98e411b46e550d4 100644 (file)
--- 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.
index f8be3b4ff5334a93cc5050a351429a6d170520ec..b7ff5d79e78dc72390badf0687aa50bb3e569404 100644 (file)
@@ -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 (file)
index f823169..0000000
+++ /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 <unistd.h>
-      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
-])
index b419b551ee96334a50c460ade8ddafc311a61cdc..7418513dcddab935690d86cea556da8e78903d1b 100644 (file)
@@ -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
index 708585537921cfad35ca525f33d95cdc90d01c89..718a4ad8b07720e56b71b2440b9398c2a3a365f8 100644 (file)
@@ -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;
 }
-
index cf8b1679538bef7f97e87ce358fa43aa4f279d29..f4503a1071cc065c3ff3ed3831424d398718501d 100644 (file)
@@ -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 ); }
index 5d362349fabda592bf2edc9e1c7c0462c83f6455..f2b138a5bf8d60487c3fae5f99b46036cc78318a 100644 (file)
@@ -299,4 +299,3 @@ static struct atom_builder config =
          .set_int = _lldpctl_atom_set_int_config };
 
 ATOM_BUILDER_REGISTER(config, 1);
-