Commit 49fb0d6d authored by Robert Schmidt's avatar Robert Schmidt

Fix shlib loaded: free memory, handle lib reload

- introduce loader_reset() that frees all memory
- resolve memory leak in loader_format_shlibpath()
- correctly handle library reload: check if a function has been
  retrieved already. Don't leak memory (strdup()), and handle multiple
  reloads of different functions from the same SO
parent ff9c1764
...@@ -69,7 +69,6 @@ char *loader_format_shlibpath(char *modname, char *version) ...@@ -69,7 +69,6 @@ char *loader_format_shlibpath(char *modname, char *version)
char *tmpstr; char *tmpstr;
char *shlibpath =NULL; char *shlibpath =NULL;
char *shlibversion=NULL; char *shlibversion=NULL;
char *cfgprefix;
paramdef_t LoaderParams[] ={{"shlibpath", NULL, 0, strptr:&shlibpath, defstrval:NULL, TYPE_STRING, 0, NULL}, paramdef_t LoaderParams[] ={{"shlibpath", NULL, 0, strptr:&shlibpath, defstrval:NULL, TYPE_STRING, 0, NULL},
{"shlibversion", NULL, 0, strptr:&shlibversion, defstrval:"", TYPE_STRING, 0, NULL}}; {"shlibversion", NULL, 0, strptr:&shlibversion, defstrval:"", TYPE_STRING, 0, NULL}};
...@@ -81,16 +80,11 @@ int ret; ...@@ -81,16 +80,11 @@ int ret;
/* looks for specific path for this module in the config file */ /* looks for specific path for this module in the config file */
/* specific value for a module path and version is located in a modname subsection of the loader section */ /* specific value for a module path and version is located in a modname subsection of the loader section */
/* shared lib name is formatted as lib<module name><module version>.so */ /* shared lib name is formatted as lib<module name><module version>.so */
cfgprefix = malloc(sizeof(LOADER_CONFIG_PREFIX)+strlen(modname)+16); char cfgprefix[sizeof(LOADER_CONFIG_PREFIX)+strlen(modname)+16];
if (cfgprefix == NULL) { sprintf(cfgprefix,LOADER_CONFIG_PREFIX ".%s",modname);
fprintf(stderr,"[LOADER] %s %d malloc error loading module %s, %s\n",__FILE__, __LINE__, modname, strerror(errno)); ret = config_get( LoaderParams,sizeof(LoaderParams)/sizeof(paramdef_t),cfgprefix);
exit_fun("[LOADER] unrecoverable error"); if (ret <0) {
} else { fprintf(stderr,"[LOADER] %s %d couldn't retrieve config from section %s\n",__FILE__, __LINE__,cfgprefix);
sprintf(cfgprefix,LOADER_CONFIG_PREFIX ".%s",modname);
int ret = config_get( LoaderParams,sizeof(LoaderParams)/sizeof(paramdef_t),cfgprefix);
if (ret <0) {
fprintf(stderr,"[LOADER] %s %d couldn't retrieve config from section %s\n",__FILE__, __LINE__,cfgprefix);
}
} }
/* no specific path, use loader default shared lib path */ /* no specific path, use loader default shared lib path */
if (shlibpath == NULL) { if (shlibpath == NULL) {
...@@ -142,6 +136,7 @@ int load_module_version_shlib(char *modname, char *version, loader_shlibfunc_t * ...@@ -142,6 +136,7 @@ int load_module_version_shlib(char *modname, char *version, loader_shlibfunc_t *
} }
shlib_path = loader_format_shlibpath(modname, version); shlib_path = loader_format_shlibpath(modname, version);
printf("shlib_path %s\n", shlib_path);
for (int i = 0; i < loader_data.numshlibs; i++) { for (int i = 0; i < loader_data.numshlibs; i++) {
if (strcmp(loader_data.shlibs[i].name, modname) == 0) { if (strcmp(loader_data.shlibs[i].name, modname) == 0) {
...@@ -198,15 +193,17 @@ int load_module_version_shlib(char *modname, char *version, loader_shlibfunc_t * ...@@ -198,15 +193,17 @@ int load_module_version_shlib(char *modname, char *version, loader_shlibfunc_t *
} }
if (farray) { if (farray) {
if (!loader_data.shlibs[lib_idx].funcarray) { loader_shlibdesc_t *shlib = &loader_data.shlibs[lib_idx];
loader_data.shlibs[lib_idx].funcarray = malloc(numf*sizeof(loader_shlibfunc_t)); if (!shlib->funcarray) {
if (!loader_data.shlibs[lib_idx].funcarray) { shlib->funcarray = calloc(numf, sizeof(loader_shlibfunc_t));
if (!shlib->funcarray) {
fprintf(stderr, "[LOADER] load_module_shlib(): unable to allocate memory\n"); fprintf(stderr, "[LOADER] load_module_shlib(): unable to allocate memory\n");
ret = -1; ret = -1;
goto load_module_shlib_exit; goto load_module_shlib_exit;
} }
shlib->len_funcarray = numf;
shlib->numfunc = 0;
} }
loader_data.shlibs[lib_idx].numfunc = 0;
for (int i = 0; i < numf; i++) { 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) { if (!farray[i].fptr) {
...@@ -215,9 +212,32 @@ int load_module_version_shlib(char *modname, char *version, loader_shlibfunc_t * ...@@ -215,9 +212,32 @@ int load_module_version_shlib(char *modname, char *version, loader_shlibfunc_t *
ret = -1; ret = -1;
goto load_module_shlib_exit; goto load_module_shlib_exit;
} }
loader_data.shlibs[lib_idx].funcarray[i].fname=strdup(farray[i].fname); /* check whether this function has been loaded before */
loader_data.shlibs[lib_idx].funcarray[i].fptr = farray[i].fptr; int j = 0;
loader_data.shlibs[lib_idx].numfunc++; for (; j < shlib->numfunc; ++j) {
if (shlib->funcarray[j].fptr == farray[i].fptr) {
int rc = strcmp(shlib->funcarray[i].fname, farray[i].fname);
AssertFatal(rc == 0,
"reloading the same fptr with different fnames (%s, %s)\n",
shlib->funcarray[i].fname, farray[i].fname);
break;
}
}
if (j == shlib->numfunc) {
if (shlib->numfunc == shlib->len_funcarray) {
loader_shlibfunc_t *n = reallocarray(shlib->funcarray, shlib->numfunc * 2, sizeof(loader_shlibfunc_t));
if (!n) {
fprintf(stderr, "[LOADER] %s(): unable to allocate memory\n", __func__);
ret = -1;
goto load_module_shlib_exit;
}
shlib->funcarray = n;
shlib->len_funcarray = shlib->numfunc * 2;
}
shlib->funcarray[j].fname = strdup(farray[i].fname);
shlib->funcarray[j].fptr = farray[i].fptr;
shlib->numfunc++;
}
} /* for int i... */ } /* for int i... */
} else { /* farray ! NULL */ } else { /* farray ! NULL */
sprintf(afname,"%s_getfarray",modname); sprintf(afname,"%s_getfarray",modname);
...@@ -248,3 +268,18 @@ void * get_shlibmodule_fptr(char *modname, char *fname) ...@@ -248,3 +268,18 @@ void * get_shlibmodule_fptr(char *modname, char *fname)
} /* for i loop on modules */ } /* for i loop on modules */
return NULL; return NULL;
} }
void loader_reset()
{
for (int i = 0; i < loader_data.numshlibs && loader_data.shlibs[i].name != NULL; i++) {
loader_shlibdesc_t *shlib = &loader_data.shlibs[i];
free(shlib->name);
free(shlib->thisshlib_path);
for (int j = 0; j < shlib->numfunc; ++j)
free(shlib->funcarray[j].fname);
free(shlib->funcarray);
shlib->numfunc = 0;
shlib->len_funcarray = 0;
}
free(loader_data.shlibs);
}
...@@ -47,6 +47,7 @@ typedef struct { ...@@ -47,6 +47,7 @@ typedef struct {
char *thisshlib_path; char *thisshlib_path;
uint32_t numfunc; uint32_t numfunc;
loader_shlibfunc_t *funcarray; loader_shlibfunc_t *funcarray;
uint32_t len_funcarray;
}loader_shlibdesc_t; }loader_shlibdesc_t;
typedef struct { typedef struct {
...@@ -90,5 +91,6 @@ extern void * get_shlibmodule_fptr(char *modname, char *fname); ...@@ -90,5 +91,6 @@ extern void * get_shlibmodule_fptr(char *modname, char *fname);
extern loader_data_t loader_data; extern loader_data_t loader_data;
#endif /* LOAD_MODULE_SHLIB_MAIN */ #endif /* LOAD_MODULE_SHLIB_MAIN */
#define load_module_shlib(M, F, N, I) load_module_version_shlib(M, NULL, F, N, I) #define load_module_shlib(M, F, N, I) load_module_version_shlib(M, NULL, F, N, I)
void loader_reset();
#endif #endif
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include "common/config/config_userapi.h" #include "common/config/config_userapi.h"
#include "common/utils/LOG/log.h" #include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h" #include "common/utils/LOG/vcd_signal_dumper.h"
#include "common/utils/load_module_shlib.h"
#include "T.h" #include "T.h"
#include "PHY/defs_gNB.h" #include "PHY/defs_gNB.h"
#include "PHY/defs_nr_common.h" #include "PHY/defs_nr_common.h"
...@@ -671,6 +672,8 @@ int main(int argc, char **argv) ...@@ -671,6 +672,8 @@ int main(int argc, char **argv)
if (ouput_vcd) if (ouput_vcd)
vcd_signal_dumper_close(); vcd_signal_dumper_close();
loader_reset();
return (n_errors); return (n_errors);
} }
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