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