194 lines
6.2 KiB
C
194 lines
6.2 KiB
C
/**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);
|
|
|
|
// 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 ///
|
|
////////////////////////////////////////////////////////////////////////
|