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 ;; KLUDGE: Giving this warning only when non-static foreign symbols
70 ;; are used would be much nicer, but actually pretty hard: we can
71 ;; get dynamic symbols thru the runtime as well, so cheking the
72 ;; list of *shared-objects* is not enough. Eugh & blech.
73 #!+(and os-provides-dlopen (not linkage-table))
74 (warn "~@<Saving cores with alien definitions referring to non-static
75 foreign symbols is unsupported on this platform: references to
76 such foreign symbols from the restarted core will not work. You
77 may be able to work around this limitation by reloading all
78 foreign definitions and code using them in the restarted core,
79 but no guarantees.~%~:@>")
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)