]> git.saurik.com Git - wxWidgets.git/blobdiff - src/iodbc/dlf.c
No change
[wxWidgets.git] / src / iodbc / dlf.c
index 9c5ed6427214fe8270d64d9e55ca7e9142954dac..46cf2329076aebebadc56a9a44a3b00edf3b3d55 100644 (file)
-/** dynamic library loader (mapping to svr4)
-
-    Copyright (C) 1995 by Ke Jin <kejin@empress.com>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-**/
-
-#ifdef DLDAPI_OS2
-#  define INCL_DOSMODULEMGR                 /* Module Manager values */
-#  define INCL_DOSERRORS                    /* Error values          */
-#  include      <os2.h>
-#  include      <stdio.h>
-#endif
+/*
+ *  dlf.c
+ *
+ *  $Id$
+ *
+ *  Dynamic Library Loader (mapping to SVR4)
+ *
+ *  The iODBC driver manager.
+ *  
+ *  Copyright (C) 1995 by Ke Jin <kejin@empress.com> 
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public
+ *  License along with this library; if not, write to the Free
+ *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
 
 
-#include  "wx/setup.h"
-#include       <../iodbc/dlf.h>
+#include       "dlf.h"
 #include       <errno.h>
 
 #include       <errno.h>
 
-#ifdef  DLDAPI_DEFINED
-# undef DLDAPI_DEFINED
+#ifdef DLDAPI_DEFINED
+#undef DLDAPI_DEFINED
 #endif
 
 #endif
 
-#ifdef  DLDAPI_SVR4_DLFCN
-# define DLDAPI_DEFINED
-static  char sccsid[] = "@(#)dynamic load interface -- SVR4 dlfcn";
+#ifdef DLDAPI_SVR4_DLFCN
+#define DLDAPI_DEFINED
+static char sccsid[] = "@(#)dynamic load interface -- SVR4 dlfcn";
 #endif
 
 #endif
 
-/*********************************
+/********************************* 
  *
  *
- *      HP/UX
+ *     HP/UX 
  *
  *********************************/
  *
  *********************************/
-#ifdef  DLDAPI_HP_SHL
-# define        DLDAPI_DEFINED
-# include       <dl.h>
 
 
-static  char sccsid[] = "@(#)dynamic load interface -- HP/UX dl(shl)";
+#ifdef DLDAPI_HP_SHL
+#define        DLDAPI_DEFINED
+#include       <dl.h>
 
 
-void*   dlopen(char* path, int mode)
+static char sccsid[] = "@(#)dynamic load interface -- HP/UX dl(shl)";
+
+void *
+dlopen (char *path, int mode)
 {
 {
-        return (void*)shl_load((char*)(path), BIND_DEFERRED, 0L);
+  return (void *) shl_load ((char *) (path), BIND_DEFERRED, 0L);
 }
 
 }
 
-void*   dlsym(void* hdll, char* sym)
+
+void *
+dlsym (void *hdll, char *sym)
 {
 {
-        void*   symaddr = 0;
-        int     ret;
+  void *symaddr = 0;
+  int ret;
 
 
-        if( ! hdll )
-                hdll = (void*)PROG_HANDLE;
+  if (!hdll)
+    hdll = (void *) PROG_HANDLE;
 
 
-        /* Remember, a driver may export calls as function pointers
-         * (i.e. with type TYPE_DATA) rather than as functions
-         * (i.e. with type TYPE_PROCEDURE). Thus, to be safe, we
-         * uses TYPE_UNDEFINED to cover all of them.
-         */
-        ret = shl_findsym((shl_t*)&hdll, sym, TYPE_UNDEFINED, &symaddr);
+  /* Remember, a driver may export calls as function pointers 
+   * (i.e. with type TYPE_DATA) rather than as functions 
+   * (i.e. with type TYPE_PROCEDURE). Thus, to be safe, we 
+   * uses TYPE_UNDEFINED to cover all of them. 
+   */
+  ret = shl_findsym ((shl_t *) & hdll, sym, TYPE_UNDEFINED, &symaddr);
 
 
-        if( ret == -1 )
-                return 0;
+  if (ret == -1)
+    return 0;
 
 
-        return symaddr;
+  return symaddr;
 }
 
 }
 
-char*   dlerror()
+
+char *
+dlerror ()
 {
 {
-        extern char*    strerror();
+  extern char *strerror ();
 
 
-        return strerror(errno);
+  return strerror (errno);
 }
 
 }
 
-int     dlclose(void* hdll)
+
+int 
+dlclose (void *hdll)
 {
 {
-        return shl_unload((shl_t)hdll);
+  return shl_unload ((shl_t) hdll);
 }
 }
+#endif /* end of HP/UX Seection */
 
 
-#endif  /* end of HP/UX Seection */
 
 /*********************************
  *
 
 /*********************************
  *
- *      IBM AIX
+ *     IBM AIX
  *
  *********************************/
  *
  *********************************/
-#ifdef  DLDAPI_AIX_LOAD
-# define        DLDAPI_DEFINED
-# include       <sys/ldr.h>
-# include       <sys/stat.h>
-# include       <nlist.h>
+
+#ifdef DLDAPI_AIX_LOAD
+#define        DLDAPI_DEFINED
+#include       <sys/types.h>
+#include       <sys/ldr.h>
+#include       <sys/stat.h>
+#include       <nlist.h>
 
 /*
 
 /*
- *   Following id sting is a copyright mark. Removing(i.e. use the
+ *   Following id sting is a copyright mark. Removing(i.e. use the 
  *   source code in this .c file without include it or make it not
  *   source code in this .c file without include it or make it not
- *   appear in the final object file of AIX platform) or modifing
- *   it without permission from original author(kejin@empress.com)
+ *   appear in the final object file of AIX platform) or modifing 
+ *   it without permission from original author(kejin@empress.com) 
  *   are copyright violation.
  */
  *   are copyright violation.
  */
-static  char sccsid[]
-        = "@(#)dynamic load interface, Copyright(c) 1995 by Ke Jin";
+static char sccsid[]
+= "@(#)dynamic load interface, Copyright(c) 1995 by Ke Jin";
 
 
-# ifndef        HTAB_SIZE
-#  define       HTAB_SIZE       256
-# endif
+#ifndef        HTAB_SIZE
+#define        HTAB_SIZE       256
+#endif
 
 
-# define        FACTOR          0.618039887 /* i.e. (sqrt(5) - 1)/2 */
+#define        FACTOR          0.618039887     /* i.e. (sqrt(5) - 1)/2 */
 
 
-# ifndef        ENTRY_SYM
-#  define       ENTRY_SYM       ".__start" /* default entry point for aix */
-# endif
+#ifndef        ENTRY_SYM
+#define        ENTRY_SYM       ".__start"      /* default entry point for aix */
+#endif
 
 typedef struct slot_s
 
 typedef struct slot_s
-{
-        char*           sym;
-        long            fdesc[3]; /* 12 bytes function descriptor */
-        struct slot_s*  next;
-} slot_t;
+  {
+    char *sym;
+    long fdesc[3];             /* 12 bytes function descriptor */
+    struct slot_s *next;
+  }
+slot_t;
 
 /* Note: on AIX, a function pointer actually points to a
  * function descriptor, a 12 bytes data. The first 4 bytes
 
 /* Note: on AIX, a function pointer actually points to a
  * function descriptor, a 12 bytes data. The first 4 bytes
- * is the virtual address of the function. The next 4 bytes
+ * is the virtual address of the function. The next 4 bytes 
  * is the virtual address of TOC (Table of Contents) of the
  * is the virtual address of TOC (Table of Contents) of the
- * object module the function belong to. The last 4 bytes
- * are always 0 for C and Fortran functions. Every object
+ * object module the function belong to. The last 4 bytes 
+ * are always 0 for C and Fortran functions. Every object 
  * module has an entry point (which can be specified at link
  * time by -e ld option). iODBC driver manager requires ODBC
  * driver shared library always use the default entry point
  * (so you shouldn't use -e ld option when creating a driver
  * module has an entry point (which can be specified at link
  * time by -e ld option). iODBC driver manager requires ODBC
  * driver shared library always use the default entry point
  * (so you shouldn't use -e ld option when creating a driver
- * share library). load() returns the function descriptor of
+ * share library). load() returns the function descriptor of 
  * a module's entry point. From which we can calculate function
  * descriptors of other functions in the same module by using
  * a module's entry point. From which we can calculate function
  * descriptors of other functions in the same module by using
- * the fact that the load() doesn't change the relative
- * offset of functions to their module entry point(i.e the
- * offset in memory loaded by load() will be as same as in
- * the module library file).
+ * the fact that the load() doesn't change the relative 
+ * offset of functions to their module entry point(i.e the 
+ * offset in memory loaded by load() will be as same as in 
+ * the module library file). 
  */
 
  */
 
-typedef slot_t*         hent_t;
-typedef struct nlist    nlist_t;
-typedef struct stat     stat_t;
+typedef slot_t *hent_t;
+typedef struct nlist nlist_t;
+typedef struct stat stat_t;
 
 typedef struct obj
 
 typedef struct obj
-{
-        int     dev;    /* device id */
-        int     ino;    /* inode number */
-        char*   path;   /* file name */
-        int     (*pentry)();    /* entry point of this share library */
-        int     refn;   /* number of reference */
-        hent_t  htab[HTAB_SIZE];
-        struct obj*
-                next;
-} obj_t;
-
-static char*    errmsg = 0;
-
-static void init_htab(hent_t* ht)
+  {
+    int dev;                   /* device id */
+    int ino;                   /* inode number */
+    char *path;                        /* file name */
+    int (*pentry) ();          /* entry point of this share library */
+    int refn;                  /* number of reference */
+    hent_t htab[HTAB_SIZE];
+    struct obj * next;
+  }
+obj_t;
+
+static char *errmsg = 0;
+
+static void 
+init_htab (hent_t * ht)
 /* initate a hashing table */
 {
 /* initate a hashing table */
 {
-        int     i;
+  int i;
 
 
-        for(i=0; i<HTAB_SIZE; i++)
-                ht[i] = (slot_t*)0;
+  for (i = 0; i < HTAB_SIZE; i++)
+    ht[i] = (slot_t *) 0;
 
 
-        return;
+  return;
 }
 
 }
 
-static void clean_htab(hent_t* ht)
+
+static void 
+clean_htab (hent_t * ht)
 /* free all slots */
 {
 /* free all slots */
 {
-        int     i;
-        slot_t* ent;
-        slot_t* tent;
+  int i;
+  slot_t *ent;
+  slot_t *tent;
 
 
-        for(i = 0; i< HTAB_SIZE; i++)
-        {
-                for( ent = ht[i]; ent; )
-                {
-                        tent = ent->next;
+  for (i = 0; i < HTAB_SIZE; i++)
+    {
+      for (ent = ht[i]; ent;)
+       {
+         tent = ent->next;
 
 
-                        free(ent->sym);
-                        free(ent);
+         free (ent->sym);
+         free (ent);
 
 
-                        ent = tent;
-                }
+         ent = tent;
+       }
 
 
-                ht[i] = 0;
-        }
+      ht[i] = 0;
+    }
 
 
-        return;
+  return;
 }
 
 }
 
-static int      hash(char* sym )
+
+static int 
+hash (char *sym)
 {
 {
-        int     a, key;
-        double  f;
+  int a, key;
+  double f;
 
 
-        if( !sym || !*sym )
-                return 0;
+  if (!sym || !*sym)
+    return 0;
 
 
-        for(key=*sym;*sym;sym++)
-        {
-                key += *sym;
-                a = key;
+  for (key = *sym; *sym; sym++)
+    {
+      key += *sym;
+      a = key;
 
 
-                key = (int)( (a<<8) + (key>>8) );
-                key = (key>0)? key:-key;
-        }
+      key = (int) ((a << 8) + (key >> 8));
+      key = (key > 0) ? key : -key;
+    }
 
 
-        f = key*FACTOR;
-        a = (int)f;
+  f = key * FACTOR;
+  a = (int) f;
 
 
-        return (int)((HTAB_SIZE - 1)*( f - a ));
+  return (int) ((HTAB_SIZE - 1) * (f - a));
 }
 
 }
 
-static hent_t   search(hent_t* htab, char* sym)
+
+static hent_t 
+search (hent_t * htab, char *sym)
 /* search hashing table to find a matched slot */
 {
 /* search hashing table to find a matched slot */
 {
-        int     key;
-        slot_t* ent;
+  int key;
+  slot_t *ent;
 
 
-        key = hash(sym);
+  key = hash (sym);
 
 
-        for(ent = htab[key]; ent; ent = ent->next )
-        {
-                if(!strcmp(ent->sym, sym))
-                        return ent;
-        }
+  for (ent = htab[key]; ent; ent = ent->next)
+    {
+      if (!strcmp (ent->sym, sym))
+       return ent;
+    }
 
 
-        return 0;       /* no match */
+  return 0;                    /* no match */
 }
 
 }
 
-static void     insert(hent_t* htab, slot_t* ent)
+
+static void 
+insert (hent_t * htab, slot_t * ent)
 /* insert a new slot to hashing table */
 {
 /* insert a new slot to hashing table */
 {
-        int     key;
+  int key;
 
 
-        key = hash(ent->sym);
+  key = hash (ent->sym);
 
 
-        ent->next = htab[key];
-        htab[key] = ent;
+  ent->next = htab[key];
+  htab[key] = ent;
 
 
-        return;
+  return;
 }
 
 }
 
-static slot_t*  slot_alloc(char* sym)
+
+static slot_t *
+slot_alloc (char *sym)
 /* allocate a new slot with symbol */
 {
 /* allocate a new slot with symbol */
 {
-        slot_t* ent;
+  slot_t *ent;
 
 
-        ent = (slot_t*)malloc(sizeof(slot_t));
+  ent = (slot_t *) malloc (sizeof (slot_t));
 
 
-        ent->sym = (char*)malloc(strlen(sym)+1);
+  ent->sym = (char *) malloc (strlen (sym) + 1);
 
 
-        if( ! ent->sym )
-        {
-                free(ent);
-                return 0;
-        }
+  if (!ent->sym)
+    {
+      free (ent);
+      return 0;
+    }
 
 
-        strcpy( ent->sym, sym );
+  strcpy (ent->sym, sym);
 
 
-        return ent;
+  return ent;
 }
 
 }
 
-static obj_t* obj_list = 0;
-
-void*   dlopen(char* file, int mode )
-{
-        stat_t  st;
-        obj_t*  pobj;
-        char    buf[1024];
-
-        if( ! file || ! *file )
-        {
-                errno = EINVAL;
-                return 0;
-        }
-
-        errno = 0;
-        errmsg = 0;
-
-#if 0
-        if( file[0] != '/' && file[0] != '.' )
-        {
-                for(;;)
-                {
-                        sprintf(buf, "/lib/%s", file);
-
-                        if( stat( buf, &st ) )
-                        {
-                                file = buf;
-                                break;
-                        }
-
-                        sprintf(buf, "/usr/lib/%s", file);
-
-                        if( stat( buf, &st ) )
-                        {
-                                file = buf;
-                                break;
-                        }
-
-                        if( stat( file, &st ) )
-                                break;
-
-                        return 0;
-                }
-        }
-        else
-#endif
-        if( stat( file, &st ) )
-                return 0;
-
-        for( pobj = obj_list; pobj; pobj = pobj->next )
-        /* find a match object */
-        {
-                if( pobj->ino == st.st_ino
-                 && pobj->dev == st.st_dev )
-                {
-                        /* found a match. increase its
-                         * reference count and return
-                         * its address */
-                        pobj->refn ++;
-                        return pobj;
-                }
-        }
-
-        pobj = (obj_t*)malloc( sizeof(obj_t) );
-
-        if( ! pobj )
-                return 0;
-
-        pobj->path = (char*)malloc( strlen(file) + 1);
-
-        if( ! pobj->path )
-        {
-                free( pobj );
-                return 0;
-        }
-
-        strcpy( pobj->path, file );
-
-        pobj->dev = st.st_dev;
-        pobj->ino = st.st_ino;
-        pobj->refn = 1;
-
-        pobj->pentry = (int(*)())load(file, 0, 0);
 
 
-        if( ! pobj->pentry )
-        {
-                free( pobj->path );
-                free( pobj );
-                return 0;
-        }
+static obj_t *obj_list = 0;
 
 
-        init_htab(pobj->htab);
-
-        pobj->next = obj_list;
-        obj_list = pobj;
-
-        return pobj;
+void *
+dlopen (char *file, int mode)
+{
+  stat_t st;
+  obj_t *pobj;
+  char buf[1024];
+
+  if (!file || !*file)
+    {
+      errno = EINVAL;
+      return 0;
+    }
+
+  errno = 0;
+  errmsg = 0;
+
+  if (stat (file, &st))
+    return 0;
+
+  for (pobj = obj_list; pobj; pobj = pobj->next)
+    /* find a match object */
+    {
+      if (pobj->ino == st.st_ino
+         && pobj->dev == st.st_dev)
+       {
+         /* found a match. increase its
+          * reference count and return 
+          * its address */
+         pobj->refn++;
+         return pobj;
+       }
+    }
+
+  pobj = (obj_t *) malloc (sizeof (obj_t));
+
+  if (!pobj)
+    return 0;
+
+  pobj->path = (char *) malloc (strlen (file) + 1);
+
+  if (!pobj->path)
+    {
+      free (pobj);
+      return 0;
+    }
+
+  strcpy (pobj->path, file);
+
+  pobj->dev = st.st_dev;
+  pobj->ino = st.st_ino;
+  pobj->refn = 1;
+
+  pobj->pentry = (int (*)()) load (file, 0, 0);
+
+  if (!pobj->pentry)
+    {
+      free (pobj->path);
+      free (pobj);
+      return 0;
+    }
+
+  init_htab (pobj->htab);
+
+  pobj->next = obj_list;
+  obj_list = pobj;
+
+  return pobj;
 }
 
 }
 
-int     dlclose(void* hobj)
+
+int 
+dlclose (void *hobj)
 {
 {
-        obj_t*  pobj = (obj_t*)hobj;
-        obj_t*  tpobj;
-        int     match = 0;
-
-        if( ! hobj )
-        {
-                errno = EINVAL;
-                return -1;
-        }
-
-        errno = 0;
-        errmsg = 0;
-
-        if( pobj == obj_list )
-        {
-                pobj->refn --;
-
-                if( pobj->refn )
-                        return 0;
-
-                match = 1;
-                obj_list = pobj->next;
-        }
-
-        for( tpobj = obj_list; !match && tpobj; tpobj = tpobj->next )
-        {
-                if( tpobj->next == pobj )
-                {
-                        pobj->refn --;
-
-                        if( pobj->refn )
-                                return 0;
-
-                        match = 1;
-                        tpobj->next = pobj->next;
-                }
-        }
-
-        if(match)
-        {
-                unload((void*)(pobj->pentry));
-                clean_htab(pobj->htab);
-                free(pobj->path);
-                free(pobj);
-        }
-
-        return 0;
+  obj_t *pobj = (obj_t *) hobj;
+  obj_t *tpobj;
+  int match = 0;
+
+  if (!hobj)
+    {
+      errno = EINVAL;
+      return -1;
+    }
+
+  errno = 0;
+  errmsg = 0;
+
+  if (pobj == obj_list)
+    {
+      pobj->refn--;
+
+      if (pobj->refn)
+       return 0;
+
+      match = 1;
+      obj_list = pobj->next;
+    }
+
+  for (tpobj = obj_list; !match && tpobj; tpobj = tpobj->next)
+    {
+      if (tpobj->next == pobj)
+       {
+         pobj->refn--;
+
+         if (pobj->refn)
+           return 0;
+
+         match = 1;
+         tpobj->next = pobj->next;
+       }
+    }
+
+  if (match)
+    {
+      unload ((void *) (pobj->pentry));
+      clean_htab (pobj->htab);
+      free (pobj->path);
+      free (pobj);
+    }
+
+  return 0;
 }
 
 }
 
-char*   dlerror()
+
+char *
+dlerror ()
 {
 {
-        extern char*    sys_errlist[];
+  extern char *sys_errlist[];
 
 
-        if( ! errmsg || ! errmsg[0] )
-        {
-                if( errno >= 0 )
-                        return sys_errlist[errno];
+  if (!errmsg || !errmsg[0])
+    {
+      if (errno >= 0)
+       return sys_errlist[errno];
 
 
-                return "";
-        }
+      return "";
+    }
 
 
-        return errmsg;
+  return errmsg;
 }
 
 }
 
-void*   dlsym(void* hdl, char* sym)
+
+void *
+dlsym (void *hdl, char *sym)
 {
 {
-        nlist_t nl[3];
-        obj_t*  pobj = (obj_t*)hdl;
-        slot_t* ent;
-        int     (*fp)();
-        long    lbuf[3];
-
-        if( !hdl || !(pobj->htab) || !sym || ! *sym )
-        {
-                errno = EINVAL;
-                return 0;
-        }
-
-        errno = 0;
-        errmsg = 0;
-
-        ent = search( pobj->htab, sym );
-
-        if( ent )
-                return ent->fdesc;
-
-#define n_name  _n._n_name
-
-        nl[0].n_name = ENTRY_SYM;
-        nl[1].n_name = sym;
-        nl[2].n_name = 0;
-
-        /* There is a potential problem here. If application
-         * did not pass a full path name, and changed the
-         * working directory after the load(), then nlist()
-         * will be unable to open the original shared library
-         * file to resolve the symbols. there are 3 ways to working
-         * round this: 1. convert to full pathname in driver
-         * manager. 2. applications always pass driver's full
-         * path name. 3. if driver itself don't support
-         * SQLGetFunctions(), call it with SQL_ALL_FUNCTIONS
-         * as flag immidately after SQLConnect(), SQLDriverConnect()
-         * and SQLBrowseConnect() to force the driver manager
-         * resolving all will be used symbols.
-         */
-        if( nlist( pobj->path, nl) == -1 )
-                return 0;
-
-        if( ! nl[0].n_type && ! nl[0].n_value )
-        {
-                errmsg = "can't locate module entry symbol";
-                return 0;
-        }
-
-        /* Note: On AIX 3.x if the object library is not
-         * built with -g compiling option, .n_type field
-         * is always 0. While on 4.x it will be 32.
-         * On AIX 4.x, if the symbol is a entry point,
-         * n_value will be 0. However, one thing is for sure
-         * that if a symbol is not existance in the file,
-         * both .n_type and .n_value would be 0.
-         */
-
-        if( ! nl[1].n_type && ! nl[1].n_value )
-        {
-                errmsg = "symbol not existance in this module";
-                return 0;
-        }
-
-        ent = slot_alloc(sym);
-
-        if( ! ent )
-                return 0;
-
-        /* catch it with a slot in the hashing table */
-        insert(pobj->htab, ent);
-
-        memcpy(ent->fdesc, pobj->pentry, sizeof(ent->fdesc));
-
-        /* now ent->fdesc[0] is the virtual address of entry point
-         * and ent->fdesc[1] is the TOC of the module
-         */
-
-        /* let's calculate the virtual address of the symbol
-         * by adding a relative offset getting from the module
-         * file symbol table, i.e
-         *
-         *  functin virtual address = entry point virtual address +
-         *     + ( function offset in file - entry point offset in file )
-         */
-
-        (ent->fdesc)[0] = (ent->fdesc)[0] +
-                ( nl[1].n_value - nl[0].n_value );
-
-        /* return the function descriptor */
-        return ent->fdesc;
+  nlist_t nl[3];
+  obj_t *pobj = (obj_t *) hdl;
+  slot_t *ent;
+  int (*fp) ();
+  long lbuf[3];
+
+  if (!hdl || !(pobj->htab) || !sym || !*sym)
+    {
+      errno = EINVAL;
+      return 0;
+    }
+
+  errno = 0;
+  errmsg = 0;
+
+  ent = search (pobj->htab, sym);
+
+  if (ent)
+    return ent->fdesc;
+
+#define        n_name  _n._n_name
+
+  nl[0].n_name = ENTRY_SYM;
+  nl[1].n_name = sym;
+  nl[2].n_name = 0;
+
+  /* There is a potential problem here. If application
+   * did not pass a full path name, and changed the
+   * working directory after the load(), then nlist()
+   * will be unable to open the original shared library
+   * file to resolve the symbols. there are 3 ways to working 
+   * round this: 1. convert to full pathname in driver
+   * manager. 2. applications always pass driver's full 
+   * path name. 3. if driver itself don't support 
+   * SQLGetFunctions(), call it with SQL_ALL_FUNCTIONS
+   * as flag immidately after SQLConnect(), SQLDriverConnect()
+   * and SQLBrowseConnect() to force the driver manager
+   * resolving all will be used symbols. 
+   */
+  if (nlist (pobj->path, nl) == -1)
+    return 0;
+
+  if (!nl[0].n_type && !nl[0].n_value)
+    {
+      errmsg = "can't locate module entry symbol";
+      return 0;
+    }
+
+  /* Note: On AIX 3.x if the object library is not
+   * built with -g compiling option, .n_type field
+   * is always 0. While on 4.x it will be 32. 
+   * On AIX 4.x, if the symbol is a entry point,
+   * n_value will be 0. However, one thing is for sure 
+   * that if a symbol is not existance in the file,
+   * both .n_type and .n_value would be 0.
+   */
+
+  if (!nl[1].n_type && !nl[1].n_value)
+    {
+      errmsg = "symbol not existance in this module";
+      return 0;
+    }
+
+  ent = slot_alloc (sym);
+
+  if (!ent)
+    return 0;
+
+  /* catch it with a slot in the hashing table */
+  insert (pobj->htab, ent);
+
+  memcpy (ent->fdesc, pobj->pentry, sizeof (ent->fdesc));
+
+  /* now ent->fdesc[0] is the virtual address of entry point
+   * and ent->fdesc[1] is the TOC of the module
+   */
+
+  /* let's calculate the virtual address of the symbol 
+   * by adding a relative offset getting from the module 
+   * file symbol table, i.e
+   *
+   *  functin virtual address = entry point virtual address +
+   *     + ( function offset in file - entry point offset in file )
+   */
+
+  (ent->fdesc)[0] = (ent->fdesc)[0] +
+      (nl[1].n_value - nl[0].n_value);
+
+  /* return the function descriptor */
+  return ent->fdesc;
 }
 }
-
-#endif  /* end of IBM AIX Section */
+#endif /* end of IBM AIX Section */
 
 
 
 
-/*********************************
+/********************************* 
  *
  *
- *      Windows 3.x, 95, NT
+ *     Windows 3.x, 95, NT
  *
  *********************************/
  *
  *********************************/
-#ifdef  DLDAPI_WINDOWS
-# define        DLDAPI_DEFINED
-# include       <windows.h>
 
 
-void FAR*       dlopen(char FAR* dll, int mode)
-{
-        HINSTANCE       hint;
+#ifdef DLDAPI_WINDOWS
+#define        DLDAPI_DEFINED
+#include       <windows.h>
 
 
-        if( dll == NULL )
-        {
-                return GetWindowWord( NULL, GWW_HINSTANCE );
-        }
+void FAR *
+dlopen (char FAR * dll, int mode)
+{
+  HINSTANCE hint;
 
 
-        hint = LoadLibrary(dll);
+  if (dll == NULL)
+    {
+      return GetWindowWord (NULL, GWW_HINSTANCE);
+    }
 
 
-        if( hint < HINSTANCE_ERROR )
-        {
-                return NULL;
-        }
+  hint = LoadLibrary (dll);
 
 
-        return (void FAR*)hint;
-}
+  if (hint < HINSTANCE_ERROR)
+    {
+      return NULL;
+    }
 
 
-void FAR*       dlsym( void FAR* hdll, char FAR* sym )
-{
-        return (void FAR*)GetProcAddress(hdll, sym);
+  return (void FAR *) hint;
 }
 
 }
 
-char FAR*       dlerror()
-{
-        return 0L; /* unimplemented yet */
-}
 
 
-int     dlclose(void FAR* hdll)
+void FAR *
+dlsym (void FAR * hdll, char FAR * sym)
 {
 {
-        FreeLibrary((HINSTANCE)hdll);
+  return (void FAR *) GetProcAddress (hdll, sym);
 }
 
 }
 
-#endif  /* end of Windows family */
 
 
-/*********************************
- *
- *      OS/2 2.x, 3.x
- *
- *********************************/
-#ifdef DLDAPI_OS2
-# define        DLDAPI_DEFINED
-/*
- *      DosLoadModule(), DosQueryProcAddress(), DosFreeModule(), ...
- */
-
-void FAR*       dlopen(char FAR* dll, int mode)
+char FAR *
+dlerror ()
 {
 {
-        APIRET  rc             = NO_ERROR;       /* API return code          */
-        UCHAR   LoadError[256] = "";             /* Area for Load fail. info */
-        HMODULE ModuleHandle   = NULLHANDLE;     /* Module handle            */
-
-        if( dll == NULL || '\0' == *dll )
-        {
-                return NULL;
-        }
-
-        rc = NO_ERROR;
-        rc = DosLoadModule( LoadError,           /* Failure info buffer      */
-                            sizeof(LoadError),   /* Size of buffer           */
-                            dll,                 /* Module to load           */
-                            &ModuleHandle );     /* Module handle returned   */
-        if (rc != NO_ERROR)
-        {
-#ifdef DEBUG
-                fprintf( stderr,
-                         "[dlf.c] dlopen: DosLoadModule(0x%08lX, %d, \"%s\", 0x%08lX) = %d\n",
-                         &LoadError, sizeof(LoadError), dll, &ModuleHandle, rc
-                       );
-                fprintf( stderr,
-                         "                ---> missing module '%s'\n",
-                         LoadError );
-#endif
-                return NULL;
-        }
-
-        return (void FAR*) ModuleHandle;
-
+  return 0L;                   /* unimplemented yet */
 }
 
 }
 
-void FAR*       dlsym( void FAR* hdll, char FAR* sym )
-{
-        APIRET  rc             = NO_ERROR;       /* API return code          */
-        PFN     ModuleAddress  = NULL;           /* Module address           */
-
-        rc = DosQueryProcAddr( (HMODULE) hdll, 0, sym, &ModuleAddress );
 
 
-        return (void FAR*) (NO_ERROR == rc) ? ModuleAddress
-                                            : NULL;
-}
-
-char FAR*       dlerror()
+int 
+dlclose (void FAR * hdll)
 {
 {
-        return 0L; /* unimplemented yet */
+  FreeLibrary ((HINSTANCE) hdll);
 }
 }
+#endif /* end of Windows family */
 
 
-int     dlclose(void FAR* hdll)
-{
-        return DosFreeModule( (HMODULE) hdll );
-}
-
-#endif
 
 /***********************************
  *
 
 /***********************************
  *
- *      other platforms
+ *     other platforms
  *
  ***********************************/
  *
  ***********************************/
-#ifdef  DLDAPI_MAC
-# define        DLDAPI_DEFINED
+
+#ifdef DLDAPI_OS2
+#define        DLDAPI_DEFINED
+/*
+ *    DosLoadModule(), DosQueryProcAddress(), DosFreeModule(), ...
+ */
+#endif
+
+#ifdef DLDAPI_MAC
+#define        DLDAPI_DEFINED
 #endif
 
 #ifdef DLDAPI_NEXT
 #endif
 
 #ifdef DLDAPI_NEXT
-# define        DLDAPI_DEFINED
+#define        DLDAPI_DEFINED
 #endif
 
 #ifndef DLDAPI_DEFINED
 #endif
 
 #ifndef DLDAPI_DEFINED
-# error "dynamic load editor undefined"
+#error "dynamic load editor undefined"
 #endif
 #endif