diff mbox series

[12/14] implement RTLD_DI_MAPINFO dlinfo() request

Message ID 20230518082854.3903342-13-stsp2@yandex.ru
State New
Headers show
Series implement RTLD_NORELOCATE api [BZ #30007] | expand

Commit Message

stsp May 18, 2023, 8:28 a.m. UTC
This request fills in the following 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 relocated. */
} Dl_mapinfo;

This structure allows the user to move an unrelocated object.

The test-suite was run on x86_64/64 and showed no regressions.

Signed-off-by: Stas Sergeev <stsp2@yandex.ru>
---
 dlfcn/dlfcn.h  | 15 ++++++++++++++-
 dlfcn/dlinfo.c | 18 ++++++++++++++++++
 2 files changed, 32 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/dlfcn/dlfcn.h b/dlfcn/dlfcn.h
index c3e228c667..7671c187a3 100644
--- a/dlfcn/dlfcn.h
+++ b/dlfcn/dlfcn.h
@@ -170,7 +170,12 @@  enum
        the number of program headers in the array.  */
     RTLD_DI_PHDR = 11,
 
-    RTLD_DI_MAX = 11
+    /* Treat ARG as Dl_mapinfo *, and store the mapping information
+       at that location.  The dlinfo call returns 0 on success or
+       -1 on failure.  */
+    RTLD_DI_MAPINFO = 12,
+
+    RTLD_DI_MAX = 12
   };
 
 
@@ -203,6 +208,14 @@  typedef struct
 # endif
 } Dl_serinfo;
 
+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 relocated. */
+} Dl_mapinfo;
+
 struct dl_find_object
 {
   __extension__ unsigned long long int dlfo_flags;
diff --git a/dlfcn/dlinfo.c b/dlfcn/dlinfo.c
index 1b5dd90ae5..8d7db7dbb8 100644
--- a/dlfcn/dlinfo.c
+++ b/dlfcn/dlinfo.c
@@ -85,6 +85,24 @@  dlinfo_doit (void *argsblock)
       *(const ElfW(Phdr) **) args->arg = l->l_phdr;
       args->result = l->l_phnum;
       break;
+
+    case RTLD_DI_MAPINFO:
+      {
+	Dl_mapinfo *info = (Dl_mapinfo *) args->arg;
+	__rtld_lock_lock_recursive (GL(dl_load_lock));
+	if (l->l_contiguous)
+	  {
+	    info->map_start = (void *) l->l_map_start;
+	    info->map_length = l->l_map_end - l->l_map_start;
+	    info->map_align = l->l_map_align;
+	    info->relocated = l->l_relocated;
+	    args->result = 0;
+	  }
+	else
+	  args->result = -1;
+	__rtld_lock_unlock_recursive (GL(dl_load_lock));
+	break;
+      }
     }
 }