From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from rcdn-iport-8.cisco.com (rcdn-iport-8.cisco.com [173.37.86.79]) by sourceware.org (Postfix) with ESMTPS id B54A639730E7; Tue, 17 Aug 2021 17:57:36 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org B54A639730E7 X-Files: 0003-Added-support-for-dlmopen.patch : 11081 IronPort-HdrOrdr: =?us-ascii?q?A9a23=3ABnRPFan10TkA2jTIdi0sczA3UuLpDfIp3D?= =?us-ascii?q?Abv31ZSRFFG/FwWfrAoB0+726QtN9xYgBDpTnuAsO9qB/nmKKdpLNhWYtKPz?= =?us-ascii?q?OW21dATrsC0WKK+VSJcBEWtNQ86U4KScZD4bPLYWSTSa3BkW+F+xFK+qjhzJ?= =?us-ascii?q?yV?= X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: =?us-ascii?q?A0CoBAAb+Bth/4cNJK1agQmBWYIrd1Y?= =?us-ascii?q?BOjGUEIIkA4EQj1iLAoF8BAcBAQENAQE1DAQBAYRiAoJvAiU0CQ4BAgQBAQE?= =?us-ascii?q?SAQEFAQEBAgEGBIERE4VoDYZCAQEBAQMnUhALEQIBAQIBLjwKCQgGE4Jygwc?= =?us-ascii?q?Pp0p4gQEygQGDTQGEaYFTECOBF41zJxyBSUSBFYE7gTM3PoJiAwEYgS44hVs?= =?us-ascii?q?Eg0AKLUU9UQEiBwIETAMoClUoATgCESmRMQcEjFGBO1GBJpt1gzKBN4QKhH6?= =?us-ascii?q?Te0UQg1WSJ5BpLaIkky9ghFACBAYFAhaBYDuBWTMaCBsVOw0Ogk4JRxkOjik?= =?us-ascii?q?DFoM3hS2FaiEDLwI2AgYLAQEDCYdFLYIYAQE?= X-IronPort-AV: E=Sophos;i="5.84,329,1620691200"; d="scan'208,223";a="920381700" Received: from alln-core-2.cisco.com ([173.36.13.135]) by rcdn-iport-8.cisco.com with ESMTP/TLS/DHE-RSA-SEED-SHA; 17 Aug 2021 17:57:35 +0000 Received: from zorba ([10.24.28.166]) by alln-core-2.cisco.com (8.15.2/8.15.2) with ESMTPS id 17HHvXLm023307 (version=TLSv1.2 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Tue, 17 Aug 2021 17:57:35 GMT Date: Tue, 17 Aug 2021 10:57:33 -0700 From: Daniel Walker To: "H.J. Lu" Cc: libc-alpha@sourceware.org, gdb@sourceware.org Subject: Re: [PATCH v2 2/2] Extend struct r_debug to support multiple namespaces Message-ID: <20210817175733.GI1633923@zorba> References: <20210817010629.593479-1-hjl.tools@gmail.com> <20210817010629.593479-3-hjl.tools@gmail.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="z6Eq5LdranGa6ru8" Content-Disposition: inline In-Reply-To: <20210817010629.593479-3-hjl.tools@gmail.com> X-Outbound-SMTP-Client: 10.24.28.166, [10.24.28.166] X-Outbound-Node: alln-core-2.cisco.com X-Spam-Status: No, score=-17.9 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_STOCKGEN, RCVD_IN_MSPIKE_H2, SPF_HELO_PASS, SPF_NONE, TXREP, USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gdb@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 17 Aug 2021 17:57:47 -0000 --z6Eq5LdranGa6ru8 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline 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 : > > 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 --z6Eq5LdranGa6ru8 Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="0003-Added-support-for-dlmopen.patch" >From a56e1a4303e1b26b9c49962d732e92e7c1311c58 Mon Sep 17 00:00:00 2001 From: gdbdev 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 --z6Eq5LdranGa6ru8--