]> git.ipfire.org Git - thirdparty/iproute2.git/commitdiff
support static-only systems
authorMike Frysinger <vapier@gentoo.org>
Fri, 6 Nov 2009 11:09:22 +0000 (06:09 -0500)
committerStephen Hemminger <stephen.hemminger@vyatta.com>
Tue, 10 Nov 2009 18:44:20 +0000 (10:44 -0800)
The iptables code supports a "no shared libs" mode where it can be used
without requiring dlfcn related functionality.  This adds similar support
to iproute2 so that it can easily be used on systems like nommu Linux (but
obviously with a few limitations -- no dynamic plugins).

Rather than modify every location that uses dlfcn.h, I hooked the dlfcn.h
header with stub functions when shared library support is disabled.  Then
symbol lookup is done via a local static lookup table (which is generated
automatically at build time) so that internal symbols can be found.

Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Makefile
genl/Makefile
genl/static-syms.c [new file with mode: 0644]
include/dlfcn.h [new file with mode: 0644]
ip/Makefile
ip/static-syms.c [new file with mode: 0644]
tc/Makefile
tc/m_ipt.c
tc/static-syms.c [new file with mode: 0644]

index 74e9d6279426f803ab88fc80ec4ef6639e7b0529..77a85c6e6071c81bdf1f7bd9903ff86817d5b020 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -10,7 +10,12 @@ ARPDDIR=/var/lib/arpd
 # Path to db_185.h include
 DBM_INCLUDE:=$(ROOTDIR)/usr/include
 
+SHARED_LIBS = y
+
 DEFINES= -DRESOLVE_HOSTNAMES -DLIBDIR=\"$(LIBDIR)\"
+ifneq ($(SHARED_LIBS),y)
+DEFINES+= -DNO_SHARED_LIBS
+endif
 
 #options if you have a bind>=4.9.4 libresolv (or, maybe, glibc)
 LDLIBS=-lresolv
index 6435875549a6ed8ef17eaa93e8d5b942ef5e56f2..44bb83cd05865a5b5ead66b7cba16a7134a68ea8 100644 (file)
@@ -1,6 +1,7 @@
 GENLOBJ=genl.o
 
 include ../Config
+SHARED_LIBS ?= y
 
 GENLMODULES :=
 GENLMODULES += ctrl.o
@@ -9,8 +10,10 @@ GENLOBJ += $(GENLMODULES)
 
 GENLLIB :=
 
+ifeq ($(SHARED_LIBS),y)
 LDFLAGS += -Wl,-export-dynamic
 LDLIBS  += -lm -ldl
+endif
 
 all: genl
 
@@ -21,3 +24,15 @@ install: all
 
 clean:
        rm -f $(GENLOBJ) $(GENLLIB) genl
+
+ifneq ($(SHARED_LIBS),y)
+
+genl: static-syms.o
+static-syms.o: static-syms.h
+static-syms.h: $(wildcard *.c)
+       files="$^" ; \
+       for s in `grep -B 3 '\<dlsym' $$files | sed -n '/snprintf/{s:.*"\([^"]*\)".*:\1:;s:%s::;p}'` ; do \
+               sed -n '/'$$s'[^ ]* =/{s:.* \([^ ]*'$$s'[^ ]*\) .*:extern char \1[] __attribute__((weak)); if (!strcmp(sym, "\1")) return \1;:;p}' $$files ; \
+       done > $@
+
+endif
diff --git a/genl/static-syms.c b/genl/static-syms.c
new file mode 100644 (file)
index 0000000..1ed3a8a
--- /dev/null
@@ -0,0 +1,6 @@
+#include <string.h>
+void *_dlsym(const char *sym)
+{
+#include "static-syms.h"
+       return NULL;
+}
diff --git a/include/dlfcn.h b/include/dlfcn.h
new file mode 100644 (file)
index 0000000..b0be5a0
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Stub dlfcn implementation for systems that lack shared library support
+ * but obviously can still reference compiled-in symbols.
+ */
+
+#ifndef NO_SHARED_LIBS
+#include_next <dlfcn.h>
+#else
+
+#define RTLD_LAZY 0
+#define _FAKE_DLFCN_HDL (void *)0xbeefcafe
+
+static inline void *dlopen(const char *file, int flag)
+{
+       if (file == NULL)
+               return _FAKE_DLFCN_HDL;
+       else
+               return NULL;
+}
+
+extern void *_dlsym(const char *sym);
+static inline void *dlsym(void *handle, const char *sym)
+{
+       if (handle != _FAKE_DLFCN_HDL)
+               return NULL;
+       return _dlsym(sym);
+}
+
+static inline char *dlerror(void)
+{
+       return NULL;
+}
+
+static inline int dlclose(void *handle)
+{
+       return (handle == _FAKE_DLFCN_HDL) ? 0 : 1;
+}
+
+#endif
index 3c185cfbb4c84e1a6c6b0b7eef66e151035abc77..51914e85aa451c138ab891e5d46c680e12afc768 100644 (file)
@@ -23,6 +23,20 @@ install: all
 clean:
        rm -f $(ALLOBJ) $(TARGETS)
 
-LDLIBS += -ldl
+SHARED_LIBS ?= y
+ifeq ($(SHARED_LIBS),y)
 
+LDLIBS += -ldl
 LDFLAGS += -Wl,-export-dynamic
+
+else
+
+ip: static-syms.o
+static-syms.o: static-syms.h
+static-syms.h: $(wildcard *.c)
+       files="$^" ; \
+       for s in `grep -B 3 '\<dlsym' $$files | sed -n '/snprintf/{s:.*"\([^"]*\)".*:\1:;s:%s::;p}'` ; do \
+               sed -n '/'$$s'[^ ]* =/{s:.* \([^ ]*'$$s'[^ ]*\) .*:extern char \1[] __attribute__((weak)); if (!strcmp(sym, "\1")) return \1;:;p}' $$files ; \
+       done > $@
+
+endif
diff --git a/ip/static-syms.c b/ip/static-syms.c
new file mode 100644 (file)
index 0000000..1ed3a8a
--- /dev/null
@@ -0,0 +1,6 @@
+#include <string.h>
+void *_dlsym(const char *sym)
+{
+#include "static-syms.h"
+       return NULL;
+}
index 3ff253586343a604c7ef2aad180a609c3b3196ea..027055cf775ad157cd89c9e294b7965c111e5c7c 100644 (file)
@@ -3,6 +3,7 @@ TCOBJ= tc.o tc_qdisc.o tc_class.o tc_filter.o tc_util.o \
        m_ematch.o emp_ematch.yacc.o emp_ematch.lex.o
 
 include ../Config
+SHARED_LIBS ?= y
 
 TCMODULES :=
 TCMODULES += q_fifo.o
@@ -57,7 +58,12 @@ else
 endif
 
 TCOBJ += $(TCMODULES)
-LDLIBS += -L. -ltc -lm -ldl
+LDLIBS += -L. -ltc -lm
+
+ifeq ($(SHARED_LIBS),y)
+LDLIBS += -ldl
+LDFLAGS += -Wl,-export-dynamic
+endif
 
 TCLIB := tc_core.o
 TCLIB += tc_red.o
@@ -72,9 +78,6 @@ ifeq ($(TC_CONFIG_ATM),y)
   TCSO += q_atm.so
 endif
 
-
-LDFLAGS += -Wl,-export-dynamic
-
 YACC := bison
 LEX := flex
 
@@ -108,3 +111,15 @@ q_atm.so: q_atm.c
 
 %.lex.c: %.l
        $(LEX) $(LEXFLAGS) -o$@ $<
+
+ifneq ($(SHARED_LIBS),y)
+
+tc: static-syms.o
+static-syms.o: static-syms.h
+static-syms.h: $(wildcard *.c)
+       files="$^" ; \
+       for s in `grep -B 3 '\<dlsym' $$files | sed -n '/snprintf/{s:.*"\([^"]*\)".*:\1:;s:%s::;p}'` ; do \
+               sed -n '/'$$s'[^ ]* =/{s:.* \([^ ]*'$$s'[^ ]*\) .*:extern char \1[] __attribute__((weak)); if (!strcmp(sym, "\1")) return \1;:;p}' $$files ; \
+       done > $@
+
+endif
index d17d32459a8b62154eced3ee53914e5905a822de..99d9965a6744b57626be13edd0931d73430f2cf0 100644 (file)
@@ -226,6 +226,10 @@ get_target_name(const char *name)
        struct iptables_target *m;
        char path[strlen(lib_dir) + sizeof ("/libipt_.so") + strlen(name)];
 
+#ifdef NO_SHARED_LIBS
+       return NULL;
+#endif
+
        new_name = malloc(strlen(name) + 1);
        lname = malloc(strlen(name) + 1);
        if (new_name)
diff --git a/tc/static-syms.c b/tc/static-syms.c
new file mode 100644 (file)
index 0000000..1ed3a8a
--- /dev/null
@@ -0,0 +1,6 @@
+#include <string.h>
+void *_dlsym(const char *sym)
+{
+#include "static-syms.h"
+       return NULL;
+}