]>
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.
17 # define INCL_DOSMODULEMGR /* Module Manager values */
18 # define INCL_DOSERRORS /* Error values */
24 #include <../iodbc/dlf.h>
28 # undef DLDAPI_DEFINED
31 #ifdef DLDAPI_SVR4_DLFCN
32 # define DLDAPI_DEFINED
33 static char sccsid
[] = "@(#)dynamic load interface -- SVR4 dlfcn";
36 /*********************************
40 *********************************/
42 # define DLDAPI_DEFINED
45 static char sccsid
[] = "@(#)dynamic load interface -- HP/UX dl(shl)";
47 void* dlopen(char* path
, int mode
)
49 return (void*)shl_load((char*)(path
), BIND_DEFERRED
, 0L);
52 void* dlsym(void* hdll
, char* sym
)
58 hdll
= (void*)PROG_HANDLE
;
60 /* Remember, a driver may export calls as function pointers
61 * (i.e. with type TYPE_DATA) rather than as functions
62 * (i.e. with type TYPE_PROCEDURE). Thus, to be safe, we
63 * uses TYPE_UNDEFINED to cover all of them.
65 ret
= shl_findsym((shl_t
*)&hdll
, sym
, TYPE_UNDEFINED
, &symaddr
);
75 extern char* strerror();
77 return strerror(errno
);
80 int dlclose(void* hdll
)
82 return shl_unload((shl_t
)hdll
);
85 #endif /* end of HP/UX Seection */
87 /*********************************
91 *********************************/
92 #ifdef DLDAPI_AIX_LOAD
93 # define DLDAPI_DEFINED
95 # include <sys/stat.h>
99 * Following id sting is a copyright mark. Removing(i.e. use the
100 * source code in this .c file without include it or make it not
101 * appear in the final object file of AIX platform) or modifing
102 * it without permission from original author(kejin@empress.com)
103 * are copyright violation.
106 = "@(#)dynamic load interface, Copyright(c) 1995 by Ke Jin";
109 # define HTAB_SIZE 256
112 # define FACTOR 0.618039887 /* i.e. (sqrt(5) - 1)/2 */
115 # define ENTRY_SYM ".__start" /* default entry point for aix */
118 typedef struct slot_s
121 long fdesc
[3]; /* 12 bytes function descriptor */
125 /* Note: on AIX, a function pointer actually points to a
126 * function descriptor, a 12 bytes data. The first 4 bytes
127 * is the virtual address of the function. The next 4 bytes
128 * is the virtual address of TOC (Table of Contents) of the
129 * object module the function belong to. The last 4 bytes
130 * are always 0 for C and Fortran functions. Every object
131 * module has an entry point (which can be specified at link
132 * time by -e ld option). iODBC driver manager requires ODBC
133 * driver shared library always use the default entry point
134 * (so you shouldn't use -e ld option when creating a driver
135 * share library). load() returns the function descriptor of
136 * a module's entry point. From which we can calculate function
137 * descriptors of other functions in the same module by using
138 * the fact that the load() doesn't change the relative
139 * offset of functions to their module entry point(i.e the
140 * offset in memory loaded by load() will be as same as in
141 * the module library file).
144 typedef slot_t
* hent_t
;
145 typedef struct nlist nlist_t
;
146 typedef struct stat stat_t
;
150 int dev
; /* device id */
151 int ino
; /* inode number */
152 char* path
; /* file name */
153 int (*pentry
)(); /* entry point of this share library */
154 int refn
; /* number of reference */
155 hent_t htab
[HTAB_SIZE
];
160 static char* errmsg
= 0;
162 static void init_htab(hent_t
* ht
)
163 /* initate a hashing table */
167 for(i
=0; i
<HTAB_SIZE
; i
++)
173 static void clean_htab(hent_t
* ht
)
180 for(i
= 0; i
< HTAB_SIZE
; i
++)
182 for( ent
= ht
[i
]; ent
; )
198 static int hash(char* sym
)
206 for(key
=*sym
;*sym
;sym
++)
211 key
= (int)( (a
<<8) + (key
>>8) );
212 key
= (key
>0)? key
:-key
;
218 return (int)((HTAB_SIZE
- 1)*( f
- a
));
221 static hent_t
search(hent_t
* htab
, char* sym
)
222 /* search hashing table to find a matched slot */
229 for(ent
= htab
[key
]; ent
; ent
= ent
->next
)
231 if(!strcmp(ent
->sym
, sym
))
235 return 0; /* no match */
238 static void insert(hent_t
* htab
, slot_t
* ent
)
239 /* insert a new slot to hashing table */
243 key
= hash(ent
->sym
);
245 ent
->next
= htab
[key
];
251 static slot_t
* slot_alloc(char* sym
)
252 /* allocate a new slot with symbol */
256 ent
= (slot_t
*)malloc(sizeof(slot_t
));
258 ent
->sym
= (char*)malloc(strlen(sym
)+1);
266 strcpy( ent
->sym
, sym
);
271 static obj_t
* obj_list
= 0;
273 void* dlopen(char* file
, int mode
)
279 if( ! file
|| ! *file
)
289 if( file
[0] != '/' && file
[0] != '.' )
293 sprintf(buf
, "/lib/%s", file
);
295 if( stat( buf
, &st
) )
301 sprintf(buf
, "/usr/lib/%s", file
);
303 if( stat( buf
, &st
) )
309 if( stat( file
, &st
) )
317 if( stat( file
, &st
) )
320 for( pobj
= obj_list
; pobj
; pobj
= pobj
->next
)
321 /* find a match object */
323 if( pobj
->ino
== st
.st_ino
324 && pobj
->dev
== st
.st_dev
)
326 /* found a match. increase its
327 * reference count and return
334 pobj
= (obj_t
*)malloc( sizeof(obj_t
) );
339 pobj
->path
= (char*)malloc( strlen(file
) + 1);
347 strcpy( pobj
->path
, file
);
349 pobj
->dev
= st
.st_dev
;
350 pobj
->ino
= st
.st_ino
;
353 pobj
->pentry
= (int(*)())load(file
, 0, 0);
362 init_htab(pobj
->htab
);
364 pobj
->next
= obj_list
;
370 int dlclose(void* hobj
)
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
);
423 extern char* sys_errlist
[];
425 if( ! errmsg
|| ! errmsg
[0] )
428 return sys_errlist
[errno
];
436 void* dlsym(void* hdl
, char* sym
)
439 obj_t
* pobj
= (obj_t
*)hdl
;
444 if( !hdl
|| !(pobj
->htab
) || !sym
|| ! *sym
)
453 ent
= search( pobj
->htab
, sym
);
458 #define n_name _n._n_name
460 nl
[0].n_name
= ENTRY_SYM
;
464 /* There is a potential problem here. If application
465 * did not pass a full path name, and changed the
466 * working directory after the load(), then nlist()
467 * will be unable to open the original shared library
468 * file to resolve the symbols. there are 3 ways to working
469 * round this: 1. convert to full pathname in driver
470 * manager. 2. applications always pass driver's full
471 * path name. 3. if driver itself don't support
472 * SQLGetFunctions(), call it with SQL_ALL_FUNCTIONS
473 * as flag immidately after SQLConnect(), SQLDriverConnect()
474 * and SQLBrowseConnect() to force the driver manager
475 * resolving all will be used symbols.
477 if( nlist( pobj
->path
, nl
) == -1 )
480 if( ! nl
[0].n_type
&& ! nl
[0].n_value
)
482 errmsg
= "can't locate module entry symbol";
486 /* Note: On AIX 3.x if the object library is not
487 * built with -g compiling option, .n_type field
488 * is always 0. While on 4.x it will be 32.
489 * On AIX 4.x, if the symbol is a entry point,
490 * n_value will be 0. However, one thing is for sure
491 * that if a symbol is not existance in the file,
492 * both .n_type and .n_value would be 0.
495 if( ! nl
[1].n_type
&& ! nl
[1].n_value
)
497 errmsg
= "symbol not existance in this module";
501 ent
= slot_alloc(sym
);
506 /* catch it with a slot in the hashing table */
507 insert(pobj
->htab
, ent
);
509 memcpy(ent
->fdesc
, pobj
->pentry
, sizeof(ent
->fdesc
));
511 /* now ent->fdesc[0] is the virtual address of entry point
512 * and ent->fdesc[1] is the TOC of the module
515 /* let's calculate the virtual address of the symbol
516 * by adding a relative offset getting from the module
517 * file symbol table, i.e
519 * functin virtual address = entry point virtual address +
520 * + ( function offset in file - entry point offset in file )
523 (ent
->fdesc
)[0] = (ent
->fdesc
)[0] +
524 ( nl
[1].n_value
- nl
[0].n_value
);
526 /* return the function descriptor */
530 #endif /* end of IBM AIX Section */
533 /*********************************
535 * Windows 3.x, 95, NT
537 *********************************/
538 #ifdef DLDAPI_WINDOWS
539 # define DLDAPI_DEFINED
540 # include <windows.h>
542 void FAR
* dlopen(char FAR
* dll
, int mode
)
548 return GetWindowWord( NULL
, GWW_HINSTANCE
);
551 hint
= LoadLibrary(dll
);
553 if( hint
< HINSTANCE_ERROR
)
558 return (void FAR
*)hint
;
561 void FAR
* dlsym( void FAR
* hdll
, char FAR
* sym
)
563 return (void FAR
*)GetProcAddress(hdll
, sym
);
568 return 0L; /* unimplemented yet */
571 int dlclose(void FAR
* hdll
)
573 FreeLibrary((HINSTANCE
)hdll
);
576 #endif /* end of Windows family */
578 /*********************************
582 *********************************/
584 # define DLDAPI_DEFINED
586 * DosLoadModule(), DosQueryProcAddress(), DosFreeModule(), ...
589 void FAR
* dlopen(char FAR
* dll
, int mode
)
591 APIRET rc
= NO_ERROR
; /* API return code */
592 UCHAR LoadError
[256] = ""; /* Area for Load fail. info */
593 HMODULE ModuleHandle
= NULLHANDLE
; /* Module handle */
595 if( dll
== NULL
|| '\0' == *dll
)
601 rc
= DosLoadModule( LoadError
, /* Failure info buffer */
602 sizeof(LoadError
), /* Size of buffer */
603 dll
, /* Module to load */
604 &ModuleHandle
); /* Module handle returned */
609 "[dlf.c] dlopen: DosLoadModule(0x%08lX, %d, \"%s\", 0x%08lX) = %d\n",
610 &LoadError
, sizeof(LoadError
), dll
, &ModuleHandle
, rc
613 " ---> missing module '%s'\n",
619 return (void FAR
*) ModuleHandle
;
623 void FAR
* dlsym( void FAR
* hdll
, char FAR
* sym
)
625 APIRET rc
= NO_ERROR
; /* API return code */
626 PFN ModuleAddress
= NULL
; /* Module address */
628 rc
= DosQueryProcAddr( (HMODULE
) hdll
, 0, sym
, &ModuleAddress
);
630 return (void FAR
*) (NO_ERROR
== rc
) ? ModuleAddress
636 return 0L; /* unimplemented yet */
639 int dlclose(void FAR
* hdll
)
641 return DosFreeModule( (HMODULE
) hdll
);
646 /***********************************
650 ***********************************/
652 # define DLDAPI_DEFINED
656 # define DLDAPI_DEFINED
659 #ifndef DLDAPI_DEFINED
660 # error "dynamic load editor undefined"