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 }