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 <pedro@palves.net> Reviewed-By: Reviewed-By: Lancelot Six <lancelot.six@amd.com>
This commit is contained in:
parent
98107b0b17
commit
8971d2788e
12 changed files with 178 additions and 252 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 ();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
168
gdb/solib.c
168
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<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 (const so_list &so : pspace->so_list)
|
||||
if (solib_contains_address_p (so, address))
|
||||
return so.so_name.c_str ();
|
||||
|
||||
for (so = pspace->so_list; so; so = so->next)
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue