Commit f2e27cfb authored by Mike Frysinger's avatar Mike Frysinger Committed by Stephen Hemminger

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: default avatarMike Frysinger <vapier@gentoo.org>
parent a7a9ddbb
......@@ -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
......
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
#include <string.h>
void *_dlsym(const char *sym)
{
#include "static-syms.h"
return NULL;
}
/*
* 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
......@@ -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
#include <string.h>
void *_dlsym(const char *sym)
{
#include "static-syms.h"
return NULL;
}
......@@ -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)
......
#include <string.h>
void *_dlsym(const char *sym)
{
#include "static-syms.h"
return NULL;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment