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
);
69 /* Converting a list of SCM strings into a argv-style array. You must
70 have ints disabled for the whole lifetime of the created argv (from
71 before MAKE_ARGV_FROM_STRINGLIST until after
72 MUST_FREE_ARGV). Atleast this is was the documentation for
73 MAKARGVFROMSTRS says, it isn't really used that way.
75 This code probably belongs into strings.c */
77 static char **scm_make_argv_from_stringlist
SCM_P ((SCM args
, int *argcp
,
78 const char *subr
, int argn
));
81 scm_make_argv_from_stringlist (args
, argcp
, subr
, argn
)
90 argc
= scm_ilength(args
);
91 argv
= (char **) scm_must_malloc ((1L+argc
)*sizeof(char *), subr
);
92 for(i
= 0; SCM_NNULLP (args
); args
= SCM_CDR (args
), i
++) {
95 SCM str
= SCM_CAR (args
);
97 SCM_ASSERT (SCM_NIMP (str
) && SCM_ROSTRINGP (str
), str
, argn
, subr
);
98 len
= 1 + SCM_ROLENGTH (str
);
99 dst
= (char *) scm_must_malloc ((long)len
, subr
);
100 src
= SCM_ROCHARS (str
);
112 static void scm_must_free_argv
SCM_P ((char **argv
));
115 scm_must_free_argv(argv
)
124 /* Coerce an arbitrary readonly-string into a zero-terminated string.
127 static SCM scm_coerce_rostring
SCM_P ((SCM rostr
, const char *subr
, int argn
));
130 scm_coerce_rostring (rostr
, subr
, argn
)
135 SCM_ASSERT (SCM_NIMP (rostr
) && SCM_ROSTRINGP (rostr
), rostr
, argn
, subr
);
136 if (SCM_SUBSTRP (rostr
))
137 rostr
= scm_makfromstr (SCM_ROCHARS (rostr
), SCM_ROLENGTH (rostr
), 0);
144 /* We can't use SCM objects here. One should be able to call
145 SCM_REGISTER_MODULE from a C++ constructor for a static
146 object. This happens before main and thus before libguile is
150 struct moddata
*link
;
155 static struct moddata
*registered_mods
= NULL
;
158 scm_register_module_xxx (module_name
, init_func
)
164 /* XXX - should we (and can we) DEFER_INTS here? */
166 for (md
= registered_mods
; md
; md
= md
->link
)
167 if (!strcmp (md
->module_name
, module_name
)) {
168 md
->init_func
= init_func
;
172 md
= (struct moddata
*)malloc (sizeof (struct moddata
));
175 "guile: can't register module (%s): not enough memory",
180 md
->module_name
= module_name
;
181 md
->init_func
= init_func
;
182 md
->link
= registered_mods
;
183 registered_mods
= md
;
186 SCM_PROC (s_registered_modules
, "c-registered-modules", 0, 0, 0, scm_registered_modules
);
189 scm_registered_modules ()
195 for (md
= registered_mods
; md
; md
= md
->link
)
196 res
= scm_cons (scm_cons (scm_makfrom0str (md
->module_name
),
197 scm_ulong2num ((unsigned long) md
->init_func
)),
202 SCM_PROC (s_clear_registered_modules
, "c-clear-registered-modules", 0, 0, 0, scm_clear_registered_modules
);
205 scm_clear_registered_modules ()
207 struct moddata
*md1
, *md2
;
211 for (md1
= registered_mods
; md1
; md1
= md2
) {
215 registered_mods
= NULL
;
218 return SCM_UNSPECIFIED
;
221 /* Dispatch to the system dependent files
223 * They define some static functions. These functions are called with
224 * deferred interrupts. When they want to throw errors, they are
225 * expected to insert a SCM_ALLOW_INTS before doing the throw. It
226 * might work to throw an error while interrupts are deferred (because
227 * they will be unconditionally allowed the next time a SCM_ALLOW_INTS
228 * is executed, SCM_DEFER_INTS and SCM_ALLOW_INTS do not nest).
231 static void sysdep_dynl_init
SCM_P ((void));
232 static void *sysdep_dynl_link
SCM_P ((const char *filename
, const char *subr
));
233 static void sysdep_dynl_unlink
SCM_P ((void *handle
, const char *subr
));
234 static void *sysdep_dynl_func
SCM_P ((const char *symbol
, void *handle
,
241 #include "dynl-shl.c"
244 #include "dynl-dld.c"
247 /* no dynamic linking available, throw errors. */
255 no_dynl_error (const char *subr
)
258 scm_misc_error (subr
, "dynamic linking not available", SCM_EOL
);
262 sysdep_dynl_link (const char *filename
,
265 no_dynl_error (subr
);
270 sysdep_dynl_unlink (void *handle
,
273 no_dynl_error (subr
);
277 sysdep_dynl_func (const char *symbol
,
281 no_dynl_error (subr
);
289 int scm_tc16_dynamic_obj
;
296 static SCM mark_dynl_obj
SCM_P ((SCM ptr
));
301 struct dynl_obj
*d
= (struct dynl_obj
*)SCM_CDR (ptr
);
305 static scm_sizet free_dynl_obj
SCM_P ((SCM ptr
));
310 scm_must_free ((char *)SCM_CDR (ptr
));
311 return sizeof (struct dynl_obj
);
314 static int print_dynl_obj
SCM_P ((SCM exp
, SCM port
, scm_print_state
*pstate
));
316 print_dynl_obj (exp
, port
, pstate
)
319 scm_print_state
*pstate
;
321 struct dynl_obj
*d
= (struct dynl_obj
*)SCM_CDR (exp
);
322 scm_puts ("#<dynamic-object ", port
);
323 scm_iprin1 (d
->filename
, port
, pstate
);
324 if (d
->handle
== NULL
)
325 scm_puts (" (unlinked)", port
);
326 scm_putc ('>', port
);
330 static scm_smobfuns dynl_obj_smob
= {
336 SCM_PROC (s_dynamic_link
, "dynamic-link", 1, 0, 0, scm_dynamic_link
);
339 scm_dynamic_link (fname
)
346 fname
= scm_coerce_rostring (fname
, s_dynamic_link
, SCM_ARG1
);
349 handle
= sysdep_dynl_link (SCM_CHARS (fname
), s_dynamic_link
);
351 d
= (struct dynl_obj
*)scm_must_malloc (sizeof (struct dynl_obj
),
358 SCM_SETCAR (z
, scm_tc16_dynamic_obj
);
364 static struct dynl_obj
*get_dynl_obj
SCM_P ((SCM obj
, const char *subr
, int argn
));
365 static struct dynl_obj
*
366 get_dynl_obj (dobj
, subr
, argn
)
372 SCM_ASSERT (SCM_NIMP (dobj
) && SCM_CAR (dobj
) == scm_tc16_dynamic_obj
,
374 d
= (struct dynl_obj
*)SCM_CDR (dobj
);
375 SCM_ASSERT (d
->handle
!= NULL
, dobj
, argn
, subr
);
379 SCM_PROC (s_dynamic_object_p
, "dynamic-object?", 1, 0, 0, scm_dynamic_object_p
);
382 scm_dynamic_object_p (SCM obj
)
384 return (SCM_NIMP (obj
) && SCM_CAR (obj
) == scm_tc16_dynamic_obj
)?
385 SCM_BOOL_T
: SCM_BOOL_F
;
388 SCM_PROC (s_dynamic_unlink
, "dynamic-unlink", 1, 0, 0, scm_dynamic_unlink
);
391 scm_dynamic_unlink (dobj
)
394 struct dynl_obj
*d
= get_dynl_obj (dobj
, s_dynamic_unlink
, SCM_ARG1
);
396 sysdep_dynl_unlink (d
->handle
, s_dynamic_unlink
);
399 return SCM_UNSPECIFIED
;
402 SCM_PROC (s_dynamic_func
, "dynamic-func", 2, 0, 0, scm_dynamic_func
);
405 scm_dynamic_func (SCM symb
, SCM dobj
)
410 symb
= scm_coerce_rostring (symb
, s_dynamic_func
, SCM_ARG1
);
411 d
= get_dynl_obj (dobj
, s_dynamic_func
, SCM_ARG2
);
414 func
= (void (*) ()) sysdep_dynl_func (SCM_CHARS (symb
), d
->handle
,
418 return scm_ulong2num ((unsigned long)func
);
421 SCM_PROC (s_dynamic_call
, "dynamic-call", 2, 0, 0, scm_dynamic_call
);
424 scm_dynamic_call (SCM func
, SCM dobj
)
428 if (SCM_NIMP (func
) && SCM_ROSTRINGP (func
))
429 func
= scm_dynamic_func (func
, dobj
);
430 fptr
= (void (*)()) scm_num2ulong (func
, (char *)SCM_ARG1
, s_dynamic_call
);
434 return SCM_UNSPECIFIED
;
437 SCM_PROC (s_dynamic_args_call
, "dynamic-args-call", 3, 0, 0, scm_dynamic_args_call
);
440 scm_dynamic_args_call (func
, dobj
, args
)
441 SCM func
, dobj
, args
;
443 int (*fptr
) (int argc
, char **argv
);
447 if (SCM_NIMP (func
) && SCM_ROSTRINGP (func
))
448 func
= scm_dynamic_func (func
, dobj
);
450 fptr
= (int (*)(int, char **)) scm_num2ulong (func
, (char *)SCM_ARG1
,
451 s_dynamic_args_call
);
453 argv
= scm_make_argv_from_stringlist (args
, &argc
, s_dynamic_args_call
,
455 result
= (*fptr
) (argc
, argv
);
456 scm_must_free_argv (argv
);
459 return SCM_MAKINUM(0L+result
);
463 scm_init_dynamic_linking ()
465 scm_tc16_dynamic_obj
= scm_newsmob (&dynl_obj_smob
);