]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
elf: Introduce _dl_debug_change_state
authorFlorian Weimer <fweimer@redhat.com>
Fri, 4 Jul 2025 19:46:16 +0000 (21:46 +0200)
committerFlorian Weimer <fweimer@redhat.com>
Mon, 18 Aug 2025 11:12:28 +0000 (13:12 +0200)
It combines updating r_state with the debugger notification.

The second change to  _dl_open introduces an additional debugger
notification for dlmopen, but debuggers are expected to ignore it.

Reviewed-by: H.J. Lu <hjl.tools@gmail.com>
(cherry picked from commit 8329939a37f483a16013dd8af8303cbcb86d92cb)

elf/dl-close.c
elf/dl-debug.c
elf/dl-load.c
elf/dl-open.c
elf/rtld.c
sysdeps/generic/ldsodefs.h

index 4c963097f4dc8d79e7d6f98e3d5ba36d61fe0b5e..fb27a1231c1c5b66d7f2f97ea6b6aaa8122d5bb5 100644 (file)
@@ -433,8 +433,7 @@ _dl_close_worker (struct link_map *map, bool force)
   /* Notify the debugger we are about to remove some loaded objects.
      LA_ACT_DELETE has already been signalled above for !unload_any.  */
   struct r_debug *r = _dl_debug_update (nsid);
-  r->r_state = RT_DELETE;
-  _dl_debug_state ();
+  _dl_debug_change_state (r, RT_DELETE);
   LIBC_PROBE (unmap_start, 2, nsid, r);
 
   if (unload_global)
@@ -726,8 +725,7 @@ _dl_close_worker (struct link_map *map, bool force)
   __rtld_lock_unlock_recursive (GL(dl_load_tls_lock));
 
   /* Notify the debugger those objects are finalized and gone.  */
-  r->r_state = RT_CONSISTENT;
-  _dl_debug_state ();
+  _dl_debug_change_state (r, RT_CONSISTENT);
   LIBC_PROBE (unmap_complete, 2, nsid, r);
 
 #ifdef SHARED
index 5c49fa847e91bd81a529defc59a4c4ca771601bc..b3777ffc136469cf109fcd26c6f14d1166fe8dd3 100644 (file)
@@ -67,6 +67,13 @@ _dl_debug_update (Lmid_t ns)
   return &r->base;
 }
 
+void
+_dl_debug_change_state (struct r_debug *r, int state)
+{
+  atomic_store_release (&r->r_state, state);
+  _dl_debug_state ();
+}
+
 /* Initialize _r_debug_extended for the namespace NS.  LDBASE is the
    run-time load address of the dynamic linker, to be put in
    _r_debug_extended.r_ldbase.  Return the address of _r_debug.  */
index 75a7187c649e02027e34af09d088b0fdadd0b0d2..8b0890499d66f67ac1fe78391d870621087579ef 100644 (file)
@@ -947,8 +947,7 @@ _dl_notify_new_object (int mode, Lmid_t nsid, struct link_map *l)
       /* Notify the debugger we have added some objects.  We need to
         call _dl_debug_initialize in a static program in case dynamic
         linking has not been used before.  */
-      r->r_state = RT_ADD;
-      _dl_debug_state ();
+      _dl_debug_change_state (r, RT_ADD);
       LIBC_PROBE (map_start, 2, nsid, r);
     }
   else
index 80f084d5c838fc1cd9331330a2fbac6c189d745a..6f6d3ddbf94c764c9ee19648517973fa210a8a77 100644 (file)
@@ -792,8 +792,7 @@ dl_open_worker (void *a)
 #ifdef SHARED
        bool was_not_consistent  = r->r_state != RT_CONSISTENT;
 #endif
-       r->r_state = RT_CONSISTENT;
-       _dl_debug_state ();
+       _dl_debug_change_state (r, RT_CONSISTENT);
        LIBC_PROBE (map_complete, 3, nsid, r, args->map);
 
 #ifdef SHARED
@@ -871,7 +870,7 @@ no more namespaces available for dlmopen()"));
        }
 
       GL(dl_ns)[nsid].libc_map = NULL;
-      _dl_debug_update (nsid)->r_state = RT_CONSISTENT;
+      _dl_debug_change_state (_dl_debug_update (nsid), RT_CONSISTENT);
     }
   /* Never allow loading a DSO in a namespace which is empty.  Such
      direct placements is only causing problems.  Also don't allow
index 809fc807989b285ef4d7d862dc8a385427f8ece5..43bfc7378afc6cc70bfa9de913fc64af0f2d8bea 100644 (file)
@@ -1850,8 +1850,7 @@ dl_main (const ElfW(Phdr) *phdr,
   elf_setup_debug_entry (main_map, r);
 
   /* We start adding objects.  */
-  r->r_state = RT_ADD;
-  _dl_debug_state ();
+  _dl_debug_change_state (r, RT_ADD);
   LIBC_PROBE (init_start, 2, LM_ID_BASE, r);
 
   /* Auditing checkpoint: we are ready to signal that the initial map
@@ -2402,8 +2401,7 @@ dl_main (const ElfW(Phdr) *phdr,
   /* Notify the debugger all new objects are now ready to go.  We must re-get
      the address since by now the variable might be in another object.  */
   r = _dl_debug_update (LM_ID_BASE);
-  r->r_state = RT_CONSISTENT;
-  _dl_debug_state ();
+  _dl_debug_change_state (r, RT_CONSISTENT);
   LIBC_PROBE (init_complete, 2, LM_ID_BASE, r);
 
   /* Auditing checkpoint: we have added all objects.  */
index 8b9ae3783056a29fd21cdb973d391d8d6713a45a..017406e7fa93c94171dd5c176c46ef08a6daff99 100644 (file)
@@ -1067,8 +1067,14 @@ extern void _dl_debug_state (void);
 rtld_hidden_proto (_dl_debug_state)
 
 /* Initialize `struct r_debug_extended' for the namespace NS.  LDBASE
-   is the run-time load address of the dynamic linker, to be put in the
-   `r_ldbase' member.  Return the address of the structure.  */
+   is the run-time load address of the dynamic linker, to be put in
+   the `r_ldbase' member.
+
+   Return the address of the r_debug structure for the namespace.
+   This is not merely a convenience or optimization, but it is
+   necessary for the LIBC_PROBE Systemtap/debugger probes to work
+   reliably: direct variable access can create probes that tools
+   cannot consume.  */
 extern struct r_debug *_dl_debug_initialize (ElfW(Addr) ldbase, Lmid_t ns)
      attribute_hidden;
 
@@ -1076,6 +1082,10 @@ extern struct r_debug *_dl_debug_initialize (ElfW(Addr) ldbase, Lmid_t ns)
    of the namespace NS.  */
 extern struct r_debug *_dl_debug_update (Lmid_t ns) attribute_hidden;
 
+/* Update R->r_state to STATE and notify the debugger by calling
+   _dl_debug_state.  */
+void _dl_debug_change_state (struct r_debug *r, int state) attribute_hidden;
+
 /* Initialize the basic data structure for the search paths.  SOURCE
    is either "LD_LIBRARY_PATH" or "--library-path".
    GLIBC_HWCAPS_PREPEND adds additional glibc-hwcaps subdirectories to