WvStreams
|
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- 00002 * 00003 * XPLC - Cross-Platform Lightweight Components 00004 * Copyright (C) 2002, Net Integration Technologies, Inc. 00005 * Copyright (C) 2002-2004, Pierre Phaneuf 00006 * Copyright (C) 2002-2004, Stéphane Lajoie 00007 * 00008 * This library is free software; you can redistribute it and/or 00009 * modify it under the terms of the GNU Lesser General Public License 00010 * as published by the Free Software Foundation; either version 2.1 of 00011 * the License, or (at your option) any later version. 00012 * 00013 * This library is distributed in the hope that it will be useful, but 00014 * WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 * Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public 00019 * License along with this library; if not, write to the Free Software 00020 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00021 * USA 00022 */ 00023 00024 #include <stdlib.h> 00025 #include <stdio.h> 00026 00027 #include "config.h" 00028 #include "loader.h" 00029 00030 #ifdef HAVE_DLFCN_H 00031 #include <dlfcn.h> 00032 #endif 00033 00034 #ifdef HAVE_MACH_O_DYLD_H 00035 #include <mach-o/dyld.h> 00036 #endif 00037 00038 #if defined(WITH_DLOPEN) && defined(ENABLE_LOADER) 00039 const char* loaderOpen(const char* aFilename, 00040 void** aHandle) { 00041 const char* rv = 0; 00042 00043 /* clear out dl error */ 00044 static_cast<void>(dlerror()); 00045 00046 *aHandle = dlopen(aFilename, RTLD_NOW); 00047 00048 if(!*aHandle) 00049 rv = dlerror(); 00050 00051 return rv; 00052 } 00053 00054 const char* loaderSymbol(void* aHandle, 00055 const char* aSymbol, 00056 void** aPointer) { 00057 /* clear out dl error */ 00058 static_cast<void>(dlerror()); 00059 00060 *aPointer = dlsym(aHandle, aSymbol); 00061 00062 return dlerror(); 00063 } 00064 00065 bool loaderClose(void*& aHandle) { 00066 bool rv; 00067 00068 rv = dlclose(aHandle) == 0; 00069 aHandle = 0; 00070 00071 return rv; 00072 } 00073 00074 #elif defined(WITH_DYLD) && defined(ENABLE_LOADER) 00075 00076 const char* loaderOpen(const char* aFilename, 00077 void** aHandle) { 00078 NSObjectFileImage ofi = 0; 00079 NSObjectFileImageReturnCode ofirc; 00080 00081 ofirc = NSCreateObjectFileImageFromFile(aFilename, &ofi); 00082 switch(ofirc) { 00083 case NSObjectFileImageSuccess: 00084 *aHandle = NSLinkModule(ofi, aFilename, 00085 NSLINKMODULE_OPTION_RETURN_ON_ERROR 00086 | NSLINKMODULE_OPTION_PRIVATE 00087 | NSLINKMODULE_OPTION_BINDNOW); 00088 NSDestroyObjectFileImage(ofi); 00089 break; 00090 case NSObjectFileImageInappropriateFile: 00091 *aHandle = 00092 const_cast<void*>(reinterpret_cast<const void*>(NSAddImage(aFilename, NSADDIMAGE_OPTION_RETURN_ON_ERROR))); 00093 break; 00094 default: 00095 return "could not open dynamic library"; 00096 break; 00097 } 00098 00099 return 0; 00100 } 00101 00102 const char* loaderSymbol(void* aHandle, 00103 const char* aSymbol, 00104 void** aPointer) { 00105 int len = strlen(aSymbol); 00106 char* sym = static_cast<char*>(malloc(len + 2)); 00107 NSSymbol* nssym = 0; 00108 00109 snprintf(sym, len + 2, "_%s", aSymbol); 00110 00111 /* Check for both possible magic numbers depending on x86/ppc byte order */ 00112 if ((((struct mach_header *)aHandle)->magic == MH_MAGIC) || 00113 (((struct mach_header *)aHandle)->magic == MH_CIGAM)) { 00114 if (NSIsSymbolNameDefinedInImage((struct mach_header *)aHandle, sym)) { 00115 nssym = (NSModule *)NSLookupSymbolInImage((struct mach_header *)aHandle, 00116 sym, 00117 NSLOOKUPSYMBOLINIMAGE_OPTION_BIND 00118 | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR); 00119 } 00120 } else { 00121 nssym = (NSModule *)NSLookupSymbolInModule(aHandle, sym); 00122 } 00123 00124 free(sym); 00125 00126 if(!nssym) { 00127 *aPointer = 0; 00128 return "symbol not found"; 00129 } 00130 00131 return 0; 00132 } 00133 00134 bool loaderClose(void*& aHandle) { 00135 aHandle = 0; 00136 return false; 00137 } 00138 00139 #elif defined(WIN32) 00140 00141 #include <windows.h> 00142 00143 const char* getErrorMessage() { 00144 static char error[1024]; 00145 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError(), 0, error, sizeof(error), 0); 00146 return error; 00147 } 00148 00149 const char* loaderOpen(const char* aFilename, 00150 void** aHandle) { 00151 const char* rv = 0; 00152 00153 UINT oldErrorMode = SetErrorMode(0); 00154 SetErrorMode(oldErrorMode | SEM_FAILCRITICALERRORS); 00155 *aHandle = LoadLibrary(aFilename); 00156 SetErrorMode(oldErrorMode); 00157 00158 if(!*aHandle) 00159 rv = getErrorMessage(); 00160 00161 return rv; 00162 } 00163 00164 const char* loaderSymbol(void* aHandle, 00165 const char* aSymbol, 00166 void** aPointer) { 00167 const char* rv = 0; 00168 00169 *aPointer = (void *)GetProcAddress(static_cast<HMODULE>(aHandle), aSymbol); 00170 00171 if(!aPointer) 00172 rv = getErrorMessage(); 00173 00174 return rv; 00175 } 00176 00177 bool loaderClose(void*& aHandle) { 00178 bool rv; 00179 00180 rv = FreeLibrary(static_cast<HMODULE>(aHandle)) != 0; 00181 aHandle = 0; 00182 00183 return rv; 00184 } 00185 00186 #else 00187 00188 const char* loaderOpen(const char* aFilename, 00189 void** aHandle) { 00190 *aHandle = 0; 00191 return "dynamic loading not supported on this platform"; 00192 } 00193 00194 const char* loaderSymbol(void* aHandle, 00195 const char* aSymbol, 00196 void** aPointer) { 00197 *aPointer = 0; 00198 return "dynamic loading not supported on this platform"; 00199 } 00200 00201 bool loaderClose(void*& aHandle) { 00202 aHandle = 0; 00203 return false; 00204 } 00205 00206 #endif