Asterisk.org: Developer Documentation (28 Oct 2009)

Wed Oct 28 15:48:47 2009

## Asterisk developer's documentation

# dlfcn.c File Reference

`#include <pthread.h>`
`#include <stdio.h>`
`#include <stdlib.h>`
`#include <string.h>`
`#include <sys/types.h>`
`#include <sys/stat.h>`
`#include <stdarg.h>`
`#include <limits.h>`
`#include <mach-o/dyld.h>`
`#include <mach-o/nlist.h>`
`#include <mach-o/getsect.h>`
`#include "asterisk/dlfcn-compat.h"`

Include dependency graph for dlfcn.c:

Go to the source code of this file.

## Data Structures

struct | dlstatus
struct | dlthread

## Defines

#define | __BSD_VISIBLE 1
#define | DL_IN_LIST 0x01
#define | dl_restrict __restrict
#define | ERR_STR_LEN 251
#define | LC_LOAD_WEAK_DYLIB (0x18 | LC_REQ_DYLD)
#define | LC_REQ_DYLD 0x80000000
#define | MAGIC_DYLIB_MOD ((NSModule) 'DYMO')
#define | MAGIC_DYLIB_OFI ((NSObjectFileImage) 'DYOF')
#define | MAX_SEARCH_PATHS 32
#define | NSADDIMAGE_OPTION_RETURN_ON_ERROR 0x1
#define | NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED 0x4
#define | NSLOOKUPSYMBOLINIMAGE_OPTION_BIND 0x0
#define | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR 0x4
#define | RTLD_SELF ((void *) -3)

## Functions

static struct dlstatus * | allocStatus (void)
static void | debug (const char *fmt,...)
int | dladdr (const void *dl_restrict p, Dl_info *dl_restrict info)
int | dlclose (void *handle)
static void | dlcompat_cleanup (void)
static void | dlcompat_init_func (void)
const char * | dlerror (void)
static void | dlerrorfree (void *data)
void * | dlopen (const char *path, int mode)
void * | dlsym (void *dl_restrict handle, const char *dl_restrict symbol)
static void * | dlsymIntern (struct dlstatus *dls, const char *symbol, int canSetError)
static void | dolock (void)
static void | dounlock (void)
static const char * | dyld_error_str (void)
static void | error (const char *str,...)
static struct stat * | findFile (const char *file, const char **fullPath)
static const char * | get_lib_name (const struct mach_header *mh)
static struct mach_header * | get_mach_header_from_NSModule (NSModule *mod)
static const char * | getFullPath (int i, const char *file)
static const char * | getSearchPath (int i)
static struct mach_header * | image_for_address (const void *address)
static void | insertStatus (struct dlstatus *dls, const struct stat *sbuf)
static int | isFlagSet (int mode, int flag)
static int | isValidStatus (struct dlstatus *status)
static struct dlstatus * | loadModule (const char *path, const struct stat *sbuf, int mode)
static struct dlstatus * | lookupStatus (const struct stat *sbuf)
static struct mach_header * | my_find_image (const char *name)
static int | promoteLocalToGlobal (struct dlstatus *dls)
static void * | reference (struct dlstatus *dls, int mode)
static void | resetdlerror (void)
static const char * | safegetenv (const char *s)
static NSSymbol * | search_linked_libs (const struct mach_header *mh, const char *symbol)
static const char * | searchList (void)
static void | warning (const char *str)

## Variables

static pthread_mutex_t | dlcompat_mutex
static pthread_key_t | dlerror_key
static struct mach_header *(* | dyld_NSAddImage )(const char *, unsigned long)=0
static int(* | dyld_NSIsSymbolNameDefinedInImage )(const struct mach_header *, const char *)=0
static NSSymbol(* | dyld_NSLookupSymbolInImage )(const struct mach_header *, const char *, unsigned long)=0
static struct dlstatus | mainStatus = { 0, MAGIC_DYLIB_MOD, NULL, -1, RTLD_GLOBAL, 0, 0, 0 }
static struct dlstatus * | stqueue = &mainStatus

## Define Documentation

#define __BSD_VISIBLE 1

Definition at line 48 of file dlfcn.c.

#define DL_IN_LIST 0x01

Definition at line 102 of file dlfcn.c.

Referenced by insertStatus(), and loadModule().

#define dl_restrict __restrict

Definition at line 54 of file dlfcn.c.

#define ERR_STR_LEN 251

Definition at line 92 of file dlfcn.c.

Referenced by error().

#define LC_LOAD_WEAK_DYLIB (0x18 | LC_REQ_DYLD)

Definition at line 58 of file dlfcn.c.

Referenced by search_linked_libs().

#define LC_REQ_DYLD 0x80000000

Definition at line 65 of file dlfcn.c.

#define MAGIC_DYLIB_MOD ((NSModule) 'DYMO')

Definition at line 99 of file dlfcn.c.

Referenced by dlclose(), dlsymIntern(), loadModule(), promoteLocalToGlobal(), and reference().

#define MAGIC_DYLIB_OFI ((NSObjectFileImage) 'DYOF')

Definition at line 98 of file dlfcn.c.

Referenced by loadModule().

#define MAX_SEARCH_PATHS 32

Definition at line 95 of file dlfcn.c.

Referenced by getSearchPath().

#define NSADDIMAGE_OPTION_RETURN_ON_ERROR 0x1

Definition at line 71 of file dlfcn.c.

Referenced by loadModule(), and my_find_image().

#define NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED 0x4

Definition at line 68 of file dlfcn.c.

Referenced by my_find_image().

#define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND 0x0

Definition at line 74 of file dlfcn.c.

Referenced by dlsymIntern(), and search_linked_libs().

#define NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR 0x4

Definition at line 77 of file dlfcn.c.

Referenced by dlsymIntern(), and search_linked_libs().

#define RTLD_SELF ((void *) -3)

Referenced by dlsymIntern().

## Function Documentation

static struct dlstatus * allocStatus | ( | void |  | ) | `[static, read]`

Definition at line 428 of file dlfcn.c.

References dlstatus::flags, malloc, dlstatus::module, and dlstatus::next.

Referenced by loadModule().

    00429 {
    00430    struct dlstatus *dls;
    00431 #ifdef REUSE_STATUS
    00432    dls = stqueue;
    00433    while (dls && dls->module)
    00434       dls = dls->next;
    00435    if (!dls)
    00436 #endif
    00437       dls = malloc(sizeof(*dls));
    00438    dls->flags = 0;
    00439    return dls;
    00440 }

static void debug | ( | const char * | fmt,
|  |  | ... |
| ) |  |  | `[static]`

Definition at line 183 of file dlfcn.c.

    00184 {
    00185 #if DEBUG > 1
    00186    va_list arg;
    00187    va_start(arg, fmt);
    00188    fprintf(stderr, "DLDEBUG: ");
    00189    vfprintf(stderr, fmt, arg);
    00190    fprintf(stderr, "\n");
    00191    fflush(stderr);
    00192    va_end(arg);
    00193 #endif
    00194 }

int dladdr | ( | const void *dl_restrict | p,
|  | Dl_info *dl_restrict | info |
| ) |  |  |

Definition at line 1167 of file dlfcn.c.

References debug, dolock(), dounlock(), and resetdlerror().

    01168 {
    01169 /*
    01170    FIXME: USe the routine image_for_address.
    01171 */
    01172    unsigned long i;
    01173    unsigned long j;
    01174    unsigned long count = _dyld_image_count();
    01175    struct mach_header *mh = 0;
    01176    struct load_command *lc = 0;
    01177    unsigned long addr = NULL;
    01178    unsigned long table_off = (unsigned long)0;
    01179    int found = 0;
    01180    if (!info)
    01181       return 0;
    01182    dolock();
    01183    resetdlerror();
    01184    info->dli_fname = 0;
    01185    info->dli_fbase = 0;
    01186    info->dli_sname = 0;
    01187    info->dli_saddr = 0;
    01188 /* Some of this was swiped from code posted by Douglas Davidson <ddavidso AT apple DOT com>
    01189  * to darwin-development AT lists DOT apple DOT com and slightly modified
    01190  */
    01191    for (i = 0; i < count; i++)
    01192    {
    01193       addr = (unsigned long)p - _dyld_get_image_vmaddr_slide(i);
    01194       mh = _dyld_get_image_header(i);
    01195       if (mh)
    01196       {
    01197          lc = (struct load_command *)((char *)mh + sizeof(struct mach_header));
    01198          for (j = 0; j < mh->ncmds; j++, lc = (struct load_command *)((char *)lc + lc->cmdsize))
    01199          {
    01200             if (LC_SEGMENT == lc->cmd &&
    01201                addr >= ((struct segment_command *)lc)->vmaddr &&
    01202                addr <
    01203                ((struct segment_command *)lc)->vmaddr + ((struct segment_command *)lc)->vmsize)
    01204             {
    01205                info->dli_fname = _dyld_get_image_name(i);
    01206                info->dli_fbase = (void *)mh;
    01207                found = 1;
    01208                break;
    01209             }
    01210          }
    01211          if (found)
    01212             break;
    01213       }
    01214    }
    01215    if (!found)
    01216    {
    01217       dounlock();
    01218       return 0;
    01219    }
    01220    lc = (struct load_command *)((char *)mh + sizeof(struct mach_header));
    01221    for (j = 0; j < mh->ncmds; j++, lc = (struct load_command *)((char *)lc + lc->cmdsize))
    01222    {
    01223       if (LC_SEGMENT == lc->cmd)
    01224       {
    01225          if (!strcmp(((struct segment_command *)lc)->segname, "__LINKEDIT"))
    01226             break;
    01227       }
    01228    }
    01229    table_off =
    01230       ((unsigned long)((struct segment_command *)lc)->vmaddr) -
    01231       ((unsigned long)((struct segment_command *)lc)->fileoff) + _dyld_get_image_vmaddr_slide(i);
    01232    debug("table off %x", table_off);
    01233
    01234    lc = (struct load_command *)((char *)mh + sizeof(struct mach_header));
    01235    for (j = 0; j < mh->ncmds; j++, lc = (struct load_command *)((char *)lc + lc->cmdsize))
    01236    {
    01237       if (LC_SYMTAB == lc->cmd)
    01238       {
    01239
    01240          struct nlist *symtable = (struct nlist *)(((struct symtab_command *)lc)->symoff + table_off);
    01241          unsigned long numsyms = ((struct symtab_command *)lc)->nsyms;
    01242          struct nlist *nearest = NULL;
    01243          unsigned long diff = 0xffffffff;
    01244          unsigned long strtable = (unsigned long)(((struct symtab_command *)lc)->stroff + table_off);
    01245          debug("symtable %x", symtable);
    01246          for (i = 0; i < numsyms; i++)
    01247          {
    01248             /* Ignore the following kinds of Symbols */
    01249             if ((!symtable->n_value)   /* Undefined */
    01250                || (symtable->n_type >= N_PEXT)  /* Debug symbol */
    01251                || (!(symtable->n_type & N_EXT)) /* Local Symbol */
    01252                )
    01253             {
    01254                symtable++;
    01255                continue;
    01256             }
    01257             if ((addr >= symtable->n_value) && (diff >= (symtable->n_value - addr)))
    01258             {
    01259                diff = (unsigned long)symtable->n_value - addr;
    01260                nearest = symtable;
    01261             }
    01262             symtable++;
    01263          }
    01264          if (nearest)
    01265          {
    01266             info->dli_saddr = nearest->n_value + ((void *)p - addr);
    01267             info->dli_sname = (char *)(strtable + nearest->n_un.n_strx);
    01268          }
    01269       }
    01270    }
    01271    dounlock();
    01272    return 1;
    01273 }

int dlclose | ( | void * | handle | ) |

Definition at line 1041 of file dlfcn.c.

References debug, dlsymIntern(), dolock(), dounlock(), error(), get_lib_name(), get_mach_header_from_NSModule(), isFlagSet(), isValidStatus(), dlstatus::lib, MAGIC_DYLIB_MOD, dlstatus::mode, dlstatus::module, name, dlstatus::refs, resetdlerror(), RTLD_NODELETE, and warning().

Referenced by __load_resource(), and ast_unload_resource().

    01042 {
    01043    struct dlstatus *dls = handle;
    01044    dolock();
    01045    resetdlerror();
    01046    if (!isValidStatus(dls))
    01047    {
    01048       goto dlcloseerror;
    01049    }
    01050    if (dls->module == MAGIC_DYLIB_MOD)
    01051    {
    01052       const char *name;
    01053       if (!dls->lib)
    01054       {
    01055          name = "global context";
    01056       }
    01057       else
    01058       {
    01059          name = get_lib_name(dls->lib);
    01060       }
    01061       warning("trying to close a .dylib!");
    01062       error("Not closing \"%s\" - dynamic libraries cannot be closed", name);
    01063       goto dlcloseerror;
    01064    }
    01065    if (!dls->module)
    01066    {
    01067       error("module already closed");
    01068       goto dlcloseerror;
    01069    }
    01070
    01071    if (dls->refs == 1)
    01072    {
    01073       unsigned long options = 0;
    01074       void (*fini) (void);
    01075       if ((fini = dlsymIntern(dls, "__fini", 0)))
    01076       {
    01077          debug("calling _fini()");
    01078          fini();
    01079       }
    01080 #ifdef __ppc__
    01081       options |= NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES;
    01082 #endif
    01083 #if 1
    01084 /*  Currently, if a module contains c++ static destructors and it is unloaded, we
    01085  *  get a segfault in atexit(), due to compiler and dynamic loader differences of
    01086  *  opinion, this works around that.
    01087  *  I really need a way to figure out from code if this is still necessary.
    01088  */
    01089       if ((const struct section *)NULL !=
    01090          getsectbynamefromheader(get_mach_header_from_NSModule(dls->module),
    01091                            "__DATA", "__mod_term_func"))
    01092       {
    01093          options |= NSUNLINKMODULE_OPTION_KEEP_MEMORY_MAPPED;
    01094       }
    01095 #endif
    01096 #ifdef RTLD_NODELETE
    01097       if (isFlagSet(dls->mode, RTLD_NODELETE))
    01098          options |= NSUNLINKMODULE_OPTION_KEEP_MEMORY_MAPPED;
    01099 #endif
    01100       if (!NSUnLinkModule(dls->module, options))
    01101       {
    01102          error("unable to unlink module");
    01103          goto dlcloseerror;
    01104       }
    01105       dls->refs--;
    01106       dls->module = 0;
    01107       /* Note: the dlstatus struct dls is neither removed from the list
    01108        * nor is the memory it occupies freed. This shouldn't pose a
    01109        * problem in mostly all cases, though.
    01110        */
    01111    }
    01112    dounlock();
    01113    return 0;
    01114   dlcloseerror:
    01115    dounlock();
    01116    return 1;
    01117 }

static void dlcompat_cleanup | ( | void |  | ) | `[static]`

Definition at line 824 of file dlfcn.c.

References dlcompat_mutex, dlerror_key, free, getSearchPath(), dlstatus::next, pthread_mutex_destroy, and searchList().

Referenced by dlcompat_init_func().

    00825 {
    00826    struct dlstatus *dls;
    00827    struct dlstatus *next;
    00828    char *data;
    00829    data = (char *)searchList();
    00830    if ( data )
    00831       free( data );
    00832    data =   (char *)getSearchPath(-1);
    00833    if ( data )
    00834       free( data );
    00835    pthread_mutex_destroy(&dlcompat_mutex);
    00836    pthread_key_delete(dlerror_key);
    00837    next = stqueue;
    00838    while (next && (next != &mainStatus))
    00839    {
    00840       dls = next;
    00841       next = dls->next;
    00842       free(dls);
    00843    }
    00844 }

static void dlcompat_init_func | ( | void |  | ) | `[static]`

Definition at line 801 of file dlfcn.c.

References dlcompat_cleanup(), dlcompat_mutex, dlerror_key, dlerrorfree(), dyld_NSAddImage, dyld_NSIsSymbolNameDefinedInImage, dyld_NSLookupSymbolInImage, and pthread_mutex_init.

Referenced by dlopen().

    00802 {
    00803    static int inited = 0;
    00804    if (!inited)
    00805    {
    00806       inited = 1;
    00807       _dyld_func_lookup("__dyld_NSAddImage", (unsigned long *)&dyld_NSAddImage);
    00808       _dyld_func_lookup("__dyld_NSIsSymbolNameDefinedInImage",
    00809                     (unsigned long *)&dyld_NSIsSymbolNameDefinedInImage);
    00810       _dyld_func_lookup("__dyld_NSLookupSymbolInImage", (unsigned long *)&dyld_NSLookupSymbolInImage);
    00811       if (pthread_mutex_init(&dlcompat_mutex, NULL))
    00812          exit(1);
    00813       if (pthread_key_create(&dlerror_key, &dlerrorfree))
    00814          exit(1);
    00815       /* And be neat and tidy and clean up after ourselves */
    00816       atexit(dlcompat_cleanup);
    00817    }
    00818 }

const char* dlerror | ( | void |  | ) |

Definition at line 1119 of file dlfcn.c.

References dlerror_key, dlthread::errset, and dlthread::errstr.

Referenced by __load_resource().

    01120 {
    01121    struct dlthread  *tss;
    01122    char * err_str;
    01123    tss = pthread_getspecific(dlerror_key);
    01124    err_str = tss->errstr;
    01125    tss = pthread_getspecific(dlerror_key);
    01126    if (tss->errset == 0)
    01127       return 0;
    01128    tss->errset = 0;
    01129    return (err_str );
    01130 }

static void dlerrorfree | ( | void * | data | ) | `[static]`

Definition at line 853 of file dlfcn.c.

References free.

Referenced by dlcompat_init_func().

    00854 {
    00855    free(data);
    00856 }

void* dlopen | ( | const char * | path,
|  | int | mode |
| ) |  |  |

Definition at line 897 of file dlfcn.c.

References dlcompat_init_func(), dolock(), dounlock(), error(), findFile(), isFlagSet(), loadModule(), lookupStatus(), reference(), dlstatus::refs, resetdlerror(), RTLD_LAZY, RTLD_NOLOAD, and RTLD_NOW.

Referenced by __load_resource().

    00898 {
    00899    const struct stat *sbuf;
    00900    struct dlstatus *dls;
    00901    const char *fullPath;
    00902    dlcompat_init_func();      /* Just in case */
    00903    dolock();
    00904    resetdlerror();
    00905    if (!path)
    00906    {
    00907       dls = &mainStatus;
    00908       goto dlopenok;
    00909    }
    00910    if (!(sbuf = findFile(path, &fullPath)))
    00911    {
    00912       error("file \"%s\" not found", path);
    00913       goto dlopenerror;
    00914    }
    00915    /* Now checks that it hasn't been closed already */
    00916    if ((dls = lookupStatus(sbuf)) && (dls->refs > 0))
    00917    {
    00918       /* debug("status found"); */
    00919       dls = reference(dls, mode);
    00920       goto dlopenok;
    00921    }
    00922 #ifdef   RTLD_NOLOAD
    00923    if (isFlagSet(mode, RTLD_NOLOAD))
    00924    {
    00925       error("no existing handle and RTLD_NOLOAD specified");
    00926       goto dlopenerror;
    00927    }
    00928 #endif
    00929    if (isFlagSet(mode, RTLD_LAZY) && isFlagSet(mode, RTLD_NOW))
    00930    {
    00931       error("how can I load something both RTLD_LAZY and RTLD_NOW?");
    00932       goto dlopenerror;
    00933    }
    00934    dls = loadModule(fullPath, sbuf, mode);
    00935
    00936   dlopenok:
    00937    dounlock();
    00938    return (void *)dls;
    00939   dlopenerror:
    00940    dounlock();
    00941    return NULL;
    00942 }

void* dlsym | ( | void *dl_restrict | handle,
|  | const char *dl_restrict | symbol |
| ) |  |  |

Definition at line 945 of file dlfcn.c.

References dlsymIntern(), dolock(), dounlock(), error(), free, and malloc.

Referenced by __load_resource().

    00946 {
    00947    int sym_len = strlen(symbol);
    00948    void *value = NULL;
    00949    char *malloc_sym = NULL;
    00950    dolock();
    00951    malloc_sym = malloc(sym_len + 2);
    00952    if (malloc_sym)
    00953    {
    00954       sprintf(malloc_sym, "_%s", symbol);
    00955       value = dlsymIntern(handle, malloc_sym, 1);
    00956       free(malloc_sym);
    00957    }
    00958    else
    00959    {
    00960       error("Unable to allocate memory");
    00961       goto dlsymerror;
    00962    }
    00963    dounlock();
    00964    return value;
    00965   dlsymerror:
    00966    dounlock();
    00967    return NULL;
    00968 }

static void * dlsymIntern | ( | struct dlstatus * | dls,
|  | const char * | symbol,
|  | int | canSetError |
| ) |  |  | `[static]`

Definition at line 560 of file dlfcn.c.

References debug, dyld_error_str(), dyld_NSIsSymbolNameDefinedInImage, dyld_NSLookupSymbolInImage, error(), free, get_mach_header_from_NSModule(), image_for_address(), isValidStatus(), dlstatus::lib, MAGIC_DYLIB_MOD, malloc, dlstatus::module, NSLOOKUPSYMBOLINIMAGE_OPTION_BIND, NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR, resetdlerror(), RTLD_DEFAULT, RTLD_NEXT, RTLD_SELF, and search_linked_libs().

Referenced by dlclose(), dlsym(), and loadModule().

    00561 {
    00562    NSSymbol *nssym = 0;
    00563    void *caller = __builtin_return_address(1);  /* Be *very* careful about inlining */
    00564    const struct mach_header *caller_mh = 0;
    00565    const char* savedErrorStr = NULL;
    00566    resetdlerror();
    00567 #ifndef RTLD_SELF
    00568 #define  RTLD_SELF      ((void *) -3)
    00569 #endif
    00570    if (NULL == dls)
    00571       dls = RTLD_SELF;
    00572    if ((RTLD_NEXT == dls) || (RTLD_SELF == dls))
    00573    {
    00574       if (dyld_NSIsSymbolNameDefinedInImage && dyld_NSLookupSymbolInImage)
    00575       {
    00576          caller_mh = image_for_address(caller);
    00577          if (RTLD_SELF == dls)
    00578          {
    00579             /* FIXME: We should be using the NSModule api, if SELF is an MH_BUNDLE
    00580              * But it appears to work anyway, and looking at the code in dyld_libfuncs.c
    00581              * this is acceptable.
    00582              */
    00583             if (dyld_NSIsSymbolNameDefinedInImage(caller_mh, symbol))
    00584             {
    00585                nssym = dyld_NSLookupSymbolInImage(caller_mh,
    00586                                           symbol,
    00587                                           NSLOOKUPSYMBOLINIMAGE_OPTION_BIND |
    00588                                           NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR);
    00589             }
    00590          }
    00591          if (!nssym)
    00592          {
    00593             if (RTLD_SELF == dls)
    00594                savedErrorStr = dyld_error_str();
    00595             nssym = search_linked_libs(caller_mh, symbol);
    00596          }
    00597       }
    00598       else
    00599       {
    00600          if (canSetError)
    00601             error("RTLD_SELF and RTLD_NEXT are not supported");
    00602          return NULL;
    00603       }
    00604    }
    00605    if (!nssym)
    00606    {
    00607
    00608       if (RTLD_DEFAULT == dls)
    00609       {
    00610          dls = &mainStatus;
    00611       }
    00612       if (!isValidStatus(dls))
    00613          return NULL;
    00614
    00615       if (dls->module != MAGIC_DYLIB_MOD)
    00616       {
    00617          nssym = NSLookupSymbolInModule(dls->module, symbol);
    00618          if (!nssym && NSIsSymbolNameDefined(symbol))
    00619          {
    00620             debug("Searching dependencies");
    00621             savedErrorStr = dyld_error_str();
    00622             nssym = search_linked_libs(get_mach_header_from_NSModule(dls->module), symbol);
    00623          }
    00624       }
    00625       else if (dls->lib && dyld_NSIsSymbolNameDefinedInImage && dyld_NSLookupSymbolInImage)
    00626       {
    00627          if (dyld_NSIsSymbolNameDefinedInImage(dls->lib, symbol))
    00628          {
    00629             nssym = dyld_NSLookupSymbolInImage(dls->lib,
    00630                                        symbol,
    00631                                        NSLOOKUPSYMBOLINIMAGE_OPTION_BIND |
    00632                                        NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR);
    00633          }
    00634          else if (NSIsSymbolNameDefined(symbol))
    00635          {
    00636             debug("Searching dependencies");
    00637             savedErrorStr = dyld_error_str();
    00638             nssym = search_linked_libs(dls->lib, symbol);
    00639          }
    00640       }
    00641       else if (dls->module == MAGIC_DYLIB_MOD)
    00642       {
    00643          /* Global context, use NSLookupAndBindSymbol */
    00644          if (NSIsSymbolNameDefined(symbol))
    00645          {
    00646             /* There doesn't seem to be a return on error option for this call???
    00647                this is potentially broken, if binding fails, it will improperly
    00648                exit the application. */
    00649             nssym = NSLookupAndBindSymbol(symbol);
    00650          }
    00651          else
    00652          {
    00653             if (savedErrorStr)
    00654                free((char*)savedErrorStr);
    00655             savedErrorStr = malloc(256);
    00656             snprintf((char*)savedErrorStr, 256, "Symbol \"%s\" not in global context",symbol);
    00657          }
    00658       }
    00659    }
    00660    /* Error reporting */
    00661    if (!nssym)
    00662    {
    00663       if (!savedErrorStr || !strlen(savedErrorStr))
    00664       {
    00665          if (savedErrorStr)
    00666             free((char*)savedErrorStr);
    00667          savedErrorStr = malloc(256);
    00668          snprintf((char*)savedErrorStr, 256,"Symbol \"%s\" not found",symbol);
    00669       }
    00670       if (canSetError)
    00671       {
    00672          error(savedErrorStr);
    00673       }
    00674       else
    00675       {
    00676          debug(savedErrorStr);
    00677       }
    00678       if (savedErrorStr)
    00679          free((char*)savedErrorStr);
    00680       return NULL;
    00681    }
    00682    return NSAddressOfSymbol(nssym);
    00683 }

static void dolock | ( | void |  | ) | `[inline, static]`

Definition at line 862 of file dlfcn.c.

References dlcompat_mutex, dlerror_key, dlthread::errset, dlthread::lockcnt, malloc, and pthread_mutex_lock.

Referenced by dladdr(), dlclose(), dlopen(), and dlsym().

    00863 {
    00864    int err = 0;
    00865    struct dlthread *tss;
    00866    tss = pthread_getspecific(dlerror_key);
    00867    if (!tss)
    00868    {
    00869       tss = malloc(sizeof(struct dlthread));
    00870       tss->lockcnt = 0;
    00871       tss->errset = 0;
    00872       if (pthread_setspecific(dlerror_key, tss))
    00873       {
    00874          fprintf(stderr,"dlcompat: pthread_setspecific failed\n");
    00875          exit(1);
    00876       }
    00877    }
    00878    if (!tss->lockcnt)
    00879       err = pthread_mutex_lock(&dlcompat_mutex);
    00880    tss->lockcnt = tss->lockcnt +1;
    00881    if (err)
    00882       exit(err);
    00883 }

static void dounlock | ( | void |  | ) | `[inline, static]`

Definition at line 885 of file dlfcn.c.

References dlcompat_mutex, dlerror_key, dlthread::lockcnt, and pthread_mutex_unlock.

Referenced by dladdr(), dlclose(), dlopen(), and dlsym().

    00886 {
    00887    int err = 0;
    00888    struct dlthread *tss;
    00889    tss = pthread_getspecific(dlerror_key);
    00890    tss->lockcnt = tss->lockcnt -1;
    00891    if (!tss->lockcnt)
    00892       err = pthread_mutex_unlock(&dlcompat_mutex);
    00893    if (err)
    00894       exit(err);
    00895 }

static const char * dyld_error_str | ( | void |  | ) | `[inline, static]`

Definition at line 544 of file dlfcn.c.

References malloc.

Referenced by dlsymIntern().

    00545 {
    00546    NSLinkEditErrors dylder;
    00547    int dylderno;
    00548    const char *dylderrstr;
    00549    const char *dyldfile;
    00550    const char* retStr = NULL;
    00551    NSLinkEditError(&dylder, &dylderno, &dyldfile, &dylderrstr);
    00552    if (dylderrstr && strlen(dylderrstr))
    00553    {
    00554       retStr = malloc(strlen(dylderrstr) +1);
    00555       strcpy((char*)retStr,dylderrstr);
    00556    }
    00557    return retStr;
    00558 }

static void error | ( | const char * | str,
|  |  | ... |
| ) |  |  | `[static]`

Definition at line 196 of file dlfcn.c.

References debug, dlerror_key, ERR_STR_LEN, dlthread::errset, and dlthread::errstr.

Referenced by append_string(), dlclose(), dlopen(), dlsym(), dlsymIntern(), handle_request(), handle_request_register(), iax2_hangup(), iax2_write(), isValidStatus(), load_module(), loadModule(), reference(), restart_monitor(), and store_config().

    00197 {
    00198    va_list arg;
    00199    struct dlthread  *tss;
    00200    char * err_str;
    00201    va_start(arg, str);
    00202    tss = pthread_getspecific(dlerror_key);
    00203    err_str = tss->errstr;
    00204    strncpy(err_str, "dlcompat: ", ERR_STR_LEN);
    00205    vsnprintf(err_str + 10, ERR_STR_LEN - 10, str, arg);
    00206    va_end(arg);
    00207    debug("ERROR: %s\n", err_str);
    00208    tss->errset = 1;
    00209 }

static struct stat * findFile | ( | const char * | file,
|  | const char ** | fullPath |
| ) |  |  | `[static, read]`

Definition at line 359 of file dlfcn.c.

References debug, and getFullPath().

Referenced by dlopen().

    00360 {
    00361    int i = 0;
    00362    static struct stat sbuf;
    00363    char *fileName;
    00364    debug("finding file %s", file);
    00365    *fullPath = file;
    00366    if (0 == stat(file, &sbuf))
    00367       return &sbuf;
    00368    if (strchr(file, '/'))
    00369       return 0;            /* If the path had a / we don't look in env var places */
    00370    fileName = NULL;
    00371    if (!fileName)
    00372       fileName = (char *)file;
    00373    while ((*fullPath = getFullPath(i++, fileName)))
    00374    {
    00375       if (0 == stat(*fullPath, &sbuf))
    00376          return &sbuf;
    00377    }
    00378    ;
    00379    return 0;
    00380 }

static const char * get_lib_name | ( | const struct mach_header * | mh | ) | `[static]`

Definition at line 228 of file dlfcn.c.

Referenced by dlclose().

    00229 {
    00230    unsigned long count = _dyld_image_count();
    00231    unsigned long i;
    00232    const char *val = NULL;
    00233    if (mh)
    00234    {
    00235       for (i = 0; i < count; i++)
    00236       {
    00237          if (mh == _dyld_get_image_header(i))
    00238          {
    00239             val = _dyld_get_image_name(i);
    00240             break;
    00241          }
    00242       }
    00243    }
    00244    return val;
    00245 }

static struct mach_header * get_mach_header_from_NSModule | ( | NSModule * | mod | ) | `[static, read]`

Definition at line 251 of file dlfcn.c.

References debug.

Referenced by dlclose(), dlsymIntern(), and loadModule().

    00252 {
    00253    const char *mod_name = NSNameOfModule(mod);
    00254    struct mach_header *mh = NULL;
    00255    unsigned long count = _dyld_image_count();
    00256    unsigned long i;
    00257    debug("Module name: %s", mod_name);
    00258    for (i = 0; i < count; i++)
    00259    {
    00260       if (!strcmp(mod_name, _dyld_get_image_name(i)))
    00261       {
    00262          mh = _dyld_get_image_header(i);
    00263          break;
    00264       }
    00265    }
    00266    return mh;
    00267 }

static const char * getFullPath | ( | int | i,
|  | const char * | file |
| ) |  |  | `[static]`

Definition at line 344 of file dlfcn.c.

References getSearchPath().

Referenced by findFile().

    00345 {
    00346    static char buf[PATH_MAX];
    00347    const char *path = getSearchPath(i);
    00348    if (path)
    00349    {
    00350       snprintf(buf, PATH_MAX, "%s/%s", path, file);
    00351    }
    00352    return path ? buf : 0;
    00353 }

static const char * getSearchPath | ( | int | i | ) | `[static]`

Definition at line 298 of file dlfcn.c.

References calloc, debug, free, list, MAX_SEARCH_PATHS, searchList(), and strsep().

Referenced by dlcompat_cleanup(), and getFullPath().

    00299 {
    00300    static const char *list = 0;
    00301    static char **path = (char **)0;
    00302    static int end = 0;
    00303    static int numsize = MAX_SEARCH_PATHS;
    00304    static char **tmp;
    00305    /* So we can call free() in the "destructor" we use i=-1 to return the alloc'd array */
    00306    if (i == -1)
    00307    {
    00308       return (const char*)path;
    00309    }
    00310    if (!path)
    00311    {
    00312       path = (char **)calloc(MAX_SEARCH_PATHS, sizeof(char **));
    00313    }
    00314    if (!list && !end)
    00315       list = searchList();
    00316    if (i >= (numsize))
    00317    {
    00318       debug("Increasing size for long PATH");
    00319       tmp = (char **)calloc((MAX_SEARCH_PATHS + numsize), sizeof(char **));
    00320       if (tmp)
    00321       {
    00322          memcpy(tmp, path, sizeof(char **) * numsize);
    00323          free(path);
    00324          path = tmp;
    00325          numsize += MAX_SEARCH_PATHS;
    00326       }
    00327       else
    00328       {
    00329          return 0;
    00330       }
    00331    }
    00332
    00333    while (!path[i] && !end)
    00334    {
    00335       path[i] = strsep((char **)&list, ":");
    00336
    00337       if (path[i][0] == 0)
    00338          path[i] = 0;
    00339       end = (list == 0);
    00340    }
    00341    return path[i];
    00342 }

struct mach_header * image_for_address | ( | const void * | address | ) | `[static, read]`

Definition at line 1135 of file dlfcn.c.

Referenced by dlsymIntern().

    01136 {
    01137    unsigned long i;
    01138    unsigned long j;
    01139    unsigned long count = _dyld_image_count();
    01140    struct mach_header *mh = 0;
    01141    struct load_command *lc = 0;
    01142    unsigned long addr = NULL;
    01143    for (i = 0; i < count; i++)
    01144    {
    01145       addr = (unsigned long)address - _dyld_get_image_vmaddr_slide(i);
    01146       mh = _dyld_get_image_header(i);
    01147       if (mh)
    01148       {
    01149          lc = (struct load_command *)((char *)mh + sizeof(struct mach_header));
    01150          for (j = 0; j < mh->ncmds; j++, lc = (struct load_command *)((char *)lc + lc->cmdsize))
    01151          {
    01152             if (LC_SEGMENT == lc->cmd &&
    01153                addr >= ((struct segment_command *)lc)->vmaddr &&
    01154                addr <
    01155                ((struct segment_command *)lc)->vmaddr + ((struct segment_command *)lc)->vmsize)
    01156             {
    01157                goto image_found;
    01158             }
    01159          }
    01160       }
    01161       mh = 0;
    01162    }
    01163   image_found:
    01164    return mh;
    01165 }

static void insertStatus | ( | struct dlstatus * | dls,
|  | const struct stat * | sbuf |
| ) |  |  | `[static]`

Definition at line 413 of file dlfcn.c.

References debug, dlstatus::device, DL_IN_LIST, dlstatus::flags, dlstatus::inode, dlstatus::mode, dlstatus::next, and dlstatus::refs.

Referenced by loadModule().

    00414 {
    00415    debug("inserting status");
    00416    dls->inode = sbuf->st_ino;
    00417    dls->device = sbuf->st_dev;
    00418    dls->refs = 0;
    00419    dls->mode = 0;
    00420    if ((dls->flags & DL_IN_LIST) == 0)
    00421    {
    00422       dls->next = stqueue;
    00423       stqueue = dls;
    00424       dls->flags |= DL_IN_LIST;
    00425    }
    00426 }

static int isFlagSet | ( | int | mode,
|  | int | flag |
| ) |  |  | `[inline, static]`

Definition at line 398 of file dlfcn.c.

Referenced by dlclose(), dlopen(), loadModule(), and reference().

    00399 {
    00400    return (mode & flag) == flag;
    00401 }

static int isValidStatus | ( | struct dlstatus * | status | ) | `[static]`

Definition at line 383 of file dlfcn.c.

References error(), FALSE, dlstatus::module, dlstatus::next, dlstatus::refs, and TRUE.

Referenced by dlclose(), and dlsymIntern().

    00384 {
    00385    /* Walk the list to verify status is contained in it */
    00386    struct dlstatus *dls = stqueue;
    00387    while (dls && status != dls)
    00388       dls = dls->next;
    00389    if (dls == 0)
    00390       error("invalid handle");
    00391    else if ((dls->module == 0) || (dls->refs == 0))
    00392       error("handle to closed library");
    00393    else
    00394       return TRUE;
    00395    return FALSE;
    00396 }

static struct dlstatus * loadModule | ( | const char * | path,
|  | const struct stat * | sbuf,
|  | int | mode |
| ) |  |  | `[static, read]`

Definition at line 685 of file dlfcn.c.

References allocStatus(), debug, DL_IN_LIST, dlsymIntern(), dyld_NSAddImage, dyld_NSIsSymbolNameDefinedInImage, dyld_NSLookupSymbolInImage, error(), dlstatus::flags, free, get_mach_header_from_NSModule(), insertStatus(), isFlagSet(), dlstatus::lib, lookupStatus(), MAGIC_DYLIB_MOD, MAGIC_DYLIB_OFI, dlstatus::module, NSADDIMAGE_OPTION_RETURN_ON_ERROR, reference(), RTLD_GLOBAL, RTLD_NOW, and warning().

Referenced by dlopen().

    00686 {
    00687    NSObjectFileImage ofi = 0;
    00688    NSObjectFileImageReturnCode ofirc;
    00689    struct dlstatus *dls;
    00690    NSLinkEditErrors ler;
    00691    int lerno;
    00692    const char *errstr;
    00693    const char *file;
    00694    void (*init) (void);
    00695    ofirc = NSCreateObjectFileImageFromFile(path, &ofi);
    00696    switch (ofirc)
    00697    {
    00698       case NSObjectFileImageSuccess:
    00699          break;
    00700       case NSObjectFileImageInappropriateFile:
    00701          if (dyld_NSAddImage && dyld_NSIsSymbolNameDefinedInImage && dyld_NSLookupSymbolInImage)
    00702          {
    00703             if (!isFlagSet(mode, RTLD_GLOBAL))
    00704             {
    00705                warning("trying to open a .dylib with RTLD_LOCAL");
    00706                error("unable to open this file with RTLD_LOCAL");
    00707                return NULL;
    00708             }
    00709          }
    00710          else
    00711          {
    00712             error("opening this file is unsupported on this system");
    00713             return NULL;
    00714          }
    00715          break;
    00716       case NSObjectFileImageFailure:
    00717          error("object file setup failure");
    00718          return NULL;
    00719       case NSObjectFileImageArch:
    00720          error("no object for this architecture");
    00721          return NULL;
    00722       case NSObjectFileImageFormat:
    00723          error("bad object file format");
    00724          return NULL;
    00725       case NSObjectFileImageAccess:
    00726          error("can't read object file");
    00727          return NULL;
    00728       default:
    00729          error("unknown error from NSCreateObjectFileImageFromFile()");
    00730          return NULL;
    00731    }
    00732    dls = lookupStatus(sbuf);
    00733    if (!dls)
    00734    {
    00735       dls = allocStatus();
    00736    }
    00737    if (!dls)
    00738    {
    00739       error("unable to allocate memory");
    00740       return NULL;
    00741    }
    00742    dls->lib = 0;
    00743    if (ofirc == NSObjectFileImageInappropriateFile)
    00744    {
    00745       if ((dls->lib = dyld_NSAddImage(path, NSADDIMAGE_OPTION_RETURN_ON_ERROR)))
    00746       {
    00747          debug("Dynamic lib loaded at %ld", dls->lib);
    00748          ofi = MAGIC_DYLIB_OFI;
    00749          dls->module = MAGIC_DYLIB_MOD;
    00750          ofirc = NSObjectFileImageSuccess;
    00751          /* Although it is possible with a bit of work to modify this so it works and
    00752             functions with RTLD_NOW, I don't deem it necessary at the moment */
    00753       }
    00754       if (!(dls->module))
    00755       {
    00756          NSLinkEditError(&ler, &lerno, &file, &errstr);
    00757          if (!errstr || (!strlen(errstr)))
    00758             error("Can't open this file type");
    00759          else
    00760             error(errstr);
    00761          if ((dls->flags & DL_IN_LIST) == 0)
    00762          {
    00763             free(dls);
    00764          }
    00765          return NULL;
    00766       }
    00767    }
    00768    else
    00769    {
    00770       dls->module = NSLinkModule(ofi, path,
    00771                            NSLINKMODULE_OPTION_RETURN_ON_ERROR |
    00772                            NSLINKMODULE_OPTION_PRIVATE |
    00773                            (isFlagSet(mode, RTLD_NOW) ? NSLINKMODULE_OPTION_BINDNOW : 0));
    00774       NSDestroyObjectFileImage(ofi);
    00775       if (dls->module)
    00776       {
    00777          dls->lib = get_mach_header_from_NSModule(dls->module);
    00778       }
    00779    }
    00780    if (!dls->module)
    00781    {
    00782       NSLinkEditError(&ler, &lerno, &file, &errstr);
    00783       if ((dls->flags & DL_IN_LIST) == 0)
    00784       {
    00785          free(dls);
    00786       }
    00787       error(errstr);
    00788       return NULL;
    00789    }
    00790
    00791    insertStatus(dls, sbuf);
    00792    dls = reference(dls, mode);
    00793    if ((init = dlsymIntern(dls, "__init", 0)))
    00794    {
    00795       debug("calling _init()");
    00796       init();
    00797    }
    00798    return dls;
    00799 }

static struct dlstatus * lookupStatus | ( | const struct stat * | sbuf | ) | `[static, read]`

Definition at line 403 of file dlfcn.c.

References debug, dlstatus::device, dlstatus::inode, and dlstatus::next.

Referenced by dlopen(), and loadModule().

    00404 {
    00405    struct dlstatus *dls = stqueue;
    00406    debug("looking for status");
    00407    while (dls && ( /* isFlagSet(dls->mode, RTLD_UNSHARED) */ 0
    00408                || sbuf->st_dev != dls->device || sbuf->st_ino != dls->inode))
    00409       dls = dls->next;
    00410    return dls;
    00411 }

static struct mach_header * my_find_image | ( | const char * | name | ) | `[static, read]`

Definition at line 476 of file dlfcn.c.

References dyld_NSAddImage, NSADDIMAGE_OPTION_RETURN_ON_ERROR, and NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED.

Referenced by search_linked_libs().

    00477 {
    00478    const struct mach_header *mh = 0;
    00479    const char *id = NULL;
    00480    int i = _dyld_image_count();
    00481    int j;
    00482    mh = (struct mach_header *)
    00483       dyld_NSAddImage(name, NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED |
    00484                   NSADDIMAGE_OPTION_RETURN_ON_ERROR);
    00485    if (!mh)
    00486    {
    00487       for (j = 0; j < i; j++)
    00488       {
    00489          id = _dyld_get_image_name(j);
    00490          if (!strcmp(id, name))
    00491          {
    00492             mh = _dyld_get_image_header(j);
    00493             break;
    00494          }
    00495       }
    00496    }
    00497    return mh;
    00498 }

static int promoteLocalToGlobal | ( | struct dlstatus * | dls | ) | `[static]`

Definition at line 442 of file dlfcn.c.

References debug, MAGIC_DYLIB_MOD, and dlstatus::module.

Referenced by reference().

    00443 {
    00444    static int (*p) (NSModule module) = 0;
    00445    debug("promoting");
    00446    if (!p)
    00447       _dyld_func_lookup("__dyld_NSMakePrivateModulePublic", (unsigned long *)&p);
    00448    return (dls->module == MAGIC_DYLIB_MOD) || (p && p(dls->module));
    00449 }

static void * reference | ( | struct dlstatus * | dls,
|  | int | mode |
| ) |  |  | `[static]`

Definition at line 451 of file dlfcn.c.

References debug, error(), isFlagSet(), MAGIC_DYLIB_MOD, dlstatus::mode, dlstatus::module, promoteLocalToGlobal(), dlstatus::refs, RTLD_GLOBAL, and warning().

Referenced by dlopen(), and loadModule().

    00452 {
    00453    if (dls)
    00454    {
    00455       if (dls->module == MAGIC_DYLIB_MOD && !isFlagSet(mode, RTLD_GLOBAL))
    00456       {
    00457          warning("trying to open a .dylib with RTLD_LOCAL");
    00458          error("unable to open a .dylib with RTLD_LOCAL");
    00459          return NULL;
    00460       }
    00461       if (isFlagSet(mode, RTLD_GLOBAL) &&
    00462          !isFlagSet(dls->mode, RTLD_GLOBAL) && !promoteLocalToGlobal(dls))
    00463       {
    00464          error("unable to promote local module to global");
    00465          return NULL;
    00466       }
    00467       dls->mode |= mode;
    00468       dls->refs++;
    00469    }
    00470    else
    00471       debug("reference called with NULL argument");
    00472
    00473    return dls;
    00474 }

static void resetdlerror | ( | void |  | ) | `[static]`

Definition at line 846 of file dlfcn.c.

References dlerror_key, and dlthread::errset.

Referenced by dladdr(), dlclose(), dlopen(), and dlsymIntern().

    00847 {
    00848    struct dlthread *tss;
    00849    tss = pthread_getspecific(dlerror_key);
    00850    tss->errset = 0;
    00851 }

static const char * safegetenv | ( | const char * | s | ) | `[static]`

Definition at line 218 of file dlfcn.c.

Referenced by searchList().

    00219 {
    00220    const char *ss = getenv(s);
    00221    return ss ? ss : "";
    00222 }

NSSymbol * search_linked_libs | ( | const struct mach_header * | mh,
|  | const char * | symbol |
| ) |  |  | `[static]`

Definition at line 506 of file dlfcn.c.

References debug, dyld_NSAddImage, dyld_NSIsSymbolNameDefinedInImage, dyld_NSLookupSymbolInImage, LC_LOAD_WEAK_DYLIB, my_find_image(), n, NSLOOKUPSYMBOLINIMAGE_OPTION_BIND, and NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR.

Referenced by dlsymIntern().

    00507 {
    00508    int n;
    00509    struct load_command *lc = 0;
    00510    struct mach_header *wh;
    00511    NSSymbol *nssym = 0;
    00512    if (dyld_NSAddImage && dyld_NSIsSymbolNameDefinedInImage && dyld_NSLookupSymbolInImage)
    00513    {
    00514       lc = (struct load_command *)((char *)mh + sizeof(struct mach_header));
    00515       for (n = 0; n < mh->ncmds; n++, lc = (struct load_command *)((char *)lc + lc->cmdsize))
    00516       {
    00517          if ((LC_LOAD_DYLIB == lc->cmd) || (LC_LOAD_WEAK_DYLIB == lc->cmd))
    00518          {
    00519             if ((wh = (struct mach_header *)
    00520                 my_find_image((char *)(((struct dylib_command *)lc)->dylib.name.offset +
    00521                                  (char *)lc))))
    00522             {
    00523                if (dyld_NSIsSymbolNameDefinedInImage(wh, symbol))
    00524                {
    00525                   nssym = dyld_NSLookupSymbolInImage(wh,
    00526                                              symbol,
    00527                                              NSLOOKUPSYMBOLINIMAGE_OPTION_BIND |
    00528                                              NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR);
    00529                   break;
    00530                }
    00531             }
    00532          }
    00533       }
    00534       if ((!nssym) && NSIsSymbolNameDefined(symbol))
    00535       {
    00536          /* I've never seen this debug message...*/
    00537          debug("Symbol \"%s\" is defined but was not found", symbol);
    00538       }
    00539    }
    00540    return nssym;
    00541 }

static const char * searchList | ( | void |  | ) | `[static]`

Definition at line 278 of file dlfcn.c.

References malloc, and safegetenv().

Referenced by dlcompat_cleanup(), and getSearchPath().

    00279 {
    00280    size_t buf_size;
    00281    static char *buf=NULL;
    00282    const char *ldlp = safegetenv("LD_LIBRARY_PATH");
    00283    const char *dyldlp = safegetenv("DYLD_LIBRARY_PATH");
    00284    const char *stdpath = getenv("DYLD_FALLBACK_LIBRARY_PATH");
    00285    if (!stdpath)
    00286       stdpath = "/usr/local/lib:/lib:/usr/lib";
    00287    if (!buf)
    00288    {
    00289       buf_size = strlen(ldlp) + strlen(dyldlp) + strlen(stdpath) + 4;
    00290       buf = malloc(buf_size);
    00291       snprintf(buf, buf_size, "%s%s%s%s%s%c", dyldlp, (dyldlp[0] ? ":" : ""), ldlp, (ldlp[0] ? ":" : ""),
    00292              stdpath, '\0');
    00293    }
    00294    return buf;
    00295 }

static void warning | ( | const char * | str | ) | `[static]`

Definition at line 211 of file dlfcn.c.

Referenced by dlclose(), loadModule(), and reference().

    00212 {
    00213 #if DEBUG > 0
    00214    fprintf(stderr, "WARNING: dlcompat: %s\n", str);
    00215 #endif
    00216 }

## Variable Documentation

pthread_mutex_t dlcompat_mutex`[static]`

Definition at line 105 of file dlfcn.c.

Referenced by dlcompat_cleanup(), dlcompat_init_func(), dolock(), and dounlock().

pthread_key_t dlerror_key`[static]`

Definition at line 108 of file dlfcn.c.

Referenced by dlcompat_cleanup(), dlcompat_init_func(), dlerror(), dolock(), dounlock(), error(), and resetdlerror().

struct mach_header*(* dyld_NSAddImage)(const char *, unsigned long)=0`[static]`

Referenced by dlcompat_init_func(), loadModule(), my_find_image(), and search_linked_libs().

int(* dyld_NSIsSymbolNameDefinedInImage)(const struct mach_header *, const char *)=0`[static]`

Referenced by dlcompat_init_func(), dlsymIntern(), loadModule(), and search_linked_libs().

NSSymbol(* dyld_NSLookupSymbolInImage)(const struct mach_header *, const char *, unsigned long)=0`[static]`

Referenced by dlcompat_init_func(), dlsymIntern(), loadModule(), and search_linked_libs().

struct dlstatus mainStatus = { 0, MAGIC_DYLIB_MOD, NULL, -1, RTLD_GLOBAL, 0, 0, 0 }`[static]`

Definition at line 133 of file dlfcn.c.

struct dlstatus* stqueue = &mainStatus`[static]`

Definition at line 134 of file dlfcn.c.