From 42ceab3ea1a997db93b65404be0ee4b17b5382d7 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sat, 24 Jun 2023 13:59:56 +0300 Subject: [PATCH] libc.a: implement _rtld_addr_phdr() to make __cxa_thread_call_dtors() operational for statically linked binaries. Noted by: andrew Reviewed by: emaste, dim Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D40748 --- lib/libc/gen/dlfcn.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/lib/libc/gen/dlfcn.c b/lib/libc/gen/dlfcn.c index 4478b41cfe9..61984e2fe86 100644 --- a/lib/libc/gen/dlfcn.c +++ b/lib/libc/gen/dlfcn.c @@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include "namespace.h" #include #include "un-namespace.h" @@ -248,13 +249,48 @@ _rtld_atfork_post(int *locks __unused) { } +#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