00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00037 #include "blocxx/BLOCXX_config.h"
00038 #if defined(BLOCXX_USE_DL)
00039 #include "blocxx/dlSharedLibrary.hpp"
00040 #include "blocxx/Format.hpp"
00041 #include "blocxx/Mutex.hpp"
00042 #include "blocxx/MutexLock.hpp"
00043 #include <dlfcn.h>
00044
00045 #include "blocxx/Types.hpp"
00046
00047 #if defined(BLOCXX_USE_FAKE_LIBS)
00048
00049 #include "blocxx/FileSystem.hpp"
00050 #include "blocxx/File.hpp"
00051 #include "blocxx/Array.hpp"
00052
00053 #define BLOCXX_FAKELIB_HEADING "FAKE"
00054 #define BLOCXX_FAKELIB_HEADING_LENGTH 4
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00068 #endif
00069
00070 #include <iostream>
00071
00072 namespace BLOCXX_NAMESPACE
00073 {
00074
00075
00076 bool dlSharedLibrary::s_call_dlclose = true;
00077
00078 Mutex dlSharedLibrary_guard;
00079
00080 dlSharedLibrary::dlSharedLibrary(void * libhandle, const String& libName)
00081 : SharedLibrary(), m_libhandle( libhandle ), m_libName(libName)
00082 {
00083 #if defined(BLOCXX_USE_FAKE_LIBS)
00084
00085 m_fakeLibrary = dlSharedLibrary::isFakeLibrary(libName);
00086
00087 if ( m_fakeLibrary )
00088 {
00089 initializeSymbolMap();
00090 }
00091 #endif
00092 }
00093
00094 dlSharedLibrary::~dlSharedLibrary()
00095 {
00096 #if !defined(BLOCXX_VALGRIND_SUPPORT) // dlclose()ing shared libs make it impossible to see where memory leaks occurred with valgrind.
00097 if (s_call_dlclose)
00098 {
00099 dlclose( m_libhandle );
00100 }
00101 #endif
00102 }
00103 bool dlSharedLibrary::doGetFunctionPointer(const String& functionName,
00104 void** fp) const
00105 {
00106 MutexLock l(dlSharedLibrary_guard);
00107 #if defined(BLOCXX_USE_FAKE_LIBS)
00108 String realFunctionName = functionName;
00109
00110
00111 if ( m_fakeLibrary )
00112 {
00113 Map<String,String>::const_iterator symIter = m_symbolMap.find(functionName);
00114 if ( symIter == m_symbolMap.end() )
00115 {
00116 return false;
00117 }
00118 realFunctionName = symIter->second;
00119 }
00120 *fp = dlsym( m_libhandle, realFunctionName.c_str() );
00121 #else
00122 *fp = dlsym( m_libhandle, functionName.c_str() );
00123 #endif
00124
00125 if (!*fp)
00126 {
00127 return false;
00128 }
00129 return true;
00130 }
00131
00132 bool dlSharedLibrary::isFakeLibrary(const String& library_path)
00133 {
00134 #if defined(BLOCXX_USE_FAKE_LIBS)
00135 if ( FileSystem::canRead(library_path) )
00136 {
00137
00138
00139 File libfile = FileSystem::openFile(library_path);
00140
00141 if ( libfile )
00142 {
00143 char buffer[(BLOCXX_FAKELIB_HEADING_LENGTH) + 1];
00144 size_t num_read = libfile.read(buffer,(BLOCXX_FAKELIB_HEADING_LENGTH));
00145 if ( num_read == (BLOCXX_FAKELIB_HEADING_LENGTH) )
00146 {
00147
00148 buffer[BLOCXX_FAKELIB_HEADING_LENGTH] = '\0';
00149 if ( String(BLOCXX_FAKELIB_HEADING) == buffer )
00150 {
00151
00152 return true;
00153 }
00154 }
00155 }
00156 }
00157 #endif
00158 return false;
00159 }
00160
00161 #if defined(BLOCXX_USE_FAKE_LIBS)
00162 void dlSharedLibrary::initializeSymbolMap()
00163 {
00164 if ( ! m_fakeLibrary )
00165 {
00166 return;
00167 }
00168
00169
00170
00171 StringArray lines = FileSystem::getFileLines(m_libName);
00172
00173 for ( StringArray::const_iterator iter = lines.begin();
00174 iter != lines.end();
00175 ++iter )
00176 {
00177
00178 if ( iter->startsWith('#') )
00179 {
00180 continue;
00181 }
00182 StringArray current_line = iter->tokenize("=");
00183
00184 if ( current_line.size() != 2 )
00185 {
00186 continue;
00187 }
00188
00189 String option = String(current_line[0]).trim();
00190 String value = String(current_line[1]).trim();
00191 m_symbolMap[option] = value;
00192 }
00193 }
00194 #endif
00195
00196 }
00197
00198 #endif
00199