1 ;;;; Foreign symbol linkage
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!IMPL")
14 ;;; *STATIC-FOREIGN-SYMBOLS* are static as opposed to "dynamic" (not
15 ;;; as opposed to C's "extern"). The table contains symbols known at
16 ;;; the time that the program was built, but not symbols defined in
17 ;;; object files which have been loaded dynamically since then.
18 (declaim (type hash-table *static-foreign-symbols*))
19 (defvar *static-foreign-symbols* (make-hash-table :test 'equal))
21 (defun find-foreign-symbol-in-table (name table)
22 (some (lambda (prefix)
23 (gethash (concatenate 'string prefix name) table))
26 (defun foreign-symbol-address-as-integer-or-nil (name &optional datap)
27 (declare (ignorable datap))
28 (or (find-foreign-symbol-in-table name *static-foreign-symbols*)
32 (values #!-linkage-table
33 (get-dynamic-foreign-symbol-address name)
35 (ensure-foreign-symbol-linkage name datap)
38 (defun foreign-symbol-address-as-integer (name &optional datap)
39 (or (foreign-symbol-address-as-integer-or-nil name datap)
40 (error "Unknown foreign symbol: ~S" name)))
42 (defun foreign-symbol-address (symbol &optional datap)
43 (declare (ignorable datap))
44 (let ((name (sb!vm:extern-alien-name symbol)))
46 (int-sap (foreign-symbol-address-as-integer name))
48 (multiple-value-bind (addr sharedp)
49 (foreign-symbol-address-as-integer name datap)
52 ;; If the address is from linkage-table and refers to data
53 ;; we need to do a bit of juggling.
54 (if (and sharedp datap)
55 ;; FIXME: 64bit badness here
56 (int-sap (sap-ref-32 (int-sap addr) 0))
60 (defun foreign-reinit ()
62 (reopen-shared-objects)
64 (linkage-table-reinit))
66 ;;; Cleanups before saving a core
68 (defun foreign-deinit ()
69 #!+(and os-provides-dlopen (not linkage-table))
70 (let ((shared (remove-if #'null (mapcar #'sb!alien::shared-object-file
73 (warn "~@<Saving cores with shared objects loaded is unsupported on ~
74 this platform: calls to foreign functions in shared objects ~
75 from the restarted core will not work. You may be able to ~
76 work around this limitation by reloading all foreign definitions ~
77 and code using them in the restarted core, but no guarantees.~%~%~
78 Shared objects in this image:~% ~{~A~^, ~}~:@>"
81 (close-shared-objects))
83 (defun foreign-symbol-in-address (sap)
84 (declare (ignorable sap))
86 (let ((addr (sap-int sap)))
87 (declare (ignorable addr))
89 (when (<= sb!vm:linkage-table-space-start
91 sb!vm:linkage-table-space-end)
92 (maphash (lambda (name info)
93 (let ((table-addr (linkage-info-address info)))
96 (+ table-addr sb!vm:linkage-table-entry-size))
97 (return-from foreign-symbol-in-address name))))
100 (with-alien ((info (struct dl-info
104 (symbol-address unsigned)))
105 (dladdr (function unsigned unsigned (* (struct dl-info)))
107 (let ((err (alien-funcall dladdr addr (addr info))))
110 (slot info 'symbol))))
111 ;; FIXME: Even in the absence of dladdr we could search the
112 ;; static foreign symbols (and *linkage-info*, for that matter).
115 ;;; How we learn about foreign symbols and dlhandles initially
116 (defvar *!initial-foreign-symbols*)
119 (defun !foreign-cold-init ()
120 (dolist (symbol *!initial-foreign-symbols*)
121 (setf (gethash (car symbol) *static-foreign-symbols*) (cdr symbol)))
122 #!+os-provides-dlopen
123 (setf *runtime-dlhandle* (dlopen-or-lose nil)
124 *shared-objects* nil))
126 #!-os-provides-dlopen
127 (define-unsupported-fun load-shared-object)