| /**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 <stdio.h> |
| #include <string.h> |
| |
| #include "base/abc/abc.h" |
| #include "mainInt.h" |
| |
| ABC_NAMESPACE_IMPL_START |
| |
| #if defined(ABC_NO_DYNAMIC_LINKING) |
| #define WIN32 |
| #endif |
| |
| #ifndef WIN32 |
| # include <sys/types.h> |
| # include <dirent.h> |
| # include <dlfcn.h> |
| #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 |
| |