Mercurial > pub > dyncall > dyncall
diff 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 |
line wrap: on
line diff
--- a/dynload/dynload_unix.c Sat Nov 09 20:34:09 2019 +0100 +++ b/dynload/dynload_unix.c Tue Nov 12 21:16:58 2019 +0100 @@ -182,6 +182,7 @@ /* unable to relate info->dlpi_addr directly to our dlopen handle, let's * do what we do on macOS above, re-dlopen the already loaded lib (just * increases ref count) and compare handles */ + /* @@@ might be b/c it's the reloc addr... see below */ lib = dlopen(info->dlpi_name, RTLD_LIGHTEST); if(lib) dlclose(lib); @@ -192,12 +193,20 @@ if(lib == (void*)d->pLib) { l = dl_strlen_strcpy(d->sOut, info->dlpi_name, d->bufSize); - /* on some platforms (e.g. Linux) dlpi_name is empty for the main process' - object, but dlpi_addr is given, in that case lookup name via dladdr */ - if(l == 0 && d->pLib == NULL && (void*)info->dlpi_addr != NULL) { - Dl_info i; - if(dladdr((void*)info->dlpi_addr, &i) != 0) - l = dl_strlen_strcpy(d->sOut, i.dli_fname, d->bufSize); + /* if dlpi_name is empty, lookup name via dladdr(proc_load_addr, ...) */ + if(l == 0 && d->pLib == NULL) { + /* dlpi_addr is the reloc base (0 if PIE), find real virtual load addr */ + void* vladdr = (void*)info->dlpi_addr; + int i = 0; + for(; i < info->dlpi_phnum; ++i) { + if(info->dlpi_phdr[i].p_type == PT_LOAD) { + vladdr = (void*)(info->dlpi_addr + info->dlpi_phdr[i].p_vaddr); + break; + } + } + Dl_info di; + if(dladdr(vladdr, &di) != 0) + l = dl_strlen_strcpy(d->sOut, di.dli_fname, d->bufSize); } }