From: Simon Marchi <simon.marchi@efficios.com>
To: gdb-patches@sourceware.org
Cc: Simon Marchi <simon.marchi@polymtl.ca>
Subject: [PATCH RESEND v2 08/10] gdb: add objfile -> solib backlink
Date: Mon, 8 Jun 2026 16:00:32 -0400 [thread overview]
Message-ID: <20260608200100.666134-9-simon.marchi@efficios.com> (raw)
In-Reply-To: <20260608200100.666134-1-simon.marchi@efficios.com>
From: Simon Marchi <simon.marchi@polymtl.ca>
The following "multiple solib_ops" patch will require accessing the
solib(s) related to an objfile fairly often. To make that easier, add
an objfile to solib backlink.
However, I learned that there may be more than one solib linked to one
objfile. The only case I am aware of is the dynamic linker itself
(ld-linux.so), where the same instance (same load address) appears in
all namespaces. We get one solib per "view" of that library, but they
all point to the same objfile. So this backlink is actually a vector.
Rename find_solib_for_objfile to find_one_solib_for_objfile to reflect
that this function returns just one of possible multiple solibs for the
given objfile (if that ever matters). To be clear, this doesn't change
its behavior, this is what it was doing before this patch.
Change-Id: I427d19407fdbc274b1790e0cae3004ee5fdbea72
---
gdb/objfiles.h | 23 +++++++++++++++++++++++
gdb/solib-svr4.c | 16 ++++++++--------
gdb/solib.c | 13 +++++++++----
3 files changed, 40 insertions(+), 12 deletions(-)
diff --git a/gdb/objfiles.h b/gdb/objfiles.h
index c8b989911e5f..9bd676f27237 100644
--- a/gdb/objfiles.h
+++ b/gdb/objfiles.h
@@ -450,6 +450,25 @@ struct objfile : intrusive_list_node<objfile>
/* Return the program space associated with this objfile. */
program_space *pspace () { return m_pspace; }
+ /* Return the list of struct solib associated to this objfile. */
+ std::vector<solib *> &solibs () { return m_solibs; }
+
+ /* Add SOLIB to the list of solibs associated to this objfile. */
+ void add_solib (solib &solib)
+ {
+ gdb_assert (std::find (m_solibs.begin (), m_solibs.end (), &solib)
+ == m_solibs.end ());
+ m_solibs.emplace_back (&solib);
+ }
+
+ /* Remove SOLIB from the list of solibs associated to this objfile. */
+ void remove_solib (solib &solib)
+ {
+ auto it = std::find (m_solibs.begin (), m_solibs.end (), &solib);
+ gdb_assert (it != m_solibs.end ());
+ m_solibs.erase (it);
+ }
+
using compunit_symtab_iterator
= owning_intrusive_list<compunit_symtab>::iterator;
using compunit_symtab_range = iterator_range<compunit_symtab_iterator>;
@@ -702,6 +721,10 @@ struct objfile : intrusive_list_node<objfile>
program_space *m_pspace;
+ /* The solibs associated to this objfile. This is a 1 objfile to N solibs
+ relationship (see solib.c for details). */
+ std::vector<solib *> m_solibs;
+
public:
/* The object file's BFD. Can be null if the objfile contains only
minimal symbols (e.g. the run time common symbols for SunOS4) or
diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
index 35c81000b10a..33fb6e3cd970 100644
--- a/gdb/solib-svr4.c
+++ b/gdb/solib-svr4.c
@@ -3592,10 +3592,10 @@ lp64_svr4_solib_ops::fetch_link_map_offsets () const
}
\f
-/* Return the DSO matching OBJFILE or nullptr if none can be found. */
+/* Return one solib matching OBJFILE or nullptr if none can be found. */
-static const solib *
-find_solib_for_objfile (struct objfile *objfile)
+static solib *
+find_one_solib_for_objfile (struct objfile *objfile)
{
if (objfile == nullptr)
return nullptr;
@@ -3605,9 +3605,9 @@ find_solib_for_objfile (struct objfile *objfile)
if (objfile->separate_debug_objfile_backlink != nullptr)
objfile = objfile->separate_debug_objfile_backlink;
- for (const solib &so : current_program_space->solibs ())
- if (so.objfile == objfile)
- return &so;
+ if (const auto &solibs = objfile->solibs ();
+ !solibs.empty ())
+ return solibs.front ();
return nullptr;
}
@@ -3676,7 +3676,7 @@ svr4_solib_ops::iterate_over_objfiles_in_search_order
r_debug object, defaulting to the initial namespace. */
svr4_info *info = get_svr4_info (current_program_space);
CORE_ADDR default_debug_base = this->default_debug_base (info);
- const solib *curr_solib = find_solib_for_objfile (current_objfile);
+ const solib *curr_solib = find_one_solib_for_objfile (current_objfile);
CORE_ADDR debug_base = find_debug_base_for_solib (curr_solib);
if (debug_base == 0)
debug_base = default_debug_base;
@@ -3691,7 +3691,7 @@ svr4_solib_ops::iterate_over_objfiles_in_search_order
If we fail, e.g. for manually added symbol files or for the main
executable, we assume that they were added to the initial
namespace. */
- const solib *solib = find_solib_for_objfile (&objfile);
+ const solib *solib = find_one_solib_for_objfile (&objfile);
CORE_ADDR solib_base = find_debug_base_for_solib (solib);
if (solib_base == 0)
solib_base = default_debug_base;
diff --git a/gdb/solib.c b/gdb/solib.c
index 1211874d22be..b2cb3870c6e0 100644
--- a/gdb/solib.c
+++ b/gdb/solib.c
@@ -633,6 +633,7 @@ solib_read_symbols (solib &so, symfile_add_flags flags)
so.objfile->addr_low = so.addr_low;
}
+ so.objfile->add_solib (so);
so.symbols_loaded = true;
}
catch (const gdb_exception_error &e)
@@ -703,10 +704,14 @@ remove_solib (program_space *pspace,
notify_solib_unloaded (pspace, *solib_it, still_in_use, false);
/* Unless the user loaded it explicitly, free SO's objfile. */
- if (solib_it->objfile != nullptr
- && !(solib_it->objfile->flags & OBJF_USERLOADED)
- && !still_in_use)
- solib_it->objfile->unlink ();
+ if (solib_it->objfile != nullptr)
+ {
+ /* Remove the objfile -> solib backlink. */
+ solib_it->objfile->remove_solib (*solib_it);
+
+ if (!(solib_it->objfile->flags & OBJF_USERLOADED) && !still_in_use)
+ solib_it->objfile->unlink ();
+ }
pspace->deleted_solibs.push_back (solib_it->name);
--
2.54.0
next prev parent reply other threads:[~2026-06-08 20:03 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-08 20:00 [PATCH RESEND v2 00/10] Multiple solib_ops in a program_space Simon Marchi
2026-06-08 20:00 ` [PATCH RESEND v2 01/10] gdb/solib-rocm: assert that host ops isn't rocm_solib_ops Simon Marchi
2026-07-06 17:08 ` [PATCH v2 1/10] " Lancelot SIX
2026-06-08 20:00 ` [PATCH RESEND v2 02/10] gdb/solib-rocm: pass reference to cache to rocm_code_object_stream_file Simon Marchi
2026-06-08 20:00 ` [PATCH RESEND v2 03/10] gdb/solib-rocm: add cached_target_fd to manage cached fd lifetime Simon Marchi
2026-07-06 17:08 ` [PATCH v2 3/10] " Lancelot SIX
2026-07-07 20:48 ` Simon Marchi
2026-06-08 20:00 ` [PATCH RESEND v2 04/10] gdb: de-constify some methods of solib_ops Simon Marchi
2026-07-06 17:09 ` [PATCH v2 4/10] " Lancelot SIX
2026-06-08 20:00 ` [PATCH RESEND v2 05/10] gdb/solib-rocm: move per-inferior data to rocm_solib_ops Simon Marchi
2026-07-06 17:09 ` [PATCH v2 5/10] " Lancelot SIX
2026-07-08 16:08 ` Simon Marchi
2026-06-08 20:00 ` [PATCH RESEND v2 06/10] gdb/solib-rocm: save inferior in rocm_solib_ops Simon Marchi
2026-07-06 17:10 ` [PATCH v2 6/10] " Lancelot SIX
2026-06-08 20:00 ` [PATCH RESEND v2 07/10] gdb/solib: add remove_solib function Simon Marchi
2026-06-08 20:00 ` Simon Marchi [this message]
2026-06-08 20:00 ` [PATCH RESEND v2 09/10] gdb: change default objfile iteration order to start with current objfile Simon Marchi
2026-06-08 20:00 ` [PATCH RESEND v2 10/10] gdb: multiple solib_ops per program space Simon Marchi
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=20260608200100.666134-9-simon.marchi@efficios.com \
--to=simon.marchi@efficios.com \
--cc=gdb-patches@sourceware.org \
--cc=simon.marchi@polymtl.ca \
/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