comparison dynload/dynload_unix.c @ 248:ab23f9f2934a

- BeOS impl for dlGetLibraryPath - more dynload doc clarifications
author Tassilo Philipp
date Fri, 05 May 2017 13:13:43 +0200
parents 06a354b2e120
children 5cfe4322c500
comparison
equal deleted inserted replaced
247:446d2220bc49 248:ab23f9f2934a
112 } 112 }
113 113
114 return l+1; /* strlen + '\0' */ 114 return l+1; /* strlen + '\0' */
115 } 115 }
116 116
117 #else /* non-Darwin --> */ 117 #elif defined(OS_OpenBSD) /* doesn't have dlinfo() but dl_iterate_phdr() --> */
118
119 #if defined(OS_OpenBSD) /* doesn't have dlinfo() but dl_iterate_phdr() --> */
120 118
121 /* @@@ dl_iterate_phdr() only exists on OpenBSD >= 3.7 */ 119 /* @@@ dl_iterate_phdr() only exists on OpenBSD >= 3.7 */
122 120
123 #include <sys/types.h> 121 #include <sys/types.h>
124 #include <link.h> 122 #include <link.h>
152 { 150 {
153 iter_phdr_data d = { pLib, sOut, bufSize }; 151 iter_phdr_data d = { pLib, sOut, bufSize };
154 return dl_iterate_phdr(iter_phdr_cb, &d); 152 return dl_iterate_phdr(iter_phdr_cb, &d);
155 } 153 }
156 154
155 #elif defined(OS_BeOS) /* neither dlinfo(), nor dl_iterate_phdr(), but ltdl stuff*/
156
157 #if 0
158 #include <ltdl.h>
159
160 typedef struct { // @@@share
161 DLLib* pLib;
162 char* sOut;
163 int bufSize;
164 } iter_phdr_data;
165
166 static int handle_map_cb(lt_dlhandle h, void* data)
167 {
168 int l = -1;
169 iter_phdr_data* d = (iter_phdr_data*)data;
170 /* same idea as with dl_iterate_phdr, see above */
171 const lt_dlinfo* dli = lt_dlgetinfo(h);
172 if(dli) {
173 void* lib = dlopen(dli->filename, RTLD_LIGHTEST);
174 if(lib) {
175 dlclose(lib);
176 if(lib == (void*)d->pLib) {
177 l = strlen(dli->filename);
178 if(l < d->bufSize) /* l+'\0' <= bufSize */
179 strcpy(d->sOut, dli->filename);
180 }
181 }
182 }
183 return l+1; /* strlen + '\0'; is 0 if lib not found, which continues iter */
184 }
185
186 int dlGetLibraryPath(DLLib* pLib, char* sOut, int bufSize)
187 {
188 iter_phdr_data d = { pLib, sOut, bufSize };
189 lt_dlinterface_id ii = lt_dlinterface_register("not_sure_here...", NULL);
190 int l = lt_dlhandle_map(ii, handle_map_cb, &d);
191 lt_dlinterface_free(ii);
192 return l;
193 }
194 #endif
195
196 /* we have lt_dlgetinfo on BeOS, which requires iterating over ltdl stuff, */
197 /* but was unable to get that to work (would also have introduced a link */
198 /* dependency on libltdl); so do a hacky dladdr() based attempt, instead, */
199 /* which might not always work, but probably is ok for nearly all libs */
200
201 int dlGetLibraryPath(DLLib* pLib, char* sOut, int bufSize)
202 {
203 /* BeOS uses ELF, cross fingers that .so is standard and look for _fini */
204 int l = -1;
205 void* s = dlsym((void*)pLib, "_fini");
206 if(s) {
207 Dl_info i;
208 if(dladdr(s, &i) != 0) {
209 l = strlen(i.dli_fname);
210 if(l < bufSize) /* l+'\0' <= bufSize */
211 strcpy(sOut, i.dli_fname);
212 }
213 }
214 return l+1; /* strlen + '\0' */
215 }
216
157 #else /* use dlinfo() --> */ 217 #else /* use dlinfo() --> */
158 218
159 #include <link.h> 219 #include <link.h>
160 220
161 int dlGetLibraryPath(DLLib* pLib, char* sOut, int bufSize) 221 int dlGetLibraryPath(DLLib* pLib, char* sOut, int bufSize)
170 return l+1; /* strlen + '\0' */ 230 return l+1; /* strlen + '\0' */
171 } 231 }
172 232
173 #endif 233 #endif
174 234
175 #endif
176