Mercurial > pub > dyncall > dyncall
comparison dynload/dynload_unix.c @ 246:06a354b2e120
changes for dynload for macOS and OpenBSD:
- reverted last commit, b/c of brainfat (wrongly assuming all libs iterated over are opened by dynload)
- make use of RTLD_NOLOAD, though, when re-dlopen-ing to get path, for performance (where available)
author | Tassilo Philipp |
---|---|
date | Thu, 04 May 2017 23:38:30 +0200 |
parents | 0ba6189a51dd |
children | ab23f9f2934a |
comparison
equal
deleted
inserted
replaced
245:0ba6189a51dd | 246:06a354b2e120 |
---|---|
66 if(pLib) | 66 if(pLib) |
67 dlclose((void*)pLib); | 67 dlclose((void*)pLib); |
68 } | 68 } |
69 | 69 |
70 | 70 |
71 /* prefer RTLD_NOLOAD for code below that merely checks lib names */ | |
72 #if defined(RTLD_NOLOAD) | |
73 # define RTLD_LIGHTEST RTLD_NOLOAD | |
74 #else | |
75 # define RTLD_LIGHTEST RTLD_LAZY | |
76 #endif | |
77 | |
78 | |
71 /* code for dlGetLibraryPath differs on Darwin */ | 79 /* code for dlGetLibraryPath differs on Darwin */ |
72 #if defined(OS_Darwin) | 80 #if defined(OS_Darwin) |
73 | 81 |
74 #include <stdint.h> | 82 #include <stdint.h> |
75 #include <mach-o/dyld.h> | 83 #include <mach-o/dyld.h> |
87 /* so "double-load" temporarily all already loaded images (just increases */ | 95 /* so "double-load" temporarily all already loaded images (just increases */ |
88 /* ref count) and compare handles until we found ours. Return the name. */ | 96 /* ref count) and compare handles until we found ours. Return the name. */ |
89 for(i=_dyld_image_count(); i>0;) /* iterate libs from end, more likely ours */ | 97 for(i=_dyld_image_count(); i>0;) /* iterate libs from end, more likely ours */ |
90 { | 98 { |
91 const char* libPath = _dyld_get_image_name(--i); | 99 const char* libPath = _dyld_get_image_name(--i); |
92 DLLib* lib = dlLoadLibrary(libPath); /* re-open same way for same handle */ | 100 void* lib = dlopen(libPath, RTLD_LIGHTEST); |
93 if(lib) { | 101 if(lib) { |
94 dlFreeLibrary(lib); | 102 dlclose(lib); |
95 if(pLib == lib) { | 103 /* compare handle pointers' high bits (in low 2 bits some flags might */ |
104 /* be stored - should be safe b/c address needs alignment, anywas) */ | |
105 if(((intptr_t)pLib ^ (intptr_t)lib) < 4) { | |
96 l = strlen(libPath); | 106 l = strlen(libPath); |
97 if(l < bufSize) /* l+'\0' <= bufSize */ | 107 if(l < bufSize) /* l+'\0' <= bufSize */ |
98 strcpy(sOut, libPath); | 108 strcpy(sOut, libPath); |
99 break; | 109 break; |
100 } | 110 } |
124 int l = -1; | 134 int l = -1; |
125 iter_phdr_data* d = (iter_phdr_data*)data; | 135 iter_phdr_data* d = (iter_phdr_data*)data; |
126 /* unable to relate info->dlpi_addr directly to our dlopen handle, let's */ | 136 /* unable to relate info->dlpi_addr directly to our dlopen handle, let's */ |
127 /* do what we do on macOS above, re-dlopen the already loaded lib (just */ | 137 /* do what we do on macOS above, re-dlopen the already loaded lib (just */ |
128 /* increases ref count) and compare handles. */ | 138 /* increases ref count) and compare handles. */ |
129 DLLib* lib = dlLoadLibrary(info->dlpi_name); /* re-open same way for same handle */ | 139 void* lib = dlopen(info->dlpi_name, RTLD_LIGHTEST); |
130 if(lib) { | 140 if(lib) { |
131 dlFreeLibrary(lib); | 141 dlclose(lib); |
132 if(lib == d->pLib) { | 142 if(lib == (void*)d->pLib) { |
133 l = strlen(info->dlpi_name); | 143 l = strlen(info->dlpi_name); |
134 if(l < d->bufSize) /* l+'\0' <= bufSize */ | 144 if(l < d->bufSize) /* l+'\0' <= bufSize */ |
135 strcpy(d->sOut, info->dlpi_name); | 145 strcpy(d->sOut, info->dlpi_name); |
136 } | 146 } |
137 } | 147 } |