#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>Go to the source code of this file.
Defines | |
| #define | __BSD_VISIBLE 1 |
| #define | dl_restrict __restrict |
| #define | LC_LOAD_WEAK_DYLIB (0x18 | LC_REQ_DYLD) |
| #define | LC_REQ_DYLD 0x80000000 |
| #define | NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED 0x4 |
| #define | NSADDIMAGE_OPTION_RETURN_ON_ERROR 0x1 |
| #define | NSLOOKUPSYMBOLINIMAGE_OPTION_BIND 0x0 |
| #define | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR 0x4 |
| #define | ERR_STR_LEN 251 |
| #define | MAX_SEARCH_PATHS 32 |
| #define | MAGIC_DYLIB_OFI ((NSObjectFileImage) 'DYOF') |
| #define | MAGIC_DYLIB_MOD ((NSModule) 'DYMO') |
| #define | DL_IN_LIST 0x01 |
| #define | RTLD_SELF ((void *) -3) |
Functions | |
| void * | dlopen (const char *path, int mode) |
| void * | dlsym (void *dl_restrict handle, const char *dl_restrict symbol) |
| int | dlclose (void *handle) |
| const char * | dlerror (void) |
| int | dladdr (const void *dl_restrict p, Dl_info *dl_restrict info) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Definition at line 98 of file dlfcn.c. Referenced by dlclose(). |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||||
|
Definition at line 1166 of file dlfcn.c. 01167 {
01168 /*
01169 FIXME: USe the routine image_for_address.
01170 */
01171 unsigned long i;
01172 unsigned long j;
01173 unsigned long count = _dyld_image_count();
01174 struct mach_header *mh = 0;
01175 struct load_command *lc = 0;
01176 unsigned long addr = NULL;
01177 unsigned long table_off = (unsigned long)0;
01178 int found = 0;
01179 if (!info)
01180 return 0;
01181 dolock();
01182 resetdlerror();
01183 info->dli_fname = 0;
01184 info->dli_fbase = 0;
01185 info->dli_sname = 0;
01186 info->dli_saddr = 0;
01187 /* Some of this was swiped from code posted by Douglas Davidson <ddavidso AT apple DOT com>
01188 * to darwin-development AT lists DOT apple DOT com and slightly modified
01189 */
01190 for (i = 0; i < count; i++)
01191 {
01192 addr = (unsigned long)p - _dyld_get_image_vmaddr_slide(i);
01193 mh = _dyld_get_image_header(i);
01194 if (mh)
01195 {
01196 lc = (struct load_command *)((char *)mh + sizeof(struct mach_header));
01197 for (j = 0; j < mh->ncmds; j++, lc = (struct load_command *)((char *)lc + lc->cmdsize))
01198 {
01199 if (LC_SEGMENT == lc->cmd &&
01200 addr >= ((struct segment_command *)lc)->vmaddr &&
01201 addr <
01202 ((struct segment_command *)lc)->vmaddr + ((struct segment_command *)lc)->vmsize)
01203 {
01204 info->dli_fname = _dyld_get_image_name(i);
01205 info->dli_fbase = (void *)mh;
01206 found = 1;
01207 break;
01208 }
01209 }
01210 if (found)
01211 break;
01212 }
01213 }
01214 if (!found)
01215 {
01216 dounlock();
01217 return 0;
01218 }
01219 lc = (struct load_command *)((char *)mh + sizeof(struct mach_header));
01220 for (j = 0; j < mh->ncmds; j++, lc = (struct load_command *)((char *)lc + lc->cmdsize))
01221 {
01222 if (LC_SEGMENT == lc->cmd)
01223 {
01224 if (!strcmp(((struct segment_command *)lc)->segname, "__LINKEDIT"))
01225 break;
01226 }
01227 }
01228 table_off =
01229 ((unsigned long)((struct segment_command *)lc)->vmaddr) -
01230 ((unsigned long)((struct segment_command *)lc)->fileoff) + _dyld_get_image_vmaddr_slide(i);
01231 debug("table off %x", table_off);
01232
01233 lc = (struct load_command *)((char *)mh + sizeof(struct mach_header));
01234 for (j = 0; j < mh->ncmds; j++, lc = (struct load_command *)((char *)lc + lc->cmdsize))
01235 {
01236 if (LC_SYMTAB == lc->cmd)
01237 {
01238
01239 struct nlist *symtable = (struct nlist *)(((struct symtab_command *)lc)->symoff + table_off);
01240 unsigned long numsyms = ((struct symtab_command *)lc)->nsyms;
01241 struct nlist *nearest = NULL;
01242 unsigned long diff = 0xffffffff;
01243 unsigned long strtable = (unsigned long)(((struct symtab_command *)lc)->stroff + table_off);
01244 debug("symtable %x", symtable);
01245 for (i = 0; i < numsyms; i++)
01246 {
01247 /* Ignore the following kinds of Symbols */
01248 if ((!symtable->n_value) /* Undefined */
01249 || (symtable->n_type >= N_PEXT) /* Debug symbol */
01250 || (!(symtable->n_type & N_EXT)) /* Local Symbol */
01251 )
01252 {
01253 symtable++;
01254 continue;
01255 }
01256 if ((addr >= symtable->n_value) && (diff >= (symtable->n_value - addr)))
01257 {
01258 diff = (unsigned long)symtable->n_value - addr;
01259 nearest = symtable;
01260 }
01261 symtable++;
01262 }
01263 if (nearest)
01264 {
01265 info->dli_saddr = nearest->n_value + ((void *)p - addr);
01266 info->dli_sname = (char *)(strtable + nearest->n_un.n_strx);
01267 }
01268 }
01269 }
01270 dounlock();
01271 return 1;
01272 }
|
|
|
Definition at line 1040 of file dlfcn.c. References dlstatus::lib, MAGIC_DYLIB_MOD, dlstatus::mode, dlstatus::module, dlstatus::refs, and RTLD_NODELETE. Referenced by ast_load_resource(), and ast_unload_resource(). 01041 {
01042 struct dlstatus *dls = handle;
01043 dolock();
01044 resetdlerror();
01045 if (!isValidStatus(dls))
01046 {
01047 goto dlcloseerror;
01048 }
01049 if (dls->module == MAGIC_DYLIB_MOD)
01050 {
01051 const char *name;
01052 if (!dls->lib)
01053 {
01054 name = "global context";
01055 }
01056 else
01057 {
01058 name = get_lib_name(dls->lib);
01059 }
01060 warning("trying to close a .dylib!");
01061 error("Not closing \"%s\" - dynamic libraries cannot be closed", name);
01062 goto dlcloseerror;
01063 }
01064 if (!dls->module)
01065 {
01066 error("module already closed");
01067 goto dlcloseerror;
01068 }
01069
01070 if (dls->refs == 1)
01071 {
01072 unsigned long options = 0;
01073 void (*fini) (void);
01074 if ((fini = dlsymIntern(dls, "__fini", 0)))
01075 {
01076 debug("calling _fini()");
01077 fini();
01078 }
01079 #ifdef __ppc__
01080 options |= NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES;
01081 #endif
01082 #if 1
01083 /* Currently, if a module contains c++ static destructors and it is unloaded, we
01084 * get a segfault in atexit(), due to compiler and dynamic loader differences of
01085 * opinion, this works around that.
01086 * I really need a way to figure out from code if this is still necessary.
01087 */
01088 if ((const struct section *)NULL !=
01089 getsectbynamefromheader(get_mach_header_from_NSModule(dls->module),
01090 "__DATA", "__mod_term_func"))
01091 {
01092 options |= NSUNLINKMODULE_OPTION_KEEP_MEMORY_MAPPED;
01093 }
01094 #endif
01095 #ifdef RTLD_NODELETE
01096 if (isFlagSet(dls->mode, RTLD_NODELETE))
01097 options |= NSUNLINKMODULE_OPTION_KEEP_MEMORY_MAPPED;
01098 #endif
01099 if (!NSUnLinkModule(dls->module, options))
01100 {
01101 error("unable to unlink module");
01102 goto dlcloseerror;
01103 }
01104 dls->refs--;
01105 dls->module = 0;
01106 /* Note: the dlstatus struct dls is neither removed from the list
01107 * nor is the memory it occupies freed. This shouldn't pose a
01108 * problem in mostly all cases, though.
01109 */
01110 }
01111 dounlock();
01112 return 0;
01113 dlcloseerror:
01114 dounlock();
01115 return 1;
01116 }
|
|
|
Definition at line 1118 of file dlfcn.c. References dlthread::errset, and dlthread::errstr. Referenced by ast_load_resource(). 01119 {
01120 struct dlthread *tss;
01121 char * err_str;
01122 tss = pthread_getspecific(dlerror_key);
01123 err_str = tss->errstr;
01124 tss = pthread_getspecific(dlerror_key);
01125 if (tss->errset == 0)
01126 return 0;
01127 tss->errset = 0;
01128 return (err_str );
01129 }
|
|
||||||||||||
|
Definition at line 896 of file dlfcn.c. References dlstatus::refs, RTLD_LAZY, RTLD_NOLOAD, and RTLD_NOW. Referenced by ast_load_resource(). 00897 {
00898 const struct stat *sbuf;
00899 struct dlstatus *dls;
00900 const char *fullPath;
00901 dlcompat_init_func(); /* Just in case */
00902 dolock();
00903 resetdlerror();
00904 if (!path)
00905 {
00906 dls = &mainStatus;
00907 goto dlopenok;
00908 }
00909 if (!(sbuf = findFile(path, &fullPath)))
00910 {
00911 error("file \"%s\" not found", path);
00912 goto dlopenerror;
00913 }
00914 /* Now checks that it hasn't been closed already */
00915 if ((dls = lookupStatus(sbuf)) && (dls->refs > 0))
00916 {
00917 /* debug("status found"); */
00918 dls = reference(dls, mode);
00919 goto dlopenok;
00920 }
00921 #ifdef RTLD_NOLOAD
00922 if (isFlagSet(mode, RTLD_NOLOAD))
00923 {
00924 error("no existing handle and RTLD_NOLOAD specified");
00925 goto dlopenerror;
00926 }
00927 #endif
00928 if (isFlagSet(mode, RTLD_LAZY) && isFlagSet(mode, RTLD_NOW))
00929 {
00930 error("how can I load something both RTLD_LAZY and RTLD_NOW?");
00931 goto dlopenerror;
00932 }
00933 dls = loadModule(fullPath, sbuf, mode);
00934
00935 dlopenok:
00936 dounlock();
00937 return (void *)dls;
00938 dlopenerror:
00939 dounlock();
00940 return NULL;
00941 }
|
|
||||||||||||
|
Definition at line 944 of file dlfcn.c. Referenced by ast_load_resource(). 00945 {
00946 int sym_len = strlen(symbol);
00947 void *value = NULL;
00948 char *malloc_sym = NULL;
00949 dolock();
00950 malloc_sym = malloc(sym_len + 2);
00951 if (malloc_sym)
00952 {
00953 sprintf(malloc_sym, "_%s", symbol);
00954 value = dlsymIntern(handle, malloc_sym, 1);
00955 free(malloc_sym);
00956 }
00957 else
00958 {
00959 error("Unable to allocate memory");
00960 goto dlsymerror;
00961 }
00962 dounlock();
00963 return value;
00964 dlsymerror:
00965 dounlock();
00966 return NULL;
00967 }
|
1.4.2