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 /* Software engineering face-lift by Greg J. Badros, 11-Dec-1999,
45 gjb@cs.washington.edu, http://www.cs.washington.edu/homes/gjb */
48 /* "dynl.c" dynamically link&load object files.
50 Modified for libguile by Marius Vollmer */
52 #if 0 /* Disabled until we know for sure that it isn't needed */
53 /* XXX - This is only here to drag in a definition of __eprintf. This
54 is needed for proper operation of dynamic linking. The real
55 solution would probably be a shared libgcc. */
61 maybe_drag_in_eprintf ()
63 assert (!maybe_drag_in_eprintf
);
74 /* Converting a list of SCM strings into a argv-style array. You must
75 have ints disabled for the whole lifetime of the created argv (from
76 before MAKE_ARGV_FROM_STRINGLIST until after
77 MUST_FREE_ARGV). Atleast this is was the documentation for
78 MAKARGVFROMSTRS says, it isn't really used that way.
80 This code probably belongs into strings.c */
83 scm_make_argv_from_stringlist (SCM args
,int *argcp
,const char *subr
,int 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
);
111 scm_must_free_argv(char **argv
)
119 /* Coerce an arbitrary readonly-string into a zero-terminated string.
123 scm_coerce_rostring (SCM rostr
,const char *subr
,int argn
)
125 SCM_ASSERT (SCM_NIMP (rostr
) && SCM_ROSTRINGP (rostr
), rostr
, argn
, subr
);
126 if (SCM_SUBSTRP (rostr
))
127 rostr
= scm_makfromstr (SCM_ROCHARS (rostr
), SCM_ROLENGTH (rostr
), 0);
134 /* We can't use SCM objects here. One should be able to call
135 SCM_REGISTER_MODULE from a C++ constructor for a static
136 object. This happens before main and thus before libguile is
140 struct moddata
*link
;
145 static struct moddata
*registered_mods
= NULL
;
148 scm_register_module_xxx (char *module_name
, void *init_func
)
152 /* XXX - should we (and can we) DEFER_INTS here? */
154 for (md
= registered_mods
; md
; md
= md
->link
)
155 if (!strcmp (md
->module_name
, module_name
)) {
156 md
->init_func
= init_func
;
160 md
= (struct moddata
*)malloc (sizeof (struct moddata
));
163 "guile: can't register module (%s): not enough memory",
168 md
->module_name
= module_name
;
169 md
->init_func
= init_func
;
170 md
->link
= registered_mods
;
171 registered_mods
= md
;
174 GUILE_PROC (scm_registered_modules
, "c-registered-modules", 0, 0, 0,
176 "Return a list of the object code modules that have been imported into
177 the current Guile process. Each element of the list is a pair whose
178 car is the name of the module (as it might be used by
179 @code{use-modules}, for instance), and whose cdr is the function handle
180 for that module's initializer function.")
181 #define FUNC_NAME s_scm_registered_modules
187 for (md
= registered_mods
; md
; md
= md
->link
)
188 res
= scm_cons (scm_cons (scm_makfrom0str (md
->module_name
),
189 scm_ulong2num ((unsigned long) md
->init_func
)),
195 GUILE_PROC (scm_clear_registered_modules
, "c-clear-registered-modules", 0, 0, 0,
197 "Destroy the list of modules registered with the current Guile process.
198 The return value is unspecified. @strong{Warning:} this function does
199 not actually unlink or deallocate these modules, but only destroys the
200 records of which modules have been loaded. It should therefore be used
201 only by module bookkeeping operations.")
202 #define FUNC_NAME s_scm_clear_registered_modules
204 struct moddata
*md1
, *md2
;
208 for (md1
= registered_mods
; md1
; md1
= md2
) {
212 registered_mods
= NULL
;
215 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 #define DYNL_GLOBAL 0x0001
235 #include "dynl-shl.c"
238 #include "dynl-dld.c"
241 /* no dynamic linking available, throw errors. */
244 sysdep_dynl_init (void)
249 no_dynl_error (const char *subr
)
252 scm_misc_error (subr
, "dynamic linking not available", SCM_EOL
);
256 sysdep_dynl_link (const char *filename
,
260 no_dynl_error (subr
);
265 sysdep_dynl_unlink (void *handle
,
268 no_dynl_error (subr
);
272 sysdep_dynl_func (const char *symbol
,
276 no_dynl_error (subr
);
284 int scm_tc16_dynamic_obj
;
292 mark_dynl_obj (SCM ptr
)
294 struct dynl_obj
*d
= (struct dynl_obj
*)SCM_CDR (ptr
);
299 free_dynl_obj (SCM ptr
)
301 scm_must_free ((char *)SCM_CDR (ptr
));
302 return sizeof (struct dynl_obj
);
306 print_dynl_obj (SCM exp
,SCM port
,scm_print_state
*pstate
)
308 struct dynl_obj
*d
= (struct dynl_obj
*)SCM_CDR (exp
);
309 scm_puts ("#<dynamic-object ", port
);
310 scm_iprin1 (d
->filename
, port
, pstate
);
311 if (d
->handle
== NULL
)
312 scm_puts (" (unlinked)", port
);
313 scm_putc ('>', port
);
317 static SCM kw_global
;
318 SCM_SYMBOL (sym_global
, "-global");
320 GUILE_PROC (scm_dynamic_link
, "dynamic-link", 1, 0, 1,
321 (SCM fname
, SCM rest
),
322 "Open the dynamic library @var{library-file}. A library handle
323 representing the opened library is returned; this handle should be used
324 as the @var{lib} argument to the following functions.")
325 #define FUNC_NAME s_scm_dynamic_link
330 int flags
= DYNL_GLOBAL
;
332 fname
= scm_coerce_rostring (fname
, FUNC_NAME
, SCM_ARG1
);
335 while (SCM_NIMP (rest
) && SCM_CONSP (rest
))
340 rest
= SCM_CDR (rest
);
342 if (!(SCM_NIMP (rest
) && SCM_CONSP (rest
)))
343 scm_misc_error (FUNC_NAME
, "keyword without value", SCM_EOL
);
345 val
= SCM_CAR (rest
);
346 rest
= SCM_CDR (rest
);
350 if (SCM_FALSEP (val
))
351 flags
&= ~DYNL_GLOBAL
;
354 scm_misc_error (FUNC_NAME
, "unknown keyword argument: %s",
355 scm_cons (kw
, SCM_EOL
));
359 handle
= sysdep_dynl_link (SCM_CHARS (fname
), flags
, FUNC_NAME
);
361 d
= (struct dynl_obj
*)scm_must_malloc (sizeof (struct dynl_obj
),
368 SCM_SETCAR (z
, scm_tc16_dynamic_obj
);
375 static struct dynl_obj
*
376 get_dynl_obj (SCM dobj
,const char *subr
,int argn
)
379 SCM_ASSERT (SCM_NIMP (dobj
) && SCM_CAR (dobj
) == scm_tc16_dynamic_obj
,
381 d
= (struct dynl_obj
*)SCM_CDR (dobj
);
382 SCM_ASSERT (d
->handle
!= NULL
, dobj
, argn
, subr
);
386 GUILE_PROC (scm_dynamic_object_p
, "dynamic-object?", 1, 0, 0,
388 "Return @code{#t} if @var{obj} is a dynamic library handle, or @code{#f}
390 #define FUNC_NAME s_scm_dynamic_object_p
392 return SCM_BOOL(SCM_NIMP (obj
) && SCM_CAR (obj
) == scm_tc16_dynamic_obj
);
396 GUILE_PROC (scm_dynamic_unlink
, "dynamic-unlink", 1, 0, 0,
398 "Unlink the library represented by @var{library-handle}, and remove any
399 imported symbols from the address space.
400 GJB:FIXME:DOC: 2nd version below:
401 Unlink the indicated object file from the application. The argument
402 @var{dynobj} should be one of the values returned by
403 @code{dynamic-link}. When @code{dynamic-unlink} has been called on
404 @var{dynobj}, it is no longer usable as an argument to the functions
405 below and you will get type mismatch errors when you try to.
407 #define FUNC_NAME s_scm_dynamic_unlink
409 struct dynl_obj
*d
= get_dynl_obj (dobj
, FUNC_NAME
, SCM_ARG1
);
411 sysdep_dynl_unlink (d
->handle
, FUNC_NAME
);
414 return SCM_UNSPECIFIED
;
418 GUILE_PROC (scm_dynamic_func
, "dynamic-func", 2, 0, 0,
419 (SCM symb
, SCM dobj
),
420 "Import the symbol @var{func} from @var{lib} (a dynamic library handle).
421 A @dfn{function handle} representing the imported function is returned.
422 GJB:FIXME:DOC: 2nd version below
423 Search the C function indicated by @var{function} (a string or symbol)
424 in @var{dynobj} and return some Scheme object that can later be used
425 with @code{dynamic-call} to actually call this function. Right now,
426 these Scheme objects are formed by casting the address of the function
427 to @code{long} and converting this number to its Scheme representation.
429 Regardless whether your C compiler prepends an underscore @samp{_} to
430 the global names in a program, you should @strong{not} include this
431 underscore in @var{function}. Guile knows whether the underscore is
432 needed or not and will add it when necessary.
435 #define FUNC_NAME s_scm_dynamic_func
440 symb
= scm_coerce_rostring (symb
, FUNC_NAME
, SCM_ARG1
);
441 d
= get_dynl_obj (dobj
, FUNC_NAME
, SCM_ARG2
);
444 func
= (void (*) ()) sysdep_dynl_func (SCM_CHARS (symb
), d
->handle
,
448 return scm_ulong2num ((unsigned long)func
);
452 GUILE_PROC (scm_dynamic_call
, "dynamic-call", 2, 0, 0,
453 (SCM func
, SCM dobj
),
454 "Call @var{lib-thunk}, a procedure of no arguments. If @var{lib-thunk}
455 is a string, it is assumed to be a symbol found in the dynamic library
456 @var{lib} and is fetched with @code{dynamic-func}. Otherwise, it should
457 be a function handle returned by a previous call to @code{dynamic-func}.
458 The return value is unspecified.
459 GJB:FIXME:DOC 2nd version below
460 Call the C function indicated by @var{function} and @var{dynobj}. The
461 function is passed no arguments and its return value is ignored. When
462 @var{function} is something returned by @code{dynamic-func}, call that
463 function and ignore @var{dynobj}. When @var{function} is a string (or
464 symbol, etc.), look it up in @var{dynobj}; this is equivalent to
467 (dynamic-call (dynamic-func @var{function} @var{dynobj} #f))
470 Interrupts are deferred while the C function is executing (with
471 @code{SCM_DEFER_INTS}/@code{SCM_ALLOW_INTS}).
473 #define FUNC_NAME s_scm_dynamic_call
477 if (SCM_NIMP (func
) && SCM_ROSTRINGP (func
))
478 func
= scm_dynamic_func (func
, dobj
);
479 fptr
= (void (*)()) scm_num2ulong (func
, (char *)SCM_ARG1
, FUNC_NAME
);
483 return SCM_UNSPECIFIED
;
487 GUILE_PROC (scm_dynamic_args_call
, "dynamic-args-call", 3, 0, 0,
488 (SCM func
, SCM dobj
, SCM args
),
489 "Call @var{proc}, a dynamically loaded function, passing it the argument
490 list @var{args} (a list of strings). As with @code{dynamic-call},
491 @var{proc} should be either a function handle or a string, in which case
492 it is first fetched from @var{lib} with @code{dynamic-func}.
494 @var{proc} is assumed to return an integer, which is used as the return
495 value from @code{dynamic-args-call}.
497 GJB:FIXME:DOC 2nd version below
498 Call the C function indicated by @var{function} and @var{dynobj}, just
499 like @code{dynamic-call}, but pass it some arguments and return its
500 return value. The C function is expected to take two arguments and
501 return an @code{int}, just like @code{main}:
504 int c_func (int argc, char **argv);
507 The parameter @var{args} must be a list of strings and is converted into
508 an array of @code{char *}. The array is passed in @var{argv} and its
509 size in @var{argc}. The return value is converted to a Scheme number
510 and returned from the call to @code{dynamic-args-call}.
514 #define FUNC_NAME s_scm_dynamic_args_call
516 int (*fptr
) (int argc
, char **argv
);
520 if (SCM_NIMP (func
) && SCM_ROSTRINGP (func
))
521 func
= scm_dynamic_func (func
, dobj
);
523 fptr
= (int (*)(int, char **)) scm_num2ulong (func
, (char *)SCM_ARG1
,
526 argv
= scm_make_argv_from_stringlist (args
, &argc
, FUNC_NAME
,
528 result
= (*fptr
) (argc
, argv
);
529 scm_must_free_argv (argv
);
532 return SCM_MAKINUM(0L+result
);
537 scm_init_dynamic_linking ()
539 scm_tc16_dynamic_obj
= scm_make_smob_type_mfpe ("dynamic-object", sizeof (struct dynl_obj
),
540 mark_dynl_obj
, free_dynl_obj
,
541 print_dynl_obj
, NULL
);
544 kw_global
= scm_make_keyword_from_dash_symbol (sym_global
);