about summary refs log tree commit diff
path: root/dlfcn/dlinfo.c
diff options
context:
space:
mode:
authorFlorian Weimer <fweimer@redhat.com>2022-04-29 17:00:53 +0200
committerFlorian Weimer <fweimer@redhat.com>2022-04-29 17:00:53 +0200
commitd056c212130280c0a54d9a4f72170ec621b70ce5 (patch)
treef7d368b4f45bcb3eba90b5e89e19ba36b1f68fe1 /dlfcn/dlinfo.c
parent93804a1ee084d4bdc620b2b9f91615c7da0fabe1 (diff)
downloadglibc-d056c212130280c0a54d9a4f72170ec621b70ce5.tar.gz
glibc-d056c212130280c0a54d9a4f72170ec621b70ce5.tar.xz
glibc-d056c212130280c0a54d9a4f72170ec621b70ce5.zip
dlfcn: Implement the RTLD_DI_PHDR request type for dlinfo
The information is theoretically available via dl_iterate_phdr as
well, but that approach is very slow if there are many shared
objects.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Tested-by: Carlos O'Donell <carlos@rehdat.com>
Diffstat (limited to 'dlfcn/dlinfo.c')
-rw-r--r--dlfcn/dlinfo.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/dlfcn/dlinfo.c b/dlfcn/dlinfo.c
index 068db5260c..0fbe670d67 100644
--- a/dlfcn/dlinfo.c
+++ b/dlfcn/dlinfo.c
@@ -28,6 +28,10 @@ struct dlinfo_args
   void *handle;
   int request;
   void *arg;
+
+  /* This is the value that is returned from dlinfo if no error is
+     signaled.  */
+  int result;
 };
 
 static void
@@ -40,6 +44,7 @@ dlinfo_doit (void *argsblock)
     {
     case RTLD_DI_CONFIGADDR:
     default:
+      args->result = -1;
       _dl_signal_error (0, NULL, NULL, N_("unsupported dlinfo request"));
       break;
 
@@ -75,6 +80,11 @@ dlinfo_doit (void *argsblock)
 	*(void **) args->arg = data;
 	break;
       }
+
+    case RTLD_DI_PHDR:
+      *(const ElfW(Phdr) **) args->arg = l->l_phdr;
+      args->result = l->l_phnum;
+      break;
     }
 }
 
@@ -82,7 +92,8 @@ static int
 dlinfo_implementation (void *handle, int request, void *arg)
 {
   struct dlinfo_args args = { handle, request, arg };
-  return _dlerror_run (&dlinfo_doit, &args) ? -1 : 0;
+  _dlerror_run (&dlinfo_doit, &args);
+  return args.result;
 }
 
 #ifdef SHARED