00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
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
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
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