summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGary V. Vaughan <gary@gnu.org>2013-09-21 23:11:09 +0700
committerGary V. Vaughan <gary@gnu.org>2013-09-21 23:11:09 +0700
commit64d44150bc5c9af45051371550f9917027e0fa41 (patch)
treeb3d1f15311909b2ff0ac89341346b2297e3299db
parent7781a595d8236fe0cc6bd2f2fdd2d67c5707eb50 (diff)
downloadm4-64d44150bc5c9af45051371550f9917027e0fa41.tar.gz
modules: huge simplification of module loading without libltdl.
Libltdl is huge and slow, and carrying the weight of support for decades old systems. We can do much better using POSIX dlopen and dlsym directly, simplifying and speeding up as we do so. * configure.ac (LT_CONFIG_LTDL_DIR, LTDL_INIT): Remove. (M4_DEFAULT_PRELOAD): Set to ""; we lost preload support along with removing libltdl. * Makefile.am: Don't include ltdl/Makefile.inc. (AM_CPPFLAGS): Manually add current directory to include search paths. * m4/m4private.h (includes): Remove ltdl.h. (INIT_SYMBOL, m4__module_init): Remove. (struct m4_module): Change handle type from lt_dlhandle to void *. * m4/m4module.h (M4INIT_HANDLER): Remove. * m4/module.c (includes): Add dlfcn.h. (m4__module_interface, iface_id, m4__module_init, module_dlerror): Remove. (m4__module_open): Drastically simplified without all the libltdl setup and interface id twiddling. Just call dlopen to get a native handle, and the dlsym to get the init function. (m4_module_import): Similarly wrt dlsym. * m4/path.c (FILE_SUFFIXES): Replace .la and LT_MODULE_EXT with hardcoded ".so". (m4_load_filename): Likewise. * modules/gnu.c: Remove libltdl preprocessor symbol renaming, and use "include_<modulename>" as the single entry point function. * modules/import.c, modules/m4.c, modules/modtest.c, modules/mpeval.c, modules/shadow.c, modules/stdlib.c, modules/time.c, modules/traditional.c: Likewise. * main.c (main): Remove calls to m4__module_init and LTDL_SET_PRELOADED_SYMBOLS. * tests/m4.in: Make sure we always have the modules/.libs and tests/.libs directories at the front of M4PATH so that the tests will find the modules they need to include. Signed-off-by: Gary V. Vaughan <gary@gnu.org>
-rw-r--r--Makefile.am5
-rw-r--r--configure.ac17
-rw-r--r--m4/m4module.h11
-rw-r--r--m4/m4private.h6
-rw-r--r--m4/module.c197
-rw-r--r--m4/path.c5
-rw-r--r--modules/gnu.c3
-rw-r--r--modules/import.c6
-rw-r--r--modules/m4.c12
-rw-r--r--modules/modtest.c6
-rw-r--r--modules/mpeval.c3
-rw-r--r--modules/shadow.c3
-rw-r--r--modules/stdlib.c3
-rw-r--r--modules/time.c3
-rw-r--r--modules/traditional.c3
-rw-r--r--src/main.c4
-rw-r--r--tests/m4.in8
17 files changed, 70 insertions, 225 deletions
diff --git a/Makefile.am b/Makefile.am
index e9807a0f..cd1d234f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -39,7 +39,7 @@ changelog_old = $(srcdir)/ChangeLog.old
# which effectively disables the auto-exporting of all other symbols.
# Revisit this if libtool on cygwin improves.
# See http://lists.gnu.org/archive/html/libtool-patches/2007-02/msg00062.html
-AM_CPPFLAGS =
+AM_CPPFLAGS = -I$(srcdir) -I.
AM_CFLAGS = $(WARN_CFLAGS) $(WERROR_CFLAGS)
AM_LDFLAGS = -export-dynamic -export-symbols-regex ".*"
EXTRA_DIST =
@@ -53,9 +53,6 @@ noinst_LTLIBRARIES=
lib_LTLIBRARIES =
EXTRA_LTLIBRARIES=
-# Include Libtool's rules.
-include ltdl/Makefile.inc
-
# Additional configuration. Version management comes from suggestions
# given in build-aux/git-version-gen.
AM_CPPFLAGS += -Ignu -I$(srcdir)/gnu \
diff --git a/configure.ac b/configure.ac
index 904f6247..6e6d722a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -47,7 +47,7 @@ dnl the m4_ namespace provided by m4sugar, so we prefer M4_ as our
dnl package-specific prefix.
m4_pattern_forbid([^M4_[A-Z]])
-AC_DEFUN([M4_DEFAULT_PRELOAD], [m4 traditional gnu])
+AC_DEFUN([M4_DEFAULT_PRELOAD], [])
M4_default_preload="M4_DEFAULT_PRELOAD"
@@ -82,22 +82,7 @@ M4_CHECK_DEBUGGING
## Libtool initialization. ##
## ----------------------- ##
LT_PREREQ([2.2])
-LT_CONFIG_LTDL_DIR([ltdl])
LT_INIT([shared dlopen win32-dll])
-LTDL_INIT([nonrecursive])
-
-# The lt_dlhandle_iterate symbol was added with libtool-2.2
-if test "x$with_included_ltdl" != "xyes"; then
- save_CFLAGS="$CFLAGS"
- save_LDFLAGS="$LDFLAGS"
- CFLAGS="$CFLAGS $LTDLINCL"
- LDFLAGS="$LDFLAGS $LIBLTDL"
- AC_CHECK_LIB([ltdl], [lt_dlhandle_iterate],
- [],
- [AC_MSG_ERROR([installed libltdl is too old])])
- LDFLAGS="$save_LDFLAGS"
- CFLAGS="$save_CFLAGS"
-fi
AC_ARG_ENABLE([gcc-warnings],
[AS_HELP_STRING([--enable-gcc-warnings],
diff --git a/m4/m4module.h b/m4/m4module.h
index 038a428b..694e77cf 100644
--- a/m4/m4module.h
+++ b/m4/m4module.h
@@ -111,17 +111,6 @@ struct m4_string_pair
static void CONC (builtin_, name) \
(m4 *context, m4_obstack *obs, size_t argc, m4_macro_args *argv)
-/* Declare a prototype, then begin the implementation of the function
- "<NAME>_LTX_m4_init_module", which will automatically be registered
- as the initialization function for module NAME. Note that NAME is
- intentionally used literally, rather than subjected to macro
- expansion. */
-#define M4INIT_HANDLER(name) \
- void name ## _LTX_m4_init_module \
- (m4 *, m4_module *, m4_obstack *); \
- void name ## _LTX_m4_init_module \
- (m4 *context, m4_module *module, m4_obstack *obs)
-
/* Declare a variable S of type "<S>_func" to be a pointer to the
function named S imported from the module M, or NULL if the import
fails. Note that M and S are intentionally used literally rather
diff --git a/m4/m4private.h b/m4/m4private.h
index 926df58f..452496da 100644
--- a/m4/m4private.h
+++ b/m4/m4private.h
@@ -22,7 +22,6 @@
#define M4PRIVATE_H 1
#include <m4/m4module.h>
-#include <ltdl.h>
#include "cloexec.h"
#include "quotearg.h"
@@ -175,20 +174,17 @@ extern void m4__builtin_print (m4_obstack *, const m4__builtin *, bool,
/* --- MODULE MANAGEMENT --- */
-#define INIT_SYMBOL "m4_init_module"
-
/* Representation of a loaded m4 module. */
struct m4_module
{
const char *name; /* Name of the module. */
- lt_dlhandle handle; /* All ltdl module information. */
+ void *handle; /* System module handle. */
m4__builtin *builtins; /* Sorted array of builtins. */
m4_macro *macros; /* Unsorted array of macros. */
size_t builtins_len; /* Number of builtins. */
m4_module *next;
};
-extern void m4__module_init (m4 *context);
extern m4_module * m4__module_open (m4 *context, const char *name,
m4_obstack *obs);
extern m4_module * m4__module_find (m4 *context, const char *name);
diff --git a/m4/module.c b/m4/module.c
index 39cd2d23..6f2a2a9e 100644
--- a/m4/module.c
+++ b/m4/module.c
@@ -20,6 +20,8 @@
#include <config.h>
+#include <dlfcn.h>
+
#include "m4private.h"
#include "xvasprintf.h"
@@ -71,10 +73,6 @@ static void install_builtin_table (m4*, m4_module *);
static void install_macro_table (m4*, m4_module *);
static int compare_builtin_CB (const void *a, const void *b);
-static int m4__module_interface (lt_dlhandle handle,
- const char *id_string);
-
-static lt_dlinterface_id iface_id = NULL;
const char *
m4_get_module_name (const m4_module *module)
@@ -99,7 +97,7 @@ m4_module_import (m4 *context, const char *module_name,
if (module)
{
- symbol_address = lt_dlsym (module->handle, symbol_name);
+ symbol_address = dlsym (module->handle, symbol_name);
if (!symbol_address)
m4_error (context, 0, 0, NULL,
@@ -230,21 +228,6 @@ m4_module_load (m4 *context, const char *name, m4_obstack *obs)
return module;
}
-
-static int
-m4__module_interface (lt_dlhandle handle, const char *id_string)
-{
- /* Shortcut. If we've already associated our wrapper with this
- handle, then we've validated the handle in the past, and don't
- need to waste any time on additional lt_dlsym calls. */
- m4_module *module = (m4_module *) lt_dlcaller_get_data (iface_id, handle);
- if (module)
- return 0;
-
- /* A valid m4 module must provide at least one of these symbols. */
- return !(lt_dlsym (handle, INIT_SYMBOL));
-}
-
/* Return successive loaded modules. */
m4_module *
@@ -263,56 +246,6 @@ m4__module_find (m4 *context, const char *name)
}
-/* Initialization. Currently the module search path in path.c is
- initialized from M4MODPATH. Only absolute path names are accepted to
- prevent the path search of the dlopen library from finding wrong
- files. */
-void
-m4__module_init (m4 *context)
-{
- int errors = 0;
-
- /* Do this only once! If we already have an iface_id, then the
- module system has already been initialized. */
- if (iface_id)
- {
- m4_error (context, 0, 0, NULL,
- _("multiple module loader initializations"));
- return;
- }
-
- errors = lt_dlinit ();
-
- /* Register with libltdl for a key to store client data against
- ltdl module handles. */
- if (!errors)
- {
- iface_id = lt_dlinterface_register ("m4 libm4", m4__module_interface);
-
- if (!iface_id)
- {
- const char *error_msg = _("libltdl client registration failed");
-
- lt_dlseterror (lt_dladderror (error_msg));
-
- /* No need to check error statuses from the calls above -- If
- either fails for some reason, a diagnostic will be set for
- lt_dlerror() anyway. */
- ++errors;
- }
- }
-
- /* Couldn't initialize the module system; diagnose and exit. */
- if (errors)
- m4_error (context, EXIT_FAILURE, 0, NULL,
- _("failed to initialize module loader: %s"), module_dlerror ());
-
-#ifdef DEBUG_MODULES
- fputs ("Module loader initialized.\n", stderr);
-#endif /* DEBUG_MODULES */
-}
-
-
/* Compare two builtins A and B for sorting, as in qsort. */
static int
compare_builtin_CB (const void *a, const void *b)
@@ -332,95 +265,53 @@ compare_builtin_CB (const void *a, const void *b)
m4_module *
m4__module_open (m4 *context, const char *name, m4_obstack *obs)
{
- static const char * suffixes[] = { "", ".la", LT_MODULE_EXT, NULL };
- char * filepath = NULL;
- lt_dlhandle handle = NULL;
- lt_dladvise advise = NULL;
+ static const char * suffixes[] = { "", ".so", NULL };
m4_module * module = NULL;
- m4_module_init_func * init_func = NULL;
assert (context);
- assert (iface_id); /* need to have called m4__module_init */
- /* Try opening as a preloaded module initially incase path searching
- has been disabled by POSIXLY_CORRECT... */
- if (!lt_dladvise_init (&advise) && !lt_dladvise_preload (&advise))
- handle = lt_dlopenadvise (name, advise);
- lt_dladvise_destroy (&advise);
+ char *filepath = m4_path_search (context, name, suffixes);
+ void *handle = NULL;
- /* ...otherwise resort to a path search anyway. */
- if (!handle)
+ if (filepath)
{
- filepath = m4_path_search (context, name, suffixes);
- if (filepath)
- {
- handle = lt_dlopenext (filepath);
- free (filepath);
- }
+ handle = dlopen (filepath, RTLD_NOW|RTLD_GLOBAL);
+ free (filepath);
}
if (handle)
{
- const lt_dlinfo *info = lt_dlgetinfo (handle);
-
- /* If we have a handle, there must be handle info. */
- assert (info);
-
-#ifdef DEBUG_MODULES
- if (info->ref_count > 1)
- {
- xfprintf (stderr, "module %s: now has %d libtool references.",
- name, info->ref_count);
- }
-#endif /* DEBUG_MODULES */
-
m4_debug_message (context, M4_DEBUG_TRACE_MODULE,
_("module %s: opening file %s"),
name ? name : MODULE_SELF_NAME,
- quotearg_style (locale_quoting_style, info->filename));
+ quotearg_style (locale_quoting_style, name));
+
+ module = (m4_module *) xzalloc (sizeof *module);
+ module->name = xstrdup (name);
+ module->handle = handle;
+ module->next = context->modules;
- /* Provide the m4_module corresponding to the lt_dlhandle, if
- not yet created. */
- module = (m4_module *) lt_dlcaller_get_data (iface_id, handle);
- if (!module)
+ context->modules = module;
+ m4_hash_insert (context->namemap, xstrdup (name), module);
+
+ /* Find and run any initializing function in the opened module,
+ the first time the module is opened. */
+ char *entry_point = xasprintf ("include_%s", name);
+ m4_module_init_func *init_func =
+ (m4_module_init_func *) dlsym (handle, entry_point);
+ free (entry_point);
+
+ if (init_func)
+ {
+ init_func (context, module, obs);
+
+ m4_debug_message (context, M4_DEBUG_TRACE_MODULE,
+ _("module %s: init hook called"), name);
+ }
+ else
{
- void *old;
- const char *err;
-
- module = (m4_module *) xzalloc (sizeof *module);
- module->name = xstrdup (name);
- module->handle = handle;
- module->next = context->modules;
-
- context->modules = module;
- m4_hash_insert (context->namemap, xstrdup (name), module);
-
- /* clear out any stale errors, since we have to use
- lt_dlerror to distinguish between success and
- failure. */
- lt_dlerror ();
- old = lt_dlcaller_set_data (iface_id, handle, module);
- assert (!old);
- err = lt_dlerror ();
- if (err)
- m4_error (context, EXIT_FAILURE, 0, NULL,
- _("unable to load module `%s': %s"), name, err);
-
- /* Find and run any initializing function in the opened module,
- the first time the module is opened. */
- init_func = (m4_module_init_func *) lt_dlsym (handle, INIT_SYMBOL);
- if (init_func)
- {
- init_func (context, module, obs);
-
- m4_debug_message (context, M4_DEBUG_TRACE_MODULE,
- _("module %s: init hook called"), name);
- }
- else
- {
- m4_error (context, EXIT_FAILURE, 0, NULL,
- _("module `%s' has no entry point"), name);
- }
+ m4_error (context, EXIT_FAILURE, 0, NULL,
+ _("module `%s' has no entry point"), name);
}
m4_debug_message (context, M4_DEBUG_TRACE_MODULE,
@@ -428,23 +319,13 @@ m4__module_open (m4 *context, const char *name, m4_obstack *obs)
}
else
{
+ const char *err = dlerror ();
+ if (!err) err = _("unknown error");
+
/* Couldn't open the module; diagnose and exit. */
m4_error (context, EXIT_FAILURE, 0, NULL,
- _("cannot open module `%s': %s"), name, module_dlerror ());
+ _("cannot open module `%s': %s"), name, err);
}
return module;
}
-
-
-/* FIXME - libtool doesn't expose lt_dlerror strings for translation. */
-static const char *
-module_dlerror (void)
-{
- const char *dlerror = lt_dlerror ();
-
- if (!dlerror)
- dlerror = _("unknown error");
-
- return dlerror;
-}
diff --git a/m4/path.c b/m4/path.c
index 9437e936..3a932897 100644
--- a/m4/path.c
+++ b/m4/path.c
@@ -41,8 +41,7 @@ static const char *FILE_SUFFIXES[] = {
"",
".m4f",
".m4",
- ".la",
- LT_MODULE_EXT,
+ ".so",
NULL
};
@@ -297,7 +296,7 @@ m4_load_filename (m4 *context, const m4_call_info *caller,
if (!m4_get_posixly_correct_opt (context)
&& suffix
- && (STREQ (suffix, LT_MODULE_EXT) || STREQ (suffix, ".la")))
+ && STREQ (suffix, ".so"))
{
m4_module_load (context, filename, obs);
}
diff --git a/modules/gnu.c b/modules/gnu.c
index 96c75475..874502e0 100644
--- a/modules/gnu.c
+++ b/modules/gnu.c
@@ -97,7 +97,8 @@ static const m4_macro m4_macro_table[] =
};
-M4INIT_HANDLER (gnu)
+void
+include_gnu (m4 *context, m4_module *module, m4_obstack *obs)
{
m4_install_builtins (context, module, m4_builtin_table);
m4_install_macros (context, module, m4_macro_table);
diff --git a/modules/import.c b/modules/import.c
index 679a50d5..9f03493c 100644
--- a/modules/import.c
+++ b/modules/import.c
@@ -28,9 +28,6 @@
# include "m4private.h"
#endif
-/* Rename exported symbols for dlpreload()ing. */
-#define m4_builtin_table import_LTX_m4_builtin_table
-
/* function macros blind side minargs maxargs */
#define builtin_functions \
BUILTIN (import, false, false, false, 0, 1) \
@@ -53,7 +50,8 @@ static const m4_builtin m4_builtin_table[] =
};
-M4INIT_HANDLER (import)
+void
+include_import (m4 *context, m4_module *module, m4_obstack *obs)
{
m4_install_builtins (context, module, m4_builtin_table);
}
diff --git a/modules/m4.c b/modules/m4.c
index ecae4c3a..ec47d01c 100644
--- a/modules/m4.c
+++ b/modules/m4.c
@@ -38,13 +38,6 @@
#include <modules/m4.h>
-/* Rename exported symbols for dlpreload()ing. */
-#define m4_set_sysval m4_LTX_m4_set_sysval
-#define m4_sysval_flush m4_LTX_m4_sysval_flush
-#define m4_dump_symbols m4_LTX_m4_dump_symbols
-#define m4_expand_ranges m4_LTX_m4_expand_ranges
-#define m4_make_temp m4_LTX_m4_make_temp
-
extern void m4_set_sysval (int);
extern void m4_sysval_flush (m4 *, bool);
extern void m4_dump_symbols (m4 *, m4_dump_symbol_data *, size_t,
@@ -113,7 +106,7 @@ static void numb_obstack (m4_obstack *obs, number value,
/* Generate a table for mapping m4 symbol names to handler functions. */
-const m4_builtin m4_builtin_table[] =
+static const m4_builtin m4_builtin_table[] =
{
#define BUILTIN(handler, macros, blind, side, min, max) \
M4BUILTIN_ENTRY (handler, #handler, macros, blind, side, min, max)
@@ -125,7 +118,8 @@ const m4_builtin m4_builtin_table[] =
};
-M4INIT_HANDLER (m4)
+void
+include_m4 (m4 *context, m4_module *module, m4_obstack *obs)
{
m4_install_builtins (context, module, m4_builtin_table);
}
diff --git a/modules/modtest.c b/modules/modtest.c
index 75450f7e..2026431d 100644
--- a/modules/modtest.c
+++ b/modules/modtest.c
@@ -28,9 +28,6 @@
# include "m4private.h"
#endif
-/* Rename exported symbols for dlpreload()ing. */
-#define export_test modtest_LTX_export_test
-
extern bool export_test (const char *foo);
/* function macros blind side minargs maxargs */
@@ -66,7 +63,8 @@ static const m4_macro m4_macro_table[] =
/**
* modtest()
**/
-M4INIT_HANDLER (modtest)
+void
+include_modtest (m4 *context, m4_module *module, m4_obstack *obs)
{
const char *s = "Test module loaded.\n";
diff --git a/modules/mpeval.c b/modules/mpeval.c
index 49afd765..4debc99d 100644
--- a/modules/mpeval.c
+++ b/modules/mpeval.c
@@ -122,7 +122,8 @@ static const m4_macro m4_macro_table[] =
};
-M4INIT_HANDLER (mpeval)
+void
+include_mpeval (m4 *context, m4_module *module, m4_obstack *obs)
{
m4_install_builtins (context, module, m4_builtin_table);
m4_install_macros (context, module, m4_macro_table);
diff --git a/modules/shadow.c b/modules/shadow.c
index 53829937..2247f397 100644
--- a/modules/shadow.c
+++ b/modules/shadow.c
@@ -58,7 +58,8 @@ static const m4_macro m4_macro_table[] =
-M4INIT_HANDLER (shadow)
+void
+include_shadow (m4 *context, m4_module *module, m4_obstack *obs)
{
const char *s = "Shadow module loaded.";
diff --git a/modules/stdlib.c b/modules/stdlib.c
index b01326df..5a300d65 100644
--- a/modules/stdlib.c
+++ b/modules/stdlib.c
@@ -70,7 +70,8 @@ static const m4_builtin m4_builtin_table[] =
};
-M4INIT_HANDLER (stdlib)
+void
+include_stdlib (m4 *context, m4_module *module, m4_obstack *obs)
{
m4_install_builtins (context, module, m4_builtin_table);
}
diff --git a/modules/time.c b/modules/time.c
index 39db75fe..5c9c2ce6 100644
--- a/modules/time.c
+++ b/modules/time.c
@@ -76,7 +76,8 @@ static const m4_builtin m4_builtin_table[] =
};
-M4INIT_HANDLER (time)
+void
+include_time (m4 *context, m4_module *module, m4_obstack *obs)
{
m4_install_builtins (context, module, m4_builtin_table);
}
diff --git a/modules/traditional.c b/modules/traditional.c
index 88a4966b..f9cb9501 100644
--- a/modules/traditional.c
+++ b/modules/traditional.c
@@ -45,7 +45,8 @@ static const m4_macro m4_macro_table[] =
{ NULL, NULL, 0, 0 },
};
-M4INIT_HANDLER (traditional)
+void
+include_traditional (m4 *context, m4_module *module, m4_obstack *obs)
{
m4_install_macros (context, module, m4_macro_table);
}
diff --git a/src/main.c b/src/main.c
index 53305451..27d6dc8e 100644
--- a/src/main.c
+++ b/src/main.c
@@ -331,12 +331,8 @@ main (int argc, char *const *argv, char *const *envp)
textdomain (PACKAGE);
#endif
- LTDL_SET_PRELOADED_SYMBOLS ();
-
context = m4_create ();
- m4__module_init (context);
-
#ifdef USE_STACKOVF
setup_stackovf_trap (argv, envp, stackovf_handler);
#endif
diff --git a/tests/m4.in b/tests/m4.in
index 2a9b7f3f..e93b0b99 100644
--- a/tests/m4.in
+++ b/tests/m4.in
@@ -34,7 +34,13 @@ else
case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
fi
+M4PATH="\
+@abs_top_builddir@/modules/.libs:\
+@abs_top_builddir@/tests/.libs:\
+${M4PATH+$M4PATH:}\
+:"
+export M4PATH
+
exec "@abs_top_builddir@/src/m4" \
- --include="@abs_top_builddir@/modules" \
${1+"$@"}
exit 1