From 8971d2788e79db2ffc1205ed36935483eedf2fab Mon Sep 17 00:00:00 2001 From: Simon Marchi Date: Thu, 19 Oct 2023 10:55:38 -0400 Subject: gdb: link so_list using intrusive_list Replace the hand-made linked list implementation with intrusive_list, simplying management of list items. Change-Id: I7f55fd88325bb197cc655c9be5a2ec966d8cc48d Approved-By: Pedro Alves Reviewed-By: Reviewed-By: Lancelot Six --- gdb/mi/mi-cmd-file.c | 8 +-- gdb/progspace.c | 4 +- gdb/progspace.h | 12 ++-- gdb/solib-aix.c | 23 +++---- gdb/solib-darwin.c | 23 +++---- gdb/solib-dsbt.c | 12 ++-- gdb/solib-frv.c | 30 ++++----- gdb/solib-rocm.c | 26 +++----- gdb/solib-svr4.c | 97 ++++++++++++----------------- gdb/solib-target.c | 19 ++---- gdb/solib.c | 168 ++++++++++++++++++++++++--------------------------- gdb/solist.h | 8 +-- 12 files changed, 178 insertions(+), 252 deletions(-) (limited to 'gdb') diff --git a/gdb/mi/mi-cmd-file.c b/gdb/mi/mi-cmd-file.c index 30682da..b9231b7 100644 --- a/gdb/mi/mi-cmd-file.c +++ b/gdb/mi/mi-cmd-file.c @@ -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); } } diff --git a/gdb/progspace.c b/gdb/progspace.c index 555fa79..4b816b4 100644 --- a/gdb/progspace.c +++ b/gdb/progspace.c @@ -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 (); diff --git a/gdb/progspace.h b/gdb/progspace.h index 20dfc2e..0a762e6 100644 --- a/gdb/progspace.h +++ b/gdb/progspace.h @@ -28,6 +28,7 @@ #include "solist.h" #include "gdbsupport/next-iterator.h" #include "gdbsupport/safe-iterator.h" +#include "gdbsupport/intrusive_list.h" #include #include @@ -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 &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 so_list; /* Number of calls to solib_add. */ unsigned int solib_add_generation = 0; diff --git a/gdb/solib-aix.c b/gdb/solib-aix.c index e5e86c4..68798e8 100644 --- a/gdb/solib-aix.c +++ b/gdb/solib-aix.c @@ -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 +solib_aix_current_sos () { - struct so_list *start = NULL, *last = NULL; - int ix; - gdb::optional> &library_list = solib_aix_get_library_list (current_inferior (), NULL); if (!library_list.has_value ()) - return NULL; + return {}; + + intrusive_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 (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. */ diff --git a/gdb/solib-darwin.c b/gdb/solib-darwin.c index a235f8a..57e61f9 100644 --- a/gdb/solib-darwin.c +++ b/gdb/solib-darwin.c @@ -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 +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 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 diff --git a/gdb/solib-dsbt.c b/gdb/solib-dsbt.c index d4383dd..d74ccdd 100644 --- a/gdb/solib-dsbt.c +++ b/gdb/solib-dsbt.c @@ -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 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 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 diff --git a/gdb/solib-frv.c b/gdb/solib-frv.c index d92c353..c391462 100644 --- a/gdb/solib-frv.c +++ b/gdb/solib-frv.c @@ -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 +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 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 (so->lm_info.get ()); + auto *li = gdb::checked_static_cast (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 (so->lm_info.get ()); + auto *li = gdb::checked_static_cast (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 (so->lm_info.get ()); + auto *li = gdb::checked_static_cast (so.lm_info.get ()); - if (so->objfile == objfile) + if (so.objfile == objfile) return li->lm_addr; } diff --git a/gdb/solib-rocm.c b/gdb/solib-rocm.c index 938c040..3dc9a06 100644 --- a/gdb/solib-rocm.c +++ b/gdb/solib-rocm.c @@ -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_from_rocm_sos (const std::vector &sos) { - struct so_list *dst = nullptr; - struct so_list **link = &dst; + intrusive_list dst; for (const rocm_so &so : sos) { @@ -218,9 +217,7 @@ so_list_from_rocm_sos (const std::vector &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 &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 rocm_solib_current_sos () { /* First, retrieve the host-side shared library list. */ - so_list *head = svr4_so_ops.current_sos (); + intrusive_list sos = svr4_so_ops.current_sos (); /* Then, the device-side shared library list. */ std::vector &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 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 { diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c index b90b4ca..6311599 100644 --- a/gdb/solib-svr4.c +++ b/gdb/solib-svr4.c @@ -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 *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_from_svr4_sos (const std::vector &sos) { - struct so_list *dst = NULL; - struct so_list **link = &dst; + intrusive_list dst; for (const svr4_so &so : sos) { @@ -1004,9 +1003,7 @@ so_list_from_svr4_sos (const std::vector &sos) newobj->so_original_name = so.name; newobj->lm_info = gdb::make_unique (*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 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 (); @@ -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 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 svr4_collect_probes_sos (svr4_info *info) { - so_list *res = nullptr; - so_list **pnext = &res; + intrusive_list res; for (const auto &tuple : info->solib_lists) { const std::vector &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 svr4_current_sos_1 (svr4_info *info) { - so_list *sos = nullptr; + intrusive_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 +svr4_current_sos () { svr4_info *info = get_svr4_info (current_program_space); - struct so_list *so_head = svr4_current_sos_1 (info); + intrusive_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 (so->lm_info.get ()); + = gdb::checked_static_cast (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; diff --git a/gdb/solib-target.c b/gdb/solib-target.c index 0881d7e..2e1c74f 100644 --- a/gdb/solib-target.c +++ b/gdb/solib-target.c @@ -227,25 +227,22 @@ solib_target_parse_libraries (const char *library) } #endif -static struct so_list * +static intrusive_list solib_target_current_sos (void) { - so_list *start = NULL, *last = NULL; + intrusive_list sos; /* Fetch the list of shared libraries. */ gdb::optional library_document = target_read_stralloc (current_inferior ()->top_target (), TARGET_OBJECT_LIBRARIES, NULL); if (!library_document) - return NULL; + return {}; /* Parse the list. */ std::vector 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 diff --git a/gdb/solib.c b/gdb/solib.c index 6a3da16..b0ae934 100644 --- a/gdb/solib.c +++ b/gdb/solib.c @@ -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 = ¤t_program_space->so_list; - while (gdb) + intrusive_list inferior = ops->current_sos (); + intrusive_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::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::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 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; } } diff --git a/gdb/solist.h b/gdb/solist.h index 9320acb..e22fd20 100644 --- a/gdb/solist.h +++ b/gdb/solist.h @@ -36,7 +36,7 @@ struct lm_info using lm_info_up = std::unique_ptr; -struct so_list +struct so_list : intrusive_list_node { /* 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 (*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; - /* Free the memory associated with a (so_list *). */ void free_so (so_list &so); -- cgit v1.1