gdb: link so_list using intrusive_list
authorSimon Marchi <simon.marchi@efficios.com>
Thu, 19 Oct 2023 14:55:38 +0000 (10:55 -0400)
committerSimon Marchi <simon.marchi@efficios.com>
Thu, 19 Oct 2023 14:57:51 +0000 (10:57 -0400)
Replace the hand-made linked list implementation with intrusive_list,
simplying management of list items.

Change-Id: I7f55fd88325bb197cc655c9be5a2ec966d8cc48d
Approved-By: Pedro Alves <pedro@palves.net>
Reviewed-By: Reviewed-By: Lancelot Six <lancelot.six@amd.com>
12 files changed:
gdb/mi/mi-cmd-file.c
gdb/progspace.c
gdb/progspace.h
gdb/solib-aix.c
gdb/solib-darwin.c
gdb/solib-dsbt.c
gdb/solib-frv.c
gdb/solib-rocm.c
gdb/solib-svr4.c
gdb/solib-target.c
gdb/solib.c
gdb/solist.h

index 30682da167b05faa668bcf3f48901eefc183e61f..b9231b7bd6a6ceab46c26abe0ced390313858773 100644 (file)
@@ -163,15 +163,15 @@ mi_cmd_file_list_shared_libraries (const char *command,
   /* Print the table header.  */
   ui_out_emit_list list_emitter (uiout, "shared-libraries");
 
-  for (struct so_list *so : current_program_space->solibs ())
+  for (const so_list &so : current_program_space->solibs ())
     {
-      if (so->so_name.empty ())
+      if (so.so_name.empty ())
        continue;
 
-      if (pattern != nullptr && !re_exec (so->so_name.c_str ()))
+      if (pattern != nullptr && !re_exec (so.so_name.c_str ()))
        continue;
 
       ui_out_emit_tuple tuple_emitter (uiout, NULL);
-      mi_output_solib_attribs (uiout, *so);
+      mi_output_solib_attribs (uiout, so);
     }
 }
index 555fa79ccce8dfb2c22a44893d840f45d87ad215..4b816b4dac8b7e20517926af1462fe01522aba55 100644 (file)
@@ -132,8 +132,8 @@ void
 program_space::free_all_objfiles ()
 {
   /* Any objfile reference would become stale.  */
-  for (struct so_list *so : current_program_space->solibs ())
-    gdb_assert (so->objfile == NULL);
+  for (const struct so_list &so : current_program_space->solibs ())
+    gdb_assert (so.objfile == NULL);
 
   while (!objfiles_list.empty ())
     objfiles_list.front ()->unlink ();
index 20dfc2e92e83d0b26f3381bfec28514490d86d90..0a762e6ad5c8ba7d6d1c35bf9209309522d84741 100644 (file)
@@ -28,6 +28,7 @@
 #include "solist.h"
 #include "gdbsupport/next-iterator.h"
 #include "gdbsupport/safe-iterator.h"
+#include "gdbsupport/intrusive_list.h"
 #include <list>
 #include <vector>
 
@@ -253,12 +254,9 @@ struct program_space
      is outside all objfiles in this progspace.  */
   struct objfile *objfile_for_address (CORE_ADDR address);
 
-  /* Return a range adapter for iterating over all the solibs in this
-     program space.  Use it like:
-
-     for (so_list *so : pspace->solibs ()) { ... }  */
-  so_list_range solibs () const
-  { return so_list_range (this->so_list); }
+  /* Return the list of  all the solibs in this program space.  */
+  intrusive_list<struct so_list> &solibs ()
+  { return so_list; }
 
   /* Close and clear exec_bfd.  If we end up with no target sections
      to read memory from, this unpushes the exec_ops target.  */
@@ -361,7 +359,7 @@ struct program_space
 
   /* List of shared objects mapped into this space.  Managed by
      solib.c.  */
-  struct so_list *so_list = NULL;
+  intrusive_list<struct so_list> so_list;
 
   /* Number of calls to solib_add.  */
   unsigned int solib_add_generation = 0;
index e5e86c49e71231876905a294b7207ff5f203810c..68798e8735acacef6f26344493ddb4a339dbbc15 100644 (file)
@@ -445,21 +445,20 @@ solib_aix_solib_create_inferior_hook (int from_tty)
 
 /* Implement the "current_sos" target_so_ops method.  */
 
-static struct so_list *
-solib_aix_current_sos (void)
+static intrusive_list<so_list>
+solib_aix_current_sos ()
 {
-  struct so_list *start = NULL, *last = NULL;
-  int ix;
-
   gdb::optional<std::vector<lm_info_aix>> &library_list
     = solib_aix_get_library_list (current_inferior (), NULL);
   if (!library_list.has_value ())
-    return NULL;
+    return {};
+
+  intrusive_list<so_list> sos;
 
   /* Build a struct so_list for each entry on the list.
      We skip the first entry, since this is the entry corresponding
      to the main executable, not a shared library.  */
-  for (ix = 1; ix < library_list->size (); ix++)
+  for (int ix = 1; ix < library_list->size (); ix++)
     {
       so_list *new_solib = new so_list;
       std::string so_name;
@@ -488,16 +487,10 @@ solib_aix_current_sos (void)
       new_solib->lm_info = gdb::make_unique<lm_info_aix> (info);
 
       /* Add it to the list.  */
-      if (!start)
-       last = start = new_solib;
-      else
-       {
-         last->next = new_solib;
-         last = new_solib;
-       }
+      sos.push_back (*new_solib);
     }
 
-  return start;
+  return sos;
 }
 
 /* Implement the "open_symbol_file_object" target_so_ops method.  */
index a235f8a0ffbf911843b5672d2e9d2e8d0daf0d7c..57e61f9643f918fcbbdeaafc94f42946800c40d1 100644 (file)
@@ -212,32 +212,31 @@ open_symbol_file_object (int from_tty)
 
 /* Build a list of currently loaded shared objects.  See solib-svr4.c.  */
 
-static struct so_list *
-darwin_current_sos (void)
+static intrusive_list<so_list>
+darwin_current_sos ()
 {
   type *ptr_type
     = builtin_type (current_inferior ()->arch ())->builtin_data_ptr;
   enum bfd_endian byte_order = type_byte_order (ptr_type);
   int ptr_len = ptr_type->length ();
   unsigned int image_info_size;
-  struct so_list *head = NULL;
-  struct so_list *tail = NULL;
-  int i;
   darwin_info *info = get_darwin_info (current_program_space);
 
   /* Be sure image infos are loaded.  */
   darwin_load_image_infos (info);
 
   if (!darwin_dyld_version_ok (info))
-    return NULL;
+    return {};
 
   image_info_size = ptr_len * 3;
 
+  intrusive_list<so_list> sos;
+
   /* Read infos for each solib.
      The first entry was rumored to be the executable itself, but this is not
      true when a large number of shared libraries are used (table expanded ?).
      We now check all entries, but discard executable images.  */
-  for (i = 0; i < info->all_image.count; i++)
+  for (int i = 0; i < info->all_image.count; i++)
     {
       CORE_ADDR iinfo = info->all_image.info + i * image_info_size;
       gdb_byte buf[image_info_size];
@@ -282,16 +281,10 @@ darwin_current_sos (void)
       li->lm_addr = load_addr;
 
       newobj->lm_info = std::move (li);
-
-      if (head == NULL)
-       head = newobj;
-      else
-       tail->next = newobj;
-
-      tail = newobj;
+      sos.push_back (*newobj);
     }
 
-  return head;
+  return sos;
 }
 
 /* Check LOAD_ADDR points to a Mach-O executable header.  Return LOAD_ADDR
index d4383dd24f1b3ae17cf02a46bc52a143d3e0a784..d74ccddada39981d991be5d57a58e46115082487 100644 (file)
@@ -512,14 +512,13 @@ lm_base (void)
    themselves.  The declaration of `struct so_list' says which fields
    we provide values for.  */
 
-static struct so_list *
+static intrusive_list<so_list>
 dsbt_current_sos (void)
 {
   bfd_endian byte_order = gdbarch_byte_order (current_inferior ()->arch ());
   CORE_ADDR lm_addr;
-  struct so_list *sos_head = NULL;
-  struct so_list **sos_next_ptr = &sos_head;
   dsbt_info *info = get_dsbt_info (current_program_space);
+  intrusive_list<so_list> sos;
 
   /* Make sure that the main executable has been relocated.  This is
      required in order to find the address of the global offset table,
@@ -616,10 +615,7 @@ dsbt_current_sos (void)
              sop->so_original_name = sop->so_name;
            }
 
-         sop->lm_info = std::move (li);
-
-         *sos_next_ptr = sop;
-         sos_next_ptr = &sop->next;
+         sos.push_back (*sop);
        }
       else
        {
@@ -630,7 +626,7 @@ dsbt_current_sos (void)
                                          sizeof (lm_buf.l_next), byte_order);
     }
 
-  return sos_head;
+  return sos;
 }
 
 /* Return 1 if PC lies in the dynamic symbol resolution code of the
index d92c35339523071cefc1e5a2fa031f04bb35a380..c391462ad9aff119f2a10154b3001b24955b58c3 100644 (file)
@@ -306,13 +306,12 @@ lm_base (void)
 
 /* Implement the "current_sos" target_so_ops method.  */
 
-static struct so_list *
-frv_current_sos (void)
+static intrusive_list<so_list>
+frv_current_sos ()
 {
   bfd_endian byte_order = gdbarch_byte_order (current_inferior ()->arch ());
   CORE_ADDR lm_addr, mgot;
-  struct so_list *sos_head = NULL;
-  struct so_list **sos_next_ptr = &sos_head;
+  intrusive_list<so_list> sos;
 
   /* Make sure that the main executable has been relocated.  This is
      required in order to find the address of the global offset table,
@@ -399,10 +398,7 @@ frv_current_sos (void)
              sop->so_original_name = sop->so_name;
            }
 
-         sop->lm_info = std::move (li);
-
-         *sos_next_ptr = sop;
-         sos_next_ptr = &sop->next;
+         sos.push_back (*sop);
        }
       else
        {
@@ -415,7 +411,7 @@ frv_current_sos (void)
 
   enable_break2 ();
 
-  return sos_head;
+  return sos;
 }
 
 
@@ -856,10 +852,10 @@ main_got (void)
 CORE_ADDR
 frv_fdpic_find_global_pointer (CORE_ADDR addr)
 {
-  for (struct so_list *so : current_program_space->solibs ())
+  for (const so_list &so : current_program_space->solibs ())
     {
       int seg;
-      auto *li = gdb::checked_static_cast<lm_info_frv *> (so->lm_info.get ());
+      auto *li = gdb::checked_static_cast<lm_info_frv *> (so.lm_info.get ());
       int_elf32_fdpic_loadmap *map = li->map;
 
       for (seg = 0; seg < map->nsegs; seg++)
@@ -913,12 +909,12 @@ frv_fdpic_find_canonical_descriptor (CORE_ADDR entry_point)
      in list of shared objects.  */
   if (addr == 0)
     {
-      for (struct so_list *so : current_program_space->solibs ())
+      for (const so_list &so : current_program_space->solibs ())
        {
-         auto *li = gdb::checked_static_cast<lm_info_frv *> (so->lm_info.get ());
+         auto *li = gdb::checked_static_cast<lm_info_frv *> (so.lm_info.get ());
 
          addr = find_canonical_descriptor_in_load_object
-                  (entry_point, got_value, name, so->abfd.get (), li);
+                  (entry_point, got_value, name, so.abfd.get(), li);
 
          if (addr != 0)
            break;
@@ -1065,11 +1061,11 @@ frv_fetch_objfile_link_map (struct objfile *objfile)
 
   /* The other link map addresses may be found by examining the list
      of shared libraries.  */
-  for (struct so_list *so : current_program_space->solibs ())
+  for (const so_list &so : current_program_space->solibs ())
     {
-      auto *li = gdb::checked_static_cast<lm_info_frv *> (so->lm_info.get ());
+      auto *li = gdb::checked_static_cast<lm_info_frv *> (so.lm_info.get ());
 
-      if (so->objfile == objfile)
+      if (so.objfile == objfile)
        return li->lm_addr;
     }
 
index 938c0402b0cb91f546ad7470194e62ce09f803d9..3dc9a068ebe8154182a76f1691c9bca492832b49 100644 (file)
@@ -204,11 +204,10 @@ rocm_solib_handle_event ()
 
 /* Create so_list objects from rocm_so objects in SOS.  */
 
-static so_list *
+static intrusive_list<so_list>
 so_list_from_rocm_sos (const std::vector<rocm_so> &sos)
 {
-  struct so_list *dst = nullptr;
-  struct so_list **link = &dst;
+  intrusive_list<so_list> dst;
 
   for (const rocm_so &so : sos)
     {
@@ -218,9 +217,7 @@ so_list_from_rocm_sos (const std::vector<rocm_so> &sos)
       newobj->so_name = so.name;
       newobj->so_original_name = so.unique_name;
 
-      newobj->next = nullptr;
-      *link = newobj;
-      link = &newobj->next;
+      dst.push_back (*newobj);
     }
 
   return dst;
@@ -229,30 +226,27 @@ so_list_from_rocm_sos (const std::vector<rocm_so> &sos)
 /* Build a list of `struct so_list' objects describing the shared
    objects currently loaded in the inferior.  */
 
-static struct so_list *
+static intrusive_list<so_list>
 rocm_solib_current_sos ()
 {
   /* First, retrieve the host-side shared library list.  */
-  so_list *head = svr4_so_ops.current_sos ();
+  intrusive_list<so_list> sos = svr4_so_ops.current_sos ();
 
   /* Then, the device-side shared library list.  */
   std::vector<rocm_so> &dev_sos = get_solib_info (current_inferior ())->solib_list;
 
   if (dev_sos.empty ())
-    return head;
+    return sos;
 
-  so_list *dev_so_list = so_list_from_rocm_sos (dev_sos);
+  intrusive_list<so_list> dev_so_list = so_list_from_rocm_sos (dev_sos);
 
-  if (head == nullptr)
+  if (sos.empty ())
     return dev_so_list;
 
   /* Append our libraries to the end of the list.  */
-  so_list *tail;
-  for (tail = head; tail->next; tail = tail->next)
-    /* Nothing.  */;
-  tail->next = dev_so_list;
+  sos.splice (std::move (dev_so_list));
 
-  return head;
+  return sos;
 }
 
 namespace {
index b90b4ca2f68048619134818e4e43453bb3b5164f..6311599ff70983a92f5ea978fe9102489bdf2c1f 100644 (file)
@@ -954,7 +954,7 @@ open_symbol_file_object (int from_tty)
 
 struct svr4_library_list
 {
-  /* The tail pointer of the current namespace.  This is internal to XML
+  /* The so list for the current namespace.  This is internal to XML
      parsing.  */
   std::vector<svr4_so> *cur_list;
 
@@ -990,11 +990,10 @@ svr4_clear_so (const so_list &so)
 
 /* Create the so_list objects equivalent to the svr4_sos in SOS.  */
 
-static so_list *
+static intrusive_list<so_list>
 so_list_from_svr4_sos (const std::vector<svr4_so> &sos)
 {
-  struct so_list *dst = NULL;
-  struct so_list **link = &dst;
+  intrusive_list<so_list> dst;
 
   for (const svr4_so &so : sos)
     {
@@ -1004,9 +1003,7 @@ so_list_from_svr4_sos (const std::vector<svr4_so> &sos)
       newobj->so_original_name = so.name;
       newobj->lm_info = gdb::make_unique<lm_info_svr4> (*so.lm_info);
 
-      newobj->next = NULL;
-      *link = newobj;
-      link = &newobj->next;
+      dst.push_back (*newobj);
     }
 
   return dst;
@@ -1186,11 +1183,11 @@ 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 struct so_list *
+static intrusive_list<so_list>
 svr4_default_sos (svr4_info *info)
 {
   if (!info->debug_loader_offset_p)
-    return NULL;
+    return {};
 
   so_list *newobj = new so_list;
   auto li = gdb::make_unique<lm_info_svr4> ();
@@ -1203,7 +1200,10 @@ svr4_default_sos (svr4_info *info)
   newobj->so_name = info->debug_loader_name;
   newobj->so_original_name = newobj->so_name;
 
-  return newobj;
+  intrusive_list<so_list> sos;
+  sos.push_back (*newobj);
+
+  return sos;
 }
 
 /* Read the whole inferior libraries chain starting at address LM.
@@ -1372,32 +1372,15 @@ svr4_current_sos_direct (struct svr4_info *info)
 
 /* Collect sos read and stored by the probes interface.  */
 
-static so_list *
+static intrusive_list<so_list>
 svr4_collect_probes_sos (svr4_info *info)
 {
-  so_list *res = nullptr;
-  so_list **pnext = &res;
+  intrusive_list<so_list> res;
 
   for (const auto &tuple : info->solib_lists)
     {
       const std::vector<svr4_so> &sos = tuple.second;
-
-      /* Allow the linker to report empty namespaces.  */
-      if (sos.empty ())
-       continue;
-
-      *pnext = so_list_from_svr4_sos (sos);
-
-      /* Update PNEXT to point to the next member of the last element.  */
-      gdb_assert (*pnext != nullptr);
-      for (;;)
-       {
-         so_list *next = *pnext;
-         if (next == nullptr)
-           break;
-
-         pnext = &next->next;
-       }
+      res.splice (so_list_from_svr4_sos (sos));
     }
 
   return res;
@@ -1406,10 +1389,10 @@ svr4_collect_probes_sos (svr4_info *info)
 /* Implement the main part of the "current_sos" target_so_ops
    method.  */
 
-static struct so_list *
+static intrusive_list<so_list>
 svr4_current_sos_1 (svr4_info *info)
 {
-  so_list *sos = nullptr;
+  intrusive_list<so_list> sos;
 
   /* If we're using the probes interface, we can use the cache as it will
      be maintained by probe update/reload actions.  */
@@ -1419,12 +1402,12 @@ svr4_current_sos_1 (svr4_info *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 == nullptr)
+  if (sos.empty ())
     {
       svr4_current_sos_direct (info);
 
       sos = svr4_collect_probes_sos (info);
-      if (sos == nullptr)
+      if (sos.empty ())
        sos = svr4_default_sos (info);
     }
 
@@ -1433,11 +1416,11 @@ svr4_current_sos_1 (svr4_info *info)
 
 /* Implement the "current_sos" target_so_ops method.  */
 
-static struct so_list *
-svr4_current_sos (void)
+static intrusive_list<so_list>
+svr4_current_sos ()
 {
   svr4_info *info = get_svr4_info (current_program_space);
-  struct so_list *so_head = svr4_current_sos_1 (info);
+  intrusive_list<so_list> sos = svr4_current_sos_1 (info);
   struct mem_range vsyscall_range;
 
   /* Filter out the vDSO module, if present.  Its symbol file would
@@ -1446,13 +1429,8 @@ svr4_current_sos (void)
   if (gdbarch_vsyscall_range (current_inferior ()->arch (), &vsyscall_range)
       && vsyscall_range.length != 0)
     {
-      struct so_list **sop;
-
-      sop = &so_head;
-      while (*sop != NULL)
+      for (auto so = sos.begin (); so != sos.end (); )
        {
-         struct so_list *so = *sop;
-
          /* We can't simply match the vDSO by starting address alone,
             because lm_info->l_addr_inferior (and also l_addr) do not
             necessarily represent the real starting address of the
@@ -1499,16 +1477,17 @@ svr4_current_sos (void)
 
          if (address_in_mem_range (li->l_ld, &vsyscall_range))
            {
-             *sop = so->next;
+             auto next = sos.erase (so);
              free_so (*so);
+             so = next;
              break;
            }
 
-         sop = &so->next;
+         ++so;
        }
     }
 
-  return so_head;
+  return sos;
 }
 
 /* Get the address of the link_map for a given OBJFILE.  */
@@ -1528,11 +1507,11 @@ svr4_fetch_objfile_link_map (struct objfile *objfile)
 
   /* The other link map addresses may be found by examining the list
      of shared libraries.  */
-  for (struct so_list *so : current_program_space->solibs ())
-    if (so->objfile == objfile)
+  for (const so_list &so : current_program_space->solibs ())
+    if (so.objfile == objfile)
       {
        auto *li
-         = gdb::checked_static_cast<lm_info_svr4 *> (so->lm_info.get ());
+         = gdb::checked_static_cast<lm_info_svr4 *> (so.lm_info.get ());
 
        return li->lm_addr;
       }
@@ -2369,13 +2348,13 @@ enable_break (struct svr4_info *info, int from_tty)
 
       /* On a running target, we can get the dynamic linker's base
         address from the shared library table.  */
-      for (struct so_list *so : current_program_space->solibs ())
+      for (const so_list &so : current_program_space->solibs ())
        {
-         if (svr4_same_1 (interp_name, so->so_original_name.c_str ()))
+         if (svr4_same_1 (interp_name, so.so_original_name.c_str ()))
            {
              load_addr_found = 1;
              loader_found_in_list = 1;
-             load_addr = lm_addr_check (*so, tmp_bfd.get ());
+             load_addr = lm_addr_check (so, tmp_bfd.get ());
              break;
            }
        }
@@ -3259,7 +3238,7 @@ svr4_lp64_fetch_link_map_offsets (void)
 
 /* Return the DSO matching OBJFILE or nullptr if none can be found.  */
 
-static so_list *
+static const so_list *
 find_solib_for_objfile (struct objfile *objfile)
 {
   if (objfile == nullptr)
@@ -3270,9 +3249,9 @@ find_solib_for_objfile (struct objfile *objfile)
   if (objfile->separate_debug_objfile_backlink != nullptr)
     objfile = objfile->separate_debug_objfile_backlink;
 
-  for (so_list *so : current_program_space->solibs ())
-    if (so->objfile == objfile)
-      return so;
+  for (const so_list &so : current_program_space->solibs ())
+    if (so.objfile == objfile)
+      return &so;
 
   return nullptr;
 }
@@ -3285,7 +3264,7 @@ find_solib_for_objfile (struct objfile *objfile)
    right thing for the main executable.  */
 
 static CORE_ADDR
-find_debug_base_for_solib (so_list *solib)
+find_debug_base_for_solib (const so_list *solib)
 {
   if (solib == nullptr)
     return 0;
@@ -3346,7 +3325,7 @@ svr4_iterate_over_objfiles_in_search_order
   /* The linker namespace to iterate identified by the address of its
      r_debug object, defaulting to the initial namespace.  */
   CORE_ADDR initial = elf_locate_base ();
-  so_list *curr_solib = find_solib_for_objfile (current_objfile);
+  const so_list *curr_solib = find_solib_for_objfile (current_objfile);
   CORE_ADDR debug_base = find_debug_base_for_solib (curr_solib);
   if (debug_base == 0)
     debug_base = initial;
@@ -3361,7 +3340,7 @@ svr4_iterate_over_objfiles_in_search_order
         If we fail, e.g. for manually added symbol files or for the main
         executable, we assume that they were added to the initial
         namespace.  */
-      so_list *solib = find_solib_for_objfile (objfile);
+      const so_list *solib = find_solib_for_objfile (objfile);
       CORE_ADDR solib_base = find_debug_base_for_solib (solib);
       if (solib_base == 0)
        solib_base = initial;
index 0881d7eda430558554af2c8caf5a570322755526..2e1c74f97e70d34d5a19d45bbe2a956db592b247 100644 (file)
@@ -227,25 +227,22 @@ solib_target_parse_libraries (const char *library)
 }
 #endif
 
-static struct so_list *
+static intrusive_list<so_list>
 solib_target_current_sos (void)
 {
-  so_list *start = NULL, *last = NULL;
+  intrusive_list<so_list> sos;
 
   /* Fetch the list of shared libraries.  */
   gdb::optional<gdb::char_vector> library_document
     = target_read_stralloc (current_inferior ()->top_target (),
                            TARGET_OBJECT_LIBRARIES, NULL);
   if (!library_document)
-    return NULL;
+    return {};
 
   /* Parse the list.  */
   std::vector<lm_info_target_up> library_list
     = solib_target_parse_libraries (library_document->data ());
 
-  if (library_list.empty ())
-    return NULL;
-
   /* Build a struct so_list for each entry on the list.  */
   for (lm_info_target_up &info : library_list)
     {
@@ -257,16 +254,10 @@ solib_target_current_sos (void)
       new_solib->lm_info = std::move (info);
 
       /* Add it to the list.  */
-      if (!start)
-       last = start = new_solib;
-      else
-       {
-         last->next = new_solib;
-         last = new_solib;
-       }
+      sos.push_back (*new_solib);
     }
 
-  return start;
+  return sos;
 }
 
 static void
index 6a3da1660bd459354af5d291d9b2d0d999e58e8c..b0ae9347f024c243c3857ba7391a458179c6a050 100644 (file)
@@ -734,10 +734,10 @@ solib_read_symbols (so_list &so, symfile_add_flags flags)
    in the list of shared libraries.  Return false otherwise.  */
 
 static bool
-solib_used (const struct so_list *const known)
+solib_used (const so_list &known)
 {
-  for (const struct so_list *pivot : current_program_space->solibs ())
-    if (pivot != known && pivot->objfile == known->objfile)
+  for (const so_list &pivot : current_program_space->solibs ())
+    if (&pivot != &known && pivot.objfile == known.objfile)
       return true;
   return false;
 }
@@ -766,8 +766,6 @@ void
 update_solib_list (int from_tty)
 {
   const target_so_ops *ops = gdbarch_so_ops (current_inferior ()->arch ());
-  struct so_list *inferior = ops->current_sos();
-  struct so_list *gdb, **gdb_link;
 
   /* We can reach here due to changing solib-search-path or the
      sysroot, before having any inferior.  */
@@ -818,42 +816,38 @@ update_solib_list (int from_tty)
      the time we're done walking GDB's list, the inferior's list
      contains only the new shared objects, which we then add.  */
 
-  gdb = current_program_space->so_list;
-  gdb_link = &current_program_space->so_list;
-  while (gdb)
+  intrusive_list<so_list> inferior = ops->current_sos ();
+  intrusive_list<so_list>::iterator gdb_iter
+    = current_program_space->so_list.begin ();
+  while (gdb_iter != current_program_space->so_list.end ())
     {
-      struct so_list *i = inferior;
-      struct so_list **i_link = &inferior;
+      intrusive_list<so_list>::iterator inferior_iter = inferior.begin ();
 
       /* Check to see whether the shared object *gdb also appears in
         the inferior's current list.  */
-      while (i)
+      for (; inferior_iter != inferior.end (); ++inferior_iter)
        {
          if (ops->same)
            {
-             if (ops->same (*gdb, *i))
+             if (ops->same (*gdb_iter, *inferior_iter))
                break;
            }
          else
            {
-             if (filename_cmp (gdb->so_original_name.c_str (),
-                               i->so_original_name.c_str ()) == 0)
-               break;        
+             if (!filename_cmp (gdb_iter->so_original_name.c_str (),
+                                inferior_iter->so_original_name.c_str ()))
+               break;
            }
-
-         i_link = &i->next;
-         i = *i_link;
        }
 
       /* 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
         it from the inferior's list, and leave it on GDB's list.  */
-      if (i)
+      if (inferior_iter != inferior.end ())
        {
-         *i_link = i->next;
-         free_so (*i);
-         gdb_link = &gdb->next;
-         gdb = *gdb_link;
+         inferior.erase (inferior_iter);
+         free_so (*inferior_iter);
+         ++gdb_iter;
        }
 
       /* If it's not on the inferior's list, remove it from GDB's tables.  */
@@ -861,52 +855,49 @@ update_solib_list (int from_tty)
        {
          /* Notify any observer that the shared object has been
             unloaded before we remove it from GDB's tables.  */
-         notify_solib_unloaded (current_program_space, *gdb);
+         notify_solib_unloaded (current_program_space, *gdb_iter);
 
-         current_program_space->deleted_solibs.push_back (gdb->so_name);
+         current_program_space->deleted_solibs.push_back (gdb_iter->so_name);
 
-         *gdb_link = gdb->next;
+         intrusive_list<so_list>::iterator gdb_iter_next
+           = current_program_space->so_list.erase (gdb_iter);
 
          /* Unless the user loaded it explicitly, free SO's objfile.  */
-         if (gdb->objfile && ! (gdb->objfile->flags & OBJF_USERLOADED)
-             && !solib_used (gdb))
-           gdb->objfile->unlink ();
+         if (gdb_iter->objfile != nullptr
+             && !(gdb_iter->objfile->flags & OBJF_USERLOADED)
+             && !solib_used (*gdb_iter))
+           gdb_iter->objfile->unlink ();
 
          /* Some targets' section tables might be referring to
             sections from so.abfd; remove them.  */
-         current_program_space->remove_target_sections (gdb);
+         current_program_space->remove_target_sections (&*gdb_iter);
 
-         free_so (*gdb);
-         gdb = *gdb_link;
+         free_so (*gdb_iter);
+         gdb_iter = gdb_iter_next;
        }
     }
 
   /* Now the inferior's list contains only shared objects that don't
      appear in GDB's list --- those that are newly loaded.  Add them
      to GDB's shared object list.  */
-  if (inferior)
+  if (!inferior.empty ())
     {
       int not_found = 0;
       const char *not_found_filename = NULL;
 
-      struct so_list *i;
-
-      /* Add the new shared objects to GDB's list.  */
-      *gdb_link = inferior;
-
       /* Fill in the rest of each of the `struct so_list' nodes.  */
-      for (i = inferior; i; i = i->next)
+      for (so_list &new_so : inferior)
        {
-         current_program_space->added_solibs.push_back (i);
+         current_program_space->added_solibs.push_back (&new_so);
 
          try
            {
              /* Fill in the rest of the `struct so_list' node.  */
-             if (!solib_map_sections (*i))
+             if (!solib_map_sections (new_so))
                {
                  not_found++;
                  if (not_found_filename == NULL)
-                   not_found_filename = i->so_original_name.c_str ();
+                   not_found_filename = new_so.so_original_name.c_str ();
                }
            }
 
@@ -919,9 +910,12 @@ update_solib_list (int from_tty)
 
          /* Notify any observer that the shared object has been
             loaded now that we've added it to GDB's tables.  */
-         notify_solib_loaded (*i);
+         notify_solib_loaded (new_so);
        }
 
+      /* Add the new shared objects to GDB's list.  */
+      current_program_space->so_list.splice (std::move (inferior));
+
       /* If a library was not found, issue an appropriate warning
         message.  We have to use a single call to warning in case the
         front end does something special with warnings, e.g., pop up
@@ -1015,8 +1009,8 @@ solib_add (const char *pattern, int from_tty, int readsyms)
     if (from_tty)
        add_flags |= SYMFILE_VERBOSE;
 
-    for (struct so_list *gdb : current_program_space->solibs ())
-      if (! pattern || re_exec (gdb->so_name.c_str ()))
+    for (so_list &gdb : current_program_space->solibs ())
+      if (! pattern || re_exec (gdb.so_name.c_str ()))
        {
          /* Normally, we would read the symbols from that library
             only if READSYMS is set.  However, we're making a small
@@ -1024,20 +1018,20 @@ solib_add (const char *pattern, int from_tty, int readsyms)
             need the library symbols to be loaded in order to provide
             thread support (x86-linux for instance).  */
          const int add_this_solib =
-           (readsyms || libpthread_solib_p (*gdb));
+           (readsyms || libpthread_solib_p (gdb));
 
          any_matches = true;
          if (add_this_solib)
            {
-             if (gdb->symbols_loaded)
+             if (gdb.symbols_loaded)
                {
                  /* If no pattern was given, be quiet for shared
                     libraries we have already loaded.  */
                  if (pattern && (from_tty || info_verbose))
                    gdb_printf (_("Symbols already loaded for %s\n"),
-                               gdb->so_name.c_str ());
+                               gdb.so_name.c_str ());
                }
-             else if (solib_read_symbols (*gdb, add_flags))
+             else if (solib_read_symbols (gdb, add_flags))
                loaded_any_symbols = true;
            }
        }
@@ -1089,11 +1083,11 @@ info_sharedlibrary_command (const char *pattern, int from_tty)
      so we need to make two passes over the libs.  */
 
   nr_libs = 0;
-  for (struct so_list *so : current_program_space->solibs ())
+  for (const so_list &so : current_program_space->solibs ())
     {
-      if (!so->so_name.empty ())
+      if (!so.so_name.empty ())
        {
-         if (pattern && ! re_exec (so->so_name.c_str ()))
+         if (pattern && ! re_exec (so.so_name.c_str ()))
            continue;
          ++nr_libs;
        }
@@ -1110,20 +1104,20 @@ info_sharedlibrary_command (const char *pattern, int from_tty)
 
     uiout->table_body ();
 
-    for (struct so_list *so : current_program_space->solibs ())
+    for (const so_list &so : current_program_space->solibs ())
       {
-       if (so->so_name.empty ())
+       if (so.so_name.empty ())
          continue;
 
-       if (pattern && ! re_exec (so->so_name.c_str ()))
+       if (pattern && ! re_exec (so.so_name.c_str ()))
          continue;
 
        ui_out_emit_tuple tuple_emitter (uiout, "lib");
 
-       if (so->addr_high != 0)
+       if (so.addr_high != 0)
          {
-           uiout->field_core_addr ("from", gdbarch, so->addr_low);
-           uiout->field_core_addr ("to", gdbarch, so->addr_high);
+           uiout->field_core_addr ("from", gdbarch, so.addr_low);
+           uiout->field_core_addr ("to", gdbarch, so.addr_high);
          }
        else
          {
@@ -1132,16 +1126,16 @@ info_sharedlibrary_command (const char *pattern, int from_tty)
          }
 
        if (! top_level_interpreter ()->interp_ui_out ()->is_mi_like_p ()
-           && so->symbols_loaded
-           && !objfile_has_symbols (so->objfile))
+           && so.symbols_loaded
+           && !objfile_has_symbols (so.objfile))
          {
            so_missing_debug_info = true;
            uiout->field_string ("syms-read", "Yes (*)");
          }
        else
-         uiout->field_string ("syms-read", so->symbols_loaded ? "Yes" : "No");
+         uiout->field_string ("syms-read", so.symbols_loaded ? "Yes" : "No");
 
-       uiout->field_string ("name", so->so_name, file_name_style.style ());
+       uiout->field_string ("name", so.so_name, file_name_style.style ());
 
        uiout->text ("\n");
       }
@@ -1189,13 +1183,11 @@ solib_contains_address_p (const so_list &solib,
 const char *
 solib_name_from_address (struct program_space *pspace, CORE_ADDR address)
 {
-  struct so_list *so = NULL;
-
-  for (so = pspace->so_list; so; so = so->next)
-    if (solib_contains_address_p (*so, address))
-      return so->so_name.c_str ();
+  for (const so_list &so : pspace->so_list)
+    if (solib_contains_address_p (so, address))
+      return so.so_name.c_str ();
 
-  return (0);
+  return nullptr;
 }
 
 /* See solib.h.  */
@@ -1220,15 +1212,13 @@ clear_solib (void)
 
   disable_breakpoints_in_shlibs ();
 
-  while (current_program_space->so_list)
+  current_program_space->so_list.clear_and_dispose ([] (so_list *so)
     {
-      struct so_list *so = current_program_space->so_list;
-
-      current_program_space->so_list = so->next;
       notify_solib_unloaded (current_program_space, *so);
-      current_program_space->remove_target_sections (so);
+      current_program_space->remove_target_sections (&so);
       free_so (*so);
-    }
+    });
+
 
   if (ops->clear_solib != nullptr)
     ops->clear_solib (current_program_space);
@@ -1323,17 +1313,17 @@ reload_shared_libraries_1 (int from_tty)
   if (print_symbol_loading_p (from_tty, 0, 0))
     gdb_printf (_("Loading symbols for shared libraries.\n"));
 
-  for (struct so_list *so : current_program_space->solibs ())
+  for (so_list &so : current_program_space->solibs ())
     {
       const char *found_pathname = NULL;
-      bool was_loaded = so->symbols_loaded != 0;
+      bool was_loaded = so.symbols_loaded != 0;
       symfile_add_flags add_flags = SYMFILE_DEFER_BP_RESET;
 
       if (from_tty)
        add_flags |= SYMFILE_VERBOSE;
 
       gdb::unique_xmalloc_ptr<char> filename
-       (tilde_expand (so->so_original_name.c_str ()));
+       (tilde_expand (so.so_original_name.c_str ()));
       gdb_bfd_ref_ptr abfd (solib_bfd_open (filename.get ()));
       if (abfd != NULL)
        found_pathname = bfd_get_filename (abfd.get ());
@@ -1342,26 +1332,26 @@ reload_shared_libraries_1 (int from_tty)
         symbol file, close that.  */
       if ((found_pathname == NULL && was_loaded)
          || (found_pathname != NULL
-             && filename_cmp (found_pathname, so->so_name.c_str ()) != 0))
+             && filename_cmp (found_pathname, so.so_name.c_str ()) != 0))
        {
-         if (so->objfile && ! (so->objfile->flags & OBJF_USERLOADED)
+         if (so.objfile && ! (so.objfile->flags & OBJF_USERLOADED)
              && !solib_used (so))
-           so->objfile->unlink ();
-         current_program_space->remove_target_sections (so);
-         so->clear ();
+           so.objfile->unlink ();
+         current_program_space->remove_target_sections (&so);
+         so.clear ();
        }
 
       /* If this shared library is now associated with a new symbol
         file, open it.  */
       if (found_pathname != NULL
          && (!was_loaded
-             || filename_cmp (found_pathname, so->so_name.c_str ()) != 0))
+             || filename_cmp (found_pathname, so.so_name.c_str ()) != 0))
        {
          bool got_error = false;
 
          try
            {
-             solib_map_sections (*so);
+             solib_map_sections (so);
            }
 
          catch (const gdb_exception_error &e)
@@ -1373,8 +1363,8 @@ reload_shared_libraries_1 (int from_tty)
            }
 
            if (!got_error
-               && (auto_solib_add || was_loaded || libpthread_solib_p (*so)))
-             solib_read_symbols (*so, add_flags);
+               && (auto_solib_add || was_loaded || libpthread_solib_p (so)))
+             solib_read_symbols (so, add_flags);
        }
     }
 }
@@ -1730,9 +1720,9 @@ remove_user_added_objfile (struct objfile *objfile)
 {
   if (objfile != 0 && objfile->flags & OBJF_USERLOADED)
     {
-      for (struct so_list *so : objfile->pspace->solibs ())
-       if (so->objfile == objfile)
-         so->objfile = NULL;
+      for (so_list &so : objfile->pspace->solibs ())
+       if (so.objfile == objfile)
+         so.objfile = nullptr;
     }
 }
 
index 9320acb7fd3e6224a7a24003e126ac364dc418fe..e22fd207c396a0c5d15117c807a4bd737644fcc7 100644 (file)
@@ -36,7 +36,7 @@ struct lm_info
 
 using lm_info_up = std::unique_ptr<lm_info>;
 
-struct so_list
+struct so_list : intrusive_list_node<so_list>
 {
   /* 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
@@ -52,8 +52,6 @@ struct so_list
      dynamic linker's tables in the inferior, and are initialized by
      current_sos.  */
 
-  struct so_list *next = nullptr;      /* next structure in linked list */
-
   /* A pointer to target specific link map information.  Often this
      will be a copy of struct link_map from the user process, but
      it need not be; it can be any collection of data needed to
@@ -121,7 +119,7 @@ struct target_so_ops
      inferior --- we don't examine any of the shared library files
      themselves.  The declaration of `struct so_list' says which fields
      we provide values for.  */
-  struct so_list *(*current_sos) (void);
+  intrusive_list<so_list> (*current_sos) ();
 
   /* Find, open, and read the symbols for the main executable.  If
      FROM_TTY is non-zero, allow messages to be printed.  */
@@ -171,8 +169,6 @@ struct target_so_ops
   void (*handle_event) (void);
 };
 
-using so_list_range = next_range<so_list>;
-
 /* Free the memory associated with a (so_list *).  */
 void free_so (so_list &so);