diff options
author | Mike Frysinger <vapier@gentoo.org> | 2009-11-06 06:09:22 -0500 |
---|---|---|
committer | Stephen Hemminger <stephen.hemminger@vyatta.com> | 2009-11-10 10:44:20 -0800 |
commit | f2e27cfb016e2465cd3f07e0b556058060702578 (patch) | |
tree | c8f111902c95f4d8624408e36aa35acdc3176cc9 | |
parent | a7a9ddbb675b7fbd184c3ab40817265b0b207a23 (diff) |
support static-only systems
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>
-rw-r--r-- | Makefile | 5 | ||||
-rw-r--r-- | genl/Makefile | 15 | ||||
-rw-r--r-- | genl/static-syms.c | 6 | ||||
-rw-r--r-- | include/dlfcn.h | 39 | ||||
-rw-r--r-- | ip/Makefile | 16 | ||||
-rw-r--r-- | ip/static-syms.c | 6 | ||||
-rw-r--r-- | tc/Makefile | 23 | ||||
-rw-r--r-- | tc/m_ipt.c | 4 | ||||
-rw-r--r-- | tc/static-syms.c | 6 |
9 files changed, 115 insertions, 5 deletions
@@ -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 diff --git a/genl/Makefile b/genl/Makefile index 64358755..44bb83cd 100644 --- a/genl/Makefile +++ b/genl/Makefile @@ -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 index 00000000..1ed3a8a9 --- /dev/null +++ b/genl/static-syms.c @@ -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 index 00000000..b0be5a0f --- /dev/null +++ b/include/dlfcn.h @@ -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 diff --git a/ip/Makefile b/ip/Makefile index 3c185cfb..51914e85 100644 --- a/ip/Makefile +++ b/ip/Makefile @@ -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 index 00000000..1ed3a8a9 --- /dev/null +++ b/ip/static-syms.c @@ -0,0 +1,6 @@ +#include <string.h> +void *_dlsym(const char *sym) +{ +#include "static-syms.h" + return NULL; +} diff --git a/tc/Makefile b/tc/Makefile index 3ff25358..027055cf 100644 --- a/tc/Makefile +++ b/tc/Makefile @@ -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 @@ -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 index 00000000..1ed3a8a9 --- /dev/null +++ b/tc/static-syms.c @@ -0,0 +1,6 @@ +#include <string.h> +void *_dlsym(const char *sym) +{ +#include "static-syms.h" + return NULL; +} |