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