forked from Imagelibrary/binutils-gdb
gdb/progspace: add solib_ops pointer in program_space
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 Approved-By: Pedro Alves <pedro@palves.net> Reviewed-By: Guinevere Larsen <guinevere@redhat.com>
This commit is contained in:
@@ -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
|
||||
|
||||
15
gdb/infcmd.c
15
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. */
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
11
gdb/infrun.c
11
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 ();
|
||||
}
|
||||
|
||||
@@ -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 calling 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 @@ private:
|
||||
/* 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;
|
||||
|
||||
55
gdb/solib.c
55
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
|
||||
|
||||
@@ -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 ();
|
||||
|
||||
|
||||
@@ -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] } {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user