Initial commit.
[CMakeLuaTailorHgBridge.git] / CMakeLua / Source / kwsys / DynamicLoader.cxx
blob1aac58c2a524d309f2d60aafe24834cda6c25478
1 /*=========================================================================
3 Program: KWSys - Kitware System Library
4 Module: $RCSfile: DynamicLoader.cxx,v $
6 Copyright (c) Kitware, Inc., Insight Consortium. All rights reserved.
7 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 This software is distributed WITHOUT ANY WARRANTY; without even
10 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11 PURPOSE. See the above copyright notices for more information.
13 =========================================================================*/
14 #include "kwsysPrivate.h"
15 #include KWSYS_HEADER(DynamicLoader.hxx)
17 #include KWSYS_HEADER(Configure.hxx)
19 // Work-around CMake dependency scanning limitation. This must
20 // duplicate the above list of headers.
21 #if 0
22 # include "DynamicLoader.hxx.in"
23 # include "Configure.hxx.in"
24 #endif
26 // This file is actually 3 different implementations.
27 // 1. HP machines which uses shl_load
28 // 2. Mac OS X 10.2.x and earlier which uses NSLinkModule
29 // 3. Windows which uses LoadLibrary
30 // 4. Most unix systems (including Mac OS X 10.3 and later) which use dlopen
31 // (default) Each part of the ifdef contains a complete implementation for
32 // the static methods of DynamicLoader.
34 // ---------------------------------------------------------------
35 // 1. Implementation for HPUX machines
36 #ifdef __hpux
37 #include <errno.h>
38 #include <dl.h>
39 #define DYNAMICLOADER_DEFINED 1
41 namespace KWSYS_NAMESPACE
44 //----------------------------------------------------------------------------
45 DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const char* libname )
47 return shl_load(libname, BIND_DEFERRED | DYNAMIC_PATH, 0L);
50 //----------------------------------------------------------------------------
51 int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
53 return !shl_unload(lib);
56 //----------------------------------------------------------------------------
57 DynamicLoader::SymbolPointer
58 DynamicLoader::GetSymbolAddress(DynamicLoader::LibraryHandle lib, const char* sym)
60 void* addr;
61 int status;
63 /* TYPE_PROCEDURE Look for a function or procedure. (This used to be default)
64 * TYPE_DATA Look for a symbol in the data segment (for example, variables).
65 * TYPE_UNDEFINED Look for any symbol.
67 status = shl_findsym (&lib, sym, TYPE_UNDEFINED, &addr);
68 void* result = (status < 0) ? (void*)0 : addr;
70 // Hack to cast pointer-to-data to pointer-to-function.
71 return *reinterpret_cast<DynamicLoader::SymbolPointer*>(&result);
74 //----------------------------------------------------------------------------
75 const char* DynamicLoader::LibPrefix()
77 return "lib";
80 //----------------------------------------------------------------------------
81 const char* DynamicLoader::LibExtension()
83 return ".sl";
86 //----------------------------------------------------------------------------
87 const char* DynamicLoader::LastError()
89 // TODO: Need implementation with errno/strerror
90 /* If successful, shl_findsym returns an integer (int) value zero. If
91 * shl_findsym cannot find sym, it returns -1 and sets errno to zero.
92 * If any other errors occur, shl_findsym returns -1 and sets errno to one
93 * of these values (defined in <errno.h>):
94 * ENOEXEC
95 * A format error was detected in the specified library.
96 * ENOSYM
97 * A symbol on which sym depends could not be found.
98 * EINVAL
99 * The specified handle is invalid.
102 if( errno == ENOEXEC
103 || errno == ENOSYM
104 || errno == EINVAL )
106 return strerror(errno);
108 // else
109 return 0;
112 } // namespace KWSYS_NAMESPACE
114 #endif //__hpux
117 // ---------------------------------------------------------------
118 // 2. Implementation for Mac OS X 10.2.x and earlier
119 #ifdef __APPLE__
120 #if MAC_OS_X_VERSION_MAX_ALLOWED < 1030
121 #include <string.h> // for strlen
122 #include <mach-o/dyld.h>
123 #define DYNAMICLOADER_DEFINED 1
125 namespace KWSYS_NAMESPACE
128 //----------------------------------------------------------------------------
129 DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const char* libname )
131 NSObjectFileImageReturnCode rc;
132 NSObjectFileImage image = 0;
134 rc = NSCreateObjectFileImageFromFile(libname, &image);
135 // rc == NSObjectFileImageInappropriateFile when trying to load a dylib file
136 if( rc != NSObjectFileImageSuccess )
138 return 0;
140 NSModule handle = NSLinkModule(image, libname,
141 NSLINKMODULE_OPTION_BINDNOW|NSLINKMODULE_OPTION_RETURN_ON_ERROR);
142 NSDestroyObjectFileImage(image);
143 return handle;
146 //----------------------------------------------------------------------------
147 int DynamicLoader::CloseLibrary( DynamicLoader::LibraryHandle lib)
149 // NSUNLINKMODULE_OPTION_KEEP_MEMORY_MAPPED
150 // With this option the memory for the module is not deallocated
151 // allowing pointers into the module to still be valid.
152 // You should use this option instead if your code experience some problems
153 // reported against Panther 10.3.9 (fixed in Tiger 10.4.2 and up)
154 bool success = NSUnLinkModule(lib, NSUNLINKMODULE_OPTION_NONE);
155 return success;
158 //----------------------------------------------------------------------------
159 DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
160 DynamicLoader::LibraryHandle lib, const char* sym)
162 void *result=0;
163 // Need to prepend symbols with '_' on Apple-gcc compilers
164 size_t len = strlen(sym);
165 char *rsym = new char[len + 1 + 1];
166 strcpy(rsym, "_");
167 strcat(rsym+1, sym);
169 NSSymbol symbol = NSLookupSymbolInModule(lib, rsym);
170 if(symbol)
172 result = NSAddressOfSymbol(symbol);
175 delete[] rsym;
176 // Hack to cast pointer-to-data to pointer-to-function.
177 return *reinterpret_cast<DynamicLoader::SymbolPointer*>(&result);
180 //----------------------------------------------------------------------------
181 const char* DynamicLoader::LibPrefix()
183 return "lib";
186 //----------------------------------------------------------------------------
187 const char* DynamicLoader::LibExtension()
189 // NSCreateObjectFileImageFromFile fail when dealing with dylib image
190 // it returns NSObjectFileImageInappropriateFile
191 //return ".dylib";
192 return ".so";
195 //----------------------------------------------------------------------------
196 const char* DynamicLoader::LastError()
198 return 0;
201 } // namespace KWSYS_NAMESPACE
203 #endif // MAC_OS_X_VERSION_MAX_ALLOWED < 1030
204 #endif // __APPLE__
206 // ---------------------------------------------------------------
207 // 3. Implementation for Windows win32 code but not cygwin
208 #if defined(_WIN32) && !defined(__CYGWIN__)
209 #include <windows.h>
210 #define DYNAMICLOADER_DEFINED 1
212 namespace KWSYS_NAMESPACE
215 //----------------------------------------------------------------------------
216 DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const char* libname)
218 DynamicLoader::LibraryHandle lh;
219 #ifdef UNICODE
220 wchar_t libn[MB_CUR_MAX];
221 mbstowcs(libn, libname, MB_CUR_MAX);
222 lh = LoadLibrary(libn);
223 #else
224 lh = LoadLibrary(libname);
225 #endif
226 return lh;
229 //----------------------------------------------------------------------------
230 int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
232 return (int)FreeLibrary(lib);
235 //----------------------------------------------------------------------------
236 DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
237 DynamicLoader::LibraryHandle lib, const char* sym)
239 // TODO: The calling convention affects the name of the symbol. We
240 // should have a tool to help get the symbol with the desired
241 // calling convention. Currently we assume cdecl.
243 // Borland:
244 // __cdecl = "_func" (default)
245 // __fastcall = "@_func"
246 // __stdcall = "func"
248 // Watcom:
249 // __cdecl = "_func"
250 // __fastcall = "@_func@X"
251 // __stdcall = "_func@X"
252 // __watcall = "func_" (default)
254 // MSVC:
255 // __cdecl = "func" (default)
256 // __fastcall = "@_func@X"
257 // __stdcall = "_func@X"
259 // Note that the "@X" part of the name above is the total size (in
260 // bytes) of the arguments on the stack.
261 void *result;
262 #if defined(__BORLANDC__) || defined(__WATCOMC__)
263 // Need to prepend symbols with '_'
264 size_t len = strlen(sym);
265 char *rsym = new char[len + 1 + 1];
266 strcpy(rsym, "_");
267 strcat(rsym, sym);
268 #else
269 const char *rsym = sym;
270 #endif
271 #ifdef UNICODE
272 wchar_t wsym[MB_CUR_MAX];
273 mbstowcs(wsym, rsym, MB_CUR_MAX);
274 result = GetProcAddress(lib, wsym);
275 #else
276 result = (void*)GetProcAddress(lib, rsym);
277 #endif
278 #if defined(__BORLANDC__) || defined(__WATCOMC__)
279 delete[] rsym;
280 #endif
281 // Hack to cast pointer-to-data to pointer-to-function.
282 #ifdef __WATCOMC__
283 return *(DynamicLoader::SymbolPointer*)(&result);
284 #else
285 return *reinterpret_cast<DynamicLoader::SymbolPointer*>(&result);
286 #endif
289 //----------------------------------------------------------------------------
290 const char* DynamicLoader::LibPrefix()
292 #ifdef __MINGW32__
293 return "lib";
294 #else
295 return "";
296 #endif
299 //----------------------------------------------------------------------------
300 const char* DynamicLoader::LibExtension()
302 return ".dll";
305 //----------------------------------------------------------------------------
306 const char* DynamicLoader::LastError()
308 LPVOID lpMsgBuf;
310 FormatMessage(
311 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
312 NULL,
313 GetLastError(),
314 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
315 (LPTSTR) &lpMsgBuf,
317 NULL
320 static char* str = 0;
321 delete [] str;
322 str = strcpy(new char[strlen((char*)lpMsgBuf)+1], (char*)lpMsgBuf);
323 // Free the buffer.
324 LocalFree( lpMsgBuf );
325 return str;
328 } // namespace KWSYS_NAMESPACE
330 #endif //_WIN32
332 // ---------------------------------------------------------------
333 // 4. Implementation for BeOS
334 #ifdef __BEOS__
335 #include <string.h> // for strerror()
336 #include <be/kernel/image.h>
337 #include <be/support/Errors.h>
338 #define DYNAMICLOADER_DEFINED 1
340 namespace KWSYS_NAMESPACE
343 static image_id last_dynamic_err = B_OK;
345 //----------------------------------------------------------------------------
346 DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const char* libname )
348 // image_id's are integers, errors are negative. Add one just in case we
349 // get a valid image_id of zero (is that even possible?).
350 image_id rc = load_add_on(libname);
351 if (rc < 0)
353 last_dynamic_err = rc;
354 return 0;
357 return rc+1;
360 //----------------------------------------------------------------------------
361 int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
363 if (!lib)
365 last_dynamic_err = B_BAD_VALUE;
366 return 0;
368 else
370 // The function dlclose() returns 0 on success, and non-zero on error.
371 status_t rc = unload_add_on(lib-1);
372 if (rc != B_OK)
374 last_dynamic_err = rc;
375 return 0;
379 return 1;
382 //----------------------------------------------------------------------------
383 DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
384 DynamicLoader::LibraryHandle lib, const char* sym)
386 // Hack to cast pointer-to-data to pointer-to-function.
387 union
389 void* pvoid;
390 DynamicLoader::SymbolPointer psym;
391 } result;
393 result.psym = NULL;
395 if (!lib)
397 last_dynamic_err = B_BAD_VALUE;
399 else
401 // !!! FIXME: BeOS can do function-only lookups...does this ever
402 // !!! FIXME: actually _want_ a data symbol lookup, or was this union
403 // !!! FIXME: a leftover of dlsym()? (s/ANY/TEXT for functions only).
404 status_t rc = get_image_symbol(lib-1,sym,B_SYMBOL_TYPE_ANY,&result.pvoid);
405 if (rc != B_OK)
407 last_dynamic_err = rc;
408 result.psym = NULL;
411 return result.psym;
414 //----------------------------------------------------------------------------
415 const char* DynamicLoader::LibPrefix()
417 return "lib";
420 //----------------------------------------------------------------------------
421 const char* DynamicLoader::LibExtension()
423 return ".so";
426 //----------------------------------------------------------------------------
427 const char* DynamicLoader::LastError()
429 const char *retval = strerror(last_dynamic_err);
430 last_dynamic_err = B_OK;
431 return retval;
434 } // namespace KWSYS_NAMESPACE
435 #endif
437 // ---------------------------------------------------------------
438 // 5. Implementation for systems without dynamic libs
439 // __gnu_blrts__ is IBM BlueGene/L
440 // __LIBCATAMOUNT__ is defined on Catamount on Cray compute nodes
441 #if defined(__gnu_blrts__) || defined(__LIBCATAMOUNT__)
442 #include <string.h> // for strerror()
443 #define DYNAMICLOADER_DEFINED 1
445 namespace KWSYS_NAMESPACE
448 //----------------------------------------------------------------------------
449 DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const char* libname )
451 return 0;
454 //----------------------------------------------------------------------------
455 int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
457 if (!lib)
459 return 0;
462 return 1;
465 //----------------------------------------------------------------------------
466 DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
467 DynamicLoader::LibraryHandle lib, const char* sym)
469 return 0;
472 //----------------------------------------------------------------------------
473 const char* DynamicLoader::LibPrefix()
475 return "lib";
478 //----------------------------------------------------------------------------
479 const char* DynamicLoader::LibExtension()
481 return ".a";
484 //----------------------------------------------------------------------------
485 const char* DynamicLoader::LastError()
487 return "General error";
490 } // namespace KWSYS_NAMESPACE
491 #endif
493 // ---------------------------------------------------------------
494 // 6. Implementation for default UNIX machines.
495 // if nothing has been defined then use this
496 #ifndef DYNAMICLOADER_DEFINED
497 #define DYNAMICLOADER_DEFINED 1
498 // Setup for most unix machines
499 #include <dlfcn.h>
501 namespace KWSYS_NAMESPACE
504 //----------------------------------------------------------------------------
505 DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const char* libname )
507 return dlopen(libname, RTLD_LAZY);
510 //----------------------------------------------------------------------------
511 int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
513 if (lib)
515 // The function dlclose() returns 0 on success, and non-zero on error.
516 return !dlclose(lib);
518 // else
519 return 0;
522 //----------------------------------------------------------------------------
523 DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
524 DynamicLoader::LibraryHandle lib, const char* sym)
526 // Hack to cast pointer-to-data to pointer-to-function.
527 union
529 void* pvoid;
530 DynamicLoader::SymbolPointer psym;
531 } result;
532 result.pvoid = dlsym(lib, sym);
533 return result.psym;
536 //----------------------------------------------------------------------------
537 const char* DynamicLoader::LibPrefix()
539 return "lib";
542 //----------------------------------------------------------------------------
543 const char* DynamicLoader::LibExtension()
545 #ifdef __CYGWIN__
546 return ".dll";
547 #else
548 return ".so";
549 #endif
552 //----------------------------------------------------------------------------
553 const char* DynamicLoader::LastError()
555 return dlerror();
558 } // namespace KWSYS_NAMESPACE
560 #endif