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.
20 * This file is 'a hell of a file'. It contain _anything_ that is neither
21 * POSIX nor ANSI. The meaning is that when these things are needed in
22 * the code, they are located in a wrapper in this file. Thus, if you need
23 * to hack the code, it's likely that you only need to hack this file.
25 * At least, that's the theory ...
33 /* Stupid MSC can't compile own headers without warning at least in VC 5.0 */
34 # pragma warning(disable: 4115 4201 4214 4514)
40 # pragma warning(default: 4115 4201 4214)
46 # define INCL_DOSMODULEMGR
48 # define DONT_TYPEDEF_PFN
60 * Most Unix systems have dlopen(), so set this as the default and
61 * unset it for platforms that don't have it - except for HPUX
64 # define DYNAMIC_HPSHLOAD
67 # if defined(HAVE_DLFCN_H) && !defined(DYNAMIC_HPSHLOAD)
68 # define DYNAMIC_DLOPEN
71 # if defined(DYNAMIC_STATIC)
72 typedef void * handle_type
;
75 # elif defined(DYNAMIC_DLOPEN)
77 typedef void *handle_type
;
81 # if defined(__CYGWIN__)
83 # define DYNLIBPST ".dll"
85 # elif defined(__APPLE__) && defined(__MACH__)
86 # define DYNLIBPRE "lib"
87 # define DYNLIBPST ".dylib"
90 # define DYNLIBPRE "lib"
91 # define DYNLIBPST ".a"
94 # define DYNLIBPRE "lib"
95 # define DYNLIBPST ".so"
98 # elif defined(DYNAMIC_AIXLOAD)
99 # include <sys/types.h>
100 # include <sys/ldr.h>
101 typedef int (*handle_type
) ;
102 # define DYNLIBPRE "lib"
103 # define DYNLIBPST ".a"
106 # elif defined(DYNAMIC_HPSHLOAD)
108 typedef shl_t handle_type
;
109 # define DYNLIBPRE "lib"
110 # define DYNLIBPST ".sl"
113 # elif defined(__BEOS__)
114 # include <be/kernel/image.h>
115 # define DYNAMIC_BEOS 1
116 typedef image_id handle_type
;
118 * BeOS add-ons are all in a directory specified in $ADDON_PATH
120 # define DYNLIBPRE "lib"
121 # define DYNLIBPST ".so"
124 # elif defined(DYNAMIC_SKYOS)
125 typedef sDllHandle
* handle_type
;
126 # define DYNLIBPRE "/boot/programs/rexx/extensions/lib"
127 # define DYNLIBPST ".dll"
128 # define DYNLIBLEN 40
130 # elif defined(DYNAMIC_OS2)
131 typedef HMODULE handle_type
;
132 /* typedef PHMODULE handle_type ; */
134 # elif defined(DYNAMIC_WIN32)
135 typedef HINSTANCE handle_type
;
137 # elif defined(DYNAMIC_VMS)
138 # define DYNLIBPRE "LIB"
139 # define DYNLIBPST ".EXE"
146 #ifdef DYNAMIC_HPSHLOAD_NOT_NEEDED
148 * HP/UX doesn't find symbols unless they are 'true data'; entrypoints
149 * for functions are not sufficient! Thus, we need to force it to
150 * 'release' that these symbols are defined. There's no need to do
151 * anything more, once it sets some flag somewhere ... it'll find'em
154 * Datatype char only used to save space ... this is never used, so
155 * there is no reason to waste space.
157 * Removed by MH 0.08h. Causes problems on HPUX 10.20 linker, and may
158 * not be needed anymore.
161 char Food_For_Fuzzy_HP_Linkers
[] = {
162 (char)exiterror
, (char)getonechar
,
164 (char)atozpos
, (char)checkparam
, (char)find_library
} ;
167 #if defined(DYNAMIC_AIXLOAD)
168 void *wrapper_dummy_for_aix( void )
173 void *wrapper_load( const tsd_t
*TSD
, const streng
*module
)
175 handle_type handle
=(handle_type
)NULL
;
176 #if defined(DYNAMIC_OS2)
180 #if defined(DYNAMIC_WIN32)
183 #if defined(DYNAMIC_HPSHLOAD) || defined(DYNAMIC_BEOS)
187 sDllHandle tmp_handle
;
189 char *file_name
, *module_name
, *udpart
, *postfix
, *orig_module
;
191 orig_module
= str_ofTSD( module
);
193 module_name
= (char *)MallocTSD( Str_len( module
) + strlen(DYNLIBPRE
) +
194 strlen(DYNLIBPST
) + 1 ) ;
195 strcpy(module_name
, DYNLIBPRE
);
196 udpart
= module_name
+ strlen(DYNLIBPRE
);
197 memcpy(udpart
, module
->value
, Str_len(module
) );
198 strcpy(udpart
+ Str_len(module
), DYNLIBPST
);
199 file_name
= module_name
;
200 postfix
= udpart
+ Str_len(module
);
201 # if defined(DYNAMIC_HPSHLOAD)
205 file_name
= module_name
= str_ofTSD(module
);
208 #if defined(DYNAMIC_STATIC)
209 handle
= static_dlopen( file_name
);
212 set_err_message(TSD
, "static_dlopen() failed loading:", file_name
);
213 handle
= (handle_type
)NULL
;
215 #elif defined(DYNAMIC_DLOPEN)
217 * Try and load the module name exactly as specified (before wrapping it
220 handle
= dlopen( orig_module
, RTLD_LAZY
) ;
223 handle
= dlopen( file_name
, RTLD_LAZY
) ;
224 /* deal with incorrect case in call */
227 mem_lower( udpart
, Str_len( module
) );
228 handle
= dlopen(module_name
, RTLD_LAZY
);
232 mem_upper( udpart
, Str_len( module
) );
233 handle
= dlopen(module_name
, RTLD_LAZY
);
235 * Reset the original module portion of the filename to be
236 * searched again so that any error message returned uses the
237 * original module name
239 if ( handle
== NULL
)
241 memcpy(udpart
, module
->value
, Str_len(module
) );
242 handle
= dlopen(module_name
, RTLD_LAZY
);
248 /* or maybe it's just not there */
254 set_err_message(TSD
, "dlopen() failed: ", msg
) ;
256 set_err_message(TSD
, "", "");
258 #elif defined(DYNAMIC_HPSHLOAD)
260 * Try and load the module name exactly as specified (before wrapping it
263 find_shared_library( TSD
, orig_module
, "SHLIB_PATH", buf
);
264 handle
= shl_load( file_name
, BIND_IMMEDIATE
| DYNAMIC_PATH
, 0L ) ;
267 find_shared_library(TSD
,module_name
,"SHLIB_PATH",buf
);
268 handle
= shl_load( file_name
, BIND_IMMEDIATE
| DYNAMIC_PATH
, 0L ) ;
271 mem_lower( udpart
, Str_len( module
) );
272 find_shared_library( TSD
, module_name
, "SHLIB_PATH", buf
);
273 handle
= shl_load( file_name
, BIND_IMMEDIATE
| DYNAMIC_PATH
,0L ) ;
277 mem_upper( udpart
, Str_len( module
) );
278 find_shared_library( TSD
, module_name
, "SHLIB_PATH", buf
);
279 handle
= shl_load( file_name
, BIND_IMMEDIATE
| DYNAMIC_PATH
,0L ) ;
285 set_err_message(TSD
, "shl_load() failed: ", strerror(errno
)) ;
286 #elif defined(DYNAMIC_AIXLOAD)
288 * Try and load the module name exactly as specified (before wrapping it
291 handle
= load( orig_module
, 1, NULL
) ;
292 if ( handle
== NULL
)
294 handle
= load( file_name
, 1, NULL
) ;
295 if ( handle
== NULL
)
297 set_err_message(TSD
, "load() failed: ", strerror( errno
)) ;
301 int rc
=loadbind( 0, (void *)wrapper_dummy_for_aix
, (void *)handle
) ;
305 set_err_message(TSD
, "loadbind() failed: ", strerror( errno
)) ;
308 #elif defined(DYNAMIC_OS2)
309 rc
= DosLoadModule( LoadError
, sizeof(LoadError
),
310 file_name
, &handle
) ;
313 set_err_message(TSD
, "DosLoadModule() unable to load DLL: ", LoadError
);
314 handle
= (handle_type
)NULL
;
316 #elif defined(DYNAMIC_WIN32)
317 handle
= LoadLibrary( file_name
) ;
321 FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM
, NULL
, GetLastError(), MAKELANGID( LANG_NEUTRAL
, SUBLANG_DEFAULT
), LoadError
, 256, NULL
) ;
322 sprintf( buf
, "Failed to load \"%s\" library: LoadLibrary() failed: ", file_name
);
323 set_err_message(TSD
, buf
, LoadError
);
325 #elif defined(DYNAMIC_BEOS)
326 handle
= load_add_on( orig_module
);
327 if (handle
< B_NO_ERROR
)
329 handle
= load_add_on( file_name
);
330 if (handle
< B_NO_ERROR
)
332 sprintf( buf
, "load_add_on() failed loading \"%s\" with error:", file_name
);
333 set_err_message(TSD
, buf
, strerror( handle
) );
334 handle
= (handle_type
)NULL
;
337 #elif defined(DYNAMIC_SKYOS)
338 handle
= (handle_type
)MallocTSD( sizeof( sDllHandle
) );
340 * Don't try and load the module without the trimmings.
341 * You get a binary popup window otherwise!
343 fprintf(stderr
,"%s %d %x %s:\n",__FILE__
,__LINE__
,handle
,file_name
);
344 if ( DllLoad( file_name
, &tmp_handle
) != 0 )
347 sprintf( buf
, "Failed to load \"%s\" library: DllLoad() failed: ", file_name
);
348 set_err_message(TSD
, buf
, strerror( errno
) );
350 handle
= (handle_type
)NULL
;
352 fprintf(stderr
,"%s %d:\n",__FILE__
,__LINE__
);
353 memcpy( handle
, &tmp_handle
, sizeof( sDllHandle
) );
354 fprintf(stderr
,"%s %d:\n",__FILE__
,__LINE__
);
357 FreeTSD( module_name
);
358 FreeTSD( orig_module
);
360 return (void *)handle
;
363 void wrapper_unload( const tsd_t
*TSD
, void *libhandle
)
365 #ifdef DYNAMIC_STATIC
367 libhandle
= libhandle
;
369 #elif defined(DYNAMIC_DLOPEN)
371 dlclose((handle_type
) libhandle
);
373 #elif defined(DYNAMIC_HPSHLOAD)
375 shl_unload((handle_type
) libhandle
);
377 #elif defined(DYNAMIC_AIXLOAD)
379 unload((handle_type
) libhandle
);
381 #elif defined(DYNAMIC_OS2)
383 DosFreeModule((handle_type
) libhandle
);
385 #elif defined(DYNAMIC_WIN32)
387 FreeLibrary((handle_type
) libhandle
);
389 #elif defined(DYNAMIC_BEOS)
391 unload_add_on((handle_type
) libhandle
);
393 #elif defined(DYNAMIC_SKYOS)
395 fprintf(stderr
,"%s %d:\n",__FILE__
,__LINE__
);
396 FreeTSD( libhandle
);
399 (libhandle
= libhandle
);
403 PFN
wrapper_get_addr( const tsd_t
*TSD
, const struct library
*lptr
, const streng
*name
)
406 handle_type handle
=(handle_type
)lptr
->handle
;
408 #if defined(DYNAMIC_WIN32)
414 #if defined(DYNAMIC_OS2)
421 #if defined(DYNAMIC_BEOS)
424 #if defined(DYNAMIC_STATIC)
427 #if defined(MODULES_NEED_USCORE)
431 funcname
= str_of( TSD
, name
) ;
433 #if defined(DYNAMIC_STATIC)
434 rc
= static_dlsym( handle
, funcname
,(void **)&addr
);
438 sprintf(buf
,"static_dlsym() failed with %d looking for %s", rc
, funcname
);
439 set_err_message(TSD
, buf
, "" ) ;
442 #elif defined(DYNAMIC_DLOPEN)
443 # if defined(MODULES_NEED_USCORE)
445 * Some platforms need to have an underscore prepended to the function
446 * name to be found in a loadable module.
449 us_func
= Str_makeTSD( Str_len( name
) + 1 );
450 memcpy( us_func
->value
, "_", 1 );
452 Str_catTSD( us_func
, name
);
453 funcname
= str_of( TSD
, us_func
);
454 Free_stringTSD( us_func
);
457 * Note, the following assignment is not allowed by ANSI, but SVR4.2
458 * includes it as an example, so it is probably safe in this context
460 addr
= (PFN
)(dlsym( handle
, funcname
)) ;
462 /* deal with, eg 'SysLoadFuncs' when the function is 'sysloadfuncs' or 'SYSLOADFUNCS' */
465 mem_upper( funcname
, strlen( funcname
) );
466 addr
= (PFN
)(dlsym( handle
, funcname
)) ;
470 mem_lower( funcname
, strlen( funcname
) );
471 addr
= (PFN
)(dlsym( handle
, funcname
)) ;
474 set_err_message( TSD
, "dlsym() failed: ", dlerror() );
478 #elif defined(DYNAMIC_HPSHLOAD)
483 if (rc
= shl_findsym( &handle
, funcname
, TYPE_PROCEDURE
, &eaddr
))
485 mem_upper( funcname
, strlen( funcname
) );
486 if (rc
= shl_findsym( &handle
, funcname
, TYPE_PROCEDURE
, &eaddr
))
488 mem_lower( funcname
, strlen( funcname
) );
489 if (rc
= shl_findsym( &handle
, funcname
, TYPE_PROCEDURE
, &eaddr
))
492 set_err_message( TSD
, "shl_findsym() failed: ", strerror(errno
) );
501 #elif defined(DYNAMIC_AIXLOAD)
504 #elif defined(DYNAMIC_OS2)
505 if ( ( sscanf( funcname
, "#%u%c", &u
, &c
) == 1 ) && ( u
!= 0 ) )
513 entryname
= funcname
;
515 rc
= DosQueryProcAddr(handle
,ordinal
,entryname
,&addr
);
518 mem_upper( entryname
, strlen( entryname
) );
519 rc
= DosQueryProcAddr(handle
,ordinal
,entryname
,&addr
);
522 mem_lower( entryname
, strlen( entryname
) );
523 rc
= DosQueryProcAddr(handle
,ordinal
,entryname
,&addr
);
527 sprintf(buf
,"DosQueryProcAddr() failed with %lu looking for %.90s", (long) rc
, funcname
);
528 set_err_message(TSD
, buf
, "" ) ;
533 #elif defined(DYNAMIC_WIN32)
534 /* 13/12/1999 JH moved cast, (HMODULE), from second parm to first. Removed
535 * a compiler warning,
537 if ( ( sscanf( funcname
, "#%u%c", &u
, &c
) == 1 ) && ( u
!= 0 ) &&
539 entryname
= (char *) u
;
541 entryname
= funcname
;
543 addr
= (PFN
) GetProcAddress( (HMODULE
) handle
, entryname
);
545 if ( ( addr
== NULL
) && ( funcname
== entryname
) )
548 addr
= (PFN
)GetProcAddress((HMODULE
)handle
,funcname
);
553 addr
= (PFN
)GetProcAddress((HMODULE
)handle
, funcname
);
559 FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM
, NULL
, GetLastError(), MAKELANGID( LANG_NEUTRAL
, SUBLANG_DEFAULT
), LoadError
, 256, NULL
);
560 sprintf( buf
, "Failed to find \"%s\" in external library: GetProcAddress() failed: ", funcname
);
561 set_err_message( TSD
, buf
, LoadError
);
564 #elif defined(DYNAMIC_BEOS)
565 rc
= get_image_symbol(handle
,funcname
,B_SYMBOL_TYPE_TEXT
,(void **)&addr
);
566 if (rc
== B_BAD_IMAGE_ID
)
569 sprintf(buf
,"get_image_symbol() failed with %d looking for %s", rc
, funcname
);
570 set_err_message( TSD
, buf
, "" );
574 #elif defined(DYNAMIC_SKYOS)
575 fprintf(stderr
,"%s %d:\n",__FILE__
,__LINE__
);
576 addr
= (PFN
)GetDllFunction( handle
, funcname
);
580 sprintf(buf
,"GetDllFunction() failed looking for %s", funcname
);
581 set_err_message( TSD
, buf
, "" );
584 fprintf(stderr
,"%s %d:\n",__FILE__
,__LINE__
);
596 * Required as entry point for DLL under SkyOS