1656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* dso_dlfcn.c -*- mode:C; c-file-style: "eay" -*- */
2656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Written by Geoff Thorpe (geoff@geoffthorpe.net) 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
59221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom/* We need to do this early, because stdio.h includes the header files
60221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom   that handle _GNU_SOURCE and other similar macros.  Defining it later
61221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom   is simply too late, because those headers are protected from re-
62221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom   inclusion.  */
63221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#ifdef __linux
64221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom# ifndef _GNU_SOURCE
65221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#  define _GNU_SOURCE	/* make sure dladdr is declared */
66221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom# endif
67221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#endif
68221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
69656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <stdio.h>
70656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "cryptlib.h"
71656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/dso.h>
72656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
73656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef DSO_DLFCN
74656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectDSO_METHOD *DSO_METHOD_dlfcn(void)
75656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
76656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return NULL;
77656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
78656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#else
79656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
80656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef HAVE_DLFCN_H
81221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom# ifdef __osf__
82221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#  define __EXTENSIONS__
83221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom# endif
84221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom# include <dlfcn.h>
85221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom# define HAVE_DLINFO 1
86221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom# if defined(_AIX) || defined(__CYGWIN__) || \
87221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom     defined(__SCO_VERSION__) || defined(_SCO_ELF) || \
88ee7afb3c942c4eefef6ed06201eafaf8ec58e2e3Brian Carlstrom     (defined(__osf__) && !defined(RTLD_NEXT))     || \
89392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom     (defined(__OpenBSD__) && !defined(RTLD_SELF)) || \
90392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	defined(__ANDROID__)
91221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#  undef HAVE_DLINFO
92221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom# endif
93656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
94656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
95656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Part of the hack in "dlfcn_load" ... */
96656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#define DSO_MAX_TRANSLATED_SIZE 256
97656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
98656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int dlfcn_load(DSO *dso);
99656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int dlfcn_unload(DSO *dso);
100656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void *dlfcn_bind_var(DSO *dso, const char *symname);
101656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic DSO_FUNC_TYPE dlfcn_bind_func(DSO *dso, const char *symname);
102656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#if 0
103656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int dlfcn_unbind(DSO *dso, char *symname, void *symptr);
104656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int dlfcn_init(DSO *dso);
105656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int dlfcn_finish(DSO *dso);
106656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic long dlfcn_ctrl(DSO *dso, int cmd, long larg, void *parg);
107656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
108656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic char *dlfcn_name_converter(DSO *dso, const char *filename);
109656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic char *dlfcn_merger(DSO *dso, const char *filespec1,
110656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	const char *filespec2);
111221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int dlfcn_pathbyaddr(void *addr,char *path,int sz);
112221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic void *dlfcn_globallookup(const char *name);
113656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
114656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic DSO_METHOD dso_meth_dlfcn = {
115656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	"OpenSSL 'dlfcn' shared library method",
116656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	dlfcn_load,
117656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	dlfcn_unload,
118656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	dlfcn_bind_var,
119656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	dlfcn_bind_func,
120656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* For now, "unbind" doesn't exist */
121656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#if 0
122656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL, /* unbind_var */
123656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL, /* unbind_func */
124656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
125656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL, /* ctrl */
126656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	dlfcn_name_converter,
127656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	dlfcn_merger,
128656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	NULL, /* init */
129221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	NULL, /* finish */
130221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	dlfcn_pathbyaddr,
131221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	dlfcn_globallookup
132656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	};
133656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
134656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectDSO_METHOD *DSO_METHOD_dlfcn(void)
135656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
136656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(&dso_meth_dlfcn);
137656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
138656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
139656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Prior to using the dlopen() function, we should decide on the flag
140656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * we send. There's a few different ways of doing this and it's a
141656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * messy venn-diagram to match up which platforms support what. So
142656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * as we don't have autoconf yet, I'm implementing a hack that could
143656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * be hacked further relatively easily to deal with cases as we find
144656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * them. Initially this is to cope with OpenBSD. */
145656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#if defined(__OpenBSD__) || defined(__NetBSD__)
146656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#	ifdef DL_LAZY
147656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#		define DLOPEN_FLAG DL_LAZY
148656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#	else
149656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#		ifdef RTLD_NOW
150656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#			define DLOPEN_FLAG RTLD_NOW
151656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#		else
152656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#			define DLOPEN_FLAG 0
153656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#		endif
154656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#	endif
155656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#else
156656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#	ifdef OPENSSL_SYS_SUNOS
157656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#		define DLOPEN_FLAG 1
158656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#	else
159656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#		define DLOPEN_FLAG RTLD_NOW /* Hope this works everywhere else */
160656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#	endif
161656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
162656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
163656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* For this DSO_METHOD, our meth_data STACK will contain;
164656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * (i) the handle (void*) returned from dlopen().
165656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
166656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
167656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int dlfcn_load(DSO *dso)
168656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
169656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	void *ptr = NULL;
170656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* See applicable comments in dso_dl.c */
171656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	char *filename = DSO_convert_filename(dso, NULL);
172656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int flags = DLOPEN_FLAG;
173656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
174656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(filename == NULL)
175656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
176656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		DSOerr(DSO_F_DLFCN_LOAD,DSO_R_NO_FILENAME);
177656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
178656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
179656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
180656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifdef RTLD_GLOBAL
181656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (dso->flags & DSO_FLAG_GLOBAL_SYMBOLS)
182656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		flags |= RTLD_GLOBAL;
183656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
184656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ptr = dlopen(filename, flags);
185656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(ptr == NULL)
186656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
187656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		DSOerr(DSO_F_DLFCN_LOAD,DSO_R_LOAD_FAILED);
188656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ERR_add_error_data(4, "filename(", filename, "): ", dlerror());
189656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
190656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
191221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if(!sk_void_push(dso->meth_data, (char *)ptr))
192656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
193656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		DSOerr(DSO_F_DLFCN_LOAD,DSO_R_STACK_ERROR);
194656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		goto err;
195656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
196656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Success */
197656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	dso->loaded_filename = filename;
198656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(1);
199656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecterr:
200656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Cleanup! */
201656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(filename != NULL)
202656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		OPENSSL_free(filename);
203656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(ptr != NULL)
204656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		dlclose(ptr);
205656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(0);
206656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
207656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
208656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int dlfcn_unload(DSO *dso)
209656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
210656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	void *ptr;
211656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(dso == NULL)
212656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
213656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		DSOerr(DSO_F_DLFCN_UNLOAD,ERR_R_PASSED_NULL_PARAMETER);
214656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return(0);
215656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
216221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if(sk_void_num(dso->meth_data) < 1)
217656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return(1);
218221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ptr = sk_void_pop(dso->meth_data);
219656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(ptr == NULL)
220656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
221656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		DSOerr(DSO_F_DLFCN_UNLOAD,DSO_R_NULL_HANDLE);
222656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* Should push the value back onto the stack in
223656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 * case of a retry. */
224221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		sk_void_push(dso->meth_data, ptr);
225656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return(0);
226656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
227656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* For now I'm not aware of any errors associated with dlclose() */
228656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	dlclose(ptr);
229656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(1);
230656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
231656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
232656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic void *dlfcn_bind_var(DSO *dso, const char *symname)
233656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
234656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	void *ptr, *sym;
235656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
236656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if((dso == NULL) || (symname == NULL))
237656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
238656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		DSOerr(DSO_F_DLFCN_BIND_VAR,ERR_R_PASSED_NULL_PARAMETER);
239656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return(NULL);
240656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
241221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if(sk_void_num(dso->meth_data) < 1)
242656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
243656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		DSOerr(DSO_F_DLFCN_BIND_VAR,DSO_R_STACK_ERROR);
244656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return(NULL);
245656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
246221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ptr = sk_void_value(dso->meth_data, sk_void_num(dso->meth_data) - 1);
247656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(ptr == NULL)
248656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
249656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		DSOerr(DSO_F_DLFCN_BIND_VAR,DSO_R_NULL_HANDLE);
250656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return(NULL);
251656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
252656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	sym = dlsym(ptr, symname);
253656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(sym == NULL)
254656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
255656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		DSOerr(DSO_F_DLFCN_BIND_VAR,DSO_R_SYM_FAILURE);
256656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ERR_add_error_data(4, "symname(", symname, "): ", dlerror());
257656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return(NULL);
258656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
259656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(sym);
260656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
261656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
262656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic DSO_FUNC_TYPE dlfcn_bind_func(DSO *dso, const char *symname)
263656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
264656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	void *ptr;
26598d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom	union {
26698d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom		DSO_FUNC_TYPE sym;
26798d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom		void *dlret;
26898d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom	} u;
269656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
270656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if((dso == NULL) || (symname == NULL))
271656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
272656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		DSOerr(DSO_F_DLFCN_BIND_FUNC,ERR_R_PASSED_NULL_PARAMETER);
273656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return(NULL);
274656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
275221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if(sk_void_num(dso->meth_data) < 1)
276656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
277656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_STACK_ERROR);
278656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return(NULL);
279656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
280221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ptr = sk_void_value(dso->meth_data, sk_void_num(dso->meth_data) - 1);
281656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(ptr == NULL)
282656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
283656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_NULL_HANDLE);
284656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return(NULL);
285656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
28698d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom	u.dlret = dlsym(ptr, symname);
28798d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom	if(u.dlret == NULL)
288656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
289656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		DSOerr(DSO_F_DLFCN_BIND_FUNC,DSO_R_SYM_FAILURE);
290656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ERR_add_error_data(4, "symname(", symname, "): ", dlerror());
291656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return(NULL);
292656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
29398d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom	return u.sym;
294656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
295656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
296656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic char *dlfcn_merger(DSO *dso, const char *filespec1,
297656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	const char *filespec2)
298656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
299656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	char *merged;
300656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
301656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(!filespec1 && !filespec2)
302656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
303656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		DSOerr(DSO_F_DLFCN_MERGER,
304656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ERR_R_PASSED_NULL_PARAMETER);
305656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return(NULL);
306656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
307656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* If the first file specification is a rooted path, it rules.
308656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	   same goes if the second file specification is missing. */
309221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (!filespec2 || (filespec1 != NULL && filespec1[0] == '/'))
310656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
311656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		merged = OPENSSL_malloc(strlen(filespec1) + 1);
312656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(!merged)
313656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
314221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			DSOerr(DSO_F_DLFCN_MERGER, ERR_R_MALLOC_FAILURE);
315656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return(NULL);
316656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
317656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		strcpy(merged, filespec1);
318656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
319656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* If the first file specification is missing, the second one rules. */
320656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else if (!filespec1)
321656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
322656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		merged = OPENSSL_malloc(strlen(filespec2) + 1);
323656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(!merged)
324656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
325656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			DSOerr(DSO_F_DLFCN_MERGER,
326656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ERR_R_MALLOC_FAILURE);
327656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return(NULL);
328656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
329656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		strcpy(merged, filespec2);
330656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
331656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
332656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* This part isn't as trivial as it looks.  It assumes that
333656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		   the second file specification really is a directory, and
334656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		   makes no checks whatsoever.  Therefore, the result becomes
335656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		   the concatenation of filespec2 followed by a slash followed
336656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		   by filespec1. */
337656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
338656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		int spec2len, len;
339656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
340221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		spec2len = strlen(filespec2);
341656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		len = spec2len + (filespec1 ? strlen(filespec1) : 0);
342656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
343656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(filespec2 && filespec2[spec2len - 1] == '/')
344656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
345656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			spec2len--;
346656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			len--;
347656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
348656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		merged = OPENSSL_malloc(len + 2);
349656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(!merged)
350656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
351656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			DSOerr(DSO_F_DLFCN_MERGER,
352656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ERR_R_MALLOC_FAILURE);
353656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return(NULL);
354656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
355656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		strcpy(merged, filespec2);
356656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		merged[spec2len] = '/';
357656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		strcpy(&merged[spec2len + 1], filespec1);
358656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
359656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(merged);
360656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
361656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
36298d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom#ifdef OPENSSL_SYS_MACOSX
36398d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom#define DSO_ext	".dylib"
36498d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom#define DSO_extlen 6
36598d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom#else
36698d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom#define DSO_ext	".so"
36798d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom#define DSO_extlen 3
36898d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom#endif
36998d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom
37098d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom
371656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic char *dlfcn_name_converter(DSO *dso, const char *filename)
372656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
373656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	char *translated;
374656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int len, rsize, transform;
375656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
376656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	len = strlen(filename);
377656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	rsize = len + 1;
378656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	transform = (strstr(filename, "/") == NULL);
379656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(transform)
380656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
38198d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom		/* We will convert this to "%s.so" or "lib%s.so" etc */
38298d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom		rsize += DSO_extlen;	/* The length of ".so" */
383656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0)
384656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			rsize += 3; /* The length of "lib" */
385656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
386656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	translated = OPENSSL_malloc(rsize);
387656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(translated == NULL)
388656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
389656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		DSOerr(DSO_F_DLFCN_NAME_CONVERTER,
390656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				DSO_R_NAME_TRANSLATION_FAILED);
391656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return(NULL);
392656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
393656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(transform)
394656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
395656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0)
39698d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom			sprintf(translated, "lib%s" DSO_ext, filename);
397656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else
39898d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom			sprintf(translated, "%s" DSO_ext, filename);
399656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
400656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else
401656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		sprintf(translated, "%s", filename);
402656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(translated);
403656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
404656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
405221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#ifdef __sgi
406221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom/*
407221304ee937bc0910948a8be1320cb8cc4eb6d36Brian CarlstromThis is a quote from IRIX manual for dladdr(3c):
408221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
409221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom     <dlfcn.h> does not contain a prototype for dladdr or definition of
410221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom     Dl_info.  The #include <dlfcn.h>  in the SYNOPSIS line is traditional,
411221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom     but contains no dladdr prototype and no IRIX library contains an
412221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom     implementation.  Write your own declaration based on the code below.
413221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
414221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom     The following code is dependent on internal interfaces that are not
415221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom     part of the IRIX compatibility guarantee; however, there is no future
416221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom     intention to change this interface, so on a practical level, the code
417221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom     below is safe to use on IRIX.
418221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom*/
419221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#include <rld_interface.h>
420221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#ifndef _RLD_INTERFACE_DLFCN_H_DLADDR
421221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#define _RLD_INTERFACE_DLFCN_H_DLADDR
422221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromtypedef struct Dl_info {
423221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    const char * dli_fname;
424221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    void       * dli_fbase;
425221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    const char * dli_sname;
426221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    void       * dli_saddr;
427221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    int          dli_version;
428221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    int          dli_reserved1;
429221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    long         dli_reserved[4];
430221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom} Dl_info;
431221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#else
432221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromtypedef struct Dl_info Dl_info;
433221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#endif
434221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#define _RLD_DLADDR             14
435221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
436221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int dladdr(void *address, Dl_info *dl)
437221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom{
438221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	void *v;
439221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	v = _rld_new_interface(_RLD_DLADDR,address,dl);
440221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return (int)v;
441221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom}
442221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#endif /* __sgi */
443221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
444221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic int dlfcn_pathbyaddr(void *addr,char *path,int sz)
445221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
446221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#ifdef HAVE_DLINFO
447221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	Dl_info dli;
448221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	int len;
449221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
450221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (addr == NULL)
451221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
452221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		union	{ int(*f)(void*,char*,int); void *p; } t =
453221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom			{ dlfcn_pathbyaddr };
454221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		addr = t.p;
455221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
456221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
457221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (dladdr(addr,&dli))
458221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
459221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		len = (int)strlen(dli.dli_fname);
460221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (sz <= 0) return len+1;
461221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		if (len >= sz) len=sz-1;
462221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		memcpy(path,dli.dli_fname,len);
463221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		path[len++]=0;
464221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		return len;
465221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
466221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
467221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	ERR_add_error_data(4, "dlfcn_pathbyaddr(): ", dlerror());
468221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#endif
469221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return -1;
470221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
471221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
472221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic void *dlfcn_globallookup(const char *name)
473221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	{
474221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	void *ret = NULL,*handle = dlopen(NULL,RTLD_LAZY);
475221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
476221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	if (handle)
477221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		{
478221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		ret = dlsym(handle,name);
479221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		dlclose(handle);
480221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom		}
481221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
482221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	return ret;
483221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom	}
484656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif /* DSO_DLFCN */
485