From d24e17f0f7749b06a89eb50adacadadf1cf4bc67 Mon Sep 17 00:00:00 2001 From: Robert Schmidt <robert.schmidt@eurecom.fr> Date: Thu, 3 May 2018 10:33:10 +0200 Subject: [PATCH] improve load_module_shlib() * check whether a library has been loaded before; in this case, don't allocate new memory but load from old library again * vital parameters, previous exit_fun are checked by AssertFatal() * structure has changed a bit to make it easier to follow (instead of nested ifs includes one goto to the end of the function) * formatting has been improved --- common/utils/load_module_shlib.c | 154 ++++++++++++++++++------------- 1 file changed, 89 insertions(+), 65 deletions(-) diff --git a/common/utils/load_module_shlib.c b/common/utils/load_module_shlib.c index c0afdb0b64..b9ce5954dd 100644 --- a/common/utils/load_module_shlib.c +++ b/common/utils/load_module_shlib.c @@ -120,75 +120,99 @@ int ret; int load_module_shlib(char *modname,loader_shlibfunc_t *farray, int numf, void *autoinit_arg) { - void *lib_handle; - initfunc_t fpi; - checkverfunc_t fpc; - getfarrayfunc_t fpg; - char *shlib_path; - char *afname=NULL; - int ret=0; - - if (loader_data.shlibpath == NULL) { - loader_init(); - } + void *lib_handle = NULL; + initfunc_t fpi; + checkverfunc_t fpc; + getfarrayfunc_t fpg; + char *shlib_path = NULL; + char *afname = NULL; + int ret = 0; + int lib_idx = -1; + + AssertFatal(modname, "no library name given\n"); + + if (!loader_data.shlibpath) { + loader_init(); + } - shlib_path = loader_format_shlibpath(modname); + shlib_path = loader_format_shlibpath(modname); - ret = 0; - lib_handle = dlopen(shlib_path, RTLD_LAZY|RTLD_NODELETE|RTLD_GLOBAL); - if (!lib_handle) { - fprintf(stderr,"[LOADER] library %s is not loaded: %s\n", shlib_path,dlerror()); - ret = -1; - } else { - printf("[LOADER] library %s successfully loaded\n", shlib_path); - afname=malloc(strlen(modname)+15); - sprintf(afname,"%s_checkbuildver",modname); - fpc = dlsym(lib_handle,afname); - if (fpc != NULL ){ - int chkver_ret = fpc(loader_data.mainexec_buildversion, &(loader_data.shlibs[loader_data.numshlibs].shlib_buildversion)); - if (chkver_ret < 0) { - fprintf(stderr,"[LOADER] %s %d lib %s, version mismatch",__FILE__, __LINE__, modname); - exit_fun("[LOADER] unrecoverable error"); - } - } - sprintf(afname,"%s_autoinit",modname); - fpi = dlsym(lib_handle,afname); + for (int i = 0; i < loader_data.numshlibs; i++) { + if (strcmp(loader_data.shlibs[i].name, modname) == 0) { + printf("[LOADER] library %s has been loaded previously, reloading function pointers\n", + shlib_path); + lib_idx = i; + break; + } + } + if (lib_idx < 0) { + lib_idx = loader_data.numshlibs; + ++loader_data.numshlibs; + AssertFatal(loader_data.numshlibs <= loader_data.maxshlibs, + "shared lib loader: can not load more than %d shlibs\n", + loader_data.maxshlibs); + loader_data.shlibs[lib_idx].name = strdup(modname); + loader_data.shlibs[lib_idx].thisshlib_path = strdup(shlib_path); + } - if (fpi != NULL ) { - fpi(autoinit_arg); - } + lib_handle = dlopen(shlib_path, RTLD_LAZY|RTLD_NODELETE|RTLD_GLOBAL); + if (!lib_handle) { + fprintf(stderr,"[LOADER] library %s is not loaded: %s\n", shlib_path,dlerror()); + ret = -1; + goto load_module_shlib_exit; + } + + printf("[LOADER] library %s successfully loaded\n", shlib_path); + afname = malloc(strlen(modname)+15); + if (!afname) { + fprintf(stderr, "[LOADER] unable to allocate memory for library %s\n", shlib_path); + ret = -1; + goto load_module_shlib_exit; + } + sprintf(afname,"%s_checkbuildver",modname); + fpc = dlsym(lib_handle,afname); + if (fpc) { + int chkver_ret = fpc(loader_data.mainexec_buildversion, + &(loader_data.shlibs[lib_idx].shlib_buildversion)); + AssertFatal(chkver_ret >= 0, + "[LOADER] %s %d lib %s, version mismatch", + __FILE__, __LINE__, modname); + } + sprintf(afname,"%s_autoinit",modname); + fpi = dlsym(lib_handle,afname); + + if (fpi) { + fpi(autoinit_arg); + } - if (farray != NULL) { - loader_data.shlibs[loader_data.numshlibs].funcarray=malloc(numf*sizeof(loader_shlibfunc_t)); - loader_data.shlibs[loader_data.numshlibs].numfunc=0; - for (int i=0; i<numf; i++) { - farray[i].fptr = dlsym(lib_handle,farray[i].fname); - if (farray[i].fptr == NULL ) { - fprintf(stderr,"[LOADER] %s %d %s function not found %s\n",__FILE__, __LINE__, dlerror(),farray[i].fname); - ret= -1; - } else { /* farray[i].fptr == NULL */ - loader_data.shlibs[loader_data.numshlibs].funcarray[i].fname=strdup(farray[i].fname); - loader_data.shlibs[loader_data.numshlibs].funcarray[i].fptr = farray[i].fptr; - loader_data.shlibs[loader_data.numshlibs].numfunc++; - }/* farray[i].fptr != NULL */ - } /* for int i... */ - } else { /* farray ! NULL */ - sprintf(afname,"%s_getfarray",modname); - fpg = dlsym(lib_handle,afname); - if (fpg != NULL ) { - loader_data.shlibs[loader_data.numshlibs].numfunc = fpg(&(loader_data.shlibs[loader_data.numshlibs].funcarray)); - } - } /* farray ! NULL */ - loader_data.shlibs[loader_data.numshlibs].name=strdup(modname); - loader_data.shlibs[loader_data.numshlibs].thisshlib_path=strdup(shlib_path); - - (loader_data.numshlibs)++; - } /* lib_handle != NULL */ - - if ( shlib_path!= NULL) free(shlib_path); - if ( afname!= NULL) free(afname); - if (lib_handle != NULL) dlclose(lib_handle); - return ret; + if (farray) { + if (!loader_data.shlibs[lib_idx].funcarray) { + loader_data.shlibs[lib_idx].funcarray = malloc(numf*sizeof(loader_shlibfunc_t)); + AssertFatal(loader_data.shlibs[lib_idx].funcarray, "unable to allocate memory\n"); + } + loader_data.shlibs[lib_idx].numfunc = 0; + for (int i = 0; i < numf; i++) { + farray[i].fptr = dlsym(lib_handle,farray[i].fname); + AssertFatal(farray[i].fptr, "%s: function not found %s\n", + dlerror(), farray[i].fname); + loader_data.shlibs[lib_idx].funcarray[i].fname=strdup(farray[i].fname); + loader_data.shlibs[lib_idx].funcarray[i].fptr = farray[i].fptr; + loader_data.shlibs[lib_idx].numfunc++; + } /* for int i... */ + } else { /* farray ! NULL */ + sprintf(afname,"%s_getfarray",modname); + fpg = dlsym(lib_handle,afname); + if (fpg) { + loader_data.shlibs[lib_idx].numfunc = + fpg(&(loader_data.shlibs[lib_idx].funcarray)); + } + } /* farray ! NULL */ + +load_module_shlib_exit: + if (shlib_path) free(shlib_path); + if (afname) free(afname); + if (lib_handle) dlclose(lib_handle); + return ret; } void * get_shlibmodule_fptr(char *modname, char *fname) -- GitLab