Main Page | Alphabetical List | Data Structures | File List | Data Fields | Globals

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:

Include dependency graph

Go to the source code of this file.

Data Structures

struct  dlthread
struct  dlstatus

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)


Define Documentation

#define __BSD_VISIBLE   1
 

Definition at line 48 of file dlfcn.c.

#define DL_IN_LIST   0x01
 

Definition at line 101 of file dlfcn.c.

#define dl_restrict   __restrict
 

Definition at line 53 of file dlfcn.c.

#define ERR_STR_LEN   251
 

Definition at line 91 of file dlfcn.c.

#define LC_LOAD_WEAK_DYLIB   (0x18 | LC_REQ_DYLD)
 

Definition at line 57 of file dlfcn.c.

#define LC_REQ_DYLD   0x80000000
 

Definition at line 64 of file dlfcn.c.

#define MAGIC_DYLIB_MOD   ((NSModule) 'DYMO')
 

Definition at line 98 of file dlfcn.c.

Referenced by dlclose().

#define MAGIC_DYLIB_OFI   ((NSObjectFileImage) 'DYOF')
 

Definition at line 97 of file dlfcn.c.

#define MAX_SEARCH_PATHS   32
 

Definition at line 94 of file dlfcn.c.

#define NSADDIMAGE_OPTION_RETURN_ON_ERROR   0x1
 

Definition at line 70 of file dlfcn.c.

#define NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED   0x4
 

Definition at line 67 of file dlfcn.c.

#define NSLOOKUPSYMBOLINIMAGE_OPTION_BIND   0x0
 

Definition at line 73 of file dlfcn.c.

#define NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR   0x4
 

Definition at line 76 of file dlfcn.c.

#define RTLD_SELF   ((void *) -3)
 


Function Documentation

int dladdr const void *dl_restrict  p,
Dl_info *dl_restrict  info
 

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 }

int dlclose void *  handle  ) 
 

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 }

const char* dlerror void   ) 
 

Definition at line 1118 of file dlfcn.c.

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 }

void* dlopen const char *  path,
int  mode
 

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 }

void* dlsym void *dl_restrict  handle,
const char *dl_restrict  symbol
 

Definition at line 944 of file dlfcn.c.

References free, and malloc.

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 }


Generated on Sat Jun 12 16:41:12 2004 for Asterisk by doxygen 1.3.7