]>
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"