1 /* dynl.c - dynamic linking
3 * Copyright (C) 1990-1997 Free Software Foundation, Inc.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this software; see the file COPYING. If not, write to
17 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18 * Boston, MA 02111-1307 USA
20 * As a special exception, the Free Software Foundation gives permission
21 * for additional uses of the text contained in its release of GUILE.
23 * The exception is that, if you link the GUILE library with other files
24 * to produce an executable, this does not by itself cause the
25 * resulting executable to be covered by the GNU General Public License.
26 * Your use of that executable is in no way restricted on account of
27 * linking the GUILE library code into it.
29 * This exception does not however invalidate any other reasons why
30 * the executable file might be covered by the GNU General Public License.
32 * This exception applies only to the code released by the
33 * Free Software Foundation under the name GUILE. If you copy
34 * code from other Free Software Foundation releases into a copy of
35 * GUILE, as the General Public License permits, the exception does
36 * not apply to the code that you add in this way. To avoid misleading
37 * anyone as to the status of such modified files, you must delete
38 * this exception notice from them.
40 * If you write modifications of your own for GUILE, it is your choice
41 * whether to permit this exception to apply to your modifications.
42 * If you do not wish that, delete this exception notice. */
44 /* "dynl.c" dynamically link&load object files.
46 Modified for libguile by Marius Vollmer */
48 /* XXX - This is only here to drag in a definition of __eprintf. This
49 is needed for proper operation of dynamic linking. The real
50 solution would probably be a shared libgcc. */
56 maybe_drag_in_eprintf ()
58 assert (!maybe_drag_in_eprintf
);
67 /* Converting a list of SCM strings into a argv-style array. You must
68 have ints disabled for the whole lifetime of the created argv (from
69 before MAKE_ARGV_FROM_STRINGLIST until after
70 MUST_FREE_ARGV). Atleast this is was the documentation for
71 MAKARGVFROMSTRS says, it isn't really used that way.
73 This code probably belongs into strings.c */
75 static char **scm_make_argv_from_stringlist
SCM_P ((SCM args
, int *argcp
,
76 char *subr
, int argn
));
79 scm_make_argv_from_stringlist (args
, argcp
, subr
, argn
)
88 argc
= scm_ilength(args
);
89 argv
= (char **) scm_must_malloc ((1L+argc
)*sizeof(char *), subr
);
90 for(i
= 0; SCM_NNULLP (args
); args
= SCM_CDR (args
), i
++) {
93 SCM str
= SCM_CAR (args
);
95 SCM_ASSERT (SCM_NIMP (str
) && SCM_ROSTRINGP (str
), str
, argn
, subr
);
96 len
= 1 + SCM_ROLENGTH (str
);
97 dst
= (char *) scm_must_malloc ((long)len
, subr
);
98 src
= SCM_ROCHARS (str
);
110 static void scm_must_free_argv
SCM_P ((char **argv
));
113 scm_must_free_argv(argv
)
122 /* Coerce an arbitrary readonly-string into a zero-terminated string.
125 static SCM scm_coerce_rostring
SCM_P ((SCM rostr
, char *subr
, int argn
));
128 scm_coerce_rostring (rostr
, subr
, argn
)
133 SCM_ASSERT (SCM_NIMP (rostr
) && SCM_ROSTRINGP (rostr
), rostr
, argn
, subr
);
134 if (SCM_SUBSTRP (rostr
))
135 rostr
= scm_makfromstr (SCM_ROCHARS (rostr
), SCM_ROLENGTH (rostr
), 0);
142 /* We can't use SCM objects here. One should be able to call
143 SCM_REGISTER_MODULE from a C++ constructor for a static
144 object. This happens before main and thus before libguile is
148 struct moddata
*link
;
153 static struct moddata
*registered_mods
= NULL
;
156 scm_register_module_xxx (module_name
, init_func
)
162 /* XXX - should we (and can we) DEFER_INTS here? */
164 for (md
= registered_mods
; md
; md
= md
->link
)
165 if (!strcmp (md
->module_name
, module_name
)) {
166 md
->init_func
= init_func
;
170 md
= (struct moddata
*)malloc (sizeof (struct moddata
));
173 "guile: can't register module (%s): not enough memory",
178 md
->module_name
= module_name
;
179 md
->init_func
= init_func
;
180 md
->link
= registered_mods
;
181 registered_mods
= md
;
184 SCM_PROC (s_registered_modules
, "c-registered-modules", 0, 0, 0, scm_registered_modules
);
187 scm_registered_modules ()
193 for (md
= registered_mods
; md
; md
= md
->link
)
194 res
= scm_cons (scm_cons (scm_makfrom0str (md
->module_name
),
195 scm_ulong2num ((unsigned long) md
->init_func
)),
200 SCM_PROC (s_clear_registered_modules
, "c-clear-registered-modules", 0, 0, 0, scm_clear_registered_modules
);
203 scm_clear_registered_modules ()
205 struct moddata
*md1
, *md2
;
209 for (md1
= registered_mods
; md1
; md1
= md2
) {
213 registered_mods
= NULL
;
216 return SCM_UNSPECIFIED
;
219 /* Dispatch to the system dependent files
221 * They define some static functions. These functions are called with
222 * deferred interrupts. When they want to throw errors, they are
223 * expected to insert a SCM_ALLOW_INTS before doing the throw. It
224 * might work to throw an error while interrupts are deferred (because
225 * they will be unconditionally allowed the next time a SCM_ALLOW_INTS
226 * is executed, SCM_DEFER_INTS and SCM_ALLOW_INTS do not nest).
229 static void sysdep_dynl_init
SCM_P ((void));
230 static void *sysdep_dynl_link
SCM_P ((char *filename
, char *subr
));
231 static void sysdep_dynl_unlink
SCM_P ((void *handle
, char *subr
));
232 static void *sysdep_dynl_func
SCM_P ((char *symbol
, void *handle
, char *subr
));
238 #include "dynl-shl.c"
241 #include "dynl-dld.c"
244 /* no dynamic linking available, throw errors. */
256 scm_misc_error (subr
, "dynamic linking not available", SCM_EOL
);
260 sysdep_dynl_link (filename
, subr
)
264 no_dynl_error (subr
);
269 sysdep_dynl_unlink (handle
, subr
)
273 no_dynl_error (subr
);
277 sysdep_dynl_func (symbol
, handle
, subr
)
282 no_dynl_error (subr
);
290 int scm_tc16_dynamic_obj
;
297 static SCM mark_dynl_obj
SCM_P ((SCM ptr
));
302 struct dynl_obj
*d
= (struct dynl_obj
*)SCM_CDR (ptr
);
303 SCM_SETGC8MARK (ptr
);
307 static scm_sizet free_dynl_obj
SCM_P ((SCM ptr
));
312 scm_must_free ((char *)SCM_CDR (ptr
));
313 return sizeof (struct dynl_obj
);
316 static int print_dynl_obj
SCM_P ((SCM exp
, SCM port
, scm_print_state
*pstate
));
318 print_dynl_obj (exp
, port
, pstate
)
321 scm_print_state
*pstate
;
323 struct dynl_obj
*d
= (struct dynl_obj
*)SCM_CDR (exp
);
324 scm_gen_puts (scm_regular_string
, "#<dynamic-object ", port
);
325 scm_iprin1 (d
->filename
, port
, pstate
);
326 if (d
->handle
== NULL
)
327 scm_gen_puts (scm_regular_string
, " (unlinked)", port
);
328 scm_gen_putc ('>', port
);
332 static scm_smobfuns dynl_obj_smob
= {
338 SCM_PROC (s_dynamic_link
, "dynamic-link", 1, 0, 0, scm_dynamic_link
);
341 scm_dynamic_link (fname
)
348 fname
= scm_coerce_rostring (fname
, s_dynamic_link
, SCM_ARG1
);
351 handle
= sysdep_dynl_link (SCM_CHARS (fname
), s_dynamic_link
);
353 d
= (struct dynl_obj
*)scm_must_malloc (sizeof (struct dynl_obj
),
360 SCM_SETCAR (z
, scm_tc16_dynamic_obj
);
366 static struct dynl_obj
*get_dynl_obj
SCM_P ((SCM obj
, char *subr
, int argn
));
367 static struct dynl_obj
*
368 get_dynl_obj (dobj
, subr
, argn
)
374 SCM_ASSERT (SCM_NIMP (dobj
) && SCM_CAR (dobj
) == scm_tc16_dynamic_obj
,
376 d
= (struct dynl_obj
*)SCM_CDR (dobj
);
377 SCM_ASSERT (d
->handle
!= NULL
, dobj
, argn
, subr
);
381 SCM_PROC (s_dynamic_object_p
, "dynamic-object?", 1, 0, 0, scm_dynamic_object_p
);
384 scm_dynamic_object_p (SCM obj
)
386 return (SCM_NIMP (obj
) && SCM_CAR (obj
) == scm_tc16_dynamic_obj
)?
387 SCM_BOOL_T
: SCM_BOOL_F
;
390 SCM_PROC (s_dynamic_unlink
, "dynamic-unlink", 1, 0, 0, scm_dynamic_unlink
);
393 scm_dynamic_unlink (dobj
)
396 struct dynl_obj
*d
= get_dynl_obj (dobj
, s_dynamic_unlink
, SCM_ARG1
);
398 sysdep_dynl_unlink (d
->handle
, s_dynamic_unlink
);
401 return SCM_UNSPECIFIED
;
404 SCM_PROC (s_dynamic_func
, "dynamic-func", 2, 0, 0, scm_dynamic_func
);
407 scm_dynamic_func (SCM symb
, SCM dobj
)
412 symb
= scm_coerce_rostring (symb
, s_dynamic_func
, SCM_ARG1
);
413 d
= get_dynl_obj (dobj
, s_dynamic_func
, SCM_ARG2
);
416 func
= (void (*) ()) sysdep_dynl_func (SCM_CHARS (symb
), d
->handle
,
420 return scm_ulong2num ((unsigned long)func
);
423 SCM_PROC (s_dynamic_call
, "dynamic-call", 2, 0, 0, scm_dynamic_call
);
426 scm_dynamic_call (SCM func
, SCM dobj
)
430 if (SCM_NIMP (func
) && SCM_ROSTRINGP (func
))
431 func
= scm_dynamic_func (func
, dobj
);
432 fptr
= (void (*)()) scm_num2ulong (func
, (char *)SCM_ARG1
, s_dynamic_call
);
436 return SCM_UNSPECIFIED
;
439 SCM_PROC (s_dynamic_args_call
, "dynamic-args-call", 3, 0, 0, scm_dynamic_args_call
);
442 scm_dynamic_args_call (func
, dobj
, args
)
443 SCM func
, dobj
, args
;
445 int (*fptr
) (int argc
, char **argv
);
449 if (SCM_NIMP (func
) && SCM_ROSTRINGP (func
))
450 func
= scm_dynamic_func (func
, dobj
);
452 fptr
= (int (*)(int, char **)) scm_num2ulong (func
, (char *)SCM_ARG1
,
453 s_dynamic_args_call
);
455 argv
= scm_make_argv_from_stringlist (args
, &argc
, s_dynamic_args_call
,
457 result
= (*fptr
) (argc
, argv
);
458 scm_must_free_argv (argv
);
461 return SCM_MAKINUM(0L+result
);
465 scm_init_dynamic_linking ()
467 scm_tc16_dynamic_obj
= scm_newsmob (&dynl_obj_smob
);