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, 675 Mass Ave, Cambridge, MA 02139, USA.
19 * As a special exception, the Free Software Foundation gives permission
20 * for additional uses of the text contained in its release of GUILE.
22 * The exception is that, if you link the GUILE library with other files
23 * to produce an executable, this does not by itself cause the
24 * resulting executable to be covered by the GNU General Public License.
25 * Your use of that executable is in no way restricted on account of
26 * linking the GUILE library code into it.
28 * This exception does not however invalidate any other reasons why
29 * the executable file might be covered by the GNU General Public License.
31 * This exception applies only to the code released by the
32 * Free Software Foundation under the name GUILE. If you copy
33 * code from other Free Software Foundation releases into a copy of
34 * GUILE, as the General Public License permits, the exception does
35 * not apply to the code that you add in this way. To avoid misleading
36 * anyone as to the status of such modified files, you must delete
37 * this exception notice from them.
39 * If you write modifications of your own for GUILE, it is your choice
40 * whether to permit this exception to apply to your modifications.
41 * 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
);
68 /* Converting a list of SCM strings into a argv-style array. You must
69 have ints disabled for the whole lifetime of the created argv (from
70 before MAKE_ARGV_FROM_STRINGLIST until after
71 MUST_FREE_ARGV). Atleast this is was the documentation for
72 MAKARGVFROMSTRS says, it isn't really used that way.
74 This code probably belongs into strings.c */
76 static char **scm_make_argv_from_stringlist
SCM_P ((SCM args
, int *argcp
,
77 char *subr
, int argn
));
80 scm_make_argv_from_stringlist (args
, argcp
, subr
, argn
)
89 argc
= scm_ilength(args
);
90 argv
= (char **) scm_must_malloc ((1L+argc
)*sizeof(char *), subr
);
91 for(i
= 0; SCM_NNULLP (args
); args
= SCM_CDR (args
), i
++) {
94 SCM str
= SCM_CAR (args
);
96 SCM_ASSERT (SCM_NIMP (str
) && SCM_ROSTRINGP (str
), str
, argn
, subr
);
97 len
= 1 + SCM_ROLENGTH (str
);
98 dst
= (char *) scm_must_malloc ((long)len
, subr
);
99 src
= SCM_ROCHARS (str
);
111 static void scm_must_free_argv
SCM_P ((char **argv
));
114 scm_must_free_argv(argv
)
123 /* Coerce an arbitrary readonly-string into a zero-terminated string.
126 static SCM scm_coerce_rostring
SCM_P ((SCM rostr
, char *subr
, int argn
));
129 scm_coerce_rostring (rostr
, subr
, argn
)
134 SCM_ASSERT (SCM_NIMP (rostr
) && SCM_ROSTRINGP (rostr
), rostr
, argn
, subr
);
135 if (SCM_SUBSTRP (rostr
))
136 rostr
= scm_makfromstr (SCM_ROCHARS (rostr
), SCM_ROLENGTH (rostr
), 0);
143 /* We can't use SCM objects here. One should be able to call
144 SCM_REGISTER_MODULE from a C++ constructor for a static
145 object. This happens before main and thus before libguile is
149 struct moddata
*link
;
154 static struct moddata
*registered_mods
= NULL
;
157 scm_register_module_xxx (module_name
, init_func
)
163 /* XXX - should we (and can we) DEFER_INTS here? */
165 for (md
= registered_mods
; md
; md
= md
->link
)
166 if (!strcmp (md
->module_name
, module_name
)) {
167 md
->init_func
= init_func
;
171 md
= (struct moddata
*)malloc (sizeof (struct moddata
));
174 "guile: can't register module (%s): not enough memory",
179 md
->module_name
= module_name
;
180 md
->init_func
= init_func
;
181 md
->link
= registered_mods
;
182 registered_mods
= md
;
185 SCM_PROC (s_registered_modules
, "c-registered-modules", 0, 0, 0, scm_registered_modules
);
188 scm_registered_modules ()
194 for (md
= registered_mods
; md
; md
= md
->link
)
195 res
= scm_cons (scm_cons (scm_makfrom0str (md
->module_name
),
196 scm_ulong2num ((unsigned long) md
->init_func
)),
201 SCM_PROC (s_clear_registered_modules
, "c-clear-registered-modules", 0, 0, 0, scm_clear_registered_modules
);
204 scm_clear_registered_modules ()
206 struct moddata
*md1
, *md2
;
210 for (md1
= registered_mods
; md1
; md1
= md2
) {
214 registered_mods
= NULL
;
217 return SCM_UNSPECIFIED
;
220 /* Dispatch to the system dependent files
222 * They define these static functions:
225 static void sysdep_dynl_init
SCM_P ((void));
226 static void *sysdep_dynl_link
SCM_P ((char *filename
, char *subr
));
227 static void sysdep_dynl_unlink
SCM_P ((void *handle
, char *subr
));
228 static void *sysdep_dynl_func
SCM_P ((char *symbol
, void *handle
, char *subr
));
234 #include "dynl-shl.c"
237 #include "dynl-dld.c"
240 /* no dynamic linking available, throw errors. */
251 scm_misc_error (subr
, "dynamic linking not available", SCM_EOL
);
255 sysdep_dynl_link (filename
, subr
)
259 no_dynl_error (subr
);
264 sysdep_dynl_unlink (handle
, subr
)
268 no_dynl_error (subr
);
272 sysdep_dynl_func (symbol
, handle
, subr
)
277 no_dynl_error (subr
);
285 int scm_tc16_dynamic_obj
;
292 static SCM mark_dynl_obj
SCM_P ((SCM ptr
));
297 struct dynl_obj
*d
= (struct dynl_obj
*)SCM_CDR (ptr
);
298 SCM_SETGC8MARK (ptr
);
302 static int print_dynl_obj
SCM_P ((SCM exp
, SCM port
, scm_print_state
*pstate
));
304 print_dynl_obj (exp
, port
, pstate
)
307 scm_print_state
*pstate
;
309 struct dynl_obj
*d
= (struct dynl_obj
*)SCM_CDR (exp
);
310 scm_gen_puts (scm_regular_string
, "#<dynamic-object ", port
);
311 scm_iprin1 (d
->filename
, port
, pstate
);
312 scm_gen_putc ('>', port
);
316 static scm_smobfuns dynl_obj_smob
= {
322 SCM_PROC (s_dynamic_link
, "dynamic-link", 1, 0, 0, scm_dynamic_link
);
325 scm_dynamic_link (fname
)
331 fname
= scm_coerce_rostring (fname
, s_dynamic_link
, SCM_ARG1
);
332 d
= (struct dynl_obj
*)scm_must_malloc (sizeof (struct dynl_obj
),
337 d
->handle
= sysdep_dynl_link (SCM_CHARS (fname
), s_dynamic_link
);
340 SCM_SETCAR (z
, scm_tc16_dynamic_obj
);
346 static struct dynl_obj
*get_dynl_obj
SCM_P ((SCM obj
, char *subr
, int argn
));
347 static struct dynl_obj
*
348 get_dynl_obj (dobj
, subr
, argn
)
354 SCM_ASSERT (SCM_NIMP (dobj
) && SCM_CAR (dobj
) == scm_tc16_dynamic_obj
,
356 d
= (struct dynl_obj
*)SCM_CDR (dobj
);
357 SCM_ASSERT (d
->handle
!= NULL
, dobj
, argn
, subr
);
361 SCM_PROC (s_dynamic_object_p
, "dynamic-object?", 1, 0, 0, scm_dynamic_object_p
);
364 scm_dynamic_object_p (SCM obj
)
366 return (SCM_NIMP (obj
) && SCM_CAR (obj
) == scm_tc16_dynamic_obj
)?
367 SCM_BOOL_T
: SCM_BOOL_F
;
370 SCM_PROC (s_dynamic_unlink
, "dynamic-unlink", 1, 0, 0, scm_dynamic_unlink
);
373 scm_dynamic_unlink (dobj
)
376 struct dynl_obj
*d
= get_dynl_obj (dobj
, s_dynamic_unlink
, SCM_ARG1
);
377 sysdep_dynl_unlink (d
->handle
, s_dynamic_unlink
);
382 SCM_PROC (s_dynamic_func
, "dynamic-func", 2, 0, 0, scm_dynamic_func
);
385 scm_dynamic_func (SCM symb
, SCM dobj
)
390 symb
= scm_coerce_rostring (symb
, s_dynamic_func
, SCM_ARG1
);
391 d
= get_dynl_obj (dobj
, s_dynamic_func
, SCM_ARG2
);
393 func
= sysdep_dynl_func (SCM_CHARS (symb
), d
->handle
, s_dynamic_func
);
394 return scm_ulong2num ((unsigned long)func
);
397 SCM_PROC (s_dynamic_call
, "dynamic-call", 2, 0, 0, scm_dynamic_call
);
400 scm_dynamic_call (SCM func
, SCM dobj
)
404 if (SCM_NIMP (func
) && SCM_ROSTRINGP (func
))
405 func
= scm_dynamic_func (func
, dobj
);
406 fptr
= (void (*)()) scm_num2ulong (func
, (char *)SCM_ARG1
, s_dynamic_call
);
411 SCM_PROC (s_dynamic_args_call
, "dynamic-args-call", 3, 0, 0, scm_dynamic_args_call
);
414 scm_dynamic_args_call (func
, dobj
, args
)
415 SCM func
, dobj
, args
;
417 int (*fptr
) (int argc
, char **argv
);
421 if (SCM_NIMP (func
) && SCM_ROSTRINGP (func
))
422 func
= scm_dynamic_func (func
, dobj
);
424 fptr
= (int (*)(int, char **)) scm_num2ulong (func
, (char *)SCM_ARG1
,
425 s_dynamic_args_call
);
426 argv
= scm_make_argv_from_stringlist (args
, &argc
, s_dynamic_args_call
,
429 result
= (*fptr
) (argc
, argv
);
431 scm_must_free_argv (argv
);
432 return SCM_MAKINUM(0L+result
);
436 scm_init_dynamic_linking ()
438 scm_tc16_dynamic_obj
= scm_newsmob (&dynl_obj_smob
);