Resync
[CMakeLuaTailorHgBridge.git] / CMakeLua / Source / kwsys / DynamicLoader.cxx
blob6d0671d9440fbabfa89b7ef48c647d0160dae5a5
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=NULL;
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 if(!lpMsgBuf)
322 return NULL;
325 static char* str = 0;
326 delete [] str;
327 str = strcpy(new char[strlen((char*)lpMsgBuf)+1], (char*)lpMsgBuf);
328 // Free the buffer.
329 LocalFree( lpMsgBuf );
330 return str;
333 } // namespace KWSYS_NAMESPACE
335 #endif //_WIN32
337 // ---------------------------------------------------------------
338 // 4. Implementation for BeOS
339 #if defined __BEOS__
341 #include <string.h> // for strerror()
343 #include <be/kernel/image.h>
344 #include <be/support/Errors.h>
346 #define DYNAMICLOADER_DEFINED 1
348 namespace KWSYS_NAMESPACE
351 static image_id last_dynamic_err = B_OK;
353 //----------------------------------------------------------------------------
354 DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const char* libname )
356 // image_id's are integers, errors are negative. Add one just in case we
357 // get a valid image_id of zero (is that even possible?).
358 image_id rc = load_add_on(libname);
359 if (rc < 0)
361 last_dynamic_err = rc;
362 return 0;
365 return rc+1;
368 //----------------------------------------------------------------------------
369 int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
371 if (!lib)
373 last_dynamic_err = B_BAD_VALUE;
374 return 0;
376 else
378 // The function dlclose() returns 0 on success, and non-zero on error.
379 status_t rc = unload_add_on(lib-1);
380 if (rc != B_OK)
382 last_dynamic_err = rc;
383 return 0;
387 return 1;
390 //----------------------------------------------------------------------------
391 DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
392 DynamicLoader::LibraryHandle lib, const char* sym)
394 // Hack to cast pointer-to-data to pointer-to-function.
395 union
397 void* pvoid;
398 DynamicLoader::SymbolPointer psym;
399 } result;
401 result.psym = NULL;
403 if (!lib)
405 last_dynamic_err = B_BAD_VALUE;
407 else
409 // !!! FIXME: BeOS can do function-only lookups...does this ever
410 // !!! FIXME: actually _want_ a data symbol lookup, or was this union
411 // !!! FIXME: a leftover of dlsym()? (s/ANY/TEXT for functions only).
412 status_t rc = get_image_symbol(lib-1,sym,B_SYMBOL_TYPE_ANY,&result.pvoid);
413 if (rc != B_OK)
415 last_dynamic_err = rc;
416 result.psym = NULL;
419 return result.psym;
422 //----------------------------------------------------------------------------
423 const char* DynamicLoader::LibPrefix()
425 return "lib";
428 //----------------------------------------------------------------------------
429 const char* DynamicLoader::LibExtension()
431 return ".so";
434 //----------------------------------------------------------------------------
435 const char* DynamicLoader::LastError()
437 const char *retval = strerror(last_dynamic_err);
438 last_dynamic_err = B_OK;
439 return retval;
442 } // namespace KWSYS_NAMESPACE
443 #endif
445 // ---------------------------------------------------------------
446 // 5. Implementation for systems without dynamic libs
447 // __gnu_blrts__ is IBM BlueGene/L
448 // __LIBCATAMOUNT__ is defined on Catamount on Cray compute nodes
449 #if defined(__gnu_blrts__) || defined(__LIBCATAMOUNT__)
450 #include <string.h> // for strerror()
451 #define DYNAMICLOADER_DEFINED 1
453 namespace KWSYS_NAMESPACE
456 //----------------------------------------------------------------------------
457 DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const char* libname )
459 return 0;
462 //----------------------------------------------------------------------------
463 int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
465 if (!lib)
467 return 0;
470 return 1;
473 //----------------------------------------------------------------------------
474 DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
475 DynamicLoader::LibraryHandle lib, const char* sym)
477 return 0;
480 //----------------------------------------------------------------------------
481 const char* DynamicLoader::LibPrefix()
483 return "lib";
486 //----------------------------------------------------------------------------
487 const char* DynamicLoader::LibExtension()
489 return ".a";
492 //----------------------------------------------------------------------------
493 const char* DynamicLoader::LastError()
495 return "General error";
498 } // namespace KWSYS_NAMESPACE
499 #endif
501 // ---------------------------------------------------------------
502 // 6. Implementation for default UNIX machines.
503 // if nothing has been defined then use this
504 #ifndef DYNAMICLOADER_DEFINED
505 #define DYNAMICLOADER_DEFINED 1
506 // Setup for most unix machines
507 #include <dlfcn.h>
509 namespace KWSYS_NAMESPACE
512 //----------------------------------------------------------------------------
513 DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const char* libname )
515 return dlopen(libname, RTLD_LAZY);
518 //----------------------------------------------------------------------------
519 int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
521 if (lib)
523 // The function dlclose() returns 0 on success, and non-zero on error.
524 return !dlclose(lib);
526 // else
527 return 0;
530 //----------------------------------------------------------------------------
531 DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
532 DynamicLoader::LibraryHandle lib, const char* sym)
534 // Hack to cast pointer-to-data to pointer-to-function.
535 union
537 void* pvoid;
538 DynamicLoader::SymbolPointer psym;
539 } result;
540 result.pvoid = dlsym(lib, sym);
541 return result.psym;
544 //----------------------------------------------------------------------------
545 const char* DynamicLoader::LibPrefix()
547 return "lib";
550 //----------------------------------------------------------------------------
551 const char* DynamicLoader::LibExtension()
553 #ifdef __CYGWIN__
554 return ".dll";
555 #else
556 return ".so";
557 #endif
560 //----------------------------------------------------------------------------
561 const char* DynamicLoader::LastError()
563 return dlerror();
566 } // namespace KWSYS_NAMESPACE
568 #endif