1 ;;;; Loading shared object files
3 ;;;; This software is part of the SBCL system. See the README file for
6 ;;;; This software is derived from the CMU CL system, which was
7 ;;;; written at Carnegie Mellon University and released into the
8 ;;;; public domain. The software is in the public domain and is
9 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
10 ;;;; files for more information.
12 (in-package "SB!ALIEN")
14 (define-unsupported-fun load-foreign
15 "Unsupported as of SBCL 0.8.13. See LOAD-SHARED-OBJECT."
16 "~S is unsupported as of SBCL 0.8.13. See LOAD-SHARED-OBJECT."
19 (define-unsupported-fun load-1-foreign
20 "Unsupported as of SBCL 0.8.13. Please use LOAD-SHARED-OBJECT."
21 "~S is unsupported as of SBCL 0.8.13. Please use LOAD-SHARED-OBJECT."
24 (define-alien-routine dlopen system-area-pointer
25 (file c-string) (mode int))
27 (define-alien-routine dlclose int
28 (handle system-area-pointer))
30 (define-alien-routine dlerror c-string)
32 (define-alien-routine dlsym system-area-pointer
33 (handle system-area-pointer)
36 (defvar *runtime-dlhandle*)
37 (defvar *shared-objects*)
39 (defstruct shared-object file sap)
41 (defun dlopen-or-lose (filename)
42 (dlerror) ; clear old errors
43 (let ((sap (dlopen filename (logior rtld-global rtld-now))))
44 (when (zerop (sap-int sap))
45 (error "Could not open ~:[runtime~;~:*shared object ~S~]: ~A"
49 (defun load-shared-object (file)
50 "Load a shared library/dynamic shared object file/general
51 dlopenable alien container, such as a .so on an ELF platform.
53 References to foreign symbols in loaded shared objects do not survive
54 intact through SB-EXT:SAVE-LISP-AND die on all platforms. See
55 SB-EXT:SAVE-LISP-AND-DIE for details."
56 (let* ((real-file (or (unix-namestring file) file))
57 (sap (dlopen-or-lose real-file))
58 (obj (make-shared-object :file real-file :sap sap)))
59 (unless (member sap *shared-objects*
60 :test #'sap= :key #'shared-object-sap)
61 (setf *shared-objects* (append *shared-objects* (list obj))))
62 (pathname real-file)))
64 (defun try-reopen-shared-object (obj)
66 (let ((sap (dlopen-or-lose (shared-object-file obj))))
67 (setf (shared-object-sap obj) sap)
70 :report "Skip this shared object and continue. References to ~
71 foreign symbols in this shared object will fail, ~
72 causing potential corruption."
75 ;;; Open libraries in *SHARED-OBJECTS* and the runtime. Called during
77 (defun reopen-shared-objects ()
78 ;; Ensure that the runtime is present in the list
79 (setf *runtime-dlhandle* (dlopen-or-lose nil)
80 *shared-objects* (mapcar #'try-reopen-shared-object *shared-objects*)))
82 ;;; Close all dlopened libraries and clear out sap entries in
84 (defun close-shared-objects ()
85 (dolist (obj (reverse *shared-objects*))
86 (dlclose (shared-object-sap obj))
87 (setf (shared-object-sap obj) nil))
88 (dlclose *runtime-dlhandle*)
89 (setf *runtime-dlhandle* nil))
91 (defun get-dynamic-foreign-symbol-address (symbol)
92 (dlerror) ; clear old errors
93 (let ((result (sap-int (dlsym *runtime-dlhandle* symbol)))
95 (if (or (not (zerop result)) (not err))
97 (dolist (obj *shared-objects*)
98 (setf result (sap-int (dlsym (shared-object-sap obj) symbol))
100 (when (or (not (zerop result)) (not err))