/**CFile**************************************************************** FileName [libSupport.c] SystemName [ABC: Logic synthesis and verification system.] PackageName [The main package.] Synopsis [Support for external libaries.] Author [Mike Case] Affiliation [UC Berkeley] Date [Ver. 1.0. Started - June 20, 2005.] Revision [$Id: libSupport.c,v 1.1 2005/09/06 19:59:51 casem Exp $] ***********************************************************************/ #include #include #include "base/abc/abc.h" #include "mainInt.h" ABC_NAMESPACE_IMPL_START #if defined(ABC_NO_DYNAMIC_LINKING) #define WIN32 #endif #ifndef WIN32 # include # include # include #endif // fix by Paddy O'Brien on Sep 22, 2009 #ifdef __CYGWIN__ #ifndef RTLD_LOCAL #define RTLD_LOCAL 0 #endif #endif #define MAX_LIBS 256 static void* libHandles[MAX_LIBS+1]; // will be null terminated typedef void (*lib_init_end_func) (Abc_Frame_t * pAbc); //////////////////////////////////////////////////////////////////////////////////////////////////// // This will find all the ABC library extensions in the current directory and load them all. //////////////////////////////////////////////////////////////////////////////////////////////////// void open_libs() { int curr_lib = 0; #ifdef WIN32 // printf("Warning: open_libs WIN32 not implemented.\n"); #else DIR* dirp; struct dirent* dp; char *env, *init_p, *p; int done; env = getenv ("ABC_LIB_PATH"); if (env == NULL) { // printf("Warning: ABC_LIB_PATH not defined. Looking into the current directory.\n"); init_p = ABC_ALLOC( char, (2*sizeof(char)) ); init_p[0]='.'; init_p[1] = 0; } else { init_p = ABC_ALLOC( char, ((strlen(env)+1)*sizeof(char)) ); strcpy (init_p, env); } // Extract directories and read libraries done = 0; p = init_p; while (!done) { char *endp = strchr (p,':'); if (endp == NULL) done = 1; // last directory in the list else *endp = 0; // end of string dirp = opendir(p); if (dirp == NULL) { // printf("Warning: directory in ABC_LIB_PATH does not exist (%s).\n", p); continue; } while ((dp = readdir(dirp)) != NULL) { if ((strncmp("libabc_", dp->d_name, 7) == 0) && (strcmp(".so", dp->d_name + strlen(dp->d_name) - 3) == 0)) { // make sure we don't overflow the handle array if (curr_lib >= MAX_LIBS) { printf("Warning: maximum number of ABC libraries (%d) exceeded. Not loading %s.\n", MAX_LIBS, dp->d_name); } // attempt to load it else { char* szPrefixed = ABC_ALLOC( char, ((strlen(dp->d_name) + strlen(p) + 2) * sizeof(char)) ); sprintf(szPrefixed, "%s/", p); strcat(szPrefixed, dp->d_name); libHandles[curr_lib] = dlopen(szPrefixed, RTLD_NOW | RTLD_LOCAL); // did the load succeed? if (libHandles[curr_lib] != 0) { printf("Loaded ABC library: %s (Abc library extension #%d)\n", szPrefixed, curr_lib); curr_lib++; } else { printf("Warning: failed to load ABC library %s:\n\t%s\n", szPrefixed, dlerror()); } ABC_FREE(szPrefixed); } } } closedir(dirp); p = endp+1; } ABC_FREE(init_p); #endif // null terminate the list of handles libHandles[curr_lib] = 0; } //////////////////////////////////////////////////////////////////////////////////////////////////// // This will close all open ABC library extensions //////////////////////////////////////////////////////////////////////////////////////////////////// void close_libs() { #ifdef WIN32 printf("Warning: close_libs WIN32 not implemented.\n"); #else int i; for (i = 0; libHandles[i] != 0; i++) { if (dlclose(libHandles[i]) != 0) { printf("Warning: failed to close library %d\n", i); } libHandles[i] = 0; } #endif } //////////////////////////////////////////////////////////////////////////////////////////////////// // This will get a pointer to a function inside of an open library //////////////////////////////////////////////////////////////////////////////////////////////////// void* get_fnct_ptr(int lib_num, char* sym_name) { #ifdef WIN32 printf("Warning: get_fnct_ptr WIN32 not implemented.\n"); return 0; #else return dlsym(libHandles[lib_num], sym_name); #endif } //////////////////////////////////////////////////////////////////////////////////////////////////// // This will call an initialization function in every open library. //////////////////////////////////////////////////////////////////////////////////////////////////// void call_inits(Abc_Frame_t* pAbc) { int i; lib_init_end_func init_func; for (i = 0; libHandles[i] != 0; i++) { init_func = (lib_init_end_func) get_fnct_ptr(i, "abc_init"); if (init_func == 0) { printf("Warning: Failed to initialize library %d.\n", i); } else { (*init_func)(pAbc); } } } //////////////////////////////////////////////////////////////////////////////////////////////////// // This will call a shutdown function in every open library. //////////////////////////////////////////////////////////////////////////////////////////////////// void call_ends(Abc_Frame_t* pAbc) { int i; lib_init_end_func end_func; for (i = 0; libHandles[i] != 0; i++) { end_func = (lib_init_end_func) get_fnct_ptr(i, "abc_end"); if (end_func == 0) { printf("Warning: Failed to end library %d.\n", i); } else { (*end_func)(pAbc); } } } void Libs_Init(Abc_Frame_t * pAbc) { open_libs(); call_inits(pAbc); } void Libs_End(Abc_Frame_t * pAbc) { call_ends(pAbc); // It's good practice to close our libraries at this point, but this can mess up any backtrace printed by Valgind. // close_libs(); } //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// ABC_NAMESPACE_IMPL_END