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