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,74 +120,98 @@ int ret; ...@@ -120,74 +120,98 @@ 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) { AssertFatal(modname, "no library name given\n");
if (!loader_data.shlibpath) {
loader_init(); 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++) {
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);
}
lib_handle = dlopen(shlib_path, RTLD_LAZY|RTLD_NODELETE|RTLD_GLOBAL); lib_handle = dlopen(shlib_path, RTLD_LAZY|RTLD_NODELETE|RTLD_GLOBAL);
if (!lib_handle) { if (!lib_handle) {
fprintf(stderr,"[LOADER] library %s is not loaded: %s\n", shlib_path,dlerror()); fprintf(stderr,"[LOADER] library %s is not loaded: %s\n", shlib_path,dlerror());
ret = -1; ret = -1;
} else { goto load_module_shlib_exit;
}
printf("[LOADER] library %s successfully loaded\n", shlib_path); printf("[LOADER] library %s successfully loaded\n", shlib_path);
afname=malloc(strlen(modname)+15); 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); sprintf(afname,"%s_checkbuildver",modname);
fpc = dlsym(lib_handle,afname); fpc = dlsym(lib_handle,afname);
if (fpc != NULL ){ if (fpc) {
int chkver_ret = fpc(loader_data.mainexec_buildversion, &(loader_data.shlibs[loader_data.numshlibs].shlib_buildversion)); int chkver_ret = fpc(loader_data.mainexec_buildversion,
if (chkver_ret < 0) { &(loader_data.shlibs[lib_idx].shlib_buildversion));
fprintf(stderr,"[LOADER] %s %d lib %s, version mismatch",__FILE__, __LINE__, modname); AssertFatal(chkver_ret >= 0,
exit_fun("[LOADER] unrecoverable error"); "[LOADER] %s %d lib %s, version mismatch",
} __FILE__, __LINE__, modname);
} }
sprintf(afname,"%s_autoinit",modname); sprintf(afname,"%s_autoinit",modname);
fpi = dlsym(lib_handle,afname); fpi = dlsym(lib_handle,afname);
if (fpi != NULL ) { if (fpi) {
fpi(autoinit_arg); 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");
}
loader_data.shlibs[lib_idx].numfunc = 0;
for (int i = 0; i < numf; i++) {
farray[i].fptr = dlsym(lib_handle,farray[i].fname); farray[i].fptr = dlsym(lib_handle,farray[i].fname);
if (farray[i].fptr == NULL ) { AssertFatal(farray[i].fptr, "%s: function not found %s\n",
fprintf(stderr,"[LOADER] %s %d %s function not found %s\n",__FILE__, __LINE__, dlerror(),farray[i].fname); dlerror(), farray[i].fname);
ret= -1; loader_data.shlibs[lib_idx].funcarray[i].fname=strdup(farray[i].fname);
} else { /* farray[i].fptr == NULL */ loader_data.shlibs[lib_idx].funcarray[i].fptr = farray[i].fptr;
loader_data.shlibs[loader_data.numshlibs].funcarray[i].fname=strdup(farray[i].fname); loader_data.shlibs[lib_idx].numfunc++;
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... */ } /* 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 */ } /* 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); load_module_shlib_exit:
if ( afname!= NULL) free(afname); if (shlib_path) free(shlib_path);
if (lib_handle != NULL) dlclose(lib_handle); if (afname) free(afname);
if (lib_handle) dlclose(lib_handle);
return ret; return ret;
} }
......
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