xref: /titanic_53/usr/src/contrib/ast/src/lib/libdll/dlfcn.c (revision 906afcb89d0412cc073b95c2d701a804a8cdb62c)
1*906afcb8SAndy Fiddaman /***********************************************************************
2*906afcb8SAndy Fiddaman *                                                                      *
3*906afcb8SAndy Fiddaman *               This software is part of the ast package               *
4*906afcb8SAndy Fiddaman *          Copyright (c) 1997-2011 AT&T Intellectual Property          *
5*906afcb8SAndy Fiddaman *                      and is licensed under the                       *
6*906afcb8SAndy Fiddaman *                 Eclipse Public License, Version 1.0                  *
7*906afcb8SAndy Fiddaman *                    by AT&T Intellectual Property                     *
8*906afcb8SAndy Fiddaman *                                                                      *
9*906afcb8SAndy Fiddaman *                A copy of the License is available at                 *
10*906afcb8SAndy Fiddaman *          http://www.eclipse.org/org/documents/epl-v10.html           *
11*906afcb8SAndy Fiddaman *         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
12*906afcb8SAndy Fiddaman *                                                                      *
13*906afcb8SAndy Fiddaman *              Information and Software Systems Research               *
14*906afcb8SAndy Fiddaman *                            AT&T Research                             *
15*906afcb8SAndy Fiddaman *                           Florham Park NJ                            *
16*906afcb8SAndy Fiddaman *                                                                      *
17*906afcb8SAndy Fiddaman *                 Glenn Fowler <gsf@research.att.com>                  *
18*906afcb8SAndy Fiddaman *                                                                      *
19*906afcb8SAndy Fiddaman ***********************************************************************/
20*906afcb8SAndy Fiddaman #pragma prototyped
21*906afcb8SAndy Fiddaman /*
22*906afcb8SAndy Fiddaman  * provide dlopen/dlsym/dlerror interface
23*906afcb8SAndy Fiddaman  *
24*906afcb8SAndy Fiddaman  * David Korn
25*906afcb8SAndy Fiddaman  * Glenn Fowler
26*906afcb8SAndy Fiddaman  * AT&T Research
27*906afcb8SAndy Fiddaman  */
28*906afcb8SAndy Fiddaman 
29*906afcb8SAndy Fiddaman static const char id[] = "\n@(#)$Id: dll library (AT&T Research) 2009-04-15 $\0\n";
30*906afcb8SAndy Fiddaman 
31*906afcb8SAndy Fiddaman #include <ast.h>
32*906afcb8SAndy Fiddaman #include <dlldefs.h>
33*906afcb8SAndy Fiddaman #include <error.h>
34*906afcb8SAndy Fiddaman 
35*906afcb8SAndy Fiddaman #define T(x)	ERROR_dictionary(x)
36*906afcb8SAndy Fiddaman 
37*906afcb8SAndy Fiddaman #if _BLD_dll && defined(__EXPORT__)
38*906afcb8SAndy Fiddaman #define extern	__EXPORT__
39*906afcb8SAndy Fiddaman #endif
40*906afcb8SAndy Fiddaman 
41*906afcb8SAndy Fiddaman #if _hdr_dlfcn && _lib_dlopen
42*906afcb8SAndy Fiddaman 
43*906afcb8SAndy Fiddaman 	/*
44*906afcb8SAndy Fiddaman 	 * standard
45*906afcb8SAndy Fiddaman 	 */
46*906afcb8SAndy Fiddaman 
47*906afcb8SAndy Fiddaman #	include <dlfcn.h>
48*906afcb8SAndy Fiddaman 
49*906afcb8SAndy Fiddaman #else
50*906afcb8SAndy Fiddaman #if _hdr_dl
51*906afcb8SAndy Fiddaman 
52*906afcb8SAndy Fiddaman 	/*
53*906afcb8SAndy Fiddaman 	 * HP-UX
54*906afcb8SAndy Fiddaman  	 */
55*906afcb8SAndy Fiddaman 
56*906afcb8SAndy Fiddaman #	include <dl.h>
57*906afcb8SAndy Fiddaman #	ifndef BIND_FIRST
58*906afcb8SAndy Fiddaman #	define BIND_FIRST	0x4
59*906afcb8SAndy Fiddaman #	endif
60*906afcb8SAndy Fiddaman #	ifndef BIND_NOSTART
61*906afcb8SAndy Fiddaman #	define BIND_NOSTART	0x10
62*906afcb8SAndy Fiddaman #	endif
63*906afcb8SAndy Fiddaman 
64*906afcb8SAndy Fiddaman 	static shl_t	all;
65*906afcb8SAndy Fiddaman 	static int	err;
66*906afcb8SAndy Fiddaman 
dlopen(const char * path,int mode)67*906afcb8SAndy Fiddaman 	extern void* dlopen(const char* path, int mode)
68*906afcb8SAndy Fiddaman 	{
69*906afcb8SAndy Fiddaman 		void*	dll;
70*906afcb8SAndy Fiddaman 
71*906afcb8SAndy Fiddaman 		if (!path)
72*906afcb8SAndy Fiddaman 			return (void*)&all;
73*906afcb8SAndy Fiddaman 		if (mode)
74*906afcb8SAndy Fiddaman 			mode = (BIND_IMMEDIATE|BIND_FIRST|BIND_NOSTART);
75*906afcb8SAndy Fiddaman 		if (!(dll = (void*)shl_load(path, mode, 0L)))
76*906afcb8SAndy Fiddaman 			err = errno;
77*906afcb8SAndy Fiddaman 		return dll;
78*906afcb8SAndy Fiddaman 	}
79*906afcb8SAndy Fiddaman 
dlclose(void * dll)80*906afcb8SAndy Fiddaman 	extern int dlclose(void* dll)
81*906afcb8SAndy Fiddaman 	{
82*906afcb8SAndy Fiddaman 		return 0;
83*906afcb8SAndy Fiddaman 	}
84*906afcb8SAndy Fiddaman 
dlsym(void * dll,const char * name)85*906afcb8SAndy Fiddaman 	extern void* dlsym(void* dll, const char* name)
86*906afcb8SAndy Fiddaman 	{
87*906afcb8SAndy Fiddaman 		shl_t	handle;
88*906afcb8SAndy Fiddaman 		long	addr;
89*906afcb8SAndy Fiddaman 
90*906afcb8SAndy Fiddaman 		handle = dll == (void*)&all ? (shl_t)0 : (shl_t)dll;
91*906afcb8SAndy Fiddaman 		if (shl_findsym(&handle, name, TYPE_UNDEFINED, &addr))
92*906afcb8SAndy Fiddaman 		{
93*906afcb8SAndy Fiddaman 			err = errno;
94*906afcb8SAndy Fiddaman 			return 0;
95*906afcb8SAndy Fiddaman 		}
96*906afcb8SAndy Fiddaman 		return (void*)addr;
97*906afcb8SAndy Fiddaman 	}
98*906afcb8SAndy Fiddaman 
dlerror(void)99*906afcb8SAndy Fiddaman 	extern char* dlerror(void)
100*906afcb8SAndy Fiddaman 	{
101*906afcb8SAndy Fiddaman 		char*	msg;
102*906afcb8SAndy Fiddaman 
103*906afcb8SAndy Fiddaman 		if (!err)
104*906afcb8SAndy Fiddaman 			return 0;
105*906afcb8SAndy Fiddaman 		msg = fmterror(err);
106*906afcb8SAndy Fiddaman 		err = 0;
107*906afcb8SAndy Fiddaman 		return msg;
108*906afcb8SAndy Fiddaman 	}
109*906afcb8SAndy Fiddaman 
110*906afcb8SAndy Fiddaman #else
111*906afcb8SAndy Fiddaman #if _sys_ldr && _lib_loadbind
112*906afcb8SAndy Fiddaman 
113*906afcb8SAndy Fiddaman 	/*
114*906afcb8SAndy Fiddaman 	 * rs6000
115*906afcb8SAndy Fiddaman 	 */
116*906afcb8SAndy Fiddaman 
117*906afcb8SAndy Fiddaman #	include <sys/ldr.h>
118*906afcb8SAndy Fiddaman #	include <xcoff.h>
119*906afcb8SAndy Fiddaman 
120*906afcb8SAndy Fiddaman 	/* xcoff module header */
121*906afcb8SAndy Fiddaman 	struct hdr
122*906afcb8SAndy Fiddaman 	{
123*906afcb8SAndy Fiddaman 		struct filehdr	f;
124*906afcb8SAndy Fiddaman 		struct aouthdr	a;
125*906afcb8SAndy Fiddaman 		struct scnhdr	s[1];
126*906afcb8SAndy Fiddaman 	};
127*906afcb8SAndy Fiddaman 
128*906afcb8SAndy Fiddaman 	static struct ld_info*	ld_info;
129*906afcb8SAndy Fiddaman 	static unsigned int	ld_info_size = 1024;
130*906afcb8SAndy Fiddaman 	static void*		last_module;
131*906afcb8SAndy Fiddaman 	static int		err;
132*906afcb8SAndy Fiddaman 
dlopen(const char * path,int mode)133*906afcb8SAndy Fiddaman 	extern void* dlopen(const char* path, int mode)
134*906afcb8SAndy Fiddaman 	{
135*906afcb8SAndy Fiddaman 		void*	dll;
136*906afcb8SAndy Fiddaman 
137*906afcb8SAndy Fiddaman 		if (!(dll = (void*)load((char*)path, mode, getenv("LIBPATH"))))
138*906afcb8SAndy Fiddaman 			err = errno;
139*906afcb8SAndy Fiddaman 		return dll;
140*906afcb8SAndy Fiddaman 	}
141*906afcb8SAndy Fiddaman 
dlclose(void * dll)142*906afcb8SAndy Fiddaman 	extern int dlclose(void* dll)
143*906afcb8SAndy Fiddaman 	{
144*906afcb8SAndy Fiddaman 		return 0;
145*906afcb8SAndy Fiddaman 	}
146*906afcb8SAndy Fiddaman 
getquery(void)147*906afcb8SAndy Fiddaman 	static int getquery(void)
148*906afcb8SAndy Fiddaman 	{
149*906afcb8SAndy Fiddaman 		if (!ld_info)
150*906afcb8SAndy Fiddaman 			ld_info = malloc(ld_info_size);
151*906afcb8SAndy Fiddaman 		for (;;)
152*906afcb8SAndy Fiddaman 		{
153*906afcb8SAndy Fiddaman 			if (!ld_info)
154*906afcb8SAndy Fiddaman 				return 1;
155*906afcb8SAndy Fiddaman 			if (!loadquery(L_GETINFO, ld_info, ld_info_size))
156*906afcb8SAndy Fiddaman 				return 0;
157*906afcb8SAndy Fiddaman 			if (errno != ENOMEM)
158*906afcb8SAndy Fiddaman 				return 1;
159*906afcb8SAndy Fiddaman 			ld_info = realloc(ld_info, ld_info_size *= 2);
160*906afcb8SAndy Fiddaman 		}
161*906afcb8SAndy Fiddaman  	}
162*906afcb8SAndy Fiddaman 
163*906afcb8SAndy Fiddaman 	/* find the loaded module whose data area contains the
164*906afcb8SAndy Fiddaman 	 * address passed in. Remember that procedure pointers
165*906afcb8SAndy Fiddaman 	 * are implemented as pointers to descriptors in the
166*906afcb8SAndy Fiddaman 	 * data area of the module defining the procedure
167*906afcb8SAndy Fiddaman 	 */
getinfo(void * module)168*906afcb8SAndy Fiddaman 	static struct ld_info* getinfo(void* module)
169*906afcb8SAndy Fiddaman 	{
170*906afcb8SAndy Fiddaman 		struct ld_info*	info = ld_info;
171*906afcb8SAndy Fiddaman 		register int	n = 1;
172*906afcb8SAndy Fiddaman 
173*906afcb8SAndy Fiddaman 		if (!ld_info || module != last_module)
174*906afcb8SAndy Fiddaman 		{
175*906afcb8SAndy Fiddaman 			last_module = module;
176*906afcb8SAndy Fiddaman 			if (getquery())
177*906afcb8SAndy Fiddaman 				return 0;
178*906afcb8SAndy Fiddaman 			info = ld_info;
179*906afcb8SAndy Fiddaman 		}
180*906afcb8SAndy Fiddaman 		while (n)
181*906afcb8SAndy Fiddaman 		{
182*906afcb8SAndy Fiddaman 			if ((char*)(info->ldinfo_dataorg) <= (char*)module &&
183*906afcb8SAndy Fiddaman 				(char*)module <= ((char*)(info->ldinfo_dataorg)
184*906afcb8SAndy Fiddaman 				+ (unsigned)(info->ldinfo_datasize)))
185*906afcb8SAndy Fiddaman 				return info;
186*906afcb8SAndy Fiddaman 			if (n=info->ldinfo_next)
187*906afcb8SAndy Fiddaman 				info = (void*)((char*)info + n);
188*906afcb8SAndy Fiddaman 		}
189*906afcb8SAndy Fiddaman 		return 0;
190*906afcb8SAndy Fiddaman 	}
191*906afcb8SAndy Fiddaman 
getloc(struct hdr * hdr,char * data,char * name)192*906afcb8SAndy Fiddaman 	static char* getloc(struct hdr* hdr, char* data, char* name)
193*906afcb8SAndy Fiddaman 	{
194*906afcb8SAndy Fiddaman 		struct ldhdr*	ldhdr;
195*906afcb8SAndy Fiddaman 		struct ldsym*	ldsym;
196*906afcb8SAndy Fiddaman 		ulong		datareloc;
197*906afcb8SAndy Fiddaman 		ulong		textreloc;
198*906afcb8SAndy Fiddaman 		int		i;
199*906afcb8SAndy Fiddaman 
200*906afcb8SAndy Fiddaman 		/* data is relocated by the difference between
201*906afcb8SAndy Fiddaman 		 * its virtual origin and where it was
202*906afcb8SAndy Fiddaman 		 * actually placed
203*906afcb8SAndy Fiddaman 		 */
204*906afcb8SAndy Fiddaman 		/*N.B. o_sndata etc. are one based */
205*906afcb8SAndy Fiddaman 		datareloc = (ulong)data - hdr->s[hdr->a.o_sndata-1].s_vaddr;
206*906afcb8SAndy Fiddaman 		/*hdr is address of header, not text, so add text s_scnptr */
207*906afcb8SAndy Fiddaman 		textreloc = (ulong)hdr + hdr->s[hdr->a.o_sntext-1].s_scnptr
208*906afcb8SAndy Fiddaman 			- hdr->s[hdr->a.o_sntext-1].s_vaddr;
209*906afcb8SAndy Fiddaman 		ldhdr = (void*)((char*)hdr+ hdr->s[hdr->a.o_snloader-1].s_scnptr);
210*906afcb8SAndy Fiddaman 		ldsym = (void*) (ldhdr+1);
211*906afcb8SAndy Fiddaman 		/* search the exports symbols */
212*906afcb8SAndy Fiddaman 		for(i=0; i < ldhdr->l_nsyms;ldsym++,i++)
213*906afcb8SAndy Fiddaman 		{
214*906afcb8SAndy Fiddaman 			char *symname,symbuf[9];
215*906afcb8SAndy Fiddaman 			char *loc;
216*906afcb8SAndy Fiddaman 			/* the symbol name representation is a nuisance since
217*906afcb8SAndy Fiddaman 			 * 8 character names appear in l_name but may
218*906afcb8SAndy Fiddaman 			 * not be null terminated. This code works around
219*906afcb8SAndy Fiddaman 			 * that by brute force
220*906afcb8SAndy Fiddaman 			 */
221*906afcb8SAndy Fiddaman 			if (ldsym->l_zeroes)
222*906afcb8SAndy Fiddaman 			{
223*906afcb8SAndy Fiddaman 				symname = symbuf;
224*906afcb8SAndy Fiddaman 				memcpy(symbuf,ldsym->l_name,8);
225*906afcb8SAndy Fiddaman 				symbuf[8] = 0;
226*906afcb8SAndy Fiddaman 			}
227*906afcb8SAndy Fiddaman 			else
228*906afcb8SAndy Fiddaman 				symname = (void*)(ldsym->l_offset + (ulong)ldhdr + ldhdr->l_stoff);
229*906afcb8SAndy Fiddaman 			if (strcmp(symname,name))
230*906afcb8SAndy Fiddaman 				continue;
231*906afcb8SAndy Fiddaman 			loc = (char*)ldsym->l_value;
232*906afcb8SAndy Fiddaman 			if ((ldsym->l_scnum==hdr->a.o_sndata) ||
233*906afcb8SAndy Fiddaman 				(ldsym->l_scnum==hdr->a.o_snbss))
234*906afcb8SAndy Fiddaman 				loc += datareloc;
235*906afcb8SAndy Fiddaman 			else if (ldsym->l_scnum==hdr->a.o_sntext)
236*906afcb8SAndy Fiddaman 				loc += textreloc;
237*906afcb8SAndy Fiddaman 			return loc;
238*906afcb8SAndy Fiddaman 		}
239*906afcb8SAndy Fiddaman 		return 0;
240*906afcb8SAndy Fiddaman 	}
241*906afcb8SAndy Fiddaman 
dlsym(void * handle,const char * name)242*906afcb8SAndy Fiddaman 	extern void* dlsym(void* handle, const char* name)
243*906afcb8SAndy Fiddaman 	{
244*906afcb8SAndy Fiddaman 		void*		addr;
245*906afcb8SAndy Fiddaman 		struct ld_info*	info;
246*906afcb8SAndy Fiddaman 
247*906afcb8SAndy Fiddaman 		if (!(info = getinfo(handle)) || !(addr = getloc(info->ldinfo_textorg,info->ldinfo_dataorg,(char*)name)))
248*906afcb8SAndy Fiddaman 		{
249*906afcb8SAndy Fiddaman 			err = errno;
250*906afcb8SAndy Fiddaman 			return 0;
251*906afcb8SAndy Fiddaman 		}
252*906afcb8SAndy Fiddaman 		return addr;
253*906afcb8SAndy Fiddaman 	}
254*906afcb8SAndy Fiddaman 
dlerror(void)255*906afcb8SAndy Fiddaman 	extern char* dlerror(void)
256*906afcb8SAndy Fiddaman 	{
257*906afcb8SAndy Fiddaman 		char*	msg;
258*906afcb8SAndy Fiddaman 
259*906afcb8SAndy Fiddaman 		if (!err)
260*906afcb8SAndy Fiddaman 			return 0;
261*906afcb8SAndy Fiddaman 		msg = fmterror(err);
262*906afcb8SAndy Fiddaman 		err = 0;
263*906afcb8SAndy Fiddaman 		return msg;
264*906afcb8SAndy Fiddaman 	}
265*906afcb8SAndy Fiddaman 
266*906afcb8SAndy Fiddaman #else
267*906afcb8SAndy Fiddaman #if _hdr_dll && _lib_dllload
268*906afcb8SAndy Fiddaman 
269*906afcb8SAndy Fiddaman 	/*
270*906afcb8SAndy Fiddaman 	 * MVS
271*906afcb8SAndy Fiddaman 	 */
272*906afcb8SAndy Fiddaman 
273*906afcb8SAndy Fiddaman #	include <dll.h>
274*906afcb8SAndy Fiddaman 
275*906afcb8SAndy Fiddaman 	static int	err;
276*906afcb8SAndy Fiddaman 
dlopen(const char * path,int mode)277*906afcb8SAndy Fiddaman 	extern void* dlopen(const char* path, int mode)
278*906afcb8SAndy Fiddaman 	{
279*906afcb8SAndy Fiddaman 		void*	dll;
280*906afcb8SAndy Fiddaman 
281*906afcb8SAndy Fiddaman 		NoP(mode);
282*906afcb8SAndy Fiddaman 		if (!(dll = (void*)dllload(path)))
283*906afcb8SAndy Fiddaman 			err = errno;
284*906afcb8SAndy Fiddaman 		return dll;
285*906afcb8SAndy Fiddaman 	}
286*906afcb8SAndy Fiddaman 
dlclose(void * dll)287*906afcb8SAndy Fiddaman 	extern int dlclose(void* dll)
288*906afcb8SAndy Fiddaman 	{
289*906afcb8SAndy Fiddaman 		return 0;
290*906afcb8SAndy Fiddaman 	}
291*906afcb8SAndy Fiddaman 
dlsym(void * handle,const char * name)292*906afcb8SAndy Fiddaman 	extern void* dlsym(void* handle, const char* name)
293*906afcb8SAndy Fiddaman 	{
294*906afcb8SAndy Fiddaman 		void*	addr;
295*906afcb8SAndy Fiddaman 
296*906afcb8SAndy Fiddaman 		if (!(addr = (void*)dllqueryfn(handle, (char*)name)))
297*906afcb8SAndy Fiddaman 			err = errno;
298*906afcb8SAndy Fiddaman 		return addr;
299*906afcb8SAndy Fiddaman 	}
300*906afcb8SAndy Fiddaman 
dlerror(void)301*906afcb8SAndy Fiddaman 	extern char* dlerror(void)
302*906afcb8SAndy Fiddaman 	{
303*906afcb8SAndy Fiddaman 		char*	msg;
304*906afcb8SAndy Fiddaman 
305*906afcb8SAndy Fiddaman 		if (!err)
306*906afcb8SAndy Fiddaman 			return 0;
307*906afcb8SAndy Fiddaman 		msg = fmterror(err);
308*906afcb8SAndy Fiddaman 		err = 0;
309*906afcb8SAndy Fiddaman 		return msg;
310*906afcb8SAndy Fiddaman 	}
311*906afcb8SAndy Fiddaman 
312*906afcb8SAndy Fiddaman #else
313*906afcb8SAndy Fiddaman #if _hdr_mach_o_dyld
314*906afcb8SAndy Fiddaman 
315*906afcb8SAndy Fiddaman 	/*
316*906afcb8SAndy Fiddaman 	 * mac[h]
317*906afcb8SAndy Fiddaman 	 */
318*906afcb8SAndy Fiddaman 
319*906afcb8SAndy Fiddaman #	include <mach-o/dyld.h>
320*906afcb8SAndy Fiddaman 
321*906afcb8SAndy Fiddaman 	typedef const struct mach_header* NSImage;
322*906afcb8SAndy Fiddaman 
323*906afcb8SAndy Fiddaman 	typedef struct Dll_s
324*906afcb8SAndy Fiddaman 	{
325*906afcb8SAndy Fiddaman 		unsigned long	magic;
326*906afcb8SAndy Fiddaman 		NSImage		image;
327*906afcb8SAndy Fiddaman 		NSModule	module;
328*906afcb8SAndy Fiddaman 		char		path[1];
329*906afcb8SAndy Fiddaman 	} Dll_t;
330*906afcb8SAndy Fiddaman 
331*906afcb8SAndy Fiddaman 	#define DL_MAGIC	0x04190c04
332*906afcb8SAndy Fiddaman 	#define DL_NEXT		((Dll_t*)RTLD_NEXT)
333*906afcb8SAndy Fiddaman 
334*906afcb8SAndy Fiddaman 	static const char*	dlmessage = "no error";
335*906afcb8SAndy Fiddaman 
336*906afcb8SAndy Fiddaman 	static const char	e_cover[] = T("cannot access covered library");
337*906afcb8SAndy Fiddaman 	static const char	e_handle[] = T("invalid handle");
338*906afcb8SAndy Fiddaman 	static const char	e_space[] = T("out of space");
339*906afcb8SAndy Fiddaman 	static const char	e_static[] = T("image statically linked");
340*906afcb8SAndy Fiddaman 	static const char	e_undefined[] = T("undefined symbol");
341*906afcb8SAndy Fiddaman 
342*906afcb8SAndy Fiddaman 	static Dll_t global = { DL_MAGIC };
343*906afcb8SAndy Fiddaman 
undefined(const char * name)344*906afcb8SAndy Fiddaman 	static void undefined(const char* name)
345*906afcb8SAndy Fiddaman 	{
346*906afcb8SAndy Fiddaman 	}
347*906afcb8SAndy Fiddaman 
multiple(NSSymbol sym,NSModule om,NSModule nm)348*906afcb8SAndy Fiddaman 	static NSModule multiple(NSSymbol sym, NSModule om, NSModule nm)
349*906afcb8SAndy Fiddaman 	{
350*906afcb8SAndy Fiddaman 		return om;
351*906afcb8SAndy Fiddaman 	}
352*906afcb8SAndy Fiddaman 
linkedit(NSLinkEditErrors c,int n,const char * f,const char * m)353*906afcb8SAndy Fiddaman 	static void linkedit(NSLinkEditErrors c, int n, const char* f, const char* m)
354*906afcb8SAndy Fiddaman 	{
355*906afcb8SAndy Fiddaman 		dlmessage = m;
356*906afcb8SAndy Fiddaman 	}
357*906afcb8SAndy Fiddaman 
358*906afcb8SAndy Fiddaman 	static NSLinkEditErrorHandlers handlers =
359*906afcb8SAndy Fiddaman 	{
360*906afcb8SAndy Fiddaman 		undefined, multiple, linkedit
361*906afcb8SAndy Fiddaman 	};
362*906afcb8SAndy Fiddaman 
dlopen(const char * path,int mode)363*906afcb8SAndy Fiddaman 	extern void* dlopen(const char* path, int mode)
364*906afcb8SAndy Fiddaman 	{
365*906afcb8SAndy Fiddaman 		Dll_t*			dll;
366*906afcb8SAndy Fiddaman 		int			i;
367*906afcb8SAndy Fiddaman 		NSObjectFileImage	image;
368*906afcb8SAndy Fiddaman 
369*906afcb8SAndy Fiddaman 		static int		init = 0;
370*906afcb8SAndy Fiddaman 
371*906afcb8SAndy Fiddaman 		if (!_dyld_present())
372*906afcb8SAndy Fiddaman 		{
373*906afcb8SAndy Fiddaman 			dlmessage = e_static;
374*906afcb8SAndy Fiddaman 			return 0;
375*906afcb8SAndy Fiddaman 		}
376*906afcb8SAndy Fiddaman 		if (!init)
377*906afcb8SAndy Fiddaman 		{
378*906afcb8SAndy Fiddaman 			init = 1;
379*906afcb8SAndy Fiddaman 			NSInstallLinkEditErrorHandlers(&handlers);
380*906afcb8SAndy Fiddaman 		}
381*906afcb8SAndy Fiddaman 		if (!path)
382*906afcb8SAndy Fiddaman 			dll = &global;
383*906afcb8SAndy Fiddaman 		else if (!(dll = newof(0, Dll_t, 1, strlen(path))))
384*906afcb8SAndy Fiddaman 		{
385*906afcb8SAndy Fiddaman 			dlmessage = e_space;
386*906afcb8SAndy Fiddaman 			return 0;
387*906afcb8SAndy Fiddaman 		}
388*906afcb8SAndy Fiddaman 		else
389*906afcb8SAndy Fiddaman 		{
390*906afcb8SAndy Fiddaman 			switch (NSCreateObjectFileImageFromFile(path, &image))
391*906afcb8SAndy Fiddaman 			{
392*906afcb8SAndy Fiddaman 			case NSObjectFileImageSuccess:
393*906afcb8SAndy Fiddaman 				dll->module = NSLinkModule(image, path, (mode & RTLD_LAZY) ? 0 : NSLINKMODULE_OPTION_BINDNOW);
394*906afcb8SAndy Fiddaman 				NSDestroyObjectFileImage(image);
395*906afcb8SAndy Fiddaman 				if (!dll->module)
396*906afcb8SAndy Fiddaman 				{
397*906afcb8SAndy Fiddaman 					free(dll);
398*906afcb8SAndy Fiddaman 					return 0;
399*906afcb8SAndy Fiddaman 				}
400*906afcb8SAndy Fiddaman 				break;
401*906afcb8SAndy Fiddaman 			case NSObjectFileImageInappropriateFile:
402*906afcb8SAndy Fiddaman 				dll->image = NSAddImage(path, 0);
403*906afcb8SAndy Fiddaman 				if (!dll->image)
404*906afcb8SAndy Fiddaman 				{
405*906afcb8SAndy Fiddaman 					free(dll);
406*906afcb8SAndy Fiddaman 					return 0;
407*906afcb8SAndy Fiddaman 				}
408*906afcb8SAndy Fiddaman 				break;
409*906afcb8SAndy Fiddaman 			default:
410*906afcb8SAndy Fiddaman 				free(dll);
411*906afcb8SAndy Fiddaman 				return 0;
412*906afcb8SAndy Fiddaman 			}
413*906afcb8SAndy Fiddaman 			strcpy(dll->path, path);
414*906afcb8SAndy Fiddaman 			dll->magic = DL_MAGIC;
415*906afcb8SAndy Fiddaman 		}
416*906afcb8SAndy Fiddaman 		return (void*)dll;
417*906afcb8SAndy Fiddaman 	}
418*906afcb8SAndy Fiddaman 
dlclose(void * handle)419*906afcb8SAndy Fiddaman 	extern int dlclose(void* handle)
420*906afcb8SAndy Fiddaman 	{
421*906afcb8SAndy Fiddaman 		Dll_t*	dll = (Dll_t*)handle;
422*906afcb8SAndy Fiddaman 
423*906afcb8SAndy Fiddaman 		if (!dll || dll == DL_NEXT || dll->magic != DL_MAGIC)
424*906afcb8SAndy Fiddaman 		{
425*906afcb8SAndy Fiddaman 			dlmessage = e_handle;
426*906afcb8SAndy Fiddaman 			return -1;
427*906afcb8SAndy Fiddaman 		}
428*906afcb8SAndy Fiddaman 		if (dll->module)
429*906afcb8SAndy Fiddaman 			NSUnLinkModule(dll->module, 0);
430*906afcb8SAndy Fiddaman 		free(dll);
431*906afcb8SAndy Fiddaman 		return 0;
432*906afcb8SAndy Fiddaman 	}
433*906afcb8SAndy Fiddaman 
434*906afcb8SAndy Fiddaman 	static NSSymbol
lookup(Dll_t * dll,const char * name)435*906afcb8SAndy Fiddaman 	lookup(Dll_t* dll, const char* name)
436*906afcb8SAndy Fiddaman 	{
437*906afcb8SAndy Fiddaman 		unsigned long	pun;
438*906afcb8SAndy Fiddaman 		void*		address;
439*906afcb8SAndy Fiddaman 
440*906afcb8SAndy Fiddaman 		if (dll == DL_NEXT)
441*906afcb8SAndy Fiddaman 		{
442*906afcb8SAndy Fiddaman 			if (!_dyld_func_lookup(name, &pun))
443*906afcb8SAndy Fiddaman 				return 0;
444*906afcb8SAndy Fiddaman 			address = (NSSymbol)pun;
445*906afcb8SAndy Fiddaman 		}
446*906afcb8SAndy Fiddaman 		else if (dll->module)
447*906afcb8SAndy Fiddaman 			address = NSLookupSymbolInModule(dll->module, name);
448*906afcb8SAndy Fiddaman 		else if (dll->image)
449*906afcb8SAndy Fiddaman 		{
450*906afcb8SAndy Fiddaman 			if (!NSIsSymbolNameDefinedInImage(dll->image, name))
451*906afcb8SAndy Fiddaman 				return 0;
452*906afcb8SAndy Fiddaman 			address = NSLookupSymbolInImage(dll->image, name, 0);
453*906afcb8SAndy Fiddaman 		}
454*906afcb8SAndy Fiddaman 		else
455*906afcb8SAndy Fiddaman 		{
456*906afcb8SAndy Fiddaman 			if (!NSIsSymbolNameDefined(name))
457*906afcb8SAndy Fiddaman 				return 0;
458*906afcb8SAndy Fiddaman 			address = NSLookupAndBindSymbol(name);
459*906afcb8SAndy Fiddaman 		}
460*906afcb8SAndy Fiddaman 		if (address)
461*906afcb8SAndy Fiddaman 			address = NSAddressOfSymbol(address);
462*906afcb8SAndy Fiddaman 		return address;
463*906afcb8SAndy Fiddaman 	}
464*906afcb8SAndy Fiddaman 
dlsym(void * handle,const char * name)465*906afcb8SAndy Fiddaman 	extern void* dlsym(void* handle, const char* name)
466*906afcb8SAndy Fiddaman 	{
467*906afcb8SAndy Fiddaman 		Dll_t*		dll = (Dll_t*)handle;
468*906afcb8SAndy Fiddaman 		NSSymbol	address;
469*906afcb8SAndy Fiddaman 		char		buf[1024];
470*906afcb8SAndy Fiddaman 
471*906afcb8SAndy Fiddaman 		if (!dll || dll != DL_NEXT && (dll->magic != DL_MAGIC || !dll->image && !dll->module))
472*906afcb8SAndy Fiddaman 		{
473*906afcb8SAndy Fiddaman 			dlmessage = e_handle;
474*906afcb8SAndy Fiddaman 			return 0;
475*906afcb8SAndy Fiddaman 		}
476*906afcb8SAndy Fiddaman 		if (!(address = lookup(dll, name)) && name[0] != '_' && strlen(name) < (sizeof(buf) - 1))
477*906afcb8SAndy Fiddaman 		{
478*906afcb8SAndy Fiddaman 			buf[0] = '_';
479*906afcb8SAndy Fiddaman 			strcpy(buf + 1, name);
480*906afcb8SAndy Fiddaman 			address = lookup(dll, buf);
481*906afcb8SAndy Fiddaman 		}
482*906afcb8SAndy Fiddaman 		if (!address)
483*906afcb8SAndy Fiddaman 		{
484*906afcb8SAndy Fiddaman 			dlmessage = dll == DL_NEXT ? e_cover : e_undefined;
485*906afcb8SAndy Fiddaman 			return 0;
486*906afcb8SAndy Fiddaman 		}
487*906afcb8SAndy Fiddaman 		return (void*)address;
488*906afcb8SAndy Fiddaman 	}
489*906afcb8SAndy Fiddaman 
dlerror(void)490*906afcb8SAndy Fiddaman 	extern char* dlerror(void)
491*906afcb8SAndy Fiddaman 	{
492*906afcb8SAndy Fiddaman 		char*	msg;
493*906afcb8SAndy Fiddaman 
494*906afcb8SAndy Fiddaman 		msg = (char*)dlmessage;
495*906afcb8SAndy Fiddaman 		dlmessage = 0;
496*906afcb8SAndy Fiddaman 		return msg;
497*906afcb8SAndy Fiddaman 	}
498*906afcb8SAndy Fiddaman 
499*906afcb8SAndy Fiddaman #else
500*906afcb8SAndy Fiddaman 	/*
501*906afcb8SAndy Fiddaman 	 * punt
502*906afcb8SAndy Fiddaman 	 */
503*906afcb8SAndy Fiddaman 
504*906afcb8SAndy Fiddaman 	static int	err;
505*906afcb8SAndy Fiddaman 
dlopen(const char * path,int mode)506*906afcb8SAndy Fiddaman 	extern void* dlopen(const char* path, int mode)
507*906afcb8SAndy Fiddaman 	{
508*906afcb8SAndy Fiddaman 		err = 1;
509*906afcb8SAndy Fiddaman 		return 0;
510*906afcb8SAndy Fiddaman 	}
511*906afcb8SAndy Fiddaman 
dlclose(void * dll)512*906afcb8SAndy Fiddaman 	extern int dlclose(void* dll)
513*906afcb8SAndy Fiddaman 	{
514*906afcb8SAndy Fiddaman 		err = 1;
515*906afcb8SAndy Fiddaman 		return 0;
516*906afcb8SAndy Fiddaman 	}
517*906afcb8SAndy Fiddaman 
dlsym(void * handle,const char * name)518*906afcb8SAndy Fiddaman 	extern void* dlsym(void* handle, const char* name)
519*906afcb8SAndy Fiddaman 	{
520*906afcb8SAndy Fiddaman 		err = 1;
521*906afcb8SAndy Fiddaman 		return 0;
522*906afcb8SAndy Fiddaman 	}
523*906afcb8SAndy Fiddaman 
dlerror(void)524*906afcb8SAndy Fiddaman 	extern char* dlerror(void)
525*906afcb8SAndy Fiddaman 	{
526*906afcb8SAndy Fiddaman 		if (!err)
527*906afcb8SAndy Fiddaman 			return 0;
528*906afcb8SAndy Fiddaman 		err = 0;
529*906afcb8SAndy Fiddaman 		return "dynamic linking not supported";
530*906afcb8SAndy Fiddaman 	}
531*906afcb8SAndy Fiddaman 
532*906afcb8SAndy Fiddaman #endif
533*906afcb8SAndy Fiddaman #endif
534*906afcb8SAndy Fiddaman #endif
535*906afcb8SAndy Fiddaman #endif
536*906afcb8SAndy Fiddaman #endif
537