dso_dl.c revision 72613
1/* dso_dl.c */ 2/* Written by Richard Levitte (levitte@openssl.org) for the OpenSSL 3 * project 2000. 4 */ 5/* ==================================================================== 6 * Copyright (c) 2000 The OpenSSL Project. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in 17 * the documentation and/or other materials provided with the 18 * distribution. 19 * 20 * 3. All advertising materials mentioning features or use of this 21 * software must display the following acknowledgment: 22 * "This product includes software developed by the OpenSSL Project 23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 24 * 25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 26 * endorse or promote products derived from this software without 27 * prior written permission. For written permission, please contact 28 * licensing@OpenSSL.org. 29 * 30 * 5. Products derived from this software may not be called "OpenSSL" 31 * nor may "OpenSSL" appear in their names without prior written 32 * permission of the OpenSSL Project. 33 * 34 * 6. Redistributions of any form whatsoever must retain the following 35 * acknowledgment: 36 * "This product includes software developed by the OpenSSL Project 37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 38 * 39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 50 * OF THE POSSIBILITY OF SUCH DAMAGE. 51 * ==================================================================== 52 * 53 * This product includes cryptographic software written by Eric Young 54 * (eay@cryptsoft.com). This product includes software written by Tim 55 * Hudson (tjh@cryptsoft.com). 56 * 57 */ 58 59#include <stdio.h> 60#include "cryptlib.h" 61#include <openssl/dso.h> 62 63#ifndef DSO_DL 64DSO_METHOD *DSO_METHOD_dl(void) 65 { 66 return NULL; 67 } 68#else 69 70#include <dl.h> 71 72/* Part of the hack in "dl_load" ... */ 73#define DSO_MAX_TRANSLATED_SIZE 256 74 75static int dl_load(DSO *dso, const char *filename); 76static int dl_unload(DSO *dso); 77static void *dl_bind_var(DSO *dso, const char *symname); 78static DSO_FUNC_TYPE dl_bind_func(DSO *dso, const char *symname); 79#if 0 80static int dl_unbind_var(DSO *dso, char *symname, void *symptr); 81static int dl_unbind_func(DSO *dso, char *symname, DSO_FUNC_TYPE symptr); 82static int dl_init(DSO *dso); 83static int dl_finish(DSO *dso); 84#endif 85static int dl_ctrl(DSO *dso, int cmd, long larg, void *parg); 86 87static DSO_METHOD dso_meth_dl = { 88 "OpenSSL 'dl' shared library method", 89 dl_load, 90 dl_unload, 91 dl_bind_var, 92 dl_bind_func, 93/* For now, "unbind" doesn't exist */ 94#if 0 95 NULL, /* unbind_var */ 96 NULL, /* unbind_func */ 97#endif 98 dl_ctrl, 99 NULL, /* init */ 100 NULL /* finish */ 101 }; 102 103DSO_METHOD *DSO_METHOD_dl(void) 104 { 105 return(&dso_meth_dl); 106 } 107 108/* For this DSO_METHOD, our meth_data STACK will contain; 109 * (i) the handle (shl_t) returned from shl_load(). 110 * NB: I checked on HPUX11 and shl_t is itself a pointer 111 * type so the cast is safe. 112 */ 113 114static int dl_load(DSO *dso, const char *filename) 115 { 116 shl_t ptr; 117 char translated[DSO_MAX_TRANSLATED_SIZE]; 118 int len; 119 120 /* The same comment as in dlfcn_load applies here. bleurgh. */ 121 len = strlen(filename); 122 if((dso->flags & DSO_FLAG_NAME_TRANSLATION) && 123 (len + 6 < DSO_MAX_TRANSLATED_SIZE) && 124 (strstr(filename, "/") == NULL)) 125 { 126 sprintf(translated, "lib%s.so", filename); 127 ptr = shl_load(translated, BIND_IMMEDIATE, NULL); 128 } 129 else 130 ptr = shl_load(filename, BIND_IMMEDIATE, NULL); 131 if(ptr == NULL) 132 { 133 DSOerr(DSO_F_DL_LOAD,DSO_R_LOAD_FAILED); 134 return(0); 135 } 136 if(!sk_push(dso->meth_data, (char *)ptr)) 137 { 138 DSOerr(DSO_F_DL_LOAD,DSO_R_STACK_ERROR); 139 shl_unload(ptr); 140 return(0); 141 } 142 return(1); 143 } 144 145static int dl_unload(DSO *dso) 146 { 147 shl_t ptr; 148 if(dso == NULL) 149 { 150 DSOerr(DSO_F_DL_UNLOAD,ERR_R_PASSED_NULL_PARAMETER); 151 return(0); 152 } 153 if(sk_num(dso->meth_data) < 1) 154 return(1); 155 /* Is this statement legal? */ 156 ptr = (shl_t)sk_pop(dso->meth_data); 157 if(ptr == NULL) 158 { 159 DSOerr(DSO_F_DL_UNLOAD,DSO_R_NULL_HANDLE); 160 /* Should push the value back onto the stack in 161 * case of a retry. */ 162 sk_push(dso->meth_data, (char *)ptr); 163 return(0); 164 } 165 shl_unload(ptr); 166 return(1); 167 } 168 169static void *dl_bind_var(DSO *dso, const char *symname) 170 { 171 shl_t ptr; 172 void *sym; 173 174 if((dso == NULL) || (symname == NULL)) 175 { 176 DSOerr(DSO_F_DL_BIND_VAR,ERR_R_PASSED_NULL_PARAMETER); 177 return(NULL); 178 } 179 if(sk_num(dso->meth_data) < 1) 180 { 181 DSOerr(DSO_F_DL_BIND_VAR,DSO_R_STACK_ERROR); 182 return(NULL); 183 } 184 ptr = (shl_t)sk_value(dso->meth_data, sk_num(dso->meth_data) - 1); 185 if(ptr == NULL) 186 { 187 DSOerr(DSO_F_DL_BIND_VAR,DSO_R_NULL_HANDLE); 188 return(NULL); 189 } 190 if (shl_findsym(&ptr, symname, TYPE_UNDEFINED, &sym) < 0) 191 { 192 DSOerr(DSO_F_DL_BIND_VAR,DSO_R_SYM_FAILURE); 193 return(NULL); 194 } 195 return(sym); 196 } 197 198static DSO_FUNC_TYPE dl_bind_func(DSO *dso, const char *symname) 199 { 200 shl_t ptr; 201 void *sym; 202 203 if((dso == NULL) || (symname == NULL)) 204 { 205 DSOerr(DSO_F_DL_BIND_FUNC,ERR_R_PASSED_NULL_PARAMETER); 206 return(NULL); 207 } 208 if(sk_num(dso->meth_data) < 1) 209 { 210 DSOerr(DSO_F_DL_BIND_FUNC,DSO_R_STACK_ERROR); 211 return(NULL); 212 } 213 ptr = (shl_t)sk_value(dso->meth_data, sk_num(dso->meth_data) - 1); 214 if(ptr == NULL) 215 { 216 DSOerr(DSO_F_DL_BIND_FUNC,DSO_R_NULL_HANDLE); 217 return(NULL); 218 } 219 if (shl_findsym(&ptr, symname, TYPE_UNDEFINED, &sym) < 0) 220 { 221 DSOerr(DSO_F_DL_BIND_FUNC,DSO_R_SYM_FAILURE); 222 return(NULL); 223 } 224 return((DSO_FUNC_TYPE)sym); 225 } 226 227static int dl_ctrl(DSO *dso, int cmd, long larg, void *parg) 228 { 229 if(dso == NULL) 230 { 231 DSOerr(DSO_F_DL_CTRL,ERR_R_PASSED_NULL_PARAMETER); 232 return(-1); 233 } 234 switch(cmd) 235 { 236 case DSO_CTRL_GET_FLAGS: 237 return dso->flags; 238 case DSO_CTRL_SET_FLAGS: 239 dso->flags = (int)larg; 240 return(0); 241 case DSO_CTRL_OR_FLAGS: 242 dso->flags |= (int)larg; 243 return(0); 244 default: 245 break; 246 } 247 DSOerr(DSO_F_DL_CTRL,DSO_R_UNKNOWN_COMMAND); 248 return(-1); 249 } 250 251#endif /* DSO_DL */ 252