1499c9786d1316bc72c539d55786bb3a65d95a83aCDT/* GMODULE - GLIB wrapper code for dynamic module loading 2d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik * Copyright (C) 1998, 2000 Tim Janik 3499c9786d1316bc72c539d55786bb3a65d95a83aCDT * 4499c9786d1316bc72c539d55786bb3a65d95a83aCDT * BeOS GMODULE implementation 5499c9786d1316bc72c539d55786bb3a65d95a83aCDT * Copyright (C) 1999 Richard Offer and Shawn T. Amundson (amundson@gtk.org) 6499c9786d1316bc72c539d55786bb3a65d95a83aCDT * 7499c9786d1316bc72c539d55786bb3a65d95a83aCDT * This library is free software; you can redistribute it and/or 8c9bd7542e1a28ba9de60048361c0a97d251833e7Tim Janik * modify it under the terms of the GNU Lesser General Public 9499c9786d1316bc72c539d55786bb3a65d95a83aCDT * License as published by the Free Software Foundation; either 10499c9786d1316bc72c539d55786bb3a65d95a83aCDT * version 2 of the License, or (at your option) any later version. 11499c9786d1316bc72c539d55786bb3a65d95a83aCDT * 12499c9786d1316bc72c539d55786bb3a65d95a83aCDT * This library is distributed in the hope that it will be useful, 13499c9786d1316bc72c539d55786bb3a65d95a83aCDT * but WITHOUT ANY WARRANTY; without even the implied warranty of 14499c9786d1316bc72c539d55786bb3a65d95a83aCDT * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15c9bd7542e1a28ba9de60048361c0a97d251833e7Tim Janik * Lesser General Public License for more details. 16499c9786d1316bc72c539d55786bb3a65d95a83aCDT * 17c9bd7542e1a28ba9de60048361c0a97d251833e7Tim Janik * You should have received a copy of the GNU Lesser General Public 18499c9786d1316bc72c539d55786bb3a65d95a83aCDT * License along with this library; if not, write to the 19499c9786d1316bc72c539d55786bb3a65d95a83aCDT * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 20499c9786d1316bc72c539d55786bb3a65d95a83aCDT * Boston, MA 02111-1307, USA. 21499c9786d1316bc72c539d55786bb3a65d95a83aCDT */ 22499c9786d1316bc72c539d55786bb3a65d95a83aCDT 23499c9786d1316bc72c539d55786bb3a65d95a83aCDT/* 24499c9786d1316bc72c539d55786bb3a65d95a83aCDT * MT safe 25499c9786d1316bc72c539d55786bb3a65d95a83aCDT */ 269757456e23195ae9496c059b0235dcf8768185cdMatthias Clasen#include "config.h" 27499c9786d1316bc72c539d55786bb3a65d95a83aCDT 28499c9786d1316bc72c539d55786bb3a65d95a83aCDT#include <be/kernel/image.h> /* image (aka DSO) handling functions... */ 29499c9786d1316bc72c539d55786bb3a65d95a83aCDT 30499c9786d1316bc72c539d55786bb3a65d95a83aCDT/* 31499c9786d1316bc72c539d55786bb3a65d95a83aCDT * The BeOS doesn't use the same symantics as Unix's dlopen.... 32499c9786d1316bc72c539d55786bb3a65d95a83aCDT * 33499c9786d1316bc72c539d55786bb3a65d95a83aCDT */ 34499c9786d1316bc72c539d55786bb3a65d95a83aCDT#ifndef RTLD_GLOBAL 35499c9786d1316bc72c539d55786bb3a65d95a83aCDT#define RTLD_GLOBAL 0 36499c9786d1316bc72c539d55786bb3a65d95a83aCDT#endif /* RTLD_GLOBAL */ 37499c9786d1316bc72c539d55786bb3a65d95a83aCDT#ifndef RTLD_LAZY 38499c9786d1316bc72c539d55786bb3a65d95a83aCDT#define RTLD_LAZY 1 39499c9786d1316bc72c539d55786bb3a65d95a83aCDT#endif /* RTLD_LAZY */ 40499c9786d1316bc72c539d55786bb3a65d95a83aCDT#ifndef RTLD_NOW 41499c9786d1316bc72c539d55786bb3a65d95a83aCDT#define RTLD_NOW 0 42499c9786d1316bc72c539d55786bb3a65d95a83aCDT#endif /* RTLD_NOW */ 43499c9786d1316bc72c539d55786bb3a65d95a83aCDT 44499c9786d1316bc72c539d55786bb3a65d95a83aCDT 45499c9786d1316bc72c539d55786bb3a65d95a83aCDT/* 46499c9786d1316bc72c539d55786bb3a65d95a83aCDT * Points to Ponder 47499c9786d1316bc72c539d55786bb3a65d95a83aCDT * 48499c9786d1316bc72c539d55786bb3a65d95a83aCDT * You can load the same DSO more than once, in which case you'll have 49499c9786d1316bc72c539d55786bb3a65d95a83aCDT * different image_id's. While this means that we don't have to worry about 50499c9786d1316bc72c539d55786bb3a65d95a83aCDT * reference counts, it could lead to problems in the future.... 51499c9786d1316bc72c539d55786bb3a65d95a83aCDT * richard. 52defca980e4c4c899f18d8a8c17b629306abfe41cTim Janik * 53defca980e4c4c899f18d8a8c17b629306abfe41cTim Janik * load_add_on() apparently does not support lazy or local binding. Need 54defca980e4c4c899f18d8a8c17b629306abfe41cTim Janik * to confirm that the actual behavior is non-lazy/local. --ds 55499c9786d1316bc72c539d55786bb3a65d95a83aCDT */ 56499c9786d1316bc72c539d55786bb3a65d95a83aCDT 57499c9786d1316bc72c539d55786bb3a65d95a83aCDT#include <Errors.h> 58499c9786d1316bc72c539d55786bb3a65d95a83aCDT#include <stdio.h> 59499c9786d1316bc72c539d55786bb3a65d95a83aCDT 60499c9786d1316bc72c539d55786bb3a65d95a83aCDT/* --- functions --- */ 61499c9786d1316bc72c539d55786bb3a65d95a83aCDTstatic gpointer 62d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik_g_module_open (const gchar *file_name, 63defca980e4c4c899f18d8a8c17b629306abfe41cTim Janik gboolean bind_lazy, 64defca980e4c4c899f18d8a8c17b629306abfe41cTim Janik gboolean bind_local) 65499c9786d1316bc72c539d55786bb3a65d95a83aCDT{ 66499c9786d1316bc72c539d55786bb3a65d95a83aCDT image_id handle; 67499c9786d1316bc72c539d55786bb3a65d95a83aCDT 68499c9786d1316bc72c539d55786bb3a65d95a83aCDT handle = load_add_on (file_name); 69d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik if (handle < B_OK) 70d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik { 71d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik gchar *msg = g_strdup_printf ("failed to load_add_on(%s): %s", 72d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik file_name, 73d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik strerror (handle)); 74d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik 75d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik g_module_set_error (msg); 76d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik g_free (msg); 77d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik 78d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik return NULL; 79d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik } 80d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik 81499c9786d1316bc72c539d55786bb3a65d95a83aCDT return (gpointer) handle; 82499c9786d1316bc72c539d55786bb3a65d95a83aCDT} 83499c9786d1316bc72c539d55786bb3a65d95a83aCDT 84499c9786d1316bc72c539d55786bb3a65d95a83aCDTstatic gpointer 85499c9786d1316bc72c539d55786bb3a65d95a83aCDT_g_module_self (void) 86499c9786d1316bc72c539d55786bb3a65d95a83aCDT{ 87499c9786d1316bc72c539d55786bb3a65d95a83aCDT image_info info; 88499c9786d1316bc72c539d55786bb3a65d95a83aCDT int32 cookie = 0; 89499c9786d1316bc72c539d55786bb3a65d95a83aCDT status_t status; 90d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik 91499c9786d1316bc72c539d55786bb3a65d95a83aCDT /* Is it always the first one? I'm guessing yes. */ 92d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik status = get_next_image_info (0, &cookie, &info); 93d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik if (status == B_OK) 94499c9786d1316bc72c539d55786bb3a65d95a83aCDT return (gpointer) info.id; 95499c9786d1316bc72c539d55786bb3a65d95a83aCDT else 96499c9786d1316bc72c539d55786bb3a65d95a83aCDT { 97d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik gchar *msg = g_strdup_printf ("failed to get_next_image_info(self): %s", 98d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik strerror (status)); 99d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik 100d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik g_module_set_error (msg); 101d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik g_free (msg); 102d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik 103499c9786d1316bc72c539d55786bb3a65d95a83aCDT return NULL; 104499c9786d1316bc72c539d55786bb3a65d95a83aCDT } 105499c9786d1316bc72c539d55786bb3a65d95a83aCDT} 106499c9786d1316bc72c539d55786bb3a65d95a83aCDT 107499c9786d1316bc72c539d55786bb3a65d95a83aCDTstatic void 108d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik_g_module_close (gpointer handle, 109d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik gboolean is_unref) 110499c9786d1316bc72c539d55786bb3a65d95a83aCDT{ 111d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik image_info info; 112d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik gchar *name; 113d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik 114d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik if (unload_add_on ((image_id) handle) != B_OK) 115d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik { 116d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik gchar *msg; 117d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik 118d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik /* Try and get the name of the image. */ 119d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik if (get_image_info ((image_id) handle, &info) != B_OK) 120d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik name = g_strdup ("unknown"); 121d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik else 122d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik name = g_strdup (info.name); 123d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik 124d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik msg = g_strdup_printf ("failed to unload_add_on(%s): %s", name, strerror (status)); 125d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik g_module_set_error (msg); 126d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik g_free (msg); 127d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik g_free (name); 128d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik } 129499c9786d1316bc72c539d55786bb3a65d95a83aCDT} 130499c9786d1316bc72c539d55786bb3a65d95a83aCDT 131499c9786d1316bc72c539d55786bb3a65d95a83aCDTstatic gpointer 132d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik_g_module_symbol (gpointer handle, 133d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik const gchar *symbol_name) 134499c9786d1316bc72c539d55786bb3a65d95a83aCDT{ 135499c9786d1316bc72c539d55786bb3a65d95a83aCDT image_id id; 136499c9786d1316bc72c539d55786bb3a65d95a83aCDT status_t status; 137499c9786d1316bc72c539d55786bb3a65d95a83aCDT image_info info; 138d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik int32 type, name_len; 139d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik void *p; 140d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik gchar *msg, name[256]; 141d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik gint n, l; 142d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik 143499c9786d1316bc72c539d55786bb3a65d95a83aCDT id = (image_id) handle; 144d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik 145d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik status = get_image_info (id, &info); 146d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik if (status != B_OK) 147499c9786d1316bc72c539d55786bb3a65d95a83aCDT { 148d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik msg = g_strdup_printf ("failed to get_image_info(): %s", strerror (status)); 149d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik g_module_set_error (msg); 150d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik g_free (msg); 151d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik 152499c9786d1316bc72c539d55786bb3a65d95a83aCDT return NULL; 153499c9786d1316bc72c539d55786bb3a65d95a83aCDT } 154d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik 155d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik l = strlen (symbol_name); 156499c9786d1316bc72c539d55786bb3a65d95a83aCDT name_len = 256; 157499c9786d1316bc72c539d55786bb3a65d95a83aCDT type = B_SYMBOL_TYPE_ANY; 158499c9786d1316bc72c539d55786bb3a65d95a83aCDT n = 0; 159d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik status = get_nth_image_symbol (id, n, name, &name_len, &type, &p); 160d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik while (status == B_OK) 161499c9786d1316bc72c539d55786bb3a65d95a83aCDT { 162d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik if (p && strncmp (name, symbol_name, l) == 0) 163d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik return p; 164d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik 165d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik if (strcmp (name, "_end") == 0) 166499c9786d1316bc72c539d55786bb3a65d95a83aCDT { 167d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik msg = g_strdup_printf ("unmatched symbol name `%s'", symbol_name); 168d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik g_module_set_error (msg); 169d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik g_free (msg); 170d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik 171d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik return NULL; 172499c9786d1316bc72c539d55786bb3a65d95a83aCDT } 173d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik 174499c9786d1316bc72c539d55786bb3a65d95a83aCDT name_len = 256; 175499c9786d1316bc72c539d55786bb3a65d95a83aCDT type = B_SYMBOL_TYPE_ANY; 176499c9786d1316bc72c539d55786bb3a65d95a83aCDT n++; 177d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik status = get_nth_image_symbol (id, n, name, &name_len, &type, &p); 178499c9786d1316bc72c539d55786bb3a65d95a83aCDT } 179d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik 180d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik msg = g_strdup_printf ("failed to get_image_symbol(%s): %s", symbol_name, strerror (status)); 181d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik g_module_set_error (msg); 182d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik g_free (msg); 183d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik 184499c9786d1316bc72c539d55786bb3a65d95a83aCDT return NULL; 185499c9786d1316bc72c539d55786bb3a65d95a83aCDT} 186499c9786d1316bc72c539d55786bb3a65d95a83aCDT 187499c9786d1316bc72c539d55786bb3a65d95a83aCDTstatic gchar* 188499c9786d1316bc72c539d55786bb3a65d95a83aCDT_g_module_build_path (const gchar *directory, 189499c9786d1316bc72c539d55786bb3a65d95a83aCDT const gchar *module_name) 190499c9786d1316bc72c539d55786bb3a65d95a83aCDT{ 191d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik g_warning ("_g_module_build_path() untested for BeOS!"); 192d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik 193d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik if (directory && *directory) 194d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik { 195d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik if (strncmp (module_name, "lib", 3) == 0) 196d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik return g_strconcat (directory, "/", module_name, NULL); 197d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik else 198c2d49b8f7e57e5527ec400677164ec0862005fa9Owen Taylor return g_strconcat (directory, "/lib", module_name, "." G_MODULE_SUFFIX, NULL); 199d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik } 200d568a76ae4976e0aa01e26e868121a07b4e91338Tim Janik else if (strncmp (module_name, "lib", 3) == 0) 201499c9786d1316bc72c539d55786bb3a65d95a83aCDT return g_strdup (module_name); 202499c9786d1316bc72c539d55786bb3a65d95a83aCDT else 203c2d49b8f7e57e5527ec400677164ec0862005fa9Owen Taylor return g_strconcat ("lib", module_name, "." G_MODULE_SUFFIX, NULL); 204499c9786d1316bc72c539d55786bb3a65d95a83aCDT} 205