Mercurial > pub > dyncall > dyncall
comparison dynload/dynload_unix.c @ 356:2f64957d6a46
- fix to dynload to build with musl libc (latter has dlinfo but not RTLD_SELF, so fallback to dl_iterate_phdr if on ELF targets)
author | Tassilo Philipp |
---|---|
date | Tue, 25 Feb 2020 16:07:45 +0100 |
parents | 85c80b0c021c |
children | 1d03a3a4220d |
comparison
equal
deleted
inserted
replaced
355:5ac53b2d5f1e | 356:2f64957d6a46 |
---|---|
38 | 38 |
39 #include <string.h> | 39 #include <string.h> |
40 | 40 |
41 #if defined(__GLIBC__) | 41 #if defined(__GLIBC__) |
42 /* @@@ version check glibc more precisely... dl_iterate_phdr(): glibc ver >= 2.2.4*/ | 42 /* @@@ version check glibc more precisely... dl_iterate_phdr(): glibc ver >= 2.2.4*/ |
43 #if (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 3) | 43 # if (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 3) |
44 # define DL_USE_GLIBC_ITER_PHDR | 44 # define DL_USE_GLIBC_ITER_PHDR |
45 #endif | 45 # endif |
46 /* to access dl_iterate_phdr(), and related w/ glibc */ | 46 /* to access dl_iterate_phdr(), and related w/ glibc */ |
47 # define _GNU_SOURCE | 47 # define _GNU_SOURCE |
48 # define __USE_GNU | 48 # define __USE_GNU |
49 #endif | 49 #endif |
50 | |
50 #include <dlfcn.h> | 51 #include <dlfcn.h> |
51 | 52 |
52 | 53 |
53 DLLib* dlLoadLibrary(const char* libPath) | 54 DLLib* dlLoadLibrary(const char* libPath) |
54 { | 55 { |
95 /* code for dlGetLibraryPath() is platform specific */ | 96 /* code for dlGetLibraryPath() is platform specific */ |
96 | 97 |
97 /* if dlinfo() exists use it (except on glibc, where it exists since version | 98 /* if dlinfo() exists use it (except on glibc, where it exists since version |
98 * 2.3.3, but its implementation is dangerous, as no checks are done whether | 99 * 2.3.3, but its implementation is dangerous, as no checks are done whether |
99 * the handle is valid, thus rendering the returned values useless) check for | 100 * the handle is valid, thus rendering the returned values useless) check for |
100 * RTLD_DI_LINKMAP which is a #define for dlinfo() on most supported targets, | 101 * RTLD_DI_LINKMAP and RTLD_SELF, which are #defines used by dlinfo() on most |
101 * or specifically check the OS (e.g. dlinfo() is originally from Solaris) */ | 102 * supported targets, or specifically check the OS (e.g. dlinfo() is originally |
102 #if (defined(RTLD_DI_LINKMAP) || defined(OS_SunOS)) && !defined(DL_USE_GLIBC_ITER_PHDR) | 103 * from Solaris) */ |
104 #if ((defined(RTLD_DI_LINKMAP) && defined(RTLD_SELF)) || defined(OS_SunOS)) && !defined(DL_USE_GLIBC_ITER_PHDR) | |
103 | 105 |
104 #include <link.h> | 106 #include <link.h> |
105 | 107 |
106 int dlGetLibraryPath(DLLib* pLib, char* sOut, int bufSize) | 108 int dlGetLibraryPath(DLLib* pLib, char* sOut, int bufSize) |
107 { | 109 { |
155 | 157 |
156 return l+1; /* strlen + '\0' */ | 158 return l+1; /* strlen + '\0' */ |
157 } | 159 } |
158 | 160 |
159 | 161 |
160 /* OpenBSD >= 3.7 has dl_iterate_phdr(), as well as glibc >= 2.2.4, however | 162 /* - OpenBSD >= 3.7 has dl_iterate_phdr(), as well as glibc >= 2.2.4 |
161 * skip and use on dladdr()-based guessing if if explicitly requested, e.g. by | 163 - also some libc impls (like musl) provide dlinfo(), but not RTLD_SELF (see above), however they might come |
162 * ./configure */ | 164 with dl_iterate_phdr (which comes from ELF program header iteration), so base it on that |
163 #elif !defined(DL_DLADDR_TO_LIBPATH) && (defined(OS_OpenBSD) || defined(DL_USE_GLIBC_ITER_PHDR)) | 165 - skip and use dladdr()-based guessing (see below) if explicitly requested, e.g. by ./configure */ |
166 #elif !defined(DL_DLADDR_TO_LIBPATH) && (defined(OS_OpenBSD) || defined(DL_USE_GLIBC_ITER_PHDR) || (!defined(RTLD_SELF) && defined(__ELF__))) | |
164 | 167 |
165 #include <sys/types.h> | 168 #include <sys/types.h> |
166 #include <link.h> | 169 #include <link.h> |
167 | 170 |
168 typedef struct { | 171 typedef struct { |
180 /* get loaded object's handle if not requesting info about process itself */ | 183 /* get loaded object's handle if not requesting info about process itself */ |
181 if(d->pLib != NULL) { | 184 if(d->pLib != NULL) { |
182 /* unable to relate info->dlpi_addr directly to our dlopen handle, let's | 185 /* unable to relate info->dlpi_addr directly to our dlopen handle, let's |
183 * do what we do on macOS above, re-dlopen the already loaded lib (just | 186 * do what we do on macOS above, re-dlopen the already loaded lib (just |
184 * increases ref count) and compare handles */ | 187 * increases ref count) and compare handles */ |
185 /* @@@ might be b/c it's the reloc addr... see below */ | 188 /* @@@ might be b/c it's the reloc addr... see below */ |
186 lib = dlopen(info->dlpi_name, RTLD_LIGHTEST); | 189 lib = dlopen(info->dlpi_name, RTLD_LIGHTEST); |
187 if(lib) | 190 if(lib) |
188 dlclose(lib); | 191 dlclose(lib); |
189 } | 192 } |
190 | 193 |