Mercurial > pub > dyncall > dyncall
comparison dynload/dynload_unix.c @ 317:3df50603afa9
- dynload fix to get proc name when elf relocation is in use
author | Tassilo Philipp |
---|---|
date | Tue, 12 Nov 2019 21:16:58 +0100 |
parents | 3840e0188520 |
children | 85c80b0c021c |
comparison
equal
deleted
inserted
replaced
316:dc8bbffc39e6 | 317:3df50603afa9 |
---|---|
180 /* get loaded object's handle if not requesting info about process itself */ | 180 /* get loaded object's handle if not requesting info about process itself */ |
181 if(d->pLib != NULL) { | 181 if(d->pLib != NULL) { |
182 /* unable to relate info->dlpi_addr directly to our dlopen handle, let's | 182 /* 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 | 183 * do what we do on macOS above, re-dlopen the already loaded lib (just |
184 * increases ref count) and compare handles */ | 184 * increases ref count) and compare handles */ |
185 /* @@@ might be b/c it's the reloc addr... see below */ | |
185 lib = dlopen(info->dlpi_name, RTLD_LIGHTEST); | 186 lib = dlopen(info->dlpi_name, RTLD_LIGHTEST); |
186 if(lib) | 187 if(lib) |
187 dlclose(lib); | 188 dlclose(lib); |
188 } | 189 } |
189 | 190 |
190 /* compare handles and get name if found; if d->pLib == NULL this will | 191 /* compare handles and get name if found; if d->pLib == NULL this will |
191 enter info on first iterated object, which is the process itself */ | 192 enter info on first iterated object, which is the process itself */ |
192 if(lib == (void*)d->pLib) { | 193 if(lib == (void*)d->pLib) { |
193 l = dl_strlen_strcpy(d->sOut, info->dlpi_name, d->bufSize); | 194 l = dl_strlen_strcpy(d->sOut, info->dlpi_name, d->bufSize); |
194 | 195 |
195 /* on some platforms (e.g. Linux) dlpi_name is empty for the main process' | 196 /* if dlpi_name is empty, lookup name via dladdr(proc_load_addr, ...) */ |
196 object, but dlpi_addr is given, in that case lookup name via dladdr */ | 197 if(l == 0 && d->pLib == NULL) { |
197 if(l == 0 && d->pLib == NULL && (void*)info->dlpi_addr != NULL) { | 198 /* dlpi_addr is the reloc base (0 if PIE), find real virtual load addr */ |
198 Dl_info i; | 199 void* vladdr = (void*)info->dlpi_addr; |
199 if(dladdr((void*)info->dlpi_addr, &i) != 0) | 200 int i = 0; |
200 l = dl_strlen_strcpy(d->sOut, i.dli_fname, d->bufSize); | 201 for(; i < info->dlpi_phnum; ++i) { |
202 if(info->dlpi_phdr[i].p_type == PT_LOAD) { | |
203 vladdr = (void*)(info->dlpi_addr + info->dlpi_phdr[i].p_vaddr); | |
204 break; | |
205 } | |
206 } | |
207 Dl_info di; | |
208 if(dladdr(vladdr, &di) != 0) | |
209 l = dl_strlen_strcpy(d->sOut, di.dli_fname, d->bufSize); | |
201 } | 210 } |
202 } | 211 } |
203 | 212 |
204 return l+1; /* strlen + '\0'; is 0 if lib not found, which continues iter */ | 213 return l+1; /* strlen + '\0'; is 0 if lib not found, which continues iter */ |
205 } | 214 } |