From d171632faa9f563f47224e0f6214f8860ed7bcc4 Mon Sep 17 00:00:00 2001 From: Tankut Baris Aktemur Date: Tue, 16 Mar 2021 19:36:39 +0100 Subject: [PATCH] gdbserver: convert the global dll list into a process_info field The 'all_dlls' list is global. This would cause the complete dll list to be reported for individual processes. Move the list into the process_info struct. Currently the dll list is used only by the win32-low target, which does not support the multi-process feature. Therefore, it practically does not matter whether the list is global or per-process. However, there may be targets that are outside the binutils-gdb repo (e.g. we, at Intel, have such a target) that have multi-process and use the dll list. So, it makes sense to do the right thing. gdbserver/ChangeLog: 2021-03-22 Tankut Baris Aktemur * inferiors.h (struct process_info) : New fields. * dll.h (loaded_dll) (unloaded_dll): Declare an overloaded version that takes a proc parameter. * dll.cc (loaded_dll) (unloaded_dll): Implement the overloaded versions. (clear_dlls): Clear all process' dll lists. (all_dlls, dlls_changed): Remove the global variables. * remote-utils.cc (prepare_resume_reply): Update to consider a dll list per proc. * server.cc (handle_qxfer_libraries): Ditto. (handle_v_attach): Ditto. (captured_main): Ditto. --- gdbserver/ChangeLog | 17 +++++++++++++++ gdbserver/dll.cc | 45 ++++++++++++++++++++++++++++----------- gdbserver/dll.h | 9 +++++--- gdbserver/inferiors.h | 7 ++++++ gdbserver/remote-utils.cc | 4 ++-- gdbserver/server.cc | 8 ++++--- 6 files changed, 70 insertions(+), 20 deletions(-) diff --git a/gdbserver/ChangeLog b/gdbserver/ChangeLog index 0e713cc6abb..d870154ac67 100644 --- a/gdbserver/ChangeLog +++ b/gdbserver/ChangeLog @@ -1,3 +1,20 @@ +2021-03-22 Tankut Baris Aktemur + + * inferiors.h (struct process_info) : New + fields. + * dll.h (loaded_dll) + (unloaded_dll): Declare an overloaded version that takes a proc + parameter. + * dll.cc (loaded_dll) + (unloaded_dll): Implement the overloaded versions. + (clear_dlls): Clear all process' dll lists. + (all_dlls, dlls_changed): Remove the global variables. + * remote-utils.cc (prepare_resume_reply): Update to consider a dll + list per proc. + * server.cc (handle_qxfer_libraries): Ditto. + (handle_v_attach): Ditto. + (captured_main): Ditto. + 2021-02-23 Simon Marchi * linux-low.cc (linux_process_target::filter_event): Return diff --git a/gdbserver/dll.cc b/gdbserver/dll.cc index cb9d91f1b66..e86b0a25a28 100644 --- a/gdbserver/dll.cc +++ b/gdbserver/dll.cc @@ -23,23 +23,40 @@ /* An "unspecified" CORE_ADDR, for match_dll. */ #define UNSPECIFIED_CORE_ADDR (~(CORE_ADDR) 0) -std::list all_dlls; -int dlls_changed; - -/* Record a newly loaded DLL at BASE_ADDR. */ +/* Record a newly loaded DLL at BASE_ADDR for the current process. */ void loaded_dll (const char *name, CORE_ADDR base_addr) { - all_dlls.emplace_back (name != NULL ? name : "", base_addr); - dlls_changed = 1; + loaded_dll (current_process (), name, base_addr); +} + +/* Record a newly loaded DLL at BASE_ADDR for PROC. */ + +void +loaded_dll (process_info *proc, const char *name, CORE_ADDR base_addr) +{ + gdb_assert (proc != nullptr); + proc->all_dlls.emplace_back (name != nullptr ? name : "", base_addr); + proc->dlls_changed = true; } -/* Record that the DLL with NAME and BASE_ADDR has been unloaded. */ +/* Record that the DLL with NAME and BASE_ADDR has been unloaded + from the current process. */ void unloaded_dll (const char *name, CORE_ADDR base_addr) { + unloaded_dll (current_process (), name, base_addr); +} + +/* Record that the DLL with NAME and BASE_ADDR has been unloaded + from PROC. */ + +void +unloaded_dll (process_info *proc, const char *name, CORE_ADDR base_addr) +{ + gdb_assert (proc != nullptr); auto pred = [&] (const dll_info &dll) { if (base_addr != UNSPECIFIED_CORE_ADDR @@ -52,9 +69,10 @@ unloaded_dll (const char *name, CORE_ADDR base_addr) return false; }; - auto iter = std::find_if (all_dlls.begin (), all_dlls.end (), pred); + auto iter = std::find_if (proc->all_dlls.begin (), proc->all_dlls.end (), + pred); - if (iter == all_dlls.end ()) + if (iter == proc->all_dlls.end ()) /* For some inferiors we might get unloaded_dll events without having a corresponding loaded_dll. In that case, the dll cannot be found in ALL_DLL, and there is nothing further for us to do. @@ -68,13 +86,16 @@ unloaded_dll (const char *name, CORE_ADDR base_addr) { /* DLL has been found so remove the entry and free associated resources. */ - all_dlls.erase (iter); - dlls_changed = 1; + proc->all_dlls.erase (iter); + proc->dlls_changed = true; } } void clear_dlls (void) { - all_dlls.clear (); + for_each_process ([] (process_info *proc) + { + proc->all_dlls.clear (); + }); } diff --git a/gdbserver/dll.h b/gdbserver/dll.h index 6707c52e440..2a29990d623 100644 --- a/gdbserver/dll.h +++ b/gdbserver/dll.h @@ -20,6 +20,8 @@ #include +struct process_info; + struct dll_info { dll_info (const std::string &name_, CORE_ADDR base_addr_) @@ -30,11 +32,12 @@ struct dll_info CORE_ADDR base_addr; }; -extern std::list all_dlls; -extern int dlls_changed; - extern void clear_dlls (void); extern void loaded_dll (const char *name, CORE_ADDR base_addr); +extern void loaded_dll (process_info *proc, const char *name, + CORE_ADDR base_addr); extern void unloaded_dll (const char *name, CORE_ADDR base_addr); +extern void unloaded_dll (process_info *proc, const char *name, + CORE_ADDR base_addr); #endif /* GDBSERVER_DLL_H */ diff --git a/gdbserver/inferiors.h b/gdbserver/inferiors.h index 018a47c26e1..7754f745cd7 100644 --- a/gdbserver/inferiors.h +++ b/gdbserver/inferiors.h @@ -20,6 +20,7 @@ #define GDBSERVER_INFERIORS_H #include "gdbsupport/gdb_vecs.h" +#include "dll.h" #include struct thread_info; @@ -68,6 +69,12 @@ struct process_info /* Private target data. */ struct process_info_private *priv = NULL; + + /* DLLs thats are loaded for this proc. */ + std::list all_dlls; + + /* Flag to mark that the DLL list has changed. */ + bool dlls_changed = false; }; /* Get the pid of PROC. */ diff --git a/gdbserver/remote-utils.cc b/gdbserver/remote-utils.cc index 4f63d73785d..509b813af27 100644 --- a/gdbserver/remote-utils.cc +++ b/gdbserver/remote-utils.cc @@ -1270,11 +1270,11 @@ prepare_resume_reply (char *buf, ptid_t ptid, } } - if (dlls_changed) + if (current_process ()->dlls_changed) { strcpy (buf, "library:;"); buf += strlen (buf); - dlls_changed = 0; + current_process ()->dlls_changed = false; } current_thread = saved_thread; diff --git a/gdbserver/server.cc b/gdbserver/server.cc index a5497e93cee..ea731d54689 100644 --- a/gdbserver/server.cc +++ b/gdbserver/server.cc @@ -1470,7 +1470,8 @@ handle_qxfer_libraries (const char *annex, std::string document = "\n"; - for (const dll_info &dll : all_dlls) + process_info *proc = current_process (); + for (const dll_info &dll : proc->all_dlls) document += string_printf (" \n", dll.name.c_str (), paddress (dll.base_addr)); @@ -2848,7 +2849,7 @@ handle_v_attach (char *own_buf) some libraries are preloaded. GDB will always poll the library list. Avoids the "stopped by shared library event" notice on the GDB side. */ - dlls_changed = 0; + current_process ()->dlls_changed = false; if (non_stop) { @@ -3796,7 +3797,8 @@ captured_main (int argc, char *argv[]) /* Don't report shared library events on the initial connection, even if some libraries are preloaded. Avoids the "stopped by shared library event" notice on gdb side. */ - dlls_changed = 0; + if (current_thread != nullptr) + current_process ()->dlls_changed = false; if (cs.last_status.kind == TARGET_WAITKIND_EXITED || cs.last_status.kind == TARGET_WAITKIND_SIGNALLED) -- 2.30.2