Commit d24e17f0 authored by Robert Schmidt's avatar Robert Schmidt

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
parent 175d28ee
...@@ -120,75 +120,99 @@ int ret; ...@@ -120,75 +120,99 @@ int ret;
int load_module_shlib(char *modname,loader_shlibfunc_t *farray, int numf, void *autoinit_arg) int load_module_shlib(char *modname,loader_shlibfunc_t *farray, int numf, void *autoinit_arg)
{ {
void *lib_handle; void *lib_handle = NULL;
initfunc_t fpi; initfunc_t fpi;
checkverfunc_t fpc; checkverfunc_t fpc;
getfarrayfunc_t fpg; getfarrayfunc_t fpg;
char *shlib_path; char *shlib_path = NULL;
char *afname=NULL; char *afname = NULL;
int ret=0; int ret = 0;
int lib_idx = -1;
if (loader_data.shlibpath == NULL) {
loader_init(); 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; for (int i = 0; i < loader_data.numshlibs; i++) {
lib_handle = dlopen(shlib_path, RTLD_LAZY|RTLD_NODELETE|RTLD_GLOBAL); if (strcmp(loader_data.shlibs[i].name, modname) == 0) {
if (!lib_handle) { printf("[LOADER] library %s has been loaded previously, reloading function pointers\n",
fprintf(stderr,"[LOADER] library %s is not loaded: %s\n", shlib_path,dlerror()); shlib_path);
ret = -1; lib_idx = i;
} else { break;
printf("[LOADER] library %s successfully loaded\n", shlib_path); }
afname=malloc(strlen(modname)+15); }
sprintf(afname,"%s_checkbuildver",modname); if (lib_idx < 0) {
fpc = dlsym(lib_handle,afname); lib_idx = loader_data.numshlibs;
if (fpc != NULL ){ ++loader_data.numshlibs;
int chkver_ret = fpc(loader_data.mainexec_buildversion, &(loader_data.shlibs[loader_data.numshlibs].shlib_buildversion)); AssertFatal(loader_data.numshlibs <= loader_data.maxshlibs,
if (chkver_ret < 0) { "shared lib loader: can not load more than %d shlibs\n",
fprintf(stderr,"[LOADER] %s %d lib %s, version mismatch",__FILE__, __LINE__, modname); loader_data.maxshlibs);
exit_fun("[LOADER] unrecoverable error"); loader_data.shlibs[lib_idx].name = strdup(modname);
} loader_data.shlibs[lib_idx].thisshlib_path = strdup(shlib_path);
} }
sprintf(afname,"%s_autoinit",modname);
fpi = dlsym(lib_handle,afname);
if (fpi != NULL ) { lib_handle = dlopen(shlib_path, RTLD_LAZY|RTLD_NODELETE|RTLD_GLOBAL);
fpi(autoinit_arg); 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) { if (farray) {
loader_data.shlibs[loader_data.numshlibs].funcarray=malloc(numf*sizeof(loader_shlibfunc_t)); if (!loader_data.shlibs[lib_idx].funcarray) {
loader_data.shlibs[loader_data.numshlibs].numfunc=0; loader_data.shlibs[lib_idx].funcarray = malloc(numf*sizeof(loader_shlibfunc_t));
for (int i=0; i<numf; i++) { AssertFatal(loader_data.shlibs[lib_idx].funcarray, "unable to allocate memory\n");
farray[i].fptr = dlsym(lib_handle,farray[i].fname); }
if (farray[i].fptr == NULL ) { loader_data.shlibs[lib_idx].numfunc = 0;
fprintf(stderr,"[LOADER] %s %d %s function not found %s\n",__FILE__, __LINE__, dlerror(),farray[i].fname); for (int i = 0; i < numf; i++) {
ret= -1; farray[i].fptr = dlsym(lib_handle,farray[i].fname);
} else { /* farray[i].fptr == NULL */ AssertFatal(farray[i].fptr, "%s: function not found %s\n",
loader_data.shlibs[loader_data.numshlibs].funcarray[i].fname=strdup(farray[i].fname); dlerror(), farray[i].fname);
loader_data.shlibs[loader_data.numshlibs].funcarray[i].fptr = farray[i].fptr; loader_data.shlibs[lib_idx].funcarray[i].fname=strdup(farray[i].fname);
loader_data.shlibs[loader_data.numshlibs].numfunc++; loader_data.shlibs[lib_idx].funcarray[i].fptr = farray[i].fptr;
}/* farray[i].fptr != NULL */ loader_data.shlibs[lib_idx].numfunc++;
} /* for int i... */ } /* for int i... */
} else { /* farray ! NULL */ } else { /* farray ! NULL */
sprintf(afname,"%s_getfarray",modname); sprintf(afname,"%s_getfarray",modname);
fpg = dlsym(lib_handle,afname); fpg = dlsym(lib_handle,afname);
if (fpg != NULL ) { if (fpg) {
loader_data.shlibs[loader_data.numshlibs].numfunc = fpg(&(loader_data.shlibs[loader_data.numshlibs].funcarray)); loader_data.shlibs[lib_idx].numfunc =
} fpg(&(loader_data.shlibs[lib_idx].funcarray));
} /* farray ! NULL */ }
loader_data.shlibs[loader_data.numshlibs].name=strdup(modname); } /* farray ! NULL */
loader_data.shlibs[loader_data.numshlibs].thisshlib_path=strdup(shlib_path);
load_module_shlib_exit:
(loader_data.numshlibs)++; if (shlib_path) free(shlib_path);
} /* lib_handle != NULL */ if (afname) free(afname);
if (lib_handle) dlclose(lib_handle);
if ( shlib_path!= NULL) free(shlib_path); return ret;
if ( afname!= NULL) free(afname);
if (lib_handle != NULL) dlclose(lib_handle);
return ret;
} }
void * get_shlibmodule_fptr(char *modname, char *fname) void * get_shlibmodule_fptr(char *modname, char *fname)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment