diff options
Diffstat (limited to 'src/base/main/libSupport.c')
| -rw-r--r-- | src/base/main/libSupport.c | 193 | 
1 files changed, 193 insertions, 0 deletions
| diff --git a/src/base/main/libSupport.c b/src/base/main/libSupport.c new file mode 100644 index 00000000..471ea09e --- /dev/null +++ b/src/base/main/libSupport.c @@ -0,0 +1,193 @@ +/**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 <stdio.h> +#include <string.h> + +#ifndef WIN32 +# include <sys/types.h> +# include <dirent.h> +# include <dlfcn.h> +#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 = malloc (2*sizeof(char)); +      init_p[0]='.'; init_p[1] = 0; +    } else { +      init_p = malloc ((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 = malloc((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()); +            } +             +            free(szPrefixed); +          } +        } +      } +      closedir(dirp); +      p = endp+1; +    } + +    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                                /// +//////////////////////////////////////////////////////////////////////// | 
