diff --git a/lib/libc/gen/dlfcn.c b/lib/libc/gen/dlfcn.c --- a/lib/libc/gen/dlfcn.c +++ b/lib/libc/gen/dlfcn.c @@ -40,6 +40,7 @@ #include #include #include +#include #include "namespace.h" #include #include "un-namespace.h" @@ -248,13 +249,48 @@ { } +#ifndef IN_LIBDL +struct _rtld_addr_phdr_cb_data { + const void *addr; + struct dl_phdr_info *dli; +}; + +static int +_rtld_addr_phdr_cb(struct dl_phdr_info *dli, size_t sz, void *arg) +{ + struct _rtld_addr_phdr_cb_data *rd; + const Elf_Phdr *ph; + unsigned i; + + rd = arg; + for (i = 0; i < dli->dlpi_phnum; i++) { + ph = &dli->dlpi_phdr[i]; + if (ph->p_type == PT_LOAD && + dli->dlpi_addr + ph->p_vaddr <= (uintptr_t)rd->addr && + (uintptr_t)rd->addr < dli->dlpi_addr + ph->p_vaddr + + ph->p_memsz) { + memcpy(rd->dli, dli, sz); + return (1); + } + } + return (0); +} +#endif + #pragma weak _rtld_addr_phdr int _rtld_addr_phdr(const void *addr __unused, struct dl_phdr_info *phdr_info_a __unused) { +#ifndef IN_LIBDL + struct _rtld_addr_phdr_cb_data rd; + rd.addr = addr; + rd.dli = phdr_info_a; + return (dl_iterate_phdr(_rtld_addr_phdr_cb, &rd)); +#else return (0); +#endif } #pragma weak _rtld_get_stack_prot