public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
From: Florian Weimer <fweimer@redhat.com>
To: libc-alpha@sourceware.org
Subject: [PATCH v2 2/3] elf: Introduce _dl_debug_change_state
Date: Tue, 06 Sep 2022 12:27:29 +0200	[thread overview]
Message-ID: <e596eeb8df983d8259550e33180d66b937aa8dad.1662456433.git.fweimer@redhat.com> (raw)
In-Reply-To: <cover.1662456433.git.fweimer@redhat.com>

It combines updating r_state with the debugger notification.

The change to  _dl_open introduces an additional debugger notification
for dlmopen, but debuggers are expected to ignore it.
---
 elf/dl-close.c             |  6 ++----
 elf/dl-debug.c             |  7 +++++++
 elf/dl-load.c              |  6 ++----
 elf/dl-open.c              |  5 ++---
 elf/rtld.c                 |  6 ++----
 sysdeps/generic/ldsodefs.h | 14 ++++++++++++--
 6 files changed, 27 insertions(+), 17 deletions(-)

diff --git a/elf/dl-close.c b/elf/dl-close.c
index bcd6e206e9..c300999e5b 100644
--- a/elf/dl-close.c
+++ b/elf/dl-close.c
@@ -460,8 +460,7 @@ _dl_close_worker (struct link_map *map, bool force)
 
   /* Notify the debugger we are about to remove some loaded objects.  */
   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)
@@ -765,8 +764,7 @@ _dl_close_worker (struct link_map *map, bool force)
     while (GL(dl_ns)[GL(dl_nns) - 1]._ns_loaded == NULL);
 
   /* 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);
 
   /* Recheck if we need to retry, release the lock.  */
diff --git a/elf/dl-debug.c b/elf/dl-debug.c
index 66f9ad375d..47961236cf 100644
--- a/elf/dl-debug.c
+++ b/elf/dl-debug.c
@@ -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.  */
diff --git a/elf/dl-load.c b/elf/dl-load.c
index 1ad0868dad..d23ad557fc 100644
--- a/elf/dl-load.c
+++ b/elf/dl-load.c
@@ -987,8 +987,7 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
 
 	  if (make_consistent && r != NULL)
 	    {
-	      r->r_state = RT_CONSISTENT;
-	      _dl_debug_state ();
+	      _dl_debug_change_state (r, RT_CONSISTENT);
 	      LIBC_PROBE (map_failed, 2, nsid, r);
 	    }
 
@@ -1507,8 +1506,7 @@ cannot enable executable stack as shared object requires");
       /* 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);
       make_consistent = true;
     }
diff --git a/elf/dl-open.c b/elf/dl-open.c
index 46e8066fd8..b67c2e099f 100644
--- a/elf/dl-open.c
+++ b/elf/dl-open.c
@@ -617,8 +617,7 @@ dl_open_worker_begin (void *a)
 
   /* Notify the debugger all new objects are now ready to go.  */
   struct r_debug *r = _dl_debug_update (args->nsid);
-  r->r_state = RT_CONSISTENT;
-  _dl_debug_state ();
+  _dl_debug_change_state (r, RT_CONSISTENT);
   LIBC_PROBE (map_complete, 3, args->nsid, r, new);
 
   _dl_open_check (new);
@@ -853,7 +852,7 @@ no more namespaces available for dlmopen()"));
       memset (&GL(dl_ns)[nsid], 0, sizeof (GL(dl_ns)[nsid]));
       __rtld_lock_initialize (GL(dl_ns)[nsid]._ns_unique_sym_table.lock);
 
-      _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
diff --git a/elf/rtld.c b/elf/rtld.c
index 3e771a93d8..ad67d7e4c5 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -1835,8 +1835,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
@@ -2409,8 +2408,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);
 
 #if defined USE_LDCONFIG && !defined MAP_COPY
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
index b088f6b1ae..31fb19c871 100644
--- a/sysdeps/generic/ldsodefs.h
+++ b/sysdeps/generic/ldsodefs.h
@@ -1060,8 +1060,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.
+
+   This function returns 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;
 
@@ -1069,6 +1075,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;
 
+/* Updates R->r_state to STATE and notifies 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
-- 
2.37.2



  parent reply	other threads:[~2022-09-06 10:27 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-09-06 10:27 [PATCH v2 0/3] Restore support for _r_debug copy relocations & interposition Florian Weimer
2022-09-06 10:27 ` [PATCH v2 1/3] elf: Introduce separate _r_debug_array variable Florian Weimer
2022-09-06 10:27 ` Florian Weimer [this message]
2022-09-06 10:27 ` [PATCH v2 3/3] elf: Restore support for _r_debug interpositions and copy relocations Florian Weimer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=e596eeb8df983d8259550e33180d66b937aa8dad.1662456433.git.fweimer@redhat.com \
    --to=fweimer@redhat.com \
    --cc=libc-alpha@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).