/* 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);
}
}
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 ();
#include "solist.h"
#include "gdbsupport/next-iterator.h"
#include "gdbsupport/safe-iterator.h"
+#include "gdbsupport/intrusive_list.h"
#include <list>
#include <vector>
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. */
/* 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;
/* 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;
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. */
/* 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];
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
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,
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
{
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
/* 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,
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
{
enable_break2 ();
- return sos_head;
+ return sos;
}
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++)
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;
/* 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;
}
/* 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)
{
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;
/* 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 {
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;
/* 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)
{
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;
/* 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> ();
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.
/* 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;
/* 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. */
/* 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);
}
/* 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
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
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. */
/* 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;
}
/* 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;
}
}
/* 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)
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;
}
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;
/* 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;
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;
}
#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)
{
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
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;
}
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. */
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<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. */
{
/* 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 ();
}
}
/* 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
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
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;
}
}
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;
}
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
{
}
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");
}
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. */
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);
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 ());
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)
}
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);
}
}
}
{
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;
}
}
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
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
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. */
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);