gdbserver: convert the global dll list into a process_info field
authorTankut Baris Aktemur <tankut.baris.aktemur@intel.com>
Tue, 16 Mar 2021 18:36:39 +0000 (19:36 +0100)
committerTankut Baris Aktemur <tankut.baris.aktemur@intel.com>
Mon, 22 Mar 2021 08:18:04 +0000 (09:18 +0100)
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  <tankut.baris.aktemur@intel.com>

* inferiors.h (struct process_info) <all_dlls, dlls_changed>: 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
gdbserver/dll.cc
gdbserver/dll.h
gdbserver/inferiors.h
gdbserver/remote-utils.cc
gdbserver/server.cc

index 0e713cc6abbad8dac18e85a84b1bcbd94b33f8c5..d870154ac6705fe93194e2863f6ed3c5061e5e51 100644 (file)
@@ -1,3 +1,20 @@
+2021-03-22  Tankut Baris Aktemur  <tankut.baris.aktemur@intel.com>
+
+       * inferiors.h (struct process_info) <all_dlls, dlls_changed>: 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  <simon.marchi@polymtl.ca>
 
        * linux-low.cc (linux_process_target::filter_event): Return
index cb9d91f1b6602213fcf8866784c991dff6c4ed96..e86b0a25a286a1fb1c21cc7a5c0e8ed44e22a636 100644 (file)
 /* An "unspecified" CORE_ADDR, for match_dll.  */
 #define UNSPECIFIED_CORE_ADDR (~(CORE_ADDR) 0)
 
-std::list<dll_info> 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 ();
+    });
 }
index 6707c52e4401a8534bcef7608204ec4c192fe2ae..2a29990d623915f22ba659679a9baa75006a5aaa 100644 (file)
@@ -20,6 +20,8 @@
 
 #include <list>
 
+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<dll_info> 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 */
index 018a47c26e1a0fa1c4217c74e2af4bee1675ba18..7754f745cd7d99e4387fc294b602d77b215f0d9b 100644 (file)
@@ -20,6 +20,7 @@
 #define GDBSERVER_INFERIORS_H
 
 #include "gdbsupport/gdb_vecs.h"
+#include "dll.h"
 #include <list>
 
 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<dll_info> all_dlls;
+
+  /* Flag to mark that the DLL list has changed.  */
+  bool dlls_changed = false;
 };
 
 /* Get the pid of PROC.  */
index 4f63d73785d26c59530429d813c233b4805a190f..509b813af27abf2b80ea134af107911d5488dbca 100644 (file)
@@ -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;
index a5497e93cee285ef5989ca9985f25d492407161b..ea731d546898990a94ca62b35688a7004bdb8d33 100644 (file)
@@ -1470,7 +1470,8 @@ handle_qxfer_libraries (const char *annex,
 
   std::string document = "<library-list version=\"1.0\">\n";
 
-  for (const dll_info &dll : all_dlls)
+  process_info *proc = current_process ();
+  for (const dll_info &dll : proc->all_dlls)
     document += string_printf
       ("  <library name=\"%s\"><segment address=\"0x%s\"/></library>\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)