📄 mal_linker.c
字号:
#line 89 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_linker.mx"#include "mal_config.h"#include "mal_linker.h"#include "mal_function.h" /* for throwException() */#include "mal_import.h" /* for slash_2_dir_sep() */static int noDlopen;#define MAXMODULES 256typedef struct{ str filename; str fullname; void **handle;} FileRecord;static FileRecord *filesLoaded;static int maxfiles = 0;static int lastfile = 0;MALfcngetLocalObjectFile(str filename){ int mode = RTLD_NOW | RTLD_GLOBAL; void *handle = NULL; char *fullname; fullname = MSP_locate_file(filename); if (fullname == NULL) {#ifdef DEBUG_MAL_LINKER stream_printf(GDKout,"Name not resolved %s\n",filename);#endif return 0; }#ifdef DEBUG_MAL_LINKER printf("attempt to load function %s from %s\n",filename, fullname);#endif handle = dlopen(fullname, mode);#ifdef DEBUG_MAL_LINKER stream_printf(GDKout, "localObjectLoaded ? %s\n",(handle!=0?"yes":"no"));#endif if (handle) return (MALfcn) dlsym(handle, filename); stream_printf(GDKout, "could not access library %s\n", dlerror()); return 0;}MALfcngetAddress(str filename, str modnme, str fcnname, int silent){ void *dl = 0; MALfcn adr; int idx;#ifdef DEBUG_MAL_LINKER2 stream_printf(GDKout, "address of %s.%s from '%s' ?\n", (modnme?modnme:"<unknown>"), fcnname, (filename?filename:"<stdin>"));#else (void) modnme;#endif#line 151 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_linker.mx" for(idx =0; idx < lastfile && filesLoaded[idx].filename; idx++) if( strcmp(filename, filesLoaded[idx].filename)==0) { adr = (MALfcn) dlsym(filesLoaded[idx].handle, fcnname); if( adr != NULL) return adr; /* found it */ }#line 163 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_linker.mx" for(idx =0; idx < lastfile && filesLoaded[idx].handle; idx++){ adr = (MALfcn) dlsym(filesLoaded[idx].handle, fcnname); if( adr != NULL) return adr; /* found it */ }#line 172 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_linker.mx" dl = dlopen(NULL, RTLD_NOW | RTLD_GLOBAL); if( dl != NULL){ adr = (MALfcn) dlsym(dl, fcnname); if( adr != NULL) return adr; /* found it */ } if( !silent) showException(MAL,"MAL.getAddress", "address of '%s.%s' not found", (modnme?modnme:"<unknown>"), fcnname); return NULL;}#line 184 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_linker.mx"#line 201 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_linker.mx"static voidinitM5Loader(){ FileRecord *newFilesLoaded; int i, newsize = maxfiles + MAXMODULES; /* assume a safe call environment */ if (filesLoaded == NULL) { mal_set_lock(mal_contextLock, "loadFiles"); if (filesLoaded == NULL) { maxfiles = MAXMODULES; filesLoaded = (FileRecord *) GDKzalloc(maxfiles * sizeof(FileRecord)); lastfile = 0; } mal_unset_lock(mal_contextLock, "loadFiles"); } else if (lastfile + 2 == maxfiles) { /* guarantee at least one free slot */ mal_set_lock(mal_contextLock, "loadFiles"); newFilesLoaded = (FileRecord *)GDKzalloc(newsize * sizeof(FileRecord)); memcpy((char *) newFilesLoaded, (char *) filesLoaded, maxfiles * sizeof(FileRecord)); GDKfree(filesLoaded); filesLoaded = newFilesLoaded; for (i = maxfiles; i < newsize; i++) { filesLoaded[i].filename = NULL; filesLoaded[i].fullname = NULL; filesLoaded[i].handle = NULL; } maxfiles = newsize; mal_unset_lock(mal_contextLock, "loadFiles"); }}intisLoaded(str modulename){ int idx; for (idx = 0; filesLoaded[idx].filename && idx < lastfile; idx++) if (strcmp(filesLoaded[idx].filename, modulename) == 0) { return 1; } return 0;}#ifndef MAXPATHLEN#define MAXPATHLEN 1024#endifstrloadLibrary(str filename){ int mode = RTLD_NOW | RTLD_GLOBAL; char nme[MAXPATHLEN]; void *handle = NULL; str fullname, s; int idx; const char *errmsg; initM5Loader(); for (idx = 0; filesLoaded[idx].filename && idx < lastfile; idx++) if (strcmp(filesLoaded[idx].filename, filename) == 0) {#ifdef DEBUG_MAL_LINKER stream_printf(GDKout, "already loaded:%s:%x\n", filename, (int)filesLoaded[idx].handle); return (str) throwException("loaderException", "Module loaded twice", filename);#endif return MAL_SUCCEED; }#line 271 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_linker.mx" s = strrchr(filename, DIR_SEP); snprintf(nme, MAXPATHLEN, "_%s", s ? s + 1 : filename); fullname = MSP_locate_file(nme); if (fullname == NULL) {#ifdef DEBUG_MAL_LINKER2 stream_printf(GDKout, "file not found %s\n", filename);#endif return MAL_SUCCEED; }/* AIX requires RTLD_MEMBER to load a module that is a member of an archive. */#ifdef RTLD_MEMBER mode |= RTLD_MEMBER;#endif handle = dlopen(fullname, mode); if (handle == NULL) { errmsg = dlerror(); if (!errmsg) errmsg = "(no error from dlerror())";#ifdef DEBUG_MAL_LINKER2 { char errbuf[1024]; snprintf(errbuf, 1024, "%s: loader error %s", filename, errmsg); stream_printf(GDKout, "load[%d]:%s %s:%s\n", lastfile, filename, fullname, errbuf); }#endif GDKfree(fullname); throw(LOADER, "loadLibrary", "%s: loader error %s", filename, errmsg); }#ifdef DEBUG_MAL_LINKER2 stream_printf(GDKout, "load[%d]:%s %s:succeeded\n", lastfile, filename, fullname);#endif mal_set_lock(mal_contextLock, "loadModule"); if (lastfile == maxfiles) { showException(MAL,"loadModule", "internal error, too many modules loaded"); } else { filesLoaded[lastfile].filename = GDKstrdup(filename); filesLoaded[lastfile].fullname = fullname; filesLoaded[lastfile].handle = handle; lastfile ++; } mal_unset_lock(mal_contextLock, "loadModule"); return MAL_SUCCEED;}#line 325 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_linker.mx"voidunloadLibraries(){ int i; mal_set_lock(mal_contextLock, "unloadModule"); for (i = 0; i < lastfile; i++) if (filesLoaded[i].fullname) { /* dlclose(filesLoaded[i].handle);*/ GDKfree(filesLoaded[i].filename); GDKfree(filesLoaded[i].fullname); } lastfile = 0; GDKfree(filesLoaded); filesLoaded=0; mal_unset_lock(mal_contextLock, "unloadModule");}#line 343 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_linker.mx"#line 357 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_linker.mx"static str preloaded[] = { "kernel/bat", 0};intisPreloaded(str nme){ int i;#ifdef DEBUG_MAL_LINKER stream_printf(GDKout, "load:%s:preloaded?\n", nme);#endif for (i = 0; preloaded[i]; i++) if (strcmp(preloaded[i], nme) == 0) return 1; return 0;}voidinitLibraries(){ int i; noDlopen = TRUE; if(noDlopen == FALSE) for(i=0;preloaded[i];i++) {#ifdef DEBUG_MAL_LINKER stream_printf(GDKout,"loading %s\n",preloaded[i]);#endif loadLibrary(preloaded[i]); }}#line 394 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_linker.mx"static char *locate_file(const char *basename, const char *ext){ char *mod_path = GDKgetenv("monet_mod_path"); char *fullname; size_t fullnamelen; size_t filelen = strlen(basename) + strlen(ext); if (mod_path == NULL) return NULL; while (*mod_path == PATH_SEP) mod_path++; if (*mod_path == 0) return NULL; fullnamelen = 512; fullname = GDKmalloc(fullnamelen); while (*mod_path) { size_t i; char *p; int fd; if ((p = strchr(mod_path, PATH_SEP)) != NULL) { i = p - mod_path; } else { i = strlen(mod_path); } while (i + filelen + 2 > fullnamelen) { fullnamelen += 512; fullname = GDKrealloc(fullname, fullnamelen); } /* we are now sure the directory name, file base name, extension, and separator fit into fullname, so we don't need to do any extra checks */ strncpy(fullname, mod_path, i); fullname[i] = DIR_SEP; strcpy(fullname + i + 1, basename); strcat(fullname + i + 1, ext); if ((fd = open(fullname, O_RDONLY)) >= 0) { close(fd); return GDKrealloc(fullname, strlen(fullname) + 1); } if ((mod_path = p) == NULL) break; while (*mod_path == PATH_SEP) mod_path++; } /* not found */ GDKfree(fullname); return NULL;}#define MAL_EXT ".mal"char *MSP_locate_script(const char *filename){ return locate_file(filename, MAL_EXT);}char *MSP_locate_file(const char *filename){ char *lib_name = GDKmalloc(strlen(filename) + strlen(SO_PREFIX) + 1); char *fullname; strcpy(lib_name, SO_PREFIX); strcpy(lib_name + strlen(SO_PREFIX), filename); fullname = locate_file(lib_name, SO_EXT);#ifdef _AIX fullname = GDKrealloc(fullname, strlen(fullname) + strlen(lib_name) + 5); strcat(fullname, "("); strcat(fullname, lib_name); strcat(fullname, ".0)");#endif GDKfree(lib_name); return fullname;}#line 474 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB5/src/mal/mal_linker.mx"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -