1 /* dynl.c - dynamic linking
3 * Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999 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 #if 0 /* Disabled until we know for sure that it isn't needed */
49 /* XXX - This is only here to drag in a definition of __eprintf. This
50 is needed for proper operation of dynamic linking. The real
51 solution would probably be a shared libgcc. */
57 maybe_drag_in_eprintf ()
59 assert (!maybe_drag_in_eprintf
);
70 /* Converting a list of SCM strings into a argv-style array. You must
71 have ints disabled for the whole lifetime of the created argv (from
72 before MAKE_ARGV_FROM_STRINGLIST until after
73 MUST_FREE_ARGV). Atleast this is was the documentation for
74 MAKARGVFROMSTRS says, it isn't really used that way.
76 This code probably belongs into strings.c */
78 static char **scm_make_argv_from_stringlist
SCM_P ((SCM args
, int *argcp
,
79 const char *subr
, int argn
));
82 scm_make_argv_from_stringlist (args
, argcp
, subr
, argn
)
91 argc
= scm_ilength(args
);
92 argv
= (char **) scm_must_malloc ((1L+argc
)*sizeof(char *), subr
);
93 for(i
= 0; SCM_NNULLP (args
); args
= SCM_CDR (args
), i
++) {
96 SCM str
= SCM_CAR (args
);
98 SCM_ASSERT (SCM_NIMP (str
) && SCM_ROSTRINGP (str
), str
, argn
, subr
);
99 len
= 1 + SCM_ROLENGTH (str
);
100 dst
= (char *) scm_must_malloc ((long)len
, subr
);
101 src
= SCM_ROCHARS (str
);
113 static void scm_must_free_argv
SCM_P ((char **argv
));
116 scm_must_free_argv(argv
)
125 /* Coerce an arbitrary readonly-string into a zero-terminated string.
128 static SCM scm_coerce_rostring
SCM_P ((SCM rostr
, const char *subr
, int argn
));
131 scm_coerce_rostring (rostr
, subr
, argn
)
136 SCM_ASSERT (SCM_NIMP (rostr
) && SCM_ROSTRINGP (rostr
), rostr
, argn
, subr
);
137 if (SCM_SUBSTRP (rostr
))
138 rostr
= scm_makfromstr (SCM_ROCHARS (rostr
), SCM_ROLENGTH (rostr
), 0);
145 /* We can't use SCM objects here. One should be able to call
146 SCM_REGISTER_MODULE from a C++ constructor for a static
147 object. This happens before main and thus before libguile is
151 struct moddata
*link
;
156 static struct moddata
*registered_mods
= NULL
;
159 scm_register_module_xxx (module_name
, init_func
)
165 /* XXX - should we (and can we) DEFER_INTS here? */
167 for (md
= registered_mods
; md
; md
= md
->link
)
168 if (!strcmp (md
->module_name
, module_name
)) {
169 md
->init_func
= init_func
;
173 md
= (struct moddata
*)malloc (sizeof (struct moddata
));
176 "guile: can't register module (%s): not enough memory",
181 md
->module_name
= module_name
;
182 md
->init_func
= init_func
;
183 md
->link
= registered_mods
;
184 registered_mods
= md
;
187 SCM_PROC (s_registered_modules
, "c-registered-modules", 0, 0, 0, scm_registered_modules
);
190 scm_registered_modules ()
196 for (md
= registered_mods
; md
; md
= md
->link
)
197 res
= scm_cons (scm_cons (scm_makfrom0str (md
->module_name
),
198 scm_ulong2num ((unsigned long) md
->init_func
)),
203 SCM_PROC (s_clear_registered_modules
, "c-clear-registered-modules", 0, 0, 0, scm_clear_registered_modules
);
206 scm_clear_registered_modules ()
208 struct moddata
*md1
, *md2
;
212 for (md1
= registered_mods
; md1
; md1
= md2
) {
216 registered_mods
= NULL
;
219 return SCM_UNSPECIFIED
;
222 /* Dispatch to the system dependent files
224 * They define some static functions. These functions are called with
225 * deferred interrupts. When they want to throw errors, they are
226 * expected to insert a SCM_ALLOW_INTS before doing the throw. It
227 * might work to throw an error while interrupts are deferred (because
228 * they will be unconditionally allowed the next time a SCM_ALLOW_INTS
229 * is executed, SCM_DEFER_INTS and SCM_ALLOW_INTS do not nest).
232 #define DYNL_GLOBAL 0x0001
234 static void sysdep_dynl_init
SCM_P ((void));
235 static void *sysdep_dynl_link
SCM_P ((const char *filename
, int flags
,
237 static void sysdep_dynl_unlink
SCM_P ((void *handle
, const char *subr
));
238 static void *sysdep_dynl_func
SCM_P ((const char *symbol
, void *handle
,
245 #include "dynl-shl.c"
248 #include "dynl-dld.c"
251 /* no dynamic linking available, throw errors. */
259 no_dynl_error (const char *subr
)
262 scm_misc_error (subr
, "dynamic linking not available", SCM_EOL
);
266 sysdep_dynl_link (const char *filename
,
270 no_dynl_error (subr
);
275 sysdep_dynl_unlink (void *handle
,
278 no_dynl_error (subr
);
282 sysdep_dynl_func (const char *symbol
,
286 no_dynl_error (subr
);
294 int scm_tc16_dynamic_obj
;
301 static SCM mark_dynl_obj
SCM_P ((SCM ptr
));
306 struct dynl_obj
*d
= (struct dynl_obj
*)SCM_CDR (ptr
);
310 static scm_sizet free_dynl_obj
SCM_P ((SCM ptr
));
315 scm_must_free ((char *)SCM_CDR (ptr
));
316 return sizeof (struct dynl_obj
);
319 static int print_dynl_obj
SCM_P ((SCM exp
, SCM port
, scm_print_state
*pstate
));
321 print_dynl_obj (exp
, port
, pstate
)
324 scm_print_state
*pstate
;
326 struct dynl_obj
*d
= (struct dynl_obj
*)SCM_CDR (exp
);
327 scm_puts ("#<dynamic-object ", port
);
328 scm_iprin1 (d
->filename
, port
, pstate
);
329 if (d
->handle
== NULL
)
330 scm_puts (" (unlinked)", port
);
331 scm_putc ('>', port
);
335 static SCM kw_global
;
336 SCM_SYMBOL (sym_global
, "-global");
338 SCM_PROC (s_dynamic_link
, "dynamic-link", 1, 0, 1, scm_dynamic_link
);
341 scm_dynamic_link (fname
, rest
)
348 int flags
= DYNL_GLOBAL
;
350 fname
= scm_coerce_rostring (fname
, s_dynamic_link
, SCM_ARG1
);
353 while (SCM_NIMP (rest
) && SCM_CONSP (rest
))
358 rest
= SCM_CDR (rest
);
360 if (!(SCM_NIMP (rest
) && SCM_CONSP (rest
)))
361 scm_misc_error (s_dynamic_link
, "keyword without value", SCM_EOL
);
363 val
= SCM_CAR (rest
);
364 rest
= SCM_CDR (rest
);
368 if (SCM_FALSEP (val
))
369 flags
&= ~DYNL_GLOBAL
;
372 scm_misc_error (s_dynamic_link
, "unknown keyword argument: %s",
373 scm_cons (kw
, SCM_EOL
));
377 handle
= sysdep_dynl_link (SCM_CHARS (fname
), flags
, s_dynamic_link
);
379 d
= (struct dynl_obj
*)scm_must_malloc (sizeof (struct dynl_obj
),
386 SCM_SETCAR (z
, scm_tc16_dynamic_obj
);
392 static struct dynl_obj
*get_dynl_obj
SCM_P ((SCM obj
, const char *subr
, int argn
));
393 static struct dynl_obj
*
394 get_dynl_obj (dobj
, subr
, argn
)
400 SCM_ASSERT (SCM_NIMP (dobj
) && SCM_CAR (dobj
) == scm_tc16_dynamic_obj
,
402 d
= (struct dynl_obj
*)SCM_CDR (dobj
);
403 SCM_ASSERT (d
->handle
!= NULL
, dobj
, argn
, subr
);
407 SCM_PROC (s_dynamic_object_p
, "dynamic-object?", 1, 0, 0, scm_dynamic_object_p
);
410 scm_dynamic_object_p (SCM obj
)
412 return (SCM_NIMP (obj
) && SCM_CAR (obj
) == scm_tc16_dynamic_obj
)?
413 SCM_BOOL_T
: SCM_BOOL_F
;
416 SCM_PROC (s_dynamic_unlink
, "dynamic-unlink", 1, 0, 0, scm_dynamic_unlink
);
419 scm_dynamic_unlink (dobj
)
422 struct dynl_obj
*d
= get_dynl_obj (dobj
, s_dynamic_unlink
, SCM_ARG1
);
424 sysdep_dynl_unlink (d
->handle
, s_dynamic_unlink
);
427 return SCM_UNSPECIFIED
;
430 SCM_PROC (s_dynamic_func
, "dynamic-func", 2, 0, 0, scm_dynamic_func
);
433 scm_dynamic_func (SCM symb
, SCM dobj
)
438 symb
= scm_coerce_rostring (symb
, s_dynamic_func
, SCM_ARG1
);
439 d
= get_dynl_obj (dobj
, s_dynamic_func
, SCM_ARG2
);
442 func
= (void (*) ()) sysdep_dynl_func (SCM_CHARS (symb
), d
->handle
,
446 return scm_ulong2num ((unsigned long)func
);
449 SCM_PROC (s_dynamic_call
, "dynamic-call", 2, 0, 0, scm_dynamic_call
);
452 scm_dynamic_call (SCM func
, SCM dobj
)
456 if (SCM_NIMP (func
) && SCM_ROSTRINGP (func
))
457 func
= scm_dynamic_func (func
, dobj
);
458 fptr
= (void (*)()) scm_num2ulong (func
, (char *)SCM_ARG1
, s_dynamic_call
);
462 return SCM_UNSPECIFIED
;
465 SCM_PROC (s_dynamic_args_call
, "dynamic-args-call", 3, 0, 0, scm_dynamic_args_call
);
468 scm_dynamic_args_call (func
, dobj
, args
)
469 SCM func
, dobj
, args
;
471 int (*fptr
) (int argc
, char **argv
);
475 if (SCM_NIMP (func
) && SCM_ROSTRINGP (func
))
476 func
= scm_dynamic_func (func
, dobj
);
478 fptr
= (int (*)(int, char **)) scm_num2ulong (func
, (char *)SCM_ARG1
,
479 s_dynamic_args_call
);
481 argv
= scm_make_argv_from_stringlist (args
, &argc
, s_dynamic_args_call
,
483 result
= (*fptr
) (argc
, argv
);
484 scm_must_free_argv (argv
);
487 return SCM_MAKINUM(0L+result
);
491 scm_init_dynamic_linking ()
493 scm_tc16_dynamic_obj
= scm_make_smob_type_mfpe ("dynamic-object", sizeof (struct dynl_obj
),
494 mark_dynl_obj
, free_dynl_obj
,
495 print_dynl_obj
, NULL
);
498 kw_global
= scm_make_keyword_from_dash_symbol (sym_global
);