From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 5BC273858D32; Mon, 8 May 2023 14:51:10 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 5BC273858D32 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1683557470; bh=7q4D+e1M9vieVflYtzqsflACaFJXzehQbWN3YOEhcA4=; h=From:To:Subject:Date:In-Reply-To:References:From; b=jxkytZSVzHzkOP05isx1UN1ZFg9Qf6vtpdTF1aj/meXo03prjz+6wI/9QC0cXXpBy 0tv+g8YOo+CAFHXrNjuTokUp2UV3tEm5ZsPCY7aYlAxxtlI5EiN31jXaZPGKKQJ8kw 30WCWdIJiluZ2NkFa63lKLj9vjrSC1EG4nw9u3Ds= From: "stsp at users dot sourceforge.net" To: glibc-bugs@sourceware.org Subject: [Bug dynamic-link/30007] rfe: dlopen to specified address Date: Mon, 08 May 2023 14:51:08 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: glibc X-Bugzilla-Component: dynamic-link X-Bugzilla-Version: unspecified X-Bugzilla-Keywords: X-Bugzilla-Severity: enhancement X-Bugzilla-Who: stsp at users dot sourceforge.net X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Resolution: X-Bugzilla-Priority: P2 X-Bugzilla-Assigned-To: unassigned at sourceware dot org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: attachments.isobsolete attachments.created Message-ID: In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://sourceware.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 List-Id: https://sourceware.org/bugzilla/show_bug.cgi?id=3D30007 Stas Sergeev changed: What |Removed |Added ---------------------------------------------------------------------------- Attachment #14753|0 |1 is obsolete| | Attachment #14795|0 |1 is obsolete| | Attachment #14799|0 |1 is obsolete| | --- Comment #37 from Stas Sergeev --- Created attachment 14867 --> https://sourceware.org/bugzilla/attachment.cgi?id=3D14867&action=3Ded= it patches RTLD_NORELOCATE api is a proposal that adds a fine-grained control over the solib dynamic-load process. It allows the user to load the solib to the particular address he needs, using the mapping type he needs. The basic idea is that after loading the solib with RTLD_NORELOCATE flag, the user can move an unrelocated object before relocating it. The API consist of the following elements: `RTLD_NORELOCATE' - new dlopen() flag. It defers the relocation of an object, allowing to perform the relocation later. Ctors are delayed, and are called immediately after the relocation is done. Relocation is performed upon the first dlsym() or dlrelocate() call with the obtained handle. This flag doesn't delay the load of an object deps, but their relocation and ctors are delayed. This flag doesn't delay the LA_ACT_CONSISTENT audit event. `int dlrelocate(void *handle)' - new function to perform the object relocation if the RTLD_NORELOCATE flag was used. The object itself and all of its dependencies are relocated. Returns EINVAL if already relocated. This function may be omitted even if RTLD_NORELOCATE was used, in which case the relocation will be performed upon the first dlsym() call with the obtained handle, but using dlrelocate() function allows to handle relocation errors and run ctors before using the object's handle. If the function returned success then ctors of an object and all of its deps were called by it. If it returned error other than EINVAL (EINVAL means object already relocated), then relocation error happened and the handle should be closed with dlclose(). `RTLD_DI_MAPINFO' - new dlinfo() request that fills in this structure: typedef struct { void *map_start; /* Beginning of mapping containing address.= */ size_t map_length; /* Length of mapping. */ size_t map_align; /* Alignment of mapping. */ int relocated; /* Indicates whether an object was relocate= d. */ } Dl_mapinfo; The user have to check the `relocated` member, and if it is 0 then the object can be moved to the new location. The new location must be aligned according to the `map_aligned' member, which is usually equal to a page size. One way to move a solib image is to use mmap() for allocating a new memory mapping, then use memcpy() to copy an image, and finally use munmap() to unmap the memory space at an old location. This request may fail if the used handle was not obtained from dlopen(). `int dlset_object_base(void *handle, void *addr)' - new function to set the new base address of an unrelocated object, after it was moved. Returns error if the object is already relocated. The base address set by this function, will be used when relocation is performed. `RTLD_DI_DEPLIST' is a new dlinfo() request that fills in this structure: typedef struct { void **deps; /* Array of handles for the deps. */ unsigned int ndeps; /* Number of entries in the list. */ } Dl_deplist; It is needed if the user wants to move also the dependencies of the loaded solib. In this case he needs to traverse the `deps' array, make RTLD_DI_MAPINFO dlinfo() request per each handle from an array, find the object he needs by inspecting the filled-in Dl_mapinfo structure, make sure this object is not relocated yet, and move it, calling dlset_object_base() at the end. Use-case. Suppose you have a VM that runs a 32bit code. Suppose you wrote a compatibility layer that allows to compile the old 32bit non-unix code under linux, into the native 64bit shared libraries. But compiling is not enough and some calls should still go to a VM. VM's memory is available in a 4Gb window somewhere in a 64bit space. In order for the code under VM to handle the calls from a 64bit solib, you need to make sure all pointers, that may be passed as a call arguments, are within 32 bits. Heap and stack are dealt with by a custom libc, but in order to use pointers to .bss objects, we need to relocate the solib to the low 32bit address. But that's not enough, because in order for that lib to be visible to the code under VM, it must also be mirrored to the VM window under the map_address =3D reloc_address+VM_window_start. RTLD_NORELOCATE solves that problem by allowing the user to mmap the shared memory into the low 32bit address space and move an object there. He may want to do so for all the library deps as well (using RTLD_DI_DEPLIS= T), or only with the ones he is interested in. Then he maps the shared memory into the VM window and either calls dlrelocate() or just starts using the solib, in which case it will be relocated on the first symbol lookup. Stas Sergeev (14): elf: switch _dl_map_segment() to anonymous mapping use initial mmap also for ET_EXEC rework maphole split do_reloc_1() from dl_open_worker_begin() split do_reloc_2() out of do_open_worker() move relocation into _dl_object_reloc() func split out _dl_finalize_segments() finalize elf segments on a relocation step implement RTLD_NORELOCATE flag add test-case for RTLD_NORELOCATE implement dlrelocate() implement RTLD_DI_MAPINFO implement dlset_object_base() implement RTLD_DI_DEPLIST bits/dlfcn.h | 3 + dlfcn/Makefile | 11 +- dlfcn/Versions | 4 + dlfcn/ctorlib1.c | 39 ++ dlfcn/dlfcn.h | 34 +- dlfcn/dlinfo.c | 28 ++ dlfcn/dlopen.c | 2 +- dlfcn/dlrelocate.c | 68 +++ dlfcn/dlset_object_base.c | 124 ++++++ dlfcn/tst-noreloc.c | 157 +++++++ elf/dl-close.c | 3 + elf/dl-load.c | 35 +- elf/dl-load.h | 8 +- elf/dl-lookup.c | 6 +- elf/dl-main.h | 2 + elf/dl-map-segments.h | 169 +++++--- elf/dl-open.c | 386 +++++++++++------- elf/rtld.c | 1 + include/dlfcn.h | 11 + include/link.h | 6 + sysdeps/generic/ldsodefs.h | 1 + sysdeps/mach/hurd/i386/libc.abilist | 2 + sysdeps/unix/sysv/linux/aarch64/libc.abilist | 2 + sysdeps/unix/sysv/linux/alpha/libc.abilist | 2 + sysdeps/unix/sysv/linux/arc/libc.abilist | 2 + sysdeps/unix/sysv/linux/arm/be/libc.abilist | 2 + sysdeps/unix/sysv/linux/arm/le/libc.abilist | 2 + sysdeps/unix/sysv/linux/csky/libc.abilist | 2 + sysdeps/unix/sysv/linux/hppa/libc.abilist | 2 + sysdeps/unix/sysv/linux/i386/libc.abilist | 2 + sysdeps/unix/sysv/linux/ia64/libc.abilist | 2 + .../sysv/linux/loongarch/lp64/libc.abilist | 2 + .../sysv/linux/m68k/coldfire/libc.abilist | 2 + .../unix/sysv/linux/m68k/m680x0/libc.abilist | 2 + .../sysv/linux/microblaze/be/libc.abilist | 2 + .../sysv/linux/microblaze/le/libc.abilist | 2 + .../sysv/linux/mips/mips32/fpu/libc.abilist | 2 + .../sysv/linux/mips/mips32/nofpu/libc.abilist | 2 + .../sysv/linux/mips/mips64/n32/libc.abilist | 2 + .../sysv/linux/mips/mips64/n64/libc.abilist | 2 + sysdeps/unix/sysv/linux/nios2/libc.abilist | 2 + sysdeps/unix/sysv/linux/or1k/libc.abilist | 2 + .../linux/powerpc/powerpc32/fpu/libc.abilist | 2 + .../powerpc/powerpc32/nofpu/libc.abilist | 2 + .../linux/powerpc/powerpc64/be/libc.abilist | 2 + .../linux/powerpc/powerpc64/le/libc.abilist | 2 + .../unix/sysv/linux/riscv/rv32/libc.abilist | 2 + .../unix/sysv/linux/riscv/rv64/libc.abilist | 2 + .../unix/sysv/linux/s390/s390-32/libc.abilist | 2 + .../unix/sysv/linux/s390/s390-64/libc.abilist | 2 + sysdeps/unix/sysv/linux/sh/be/libc.abilist | 2 + sysdeps/unix/sysv/linux/sh/le/libc.abilist | 2 + .../sysv/linux/sparc/sparc32/libc.abilist | 2 + .../sysv/linux/sparc/sparc64/libc.abilist | 2 + .../unix/sysv/linux/x86_64/64/libc.abilist | 2 + .../unix/sysv/linux/x86_64/x32/libc.abilist | 2 + 56 files changed, 941 insertions(+), 227 deletions(-) create mode 100644 dlfcn/ctorlib1.c create mode 100644 dlfcn/dlrelocate.c create mode 100644 dlfcn/dlset_object_base.c create mode 100644 dlfcn/tst-noreloc.c --=20 2.39.2 --=20 You are receiving this mail because: You are on the CC list for the bug.=