Doxygen Source Code Documentation
dlfcn.h File Reference
Go to the source code of this file.
Defines | |
| #define | RTLD_LAZY 0x1 |
| #define | RTLD_NOW 0x2 |
| #define | RTLD_LOCAL 0x4 |
| #define | RTLD_GLOBAL 0x8 |
| #define | RTLD_NOLOAD 0x10 |
| #define | RTLD_SHARED 0x20 |
| #define | RTLD_UNSHARED 0x40 |
| #define | RTLD_NODELETE 0x80 |
| #define | RTLD_LAZY_UNDEF 0x100 |
Functions | |
| void * | dlopen (const char *path, int mode) |
| void * | dlsym (void *handle, const char *symbol) |
| const char * | dlerror (void) |
| int | dlclose (void *handle) |
Define Documentation
|
|
Definition at line 48 of file dlfcn.h. Referenced by dlopen(). |
|
|
|
|
|
|
|
|
Definition at line 47 of file dlfcn.h. Referenced by dlopen(). |
|
|
|
|
|
Definition at line 49 of file dlfcn.h. Referenced by dlopen(). |
|
|
Definition at line 46 of file dlfcn.h. Referenced by dlopen(). |
|
|
|
|
|
Definition at line 51 of file dlfcn.h. Referenced by dlopen(). |
Function Documentation
|
|
Definition at line 462 of file dlopen.c. References DEBUG_PRINT, DEBUG_PRINT1, dlerror_pointer, dlopen_handle::dlopen_count, dlopen_handle::dlopen_mode, free, dlopen_handle::module, dlopen_handle::next, dlopen_handle::prev, RTLD_LAZY_UNDEF, and RTLD_NODELETE.
00464 {
00465 struct dlopen_handle *p, *q;
00466 unsigned long options;
00467 NSSymbol NSSymbol;
00468 void (*fini)(void);
00469
00470 DEBUG_PRINT1("libdl: dlclose(%p) -> ", handle);
00471
00472 dlerror_pointer = NULL;
00473 q = (struct dlopen_handle *)handle;
00474 p = dlopen_handles;
00475 while(p != NULL){
00476 if(p == q){
00477 /* if the dlopen() count is not zero we are done */
00478 p->dlopen_count--;
00479 if(p->dlopen_count != 0){
00480 DEBUG_PRINT("OK");
00481 return(0);
00482 }
00483
00484 /* call the fini function if one exists */
00485 NSSymbol = NSLookupSymbolInModule(p->module, "__fini");
00486 if(NSSymbol != NULL){
00487 fini = NSAddressOfSymbol(NSSymbol);
00488 fini();
00489 }
00490
00491 /* unlink the module for this handle */
00492 options = 0;
00493 if(p->dlopen_mode & RTLD_NODELETE)
00494 options |= NSUNLINKMODULE_OPTION_KEEP_MEMORY_MAPPED;
00495 if(p->dlopen_mode & RTLD_LAZY_UNDEF)
00496 options |= NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES;
00497 if(NSUnLinkModule(p->module, options) == FALSE){
00498 dlerror_pointer = "NSUnLinkModule() failed for dlclose()";
00499 DEBUG_PRINT1("ERROR: %s\n", dlerror_pointer);
00500 return(-1);
00501 }
00502 if(p->prev != NULL)
00503 p->prev->next = p->next;
00504 if(p->next != NULL)
00505 p->next->prev = p->prev;
00506 if(dlopen_handles == p)
00507 dlopen_handles = p->next;
00508 free(p);
00509 DEBUG_PRINT("OK");
00510 return(0);
00511 }
00512 p = p->next;
00513 }
00514 dlerror_pointer = "invalid handle passed to dlclose()";
00515 DEBUG_PRINT1("ERROR: %s\n", dlerror_pointer);
00516 return(-1);
00517 }
|
|
|
Definition at line 448 of file dlopen.c. References dlerror_pointer, and p.
00450 {
00451 const char *p;
00452
00453 p = (const char *)dlerror_pointer;
00454 dlerror_pointer = NULL;
00455 return(p);
00456 }
|
|
||||||||||||
|
Definition at line 185 of file dlopen.c. References _dl_search_paths(), DEBUG_PRINT1, DEBUG_PRINT2, dlopen_handle::dev, dlerror_pointer, dlopen_handle::dlopen_count, dlopen_handle::dlopen_mode, dlopen_handle::ino, malloc, dlopen_handle::module, dlopen_handle::next, NSMakePrivateModulePublic(), dlopen_handle::prev, retval(), RTLD_GLOBAL, RTLD_LAZY_UNDEF, RTLD_LOCAL, RTLD_NODELETE, RTLD_NOLOAD, RTLD_NOW, RTLD_UNSHARED, and strerror().
00188 {
00189 const char *module_path;
00190 void *retval;
00191 struct stat stat_buf;
00192 NSObjectFileImage objectFileImage;
00193 NSObjectFileImageReturnCode ofile_result_code;
00194 NSModule module;
00195 struct dlopen_handle *p;
00196 unsigned long options;
00197 NSSymbol NSSymbol;
00198 void (*init)(void);
00199 char pathbuf[PATH_MAX];
00200
00201 DEBUG_PRINT2("libdl: dlopen(%s,0x%x) -> ", path, (unsigned int)mode);
00202
00203 dlerror_pointer = NULL;
00204 /*
00205 * A NULL path is to indicate the caller wants a handle for the
00206 * main program.
00207 */
00208 if(path == NULL){
00209 retval = (void *)&main_program_handle;
00210 DEBUG_PRINT1("main / %p\n", retval);
00211 return(retval);
00212 }
00213
00214 /* see if the path exists and if so get the device and inode number */
00215 if(stat(path, &stat_buf) == -1){
00216 dlerror_pointer = strerror(errno);
00217
00218 if(path[0] == '/'){
00219 DEBUG_PRINT1("ERROR (stat): %s\n", dlerror_pointer);
00220 return(NULL);
00221 }
00222
00223 /* search for the module in various places */
00224 if(_dl_search_paths(path, pathbuf, &stat_buf)){
00225 /* dlerror_pointer is unmodified */
00226 DEBUG_PRINT1("ERROR (stat): %s\n", dlerror_pointer);
00227 return(NULL);
00228 }
00229 DEBUG_PRINT1("found %s -> ", pathbuf);
00230 module_path = pathbuf;
00231 dlerror_pointer = NULL;
00232 }
00233 else{
00234 module_path = path;
00235 }
00236
00237 /*
00238 * If we don't want an unshared handle see if we already have a handle
00239 * for this path.
00240 */
00241 if((mode & RTLD_UNSHARED) != RTLD_UNSHARED){
00242 p = dlopen_handles;
00243 while(p != NULL){
00244 if(p->dev == stat_buf.st_dev && p->ino == stat_buf.st_ino){
00245 /* skip unshared handles */
00246 if((p->dlopen_mode & RTLD_UNSHARED) == RTLD_UNSHARED)
00247 continue;
00248 /*
00249 * We have already created a handle for this path. The
00250 * caller might be trying to promote an RTLD_LOCAL handle
00251 * to a RTLD_GLOBAL. Or just looking it up with
00252 * RTLD_NOLOAD.
00253 */
00254 if((p->dlopen_mode & RTLD_LOCAL) == RTLD_LOCAL &&
00255 (mode & RTLD_GLOBAL) == RTLD_GLOBAL){
00256 /* promote the handle */
00257 if(NSMakePrivateModulePublic(p->module) == TRUE){
00258 p->dlopen_mode &= ~RTLD_LOCAL;
00259 p->dlopen_mode |= RTLD_GLOBAL;
00260 p->dlopen_count++;
00261 DEBUG_PRINT1("%p\n", p);
00262 return(p);
00263 }
00264 else{
00265 dlerror_pointer = "can't promote handle from "
00266 "RTLD_LOCAL to RTLD_GLOBAL";
00267 DEBUG_PRINT1("ERROR: %s\n", dlerror_pointer);
00268 return(NULL);
00269 }
00270 }
00271 p->dlopen_count++;
00272 DEBUG_PRINT1("%p\n", p);
00273 return(p);
00274 }
00275 p = p->next;
00276 }
00277 }
00278
00279 /*
00280 * We do not have a handle for this path if we were just trying to
00281 * look it up return NULL to indicate we don't have it.
00282 */
00283 if((mode & RTLD_NOLOAD) == RTLD_NOLOAD){
00284 dlerror_pointer = "no existing handle for path RTLD_NOLOAD test";
00285 DEBUG_PRINT1("ERROR: %s\n", dlerror_pointer);
00286 return(NULL);
00287 }
00288
00289 /* try to create an object file image from this path */
00290 ofile_result_code = NSCreateObjectFileImageFromFile(module_path,
00291 &objectFileImage);
00292 if(ofile_result_code != NSObjectFileImageSuccess){
00293 switch(ofile_result_code){
00294 case NSObjectFileImageFailure:
00295 dlerror_pointer = "object file setup failure";
00296 DEBUG_PRINT1("ERROR: %s\n", dlerror_pointer);
00297 return(NULL);
00298 case NSObjectFileImageInappropriateFile:
00299 dlerror_pointer = "not a Mach-O MH_BUNDLE file type";
00300 DEBUG_PRINT1("ERROR: %s\n", dlerror_pointer);
00301 return(NULL);
00302 case NSObjectFileImageArch:
00303 dlerror_pointer = "no object for this architecture";
00304 DEBUG_PRINT1("ERROR: %s\n", dlerror_pointer);
00305 return(NULL);
00306 case NSObjectFileImageFormat:
00307 dlerror_pointer = "bad object file format";
00308 DEBUG_PRINT1("ERROR: %s\n", dlerror_pointer);
00309 return(NULL);
00310 case NSObjectFileImageAccess:
00311 dlerror_pointer = "can't read object file";
00312 DEBUG_PRINT1("ERROR: %s\n", dlerror_pointer);
00313 return(NULL);
00314 default:
00315 dlerror_pointer = "unknown error from "
00316 "NSCreateObjectFileImageFromFile()";
00317 DEBUG_PRINT1("ERROR: %s\n", dlerror_pointer);
00318 return(NULL);
00319 }
00320 }
00321
00322 /* try to link in this object file image */
00323 options = NSLINKMODULE_OPTION_PRIVATE;
00324 if((mode & RTLD_NOW) == RTLD_NOW)
00325 options |= NSLINKMODULE_OPTION_BINDNOW;
00326 module = NSLinkModule(objectFileImage, module_path, options);
00327 NSDestroyObjectFileImage(objectFileImage) ;
00328 if(module == NULL){
00329 dlerror_pointer = "NSLinkModule() failed for dlopen()";
00330 DEBUG_PRINT1("ERROR: %s\n", dlerror_pointer);
00331 return(NULL);
00332 }
00333
00334 /*
00335 * If the handle is to be global promote the handle. It is done this
00336 * way to avoid multiply defined symbols.
00337 */
00338 if((mode & RTLD_GLOBAL) == RTLD_GLOBAL){
00339 if(NSMakePrivateModulePublic(module) == FALSE){
00340 dlerror_pointer = "can't promote handle from RTLD_LOCAL to "
00341 "RTLD_GLOBAL";
00342 DEBUG_PRINT1("ERROR: %s\n", dlerror_pointer);
00343 return(NULL);
00344 }
00345 }
00346
00347 p = malloc(sizeof(struct dlopen_handle));
00348 if(p == NULL){
00349 dlerror_pointer = "can't allocate memory for the dlopen handle";
00350 DEBUG_PRINT1("ERROR: %s\n", dlerror_pointer);
00351 return(NULL);
00352 }
00353
00354 /* fill in the handle */
00355 p->dev = stat_buf.st_dev;
00356 p->ino = stat_buf.st_ino;
00357 if(mode & RTLD_GLOBAL)
00358 p->dlopen_mode = RTLD_GLOBAL;
00359 else
00360 p->dlopen_mode = RTLD_LOCAL;
00361 p->dlopen_mode |= (mode & RTLD_UNSHARED) |
00362 (mode & RTLD_NODELETE) |
00363 (mode & RTLD_LAZY_UNDEF);
00364 p->dlopen_count = 1;
00365 p->module = module;
00366 p->prev = NULL;
00367 p->next = dlopen_handles;
00368 if(dlopen_handles != NULL)
00369 dlopen_handles->prev = p;
00370 dlopen_handles = p;
00371
00372 /* call the init function if one exists */
00373 NSSymbol = NSLookupSymbolInModule(p->module, "__init");
00374 if(NSSymbol != NULL){
00375 init = NSAddressOfSymbol(NSSymbol);
00376 init();
00377 }
00378
00379 DEBUG_PRINT1("%p\n", p);
00380 return(p);
00381 }
|
|
||||||||||||
|
Definition at line 387 of file dlopen.c. References DEBUG_PRINT1, DEBUG_PRINT2, dlerror_pointer, dlopen_handle::module, and dlopen_handle::next.
00390 {
00391 struct dlopen_handle *dlopen_handle, *p;
00392 NSSymbol NSSymbol;
00393 void *address;
00394
00395 DEBUG_PRINT2("libdl: dlsym(%p,%s) -> ", handle, symbol);
00396
00397 dlopen_handle = (struct dlopen_handle *)handle;
00398
00399 /*
00400 * If this is the handle for the main program do a global lookup.
00401 */
00402 if(dlopen_handle == (struct dlopen_handle *)&main_program_handle){
00403 if(NSIsSymbolNameDefined(symbol) == TRUE){
00404 NSSymbol = NSLookupAndBindSymbol(symbol);
00405 address = NSAddressOfSymbol(NSSymbol);
00406 dlerror_pointer = NULL;
00407 DEBUG_PRINT1("%p\n", address);
00408 return(address);
00409 }
00410 else{
00411 dlerror_pointer = "symbol not found";
00412 DEBUG_PRINT1("ERROR: %s\n", dlerror_pointer);
00413 return(NULL);
00414 }
00415 }
00416
00417 /*
00418 * Find this handle and do a lookup in just this module.
00419 */
00420 p = dlopen_handles;
00421 while(p != NULL){
00422 if(dlopen_handle == p){
00423 NSSymbol = NSLookupSymbolInModule(p->module, symbol);
00424 if(NSSymbol != NULL){
00425 address = NSAddressOfSymbol(NSSymbol);
00426 dlerror_pointer = NULL;
00427 DEBUG_PRINT1("%p\n", address);
00428 return(address);
00429 }
00430 else{
00431 dlerror_pointer = "symbol not found";
00432 DEBUG_PRINT1("ERROR: %s\n", dlerror_pointer);
00433 return(NULL);
00434 }
00435 }
00436 p = p->next;
00437 }
00438
00439 dlerror_pointer = "bad handle passed to dlsym()";
00440 DEBUG_PRINT1("ERROR: %s\n", dlerror_pointer);
00441 return(NULL);
00442 }
|