1656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* dso_dl.c -*- mode:C; c-file-style: "eay" -*- */
2656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
3656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * project 2000.
4656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
5656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* ====================================================================
6656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
7656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
8656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Redistribution and use in source and binary forms, with or without
9656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * modification, are permitted provided that the following conditions
10656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * are met:
11656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
12656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 1. Redistributions of source code must retain the above copyright
13656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer.
14656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
15656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
16656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer in
17656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    the documentation and/or other materials provided with the
18656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    distribution.
19656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
20656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 3. All advertising materials mentioning features or use of this
21656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    software must display the following acknowledgment:
22656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes software developed by the OpenSSL Project
23656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
25656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    endorse or promote products derived from this software without
27656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    prior written permission. For written permission, please contact
28656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    licensing@OpenSSL.org.
29656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
30656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 5. Products derived from this software may not be called "OpenSSL"
31656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    nor may "OpenSSL" appear in their names without prior written
32656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    permission of the OpenSSL Project.
33656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
34656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 6. Redistributions of any form whatsoever must retain the following
35656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    acknowledgment:
36656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes software developed by the OpenSSL Project
37656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
39656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OF THE POSSIBILITY OF SUCH DAMAGE.
51656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ====================================================================
52656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
53656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This product includes cryptographic software written by Eric Young
54656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * (eay@cryptsoft.com).  This product includes software written by Tim
55656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Hudson (tjh@cryptsoft.com).
56656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
57656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
58656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
59656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <stdio.h>
60656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "cryptlib.h"
61656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/dso.h>
62656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
63656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef DSO_DL
64656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectDSO_METHOD *DSO_METHOD_dl(void)
65656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project       {
66656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project       return NULL;
67656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project       }
68656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#else
69656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
70656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <dl.h>
71656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
72656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Part of the hack in "dl_load" ... */
73656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define DSO_MAX_TRANSLATED_SIZE 256
74656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
75656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int dl_load(DSO *dso);
76656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int dl_unload(DSO *dso);
77656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void *dl_bind_var(DSO *dso, const char *symname);
78656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic DSO_FUNC_TYPE dl_bind_func(DSO *dso, const char *symname);
79656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#if 0
80656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int dl_unbind_var(DSO *dso, char *symname, void *symptr);
81656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int dl_unbind_func(DSO *dso, char *symname, DSO_FUNC_TYPE symptr);
82656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int dl_init(DSO *dso);
83656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int dl_finish(DSO *dso);
84656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int dl_ctrl(DSO *dso, int cmd, long larg, void *parg);
85656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
86656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic char *dl_name_converter(DSO *dso, const char *filename);
87656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic char *dl_merger(DSO *dso, const char *filespec1, const char *filespec2);
88221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int dl_pathbyaddr(void *addr,char *path,int sz);
89221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic void *dl_globallookup(const char *name);
90656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
91656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic DSO_METHOD dso_meth_dl = {
92656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	"OpenSSL 'dl' shared library method",
93656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	dl_load,
94656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	dl_unload,
95656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	dl_bind_var,
96656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	dl_bind_func,
97656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* For now, "unbind" doesn't exist */
98656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#if 0
99656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL, /* unbind_var */
100656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL, /* unbind_func */
101656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
102656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL, /* ctrl */
103656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	dl_name_converter,
104656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	dl_merger,
105656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL, /* init */
106221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	NULL, /* finish */
107221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	dl_pathbyaddr,
108221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	dl_globallookup
109656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	};
110656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
111656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectDSO_METHOD *DSO_METHOD_dl(void)
112656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
113656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(&dso_meth_dl);
114656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
115656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
116656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* For this DSO_METHOD, our meth_data STACK will contain;
117656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * (i) the handle (shl_t) returned from shl_load().
118656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * NB: I checked on HPUX11 and shl_t is itself a pointer
119656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * type so the cast is safe.
120656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
121656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
122656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int dl_load(DSO *dso)
123656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
124656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	shl_t ptr = NULL;
125656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* We don't do any fancy retries or anything, just take the method's
126656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 * (or DSO's if it has the callback set) best translation of the
127656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 * platform-independant filename and try once with that. */
128656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	char *filename= DSO_convert_filename(dso, NULL);
129656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
130656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(filename == NULL)
131656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
132656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		DSOerr(DSO_F_DL_LOAD,DSO_R_NO_FILENAME);
133656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
134656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
135656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ptr = shl_load(filename, BIND_IMMEDIATE |
136656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		(dso->flags&DSO_FLAG_NO_NAME_TRANSLATION?0:DYNAMIC_PATH), 0L);
137656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(ptr == NULL)
138656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
139656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		DSOerr(DSO_F_DL_LOAD,DSO_R_LOAD_FAILED);
140656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ERR_add_error_data(4, "filename(", filename, "): ",
141656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			strerror(errno));
142656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
143656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
144656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(!sk_push(dso->meth_data, (char *)ptr))
145656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
146656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		DSOerr(DSO_F_DL_LOAD,DSO_R_STACK_ERROR);
147656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
148656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
149656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Success, stick the converted filename we've loaded under into the DSO
150656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 * (it also serves as the indicator that we are currently loaded). */
151656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	dso->loaded_filename = filename;
152656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(1);
153656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecterr:
154656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Cleanup! */
155656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(filename != NULL)
156656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		OPENSSL_free(filename);
157656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(ptr != NULL)
158656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		shl_unload(ptr);
159656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(0);
160656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
161656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
162656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int dl_unload(DSO *dso)
163656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
164656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	shl_t ptr;
165656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(dso == NULL)
166656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
167656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		DSOerr(DSO_F_DL_UNLOAD,ERR_R_PASSED_NULL_PARAMETER);
168656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return(0);
169656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
170656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(sk_num(dso->meth_data) < 1)
171656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return(1);
172656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Is this statement legal? */
173656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ptr = (shl_t)sk_pop(dso->meth_data);
174656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(ptr == NULL)
175656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
176656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		DSOerr(DSO_F_DL_UNLOAD,DSO_R_NULL_HANDLE);
177656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Should push the value back onto the stack in
178656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * case of a retry. */
179656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		sk_push(dso->meth_data, (char *)ptr);
180656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return(0);
181656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
182656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	shl_unload(ptr);
183656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(1);
184656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
185656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
186656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void *dl_bind_var(DSO *dso, const char *symname)
187656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
188656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	shl_t ptr;
189656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	void *sym;
190656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
191656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if((dso == NULL) || (symname == NULL))
192656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
193656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		DSOerr(DSO_F_DL_BIND_VAR,ERR_R_PASSED_NULL_PARAMETER);
194656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return(NULL);
195656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
196656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(sk_num(dso->meth_data) < 1)
197656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
198656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		DSOerr(DSO_F_DL_BIND_VAR,DSO_R_STACK_ERROR);
199656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return(NULL);
200656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
201656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ptr = (shl_t)sk_value(dso->meth_data, sk_num(dso->meth_data) - 1);
202656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(ptr == NULL)
203656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
204656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		DSOerr(DSO_F_DL_BIND_VAR,DSO_R_NULL_HANDLE);
205656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return(NULL);
206656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
207656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (shl_findsym(&ptr, symname, TYPE_UNDEFINED, &sym) < 0)
208656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
209656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		DSOerr(DSO_F_DL_BIND_VAR,DSO_R_SYM_FAILURE);
210656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ERR_add_error_data(4, "symname(", symname, "): ",
211656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			strerror(errno));
212656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return(NULL);
213656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
214656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(sym);
215656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
216656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
217656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic DSO_FUNC_TYPE dl_bind_func(DSO *dso, const char *symname)
218656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
219656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	shl_t ptr;
220656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	void *sym;
221656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
222656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if((dso == NULL) || (symname == NULL))
223656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
224656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		DSOerr(DSO_F_DL_BIND_FUNC,ERR_R_PASSED_NULL_PARAMETER);
225656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return(NULL);
226656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
227656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(sk_num(dso->meth_data) < 1)
228656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
229656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		DSOerr(DSO_F_DL_BIND_FUNC,DSO_R_STACK_ERROR);
230656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return(NULL);
231656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
232656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ptr = (shl_t)sk_value(dso->meth_data, sk_num(dso->meth_data) - 1);
233656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(ptr == NULL)
234656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
235656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		DSOerr(DSO_F_DL_BIND_FUNC,DSO_R_NULL_HANDLE);
236656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return(NULL);
237656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
238656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (shl_findsym(&ptr, symname, TYPE_UNDEFINED, &sym) < 0)
239656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
240656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		DSOerr(DSO_F_DL_BIND_FUNC,DSO_R_SYM_FAILURE);
241656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ERR_add_error_data(4, "symname(", symname, "): ",
242656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			strerror(errno));
243656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return(NULL);
244656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
245656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return((DSO_FUNC_TYPE)sym);
246656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
247656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
248656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic char *dl_merger(DSO *dso, const char *filespec1, const char *filespec2)
249656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
250656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	char *merged;
251656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
252656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(!filespec1 && !filespec2)
253656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
254656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		DSOerr(DSO_F_DL_MERGER,
255656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ERR_R_PASSED_NULL_PARAMETER);
256656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return(NULL);
257656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
258656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* If the first file specification is a rooted path, it rules.
259656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	   same goes if the second file specification is missing. */
260656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!filespec2 || filespec1[0] == '/')
261656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
262656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		merged = OPENSSL_malloc(strlen(filespec1) + 1);
263656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(!merged)
264656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
265656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			DSOerr(DSO_F_DL_MERGER,
266656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ERR_R_MALLOC_FAILURE);
267656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return(NULL);
268656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
269656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		strcpy(merged, filespec1);
270656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
271656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* If the first file specification is missing, the second one rules. */
272656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else if (!filespec1)
273656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
274656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		merged = OPENSSL_malloc(strlen(filespec2) + 1);
275656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(!merged)
276656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
277656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			DSOerr(DSO_F_DL_MERGER,
278656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ERR_R_MALLOC_FAILURE);
279656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return(NULL);
280656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
281656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		strcpy(merged, filespec2);
282656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
283656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
284656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* This part isn't as trivial as it looks.  It assumes that
285656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		   the second file specification really is a directory, and
286656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		   makes no checks whatsoever.  Therefore, the result becomes
287656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		   the concatenation of filespec2 followed by a slash followed
288656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		   by filespec1. */
289656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
290656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		int spec2len, len;
291656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
292656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		spec2len = (filespec2 ? strlen(filespec2) : 0);
293656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		len = spec2len + (filespec1 ? strlen(filespec1) : 0);
294656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
295656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(filespec2 && filespec2[spec2len - 1] == '/')
296656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
297656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			spec2len--;
298656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			len--;
299656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
300656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		merged = OPENSSL_malloc(len + 2);
301656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(!merged)
302656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
303656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			DSOerr(DSO_F_DL_MERGER,
304656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ERR_R_MALLOC_FAILURE);
305656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return(NULL);
306656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
307656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		strcpy(merged, filespec2);
308656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		merged[spec2len] = '/';
309656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		strcpy(&merged[spec2len + 1], filespec1);
310656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
311656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(merged);
312656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
313656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
314656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* This function is identical to the one in dso_dlfcn.c, but as it is highly
315656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * unlikely that both the "dl" *and* "dlfcn" variants are being compiled at the
316656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * same time, there's no great duplicating the code. Figuring out an elegant
317656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * way to share one copy of the code would be more difficult and would not
318656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * leave the implementations independant. */
319656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#if defined(__hpux)
320656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic const char extension[] = ".sl";
321656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#else
322656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic const char extension[] = ".so";
323656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
324656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic char *dl_name_converter(DSO *dso, const char *filename)
325656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
326656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	char *translated;
327656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int len, rsize, transform;
328656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
329656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	len = strlen(filename);
330656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	rsize = len + 1;
331656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	transform = (strstr(filename, "/") == NULL);
332656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
333656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* We will convert this to "%s.s?" or "lib%s.s?" */
334656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		rsize += strlen(extension);/* The length of ".s?" */
335656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0)
336656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			rsize += 3; /* The length of "lib" */
337656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
338656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	translated = OPENSSL_malloc(rsize);
339656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(translated == NULL)
340656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
341656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		DSOerr(DSO_F_DL_NAME_CONVERTER,
342656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				DSO_R_NAME_TRANSLATION_FAILED);
343656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return(NULL);
344656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
345656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(transform)
346656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
347656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0)
348656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			sprintf(translated, "lib%s%s", filename, extension);
349656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else
350656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			sprintf(translated, "%s%s", filename, extension);
351656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
352656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
353656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		sprintf(translated, "%s", filename);
354656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(translated);
355656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
356656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
357221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int dl_pathbyaddr(void *addr,char *path,int sz)
358221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
359221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	struct shl_descriptor inf;
360221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int i,len;
361221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
362221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (addr == NULL)
363221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
364221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		union	{ int(*f)(void*,char*,int); void *p; } t =
365221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			{ dl_pathbyaddr };
366221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		addr = t.p;
367221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
368221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
369221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	for (i=-1;shl_get_r(i,&inf)==0;i++)
370221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
371221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (((size_t)addr >= inf.tstart && (size_t)addr < inf.tend) ||
372221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		    ((size_t)addr >= inf.dstart && (size_t)addr < inf.dend))
373221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			{
374221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			len = (int)strlen(inf.filename);
375221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (sz <= 0) return len+1;
376221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			if (len >= sz) len=sz-1;
377221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			memcpy(path,inf.filename,len);
378221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			path[len++] = 0;
379221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			return len;
380221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			}
381221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
382221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
383221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return -1;
384221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
385221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
386221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic void *dl_globallookup(const char *name)
387221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
388221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	void *ret;
389221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	shl_t h = NULL;
390221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
391221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return shl_findsym(&h,name,TYPE_UNDEFINED,&ret) ? NULL : ret;
392221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
393656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif /* DSO_DL */
394