/**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 "mainInt.h" #include #include #ifndef WIN32 # include # include # include #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; dirp = opendir("."); 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 = malloc((strlen(dp->d_name) + 3) * sizeof(char)); strcpy(szPrefixed, "./"); 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()); } free(szPrefixed); } } } closedir(dirp); #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 /// ////////////////////////////////////////////////////////////////////////