* [PATCH v3 1/6] gdb/testsuite: check that "info shared" and "info linker-namespaces" before running don't crash
@ 2025-06-16 19:32 Simon Marchi
2025-06-16 19:33 ` [PATCH v3 2/6] gdb/solib: fix formatting of "info linker-namespaces" error message Simon Marchi
` (5 more replies)
0 siblings, 6 replies; 28+ messages in thread
From: Simon Marchi @ 2025-06-16 19:32 UTC (permalink / raw)
To: gdb-patches; +Cc: Simon Marchi
This patch is new in v3.
While writing my solib_ops C++ification series, I broke this, and it
didn't seem to be caught by the testsuite. Add a test for those.
The exact message for "info linker-namespaces" varies depending on the
solib_ops of the target architecture (whether ops->num_active_namespaces
is nullptr or not). For now, just accept any message (a crash will
still be caught). A later patch in this series will make the message
consistent and update this test.
Change-Id: I6bce2ff317447bbf321fc9cbd2d42c3dcea0c683
---
gdb/testsuite/gdb.base/dlmopen-ns-ids.exp | 5 +++++
gdb/testsuite/gdb.base/info-shared.exp | 3 +++
2 files changed, 8 insertions(+)
diff --git a/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp b/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp
index 94b4a6e50bcf..8613056a7c8b 100644
--- a/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp
+++ b/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp
@@ -169,6 +169,11 @@ proc_with_prefix test_conv_vars {} {
proc test_info_linker_namespaces {} {
clean_restart $::binfile
+ # Check that "info linker-namespaces" while the inferior is not running
+ # doesn't crash.
+ gdb_test "info linker-namespaces" ".*" \
+ "info linker-namespaces before running"
+
if { ![runto_main] } {
return
}
diff --git a/gdb/testsuite/gdb.base/info-shared.exp b/gdb/testsuite/gdb.base/info-shared.exp
index 6f1b2d6af7e0..e81b28e27a5b 100644
--- a/gdb/testsuite/gdb.base/info-shared.exp
+++ b/gdb/testsuite/gdb.base/info-shared.exp
@@ -79,6 +79,9 @@ proc check_info_shared { test expect1 expect2 } {
}
}
+# Check that "info shared" before running doesn't crash.
+check_info_shared "info sharedlibrary before running" 0 0
+
# Start the inferior, and check neither of the libraries are loaded at
# the start.
if ![runto_main] {
base-commit: 62f1dbee49983c1820bc32015d2e8cd2d085c4dd
--
2.49.0
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v3 2/6] gdb/solib: fix formatting of "info linker-namespaces" error message
2025-06-16 19:32 [PATCH v3 1/6] gdb/testsuite: check that "info shared" and "info linker-namespaces" before running don't crash Simon Marchi
@ 2025-06-16 19:33 ` Simon Marchi
2025-06-20 18:12 ` Pedro Alves
2025-06-16 19:33 ` [PATCH v3 3/6] gdb/solib: add solib -> solib_ops backlink Simon Marchi
` (4 subsequent siblings)
5 siblings, 1 reply; 28+ messages in thread
From: Simon Marchi @ 2025-06-16 19:33 UTC (permalink / raw)
To: gdb-patches; +Cc: Simon Marchi
This patch is new in v3.
Add spaces after the first period and add a period at the end, resulting
in:
(gdb) info linker-namespaces
❌️ Current inferior does not support linker namespaces. Use "info sharedlibrary" instead.
Change-Id: Ib3f1647cedcdb68852a3c63df26ea3e6f791b1b1
---
gdb/solib.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/gdb/solib.c b/gdb/solib.c
index 7721fd673ae3..90e7b906222c 100644
--- a/gdb/solib.c
+++ b/gdb/solib.c
@@ -1163,8 +1163,8 @@ info_linker_namespace_command (const char *pattern, int from_tty)
/* This command only really makes sense for inferiors that support
linker namespaces, so we can leave early. */
if (ops->num_active_namespaces == nullptr)
- error (_("Current inferior does not support linker namespaces." \
- "Use \"info sharedlibrary\" instead"));
+ error (_("Current inferior does not support linker namespaces. " \
+ "Use \"info sharedlibrary\" instead."));
struct ui_out *uiout = current_uiout;
std::vector<std::pair<int, std::vector<const solib *>>> all_solibs_to_print;
--
2.49.0
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v3 3/6] gdb/solib: add solib -> solib_ops backlink
2025-06-16 19:32 [PATCH v3 1/6] gdb/testsuite: check that "info shared" and "info linker-namespaces" before running don't crash Simon Marchi
2025-06-16 19:33 ` [PATCH v3 2/6] gdb/solib: fix formatting of "info linker-namespaces" error message Simon Marchi
@ 2025-06-16 19:33 ` Simon Marchi
2025-06-20 18:17 ` Pedro Alves
2025-06-16 19:33 ` [PATCH v3 4/6] gdb/solib: use solib::ops for operations that concern a single solib Simon Marchi
` (3 subsequent siblings)
5 siblings, 1 reply; 28+ messages in thread
From: Simon Marchi @ 2025-06-16 19:33 UTC (permalink / raw)
To: gdb-patches; +Cc: Simon Marchi
The subsequent C++ification commit makes it so that one struct solib_ops
is instantiated for each program space. For some operations, it will
then become necessary to be able to get the right solib_ops instance
from a given solib. Add an solib -> solib_ops backlink for that.
Change-Id: Ib95407b3fa5fcfba55cf874e0e9dcd2d43a402e4
---
gdb/solib-aix.c | 2 +-
gdb/solib-darwin.c | 2 +-
gdb/solib-dsbt.c | 2 +-
gdb/solib-frv.c | 2 +-
gdb/solib-rocm.c | 2 +-
gdb/solib-svr4.c | 4 ++--
gdb/solib-target.c | 2 +-
gdb/solib.h | 15 +++++++++++++++
8 files changed, 23 insertions(+), 8 deletions(-)
diff --git a/gdb/solib-aix.c b/gdb/solib-aix.c
index 4af83de4d371..17eeba940770 100644
--- a/gdb/solib-aix.c
+++ b/gdb/solib-aix.c
@@ -480,7 +480,7 @@ solib_aix_current_sos ()
}
/* Add it to the list. */
- auto &new_solib = sos.emplace_back ();
+ auto &new_solib = sos.emplace_back (solib_aix_so_ops);
new_solib.original_name = so_name;
new_solib.name = so_name;
new_solib.lm_info = std::make_unique<lm_info_aix> (info);
diff --git a/gdb/solib-darwin.c b/gdb/solib-darwin.c
index 4003c77748ca..88a2962f5dd5 100644
--- a/gdb/solib-darwin.c
+++ b/gdb/solib-darwin.c
@@ -250,7 +250,7 @@ darwin_current_sos ()
break;
/* Create and fill the new struct solib element. */
- auto &newobj = sos.emplace_back ();
+ auto &newobj = sos.emplace_back (darwin_so_ops);
auto li = std::make_unique<lm_info_darwin> ();
diff --git a/gdb/solib-dsbt.c b/gdb/solib-dsbt.c
index 2b3153692805..f6748b69353a 100644
--- a/gdb/solib-dsbt.c
+++ b/gdb/solib-dsbt.c
@@ -584,7 +584,7 @@ dsbt_current_sos (void)
break;
}
- auto &sop = sos.emplace_back ();
+ auto &sop = sos.emplace_back (dsbt_so_ops);
auto li = std::make_unique<lm_info_dsbt> ();
li->map = loadmap;
/* Fetch the name. */
diff --git a/gdb/solib-frv.c b/gdb/solib-frv.c
index ceef72208a1b..12d3140b513c 100644
--- a/gdb/solib-frv.c
+++ b/gdb/solib-frv.c
@@ -367,7 +367,7 @@ frv_current_sos ()
break;
}
- auto &sop = sos.emplace_back ();
+ auto &sop = sos.emplace_back (frv_so_ops);
auto li = std::make_unique<lm_info_frv> ();
li->map = loadmap;
li->got_value = got_addr;
diff --git a/gdb/solib-rocm.c b/gdb/solib-rocm.c
index b27613bbf91a..a3599562e795 100644
--- a/gdb/solib-rocm.c
+++ b/gdb/solib-rocm.c
@@ -210,7 +210,7 @@ solibs_from_rocm_sos (const std::vector<rocm_so> &sos)
for (const rocm_so &so : sos)
{
- auto &newobj = dst.emplace_back ();
+ auto &newobj = dst.emplace_back (rocm_solib_ops);
newobj.lm_info = std::make_unique<lm_info_svr4> (*so.lm_info);
newobj.name = so.name;
diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
index 48aace1feb48..deefc2578599 100644
--- a/gdb/solib-svr4.c
+++ b/gdb/solib-svr4.c
@@ -1050,7 +1050,7 @@ solib_from_svr4_sos (const std::vector<svr4_so> &sos)
for (const svr4_so &so : sos)
{
- auto &newobj = dst.emplace_back ();
+ auto &newobj = dst.emplace_back (svr4_so_ops);
newobj.name = so.name;
newobj.original_name = so.name;
@@ -1250,7 +1250,7 @@ svr4_default_sos (svr4_info *info)
li->l_addr_p = 1;
owning_intrusive_list<solib> sos;
- auto &newobj = sos.emplace_back ();
+ auto &newobj = sos.emplace_back (svr4_so_ops);
newobj.lm_info = std::move (li);
newobj.name = info->debug_loader_name;
diff --git a/gdb/solib-target.c b/gdb/solib-target.c
index 68dc3cc92c0a..61b841928ff8 100644
--- a/gdb/solib-target.c
+++ b/gdb/solib-target.c
@@ -245,7 +245,7 @@ solib_target_current_sos (void)
/* Build a struct solib for each entry on the list. */
for (lm_info_target_up &info : library_list)
{
- auto &new_solib = sos.emplace_back ();
+ auto &new_solib = sos.emplace_back (solib_target_so_ops);
/* We don't need a copy of the name in INFO anymore. */
new_solib.name = std::move (info->name);
diff --git a/gdb/solib.h b/gdb/solib.h
index f5922aa5f5d6..09d56c08b953 100644
--- a/gdb/solib.h
+++ b/gdb/solib.h
@@ -54,8 +54,19 @@ struct lm_info
using lm_info_up = std::unique_ptr<lm_info>;
+struct solib_ops;
+
struct solib : intrusive_list_node<solib>
{
+ /* Constructor
+
+ OPS is the solib_ops implementation providing this solib. */
+ explicit solib (const solib_ops &ops) : m_ops (&ops) {}
+
+ /* Return the solib_ops implementation providing this solib. */
+ const solib_ops &ops () const
+ { return *m_ops; }
+
/* Free symbol-file related contents of SO and reset for possible reloading
of SO. If we have opened a BFD for SO, close it. If we have placed SO's
sections in some target's section table, the caller is responsible for
@@ -111,6 +122,10 @@ struct solib : intrusive_list_node<solib>
that supports outputting multiple segments once the related code
supports them. */
CORE_ADDR addr_low = 0, addr_high = 0;
+
+private:
+ /* The solib_ops responsible for this solib. */
+ const solib_ops *m_ops;
};
/* A unique pointer to an solib. */
--
2.49.0
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v3 4/6] gdb/solib: use solib::ops for operations that concern a single solib
2025-06-16 19:32 [PATCH v3 1/6] gdb/testsuite: check that "info shared" and "info linker-namespaces" before running don't crash Simon Marchi
2025-06-16 19:33 ` [PATCH v3 2/6] gdb/solib: fix formatting of "info linker-namespaces" error message Simon Marchi
2025-06-16 19:33 ` [PATCH v3 3/6] gdb/solib: add solib -> solib_ops backlink Simon Marchi
@ 2025-06-16 19:33 ` Simon Marchi
2025-06-20 18:17 ` Pedro Alves
2025-06-16 19:33 ` [PATCH v3 5/6] gdb/progspace: add solib_ops pointer in program_space Simon Marchi
` (2 subsequent siblings)
5 siblings, 1 reply; 28+ messages in thread
From: Simon Marchi @ 2025-06-16 19:33 UTC (permalink / raw)
To: gdb-patches; +Cc: Simon Marchi
For operations that concern a single solib, use the solib_ops backlink
added in the previous patch (solib::ops), instead of using the solib_ops
from the gdbarch. This is a small / easy step towards not using
gdbarch_so_ops, which is necessary for the C++ification patch later in
this series.
There is no change in behavior expected.
Change-Id: If80e9ea717a2788bada1cf0940cda3c73933bcff
---
gdb/solib.c | 36 +++++++++++++++---------------------
1 file changed, 15 insertions(+), 21 deletions(-)
diff --git a/gdb/solib.c b/gdb/solib.c
index 90e7b906222c..d008a72c5a38 100644
--- a/gdb/solib.c
+++ b/gdb/solib.c
@@ -482,10 +482,8 @@ solib_bfd_open (const char *pathname)
static int
solib_map_sections (solib &so)
{
- const solib_ops *ops = gdbarch_so_ops (current_inferior ()->arch ());
-
gdb::unique_xmalloc_ptr<char> filename (tilde_expand (so.name.c_str ()));
- gdb_bfd_ref_ptr abfd (ops->bfd_open (filename.get ()));
+ gdb_bfd_ref_ptr abfd (so.ops ().bfd_open (filename.get ()));
/* If we have a core target then the core target might have some helpful
information (i.e. build-ids) about the shared libraries we are trying
@@ -495,7 +493,7 @@ solib_map_sections (solib &so)
If we don't have a core target then this will return an empty struct
with no hint information, we then lookup the shared library based on
its filename. */
- std::optional<CORE_ADDR> solib_addr = ops->find_solib_addr (so);
+ std::optional<CORE_ADDR> solib_addr = so.ops ().find_solib_addr (so);
std::optional <const core_target_mapped_file_info> mapped_file_info
= core_target_find_mapped_file (so.name.c_str (), solib_addr);
@@ -519,7 +517,7 @@ solib_map_sections (solib &so)
However, if it was good enough during the mapped file
processing, we assume it's good enough now. */
if (!mapped_file_info->filename ().empty ())
- abfd = ops->bfd_open (mapped_file_info->filename ().c_str ());
+ abfd = so.ops ().bfd_open (mapped_file_info->filename ().c_str ());
else
abfd = nullptr;
@@ -559,7 +557,7 @@ solib_map_sections (solib &so)
/* Relocate the section binding addresses as recorded in the shared
object's file by the base address to which the object was actually
mapped. */
- ops->relocate_section_addresses (so, &p);
+ so.ops ().relocate_section_addresses (so, &p);
/* If the target didn't provide information about the address
range of the shared object, assume we want the location of
@@ -586,8 +584,6 @@ solib_map_sections (solib &so)
void
solib::clear ()
{
- const solib_ops *ops = gdbarch_so_ops (current_inferior ()->arch ());
-
this->sections.clear ();
this->abfd = nullptr;
@@ -602,8 +598,8 @@ solib::clear ()
this->name = this->original_name;
/* Do the same for target-specific data. */
- if (ops->clear_so != NULL)
- ops->clear_so (*this);
+ if (this->ops ().clear_so != NULL)
+ this->ops ().clear_so (*this);
}
lm_info::~lm_info () = default;
@@ -1827,19 +1823,17 @@ static value *
linker_namespace_make_value (gdbarch *gdbarch, internalvar *var,
void *ignore)
{
- const solib_ops *ops = gdbarch_so_ops (gdbarch);
int nsid = 0;
- if (ops->find_solib_ns != nullptr)
- {
- CORE_ADDR curr_pc = get_frame_pc (get_selected_frame ());
- for (const solib &so : current_program_space->solibs ())
- if (solib_contains_address_p (so, curr_pc))
- {
- nsid = ops->find_solib_ns (so);
- break;
- }
- }
+ CORE_ADDR curr_pc = get_frame_pc (get_selected_frame ());
+ for (const solib &so : current_program_space->solibs ())
+ if (solib_contains_address_p (so, curr_pc))
+ {
+ if (so.ops ().find_solib_ns != nullptr)
+ nsid = so.ops ().find_solib_ns (so);
+
+ break;
+ }
/* If the PC is not in an SO, or the solib_ops doesn't support
linker namespaces, the inferior is in the default namespace. */
--
2.49.0
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v3 5/6] gdb/progspace: add solib_ops pointer in program_space
2025-06-16 19:32 [PATCH v3 1/6] gdb/testsuite: check that "info shared" and "info linker-namespaces" before running don't crash Simon Marchi
` (2 preceding siblings ...)
2025-06-16 19:33 ` [PATCH v3 4/6] gdb/solib: use solib::ops for operations that concern a single solib Simon Marchi
@ 2025-06-16 19:33 ` Simon Marchi
2025-06-17 19:45 ` Guinevere Larsen
` (2 more replies)
2025-06-16 19:33 ` [PATCH v3 6/6] gdb/solib: C++ify solib_ops Simon Marchi
2025-06-20 18:12 ` [PATCH v3 1/6] gdb/testsuite: check that "info shared" and "info linker-namespaces" before running don't crash Pedro Alves
5 siblings, 3 replies; 28+ messages in thread
From: Simon Marchi @ 2025-06-16 19:33 UTC (permalink / raw)
To: gdb-patches; +Cc: Simon Marchi
New in v3:
- add some ops nullptr checks in print_solib_list_table and
info_linker_namespace_command
The subsequent C++ification patch in this series will allocate one
instance of solib_ops per program space. That instance will be held in
struct program_space. As a small step towards this, add an `solib_ops
*` field to `struct program_space`. This field represents the solib_ops
currently used to manage the solibs in that program space. Initialize
it with the result of `gdbarch_so_ops` in `post_create_inferior`, and
use it whenever we need to do some solib stuff, rather than using
`gdbarch_so_ops` directly.
The difficulty here is knowing when exactly to set and unset the solib
ops. What I have here passes the testsuite on Linux, but with more
testing we will probably discover more spots where it's needed.
The C++ification patch will turn this field into a unique pointer.
With this patch, the message we get when running "info
linker-namespaces" becomes always the same, so update the test in
gdb.base/dlmopen-ns-ids.exp.
Change-Id: Ide8ddc57328895720fcd645d46dc34491f84c656
---
gdb/corelow.c | 2 +-
gdb/infcmd.c | 15 ++++---
gdb/inferior.h | 9 +++-
gdb/infrun.c | 11 ++++-
gdb/progspace.h | 20 +++++++++
gdb/solib.c | 55 +++++++++++++----------
gdb/target.c | 1 +
gdb/testsuite/gdb.base/dlmopen-ns-ids.exp | 3 +-
gdb/tracectf.c | 2 +-
gdb/tracefile-tfile.c | 2 +-
10 files changed, 83 insertions(+), 37 deletions(-)
diff --git a/gdb/corelow.c b/gdb/corelow.c
index b5895de9e9c6..d92585c67bfd 100644
--- a/gdb/corelow.c
+++ b/gdb/corelow.c
@@ -1180,7 +1180,7 @@ core_target_open (const char *arg, int from_tty)
if (current_program_space->exec_bfd () == nullptr)
set_gdbarch_from_file (current_program_space->core_bfd ());
- post_create_inferior (from_tty);
+ post_create_inferior (from_tty, true);
/* Now go through the target stack looking for threads since there
may be a thread_stratum target loaded on top of target core by
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index e9b58ce55210..1adad5c3eaa3 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -224,14 +224,11 @@ strip_bg_char (const char *args, int *bg_char_p)
return make_unique_xstrdup (args);
}
-/* Common actions to take after creating any sort of inferior, by any
- means (running, attaching, connecting, et cetera). The target
- should be stopped. */
+/* See inferior.h. */
void
-post_create_inferior (int from_tty)
+post_create_inferior (int from_tty, bool set_pspace_solib_ops)
{
-
/* Be sure we own the terminal in case write operations are performed. */
target_terminal::ours_for_output ();
@@ -261,6 +258,10 @@ post_create_inferior (int from_tty)
throw;
}
+ if (set_pspace_solib_ops)
+ current_program_space->set_solib_ops
+ (*gdbarch_so_ops (current_inferior ()->arch ()));
+
if (current_program_space->exec_bfd ())
{
const unsigned solib_add_generation
@@ -482,7 +483,7 @@ run_command_1 (const char *args, int from_tty, enum run_how run_how)
/* Pass zero for FROM_TTY, because at this point the "run" command
has done its thing; now we are setting up the running program. */
- post_create_inferior (0);
+ post_create_inferior (0, true);
/* Queue a pending event so that the program stops immediately. */
if (run_how == RUN_STOP_AT_FIRST_INSN)
@@ -2506,7 +2507,7 @@ setup_inferior (int from_tty)
/* Take any necessary post-attaching actions for this platform. */
target_post_attach (inferior_ptid.pid ());
- post_create_inferior (from_tty);
+ post_create_inferior (from_tty, true);
}
/* What to do after the first program stops after attaching. */
diff --git a/gdb/inferior.h b/gdb/inferior.h
index 54f5229b420f..fe94e289bdc7 100644
--- a/gdb/inferior.h
+++ b/gdb/inferior.h
@@ -213,7 +213,14 @@ extern ptid_t gdb_startup_inferior (pid_t pid, int num_traps);
extern void setup_inferior (int from_tty);
-extern void post_create_inferior (int from_tty);
+/* Common actions to take after creating any sort of inferior, by any
+ means (running, attaching, connecting, et cetera). The target
+ should be stopped.
+
+ If SET_PSPACE_SOLIB_OPS is true, initialize the program space's solib
+ provider using the current inferior's architecture. */
+
+extern void post_create_inferior (int from_tty, bool set_pspace_solib_ops);
extern void attach_command (const char *, int);
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 2e02642c52a4..5cdf66d26dcb 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -472,6 +472,7 @@ holding the child stopped. Try \"set %ps\" or \"%ps\".\n"),
inferior *parent_inf = current_inferior ();
inferior *child_inf = nullptr;
+ bool child_has_new_pspace = false;
gdb_assert (parent_inf->thread_waiting_for_vfork_done == nullptr);
@@ -536,6 +537,7 @@ holding the child stopped. Try \"set %ps\" or \"%ps\".\n"),
else
{
child_inf->pspace = new program_space (new_address_space ());
+ child_has_new_pspace = true;
child_inf->aspace = child_inf->pspace->aspace;
child_inf->removable = true;
clone_program_space (child_inf->pspace, parent_inf->pspace);
@@ -625,6 +627,7 @@ holding the child stopped. Try \"set %ps\" or \"%ps\".\n"),
else
{
child_inf->pspace = new program_space (new_address_space ());
+ child_has_new_pspace = true;
child_inf->aspace = child_inf->pspace->aspace;
child_inf->removable = true;
child_inf->symfile_flags = SYMFILE_NO_READ;
@@ -723,7 +726,8 @@ holding the child stopped. Try \"set %ps\" or \"%ps\".\n"),
maybe_restore.emplace ();
switch_to_thread (*child_inf->threads ().begin ());
- post_create_inferior (0);
+
+ post_create_inferior (0, child_has_new_pspace);
}
return false;
@@ -1321,6 +1325,7 @@ follow_exec (ptid_t ptid, const char *exec_file_target)
we don't want those to be satisfied by the libraries of the
previous incarnation of this process. */
no_shared_libraries (current_program_space);
+ current_program_space->unset_solib_ops ();
inferior *execing_inferior = current_inferior ();
inferior *following_inferior;
@@ -1377,6 +1382,8 @@ follow_exec (ptid_t ptid, const char *exec_file_target)
registers. */
target_find_description ();
+ current_program_space->set_solib_ops
+ (*gdbarch_so_ops (following_inferior->arch ()));
gdb::observers::inferior_execd.notify (execing_inferior, following_inferior);
breakpoint_re_set ();
@@ -3818,7 +3825,7 @@ start_remote (int from_tty)
/* Now that the inferior has stopped, do any bookkeeping like
loading shared libraries. We want to do this before normal_stop,
so that the displayed frame is up to date. */
- post_create_inferior (from_tty);
+ post_create_inferior (from_tty, true);
normal_stop ();
}
diff --git a/gdb/progspace.h b/gdb/progspace.h
index 5e5d5edd9b4b..abb448195d74 100644
--- a/gdb/progspace.h
+++ b/gdb/progspace.h
@@ -231,6 +231,23 @@ struct program_space
is outside all objfiles in this progspace. */
struct objfile *objfile_for_address (CORE_ADDR address);
+ /* Set this program space's solib provider.
+
+ The solib provider must be unset prior to call this method. */
+ void set_solib_ops (const struct solib_ops &ops)
+ {
+ gdb_assert (m_solib_ops == nullptr);
+ m_solib_ops = &ops;
+ };
+
+ /* Unset this program space's solib provider. */
+ void unset_solib_ops ()
+ { m_solib_ops = nullptr; }
+
+ /* Get this program space's solib provider. */
+ const struct solib_ops *solib_ops () const
+ { return m_solib_ops; }
+
/* Return the list of all the solibs in this program space. */
owning_intrusive_list<solib> &solibs ()
{ return m_solib_list; }
@@ -355,6 +372,9 @@ struct program_space
/* All known objfiles are kept in a linked list. */
owning_intrusive_list<objfile> m_objfiles_list;
+ /* solib_ops implementation used to provide solibs in this program space. */
+ const struct solib_ops *m_solib_ops = nullptr;
+
/* List of shared objects mapped into this space. Managed by
solib.c. */
owning_intrusive_list<solib> m_solib_list;
diff --git a/gdb/solib.c b/gdb/solib.c
index d008a72c5a38..675f64e2ae51 100644
--- a/gdb/solib.c
+++ b/gdb/solib.c
@@ -707,7 +707,10 @@ notify_solib_unloaded (program_space *pspace, const solib &so,
void
update_solib_list (int from_tty)
{
- const solib_ops *ops = gdbarch_so_ops (current_inferior ()->arch ());
+ const solib_ops *ops = current_program_space->solib_ops ();
+
+ if (ops == nullptr)
+ return;
/* We can reach here due to changing solib-search-path or the
sysroot, before having any inferior. */
@@ -1021,16 +1024,21 @@ print_solib_list_table (std::vector<const solib *> solib_list,
gdbarch *gdbarch = current_inferior ()->arch ();
/* "0x", a little whitespace, and two hex digits per byte of pointers. */
int addr_width = 4 + (gdbarch_ptr_bit (gdbarch) / 4);
- const solib_ops *ops = gdbarch_so_ops (gdbarch);
+ const solib_ops *ops = current_program_space->solib_ops ();
struct ui_out *uiout = current_uiout;
bool so_missing_debug_info = false;
+ if (ops == nullptr)
+ return;
+
/* There are 3 conditions for this command to print solib namespaces,
first PRINT_NAMESPACE has to be true, second the solib_ops has to
support multiple namespaces, and third there must be more than one
active namespace. Fold all these into the PRINT_NAMESPACE condition. */
- print_namespace = print_namespace && ops->num_active_namespaces != nullptr
- && ops->num_active_namespaces () > 1;
+ print_namespace = (print_namespace
+ && ops != nullptr
+ && ops->num_active_namespaces != nullptr
+ && ops->num_active_namespaces () > 1);
int num_cols = 4;
if (print_namespace)
@@ -1155,10 +1163,11 @@ info_sharedlibrary_command (const char *pattern, int from_tty)
static void
info_linker_namespace_command (const char *pattern, int from_tty)
{
- const solib_ops *ops = gdbarch_so_ops (current_inferior ()->arch ());
+ const solib_ops *ops = current_program_space->solib_ops ();
+
/* This command only really makes sense for inferiors that support
linker namespaces, so we can leave early. */
- if (ops->num_active_namespaces == nullptr)
+ if (ops == nullptr || ops->num_active_namespaces == nullptr)
error (_("Current inferior does not support linker namespaces. " \
"Use \"info sharedlibrary\" instead."));
@@ -1273,9 +1282,9 @@ solib_name_from_address (struct program_space *pspace, CORE_ADDR address)
bool
solib_keep_data_in_core (CORE_ADDR vaddr, unsigned long size)
{
- const solib_ops *ops = gdbarch_so_ops (current_inferior ()->arch ());
+ const solib_ops *ops = current_program_space->solib_ops ();
- if (ops->keep_data_in_core)
+ if (ops != nullptr && ops->keep_data_in_core != nullptr)
return ops->keep_data_in_core (vaddr, size) != 0;
else
return false;
@@ -1286,8 +1295,6 @@ solib_keep_data_in_core (CORE_ADDR vaddr, unsigned long size)
void
clear_solib (program_space *pspace)
{
- const solib_ops *ops = gdbarch_so_ops (current_inferior ()->arch ());
-
for (solib &so : pspace->solibs ())
{
bool still_in_use
@@ -1299,7 +1306,9 @@ clear_solib (program_space *pspace)
pspace->solibs ().clear ();
- if (ops->clear_solib != nullptr)
+ const solib_ops *ops = pspace->solib_ops ();
+
+ if (ops != nullptr && ops->clear_solib != nullptr)
ops->clear_solib (pspace);
}
@@ -1311,9 +1320,9 @@ clear_solib (program_space *pspace)
void
solib_create_inferior_hook (int from_tty)
{
- const solib_ops *ops = gdbarch_so_ops (current_inferior ()->arch ());
+ const solib_ops *ops = current_program_space->solib_ops ();
- if (ops->solib_create_inferior_hook != nullptr)
+ if (ops != nullptr && ops->solib_create_inferior_hook != nullptr)
ops->solib_create_inferior_hook (from_tty);
}
@@ -1322,10 +1331,10 @@ solib_create_inferior_hook (int from_tty)
bool
in_solib_dynsym_resolve_code (CORE_ADDR pc)
{
- const auto in_dynsym_resolve_code
- = gdbarch_so_ops (current_inferior ()->arch ())->in_dynsym_resolve_code;
+ const solib_ops *ops = current_program_space->solib_ops ();
- return in_dynsym_resolve_code && in_dynsym_resolve_code (pc);
+ return (ops != nullptr && ops->in_dynsym_resolve_code != nullptr
+ && ops->in_dynsym_resolve_code (pc));
}
/* Implements the "sharedlibrary" command. */
@@ -1367,9 +1376,9 @@ no_shared_libraries_command (const char *ignored, int from_tty)
void
update_solib_breakpoints (void)
{
- const solib_ops *ops = gdbarch_so_ops (current_inferior ()->arch ());
+ const solib_ops *ops = current_program_space->solib_ops ();
- if (ops->update_breakpoints != NULL)
+ if (ops != nullptr && ops->update_breakpoints != nullptr)
ops->update_breakpoints ();
}
@@ -1378,9 +1387,9 @@ update_solib_breakpoints (void)
void
handle_solib_event (void)
{
- const solib_ops *ops = gdbarch_so_ops (current_inferior ()->arch ());
+ const solib_ops *ops = current_program_space->solib_ops ();
- if (ops->handle_event != NULL)
+ if (ops != nullptr && ops->handle_event != nullptr)
ops->handle_event ();
current_inferior ()->pspace->clear_solib_cache ();
@@ -1464,8 +1473,6 @@ reload_shared_libraries (const char *ignored, int from_tty,
{
reload_shared_libraries_1 (from_tty);
- const solib_ops *ops = gdbarch_so_ops (current_inferior ()->arch ());
-
/* Creating inferior hooks here has two purposes. First, if we reload
shared libraries then the address of solib breakpoint we've computed
previously might be no longer valid. For example, if we forgot to set
@@ -1477,9 +1484,11 @@ reload_shared_libraries (const char *ignored, int from_tty,
about ld.so. */
if (target_has_execution ())
{
+ const solib_ops *ops = current_program_space->solib_ops ();
+
/* Reset or free private data structures not associated with
solib entries. */
- if (ops->clear_solib != nullptr)
+ if (ops != nullptr && ops->clear_solib != nullptr)
ops->clear_solib (current_program_space);
/* Remove any previous solib event breakpoint. This is usually
diff --git a/gdb/target.c b/gdb/target.c
index 522bed8e939c..7a296572830e 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -2464,6 +2464,7 @@ target_pre_inferior ()
if (!gdbarch_has_global_solist (current_inferior ()->arch ()))
{
no_shared_libraries (current_program_space);
+ current_program_space->unset_solib_ops ();
invalidate_target_mem_regions ();
diff --git a/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp b/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp
index 8613056a7c8b..4d3e8eba2ab1 100644
--- a/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp
+++ b/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp
@@ -171,7 +171,8 @@ proc test_info_linker_namespaces {} {
# Check that "info linker-namespaces" while the inferior is not running
# doesn't crash.
- gdb_test "info linker-namespaces" ".*" \
+ gdb_test "info linker-namespaces" \
+ "Current inferior does not support linker namespaces\\. Use \"info sharedlibrary\" instead\\." \
"info linker-namespaces before running"
if { ![runto_main] } {
diff --git a/gdb/tracectf.c b/gdb/tracectf.c
index 1650e676d814..ce0b0079a29e 100644
--- a/gdb/tracectf.c
+++ b/gdb/tracectf.c
@@ -1174,7 +1174,7 @@ ctf_target_open (const char *args, int from_tty)
merge_uploaded_trace_state_variables (&uploaded_tsvs);
merge_uploaded_tracepoints (&uploaded_tps);
- post_create_inferior (from_tty);
+ post_create_inferior (from_tty, true);
}
/* This is the implementation of target_ops method to_close. Destroy
diff --git a/gdb/tracefile-tfile.c b/gdb/tracefile-tfile.c
index 5f8b338df4cc..093b10e51d6e 100644
--- a/gdb/tracefile-tfile.c
+++ b/gdb/tracefile-tfile.c
@@ -567,7 +567,7 @@ tfile_target_open (const char *arg, int from_tty)
merge_uploaded_tracepoints (&uploaded_tps);
- post_create_inferior (from_tty);
+ post_create_inferior (from_tty, true);
}
/* Interpret the given line from the definitions part of the trace
--
2.49.0
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v3 6/6] gdb/solib: C++ify solib_ops
2025-06-16 19:32 [PATCH v3 1/6] gdb/testsuite: check that "info shared" and "info linker-namespaces" before running don't crash Simon Marchi
` (3 preceding siblings ...)
2025-06-16 19:33 ` [PATCH v3 5/6] gdb/progspace: add solib_ops pointer in program_space Simon Marchi
@ 2025-06-16 19:33 ` Simon Marchi
2025-06-20 18:20 ` Pedro Alves
2025-06-20 18:12 ` [PATCH v3 1/6] gdb/testsuite: check that "info shared" and "info linker-namespaces" before running don't crash Pedro Alves
5 siblings, 1 reply; 28+ messages in thread
From: Simon Marchi @ 2025-06-16 19:33 UTC (permalink / raw)
To: gdb-patches; +Cc: Simon Marchi
Convert solib_ops into an abstract base class (with abstract methods,
some of them with default implementations) and convert all the existing
solib_ops instances to solib_ops derived classes / implementations.
Prior to this patch, solib_ops is a structure holding function pointers,
of which there are only a handful of global instances (in the
`solib-*.c` files). When passing an `solib_ops *` around, it's a
pointer to one of these instances. After this patch, there are no more
global solib_ops instances. Instances are created as needed and stored
in struct program_space. These instances could eventually be made to
contain the program space-specific data, which is currently kept in
per-program space registries (I have some pending patches for that).
Prior to this patch, `gdbarch_so_ops` is a gdbarch method that returns a
pointer to the appropriate solib_ops implementation for the gdbarch.
This is replaced with the `gdbarch_new_solib_ops` method, which returns
a new instance of the appropriate solib_ops implementation for this
gdbarch. This requires introducing some factory functions for the
various solib_ops implementation, to be used as `gdbarch_new_solib_ops`
callbacks. For instance:
solib_ops_up
new_linux_ilp32_svr4_solib_ops ()
{
return std::make_unique<linux_ilp32_svr4_solib_ops> ();
}
The previous code is full of cases of tdep files copying some base
solib_ops implementation, and overriding one or more function pointer
(see ppc_linux_init_abi, for instance). I tried to convert all of this
is a class hierarchy. I like that it's now possible to get a good
static view of all the existing solib_ops variants. The hierarchy looks
like this:
solib_ops
├── aix_solib_ops
├── darwin_solib_ops
├── dsbt_solib_ops
├── frv_solib_ops
├── rocm_solib_ops
├── svr4_solib_ops
│ ├── ilp32_svr4_solib_ops
│ ├── lp64_svr4_solib_ops
│ ├── linux_ilp32_svr4_solib_ops
│ │ ├── mips_linux_ilp32_svr4_solib_ops
│ │ └── ppc_linux_ilp32_svr4_solib_ops
│ ├── linux_lp64_svr4_solib_ops
│ │ └── mips_linux_lp64_svr4_solib_ops
│ ├── mips_nbsd_ilp32_svr4_solib_ops
│ ├── mips_nbsd_lp64_svr4_solib_ops
│ ├── mips_fbsd_ilp32_svr4_solib_ops
│ └── mips_fbsd_lp64_svr4_solib_ops
└── target_solib_ops
└── windows_solib_ops
The solib-svr4 code has per-arch specialization to provide a
link_map_offsets, containing the offsets of the interesting fields in
`struct link_map` on that particular architecture. Prior to this patch,
arches would set a callback returning the appropriate link_map_offsets
by calling `set_solib_svr4_fetch_link_map_offsets`, which also happened
to set the gdbarch's so_ops to `&svr_so_ops`. I converted this to an
abstract virtual method of `struct svr4_solib_ops`, meaning that all
classes deriving from svr4_solib_ops must provide a method returning the
appropriate link_map_offsets for the architecture. I renamed
`set_solib_svr4_fetch_link_map_offsets` to `set_solib_svr4_ops`. This
function is still necessary because it also calls
set_gdbarch_iterate_over_objfiles_in_search_order, but if it was not for
that, we could get rid of it.
There is a little "base class template" hack in mips-linux-tdep.c,
because both mips_linux_ilp32_svr4_solib_ops and
mips_linux_lp64_svr4_solib_ops need to derive from different SVR4 base
classes (linux_ilp32_svr4_solib_ops and linux_lp64_svr4_solib_ops), but
they both want to override the in_dynsym_resolve_code method with the
same implementation. Let me know if there's a more straightforward way
to do this.
The solib_ops::supports_namespaces method is new: the support for
namespaces was previously predicated by the presence or absence of a
find_solib_ns method. It now needs to be explicit.
There is a new progspace::release_solib_ops method, which is only needed
for rocm_solib_ops. For the moment, rocm_solib_ops replaces and wraps
the existing svr4_solib_ops instance, in order to combine the results of
the two. The plan is to have a subsequent patch to allow program spaces to have
multiple solib_ops, removing the need that release_solib_ops.
Speaking of rocm_solib_ops: it previously overrode only a few methods by
copying svr4_solib_ops and overwriting some function pointers. Now, it
needs to implement all the methods that svr4_solib_ops implements, in
order to forward the call. Otherwise, the default solib_ops method woul
be called, hiding the svr4_solib_ops implementation. Again, this can be
removed once we have support for multiple solib_ops in a program_space.
There is also a small change in how rocm_solib_ops is activated. Prior
to this patch, it's done at the end of rocm_update_solib_list. Since it
overrides the function pointer in the static svr4_solib_ops, and then
overwrites the host gdbarch, so_ops field, it's something that happens
only once. After the patch though, we need to set rocm_solib_ops in all
the program spaces that appear. We do this in
rocm_solib_target_inferior_created and in the new
rocm_solib_target_inferior_execd. After this, I will explore doing a
change where rocm_solib_ops is only set when we detect the ROCm runtime
is loaded.
Change-Id: I5896b5bcbf8bdb024d67980380feba1ffefaa4c9
---
gdb/Makefile.in | 3 +
gdb/aarch64-fbsd-tdep.c | 3 +-
gdb/aarch64-linux-tdep.c | 5 +-
gdb/alpha-linux-tdep.c | 5 +-
gdb/alpha-netbsd-tdep.c | 3 +-
gdb/alpha-obsd-tdep.c | 3 +-
gdb/amd-dbgapi-target.c | 18 +-
gdb/amd-dbgapi-target.h | 5 +
gdb/amd64-darwin-tdep.c | 2 +-
gdb/amd64-fbsd-tdep.c | 3 +-
gdb/amd64-gnu-tdep.c | 3 +-
gdb/amd64-linux-tdep.c | 7 +-
gdb/amd64-netbsd-tdep.c | 3 +-
gdb/amd64-obsd-tdep.c | 3 +-
gdb/amd64-sol2-tdep.c | 3 +-
gdb/arc-linux-tdep.c | 4 +-
gdb/arm-fbsd-tdep.c | 3 +-
gdb/arm-linux-tdep.c | 4 +-
gdb/arm-netbsd-tdep.c | 3 +-
gdb/arm-obsd-tdep.c | 3 +-
gdb/configure.tgt | 62 ++++--
gdb/cris-linux-tdep.c | 5 +-
gdb/csky-linux-tdep.c | 4 +-
gdb/dicos-tdep.c | 2 +-
gdb/frv-tdep.c | 3 +-
gdb/frv-tdep.h | 3 -
gdb/gdbarch-gen.c | 24 +--
gdb/gdbarch-gen.h | 7 +-
gdb/gdbarch.h | 1 +
gdb/gdbarch_components.py | 12 +-
gdb/hppa-bsd-tdep.c | 3 +-
gdb/hppa-linux-tdep.c | 4 +-
gdb/i386-darwin-tdep.c | 2 +-
gdb/i386-fbsd-tdep.c | 3 +-
gdb/i386-gnu-tdep.c | 3 +-
gdb/i386-linux-tdep.c | 4 +-
gdb/i386-netbsd-tdep.c | 3 +-
gdb/i386-obsd-tdep.c | 3 +-
gdb/i386-sol2-tdep.c | 3 +-
gdb/ia64-linux-tdep.c | 4 +-
gdb/infcmd.c | 2 +-
gdb/infrun.c | 2 +-
gdb/linux-tdep.c | 61 ------
gdb/linux-tdep.h | 6 +-
gdb/loongarch-linux-tdep.c | 8 +-
gdb/m32r-linux-tdep.c | 4 +-
gdb/m68k-bsd-tdep.c | 3 +-
gdb/m68k-linux-tdep.c | 4 +-
gdb/microblaze-linux-tdep.c | 4 +-
gdb/mips-fbsd-tdep.c | 57 ++++-
gdb/mips-linux-tdep.c | 65 ++++--
gdb/mips-netbsd-tdep.c | 54 ++++-
gdb/mips64-obsd-tdep.c | 3 +-
gdb/mn10300-linux-tdep.c | 4 +-
gdb/or1k-linux-tdep.c | 4 +-
gdb/ppc-fbsd-tdep.c | 6 +-
gdb/ppc-linux-tdep.c | 46 ++--
gdb/ppc-netbsd-tdep.c | 3 +-
gdb/ppc-obsd-tdep.c | 3 +-
gdb/progspace.h | 17 +-
gdb/riscv-fbsd-tdep.c | 7 +-
gdb/riscv-linux-tdep.c | 8 +-
gdb/rs6000-aix-tdep.c | 2 +-
gdb/s390-linux-tdep.c | 7 +-
gdb/sh-linux-tdep.c | 4 +-
gdb/sh-netbsd-tdep.c | 3 +-
gdb/solib-aix.c | 67 +++---
gdb/solib-aix.h | 7 +-
gdb/solib-darwin.c | 65 +++---
gdb/solib-darwin.h | 6 +-
gdb/solib-dsbt.c | 59 ++---
gdb/solib-dsbt.h | 6 +-
gdb/solib-frv.c | 63 +++---
gdb/solib-frv.h | 28 +++
gdb/solib-rocm.c | 148 +++++++++----
gdb/solib-svr4-linux.c | 98 +++++++++
gdb/solib-svr4-linux.h | 47 ++++
gdb/solib-svr4.c | 415 +++++++++++++++---------------------
gdb/solib-svr4.h | 126 +++++++++--
gdb/solib-target.c | 40 ++--
gdb/solib-target.h | 16 +-
gdb/solib.c | 88 ++++----
gdb/solib.h | 137 +++++++-----
gdb/sparc-linux-tdep.c | 4 +-
gdb/sparc-netbsd-tdep.c | 3 +-
gdb/sparc-sol2-tdep.c | 3 +-
gdb/sparc64-fbsd-tdep.c | 3 +-
gdb/sparc64-linux-tdep.c | 4 +-
gdb/sparc64-netbsd-tdep.c | 3 +-
gdb/sparc64-obsd-tdep.c | 3 +-
gdb/sparc64-sol2-tdep.c | 3 +-
gdb/tic6x-linux-tdep.c | 2 +-
gdb/tilegx-linux-tdep.c | 7 +-
gdb/vax-netbsd-tdep.c | 3 +-
gdb/windows-tdep.c | 26 ++-
gdb/xtensa-linux-tdep.c | 4 +-
gdb/xtensa-tdep.c | 3 +-
97 files changed, 1224 insertions(+), 891 deletions(-)
create mode 100644 gdb/solib-frv.h
create mode 100644 gdb/solib-svr4-linux.c
create mode 100644 gdb/solib-svr4-linux.h
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 998203ce1e20..fc0c56564c23 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -891,6 +891,7 @@ ALL_TARGET_OBS = \
solib-dsbt.o \
solib-frv.o \
solib-svr4.o \
+ solib-svr4-linux.o \
sparc-linux-tdep.o \
sparc-netbsd-tdep.o \
sparc-obsd-tdep.o \
@@ -1478,7 +1479,9 @@ HFILES_NO_SRCDIR = \
solib.h \
solib-aix.h \
solib-darwin.h \
+ solib-frv.h \
solib-svr4.h \
+ solib-svr4-linux.h \
solib-target.h \
source.h \
source-cache.h \
diff --git a/gdb/aarch64-fbsd-tdep.c b/gdb/aarch64-fbsd-tdep.c
index 07fa38a37285..7227456b7a6f 100644
--- a/gdb/aarch64-fbsd-tdep.c
+++ b/gdb/aarch64-fbsd-tdep.c
@@ -239,8 +239,7 @@ aarch64_fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
/* Generic FreeBSD support. */
fbsd_init_abi (info, gdbarch);
- set_solib_svr4_fetch_link_map_offsets (gdbarch,
- svr4_lp64_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_svr4_lp64_solib_ops);
tramp_frame_prepend_unwinder (gdbarch, &aarch64_fbsd_sigframe);
diff --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c
index a194ac809c23..43b5e2a781f0 100644
--- a/gdb/aarch64-linux-tdep.c
+++ b/gdb/aarch64-linux-tdep.c
@@ -23,6 +23,7 @@
#include "extract-store-integer.h"
#include "gdbarch.h"
#include "glibc-tdep.h"
+#include "solib-svr4-linux.h"
#include "linux-tdep.h"
#include "svr4-tls-tdep.h"
#include "aarch64-tdep.h"
@@ -2768,9 +2769,7 @@ aarch64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
tdep->lowest_pc = 0x8000;
linux_init_abi (info, gdbarch, 1);
-
- set_solib_svr4_fetch_link_map_offsets (gdbarch,
- linux_lp64_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_linux_lp64_svr4_solib_ops);
/* Enable TLS support. */
set_gdbarch_fetch_tls_load_module_address (gdbarch,
diff --git a/gdb/alpha-linux-tdep.c b/gdb/alpha-linux-tdep.c
index 2f6affa6a6d5..0ad731e567ed 100644
--- a/gdb/alpha-linux-tdep.c
+++ b/gdb/alpha-linux-tdep.c
@@ -17,6 +17,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "frame.h"
+#include "solib-svr4-linux.h"
#include "osabi.h"
#include "solib-svr4.h"
#include "symtab.h"
@@ -369,9 +370,7 @@ alpha_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
tdep->jb_elt_size = 8;
set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
-
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, linux_lp64_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_linux_lp64_svr4_solib_ops);
/* Enable TLS support. */
set_gdbarch_fetch_tls_load_module_address (gdbarch,
diff --git a/gdb/alpha-netbsd-tdep.c b/gdb/alpha-netbsd-tdep.c
index a24003918bba..1c1dc66791e7 100644
--- a/gdb/alpha-netbsd-tdep.c
+++ b/gdb/alpha-netbsd-tdep.c
@@ -264,8 +264,7 @@ alphanbsd_init_abi (struct gdbarch_info info,
set_gdbarch_software_single_step (gdbarch, alpha_software_single_step);
/* NetBSD/alpha has SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_lp64_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_svr4_lp64_solib_ops);
tdep->dynamic_sigtramp_offset = alphanbsd_sigtramp_offset;
tdep->pc_in_sigtramp = alphanbsd_pc_in_sigtramp;
diff --git a/gdb/alpha-obsd-tdep.c b/gdb/alpha-obsd-tdep.c
index b5ddbbc61cf4..6d153bb1b413 100644
--- a/gdb/alpha-obsd-tdep.c
+++ b/gdb/alpha-obsd-tdep.c
@@ -109,8 +109,7 @@ alphaobsd_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch)
set_gdbarch_software_single_step (gdbarch, alpha_software_single_step);
/* OpenBSD/alpha has SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_lp64_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_svr4_lp64_solib_ops);
set_gdbarch_skip_solib_resolver (gdbarch, obsd_skip_solib_resolver);
tdep->dynamic_sigtramp_offset = alphaobsd_sigtramp_offset;
diff --git a/gdb/amd-dbgapi-target.c b/gdb/amd-dbgapi-target.c
index e2a8ec83404e..564dcc1dc48c 100644
--- a/gdb/amd-dbgapi-target.c
+++ b/gdb/amd-dbgapi-target.c
@@ -104,12 +104,26 @@ amd_dbgapi_lib_debug_module ()
static gdb::observers::token amd_dbgapi_target_inferior_created_observer_token;
+/* See amd-dbgapi-target.h. */
+
const gdb::observers::token &
get_amd_dbgapi_target_inferior_created_observer_token ()
{
return amd_dbgapi_target_inferior_created_observer_token;
}
+/* inferior_execd observer token. */
+
+static gdb::observers::token amd_dbgapi_target_inferior_execd_observer_token;
+
+/* See amd-dbgapi-target.h. */
+
+const gdb::observers::token &
+get_amd_dbgapi_target_inferior_execd_observer_token ()
+{
+ return amd_dbgapi_target_inferior_execd_observer_token;
+}
+
/* A type holding coordinates, etc. info for a given wave. */
struct wave_coordinates
@@ -2506,7 +2520,9 @@ _initialize_amd_dbgapi_target ()
gdb::observers::inferior_created.attach
(amd_dbgapi_target_inferior_created,
amd_dbgapi_target_inferior_created_observer_token, "amd-dbgapi");
- gdb::observers::inferior_execd.attach (amd_dbgapi_inferior_execd, "amd-dbgapi");
+ gdb::observers::inferior_execd.attach
+ (amd_dbgapi_inferior_execd, amd_dbgapi_target_inferior_execd_observer_token,
+ "amd-dbgapi");
gdb::observers::inferior_forked.attach (amd_dbgapi_inferior_forked, "amd-dbgapi");
gdb::observers::inferior_exit.attach (amd_dbgapi_inferior_exited, "amd-dbgapi");
gdb::observers::inferior_pre_detach.attach (amd_dbgapi_inferior_pre_detach, "amd-dbgapi");
diff --git a/gdb/amd-dbgapi-target.h b/gdb/amd-dbgapi-target.h
index dd37ba3b82d2..fe3a50ba33b0 100644
--- a/gdb/amd-dbgapi-target.h
+++ b/gdb/amd-dbgapi-target.h
@@ -54,6 +54,11 @@ using is_amd_dbgapi_handle
const gdb::observers::token &
get_amd_dbgapi_target_inferior_created_observer_token ();
+/* Get the token of amd-dbgapi's inferior_execd observer. */
+
+const gdb::observers::token &
+ get_amd_dbgapi_target_inferior_execd_observer_token ();
+
/* Comparison operators for amd-dbgapi handle types. */
template <typename T,
diff --git a/gdb/amd64-darwin-tdep.c b/gdb/amd64-darwin-tdep.c
index dde023e0fb08..f26ccc49f2c0 100644
--- a/gdb/amd64-darwin-tdep.c
+++ b/gdb/amd64-darwin-tdep.c
@@ -113,7 +113,7 @@ x86_darwin_init_abi_64 (struct gdbarch_info info, struct gdbarch *gdbarch)
tdep->jb_pc_offset = 56;
- set_gdbarch_so_ops (gdbarch, &darwin_so_ops);
+ set_gdbarch_new_solib_ops (gdbarch, new_darwin_solib_ops);
}
void _initialize_amd64_darwin_tdep ();
diff --git a/gdb/amd64-fbsd-tdep.c b/gdb/amd64-fbsd-tdep.c
index eea01054aca0..b936a70bb54f 100644
--- a/gdb/amd64-fbsd-tdep.c
+++ b/gdb/amd64-fbsd-tdep.c
@@ -328,8 +328,7 @@ amd64fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
amd64fbsd_core_read_description);
/* FreeBSD uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_lp64_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_svr4_lp64_solib_ops);
set_gdbarch_fetch_tls_load_module_address (gdbarch,
svr4_fetch_objfile_link_map);
diff --git a/gdb/amd64-gnu-tdep.c b/gdb/amd64-gnu-tdep.c
index 602fa8e61160..3dfdf81adf8b 100644
--- a/gdb/amd64-gnu-tdep.c
+++ b/gdb/amd64-gnu-tdep.c
@@ -218,8 +218,7 @@ amd64_gnu_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
tdep->sc_num_regs = ARRAY_SIZE (amd64_gnu_sc_reg_offset);
/* Hurd uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_lp64_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_svr4_lp64_solib_ops);
}
void _initialize_amd64_gnu_tdep ();
diff --git a/gdb/amd64-linux-tdep.c b/gdb/amd64-linux-tdep.c
index e5a2ab9dd526..8a44d233caa3 100644
--- a/gdb/amd64-linux-tdep.c
+++ b/gdb/amd64-linux-tdep.c
@@ -33,6 +33,7 @@
#include "amd64-linux-tdep.h"
#include "i386-linux-tdep.h"
#include "linux-tdep.h"
+#include "solib-svr4-linux.h"
#include "svr4-tls-tdep.h"
#include "gdbsupport/x86-xstate.h"
#include "inferior.h"
@@ -2130,8 +2131,7 @@ amd64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
tdep->i386_syscall_record = amd64_linux_syscall_record;
/* GNU/Linux uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, linux_lp64_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_linux_lp64_svr4_solib_ops);
/* Register DTrace handlers. */
set_gdbarch_dtrace_parse_probe_argument (gdbarch, amd64_dtrace_parse_probe_argument);
@@ -2344,8 +2344,7 @@ amd64_x32_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
tdep->i386_syscall_record = amd64_x32_linux_syscall_record;
/* GNU/Linux uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, linux_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_linux_ilp32_svr4_solib_ops);
}
void _initialize_amd64_linux_tdep ();
diff --git a/gdb/amd64-netbsd-tdep.c b/gdb/amd64-netbsd-tdep.c
index f4464b796118..d1e088003dba 100644
--- a/gdb/amd64-netbsd-tdep.c
+++ b/gdb/amd64-netbsd-tdep.c
@@ -116,8 +116,7 @@ amd64nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
tdep->sc_num_regs = ARRAY_SIZE (amd64nbsd_r_reg_offset);
/* NetBSD uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_lp64_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_svr4_lp64_solib_ops);
}
void _initialize_amd64nbsd_tdep ();
diff --git a/gdb/amd64-obsd-tdep.c b/gdb/amd64-obsd-tdep.c
index 5acc380e7995..bd3d655a5e08 100644
--- a/gdb/amd64-obsd-tdep.c
+++ b/gdb/amd64-obsd-tdep.c
@@ -443,8 +443,7 @@ amd64obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
bsd_uthread_set_collect_uthread (gdbarch, amd64obsd_collect_uthread);
/* OpenBSD uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_lp64_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_svr4_lp64_solib_ops);
/* Unwind kernel trap frames correctly. */
frame_unwind_prepend_unwinder (gdbarch, &amd64obsd_trapframe_unwind);
diff --git a/gdb/amd64-sol2-tdep.c b/gdb/amd64-sol2-tdep.c
index 84d5f87b814a..7c9fa1965aeb 100644
--- a/gdb/amd64-sol2-tdep.c
+++ b/gdb/amd64-sol2-tdep.c
@@ -96,8 +96,7 @@ amd64_sol2_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
tdep->sc_num_regs = tdep->gregset_num_regs;
/* Solaris uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_lp64_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_svr4_lp64_solib_ops);
}
void _initialize_amd64_sol2_tdep ();
diff --git a/gdb/arc-linux-tdep.c b/gdb/arc-linux-tdep.c
index adf669151d1e..dfa5fc225b07 100644
--- a/gdb/arc-linux-tdep.c
+++ b/gdb/arc-linux-tdep.c
@@ -19,6 +19,7 @@
/* GDB header files. */
#include "linux-tdep.h"
+#include "solib-svr4-linux.h"
#include "objfiles.h"
#include "opcode/arc.h"
#include "osabi.h"
@@ -736,8 +737,7 @@ arc_linux_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch)
/* GNU/Linux uses SVR4-style shared libraries, with 32-bit ints, longs
and pointers (ILP32). */
- set_solib_svr4_fetch_link_map_offsets (gdbarch,
- linux_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_linux_ilp32_svr4_solib_ops);
}
/* Suppress warning from -Wmissing-prototypes. */
diff --git a/gdb/arm-fbsd-tdep.c b/gdb/arm-fbsd-tdep.c
index c9a466f91cd4..2e9024136f93 100644
--- a/gdb/arm-fbsd-tdep.c
+++ b/gdb/arm-fbsd-tdep.c
@@ -300,8 +300,7 @@ arm_fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
tramp_frame_prepend_unwinder (gdbarch, &arm_fbsd_sigframe);
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_svr4_ilp32_solib_ops);
tdep->jb_pc = 24;
tdep->jb_elt_size = 4;
diff --git a/gdb/arm-linux-tdep.c b/gdb/arm-linux-tdep.c
index 485a5d9cee36..316b3e733cef 100644
--- a/gdb/arm-linux-tdep.c
+++ b/gdb/arm-linux-tdep.c
@@ -41,6 +41,7 @@
#include "arm-tdep.h"
#include "arm-linux-tdep.h"
#include "linux-tdep.h"
+#include "solib-svr4-linux.h"
#include "glibc-tdep.h"
#include "arch-utils.h"
#include "inferior.h"
@@ -1801,8 +1802,7 @@ arm_linux_init_abi (struct gdbarch_info info,
}
tdep->jb_elt_size = ARM_LINUX_JB_ELEMENT_SIZE;
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, linux_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_linux_ilp32_svr4_solib_ops);
/* Single stepping. */
set_gdbarch_software_single_step (gdbarch, arm_linux_software_single_step);
diff --git a/gdb/arm-netbsd-tdep.c b/gdb/arm-netbsd-tdep.c
index a16205436a9a..89fcbde10283 100644
--- a/gdb/arm-netbsd-tdep.c
+++ b/gdb/arm-netbsd-tdep.c
@@ -156,8 +156,7 @@ arm_netbsd_elf_init_abi (struct gdbarch_info info,
tdep->fp_model = ARM_FLOAT_SOFT_VFP;
/* NetBSD ELF uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_svr4_ilp32_solib_ops);
}
void _initialize_arm_netbsd_tdep ();
diff --git a/gdb/arm-obsd-tdep.c b/gdb/arm-obsd-tdep.c
index 6fd4c8544719..a2ec923854ca 100644
--- a/gdb/arm-obsd-tdep.c
+++ b/gdb/arm-obsd-tdep.c
@@ -83,8 +83,7 @@ armobsd_init_abi (struct gdbarch_info info,
tramp_frame_prepend_unwinder (gdbarch, &armobsd_sigframe);
/* OpenBSD/arm uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_svr4_ilp32_solib_ops);
set_gdbarch_skip_solib_resolver (gdbarch, obsd_skip_solib_resolver);
tdep->jb_pc = 24;
diff --git a/gdb/configure.tgt b/gdb/configure.tgt
index e9b306809dc1..255c77e9f8c0 100644
--- a/gdb/configure.tgt
+++ b/gdb/configure.tgt
@@ -150,14 +150,15 @@ aarch64*-*-linux*)
arch/aarch64-scalable-linux.o \
arch/arm.o arch/arm-linux.o arch/arm-get-next-pcs.o \
arm-tdep.o arm-linux-tdep.o \
- glibc-tdep.o linux-tdep.o solib-svr4.o svr4-tls-tdep.o \
+ glibc-tdep.o linux-tdep.o solib-svr4.o \
+ solib-svr4-linux.o svr4-tls-tdep.o \
symfile-mem.o linux-record.o"
;;
alpha*-*-linux*)
# Target: Little-endian Alpha running Linux
gdb_target_obs="alpha-mdebug-tdep.o alpha-linux-tdep.o \
- linux-tdep.o solib-svr4.o"
+ linux-tdep.o solib-svr4.o solib-svr4-linux.o"
;;
alpha*-*-netbsd* | alpha*-*-knetbsd*-gnu)
# Target: NetBSD/alpha
@@ -179,7 +180,7 @@ amdgcn*-*-*)
am33_2.0*-*-linux*)
# Target: Matsushita mn10300 (AM33) running Linux
gdb_target_obs="mn10300-tdep.o mn10300-linux-tdep.o linux-tdep.o \
- solib-svr4.o"
+ solib-svr4.o solib-svr4-linux.o"
;;
arc*-*-elf32)
@@ -189,7 +190,8 @@ arc*-*-elf32)
arc*-*-linux*)
# Target: ARC machine running Linux
- gdb_target_obs="arc-linux-tdep.o linux-tdep.o solib-svr4.o"
+ gdb_target_obs="arc-linux-tdep.o linux-tdep.o solib-svr4.o \
+ solib-svr4-linux.o"
;;
arm*-wince-pe | arm*-*-mingw32ce*)
@@ -199,7 +201,8 @@ arm*-wince-pe | arm*-*-mingw32ce*)
arm*-*-linux*)
# Target: ARM based machine running GNU/Linux
gdb_target_obs="arch/arm-linux.o arm-linux-tdep.o glibc-tdep.o \
- solib-svr4.o symfile-mem.o linux-tdep.o linux-record.o"
+ solib-svr4.o solib-svr4-linux.o symfile-mem.o \
+ linux-tdep.o linux-record.o"
;;
arm*-*-freebsd*)
# Target: FreeBSD/arm
@@ -239,13 +242,14 @@ bpf-*-*)
cris*)
# Target: CRIS
- gdb_target_obs="cris-tdep.o cris-linux-tdep.o linux-tdep.o solib-svr4.o"
+ gdb_target_obs="cris-tdep.o cris-linux-tdep.o linux-tdep.o \
+ solib-svr4.o solib-svr4-linux.o"
;;
csky*-*-linux*)
# Target: CSKY running GNU/Linux
gdb_target_obs="csky-tdep.o csky-linux-tdep.o glibc-tdep.o \
- linux-tdep.o solib-svr4.o"
+ linux-tdep.o solib-svr4.o solib-svr4-linux.o"
;;
csky*-*-*)
@@ -270,7 +274,8 @@ h8300-*-*)
hppa*-*-linux*)
# Target: HP PA-RISC running Linux
gdb_target_obs="hppa-linux-tdep.o glibc-tdep.o \
- linux-tdep.o solib-svr4.o symfile-mem.o"
+ linux-tdep.o solib-svr4.o solib-svr4-linux.o \
+ symfile-mem.o"
;;
hppa*-*-netbsd*)
# Target: NetBSD/hppa
@@ -315,7 +320,7 @@ i[34567]86-*-linux*)
# Target: Intel 386 running GNU/Linux
gdb_target_obs="i386-linux-tdep.o \
glibc-tdep.o \
- solib-svr4.o symfile-mem.o \
+ solib-svr4.o solib-svr4-linux.o symfile-mem.o \
linux-tdep.o linux-record.o \
arch/i386-linux-tdesc.o \
arch/x86-linux-tdesc-features.o"
@@ -345,7 +350,7 @@ i[34567]86-*-go32* | i[34567]86-*-msdosdjgpp*)
ia64-*-linux*)
# Target: Intel IA-64 running GNU/Linux
gdb_target_obs="ia64-linux-tdep.o linux-tdep.o \
- solib-svr4.o symfile-mem.o"
+ solib-svr4.o solib-svr4-linux.o symfile-mem.o"
;;
ia64-*-*vms*)
# Target: Intel IA-64 running OpenVMS
@@ -363,7 +368,8 @@ lm32-*-*)
loongarch*-*-linux*)
# Target: LoongArch running Linux
gdb_target_obs="loongarch-linux-tdep.o glibc-tdep.o \
- linux-tdep.o solib-svr4.o linux-record.o"
+ linux-tdep.o solib-svr4.o solib-svr4-linux.o \
+ linux-record.o"
;;
m32c-*-*)
@@ -374,8 +380,8 @@ m32c-*-*)
m32r*-*-linux*)
# Target: Renesas M32R running GNU/Linux
gdb_target_obs="m32r-tdep.o m32r-linux-tdep.o \
- glibc-tdep.o solib-svr4.o symfile-mem.o \
- linux-tdep.o"
+ glibc-tdep.o solib-svr4.o solib-svr4-linux.o \
+ symfile-mem.o linux-tdep.o"
;;
m32r*-*-*)
# Target: Renesas m32r processor
@@ -395,7 +401,8 @@ fido-*-elf*)
m68*-*-linux*)
# Target: Motorola m68k with a.out and ELF
gdb_target_obs="m68k-tdep.o m68k-linux-tdep.o solib-svr4.o \
- linux-tdep.o glibc-tdep.o symfile-mem.o"
+ solib-svr4-linux.o linux-tdep.o glibc-tdep.o \
+ symfile-mem.o"
;;
m68*-*-netbsd* | m68*-*-knetbsd*-gnu)
# Target: NetBSD/m68k
@@ -415,7 +422,7 @@ mep-*-*)
microblaze*-linux-*|microblaze*-*-linux*)
# Target: Xilinx MicroBlaze running Linux
gdb_target_obs="microblaze-tdep.o microblaze-linux-tdep.o solib-svr4.o \
- symfile-mem.o linux-tdep.o"
+ solib-svr4-linux.o symfile-mem.o linux-tdep.o"
;;
microblaze*-*-*)
# Target: Xilinx MicroBlaze running standalone
@@ -425,7 +432,8 @@ microblaze*-*-*)
mips*-*-linux*)
# Target: Linux/MIPS
gdb_target_obs="mips-tdep.o mips-linux-tdep.o glibc-tdep.o \
- solib-svr4.o symfile-mem.o linux-tdep.o"
+ solib-svr4.o solib-svr4-linux.o symfile-mem.o \
+ linux-tdep.o"
;;
mips*-*-netbsd* | mips*-*-knetbsd*-gnu)
# Target: MIPS running NetBSD
@@ -469,7 +477,8 @@ nds32*-*-elf)
or1k*-*-linux*)
# Target: OpenCores OpenRISC 1000 32-bit running Linux
gdb_target_obs="or1k-tdep.o or1k-linux-tdep.o solib-svr4.o \
- symfile-mem.o glibc-tdep.o linux-tdep.o"
+ solib-svr4-linux.o symfile-mem.o glibc-tdep.o \
+ linux-tdep.o"
;;
or1k-*-* | or1knd-*-*)
@@ -503,7 +512,8 @@ powerpc-*-aix* | rs6000-*-* | powerpc64-*-aix*)
powerpc*-*-linux*)
# Target: PowerPC running Linux
gdb_target_obs="rs6000-tdep.o ppc-linux-tdep.o ppc-sysv-tdep.o \
- ppc64-tdep.o solib-svr4.o svr4-tls-tdep.o \
+ ppc64-tdep.o solib-svr4.o solib-svr4-linux.o \
+ svr4-tls-tdep.o \
glibc-tdep.o symfile-mem.o linux-tdep.o \
ravenscar-thread.o ppc-ravenscar-thread.o \
linux-record.o \
@@ -524,6 +534,7 @@ powerpc*-*-*)
s390*-*-linux*)
# Target: S390 running Linux
gdb_target_obs="s390-linux-tdep.o s390-tdep.o solib-svr4.o \
+ solib-svr4-linux.o \
linux-tdep.o linux-record.o symfile-mem.o \
svr4-tls-tdep.o"
;;
@@ -536,7 +547,8 @@ riscv*-*-freebsd*)
riscv*-*-linux*)
# Target: Linux/RISC-V
gdb_target_obs="riscv-linux-tdep.o riscv-canonicalize-syscall-gen.o \
- glibc-tdep.o linux-tdep.o solib-svr4.o symfile-mem.o \
+ glibc-tdep.o linux-tdep.o solib-svr4.o solib-svr4-linux.o \
+ symfile-mem.o \
linux-record.o svr4-tls-tdep.o"
;;
@@ -558,7 +570,7 @@ rx-*-*)
sh*-*-linux*)
# Target: GNU/Linux Super-H
gdb_target_obs="sh-tdep.o sh-linux-tdep.o \
- solib-svr4.o symfile-mem.o \
+ solib-svr4.o solib-svr4-linux.o symfile-mem.o \
glibc-tdep.o linux-tdep.o"
;;
sh*-*-netbsd* | sh*-*-knetbsd*-gnu)
@@ -577,7 +589,8 @@ sh*)
sparc-*-linux*)
# Target: GNU/Linux SPARC
gdb_target_obs="sparc-tdep.o \
- sparc-linux-tdep.o solib-svr4.o symfile-mem.o \
+ sparc-linux-tdep.o solib-svr4.o solib-svr4-linux.o \
+ symfile-mem.o \
linux-tdep.o \
ravenscar-thread.o sparc-ravenscar-thread.o"
if test "x$have_64_bit_bfd" = "xyes"; then
@@ -590,7 +603,8 @@ sparc64-*-linux*)
# Target: GNU/Linux UltraSPARC
gdb_target_obs="sparc64-tdep.o \
sparc64-linux-tdep.o sparc-tdep.o \
- sparc-linux-tdep.o solib-svr4.o linux-tdep.o \
+ sparc-linux-tdep.o solib-svr4.o solib-svr4-linux.o \
+ linux-tdep.o \
ravenscar-thread.o sparc-ravenscar-thread.o"
;;
sparc*-*-freebsd* | sparc*-*-kfreebsd*-gnu)
@@ -658,6 +672,7 @@ tic6x-*-*)
tilegx-*-linux*)
# Target: TILE-Gx
gdb_target_obs="tilegx-tdep.o tilegx-linux-tdep.o solib-svr4.o \
+ solib-svr4-linux.o \
symfile-mem.o glibc-tdep.o linux-tdep.o"
;;
@@ -708,7 +723,8 @@ x86_64-*-linux*)
# Target: GNU/Linux x86-64
gdb_target_obs="amd64-linux-tdep.o ${i386_tobjs} \
i386-linux-tdep.o glibc-tdep.o svr4-tls-tdep.o \
- solib-svr4.o symfile-mem.o linux-tdep.o linux-record.o \
+ solib-svr4.o solib-svr4-linux.o symfile-mem.o \
+ linux-tdep.o linux-record.o \
arch/i386-linux-tdesc.o arch/amd64-linux-tdesc.o \
arch/x86-linux-tdesc-features.o"
;;
diff --git a/gdb/cris-linux-tdep.c b/gdb/cris-linux-tdep.c
index b2ac80d371c3..80e4c886fbfb 100644
--- a/gdb/cris-linux-tdep.c
+++ b/gdb/cris-linux-tdep.c
@@ -23,6 +23,7 @@
#include "osabi.h"
#include "linux-tdep.h"
+#include "solib-svr4-linux.h"
#include "solib-svr4.h"
#include "symtab.h"
#include "gdbarch.h"
@@ -41,9 +42,7 @@ cris_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
set_gdbarch_fetch_tls_load_module_address (gdbarch,
svr4_fetch_objfile_link_map);
- set_solib_svr4_fetch_link_map_offsets (gdbarch,
- linux_ilp32_fetch_link_map_offsets);
-
+ set_solib_svr4_ops (gdbarch, new_linux_ilp32_svr4_solib_ops);
}
void _initialize_cris_linux_tdep ();
diff --git a/gdb/csky-linux-tdep.c b/gdb/csky-linux-tdep.c
index 2afb35846bda..724542a10665 100644
--- a/gdb/csky-linux-tdep.c
+++ b/gdb/csky-linux-tdep.c
@@ -22,6 +22,7 @@
#include "osabi.h"
#include "glibc-tdep.h"
#include "linux-tdep.h"
+#include "solib-svr4-linux.h"
#include "gdbarch.h"
#include "solib-svr4.h"
#include "regset.h"
@@ -407,8 +408,7 @@ csky_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
/* Shared library handling. */
set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver);
- set_solib_svr4_fetch_link_map_offsets (gdbarch,
- linux_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_linux_ilp32_svr4_solib_ops);
/* Enable TLS support. */
set_gdbarch_fetch_tls_load_module_address (gdbarch,
diff --git a/gdb/dicos-tdep.c b/gdb/dicos-tdep.c
index 4dfac76654e8..fd43d9d859e6 100644
--- a/gdb/dicos-tdep.c
+++ b/gdb/dicos-tdep.c
@@ -27,7 +27,7 @@
void
dicos_init_abi (struct gdbarch *gdbarch)
{
- set_gdbarch_so_ops (gdbarch, &solib_target_so_ops);
+ set_gdbarch_new_solib_ops (gdbarch, new_target_solib_ops);
/* Every process, although has its own address space, sees the same
list of shared libraries. There's no "main executable" in DICOS,
diff --git a/gdb/frv-tdep.c b/gdb/frv-tdep.c
index 360887247ebc..9baa9cc24c21 100644
--- a/gdb/frv-tdep.c
+++ b/gdb/frv-tdep.c
@@ -25,6 +25,7 @@
#include "frame.h"
#include "frame-unwind.h"
#include "frame-base.h"
+#include "solib-frv.h"
#include "trad-frame.h"
#include "dis-asm.h"
#include "sim-regno.h"
@@ -1554,7 +1555,7 @@ frv_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
set_gdbarch_convert_from_func_ptr_addr (gdbarch,
frv_convert_from_func_ptr_addr);
- set_gdbarch_so_ops (gdbarch, &frv_so_ops);
+ set_gdbarch_new_solib_ops (gdbarch, new_frv_solib_ops);
/* Hook in ABI-specific overrides, if they have been registered. */
gdbarch_init_osabi (info, gdbarch);
diff --git a/gdb/frv-tdep.h b/gdb/frv-tdep.h
index 07982b40db0f..7b51b428e9c4 100644
--- a/gdb/frv-tdep.h
+++ b/gdb/frv-tdep.h
@@ -118,7 +118,4 @@ CORE_ADDR frv_fdpic_find_canonical_descriptor (CORE_ADDR entry_point);
needed for TLS support. */
CORE_ADDR frv_fetch_objfile_link_map (struct objfile *objfile);
-struct solib_ops;
-extern const solib_ops frv_so_ops;
-
#endif /* GDB_FRV_TDEP_H */
diff --git a/gdb/gdbarch-gen.c b/gdb/gdbarch-gen.c
index 32d16598940b..d191131d7b24 100644
--- a/gdb/gdbarch-gen.c
+++ b/gdb/gdbarch-gen.c
@@ -157,7 +157,7 @@ struct gdbarch
gdbarch_single_step_through_delay_ftype *single_step_through_delay = nullptr;
gdbarch_print_insn_ftype *print_insn = default_print_insn;
gdbarch_skip_trampoline_code_ftype *skip_trampoline_code = generic_skip_trampoline_code;
- const solib_ops * so_ops = &solib_target_so_ops;
+ gdbarch_new_solib_ops_ftype *new_solib_ops = new_target_solib_ops;
gdbarch_skip_solib_resolver_ftype *skip_solib_resolver = generic_skip_solib_resolver;
gdbarch_in_solib_return_trampoline_ftype *in_solib_return_trampoline = generic_in_solib_return_trampoline;
gdbarch_in_indirect_branch_thunk_ftype *in_indirect_branch_thunk = default_in_indirect_branch_thunk;
@@ -425,7 +425,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
/* Skip verify of single_step_through_delay, has predicate. */
/* Skip verify of print_insn, invalid_p == 0. */
/* Skip verify of skip_trampoline_code, invalid_p == 0. */
- /* Skip verify of so_ops, invalid_p == 0. */
+ /* Skip verify of new_solib_ops, invalid_p == 0. */
/* Skip verify of skip_solib_resolver, invalid_p == 0. */
/* Skip verify of in_solib_return_trampoline, invalid_p == 0. */
/* Skip verify of in_indirect_branch_thunk, invalid_p == 0. */
@@ -966,8 +966,8 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
"gdbarch_dump: skip_trampoline_code = <%s>\n",
host_address_to_string (gdbarch->skip_trampoline_code));
gdb_printf (file,
- "gdbarch_dump: so_ops = %s\n",
- host_address_to_string (gdbarch->so_ops));
+ "gdbarch_dump: new_solib_ops = <%s>\n",
+ host_address_to_string (gdbarch->new_solib_ops));
gdb_printf (file,
"gdbarch_dump: skip_solib_resolver = <%s>\n",
host_address_to_string (gdbarch->skip_solib_resolver));
@@ -3469,21 +3469,21 @@ set_gdbarch_skip_trampoline_code (struct gdbarch *gdbarch,
gdbarch->skip_trampoline_code = skip_trampoline_code;
}
-const solib_ops *
-gdbarch_so_ops (struct gdbarch *gdbarch)
+solib_ops_up
+gdbarch_new_solib_ops (struct gdbarch *gdbarch)
{
gdb_assert (gdbarch != NULL);
- /* Skip verify of so_ops, invalid_p == 0. */
+ gdb_assert (gdbarch->new_solib_ops != NULL);
if (gdbarch_debug >= 2)
- gdb_printf (gdb_stdlog, "gdbarch_so_ops called\n");
- return gdbarch->so_ops;
+ gdb_printf (gdb_stdlog, "gdbarch_new_solib_ops called\n");
+ return gdbarch->new_solib_ops ();
}
void
-set_gdbarch_so_ops (struct gdbarch *gdbarch,
- const solib_ops * so_ops)
+set_gdbarch_new_solib_ops (struct gdbarch *gdbarch,
+ gdbarch_new_solib_ops_ftype new_solib_ops)
{
- gdbarch->so_ops = so_ops;
+ gdbarch->new_solib_ops = new_solib_ops;
}
CORE_ADDR
diff --git a/gdb/gdbarch-gen.h b/gdb/gdbarch-gen.h
index 313a8f198fdb..b5a3762f438e 100644
--- a/gdb/gdbarch-gen.h
+++ b/gdb/gdbarch-gen.h
@@ -818,10 +818,11 @@ typedef CORE_ADDR (gdbarch_skip_trampoline_code_ftype) (const frame_info_ptr &fr
extern CORE_ADDR gdbarch_skip_trampoline_code (struct gdbarch *gdbarch, const frame_info_ptr &frame, CORE_ADDR pc);
extern void set_gdbarch_skip_trampoline_code (struct gdbarch *gdbarch, gdbarch_skip_trampoline_code_ftype *skip_trampoline_code);
-/* Vtable of solib operations functions. */
+/* Return a newly-allocated solib_ops object capable of providing the solibs for this architecture. */
-extern const solib_ops * gdbarch_so_ops (struct gdbarch *gdbarch);
-extern void set_gdbarch_so_ops (struct gdbarch *gdbarch, const solib_ops * so_ops);
+typedef solib_ops_up (gdbarch_new_solib_ops_ftype) ();
+extern solib_ops_up gdbarch_new_solib_ops (struct gdbarch *gdbarch);
+extern void set_gdbarch_new_solib_ops (struct gdbarch *gdbarch, gdbarch_new_solib_ops_ftype *new_solib_ops);
/* If in_solib_dynsym_resolve_code() returns true, and SKIP_SOLIB_RESOLVER
evaluates non-zero, this is the address where the debugger will place
diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h
index 9feb2cc24e5b..6accbd2fd5ee 100644
--- a/gdb/gdbarch.h
+++ b/gdb/gdbarch.h
@@ -30,6 +30,7 @@
#include "displaced-stepping.h"
#include "gdbsupport/gdb-checked-static-cast.h"
#include "registry.h"
+#include "solib.h"
struct floatformat;
struct ui_file;
diff --git a/gdb/gdbarch_components.py b/gdb/gdbarch_components.py
index ec09d9550889..000729494611 100644
--- a/gdb/gdbarch_components.py
+++ b/gdb/gdbarch_components.py
@@ -1431,12 +1431,12 @@ Function(
invalid=False,
)
-Value(
- comment="Vtable of solib operations functions.",
- type="const solib_ops *",
- name="so_ops",
- predefault="&solib_target_so_ops",
- printer="host_address_to_string (gdbarch->so_ops)",
+Function(
+ comment="Return a newly-allocated solib_ops object capable of providing the solibs for this architecture.",
+ type="solib_ops_up",
+ name="new_solib_ops",
+ params=[],
+ predefault="new_target_solib_ops",
invalid=False,
)
diff --git a/gdb/hppa-bsd-tdep.c b/gdb/hppa-bsd-tdep.c
index db6c92f8aab5..f7269c921b55 100644
--- a/gdb/hppa-bsd-tdep.c
+++ b/gdb/hppa-bsd-tdep.c
@@ -128,8 +128,7 @@ hppabsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
set_gdbarch_skip_trampoline_code (gdbarch, hppa_skip_trampoline_code);
/* OpenBSD and NetBSD use SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_svr4_ilp32_solib_ops);
/* Hook in the DWARF CFI frame unwinder. */
dwarf2_frame_set_init_reg (gdbarch, hppabsd_dwarf2_frame_init_reg);
diff --git a/gdb/hppa-linux-tdep.c b/gdb/hppa-linux-tdep.c
index 16cdd4540165..b6a43ffa740c 100644
--- a/gdb/hppa-linux-tdep.c
+++ b/gdb/hppa-linux-tdep.c
@@ -32,6 +32,7 @@
#include "regcache.h"
#include "hppa-tdep.h"
#include "linux-tdep.h"
+#include "solib-svr4-linux.h"
#include "elf/common.h"
/* Map DWARF DBX register numbers to GDB register numbers. */
@@ -499,8 +500,7 @@ hppa_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
frame_unwind_append_unwinder (gdbarch, &hppa_linux_sigtramp_frame_unwind);
/* GNU/Linux uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, linux_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_linux_ilp32_svr4_solib_ops);
tdep->in_solib_call_trampoline = hppa_in_solib_call_trampoline;
set_gdbarch_skip_trampoline_code (gdbarch, hppa_skip_trampoline_code);
diff --git a/gdb/i386-darwin-tdep.c b/gdb/i386-darwin-tdep.c
index 6180e0293a6e..9a1f39273942 100644
--- a/gdb/i386-darwin-tdep.c
+++ b/gdb/i386-darwin-tdep.c
@@ -271,7 +271,7 @@ i386_darwin_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
alignment. */
set_gdbarch_long_double_bit (gdbarch, 128);
- set_gdbarch_so_ops (gdbarch, &darwin_so_ops);
+ set_gdbarch_new_solib_ops (gdbarch, new_darwin_solib_ops);
}
static enum gdb_osabi
diff --git a/gdb/i386-fbsd-tdep.c b/gdb/i386-fbsd-tdep.c
index 72237d89cfcc..5840b618e8fd 100644
--- a/gdb/i386-fbsd-tdep.c
+++ b/gdb/i386-fbsd-tdep.c
@@ -402,8 +402,7 @@ i386fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
i386fbsd_core_read_description);
/* FreeBSD uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_svr4_ilp32_solib_ops);
set_gdbarch_fetch_tls_load_module_address (gdbarch,
svr4_fetch_objfile_link_map);
diff --git a/gdb/i386-gnu-tdep.c b/gdb/i386-gnu-tdep.c
index 97fbc697b845..18fb2a6d2098 100644
--- a/gdb/i386-gnu-tdep.c
+++ b/gdb/i386-gnu-tdep.c
@@ -180,8 +180,7 @@ i386gnu_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
/* Hurd uses SVR4-style shared libraries. */
set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_svr4_ilp32_solib_ops);
/* Hurd uses the dynamic linker included in the GNU C Library. */
set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver);
diff --git a/gdb/i386-linux-tdep.c b/gdb/i386-linux-tdep.c
index 4b05cc6870b5..93b518d93afc 100644
--- a/gdb/i386-linux-tdep.c
+++ b/gdb/i386-linux-tdep.c
@@ -30,6 +30,7 @@
#include "i386-tdep.h"
#include "i386-linux-tdep.h"
#include "linux-tdep.h"
+#include "solib-svr4-linux.h"
#include "utils.h"
#include "glibc-tdep.h"
#include "solib-svr4.h"
@@ -1461,8 +1462,7 @@ i386_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
/* GNU/Linux uses SVR4-style shared libraries. */
set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, linux_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_linux_ilp32_svr4_solib_ops);
/* GNU/Linux uses the dynamic linker included in the GNU C Library. */
set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver);
diff --git a/gdb/i386-netbsd-tdep.c b/gdb/i386-netbsd-tdep.c
index 701ce048b5e8..d9a3e375d621 100644
--- a/gdb/i386-netbsd-tdep.c
+++ b/gdb/i386-netbsd-tdep.c
@@ -415,8 +415,7 @@ i386nbsdelf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
i386_elf_init_abi (info, gdbarch);
/* NetBSD ELF uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_svr4_ilp32_solib_ops);
/* NetBSD ELF uses -fpcc-struct-return by default. */
tdep->struct_return = pcc_struct_return;
diff --git a/gdb/i386-obsd-tdep.c b/gdb/i386-obsd-tdep.c
index be656688b369..0ea12d82f1b0 100644
--- a/gdb/i386-obsd-tdep.c
+++ b/gdb/i386-obsd-tdep.c
@@ -441,8 +441,7 @@ i386obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
frame_unwind_prepend_unwinder (gdbarch, &i386obsd_trapframe_unwind);
/* OpenBSD ELF uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_svr4_ilp32_solib_ops);
}
void _initialize_i386obsd_tdep ();
diff --git a/gdb/i386-sol2-tdep.c b/gdb/i386-sol2-tdep.c
index e842236718d6..ffc95f41f0ca 100644
--- a/gdb/i386-sol2-tdep.c
+++ b/gdb/i386-sol2-tdep.c
@@ -86,8 +86,7 @@ i386_sol2_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
tdep->sc_num_regs = tdep->gregset_num_regs;
/* Solaris has SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_svr4_ilp32_solib_ops);
}
\f
diff --git a/gdb/ia64-linux-tdep.c b/gdb/ia64-linux-tdep.c
index c45b2bb26e89..d84848f1c35a 100644
--- a/gdb/ia64-linux-tdep.c
+++ b/gdb/ia64-linux-tdep.c
@@ -26,6 +26,7 @@
#include "solib-svr4.h"
#include "symtab.h"
#include "linux-tdep.h"
+#include "solib-svr4-linux.h"
#include "regset.h"
#include <ctype.h>
@@ -235,8 +236,7 @@ ia64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, linux_lp64_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_linux_lp64_svr4_solib_ops);
/* Enable TLS support. */
set_gdbarch_fetch_tls_load_module_address (gdbarch,
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index 1adad5c3eaa3..6c67a918f57a 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -260,7 +260,7 @@ post_create_inferior (int from_tty, bool set_pspace_solib_ops)
if (set_pspace_solib_ops)
current_program_space->set_solib_ops
- (*gdbarch_so_ops (current_inferior ()->arch ()));
+ (gdbarch_new_solib_ops (current_inferior ()->arch ()));
if (current_program_space->exec_bfd ())
{
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 5cdf66d26dcb..5c652045e8ac 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -1383,7 +1383,7 @@ follow_exec (ptid_t ptid, const char *exec_file_target)
target_find_description ();
current_program_space->set_solib_ops
- (*gdbarch_so_ops (following_inferior->arch ()));
+ (gdbarch_new_solib_ops (following_inferior->arch ()));
gdb::observers::inferior_execd.notify (execing_inferior, following_inferior);
breakpoint_re_set ();
diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c
index 1e339b59e2e8..12c05f31d53a 100644
--- a/gdb/linux-tdep.c
+++ b/gdb/linux-tdep.c
@@ -3118,64 +3118,3 @@ more information about this file, refer to the manpage of proc(5) and core(5).")
&setlist, &showlist);
}
-
-/* Fetch (and possibly build) an appropriate `link_map_offsets' for
- ILP32/LP64 Linux systems which don't have the r_ldsomap field. */
-
-link_map_offsets *
-linux_ilp32_fetch_link_map_offsets ()
-{
- static link_map_offsets lmo;
- static link_map_offsets *lmp = nullptr;
-
- if (lmp == nullptr)
- {
- lmp = &lmo;
-
- lmo.r_version_offset = 0;
- lmo.r_version_size = 4;
- lmo.r_map_offset = 4;
- lmo.r_brk_offset = 8;
- lmo.r_ldsomap_offset = -1;
- lmo.r_next_offset = 20;
-
- /* Everything we need is in the first 20 bytes. */
- lmo.link_map_size = 20;
- lmo.l_addr_offset = 0;
- lmo.l_name_offset = 4;
- lmo.l_ld_offset = 8;
- lmo.l_next_offset = 12;
- lmo.l_prev_offset = 16;
- }
-
- return lmp;
-}
-
-link_map_offsets *
-linux_lp64_fetch_link_map_offsets ()
-{
- static link_map_offsets lmo;
- static link_map_offsets *lmp = nullptr;
-
- if (lmp == nullptr)
- {
- lmp = &lmo;
-
- lmo.r_version_offset = 0;
- lmo.r_version_size = 4;
- lmo.r_map_offset = 8;
- lmo.r_brk_offset = 16;
- lmo.r_ldsomap_offset = -1;
- lmo.r_next_offset = 40;
-
- /* Everything we need is in the first 40 bytes. */
- lmo.link_map_size = 40;
- lmo.l_addr_offset = 0;
- lmo.l_name_offset = 8;
- lmo.l_ld_offset = 16;
- lmo.l_next_offset = 24;
- lmo.l_prev_offset = 32;
- }
-
- return lmp;
-}
diff --git a/gdb/linux-tdep.h b/gdb/linux-tdep.h
index 7485fc132a63..3d82ea5bbdf3 100644
--- a/gdb/linux-tdep.h
+++ b/gdb/linux-tdep.h
@@ -22,6 +22,7 @@
#include "bfd.h"
#include "displaced-stepping.h"
+#include "solib.h"
struct inferior;
struct regcache;
@@ -112,9 +113,4 @@ extern CORE_ADDR linux_get_hwcap2 (const std::optional<gdb::byte_vector> &auxv,
extern CORE_ADDR linux_get_hwcap2 ();
-/* Fetch (and possibly build) an appropriate `struct link_map_offsets'
- for ILP32 and LP64 Linux systems. */
-extern struct link_map_offsets *linux_ilp32_fetch_link_map_offsets ();
-extern struct link_map_offsets *linux_lp64_fetch_link_map_offsets ();
-
#endif /* GDB_LINUX_TDEP_H */
diff --git a/gdb/loongarch-linux-tdep.c b/gdb/loongarch-linux-tdep.c
index 38485e04b1ec..af6474e8390b 100644
--- a/gdb/loongarch-linux-tdep.c
+++ b/gdb/loongarch-linux-tdep.c
@@ -25,6 +25,7 @@
#include "inferior.h"
#include "linux-record.h"
#include "linux-tdep.h"
+#include "solib-svr4-linux.h"
#include "loongarch-tdep.h"
#include "record-full.h"
#include "regset.h"
@@ -1145,10 +1146,9 @@ loongarch_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
linux_init_abi (info, gdbarch, 0);
- set_solib_svr4_fetch_link_map_offsets (gdbarch,
- info.bfd_arch_info->bits_per_address == 32
- ? linux_ilp32_fetch_link_map_offsets
- : linux_lp64_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, (info.bfd_arch_info->bits_per_address == 32
+ ? new_linux_ilp32_svr4_solib_ops
+ : new_linux_lp64_svr4_solib_ops));
/* GNU/Linux uses SVR4-style shared libraries. */
set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
diff --git a/gdb/m32r-linux-tdep.c b/gdb/m32r-linux-tdep.c
index 4fbe7d9927c0..52061923f8eb 100644
--- a/gdb/m32r-linux-tdep.c
+++ b/gdb/m32r-linux-tdep.c
@@ -36,6 +36,7 @@
#include "m32r-tdep.h"
#include "linux-tdep.h"
+#include "solib-svr4-linux.h"
#include "gdbarch.h"
\f
@@ -461,8 +462,7 @@ m32r_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
/* GNU/Linux uses SVR4-style shared libraries. */
set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, linux_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_linux_ilp32_svr4_solib_ops);
/* Core file support. */
set_gdbarch_iterate_over_regset_sections
diff --git a/gdb/m68k-bsd-tdep.c b/gdb/m68k-bsd-tdep.c
index 09c57c6e61da..8155f7d2fe06 100644
--- a/gdb/m68k-bsd-tdep.c
+++ b/gdb/m68k-bsd-tdep.c
@@ -147,8 +147,7 @@ m68kbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
tdep->struct_return = pcc_struct_return;
/* NetBSD ELF uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_svr4_ilp32_solib_ops);
}
void _initialize_m68kbsd_tdep ();
diff --git a/gdb/m68k-linux-tdep.c b/gdb/m68k-linux-tdep.c
index cfc37abc59c6..baaf0d4c9740 100644
--- a/gdb/m68k-linux-tdep.c
+++ b/gdb/m68k-linux-tdep.c
@@ -35,6 +35,7 @@
#include "observable.h"
#include "elf/common.h"
#include "linux-tdep.h"
+#include "solib-svr4-linux.h"
#include "regset.h"
\f
/* Offsets (in target ints) into jmp_buf. */
@@ -407,8 +408,7 @@ m68k_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
/* Shared library handling. */
/* GNU/Linux uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets (gdbarch,
- linux_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_linux_ilp32_svr4_solib_ops);
/* GNU/Linux uses the dynamic linker included in the GNU C Library. */
set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver);
diff --git a/gdb/microblaze-linux-tdep.c b/gdb/microblaze-linux-tdep.c
index 8dcbeaafb834..9d18fbe7aa04 100644
--- a/gdb/microblaze-linux-tdep.c
+++ b/gdb/microblaze-linux-tdep.c
@@ -35,6 +35,7 @@
#include "frame-unwind.h"
#include "tramp-frame.h"
#include "linux-tdep.h"
+#include "solib-svr4-linux.h"
static int
microblaze_linux_memory_remove_breakpoint (struct gdbarch *gdbarch,
@@ -125,8 +126,7 @@ microblaze_linux_init_abi (struct gdbarch_info info,
microblaze_linux_memory_remove_breakpoint);
/* Shared library handling. */
- set_solib_svr4_fetch_link_map_offsets (gdbarch,
- linux_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_linux_ilp32_svr4_solib_ops);
/* Trampolines. */
tramp_frame_prepend_unwinder (gdbarch,
diff --git a/gdb/mips-fbsd-tdep.c b/gdb/mips-fbsd-tdep.c
index c280527b6abb..f00ab31db3c9 100644
--- a/gdb/mips-fbsd-tdep.c
+++ b/gdb/mips-fbsd-tdep.c
@@ -476,12 +476,28 @@ mips_fbsd_skip_solib_resolver (struct gdbarch *gdbarch, CORE_ADDR pc)
return fbsd_skip_solib_resolver (gdbarch, pc);
}
-/* FreeBSD/mips uses a slightly different `struct link_map' than the
- other FreeBSD platforms as it includes an additional `l_off'
- member. */
+/* solib_ops for ILP32 FreeBSD/MIPS systems. */
-static struct link_map_offsets *
-mips_fbsd_ilp32_fetch_link_map_offsets (void)
+struct mips_fbsd_ilp32_solib_ops : public svr4_solib_ops
+{
+ /* FreeBSD/MIPS uses a slightly different `struct link_map' than the
+ other FreeBSD platforms as it includes an additional `l_off' member. */
+
+ link_map_offsets *fetch_link_map_offsets () const override;
+};
+
+/* Return a new solib_ops for ILP32 FreeBSD/MIPS systems. */
+
+static solib_ops_up
+new_mips_fbsd_ilp32_solib_ops ()
+{
+ return std::make_unique<mips_fbsd_ilp32_solib_ops> ();
+}
+
+/* See mips_fbsd_ilp32_solib_ops. */
+
+link_map_offsets *
+mips_fbsd_ilp32_solib_ops::fetch_link_map_offsets () const
{
static struct link_map_offsets lmo;
static struct link_map_offsets *lmp = NULL;
@@ -508,8 +524,28 @@ mips_fbsd_ilp32_fetch_link_map_offsets (void)
return lmp;
}
-static struct link_map_offsets *
-mips_fbsd_lp64_fetch_link_map_offsets (void)
+/* solib_ops for LP64 FreeBSD/MIPS systems. */
+
+struct mips_fbsd_lp64_solib_ops : public svr4_solib_ops
+{
+ /* FreeBSD/MIPS uses a slightly different `struct link_map' than the
+ other FreeBSD platforms as it includes an additional `l_off' member. */
+
+ link_map_offsets *fetch_link_map_offsets () const override;
+};
+
+/* Return a new solib_ops for LP64 FreeBSD/MIPS systems. */
+
+static solib_ops_up
+new_mips_fbsd_lp64_solib_ops ()
+{
+ return std::make_unique<mips_fbsd_lp64_solib_ops> ();
+}
+
+/* See mips_fbsd_lp64_solib_ops. */
+
+link_map_offsets *
+mips_fbsd_lp64_solib_ops::fetch_link_map_offsets () const
{
static struct link_map_offsets lmo;
static struct link_map_offsets *lmp = NULL;
@@ -565,10 +601,9 @@ mips_fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
set_gdbarch_skip_solib_resolver (gdbarch, mips_fbsd_skip_solib_resolver);
/* FreeBSD/mips has SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, (gdbarch_ptr_bit (gdbarch) == 32 ?
- mips_fbsd_ilp32_fetch_link_map_offsets :
- mips_fbsd_lp64_fetch_link_map_offsets));
+ set_solib_svr4_ops (gdbarch, (gdbarch_ptr_bit (gdbarch) == 32
+ ? new_mips_fbsd_ilp32_solib_ops
+ : new_mips_fbsd_lp64_solib_ops));
}
void _initialize_mips_fbsd_tdep ();
diff --git a/gdb/mips-linux-tdep.c b/gdb/mips-linux-tdep.c
index bf3df3697e15..29633d8298df 100644
--- a/gdb/mips-linux-tdep.c
+++ b/gdb/mips-linux-tdep.c
@@ -36,6 +36,7 @@
#include "mips-linux-tdep.h"
#include "glibc-tdep.h"
#include "linux-tdep.h"
+#include "solib-svr4-linux.h"
#include "xml-syscall.h"
#include "gdbsupport/gdb_signals.h"
#include "inferior.h"
@@ -45,8 +46,6 @@
#include "features/mips64-linux.c"
#include "features/mips64-dsp-linux.c"
-static solib_ops mips_svr4_so_ops;
-
/* This enum represents the signals' numbers on the MIPS
architecture. It just contains the signal definitions which are
different from the generic implementation.
@@ -666,15 +665,22 @@ mips_linux_in_dynsym_stub (CORE_ADDR pc)
return 1;
}
-/* Return true iff PC belongs to the dynamic linker resolution
- code, a PLT entry, or a lazy binding stub. */
+/* Mix-in class to add Linux/MIPS-specific methods to a base solib_ops
+ class. */
-static bool
-mips_linux_in_dynsym_resolve_code (CORE_ADDR pc)
+template <typename Base>
+struct mips_linux_svr4_solib_ops : public Base
+{
+ bool in_dynsym_resolve_code (CORE_ADDR pc) const override;
+};
+
+template <typename Base>
+bool
+mips_linux_svr4_solib_ops<Base>::in_dynsym_resolve_code (CORE_ADDR pc) const
{
/* Check whether PC is in the dynamic linker. This also checks
whether it is in the .plt section, used by non-PIC executables. */
- if (svr4_in_dynsym_resolve_code (pc))
+ if (Base::in_dynsym_resolve_code (pc))
return true;
/* Likewise for the stubs. They live in the .MIPS.stubs section these
@@ -686,6 +692,32 @@ mips_linux_in_dynsym_resolve_code (CORE_ADDR pc)
return false;
}
+/* solib_ops for ILP32 Linux/MIPS systems. */
+
+using mips_linux_ilp32_svr4_solib_ops
+ = mips_linux_svr4_solib_ops<linux_ilp32_svr4_solib_ops>;
+
+/* Return a new solib_ops for ILP32 Linux/MIPS systems. */
+
+static solib_ops_up
+new_mips_linux_ilp32_svr4_solib_ops ()
+{
+ return std::make_unique<mips_linux_ilp32_svr4_solib_ops> ();
+}
+
+/* solib_ops for LP64 Linux/MIPS systems. */
+
+using mips_linux_lp64_svr4_solib_ops
+ = mips_linux_svr4_solib_ops<linux_lp64_svr4_solib_ops>;
+
+/* Return a new solib_ops for LP64 Linux/MIPS systems. */
+
+static solib_ops_up
+new_mips_linux_lp64_svr4_solib_ops ()
+{
+ return std::make_unique<mips_linux_lp64_svr4_solib_ops> ();
+}
+
/* See the comments for SKIP_SOLIB_RESOLVER at the top of infrun.c,
and glibc_skip_solib_resolver in glibc-tdep.c. The normal glibc
implementation of this triggers at "fixup" from the same objfile as
@@ -1537,8 +1569,7 @@ mips_linux_init_abi (struct gdbarch_info info,
case MIPS_ABI_O32:
set_gdbarch_get_longjmp_target (gdbarch,
mips_linux_get_longjmp_target);
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, linux_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_mips_linux_ilp32_svr4_solib_ops);
tramp_frame_prepend_unwinder (gdbarch, µmips_linux_o32_sigframe);
tramp_frame_prepend_unwinder (gdbarch,
µmips_linux_o32_rt_sigframe);
@@ -1549,8 +1580,7 @@ mips_linux_init_abi (struct gdbarch_info info,
case MIPS_ABI_N32:
set_gdbarch_get_longjmp_target (gdbarch,
mips_linux_get_longjmp_target);
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, linux_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_mips_linux_ilp32_svr4_solib_ops);
set_gdbarch_long_double_bit (gdbarch, 128);
set_gdbarch_long_double_format (gdbarch, floatformats_ieee_quad);
tramp_frame_prepend_unwinder (gdbarch,
@@ -1561,8 +1591,7 @@ mips_linux_init_abi (struct gdbarch_info info,
case MIPS_ABI_N64:
set_gdbarch_get_longjmp_target (gdbarch,
mips64_linux_get_longjmp_target);
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, linux_lp64_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_mips_linux_lp64_svr4_solib_ops);
set_gdbarch_long_double_bit (gdbarch, 128);
set_gdbarch_long_double_format (gdbarch, floatformats_ieee_quad);
tramp_frame_prepend_unwinder (gdbarch,
@@ -1582,16 +1611,6 @@ mips_linux_init_abi (struct gdbarch_info info,
set_gdbarch_fetch_tls_load_module_address (gdbarch,
svr4_fetch_objfile_link_map);
- /* Initialize this lazily, to avoid an initialization order
- dependency on solib-svr4.c's _initialize routine. */
- if (mips_svr4_so_ops.in_dynsym_resolve_code == NULL)
- {
- mips_svr4_so_ops = svr4_so_ops;
- mips_svr4_so_ops.in_dynsym_resolve_code
- = mips_linux_in_dynsym_resolve_code;
- }
- set_gdbarch_so_ops (gdbarch, &mips_svr4_so_ops);
-
set_gdbarch_write_pc (gdbarch, mips_linux_write_pc);
set_gdbarch_core_read_description (gdbarch,
diff --git a/gdb/mips-netbsd-tdep.c b/gdb/mips-netbsd-tdep.c
index c9bdaa6800bb..165bf95c1881 100644
--- a/gdb/mips-netbsd-tdep.c
+++ b/gdb/mips-netbsd-tdep.c
@@ -288,13 +288,27 @@ mipsnbsd_cannot_store_register (struct gdbarch *gdbarch, int regno)
|| regno == mips_regnum (gdbarch)->fp_implementation_revision);
}
-/* Shared library support. */
+/* solib_ops for ILP32 NetBSD/MIPS systems. */
-/* NetBSD/mips uses a slightly different `struct link_map' than the
- other NetBSD platforms. */
+struct mips_nbsd_ilp32_svr4_solib_ops : public svr4_solib_ops
+{
+ /* NetBSD/MIPS uses a slightly different `struct link_map' than the
+ other NetBSD platforms. */
+ link_map_offsets *fetch_link_map_offsets () const override;
+};
-static struct link_map_offsets *
-mipsnbsd_ilp32_fetch_link_map_offsets (void)
+/* Return a new solib_ops for ILP32 NetBSD/MIPS systems. */
+
+static solib_ops_up
+new_mips_nbsd_ilp32_svr4_solib_ops ()
+{
+ return std::make_unique<mips_nbsd_ilp32_svr4_solib_ops> ();
+}
+
+/* See mips_nbsd_ilp32_svr4_solib_ops. */
+
+link_map_offsets *
+mips_nbsd_ilp32_svr4_solib_ops::fetch_link_map_offsets () const
{
static struct link_map_offsets lmo;
static struct link_map_offsets *lmp = NULL;
@@ -322,8 +336,27 @@ mipsnbsd_ilp32_fetch_link_map_offsets (void)
return lmp;
}
-static struct link_map_offsets *
-mipsnbsd_lp64_fetch_link_map_offsets (void)
+/* solib_ops for LP64 NetBSD/MIPS systems. */
+
+struct mips_nbsd_lp64_svr4_solib_ops : public svr4_solib_ops
+{
+ /* NetBSD/MIPS uses a slightly different `struct link_map' than the
+ other NetBSD platforms. */
+ link_map_offsets *fetch_link_map_offsets () const override;
+};
+
+/* Return a new solib_ops for LP64 NetBSD/MIPS systems. */
+
+static solib_ops_up
+new_mips_nbsd_lp64_svr4_solib_ops ()
+{
+ return std::make_unique<mips_nbsd_lp64_svr4_solib_ops> ();
+}
+
+/* See mips_nbsd_lp64_svr4_solib_ops. */
+
+link_map_offsets *
+mips_nbsd_lp64_svr4_solib_ops::fetch_link_map_offsets () const
{
static struct link_map_offsets lmo;
static struct link_map_offsets *lmp = NULL;
@@ -369,10 +402,9 @@ mipsnbsd_init_abi (struct gdbarch_info info,
set_gdbarch_software_single_step (gdbarch, mips_software_single_step);
/* NetBSD/mips has SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, (gdbarch_ptr_bit (gdbarch) == 32 ?
- mipsnbsd_ilp32_fetch_link_map_offsets :
- mipsnbsd_lp64_fetch_link_map_offsets));
+ set_solib_svr4_ops (gdbarch, (gdbarch_ptr_bit (gdbarch) == 32
+ ? new_mips_nbsd_ilp32_svr4_solib_ops
+ : new_mips_nbsd_lp64_svr4_solib_ops));
}
void _initialize_mipsnbsd_tdep ();
diff --git a/gdb/mips64-obsd-tdep.c b/gdb/mips64-obsd-tdep.c
index d0c9a1c86587..2d856c1442f2 100644
--- a/gdb/mips64-obsd-tdep.c
+++ b/gdb/mips64-obsd-tdep.c
@@ -150,8 +150,7 @@ mips64obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
obsd_init_abi(info, gdbarch);
/* OpenBSD/mips64 has SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_lp64_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_svr4_lp64_solib_ops);
}
void _initialize_mips64obsd_tdep ();
diff --git a/gdb/mn10300-linux-tdep.c b/gdb/mn10300-linux-tdep.c
index 3334ca0cc7d2..0fa5db972151 100644
--- a/gdb/mn10300-linux-tdep.c
+++ b/gdb/mn10300-linux-tdep.c
@@ -29,6 +29,7 @@
#include "trad-frame.h"
#include "tramp-frame.h"
#include "linux-tdep.h"
+#include "solib-svr4-linux.h"
#include "gdbarch.h"
/* Transliterated from <asm-mn10300/elf.h>... */
@@ -707,8 +708,7 @@ am33_linux_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch)
set_gdbarch_iterate_over_regset_sections
(gdbarch, am33_iterate_over_regset_sections);
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, linux_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_linux_ilp32_svr4_solib_ops);
tramp_frame_prepend_unwinder (gdbarch, &am33_linux_sigframe);
tramp_frame_prepend_unwinder (gdbarch, &am33_linux_rt_sigframe);
diff --git a/gdb/or1k-linux-tdep.c b/gdb/or1k-linux-tdep.c
index 4784e0b73e94..ca7562ee9a59 100644
--- a/gdb/or1k-linux-tdep.c
+++ b/gdb/or1k-linux-tdep.c
@@ -20,6 +20,7 @@
#include "osabi.h"
#include "glibc-tdep.h"
#include "linux-tdep.h"
+#include "solib-svr4-linux.h"
#include "solib-svr4.h"
#include "regset.h"
#include "tramp-frame.h"
@@ -144,8 +145,7 @@ or1k_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
linux_init_abi (info, gdbarch, 0);
- set_solib_svr4_fetch_link_map_offsets (gdbarch,
- linux_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_linux_ilp32_svr4_solib_ops);
/* GNU/Linux uses SVR4-style shared libraries. */
set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
diff --git a/gdb/ppc-fbsd-tdep.c b/gdb/ppc-fbsd-tdep.c
index 3bab0318f487..5705bd96c314 100644
--- a/gdb/ppc-fbsd-tdep.c
+++ b/gdb/ppc-fbsd-tdep.c
@@ -332,8 +332,7 @@ ppcfbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
set_gdbarch_return_value (gdbarch, ppcfbsd_return_value);
set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
- set_solib_svr4_fetch_link_map_offsets (gdbarch,
- svr4_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_svr4_ilp32_solib_ops);
frame_unwind_append_unwinder (gdbarch, &ppcfbsd_sigtramp_frame_unwind);
set_gdbarch_gcore_bfd_target (gdbarch, "elf32-powerpc");
@@ -347,8 +346,7 @@ ppcfbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
ppc64_elf_make_msymbol_special);
set_gdbarch_skip_trampoline_code (gdbarch, ppc64_skip_trampoline_code);
- set_solib_svr4_fetch_link_map_offsets (gdbarch,
- svr4_lp64_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_svr4_lp64_solib_ops);
set_gdbarch_gcore_bfd_target (gdbarch, "elf64-powerpc");
}
diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c
index b3cc4d5485e2..8f93d468bf99 100644
--- a/gdb/ppc-linux-tdep.c
+++ b/gdb/ppc-linux-tdep.c
@@ -48,6 +48,7 @@
#include "arch-utils.h"
#include "xml-syscall.h"
#include "linux-tdep.h"
+#include "solib-svr4-linux.h"
#include "svr4-tls-tdep.h"
#include "linux-record.h"
#include "record-full.h"
@@ -86,8 +87,6 @@
#include "features/rs6000/powerpc-e500l.c"
#include "dwarf2/frame.h"
-/* Shared library operations for PowerPC-Linux. */
-static solib_ops powerpc_so_ops;
/* The syscall's XML filename for PPC and PPC64. */
#define XML_SYSCALL_FILENAME_PPC "syscalls/ppc-linux.xml"
@@ -306,16 +305,33 @@ static const struct ppc_insn_pattern powerpc32_plt_stub_so_2[] =
/* The max number of insns we check using ppc_insns_match_pattern. */
#define POWERPC32_PLT_CHECK_LEN (ARRAY_SIZE (powerpc32_plt_stub) - 1)
-/* Check if PC is in PLT stub. For non-secure PLT, stub is in .plt
- section. For secure PLT, stub is in .text and we need to check
- instruction patterns. */
+/* solib_ops for ILP32 PowerPC/Linux systems. */
-static bool
-powerpc_linux_in_dynsym_resolve_code (CORE_ADDR pc)
+struct ppc_linux_ilp32_svr4_solib_ops : public linux_ilp32_svr4_solib_ops
+{
+ /* Check if PC is in PLT stub. For non-secure PLT, stub is in .plt
+ section. For secure PLT, stub is in .text and we need to check
+ instruction patterns. */
+
+ bool in_dynsym_resolve_code (CORE_ADDR pc) const override;
+};
+
+/* Return a new solib_ops for ILP32 PowerPC/Linux systems. */
+
+static solib_ops_up
+new_ppc_linux_ilp32_svr4_solib_ops ()
+{
+ return std::make_unique<ppc_linux_ilp32_svr4_solib_ops> ();
+}
+
+/* See ppc_linux_ilp32_svr4_solib_ops. */
+
+bool
+ppc_linux_ilp32_svr4_solib_ops::in_dynsym_resolve_code (CORE_ADDR pc) const
{
/* Check whether PC is in the dynamic linker. This also checks
whether it is in the .plt section, used by non-PIC executables. */
- if (svr4_in_dynsym_resolve_code (pc))
+ if (linux_ilp32_svr4_solib_ops::in_dynsym_resolve_code (pc))
return true;
/* Check if we are in the resolver. */
@@ -2265,8 +2281,6 @@ ppc_linux_init_abi (struct gdbarch_info info,
/* Shared library handling. */
set_gdbarch_skip_trampoline_code (gdbarch, ppc_skip_trampoline_code);
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, linux_ilp32_fetch_link_map_offsets);
/* Setting the correct XML syscall filename. */
set_xml_syscall_file_name (gdbarch, XML_SYSCALL_FILENAME_PPC);
@@ -2283,14 +2297,7 @@ ppc_linux_init_abi (struct gdbarch_info info,
else
set_gdbarch_gcore_bfd_target (gdbarch, "elf32-powerpc");
- if (powerpc_so_ops.in_dynsym_resolve_code == NULL)
- {
- powerpc_so_ops = svr4_so_ops;
- /* Override dynamic resolve function. */
- powerpc_so_ops.in_dynsym_resolve_code =
- powerpc_linux_in_dynsym_resolve_code;
- }
- set_gdbarch_so_ops (gdbarch, &powerpc_so_ops);
+ set_solib_svr4_ops (gdbarch, new_ppc_linux_ilp32_svr4_solib_ops);
set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver);
}
@@ -2317,8 +2324,7 @@ ppc_linux_init_abi (struct gdbarch_info info,
/* Shared library handling. */
set_gdbarch_skip_trampoline_code (gdbarch, ppc64_skip_trampoline_code);
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, linux_lp64_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_linux_lp64_svr4_solib_ops);
/* Setting the correct XML syscall filename. */
set_xml_syscall_file_name (gdbarch, XML_SYSCALL_FILENAME_PPC64);
diff --git a/gdb/ppc-netbsd-tdep.c b/gdb/ppc-netbsd-tdep.c
index 911c012983e6..b030f93a2525 100644
--- a/gdb/ppc-netbsd-tdep.c
+++ b/gdb/ppc-netbsd-tdep.c
@@ -179,8 +179,7 @@ ppcnbsd_init_abi (struct gdbarch_info info,
set_gdbarch_return_value (gdbarch, ppcnbsd_return_value);
/* NetBSD uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_svr4_ilp32_solib_ops);
set_gdbarch_iterate_over_regset_sections
(gdbarch, ppcnbsd_iterate_over_regset_sections);
diff --git a/gdb/ppc-obsd-tdep.c b/gdb/ppc-obsd-tdep.c
index 5e271c1c7be3..dc00227a0c29 100644
--- a/gdb/ppc-obsd-tdep.c
+++ b/gdb/ppc-obsd-tdep.c
@@ -254,8 +254,7 @@ ppcobsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
set_gdbarch_return_value (gdbarch, ppc_sysv_abi_broken_return_value);
/* OpenBSD uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_svr4_ilp32_solib_ops);
set_gdbarch_iterate_over_regset_sections
(gdbarch, ppcobsd_iterate_over_regset_sections);
diff --git a/gdb/progspace.h b/gdb/progspace.h
index abb448195d74..c84a95c96657 100644
--- a/gdb/progspace.h
+++ b/gdb/progspace.h
@@ -21,6 +21,7 @@
#ifndef GDB_PROGSPACE_H
#define GDB_PROGSPACE_H
+#include "solib.h"
#include "target.h"
#include "gdb_bfd.h"
#include "registry.h"
@@ -234,19 +235,23 @@ struct program_space
/* Set this program space's solib provider.
The solib provider must be unset prior to call this method. */
- void set_solib_ops (const struct solib_ops &ops)
+ void set_solib_ops (solib_ops_up ops)
{
gdb_assert (m_solib_ops == nullptr);
- m_solib_ops = &ops;
+ m_solib_ops = std::move (ops);
};
- /* Unset this program space's solib provider. */
+ /* Unset and free this program space's solib provider. */
void unset_solib_ops ()
{ m_solib_ops = nullptr; }
+ /* Unset and return this program space's solib provider. */
+ solib_ops_up release_solib_ops ()
+ { return std::move (m_solib_ops); }
+
/* Get this program space's solib provider. */
- const struct solib_ops *solib_ops () const
- { return m_solib_ops; }
+ struct solib_ops *solib_ops () const
+ { return m_solib_ops.get (); }
/* Return the list of all the solibs in this program space. */
owning_intrusive_list<solib> &solibs ()
@@ -373,7 +378,7 @@ struct program_space
owning_intrusive_list<objfile> m_objfiles_list;
/* solib_ops implementation used to provide solibs in this program space. */
- const struct solib_ops *m_solib_ops = nullptr;
+ solib_ops_up m_solib_ops;
/* List of shared objects mapped into this space. Managed by
solib.c. */
diff --git a/gdb/riscv-fbsd-tdep.c b/gdb/riscv-fbsd-tdep.c
index fcb91caf5fb6..69e14ac47e3a 100644
--- a/gdb/riscv-fbsd-tdep.c
+++ b/gdb/riscv-fbsd-tdep.c
@@ -191,10 +191,9 @@ riscv_fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
set_gdbarch_software_single_step (gdbarch, riscv_software_single_step);
- set_solib_svr4_fetch_link_map_offsets (gdbarch,
- (riscv_isa_xlen (gdbarch) == 4
- ? svr4_ilp32_fetch_link_map_offsets
- : svr4_lp64_fetch_link_map_offsets));
+ set_solib_svr4_ops (gdbarch, (riscv_isa_xlen (gdbarch) == 4
+ ? new_svr4_ilp32_solib_ops
+ : new_svr4_lp64_solib_ops));
tramp_frame_prepend_unwinder (gdbarch, &riscv_fbsd_sigframe);
diff --git a/gdb/riscv-linux-tdep.c b/gdb/riscv-linux-tdep.c
index e1ea6158a45c..fb21fa0cfa1a 100644
--- a/gdb/riscv-linux-tdep.c
+++ b/gdb/riscv-linux-tdep.c
@@ -20,6 +20,7 @@
#include "osabi.h"
#include "glibc-tdep.h"
#include "linux-tdep.h"
+#include "solib-svr4-linux.h"
#include "svr4-tls-tdep.h"
#include "solib-svr4.h"
#include "regset.h"
@@ -512,10 +513,9 @@ riscv_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
set_gdbarch_software_single_step (gdbarch, riscv_software_single_step);
- set_solib_svr4_fetch_link_map_offsets (gdbarch,
- (riscv_isa_xlen (gdbarch) == 4
- ? linux_ilp32_fetch_link_map_offsets
- : linux_lp64_fetch_link_map_offsets));
+ set_solib_svr4_ops (gdbarch, (riscv_isa_xlen (gdbarch) == 4
+ ? new_linux_ilp32_svr4_solib_ops
+ : new_linux_lp64_svr4_solib_ops));
/* GNU/Linux uses SVR4-style shared libraries. */
set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
diff --git a/gdb/rs6000-aix-tdep.c b/gdb/rs6000-aix-tdep.c
index ab9feb38fb78..214fb88c32cc 100644
--- a/gdb/rs6000-aix-tdep.c
+++ b/gdb/rs6000-aix-tdep.c
@@ -1411,7 +1411,7 @@ rs6000_aix_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch)
set_gdbarch_wchar_signed (gdbarch, 0);
set_gdbarch_auto_wide_charset (gdbarch, rs6000_aix_auto_wide_charset);
- set_gdbarch_so_ops (gdbarch, &solib_aix_so_ops);
+ set_gdbarch_new_solib_ops (gdbarch, new_aix_solib_ops);
frame_unwind_append_unwinder (gdbarch, &aix_sighandle_frame_unwind);
}
diff --git a/gdb/s390-linux-tdep.c b/gdb/s390-linux-tdep.c
index bd1f42ca8d25..e22e1454bed6 100644
--- a/gdb/s390-linux-tdep.c
+++ b/gdb/s390-linux-tdep.c
@@ -29,6 +29,7 @@
#include "gdbcore.h"
#include "linux-record.h"
#include "linux-tdep.h"
+#include "solib-svr4-linux.h"
#include "svr4-tls-tdep.h"
#include "objfiles.h"
#include "osabi.h"
@@ -1214,8 +1215,7 @@ s390_linux_init_abi_31 (struct gdbarch_info info, struct gdbarch *gdbarch)
s390_linux_init_abi_any (info, gdbarch);
- set_solib_svr4_fetch_link_map_offsets (gdbarch,
- linux_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_linux_ilp32_svr4_solib_ops);
set_xml_syscall_file_name (gdbarch, XML_SYSCALL_FILENAME_S390);
}
@@ -1230,8 +1230,7 @@ s390_linux_init_abi_64 (struct gdbarch_info info, struct gdbarch *gdbarch)
s390_linux_init_abi_any (info, gdbarch);
- set_solib_svr4_fetch_link_map_offsets (gdbarch,
- linux_lp64_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_linux_lp64_svr4_solib_ops);
set_xml_syscall_file_name (gdbarch, XML_SYSCALL_FILENAME_S390X);
}
diff --git a/gdb/sh-linux-tdep.c b/gdb/sh-linux-tdep.c
index f0b35d3063a6..c28ec361eb05 100644
--- a/gdb/sh-linux-tdep.c
+++ b/gdb/sh-linux-tdep.c
@@ -28,6 +28,7 @@
#include "glibc-tdep.h"
#include "sh-tdep.h"
#include "linux-tdep.h"
+#include "solib-svr4-linux.h"
#include "gdbarch.h"
#define REGSx16(base) \
@@ -187,8 +188,7 @@ sh_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
/* GNU/Linux uses SVR4-style shared libraries. */
set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, linux_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_linux_ilp32_svr4_solib_ops);
set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver);
set_gdbarch_fetch_tls_load_module_address (gdbarch,
diff --git a/gdb/sh-netbsd-tdep.c b/gdb/sh-netbsd-tdep.c
index f99566f2fd59..685ba3c0585d 100644
--- a/gdb/sh-netbsd-tdep.c
+++ b/gdb/sh-netbsd-tdep.c
@@ -68,8 +68,7 @@ shnbsd_init_abi (struct gdbarch_info info,
tdep->core_gregmap = (struct sh_corefile_regmap *)regmap;
tdep->sizeof_gregset = 84;
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_svr4_ilp32_solib_ops);
}
void _initialize_shnbsd_tdep ();
diff --git a/gdb/solib-aix.c b/gdb/solib-aix.c
index 17eeba940770..91cc1d8c66de 100644
--- a/gdb/solib-aix.c
+++ b/gdb/solib-aix.c
@@ -24,6 +24,24 @@
#include "xcoffread.h"
#include "observable.h"
+/* solib_ops for AIX systems. */
+
+struct aix_solib_ops : public solib_ops
+{
+ void relocate_section_addresses (solib &so, target_section *) const override;
+ void create_inferior_hook (int from_tty) override;
+ owning_intrusive_list<solib> current_sos () override;
+ gdb_bfd_ref_ptr bfd_open (const char *pathname) override;
+};
+
+/* See solib-aix.h. */
+
+solib_ops_up
+new_aix_solib_ops ()
+{
+ return std::make_unique<aix_solib_ops> ();
+}
+
/* Our private data in struct solib. */
struct lm_info_aix final : public lm_info
@@ -306,10 +324,9 @@ solib_aix_bss_data_overlap (bfd *abfd)
return 0;
}
-/* Implement the "relocate_section_addresses" solib_ops method. */
-
-static void
-solib_aix_relocate_section_addresses (solib &so, target_section *sec)
+void
+aix_solib_ops::relocate_section_addresses (solib &so,
+ target_section *sec) const
{
struct bfd_section *bfd_sect = sec->the_bfd_section;
bfd *abfd = bfd_sect->owner;
@@ -410,10 +427,8 @@ solib_aix_get_section_offsets (struct objfile *objfile,
return offsets;
}
-/* Implement the "solib_create_inferior_hook" solib_ops method. */
-
-static void
-solib_aix_solib_create_inferior_hook (int from_tty)
+void
+aix_solib_ops::create_inferior_hook (int from_tty)
{
const char *warning_msg = "unable to relocate main executable";
@@ -441,10 +456,8 @@ solib_aix_solib_create_inferior_hook (int from_tty)
}
}
-/* Implement the "current_sos" solib_ops method. */
-
-static owning_intrusive_list<solib>
-solib_aix_current_sos ()
+owning_intrusive_list<solib>
+aix_solib_ops::current_sos ()
{
std::optional<std::vector<lm_info_aix>> &library_list
= solib_aix_get_library_list (current_inferior (), NULL);
@@ -480,7 +493,7 @@ solib_aix_current_sos ()
}
/* Add it to the list. */
- auto &new_solib = sos.emplace_back (solib_aix_so_ops);
+ auto &new_solib = sos.emplace_back (*this);
new_solib.original_name = so_name;
new_solib.name = so_name;
new_solib.lm_info = std::make_unique<lm_info_aix> (info);
@@ -489,10 +502,8 @@ solib_aix_current_sos ()
return sos;
}
-/* Implement the "bfd_open" solib_ops method. */
-
-static gdb_bfd_ref_ptr
-solib_aix_bfd_open (const char *pathname)
+gdb_bfd_ref_ptr
+aix_solib_ops::bfd_open (const char *pathname)
{
/* The pathname is actually a synthetic filename with the following
form: "/path/to/sharedlib(member.o)" (double-quotes excluded).
@@ -506,7 +517,7 @@ solib_aix_bfd_open (const char *pathname)
int found_file;
if (pathname[path_len - 1] != ')')
- return solib_bfd_open (pathname);
+ return solib_ops::bfd_open (pathname);
/* Search for the associated parens. */
sep = strrchr (pathname, '(');
@@ -516,7 +527,7 @@ solib_aix_bfd_open (const char *pathname)
to open pathname without decoding, possibly leading to
a failure), rather than triggering an assert failure). */
warning (_("missing '(' in shared object pathname: %s"), pathname);
- return solib_bfd_open (pathname);
+ return solib_ops::bfd_open (pathname);
}
filename_len = sep - pathname;
@@ -659,24 +670,6 @@ solib_aix_normal_stop_observer (struct bpstat *unused_1, int unused_2)
data->library_list.reset ();
}
-/* The solib_ops for AIX targets. */
-const solib_ops solib_aix_so_ops =
-{
- solib_aix_relocate_section_addresses,
- nullptr,
- nullptr,
- solib_aix_solib_create_inferior_hook,
- solib_aix_current_sos,
- nullptr,
- nullptr,
- solib_aix_bfd_open,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- default_find_solib_addr,
-};
-
void _initialize_solib_aix ();
void
_initialize_solib_aix ()
diff --git a/gdb/solib-aix.h b/gdb/solib-aix.h
index 7a1bc7b4b567..ac824e547cfa 100644
--- a/gdb/solib-aix.h
+++ b/gdb/solib-aix.h
@@ -18,9 +18,12 @@
#ifndef GDB_SOLIB_AIX_H
#define GDB_SOLIB_AIX_H
-struct solib_ops;
-extern const solib_ops solib_aix_so_ops;
+#include "solib.h"
extern CORE_ADDR solib_aix_get_toc_value (CORE_ADDR pc);
+/* Return a new solib_ops for AIX systems. */
+
+solib_ops_up new_aix_solib_ops ();
+
#endif /* GDB_SOLIB_AIX_H */
diff --git a/gdb/solib-darwin.c b/gdb/solib-darwin.c
index 88a2962f5dd5..aece190a711d 100644
--- a/gdb/solib-darwin.c
+++ b/gdb/solib-darwin.c
@@ -33,6 +33,25 @@
#include "mach-o.h"
#include "mach-o/external.h"
+/* solib_ops for Darwin systems. */
+
+struct darwin_solib_ops : public solib_ops
+{
+ void relocate_section_addresses (solib &so, target_section *) const override;
+ void clear_solib (program_space *pspace) override;
+ void create_inferior_hook (int from_tty) override;
+ owning_intrusive_list<solib> current_sos () override;
+ gdb_bfd_ref_ptr bfd_open (const char *pathname) override;
+};
+
+/* See solib-darwin.h. */
+
+solib_ops_up
+new_darwin_solib_ops ()
+{
+ return std::make_unique<darwin_solib_ops> ();
+}
+
struct gdb_dyld_image_info
{
/* Base address (which corresponds to the Mach-O header). */
@@ -188,10 +207,8 @@ find_program_interpreter (void)
return buf;
}
-/* Build a list of currently loaded shared objects. See solib-svr4.c. */
-
-static owning_intrusive_list<solib>
-darwin_current_sos ()
+owning_intrusive_list<solib>
+darwin_solib_ops::current_sos ()
{
type *ptr_type
= builtin_type (current_inferior ()->arch ())->builtin_data_ptr;
@@ -250,7 +267,7 @@ darwin_current_sos ()
break;
/* Create and fill the new struct solib element. */
- auto &newobj = sos.emplace_back (darwin_so_ops);
+ auto &newobj = sos.emplace_back (*this);
auto li = std::make_unique<lm_info_darwin> ();
@@ -457,10 +474,8 @@ darwin_solib_read_all_image_info_addr (struct darwin_info *info)
info->all_image_addr = extract_unsigned_integer (buf, len, BFD_ENDIAN_BIG);
}
-/* Shared library startup support. See documentation in solib-svr4.c. */
-
-static void
-darwin_solib_create_inferior_hook (int from_tty)
+void
+darwin_solib_ops::create_inferior_hook (int from_tty)
{
/* Everything below only makes sense if we have a running inferior. */
if (!target_has_execution ())
@@ -560,8 +575,8 @@ darwin_solib_create_inferior_hook (int from_tty)
create_solib_event_breakpoint (current_inferior ()->arch (), notifier);
}
-static void
-darwin_clear_solib (program_space *pspace)
+void
+darwin_solib_ops::clear_solib (program_space *pspace)
{
darwin_info *info = get_darwin_info (pspace);
@@ -572,8 +587,9 @@ darwin_clear_solib (program_space *pspace)
/* The section table is built from bfd sections using bfd VMAs.
Relocate these VMAs according to solib info. */
-static void
-darwin_relocate_section_addresses (solib &so, target_section *sec)
+void
+darwin_solib_ops::relocate_section_addresses (solib &so,
+ target_section *sec) const
{
auto *li = gdb::checked_static_cast<lm_info_darwin *> (so.lm_info.get ());
@@ -592,9 +608,9 @@ darwin_relocate_section_addresses (solib &so, target_section *sec)
if (sec->addr < so.addr_low)
so.addr_low = sec->addr;
}
-\f
-static gdb_bfd_ref_ptr
-darwin_bfd_open (const char *pathname)
+
+gdb_bfd_ref_ptr
+darwin_solib_ops::bfd_open (const char *pathname)
{
int found_file;
@@ -622,20 +638,3 @@ darwin_bfd_open (const char *pathname)
return res;
}
-
-const solib_ops darwin_so_ops =
-{
- darwin_relocate_section_addresses,
- nullptr,
- darwin_clear_solib,
- darwin_solib_create_inferior_hook,
- darwin_current_sos,
- nullptr,
- nullptr,
- darwin_bfd_open,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- default_find_solib_addr,
-};
diff --git a/gdb/solib-darwin.h b/gdb/solib-darwin.h
index b96e744669fb..09dac6bf52ba 100644
--- a/gdb/solib-darwin.h
+++ b/gdb/solib-darwin.h
@@ -20,8 +20,10 @@
#ifndef GDB_SOLIB_DARWIN_H
#define GDB_SOLIB_DARWIN_H
-struct solib_ops;
+#include "solib.h"
-extern const solib_ops darwin_so_ops;
+/* Return a new solib_ops for Darwin systems. */
+
+extern solib_ops_up new_darwin_solib_ops ();
#endif /* GDB_SOLIB_DARWIN_H */
diff --git a/gdb/solib-dsbt.c b/gdb/solib-dsbt.c
index f6748b69353a..97e32d19e57d 100644
--- a/gdb/solib-dsbt.c
+++ b/gdb/solib-dsbt.c
@@ -120,6 +120,25 @@ struct dbst_ext_link_map
ext_ptr l_next, l_prev; /* struct link_map *l_next, *l_prev; */
};
+/* solib_ops for DSBT systems. */
+
+struct dsbt_solib_ops : public solib_ops
+{
+ void relocate_section_addresses (solib &so, target_section *) const override;
+ void clear_solib (program_space *pspace) override;
+ void create_inferior_hook (int from_tty) override;
+ owning_intrusive_list<solib> current_sos () override;
+ bool in_dynsym_resolve_code (CORE_ADDR pc) const override;
+};
+
+/* See solib-dsbt.h. */
+
+solib_ops_up
+new_dsbt_solib_ops ()
+{
+ return std::make_unique<dsbt_solib_ops> ();
+}
+
/* Link map info to include in an allocated solib entry */
struct lm_info_dsbt final : public lm_info
@@ -502,8 +521,8 @@ lm_base (void)
themselves. The declaration of `struct solib' says which fields
we provide values for. */
-static owning_intrusive_list<solib>
-dsbt_current_sos (void)
+owning_intrusive_list<solib>
+dsbt_solib_ops::current_sos ()
{
bfd_endian byte_order = gdbarch_byte_order (current_inferior ()->arch ());
CORE_ADDR lm_addr;
@@ -584,7 +603,7 @@ dsbt_current_sos (void)
break;
}
- auto &sop = sos.emplace_back (dsbt_so_ops);
+ auto &sop = sos.emplace_back (*this);
auto li = std::make_unique<lm_info_dsbt> ();
li->map = loadmap;
/* Fetch the name. */
@@ -623,8 +642,8 @@ dsbt_current_sos (void)
/* Return true if PC lies in the dynamic symbol resolution code of the
run time loader. */
-static bool
-dsbt_in_dynsym_resolve_code (CORE_ADDR pc)
+bool
+dsbt_solib_ops::in_dynsym_resolve_code (CORE_ADDR pc) const
{
dsbt_info *info = get_dsbt_info (current_program_space);
@@ -840,8 +859,8 @@ dsbt_relocate_main_executable (void)
For the DSBT shared library, the main executable needs to be relocated.
The shared library breakpoints also need to be enabled. */
-static void
-dsbt_solib_create_inferior_hook (int from_tty)
+void
+dsbt_solib_ops::create_inferior_hook (int from_tty)
{
/* Relocate main executable. */
dsbt_relocate_main_executable ();
@@ -854,8 +873,8 @@ dsbt_solib_create_inferior_hook (int from_tty)
}
}
-static void
-dsbt_clear_solib (program_space *pspace)
+void
+dsbt_solib_ops::clear_solib (program_space *pspace)
{
dsbt_info *info = get_dsbt_info (pspace);
@@ -866,8 +885,9 @@ dsbt_clear_solib (program_space *pspace)
info->main_executable_lm_info = NULL;
}
-static void
-dsbt_relocate_section_addresses (solib &so, target_section *sec)
+void
+dsbt_solib_ops::relocate_section_addresses (solib &so,
+ target_section *sec) const
{
int seg;
auto *li = gdb::checked_static_cast<lm_info_dsbt *> (so.lm_info.get ());
@@ -893,23 +913,6 @@ show_dsbt_debug (struct ui_file *file, int from_tty,
gdb_printf (file, _("solib-dsbt debugging is %s.\n"), value);
}
-const solib_ops dsbt_so_ops =
-{
- dsbt_relocate_section_addresses,
- nullptr,
- dsbt_clear_solib,
- dsbt_solib_create_inferior_hook,
- dsbt_current_sos,
- nullptr,
- dsbt_in_dynsym_resolve_code,
- solib_bfd_open,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- default_find_solib_addr,
-};
-
void _initialize_dsbt_solib ();
void
_initialize_dsbt_solib ()
diff --git a/gdb/solib-dsbt.h b/gdb/solib-dsbt.h
index d5c52c69e432..47b03bba589b 100644
--- a/gdb/solib-dsbt.h
+++ b/gdb/solib-dsbt.h
@@ -20,8 +20,10 @@
#ifndef GDB_SOLIB_DSBT_H
#define GDB_SOLIB_DSBT_H
-struct solib_ops;
+#include "solib.h"
-extern const solib_ops dsbt_so_ops;
+/* Return a new solib_ops for DSBT systems. */
+
+solib_ops_up new_dsbt_solib_ops ();
#endif /* GDB_SOLIB_DSBT_H */
diff --git a/gdb/solib-frv.c b/gdb/solib-frv.c
index 12d3140b513c..6ef83672577d 100644
--- a/gdb/solib-frv.c
+++ b/gdb/solib-frv.c
@@ -26,6 +26,26 @@
#include "elf/frv.h"
#include "gdb_bfd.h"
#include "inferior.h"
+#include "solib-frv.h"
+
+/* solib_ops for FR-V systems. */
+
+struct frv_solib_ops : public solib_ops
+{
+ void relocate_section_addresses (solib &so, target_section *) const override;
+ void clear_solib (program_space *pspace) override;
+ void create_inferior_hook (int from_tty) override;
+ owning_intrusive_list<solib> current_sos () override;
+ bool in_dynsym_resolve_code (CORE_ADDR pc) const override;
+};
+
+/* See solib-frv.h. */
+
+solib_ops_up
+new_frv_solib_ops ()
+{
+ return std::make_unique<frv_solib_ops> ();
+}
/* FR-V pointers are four bytes wide. */
enum { FRV_PTR_SIZE = 4 };
@@ -293,11 +313,8 @@ lm_base (void)
return lm_base_cache;
}
-
-/* Implement the "current_sos" solib_ops method. */
-
-static owning_intrusive_list<solib>
-frv_current_sos ()
+owning_intrusive_list<solib>
+frv_solib_ops::current_sos ()
{
bfd_endian byte_order = gdbarch_byte_order (current_inferior ()->arch ());
CORE_ADDR lm_addr, mgot;
@@ -367,7 +384,7 @@ frv_current_sos ()
break;
}
- auto &sop = sos.emplace_back (frv_so_ops);
+ auto &sop = sos.emplace_back (*this);
auto li = std::make_unique<lm_info_frv> ();
li->map = loadmap;
li->got_value = got_addr;
@@ -414,8 +431,8 @@ static CORE_ADDR interp_text_sect_high;
static CORE_ADDR interp_plt_sect_low;
static CORE_ADDR interp_plt_sect_high;
-static bool
-frv_in_dynsym_resolve_code (CORE_ADDR pc)
+bool
+frv_solib_ops::in_dynsym_resolve_code (CORE_ADDR pc) const
{
return ((pc >= interp_text_sect_low && pc < interp_text_sect_high)
|| (pc >= interp_plt_sect_low && pc < interp_plt_sect_high)
@@ -776,8 +793,8 @@ frv_relocate_main_executable (void)
to be relocated. The shared library breakpoints also need to be
enabled. */
-static void
-frv_solib_create_inferior_hook (int from_tty)
+void
+frv_solib_ops::create_inferior_hook (int from_tty)
{
/* Relocate main executable. */
frv_relocate_main_executable ();
@@ -790,8 +807,8 @@ frv_solib_create_inferior_hook (int from_tty)
}
}
-static void
-frv_clear_solib (program_space *pspace)
+void
+frv_solib_ops::clear_solib (program_space *pspace)
{
lm_base_cache = 0;
enable_break2_done = 0;
@@ -801,8 +818,9 @@ frv_clear_solib (program_space *pspace)
main_executable_lm_info = NULL;
}
-static void
-frv_relocate_section_addresses (solib &so, target_section *sec)
+void
+frv_solib_ops::relocate_section_addresses (solib &so,
+ target_section *sec) const
{
int seg;
auto *li = gdb::checked_static_cast<lm_info_frv *> (so.lm_info.get ());
@@ -1063,20 +1081,3 @@ frv_fetch_objfile_link_map (struct objfile *objfile)
/* Not found! */
return 0;
}
-
-const solib_ops frv_so_ops =
-{
- frv_relocate_section_addresses,
- nullptr,
- frv_clear_solib,
- frv_solib_create_inferior_hook,
- frv_current_sos,
- nullptr,
- frv_in_dynsym_resolve_code,
- solib_bfd_open,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- default_find_solib_addr,
-};
diff --git a/gdb/solib-frv.h b/gdb/solib-frv.h
new file mode 100644
index 000000000000..0f43b39cd3e5
--- /dev/null
+++ b/gdb/solib-frv.h
@@ -0,0 +1,28 @@
+/* Handle FR-V (FDPIC) shared libraries for GDB, the GNU Debugger.
+ Copyright (C) 2024 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef GDB_SOLIB_FRV_H
+#define GDB_SOLIB_FRV_H
+
+#include "solib.h"
+
+/* Return a new solib_ops for FR-V systems. */
+
+solib_ops_up new_frv_solib_ops ();
+
+#endif /* GDB_SOLIB_FRV_H */
diff --git a/gdb/solib-rocm.c b/gdb/solib-rocm.c
index a3599562e795..ab7dc3e66808 100644
--- a/gdb/solib-rocm.c
+++ b/gdb/solib-rocm.c
@@ -26,6 +26,7 @@
#include "event-top.h"
#include "gdbsupport/fileio.h"
#include "inferior.h"
+#include "linux-tdep.h"
#include "observable.h"
#include "solib.h"
#include "solib-svr4.h"
@@ -153,7 +154,69 @@ struct solib_info
/* Per-inferior data key. */
static const registry<inferior>::key<solib_info> rocm_solib_data;
-static solib_ops rocm_solib_ops;
+/* solib_ops for ROCm systems. */
+
+struct rocm_solib_ops : public solib_ops
+{
+ /* HOST_OPS is the host solib_ops that rocm_solib_ops hijacks / wraps,
+ in order to provide support for ROCm code objects. */
+ explicit rocm_solib_ops (solib_ops_up host_ops)
+ : m_host_ops (std::move (host_ops))
+ {
+ }
+
+ /* The methods implemented by rocm_solib_ops. */
+ owning_intrusive_list<solib> current_sos () override;
+ void create_inferior_hook (int from_tty) override;
+ gdb_bfd_ref_ptr bfd_open (const char *pathname) override;
+ void relocate_section_addresses (solib &so, target_section *) const override;
+ void handle_event () override;
+
+ /* Implement the following methods just to forward the calls to the host
+ solib_ops. We currently need to implement all the methods that
+ svr4_solib_ops implements. */
+ void clear_so (const solib &so) const override
+ { return m_host_ops->clear_so (so); }
+
+ void clear_solib (program_space *pspace) override
+ { return m_host_ops->clear_solib (pspace); }
+
+ bool open_symbol_file_object (int from_tty) override
+ { return m_host_ops->open_symbol_file_object (from_tty); }
+
+ bool in_dynsym_resolve_code (CORE_ADDR pc) const override
+ { return m_host_ops->in_dynsym_resolve_code (pc); }
+
+ bool same (const solib &gdb, const solib &inferior) const override
+ { return m_host_ops->same (gdb, inferior); }
+
+ bool keep_data_in_core (CORE_ADDR vaddr, unsigned long size) override
+ { return m_host_ops->keep_data_in_core (vaddr, size); }
+
+ void update_breakpoints () const override
+ { return m_host_ops->update_breakpoints (); }
+
+ std::optional<CORE_ADDR> find_solib_addr (solib &so) const override
+ { return m_host_ops->find_solib_addr (so); }
+
+ bool supports_namespaces () const override
+ { return true; }
+
+ int find_solib_ns (const solib &so) const override
+ { return m_host_ops->find_solib_ns (so); }
+
+ int num_active_namespaces () const override
+ { return m_host_ops->num_active_namespaces (); }
+
+ std::vector<const solib *> get_solibs_in_ns (int nsid) const override
+ { return m_host_ops->get_solibs_in_ns (nsid); }
+
+private:
+ owning_intrusive_list<solib>
+ solibs_from_rocm_sos (const std::vector<rocm_so> &sos);
+
+ solib_ops_up m_host_ops;
+};
/* Fetch the solib_info data for INF. */
@@ -170,13 +233,13 @@ get_solib_info (inferior *inf)
/* Relocate section addresses. */
-static void
-rocm_solib_relocate_section_addresses (solib &so,
- struct target_section *sec)
+void
+rocm_solib_ops::relocate_section_addresses (solib &so,
+ struct target_section *sec) const
{
if (!is_amdgpu_arch (gdbarch_from_bfd (so.abfd.get ())))
{
- svr4_so_ops.relocate_section_addresses (so, sec);
+ m_host_ops->relocate_section_addresses (so, sec);
return;
}
@@ -187,30 +250,30 @@ rocm_solib_relocate_section_addresses (solib &so,
static void rocm_update_solib_list ();
-static void
-rocm_solib_handle_event ()
+void
+rocm_solib_ops::handle_event ()
{
- /* Since we sit on top of svr4_so_ops, we might get called following an event
- concerning host libraries. We must therefore forward the call. If the
- event was for a ROCm code object, it will be a no-op. On the other hand,
+ /* Since we sit on top of a host solib_ops, we might get called following an
+ event concerning host libraries. We must therefore forward the call. If
+ the event was for a ROCm code object, it will be a no-op. On the other hand
if the event was for host libraries, rocm_update_solib_list will be
essentially be a no-op (it will reload the same code object list as was
previously loaded). */
- svr4_so_ops.handle_event ();
+ m_host_ops->handle_event ();
rocm_update_solib_list ();
}
/* Create solib objects from rocm_so objects in SOS. */
-static owning_intrusive_list<solib>
-solibs_from_rocm_sos (const std::vector<rocm_so> &sos)
+owning_intrusive_list<solib>
+rocm_solib_ops::solibs_from_rocm_sos (const std::vector<rocm_so> &sos)
{
owning_intrusive_list<solib> dst;
for (const rocm_so &so : sos)
{
- auto &newobj = dst.emplace_back (rocm_solib_ops);
+ auto &newobj = dst.emplace_back (*this);
newobj.lm_info = std::make_unique<lm_info_svr4> (*so.lm_info);
newobj.name = so.name;
@@ -223,11 +286,11 @@ solibs_from_rocm_sos (const std::vector<rocm_so> &sos)
/* Build a list of `struct solib' objects describing the shared
objects currently loaded in the inferior. */
-static owning_intrusive_list<solib>
-rocm_solib_current_sos ()
+owning_intrusive_list<solib>
+rocm_solib_ops::current_sos ()
{
/* First, retrieve the host-side shared library list. */
- owning_intrusive_list<solib> sos = svr4_so_ops.current_sos ();
+ owning_intrusive_list<solib> sos = m_host_ops->current_sos ();
/* Then, the device-side shared library list. */
std::vector<rocm_so> &dev_sos = get_solib_info (current_inferior ())->solib_list;
@@ -579,12 +642,12 @@ rocm_bfd_iovec_open (bfd *abfd, inferior *inferior)
}
}
-static gdb_bfd_ref_ptr
-rocm_solib_bfd_open (const char *pathname)
+gdb_bfd_ref_ptr
+rocm_solib_ops::bfd_open (const char *pathname)
{
/* Handle regular files with SVR4 open. */
if (strstr (pathname, "://") == nullptr)
- return svr4_so_ops.bfd_open (pathname);
+ return m_host_ops->bfd_open (pathname);
auto open = [] (bfd *nbfd) -> gdb_bfd_iovec_base *
{
@@ -668,12 +731,12 @@ rocm_solib_bfd_open (const char *pathname)
return abfd;
}
-static void
-rocm_solib_create_inferior_hook (int from_tty)
+void
+rocm_solib_ops::create_inferior_hook (int from_tty)
{
get_solib_info (current_inferior ())->solib_list.clear ();
- svr4_so_ops.solib_create_inferior_hook (from_tty);
+ m_host_ops->create_inferior_hook (from_tty);
}
static void
@@ -736,22 +799,6 @@ rocm_update_solib_list ()
sos.emplace_back (uri_bytes, std::move (unique_name), std::move (li));
}
-
- if (rocm_solib_ops.current_sos == NULL)
- {
- /* Override what we need to. */
- rocm_solib_ops = svr4_so_ops;
- rocm_solib_ops.current_sos = rocm_solib_current_sos;
- rocm_solib_ops.solib_create_inferior_hook
- = rocm_solib_create_inferior_hook;
- rocm_solib_ops.bfd_open = rocm_solib_bfd_open;
- rocm_solib_ops.relocate_section_addresses
- = rocm_solib_relocate_section_addresses;
- rocm_solib_ops.handle_event = rocm_solib_handle_event;
-
- /* Engage the ROCm so_ops. */
- set_gdbarch_so_ops (current_inferior ()->arch (), &rocm_solib_ops);
- }
}
static void
@@ -759,6 +806,10 @@ rocm_solib_target_inferior_created (inferior *inf)
{
get_solib_info (inf)->solib_list.clear ();
+ auto prev_ops = inf->pspace->release_solib_ops ();
+ auto rocm_ops = std::make_unique<rocm_solib_ops> (std::move (prev_ops));
+ inf->pspace->set_solib_ops (std::move (rocm_ops));
+
rocm_update_solib_list ();
/* Force GDB to reload the solibs. */
@@ -766,6 +817,21 @@ rocm_solib_target_inferior_created (inferior *inf)
solib_add (nullptr, 0, auto_solib_add);
}
+static void
+rocm_solib_target_inferior_execd (inferior *exec_inf, inferior *follow_inf)
+{
+ /* Engage the ROCm so_ops, but only if dbgapi is attached to the inferior
+ (avoiding remote inferiors and core file debugging). */
+ if (get_amd_dbgapi_process_id (follow_inf) == AMD_DBGAPI_PROCESS_NONE)
+ return;
+
+ auto prev_ops = follow_inf->pspace->release_solib_ops ();
+ auto rocm_ops = std::make_unique<rocm_solib_ops> (std::move (prev_ops));
+ follow_inf->pspace->set_solib_ops (std::move (rocm_ops));
+
+ get_solib_info (exec_inf)->solib_list.clear ();
+}
+
/* -Wmissing-prototypes */
extern initialize_file_ftype _initialize_rocm_solib;
@@ -779,4 +845,8 @@ _initialize_rocm_solib ()
(rocm_solib_target_inferior_created,
"solib-rocm",
{ &get_amd_dbgapi_target_inferior_created_observer_token () });
+
+ gdb::observers::inferior_execd.attach
+ (rocm_solib_target_inferior_execd, "solib-rocm",
+ { &get_amd_dbgapi_target_inferior_execd_observer_token () });
}
diff --git a/gdb/solib-svr4-linux.c b/gdb/solib-svr4-linux.c
new file mode 100644
index 000000000000..c4bd8d89cfab
--- /dev/null
+++ b/gdb/solib-svr4-linux.c
@@ -0,0 +1,98 @@
+/* Target-dependent code for GNU/Linux using SVR4-style libraries.
+
+ Copyright (C) 2025 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "solib-svr4-linux.h"
+
+/* See solib-svr4-linux.h. */
+
+solib_ops_up
+new_linux_ilp32_svr4_solib_ops ()
+{
+ return std::make_unique<linux_ilp32_svr4_solib_ops> ();
+}
+
+/* See solib-svr4-linux.h. */
+
+link_map_offsets *
+linux_ilp32_svr4_solib_ops::fetch_link_map_offsets () const
+{
+ static link_map_offsets lmo;
+ static link_map_offsets *lmp = nullptr;
+
+ if (lmp == nullptr)
+ {
+ lmp = &lmo;
+
+ lmo.r_version_offset = 0;
+ lmo.r_version_size = 4;
+ lmo.r_map_offset = 4;
+ lmo.r_brk_offset = 8;
+ lmo.r_ldsomap_offset = -1;
+ lmo.r_next_offset = 20;
+
+ /* Everything we need is in the first 20 bytes. */
+ lmo.link_map_size = 20;
+ lmo.l_addr_offset = 0;
+ lmo.l_name_offset = 4;
+ lmo.l_ld_offset = 8;
+ lmo.l_next_offset = 12;
+ lmo.l_prev_offset = 16;
+ }
+
+ return lmp;
+}
+
+/* See solib-svr4-linux.h. */
+
+solib_ops_up
+new_linux_lp64_svr4_solib_ops ()
+{
+ return std::make_unique<linux_lp64_svr4_solib_ops> ();
+}
+
+/* See linux-tdep.h. */
+
+link_map_offsets *
+linux_lp64_svr4_solib_ops::fetch_link_map_offsets () const
+{
+ static link_map_offsets lmo;
+ static link_map_offsets *lmp = nullptr;
+
+ if (lmp == nullptr)
+ {
+ lmp = &lmo;
+
+ lmo.r_version_offset = 0;
+ lmo.r_version_size = 4;
+ lmo.r_map_offset = 8;
+ lmo.r_brk_offset = 16;
+ lmo.r_ldsomap_offset = -1;
+ lmo.r_next_offset = 40;
+
+ /* Everything we need is in the first 40 bytes. */
+ lmo.link_map_size = 40;
+ lmo.l_addr_offset = 0;
+ lmo.l_name_offset = 8;
+ lmo.l_ld_offset = 16;
+ lmo.l_next_offset = 24;
+ lmo.l_prev_offset = 32;
+ }
+
+ return lmp;
+}
diff --git a/gdb/solib-svr4-linux.h b/gdb/solib-svr4-linux.h
new file mode 100644
index 000000000000..885785fdfcba
--- /dev/null
+++ b/gdb/solib-svr4-linux.h
@@ -0,0 +1,47 @@
+/* Target-dependent code for GNU/Linux using SVR4-style libraries.
+
+ Copyright (C) 2025 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef GDB_SOLIB_SVR4_LINUX_H
+#define GDB_SOLIB_SVR4_LINUX_H
+
+#include "solib-svr4.h"
+
+/* solib_ops for ILP32 Linux systems. */
+
+struct linux_ilp32_svr4_solib_ops : public svr4_solib_ops
+{
+ link_map_offsets *fetch_link_map_offsets () const override;
+};
+
+/* solib_ops for LP64 Linux systems. */
+
+struct linux_lp64_svr4_solib_ops : public svr4_solib_ops
+{
+ link_map_offsets *fetch_link_map_offsets () const override;
+};
+
+/* Return a new solib_ops for ILP32 Linux systems. */
+
+extern solib_ops_up new_linux_ilp32_svr4_solib_ops ();
+
+/* Return a new solib_ops for LP64 Linux systems. */
+
+extern solib_ops_up new_linux_lp64_svr4_solib_ops ();
+
+#endif /* GDB_SOLIB_SVR4_LINUX_H */
diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
index deefc2578599..e9430281bca0 100644
--- a/gdb/solib-svr4.c
+++ b/gdb/solib-svr4.c
@@ -47,7 +47,6 @@
#include <map>
-static struct link_map_offsets *svr4_fetch_link_map_offsets (void);
static void svr4_relocate_main_executable (void);
static void probes_table_remove_objfile_probes (struct objfile *objfile);
static void svr4_iterate_over_objfiles_in_search_order
@@ -89,27 +88,6 @@ static const char * const main_name_list[] =
NULL
};
-/* What to do when a probe stop occurs. */
-
-enum probe_action
-{
- /* Something went seriously wrong. Stop using probes and
- revert to using the older interface. */
- PROBES_INTERFACE_FAILED,
-
- /* No action is required. The shared object list is still
- valid. */
- DO_NOTHING,
-
- /* The shared object list should be reloaded entirely. */
- FULL_RELOAD,
-
- /* Attempt to incrementally update the shared object list. If
- the update fails or is not possible, fall back to reloading
- the list in full. */
- UPDATE_OR_RELOAD,
-};
-
/* A probe's name and its associated action. */
struct probe_info
@@ -184,8 +162,8 @@ svr4_same (const char *gdb_name, const char *inferior_name,
return gdb_lm_info.l_addr_inferior == inferior_lm_info.l_addr_inferior;
}
-static int
-svr4_same (const solib &gdb, const solib &inferior)
+bool
+svr4_solib_ops::same (const solib &gdb, const solib &inferior) const
{
auto *lmg
= gdb::checked_static_cast<const lm_info_svr4 *> (gdb.lm_info.get ());
@@ -196,10 +174,10 @@ svr4_same (const solib &gdb, const solib &inferior)
inferior.original_name.c_str (), *lmg, *lmi);
}
-static lm_info_svr4_up
-lm_info_read (CORE_ADDR lm_addr)
+lm_info_svr4_up
+svr4_solib_ops::read_lm_info (CORE_ADDR lm_addr) const
{
- struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
+ link_map_offsets *lmo = this->fetch_link_map_offsets ();
lm_info_svr4_up lm_info;
gdb::byte_vector lm (lmo->link_map_size);
@@ -229,16 +207,16 @@ lm_info_read (CORE_ADDR lm_addr)
return lm_info;
}
-static int
-has_lm_dynamic_from_link_map (void)
+int
+svr4_solib_ops::has_lm_dynamic_from_link_map () const
{
- struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
+ link_map_offsets *lmo = this->fetch_link_map_offsets ();
return lmo->l_ld_offset >= 0;
}
-static CORE_ADDR
-lm_addr_check (const solib &so, bfd *abfd)
+CORE_ADDR
+svr4_solib_ops::lm_addr_check (const solib &so, bfd *abfd) const
{
auto *li = gdb::checked_static_cast<lm_info_svr4 *> (so.lm_info.get ());
@@ -249,7 +227,7 @@ lm_addr_check (const solib &so, bfd *abfd)
l_addr = li->l_addr_inferior;
- if (! abfd || ! has_lm_dynamic_from_link_map ())
+ if (!abfd || !this->has_lm_dynamic_from_link_map ())
goto set_addr;
l_dynaddr = li->l_ld;
@@ -475,8 +453,8 @@ svr4_is_default_namespace (const svr4_info *info, CORE_ADDR debug_base)
/* Free the probes table. */
-static void
-free_probes_table (struct svr4_info *info)
+void
+svr4_solib_ops::free_probes_table (svr4_info *info) const
{
info->probes_table.reset (nullptr);
}
@@ -820,10 +798,10 @@ elf_locate_base (void)
checking r_version for a known version number, or r_state for
RT_CONSISTENT. */
-static CORE_ADDR
-solib_svr4_r_map (CORE_ADDR debug_base)
+CORE_ADDR
+svr4_solib_ops::read_r_map (CORE_ADDR debug_base) const
{
- struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
+ link_map_offsets *lmo = this->fetch_link_map_offsets ();
type *ptr_type
= builtin_type (current_inferior ()->arch ())->builtin_data_ptr;
CORE_ADDR addr = 0;
@@ -843,10 +821,10 @@ solib_svr4_r_map (CORE_ADDR debug_base)
/* Find r_brk from the inferior's debug base. */
-static CORE_ADDR
-solib_svr4_r_brk (struct svr4_info *info)
+CORE_ADDR
+svr4_solib_ops::find_r_brk (svr4_info *info) const
{
- struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
+ link_map_offsets *lmo = this->fetch_link_map_offsets ();
type *ptr_type
= builtin_type (current_inferior ()->arch ())->builtin_data_ptr;
@@ -857,10 +835,10 @@ solib_svr4_r_brk (struct svr4_info *info)
/* Find the link map for the dynamic linker (if it is not in the
normal list of loaded shared objects). */
-static CORE_ADDR
-solib_svr4_r_ldsomap (struct svr4_info *info)
+CORE_ADDR
+svr4_solib_ops::find_r_ldsomap (svr4_info *info) const
{
- struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
+ link_map_offsets *lmo = this->fetch_link_map_offsets ();
type *ptr_type
= builtin_type (current_inferior ()->arch ())->builtin_data_ptr;
enum bfd_endian byte_order = type_byte_order (ptr_type);
@@ -888,10 +866,10 @@ solib_svr4_r_ldsomap (struct svr4_info *info)
/* Find the next namespace from the r_next field. */
-static CORE_ADDR
-solib_svr4_r_next (CORE_ADDR debug_base)
+CORE_ADDR
+svr4_solib_ops::read_r_next (CORE_ADDR debug_base) const
{
- link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
+ link_map_offsets *lmo = this->fetch_link_map_offsets ();
type *ptr_type
= builtin_type (current_inferior ()->arch ())->builtin_data_ptr;
bfd_endian byte_order = type_byte_order (ptr_type);
@@ -923,8 +901,8 @@ solib_svr4_r_next (CORE_ADDR debug_base)
memory areas containing the l_name string are saved in the core
file. */
-static int
-svr4_keep_data_in_core (CORE_ADDR vaddr, unsigned long size)
+bool
+svr4_solib_ops::keep_data_in_core (CORE_ADDR vaddr, unsigned long size)
{
struct svr4_info *info;
CORE_ADDR ldsomap;
@@ -934,13 +912,13 @@ svr4_keep_data_in_core (CORE_ADDR vaddr, unsigned long size)
info->debug_base = elf_locate_base ();
if (info->debug_base == 0)
- return 0;
+ return false;
- ldsomap = solib_svr4_r_ldsomap (info);
+ ldsomap = this->find_r_ldsomap (info);
if (!ldsomap)
- return 0;
+ return false;
- std::unique_ptr<lm_info_svr4> li = lm_info_read (ldsomap);
+ std::unique_ptr<lm_info_svr4> li = this->read_lm_info (ldsomap);
name_lm = li != NULL ? li->l_name : 0;
return (name_lm >= vaddr && name_lm < vaddr + size);
@@ -948,11 +926,11 @@ svr4_keep_data_in_core (CORE_ADDR vaddr, unsigned long size)
/* See solib.h. */
-static int
-open_symbol_file_object (int from_tty)
+bool
+svr4_solib_ops::open_symbol_file_object (int from_tty)
{
CORE_ADDR lm, l_name;
- struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
+ link_map_offsets *lmo = this->fetch_link_map_offsets ();
type *ptr_type
= builtin_type (current_inferior ()->arch ())->builtin_data_ptr;
int l_name_size = ptr_type->length ();
@@ -965,17 +943,17 @@ open_symbol_file_object (int from_tty)
if (current_program_space->symfile_object_file)
if (!query (_("Attempt to reload symbols from process? ")))
- return 0;
+ return false;
/* Always locate the debug struct, in case it has moved. */
info->debug_base = elf_locate_base ();
if (info->debug_base == 0)
- return 0; /* failed somehow... */
+ return false; /* failed somehow... */
/* First link map member should be the executable. */
- lm = solib_svr4_r_map (info->debug_base);
+ lm = this->read_r_map (info->debug_base);
if (lm == 0)
- return 0; /* failed somehow... */
+ return false; /* failed somehow... */
/* Read address of name from target memory to GDB. */
read_memory (lm + lmo->l_name_offset, l_name_buf.data (), l_name_size);
@@ -984,7 +962,7 @@ open_symbol_file_object (int from_tty)
l_name = extract_typed_address (l_name_buf.data (), ptr_type);
if (l_name == 0)
- return 0; /* No filename. */
+ return false; /* No filename. */
/* Now fetch the filename from target memory. */
gdb::unique_xmalloc_ptr<char> filename
@@ -993,13 +971,13 @@ open_symbol_file_object (int from_tty)
if (filename == nullptr)
{
warning (_("failed to read exec filename from attached file"));
- return 0;
+ return false;
}
/* Have a pathname: read the symbol file. */
symbol_file_add_main (filename.get (), add_flags);
- return 1;
+ return true;
}
/* Data exchange structure for the XML parser as returned by
@@ -1032,8 +1010,8 @@ svr4_free_objfile_observer (struct objfile *objfile)
/* Implement solib_ops.clear_so. */
-static void
-svr4_clear_so (const solib &so)
+void
+svr4_solib_ops::clear_so (const solib &so) const
{
auto *li = gdb::checked_static_cast<lm_info_svr4 *> (so.lm_info.get ());
@@ -1043,14 +1021,14 @@ svr4_clear_so (const solib &so)
/* Create the solib objects equivalent to the svr4_sos in SOS. */
-static owning_intrusive_list<solib>
-solib_from_svr4_sos (const std::vector<svr4_so> &sos)
+owning_intrusive_list<solib>
+svr4_solib_ops::solibs_from_svr4_sos (const std::vector<svr4_so> &sos)
{
owning_intrusive_list<solib> dst;
for (const svr4_so &so : sos)
{
- auto &newobj = dst.emplace_back (svr4_so_ops);
+ auto &newobj = dst.emplace_back (*this);
newobj.name = so.name;
newobj.original_name = so.name;
@@ -1237,8 +1215,8 @@ svr4_current_sos_via_xfer_libraries (struct svr4_library_list *list,
/* If no shared library information is available from the dynamic
linker, build a fallback list from other sources. */
-static owning_intrusive_list<solib>
-svr4_default_sos (svr4_info *info)
+owning_intrusive_list<solib>
+svr4_solib_ops::default_sos (svr4_info *info)
{
if (!info->debug_loader_offset_p)
return {};
@@ -1250,7 +1228,7 @@ svr4_default_sos (svr4_info *info)
li->l_addr_p = 1;
owning_intrusive_list<solib> sos;
- auto &newobj = sos.emplace_back (svr4_so_ops);
+ auto &newobj = sos.emplace_back (*this);
newobj.lm_info = std::move (li);
newobj.name = info->debug_loader_name;
@@ -1266,16 +1244,16 @@ svr4_default_sos (svr4_info *info)
is returned the entries stored to LINK_PTR_PTR are still valid although they may
represent only part of the inferior library list. */
-static int
-svr4_read_so_list (svr4_info *info, CORE_ADDR lm, CORE_ADDR prev_lm,
- std::vector<svr4_so> &sos, int ignore_first)
+int
+svr4_solib_ops::read_so_list (svr4_info *info, CORE_ADDR lm, CORE_ADDR prev_lm,
+ std::vector<svr4_so> &sos, int ignore_first) const
{
CORE_ADDR first_l_name = 0;
CORE_ADDR next_lm;
for (; lm != 0; prev_lm = lm, lm = next_lm)
{
- lm_info_svr4_up li = lm_info_read (lm);
+ lm_info_svr4_up li = this->read_lm_info (lm);
if (li == NULL)
return 0;
@@ -1331,8 +1309,8 @@ svr4_read_so_list (svr4_info *info, CORE_ADDR lm, CORE_ADDR prev_lm,
stored by the probes interface. Handle special cases relating
to the first elements of the list in default namespace. */
-static void
-svr4_current_sos_direct (struct svr4_info *info)
+void
+svr4_solib_ops::current_sos_direct (svr4_info *info) const
{
CORE_ADDR lm;
bool ignore_first;
@@ -1398,15 +1376,15 @@ svr4_current_sos_direct (struct svr4_info *info)
/* Collect the sos in each namespace. */
CORE_ADDR debug_base = info->debug_base;
for (; debug_base != 0;
- ignore_first = false, debug_base = solib_svr4_r_next (debug_base))
+ ignore_first = false, debug_base = this->read_r_next (debug_base))
{
/* Walk the inferior's link map list, and build our so_list list. */
- lm = solib_svr4_r_map (debug_base);
+ lm = this->read_r_map (debug_base);
if (lm != 0)
{
svr4_maybe_add_namespace (info, debug_base);
- svr4_read_so_list (info, lm, 0, info->solib_lists[debug_base],
- ignore_first);
+ this->read_so_list (info, lm, 0, info->solib_lists[debug_base],
+ ignore_first);
}
}
@@ -1419,15 +1397,15 @@ svr4_current_sos_direct (struct svr4_info *info)
r_debug object. If we added it to the default namespace (as it was),
we would probably run into inconsistencies with the load map's
prev/next links (I wonder if we did). */
- debug_base = solib_svr4_r_ldsomap (info);
+ debug_base = this->find_r_ldsomap (info);
if (debug_base != 0)
{
/* Add the dynamic linker's namespace unless we already did. */
if (info->solib_lists.find (debug_base) == info->solib_lists.end ())
{
svr4_maybe_add_namespace (info, debug_base);
- svr4_read_so_list (info, debug_base, 0, info->solib_lists[debug_base],
- 0);
+ this->read_so_list (info, debug_base, 0,
+ info->solib_lists[debug_base], 0);
}
}
@@ -1436,15 +1414,15 @@ svr4_current_sos_direct (struct svr4_info *info)
/* Collect sos read and stored by the probes interface. */
-static owning_intrusive_list<solib>
-svr4_collect_probes_sos (svr4_info *info)
+owning_intrusive_list<solib>
+svr4_solib_ops::collect_probes_sos (svr4_info *info)
{
owning_intrusive_list<solib> res;
for (const auto &tuple : info->solib_lists)
{
const std::vector<svr4_so> &sos = tuple.second;
- res.splice (solib_from_svr4_sos (sos));
+ res.splice (this->solibs_from_svr4_sos (sos));
}
return res;
@@ -1453,26 +1431,26 @@ svr4_collect_probes_sos (svr4_info *info)
/* Implement the main part of the "current_sos" solib_ops
method. */
-static owning_intrusive_list<solib>
-svr4_current_sos_1 (svr4_info *info)
+owning_intrusive_list<solib>
+svr4_solib_ops::current_sos_1 (svr4_info *info)
{
owning_intrusive_list<solib> sos;
/* If we're using the probes interface, we can use the cache as it will
be maintained by probe update/reload actions. */
if (info->probes_table != nullptr)
- sos = svr4_collect_probes_sos (info);
+ sos = this->collect_probes_sos (info);
/* If we're not using the probes interface or if we didn't cache
anything, read the sos to fill the cache, then collect them from the
cache. */
if (sos.empty ())
{
- svr4_current_sos_direct (info);
+ this->current_sos_direct (info);
- sos = svr4_collect_probes_sos (info);
+ sos = this->collect_probes_sos (info);
if (sos.empty ())
- sos = svr4_default_sos (info);
+ sos = this->default_sos (info);
}
return sos;
@@ -1480,11 +1458,11 @@ svr4_current_sos_1 (svr4_info *info)
/* Implement the "current_sos" solib_ops method. */
-static owning_intrusive_list<solib>
-svr4_current_sos ()
+owning_intrusive_list<solib>
+svr4_solib_ops::current_sos ()
{
svr4_info *info = get_svr4_info (current_program_space);
- owning_intrusive_list<solib> sos = svr4_current_sos_1 (info);
+ owning_intrusive_list<solib> sos = this->current_sos_1 (info);
struct mem_range vsyscall_range;
/* Filter out the vDSO module, if present. Its symbol file would
@@ -1731,7 +1709,11 @@ tls_maybe_fill_slot (solib &so)
{
/* Cause svr4_current_sos() to be run if it hasn't been already. */
if (info->main_lm_addr == 0)
- svr4_current_sos_direct (info);
+ {
+ auto &ops
+ = gdb::checked_static_cast<svr4_solib_ops &> (so.ops ());
+ ops.current_sos_direct (info);
+ }
/* Quit early when main_lm_addr is still 0. */
if (info->main_lm_addr == 0)
@@ -1802,7 +1784,7 @@ match_main (const char *soname)
SVR4 run time loader. */
bool
-svr4_in_dynsym_resolve_code (CORE_ADDR pc)
+svr4_solib_ops::in_dynsym_resolve_code (CORE_ADDR pc) const
{
struct svr4_info *info = get_svr4_info (current_program_space);
@@ -2001,12 +1983,10 @@ solib_event_probe_action (struct probe_and_action *pa)
shared objects from the inferior. Handle special cases relating
to the first elements of the list. Returns nonzero on success. */
-static int
-solist_update_full (struct svr4_info *info)
+void
+svr4_solib_ops::update_full (svr4_info *info) const
{
- svr4_current_sos_direct (info);
-
- return 1;
+ this->current_sos_direct (info);
}
/* Update the shared object list starting from the link-map entry
@@ -2014,9 +1994,9 @@ solist_update_full (struct svr4_info *info)
nonzero if the list was successfully updated, or zero to indicate
failure. */
-static int
-solist_update_incremental (svr4_info *info, CORE_ADDR debug_base,
- CORE_ADDR lm)
+int
+svr4_solib_ops::update_incremental (svr4_info *info, CORE_ADDR debug_base,
+ CORE_ADDR lm) const
{
/* Fall back to a full update if we are using a remote target
that does not support incremental transfers. */
@@ -2094,7 +2074,7 @@ solist_update_incremental (svr4_info *info, CORE_ADDR debug_base,
above check and deferral to solist_update_full ensures
that this call to svr4_read_so_list will never see the
first element. */
- if (!svr4_read_so_list (info, lm, prev_lm, solist, 0))
+ if (!this->read_so_list (info, lm, prev_lm, solist, 0))
return 0;
}
@@ -2105,8 +2085,8 @@ solist_update_incremental (svr4_info *info, CORE_ADDR debug_base,
original interface. We don't reset the breakpoints as the
ones set up for the probes-based interface are adequate. */
-static void
-disable_probes_interface (svr4_info *info)
+void
+svr4_solib_ops::disable_probes_interface (svr4_info *info) const
{
warning (_("Probes-based dynamic linker interface failed.\n"
"Reverting to original interface."));
@@ -2121,8 +2101,8 @@ disable_probes_interface (svr4_info *info)
probes-based linker interface. Do nothing if using the
standard interface. */
-static void
-svr4_handle_solib_event (void)
+void
+svr4_solib_ops::handle_event ()
{
struct svr4_info *info = get_svr4_info (current_program_space);
struct probe_and_action *pa;
@@ -2147,9 +2127,9 @@ svr4_handle_solib_event (void)
/* If anything goes wrong we revert to the original linker
interface. */
- auto cleanup = make_scope_exit ([info] ()
+ auto cleanup = make_scope_exit ([this, info] ()
{
- disable_probes_interface (info);
+ this->disable_probes_interface (info);
});
action = solib_event_probe_action (pa);
@@ -2251,15 +2231,12 @@ svr4_handle_solib_event (void)
if (action == UPDATE_OR_RELOAD)
{
- if (!solist_update_incremental (info, debug_base, lm))
+ if (!this->update_incremental (info, debug_base, lm))
action = FULL_RELOAD;
}
if (action == FULL_RELOAD)
- {
- if (!solist_update_full (info))
- return;
- }
+ this->update_full (info);
cleanup.release ();
}
@@ -2306,8 +2283,8 @@ svr4_update_solib_event_breakpoint (struct breakpoint *b)
/* Enable or disable optional solib event breakpoints as appropriate.
Called whenever stop_on_solib_events is changed. */
-static void
-svr4_update_solib_event_breakpoints (void)
+void
+svr4_solib_ops::update_breakpoints () const
{
for (breakpoint &bp : all_breakpoints_safe ())
svr4_update_solib_event_breakpoint (&bp);
@@ -2318,10 +2295,10 @@ svr4_update_solib_event_breakpoints (void)
solib event breakpoint will be created and registered for each
probe. */
-static void
-svr4_create_probe_breakpoints (svr4_info *info, struct gdbarch *gdbarch,
- const std::vector<probe *> *probes,
- struct objfile *objfile)
+void
+svr4_solib_ops::create_probe_breakpoints (svr4_info *info, gdbarch *gdbarch,
+ const std::vector<probe *> *probes,
+ objfile *objfile) const
{
for (int i = 0; i < NUM_PROBES; i++)
{
@@ -2339,17 +2316,17 @@ svr4_create_probe_breakpoints (svr4_info *info, struct gdbarch *gdbarch,
}
}
- svr4_update_solib_event_breakpoints ();
+ this->update_breakpoints ();
}
/* Find all the glibc named probes. Only if all of the probes are found, then
create them and return true. Otherwise return false. If WITH_PREFIX is set
then add "rtld" to the front of the probe names. */
-static bool
-svr4_find_and_create_probe_breakpoints (svr4_info *info,
- struct gdbarch *gdbarch,
- struct obj_section *os,
- bool with_prefix)
+bool
+svr4_solib_ops::find_and_create_probe_breakpoints (svr4_info *info,
+ gdbarch *gdbarch,
+ obj_section *os,
+ bool with_prefix) const
{
SOLIB_SCOPED_DEBUG_START_END ("objfile=%s, with_prefix=%d",
os->objfile->original_name, with_prefix);
@@ -2427,7 +2404,7 @@ svr4_find_and_create_probe_breakpoints (svr4_info *info,
/* All probes found. Now create them. */
solib_debug_printf ("using probes interface");
- svr4_create_probe_breakpoints (info, gdbarch, probes, os->objfile);
+ this->create_probe_breakpoints (info, gdbarch, probes, os->objfile);
return true;
}
@@ -2443,15 +2420,16 @@ svr4_find_and_create_probe_breakpoints (svr4_info *info,
probes aren't found, a single breakpoint is set on the original
marker function. */
-static void
-svr4_create_solib_event_breakpoints (svr4_info *info, struct gdbarch *gdbarch,
- CORE_ADDR address)
+void
+svr4_solib_ops::create_event_breakpoints (svr4_info *info, gdbarch *gdbarch,
+ CORE_ADDR address) const
{
struct obj_section *os = find_pc_section (address);
if (os == nullptr
- || (!svr4_find_and_create_probe_breakpoints (info, gdbarch, os, false)
- && !svr4_find_and_create_probe_breakpoints (info, gdbarch, os, true)))
+ || (!this->find_and_create_probe_breakpoints (info, gdbarch, os, false)
+ && !this->find_and_create_probe_breakpoints (info, gdbarch, os,
+ true)))
{
solib_debug_printf ("falling back to r_brk breakpoint: addr=%s",
paddress (gdbarch, address));
@@ -2491,8 +2469,8 @@ svr4_create_solib_event_breakpoints (svr4_info *info, struct gdbarch *gdbarch,
depending upon whether or not the library is being mapped or unmapped,
and then set to RT_CONSISTENT after the library is mapped/unmapped. */
-static int
-enable_break (struct svr4_info *info, int from_tty)
+int
+svr4_solib_ops::enable_break (svr4_info *info, int from_tty) const
{
const char * const *bkpt_namep;
asection *interp_sect;
@@ -2508,8 +2486,8 @@ 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->debug_base) != 0)
- sym_addr = solib_svr4_r_brk (info);
+ if (info->debug_base && this->read_r_map (info->debug_base) != 0)
+ sym_addr = this->find_r_brk (info);
if (sym_addr != 0)
{
@@ -2568,8 +2546,8 @@ enable_break (struct svr4_info *info, int from_tty)
= info->interp_plt_sect_low + bfd_section_size (interp_sect);
}
- svr4_create_solib_event_breakpoints
- (info, current_inferior ()->arch (), sym_addr);
+ this->create_event_breakpoints (info, current_inferior ()->arch (),
+ sym_addr);
return 1;
}
}
@@ -2621,7 +2599,7 @@ enable_break (struct svr4_info *info, int from_tty)
{
load_addr_found = 1;
loader_found_in_list = 1;
- load_addr = lm_addr_check (so, tmp_bfd.get ());
+ load_addr = this->lm_addr_check (so, tmp_bfd.get ());
break;
}
}
@@ -2728,9 +2706,8 @@ enable_break (struct svr4_info *info, int from_tty)
if (sym_addr != 0)
{
- svr4_create_solib_event_breakpoints (info,
- current_inferior ()->arch (),
- load_addr + sym_addr);
+ this->create_event_breakpoints (info, current_inferior ()->arch (),
+ load_addr + sym_addr);
return 1;
}
@@ -2757,9 +2734,8 @@ enable_break (struct svr4_info *info, int from_tty)
sym_addr = gdbarch_convert_from_func_ptr_addr
(current_inferior ()->arch (), sym_addr,
current_inferior ()->top_target ());
- svr4_create_solib_event_breakpoints (info,
- current_inferior ()->arch (),
- sym_addr);
+ this->create_event_breakpoints (info, current_inferior ()->arch (),
+ sym_addr);
return 1;
}
}
@@ -2777,8 +2753,9 @@ enable_break (struct svr4_info *info, int from_tty)
sym_addr = gdbarch_convert_from_func_ptr_addr
(current_inferior ()->arch (), sym_addr,
current_inferior ()->top_target ());
- svr4_create_solib_event_breakpoints
- (info, current_inferior ()->arch (), sym_addr);
+ this->create_event_breakpoints (info,
+ current_inferior ()->arch (),
+ sym_addr);
return 1;
}
}
@@ -3302,15 +3279,15 @@ svr4_relocate_main_executable (void)
addresses, and saving sufficient information about them to allow
their symbols to be read at a later time. */
-static void
-svr4_solib_create_inferior_hook (int from_tty)
+void
+svr4_solib_ops::create_inferior_hook (int from_tty)
{
struct svr4_info *info;
info = get_svr4_info (current_program_space);
/* Clear the probes-based interface's state. */
- free_probes_table (info);
+ this->free_probes_table (info);
info->solib_lists.clear ();
info->namespace_id.clear ();
info->active_namespaces.clear ();
@@ -3323,12 +3300,12 @@ svr4_solib_create_inferior_hook (int from_tty)
if (!target_has_execution ())
return;
- if (!enable_break (info, from_tty))
+ if (!this->enable_break (info, from_tty))
return;
}
-static void
-svr4_clear_solib (program_space *pspace)
+void
+svr4_solib_ops::clear_solib (program_space *pspace)
{
svr4_info *info = get_svr4_info (pspace);
info->debug_base = 0;
@@ -3391,15 +3368,15 @@ find_loadable_elf_internal_phdr (bfd *abfd, bfd_section *asect)
return nullptr;
}
-/* Implement solib_ops::relocate_section_addresses() for svr4 targets. */
-
-static void
-svr4_relocate_section_addresses (solib &so, target_section *sec)
+void
+svr4_solib_ops::relocate_section_addresses (solib &so,
+ target_section *sec) const
{
bfd *abfd = sec->the_bfd_section->owner;
- sec->addr = svr4_truncate_ptr (sec->addr + lm_addr_check (so, abfd));
- sec->endaddr = svr4_truncate_ptr (sec->endaddr + lm_addr_check (so, abfd));
+ sec->addr = svr4_truncate_ptr (sec->addr + this->lm_addr_check (so, abfd));
+ sec->endaddr
+ = svr4_truncate_ptr (sec->endaddr + this->lm_addr_check (so, abfd));
struct bfd_section *asect = sec->the_bfd_section;
gdb_assert (asect != nullptr);
@@ -3469,56 +3446,23 @@ svr4_relocate_section_addresses (solib &so, target_section *sec)
}
}
}
-\f
-/* Architecture-specific operations. */
-
-struct solib_svr4_ops
-{
- /* Return a description of the layout of `struct link_map'. */
- struct link_map_offsets *(*fetch_link_map_offsets)(void) = nullptr;
-};
-
-/* Per-architecture data key. */
-static const registry<gdbarch>::key<struct solib_svr4_ops> solib_svr4_data;
-
-/* Return a default for the architecture-specific operations. */
-
-static struct solib_svr4_ops *
-get_ops (struct gdbarch *gdbarch)
-{
- struct solib_svr4_ops *ops = solib_svr4_data.get (gdbarch);
- if (ops == nullptr)
- ops = solib_svr4_data.emplace (gdbarch);
- return ops;
-}
-
-/* Set the architecture-specific `struct link_map_offsets' fetcher for
- GDBARCH to FLMO. Also, install SVR4 solib_ops into GDBARCH. */
+/* See solib-svr4.h. */
void
-set_solib_svr4_fetch_link_map_offsets (struct gdbarch *gdbarch,
- struct link_map_offsets *(*flmo) (void))
+set_solib_svr4_ops (gdbarch *gdbarch, gdbarch_new_solib_ops_ftype new_solib_ops)
{
- struct solib_svr4_ops *ops = get_ops (gdbarch);
-
- ops->fetch_link_map_offsets = flmo;
-
- set_gdbarch_so_ops (gdbarch, &svr4_so_ops);
+ set_gdbarch_new_solib_ops (gdbarch, new_solib_ops);
set_gdbarch_iterate_over_objfiles_in_search_order
(gdbarch, svr4_iterate_over_objfiles_in_search_order);
}
-/* Fetch a link_map_offsets structure using the architecture-specific
- `struct link_map_offsets' fetcher. */
+/* See solib-svr4.h. */
-static struct link_map_offsets *
-svr4_fetch_link_map_offsets (void)
+solib_ops_up
+new_svr4_ilp32_solib_ops ()
{
- struct solib_svr4_ops *ops = get_ops (current_inferior ()->arch ());
-
- gdb_assert (ops->fetch_link_map_offsets);
- return ops->fetch_link_map_offsets ();
+ return std::make_unique<ilp32_svr4_solib_ops> ();
}
/* Most OS'es that have SVR4-style ELF dynamic libraries define a
@@ -3528,8 +3472,8 @@ svr4_fetch_link_map_offsets (void)
/* Fetch (and possibly build) an appropriate `struct link_map_offsets'
for an ILP32 SVR4 system. */
-struct link_map_offsets *
-svr4_ilp32_fetch_link_map_offsets (void)
+link_map_offsets *
+ilp32_svr4_solib_ops::fetch_link_map_offsets () const
{
static struct link_map_offsets lmo;
static struct link_map_offsets *lmp = NULL;
@@ -3557,11 +3501,26 @@ svr4_ilp32_fetch_link_map_offsets (void)
return lmp;
}
+/* solib_ops for LP64 SVR4 systems. */
+
+struct lp64_svr4_solib_ops : public svr4_solib_ops
+{
+ link_map_offsets *fetch_link_map_offsets () const override;
+};
+
+/* See solib-svr4.h. */
+
+solib_ops_up
+new_svr4_lp64_solib_ops ()
+{
+ return std::make_unique<lp64_svr4_solib_ops> ();
+}
+
/* Fetch (and possibly build) an appropriate `struct link_map_offsets'
for an LP64 SVR4 system. */
-struct link_map_offsets *
-svr4_lp64_fetch_link_map_offsets (void)
+link_map_offsets *
+lp64_svr4_solib_ops::fetch_link_map_offsets () const
{
static struct link_map_offsets lmo;
static struct link_map_offsets *lmp = NULL;
@@ -3708,19 +3667,15 @@ svr4_iterate_over_objfiles_in_search_order
}
}
-/* See solib_ops::find_solib_addr in solist.h. */
-
-static std::optional<CORE_ADDR>
-svr4_find_solib_addr (solib &so)
+std::optional<CORE_ADDR>
+svr4_solib_ops::find_solib_addr (solib &so) const
{
auto *li = gdb::checked_static_cast<lm_info_svr4 *> (so.lm_info.get ());
return li->l_addr_inferior;
}
-/* See solib_ops::find_solib_ns in solist.h. */
-
-static int
-svr4_find_solib_ns (const solib &so)
+int
+svr4_solib_ops::find_solib_ns (const solib &so) const
{
CORE_ADDR debug_base = find_debug_base_for_solib (&so);
svr4_info *info = get_svr4_info (current_program_space);
@@ -3735,17 +3690,15 @@ svr4_find_solib_ns (const solib &so)
error (_("No namespace found"));
}
-/* see solib_ops::num_active_namespaces in solist.h. */
-static int
-svr4_num_active_namespaces ()
+int
+svr4_solib_ops::num_active_namespaces () const
{
svr4_info *info = get_svr4_info (current_program_space);
return info->active_namespaces.size ();
}
-/* See solib_ops::get_solibs_in_ns in solist.h. */
-static std::vector<const solib *>
-svr4_get_solibs_in_ns (int nsid)
+std::vector<const solib *>
+svr4_solib_ops::get_solibs_in_ns (int nsid) const
{
std::vector<const solib*> ns_solibs;
svr4_info *info = get_svr4_info (current_program_space);
@@ -3791,26 +3744,6 @@ svr4_get_solibs_in_ns (int nsid)
return ns_solibs;
}
-const struct solib_ops svr4_so_ops =
-{
- svr4_relocate_section_addresses,
- svr4_clear_so,
- svr4_clear_solib,
- svr4_solib_create_inferior_hook,
- svr4_current_sos,
- open_symbol_file_object,
- svr4_in_dynsym_resolve_code,
- solib_bfd_open,
- svr4_same,
- svr4_keep_data_in_core,
- svr4_update_solib_event_breakpoints,
- svr4_handle_solib_event,
- svr4_find_solib_addr,
- svr4_find_solib_ns,
- svr4_num_active_namespaces,
- svr4_get_solibs_in_ns,
-};
-
void _initialize_svr4_solib ();
void
_initialize_svr4_solib ()
diff --git a/gdb/solib-svr4.h b/gdb/solib-svr4.h
index 1ff9be78a43d..a7be4c902e75 100644
--- a/gdb/solib-svr4.h
+++ b/gdb/solib-svr4.h
@@ -20,12 +20,15 @@
#ifndef GDB_SOLIB_SVR4_H
#define GDB_SOLIB_SVR4_H
+#include "gdbarch.h"
#include "solib.h"
struct objfile;
-struct solib_ops;
-
-extern const solib_ops svr4_so_ops;
+struct link_map_offsets;
+struct probe_and_action;
+struct svr4_info;
+struct svr4_library_list;
+struct svr4_so;
/* Link map info to include in an allocated solib entry. */
@@ -50,6 +53,101 @@ struct lm_info_svr4 final : public lm_info
using lm_info_svr4_up = std::unique_ptr<lm_info_svr4>;
+/* What to do when a probe stop occurs. */
+
+enum probe_action
+{
+ /* Something went seriously wrong. Stop using probes and
+ revert to using the older interface. */
+ PROBES_INTERFACE_FAILED,
+
+ /* No action is required. The shared object list is still
+ valid. */
+ DO_NOTHING,
+
+ /* The shared object list should be reloaded entirely. */
+ FULL_RELOAD,
+
+ /* Attempt to incrementally update the shared object list. If
+ the update fails or is not possible, fall back to reloading
+ the list in full. */
+ UPDATE_OR_RELOAD,
+};
+
+/* solib_ops for SVR4 systems. */
+
+struct svr4_solib_ops : public solib_ops
+{
+ void relocate_section_addresses (solib &so, target_section *) const override;
+ void clear_so (const solib &so) const override;
+ void clear_solib (program_space *pspace) override;
+ void create_inferior_hook (int from_tty) override;
+ owning_intrusive_list<solib> current_sos () override;
+ bool open_symbol_file_object (int from_tty) override;
+ bool in_dynsym_resolve_code (CORE_ADDR pc) const override;
+ bool same (const solib &gdb, const solib &inferior) const override;
+ bool keep_data_in_core (CORE_ADDR vaddr, unsigned long size) override;
+ void update_breakpoints () const override;
+ void handle_event () override;
+ std::optional<CORE_ADDR> find_solib_addr (solib &so) const override;
+ bool supports_namespaces () const override { return true; }
+ int find_solib_ns (const solib &so) const override;
+ int num_active_namespaces () const override;
+ std::vector<const solib *> get_solibs_in_ns (int nsid) const override;
+
+ /* Return the appropriate link map offsets table for the architecture. */
+ virtual link_map_offsets *fetch_link_map_offsets () const = 0;
+
+ /* This needs to be public because it's accessed from an observer. */
+ void current_sos_direct (svr4_info *info) const;
+
+private:
+ void create_probe_breakpoints (svr4_info *info, gdbarch *gdbarch,
+ const std::vector<probe *> *probes,
+ objfile *objfile) const;
+ bool find_and_create_probe_breakpoints (svr4_info *info, gdbarch *gdbarch,
+ obj_section *os,
+ bool with_prefix) const;
+ void create_event_breakpoints (svr4_info *info, gdbarch *gdbarch,
+ CORE_ADDR address) const;
+ int enable_break (svr4_info *info, int from_tty) const;
+ bool is_default_namespace (CORE_ADDR debug_base) const;
+ void free_probes_table (svr4_info *info) const;
+ CORE_ADDR find_r_brk (svr4_info *info) const;
+ CORE_ADDR find_r_ldsomap (svr4_info *info) const;
+ owning_intrusive_list<solib> default_sos (svr4_info *info);
+ int read_so_list (svr4_info *info, CORE_ADDR lm, CORE_ADDR prev_lm,
+ std::vector<svr4_so> &sos, int ignore_first) const;
+ lm_info_svr4_up read_lm_info (CORE_ADDR lm_addr) const;
+ int has_lm_dynamic_from_link_map () const;
+ CORE_ADDR lm_addr_check (const solib &so, bfd *abfd) const;
+ CORE_ADDR read_r_next (CORE_ADDR debug_base) const;
+ CORE_ADDR read_r_map (CORE_ADDR debug_base) const;
+ int parse_libraries (const char *document, svr4_library_list *list);
+ int current_sos_via_xfer_libraries (svr4_library_list *list,
+ const char *annex) const;
+ owning_intrusive_list<solib> collect_probes_sos (svr4_info *info);
+ owning_intrusive_list<solib> current_sos_1 (svr4_info *info);
+ owning_intrusive_list<solib> solibs_from_svr4_sos
+ (const std::vector<svr4_so> &sos);
+ void register_event_probe (objfile *objfile, probe *prob, CORE_ADDR address,
+ enum probe_action action) const;
+ void disable_probes_interface (svr4_info *info) const;
+ probe_and_action *event_probe_at (CORE_ADDR address) const;
+ void update_full (svr4_info *info) const;
+ int update_incremental (svr4_info *info, CORE_ADDR debug_base,
+ CORE_ADDR lm) const;
+ bool update_event_breakpoint (breakpoint *b) const;
+ CORE_ADDR find_debug_base (const solib *solib) const;
+};
+
+/* solib_ops for ILP32 SVR4 systems. */
+
+struct ilp32_svr4_solib_ops : public svr4_solib_ops
+{
+ link_map_offsets *fetch_link_map_offsets () const override;
+};
+
/* Critical offsets and sizes which describe struct r_debug and
struct link_map on SVR4-like targets. All offsets and sizes are
in bytes unless otherwise specified. */
@@ -91,26 +189,22 @@ struct link_map_offsets
int l_name_offset;
};
-/* set_solib_svr4_fetch_link_map_offsets() is intended to be called by
- a <arch>_gdbarch_init() function. It is used to establish an
- architecture specific link_map_offsets fetcher for the architecture
- being defined. */
+/* Set the gdbarch methods for SVR4 systems. */
-extern void set_solib_svr4_fetch_link_map_offsets
- (struct gdbarch *gdbarch, struct link_map_offsets *(*func) (void));
+extern void set_solib_svr4_ops (gdbarch *gdbarch,
+ gdbarch_new_solib_ops_ftype new_solib_ops);
/* This function is called by thread_db.c. Return the address of the
link map for the given objfile. */
extern CORE_ADDR svr4_fetch_objfile_link_map (struct objfile *objfile);
-/* Fetch (and possibly build) an appropriate `struct link_map_offsets'
- for ILP32 and LP64 SVR4 systems. */
-extern struct link_map_offsets *svr4_ilp32_fetch_link_map_offsets (void);
-extern struct link_map_offsets *svr4_lp64_fetch_link_map_offsets (void);
+/* Return a new solib_ops for ILP32 SVR4 systems. */
-/* Return true if PC lies in the dynamic symbol resolution code of the
- SVR4 run time loader. */
-bool svr4_in_dynsym_resolve_code (CORE_ADDR pc);
+extern solib_ops_up new_svr4_ilp32_solib_ops ();
+
+/* Return a new solib_ops for LP64 SVR4 systems. */
+
+extern solib_ops_up new_svr4_lp64_solib_ops ();
/* For the MUSL C library, given link map address LM_ADDR, return the
corresponding TLS module id, or 0 if not found. */
diff --git a/gdb/solib-target.c b/gdb/solib-target.c
index 61b841928ff8..5b26f5be34a8 100644
--- a/gdb/solib-target.c
+++ b/gdb/solib-target.c
@@ -209,6 +209,14 @@ static const struct gdb_xml_element library_list_elements[] = {
{ NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
};
+/* See solib-target.h. */
+
+solib_ops_up
+new_target_solib_ops ()
+{
+ return std::make_unique<target_solib_ops> ();
+}
+
static std::vector<lm_info_target_up>
solib_target_parse_libraries (const char *library)
{
@@ -226,8 +234,8 @@ solib_target_parse_libraries (const char *library)
}
#endif
-static owning_intrusive_list<solib>
-solib_target_current_sos (void)
+owning_intrusive_list<solib>
+target_solib_ops::current_sos ()
{
owning_intrusive_list<solib> sos;
@@ -245,7 +253,7 @@ solib_target_current_sos (void)
/* Build a struct solib for each entry on the list. */
for (lm_info_target_up &info : library_list)
{
- auto &new_solib = sos.emplace_back (solib_target_so_ops);
+ auto &new_solib = sos.emplace_back (*this);
/* We don't need a copy of the name in INFO anymore. */
new_solib.name = std::move (info->name);
@@ -256,8 +264,9 @@ solib_target_current_sos (void)
return sos;
}
-static void
-solib_target_relocate_section_addresses (solib &so, target_section *sec)
+void
+target_solib_ops::relocate_section_addresses (solib &so,
+ target_section *sec) const
{
CORE_ADDR offset;
auto *li = gdb::checked_static_cast<lm_info_target *> (so.lm_info.get ());
@@ -376,28 +385,11 @@ Could not relocate shared library \"%s\": bad offsets"), so.name.c_str ());
sec->endaddr += offset;
}
-static bool
-solib_target_in_dynsym_resolve_code (CORE_ADDR pc)
+bool
+target_solib_ops::in_dynsym_resolve_code (CORE_ADDR pc) const
{
/* We don't have a range of addresses for the dynamic linker; there
may not be one in the program's address space. So only report
PLT entries (which may be import stubs). */
return in_plt_section (pc);
}
-
-const solib_ops solib_target_so_ops =
-{
- solib_target_relocate_section_addresses,
- nullptr,
- nullptr,
- nullptr,
- solib_target_current_sos,
- nullptr,
- solib_target_in_dynsym_resolve_code,
- solib_bfd_open,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- default_find_solib_addr,
-};
diff --git a/gdb/solib-target.h b/gdb/solib-target.h
index f8a22fd6f6ad..8a5f8432345b 100644
--- a/gdb/solib-target.h
+++ b/gdb/solib-target.h
@@ -20,7 +20,19 @@
#ifndef GDB_SOLIB_TARGET_H
#define GDB_SOLIB_TARGET_H
-struct solib_ops;
-extern const solib_ops solib_target_so_ops;
+#include "solib.h"
+
+/* solib_ops for systems fetching solibs from the target. */
+
+struct target_solib_ops : solib_ops
+{
+ void relocate_section_addresses (solib &so, target_section *) const override;
+ owning_intrusive_list<solib> current_sos () override;
+ bool in_dynsym_resolve_code (CORE_ADDR pc) const override;
+};
+
+/* Return a new solib_ops for systems fetching solibs from the target. */
+
+solib_ops_up new_target_solib_ops ();
#endif /* GDB_SOLIB_TARGET_H */
diff --git a/gdb/solib.c b/gdb/solib.c
index 675f64e2ae51..bea0534cb502 100644
--- a/gdb/solib.c
+++ b/gdb/solib.c
@@ -467,6 +467,12 @@ solib_bfd_open (const char *pathname)
return abfd;
}
+gdb_bfd_ref_ptr
+solib_ops::bfd_open (const char *pathname)
+{
+ return solib_bfd_open (pathname);
+}
+
/* Given a pointer to one of the shared objects in our list of mapped
objects, use the recorded name to open a bfd descriptor for the
object, build a section table, relocate all the section addresses
@@ -598,8 +604,7 @@ solib::clear ()
this->name = this->original_name;
/* Do the same for target-specific data. */
- if (this->ops ().clear_so != NULL)
- this->ops ().clear_so (*this);
+ this->ops ().clear_so (*this);
}
lm_info::~lm_info () = default;
@@ -707,7 +712,7 @@ notify_solib_unloaded (program_space *pspace, const solib &so,
void
update_solib_list (int from_tty)
{
- const solib_ops *ops = current_program_space->solib_ops ();
+ solib_ops *ops = current_program_space->solib_ops ();
if (ops == nullptr)
return;
@@ -722,8 +727,7 @@ update_solib_list (int from_tty)
have not opened a symbol file, we may be able to get its
symbols now! */
if (inf->attach_flag
- && current_program_space->symfile_object_file == nullptr
- && ops->open_symbol_file_object != nullptr)
+ && current_program_space->symfile_object_file == nullptr)
{
try
{
@@ -772,19 +776,8 @@ update_solib_list (int from_tty)
/* Check to see whether the shared object *gdb also appears in
the inferior's current list. */
for (; inferior_iter != inferior.end (); ++inferior_iter)
- {
- if (ops->same)
- {
- if (ops->same (*gdb_iter, *inferior_iter))
- break;
- }
- else
- {
- if (!filename_cmp (gdb_iter->original_name.c_str (),
- inferior_iter->original_name.c_str ()))
- break;
- }
- }
+ if (ops->same (*gdb_iter, *inferior_iter))
+ break;
/* If the shared object appears on the inferior's list too, then
it's still loaded, so we don't need to do anything. Delete
@@ -1037,7 +1030,7 @@ print_solib_list_table (std::vector<const solib *> solib_list,
active namespace. Fold all these into the PRINT_NAMESPACE condition. */
print_namespace = (print_namespace
&& ops != nullptr
- && ops->num_active_namespaces != nullptr
+ && ops->supports_namespaces ()
&& ops->num_active_namespaces () > 1);
int num_cols = 4;
@@ -1167,7 +1160,7 @@ info_linker_namespace_command (const char *pattern, int from_tty)
/* This command only really makes sense for inferiors that support
linker namespaces, so we can leave early. */
- if (ops == nullptr || ops->num_active_namespaces == nullptr)
+ if (ops == nullptr || !ops->supports_namespaces ())
error (_("Current inferior does not support linker namespaces. " \
"Use \"info sharedlibrary\" instead."));
@@ -1277,17 +1270,21 @@ solib_name_from_address (struct program_space *pspace, CORE_ADDR address)
return nullptr;
}
+bool
+solib_ops::same (const solib &a, const solib &b) const
+{
+ return (filename_cmp (a.original_name.c_str (), b.original_name.c_str ())
+ == 0);
+}
+
/* See solib.h. */
bool
solib_keep_data_in_core (CORE_ADDR vaddr, unsigned long size)
{
- const solib_ops *ops = current_program_space->solib_ops ();
+ solib_ops *ops = current_program_space->solib_ops ();
- if (ops != nullptr && ops->keep_data_in_core != nullptr)
- return ops->keep_data_in_core (vaddr, size) != 0;
- else
- return false;
+ return ops != nullptr && ops->keep_data_in_core (vaddr, size);
}
/* See solib.h. */
@@ -1306,9 +1303,8 @@ clear_solib (program_space *pspace)
pspace->solibs ().clear ();
- const solib_ops *ops = pspace->solib_ops ();
-
- if (ops != nullptr && ops->clear_solib != nullptr)
+ if (solib_ops *ops = pspace->solib_ops ();
+ ops != nullptr)
ops->clear_solib (pspace);
}
@@ -1320,10 +1316,9 @@ clear_solib (program_space *pspace)
void
solib_create_inferior_hook (int from_tty)
{
- const solib_ops *ops = current_program_space->solib_ops ();
-
- if (ops != nullptr && ops->solib_create_inferior_hook != nullptr)
- ops->solib_create_inferior_hook (from_tty);
+ if (solib_ops *ops = current_program_space->solib_ops ();
+ ops != nullptr)
+ ops->create_inferior_hook (from_tty);
}
/* See solib.h. */
@@ -1333,8 +1328,7 @@ in_solib_dynsym_resolve_code (CORE_ADDR pc)
{
const solib_ops *ops = current_program_space->solib_ops ();
- return (ops != nullptr && ops->in_dynsym_resolve_code != nullptr
- && ops->in_dynsym_resolve_code (pc));
+ return ops != nullptr && ops->in_dynsym_resolve_code (pc);
}
/* Implements the "sharedlibrary" command. */
@@ -1378,7 +1372,7 @@ update_solib_breakpoints (void)
{
const solib_ops *ops = current_program_space->solib_ops ();
- if (ops != nullptr && ops->update_breakpoints != nullptr)
+ if (ops != nullptr)
ops->update_breakpoints ();
}
@@ -1387,9 +1381,8 @@ update_solib_breakpoints (void)
void
handle_solib_event (void)
{
- const solib_ops *ops = current_program_space->solib_ops ();
-
- if (ops != nullptr && ops->handle_event != nullptr)
+ if (solib_ops *ops = current_program_space->solib_ops ();
+ ops != nullptr)
ops->handle_event ();
current_inferior ()->pspace->clear_solib_cache ();
@@ -1422,7 +1415,8 @@ reload_shared_libraries_1 (int from_tty)
gdb::unique_xmalloc_ptr<char> filename (
tilde_expand (so.original_name.c_str ()));
- gdb_bfd_ref_ptr abfd (solib_bfd_open (filename.get ()));
+
+ gdb_bfd_ref_ptr abfd = so.ops ().bfd_open (filename.get ());
if (abfd != NULL)
found_pathname = bfd_get_filename (abfd.get ());
@@ -1484,11 +1478,10 @@ reload_shared_libraries (const char *ignored, int from_tty,
about ld.so. */
if (target_has_execution ())
{
- const solib_ops *ops = current_program_space->solib_ops ();
-
/* Reset or free private data structures not associated with
solib entries. */
- if (ops != nullptr && ops->clear_solib != nullptr)
+ if (solib_ops *ops = current_program_space->solib_ops ();
+ ops != nullptr)
ops->clear_solib (current_program_space);
/* Remove any previous solib event breakpoint. This is usually
@@ -1815,15 +1808,8 @@ remove_user_added_objfile (struct objfile *objfile)
}
}
-/* See solist.h. */
-
-std::optional<CORE_ADDR>
-default_find_solib_addr (solib &so)
-{
- return {};
-}
-
/* Implementation of the linker_namespace convenience variable.
+
This returns the GDB internal identifier of the linker namespace,
for the selected frame, as an integer. If the inferior doesn't support
linker namespaces, this always returns 0. */
@@ -1838,7 +1824,7 @@ linker_namespace_make_value (gdbarch *gdbarch, internalvar *var,
for (const solib &so : current_program_space->solibs ())
if (solib_contains_address_p (so, curr_pc))
{
- if (so.ops ().find_solib_ns != nullptr)
+ if (so.ops ().supports_namespaces ())
nsid = so.ops ().find_solib_ns (so);
break;
diff --git a/gdb/solib.h b/gdb/solib.h
index 09d56c08b953..a3104e47e40e 100644
--- a/gdb/solib.h
+++ b/gdb/solib.h
@@ -61,10 +61,10 @@ struct solib : intrusive_list_node<solib>
/* Constructor
OPS is the solib_ops implementation providing this solib. */
- explicit solib (const solib_ops &ops) : m_ops (&ops) {}
+ explicit solib (solib_ops &ops) : m_ops (&ops) {}
/* Return the solib_ops implementation providing this solib. */
- const solib_ops &ops () const
+ solib_ops &ops () const
{ return *m_ops; }
/* Free symbol-file related contents of SO and reset for possible reloading
@@ -125,7 +125,7 @@ struct solib : intrusive_list_node<solib>
private:
/* The solib_ops responsible for this solib. */
- const solib_ops *m_ops;
+ solib_ops *m_ops;
};
/* A unique pointer to an solib. */
@@ -133,22 +133,31 @@ using solib_up = std::unique_ptr<solib>;
struct solib_ops
{
+ virtual ~solib_ops () = default;
+
/* Adjust the section binding addresses by the base address at
which the object was actually mapped. */
- void (*relocate_section_addresses) (solib &so, target_section *);
+ virtual void relocate_section_addresses (solib &so, target_section *) const
+ = 0;
/* Reset private data structures associated with SO.
This is called when SO is about to be reloaded.
- It is also called when SO is about to be freed. */
- void (*clear_so) (const solib &so);
+ It is also called when SO is about to be freed.
+
+ Defaults to no-op. */
+ virtual void clear_so (const solib &so) const {}
/* Free private data structures associated to PSPACE. This method
should not free resources associated to individual solib entries,
- those are cleared by the clear_so method. */
- void (*clear_solib) (program_space *pspace);
+ those are cleared by the clear_so method.
- /* Target dependent code to run after child process fork. */
- void (*solib_create_inferior_hook) (int from_tty);
+ Defaults to no-op. */
+ virtual void clear_solib (program_space *pspace) {}
+
+ /* Target dependent code to run after child process fork.
+
+ Defaults to no-op. */
+ virtual void create_inferior_hook (int from_tty) {};
/* Construct a list of the currently loaded shared objects. This
list does not include an entry for the main executable file.
@@ -157,45 +166,51 @@ struct solib_ops
inferior --- we don't examine any of the shared library files
themselves. The declaration of `struct solib' says which fields
we provide values for. */
- owning_intrusive_list<solib> (*current_sos) ();
+ virtual owning_intrusive_list<solib> current_sos () = 0;
/* Find, open, and read the symbols for the main executable. If
- FROM_TTY is non-zero, allow messages to be printed. */
- int (*open_symbol_file_object) (int from_ttyp);
+ FROM_TTY is non-zero, allow messages to be printed.
+
+ Return true if this was done successfully. Defaults to false. */
+ virtual bool open_symbol_file_object (int from_tty) { return false; }
/* Determine if PC lies in the dynamic symbol resolution code of
- the run time loader. */
- bool (*in_dynsym_resolve_code) (CORE_ADDR pc);
+ the run time loader.
+
+ Defaults to false. */
+ virtual bool in_dynsym_resolve_code (CORE_ADDR pc) const
+ { return false; };
/* Find and open shared library binary file. */
- gdb_bfd_ref_ptr (*bfd_open) (const char *pathname);
+ virtual gdb_bfd_ref_ptr bfd_open (const char *pathname);
- /* Given two solib objects, one from the GDB thread list
- and another from the list returned by current_sos, return 1
- if they represent the same library.
- Falls back to using strcmp on ORIGINAL_NAME when set to nullptr. */
- int (*same) (const solib &gdb, const solib &inferior);
+ /* Given two solib objects, GDB from the GDB thread list and INFERIOR from the
+ list returned by current_sos, return true if they represent the same library.
+
+ Defaults to comparing the solib original names using filename_cmp. */
+ virtual bool same (const solib &gdb, const solib &inferior) const;
/* Return whether a region of memory must be kept in a core file
for shared libraries loaded before "gcore" is used to be
handled correctly when the core file is loaded. This only
applies when the section would otherwise not be kept in the
- core file (in particular, for readonly sections). */
- int (*keep_data_in_core) (CORE_ADDR vaddr,
- unsigned long size);
+ core file (in particular, for readonly sections).
- /* Enable or disable optional solib event breakpoints as
- appropriate. This should be called whenever
- stop_on_solib_events is changed. This pointer can be
- NULL, in which case no enabling or disabling is necessary
- for this target. */
- void (*update_breakpoints) (void);
+ Defaults to false. */
+ virtual bool keep_data_in_core (CORE_ADDR vaddr, unsigned long size)
+ { return false; };
- /* Target-specific processing of solib events that will be
- performed before solib_add is called. This pointer can be
- NULL, in which case no specific preprocessing is necessary
- for this target. */
- void (*handle_event) (void);
+ /* Enable or disable optional solib event breakpoints as appropriate. This
+ should be called whenever stop_on_solib_events is changed.
+
+ Defaults to no-op. */
+ virtual void update_breakpoints () const {};
+
+ /* Target-specific processing of solib events that will be performed before
+ solib_add is called.
+
+ Defaults to no-op. */
+ virtual void handle_event () {};
/* Return an address within the inferior's address space which is known
to be part of SO. If there is no such address, or GDB doesn't know
@@ -210,28 +225,45 @@ struct solib_ops
mapped file, and thus to a build-id. GDB can then use this
information to help locate the shared library objfile, if the objfile
is not in the expected place (as defined by the shared libraries file
- name). */
- std::optional<CORE_ADDR> (*find_solib_addr) (solib &so);
+ name).
- /* Return which linker namespace contains the current so.
- If the linker or libc does not support linkage namespaces at all
- (which is basically all of them but solib-svr4), this function should
- be set to nullptr, so that "info shared" won't add an unnecessary
- column.
+ The default implementation of returns an empty option, indicating GDB is
+ unable to find an address within the library SO. */
+ virtual std::optional<CORE_ADDR> find_solib_addr (solib &so) const
+ { return {}; };
- If the namespace can not be determined (such as when we're stepping
- though the dynamic linker), this function should throw a
- gdb_exception_error. */
- int (*find_solib_ns) (const solib &so);
+ /* Return true if the linker or libc supports linkage namespaces.
- /* Returns the number of active namespaces in the inferior. */
- int (*num_active_namespaces) ();
+ Defaults to false. */
+ virtual bool supports_namespaces () const { return false; }
+
+ /* Return which linker namespace contains SO.
+
+ The supports_namespaces method must return true for this to be
+ called.
+
+ Throw an error if the namespace can not be determined (such as when we're
+ stepping though the dynamic linker). */
+ virtual int find_solib_ns (const solib &so) const
+ { gdb_assert_not_reached ("namespaces not supported"); }
+
+ /* Returns the number of active namespaces in the inferior.
+
+ The supports_namespaces method must return true for this to be called. */
+ virtual int num_active_namespaces () const
+ { gdb_assert_not_reached ("namespaces not supported"); }
/* Returns all solibs for a given namespace. If the namespace is not
- active, returns an empty vector. */
- std::vector<const solib *> (*get_solibs_in_ns) (int ns);
+ active, returns an empty vector.
+
+ The supports_namespaces method must return true for this to be called. */
+ virtual std::vector<const solib *> get_solibs_in_ns (int ns) const
+ { gdb_assert_not_reached ("namespaces not supported"); }
};
+/* A unique pointer to an solib_ops. */
+using solib_ops_up = std::unique_ptr<solib_ops>;
+
/* Find main executable binary file. */
extern gdb::unique_xmalloc_ptr<char> exec_file_find (const char *in_pathname,
int *fd);
@@ -246,11 +278,6 @@ extern gdb_bfd_ref_ptr solib_bfd_fopen (const char *pathname, int fd);
/* Find solib binary file and open it. */
extern gdb_bfd_ref_ptr solib_bfd_open (const char *in_pathname);
-/* A default implementation of the solib_ops::find_solib_addr callback.
- This just returns an empty std::optional<CORE_ADDR> indicating GDB is
- unable to find an address within the library SO. */
-extern std::optional<CORE_ADDR> default_find_solib_addr (solib &so);
-
/* Called when we free all symtabs of PSPACE, to free the shared library
information as well. */
diff --git a/gdb/sparc-linux-tdep.c b/gdb/sparc-linux-tdep.c
index 27706b72c7ef..06f6e06ecc9b 100644
--- a/gdb/sparc-linux-tdep.c
+++ b/gdb/sparc-linux-tdep.c
@@ -33,6 +33,7 @@
#include "tramp-frame.h"
#include "xml-syscall.h"
#include "linux-tdep.h"
+#include "solib-svr4-linux.h"
/* The syscall's XML filename for sparc 32-bit. */
#define XML_SYSCALL_FILENAME_SPARC32 "syscalls/sparc-linux.xml"
@@ -436,8 +437,7 @@ sparc32_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
/* GNU/Linux has SVR4-style shared libraries... */
set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, linux_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_linux_ilp32_svr4_solib_ops);
/* ...which means that we need some special handling when doing
prologue analysis. */
diff --git a/gdb/sparc-netbsd-tdep.c b/gdb/sparc-netbsd-tdep.c
index 84e3a979c6cd..1e9305440d76 100644
--- a/gdb/sparc-netbsd-tdep.c
+++ b/gdb/sparc-netbsd-tdep.c
@@ -313,8 +313,7 @@ sparc32nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
frame_unwind_append_unwinder (gdbarch, &sparc32nbsd_sigcontext_frame_unwind);
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_svr4_ilp32_solib_ops);
}
void _initialize_sparcnbsd_tdep ();
diff --git a/gdb/sparc-sol2-tdep.c b/gdb/sparc-sol2-tdep.c
index 5c6085acabbf..51d93910630c 100644
--- a/gdb/sparc-sol2-tdep.c
+++ b/gdb/sparc-sol2-tdep.c
@@ -207,8 +207,7 @@ sparc32_sol2_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
/* Solaris has SVR4-style shared libraries... */
set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_svr4_ilp32_solib_ops);
/* ...which means that we need some special handling when doing
prologue analysis. */
diff --git a/gdb/sparc64-fbsd-tdep.c b/gdb/sparc64-fbsd-tdep.c
index 738c3d11c59c..9adbcce01b77 100644
--- a/gdb/sparc64-fbsd-tdep.c
+++ b/gdb/sparc64-fbsd-tdep.c
@@ -238,8 +238,7 @@ sparc64fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
/* FreeBSD/sparc64 has SVR4-style shared libraries. */
set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_lp64_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_svr4_lp64_solib_ops);
}
void _initialize_sparc64fbsd_tdep ();
diff --git a/gdb/sparc64-linux-tdep.c b/gdb/sparc64-linux-tdep.c
index 6e7281c91882..af15175b0795 100644
--- a/gdb/sparc64-linux-tdep.c
+++ b/gdb/sparc64-linux-tdep.c
@@ -32,6 +32,7 @@
#include "tramp-frame.h"
#include "xml-syscall.h"
#include "linux-tdep.h"
+#include "solib-svr4-linux.h"
/* ADI specific si_code */
#ifndef SEGV_ACCADI
@@ -383,8 +384,7 @@ sparc64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
/* GNU/Linux has SVR4-style shared libraries... */
set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, linux_lp64_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_linux_lp64_svr4_solib_ops);
/* ...which means that we need some special handling when doing
prologue analysis. */
diff --git a/gdb/sparc64-netbsd-tdep.c b/gdb/sparc64-netbsd-tdep.c
index 19195987451c..8b3e013be562 100644
--- a/gdb/sparc64-netbsd-tdep.c
+++ b/gdb/sparc64-netbsd-tdep.c
@@ -266,8 +266,7 @@ sparc64nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
/* NetBSD/sparc64 has SVR4-style shared libraries. */
set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_lp64_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_svr4_lp64_solib_ops);
}
void _initialize_sparc64nbsd_tdep ();
diff --git a/gdb/sparc64-obsd-tdep.c b/gdb/sparc64-obsd-tdep.c
index 657f548537e7..cd8f3288995b 100644
--- a/gdb/sparc64-obsd-tdep.c
+++ b/gdb/sparc64-obsd-tdep.c
@@ -440,8 +440,7 @@ sparc64obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
obsd_init_abi (info, gdbarch);
/* OpenBSD/sparc64 has SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_lp64_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_svr4_lp64_solib_ops);
set_gdbarch_skip_solib_resolver (gdbarch, obsd_skip_solib_resolver);
/* OpenBSD provides a user-level threads implementation. */
diff --git a/gdb/sparc64-sol2-tdep.c b/gdb/sparc64-sol2-tdep.c
index 72a07ecef8ce..bb906efd29b4 100644
--- a/gdb/sparc64-sol2-tdep.c
+++ b/gdb/sparc64-sol2-tdep.c
@@ -214,8 +214,7 @@ sparc64_sol2_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
/* Solaris has SVR4-style shared libraries... */
set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_lp64_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_svr4_lp64_solib_ops);
/* ...which means that we need some special handling when doing
prologue analysis. */
diff --git a/gdb/tic6x-linux-tdep.c b/gdb/tic6x-linux-tdep.c
index 280d46dc487b..4dfb6f280bb7 100644
--- a/gdb/tic6x-linux-tdep.c
+++ b/gdb/tic6x-linux-tdep.c
@@ -169,7 +169,7 @@ tic6x_uclinux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
linux_init_abi (info, gdbarch, 0);
/* Shared library handling. */
- set_gdbarch_so_ops (gdbarch, &dsbt_so_ops);
+ set_gdbarch_new_solib_ops (gdbarch, new_dsbt_solib_ops);
tdep->syscall_next_pc = tic6x_linux_syscall_next_pc;
diff --git a/gdb/tilegx-linux-tdep.c b/gdb/tilegx-linux-tdep.c
index a0e69543f88b..92e5d0418b12 100644
--- a/gdb/tilegx-linux-tdep.c
+++ b/gdb/tilegx-linux-tdep.c
@@ -19,6 +19,7 @@
#include "osabi.h"
#include "linux-tdep.h"
+#include "solib-svr4-linux.h"
#include "glibc-tdep.h"
#include "solib-svr4.h"
#include "symtab.h"
@@ -119,11 +120,9 @@ tilegx_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
/* GNU/Linux uses SVR4-style shared libraries. */
if (arch_size == 32)
- set_solib_svr4_fetch_link_map_offsets (gdbarch,
- linux_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_linux_ilp32_svr4_solib_ops);
else
- set_solib_svr4_fetch_link_map_offsets (gdbarch,
- linux_lp64_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_linux_lp64_svr4_solib_ops);
/* Enable TLS support. */
set_gdbarch_fetch_tls_load_module_address (gdbarch,
diff --git a/gdb/vax-netbsd-tdep.c b/gdb/vax-netbsd-tdep.c
index 34a9150fdb27..fabd98218d4b 100644
--- a/gdb/vax-netbsd-tdep.c
+++ b/gdb/vax-netbsd-tdep.c
@@ -32,8 +32,7 @@ vaxnbsd_elf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
nbsd_init_abi (info, gdbarch);
/* NetBSD ELF uses SVR4-style shared libraries. */
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_svr4_ilp32_solib_ops);
}
void _initialize_vaxnbsd_tdep ();
diff --git a/gdb/windows-tdep.c b/gdb/windows-tdep.c
index d8858a7f1450..75437a145d6a 100644
--- a/gdb/windows-tdep.c
+++ b/gdb/windows-tdep.c
@@ -862,10 +862,25 @@ windows_get_siginfo_type (struct gdbarch *gdbarch)
return siginfo_type;
}
+/* solib_ops for Windows systems. */
+
+struct windows_solib_ops : target_solib_ops
+{
+ void create_inferior_hook (int from_tty) override;
+};
+
+/* Return a new solib_ops for Windows systems. */
+
+static solib_ops_up
+new_windows_solib_ops ()
+{
+ return std::make_unique<windows_solib_ops> ();
+}
+
/* Implement the "solib_create_inferior_hook" solib_ops method. */
-static void
-windows_solib_create_inferior_hook (int from_tty)
+void
+windows_solib_ops::create_inferior_hook (int from_tty)
{
CORE_ADDR exec_base = 0;
@@ -910,8 +925,6 @@ windows_solib_create_inferior_hook (int from_tty)
}
}
-static solib_ops windows_so_ops;
-
/* Common parts for gdbarch initialization for the Windows and Cygwin OS
ABIs. */
@@ -928,10 +941,7 @@ windows_init_abi_common (struct gdbarch_info info, struct gdbarch *gdbarch)
set_gdbarch_iterate_over_objfiles_in_search_order
(gdbarch, windows_iterate_over_objfiles_in_search_order);
- windows_so_ops = solib_target_so_ops;
- windows_so_ops.solib_create_inferior_hook
- = windows_solib_create_inferior_hook;
- set_gdbarch_so_ops (gdbarch, &windows_so_ops);
+ set_gdbarch_new_solib_ops (gdbarch, new_windows_solib_ops);
set_gdbarch_get_siginfo_type (gdbarch, windows_get_siginfo_type);
}
diff --git a/gdb/xtensa-linux-tdep.c b/gdb/xtensa-linux-tdep.c
index b72d683b3b40..eaa46cf788ab 100644
--- a/gdb/xtensa-linux-tdep.c
+++ b/gdb/xtensa-linux-tdep.c
@@ -20,6 +20,7 @@
#include "xtensa-tdep.h"
#include "osabi.h"
#include "linux-tdep.h"
+#include "solib-svr4-linux.h"
#include "solib-svr4.h"
#include "symtab.h"
#include "gdbarch.h"
@@ -111,8 +112,7 @@ xtensa_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
linux_init_abi (info, gdbarch, 0);
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, linux_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_linux_ilp32_svr4_solib_ops);
set_gdbarch_gdb_signal_from_target (gdbarch,
xtensa_linux_gdb_signal_from_target);
diff --git a/gdb/xtensa-tdep.c b/gdb/xtensa-tdep.c
index a4bbffb8f114..85a6bee5b6f5 100644
--- a/gdb/xtensa-tdep.c
+++ b/gdb/xtensa-tdep.c
@@ -3238,8 +3238,7 @@ xtensa_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
set_gdbarch_iterate_over_regset_sections
(gdbarch, xtensa_iterate_over_regset_sections);
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+ set_solib_svr4_ops (gdbarch, new_svr4_ilp32_solib_ops);
/* Hook in the ABI-specific overrides, if they have been registered. */
gdbarch_init_osabi (info, gdbarch);
--
2.49.0
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v3 5/6] gdb/progspace: add solib_ops pointer in program_space
2025-06-16 19:33 ` [PATCH v3 5/6] gdb/progspace: add solib_ops pointer in program_space Simon Marchi
@ 2025-06-17 19:45 ` Guinevere Larsen
2025-06-17 20:33 ` Simon Marchi
2025-06-20 18:19 ` Pedro Alves
2025-09-02 14:49 ` Tom de Vries
2 siblings, 1 reply; 28+ messages in thread
From: Guinevere Larsen @ 2025-06-17 19:45 UTC (permalink / raw)
To: Simon Marchi, gdb-patches
On 6/16/25 4:33 PM, Simon Marchi wrote:
> New in v3:
>
> - add some ops nullptr checks in print_solib_list_table and
> info_linker_namespace_command
>
> The subsequent C++ification patch in this series will allocate one
> instance of solib_ops per program space. That instance will be held in
> struct program_space. As a small step towards this, add an `solib_ops
> *` field to `struct program_space`. This field represents the solib_ops
> currently used to manage the solibs in that program space. Initialize
> it with the result of `gdbarch_so_ops` in `post_create_inferior`, and
> use it whenever we need to do some solib stuff, rather than using
> `gdbarch_so_ops` directly.
>
> The difficulty here is knowing when exactly to set and unset the solib
> ops. What I have here passes the testsuite on Linux, but with more
> testing we will probably discover more spots where it's needed.
>
> The C++ification patch will turn this field into a unique pointer.
>
> With this patch, the message we get when running "info
> linker-namespaces" becomes always the same, so update the test in
> gdb.base/dlmopen-ns-ids.exp.
>
> Change-Id: Ide8ddc57328895720fcd645d46dc34491f84c656
Thanks for working on this series! I have one very minor nit in this
patch, but with that fixes, you can feel free to add my review tag
Reviewed-By: Guinevere Larsen <guinevere@redhat.com>
Feel free to add it to patches 1-4 as well, as I looked over them and
they all LGTM. I still don't feel qualified to offer it for patch 6, though.
> ---
> gdb/corelow.c | 2 +-
> gdb/infcmd.c | 15 ++++---
> gdb/inferior.h | 9 +++-
> gdb/infrun.c | 11 ++++-
> gdb/progspace.h | 20 +++++++++
> gdb/solib.c | 55 +++++++++++++----------
> gdb/target.c | 1 +
> gdb/testsuite/gdb.base/dlmopen-ns-ids.exp | 3 +-
> gdb/tracectf.c | 2 +-
> gdb/tracefile-tfile.c | 2 +-
> 10 files changed, 83 insertions(+), 37 deletions(-)
>
<snip>
> diff --git a/gdb/solib.c b/gdb/solib.c
> index d008a72c5a38..675f64e2ae51 100644
> --- a/gdb/solib.c
> +++ b/gdb/solib.c
> @@ -707,7 +707,10 @@ notify_solib_unloaded (program_space *pspace, const solib &so,
> void
> update_solib_list (int from_tty)
> {
> - const solib_ops *ops = gdbarch_so_ops (current_inferior ()->arch ());
> + const solib_ops *ops = current_program_space->solib_ops ();
> +
> + if (ops == nullptr)
> + return;
>
> /* We can reach here due to changing solib-search-path or the
> sysroot, before having any inferior. */
> @@ -1021,16 +1024,21 @@ print_solib_list_table (std::vector<const solib *> solib_list,
> gdbarch *gdbarch = current_inferior ()->arch ();
> /* "0x", a little whitespace, and two hex digits per byte of pointers. */
> int addr_width = 4 + (gdbarch_ptr_bit (gdbarch) / 4);
> - const solib_ops *ops = gdbarch_so_ops (gdbarch);
> + const solib_ops *ops = current_program_space->solib_ops ();
> struct ui_out *uiout = current_uiout;
> bool so_missing_debug_info = false;
>
> + if (ops == nullptr)
> + return;
> +
> /* There are 3 conditions for this command to print solib namespaces,
> first PRINT_NAMESPACE has to be true, second the solib_ops has to
> support multiple namespaces, and third there must be more than one
> active namespace. Fold all these into the PRINT_NAMESPACE condition. */
> - print_namespace = print_namespace && ops->num_active_namespaces != nullptr
> - && ops->num_active_namespaces () > 1;
> + print_namespace = (print_namespace
> + && ops != nullptr
This check is redundant with the previous early exit. The only reason I
bring this up is because the comment brings up "3 conditions" but there
are 4 checks in this expression. The comment isn't wrong, but it does
the code confusing until you figure out that checking if solib_ops is
present isn't one of the conditions.
--
Cheers,
Guinevere Larsen
She/Her/Hers
> + && ops->num_active_namespaces != nullptr
> + && ops->num_active_namespaces () > 1);
>
> int num_cols = 4;
> if (print_namespace)
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v3 5/6] gdb/progspace: add solib_ops pointer in program_space
2025-06-17 19:45 ` Guinevere Larsen
@ 2025-06-17 20:33 ` Simon Marchi
2025-06-18 11:51 ` Guinevere Larsen
0 siblings, 1 reply; 28+ messages in thread
From: Simon Marchi @ 2025-06-17 20:33 UTC (permalink / raw)
To: Guinevere Larsen, Simon Marchi, gdb-patches
On 6/17/25 3:45 PM, Guinevere Larsen wrote:
> On 6/16/25 4:33 PM, Simon Marchi wrote:
>> New in v3:
>>
>> - add some ops nullptr checks in print_solib_list_table and
>> info_linker_namespace_command
>>
>> The subsequent C++ification patch in this series will allocate one
>> instance of solib_ops per program space. That instance will be held in
>> struct program_space. As a small step towards this, add an `solib_ops
>> *` field to `struct program_space`. This field represents the solib_ops
>> currently used to manage the solibs in that program space. Initialize
>> it with the result of `gdbarch_so_ops` in `post_create_inferior`, and
>> use it whenever we need to do some solib stuff, rather than using
>> `gdbarch_so_ops` directly.
>>
>> The difficulty here is knowing when exactly to set and unset the solib
>> ops. What I have here passes the testsuite on Linux, but with more
>> testing we will probably discover more spots where it's needed.
>>
>> The C++ification patch will turn this field into a unique pointer.
>>
>> With this patch, the message we get when running "info
>> linker-namespaces" becomes always the same, so update the test in
>> gdb.base/dlmopen-ns-ids.exp.
>>
>> Change-Id: Ide8ddc57328895720fcd645d46dc34491f84c656
>
> Thanks for working on this series! I have one very minor nit in this patch, but with that fixes, you can feel free to add my review tag
>
> Reviewed-By: Guinevere Larsen <guinevere@redhat.com>
>
> Feel free to add it to patches 1-4 as well, as I looked over them and they all LGTM. I still don't feel qualified to offer it for patch 6, though.
Thank you!
Given your review, I plan to push this series probably tomorrow. You
can start rebasing and adjusting your series on top, and then I can
hopefully review it this week (note that I'm off this Friday, so it
would have to be Thursday max).
>> @@ -1021,16 +1024,21 @@ print_solib_list_table (std::vector<const solib *> solib_list,
>> gdbarch *gdbarch = current_inferior ()->arch ();
>> /* "0x", a little whitespace, and two hex digits per byte of pointers. */
>> int addr_width = 4 + (gdbarch_ptr_bit (gdbarch) / 4);
>> - const solib_ops *ops = gdbarch_so_ops (gdbarch);
>> + const solib_ops *ops = current_program_space->solib_ops ();
>> struct ui_out *uiout = current_uiout;
>> bool so_missing_debug_info = false;
>> + if (ops == nullptr)
>> + return;
>> +
>> /* There are 3 conditions for this command to print solib namespaces,
>> first PRINT_NAMESPACE has to be true, second the solib_ops has to
>> support multiple namespaces, and third there must be more than one
>> active namespace. Fold all these into the PRINT_NAMESPACE condition. */
>> - print_namespace = print_namespace && ops->num_active_namespaces != nullptr
>> - && ops->num_active_namespaces () > 1;
>> + print_namespace = (print_namespace
>> + && ops != nullptr
>
> This check is redundant with the previous early exit. The only reason
> I bring this up is because the comment brings up "3 conditions" but
> there are 4 checks in this expression. The comment isn't wrong, but it
> does the code confusing until you figure out that checking if
> solib_ops is present isn't one of the conditions.
You're right, it's redundant, I'll fix it. Note to self: returning
early means that the table will not be output at all. Check if
returning early is a problem for e.g. MI, when the inferior is not
running.
Simon
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v3 5/6] gdb/progspace: add solib_ops pointer in program_space
2025-06-17 20:33 ` Simon Marchi
@ 2025-06-18 11:51 ` Guinevere Larsen
2025-06-18 14:43 ` Simon Marchi
0 siblings, 1 reply; 28+ messages in thread
From: Guinevere Larsen @ 2025-06-18 11:51 UTC (permalink / raw)
To: Simon Marchi, Simon Marchi, gdb-patches
[-- Attachment #1: Type: text/plain, Size: 931 bytes --]
On 6/17/25 5:33 PM, Simon Marchi wrote:
>> Thanks for working on this series! I have one very minor nit in this patch, but with that fixes, you can feel free to add my review tag
>>
>> Reviewed-By: Guinevere Larsen<guinevere@redhat.com>
>>
>> Feel free to add it to patches 1-4 as well, as I looked over them and they all LGTM. I still don't feel qualified to offer it for patch 6, though.
> Thank you!
>
> Given your review, I plan to push this series probably tomorrow. You
> can start rebasing and adjusting your series on top, and then I can
> hopefully review it this week (note that I'm off this Friday, so it
> would have to be Thursday max).
I'll rebase and try to get it ready to send to the list by tomorrow, but
I'll also go on vacation starting friday and only return July 7th, so if
that series gets approved before GDB 17 branches, I'll need someone to
push it for me.
--
Cheers,
Guinevere Larsen
She/Her/Hers
[-- Attachment #2: Type: text/html, Size: 1591 bytes --]
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v3 5/6] gdb/progspace: add solib_ops pointer in program_space
2025-06-18 11:51 ` Guinevere Larsen
@ 2025-06-18 14:43 ` Simon Marchi
2025-06-18 15:01 ` Guinevere Larsen
0 siblings, 1 reply; 28+ messages in thread
From: Simon Marchi @ 2025-06-18 14:43 UTC (permalink / raw)
To: Guinevere Larsen, Simon Marchi, gdb-patches
On 6/18/25 7:51 AM, Guinevere Larsen wrote:
> On 6/17/25 5:33 PM, Simon Marchi wrote:
>>> Thanks for working on this series! I have one very minor nit in this patch, but with that fixes, you can feel free to add my review tag
>>>
>>> Reviewed-By: Guinevere Larsen <guinevere@redhat.com>
>>>
>>> Feel free to add it to patches 1-4 as well, as I looked over them and they all LGTM. I still don't feel qualified to offer it for patch 6, though.
>> Thank you!
>>
>> Given your review, I plan to push this series probably tomorrow. You
>> can start rebasing and adjusting your series on top, and then I can
>> hopefully review it this week (note that I'm off this Friday, so it
>> would have to be Thursday max).
>
> I'll rebase and try to get it ready to send to the list by tomorrow, but I'll also go on vacation starting friday and only return July 7th, so if that series gets approved before GDB 17 branches, I'll need someone to push it for me.
Actually, which patches of my series would be useful to you? Would it
be sufficient to merge patches 1 to 3, or 1 to 4? I think they are
relatively low-risk, compared to the last two. It feels safer to merge
the last two just after the GDB 17 branching, so that they have more
time to get tested in master.
Simon
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v3 5/6] gdb/progspace: add solib_ops pointer in program_space
2025-06-18 14:43 ` Simon Marchi
@ 2025-06-18 15:01 ` Guinevere Larsen
0 siblings, 0 replies; 28+ messages in thread
From: Guinevere Larsen @ 2025-06-18 15:01 UTC (permalink / raw)
To: Simon Marchi, Simon Marchi, gdb-patches
On 6/18/25 11:43 AM, Simon Marchi wrote:
> On 6/18/25 7:51 AM, Guinevere Larsen wrote:
>> On 6/17/25 5:33 PM, Simon Marchi wrote:
>>>> Thanks for working on this series! I have one very minor nit in this patch, but with that fixes, you can feel free to add my review tag
>>>>
>>>> Reviewed-By: Guinevere Larsen <guinevere@redhat.com>
>>>>
>>>> Feel free to add it to patches 1-4 as well, as I looked over them and they all LGTM. I still don't feel qualified to offer it for patch 6, though.
>>> Thank you!
>>>
>>> Given your review, I plan to push this series probably tomorrow. You
>>> can start rebasing and adjusting your series on top, and then I can
>>> hopefully review it this week (note that I'm off this Friday, so it
>>> would have to be Thursday max).
>> I'll rebase and try to get it ready to send to the list by tomorrow, but I'll also go on vacation starting friday and only return July 7th, so if that series gets approved before GDB 17 branches, I'll need someone to push it for me.
> Actually, which patches of my series would be useful to you? Would it
> be sufficient to merge patches 1 to 3, or 1 to 4? I think they are
> relatively low-risk, compared to the last two. It feels safer to merge
> the last two just after the GDB 17 branching, so that they have more
> time to get tested in master.
>
> Simon
>
Unfortunately, I need patch 5, there's no way around it.
Missing the branch point won't be the end of the world, it would just be
good feature to send with all the other linker namespaces improvements
GDB 17 will have. But there are other things planned for GDB 18, so it's
not like it'll be the only thing missing.
--
Cheers,
Guinevere Larsen
She/Her/Hers
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v3 1/6] gdb/testsuite: check that "info shared" and "info linker-namespaces" before running don't crash
2025-06-16 19:32 [PATCH v3 1/6] gdb/testsuite: check that "info shared" and "info linker-namespaces" before running don't crash Simon Marchi
` (4 preceding siblings ...)
2025-06-16 19:33 ` [PATCH v3 6/6] gdb/solib: C++ify solib_ops Simon Marchi
@ 2025-06-20 18:12 ` Pedro Alves
2025-06-26 17:30 ` Simon Marchi
5 siblings, 1 reply; 28+ messages in thread
From: Pedro Alves @ 2025-06-20 18:12 UTC (permalink / raw)
To: Simon Marchi, gdb-patches
On 2025-06-16 20:32, Simon Marchi wrote:
> This patch is new in v3.
>
> While writing my solib_ops C++ification series, I broke this, and it
> didn't seem to be caught by the testsuite. Add a test for those.
>
> The exact message for "info linker-namespaces" varies depending on the
> solib_ops of the target architecture (whether ops->num_active_namespaces
> is nullptr or not). For now, just accept any message (a crash will
> still be caught). A later patch in this series will make the message
> consistent and update this test.
>
> Change-Id: I6bce2ff317447bbf321fc9cbd2d42c3dcea0c683
> ---
> gdb/testsuite/gdb.base/dlmopen-ns-ids.exp | 5 +++++
> gdb/testsuite/gdb.base/info-shared.exp | 3 +++
> 2 files changed, 8 insertions(+)
>
> diff --git a/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp b/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp
> index 94b4a6e50bcf..8613056a7c8b 100644
> --- a/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp
> +++ b/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp
> @@ -169,6 +169,11 @@ proc_with_prefix test_conv_vars {} {
> proc test_info_linker_namespaces {} {
> clean_restart $::binfile
>
> + # Check that "info linker-namespaces" while the inferior is not running
> + # doesn't crash.
> + gdb_test "info linker-namespaces" ".*" \
You can write "" instead of ".*". It'd be the same, a leading ".*" is already implied.
Otherwise LGTM.
Approved-By: Pedro Alves <pedro@palves.net>
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v3 2/6] gdb/solib: fix formatting of "info linker-namespaces" error message
2025-06-16 19:33 ` [PATCH v3 2/6] gdb/solib: fix formatting of "info linker-namespaces" error message Simon Marchi
@ 2025-06-20 18:12 ` Pedro Alves
2025-06-26 17:35 ` Simon Marchi
0 siblings, 1 reply; 28+ messages in thread
From: Pedro Alves @ 2025-06-20 18:12 UTC (permalink / raw)
To: Simon Marchi, gdb-patches
On 2025-06-16 20:33, Simon Marchi wrote:
> This patch is new in v3.
>
> Add spaces after the first period and add a period at the end, resulting
> in:
>
> (gdb) info linker-namespaces
> ❌️ Current inferior does not support linker namespaces. Use "info sharedlibrary" instead.
>
> Change-Id: Ib3f1647cedcdb68852a3c63df26ea3e6f791b1b1
> ---
> gdb/solib.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/gdb/solib.c b/gdb/solib.c
> index 7721fd673ae3..90e7b906222c 100644
> --- a/gdb/solib.c
> +++ b/gdb/solib.c
> @@ -1163,8 +1163,8 @@ info_linker_namespace_command (const char *pattern, int from_tty)
> /* This command only really makes sense for inferiors that support
> linker namespaces, so we can leave early. */
> if (ops->num_active_namespaces == nullptr)
> - error (_("Current inferior does not support linker namespaces." \
> - "Use \"info sharedlibrary\" instead"));
> + error (_("Current inferior does not support linker namespaces. " \
> + "Use \"info sharedlibrary\" instead."));
>
You could remove the useless continuation backslash too, while at it.
Approved-By: Pedro Alves <pedro@palves.net>
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v3 3/6] gdb/solib: add solib -> solib_ops backlink
2025-06-16 19:33 ` [PATCH v3 3/6] gdb/solib: add solib -> solib_ops backlink Simon Marchi
@ 2025-06-20 18:17 ` Pedro Alves
0 siblings, 0 replies; 28+ messages in thread
From: Pedro Alves @ 2025-06-20 18:17 UTC (permalink / raw)
To: Simon Marchi, gdb-patches
On 2025-06-16 20:33, Simon Marchi wrote:
> The subsequent C++ification commit makes it so that one struct solib_ops
> is instantiated for each program space. For some operations, it will
> then become necessary to be able to get the right solib_ops instance
> from a given solib. Add an solib -> solib_ops backlink for that.
>
> Change-Id: Ib95407b3fa5fcfba55cf874e0e9dcd2d43a402e4
Approved-By: Pedro Alves <pedro@palves.net>
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v3 4/6] gdb/solib: use solib::ops for operations that concern a single solib
2025-06-16 19:33 ` [PATCH v3 4/6] gdb/solib: use solib::ops for operations that concern a single solib Simon Marchi
@ 2025-06-20 18:17 ` Pedro Alves
0 siblings, 0 replies; 28+ messages in thread
From: Pedro Alves @ 2025-06-20 18:17 UTC (permalink / raw)
To: Simon Marchi, gdb-patches
On 2025-06-16 20:33, Simon Marchi wrote:
> For operations that concern a single solib, use the solib_ops backlink
> added in the previous patch (solib::ops), instead of using the solib_ops
> from the gdbarch. This is a small / easy step towards not using
> gdbarch_so_ops, which is necessary for the C++ification patch later in
> this series.
>
> There is no change in behavior expected.
>
Approved-By: Pedro Alves <pedro@palves.net>
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v3 5/6] gdb/progspace: add solib_ops pointer in program_space
2025-06-16 19:33 ` [PATCH v3 5/6] gdb/progspace: add solib_ops pointer in program_space Simon Marchi
2025-06-17 19:45 ` Guinevere Larsen
@ 2025-06-20 18:19 ` Pedro Alves
2025-06-26 17:37 ` Simon Marchi
2025-09-02 14:49 ` Tom de Vries
2 siblings, 1 reply; 28+ messages in thread
From: Pedro Alves @ 2025-06-20 18:19 UTC (permalink / raw)
To: Simon Marchi, gdb-patches
On 2025-06-16 20:33, Simon Marchi wrote:
> New in v3:
>
> - add some ops nullptr checks in print_solib_list_table and
> info_linker_namespace_command
>
> The subsequent C++ification patch in this series will allocate one
> instance of solib_ops per program space. That instance will be held in
> struct program_space. As a small step towards this, add an `solib_ops
> *` field to `struct program_space`. This field represents the solib_ops
> currently used to manage the solibs in that program space. Initialize
> it with the result of `gdbarch_so_ops` in `post_create_inferior`, and
> use it whenever we need to do some solib stuff, rather than using
> `gdbarch_so_ops` directly.
>
> The difficulty here is knowing when exactly to set and unset the solib
> ops. What I have here passes the testsuite on Linux, but with more
> testing we will probably discover more spots where it's needed.
One important detail is keeping the solibs listed after the inferior exits.
This is so the user can set breakpoints in shared library symbols for the
next re-run.
Your patches preserve that, which is good. I don't recall off hand if there's
a testcase ensure it.
Tiny nit below. Other than that:
Approved-By: Pedro Alves <pedro@palves.net>
> diff --git a/gdb/progspace.h b/gdb/progspace.h
> index 5e5d5edd9b4b..abb448195d74 100644
> --- a/gdb/progspace.h
> +++ b/gdb/progspace.h
> @@ -231,6 +231,23 @@ struct program_space
> is outside all objfiles in this progspace. */
> struct objfile *objfile_for_address (CORE_ADDR address);
>
> + /* Set this program space's solib provider.
> +
> + The solib provider must be unset prior to call this method. */
"prior to call" -> prior to calling"
> + void set_solib_ops (const struct solib_ops &ops)
> + {
> + gdb_assert (m_solib_ops == nullptr);
> + m_solib_ops = &ops;
> + };
> +
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v3 6/6] gdb/solib: C++ify solib_ops
2025-06-16 19:33 ` [PATCH v3 6/6] gdb/solib: C++ify solib_ops Simon Marchi
@ 2025-06-20 18:20 ` Pedro Alves
2025-06-26 18:04 ` Simon Marchi
0 siblings, 1 reply; 28+ messages in thread
From: Pedro Alves @ 2025-06-20 18:20 UTC (permalink / raw)
To: Simon Marchi, gdb-patches
Hi!
On 2025-06-16 20:33, Simon Marchi wrote:
> Convert solib_ops into an abstract base class (with abstract methods,
> some of them with default implementations) and convert all the existing
> solib_ops instances to solib_ops derived classes / implementations.
Thanks a lot for doing this.
Some small nits below. Other than that:
Approved-By: Pedro Alves <pedro@palves.net>
>
> Prior to this patch, solib_ops is a structure holding function pointers,
> of which there are only a handful of global instances (in the
> `solib-*.c` files). When passing an `solib_ops *` around, it's a
> pointer to one of these instances. After this patch, there are no more
> global solib_ops instances. Instances are created as needed and stored
> in struct program_space. These instances could eventually be made to
> contain the program space-specific data, which is currently kept in
> per-program space registries (I have some pending patches for that).
>
> Prior to this patch, `gdbarch_so_ops` is a gdbarch method that returns a
> pointer to the appropriate solib_ops implementation for the gdbarch.
> This is replaced with the `gdbarch_new_solib_ops` method, which returns
> a new instance of the appropriate solib_ops implementation for this
> gdbarch. This requires introducing some factory functions for the
> various solib_ops implementation, to be used as `gdbarch_new_solib_ops`
> callbacks. For instance:
>
> solib_ops_up
> new_linux_ilp32_svr4_solib_ops ()
> {
> return std::make_unique<linux_ilp32_svr4_solib_ops> ();
> }
>
(Annoying) nit: I'd say that factory functions that return a non-raw pointer are more
typically named make_foo, like std::make_unique. new_foo suggests that they would return a
raw pointer, like operator new.
> There is a little "base class template" hack in mips-linux-tdep.c,
> because both mips_linux_ilp32_svr4_solib_ops and
> mips_linux_lp64_svr4_solib_ops need to derive from different SVR4 base
> classes (linux_ilp32_svr4_solib_ops and linux_lp64_svr4_solib_ops), but
> they both want to override the in_dynsym_resolve_code method with the
> same implementation. Let me know if there's a more straightforward way
> to do this.
I don't know why would call this a hack. This is a CRTP mixin, a standard
technique, that we use in other places in GDB, for the same reason. I think
you should just say that instead.
We should be able to simplify such code a bit with C++23, with the new
explicit object parameter syntax.
>
> The solib_ops::supports_namespaces method is new: the support for
> namespaces was previously predicated by the presence or absence of a
> find_solib_ns method. It now needs to be explicit.
>
> There is a new progspace::release_solib_ops method, which is only needed
> for rocm_solib_ops. For the moment, rocm_solib_ops replaces and wraps
> the existing svr4_solib_ops instance, in order to combine the results of
> the two. The plan is to have a subsequent patch to allow program spaces to have
> multiple solib_ops, removing the need that release_solib_ops.
Some word missing in "need that release_solib_ops". I guess "for".
>
> Speaking of rocm_solib_ops: it previously overrode only a few methods by
> copying svr4_solib_ops and overwriting some function pointers. Now, it
> needs to implement all the methods that svr4_solib_ops implements, in
> order to forward the call. Otherwise, the default solib_ops method woul
woul -> would
> --- a/gdb/progspace.h
> +++ b/gdb/progspace.h
> @@ -21,6 +21,7 @@
> #ifndef GDB_PROGSPACE_H
> #define GDB_PROGSPACE_H
>
> +#include "solib.h"
> #include "target.h"
> #include "gdb_bfd.h"
> #include "registry.h"
> @@ -234,19 +235,23 @@ struct program_space
> /* Set this program space's solib provider.
>
> The solib provider must be unset prior to call this method. */
> - void set_solib_ops (const struct solib_ops &ops)
> + void set_solib_ops (solib_ops_up ops)
> {
> gdb_assert (m_solib_ops == nullptr);
> - m_solib_ops = &ops;
> + m_solib_ops = std::move (ops);
> };
>
> - /* Unset this program space's solib provider. */
> + /* Unset and free this program space's solib provider. */
> void unset_solib_ops ()
> { m_solib_ops = nullptr; }
>
> + /* Unset and return this program space's solib provider. */
> + solib_ops_up release_solib_ops ()
> + { return std::move (m_solib_ops); }
> +
> /* Get this program space's solib provider. */
> - const struct solib_ops *solib_ops () const
> - { return m_solib_ops; }
> + struct solib_ops *solib_ops () const
> + { return m_solib_ops.get (); }
Curious that const dropped here and other places. Was const previously
just wrong?
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v3 1/6] gdb/testsuite: check that "info shared" and "info linker-namespaces" before running don't crash
2025-06-20 18:12 ` [PATCH v3 1/6] gdb/testsuite: check that "info shared" and "info linker-namespaces" before running don't crash Pedro Alves
@ 2025-06-26 17:30 ` Simon Marchi
0 siblings, 0 replies; 28+ messages in thread
From: Simon Marchi @ 2025-06-26 17:30 UTC (permalink / raw)
To: Pedro Alves, Simon Marchi, gdb-patches
On 2025-06-20 14:12, Pedro Alves wrote:
> On 2025-06-16 20:32, Simon Marchi wrote:
>> This patch is new in v3.
>>
>> While writing my solib_ops C++ification series, I broke this, and it
>> didn't seem to be caught by the testsuite. Add a test for those.
>>
>> The exact message for "info linker-namespaces" varies depending on the
>> solib_ops of the target architecture (whether ops->num_active_namespaces
>> is nullptr or not). For now, just accept any message (a crash will
>> still be caught). A later patch in this series will make the message
>> consistent and update this test.
>>
>> Change-Id: I6bce2ff317447bbf321fc9cbd2d42c3dcea0c683
>> ---
>> gdb/testsuite/gdb.base/dlmopen-ns-ids.exp | 5 +++++
>> gdb/testsuite/gdb.base/info-shared.exp | 3 +++
>> 2 files changed, 8 insertions(+)
>>
>> diff --git a/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp b/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp
>> index 94b4a6e50bcf..8613056a7c8b 100644
>> --- a/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp
>> +++ b/gdb/testsuite/gdb.base/dlmopen-ns-ids.exp
>> @@ -169,6 +169,11 @@ proc_with_prefix test_conv_vars {} {
>> proc test_info_linker_namespaces {} {
>> clean_restart $::binfile
>>
>> + # Check that "info linker-namespaces" while the inferior is not running
>> + # doesn't crash.
>> + gdb_test "info linker-namespaces" ".*" \
>
> You can write "" instead of ".*". It'd be the same, a leading ".*" is already implied.
Thanks, fixed.
Simon
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v3 2/6] gdb/solib: fix formatting of "info linker-namespaces" error message
2025-06-20 18:12 ` Pedro Alves
@ 2025-06-26 17:35 ` Simon Marchi
0 siblings, 0 replies; 28+ messages in thread
From: Simon Marchi @ 2025-06-26 17:35 UTC (permalink / raw)
To: Pedro Alves, Simon Marchi, gdb-patches
On 2025-06-20 14:12, Pedro Alves wrote:
> On 2025-06-16 20:33, Simon Marchi wrote:
>> This patch is new in v3.
>>
>> Add spaces after the first period and add a period at the end, resulting
>> in:
>>
>> (gdb) info linker-namespaces
>> ❌️ Current inferior does not support linker namespaces. Use "info sharedlibrary" instead.
>>
>> Change-Id: Ib3f1647cedcdb68852a3c63df26ea3e6f791b1b1
>> ---
>> gdb/solib.c | 4 ++--
>> 1 file changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/gdb/solib.c b/gdb/solib.c
>> index 7721fd673ae3..90e7b906222c 100644
>
>> --- a/gdb/solib.c
>> +++ b/gdb/solib.c
>> @@ -1163,8 +1163,8 @@ info_linker_namespace_command (const char *pattern, int from_tty)
>> /* This command only really makes sense for inferiors that support
>> linker namespaces, so we can leave early. */
>> if (ops->num_active_namespaces == nullptr)
>> - error (_("Current inferior does not support linker namespaces." \
>> - "Use \"info sharedlibrary\" instead"));
>> + error (_("Current inferior does not support linker namespaces. " \
>> + "Use \"info sharedlibrary\" instead."));
>>
>
> You could remove the useless continuation backslash too, while at it.
Thanks, done.
Simon
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v3 5/6] gdb/progspace: add solib_ops pointer in program_space
2025-06-20 18:19 ` Pedro Alves
@ 2025-06-26 17:37 ` Simon Marchi
0 siblings, 0 replies; 28+ messages in thread
From: Simon Marchi @ 2025-06-26 17:37 UTC (permalink / raw)
To: Pedro Alves, Simon Marchi, gdb-patches
On 2025-06-20 14:19, Pedro Alves wrote:
> On 2025-06-16 20:33, Simon Marchi wrote:
>> New in v3:
>>
>> - add some ops nullptr checks in print_solib_list_table and
>> info_linker_namespace_command
>>
>> The subsequent C++ification patch in this series will allocate one
>> instance of solib_ops per program space. That instance will be held in
>> struct program_space. As a small step towards this, add an `solib_ops
>> *` field to `struct program_space`. This field represents the solib_ops
>> currently used to manage the solibs in that program space. Initialize
>> it with the result of `gdbarch_so_ops` in `post_create_inferior`, and
>> use it whenever we need to do some solib stuff, rather than using
>> `gdbarch_so_ops` directly.
>>
>> The difficulty here is knowing when exactly to set and unset the solib
>> ops. What I have here passes the testsuite on Linux, but with more
>> testing we will probably discover more spots where it's needed.
>
> One important detail is keeping the solibs listed after the inferior exits.
> This is so the user can set breakpoints in shared library symbols for the
> next re-run.
>
> Your patches preserve that, which is good. I don't recall off hand if there's
> a testcase ensure it.
>
> Tiny nit below. Other than that:
>
> Approved-By: Pedro Alves <pedro@palves.net>
>
>> diff --git a/gdb/progspace.h b/gdb/progspace.h
>> index 5e5d5edd9b4b..abb448195d74 100644
>> --- a/gdb/progspace.h
>> +++ b/gdb/progspace.h
>> @@ -231,6 +231,23 @@ struct program_space
>> is outside all objfiles in this progspace. */
>> struct objfile *objfile_for_address (CORE_ADDR address);
>>
>> + /* Set this program space's solib provider.
>> +
>> + The solib provider must be unset prior to call this method. */
>
>
> "prior to call" -> prior to calling"
Thanks, fixed.
Simon
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v3 6/6] gdb/solib: C++ify solib_ops
2025-06-20 18:20 ` Pedro Alves
@ 2025-06-26 18:04 ` Simon Marchi
2025-06-27 22:04 ` Tom de Vries
0 siblings, 1 reply; 28+ messages in thread
From: Simon Marchi @ 2025-06-26 18:04 UTC (permalink / raw)
To: Pedro Alves, Simon Marchi, gdb-patches
On 2025-06-20 14:20, Pedro Alves wrote:
> Hi!
>
> On 2025-06-16 20:33, Simon Marchi wrote:
>> Convert solib_ops into an abstract base class (with abstract methods,
>> some of them with default implementations) and convert all the existing
>> solib_ops instances to solib_ops derived classes / implementations.
>
> Thanks a lot for doing this.
>
> Some small nits below. Other than that:
>
> Approved-By: Pedro Alves <pedro@palves.net>
>
>>
>> Prior to this patch, solib_ops is a structure holding function pointers,
>> of which there are only a handful of global instances (in the
>> `solib-*.c` files). When passing an `solib_ops *` around, it's a
>> pointer to one of these instances. After this patch, there are no more
>> global solib_ops instances. Instances are created as needed and stored
>> in struct program_space. These instances could eventually be made to
>> contain the program space-specific data, which is currently kept in
>> per-program space registries (I have some pending patches for that).
>>
>> Prior to this patch, `gdbarch_so_ops` is a gdbarch method that returns a
>> pointer to the appropriate solib_ops implementation for the gdbarch.
>> This is replaced with the `gdbarch_new_solib_ops` method, which returns
>> a new instance of the appropriate solib_ops implementation for this
>> gdbarch. This requires introducing some factory functions for the
>> various solib_ops implementation, to be used as `gdbarch_new_solib_ops`
>> callbacks. For instance:
>>
>> solib_ops_up
>> new_linux_ilp32_svr4_solib_ops ()
>> {
>> return std::make_unique<linux_ilp32_svr4_solib_ops> ();
>> }
>>
>
> (Annoying) nit: I'd say that factory functions that return a non-raw pointer are more
> typically named make_foo, like std::make_unique. new_foo suggests that they would return a
> raw pointer, like operator new.
Np, it's a quick change. Done.
>> There is a little "base class template" hack in mips-linux-tdep.c,
>> because both mips_linux_ilp32_svr4_solib_ops and
>> mips_linux_lp64_svr4_solib_ops need to derive from different SVR4 base
>> classes (linux_ilp32_svr4_solib_ops and linux_lp64_svr4_solib_ops), but
>> they both want to override the in_dynsym_resolve_code method with the
>> same implementation. Let me know if there's a more straightforward way
>> to do this.
>
> I don't know why would call this a hack. This is a CRTP mixin, a standard
> technique, that we use in other places in GDB, for the same reason. I think
> you should just say that instead.
Ack, done.
> We should be able to simplify such code a bit with C++23, with the new
> explicit object parameter syntax.
I have seen this, but haven't internalized yet how it can be useful.
>> The solib_ops::supports_namespaces method is new: the support for
>> namespaces was previously predicated by the presence or absence of a
>> find_solib_ns method. It now needs to be explicit.
>>
>> There is a new progspace::release_solib_ops method, which is only needed
>> for rocm_solib_ops. For the moment, rocm_solib_ops replaces and wraps
>> the existing svr4_solib_ops instance, in order to combine the results of
>> the two. The plan is to have a subsequent patch to allow program spaces to have
>> multiple solib_ops, removing the need that release_solib_ops.
>
>
> Some word missing in "need that release_solib_ops". I guess "for".
Replacing "that" with "for", actually. Fixed.
>> Speaking of rocm_solib_ops: it previously overrode only a few methods by
>> copying svr4_solib_ops and overwriting some function pointers. Now, it
>> needs to implement all the methods that svr4_solib_ops implements, in
>> order to forward the call. Otherwise, the default solib_ops method woul
>
> woul -> would
Fixed.
>> --- a/gdb/progspace.h
>> +++ b/gdb/progspace.h
>> @@ -21,6 +21,7 @@
>> #ifndef GDB_PROGSPACE_H
>> #define GDB_PROGSPACE_H
>>
>> +#include "solib.h"
>> #include "target.h"
>> #include "gdb_bfd.h"
>> #include "registry.h"
>> @@ -234,19 +235,23 @@ struct program_space
>> /* Set this program space's solib provider.
>>
>> The solib provider must be unset prior to call this method. */
>> - void set_solib_ops (const struct solib_ops &ops)
>> + void set_solib_ops (solib_ops_up ops)
>> {
>> gdb_assert (m_solib_ops == nullptr);
>> - m_solib_ops = &ops;
>> + m_solib_ops = std::move (ops);
>> };
>>
>> - /* Unset this program space's solib provider. */
>> + /* Unset and free this program space's solib provider. */
>> void unset_solib_ops ()
>> { m_solib_ops = nullptr; }
>>
>> + /* Unset and return this program space's solib provider. */
>> + solib_ops_up release_solib_ops ()
>> + { return std::move (m_solib_ops); }
>> +
>> /* Get this program space's solib provider. */
>> - const struct solib_ops *solib_ops () const
>> - { return m_solib_ops; }
>> + struct solib_ops *solib_ops () const
>> + { return m_solib_ops.get (); }
>
> Curious that const dropped here and other places. Was const previously
> just wrong?
Ah, it's because I have followup patches (not sure if/when I'll post
them) that change solib implementations to move the data from registries
to fields of solib_ops_* objects directly. Doing so requires making
some methods non-const, and so to call them we need
program_space::solib_ops to return a non-const solib_ops.
But for the moment, given that solib_ops_* objects don't keep data, it
would make more sense to leave everything const. I will make all the
methods const again (like I had initially) and make
program_space::solib_ops return a const object. We can remove the
consts if/when it's justified to do so.
Thanks for the review, I will push the series shortly, when I'm done
addressing these comments.
Simon
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v3 6/6] gdb/solib: C++ify solib_ops
2025-06-26 18:04 ` Simon Marchi
@ 2025-06-27 22:04 ` Tom de Vries
2025-06-27 22:46 ` Thiago Jung Bauermann
0 siblings, 1 reply; 28+ messages in thread
From: Tom de Vries @ 2025-06-27 22:04 UTC (permalink / raw)
To: Simon Marchi, Pedro Alves, Simon Marchi, gdb-patches
On 6/26/25 20:04, Simon Marchi wrote:
> I will push the series shortly, when I'm done
> addressing these comments.
I did a mingw cross build from trunk, and ran into:
...
/usr/lib64/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld:
arch-utils.o:arch-utils.c:(.rdata$.refptr._Z21make_target_solib_opsv[.refptr._Z21make_target_solib_opsv]+0x0):
undefined reference to `make_target_solib_ops()'
collect2: error: ld returned 1 exit status
make[1]: *** [Makefile:2253: gdb.exe] Error 1
make[1]: Leaving directory '/data/vries/w/build/gdb'
make: *** [Makefile:11391: all-gdb] Error 2
$
...
I suppose due to this commit.
Thanks,
- Tom
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v3 6/6] gdb/solib: C++ify solib_ops
2025-06-27 22:04 ` Tom de Vries
@ 2025-06-27 22:46 ` Thiago Jung Bauermann
2025-06-28 5:25 ` Simon Marchi
0 siblings, 1 reply; 28+ messages in thread
From: Thiago Jung Bauermann @ 2025-06-27 22:46 UTC (permalink / raw)
To: Tom de Vries; +Cc: Simon Marchi, Pedro Alves, Simon Marchi, gdb-patches
Tom de Vries <tdevries@suse.de> writes:
> On 6/26/25 20:04, Simon Marchi wrote:
>> I will push the series shortly, when I'm done
>> addressing these comments.
>
> I did a mingw cross build from trunk, and ran into:
> ...
> /usr/lib64/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld:
> arch-utils.o:arch-utils.c:(.rdata$.refptr._Z21make_target_solib_opsv[.refptr._Z21make_target_solib_opsv]+0x0):
> undefined reference to `make_target_solib_ops()'
> collect2: error: ld returned 1 exit status
> make[1]: *** [Makefile:2253: gdb.exe] Error 1
> make[1]: Leaving directory '/data/vries/w/build/gdb'
> make: *** [Makefile:11391: all-gdb] Error 2
> $
> ...
>
> I suppose due to this commit.
I'm also seeing it on a native build with FreeBSD on aarch64:
CXXLD gdb
ld: error: undefined symbol: make_target_solib_ops()
>>> referenced by dicos-tdep.c:30 (/home/bauermann/src/binutils-gdb-wt/gdb/dicos-tdep.c:30)
>>> dicos-tdep.o:(dicos_init_abi(gdbarch*))
>>> referenced by dicos-tdep.c:30 (/home/bauermann/src/binutils-gdb-wt/gdb/dicos-tdep.c:30)
>>> dicos-tdep.o:(dicos_init_abi(gdbarch*))
>>> referenced by gdbarch-gen.c:160 (/home/bauermann/src/binutils-gdb-wt/gdb/gdbarch-gen.c:160)
>>> arch-utils.o:(gdbarch::gdbarch())
>>> referenced 1 more times
c++: error: linker command failed with exit code 1 (use -v to see invocation)
gmake[2]: *** [Makefile:2253: gdb] Error 1
--
Thiago
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v3 6/6] gdb/solib: C++ify solib_ops
2025-06-27 22:46 ` Thiago Jung Bauermann
@ 2025-06-28 5:25 ` Simon Marchi
2025-06-28 6:27 ` Tom de Vries
0 siblings, 1 reply; 28+ messages in thread
From: Simon Marchi @ 2025-06-28 5:25 UTC (permalink / raw)
To: Thiago Jung Bauermann, Tom de Vries
Cc: Pedro Alves, Simon Marchi, gdb-patches
On 2025-06-27 18:46, Thiago Jung Bauermann wrote:
> Tom de Vries <tdevries@suse.de> writes:
>
>> On 6/26/25 20:04, Simon Marchi wrote:
>>> I will push the series shortly, when I'm done
>>> addressing these comments.
>>
>> I did a mingw cross build from trunk, and ran into:
>> ...
>> /usr/lib64/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld:
>> arch-utils.o:arch-utils.c:(.rdata$.refptr._Z21make_target_solib_opsv[.refptr._Z21make_target_solib_opsv]+0x0):
>> undefined reference to `make_target_solib_ops()'
>> collect2: error: ld returned 1 exit status
>> make[1]: *** [Makefile:2253: gdb.exe] Error 1
>> make[1]: Leaving directory '/data/vries/w/build/gdb'
>> make: *** [Makefile:11391: all-gdb] Error 2
>> $
>> ...
>>
>> I suppose due to this commit.
>
> I'm also seeing it on a native build with FreeBSD on aarch64:
>
> CXXLD gdb
> ld: error: undefined symbol: make_target_solib_ops()
>>>> referenced by dicos-tdep.c:30 (/home/bauermann/src/binutils-gdb-wt/gdb/dicos-tdep.c:30)
>>>> dicos-tdep.o:(dicos_init_abi(gdbarch*))
>>>> referenced by dicos-tdep.c:30 (/home/bauermann/src/binutils-gdb-wt/gdb/dicos-tdep.c:30)
>>>> dicos-tdep.o:(dicos_init_abi(gdbarch*))
>>>> referenced by gdbarch-gen.c:160 (/home/bauermann/src/binutils-gdb-wt/gdb/gdbarch-gen.c:160)
>>>> arch-utils.o:(gdbarch::gdbarch())
>>>> referenced 1 more times
> c++: error: linker command failed with exit code 1 (use -v to see invocation)
> gmake[2]: *** [Makefile:2253: gdb] Error 1
>
Sorry about that. Unfortunately, I didn't manage to reproduce. I
tried:
- a native build on FreeBSD/amd64
- a native build on FreeBSD/amd64 --enable-targets=all
- a cross-build for mingw64 on Linux
What I don't understand from your logs is that make_target_solib_ops is
defined in solib-target.c, which is always included in the build
(solib-target.c is specified in COMMON_SFILES, in gdb/Makefile.in). Do
you see solib-target.c being compiled in these builds?
Simon
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v3 6/6] gdb/solib: C++ify solib_ops
2025-06-28 5:25 ` Simon Marchi
@ 2025-06-28 6:27 ` Tom de Vries
0 siblings, 0 replies; 28+ messages in thread
From: Tom de Vries @ 2025-06-28 6:27 UTC (permalink / raw)
To: Simon Marchi, Thiago Jung Bauermann
Cc: Pedro Alves, Simon Marchi, gdb-patches
On 6/28/25 07:25, Simon Marchi wrote:
>
>
> On 2025-06-27 18:46, Thiago Jung Bauermann wrote:
>> Tom de Vries <tdevries@suse.de> writes:
>>
>>> On 6/26/25 20:04, Simon Marchi wrote:
>>>> I will push the series shortly, when I'm done
>>>> addressing these comments.
>>>
>>> I did a mingw cross build from trunk, and ran into:
>>> ...
>>> /usr/lib64/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld:
>>> arch-utils.o:arch-utils.c:(.rdata$.refptr._Z21make_target_solib_opsv[.refptr._Z21make_target_solib_opsv]+0x0):
>>> undefined reference to `make_target_solib_ops()'
>>> collect2: error: ld returned 1 exit status
>>> make[1]: *** [Makefile:2253: gdb.exe] Error 1
>>> make[1]: Leaving directory '/data/vries/w/build/gdb'
>>> make: *** [Makefile:11391: all-gdb] Error 2
>>> $
>>> ...
>>>
>>> I suppose due to this commit.
>>
>> I'm also seeing it on a native build with FreeBSD on aarch64:
>>
>> CXXLD gdb
>> ld: error: undefined symbol: make_target_solib_ops()
>>>>> referenced by dicos-tdep.c:30 (/home/bauermann/src/binutils-gdb-wt/gdb/dicos-tdep.c:30)
>>>>> dicos-tdep.o:(dicos_init_abi(gdbarch*))
>>>>> referenced by dicos-tdep.c:30 (/home/bauermann/src/binutils-gdb-wt/gdb/dicos-tdep.c:30)
>>>>> dicos-tdep.o:(dicos_init_abi(gdbarch*))
>>>>> referenced by gdbarch-gen.c:160 (/home/bauermann/src/binutils-gdb-wt/gdb/gdbarch-gen.c:160)
>>>>> arch-utils.o:(gdbarch::gdbarch())
>>>>> referenced 1 more times
>> c++: error: linker command failed with exit code 1 (use -v to see invocation)
>> gmake[2]: *** [Makefile:2253: gdb] Error 1
>>
>
> Sorry about that. Unfortunately, I didn't manage to reproduce. I
> tried:
>
> - a native build on FreeBSD/amd64
> - a native build on FreeBSD/amd64 --enable-targets=all
> - a cross-build for mingw64 on Linux
>
> What I don't understand from your logs is that make_target_solib_ops is
> defined in solib-target.c, which is always included in the build
> (solib-target.c is specified in COMMON_SFILES, in gdb/Makefile.in). Do
> you see solib-target.c being compiled in these builds?
>
Hi Simon,
I see it being compiled and included in the link line.
I've attached the build log to a PR I've filed for this issue (
https://sourceware.org/bugzilla/show_bug.cgi?id=33118 ).
Thanks,
- Tom
> Simon
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v3 5/6] gdb/progspace: add solib_ops pointer in program_space
2025-06-16 19:33 ` [PATCH v3 5/6] gdb/progspace: add solib_ops pointer in program_space Simon Marchi
2025-06-17 19:45 ` Guinevere Larsen
2025-06-20 18:19 ` Pedro Alves
@ 2025-09-02 14:49 ` Tom de Vries
2025-09-02 16:05 ` Simon Marchi
2 siblings, 1 reply; 28+ messages in thread
From: Tom de Vries @ 2025-09-02 14:49 UTC (permalink / raw)
To: Simon Marchi, gdb-patches
On 6/16/25 21:33, Simon Marchi wrote:
> + The solib provider must be unset prior to call this method. */
> + void set_solib_ops (const struct solib_ops &ops)
> + {
> + gdb_assert (m_solib_ops == nullptr);
> + m_solib_ops = &ops;
> + };
This assert triggers with test-case
gdb.server/extended-remote-restart.exp and target board
native-extended-gdbserver, starting with the commit that introduced it.
I've filed a PR about this (
https://sourceware.org/bugzilla/show_bug.cgi?id=33357 ).
Thanks,
- Tom
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v3 5/6] gdb/progspace: add solib_ops pointer in program_space
2025-09-02 14:49 ` Tom de Vries
@ 2025-09-02 16:05 ` Simon Marchi
2025-09-02 16:34 ` Tom de Vries
0 siblings, 1 reply; 28+ messages in thread
From: Simon Marchi @ 2025-09-02 16:05 UTC (permalink / raw)
To: Tom de Vries, Simon Marchi, gdb-patches
On 9/2/25 10:49 AM, Tom de Vries wrote:
> On 6/16/25 21:33, Simon Marchi wrote:
>> + The solib provider must be unset prior to call this method. */
>> + void set_solib_ops (const struct solib_ops &ops)
>> + {
>> + gdb_assert (m_solib_ops == nullptr);
>> + m_solib_ops = &ops;
>> + };
>
> This assert triggers with test-case gdb.server/extended-remote-restart.exp and target board native-extended-gdbserver, starting with the commit that introduced it.
>
> I've filed a PR about this ( https://sourceware.org/bugzilla/show_bug.cgi?id=33357 ).
>
> Thanks,
> - Tom
This is fixed by this pending series, which I had forgotten about:
https://inbox.sourceware.org/gdb-patches/20250708205619.3582933-1-simon.marchi@polymtl.ca/
Can you can confirm that it fixes the issue on your side?
Simon
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v3 5/6] gdb/progspace: add solib_ops pointer in program_space
2025-09-02 16:05 ` Simon Marchi
@ 2025-09-02 16:34 ` Tom de Vries
0 siblings, 0 replies; 28+ messages in thread
From: Tom de Vries @ 2025-09-02 16:34 UTC (permalink / raw)
To: Simon Marchi, Simon Marchi, gdb-patches
On 9/2/25 18:05, Simon Marchi wrote:
> On 9/2/25 10:49 AM, Tom de Vries wrote:
>> On 6/16/25 21:33, Simon Marchi wrote:
>>> + The solib provider must be unset prior to call this method. */
>>> + void set_solib_ops (const struct solib_ops &ops)
>>> + {
>>> + gdb_assert (m_solib_ops == nullptr);
>>> + m_solib_ops = &ops;
>>> + };
>>
>> This assert triggers with test-case gdb.server/extended-remote-restart.exp and target board native-extended-gdbserver, starting with the commit that introduced it.
>>
>> I've filed a PR about this ( https://sourceware.org/bugzilla/show_bug.cgi?id=33357 ).
>>
>> Thanks,
>> - Tom
>
> This is fixed by this pending series, which I had forgotten about:
>
> https://inbox.sourceware.org/gdb-patches/20250708205619.3582933-1-simon.marchi@polymtl.ca/
>
> Can you can confirm that it fixes the issue on your side?
It does.
After applying the series and rebuilding, we're back to the gdbserver
assertion failure mentioned in the PR:
...
=== gdb Summary ===
# of unexpected core files 1
# of expected passes 28
...
Thanks,
- Tom
^ permalink raw reply [flat|nested] 28+ messages in thread
end of thread, other threads:[~2025-09-02 16:36 UTC | newest]
Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-06-16 19:32 [PATCH v3 1/6] gdb/testsuite: check that "info shared" and "info linker-namespaces" before running don't crash Simon Marchi
2025-06-16 19:33 ` [PATCH v3 2/6] gdb/solib: fix formatting of "info linker-namespaces" error message Simon Marchi
2025-06-20 18:12 ` Pedro Alves
2025-06-26 17:35 ` Simon Marchi
2025-06-16 19:33 ` [PATCH v3 3/6] gdb/solib: add solib -> solib_ops backlink Simon Marchi
2025-06-20 18:17 ` Pedro Alves
2025-06-16 19:33 ` [PATCH v3 4/6] gdb/solib: use solib::ops for operations that concern a single solib Simon Marchi
2025-06-20 18:17 ` Pedro Alves
2025-06-16 19:33 ` [PATCH v3 5/6] gdb/progspace: add solib_ops pointer in program_space Simon Marchi
2025-06-17 19:45 ` Guinevere Larsen
2025-06-17 20:33 ` Simon Marchi
2025-06-18 11:51 ` Guinevere Larsen
2025-06-18 14:43 ` Simon Marchi
2025-06-18 15:01 ` Guinevere Larsen
2025-06-20 18:19 ` Pedro Alves
2025-06-26 17:37 ` Simon Marchi
2025-09-02 14:49 ` Tom de Vries
2025-09-02 16:05 ` Simon Marchi
2025-09-02 16:34 ` Tom de Vries
2025-06-16 19:33 ` [PATCH v3 6/6] gdb/solib: C++ify solib_ops Simon Marchi
2025-06-20 18:20 ` Pedro Alves
2025-06-26 18:04 ` Simon Marchi
2025-06-27 22:04 ` Tom de Vries
2025-06-27 22:46 ` Thiago Jung Bauermann
2025-06-28 5:25 ` Simon Marchi
2025-06-28 6:27 ` Tom de Vries
2025-06-20 18:12 ` [PATCH v3 1/6] gdb/testsuite: check that "info shared" and "info linker-namespaces" before running don't crash Pedro Alves
2025-06-26 17:30 ` Simon Marchi
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox