2 * The Regina Rexx Interpreter
3 * Copyright (C) 1993-1994 Anders Christensen <anders@pvv.unit.no>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library 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 GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the Free
17 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 * This file is 'a hell of a file'. It contain _anything_ that is neither
26 * POSIX nor ANSI. The meaning is that when these things are needed in
27 * the code, they are located in a wrapper in this file. Thus, if you need
28 * to hack the code, it's likely that you only need to hack this file.
30 * At least, that's the theory ...
36 /* Stupid MSC can't compile own headers without warning at least in VC 5.0 */
37 # pragma warning(disable: 4115 4201 4214)
43 # pragma warning(default: 4115 4201 4214)
49 # define INCL_DOSMODULEMGR
51 # define DONT_TYPEDEF_PFN
64 * Most Unix systems have dlopen(), so set this as the default and
65 * unset it for platforms that don't have it - except for HPUX
68 # define DYNAMIC_HPSHLOAD
71 # if defined(HAVE_DLFCN_H) && !defined(DYNAMIC_HPSHLOAD)
72 # define DYNAMIC_DLOPEN
75 # if defined(DYNAMIC_DLOPEN)
77 typedef void *handle_type
;
81 # if defined(__CYGWIN__)
83 # define DYNLIBPST ".dll"
86 # define DYNLIBPRE "lib"
88 # define DYNLIBPST ".a"
91 # define DYNLIBPST ".so"
95 # elif defined(DYNAMIC_AIXLOAD)
96 # include <sys/types.h>
98 typedef int (*handle_type
) ;
99 # define DYNLIBPRE "lib"
100 # define DYNLIBPST ".a"
103 # elif defined(DYNAMIC_HPSHLOAD)
105 typedef shl_t handle_type
;
106 # define DYNLIBPRE "lib"
107 # define DYNLIBPST ".sl"
110 # elif defined(__BEOS__)
111 # include <be/kernel/image.h>
112 # define DYNAMIC_BEOS 1
113 typedef image_id handle_type
;
115 * BeOS add-ons are all in a directory specified in $ADDON_PATH
117 # define DYNLIBPRE "lib"
118 # define DYNLIBPST ".so"
121 # elif defined(DYNAMIC_OS2)
122 typedef HMODULE handle_type
;
123 /* typedef PHMODULE handle_type ; */
125 # elif defined(DYNAMIC_WIN32)
126 typedef HINSTANCE handle_type
;
127 # elif defined(DYNAMIC_VMS)
128 # define DYNLIBPRE "LIB"
129 # define DYNLIBPST ".EXE"
136 #ifdef DYNAMIC_HPSHLOAD_NOT_NEEDED
138 * HP/UX doesn't find symbols unless they are 'true data'; entrypoints
139 * for functions are not sufficient! Thus, we need to force it to
140 * 'release' that these symbols are defined. There's no need to do
141 * anything more, once it sets some flag somewhere ... it'll find'em
144 * Datatype char only used to save space ... this is never used, so
145 * there is no reason to waste space.
147 * Removed by MH 0.08h. Causes problems on HPUX 10.20 linker, and may
148 * not be needed anymore.
151 char Food_For_Fuzzy_HP_Linkers
[] = {
152 (char)exiterror
, (char)getonechar
,
154 (char)atozpos
, (char)checkparam
, (char)loadrxfunc
} ;
157 #if defined(DYNAMIC_AIXLOAD)
158 void *wrapper_dummy_for_aix( void )
163 /* versions of strlwr & strupr to simulate case-insensitivity */
164 static void rxstrlwr(unsigned char * s
, unsigned char *e
)
168 *s
= (unsigned char) (tolower(*s
));
173 static void rxstrupr(unsigned char * s
, unsigned char *e
)
177 *s
= (unsigned char) (toupper(*s
));
183 void *wrapper_load( const tsd_t
*TSD
, const streng
*module
)
185 handle_type handle
=(handle_type
)NULL
;
186 #if defined(DYNAMIC_OS2)
190 #if defined(DYNAMIC_WIN32)
193 #if defined(DYNAMIC_HPSHLOAD)
196 char *file_name
, *module_name
, *udpart
, *postfix
;
199 file_name
= module_name
= str_ofTSD(module
);
201 module_name
= MallocTSD( Str_len( module
) + strlen(DYNLIBPRE
) +
202 strlen(DYNLIBPST
) + 1 ) ;
203 strcpy(module_name
, DYNLIBPRE
);
204 udpart
= module_name
+ strlen(DYNLIBPRE
);
205 memcpy(udpart
, module
->value
, Str_len(module
) );
206 strcpy(udpart
+ Str_len(module
), DYNLIBPST
);
207 file_name
= module_name
;
208 postfix
= udpart
+ Str_len(module
);
209 # if defined(DYNAMIC_HPSHLOAD)
210 find_shared_library(TSD
,module_name
,"SHLIB_PATH",buf
);
215 #if defined(DYNAMIC_DLOPEN)
216 handle
= dlopen( file_name
, RTLD_LAZY
) ;
218 /* deal with incorrect case in call */
221 rxstrlwr(udpart
,postfix
);
222 handle
= dlopen(module_name
, RTLD_LAZY
);
226 rxstrupr(udpart
,postfix
);
227 handle
= dlopen(module_name
, RTLD_LAZY
);
229 * Reset the original module portion of the filename to be
230 * searched again so that any error message returned uses the
231 * original module name
233 if ( handle
== NULL
)
235 memcpy(udpart
, module
->value
, Str_len(module
) );
236 handle
= dlopen(module_name
, RTLD_LAZY
);
241 /* or maybe it's just not there */
247 set_err_message(TSD
, "dlopen() failed: ", msg
) ;
249 set_err_message(TSD
, "", "");
251 #elif defined(DYNAMIC_HPSHLOAD)
252 handle
= shl_load( file_name
, BIND_IMMEDIATE
| DYNAMIC_PATH
, 0L ) ;
255 rxstrlwr(udpart
,postfix
);
256 find_shared_library(TSD
,module_name
,"SHLIB_PATH",buf
);
257 handle
= shl_load( file_name
, BIND_IMMEDIATE
| DYNAMIC_PATH
,0L ) ;
261 rxstrupr(udpart
,postfix
);
262 find_shared_library(TSD
,module_name
,"SHLIB_PATH",buf
);
263 handle
= shl_load( file_name
, BIND_IMMEDIATE
| DYNAMIC_PATH
,0L ) ;
268 set_err_message(TSD
, "shl_load() failed: ", strerror(errno
)) ;
269 #elif defined(DYNAMIC_AIXLOAD)
270 handle
= load( file_name
, 1, NULL
) ;
273 int rc
=loadbind( 0, (void *)wrapper_dummy_for_aix
, (void *)handle
) ;
278 set_err_message(TSD
, "load() failed: ", strerror( errno
)) ;
279 #elif defined(DYNAMIC_OS2)
280 rc
= DosLoadModule( LoadError
, sizeof(LoadError
),
281 file_name
, &handle
) ;
284 set_err_message(TSD
, "DosLoadModule() unable to load DLL: ", LoadError
);
285 handle
= (handle_type
)NULL
;
287 #elif defined(DYNAMIC_WIN32)
288 handle
= LoadLibrary( file_name
) ;
291 FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM
, NULL
, GetLastError(), MAKELANGID( LANG_NEUTRAL
, SUBLANG_DEFAULT
), LoadError
, 256, NULL
) ;
292 set_err_message(TSD
, "LoadLibrary() failed: ", LoadError
);
294 #elif defined(DYNAMIC_BEOS)
295 handle
= load_add_on( file_name
);
296 if (handle
== B_ERROR
)
298 set_err_message(TSD
, "load_add_on() failed loading:", file_name
);
299 handle
= (handle_type
)NULL
;
303 FreeTSD(module_name
);
305 return (void *)handle
;
308 PFN
wrapper_get_addr( const tsd_t
*TSD
, const struct library
*lptr
, const streng
*name
)
311 handle_type handle
=(handle_type
)lptr
->handle
;
313 #if defined(DYNAMIC_WIN32)
316 #if defined(DYNAMIC_OS2)
319 #if defined(DYNAMIC_BEOS)
322 #if defined(MODULES_NEED_USCORE)
326 funcname
= str_of( TSD
, name
) ;
328 #if defined(DYNAMIC_DLOPEN)
329 # if defined(MODULES_NEED_USCORE)
331 * Some platforms need to have an underscore prepended to the function
332 * name to be found in a loadable module.
335 us_func
= Str_makeTSD( Str_len( name
) + 1 );
336 memcpy( us_func
->value
, "_", 1 );
338 Str_catTSD( us_func
, name
);
339 funcname
= str_of( TSD
, us_func
);
342 * Note, the following assignment is not allowed by ANSI, but SVR4.2
343 * includes it as an example, so it is probably safe in this context
345 addr
= (PFN
)(dlsym( handle
, funcname
)) ;
347 /* deal with, eg 'SysLoadFuncs' when the function is 'sysloadfuncs' or 'SYSLOADFUNCS' */
350 rxstrupr(funcname
,NULL
);
351 addr
= (PFN
)(dlsym( handle
, funcname
)) ;
355 rxstrlwr(funcname
,NULL
);
356 addr
= (PFN
)(dlsym( handle
, funcname
)) ;
359 set_err_message(TSD
, "dlsym() failed: ", dlerror()) ;
363 #elif defined(DYNAMIC_HPSHLOAD)
368 if (rc
= shl_findsym( &handle
, funcname
, TYPE_PROCEDURE
, &eaddr
))
370 rxstrupr(funcname
,NULL
);
371 if (rc
= shl_findsym( &handle
, funcname
, TYPE_PROCEDURE
, &eaddr
))
373 rxstrlwr(funcname
,NULL
);
374 if (rc
= shl_findsym( &handle
, funcname
, TYPE_PROCEDURE
, &eaddr
))
377 set_err_message(TSD
, "shl_findsym() failed: ", strerror(errno
)) ;
385 #elif defined(DYNAMIC_AIXLOAD)
387 #elif defined(DYNAMIC_OS2)
388 rc
= DosQueryProcAddr(handle
,0L,funcname
,&addr
);
392 sprintf(buf
,"DosQueryProcAddr() failed with %ld looking for %s", (long) rc
, funcname
);
393 set_err_message(TSD
, buf
, "" ) ;
395 #elif defined(DYNAMIC_WIN32)
396 /* 13/12/1999 JH moved cast, (HMODULE), from second parm to first. Removed
397 * a compiler warning,
399 addr
= (PFN
)GetProcAddress((HMODULE
)handle
,funcname
);
404 addr
= (PFN
)GetProcAddress((HMODULE
)handle
,funcname
);
409 addr
= (PFN
)GetProcAddress((HMODULE
)handle
, funcname
);
412 FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM
, NULL
, GetLastError(), MAKELANGID( LANG_NEUTRAL
, SUBLANG_DEFAULT
), LoadError
, 256, NULL
) ;
413 set_err_message(TSD
, "GetProcAddress() failed: ", LoadError
) ;
417 #elif defined(DYNAMIC_BEOS)
418 rc
= get_image_symbol(handle
,funcname
,B_SYMBOL_TYPE_TEXT
,(void **)&addr
);
419 if (rc
== B_BAD_IMAGE_ID
)
422 sprintf(buf
,"get_image_symbol() failed with %d looking for %s", rc
, funcname
);
423 set_err_message(TSD
, buf
, "" ) ;
428 FreeTSD( funcname
) ;