dlSharedLibraryLoader.cpp

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

Generated on Fri Jun 16 15:39:08 2006 for blocxx by  doxygen 1.4.6