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
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065 #include <vpr/vprConfig.h>
00066
00067 #include <stdio.h>
00068 #include <stdlib.h>
00069 #include <string.h>
00070 #include <sys/types.h>
00071 #include <sys/stat.h>
00072 #include <stdarg.h>
00073 #include <limits.h>
00074 #include <mach-o/dyld.h>
00075 #include <boost/concept_check.hpp>
00076
00077 #include <vpr/Util/Assert.h>
00078 #include <vpr/Util/Debug.h>
00079 #include <vpr/md/DARWIN/DynLoad/LibraryDYLD.h>
00080
00081
00082 #ifndef _POSIX_SOURCE
00083
00084
00085
00086 typedef struct dl_info {
00087 const char *dli_fname;
00088 void *dli_fbase;
00089 const char *dli_sname;
00090 void *dli_saddr;
00091 } Dl_info;
00092
00093 #endif
00094
00095 #define RTLD_LAZY 0x1
00096 #define RTLD_NOW 0x2
00097 #define RTLD_LOCAL 0x4
00098 #define RTLD_GLOBAL 0x8
00099
00100 #ifndef _POSIX_SOURCE
00101 #define RTLD_NOLOAD 0x10
00102 #define RTLD_NODELETE 0x80
00103
00104
00105
00106
00107 #define RTLD_NEXT ((void *) -1)
00108 #define RTLD_DEFAULT ((void *) -2)
00109 #endif
00110
00111 namespace
00112 {
00113
00114 static const unsigned int ERR_STR_LEN(256);
00115
00116
00117 static const char* error(int setget, const char *str, ...)
00118 {
00119 static char errstr[ERR_STR_LEN];
00120 static int err_filled = 0;
00121 const char *retval;
00122 NSLinkEditErrors ler;
00123 int lerno;
00124 const char *dylderrstr;
00125 const char *file;
00126 va_list arg;
00127 if (setget <= 0)
00128 {
00129 va_start(arg, str);
00130 strncpy(errstr, "dlsimple: ", ERR_STR_LEN);
00131 vsnprintf(errstr + 10, ERR_STR_LEN - 10, str, arg);
00132 va_end(arg);
00133
00134 if (setget == 0) {
00135 NSLinkEditError(&ler, &lerno, &file, &dylderrstr);
00136 fprintf(stderr,"dyld: %s\n",dylderrstr);
00137 if (dylderrstr && strlen(dylderrstr))
00138 strncpy(errstr,dylderrstr,ERR_STR_LEN);
00139 }
00140 err_filled = 1;
00141 retval = NULL;
00142 }
00143 else
00144 {
00145 if (!err_filled)
00146 retval = NULL;
00147 else
00148 retval = errstr;
00149 err_filled = 0;
00150 }
00151 return retval;
00152 }
00153
00154 }
00155
00156 namespace vpr
00157 {
00158
00159 vpr::ReturnStatus LibraryDYLD::load()
00160 {
00161 vpr::ReturnStatus status;
00162
00163 if ( std::string("") != mName )
00164 {
00165 mLibrary = internalDlopen(mName.c_str(), RTLD_NOW | RTLD_GLOBAL);
00166 }
00167 else
00168 {
00169 mLibrary = internalDlopen(NULL, RTLD_NOW | RTLD_GLOBAL);
00170 }
00171
00172 if ( NULL == mLibrary )
00173 {
00174 vprDEBUG_CONT(vprDBG_ALL, vprDBG_WARNING_LVL)
00175 << std::endl << vprDEBUG_FLUSH;
00176 vprDEBUG(vprDBG_ALL, vprDBG_WARNING_LVL)
00177 << clrOutNORM(clrYELLOW, "WARNING:") << " Could not load '" << mName
00178 << "'\n" << vprDEBUG_FLUSH;
00179 vprDEBUG_NEXT(vprDBG_ALL, vprDBG_WARNING_LVL)
00180 << internalDlerror() << std::endl << vprDEBUG_FLUSH;
00181 status.setCode(vpr::ReturnStatus::Fail);
00182 }
00183
00184 return status;
00185 }
00186
00187 vpr::ReturnStatus LibraryDYLD::unload()
00188 {
00189 vprASSERT(mLibrary != NULL && "No library to unload");
00190 vpr::ReturnStatus status;
00191
00192 if ( internalDlclose(mLibrary) != 0 )
00193 {
00194 status.setCode(vpr::ReturnStatus::Fail);
00195 }
00196 else
00197 {
00198 mLibrary = NULL;
00199 }
00200
00201 return status;
00202 }
00203
00204 void* LibraryDYLD::findSymbolAndLibrary(const char* symbolName,
00205 LibraryDYLD& lib)
00206 {
00207 boost::ignore_unused_variable_warning(symbolName);
00208 boost::ignore_unused_variable_warning(lib);
00209 vprASSERT(false && "Not implemented yet");
00210 return NULL;
00211 }
00212
00213
00214 void* LibraryDYLD::internalDlopen(const char* path, int mode)
00215 {
00216 void *module = 0;
00217 NSObjectFileImage ofi = 0;
00218 NSObjectFileImageReturnCode ofirc;
00219 static int (*make_private_module_public) (NSModule module) = 0;
00220 unsigned int flags = NSLINKMODULE_OPTION_RETURN_ON_ERROR | NSLINKMODULE_OPTION_PRIVATE;
00221
00222
00223
00224 if (!path)
00225 return (void *)-1;
00226
00227
00228 ofirc = NSCreateObjectFileImageFromFile(path, &ofi);
00229 switch (ofirc)
00230 {
00231 case NSObjectFileImageSuccess:
00232
00233 if (!(mode & RTLD_LAZY)) flags += NSLINKMODULE_OPTION_BINDNOW;
00234 module = NSLinkModule(ofi, path,flags);
00235
00236 NSDestroyObjectFileImage(ofi);
00237
00238
00239
00240 if ((mode & RTLD_GLOBAL))
00241 {
00242 if (!make_private_module_public)
00243 {
00244 _dyld_func_lookup("__dyld_NSMakePrivateModulePublic",
00245 (unsigned long *)&make_private_module_public);
00246 }
00247 make_private_module_public(module);
00248 }
00249 break;
00250 case NSObjectFileImageInappropriateFile:
00251
00252 module = (void *)NSAddImage(path, NSADDIMAGE_OPTION_RETURN_ON_ERROR);
00253 break;
00254 case NSObjectFileImageFailure:
00255 error(0,"Object file setup failure : \"%s\"", path);
00256 return 0;
00257 case NSObjectFileImageArch:
00258 error(0,"No object for this architecture : \"%s\"", path);
00259 return 0;
00260 case NSObjectFileImageFormat:
00261 error(0,"Bad object file format : \"%s\"", path);
00262 return 0;
00263 case NSObjectFileImageAccess:
00264 error(0,"Can't read object file : \"%s\"", path);
00265 return 0;
00266 }
00267 if (!module)
00268 error(0, "Can not open \"%s\"", path);
00269 return module;
00270 }
00271
00272
00273 const char* LibraryDYLD::internalDlerror()
00274 {
00275 return error(1, (char *)NULL);
00276 }
00277
00278
00279 int LibraryDYLD::internalDlclose(void* handle)
00280 {
00281 if ((((struct mach_header *)handle)->magic == MH_MAGIC) ||
00282 (((struct mach_header *)handle)->magic == MH_CIGAM))
00283 {
00284 error(-1, "Can't remove dynamic libraries on darwin");
00285 return 0;
00286 }
00287 if (!NSUnLinkModule(handle, 0))
00288 {
00289 error(0, "unable to unlink module %s", NSNameOfModule(handle));
00290 return 1;
00291 }
00292 return 0;
00293 }
00294
00295
00296 void* LibraryDYLD::internalDlsym(void* handle, const char* symbol)
00297 {
00298 int sym_len = strlen(symbol);
00299 void *value = NULL;
00300 char *malloc_sym = NULL;
00301 NSSymbol *nssym = 0;
00302 malloc_sym = malloc(sym_len + 2);
00303 if (malloc_sym)
00304 {
00305 sprintf(malloc_sym, "_%s", symbol);
00306
00307 if (handle == (void *)-1)
00308 {
00309
00310 if (NSIsSymbolNameDefined(malloc_sym))
00311 {
00312 nssym = NSLookupAndBindSymbol(malloc_sym);
00313 }
00314 }
00315
00316
00317 else
00318 {
00319
00320 if ((((struct mach_header *)handle)->magic == MH_MAGIC) ||
00321 (((struct mach_header *)handle)->magic == MH_CIGAM))
00322 {
00323 if (NSIsSymbolNameDefinedInImage((struct mach_header *)handle, malloc_sym))
00324 {
00325 nssym = NSLookupSymbolInImage((struct mach_header *)handle,
00326 malloc_sym,
00327 NSLOOKUPSYMBOLINIMAGE_OPTION_BIND
00328 | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR);
00329 }
00330
00331 }
00332 else
00333 {
00334 nssym = NSLookupSymbolInModule(handle, malloc_sym);
00335 }
00336 }
00337 if (!nssym)
00338 {
00339 error(0, "Symbol \"%s\" Not found", symbol);
00340 }
00341 value = NSAddressOfSymbol(nssym);
00342 free(malloc_sym);
00343 }
00344 else
00345 {
00346 error(-1, "Unable to allocate memory");
00347 }
00348 return value;
00349 }
00350
00351 }