]>
git.saurik.com Git - wxWidgets.git/blob - src/iodbc/dlf.c
   6  *  Dynamic Library Loader (mapping to SVR4) 
   8  *  The iODBC driver manager. 
  10  *  Copyright (C) 1995 by Ke Jin <kejin@empress.com>  
  12  *  This library is free software; you can redistribute it and/or 
  13  *  modify it under the terms of the GNU Library General Public 
  14  *  License as published by the Free Software Foundation; either 
  15  *  version 2 of the License, or (at your option) any later version. 
  17  *  This library is distributed in the hope that it will be useful, 
  18  *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
  19  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
  20  *  Library General Public License for more details. 
  22  *  You should have received a copy of the GNU Library General Public 
  23  *  License along with this library; if not, write to the Free 
  24  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
  34 #ifdef  DLDAPI_SVR4_DLFCN 
  35 #define DLDAPI_DEFINED 
  36 static char sccsid
[] = "@(#)dynamic load interface -- SVR4 dlfcn"; 
  39 /*********************************  
  43  *********************************/ 
  46 #define DLDAPI_DEFINED 
  49 static char sccsid
[] = "@(#)dynamic load interface -- HP/UX dl(shl)"; 
  52 dlopen (char *path
, int mode
) 
  54   return (void *) shl_load ((char *) (path
), BIND_DEFERRED
, 0L); 
  59 dlsym (void *hdll
, char *sym
) 
  65     hdll 
= (void *) PROG_HANDLE
; 
  67   /* Remember, a driver may export calls as function pointers  
  68    * (i.e. with type TYPE_DATA) rather than as functions  
  69    * (i.e. with type TYPE_PROCEDURE). Thus, to be safe, we  
  70    * uses TYPE_UNDEFINED to cover all of them.  
  72   ret 
= shl_findsym ((shl_t 
*) & hdll
, sym
, TYPE_UNDEFINED
, &symaddr
); 
  84   extern char *strerror (); 
  86   return strerror (errno
); 
  93   return shl_unload ((shl_t
) hdll
); 
  95 #endif /* end of HP/UX Seection */ 
  98 /********************************* 
 102  *********************************/ 
 104 #ifdef  DLDAPI_AIX_LOAD 
 105 #define DLDAPI_DEFINED 
 106 #include        <sys/types.h> 
 108 #include        <sys/stat.h> 
 112  *   Following id sting is a copyright mark. Removing(i.e. use the  
 113  *   source code in this .c file without include it or make it not 
 114  *   appear in the final object file of AIX platform) or modifing  
 115  *   it without permission from original author(kejin@empress.com)  
 116  *   are copyright violation. 
 119 = "@(#)dynamic load interface, Copyright(c) 1995 by Ke Jin"; 
 122 #define HTAB_SIZE       256 
 125 #define FACTOR          0.618039887     /* i.e. (sqrt(5) - 1)/2 */ 
 128 #define ENTRY_SYM       ".__start"      /* default entry point for aix */ 
 131 typedef struct slot_s
 
 134     long fdesc
[3];              /* 12 bytes function descriptor */ 
 139 /* Note: on AIX, a function pointer actually points to a 
 140  * function descriptor, a 12 bytes data. The first 4 bytes 
 141  * is the virtual address of the function. The next 4 bytes  
 142  * is the virtual address of TOC (Table of Contents) of the 
 143  * object module the function belong to. The last 4 bytes  
 144  * are always 0 for C and Fortran functions. Every object  
 145  * module has an entry point (which can be specified at link 
 146  * time by -e ld option). iODBC driver manager requires ODBC 
 147  * driver shared library always use the default entry point 
 148  * (so you shouldn't use -e ld option when creating a driver 
 149  * share library). load() returns the function descriptor of  
 150  * a module's entry point. From which we can calculate function 
 151  * descriptors of other functions in the same module by using 
 152  * the fact that the load() doesn't change the relative  
 153  * offset of functions to their module entry point(i.e the  
 154  * offset in memory loaded by load() will be as same as in  
 155  * the module library file).  
 158 typedef slot_t 
*hent_t
; 
 159 typedef struct nlist nlist_t
; 
 160 typedef struct stat stat_t
; 
 164     int dev
;                    /* device id */ 
 165     int ino
;                    /* inode number */ 
 166     char *path
;                 /* file name */ 
 167     int (*pentry
) ();           /* entry point of this share library */ 
 168     int refn
;                   /* number of reference */ 
 169     hent_t htab
[HTAB_SIZE
]; 
 174 static char *errmsg 
= 0; 
 177 init_htab (hent_t 
* ht
) 
 178 /* initate a hashing table */ 
 182   for (i 
= 0; i 
< HTAB_SIZE
; i
++) 
 183     ht
[i
] = (slot_t 
*) 0; 
 190 clean_htab (hent_t 
* ht
) 
 197   for (i 
= 0; i 
< HTAB_SIZE
; i
++) 
 199       for (ent 
= ht
[i
]; ent
;) 
 225   for (key 
= *sym
; *sym
; sym
++) 
 230       key 
= (int) ((a 
<< 8) + (key 
>> 8)); 
 231       key 
= (key 
> 0) ? key 
: -key
; 
 237   return (int) ((HTAB_SIZE 
- 1) * (f 
- a
)); 
 242 search (hent_t 
* htab
, char *sym
) 
 243 /* search hashing table to find a matched slot */ 
 250   for (ent 
= htab
[key
]; ent
; ent 
= ent
->next
) 
 252       if (!strcmp (ent
->sym
, sym
)) 
 256   return 0;                     /* no match */ 
 261 insert (hent_t 
* htab
, slot_t 
* ent
) 
 262 /* insert a new slot to hashing table */ 
 266   key 
= hash (ent
->sym
); 
 268   ent
->next 
= htab
[key
]; 
 276 slot_alloc (char *sym
) 
 277 /* allocate a new slot with symbol */ 
 281   ent 
= (slot_t 
*) malloc (sizeof (slot_t
)); 
 283   ent
->sym 
= (char *) malloc (strlen (sym
) + 1); 
 291   strcpy (ent
->sym
, sym
); 
 297 static obj_t 
*obj_list 
= 0; 
 300 dlopen (char *file
, int mode
) 
 315   if (stat (file
, &st
)) 
 318   for (pobj 
= obj_list
; pobj
; pobj 
= pobj
->next
) 
 319     /* find a match object */ 
 321       if (pobj
->ino 
== st
.st_ino
 
 322           && pobj
->dev 
== st
.st_dev
) 
 324           /* found a match. increase its 
 325            * reference count and return  
 332   pobj 
= (obj_t 
*) malloc (sizeof (obj_t
)); 
 337   pobj
->path 
= (char *) malloc (strlen (file
) + 1); 
 345   strcpy (pobj
->path
, file
); 
 347   pobj
->dev 
= st
.st_dev
; 
 348   pobj
->ino 
= st
.st_ino
; 
 351   pobj
->pentry 
= (int (*)()) load (file
, 0, 0); 
 360   init_htab (pobj
->htab
); 
 362   pobj
->next 
= obj_list
; 
 372   obj_t 
*pobj 
= (obj_t 
*) hobj
; 
 385   if (pobj 
== obj_list
) 
 393       obj_list 
= pobj
->next
; 
 396   for (tpobj 
= obj_list
; !match 
&& tpobj
; tpobj 
= tpobj
->next
) 
 398       if (tpobj
->next 
== pobj
) 
 406           tpobj
->next 
= pobj
->next
; 
 412       unload ((void *) (pobj
->pentry
)); 
 413       clean_htab (pobj
->htab
); 
 425   extern char *sys_errlist
[]; 
 427   if (!errmsg 
|| !errmsg
[0]) 
 430         return sys_errlist
[errno
]; 
 440 dlsym (void *hdl
, char *sym
) 
 443   obj_t 
*pobj 
= (obj_t 
*) hdl
; 
 448   if (!hdl 
|| !(pobj
->htab
) || !sym 
|| !*sym
) 
 457   ent 
= search (pobj
->htab
, sym
); 
 462 #define n_name  _n._n_name 
 464   nl
[0].n_name 
= ENTRY_SYM
; 
 468   /* There is a potential problem here. If application 
 469    * did not pass a full path name, and changed the 
 470    * working directory after the load(), then nlist() 
 471    * will be unable to open the original shared library 
 472    * file to resolve the symbols. there are 3 ways to working  
 473    * round this: 1. convert to full pathname in driver 
 474    * manager. 2. applications always pass driver's full  
 475    * path name. 3. if driver itself don't support  
 476    * SQLGetFunctions(), call it with SQL_ALL_FUNCTIONS 
 477    * as flag immidately after SQLConnect(), SQLDriverConnect() 
 478    * and SQLBrowseConnect() to force the driver manager 
 479    * resolving all will be used symbols.  
 481   if (nlist (pobj
->path
, nl
) == -1) 
 484   if (!nl
[0].n_type 
&& !nl
[0].n_value
) 
 486       errmsg 
= "can't locate module entry symbol"; 
 490   /* Note: On AIX 3.x if the object library is not 
 491    * built with -g compiling option, .n_type field 
 492    * is always 0. While on 4.x it will be 32.  
 493    * On AIX 4.x, if the symbol is a entry point, 
 494    * n_value will be 0. However, one thing is for sure  
 495    * that if a symbol is not existance in the file, 
 496    * both .n_type and .n_value would be 0. 
 499   if (!nl
[1].n_type 
&& !nl
[1].n_value
) 
 501       errmsg 
= "symbol not existance in this module"; 
 505   ent 
= slot_alloc (sym
); 
 510   /* catch it with a slot in the hashing table */ 
 511   insert (pobj
->htab
, ent
); 
 513   memcpy (ent
->fdesc
, pobj
->pentry
, sizeof (ent
->fdesc
)); 
 515   /* now ent->fdesc[0] is the virtual address of entry point 
 516    * and ent->fdesc[1] is the TOC of the module 
 519   /* let's calculate the virtual address of the symbol  
 520    * by adding a relative offset getting from the module  
 521    * file symbol table, i.e 
 523    *  functin virtual address = entry point virtual address + 
 524    *     + ( function offset in file - entry point offset in file ) 
 527   (ent
->fdesc
)[0] = (ent
->fdesc
)[0] + 
 528       (nl
[1].n_value 
- nl
[0].n_value
); 
 530   /* return the function descriptor */ 
 533 #endif /* end of IBM AIX Section */ 
 536 /*********************************  
 538  *      Windows 3.x, 95, NT 
 540  *********************************/ 
 542 #ifdef  DLDAPI_WINDOWS 
 543 #define DLDAPI_DEFINED 
 547 dlopen (char FAR 
* dll
, int mode
) 
 553       return GetWindowWord (NULL
, GWW_HINSTANCE
); 
 556   hint 
= LoadLibrary (dll
); 
 558   if (hint 
< HINSTANCE_ERROR
) 
 563   return (void FAR 
*) hint
; 
 568 dlsym (void FAR 
* hdll
, char FAR 
* sym
) 
 570   return (void FAR 
*) GetProcAddress (hdll
, sym
); 
 577   return 0L;                    /* unimplemented yet */ 
 582 dlclose (void FAR 
* hdll
) 
 584   FreeLibrary ((HINSTANCE
) hdll
); 
 586 #endif /* end of Windows family */ 
 589 /*********************************** 
 593  ***********************************/ 
 596 #define DLDAPI_DEFINED 
 598  *    DosLoadModule(), DosQueryProcAddress(), DosFreeModule(), ... 
 603 #define DLDAPI_DEFINED 
 607 #define DLDAPI_DEFINED 
 610 #ifndef DLDAPI_DEFINED 
 611 #error  "dynamic load editor undefined"