]>
git.saurik.com Git - wxWidgets.git/blob - src/iodbc/dlf.c
1 /** dynamic library loader (mapping to svr4)
3 Copyright (C) 1995 by Ke Jin <kejin@empress.com>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
18 #include <../iodbc/dlf.h>
22 # undef DLDAPI_DEFINED
25 #ifdef DLDAPI_SVR4_DLFCN
26 # define DLDAPI_DEFINED
27 static char sccsid
[] = "@(#)dynamic load interface -- SVR4 dlfcn";
30 /*********************************
34 *********************************/
36 # define DLDAPI_DEFINED
39 static char sccsid
[] = "@(#)dynamic load interface -- HP/UX dl(shl)";
41 void* dlopen(char* path
, int mode
)
43 return (void*)shl_load((char*)(path
), BIND_DEFERRED
, 0L);
46 void* dlsym(void* hdll
, char* sym
)
52 hdll
= (void*)PROG_HANDLE
;
54 /* Remember, a driver may export calls as function pointers
55 * (i.e. with type TYPE_DATA) rather than as functions
56 * (i.e. with type TYPE_PROCEDURE). Thus, to be safe, we
57 * uses TYPE_UNDEFINED to cover all of them.
59 ret
= shl_findsym((shl_t
*)&hdll
, sym
, TYPE_UNDEFINED
, &symaddr
);
69 extern char* strerror();
71 return strerror(errno
);
74 int dlclose(void* hdll
)
76 return shl_unload((shl_t
)hdll
);
79 #endif /* end of HP/UX Seection */
81 /*********************************
85 *********************************/
86 #ifdef DLDAPI_AIX_LOAD
87 # define DLDAPI_DEFINED
88 # include <sys/types.h>
90 # include <sys/stat.h>
94 * Following id sting is a copyright mark. Removing(i.e. use the
95 * source code in this .c file without include it or make it not
96 * appear in the final object file of AIX platform) or modifing
97 * it without permission from original author(kejin@empress.com)
98 * are copyright violation.
101 = "@(#)dynamic load interface, Copyright(c) 1995 by Ke Jin";
104 # define HTAB_SIZE 256
107 # define FACTOR 0.618039887 /* i.e. (sqrt(5) - 1)/2 */
110 # define ENTRY_SYM ".__start" /* default entry point for aix */
113 typedef struct slot_s
116 long fdesc
[3]; /* 12 bytes function descriptor */
120 /* Note: on AIX, a function pointer actually points to a
121 * function descriptor, a 12 bytes data. The first 4 bytes
122 * is the virtual address of the function. The next 4 bytes
123 * is the virtual address of TOC (Table of Contents) of the
124 * object module the function belong to. The last 4 bytes
125 * are always 0 for C and Fortran functions. Every object
126 * module has an entry point (which can be specified at link
127 * time by -e ld option). iODBC driver manager requires ODBC
128 * driver shared library always use the default entry point
129 * (so you shouldn't use -e ld option when creating a driver
130 * share library). load() returns the function descriptor of
131 * a module's entry point. From which we can calculate function
132 * descriptors of other functions in the same module by using
133 * the fact that the load() doesn't change the relative
134 * offset of functions to their module entry point(i.e the
135 * offset in memory loaded by load() will be as same as in
136 * the module library file).
139 typedef slot_t
* hent_t
;
140 typedef struct nlist nlist_t
;
141 typedef struct stat stat_t
;
145 int dev
; /* device id */
146 int ino
; /* inode number */
147 char* path
; /* file name */
148 int (*pentry
)(); /* entry point of this share library */
149 int refn
; /* number of reference */
150 hent_t htab
[HTAB_SIZE
];
155 static char* errmsg
= 0;
157 static void init_htab(hent_t
* ht
)
158 /* initate a hashing table */
162 for(i
=0; i
<HTAB_SIZE
; i
++)
168 static void clean_htab(hent_t
* ht
)
175 for(i
= 0; i
< HTAB_SIZE
; i
++)
177 for( ent
= ht
[i
]; ent
; )
193 static int hash(char* sym
)
201 for(key
=*sym
;*sym
;sym
++)
206 key
= (int)( (a
<<8) + (key
>>8) );
207 key
= (key
>0)? key
:-key
;
213 return (int)((HTAB_SIZE
- 1)*( f
- a
));
216 static hent_t
search(hent_t
* htab
, char* sym
)
217 /* search hashing table to find a matched slot */
224 for(ent
= htab
[key
]; ent
; ent
= ent
->next
)
226 if(!strcmp(ent
->sym
, sym
))
230 return 0; /* no match */
233 static void insert(hent_t
* htab
, slot_t
* ent
)
234 /* insert a new slot to hashing table */
238 key
= hash(ent
->sym
);
240 ent
->next
= htab
[key
];
246 static slot_t
* slot_alloc(char* sym
)
247 /* allocate a new slot with symbol */
251 ent
= (slot_t
*)malloc(sizeof(slot_t
));
253 ent
->sym
= (char*)malloc(strlen(sym
)+1);
261 strcpy( ent
->sym
, sym
);
266 static obj_t
* obj_list
= 0;
268 void* dlopen(char* file
, int mode
)
274 if( ! file
|| ! *file
)
284 if( file
[0] != '/' && file
[0] != '.' )
288 sprintf(buf
, "/lib/%s", file
);
290 if( stat( buf
, &st
) )
296 sprintf(buf
, "/usr/lib/%s", file
);
298 if( stat( buf
, &st
) )
304 if( stat( file
, &st
) )
312 if( stat( file
, &st
) )
315 for( pobj
= obj_list
; pobj
; pobj
= pobj
->next
)
316 /* find a match object */
318 if( pobj
->ino
== st
.st_ino
319 && pobj
->dev
== st
.st_dev
)
321 /* found a match. increase its
322 * reference count and return
329 pobj
= (obj_t
*)malloc( sizeof(obj_t
) );
334 pobj
->path
= (char*)malloc( strlen(file
) + 1);
342 strcpy( pobj
->path
, file
);
344 pobj
->dev
= st
.st_dev
;
345 pobj
->ino
= st
.st_ino
;
348 pobj
->pentry
= (int(*)())load(file
, 0, 0);
357 init_htab(pobj
->htab
);
359 pobj
->next
= obj_list
;
365 int dlclose(void* hobj
)
367 obj_t
* pobj
= (obj_t
*)hobj
;
380 if( pobj
== obj_list
)
388 obj_list
= pobj
->next
;
391 for( tpobj
= obj_list
; !match
&& tpobj
; tpobj
= tpobj
->next
)
393 if( tpobj
->next
== pobj
)
401 tpobj
->next
= pobj
->next
;
407 unload((void*)(pobj
->pentry
));
408 clean_htab(pobj
->htab
);
418 extern char* sys_errlist
[];
420 if( ! errmsg
|| ! errmsg
[0] )
423 return sys_errlist
[errno
];
431 void* dlsym(void* hdl
, char* sym
)
434 obj_t
* pobj
= (obj_t
*)hdl
;
439 if( !hdl
|| !(pobj
->htab
) || !sym
|| ! *sym
)
448 ent
= search( pobj
->htab
, sym
);
453 #define n_name _n._n_name
455 nl
[0].n_name
= ENTRY_SYM
;
459 /* There is a potential problem here. If application
460 * did not pass a full path name, and changed the
461 * working directory after the load(), then nlist()
462 * will be unable to open the original shared library
463 * file to resolve the symbols. there are 3 ways to working
464 * round this: 1. convert to full pathname in driver
465 * manager. 2. applications always pass driver's full
466 * path name. 3. if driver itself don't support
467 * SQLGetFunctions(), call it with SQL_ALL_FUNCTIONS
468 * as flag immidately after SQLConnect(), SQLDriverConnect()
469 * and SQLBrowseConnect() to force the driver manager
470 * resolving all will be used symbols.
472 if( nlist( pobj
->path
, nl
) == -1 )
475 if( ! nl
[0].n_type
&& ! nl
[0].n_value
)
477 errmsg
= "can't locate module entry symbol";
481 /* Note: On AIX 3.x if the object library is not
482 * built with -g compiling option, .n_type field
483 * is always 0. While on 4.x it will be 32.
484 * On AIX 4.x, if the symbol is a entry point,
485 * n_value will be 0. However, one thing is for sure
486 * that if a symbol is not existance in the file,
487 * both .n_type and .n_value would be 0.
490 if( ! nl
[1].n_type
&& ! nl
[1].n_value
)
492 errmsg
= "symbol not existance in this module";
496 ent
= slot_alloc(sym
);
501 /* catch it with a slot in the hashing table */
502 insert(pobj
->htab
, ent
);
504 memcpy(ent
->fdesc
, pobj
->pentry
, sizeof(ent
->fdesc
));
506 /* now ent->fdesc[0] is the virtual address of entry point
507 * and ent->fdesc[1] is the TOC of the module
510 /* let's calculate the virtual address of the symbol
511 * by adding a relative offset getting from the module
512 * file symbol table, i.e
514 * functin virtual address = entry point virtual address +
515 * + ( function offset in file - entry point offset in file )
518 (ent
->fdesc
)[0] = (ent
->fdesc
)[0] +
519 ( nl
[1].n_value
- nl
[0].n_value
);
521 /* return the function descriptor */
525 #endif /* end of IBM AIX Section */
528 /*********************************
530 * Windows 3.x, 95, NT
532 *********************************/
533 #ifdef DLDAPI_WINDOWS
534 # define DLDAPI_DEFINED
535 # include <windows.h>
537 void FAR
* dlopen(char FAR
* dll
, int mode
)
543 return GetWindowWord( NULL
, GWW_HINSTANCE
);
546 hint
= LoadLibrary(dll
);
548 if( hint
< HINSTANCE_ERROR
)
553 return (void FAR
*)hint
;
556 void FAR
* dlsym( void FAR
* hdll
, char FAR
* sym
)
558 return (void FAR
*)GetProcAddress(hdll
, sym
);
563 return 0L; /* unimplemented yet */
566 int dlclose(void FAR
* hdll
)
568 FreeLibrary((HINSTANCE
)hdll
);
571 #endif /* end of Windows family */
573 /***********************************
577 ***********************************/
579 # define DLDAPI_DEFINED
581 * DosLoadModule(), DosQueryProcAddress(), DosFreeModule(), ...
586 # define DLDAPI_DEFINED
590 # define DLDAPI_DEFINED
593 #ifndef DLDAPI_DEFINED
594 # error "dynamic load editor undefined"