aboutsummaryrefslogtreecommitdiff
path: root/gdb/solib.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/solib.c')
-rw-r--r--gdb/solib.c199
1 files changed, 86 insertions, 113 deletions
diff --git a/gdb/solib.c b/gdb/solib.c
index 881f0d9..fdefdf0 100644
--- a/gdb/solib.c
+++ b/gdb/solib.c
@@ -46,7 +46,6 @@
#include "gdb_bfd.h"
#include "gdbsupport/filestuff.h"
#include "gdbsupport/scoped_fd.h"
-#include "debuginfod-support.h"
#include "source.h"
#include "cli/cli-style.h"
@@ -114,7 +113,6 @@ show_solib_search_path (struct ui_file *file, int from_tty,
static gdb::unique_xmalloc_ptr<char>
solib_find_1 (const char *in_pathname, int *fd, bool is_solib)
{
- const solib_ops *ops = gdbarch_so_ops (current_inferior ()->arch ());
int found_file = -1;
gdb::unique_xmalloc_ptr<char> temp_pathname;
const char *fskind = effective_target_file_system_kind ();
@@ -297,12 +295,6 @@ solib_find_1 (const char *in_pathname, int *fd, bool is_solib)
target_lbasename (fskind, in_pathname),
O_RDONLY | O_BINARY, &temp_pathname);
- /* If not found, and we're looking for a solib, try to use target
- supplied solib search method. */
- if (is_solib && found_file < 0 && ops->find_and_open_solib)
- found_file = ops->find_and_open_solib (in_pathname, O_RDONLY | O_BINARY,
- &temp_pathname);
-
/* If not found, next search the inferior's $PATH environment variable. */
if (found_file < 0 && sysroot == NULL)
found_file = openp (current_inferior ()->environment.get ("PATH"),
@@ -476,58 +468,6 @@ solib_bfd_open (const char *pathname)
return abfd;
}
-/* Mapping of a core file's shared library sonames to their respective
- build-ids. Added to the registries of core file bfds. */
-
-typedef std::unordered_map<std::string, std::string> soname_build_id_map;
-
-/* Key used to associate a soname_build_id_map to a core file bfd. */
-
-static const struct registry<bfd>::key<soname_build_id_map>
- cbfd_soname_build_id_data_key;
-
-/* See solib.h. */
-
-void
-set_cbfd_soname_build_id (gdb_bfd_ref_ptr abfd, const char *soname,
- const bfd_build_id *build_id)
-{
- gdb_assert (abfd.get () != nullptr);
- gdb_assert (soname != nullptr);
- gdb_assert (build_id != nullptr);
-
- soname_build_id_map *mapptr
- = cbfd_soname_build_id_data_key.get (abfd.get ());
-
- if (mapptr == nullptr)
- mapptr = cbfd_soname_build_id_data_key.emplace (abfd.get ());
-
- (*mapptr)[soname] = build_id_to_string (build_id);
-}
-
-/* If SONAME had a build-id associated with it in ABFD's registry by a
- previous call to set_cbfd_soname_build_id then return the build-id
- as a NULL-terminated hex string. */
-
-static gdb::unique_xmalloc_ptr<char>
-get_cbfd_soname_build_id (gdb_bfd_ref_ptr abfd, const char *soname)
-{
- if (abfd.get () == nullptr || soname == nullptr)
- return {};
-
- soname_build_id_map *mapptr
- = cbfd_soname_build_id_data_key.get (abfd.get ());
-
- if (mapptr == nullptr)
- return {};
-
- auto it = mapptr->find (lbasename (soname));
- if (it == mapptr->end ())
- return {};
-
- return make_unique_xstrdup (it->second.c_str ());
-}
-
/* Given a pointer to one of the shared objects in our list of mapped
objects, use the recorded name to open a bfd descriptor for the
object, build a section table, relocate all the section addresses
@@ -547,36 +487,55 @@ solib_map_sections (solib &so)
gdb::unique_xmalloc_ptr<char> filename (tilde_expand (so.so_name.c_str ()));
gdb_bfd_ref_ptr abfd (ops->bfd_open (filename.get ()));
- gdb::unique_xmalloc_ptr<char> build_id_hexstr
- = get_cbfd_soname_build_id (current_program_space->cbfd,
- so.so_name.c_str ());
+
+ /* If we have a core target then the core target might have some helpful
+ information (i.e. build-ids) about the shared libraries we are trying
+ to load. Grab those hints now and use the below to validate or find
+ the shared libraries.
+
+ If we don't have a core target then this will return an empty struct
+ with no hint information, we then lookup the shared library based on
+ its filename. */
+ std::optional<CORE_ADDR> solib_addr = ops->find_solib_addr (so);
+ std::optional <const core_target_mapped_file_info> mapped_file_info
+ = core_target_find_mapped_file (so.so_name.c_str (), solib_addr);
/* If we already know the build-id of this solib from a core file, verify
it matches ABFD's build-id. If there is a mismatch or the solib wasn't
found, attempt to query debuginfod for the correct solib. */
- if (build_id_hexstr.get () != nullptr)
+ if (mapped_file_info.has_value ())
{
- bool mismatch = false;
+ bool mismatch = (abfd != nullptr
+ && build_id_bfd_get (abfd.get ()) != nullptr
+ && !build_id_equal (mapped_file_info->build_id (),
+ build_id_bfd_get (abfd.get ())));
- if (abfd != nullptr && abfd->build_id != nullptr)
- {
- std::string build_id = build_id_to_string (abfd->build_id);
-
- if (build_id != build_id_hexstr.get ())
- mismatch = true;
- }
if (abfd == nullptr || mismatch)
{
- scoped_fd fd = debuginfod_exec_query (
- (const unsigned char *) build_id_hexstr.get (), 0,
- so.so_name.c_str (), &filename);
-
- if (fd.get () >= 0)
- abfd = ops->bfd_open (filename.get ());
- else if (mismatch)
- warning (_ ("Build-id of %ps does not match core file."),
- styled_string (file_name_style.style (),
- filename.get ()));
+ /* If GDB found a suitable file during the file mapping
+ processing stage then lets use that. We don't check the
+ build-id after opening this file, either this file was found
+ by build-id, in which case it's going to match, or this file
+ doesn't have a build-id, so checking tells us nothing.
+ However, if it was good enough during the mapped file
+ processing, we assume it's good enough now. */
+ if (!mapped_file_info->filename ().empty ())
+ abfd = ops->bfd_open (mapped_file_info->filename ().c_str ());
+ else
+ abfd = nullptr;
+
+ if (abfd == nullptr)
+ abfd = find_objfile_by_build_id (current_program_space,
+ mapped_file_info->build_id (),
+ so.so_name.c_str ());
+
+ if (abfd == nullptr && mismatch)
+ {
+ warning (_ ("Build-id of %ps does not match core file."),
+ styled_string (file_name_style.style (),
+ filename.get ()));
+ abfd = nullptr;
+ }
}
}
@@ -634,7 +593,7 @@ solib::clear ()
this->abfd = nullptr;
/* Our caller closed the objfile, possibly via objfile_purge_solibs. */
- this->symbols_loaded = 0;
+ this->symbols_loaded = false;
this->objfile = nullptr;
this->addr_low = this->addr_high = 0;
@@ -694,7 +653,7 @@ solib_read_symbols (solib &so, symfile_add_flags flags)
so.objfile->addr_low = so.addr_low;
}
- so.symbols_loaded = 1;
+ so.symbols_loaded = true;
}
catch (const gdb_exception_error &e)
{
@@ -710,15 +669,16 @@ solib_read_symbols (solib &so, symfile_add_flags flags)
return false;
}
-/* Return true if KNOWN->objfile is used by any other so_list object
- in the list of shared libraries. Return false otherwise. */
+/* Return true if KNOWN->objfile is used by any other solib object
+ in PSPACE's list of shared libraries. Return false otherwise. */
static bool
-solib_used (const solib &known)
+solib_used (program_space *pspace, const solib &known)
{
- for (const solib &pivot : current_program_space->solibs ())
+ for (const solib &pivot : pspace->solibs ())
if (&pivot != &known && pivot.objfile == known.objfile)
return true;
+
return false;
}
@@ -796,8 +756,8 @@ 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. */
- intrusive_list<solib> inferior = ops->current_sos ();
- intrusive_list<solib>::iterator gdb_iter
+ owning_intrusive_list<solib> inferior = ops->current_sos ();
+ owning_intrusive_list<solib>::iterator gdb_iter
= current_program_space->so_list.begin ();
while (gdb_iter != current_program_space->so_list.end ())
{
@@ -826,7 +786,6 @@ update_solib_list (int from_tty)
if (inferior_iter != inferior.end ())
{
inferior.erase (inferior_iter);
- delete &*inferior_iter;
++gdb_iter;
}
@@ -839,21 +798,17 @@ update_solib_list (int from_tty)
current_program_space->deleted_solibs.push_back (gdb_iter->so_name);
- intrusive_list<solib>::iterator gdb_iter_next
- = current_program_space->so_list.erase (gdb_iter);
-
/* Unless the user loaded it explicitly, free SO's objfile. */
if (gdb_iter->objfile != nullptr
&& !(gdb_iter->objfile->flags & OBJF_USERLOADED)
- && !solib_used (*gdb_iter))
+ && !solib_used (current_program_space, *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_iter);
- delete &*gdb_iter;
- gdb_iter = gdb_iter_next;
+ gdb_iter = current_program_space->so_list.erase (gdb_iter);
}
}
@@ -1192,11 +1147,13 @@ clear_solib (program_space *pspace)
disable_breakpoints_in_shlibs (pspace);
- pspace->so_list.clear_and_dispose ([pspace] (solib *so) {
- notify_solib_unloaded (pspace, *so);
- pspace->remove_target_sections (so);
- delete so;
- });
+ for (solib &so : pspace->so_list)
+ {
+ notify_solib_unloaded (pspace, so);
+ pspace->remove_target_sections (&so);
+ };
+
+ pspace->so_list.clear ();
if (ops->clear_solib != nullptr)
ops->clear_solib (pspace);
@@ -1234,21 +1191,29 @@ sharedlibrary_command (const char *args, int from_tty)
solib_add (args, from_tty, 1);
}
-/* Implements the command "nosharedlibrary", which discards symbols
- that have been auto-loaded from shared libraries. Symbols from
- shared libraries that were added by explicit request of the user
- are not discarded. Also called from remote.c. */
+/* See solib.h. */
void
-no_shared_libraries (const char *ignored, int from_tty)
+no_shared_libraries (program_space *pspace)
{
/* The order of the two routines below is important: clear_solib notifies
the solib_unloaded observers, and some of these observers might need
access to their associated objfiles. Therefore, we can not purge the
solibs' objfiles before clear_solib has been called. */
- clear_solib (current_program_space);
- objfile_purge_solibs ();
+ clear_solib (pspace);
+ objfile_purge_solibs (pspace);
+}
+
+/* Implements the command "nosharedlibrary", which discards symbols
+ that have been auto-loaded from shared libraries. Symbols from
+ shared libraries that were added by explicit request of the user
+ are not discarded. */
+
+static void
+no_shared_libraries_command (const char *ignored, int from_tty)
+{
+ no_shared_libraries (current_program_space);
}
/* See solib.h. */
@@ -1294,7 +1259,7 @@ reload_shared_libraries_1 (int from_tty)
for (solib &so : current_program_space->solibs ())
{
const char *found_pathname = NULL;
- bool was_loaded = so.symbols_loaded != 0;
+ bool was_loaded = so.symbols_loaded;
symfile_add_flags add_flags = SYMFILE_DEFER_BP_RESET;
if (from_tty)
@@ -1313,7 +1278,7 @@ reload_shared_libraries_1 (int from_tty)
&& filename_cmp (found_pathname, so.so_name.c_str ()) != 0))
{
if (so.objfile && !(so.objfile->flags & OBJF_USERLOADED)
- && !solib_used (so))
+ && !solib_used (current_program_space, so))
so.objfile->unlink ();
current_program_space->remove_target_sections (&so);
so.clear ();
@@ -1700,12 +1665,20 @@ remove_user_added_objfile (struct objfile *objfile)
{
if (objfile->flags & OBJF_USERLOADED)
{
- for (solib &so : objfile->pspace->solibs ())
+ for (solib &so : objfile->pspace ()->solibs ())
if (so.objfile == objfile)
so.objfile = nullptr;
}
}
+/* See solist.h. */
+
+std::optional<CORE_ADDR>
+default_find_solib_addr (solib &so)
+{
+ return {};
+}
+
void _initialize_solib ();
void
@@ -1725,7 +1698,7 @@ _initialize_solib ()
= add_info ("sharedlibrary", info_sharedlibrary_command,
_ ("Status of loaded shared object libraries."));
add_info_alias ("dll", info_sharedlibrary_cmd, 1);
- add_com ("nosharedlibrary", class_files, no_shared_libraries,
+ add_com ("nosharedlibrary", class_files, no_shared_libraries_command,
_ ("Unload all shared object library symbols."));
add_setshow_boolean_cmd ("auto-solib-add", class_support, &auto_solib_add,