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