From: Nikodemus S. <tsi...@cc...> - 2003-09-27 17:02:32
|
The appended patch fixes the problem I reported earlier with libc variables such as environ and load-1-foreign. The rationale of using the runtime handle for all symbols is here: http://www.opengroup.org/onlinepubs/007904975/functions/dlopen.html The essential bit goes: "If the value of file is 0, dlopen() shall provide a handle on a global symbol object. This object shall provide access to the symbols from an ordered set of objects consisting of the original program image file, together with any objects loaded at program start-up as specified by that process image file (for example, shared libraries), and the set of objects loaded using a dlopen() operation together with the RTLD_GLOBAL flag. As the latter set of objects can change during execution, the set identified by handle can also change dynamically." Cheers, -- Nikodemus Index: src/code/foreign.lisp =================================================================== RCS file: /cvsroot/sbcl/sbcl/src/code/foreign.lisp,v retrieving revision 1.18 diff -u -r1.18 foreign.lisp --- src/code/foreign.lisp 29 Jul 2003 13:01:55 -0000 1.18 +++ src/code/foreign.lisp 27 Sep 2003 16:41:12 -0000 @@ -82,9 +82,11 @@ ; obj file were linked directly ; into the program)? -;;; a list of handles returned from dlopen(3) (or possibly some -;;; bogus value temporarily during initialization) +;;; A list of handles returned from dlopen(3) (or possibly some +;;; bogus value temporarily during initialization). The runtime +;;; handle is kept in *GLOBAL-DLHANDLE*. (defvar *handles-from-dlopen* nil) +(defvar *global-dlhandle*) ;;; Dynamically loaded stuff isn't there upon restoring from a save. ;;; Clearing the variable this way was originally done primarily for @@ -108,7 +110,9 @@ ;;; dan 2001.05.10 suspects that objection (1) is bogus for ;;; dlsym()-enabled systems -(push (lambda () (setq *handles-from-dlopen* nil)) +(push (lambda () + (setq *handles-from-dlopen* nil + *global-dlhandle* nil)) *after-save-initializations*) (defvar *dso-linker* "/usr/bin/ld") @@ -136,11 +140,11 @@ ;;; FIXME: It would work just as well to do it once at startup, actually. ;;; Then at least we know it's done. -dan 2001.05.10 (defun ensure-runtime-symbol-table-opened () - (unless *handles-from-dlopen* + (unless *global-dlhandle* ;; Prevent recursive call if dlopen() isn't defined. - (setf *handles-from-dlopen* (int-sap 0)) - (setf *handles-from-dlopen* (list (dlopen nil rtld-lazy))) - (when (zerop (sb-sys:sap-int (first *handles-from-dlopen*))) + (setf *global-dlhandle* (int-sap 0) + *global-dlhandle* (dlopen nil (logior rtld-lazy rtld-global))) + (when (zerop (sb-sys:sap-int *global-dlhandle*)) (error "can't open our own binary's symbol table: ~S" (dlerror))))) (defun load-1-foreign (file) @@ -169,20 +173,11 @@ (defun get-dynamic-foreign-symbol-address (symbol) (ensure-runtime-symbol-table-opened) - ;; Find the symbol in any of the loaded object files. Search in - ;; reverse order of loading, so that later loadings take precedence. - ;; - ;; FIXME: The way that we use PUSHNEW SAP in LOAD-1-FOREIGN means - ;; that the list isn't guaranteed to be in reverse order of loading, - ;; at least not if a file is loaded more than once. Is this the - ;; right thing? (In what cases does it matter?) - (dolist (handle *handles-from-dlopen*) - ;; KLUDGE: We implicitly exclude the possibility that the variable - ;; could actually be NULL, but the man page for dlsym(3) - ;; recommends doing a more careful test. -- WHN 20000825 - (let ((possible-result (sap-int (dlsym handle symbol)))) + ;; Find the symbol in any of the loaded object files. + ;; Search order is handled by DLSYM. + (let ((possible-result (sap-int (dlsym *global-dlhandle* symbol)))) (unless (zerop possible-result) - (return possible-result))))) + possible-result))) ;;; Dan Barlow's quick summary from IRC 2003-06-21: ;;; fwiw, load-foreign does random stuff with ld so that you can use |