modules: support _ symbol prefix requirement for dlsym.
[m4/ericb.git] / m4 / module.c
blob8efb1a99322df27b34f2d2337a296f71d806c712
1 /* GNU m4 -- A simple macro processor
2 Copyright (C) 1989-1994, 1998-1999, 2002-2008, 2010, 2013 Free
3 Software Foundation, Inc.
5 This file is part of GNU M4.
7 GNU M4 is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 GNU M4 is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include <config.h>
23 #include <dlfcn.h>
25 #include "m4private.h"
26 #include "xvasprintf.h"
28 /* Define this to see runtime debug info. Implied by DEBUG. */
29 /*#define DEBUG_MODULES */
32 * This file implements dynamic modules in GNU M4. A module is a
33 * compiled shared object, that can be loaded into GNU M4 at run
34 * time. Information about creating modules is in ../modules/README.
36 * This implementation uses libltdl, which is in turn can open modules
37 * using either dlopen(3) (exists on GNU/Linux, OSF, Solaris, SunOS and
38 * others), shl_load(3) (exists on HPUX), LoadLibrary(3) (exists on
39 * Windows, cygwin, OS/2), load_add_on(3) (exists on BeOS), NSAddImage
40 * (exists on MacOS) and can also fall back to dld_link(3) from GNU
41 * libdld or lt_dlpreload from libtool if shared libraries are not
42 * available on the host machine.
44 * An M4 module will usually define an external symbol named after the
45 * basename of the loadable module:
47 * void
48 * mymod_LTX_m4_init_module (m4 *context, m4_module *module,
49 * m4_obstack *obs)
51 * The function is only called the first time the module is included
52 * and generally uses either `m4_install_builtins' or
53 * `m4_install_macros' (or both!) to register whatever builtins and
54 * macros are provided by the module.
56 * To load a module, call m4_module_load(), which searches for the
57 * module in directories from M4PATH. The search path is initialized
58 * from the environment variable M4PATH, followed by the configuration
59 * time default where the modules shipped with M4 itself are installed.
60 * `m4_module_load' returns NULL on failure, or else an opaque module
61 * handle for the newly mapped vm segment containing the module code.
62 * If the module is not already loaded, m4_module_load() the builtins
63 * and macros registered by `mymod_LTX_m4_init_module' are installed
64 * into the symbol table using `install_builtin_table' and `install_
65 * macro_table' respectively.
66 **/
68 #define MODULE_SELF_NAME "!myself!"
70 #if NEED_USCORE
71 static void *
72 uscore_sym (void *handle, const char *symbol)
74 char *symname = xasprintf ("_%s", symbol);
75 void *address = dlsym (handle, symname);
76 free (symname);
77 return address;
80 #define dlsym uscore_sym
81 #endif
83 static const char * module_dlerror (void);
85 static void install_builtin_table (m4*, m4_module *);
86 static void install_macro_table (m4*, m4_module *);
88 static int compare_builtin_CB (const void *a, const void *b);
90 const char *
91 m4_get_module_name (const m4_module *module)
93 assert (module);
94 return module->name;
97 void *
98 m4_module_import (m4 *context, const char *module_name,
99 const char *symbol_name, m4_obstack *obs)
101 m4_module * module = m4__module_find (context, module_name);
102 void * symbol_address = NULL;
104 /* Try to load the module if it is not yet available (errors are
105 diagnosed by m4_module_load). */
106 /* FIXME - should this use m4__module_open instead, to avoid
107 polluting the symbol table when importing a function? */
108 if (!module)
109 module = m4_module_load (context, module_name, obs);
111 if (module)
113 symbol_address = dlsym (module->handle, symbol_name);
115 if (!symbol_address)
116 m4_error (context, 0, 0, NULL,
117 _("cannot load symbol `%s' from module `%s'"),
118 symbol_name, module_name);
121 return symbol_address;
124 void
125 m4_install_builtins (m4 *context, m4_module *module, const m4_builtin *bp)
127 assert (context);
128 assert (module);
129 assert (bp);
131 const m4_builtin *tmp;
132 m4__builtin *builtin;
133 for (tmp = bp; tmp->name; tmp++)
134 module->builtins_len++;
135 module->builtins = (m4__builtin *) xnmalloc (module->builtins_len,
136 sizeof *module->builtins);
137 for (builtin = module->builtins; bp->name != NULL; bp++, builtin++)
139 /* Sanity check that builtins meet the required interface. */
140 assert (bp->min_args <= bp->max_args);
141 assert (bp->min_args > 0 ||
142 (bp->flags & (M4_BUILTIN_BLIND|M4_BUILTIN_SIDE_EFFECT)) == 0);
143 assert (bp->max_args ||
144 (bp->flags & M4_BUILTIN_FLATTEN_ARGS) == 0);
145 assert ((bp->flags & ~M4_BUILTIN_FLAGS_MASK) == 0);
146 memcpy (&builtin->builtin, bp, sizeof *bp);
147 builtin->builtin.name = xstrdup (bp->name);
148 builtin->module = module;
150 qsort (module->builtins, module->builtins_len,
151 sizeof *module->builtins, compare_builtin_CB);
154 static void
155 install_builtin_table (m4 *context, m4_module *module)
157 size_t i;
159 assert (context);
160 assert (module);
161 for (i = 0; i < module->builtins_len; i++)
163 m4_symbol_value *value = m4_symbol_value_create ();
164 const char *name = module->builtins[i].builtin.name;
166 m4__set_symbol_value_builtin (value, &module->builtins[i]);
167 if (m4_get_prefix_builtins_opt (context))
168 name = xasprintf ("m4_%s", name);
170 m4_symbol_pushdef (M4SYMTAB, name, strlen (name), value);
172 if (m4_get_prefix_builtins_opt (context))
173 DELETE (name);
175 if (i)
176 m4_debug_message (context, M4_DEBUG_TRACE_MODULE,
177 _("module %s: builtins loaded"),
178 m4_get_module_name (module));
181 void
182 m4_install_macros (m4 *context, m4_module *module, const m4_macro *mp)
184 assert (context);
185 assert (module);
186 assert (mp);
188 module->macros = (m4_macro *) mp;
191 static void
192 install_macro_table (m4 *context, m4_module *module)
194 const m4_macro *mp;
196 assert (context);
197 assert (module);
199 mp = module->macros;
201 if (mp)
203 for (; mp->name != NULL; mp++)
205 m4_symbol_value *value = m4_symbol_value_create ();
206 size_t len = strlen (mp->value);
208 /* Sanity check that builtins meet the required interface. */
209 assert (mp->min_args <= mp->max_args);
211 m4_set_symbol_value_text (value, xmemdup0 (mp->value, len), len, 0);
212 VALUE_MODULE (value) = module;
213 VALUE_MIN_ARGS (value) = mp->min_args;
214 VALUE_MAX_ARGS (value) = mp->max_args;
216 m4_symbol_pushdef (M4SYMTAB, mp->name, strlen (mp->name), value);
219 m4_debug_message (context, M4_DEBUG_TRACE_MODULE,
220 _("module %s: macros loaded"),
221 m4_get_module_name (module));
225 m4_module *
226 m4_module_load (m4 *context, const char *name, m4_obstack *obs)
228 m4_module *module = m4__module_find (context, name);
230 if (!module)
232 module = m4__module_open (context, name, obs);
234 if (module)
236 install_builtin_table (context, module);
237 install_macro_table (context, module);
241 return module;
245 /* Return successive loaded modules. */
246 m4_module *
247 m4_module_next (m4 *context, m4_module *module)
249 return module ? module->next : context->modules;
252 /* Return the first loaded module that passes the registered interface test
253 and is called NAME. */
254 m4_module *
255 m4__module_find (m4 *context, const char *name)
257 m4_module **pmodule = (m4_module **) m4_hash_lookup (context->namemap, name);
258 return pmodule ? *pmodule : NULL;
262 /* Compare two builtins A and B for sorting, as in qsort. */
263 static int
264 compare_builtin_CB (const void *a, const void *b)
266 const m4__builtin *builtin_a = (const m4__builtin *) a;
267 const m4__builtin *builtin_b = (const m4__builtin *) b;
268 int result = strcmp (builtin_a->builtin.name, builtin_b->builtin.name);
269 /* A builtin module should never provide two builtins with the same
270 name. */
271 assert (result || a == b);
272 return result;
275 /* Load a module. NAME can be a absolute file name or, if relative,
276 it is searched for in the module path. The module is unloaded in
277 case of error. */
278 m4_module *
279 m4__module_open (m4 *context, const char *name, m4_obstack *obs)
281 static const char * suffixes[] = { "", ".so", ".dll", NULL };
282 m4_module * module = NULL;
284 assert (context);
286 char *filepath = m4_path_search (context, name, suffixes);
287 void *handle = NULL;
289 /* Use system module search path if m4_path_search fails. */
290 if (!filepath)
291 filepath = xstrdup (name);
293 if (filepath)
295 handle = dlopen (filepath, RTLD_NOW|RTLD_GLOBAL);
296 free (filepath);
299 if (handle)
301 m4_debug_message (context, M4_DEBUG_TRACE_MODULE,
302 _("module %s: opening file %s"),
303 name ? name : MODULE_SELF_NAME,
304 quotearg_style (locale_quoting_style, name));
306 module = (m4_module *) xzalloc (sizeof *module);
307 module->name = xstrdup (name);
308 module->handle = handle;
309 module->next = context->modules;
311 context->modules = module;
312 m4_hash_insert (context->namemap, xstrdup (name), module);
314 /* Find and run any initializing function in the opened module,
315 the first time the module is opened. */
316 char *entry_point = xasprintf ("include_%s", name);
317 m4_module_init_func *init_func =
318 (m4_module_init_func *) dlsym (handle, entry_point);
319 free (entry_point);
321 if (init_func)
323 init_func (context, module, obs);
325 m4_debug_message (context, M4_DEBUG_TRACE_MODULE,
326 _("module %s: init hook called"), name);
328 else
330 m4_error (context, EXIT_FAILURE, 0, NULL,
331 _("module `%s' has no entry point"), name);
334 m4_debug_message (context, M4_DEBUG_TRACE_MODULE,
335 _("module %s: opened"), name);
337 else
339 const char *err = dlerror ();
340 if (!err) err = _("unknown error");
342 /* Couldn't open the module; diagnose and exit. */
343 m4_error (context, EXIT_FAILURE, 0, NULL,
344 _("cannot open module `%s': %s"), name, err);
347 return module;