blocxx
|
00001 /******************************************************************************* 00002 * Copyright (C) 2005, Vintela, Inc. All rights reserved. 00003 * Copyright (C) 2006, Novell, Inc. All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions are met: 00007 * 00008 * * Redistributions of source code must retain the above copyright notice, 00009 * this list of conditions and the following disclaimer. 00010 * * Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * * Neither the name of 00014 * Vintela, Inc., 00015 * nor Novell, Inc., 00016 * nor the names of its contributors or employees may be used to 00017 * endorse or promote products derived from this software without 00018 * specific prior written permission. 00019 * 00020 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00021 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00022 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00023 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 00024 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00025 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00026 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00027 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00028 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00029 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00030 * POSSIBILITY OF SUCH DAMAGE. 00031 *******************************************************************************/ 00032 00033 00038 #include "blocxx/BLOCXX_config.h" 00039 #if defined(BLOCXX_USE_DL) 00040 #include "blocxx/dlSharedLibraryLoader.hpp" 00041 #include "blocxx/dlSharedLibrary.hpp" 00042 #include "blocxx/Format.hpp" 00043 #include "blocxx/GlobalString.hpp" 00044 #include <dlfcn.h> 00045 00046 namespace BLOCXX_NAMESPACE 00047 { 00048 00049 namespace 00050 { 00051 GlobalString COMPONENT_NAME = BLOCXX_GLOBAL_STRING_INIT("blocxx.dlSharedLibraryLoader"); 00052 } 00054 SharedLibraryRef 00055 dlSharedLibraryLoader::loadSharedLibrary(const String& filename) const 00056 { 00057 // There is a reason to use RTLD_NOW. If some symbols can't be resolved because 00058 // the shared library is built incorrectly or missing some symbols or something, 00059 // then using RTLD_NOW will cause dlopen() to fail, and then the error can be detected 00060 // and handled. If RTLD_LAZY is specified, dlopen() won't fail, but when code is 00061 // executed that tries to use an unresolvable symbol, that will cause a segfault. 00062 // RTLD_GLOBAL is necessary for proper exception and rtti support with gcc. 00063 // See http://gcc.gnu.org/faq.html#dso, so even though it may cause symbol conflicts, 00064 // we have to live with it. 00065 void* libhandle = dlopen(filename.c_str(), RTLD_NOW | RTLD_GLOBAL); 00066 00067 String first_error = dlerror(); 00068 String second_error; 00069 00070 #if defined(BLOCXX_USE_FAKE_LIBS) 00071 // This section, if it determines that a library is fake, will attempt 00072 // to load NULL (which, on most dlopen platforms should return a handle 00073 // to the main executable). This handle can be used just like any 00074 // other, assuming that the main executable was linked with the proper 00075 // export flags (--export-dynamic on linux, -bexpall on AIX, etc.). 00076 if ( !libhandle ) 00077 { 00078 if ( dlSharedLibrary::isFakeLibrary(filename) ) 00079 { 00080 libhandle = dlopen(NULL, RTLD_NOW | RTLD_GLOBAL); 00081 00082 if ( !libhandle ) 00083 { 00084 second_error = dlerror(); 00085 } 00086 } 00087 } 00088 #endif /* defined(BLOCXX_USE_FAKE_LIBS) */ 00089 if (libhandle) 00090 { 00091 return SharedLibraryRef( new dlSharedLibrary(libhandle, 00092 filename)); 00093 } 00094 else 00095 { 00096 Logger logger(COMPONENT_NAME); 00097 BLOCXX_LOG_ERROR(logger, Format("dlSharedLibraryLoader::loadSharedLibrary " 00098 "dlopen returned NULL. Error is: %1", first_error)); 00099 if ( !second_error.empty() ) 00100 { 00101 BLOCXX_LOG_ERROR(logger, Format("dlSharedLibraryLoader::loadSharedLibrary (fakelib) " 00102 "dlopen returned NULL. Error is: %1", second_error)); 00103 } 00104 return SharedLibraryRef( 0 ); 00105 } 00106 } 00107 00109 SharedLibraryLoaderRef 00110 SharedLibraryLoader::createSharedLibraryLoader() 00111 { 00112 return SharedLibraryLoaderRef(new dlSharedLibraryLoader); 00113 } 00115 dlSharedLibraryLoader::~dlSharedLibraryLoader() 00116 { 00117 } 00118 00119 } // end namespace BLOCXX_NAMESPACE 00120 00121 #endif // BLOCXX_USE_DL