1160814Ssimon/* dso_dlfcn.c -*- mode:C; c-file-style: "eay" -*- */ 2296341Sdelphij/* 3296341Sdelphij * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project 4296341Sdelphij * 2000. 568651Skris */ 668651Skris/* ==================================================================== 768651Skris * Copyright (c) 2000 The OpenSSL Project. All rights reserved. 868651Skris * 968651Skris * Redistribution and use in source and binary forms, with or without 1068651Skris * modification, are permitted provided that the following conditions 1168651Skris * are met: 1268651Skris * 1368651Skris * 1. Redistributions of source code must retain the above copyright 14296341Sdelphij * notice, this list of conditions and the following disclaimer. 1568651Skris * 1668651Skris * 2. Redistributions in binary form must reproduce the above copyright 1768651Skris * notice, this list of conditions and the following disclaimer in 1868651Skris * the documentation and/or other materials provided with the 1968651Skris * distribution. 2068651Skris * 2168651Skris * 3. All advertising materials mentioning features or use of this 2268651Skris * software must display the following acknowledgment: 2368651Skris * "This product includes software developed by the OpenSSL Project 2468651Skris * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 2568651Skris * 2668651Skris * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 2768651Skris * endorse or promote products derived from this software without 2868651Skris * prior written permission. For written permission, please contact 2968651Skris * licensing@OpenSSL.org. 3068651Skris * 3168651Skris * 5. Products derived from this software may not be called "OpenSSL" 3268651Skris * nor may "OpenSSL" appear in their names without prior written 3368651Skris * permission of the OpenSSL Project. 3468651Skris * 3568651Skris * 6. Redistributions of any form whatsoever must retain the following 3668651Skris * acknowledgment: 3768651Skris * "This product includes software developed by the OpenSSL Project 3868651Skris * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 3968651Skris * 4068651Skris * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 4168651Skris * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4268651Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 4368651Skris * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 4468651Skris * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 4568651Skris * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 4668651Skris * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 4768651Skris * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4868651Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 4968651Skris * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 5068651Skris * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 5168651Skris * OF THE POSSIBILITY OF SUCH DAMAGE. 5268651Skris * ==================================================================== 5368651Skris * 5468651Skris * This product includes cryptographic software written by Eric Young 5568651Skris * (eay@cryptsoft.com). This product includes software written by Tim 5668651Skris * Hudson (tjh@cryptsoft.com). 5768651Skris * 5868651Skris */ 5968651Skris 60296341Sdelphij/* 61296341Sdelphij * We need to do this early, because stdio.h includes the header files that 62296341Sdelphij * handle _GNU_SOURCE and other similar macros. Defining it later is simply 63296341Sdelphij * too late, because those headers are protected from re- inclusion. 64296341Sdelphij */ 65279264Sdelphij#ifndef _GNU_SOURCE 66296341Sdelphij# define _GNU_SOURCE /* make sure dladdr is declared */ 67238405Sjkim#endif 68238405Sjkim 6968651Skris#include <stdio.h> 7068651Skris#include "cryptlib.h" 7168651Skris#include <openssl/dso.h> 7268651Skris 7368651Skris#ifndef DSO_DLFCN 7468651SkrisDSO_METHOD *DSO_METHOD_dlfcn(void) 75296341Sdelphij{ 76296341Sdelphij return NULL; 77296341Sdelphij} 7868651Skris#else 7968651Skris 80296341Sdelphij# ifdef HAVE_DLFCN_H 81296341Sdelphij# ifdef __osf__ 82296341Sdelphij# define __EXTENSIONS__ 83296341Sdelphij# endif 84296341Sdelphij# include <dlfcn.h> 85296341Sdelphij# define HAVE_DLINFO 1 86296341Sdelphij# if defined(_AIX) || defined(__CYGWIN__) || \ 87238405Sjkim defined(__SCO_VERSION__) || defined(_SCO_ELF) || \ 88238405Sjkim (defined(__osf__) && !defined(RTLD_NEXT)) || \ 89238405Sjkim (defined(__OpenBSD__) && !defined(RTLD_SELF)) || \ 90296341Sdelphij defined(__ANDROID__) 91296341Sdelphij# undef HAVE_DLINFO 92296341Sdelphij# endif 93238405Sjkim# endif 9468651Skris 9568651Skris/* Part of the hack in "dlfcn_load" ... */ 96296341Sdelphij# define DSO_MAX_TRANSLATED_SIZE 256 9768651Skris 98109998Smarkmstatic int dlfcn_load(DSO *dso); 9968651Skrisstatic int dlfcn_unload(DSO *dso); 10068651Skrisstatic void *dlfcn_bind_var(DSO *dso, const char *symname); 10168651Skrisstatic DSO_FUNC_TYPE dlfcn_bind_func(DSO *dso, const char *symname); 102296341Sdelphij# if 0 10368651Skrisstatic int dlfcn_unbind(DSO *dso, char *symname, void *symptr); 10468651Skrisstatic int dlfcn_init(DSO *dso); 10568651Skrisstatic int dlfcn_finish(DSO *dso); 106109998Smarkmstatic long dlfcn_ctrl(DSO *dso, int cmd, long larg, void *parg); 107296341Sdelphij# endif 108109998Smarkmstatic char *dlfcn_name_converter(DSO *dso, const char *filename); 109160814Ssimonstatic char *dlfcn_merger(DSO *dso, const char *filespec1, 110296341Sdelphij const char *filespec2); 111296341Sdelphijstatic int dlfcn_pathbyaddr(void *addr, char *path, int sz); 112238405Sjkimstatic void *dlfcn_globallookup(const char *name); 11368651Skris 11468651Skrisstatic DSO_METHOD dso_meth_dlfcn = { 115296341Sdelphij "OpenSSL 'dlfcn' shared library method", 116296341Sdelphij dlfcn_load, 117296341Sdelphij dlfcn_unload, 118296341Sdelphij dlfcn_bind_var, 119296341Sdelphij dlfcn_bind_func, 12068651Skris/* For now, "unbind" doesn't exist */ 121296341Sdelphij# if 0 122296341Sdelphij NULL, /* unbind_var */ 123296341Sdelphij NULL, /* unbind_func */ 124296341Sdelphij# endif 125296341Sdelphij NULL, /* ctrl */ 126296341Sdelphij dlfcn_name_converter, 127296341Sdelphij dlfcn_merger, 128296341Sdelphij NULL, /* init */ 129296341Sdelphij NULL, /* finish */ 130296341Sdelphij dlfcn_pathbyaddr, 131296341Sdelphij dlfcn_globallookup 132296341Sdelphij}; 13368651Skris 13468651SkrisDSO_METHOD *DSO_METHOD_dlfcn(void) 135296341Sdelphij{ 136296341Sdelphij return (&dso_meth_dlfcn); 137296341Sdelphij} 13868651Skris 139296341Sdelphij/* 140296341Sdelphij * Prior to using the dlopen() function, we should decide on the flag we 141296341Sdelphij * send. There's a few different ways of doing this and it's a messy 142296341Sdelphij * venn-diagram to match up which platforms support what. So as we don't have 143296341Sdelphij * autoconf yet, I'm implementing a hack that could be hacked further 144296341Sdelphij * relatively easily to deal with cases as we find them. Initially this is to 145296341Sdelphij * cope with OpenBSD. 146296341Sdelphij */ 147296341Sdelphij# if defined(__OpenBSD__) || defined(__NetBSD__) 148296341Sdelphij# ifdef DL_LAZY 149296341Sdelphij# define DLOPEN_FLAG DL_LAZY 150296341Sdelphij# else 151296341Sdelphij# ifdef RTLD_NOW 152296341Sdelphij# define DLOPEN_FLAG RTLD_NOW 153296341Sdelphij# else 154296341Sdelphij# define DLOPEN_FLAG 0 155296341Sdelphij# endif 156296341Sdelphij# endif 157296341Sdelphij# else 158296341Sdelphij# ifdef OPENSSL_SYS_SUNOS 159296341Sdelphij# define DLOPEN_FLAG 1 160296341Sdelphij# else 161296341Sdelphij# define DLOPEN_FLAG RTLD_NOW /* Hope this works everywhere else */ 162296341Sdelphij# endif 163296341Sdelphij# endif 16468651Skris 165296341Sdelphij/* 166296341Sdelphij * For this DSO_METHOD, our meth_data STACK will contain; (i) the handle 167296341Sdelphij * (void*) returned from dlopen(). 16868651Skris */ 16968651Skris 170109998Smarkmstatic int dlfcn_load(DSO *dso) 171296341Sdelphij{ 172296341Sdelphij void *ptr = NULL; 173296341Sdelphij /* See applicable comments in dso_dl.c */ 174296341Sdelphij char *filename = DSO_convert_filename(dso, NULL); 175296341Sdelphij int flags = DLOPEN_FLAG; 17668651Skris 177296341Sdelphij if (filename == NULL) { 178296341Sdelphij DSOerr(DSO_F_DLFCN_LOAD, DSO_R_NO_FILENAME); 179296341Sdelphij goto err; 180296341Sdelphij } 181296341Sdelphij# ifdef RTLD_GLOBAL 182296341Sdelphij if (dso->flags & DSO_FLAG_GLOBAL_SYMBOLS) 183296341Sdelphij flags |= RTLD_GLOBAL; 184296341Sdelphij# endif 185296341Sdelphij ptr = dlopen(filename, flags); 186296341Sdelphij if (ptr == NULL) { 187296341Sdelphij DSOerr(DSO_F_DLFCN_LOAD, DSO_R_LOAD_FAILED); 188296341Sdelphij ERR_add_error_data(4, "filename(", filename, "): ", dlerror()); 189296341Sdelphij goto err; 190296341Sdelphij } 191296341Sdelphij if (!sk_void_push(dso->meth_data, (char *)ptr)) { 192296341Sdelphij DSOerr(DSO_F_DLFCN_LOAD, DSO_R_STACK_ERROR); 193296341Sdelphij goto err; 194296341Sdelphij } 195296341Sdelphij /* Success */ 196296341Sdelphij dso->loaded_filename = filename; 197296341Sdelphij return (1); 198296341Sdelphij err: 199296341Sdelphij /* Cleanup! */ 200296341Sdelphij if (filename != NULL) 201296341Sdelphij OPENSSL_free(filename); 202296341Sdelphij if (ptr != NULL) 203296341Sdelphij dlclose(ptr); 204296341Sdelphij return (0); 205109998Smarkm} 20668651Skris 20768651Skrisstatic int dlfcn_unload(DSO *dso) 208296341Sdelphij{ 209296341Sdelphij void *ptr; 210296341Sdelphij if (dso == NULL) { 211296341Sdelphij DSOerr(DSO_F_DLFCN_UNLOAD, ERR_R_PASSED_NULL_PARAMETER); 212296341Sdelphij return (0); 213296341Sdelphij } 214296341Sdelphij if (sk_void_num(dso->meth_data) < 1) 215296341Sdelphij return (1); 216296341Sdelphij ptr = sk_void_pop(dso->meth_data); 217296341Sdelphij if (ptr == NULL) { 218296341Sdelphij DSOerr(DSO_F_DLFCN_UNLOAD, DSO_R_NULL_HANDLE); 219296341Sdelphij /* 220296341Sdelphij * Should push the value back onto the stack in case of a retry. 221296341Sdelphij */ 222296341Sdelphij sk_void_push(dso->meth_data, ptr); 223296341Sdelphij return (0); 224296341Sdelphij } 225296341Sdelphij /* For now I'm not aware of any errors associated with dlclose() */ 226296341Sdelphij dlclose(ptr); 227296341Sdelphij return (1); 228296341Sdelphij} 22968651Skris 23068651Skrisstatic void *dlfcn_bind_var(DSO *dso, const char *symname) 231296341Sdelphij{ 232296341Sdelphij void *ptr, *sym; 23368651Skris 234296341Sdelphij if ((dso == NULL) || (symname == NULL)) { 235296341Sdelphij DSOerr(DSO_F_DLFCN_BIND_VAR, ERR_R_PASSED_NULL_PARAMETER); 236296341Sdelphij return (NULL); 237296341Sdelphij } 238296341Sdelphij if (sk_void_num(dso->meth_data) < 1) { 239296341Sdelphij DSOerr(DSO_F_DLFCN_BIND_VAR, DSO_R_STACK_ERROR); 240296341Sdelphij return (NULL); 241296341Sdelphij } 242296341Sdelphij ptr = sk_void_value(dso->meth_data, sk_void_num(dso->meth_data) - 1); 243296341Sdelphij if (ptr == NULL) { 244296341Sdelphij DSOerr(DSO_F_DLFCN_BIND_VAR, DSO_R_NULL_HANDLE); 245296341Sdelphij return (NULL); 246296341Sdelphij } 247296341Sdelphij sym = dlsym(ptr, symname); 248296341Sdelphij if (sym == NULL) { 249296341Sdelphij DSOerr(DSO_F_DLFCN_BIND_VAR, DSO_R_SYM_FAILURE); 250296341Sdelphij ERR_add_error_data(4, "symname(", symname, "): ", dlerror()); 251296341Sdelphij return (NULL); 252296341Sdelphij } 253296341Sdelphij return (sym); 254296341Sdelphij} 25568651Skris 25668651Skrisstatic DSO_FUNC_TYPE dlfcn_bind_func(DSO *dso, const char *symname) 257296341Sdelphij{ 258296341Sdelphij void *ptr; 259296341Sdelphij union { 260296341Sdelphij DSO_FUNC_TYPE sym; 261296341Sdelphij void *dlret; 262296341Sdelphij } u; 26368651Skris 264296341Sdelphij if ((dso == NULL) || (symname == NULL)) { 265296341Sdelphij DSOerr(DSO_F_DLFCN_BIND_FUNC, ERR_R_PASSED_NULL_PARAMETER); 266296341Sdelphij return (NULL); 267296341Sdelphij } 268296341Sdelphij if (sk_void_num(dso->meth_data) < 1) { 269296341Sdelphij DSOerr(DSO_F_DLFCN_BIND_FUNC, DSO_R_STACK_ERROR); 270296341Sdelphij return (NULL); 271296341Sdelphij } 272296341Sdelphij ptr = sk_void_value(dso->meth_data, sk_void_num(dso->meth_data) - 1); 273296341Sdelphij if (ptr == NULL) { 274296341Sdelphij DSOerr(DSO_F_DLFCN_BIND_FUNC, DSO_R_NULL_HANDLE); 275296341Sdelphij return (NULL); 276296341Sdelphij } 277296341Sdelphij u.dlret = dlsym(ptr, symname); 278296341Sdelphij if (u.dlret == NULL) { 279296341Sdelphij DSOerr(DSO_F_DLFCN_BIND_FUNC, DSO_R_SYM_FAILURE); 280296341Sdelphij ERR_add_error_data(4, "symname(", symname, "): ", dlerror()); 281296341Sdelphij return (NULL); 282296341Sdelphij } 283296341Sdelphij return u.sym; 284296341Sdelphij} 28568651Skris 286160814Ssimonstatic char *dlfcn_merger(DSO *dso, const char *filespec1, 287296341Sdelphij const char *filespec2) 288296341Sdelphij{ 289296341Sdelphij char *merged; 290160814Ssimon 291296341Sdelphij if (!filespec1 && !filespec2) { 292296341Sdelphij DSOerr(DSO_F_DLFCN_MERGER, ERR_R_PASSED_NULL_PARAMETER); 293296341Sdelphij return (NULL); 294296341Sdelphij } 295296341Sdelphij /* 296296341Sdelphij * If the first file specification is a rooted path, it rules. same goes 297296341Sdelphij * if the second file specification is missing. 298296341Sdelphij */ 299296341Sdelphij if (!filespec2 || (filespec1 != NULL && filespec1[0] == '/')) { 300296341Sdelphij merged = OPENSSL_malloc(strlen(filespec1) + 1); 301296341Sdelphij if (!merged) { 302296341Sdelphij DSOerr(DSO_F_DLFCN_MERGER, ERR_R_MALLOC_FAILURE); 303296341Sdelphij return (NULL); 304296341Sdelphij } 305296341Sdelphij strcpy(merged, filespec1); 306296341Sdelphij } 307296341Sdelphij /* 308296341Sdelphij * If the first file specification is missing, the second one rules. 309296341Sdelphij */ 310296341Sdelphij else if (!filespec1) { 311296341Sdelphij merged = OPENSSL_malloc(strlen(filespec2) + 1); 312296341Sdelphij if (!merged) { 313296341Sdelphij DSOerr(DSO_F_DLFCN_MERGER, ERR_R_MALLOC_FAILURE); 314296341Sdelphij return (NULL); 315296341Sdelphij } 316296341Sdelphij strcpy(merged, filespec2); 317296341Sdelphij } else { 318296341Sdelphij /* 319296341Sdelphij * This part isn't as trivial as it looks. It assumes that the 320296341Sdelphij * second file specification really is a directory, and makes no 321296341Sdelphij * checks whatsoever. Therefore, the result becomes the 322296341Sdelphij * concatenation of filespec2 followed by a slash followed by 323296341Sdelphij * filespec1. 324296341Sdelphij */ 325296341Sdelphij int spec2len, len; 326160814Ssimon 327296341Sdelphij spec2len = strlen(filespec2); 328296341Sdelphij len = spec2len + strlen(filespec1); 329160814Ssimon 330296341Sdelphij if (spec2len && filespec2[spec2len - 1] == '/') { 331296341Sdelphij spec2len--; 332296341Sdelphij len--; 333296341Sdelphij } 334296341Sdelphij merged = OPENSSL_malloc(len + 2); 335296341Sdelphij if (!merged) { 336296341Sdelphij DSOerr(DSO_F_DLFCN_MERGER, ERR_R_MALLOC_FAILURE); 337296341Sdelphij return (NULL); 338296341Sdelphij } 339296341Sdelphij strcpy(merged, filespec2); 340296341Sdelphij merged[spec2len] = '/'; 341296341Sdelphij strcpy(&merged[spec2len + 1], filespec1); 342296341Sdelphij } 343296341Sdelphij return (merged); 344296341Sdelphij} 345160814Ssimon 346296341Sdelphij# ifdef OPENSSL_SYS_MACOSX 347296341Sdelphij# define DSO_ext ".dylib" 348296341Sdelphij# define DSO_extlen 6 349296341Sdelphij# else 350296341Sdelphij# define DSO_ext ".so" 351296341Sdelphij# define DSO_extlen 3 352296341Sdelphij# endif 353205128Ssimon 354109998Smarkmstatic char *dlfcn_name_converter(DSO *dso, const char *filename) 355296341Sdelphij{ 356296341Sdelphij char *translated; 357296341Sdelphij int len, rsize, transform; 358109998Smarkm 359296341Sdelphij len = strlen(filename); 360296341Sdelphij rsize = len + 1; 361296341Sdelphij transform = (strstr(filename, "/") == NULL); 362296341Sdelphij if (transform) { 363296341Sdelphij /* We will convert this to "%s.so" or "lib%s.so" etc */ 364296341Sdelphij rsize += DSO_extlen; /* The length of ".so" */ 365296341Sdelphij if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0) 366296341Sdelphij rsize += 3; /* The length of "lib" */ 367296341Sdelphij } 368296341Sdelphij translated = OPENSSL_malloc(rsize); 369296341Sdelphij if (translated == NULL) { 370296341Sdelphij DSOerr(DSO_F_DLFCN_NAME_CONVERTER, DSO_R_NAME_TRANSLATION_FAILED); 371296341Sdelphij return (NULL); 372296341Sdelphij } 373296341Sdelphij if (transform) { 374296341Sdelphij if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0) 375296341Sdelphij sprintf(translated, "lib%s" DSO_ext, filename); 376296341Sdelphij else 377296341Sdelphij sprintf(translated, "%s" DSO_ext, filename); 378296341Sdelphij } else 379296341Sdelphij sprintf(translated, "%s", filename); 380296341Sdelphij return (translated); 381296341Sdelphij} 38268651Skris 383296341Sdelphij# ifdef __sgi 384296341Sdelphij/*- 385238405SjkimThis is a quote from IRIX manual for dladdr(3c): 386238405Sjkim 387238405Sjkim <dlfcn.h> does not contain a prototype for dladdr or definition of 388238405Sjkim Dl_info. The #include <dlfcn.h> in the SYNOPSIS line is traditional, 389238405Sjkim but contains no dladdr prototype and no IRIX library contains an 390238405Sjkim implementation. Write your own declaration based on the code below. 391238405Sjkim 392238405Sjkim The following code is dependent on internal interfaces that are not 393238405Sjkim part of the IRIX compatibility guarantee; however, there is no future 394238405Sjkim intention to change this interface, so on a practical level, the code 395238405Sjkim below is safe to use on IRIX. 396238405Sjkim*/ 397296341Sdelphij# include <rld_interface.h> 398296341Sdelphij# ifndef _RLD_INTERFACE_DLFCN_H_DLADDR 399296341Sdelphij# define _RLD_INTERFACE_DLFCN_H_DLADDR 400238405Sjkimtypedef struct Dl_info { 401296341Sdelphij const char *dli_fname; 402296341Sdelphij void *dli_fbase; 403296341Sdelphij const char *dli_sname; 404296341Sdelphij void *dli_saddr; 405296341Sdelphij int dli_version; 406296341Sdelphij int dli_reserved1; 407296341Sdelphij long dli_reserved[4]; 408238405Sjkim} Dl_info; 409296341Sdelphij# else 410238405Sjkimtypedef struct Dl_info Dl_info; 411296341Sdelphij# endif 412296341Sdelphij# define _RLD_DLADDR 14 413238405Sjkim 414238405Sjkimstatic int dladdr(void *address, Dl_info *dl) 415238405Sjkim{ 416296341Sdelphij void *v; 417296341Sdelphij v = _rld_new_interface(_RLD_DLADDR, address, dl); 418296341Sdelphij return (int)v; 419238405Sjkim} 420296341Sdelphij# endif /* __sgi */ 421238405Sjkim 422296341Sdelphijstatic int dlfcn_pathbyaddr(void *addr, char *path, int sz) 423296341Sdelphij{ 424296341Sdelphij# ifdef HAVE_DLINFO 425296341Sdelphij Dl_info dli; 426296341Sdelphij int len; 427238405Sjkim 428296341Sdelphij if (addr == NULL) { 429296341Sdelphij union { 430296341Sdelphij int (*f) (void *, char *, int); 431296341Sdelphij void *p; 432296341Sdelphij } t = { 433296341Sdelphij dlfcn_pathbyaddr 434296341Sdelphij }; 435296341Sdelphij addr = t.p; 436296341Sdelphij } 437238405Sjkim 438296341Sdelphij if (dladdr(addr, &dli)) { 439296341Sdelphij len = (int)strlen(dli.dli_fname); 440296341Sdelphij if (sz <= 0) 441296341Sdelphij return len + 1; 442296341Sdelphij if (len >= sz) 443296341Sdelphij len = sz - 1; 444296341Sdelphij memcpy(path, dli.dli_fname, len); 445296341Sdelphij path[len++] = 0; 446296341Sdelphij return len; 447296341Sdelphij } 448238405Sjkim 449296341Sdelphij ERR_add_error_data(2, "dlfcn_pathbyaddr(): ", dlerror()); 450296341Sdelphij# endif 451296341Sdelphij return -1; 452296341Sdelphij} 453238405Sjkim 454238405Sjkimstatic void *dlfcn_globallookup(const char *name) 455296341Sdelphij{ 456296341Sdelphij void *ret = NULL, *handle = dlopen(NULL, RTLD_LAZY); 457238405Sjkim 458296341Sdelphij if (handle) { 459296341Sdelphij ret = dlsym(handle, name); 460296341Sdelphij dlclose(handle); 461296341Sdelphij } 462296341Sdelphij 463296341Sdelphij return ret; 464296341Sdelphij} 465296341Sdelphij#endif /* DSO_DLFCN */ 466