gdb: make solib-svr4 not use so_list internally

A subsequent patch makes use of non-trivial types in struct so_list.
This trips on the fact that svr4_copy_library_list uses memcpy to copy
so_list objects:

      so_list *newobj = new so_list;
      memcpy (newobj, src, sizeof (struct so_list));

solib-svr4 maintains lists of so_list objects in its own internal data
structures.  When requested to return a list of so_list objects (through
target_so_ops::current_sos), it duplicates the internal so_list lists,
using memcpy.  When changing so_list to make it non-trivial, we would
need to replace this use of memcpy somehow.  That would mean making
so_list copyable, with all the complexity that entails, just to satisfy
this internal usage of solib-svr4 (and solib-rocm, which does the same).

Change solib-svr4 to use its own data type for its internal lists.  The
use of so_list is a bit overkill anyway, as most fields of so_list are
irrelevant for this internal use.

 - Introduce svr4_so, which contains just an std::string for the name
   and a unique_ptr for the lm_info.
 - Change the internal so_list lists to be std::vector<svr4_so>.  Vector
   seems like a good choice for this, we don't need to insert/remove
   elements in the middle of these internal lists.
 - Remove svr4_free_library_list, free_solib_lists and ~svr4_info, as
   everything is managed automatically now.
 - Replace svr4_copy_library_list (which duplicated internal lists in
   order to return them to the core) with so_list_from_svr4_sos, which
   creates an so_list list from a vector of svr4_so.
 - Generalize svr4_same a bit, because find_debug_base_for_solib now
   needs to compare an so_list and an svr4_so to see if they are the
   same.

Change-Id: I6012e48e07aace2a8172b74b389f9547ce777877
Approved-By: Pedro Alves <pedro@palves.net>
Reviewed-By: Reviewed-By: Lancelot Six <lancelot.six@amd.com>
This commit is contained in:
Simon Marchi 2023-10-10 14:45:05 -04:00
parent 3fcbae9d9c
commit 96bb3873ec
2 changed files with 100 additions and 177 deletions

View file

@ -50,7 +50,6 @@
static struct link_map_offsets *svr4_fetch_link_map_offsets (void); static struct link_map_offsets *svr4_fetch_link_map_offsets (void);
static int svr4_have_link_map_offsets (void); static int svr4_have_link_map_offsets (void);
static void svr4_relocate_main_executable (void); static void svr4_relocate_main_executable (void);
static void svr4_free_library_list (so_list *solist);
static void probes_table_remove_objfile_probes (struct objfile *objfile); static void probes_table_remove_objfile_probes (struct objfile *objfile);
static void svr4_iterate_over_objfiles_in_search_order static void svr4_iterate_over_objfiles_in_search_order
(gdbarch *gdbarch, iterate_over_objfiles_in_search_order_cb_ftype cb, (gdbarch *gdbarch, iterate_over_objfiles_in_search_order_cb_ftype cb,
@ -172,26 +171,35 @@ svr4_same_1 (const char *gdb_so_name, const char *inferior_so_name)
return 0; return 0;
} }
static int static bool
svr4_same (const so_list &gdb, const so_list &inferior) svr4_same (const char *gdb_name, const char *inferior_name,
const lm_info_svr4 &gdb_lm_info,
const lm_info_svr4 &inferior_lm_info)
{ {
if (!svr4_same_1 (gdb.so_original_name, inferior.so_original_name)) if (!svr4_same_1 (gdb_name, inferior_name))
return false; return false;
/* There may be different instances of the same library, in different /* There may be different instances of the same library, in different
namespaces. Each instance, however, must have been loaded at a namespaces. Each instance, however, must have been loaded at a
different address so its relocation offset would be different. */ different address so its relocation offset would be different. */
return gdb_lm_info.l_addr_inferior == inferior_lm_info.l_addr_inferior;
}
static int
svr4_same (const so_list &gdb, const so_list &inferior)
{
auto *lmg = gdb::checked_static_cast<const lm_info_svr4 *> (gdb.lm_info); auto *lmg = gdb::checked_static_cast<const lm_info_svr4 *> (gdb.lm_info);
auto *lmi = gdb::checked_static_cast<const lm_info_svr4 *> (inferior.lm_info); auto *lmi = gdb::checked_static_cast<const lm_info_svr4 *> (inferior.lm_info);
return (lmg->l_addr_inferior == lmi->l_addr_inferior); return svr4_same (gdb.so_original_name, inferior.so_original_name,
*lmg, *lmi);
} }
static std::unique_ptr<lm_info_svr4> static lm_info_svr4_up
lm_info_read (CORE_ADDR lm_addr) lm_info_read (CORE_ADDR lm_addr)
{ {
struct link_map_offsets *lmo = svr4_fetch_link_map_offsets (); struct link_map_offsets *lmo = svr4_fetch_link_map_offsets ();
std::unique_ptr<lm_info_svr4> lm_info; lm_info_svr4_up lm_info;
gdb::byte_vector lm (lmo->link_map_size); gdb::byte_vector lm (lmo->link_map_size);
@ -203,7 +211,7 @@ lm_info_read (CORE_ADDR lm_addr)
type *ptr_type type *ptr_type
= builtin_type (current_inferior ()->arch ())->builtin_data_ptr; = builtin_type (current_inferior ()->arch ())->builtin_data_ptr;
lm_info.reset (new lm_info_svr4); lm_info = gdb::make_unique<lm_info_svr4> ();
lm_info->lm_addr = lm_addr; lm_info->lm_addr = lm_addr;
lm_info->l_addr_inferior = extract_typed_address (&lm[lmo->l_addr_offset], lm_info->l_addr_inferior = extract_typed_address (&lm[lmo->l_addr_offset],
@ -333,13 +341,20 @@ lm_addr_check (const so_list &so, bfd *abfd)
return li->l_addr; return li->l_addr;
} }
struct svr4_so
{
svr4_so (const char *name, lm_info_svr4_up lm_info)
: name (name), lm_info (std::move (lm_info))
{}
std::string name;
lm_info_svr4_up lm_info;
};
/* Per pspace SVR4 specific data. */ /* Per pspace SVR4 specific data. */
struct svr4_info struct svr4_info
{ {
svr4_info () = default;
~svr4_info ();
/* Base of dynamic linker structures in default namespace. */ /* Base of dynamic linker structures in default namespace. */
CORE_ADDR debug_base = 0; CORE_ADDR debug_base = 0;
@ -385,7 +400,7 @@ struct svr4_info
The special entry zero is reserved for a linear list to support The special entry zero is reserved for a linear list to support
gdbstubs that do not support namespaces. */ gdbstubs that do not support namespaces. */
std::map<CORE_ADDR, so_list *> solib_lists; std::map<CORE_ADDR, std::vector<svr4_so>> solib_lists;
}; };
/* Per-program-space data key. */ /* Per-program-space data key. */
@ -407,23 +422,6 @@ free_probes_table (struct svr4_info *info)
info->probes_table.reset (nullptr); info->probes_table.reset (nullptr);
} }
/* Free the solib lists for all namespaces. */
static void
free_solib_lists (svr4_info *info)
{
for (const std::pair<CORE_ADDR, so_list *> tuple
: info->solib_lists)
svr4_free_library_list (tuple.second);
info->solib_lists.clear ();
}
svr4_info::~svr4_info ()
{
free_solib_lists (this);
}
/* Get the svr4 data for program space PSPACE. If none is found yet, add it now. /* Get the svr4 data for program space PSPACE. If none is found yet, add it now.
This function always returns a valid object. */ This function always returns a valid object. */
@ -955,7 +953,7 @@ struct svr4_library_list
{ {
/* The tail pointer of the current namespace. This is internal to XML /* The tail pointer of the current namespace. This is internal to XML
parsing. */ parsing. */
so_list **tailp; std::vector<svr4_so> *cur_list;
/* Inferior address of struct link_map used for the main executable. It is /* Inferior address of struct link_map used for the main executable. It is
NULL if not known. */ NULL if not known. */
@ -965,7 +963,7 @@ struct svr4_library_list
not include any default sos. not include any default sos.
See comment on struct svr4_info.solib_lists. */ See comment on struct svr4_info.solib_lists. */
std::map<CORE_ADDR, so_list *> solib_lists; std::map<CORE_ADDR, std::vector<svr4_so>> solib_lists;
}; };
/* This module's 'free_objfile' observer. */ /* This module's 'free_objfile' observer. */
@ -987,41 +985,27 @@ svr4_clear_so (const so_list &so)
li->l_addr_p = 0; li->l_addr_p = 0;
} }
/* Free so_list built so far. */ /* Create the so_list objects equivalent to the svr4_sos in SOS. */
static void static so_list *
svr4_free_library_list (so_list *list) so_list_from_svr4_sos (const std::vector<svr4_so> &sos)
{
while (list != NULL)
{
struct so_list *next = list->next;
free_so (*list);
list = next;
}
}
/* Copy library list. */
static struct so_list *
svr4_copy_library_list (struct so_list *src)
{ {
struct so_list *dst = NULL; struct so_list *dst = NULL;
struct so_list **link = &dst; struct so_list **link = &dst;
while (src != NULL) for (const svr4_so &so : sos)
{ {
so_list *newobj = new so_list; so_list *newobj = new so_list;
memcpy (newobj, src, sizeof (struct so_list));
auto *src_li = gdb::checked_static_cast<lm_info_svr4 *> (src->lm_info); strncpy (newobj->so_name, so.name.c_str (),
newobj->lm_info = new lm_info_svr4 (*src_li); sizeof (newobj->so_name) - 1);
newobj->so_name[sizeof (newobj->so_name) - 1] = 0;
strcpy (newobj->so_original_name, newobj->so_name);
newobj->lm_info = new lm_info_svr4 (*so.lm_info);
newobj->next = NULL; newobj->next = NULL;
*link = newobj; *link = newobj;
link = &newobj->next; link = &newobj->next;
src = src->next;
} }
return dst; return dst;
@ -1050,48 +1034,25 @@ library_list_start_library (struct gdb_xml_parser *parser,
ULONGEST *l_ldp ULONGEST *l_ldp
= (ULONGEST *) xml_find_attribute (attributes, "l_ld")->value.get (); = (ULONGEST *) xml_find_attribute (attributes, "l_ld")->value.get ();
so_list *new_elem = new so_list; lm_info_svr4_up li = gdb::make_unique<lm_info_svr4> ();
lm_info_svr4 *li = new lm_info_svr4;
new_elem->lm_info = li;
li->lm_addr = *lmp; li->lm_addr = *lmp;
li->l_addr_inferior = *l_addrp; li->l_addr_inferior = *l_addrp;
li->l_ld = *l_ldp; li->l_ld = *l_ldp;
strncpy (new_elem->so_name, name, sizeof (new_elem->so_name) - 1); std::vector<svr4_so> *solist;
new_elem->so_name[sizeof (new_elem->so_name) - 1] = 0;
strcpy (new_elem->so_original_name, new_elem->so_name);
/* Older versions did not supply lmid. Put the element into the flat /* Older versions did not supply lmid. Put the element into the flat
list of the special namespace zero in that case. */ list of the special namespace zero in that case. */
gdb_xml_value *at_lmid = xml_find_attribute (attributes, "lmid"); gdb_xml_value *at_lmid = xml_find_attribute (attributes, "lmid");
if (at_lmid == nullptr) if (at_lmid == nullptr)
{ solist = list->cur_list;
*list->tailp = new_elem;
list->tailp = &new_elem->next;
}
else else
{ {
ULONGEST lmid = *(ULONGEST *) at_lmid->value.get (); ULONGEST lmid = *(ULONGEST *) at_lmid->value.get ();
solist = &list->solib_lists[lmid];
/* Ensure that the element is actually initialized. */
if (list->solib_lists.find (lmid) == list->solib_lists.end ())
list->solib_lists[lmid] = nullptr;
so_list **psolist = &list->solib_lists[lmid];
so_list **pnext = psolist;
/* Walk to the end of the list if we have one. */
so_list *solist = *psolist;
if (solist != nullptr)
{
for (; solist->next != nullptr; solist = solist->next)
/* Nothing. */;
pnext = &solist->next;
}
*pnext = new_elem;
} }
solist->emplace_back (name, std::move (li));
} }
/* Handle the start of a <library-list-svr4> element. */ /* Handle the start of a <library-list-svr4> element. */
@ -1117,9 +1078,7 @@ svr4_library_list_start_list (struct gdb_xml_parser *parser,
/* Older gdbserver do not support namespaces. We use the special /* Older gdbserver do not support namespaces. We use the special
namespace zero for a linear list of libraries. */ namespace zero for a linear list of libraries. */
so_list **solist = &list->solib_lists[0]; list->cur_list = &list->solib_lists[0];
*solist = nullptr;
list->tailp = solist;
} }
/* The allowed elements and attributes for an XML library list. /* The allowed elements and attributes for an XML library list.
@ -1169,13 +1128,9 @@ static int
svr4_parse_libraries (const char *document, struct svr4_library_list *list) svr4_parse_libraries (const char *document, struct svr4_library_list *list)
{ {
auto cleanup = make_scope_exit ([list] () auto cleanup = make_scope_exit ([list] ()
{ { list->solib_lists.clear (); });
for (const std::pair<CORE_ADDR, so_list *> tuple
: list->solib_lists)
svr4_free_library_list (tuple.second);
});
list->tailp = nullptr; list->cur_list = nullptr;
list->main_lm = 0; list->main_lm = 0;
list->solib_lists.clear (); list->solib_lists.clear ();
if (gdb_xml_parse_quick (_("target library list"), "library-list-svr4.dtd", if (gdb_xml_parse_quick (_("target library list"), "library-list-svr4.dtd",
@ -1253,25 +1208,21 @@ svr4_default_sos (svr4_info *info)
/* Read the whole inferior libraries chain starting at address LM. /* Read the whole inferior libraries chain starting at address LM.
Expect the first entry in the chain's previous entry to be PREV_LM. Expect the first entry in the chain's previous entry to be PREV_LM.
Add the entries to the tail referenced by LINK_PTR_PTR. Ignore the Add the entries to SOS. Ignore the first entry if IGNORE_FIRST and set
first entry if IGNORE_FIRST and set global MAIN_LM_ADDR according global MAIN_LM_ADDR according to it. Returns nonzero upon success. If zero
to it. Returns nonzero upon success. If zero is returned the is returned the entries stored to LINK_PTR_PTR are still valid although they may
entries stored to LINK_PTR_PTR are still valid although they may
represent only part of the inferior library list. */ represent only part of the inferior library list. */
static int static int
svr4_read_so_list (svr4_info *info, CORE_ADDR lm, CORE_ADDR prev_lm, svr4_read_so_list (svr4_info *info, CORE_ADDR lm, CORE_ADDR prev_lm,
struct so_list ***link_ptr_ptr, int ignore_first) std::vector<svr4_so> &sos, int ignore_first)
{ {
CORE_ADDR first_l_name = 0; CORE_ADDR first_l_name = 0;
CORE_ADDR next_lm; CORE_ADDR next_lm;
for (; lm != 0; prev_lm = lm, lm = next_lm) for (; lm != 0; prev_lm = lm, lm = next_lm)
{ {
so_list_up newobj (new so_list); lm_info_svr4_up li = lm_info_read (lm);
lm_info_svr4 *li = lm_info_read (lm).release ();
newobj->lm_info = li;
if (li == NULL) if (li == NULL)
return 0; return 0;
@ -1298,9 +1249,9 @@ svr4_read_so_list (svr4_info *info, CORE_ADDR lm, CORE_ADDR prev_lm,
} }
/* Extract this shared object's name. */ /* Extract this shared object's name. */
gdb::unique_xmalloc_ptr<char> buffer gdb::unique_xmalloc_ptr<char> name
= target_read_string (li->l_name, SO_NAME_MAX_PATH_SIZE - 1); = target_read_string (li->l_name, SO_NAME_MAX_PATH_SIZE - 1);
if (buffer == nullptr) if (name == nullptr)
{ {
/* If this entry's l_name address matches that of the /* If this entry's l_name address matches that of the
inferior executable, then this is not a normal shared inferior executable, then this is not a normal shared
@ -1311,19 +1262,12 @@ svr4_read_so_list (svr4_info *info, CORE_ADDR lm, CORE_ADDR prev_lm,
continue; continue;
} }
strncpy (newobj->so_name, buffer.get (), SO_NAME_MAX_PATH_SIZE - 1);
newobj->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
strcpy (newobj->so_original_name, newobj->so_name);
/* If this entry has no name, or its name matches the name /* If this entry has no name, or its name matches the name
for the main executable, don't include it in the list. */ for the main executable, don't include it in the list. */
if (! newobj->so_name[0] || match_main (newobj->so_name)) if (*name == '\0' || match_main (name.get ()))
continue; continue;
newobj->next = 0; sos.emplace_back (name.get (), std::move (li));
/* Don't free it now. */
**link_ptr_ptr = newobj.release ();
*link_ptr_ptr = &(**link_ptr_ptr)->next;
} }
return 1; return 1;
@ -1342,7 +1286,7 @@ svr4_current_sos_direct (struct svr4_info *info)
struct svr4_library_list library_list; struct svr4_library_list library_list;
/* Remove any old libraries. We're going to read them back in again. */ /* Remove any old libraries. We're going to read them back in again. */
free_solib_lists (info); info->solib_lists.clear ();
/* Fall back to manual examination of the target if the packet is not /* Fall back to manual examination of the target if the packet is not
supported or gdbserver failed to find DT_DEBUG. gdb.server/solib-list.exp supported or gdbserver failed to find DT_DEBUG. gdb.server/solib-list.exp
@ -1362,10 +1306,10 @@ svr4_current_sos_direct (struct svr4_info *info)
/* Remove an empty special zero namespace so we know that when there /* Remove an empty special zero namespace so we know that when there
is one, it is actually used, and we have a flat list without is one, it is actually used, and we have a flat list without
namespace information. */ namespace information. */
if ((library_list.solib_lists.find (0) auto it_0 = library_list.solib_lists.find (0);
!= library_list.solib_lists.end ()) if (it_0 != library_list.solib_lists.end ()
&& (library_list.solib_lists[0] == nullptr)) && it_0->second.empty ())
library_list.solib_lists.erase (0); library_list.solib_lists.erase (it_0);
/* Replace the (empty) solib_lists in INFO with the one generated /* Replace the (empty) solib_lists in INFO with the one generated
from the target. We don't want to copy it on assignment and then from the target. We don't want to copy it on assignment and then
@ -1391,9 +1335,7 @@ svr4_current_sos_direct (struct svr4_info *info)
ignore_first = true; ignore_first = true;
auto cleanup = make_scope_exit ([info] () auto cleanup = make_scope_exit ([info] ()
{ { info->solib_lists.clear (); });
free_solib_lists (info);
});
/* Collect the sos in each namespace. */ /* Collect the sos in each namespace. */
CORE_ADDR debug_base = info->debug_base; CORE_ADDR debug_base = info->debug_base;
@ -1403,12 +1345,8 @@ svr4_current_sos_direct (struct svr4_info *info)
/* Walk the inferior's link map list, and build our so_list list. */ /* Walk the inferior's link map list, and build our so_list list. */
lm = solib_svr4_r_map (debug_base); lm = solib_svr4_r_map (debug_base);
if (lm != 0) if (lm != 0)
{ svr4_read_so_list (info, lm, 0, info->solib_lists[debug_base],
so_list **sos = &info->solib_lists[debug_base]; ignore_first);
*sos = nullptr;
svr4_read_so_list (info, lm, 0, &sos, ignore_first);
}
} }
/* On Solaris, the dynamic linker is not in the normal list of /* On Solaris, the dynamic linker is not in the normal list of
@ -1425,11 +1363,8 @@ svr4_current_sos_direct (struct svr4_info *info)
{ {
/* Add the dynamic linker's namespace unless we already did. */ /* Add the dynamic linker's namespace unless we already did. */
if (info->solib_lists.find (debug_base) == info->solib_lists.end ()) if (info->solib_lists.find (debug_base) == info->solib_lists.end ())
{ svr4_read_so_list (info, debug_base, 0, info->solib_lists[debug_base],
so_list **sos = &info->solib_lists[debug_base]; 0);
*sos = nullptr;
svr4_read_so_list (info, debug_base, 0, &sos, 0);
}
} }
cleanup.release (); cleanup.release ();
@ -1440,19 +1375,18 @@ svr4_current_sos_direct (struct svr4_info *info)
static so_list * static so_list *
svr4_collect_probes_sos (svr4_info *info) svr4_collect_probes_sos (svr4_info *info)
{ {
so_list *sos = nullptr; so_list *res = nullptr;
so_list **pnext = &sos; so_list **pnext = &res;
for (const std::pair<CORE_ADDR, so_list *> tuple for (const auto &tuple : info->solib_lists)
: info->solib_lists)
{ {
so_list *solist = tuple.second; const std::vector<svr4_so> &sos = tuple.second;
/* Allow the linker to report empty namespaces. */ /* Allow the linker to report empty namespaces. */
if (solist == nullptr) if (sos.empty ())
continue; continue;
*pnext = svr4_copy_library_list (solist); *pnext = so_list_from_svr4_sos (sos);
/* Update PNEXT to point to the next member of the last element. */ /* Update PNEXT to point to the next member of the last element. */
gdb_assert (*pnext != nullptr); gdb_assert (*pnext != nullptr);
@ -1466,7 +1400,7 @@ svr4_collect_probes_sos (svr4_info *info)
} }
} }
return sos; return res;
} }
/* Implement the main part of the "current_sos" target_so_ops /* Implement the main part of the "current_sos" target_so_ops
@ -1853,16 +1787,10 @@ solist_update_incremental (svr4_info *info, CORE_ADDR debug_base,
if (info->solib_lists.find (0) != info->solib_lists.end ()) if (info->solib_lists.find (0) != info->solib_lists.end ())
return 0; return 0;
/* Ensure that the element is actually initialized. */ std::vector<svr4_so> &solist = info->solib_lists[debug_base];
if (info->solib_lists.find (debug_base) == info->solib_lists.end ())
info->solib_lists[debug_base] = nullptr;
so_list **psolist = &info->solib_lists[debug_base];
so_list **pnext = nullptr;
so_list *solist = *psolist;
CORE_ADDR prev_lm; CORE_ADDR prev_lm;
if (solist == nullptr) if (solist.empty ())
{ {
/* svr4_current_sos_direct contains logic to handle a number of /* svr4_current_sos_direct contains logic to handle a number of
special cases relating to the first elements of the list in special cases relating to the first elements of the list in
@ -1872,18 +1800,9 @@ solist_update_incremental (svr4_info *info, CORE_ADDR debug_base,
return 0; return 0;
prev_lm = 0; prev_lm = 0;
pnext = psolist;
} }
else else
{ prev_lm = solist.back ().lm_info->lm_addr;
/* Walk to the end of the list. */
for (; solist->next != nullptr; solist = solist->next)
/* Nothing. */;
auto *li = gdb::checked_static_cast<lm_info_svr4 *> (solist->lm_info);
prev_lm = li->lm_addr;
pnext = &solist->next;
}
/* Read the new objects. */ /* Read the new objects. */
if (info->using_xfer) if (info->using_xfer)
@ -1905,24 +1824,23 @@ solist_update_incremental (svr4_info *info, CORE_ADDR debug_base,
We expect gdbserver to provide updates for the namespace that We expect gdbserver to provide updates for the namespace that
contains LM, which would be this namespace... */ contains LM, which would be this namespace... */
so_list *sos = nullptr; std::vector<svr4_so> sos;
if (library_list.solib_lists.find (debug_base) auto it_debug_base = library_list.solib_lists.find (debug_base);
!= library_list.solib_lists.end ()) if (it_debug_base != library_list.solib_lists.end ())
std::swap (sos, library_list.solib_lists[debug_base]); std::swap (sos, it_debug_base->second);
if (sos == nullptr) else
{ {
/* ...or for the special zero namespace for earlier versions... */ /* ...or for the special zero namespace for earlier versions... */
if (library_list.solib_lists.find (0) auto it_0 = library_list.solib_lists.find (0);
!= library_list.solib_lists.end ()) if (it_0 != library_list.solib_lists.end ())
std::swap (sos, library_list.solib_lists[0]); std::swap (sos, it_0->second);
} }
/* ...but nothing else. */ /* ...but nothing else. */
for (const std::pair<CORE_ADDR, so_list *> tuple for (const auto &tuple : library_list.solib_lists)
: library_list.solib_lists) gdb_assert (tuple.second.empty ());
gdb_assert (tuple.second == nullptr);
*pnext = sos; std::move (sos.begin (), sos.end (), std::back_inserter (solist));
} }
else else
{ {
@ -1930,7 +1848,7 @@ solist_update_incremental (svr4_info *info, CORE_ADDR debug_base,
above check and deferral to solist_update_full ensures above check and deferral to solist_update_full ensures
that this call to svr4_read_so_list will never see the that this call to svr4_read_so_list will never see the
first element. */ first element. */
if (!svr4_read_so_list (info, lm, prev_lm, &pnext, 0)) if (!svr4_read_so_list (info, lm, prev_lm, solist, 0))
return 0; return 0;
} }
@ -1948,7 +1866,7 @@ disable_probes_interface (svr4_info *info)
"Reverting to original interface.")); "Reverting to original interface."));
free_probes_table (info); free_probes_table (info);
free_solib_lists (info); info->solib_lists.clear ();
} }
/* Update the solib list as appropriate when using the /* Update the solib list as appropriate when using the
@ -3145,7 +3063,7 @@ svr4_solib_create_inferior_hook (int from_tty)
/* Clear the probes-based interface's state. */ /* Clear the probes-based interface's state. */
free_probes_table (info); free_probes_table (info);
free_solib_lists (info); info->solib_lists.clear ();
/* Relocate the main executable if necessary. */ /* Relocate the main executable if necessary. */
svr4_relocate_main_executable (); svr4_relocate_main_executable ();
@ -3373,14 +3291,17 @@ find_debug_base_for_solib (so_list *solib)
svr4_info *info = get_svr4_info (current_program_space); svr4_info *info = get_svr4_info (current_program_space);
gdb_assert (info != nullptr); gdb_assert (info != nullptr);
for (const std::pair<CORE_ADDR, so_list *> tuple
: info->solib_lists) const lm_info_svr4 *lm_info = (const lm_info_svr4 *) solib->lm_info;
for (const auto &tuple : info->solib_lists)
{ {
CORE_ADDR debug_base = tuple.first; CORE_ADDR debug_base = tuple.first;
so_list *solist = tuple.second; const std::vector<svr4_so> &sos = tuple.second;
for (; solist != nullptr; solist = solist->next) for (const svr4_so &so : sos)
if (svr4_same (*solib, *solist)) if (svr4_same (solib->so_original_name, so.name.c_str (),
*lm_info, *so.lm_info))
return debug_base; return debug_base;
} }

View file

@ -48,6 +48,8 @@ struct lm_info_svr4 final : public lm_info
CORE_ADDR l_ld = 0, l_next = 0, l_prev = 0, l_name = 0; CORE_ADDR l_ld = 0, l_next = 0, l_prev = 0, l_name = 0;
}; };
using lm_info_svr4_up = std::unique_ptr<lm_info_svr4>;
/* Critical offsets and sizes which describe struct r_debug and /* Critical offsets and sizes which describe struct r_debug and
struct link_map on SVR4-like targets. All offsets and sizes are struct link_map on SVR4-like targets. All offsets and sizes are
in bytes unless otherwise specified. */ in bytes unless otherwise specified. */