public inbox for gdb@sourceware.org
 help / color / mirror / Atom feed
From: Daniel Walker <danielwa@cisco.com>
To: "H.J. Lu" <hjl.tools@gmail.com>
Cc: libc-alpha@sourceware.org, gdb@sourceware.org
Subject: Re: [PATCH v2 2/2] Extend struct r_debug to support multiple namespaces
Date: Tue, 17 Aug 2021 10:57:33 -0700	[thread overview]
Message-ID: <20210817175733.GI1633923@zorba> (raw)
In-Reply-To: <20210817010629.593479-3-hjl.tools@gmail.com>

[-- Attachment #1: Type: text/plain, Size: 1251 bytes --]

On Mon, Aug 16, 2021 at 06:06:29PM -0700, H.J. Lu wrote:
> Glibc does not provide an interface for debugger to access libraries
> loaded in multiple namespaces via dlmopen.
> 
> The current rtld-debugger interface is described in the file:
> 
> elf/rtld-debugger-interface.txt
> 
> under the "Standard debugger interface" heading.  This interface only
> provides access to the first link-map (LM_ID_BASE).
> 
> Based on the patch from Conan C Huang <conhuang@cisco.com>:
> 
> https://sourceware.org/pipermail/libc-alpha/2020-June/115448.html
> 
> 1. Bump r_version to 2.  This triggers the GDB bug:
> 
> https://sourceware.org/bugzilla/show_bug.cgi?id=28236
> 
> 2. Add struct r_debug_extended to extend struct r_debug into a linked-list,
> where each element correlates to an unique namespace.
> 3. Add a hidden symbol, _r_debug_extended, for struct r_debug_extended.
> 4. Provide the compatibility symbol, _r_debug, with size of struct r_debug,
> as an alise of _r_debug_extended, for programs which reference _r_debug.


I've attached the GDB patch which was created at Cisco to support our version of
this type of feature which is similar to what you've created. You might be able
to make some small modifications to make it work for you.

Daniel

[-- Attachment #2: 0003-Added-support-for-dlmopen.patch --]
[-- Type: text/x-diff, Size: 11081 bytes --]

From a56e1a4303e1b26b9c49962d732e92e7c1311c58 Mon Sep 17 00:00:00 2001
From: gdbdev <gdbdev@meson.cisco.com>
Date: Wed, 20 Jan 2021 00:07:30 -0800
Subject: [PATCH] Added support for dlmopen.

Introduced new dynamic section entry (DT_DEBUG_DLMOPEN).

Glibc and linker require associated patch for this feature to work.
---
 elfcpp/elfcpp.h           |  1 +
 gdb/gdbserver/linux-low.c | 18 ++++++--
 gdb/solib-svr4.c          | 88 +++++++++++++++++++++++++++++----------
 gdb/solib-svr4.h          |  6 +++
 include/elf/common.h      |  1 +
 5 files changed, 88 insertions(+), 26 deletions(-)

diff --git a/elfcpp/elfcpp.h b/elfcpp/elfcpp.h
index d94db26071e..47b281c70e4 100644
--- a/elfcpp/elfcpp.h
+++ b/elfcpp/elfcpp.h
@@ -714,6 +714,7 @@ enum DT
   DT_FINI_ARRAYSZ = 28,
   DT_RUNPATH = 29,
   DT_FLAGS = 30,
+  DT_DEBUG_DLMOPEN = 38,
 
   // This is used to mark a range of dynamic tags.  It is not really
   // a tag value.
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index 4255795ea67..247a8d78f10 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -6856,6 +6856,12 @@ struct link_map_offsets
 
     /* Offset to l_prev field in struct link_map.  */
     int l_prev_offset;
+
+    /* Offset of r_debug_dlmopen.r_debug.  */
+    int r_debug_dlm_offset;
+
+    /* Offset of r_debug_dlmopen.r_next.  */
+    int r_next_dlm_offset;
   };
 
 /* Construct qXfer:libraries-svr4:read reply.  */
@@ -6877,7 +6883,9 @@ linux_qxfer_libraries_svr4 (const char *annex, unsigned char *readbuf,
       4,     /* l_name offset in link_map.  */
       8,     /* l_ld offset in link_map.  */
       12,    /* l_next offset in link_map.  */
-      16     /* l_prev offset in link_map.  */
+      16,    /* l_prev offset in link_map.  */
+      0,     /* r_debug_dlm offset.  */
+      4      /* r_next_dlm offset.  */
     };
 
   static const struct link_map_offsets lmo_64bit_offsets =
@@ -6888,7 +6896,9 @@ linux_qxfer_libraries_svr4 (const char *annex, unsigned char *readbuf,
       8,     /* l_name offset in link_map.  */
       16,    /* l_ld offset in link_map.  */
       24,    /* l_next offset in link_map.  */
-      32     /* l_prev offset in link_map.  */
+      32,    /* l_prev offset in link_map.  */
+      0,     /* r_debug_dlm offset.  */
+      8      /* r_next_dlm offset.  */
     };
   const struct link_map_offsets *lmo;
   unsigned int machine;
@@ -6953,7 +6963,7 @@ linux_qxfer_libraries_svr4 (const char *annex, unsigned char *readbuf,
 	  if (linux_read_memory (priv->r_debug + lmo->r_version_offset,
 				 (unsigned char *) &r_version,
 				 sizeof (r_version)) != 0
-	      || r_version != 1)
+	      || (r_version != 1 && r_version != 3))
 	    {
 	      warning ("unexpected r_debug version %d", r_version);
 	    }
@@ -6982,12 +6992,14 @@ linux_qxfer_libraries_svr4 (const char *annex, unsigned char *readbuf,
     {
       unsigned char libname[PATH_MAX];
 
+#if 0
       if (lm_prev != l_prev)
 	{
 	  warning ("Corrupted shared library list: 0x%lx != 0x%lx",
 		   (long) lm_prev, (long) l_prev);
 	  break;
 	}
+#endif
 
       /* Ignore the first entry even if it has valid name as the first entry
 	 corresponds to the main executable.  The first entry should not be
diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
index 3714c59748b..2763e8ae534 100644
--- a/gdb/solib-svr4.c
+++ b/gdb/solib-svr4.c
@@ -851,14 +851,10 @@ locate_base (struct svr4_info *info)
 
 /* Find the first element in the inferior's dynamic link map, and
    return its address in the inferior.  Return zero if the address
-   could not be determined.
-
-   FIXME: Perhaps we should validate the info somehow, perhaps by
-   checking r_version for a known version number, or r_state for
-   RT_CONSISTENT.  */
+   could not be determined.  */
 
 static CORE_ADDR
-solib_svr4_r_map (struct svr4_info *info)
+solib_svr4_r_map (CORE_ADDR debug_base)
 {
   struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
   struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
@@ -866,7 +862,7 @@ solib_svr4_r_map (struct svr4_info *info)
 
   try
     {
-      addr = read_memory_typed_address (info->debug_base + lmo->r_map_offset,
+      addr = read_memory_typed_address (debug_base + lmo->r_map_offset,
                                         ptr_type);
     }
   catch (const gdb_exception_error &ex)
@@ -913,7 +909,7 @@ solib_svr4_r_ldsomap (struct svr4_info *info)
       exception_print (gdb_stderr, ex);
     }
 
-  if (version < 2 || lmo->r_ldsomap_offset == -1)
+  if (version != 2 || lmo->r_ldsomap_offset == -1)
     return 0;
 
   return read_memory_typed_address (info->debug_base + lmo->r_ldsomap_offset,
@@ -979,7 +975,7 @@ open_symbol_file_object (int from_tty)
     return 0;	/* failed somehow...  */
 
   /* First link map member should be the executable.  */
-  lm = solib_svr4_r_map (info);
+  lm = solib_svr4_r_map (info->debug_base);
   if (lm == 0)
     return 0;	/* failed somehow...  */
 
@@ -1294,6 +1290,7 @@ svr4_read_so_list (svr4_info *info, CORE_ADDR lm, CORE_ADDR prev_lm,
 {
   CORE_ADDR first_l_name = 0;
   CORE_ADDR next_lm;
+	(void)prev_lm;
 
   for (; lm != 0; prev_lm = lm, lm = next_lm)
     {
@@ -1308,7 +1305,7 @@ svr4_read_so_list (svr4_info *info, CORE_ADDR lm, CORE_ADDR prev_lm,
 	return 0;
 
       next_lm = li->l_next;
-
+#if 0
       if (li->l_prev != prev_lm)
 	{
 	  warning (_("Corrupted shared library list: %s != %s"),
@@ -1316,6 +1313,7 @@ svr4_read_so_list (svr4_info *info, CORE_ADDR lm, CORE_ADDR prev_lm,
 		   paddress (target_gdbarch (), li->l_prev));
 	  return 0;
 	}
+#endif
 
       /* For SVR4 versions, the first entry in the link map is for the
          inferior executable, so we must ignore it.  For some versions of
@@ -1362,6 +1360,29 @@ svr4_read_so_list (svr4_info *info, CORE_ADDR lm, CORE_ADDR prev_lm,
   return 1;
 }
 
+/* Locate address of _r_debug_dlmopen struct. */
+static CORE_ADDR
+locate_dlmopen_base ()
+{
+  struct bound_minimal_symbol msymbol;
+  CORE_ADDR dyn_ptr;
+
+  /* Find DT_DEBUG_DLMOPEN entry in .dynamic section.
+  DT_DEBUG_DLMOPEN entry is not yet introduced.*/
+  if (scan_dyntag (DT_DEBUG_DLMOPEN, exec_bfd, &dyn_ptr, NULL)
+      || scan_dyntag_auxv (DT_DEBUG_DLMOPEN, &dyn_ptr, NULL))
+    return dyn_ptr;
+
+  /* This may be a static executable.  Look for the symbol
+  conventionally named _r_debug_dlmopen.  */
+  msymbol = lookup_minimal_symbol ("_r_debug_dlmopen", NULL, symfile_objfile);
+  if (msymbol.minsym != NULL)
+    return BMSYMBOL_VALUE_ADDRESS (msymbol);
+
+  /* _r_debug_dlmopen struct not found.  */
+  return 0;
+}
+
 /* Read the full list of currently loaded shared objects directly
    from the inferior, without referring to any libraries read and
    stored by the probes interface.  Handle special cases relating
@@ -1375,6 +1396,11 @@ svr4_current_sos_direct (struct svr4_info *info)
   struct so_list **link_ptr = &head;
   int ignore_first;
   struct svr4_library_list library_list;
+  struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
+  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
+  CORE_ADDR r_debug_ptr;
+  CORE_ADDR r_debug_dlmopen_ptr = 0;
+  struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
 
   /* Fall back to manual examination of the target if the packet is not
      supported or gdbserver failed to find DT_DEBUG.  gdb.server/solib-list.exp
@@ -1415,11 +1441,28 @@ svr4_current_sos_direct (struct svr4_info *info)
       svr4_free_library_list (&head);
     });
 
-  /* Walk the inferior's link map list, and build our list of
-     `struct so_list' nodes.  */
-  lm = solib_svr4_r_map (info);
-  if (lm)
-    svr4_read_so_list (info, lm, 0, &link_ptr, ignore_first);
+  r_debug_ptr = info->debug_base;
+  r_debug_dlmopen_ptr = locate_dlmopen_base ();
+  do
+    {
+      /* Walk the inferior's link map list, and build our list of
+         `struct so_list' nodes.  */
+      lm = solib_svr4_r_map (r_debug_ptr);
+      if (lm)
+        svr4_read_so_list (info, lm, 0, &link_ptr, ignore_first);
+      ignore_first = 0;
+      if (r_debug_dlmopen_ptr != 0){
+        r_debug_dlmopen_ptr
+		  = read_memory_typed_address (r_debug_dlmopen_ptr +
+		                 lmo->r_next_dlm_offset, ptr_type);
+        if (r_debug_dlmopen_ptr != 0)
+          r_debug_ptr
+            = read_memory_typed_address ( r_debug_dlmopen_ptr +
+			              lmo->r_debug_dlm_offset, ptr_type);
+        else
+          r_debug_ptr = 0;
+      }
+    } while ((r_debug_dlmopen_ptr !=0) && (r_debug_ptr != 0));
 
   /* On Solaris, the dynamic linker is not in the normal list of
      shared objects, so make sure we pick it up too.  Having
@@ -1944,13 +1987,6 @@ svr4_handle_solib_event (void)
     if (locate_base (info) == 0)
       return;
 
-    /* GDB does not currently support libraries loaded via dlmopen
-       into namespaces other than the initial one.  We must ignore
-       any namespace other than the initial namespace here until
-       support for this is added to GDB.  */
-    if (debug_base != info->debug_base)
-      action = DO_NOTHING;
-
     if (action == UPDATE_OR_RELOAD)
       {
 	try
@@ -2212,7 +2248,7 @@ enable_break (struct svr4_info *info, int from_tty)
 
   solib_add (NULL, from_tty, auto_solib_add);
   sym_addr = 0;
-  if (info->debug_base && solib_svr4_r_map (info) != 0)
+  if (info->debug_base && solib_svr4_r_map (info->debug_base) != 0)
     sym_addr = solib_svr4_r_brk (info);
 
   if (sym_addr != 0)
@@ -3160,6 +3196,9 @@ svr4_ilp32_fetch_link_map_offsets (void)
       lmo.r_brk_offset = 8;
       lmo.r_ldsomap_offset = 20;
 
+      lmo.r_debug_dlm_offset = 0;
+      lmo.r_next_dlm_offset = 4;
+
       /* Everything we need is in the first 20 bytes.  */
       lmo.link_map_size = 20;
       lmo.l_addr_offset = 0;
@@ -3191,6 +3230,9 @@ svr4_lp64_fetch_link_map_offsets (void)
       lmo.r_brk_offset = 16;
       lmo.r_ldsomap_offset = 40;
 
+      lmo.r_debug_dlm_offset = 0;
+      lmo.r_next_dlm_offset = 8;
+
       /* Everything we need is in the first 40 bytes.  */
       lmo.link_map_size = 40;
       lmo.l_addr_offset = 0;
diff --git a/gdb/solib-svr4.h b/gdb/solib-svr4.h
index 30dd6bc0b36..2700d54d733 100644
--- a/gdb/solib-svr4.h
+++ b/gdb/solib-svr4.h
@@ -66,6 +66,12 @@ struct link_map_offsets
     /* Offset of r_debug.r_ldsomap.  */
     int r_ldsomap_offset;
 
+    /* Offset of r_debug_dlmopen.r_debug_dlm.  */
+    int r_debug_dlm_offset;
+
+    /* Offset of r_debug_dlmopen.r_next_dlm.  */
+    int r_next_dlm_offset;
+
     /* Size of struct link_map (or equivalent), or at least enough of it
        to be able to obtain the fields below.  */
     int link_map_size;
diff --git a/include/elf/common.h b/include/elf/common.h
index 75c4fb7e9d7..5bd1abc1c59 100644
--- a/include/elf/common.h
+++ b/include/elf/common.h
@@ -975,6 +975,7 @@
 #define DT_FINI_ARRAYSZ 28
 #define DT_RUNPATH	29
 #define DT_FLAGS	30
+#define DT_DEBUG_DLMOPEN 38
 #define DT_ENCODING	32
 #define DT_PREINIT_ARRAY   32
 #define DT_PREINIT_ARRAYSZ 33
-- 
2.26.2.Cisco


  parent reply	other threads:[~2021-08-17 17:57 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-08-17  1:06 [PATCH v2 0/2] " H.J. Lu
2021-08-17  1:06 ` [PATCH v2 1/2] Add declare_object_symbol_alias for assembly codes [BZ #28128] H.J. Lu
2021-08-17  1:06 ` [PATCH v2 2/2] Extend struct r_debug to support multiple namespaces H.J. Lu
2021-08-17 17:44   ` Daniel Walker
2021-08-17 20:25     ` H.J. Lu
2021-08-18  0:14       ` H.J. Lu
2021-08-17 17:57   ` Daniel Walker [this message]
2021-08-17 20:26     ` H.J. Lu
2021-08-18  0:21       ` H.J. Lu
2021-08-18  2:36         ` H.J. Lu
2021-08-18 13:34           ` H.J. Lu
2021-08-17 17:57 ` [PATCH v2 0/2] " Joseph Myers

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=20210817175733.GI1633923@zorba \
    --to=danielwa@cisco.com \
    --cc=gdb@sourceware.org \
    --cc=hjl.tools@gmail.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).