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