From patchwork Fri Mar 17 06:32:10 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: stsp X-Patchwork-Id: 66503 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 9E8F6385482C for ; Fri, 17 Mar 2023 06:35:13 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 9E8F6385482C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1679034913; bh=jPBpuh7+5SywDlOTPnrzaKwaw3Q13Oa+Qta92KBgaPU=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=uYsypdLK7tuYTu7GkfZxt5gNT87YT9aOkYZZU3dtme/dEbf6qY/zd6z0M1by4lj4r Bw8j5+mZca10QUGCHX9A3N9BGHZgsgNfdlFqL8c+j9d8lGQR5S7XGmCji2OM6B3gVC REkoJgmSh8Utg45RPIF50wxPZBWGnfmJIB6jc8pA= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from forward104p.mail.yandex.net (forward104p.mail.yandex.net [IPv6:2a02:6b8:0:1472:2741:0:8b7:107]) by sourceware.org (Postfix) with ESMTPS id C8AB8385B53E for ; Fri, 17 Mar 2023 06:32:39 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org C8AB8385B53E Received: from sas9-2d24a7e69f58.qloud-c.yandex.net (sas9-2d24a7e69f58.qloud-c.yandex.net [IPv6:2a02:6b8:c11:2298:0:640:2d24:a7e6]) by forward104p.mail.yandex.net (Yandex) with ESMTP id 5B2223C21268 for ; Fri, 17 Mar 2023 09:32:38 +0300 (MSK) Received: by sas9-2d24a7e69f58.qloud-c.yandex.net (smtp/Yandex) with ESMTPSA id QWeJF9abi0U1-DMIqT6ZG; Fri, 17 Mar 2023 09:32:37 +0300 X-Yandex-Fwd: 1 To: libc-alpha@sourceware.org Cc: Stas Sergeev Subject: [PATCH 11/11] dlfcn,elf: implement dlmem() [BZ #11767] Date: Fri, 17 Mar 2023 11:32:10 +0500 Message-Id: <20230317063210.4118076-12-stsp2@yandex.ru> X-Mailer: git-send-email 2.37.2 In-Reply-To: <20230317063210.4118076-1-stsp2@yandex.ru> References: <20230317063210.4118076-1-stsp2@yandex.ru> MIME-Version: 1.0 X-Spam-Status: No, score=-11.3 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, GIT_PATCH_0, KAM_SHORT, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Stas Sergeev via Libc-alpha From: stsp Reply-To: Stas Sergeev Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" This patch adds the following function: void *dlmem(const unsigned char *buffer, size_t size, int flags, struct dlmem_args *dlm_args); It is the same as dlopen() but allows to dynamic-link solibs from the memory buffer, rather than from a file as dlopen() does. "buffer" arg is the pointer to the solib image in memory. "size" is the solib image size. Must be smaller-or-equal to the actual buffer size. "flags" is the same flags argument used in dlopen(). "dlm_args" is an optional argument that allows to specify the load namespace and a premap callback. The idea behind the implementation is very simple: where the dlopen() would mmap() the file, dlmem() does anonymous mmap()+memcpy(). Or if premap callback is provided, then it is used to map the needed address space. This patch adds a test-case named tst-dlmem. It checks that dlmem worked by resolving the solib symbols. Then it checks the advanced functionality of creating the library duplicate. The test-suite was run on x86_64/64 and showed no regressions. Signed-off-by: Stas Sergeev --- dlfcn/Makefile | 5 +- dlfcn/Versions | 3 + dlfcn/dlfcn.h | 15 ++ dlfcn/dlmem.c | 102 +++++++++++ dlfcn/glreflib1.c | 2 + dlfcn/tst-dlmem.c | 166 ++++++++++++++++++ elf/dl-load.c | 148 ++++++++++++++++ elf/dl-load.h | 3 + elf/dl-main.h | 12 ++ elf/dl-open.c | 12 ++ elf/rtld.c | 1 + include/dlfcn.h | 4 + manual/dynlink.texi | 1 + sysdeps/generic/ldsodefs.h | 9 + sysdeps/mach/hurd/i386/libc.abilist | 1 + sysdeps/unix/sysv/linux/aarch64/libc.abilist | 1 + sysdeps/unix/sysv/linux/alpha/libc.abilist | 1 + sysdeps/unix/sysv/linux/arc/libc.abilist | 1 + sysdeps/unix/sysv/linux/arm/be/libc.abilist | 1 + sysdeps/unix/sysv/linux/arm/le/libc.abilist | 1 + sysdeps/unix/sysv/linux/csky/libc.abilist | 1 + sysdeps/unix/sysv/linux/hppa/libc.abilist | 1 + sysdeps/unix/sysv/linux/i386/libc.abilist | 1 + sysdeps/unix/sysv/linux/ia64/libc.abilist | 1 + .../sysv/linux/loongarch/lp64/libc.abilist | 1 + .../sysv/linux/m68k/coldfire/libc.abilist | 1 + .../unix/sysv/linux/m68k/m680x0/libc.abilist | 1 + .../sysv/linux/microblaze/be/libc.abilist | 1 + .../sysv/linux/microblaze/le/libc.abilist | 1 + .../sysv/linux/mips/mips32/fpu/libc.abilist | 1 + .../sysv/linux/mips/mips32/nofpu/libc.abilist | 1 + .../sysv/linux/mips/mips64/n32/libc.abilist | 1 + .../sysv/linux/mips/mips64/n64/libc.abilist | 1 + sysdeps/unix/sysv/linux/nios2/libc.abilist | 1 + sysdeps/unix/sysv/linux/or1k/libc.abilist | 1 + .../linux/powerpc/powerpc32/fpu/libc.abilist | 1 + .../powerpc/powerpc32/nofpu/libc.abilist | 1 + .../linux/powerpc/powerpc64/be/libc.abilist | 1 + .../linux/powerpc/powerpc64/le/libc.abilist | 1 + .../unix/sysv/linux/riscv/rv32/libc.abilist | 1 + .../unix/sysv/linux/riscv/rv64/libc.abilist | 1 + .../unix/sysv/linux/s390/s390-32/libc.abilist | 1 + .../unix/sysv/linux/s390/s390-64/libc.abilist | 1 + sysdeps/unix/sysv/linux/sh/be/libc.abilist | 1 + sysdeps/unix/sysv/linux/sh/le/libc.abilist | 1 + .../sysv/linux/sparc/sparc32/libc.abilist | 1 + .../sysv/linux/sparc/sparc64/libc.abilist | 1 + .../unix/sysv/linux/x86_64/64/libc.abilist | 1 + .../unix/sysv/linux/x86_64/x32/libc.abilist | 1 + 49 files changed, 517 insertions(+), 1 deletion(-) create mode 100644 dlfcn/dlmem.c create mode 100644 dlfcn/tst-dlmem.c diff --git a/dlfcn/Makefile b/dlfcn/Makefile index 1fa7fea1ef..c6deef6e43 100644 --- a/dlfcn/Makefile +++ b/dlfcn/Makefile @@ -28,6 +28,7 @@ routines = \ dlclose \ dlerror \ dlinfo \ + dlmem \ dlmopen \ dlopen \ dlsym \ @@ -51,7 +52,8 @@ endif ifeq (yes,$(build-shared)) tests = glrefmain failtest tst-dladdr default errmsg1 tstcxaatexit \ bug-dlopen1 bug-dlsym1 tst-dlinfo bug-atexit1 bug-atexit2 \ - bug-atexit3 tstatexit bug-dl-leaf tst-rec-dlopen + bug-atexit3 tstatexit bug-dl-leaf tst-rec-dlopen tst-dlmem +CPPFLAGS-tst-dlmem.c += -DBUILDDIR=\"$(objpfx)\" endif modules-names = glreflib1 glreflib2 glreflib3 failtestmod defaultmod1 \ defaultmod2 errmsg1mod modatexit modcxaatexit \ @@ -102,6 +104,7 @@ $(objpfx)glrefmain.out: $(objpfx)glrefmain \ $(objpfx)failtest.out: $(objpfx)failtestmod.so $(objpfx)tst-dladdr.out: $(objpfx)glreflib1.so +$(objpfx)tst-dlmem.out: $(objpfx)glreflib1.so $(objpfx)tst-dlinfo.out: $(objpfx)glreflib3.so LDFLAGS-glreflib3.so = -Wl,-rpath,: diff --git a/dlfcn/Versions b/dlfcn/Versions index cc34eb824d..b427c9c3a3 100644 --- a/dlfcn/Versions +++ b/dlfcn/Versions @@ -28,6 +28,9 @@ libc { dlsym; dlvsym; } + GLIBC_2.38 { + dlmem; + } GLIBC_PRIVATE { __libc_dlerror_result; _dlerror_run; diff --git a/dlfcn/dlfcn.h b/dlfcn/dlfcn.h index c5d192597d..e517882ebf 100644 --- a/dlfcn/dlfcn.h +++ b/dlfcn/dlfcn.h @@ -68,6 +68,21 @@ extern void *dlsym (void *__restrict __handle, /* Like `dlopen', but request object to be allocated in a new namespace. */ extern void *dlmopen (Lmid_t __nsid, const char *__file, int __mode) __THROWNL; +/* Callback for dlmem. */ +typedef void * +(dlmem_premap_t) (void *mappref, size_t maplength, size_t mapalign, + unsigned prot, void *cookie); + +struct dlmem_args { + Lmid_t nsid; + dlmem_premap_t *premap; + void *cookie; +}; + +/* Like `dlmopen', but loads shared object from memory buffer. */ +extern void *dlmem (const unsigned char *buffer, size_t size, int mode, + struct dlmem_args *dlm_args); + /* Find the run-time address in the shared object HANDLE refers to of the symbol called NAME with VERSION. */ extern void *dlvsym (void *__restrict __handle, diff --git a/dlfcn/dlmem.c b/dlfcn/dlmem.c new file mode 100644 index 0000000000..548f6f34eb --- /dev/null +++ b/dlfcn/dlmem.c @@ -0,0 +1,102 @@ +/* Load a shared object from memory. + Copyright (C) 1995-2022 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include +#include +#include +#include + +struct _dlmem_args +{ + /* The arguments for dlmem_doit. */ + const unsigned char *buffer; + size_t size; + int mode; + struct dlmem_args *args; + /* The return value of dlmem_doit. */ + void *new; + /* Address of the caller. */ + const void *caller; +}; + +static void +dlmem_doit (void *a) +{ + struct _dlmem_args *args = (struct _dlmem_args *) a; + + if (args->mode & ~(RTLD_BINDING_MASK | RTLD_NOLOAD | RTLD_DEEPBIND + | RTLD_GLOBAL | RTLD_LOCAL | RTLD_NODELETE + | __RTLD_SPROF)) + _dl_signal_error (0, NULL, NULL, _("invalid mode parameter")); + + args->new = GLRO(dl_mem) (args->buffer, args->size, + args->mode | __RTLD_DLOPEN, + args->args, + args->caller, + __libc_argc, __libc_argv, __environ); +} + + +static void * +dlmem_implementation (const unsigned char *buffer, size_t size, int mode, + struct dlmem_args *dlm_args, void *dl_caller) +{ + struct _dlmem_args args; + args.buffer = buffer; + args.size = size; + args.mode = mode; + args.args = dlm_args; + args.caller = dl_caller; + + return _dlerror_run (dlmem_doit, &args) ? NULL : args.new; +} + +#ifdef SHARED +void * +___dlmem (const unsigned char *buffer, size_t size, int mode, + struct dlmem_args *dlm_args) +{ + if (GLRO (dl_dlfcn_hook) != NULL) + return GLRO (dl_dlfcn_hook)->dlmem (buffer, size, mode, dlm_args, + RETURN_ADDRESS (0)); + else + return dlmem_implementation (buffer, size, mode, dlm_args, + RETURN_ADDRESS (0)); +} +versioned_symbol (libc, ___dlmem, dlmem, GLIBC_2_38); + +#else /* !SHARED */ +/* Also used with _dlfcn_hook. */ +void * +__dlmem (const unsigned char *buffer, size_t size, int mode, + struct dlmem_args *dlm_args, void *dl_caller) +{ + return dlmem_implementation (buffer, size, mode, dlm_args, dl_caller); +} + +void * +___dlmem (const unsigned char *buffer, size_t size, int mode, + struct dlmem_args *dlm_args) +{ + return __dlmem (buffer, size, mode, dlm_args, RETURN_ADDRESS (0)); +} +weak_alias (___dlmem, dlmem) +static_link_warning (dlmem) +#endif /* !SHARED */ diff --git a/dlfcn/glreflib1.c b/dlfcn/glreflib1.c index f26832fabe..bab3fcd1b0 100644 --- a/dlfcn/glreflib1.c +++ b/dlfcn/glreflib1.c @@ -22,3 +22,5 @@ ref1 (void) { return 42; } + +int bar = 35; diff --git a/dlfcn/tst-dlmem.c b/dlfcn/tst-dlmem.c new file mode 100644 index 0000000000..12209bfe5e --- /dev/null +++ b/dlfcn/tst-dlmem.c @@ -0,0 +1,166 @@ +/* Test for dlmem. + Copyright (C) 2000-2022 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static size_t maplen; + +static void * +premap_dlmem (void *mappref, size_t maplength, size_t mapalign, + unsigned prot, void *cookie) +{ + int fd = * (int *) cookie; + int err; + + /* See if we support such parameters. */ + if (mappref || mapalign > 4096) + return MAP_FAILED; + + fprintf (stderr, "%s\n", __func__); + + err = ftruncate (fd, maplength); + if (err) + error (EXIT_FAILURE, 0, "ftruncate() failed"); + maplen = maplength; + return mmap (NULL, maplength, prot, MAP_SHARED | MAP_FILE +#ifdef MAP_32BIT + | MAP_32BIT +#endif + , fd, 0); +} + +#define TEST_FUNCTION do_test +extern int do_test (void); + +int +do_test (void) +{ + void *handle; + void *addr; + int (*sym) (void); /* We load ref1 from glreflib1.c. */ + int *bar, *bar2; + unsigned char *addr2; + Dl_info info; + int ret; + int fd; + int num; + off_t len; + struct link_map *lm; + const char *shm_name = "/tst-dlmem"; + int shm_fd; + struct dlmem_args a; + + shm_fd = memfd_create (shm_name, 0); + if (shm_fd == -1) + error (EXIT_FAILURE, 0, "shm_open() failed"); + + fd = open (BUILDDIR "glreflib1.so", O_RDONLY); + if (fd == -1) + error (EXIT_FAILURE, 0, "cannot open: glreflib1.so"); + len = lseek (fd, 0, SEEK_END); + lseek (fd, 0, SEEK_SET); + addr = mmap (NULL, len, PROT_READ, MAP_PRIVATE, fd, 0); + if (addr == MAP_FAILED) + error (EXIT_FAILURE, 0, "cannot mmap: glreflib1.so"); + a.nsid = LM_ID_BASE; + a.premap = premap_dlmem; + a.cookie = &shm_fd; + handle = dlmem (addr, len, RTLD_NOW | RTLD_LOCAL, &a); + if (handle == NULL) + error (EXIT_FAILURE, 0, "cannot load: glreflib1.so"); + munmap (addr, len); + close (fd); + /* Check if premap was called. */ + TEST_VERIFY (maplen != 0); + + sym = dlsym (handle, "ref1"); + if (sym == NULL) + error (EXIT_FAILURE, 0, "dlsym failed"); + + memset (&info, 0, sizeof (info)); + ret = dladdr (sym, &info); + if (ret == 0) + error (EXIT_FAILURE, 0, "dladdr failed"); +#ifdef MAP_32BIT + /* Make sure MAP_32BIT worked. */ + if ((unsigned long) info.dli_fbase >= 0x100000000) + error (EXIT_FAILURE, 0, "premap audit didn't work"); +#endif + ret = dlinfo (handle, RTLD_DI_LINKMAP, &lm); + if (ret != 0) + error (EXIT_FAILURE, 0, "dlinfo failed"); + + printf ("info.dli_fname = %p (\"%s\")\n", info.dli_fname, info.dli_fname); + printf ("info.dli_fbase = %p\n", info.dli_fbase); + printf ("info.dli_sname = %p (\"%s\")\n", info.dli_sname, info.dli_sname); + printf ("info.dli_saddr = %p\n", info.dli_saddr); + printf ("lm->l_addr = %lx\n", lm->l_addr); + + if (info.dli_fname == NULL) + error (EXIT_FAILURE, 0, "dli_fname is NULL"); + if (info.dli_fbase == NULL) + error (EXIT_FAILURE, 0, "dli_fbase is NULL"); + if (info.dli_sname == NULL) + error (EXIT_FAILURE, 0, "dli_sname is NULL"); + if (info.dli_saddr == NULL) + error (EXIT_FAILURE, 0, "dli_saddr is NULL"); + + num = sym (); + if (num != 42) + error (EXIT_FAILURE, 0, "bad return from ref1"); + + /* Now try symbol duplication. */ + bar = dlsym (handle, "bar"); + if (bar == NULL) + error (EXIT_FAILURE, 0, "dlsym failed"); + TEST_COMPARE (*bar, 35); + /* write another value */ +#define TEST_BAR_VAL 48 + *bar = TEST_BAR_VAL; + + /* Create second instance of the solib. */ + addr2 = mmap (NULL, maplen, PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_SHARED, shm_fd, 0); + if (addr2 == MAP_FAILED) + error (EXIT_FAILURE, 0, "cannot mmap shm\n"); + /* Find our bar symbol duplicate. */ + ret = dladdr (bar, &info); + if (ret == 0) + error (EXIT_FAILURE, 0, "dladdr failed"); + bar2 = (int *) (addr2 + (info.dli_saddr - info.dli_fbase)); + /* See if we found the right one. */ + TEST_COMPARE (*bar2, TEST_BAR_VAL); + + munmap (addr2, maplen); + dlclose (handle); + + return 0; +} + + +#include diff --git a/elf/dl-load.c b/elf/dl-load.c index 4b40a92864..6ce118787f 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -75,6 +75,7 @@ struct filebuf #include #include #include +#include #include #include @@ -2344,6 +2345,153 @@ _dl_map_object (struct link_map *loader, const char *name, return __dl_map_object (loader, name, NULL, type, trace_mode, mode, nsid); } +static void * +do_mmapcpy (void *addr, size_t length, int prot, int flags, + void *arg, off_t offset) +{ + const struct dlmem_fbuf *fb = arg; + + assert (flags & MAP_FIXED); + if (__mprotect (addr, length, PROT_READ | PROT_WRITE) == -1) + return MAP_FAILED; + if (offset < fb->len) + { + size_t to_copy = length; + if (offset + to_copy > fb->len) + to_copy = fb->len - offset; + memcpy (addr, fb->buf + offset, to_copy); + } + if (__mprotect (addr, length, prot) == -1) + return MAP_FAILED; + return addr; +} + +static void * +do_dlmem_premap (void *mappref, size_t maplength, size_t mapalign, + unsigned prot, void *cookie) +{ + struct dlmem_fbuf *fb = cookie; + void *ret = MAP_FAILED; + + if (fb->dlm_args && fb->dlm_args->premap) + ret = fb->dlm_args->premap (mappref, maplength, mapalign, prot, + fb->dlm_args->cookie); + if (ret == MAP_FAILED) + ret = (void *) _dl_map_segment ((ElfW(Addr)) mappref, maplength, + mapalign, prot); + return ret; +} + +static ssize_t +do_pread_memcpy (void *arg, void *buf, size_t count, off_t offset) +{ + struct dlmem_fbuf *fb = arg; + if (offset >= fb->len) + return -1; + if (offset + count > fb->len) + count = fb->len - offset; + if (count) + memcpy (buf, fb->buf + offset, count); + return count; +} + +static struct link_map * +___dl_map_object_from_mem (struct link_map *loader, const char *name, + void *private, int type, int trace_mode, + int mode, Lmid_t nsid, struct filebuf *fbp) +{ + struct link_map *l; + int err; + /* Initialize to keep the compiler happy. */ + const char *errstring = NULL; + int errval = 0; + struct r_debug *r = _dl_debug_update (nsid); + bool make_consistent = false; + struct r_file_id id = {}; + + assert (nsid >= 0); + assert (nsid < GL(dl_nns)); + + /* Will be true if we found a DSO which is of the other ELF class. */ + bool found_other_class = false; + + err = do_open_verify (name, private, fbp, + loader ?: GL(dl_ns)[nsid]._ns_loaded, + &found_other_class, false, do_pread_memcpy); + if (err) + return NULL; + + /* In case the LOADER information has only been provided to get to + the appropriate RUNPATH/RPATH information we do not need it + anymore. */ + if (mode & __RTLD_CALLMAP) + loader = NULL; + + if (mode & RTLD_NOLOAD) + { + /* We are not supposed to load the object unless it is already + loaded. So return now. */ + return NULL; + } + + /* Print debugging message. */ + if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES)) + _dl_debug_printf ("dlmem [%lu]; generating link map\n", nsid); + + /* Enter the new object in the list of loaded objects. */ + l = _dl_new_object ((char *) name, name, type, loader, mode, nsid); + if (__glibc_unlikely (l == NULL)) + { + errstring = N_("cannot create shared object descriptor"); + goto lose_errno; + } + + void *stack_end = __libc_stack_end; + if (_ld_map_object_1 (l, private, fbp, mode, loader, &stack_end, &errval, + &errstring, do_mmapcpy, do_dlmem_premap)) + goto lose; + + _ld_map_object_2 (l, mode, id, NULL, nsid, r, &make_consistent); + return l; + +lose_errno: + errval = errno; +lose: + if (l != NULL && l->l_map_start != 0) + _dl_unmap_segments (l); + if (l != NULL && l->l_origin != (char *) -1l) + free ((char *) l->l_origin); + if (l != NULL && !l->l_libname->dont_free) + free (l->l_libname); + if (l != NULL && l->l_phdr_allocated) + free ((void *) l->l_phdr); + free (l); + + if (make_consistent && r != NULL) + { + r->r_state = RT_CONSISTENT; + _dl_debug_state (); + LIBC_PROBE (map_failed, 2, nsid, r); + } + + _dl_signal_error (errval, NULL, NULL, errstring); + return NULL; +} + +struct link_map * +__dl_map_object_from_mem (struct link_map *loader, const char *name, + void *private, int type, int trace_mode, + int mode, Lmid_t nsid) +{ + struct link_map *ret; + struct filebuf fb = {}; + + ret = ___dl_map_object_from_mem (loader, name, private, type, trace_mode, + mode, nsid, &fb); + filebuf_done (&fb); + return ret; +} + struct add_path_state { bool counting; diff --git a/elf/dl-load.h b/elf/dl-load.h index 00d74979e6..20b7411027 100644 --- a/elf/dl-load.h +++ b/elf/dl-load.h @@ -107,6 +107,9 @@ _dl_postprocess_loadcmd (struct link_map *l, const ElfW(Ehdr) *header, - c->mapoff); } +static void * +do_mmap (void *addr, size_t length, int prot, int flags, + void *arg, off_t offset); /* This is a subroutine of _dl_map_object_from_fd. It is responsible for filling in several fields in *L: l_map_start, l_map_end, l_addr, diff --git a/elf/dl-main.h b/elf/dl-main.h index 344a87d5e8..e60fafaeb6 100644 --- a/elf/dl-main.h +++ b/elf/dl-main.h @@ -104,6 +104,13 @@ struct dl_main_state bool version_info; }; +struct dlmem_fbuf +{ + ssize_t len; + const unsigned char *buf; + struct dlmem_args *dlm_args; +}; + /* Open the shared object NAME and map in its segments. LOADER's DT_RPATH is used in searching for NAME. If the object is already opened, returns its existing map. */ @@ -112,6 +119,11 @@ __dl_map_object (struct link_map *loader, const char *name, void *private, int type, int trace_mode, int mode, Lmid_t nsid) attribute_hidden; +extern struct link_map * +__dl_map_object_from_mem (struct link_map *loader, + const char *name, void *private, + int type, int trace_mode, int mode, + Lmid_t nsid) attribute_hidden; /* Helper function to invoke _dl_init_paths with the right arguments from *STATE. */ diff --git a/elf/dl-open.c b/elf/dl-open.c index f3886c21bc..537a1e6003 100644 --- a/elf/dl-open.c +++ b/elf/dl-open.c @@ -953,6 +953,18 @@ _dl_open (const char *file, int mode, const void *caller_dlopen, Lmid_t nsid, __dl_map_object); } +void * +_dl_mem (const unsigned char *buffer, size_t size, int mode, + struct dlmem_args *dlm_args, const void *caller_dlopen, + int argc, char *argv[], char *env[]) +{ + struct dlmem_fbuf fb = { .buf = buffer, .len = size, .dlm_args = dlm_args }; + Lmid_t nsid = dlm_args ? dlm_args->nsid : LM_ID_BASE; + + return do_dl_open ("", &fb, mode, caller_dlopen, nsid, argc, argv, env, + __dl_map_object_from_mem); +} + void _dl_show_scope (struct link_map *l, int from) { diff --git a/elf/rtld.c b/elf/rtld.c index f82fbeb132..1877ec9f16 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -370,6 +370,7 @@ struct rtld_global_ro _rtld_global_ro attribute_relro = ._dl_mcount = _dl_mcount, ._dl_lookup_symbol_x = _dl_lookup_symbol_x, ._dl_open = _dl_open, + ._dl_mem = _dl_mem, ._dl_close = _dl_close, ._dl_catch_error = _dl_catch_error, ._dl_error_free = _dl_error_free, diff --git a/include/dlfcn.h b/include/dlfcn.h index ae25f05303..6205cf407d 100644 --- a/include/dlfcn.h +++ b/include/dlfcn.h @@ -100,6 +100,8 @@ struct dlfcn_hook { /* Public interfaces. */ void *(*dlopen) (const char *file, int mode, void *dl_caller); + void *(*dlmem) (const unsigned char *buffer, size_t size, int mode, + struct dlmem_args *dlm_args, void *dl_caller); int (*dlclose) (void *handle); void *(*dlsym) (void *handle, const char *name, void *dl_caller); void *(*dlvsym) (void *handle, const char *name, const char *version, @@ -123,6 +125,8 @@ struct dlfcn_hook the __libc_dl* functions defined in elf/dl-libc.c instead. */ extern void *__dlopen (const char *file, int mode, void *caller); +extern void *__dlmem (const unsigned char *file, size_t size, int mode, + struct dlmem_args *dlm_args, void *caller); extern void *__dlmopen (Lmid_t nsid, const char *file, int mode, void *dl_caller); extern int __dlclose (void *handle); diff --git a/manual/dynlink.texi b/manual/dynlink.texi index 6a4a50d3f0..21bc6c067c 100644 --- a/manual/dynlink.texi +++ b/manual/dynlink.texi @@ -209,6 +209,7 @@ This function is a GNU extension. @c dladdr1 @c dlclose @c dlerror +@c dlmem @c dlmopen @c dlopen @c dlsym diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index c99dad77cc..abca95b18c 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -669,6 +669,9 @@ struct rtld_global_ro struct link_map *); void *(*_dl_open) (const char *file, int mode, const void *caller_dlopen, Lmid_t nsid, int argc, char *argv[], char *env[]); + void *(*_dl_mem) (const unsigned char *buffer, size_t size, int mode, + struct dlmem_args *dlm_args, const void *caller_dlopen, + int argc, char *argv[], char *env[]); void (*_dl_close) (void *map); /* libdl in a secondary namespace (after dlopen) must use _dl_catch_error from the main namespace, so it has to be @@ -1249,6 +1252,12 @@ extern void *_dl_open (const char *name, int mode, const void *caller, Lmid_t nsid, int argc, char *argv[], char *env[]) attribute_hidden; +/* Open shared object from memory buffer. */ +extern void *_dl_mem (const unsigned char *buffer, size_t size, int mode, + struct dlmem_args *dlm_args, const void *caller, + int argc, char *argv[], char *env[]) + attribute_hidden; + /* Free or queue for freeing scope OLD. If other threads might be in the middle of _dl_fixup, _dl_profile_fixup or dl*sym using the old scope, OLD can't be freed until no thread is using it. */ diff --git a/sysdeps/mach/hurd/i386/libc.abilist b/sysdeps/mach/hurd/i386/libc.abilist index ed0c4789eb..1880004336 100644 --- a/sysdeps/mach/hurd/i386/libc.abilist +++ b/sysdeps/mach/hurd/i386/libc.abilist @@ -2326,6 +2326,7 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist index 0e2d9c3045..c4d31cabed 100644 --- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist +++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist @@ -2665,3 +2665,4 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist index f1bec1978d..93b37a1e1d 100644 --- a/sysdeps/unix/sysv/linux/alpha/libc.abilist +++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist @@ -2774,6 +2774,7 @@ GLIBC_2.38 __nldbl___isoc23_vsscanf F GLIBC_2.38 __nldbl___isoc23_vswscanf F GLIBC_2.38 __nldbl___isoc23_vwscanf F GLIBC_2.38 __nldbl___isoc23_wscanf F +GLIBC_2.38 dlmem F GLIBC_2.4 _IO_fprintf F GLIBC_2.4 _IO_printf F GLIBC_2.4 _IO_sprintf F diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist index aa874b88d0..9fec2308c3 100644 --- a/sysdeps/unix/sysv/linux/arc/libc.abilist +++ b/sysdeps/unix/sysv/linux/arc/libc.abilist @@ -2426,3 +2426,4 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist index afbd57da6f..bd0f04e58a 100644 --- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist @@ -546,6 +546,7 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F GLIBC_2.4 _Exit F GLIBC_2.4 _IO_2_1_stderr_ D 0xa0 GLIBC_2.4 _IO_2_1_stdin_ D 0xa0 diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist index e7364cd3fe..dccc49c8d6 100644 --- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist @@ -543,6 +543,7 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F GLIBC_2.4 _Exit F GLIBC_2.4 _IO_2_1_stderr_ D 0xa0 GLIBC_2.4 _IO_2_1_stdin_ D 0xa0 diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist index 913fa59215..0df8524ac0 100644 --- a/sysdeps/unix/sysv/linux/csky/libc.abilist +++ b/sysdeps/unix/sysv/linux/csky/libc.abilist @@ -2702,3 +2702,4 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist index 43af3a9811..fa4680e97a 100644 --- a/sysdeps/unix/sysv/linux/hppa/libc.abilist +++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist @@ -2651,6 +2651,7 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist index af72f8fab0..bfb1bde49d 100644 --- a/sysdeps/unix/sysv/linux/i386/libc.abilist +++ b/sysdeps/unix/sysv/linux/i386/libc.abilist @@ -2835,6 +2835,7 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/ia64/libc.abilist b/sysdeps/unix/sysv/linux/ia64/libc.abilist index 48cbb0fa50..e53505abe0 100644 --- a/sysdeps/unix/sysv/linux/ia64/libc.abilist +++ b/sysdeps/unix/sysv/linux/ia64/libc.abilist @@ -2600,6 +2600,7 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist b/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist index c15884bb0b..9f56cbdcab 100644 --- a/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist +++ b/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist @@ -2186,3 +2186,4 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist index 3738db81df..d5443b1198 100644 --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist @@ -547,6 +547,7 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F GLIBC_2.4 _Exit F GLIBC_2.4 _IO_2_1_stderr_ D 0x98 GLIBC_2.4 _IO_2_1_stdin_ D 0x98 diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist index ed13627752..640c8b8c4a 100644 --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist @@ -2778,6 +2778,7 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist index 8357738621..79b400efc6 100644 --- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist @@ -2751,3 +2751,4 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist index 58c5da583d..38b4098950 100644 --- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist @@ -2748,3 +2748,4 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist index d3741945cd..9a4f909a25 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist @@ -2743,6 +2743,7 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist index 5319fdc204..c8b9f85fdb 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist @@ -2741,6 +2741,7 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist index 1743ea6eb9..0887b67394 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist @@ -2749,6 +2749,7 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist index 9b1f53c6ac..1c3a6f4bee 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist @@ -2651,6 +2651,7 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/nios2/libc.abilist b/sysdeps/unix/sysv/linux/nios2/libc.abilist index ae1c6ca1b5..31b23859a4 100644 --- a/sysdeps/unix/sysv/linux/nios2/libc.abilist +++ b/sysdeps/unix/sysv/linux/nios2/libc.abilist @@ -2790,3 +2790,4 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F diff --git a/sysdeps/unix/sysv/linux/or1k/libc.abilist b/sysdeps/unix/sysv/linux/or1k/libc.abilist index a7c572c947..59f4aa7766 100644 --- a/sysdeps/unix/sysv/linux/or1k/libc.abilist +++ b/sysdeps/unix/sysv/linux/or1k/libc.abilist @@ -2172,3 +2172,4 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist index 074fa031a7..d715d0ae97 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist @@ -2817,6 +2817,7 @@ GLIBC_2.38 __nldbl___isoc23_vsscanf F GLIBC_2.38 __nldbl___isoc23_vswscanf F GLIBC_2.38 __nldbl___isoc23_vwscanf F GLIBC_2.38 __nldbl___isoc23_wscanf F +GLIBC_2.38 dlmem F GLIBC_2.4 _IO_fprintf F GLIBC_2.4 _IO_printf F GLIBC_2.4 _IO_sprintf F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist index dfcb4bd2d5..3addcf3d17 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist @@ -2850,6 +2850,7 @@ GLIBC_2.38 __nldbl___isoc23_vsscanf F GLIBC_2.38 __nldbl___isoc23_vswscanf F GLIBC_2.38 __nldbl___isoc23_vwscanf F GLIBC_2.38 __nldbl___isoc23_wscanf F +GLIBC_2.38 dlmem F GLIBC_2.4 _IO_fprintf F GLIBC_2.4 _IO_printf F GLIBC_2.4 _IO_sprintf F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist index 63bbccf3f9..5365978277 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist @@ -2571,6 +2571,7 @@ GLIBC_2.38 __nldbl___isoc23_vsscanf F GLIBC_2.38 __nldbl___isoc23_vswscanf F GLIBC_2.38 __nldbl___isoc23_vwscanf F GLIBC_2.38 __nldbl___isoc23_wscanf F +GLIBC_2.38 dlmem F GLIBC_2.4 _IO_fprintf F GLIBC_2.4 _IO_printf F GLIBC_2.4 _IO_sprintf F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist index ab85fd61ef..f0af576192 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist @@ -2885,3 +2885,4 @@ GLIBC_2.38 __nldbl___isoc23_vsscanf F GLIBC_2.38 __nldbl___isoc23_vswscanf F GLIBC_2.38 __nldbl___isoc23_vwscanf F GLIBC_2.38 __nldbl___isoc23_wscanf F +GLIBC_2.38 dlmem F diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist index b716f5c763..941fd40ea8 100644 --- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist +++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist @@ -2428,3 +2428,4 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist index 774e777b65..74f58439ad 100644 --- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist +++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist @@ -2628,3 +2628,4 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist index 8625135c48..cf3a10aa76 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist @@ -2815,6 +2815,7 @@ GLIBC_2.38 __nldbl___isoc23_vsscanf F GLIBC_2.38 __nldbl___isoc23_vswscanf F GLIBC_2.38 __nldbl___isoc23_vwscanf F GLIBC_2.38 __nldbl___isoc23_wscanf F +GLIBC_2.38 dlmem F GLIBC_2.4 _IO_fprintf F GLIBC_2.4 _IO_printf F GLIBC_2.4 _IO_sprintf F diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist index d00c7eb262..2ad97f87b2 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist @@ -2608,6 +2608,7 @@ GLIBC_2.38 __nldbl___isoc23_vsscanf F GLIBC_2.38 __nldbl___isoc23_vswscanf F GLIBC_2.38 __nldbl___isoc23_vwscanf F GLIBC_2.38 __nldbl___isoc23_wscanf F +GLIBC_2.38 dlmem F GLIBC_2.4 _IO_fprintf F GLIBC_2.4 _IO_printf F GLIBC_2.4 _IO_sprintf F diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist index b63037241d..7c81b94953 100644 --- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist @@ -2658,6 +2658,7 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist index d80055617d..0493d6b456 100644 --- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist @@ -2655,6 +2655,7 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist index 5be55c11d2..6fd09f6499 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist @@ -2810,6 +2810,7 @@ GLIBC_2.38 __nldbl___isoc23_vsscanf F GLIBC_2.38 __nldbl___isoc23_vswscanf F GLIBC_2.38 __nldbl___isoc23_vwscanf F GLIBC_2.38 __nldbl___isoc23_wscanf F +GLIBC_2.38 dlmem F GLIBC_2.4 _IO_fprintf F GLIBC_2.4 _IO_printf F GLIBC_2.4 _IO_sprintf F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist index 475fdaae15..24dbc4801f 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist @@ -2623,6 +2623,7 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist index 6cfb928bc8..522ca8e8aa 100644 --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist @@ -2574,6 +2574,7 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F GLIBC_2.4 __confstr_chk F GLIBC_2.4 __fgets_chk F GLIBC_2.4 __fgets_unlocked_chk F diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist index c735097172..42b170c805 100644 --- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist @@ -2680,3 +2680,4 @@ GLIBC_2.38 __isoc23_wcstoull F GLIBC_2.38 __isoc23_wcstoull_l F GLIBC_2.38 __isoc23_wcstoumax F GLIBC_2.38 __isoc23_wscanf F +GLIBC_2.38 dlmem F