1 /* GMODULE - GLIB wrapper code for dynamic module loading 2 * Copyright (C) 1998, 2000 Tim Janik 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with this library; if not, write to the 16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 17 * Boston, MA 02111-1307, USA. 18 */ 19 20 /* 21 * Modified by the GLib Team and others 1997-2000. See the AUTHORS 22 * file for a list of people on the GLib Team. See the ChangeLog 23 * files for a list of changes. These files are distributed with 24 * GLib at ftp://ftp.gtk.org/pub/gtk/. 25 */ 26 27 /* 28 * MT safe 29 */ 30 #include "config.h" 31 32 #include <dl.h> 33 34 35 /* some flags are missing on some systems, so we provide 36 * harmless defaults. 37 * 38 * Mandatory: 39 * BIND_IMMEDIATE - Resolve symbol references when the library is loaded. 40 * BIND_DEFERRED - Delay code symbol resolution until actual reference. 41 * 42 * Optionally: 43 * BIND_FIRST - Place the library at the head of the symbol search order. 44 * BIND_NONFATAL - The default BIND_IMMEDIATE behavior is to treat all unsatisfied 45 * symbols as fatal. This flag allows binding of unsatisfied code 46 * symbols to be deferred until use. 47 * [Perl: For certain libraries, like DCE, deferred binding often 48 * causes run time problems. Adding BIND_NONFATAL to BIND_IMMEDIATE 49 * still allows unresolved references in situations like this.] 50 * BIND_NOSTART - Do not call the initializer for the shared library when the 51 * library is loaded, nor on a future call to shl_unload(). 52 * BIND_VERBOSE - Print verbose messages concerning possible unsatisfied symbols. 53 * 54 * hp9000s700/hp9000s800: 55 * BIND_RESTRICTED - Restrict symbols visible by the library to those present at 56 * library load time. 57 * DYNAMIC_PATH - Allow the loader to dynamically search for the library specified 58 * by the path argument. 59 */ 60 #ifndef DYNAMIC_PATH 61 #define DYNAMIC_PATH 0 62 #endif /* DYNAMIC_PATH */ 63 #ifndef BIND_RESTRICTED 64 #define BIND_RESTRICTED 0 65 #endif /* BIND_RESTRICTED */ 66 67 #define OPT_BIND_FLAGS (BIND_NONFATAL | BIND_VERBOSE) 68 69 70 /* --- functions --- */ 71 72 /* 73 * shl_load() does not appear to support making symbols invisible to 74 * the global namespace. However, the default is to put the library 75 * last in the search order, which is approximately what we want, 76 * since it will cause symbols that conflict with existing symbols to 77 * be invisible. It is unclear if BIND_FIRST should be used when 78 * bind_local==0, since it may cause the loaded symbols to be used 79 * preferentially to the application's symbols, which is Almost 80 * Always Wrong. --ds 81 */ 82 static gpointer 83 _g_module_open (const gchar *file_name, 84 gboolean bind_lazy, 85 gboolean bind_local) 86 { 87 shl_t shl_handle; 88 89 shl_handle = shl_load (file_name, 90 (bind_lazy ? BIND_DEFERRED : BIND_IMMEDIATE) | OPT_BIND_FLAGS, 0); 91 if (!shl_handle) 92 { 93 /* the hp-docs say we should better abort() if errno==ENOSYM ;( */ 94 g_module_set_error (g_strerror (errno)); 95 } 96 97 return (gpointer) shl_handle; 98 } 99 100 static gpointer 101 _g_module_self (void) 102 { 103 shl_t shl_handle; 104 105 shl_handle = PROG_HANDLE; 106 if (!shl_handle) 107 g_module_set_error (g_strerror (errno)); 108 109 return shl_handle; 110 } 111 112 static void 113 _g_module_close (gpointer handle, 114 gboolean is_unref) 115 { 116 if (!is_unref) 117 { 118 if (shl_unload ((shl_t) handle) != 0) 119 g_module_set_error (g_strerror (errno)); 120 } 121 } 122 123 static gpointer 124 _g_module_symbol (gpointer handle, 125 const gchar *symbol_name) 126 { 127 gpointer p = NULL; 128 129 /* should we restrict lookups to TYPE_PROCEDURE? 130 */ 131 if (handle == PROG_HANDLE) 132 { 133 /* PROG_HANDLE will only lookup symbols in the program itself, not honouring 134 * libraries. passing NULL as a handle will also try to lookup the symbol 135 * in currently loaded libraries. fix pointed out and supplied by: 136 * David Gero <dgero (at) nortelnetworks.com> 137 */ 138 handle = NULL; 139 } 140 if (shl_findsym ((shl_t*) &handle, symbol_name, TYPE_UNDEFINED, &p) != 0 || 141 handle == NULL || p == NULL) 142 { 143 /* the hp-docs say we should better abort() if errno==ENOSYM ;( */ 144 g_module_set_error (g_strerror (errno)); 145 } 146 147 return p; 148 } 149 150 static gchar* 151 _g_module_build_path (const gchar *directory, 152 const gchar *module_name) 153 { 154 if (directory && *directory) 155 if (strncmp (module_name, "lib", 3) == 0) 156 return g_strconcat (directory, "/", module_name, NULL); 157 else 158 return g_strconcat (directory, "/lib", module_name, ".sl", NULL); 159 else if (strncmp (module_name, "lib", 3) == 0) 160 return g_strdup (module_name); 161 else 162 return g_strconcat ("lib", module_name, ".sl", NULL); 163 } 164