/* dlsym, prepend the underscore and call dlsymIntern */ void *dlsym(void *handle, const char *symbol) { static char undersym[257]; /* Saves calls to malloc(3) */ int sym_len = strlen(symbol); void *value = NULL; char *malloc_sym = NULL; if (sym_len < 256) { snprintf(undersym, 256, "_%s", symbol); value = dlsymIntern(handle, undersym); } else { malloc_sym = (char*)malloc(sym_len + 2); if (malloc_sym) { sprintf(malloc_sym, "_%s", symbol); value = dlsymIntern(handle, malloc_sym); pari_free(malloc_sym); } else error(0, "Unable to allocate memory"); } return value; }
int dlclose(void * handle) { struct dlstatus * dls = handle; if (!isValidStatus(dls)) return 1; if (dls->module == MAGIC_DYLIB_MOD) { warning("trying to close a .dylib!"); error("dynamic libraries cannot be closed"); // Code inside the PAL expects to be able to dlclose anything that // could be dlopen'd, so we return success here. It doesn't matter // that we don't do anything; the PAL doesn't require any action // as a result of this dlclose. Clients of the PAL can't call // dlclose() directly, so this isn't a concern. return 0; } if (!dls->module) { error("module already closed"); return 1; } dls->refs--; if (!dls->refs) { unsigned long options = 0; void (*fini)(void); if ((fini = dlsymIntern(dls, "__fini",0))) { debug("calling _fini()"); fini(); } if (isFlagSet(dls->mode, RTLD_NODELETE)) options |= NSUNLINKMODULE_OPTION_KEEP_MEMORY_MAPPED; if (!NSUnLinkModule(dls->module, options)) { error("unable to unlink module"); return 1; } dls->module = 0; /* Note: the dlstatus struct dls is neither removed from the list * nor is the memory it occupies freed. This shouldn't pose a * problem in mostly all cases, though. */ } return 0; }
void *dlsym(void * handle, const char *symbol) { struct dlstatus * dls = handle; char *mangledSymbol; void *addr = 0; if (!isValidStatus(dls)) return NULL; // We need to "mangle" the symbol name because dyld only deals // with symbol names as the linker constructs them. The linker // adds a leading underscore. mangledSymbol = alloca(strlen(symbol) + 2); mangledSymbol[0] = '_'; mangledSymbol[1] = '\0'; strcat(mangledSymbol, symbol); addr = dlsymIntern(dls, mangledSymbol, 1); return addr; }
static struct dlstatus *loadModule(const char *path, const struct stat *sbuf, int mode) { NSObjectFileImage ofi = 0; NSObjectFileImageReturnCode ofirc; struct dlstatus *dls; NSLinkEditErrors ler; int lerno; const char *errstr; const char *file; void (*init) (void); ofirc = NSCreateObjectFileImageFromFile(path, &ofi); switch (ofirc) { case NSObjectFileImageSuccess: break; case NSObjectFileImageInappropriateFile: if (dyld_NSAddImage && dyld_NSIsSymbolNameDefinedInImage && dyld_NSLookupSymbolInImage) { if (isFlagSet(mode, RTLD_LOCAL)) { warning("trying to open a .dylib with RTLD_LOCAL"); error("unable to open this file with RTLD_LOCAL"); return NULL; } } else { error("opening this file is unsupported on this system"); return NULL; } break; case NSObjectFileImageFailure: error("object file setup failure"); return NULL; case NSObjectFileImageArch: error("no object for this architecture"); return NULL; case NSObjectFileImageFormat: error("bad object file format"); return NULL; case NSObjectFileImageAccess: error("can't read object file"); return NULL; default: error("unknown error from NSCreateObjectFileImageFromFile()"); return NULL; } dls = lookupStatus(sbuf); if (!dls) { dls = allocStatus(); } if (!dls) { error("unable to allocate memory"); return NULL; } dls->lib = 0; if (ofirc == NSObjectFileImageInappropriateFile) { if ((dls->lib = dyld_NSAddImage(path, NSADDIMAGE_OPTION_RETURN_ON_ERROR))) { debug("Dynamic lib loaded at %ld", dls->lib); ofi = MAGIC_DYLIB_OFI; dls->module = MAGIC_DYLIB_MOD; ofirc = NSObjectFileImageSuccess; /* Although it is possible with a bit of work to modify this so it works and functions with RTLD_NOW, I don't deem it necessary at the moment */ } if (!(dls->module)) { NSLinkEditError(&ler, &lerno, &file, &errstr); if (!errstr || (!strlen(errstr))) error("Can't open this file type"); else error(errstr); if ((dls->flags & DL_IN_LIST) == 0) { free(dls); } return NULL; } } else { dls->module = NSLinkModule(ofi, path, NSLINKMODULE_OPTION_RETURN_ON_ERROR | NSLINKMODULE_OPTION_PRIVATE | (isFlagSet(mode, RTLD_NOW) ? NSLINKMODULE_OPTION_BINDNOW : 0)); NSDestroyObjectFileImage(ofi); if (dls->module) { dls->lib = get_mach_header_from_NSModule(dls->module); } } if (!dls->module) { NSLinkEditError(&ler, &lerno, &file, &errstr); if ((dls->flags & DL_IN_LIST) == 0) { free(dls); } error(errstr); return NULL; } insertStatus(dls, sbuf); dls = reference(dls, mode); if ((init = dlsymIntern(dls, "__init", 0))) { debug("calling _init()"); init(); } return dls; }
static struct dlstatus * loadModule(const char * path, const struct stat * sbuf, int mode) { NSObjectFileImage ofi = 0; NSObjectFileImageReturnCode ofirc; struct dlstatus * dls; NSLinkEditErrors ler; int lerno; const char* errstr; const char* file; void (*init)(void); ofirc = NSCreateObjectFileImageFromFile(path, &ofi); switch (ofirc) { case NSObjectFileImageSuccess: break; case NSObjectFileImageInappropriateFile: if (isFlagSet(mode, RTLD_LOCAL)) { warning("trying to open a .dylib with RTLD_LOCAL"); error("unable to open this file with RTLD_LOCAL"); return NULL; } break; case NSObjectFileImageFailure: error("object file setup failure"); return NULL; case NSObjectFileImageArch: error("no object for this architecture"); return NULL; case NSObjectFileImageFormat: error("bad object file format"); return NULL; case NSObjectFileImageAccess: error("can't read object file"); return NULL; default: error("unknown error from NSCreateObjectFileImageFromFile()"); return NULL; } dls = lookupStatus(sbuf); if (!dls) { dls = allocStatus(); } if (!dls) { error("unable to allocate memory"); return NULL; } dls->lib=0; if (ofirc == NSObjectFileImageInappropriateFile) { if ((dls->lib = NSAddImage(path, NSADDIMAGE_OPTION_RETURN_ON_ERROR))) { debug("Dynamic lib loaded at %ld",dls->lib); ofi = MAGIC_DYLIB_OFI; dls->module = MAGIC_DYLIB_MOD; ofirc = NSObjectFileImageSuccess; } } else { /* Should change this to take care of RLTD_LAZY etc */ dls->module = NSLinkModule(ofi, path, NSLINKMODULE_OPTION_RETURN_ON_ERROR | NSLINKMODULE_OPTION_PRIVATE | NSLINKMODULE_OPTION_BINDNOW); NSDestroyObjectFileImage(ofi); } if (!dls->module) { NSLinkEditError(&ler,&lerno,&file,&errstr); free(dls); error(errstr); return NULL; } insertStatus(dls, sbuf); if ((init = dlsymIntern(dls, "__init",0))) { debug("calling _init()"); init(); } return dls; }