git: 42ceab3ea1a9 - main - libc.a: implement _rtld_addr_phdr()
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 25 Jun 2023 18:28:06 UTC
The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=42ceab3ea1a997db93b65404be0ee4b17b5382d7 commit 42ceab3ea1a997db93b65404be0ee4b17b5382d7 Author: Konstantin Belousov <kib@FreeBSD.org> AuthorDate: 2023-06-24 10:59:56 +0000 Commit: Konstantin Belousov <kib@FreeBSD.org> CommitDate: 2023-06-25 18:27:25 +0000 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 4478b41cfe98..61984e2fe86c 100644 --- a/lib/libc/gen/dlfcn.c +++ b/lib/libc/gen/dlfcn.c @@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$"); #include <dlfcn.h> #include <link.h> #include <stddef.h> +#include <string.h> #include "namespace.h" #include <pthread.h> #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